日々常々

ふつうのプログラマがあたりまえにしたいこと。

git commit --amend したコミットをバラしたい

git commit --amend ってのがあります。思いっきり適当に説明すると「現在の変更を一つ前のコミットに混ぜ込む」です。

とりあえずinitして、空コミットして、aコミットしてbコミットする。

$ git commit -m 'init' --allow-empty
[master (root-commit) 6031e0e] init
$ touch a
$ git add a
$ git commit -m'add a'
[master c0e69ee] add a
 0 files changed
 create mode 100644 a
$ 
$ touch b
$ git add b
$ git commit -m'add b'
[master 55268c7] add b
 0 files changed
 create mode 100644 b
$ 

で、次に cを足したいけど、bのコミットに混ぜたい。となるとこうする。

$ touch c
$ git add c
$ git commit --amend -m'add b & c'
[master eea0e6a] add b & c
 0 files changed
 create mode 100644 b
 create mode 100644 c

logはこうなります。

$ git log --oneline
eea0e6a add b & c
c0e69ee add a
6031e0e init
$ 

このあと、d,e,fを追加してaを編集したってのを全部amendするとこうなります。

$ git log --oneline
7bdced5 add b & c & d & e & f & modify a
c0e69ee add a
6031e0e init
$ 

うっかり変なものを混ぜてしまった

しかしどこかで問題が起こって「eの追加前に戻したい!」と思った時、ぱっと見ではそのコミットは残ってないように見えます。

でもgitは基本的にコミットしたのは残ってます。
gitkで見るとこうなってたりします。

reflogでも見れます。

$ git reflog
0a5afd6 HEAD@{0}: commit (amend): add b & c & d & e & modify a
c6f71a4 HEAD@{1}: commit (amend): add b & c & d & e
a8bd8c1 HEAD@{2}: commit (amend): add b & c & d
eea0e6a HEAD@{3}: commit (amend): add b & c
55268c7 HEAD@{4}: commit: add b
c0e69ee HEAD@{5}: commit: add a
6031e0e HEAD@{6}: commit (initial): init

あとは適当にcheckoutすれば戻せますね。今回はeを追加した時に戻したい、なので……

git checkout a8bd8c1

とかでしょうか。必要なら適当にここからブランチを作ればいいと思います。

適当に繋げる

$ git checkout 55268c7 -b branch
$ git cherry-pick eea0e6a
[branch 6176fae] add b & c
 0 files changed
 create mode 100644 c
$ git cherry-pick a8bd8c1
[branch 5841179] add b & c & d
 0 files changed
 create mode 100644 d
$ git cherry-pick c6f71a4
[branch bf2d3c3] add b & c & d & e
 0 files changed
 create mode 100644 e
$ git cherry-pick 0a5afd6
[branch 789430b] add b & c & d & e & modify a
 1 file changed, 1 insertion(+)
$ git cherry-pick 7bdced5
[branch ac80b19] add b & c & d & e & f & modify a
 0 files changed
 create mode 100644 f

こんな感じ?

コメントが気に食わないとかは適当に直せばいいと思う。

…amendってついてるのをバラすくらいなら、なんかスクリプト書ける気もしないでもない。