Git revert でコンフリクトが出て元に戻せない
git revert でコンフリクトが発生したら、衝突箇所を手動で解決して git add → git revert --continue で続行する。
途中で諦める場合は git revert --abort で revert 自体を取り消せる。
マージコミットを revert するときは -m で親番号の指定が必須。
#revert#conflict#undo#merge-commit
公開:
要約
git revert でコンフリクトが出るのは、revert したい変更と現在の HEAD の内容が同じ行で食い違っているため。
コンフリクトマーカーを手動で編集 → git add → git revert --continue の順で進めれば再開できる。
途中で諦めるなら git revert --abort。
マージコミットを revert する場合は -m で親番号の指定が必須。
よくある原因
- revert 対象のコミットが触ったファイルを、その後の別コミットがさらに変更しており、Git が自動で打ち消し差分を当てられない。
- マージコミットには親が 2 つあるため、
git revert <merge-commit>だけでは「どちらの親に戻すか」を Git が決められずfatal: commit ... is a merge but no -m option was givenで失敗する。 - コンフリクト解決中に
git commitだけ実行してしまい、REVERT_HEADの状態が解除されないまま履歴が中途半端になる。 - 既に手動で部分的に元に戻したコード片を、もう一度
git revertでも消そうとして同じ行を二重に削ろうとする。
解決策
1. コンフリクトマーカーを解決して continue する
git status # Unmerged paths: の一覧を確認
# エディタで <<<<<<< ======= >>>>>>> を編集
git add path/to/file
git revert --continue # revert のコミットメッセージを編集して確定--continue の代わりに git commit を打っても進めるが、git revert --continue を使うとデフォルトメッセージ(Revert "...")が自動で入る。
2. マージコミットの revert は親番号を指定する
git revert -m 1 <merge-commit>-m 1 は「1 番目の親(通常は main 側)を残し、もう一方の親が持ち込んだ差分を打ち消す」という意味。
詳しくは 公式ドキュメント の -m parent-number を参照。
3. 途中で諦めて元に戻す
git revert --abortrevert を始める前の HEAD と作業ツリーに戻る。--quit だと revert 状態だけクリアして作業ツリーは残るので、用途で使い分ける。
4. 連続コミットをまとめて revert する
git revert --no-commit <old>..<new>
# 必要なら手動で調整したあと
git commit -m "Revert a..b range"--no-commit で打ち消し差分だけステージしておくと、複数のコミットを 1 つの revert コミットにまとめられる。