Git のファストフォワードマージとは
Git で他のブランチを現在のブランチにマージさせる時に発生しうるファストフォワードマージとはどのようなものなのか, どのような時に起こるのか起こらないのか紹介します.
ファストフォワードマージとは
Git のファストフォワードマージとは, マージされるブランチの HEAD をマージするブランチの先端にそのまま移動させるマージを指します.
ファストフォワードという言葉がテープを急いで先に進めるという意味のように, ファストフォワードマージはマージコンフリクトが一切発生しない素早いマージのためこのように呼ばれるのでしょう.
例えば次のような master
ブランチに hotfix
ブランチをマージさせると, そのマージはファストフォワードとなります:
A -- B -- C <- hotfix
/
/
D --- E ---F ---G <- master <- HEAD
次のコマンドで master
に hotfix
をマージさせると:
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
ブランチの HEAD
がG
から hotfix
ブランチの C
にそのまま移動します.
master
と hotfix
が分岐しない連続的なヒストリのためこのようにすることができます.
ファストフォワードマージとならない場合
マージがファストフォワードマージとならない場合として, マージされるブランチ同士が分岐している場合です.
次のように master
ブランチと hotfix
ブランチがコミット E
から分岐している場合, master
ブランチに hotfix
ブランチをマージさせるとマージコンフリクトが発生し, そのコンフリクトを解決してコミット H
を作るため, ファストフォワードマージとなりません. いわゆる E
, C
G
の 3 点による 3-way マージとなります:
A -- B -- C <- hotfix
/
/
D --- E ---F ---G <- master <- HEAD
次のコマンドで master
に hotfix
をマージすると:
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)
このようにマージするブランチ同士が分岐していると, ファストフォワードマージとなりません.
まとめ
ファストフォワードマージは, マージを行う際にマージされるブランチから分岐していない, ただ上積みにされたブランチをマージする時に発生します.
参考資料
関連記事
Git の mergetool で vimdiff を指定して Vim でマージコンフリクトを解決してみた2018.08.20
Git のコミット履歴を大胆に書き換えるなら git rebase -i がオススメ2018.08.23
Git の merge.conflictStyle を merge から diff3 に変更したら, マージコンフリクトがより解決しやすくなった2018.08.19
Git で再帰的ストラテジでマージする時のストラテジオプション ours と theirs の違い2018.08.18
Git の 3-way マージで共通祖先が 2 つの場合, 共通祖先はどんな感じになるのか調べてみた2018.08.22