カレントブランチに対して上流開発ブランチからの rebase を行う際に、コンフリクトが生じ、以下のメッセージが出て処理が止まったとする。
$ git rebase @{upstream} First, rewinding head to replay your work on top of it... Applying: THIS_COMMIT_MESSAGE_TITLE0 Using index info to reconstruct a base tree... M relative/path/to/file.txt Falling back to patching base and 3-way merge... Auto-merging relative/path/to/file.txt CONFLICT (content): Merge conflict in relative/path/to/file.txt Failed to merge in the changes. Patch failed at 0001 THIS_COMMIT_MESSAGE_TITLE0 The copy of the patch that failed is found in: /home/path/to/GIT_WORK_TREE/.git/rebase-apply/patch When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort".
ここでするべきことは表示されたメッセージに書かれたとおりだが、この情報は git status で確認することも可能。
$ git status rebase in progress; onto XXXXXXX You are currently rebasing branch 'current/branch/name/at/starting/rebase' on 'XXXXXXX'. (fix conflicts and then run "git rebase --continue") (use "git rebase --skip" to skip this patch) (use "git rebase --abort" to check out the original branch) Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) both modified: relative/path/to/file.txt no changes added to commit (use "git add" and/or "git commit -a")
また、diff コマンドを使えばコンフリクトが発生した場所を確認できる。
$ git diff diff --cc relative/path/to/file.txt index DDDDDDD,BBBBBBB..0000000 --- a/relative/path/to/file.txt +++ b/relative/path/to/file.txt @@@ -5,7 -5,7 +5,11 @@@ msgid " CCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ++<<<<<<< HEAD +OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ++======= + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT ++>>>>>>> THIS_COMMIT_MESSAGE_TITLE0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCC @@@ -13,7 -13,7 +17,11 @@@ CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ++<<<<<<< HEAD +OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ++======= + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT ++>>>>>>> THIS_COMMIT_MESSAGE_TITLE0 CCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCC
ここでは @{upstream} の変更を優先してコンフリクトを解消する。つまり、HEAD からの行を残して、THIS_COMMIT_MESSAGE_TITLE0 からの行を削除する。ここで大事なのは、git checkout --ours を使うこと。git checkout --theirs は間違い。なぜなら、git rebase でコンフリクトが起きた場合、カレントブランチは rebase を実行したブランチではなく、新たに作られた rebase 作業用の無名ブランチにいて、この無名ブランチは @{upstream} と rebase 実行時のカレントブランチの共通の子孫から作られ、先に @{upstream} (ours) の変更が取り込まれ、そして今 rebase 実行時のカレントブランチ (theirs) の変更が取り込もうとした際にコンフリクトが起きたから。
$ git checkout --ours relative/path/to/file.txt $ git branch * (no branch, rebasing current/branch/name/at/starting/rebase) current/branch/name/at/starting/rebase (snip)
コンフリクトの解決が済んだら git diff で確認。git は修正があったファイルを知っているので、diff を取ってくれるが、結局違いはない事がわかる。OK なので git add でワーキングツリーの内容をインデックスに登録。
$ git diff diff --cc relative/path/to/file.txt index DDDDDDD,BBBBBBB..0000000 --- a/relative/path/to/file.txt +++ b/relative/path/to/file.txt $ git add relative/path/to/file.txt
git rebase の再開を指令すると、rebase 実行時のカレントブランチの変更が全て破棄されているけど良いか聞かれる。
$ git rebase --continue Applying: THIS_COMMIT_MESSAGE_TITLE0 No changes - did you forget to use 'git add'? If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch. When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort".
今回の場合問題ないので、git rebase --skip。新たにコンフリクト発生。先程と同様に @{upstream} の修正を優先して取り込む。コンフリクトが発生したファイルが複数個あって、@{upstream} の修正を取り込む方針で問題ないことがわかっているならば、 git rebase --skip を何回も実行してもOK。
$ git rebase --skip Applying: THIS_COMMIT_MESSAGE_TITLE1 Using index info to reconstruct a base tree... M relative/path/to/file.txt Falling back to patching base and 3-way merge... Auto-merging relative/path/to/file.txt CONFLICT (content): Merge conflict in relative/path/to/file.txt Failed to merge in the changes. Patch failed at 0002 THIS_COMMIT_MESSAGE_TITLE1 The copy of the patch that failed is found in: /home/path/to/GIT_WORK_TREE/.git/rebase-apply/patch When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort".