2017年01月10日(火) [長年日記]
■ [dev][howto] Gitでブランチのマージを取り消してやり直す
Gitでブランチのマージを取り消し、ブランチを修正して再度マージする方法をメモ。マージ元のブランチをbranch1、マージ先のブランチをmasterとする。
マージの取り消し
[master] ---o---o---M---x / [branch1] ---A---B
Mでbranch1をmasterへマージしたけどこれを取り消したい。このときはgit revertを使うのが簡単そう。
% git checkout master % git revert -m 1 M
これで
[master] ---o---o---M---x---W / [branch1] ---A---B
という状態になって、masterにMで入った変更は元に戻る。マージコミットに対するgit revertには-mオプションが必要なのが面倒。-m 1がデフォルトではいかんのか。
ブランチをもう一度マージする
上の後でbranch1に修正を加えて再びmasterへマージするにはどうするか。
[master] ---o---o---M---x---W---x---? / / [branch1] ---A---B-----------C---D
普通にマージしてしまうとAとBの変更がmasterにマージされない。
Undoing MergesにあるようにmasterブランチにWを取り消すコミットをした後でbranch1をmasterへマージすればいいみたいだけれど、マージの直前にmasterを更新するというのは危ういと感じる。マージし忘れる可能性があるから。
git revertのマニュアルからリンクされているrevert-a-faulty-merge.txtを読めば理解が進むと思われるが長いので読んでいない。
にあるようにWをbranch1に取り込んだ後でbranch1上でWを取り消すというのはいいように思ったのだけれど、試してみるとこうしてもAとBの変更はmasterに反映されなかった。なんでや。
なので、「ブランチをもう一度マージする」いい方法はわからない。
新しいブランチでやり直す
仕方ないので、マージのやり直しは次のように新しいbranch2を作って行えばいいと思う。
[master] ---o---o---M---x---W / \ [branch1] ---A---B \ \ [branch2] R
branch2ではRでWを取り消す。こうすればAとBが復活する。
% git checkout master % git branch -b branch2 % git revert W
そのあとでCとDの変更をしてNでマージする。
[master] ---o---o---M---x---W---x-----------N / \ / [branch1] ---A---B \ / \ / [branch2] R---C---D
(CとDのコミットをした後) % git checkout master % git merge branch2