Git – merge – no-fast-forward – 競合なし

概要

  • ブランチをマージするとき、それぞれのマージでコミットがされているが、各コミットは互いに競合しない場合
  • このようなときは、Gitがその内容を解析して、マージコミットを発行してマージされる
  • この場合、マージ下でも作業が発生しているので、単なる早送り(fast-forward)にはならない
  • このようなマージをno-fast-forwardと呼ぶ

準備

リポジトリーの準備

Git-ブランチ-基本操作-fast-fowardのリポジトリーを使う。イニシャルコミットの状態から始める。

ブランチの作成

git branchコマンドで、topicブランチを作る。

各ブランチでの変更作業

mainブランチとtopicブランチで交互にコミット

まずmainブランチでmain.txtファイルを新規作成してコミット。

topicブランチに移動してtopic.txtを新規作成、コミット。

mainブランチに移動してmain.txtの内容を更新。

topicブランチに移動してtopic.txtの内容を更新。

状態確認

mainブランチの状態は以下の通り。

topicブランチの状態は以下の通り。

mainブランチとtopicブランチのコミットは独立に行われていて、互いに影響していない。

マージ

mainブランチでtopicブランチのコミットをマージ。

git merge topic実行直後にエディター画面になり、以下のように表示される。

末尾に「マージテスト」の1行を追加し、保存・終了(vi/vimエディターの場合は:wq)。

するとコマンドラインに戻り、mainブランチから見て1つのファイル(topic.txt)が更新(作成)され、2行挿入されていることが表示されている。

マージの結果、2つのファイルとその内容が反映されている。

ログを確認すると、時系列でmainブランチ、topicブランチでの各コミットが並び、最後にマージコミットも記録されている。

ログ表示のオプションで、ブランチごとのコミットがわかるよう、以下のコマンドで表示させてみる。

git log --graph

なお、この段階でtopicブランチのコミット履歴はそのまま残っている。

マージ後は以下のような状態。

mainブランチでは一連のコミットが時系列順に並べられるが、main/topic各ブランチでのコミットは識別されている。また、topicブランチでのコミット履歴も別に残っている。

マージの巻き戻し

効かない例

競合が発生していないのでabortは効かない。

もちろん、マージコミットの場所でも効かない。

失敗例

マージコミットの1つ手前のtopicでリセットすると、topicブランチでのコミットだけが残ってしまった。

mainブランチでのログ。main関係のコミットが消えてしまった。

topicブランチでのログ。こちらは変化なし。

正しい巻き戻し方

以下のいずれか。

reset --hard HEAD^
git reset --hard HEAD~

mainブランチのログ。mainでのコミットだけが残っている。

topicブランチのログ。topicでのコミットのみ。

マージ後のブランチ削除

再度マージする。

ログ確認。

topicブランチ削除。

mainブランチのログにはno-fast-forwardマージの記録が残る。

fast-forwardマージは不可

main/topic各ブランチでコミットがある状態では、fast-forwardでのマージを強制できない。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です