git でコミットを分解する

git を使うと、ブランチをさくさく切ることができてそのブランチにとりあえずコミットしておいて、後で適当にきれいにまとめ上げて master へマージするなんてことがお手軽にできます。
変なところが適当で、変なところには几帳面な自分にはまさに打って付けな感じで、Subversion とかではなかなかコミットできなかったものの、今はとりあえず途中であってもコミットして、あとで修正するなんてこともやっています。

作業途中でもコミットできるのは便利なのですが、依存関係の問題でコミットしたものの一部を取り出してコミットしなおして、その部分だけを他のブランチへ入れたいなんてことがありました。
言い換えれば branchA の HEAD^ を分解する、HEAD^ の中にある一部のファイルだけを取り出してコミットし直すというのが今回やりたいことです。

git checkout branchA
git reset --soft HEAD^

–soft を使うとコミットのみを取り消すことができます。
ちなみに –hard はコミットをなかったことにするものですので、コミット自体消えてしまいます。
これで index に記録された状態にまで戻ります。

この状態で通常の git reset をすれば、index 記録前の状態に戻るので、今回必要なファイルを index に記録するようにすればいいです。

すなわち

git reset .
git add foo
git commit

ということになります。

後は残りの部分を通常と同じようにコミットし、必要な部分を cherry-pick すれば、今回やりたいことはできました。

参考文献