📚

【Git】fast-forwardとnon fast-forwardの違いについての備忘録

2023/05/02に公開

導入

マージのオプションであるfast-forwardとnon fast-forwardの違いについて大雑把に整理した。

そもそも

  • fast-forwardとnon fast-forwardとはマージ(merge)のオプションである。
  • マージ実行時にオプションを加えることができる。
  • fast-forwardマージは早送りマージとも言われる。

※説明の際に用いるブランチについて以下のような構成となっていることとする。

  • mainブランチ。
  • featureブランチはmainブランチから分岐。
  • featureブランチをmainブランチにマージしたい。

fast-forward(早送り)マージについて

git checkout main 
git merge feature

省略せずに書くと以下のようになる。

 git checkout main
 git merge --ff feature
  • デフォルトの設定ではfast-forward(早送り)になっている。


fast-forwardマージした時のGitHubのNetwork graph

non fast-forwardマージについて

git checkout main 
git merge --no-ff feature
  • マージをするときに「--no-ff」と追加で書く。

    non fast-forwardマージした時のGitHubのNetwork graph

ドキュメントを読んでみる

ここではGitのDocumentationのReferenceからマージのオプションについて読んでみることにする。

--commit
--no-commit
Perform the merge and commit the result. This option can be used to override --no-commit.

With --no-commit perform the merge and stop just before creating a merge commit, to give the user a chance to inspect and further tweak the merge result before committing.

Note that fast-forward updates do not create a merge commit and therefore there is no way to stop those merges with --no-commit. Thus, if you want to ensure your branch is not changed or updated by the merge command, use --no-ff with --no-commit.

引用元:https://git-scm.com/docs/merge-options
上記の文章をDeepLで翻訳し、少し修正した文章が以下のものになる。

--commit
--no-commit
マージを実行し、その結果をコミットする。このオプションは --no-commit を上書きするために使用することができます。

no-commitを使用すると、マージを実行し、マージコミットを作成する直前に停止し、コミットする前にマージ結果を検査し、さらに調整する機会をユーザーに与えます。

fast-forward更新はマージコミットを作成しないので、--no-commitでそれらのマージを停止する方法がないことに注意してください。したがって、マージコマンドによってブランチが変更または更新されないようにしたい場合は、--no-commit とともに --no-ff を使用します。

一番下の段落が関係ありそうだ。
ポイントとしては

  • fast-forwardはマージコミットを作成しない

という点だろうか。
この「マージコミット」があるかないかという点が違いの一つだろう。
「マージコミット」についてはGitHubのネットワークグラフを見ると何となく理解できるかもしれない。


fast-forwardマージ

non fast-forwardマージ:上図…featureブランチの2つ目の丸に「fourth commit」、下図…ブランチ合流点に「Merge branch 'feature'」
fast-forwardマージのネットワークグラフを見るとコミットを表す丸が4つあり、最後の丸が「fourth commit」となっている。
対して、non fast-forwardマージ時はfeatureブランチの2つ目の丸が「fourth commit」となっており、ブランチの合流点が「Merge branch 'feature'」という丸になっている。
つまり、ブランチの合流点にある「Merge branch 'feature'」という丸が「マージコミット」ということなのだろう。
この合流点が表されるかどうかという点がfast-forwardマージとnon fast-forwardの違いと言える。

使い分け

fast-forwardマージ

  • マージ元のブランチ(今回でいうmainブランチ)に変更がなかった場合。

non fast-forwardマージ

  • マージ元のブランチに新しいコミットが発生している場合。
  • マージするブランチ(今回でいうfeatureブランチ)を分かりやすく残したい場合。
  • 明示的にマージが行われたことを示したい場合。

おまけ

non fast-forwardオプションをデフォルト設定にする。

git config --global merge.ff false

参考リンク

https://git-scm.com/docs/merge-options
https://git-scm.com/docs/git-merge
↓分かりやすくマージについて説明されている。
https://backlog.com/ja/git-tutorial/stepup/04/

Discussion