【Git】Merge commitをrevertする方法 (error: commit xxx is a merge but no -m option was given.)

git エンジニア
記事内に広告が含まれています。

merge commitをrevertで取り消す時に、下記のエラーが出たことがないでしょうか?

% git revert 504c0d33
error: commit 504c0d33e29dc4488bd1b4eb95574cd1f211fbcc is a merge but no -m option was given.
fatal: revert failed

 

しゅんご
しゅんご

この記事では、merge commitを取り消す方法をご紹介します!

 

そもそもRevertとは?

特定のcommitを打ち消すためのcommitを作成するコマンド

revertはcommitを打ち消すためのコマンドです。

revertすると、指定したcommitを取り消す、commitが作成されます。

 

例えば下記のようなcommit(47b4348)があるとします。

% git log --oneline
47b4348 commit-1

このcommitを取り消したいときには、commitを指定してrevertします。

% git revert 47b4348

すると、commit(47b4348)は取り消すための、新しいcommit(566fa3e)が追加されます。

% git log --oneline
566fa3e Revert "commit-1"
47b4348 commit-1

これが通常のcommitをrevertするときの流れです。

 

オプション「-m」なしでmerge commitをrevertできない

merge commitをrevertするときは、通常のcommitのrevertとは異なります。

 

例えば、下記のようなPRのmerge commitを取り消す場合で考えてみます。

% git log --oneline
504c0d33 Merge pull request #123 from xxxxxx

通常のcommitと同じようにmerge commitを指定してrevertしても、

「-m を指定していないのでrevertに失敗した」というエラーが出ます

% git revert 504c0d33
error: commit 504c0d33e29dc4488bd1b4eb95574cd1f211fbcc is a merge but no -m option was given.
fatal: revert failed
しゅんご
しゅんご

merge commitをrevertする時には、

オプション「-m 」を付けないと取り消すことができません。

 

Merge commitを取り消す方法 (オプション「-m」を指定する)

merge commitをrevertするには2つの方法があります。

例として、mainブランチにdevelopブランチをmergeしたcommitがあるとします。

 

方法1. git revert -m 1 (基本的にこちらを使う)

オプションで「-m 1」を指定すると、「mergeされたブランチ」の状態になります。

merge commitでrevertするときは、基本的にこちらを使用することがほとんどです。

% git revert -m 1 <merge commit id>

例で説明すると、

mergeしたdevelopのcommitを削除して、developブランチをmerge前のmainブランチと同じ状態に戻ります。

 

方法2. git revert -m 2

オプションで「-m 2」を指定すると、「mergeしたブランチ」の状態になります。

こちらはほとんど使うことがないと思います。(私は使ったことがありません。。。)

% git revert -m 2 <merge commit id>

例で説明すると、mainブランチがdevelopブランチと同じ状態になります。

 

git revertの オプション「-m」について

「-m」はmainline(メインライン)を表す

revertコマンドのヘルプを見ると、

「-m」はmainlineの省略であり、mainlineのparentを指定してくださいと書かれています。

% git revert -h

...
    --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       how to strip spaces and #comments from message
    -n, --no-commit       don't automatically commit
    -e, --edit            edit the commit message
    -s, --signoff         add Signed-off-by:
    -m, --mainline 
                          select mainline parent
    --rerere-autoupdate   update the index with reused conflict resolution if possible

参考: revert | Git

 

merge commitには2つの親commitがある

merge commitの詳細を見てみると、

Merge: e41ec146 7f0af4ef」とあり、commitが2つあることがわかります。

「mergeされたブランチのcommit」と「mergeしたブランチのcommit」です。

% git show 504c0d33
commit 504c0d33e29dc4488bd1b4eb95574cd1f211fbcc (HEAD -> main, origin/main)
Merge: e41ec146 7f0af4ef
Author: xxxxxxxxx
Date:   xxxxxxxxx

左側のcommit(e41ec146)が「1」、右側のcommit(7f0af4ef)が「2」となっています。

 

「-m」オプションでは「1」か「2」のどちらかを指定して、

どちらのブランチを正とするかを選択する必要があります。

 

番外編: PRをGithubの画面から取り消す場合

これまではコマンドでPRのmerge commitをrevertする方法を説明してきましたが、

Githubの画面からPRを取り消すことで、merge commitをrevertすることもできます。

参考までに添付しておきます!

Pull Request を打ち消す | Github

 

まとめ

下記のように、merge commitをrevertする方法は2つありますが、

「git revert -m 1」を使うことがほとんどだと思います。

 

コマンド revert後 備考
git revert -m 1 mergeされたブランチになる よく使用するのはこっち
git revert -m 2 mergeしたブランチになる

 

しゅんご
しゅんご

merge commitをrevertする方法がわからない方の

参考になれば幸いです!

コメント