git rebase
は便利ですが、時々コンフリクトが起きて停止します:
$ git rebase master
Applying: Add GeneratedColumn
Applying: Add EnumerateGeneratedColumns
Applying: Use EnumerateGeneratedColumns to CreateQuery
Using index info to reconstruct a base tree...
M AAA/BBB/Summary.cs
Falling back to patching base and 3-way merge...
Auto-merging AAA/BBB/Summary.cs
CONFLICT (content): Merge conflict in AAA/BBB/Summary.cs
Failed to merge in the changes.
Patch failed at 0037 Use EnumerateGeneratedColumns to CreateQuery
The copy of the patch that failed is found in:
c:/Users/VimWizard/projects/SecretProject/.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 diff
で確認しますよね。
あれこれ端末内で情報を表示して状況を確認した結果、コンフリクトの解決に取り掛かる訳ですが、
解決するには元々 何のコミットをapplyしようとしてコンフリクトしたのか という情報も重要です。
この情報自体は上記の git rebase
からのメッセージに含まれています。
が、しかし、
git status
や git diff
を何回も実行しているので git rebase
のメッセージは流れています。git rebase
はコンフリクトしたコミットのコミットメッセージは表示してくれているものの、どうにかして一発でapplyし損ねたコミットを表示できないものでしょうか。
ヒントは git rebase
からのメッセージにあります:
The copy of the patch that failed is found in:
c:/Users/VimWizard/projects/SecretProject/.git/rebase-apply/patch
このファイルには以下の内容が含まれています:
git diff
の形式)という訳で問題のコミットは次のコマンドで即座に表示できます:
git show $(head -n1 "$(git rev-parse --git-dir)/rebase-apply/patch")
でもこれだとrebase中でない時にうっかり実行するとよく分からないことになりますね。
ファイルが存在する場合にのみ実行されるようにしましょう:
f="$(git rev-parse --git-dir)/rebase-apply/patch"
if [ -f "$f" ]
then
git show $(head -n1 "$f")
else
echo "Heh?"
fi
流石に長ったらしくて即座に入力できないし覚えてもいられないので好みに合わせてエイリアスを設定しておくと良いでしょう:
git config alias.wtf 'f="$(git rev-parse --git-dir)/rebase-apply/patch"; if [ -f "$f" ]; then git show $(head -n1 "$f"); else echo "Heh?"; fi'
これで困った時は
git wtf
で解決できるようになりました。やりましたね。
次回は Mercurial 編です。