Git

マージコミットをrevertする方法【mオプション】

コミットログを残しつつコミットを取り消したいときは revert を使いますが、マージコミットを普通に revert しようとするとこんなエラーが出ると思います。

$ git revert 4ca4c46e708544e84a446914068906bea67e6097
error: commit 4ca4c46e708544e84a446914068906bea67e6097 is a merge but no -m option was given.
fatal: revert failed

今回は、このエラーメッセージにもある revert-m オプションについて解説していきます。

この記事で分かること

  • マージコミットを revert する方法
  • revert-m オプションの意味と使い方

環境

  • git 2.32.0

急ぎの方向け解決方法

マージ先のブランチを前の状態に戻したいときは、マージ先ブランチで以下コマンドを実行してください。(基本はこっちだと思います)

git revert -m 1 <マージコミットID>

逆にマージ元ブランチの前の状態に戻したいときは以下のようにしてやりましょう。

git revert -m 2 <マージコミットID>

エラーの原因

エラーメッセージに書いてある通り、「revert 対象のコミットがマージコミットだから -m オプションをつけてあげないとダメだよ!」って言われてます。

解決方法

言われたとおりに -m オプションをつけてあげましょう。
まずは git revert -h でこのオプションの使い方を見てみます。

$ git revert -h
usage: git revert [<options>] <commit-ish>...
   or: git revert <subcommand>

    --quit                end revert or cherry-pick sequence
    --continue            resume revert or cherry-pick sequence
    --abort               cancel revert or cherry-pick sequence
    --skip                skip current commit and continue
    --cleanup <mode>      how to strip spaces and #comments from message
    -n, --no-commit       don't automatically commit
    -e, --edit            edit the commit message
    -s, --signoff         add a Signed-off-by trailer
    -m, --mainline <parent-number>
                          select mainline parent
    --rerere-autoupdate   update the index with reused conflict resolution if possible
    --strategy <strategy>
                          merge strategy
    -X, --strategy-option <option>
                          option for merge strategy
    -S, --gpg-sign[=<key-id>]
                          GPG sign commit

parent-numbermainline parent is 何って感じだと思います(私はわかりませんでした!)

ググってみると、
parent-number ... マージコミットの親コミット(マージ先ブランチ、マージ元ブランチそれぞれの最新のコミット)の番号
mainline parent ... マージ先、マージ元のどっちの親コミットを選択するのか
ということでした。

まずは parent-number について。
親コミットの番号は git log <マージコミットID> で確認できます。

$ git log 4ca4c46e708544e84a446914068906bea67e6097
commit 4ca4c46e708544e84a446914068906bea67e6097
Merge: b380348 3d01002
Author: hiroya-akeoka <mowoarm232@gmail.com>
Date:   Mon Apr 4 08:15:13 2022 +0900

    Merge branch 'develop'

commit b380348f1419597b3cee1d369dffee9df9fd1ad7
Author: hiroya-akeoka <mowoarm232@gmail.com>
Date:   Mon Apr 4 08:12:25 2022 +0900

    main commit 2

commit 3d01002fd8b061206544c6fb22c228b9e80740b5 (develop)
Author: hiroya-akeoka <mowoarm232@gmail.com>
Date:   Mon Apr 4 08:11:55 2022 +0900

    develop commit 1

commit 0ed5fd2a9067f5efa225b09a8764b512f8c8241e
Author: hiroya-akeoka <mowoarm232@gmail.com>
Date:   Mon Apr 4 08:10:49 2022 +0900

    main commit 1

commit cedc58bbeedd812457e5ee33ec4ae0a8f1d09df5 (origin/main, origin/HEAD)
Author: hiroya-akeoka <mowoarm232@gmail.com>
Date:   Sat Jun 26 10:32:09 2021 +0900

    first commit

一番上のマージコミットの Merge: の後ろに書いてあるのが親コミットで、左から 1,2 番になっています。
左の一番目の親コミットb380348 が今回のマージ先ブランチの親コミット(main commit 2)のコミット ID なので、マージ先ブランチの前の状態に戻したいときは以下のようになります。

git revert -m 1 <マージコミットID>

逆に、マージ元ブランチの前の状態に戻したいときは二番目の親コミット3d01002(develop commit 1のコミット ID)に戻したいので

git revert -m 2 <マージコミットID>

とすれば OK です!

-Git