作業ノート

様々なまとめ、雑感など

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が終了する。

参考