Gitの小ネタおれおれAdvent Calendar 2022 – 07 日目

ここまでのあらすじ:別のブランチで作業していた新機能の実装と検証が終わり、無事 main へとマージされた。ところが問題なかったはずなのになぜかエラーが鬼のように出てきて!? いったんマージ前の状態に戻さなきゃ!

先に結論

-m1 あるいは -m 1 を付けて revert します。

$ git revert -m1 2d8ebb9

2d8ebb9 は該当のマージコミットの ID です。

-m1 の意味

というわけでとりあえず revert します。

$ git revert 2d8ebb9
error: commit 2d8ebb97a40f8b4fe5436b8199e9a0f3c55833ef is a merge but no -m option was given.
fatal: revert failed

はいエラーですね~~~!

revert は変更の逆をコミットすることで元に戻す機能ですが、マージの場合はその 2 本の流れのうちどちらを本線 mainline として残すかの指定が必要です。エラーのメッセージにあるように -m オプションでその情報を与えます。

git revert --help に -m の説明があります。

-m parent-number, --mainline parent-number

Usually you cannot revert a merge because you do not know which side of the merge should be considered the mainline. This option specifies the parent number (starting from 1) of the mainline and allows revert to reverse the change relative to the specified parent.

Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.

See the revert-a-faulty-merge How-To[1] for more details.

git log で親番号を確認

こんなコミット状況だったとします。(上が新しいコミット。)

(↑新しい)
*   7317aad Merge branch 'greatFeature' into main  (HEAD -> main, greatFeature)
|\  
| * 9e71033 bbb
* | cd8605a aaa
|/  
* c0ae173 origin
(↓古い)

git log でマージコミットを確認すると、”Merge:” の項にコミット ID が表示されています。

commit 7317aad99fafe6ae3c191cad04db30edb126d88b (HEAD -> main, greatFeature)
Merge: cd8605a 9e71033
Author: Ginpei <[email protected]>
Date:   Sat Dec 3 13:58:56 2022 -0800

    Merge branch 'greatFeature' into main

このふたつのコミット ID はマージ直前のコミットを指し、つまりこのマージコミットの親コミットになります。

そして順に親番号 parent number が 1 と 2 です。-m オプションにはこの親番号をもってどちらが本線 mainline かを指示します。

この場合では -m1 とすると “cd8605a aaa” が残り “9e71033 bbb” の更新が戻ります。(”c0ae173 origin” との間にもっとコミットがあれば、もちろんそれらも全て対象です。)

逆に “9e71033 bbb” を残す場合は -m2 です。

おしまい

自分の無知故か正直 -m1 が初期値で良いんじゃないかと思ってます。

みなさんいかがですか