症状

git revert でマージコミットを取り消そうとしたら「error: commit is a merge but no -m option was given」と表示される

結論:まずこれを確認

  • マージコミットの revert には -m オプション(親番号の指定)が必要
  • 通常は -m 1 を指定する(マージ先のブランチを残す)
  • git log --oneline でマージコミットのハッシュを確認してから実行する

操作フロー

    flowchart TD
    A[マージを取り消したい] --> B{push済み?}
    B -->|Yes| C[git revert を使う]
    B -->|No| D[git reset も選択肢]
    C --> E{マージコミット?}
    E -->|Yes| F[git revert -m 1 を使う]
    E -->|No| G[git revert のみでOK]
    F --> H[親番号を確認]
    H --> I[git log で親を確認]
    I --> J[git revert -m 1 ハッシュ]
    J --> K[git status で確認]
    G --> K
    D --> L[git reset --hard]
  

よくある原因

  • -m オプションを付けていない → マージコミットには親が2つあるため、どちらの親に戻すか指定が必要
  • 親番号を間違えている-m 1 はマージ先(通常main)、-m 2 はマージ元(feature)を指す
  • マージコミットかどうか確認していないgit log で親が2つあるか確認する
  • revert後に再マージできない → revertのrevertが必要になる場合がある
  • コンフリクトが発生した → revert時も通常のコンフリクト解決と同様に対処する
  • 間違ったコミットをrevertした → revertしたコミット自体をrevertする

操作手順

ステップ1: マージコミットを特定する

    git log --oneline --graph -10
  

出力例:

    *   abc1234 Merge branch 'feature' into main
|\
| * def5678 Add new feature
| * ghi9012 Fix bug
|/
* jkl3456 Previous commit on main
  

🔍 チェックポイント: Merge branch と表示されているコミットがマージコミット。* が2本の線から合流している箇所。

ステップ2: 親コミットを確認する

    git show abc1234 --format="%P"
  

出力例:

    jkl3456 def5678
  
  • 1番目の親(jkl3456)= マージ先(main)
  • 2番目の親(def5678)= マージ元(feature)

🔍 チェックポイント: 親が2つ表示されていればマージコミット

ステップ3: revert を実行する

マージ先(main)の状態に戻す場合(一般的):

    git revert -m 1 abc1234
  

コミットメッセージの編集画面が開く。デフォルトのままでよければ保存して閉じる。

🔍 チェックポイント: 「Revert “Merge branch ‘feature’ into main”」のようなコミットが作成される

ステップ4: 結果を確認する

    git log --oneline -5
git status
git diff HEAD~1
  

🔍 チェックポイント: マージで追加された変更が打ち消されていることを確認

ステップ5: リモートに反映する

    git push origin main
  

NG行動(やってはいけないこと)

  • -m オプションなしで実行する → エラーになる
  • 親番号を確認せずに -m 2 を指定する → 意図しない状態になる可能性がある
  • push済みコミットに git reset を使う → 他の人の作業に影響する
  • revert後にすぐ同じブランチを再マージする → 変更が反映されない(revertをrevertする必要がある)
  • --no-commit オプションを理解せずに使う → 自動コミットされないため、手動でのコミットが必要

よくある質問(FAQ)

Q1: -m 1-m 2 はどう違う?

A: -m 1 はマージ先(通常main)を残し、マージ元(feature)の変更を取り消す。-m 2 はその逆で、マージ元を残す。ほとんどの場合 -m 1 を使用する。

    # mainにfeatureをマージした場合
git revert -m 1 <hash>  # featureの変更を取り消す(一般的)
git revert -m 2 <hash>  # mainの変更を取り消す(稀)
  

Q2: revertした後に同じfeatureブランチを再マージしたい場合は?

A: revertコミット自体をrevertする必要がある。

    # revertコミットのハッシュを確認
git log --oneline -5

# revertをrevertする
git revert <revertコミットのハッシュ>

# その後、再マージする
git merge feature
  

Q3: revert時にコンフリクトが発生した場合は?

A: 通常のコンフリクト解決と同様に対処する。

    # コンフリクトしたファイルを編集して解決
git add <解決したファイル>
git revert --continue

# revertを中止したい場合
git revert --abort
  

関連するトラブル

準備中

解決しない場合

  • 公式ドキュメント: git-revert
  • 確認すべきログ: git log --oneline --graph でコミット履歴を確認
  • 次に調べるキーワード: 「git revert -m 親番号」「マージコミット 取り消し」「git revert conflict」