git rebaseで、誤って終了したときの対応方法
前回のエントリでは、マージコミットが含まれるブランチでrebaseする方法をまとめた。
実はこのとき
$ git rebase -i HEAD~~
-i
オプションのみ指定して実行して、マージコミットが含まれていないことに気づいたので
$ git rebase -i HEAD~~
Successfully rebased and updated refs/heads/master.
何も変更しないつもりでそのままエディタを終了したのだが、ブランチを確認したところ
$ git log --graph --pretty=format:'%h -%d %s' --abbrev-commit --date=relative
* b2b6cf6 - (HEAD, master) add b.txt
* f5622e4 - add a.txt
* 0d8bbff - new
マージコミットがすべてなくなってしまった。このときに対応した方法について。
まず、reflog
でgitコマンドの実行履歴を参照する。
$ git reflog
b2b6cf6 HEAD@{0}: rebase -i (finish): returning to refs/heads/master
b2b6cf6 HEAD@{1}: rebase -i (pick): add b.txt
f5622e4 HEAD@{2}: rebase -i (start): checkout HEAD~~
cd00264 HEAD@{3}: merge branch-b: Merge made by the 'recursive' strategy.
521e66f HEAD@{4}: checkout: moving from branch-b to master
8f7b4c7 HEAD@{5}: commit: add b.txt
521e66f HEAD@{6}: checkout: moving from master to branch-b
521e66f HEAD@{7}: merge branch-a: Merge made by the 'recursive' strategy.
0d8bbff HEAD@{8}: checkout: moving from branch-a to master
f5622e4 HEAD@{9}: commit: add a.txt
0d8bbff HEAD@{10}: checkout: moving from master to branch-a
0d8bbff HEAD@{11}: commit (initial): new
ここからrebase
を開始する直前の状態を確認し(HEAD@{3}
の部分)
$ git reset --hard HEAD@{3}
HEAD is now at cd00264 Merge branch 'branch-b'
reset
で該当部分までリセットする。こうすると
$ git log --graph --pretty=format:'%h -%d %s' --abbrev-commit --date=relative
* cd00264 - (HEAD, master) Merge branch 'branch-b'
|\
| * 8f7b4c7 - add b.txt
|/
* 521e66f - Merge branch 'branch-a'
|\
| * f5622e4 - add a.txt
|/
* 0d8bbff - new
rebase
する前の状態まで戻る。
なお、rebase
の-i
オプションで何も変更しないようにするには、エディタで表示しているときに
pick f5622e4 add a.txt
pick 8f7b4c7 add b.txt
# Rebase 0d8bbff..cd00264 onto 0d8bbff ( 2 TODO item(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
上記のpickコマンドで始まる行(最初の2行)をすべて削除して保存し、エディタを終了すると
$ git rebase -i HEAD~~
Nothing to do
何も変更されずにrebase
が終了する。