Dev Study
← Gitの内部構造から理解する コース

8. マージ — なぜポインタの付け替えで済むことがあるのか

マージには大きく2つの場合があります。どちらになるかは「履歴が分岐しているかどうか」だけで決まり、内部構造を知っていれば事前に予測できます。

① 分岐していない場合 — fast-forward

mainがfeatureの祖先になっているとき
A ← B ← Cmain は A、feature は C を指す
mainから見ると、Cへは一本道でたどり着ける
mainファイルの40文字をCのハッシュに書き換えるだけ新しいコミットは作られない
  • ・作られるオブジェクトは0個。41バイトのファイルの中身が変わるだけ
  • ・履歴は一本のまま。マージした痕跡はコミットには残らない
  • ・これが「マージがポインタの付け替えに近い」場合の正体

mainに何も新しいコミットがなければ、featureの先端まで「早送り」すれば済みます。これをfast-forwardと呼びます。

② 分岐している場合 — マージコミット

両方のブランチが独自に進んでいるとき
共通の祖先 B
ここから両側が別々に進んだ
main: DBの子
feature: EBの子
早送りできないので新しいコミットを作る
マージコミット Mparent が2つ: D と E
  • ・Mは parent 行を2つ持つ。ここで履歴が「合流」する
  • ・これ以降、履歴は一本の鎖ではなくグラフになる
  • ・Gitは共通の祖先Bを自動で見つけ、3点(B・D・E)を比べて統合する

この「共通の祖先を見つけて3方向を比べる」という方式を3-way mergeと呼びます。次のコンフリクトの説明に直結します。

サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗