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ってついてるのをバラすくらいなら、なんかスクリプト書ける気もしないでもない。