コードを書いていてよくやらかしがちなのが、branch切り替えわすれたままcommitしてしまうケース。
特にmaster
で直接書いてしまって「やっべやらかした」はおそらく結構な人たちが経験することと思われる。
本エントリではその修正法をおおまかに2つに分けて紹介する。
ただし、pushしてしまった場合はもう無かったことにはできない場合が多い(CIをやらせている場合はまず不可能)ので、大人しくRevertするかReposのメンテナに相談すること。
commitが1つだけの場合
cherry-pickすると結構面倒なので、commitがまだ1つで済んでいる場合はSoftResetしてからcheckoutするのが一番簡単かつ速い。と思う。
ちなみにSoftResetとはファイルの変更を保持したままcommit直前の状態に戻すことを指す。
# HEADの1つ前の状態に変更を保持したまま戻す
$ git reset --soft HEAD\^
# 正しいbranchにcheckout
$ git checkout hogefuga#846
# 同じ内容でcommit
$ git commit -m 'hogefuga'
commitが複数の場合
この場合は再度commitし直すのが非常に手間なので、cherry-pickで正しいbranchにcommitを持ってくるのが一番最適。でも多少面倒である。
そしてcherry-pick時におけるハッシュの指定について気をつけないといけないところがある。
例えば上のスクリーンショットのピンクの範囲を正しいbranchに持ってきたい時だが、始点として指定するハッシュはコピーする1つ前を指定しないといけない。(終点は範囲中の最後でOK)
スクショの例で言えば439c2cd..f30759b
で指定すれば良い。
これをしくじるとconflictが起きるが、慌てずにスタート地点にHardResetしてやり直せばOK。
# `git log --oneline` などを使ってcommitのハッシュを調べる
$ git log --oneline
# 今回は間違ってcommitしたbranchを `master`
# 作業する前の位置を `origin/master` と仮定し、まずは作業前のポジションにcheckoutする
$ git checkout origin/master
# commitするはずだったbranchを作る
$ git checkout -b hogefuga#846
# 調べた始点と終点のcommitハッシュでcherry-pickする
$ git cherry-pick START_POINT..END_POINT
# 正常にコピーできたら間違ってcommitしたものを消す
$ git checkout master
$ git reset --hard origin/master
まとめ
1つだけならまだいいが、複数に渡ると非常に面倒なのでcommitする前にbranchは確認したほうがいいです。
記載内容が間違っていたらコメントで指摘してもらえるとうれしいです。