git rebaseでconflictした際の対応をシンプルに確認


概要

下記のように、ある地点からfeatureブランチを切って開発を進めている間に、masterブランチにもcommitが行われるような状況はよくあると思います。

この状況にて、featureブランチからPRを出すときには、feature側にてmasterの先頭から変更コミットを生やすようにすることが多いと思います(fast-forward?)。

このときmasterのコミットとfeatureのコミットがコンフリクトした場合のgit rebase --continuegit rebase --skipの挙動を確認していきます。

状況

下記のようなgit logの状況から、featureブランチ側でgit rebase masterをしていきます。

  • target1 in featuretarget2 in featureのコミットはmasterのコミットとコンフリクトしています。
  • target3 in featureのコミットはコンフリクトしません。

rebaseしてみる

git rebase masterする

featureブランチにて、git rebase masterをすると以下のようになります。

[nannany@minamiyoshihikonoMacBook-Pro practice-git (feature)]$ git rebase master    
First, rewinding head to replay your work on top of it...
Applying: target1 in feature
Using index info to reconstruct a base tree...
M       target1.md
Falling back to patching base and 3-way merge...
Auto-merging target1.md
CONFLICT (content): Merge conflict in target1.md
error: Failed to merge in the changes.
Patch failed at 0001 target1 in feature
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

上記の状況はmasterブランチの先端にtarget1 in featureのコミットをつけようとしてコンフリクトしている状況です。

コンフリクトを解消したらgit add .します。

[nannany@minamiyoshihikonoMacBook-Pro practice-git (feature *+|REBASE 1/3)]$ git add .   

git rebase --continue

1つ目のコミットのコンフリクトを解消してgit add .したら、rebaseを続けるためgit rebase --continueします。

[nannany@minamiyoshihikonoMacBook-Pro practice-git (feature +|REBASE 1/3)]$ git rebase --continue 
Applying: target1 in feature
Applying: target2 in feature
Using index info to reconstruct a base tree...
M       target2.md
Falling back to patching base and 3-way merge...
Auto-merging target2.md
CONFLICT (content): Merge conflict in target2.md
error: Failed to merge in the changes.
Patch failed at 0002 target2 in feature
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

上記は2つ目のコミットを先ほどつけたコミットのさらに先端につけようとしてコンフリクトしている状況です。

ここでもコンフリクトするので解消します。ただし、今回はmaster側の変更を取り込むこととします。コンフリクト解消したら、git add .します。

git rebase --skip

先ほどの、target2 in featureコミットは結局反映しないので、コミット履歴には残さないようにしたいです。そのような時はgit rebase --skipをします。

[nannany@minamiyoshihikonoMacBook-Pro practice-git (feature *+|REBASE 2/3)]$ git rebase --skip       
Applying: target3 in feature

これでtarget2 in featureはコミット履歴には残らないようになります。

target3 in featureのコミットは?

target3 in featureのコミットはコンフリクトしないので、何もせずともそのままコミット履歴に残ります。

最終的なコミット履歴は?

コミット履歴は最終的に下記のようになります。

masterブランチの先にskipしたtarget2 in feature以外のコミットがくっついていることが分かります。