TIL
merge commit は親が 2 つ (以上) あるので、revert するときはどちらの親に戻したいかを -m
(--mainline
) で指定する。
起きたこと
「意図せず feature branch を main に混ぜて push しまった」と呼ばれて飛び出したんだが、コミットツリーがこうなっていた。
525adcbf69 ●─╮ [main] {origin/main} Merge branch 'main' of ... de745c8669 │ ∙ commit for main 2060e2be19 │ ∙ commit for main 813528befb ∙ │ commit for feature 9ed9cb80a9 ∙ │ commit for feature 9f8e1bb2e1 ∙ │ commit for feature
元々の main 最新は de745c8669
で、そこに feature branch を merge してしまったっぽい。
merge commit を revert して push すれば良いかなと思って
$ git revert -m1 525adcbf69
をしたんだが、何かおかしい。僕の意図としては de745c8669
と同じ状態になって欲しかったんだけど、813528befb
と同じ状態になった。
revert で親のどっちにするのか選べたっけ、と man git-revert
していたら -m parent-number, --mainline parent-number
の記述が見えて、納得した。何も考えずに -m1
としたのが間違いで、-m2
とすべきだった。
git revert の -m
merge commit には親が 2 つある。
$ git show 525adcbf69 commit 525adcbf69824c1888504f5c07f69697baad5aa8 Merge: 813528befb de745c8669 ...
このどちらの状態に戻すのかを指定するのが -m
(--mainline
) オプション。
なお、octopus merge の場合は 3 以上を使うこともある。
5580d0beb1 ●─┬─╮ [main] Merge branches 'foo', 'bar' and 'baz' a5334bc232 │ │ ∙ [baz] Add baz 0b9531a81e │ ∙ │ [bar] Add bar b54c490b75 ∙ │ │ [foo] Add foo 2dfb6b27be ◎─┴─╯ Initial commit
親が 3 つあるので
$ git show commit 5580d0beb173c8e8695f4c0782e3620e93f13cb1 Merge: b54c490 0b9531a a5334bc ...
revert で 3 番目に戻す、とすると
$ git revert -m3 5580d0beb1 [main 2825475] Revert "Merge branches 'foo', 'bar' and 'baz'" 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bar delete mode 100644 foo
baz
branch の状態になる。
感想
-m1
は merge commit を revert するときのおまじないとして覚えていたので、-m
は merge の m ぐらいのつもりだったが、全然違った。
feature branch に main をマージした上で、branch 名を main にした (もしくは feature branch の push 先として main を指定してしまった)、というトラブルは git 生活 10 年超で初めて見て、面白かったです。