結論
先に書いておく。使い所がわからんかった。
発端
複数人で開発中のブランチで下記の事象が起きました。(DEV1とDEV2ブランチが存在するとします)
この時に、先にリリースする予定だったDEV1より先にDEV2がメインブランチに合流してしまった。
DEV2での変更がDEV1の変更に影響が有るリスクが高いので、DEV2のマージを取り消したい。
当時に採った対応
「マージコミットのリバート」とかでググると、大体以下のコマンドが出てきた。
$ git revert -m 1 <マージコミットのハッシュ>
ヘルプとかを読んでも問題無さそうなので脳死で入力した。
https://git-scm.com/docs/git-revert#Documentation/git-revert.txt---mainlineparent-number
疑問
オプションの--mainline
を脳死で1を指定したが、git revert --mainline 2
(マージした側のブランチ)を指定するとどうなるか?と言う訳で検証してみよう。そうしよう。
Let's 検証
準備
こんな感じで簡易的に実験してみる。
とりあえずREADMEに初回コミット
+ 初回コミット
master
からdevelop
を派生して追記コミット
初回コミット
+ 開発で追記するよ
競合を発生させるためにmaster
で追記する
初回コミット
+ 本流の追記コミット1行目
+ 本流の追記コミット2行目
マージするぞ
$ git checkout master
-- マージコミット付けとく
$ git merge --no-ff develop
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
予定調和で衝突したので適当に解消させる。
$ vi README
これを、、
初回コミット
<<<<<<< HEAD
本流の追記コミット1行目
本流の追記コミット2行目
=======
開発で追記するよ
>>>>>>> develop
こうじゃ!
初回コミット
開発で追記するよ
本流の追記コミット1行目
本流の追記コミット2行目
解消をコミットして下準備が完了。
$ git add README
$ git commit
$ git log --oneline --graph
* 409bc75 (HEAD -> master) Merge branch 'develop' <= ★こいつを revert で取り消すぞ
|\
| * d8487d0 (develop) 開発で追記
* | c128797 本流の追加コミット
|/
* 5191404 初回コミット
マージを取り消してみる
まずは、通常で使う合流ブランチの変更を取り消す方から、
$ git revert -n -m 1 409bc75
READMEの内容は?
初回コミット
本流の追記コミット1行目
本流の追記コミット2行目
まぁ、当然やな。
次は試したかった、本流ブランチの変更を取り消す方やるぞ!
間違えてマージ前まで戻っちゃったのでハッシュ変わっちゃった。
$ git log --oneline --graph
* 25a8a33 (HEAD -> master) Merge branch 'develop'
|\
| * d8487d0 (develop) 開発で追記
* | c128797 本流の追加コミット
|/
* 5191404 初回コミット
$ git revert -n -m 2 25a8a33
$ less README
初回コミット
開発で追記するよ
うん。。まぁ挙動としては理解できるよ。
どう言うことだってばよ?
まぁあれだ、衝突に対して、どちらの変更を残すかって事だよ。
この辺はググればたくさん出てくるが、マージコミットでは 合流先と合流元 のハッシュを持ってます。
$ git log
commit 25a8a333d07d518eb6938713776755fac6412c2f (HEAD -> master)
Merge: c128797 d8487d0
Author: ****************
Date: Fri Oct 28 20:11:13 2022 +0900
Merge branch 'develop'
リバートする際は、どちらの変更を正とするか指示しているだけみたい。
チェックアウトコマンドで--ours
と--theirs
を指定するみたいな物だね。
検証してないですが、衝突してなかったら単純に差分が消去されるだけになると思うよ。
あと revert の逆の cherry-pick でもやる事は同じだと思うよ。
https://git-scm.com/docs/git-cherry-pick#Documentation/git-cherry-pick.txt---mainlineltparent-numbergt