Git のファストフォワードマージとは


Git で他のブランチを現在のブランチにマージさせる時に発生しうるファストフォワードマージとはどのようなものなのか, どのような時に起こるのか起こらないのか紹介します.

ファストフォワードマージとは

Git のファストフォワードマージとは, マージされるブランチの HEAD をマージするブランチの先端にそのまま移動させるマージを指します.

ファストフォワードという言葉がテープを急いで先に進めるという意味のように, ファストフォワードマージはマージコンフリクトが一切発生しない素早いマージのためこのように呼ばれるのでしょう.

例えば次のような master ブランチに hotfix ブランチをマージさせると, そのマージはファストフォワードとなります:

                       A -- B -- C <- hotfix
                      /
                     /
    D --- E ---F ---G <- master <- HEAD

次のコマンドで masterhotfix をマージさせると:

git merge hotfix

次のようなメッセージが表示されます:

Updating ecaf02c..754d0b9
Fast-forward
 example.txt | 3 +++
 1 file changed, 3 insertions(+)

メッセージに Fast-forward とあるように, このマージがファストフォワードであると確認できます.

するとヒストリはこのようになります:

    D --- E ---F ---G --- A --- B --- C (HEAD -> master, hotfix)

このようにファストフォワードマージの場合, master ブランチの HEADG から hotfix ブランチの C にそのまま移動します.

masterhotfix が分岐しない連続的なヒストリのためこのようにすることができます.

ファストフォワードマージとならない場合

マージがファストフォワードマージとならない場合として, マージされるブランチ同士が分岐している場合です.

次のように master ブランチと hotfix ブランチがコミット E から分岐している場合, master ブランチに hotfix ブランチをマージさせるとマージコンフリクトが発生し, そのコンフリクトを解決してコミット H を作るため, ファストフォワードマージとなりません. いわゆる E, C G の 3 点による 3-way マージとなります:

             A -- B -- C <- hotfix
            /
           /
    D --- E ---F ---G <- master <- HEAD

次のコマンドで masterhotfix をマージすると:

git merge hotfix

このようなメーセージが表示されます:

Auto-merging example.txt
CONFLICT (content): Merge conflict in example.txt
Automatic merge failed; fix conflicts and then commit the result.

メッセージに Merge conflict とあるように, マージコンフリクトが発生するので, それを解決したコミットをしなくてはいけません.

そして新たなコミット H が作られ, ヒストリは次のようになります:

             A -- B -- C
            /           \
           /             \
    D --- E ---F ---G --- H (HEAD -> master, hotfix)

このようにマージするブランチ同士が分岐していると, ファストフォワードマージとなりません.

まとめ

ファストフォワードマージは, マージを行う際にマージされるブランチから分岐していない, ただ上積みにされたブランチをマージする時に発生します.

参考資料