🐧 Linux 総合学習プラットフォーム
Git バージョン管理 ・ 中級

ブランチとマージ

ブランチは履歴を枝分かれさせる仕組みで、本流に影響を与えずに新機能や修正を試せます。git branch で一覧や作成を行い、git switch(または git checkout)で作業対象を切り替えます。枝で仕上げた変更は git merge で元のブランチに取り込みます。いまどの枝にいるかは HEAD という印が指し示しており、切り替えると HEAD の指す先が動きます。

新機能を試したいが、本流を壊すのは怖い。そんなときに使うのがブランチ(git-branch)だ。履歴を枝分かれさせる仕組みである。

本流(多くの場合 main という名前の枝)を壊さないまま、別の枝で新機能の開発や実験を進め、うまくいったら本流に合流させる。この合流がマージ(git-merge)だ。

💡
ポイントブランチは履歴を枝分かれさせる仕組み。本流を壊さず別の枝で試し、うまくいったらマージで本流に合流させる。

なぜ枝を分けるのか。開発途中の不安定な状態を本流に混ぜずに済むからだ。たとえば新機能を作っている最中に、本流に対して急ぎの不具合修正が必要になっても、枝が分かれていればお互いに干渉しない。

🔗
たとえブランチは「あるコミットを指す軽い目印」にすぎない。だから作るのも切り替えるのも一瞬で、何本でも気軽に分けられる。

Git のブランチは内部的には「あるコミットを指す軽い目印」にすぎない。だから作るのも切り替えるのも一瞬で、気軽に何本でも分けられるのが大きな特徴だ。

枝分かれして、戻ってくるmainfeature① 本流のコミット② 枝を作って移る③ 枝の上でコミット④ マージで合流本流を壊さないまま別の枝で試し、仕上がってから1本に戻す

🌱 枝を作って乗り移る

現在のブランチの一覧は git branch で確認する。実行すると枝の名前が並び、いま自分がいる枝には先頭に * が付く。

新しい枝を作ってそこへ移動するには git switch -c <名前> を使う。-c は create(作成)の意味だ。たとえば git switch -c feature と打つと feature という枝が作られ、同時にそこへ移動する。移動後にもう一度 git branch を打つと、* が feature に移っているのが分かる。

git branch で一覧(* が現在地)、git switch -c feature で feature を作って移動、git switch main で本流へ戻る。

元の枝へ戻るときは -c を付けずに git switch main とする。

つまずき以前は git checkout -b feature と書いた。checkout は今も使えるが「切り替え」と「復元」を兼ねて紛らわしいため、目的別の git switch が現在の推奨だ。

なお、以前は同じことを git checkout -b feature と書いていた。今でも checkout は使えるが、「枝の切り替え」と「ファイルの復元」という別々の役割を1つに抱えていて紛らわしかった。そのため、目的別に分かれた git switch が現在の推奨だ。古い資料では checkout が出てくるので、読み替えられるようにしておくと安心だ。

🎯 切り替えるとき内部で何が起きるか

いま自分がどの枝にいるかは、HEAD(git-head)という印が指し示している。HEAD は「現在の作業位置」を表す矢印で、ふだんは今いるブランチの先頭のコミットを指している。

git switch で枝を切り替えると、この HEAD の指す先が移動する。それに合わせて作業ツリーの中身も、切り替えた枝の状態に入れ替わる。

mainfeatureHEAD枝の切り替え=HEAD の指す先を別の枝へ向け直すこと

つまり枝を切り替えるとは、HEAD を別の枝へ向け直すことだ。そう考えると、頭の中で整理しやすくなる。

🔀 枝を本流へ戻すマージ

枝の上で git add と git commit を重ねて作業を仕上げたら、本流に戻ってから取り込む。

具体的な流れはこうだ。feature 上で echo 'feature work' > feature.txt のように作業し、git add feature.txt、git commit -m 'Add feature file' でコミットする。そのうえで git switch main で本流へ移り、git merge feature と打って feature の成果を取り込む。

git switch main で本流へ移り、git merge feature と打つと feature の成果を本流に取り込める。

このとき、本流側に枝を分けたあとの新しいコミットが無ければ、Git は本流の目印を枝の先頭までスッと進めるだけで合流が完了する。これを fast-forward(早送り)と呼び、「Fast-forward」と表示され、新しいコミットは作られない。

fast-forward(早送り)本流が進んでいなければ目印を進めるだけ3-way merge(両方が進んだ場合)マージコミット

一方、本流と枝の両方がそれぞれ別々にコミットを進めていた場合は早送りできない。Git は両者を突き合わせて1つの「マージコミット」を新たに作る。これは共通の祖先・本流の先端・枝の先端という3点を見比べて統合するため、3-way merge(3方向マージ)と呼ばれる。

⚡ 衝突したらどうするか

マージで初学者が身構えるのがコンフリクト(衝突)だ。これは、2つの枝で同じファイルの同じ行を別々の内容に書き換えていたときに起こる。

Git はどちらを採用すべきか自分では判断できない。だから勝手に決めずに印を付けて人間に委ねる。

つまずきコンフリクトは「同じファイルの同じ行を別々に書き換えた」ときに起こる。Git は勝手に決めず、印を付けて人間に判断を委ねる。

マージを実行すると「CONFLICT」と表示され、「fix conflicts and then commit the result(衝突を直してからコミットせよ)」という案内が出る。

衝突したファイルを開くと、Git が印を書き込んでいる。&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD から ======= までが今いる枝側の内容、======= から &gt;&gt;&gt;&gt;&gt;&gt;&gt; までが取り込もうとした枝側の内容だ。

🧩 衝突を解決する手順

印が書き込まれたファイルの解決手順は、あわてなければ簡単だ。

<<<<<<< HEAD今いる枝の内容=======取り込む枝の内容>>>>>>>印を消し残す形に残したい最終形だけgit add → git commit

エディタでそのファイルを開き、&lt;&lt;&lt;&lt;&lt;&lt;&lt;・=======・&gt;&gt;&gt;&gt;&gt;&gt;&gt; の3種類の印と、不要なほうの内容を削って、残したい最終形だけにする。

あとは git add でそのファイルを載せ、git commit で確定すればマージ完了だ。最後に git status を打ち、「nothing to commit, working tree clean」と出れば解決できている。

つまずき最も多い失敗は ======= などの印を消し忘れてコミットすること。3種類の印は必ず全部消す。衝突中のファイルは git status が Unmerged paths として教えてくれる。

ここで最も多い失敗が、======= などの印を消し忘れて、そのままコミットしてしまうことだ。3種類の印は必ず全部消すこと、そして今どのファイルが衝突中かは git status が「Unmerged paths」として教えてくれること。この2点を覚えておけば落ち着いて対処できる。

🛠 実務ではどう回すのか

実務では、「1つの作業につき1本の枝」を基本にすると見通しが良くなる。

コツ新機能なら feature-login、不具合修正なら fix-crash のように、何の作業か分かる名前で枝を切る。1作業1ブランチが見通しの基本だ。

新機能なら feature-login、不具合修正なら fix-crash のように、何の作業かが分かる名前で枝を切る。その枝で作業し終えたら本流へマージし、不要になった枝は片付ける。この流れを繰り返す。

本流を常に「動く状態」に保ったまま、危なっかしい作業は枝の上で完結させられる。これがブランチを使う最大の利点だ。

複数人で開発するときはこの恩恵がいっそう大きい。各自が自分の枝で並行して進め、できたものを順にマージしていくのが、現代的な開発の基本形になっている。

まずはひとりでも、機能ごとに枝を分けて作業する練習から始めると、マージとコンフリクトの感覚が自然に身につく。

この項目に出てくる用語

ブランチぶらんち
履歴を枝分かれさせて並行作業するための仕組み。
マージまーじ
別ブランチの変更を、いまのブランチに統合する操作。
HEADへっど
いま自分が見ている(作業中の)コミットを指す印。

関連コマンド

git branchgit switchgit checkoutgit merge

▶ 学習アプリでこの続きを学ぶ・演習する