#はじめに
(Git初心者なので内容が間違ってても大目に見てください)
ごく稀に(特に一人で作業をしていたり、ローカルで作業したりなど)過去にコミットした内容をまとめたくなる時が出てくると思います。
このような時、通常はgit rebase -i
でコミットをマージしていくのが一般的です。
この辺りの方法は世の中に溢れているので、ググってみてください。
https://qiita.com/tsuuuuu_san/items/f708a9f7ea8ab8eb6945
http://www-creators.com/archives/2850
#困りごと
が、しかし!!まとめたいコミットのツリーの途中にブランチが切られている場合、git rebase -i
を行うとカオスな状態になってしまいます。
ちょっと何言ってるか分からないと思うので実際の事例を見ていきたいと思います。
今、master
の最初の方に作られたコミットadd c
とadd d
をまとめたいとします。
なお2個前のコミットでbranch
という名前でブランチが切られています。
この状態でgit rebase -i
を実行してみましょう。
git rebase -i HEAD~5 //5個前まで遡って修正する
pick 5b22e12 add c
squash 0365976 add d //これを直前のコミットと一緒にしたい
pick 591e2e8 add e
pick 804ff18 add f
pick 015ce44 add g
add c and d //という名前にする
$\Huge{Why\ Git!!!!!!!!}$
#Gitは悪くなかった
本来add e
でブランチされるはずのbranch
がadd b
でブランチされてしまっています。
一体何が起きているのでしょうか?
実はこれ、add c
とadd d
がまとめられたmaster
のツリーを新たにadd b
にrebase
しているんです。
rebase
のやっていることは以下を参考にするとわかりやすいです。
https://www.slideshare.net/kotas/git-15276118
理由は分かったけれど、求めたいた形と違いますね。
そこでbranchの接続元をmasterツリー内のadd e
に接続し直すことで元の状態に戻してあげます。
#救世主 git rebase --onto
ブランチを付け替えるにはgit rebase --onto
を使います。
こちらの解説は以下の記事が分かりやすかったです。
https://gist.github.com/hankei6km/4301ebc7e320b987de1f7a5b0acb994a
今やりたいことは、branch
のコミット名add f-b
をmaster
のコミット名add e
に付け替えることです。
ここで文法をおさらいすると、
git rebase --onto A B C
A
: 付け替え先のコミット名
B
: 付け替える前の分岐元のコミット名
C
: 付け替えたいブランチ名
今回の例に当てはめてみると、
A
: master
内のadd e(=3298c46)
B
: branch
内のadd e(=591e2e8)
C
: branch
となります。では早速実行してみましょう。
git checkout branch //masterからbranchに移動(これが必要かどうかは不明・・・)
git rebase --onto 3298c46 591e2e8 branch
結果を見てみると・・・
上手くいきました🤗
(branchとmasterの色と場所が変わっているのは目を瞑ってください、GitUpの仕様です)
#最後に
もう少し良い方法がある気がします・・・もし知っている方教えてください。
また、過去のコミットを修正するのはあまり良くないのでは?と思うので使用はほどほどに。