🔖

Gitでrevertしたらマージできなくなった話とその回避法

に公開

はじめに

Gitのrevertコマンドは、
間違ったコミットを取り消したいときに使える上、履歴も残すことができます。
しかし、とあるリポジトリでrevertを行ったところ、
変更が反映されないという状態に陥りました。

git revert とは

一言で言うと、過去のコミットを打ち消すための“新しいコミット”を作るコマンドです。

git revert <コミットハッシュ>

git resetと違って履歴は消えません。
また、チーム開発でも安全に使うことができます。
その分、履歴が積み上がっていくのが特徴です。
つまり、変更をなかったことにするのではなく、「取り消したという記録を残す」ことになります。

実例:revertを使用したら変更が反映されなかった

例えば以下の操作をしたとします:

# mainブランチを最新状態にする
git checkout main
git pull origin main

# mainブランチからfeatureブランチを作成
git checkout -b feature

# 機能Aの追加
echo "機能A" > feature.txt
git add feature.txt
git commit -m "機能Aを追加"

# リモートリポジトリに反映
git push -u origin feature

# featureブランチをmainブランチにマージ
git checkout main
git merge feature

# mainブランチでrevert
git revert HEAD

# リモートリポジトリに反映
git push -u origin main

# featureブランチをmainブランチにマージ
git merge feature

最後の git merge feature の実行時、Gitは「すでに最新の状態です(Already up to date)」と返してきました。

原因

Git側は「featureブランチの変更はすでに取り込んでおり、その後revertで取り消した。だからもうマージする必要はない」と判断したのです。

回避策・対処法

1. git logで履歴を視覚的にチェック

git log --oneline --graph

2. 意図しない履歴の干渉が起きた場合は、新しいブランチで復旧

git checkout -b fix/revert-issue

3.git reflogで過去の状態をたどる

git reflog
git checkout <過去の状態のハッシュ>

4. 最悪、手動で必要な差分だけ新しいコミットとして復元する

追記:切り直すブランチの判断基準

ブランチをどこから切り直すか、あらかじめ判断基準を持っておくと安心です。

状況 切り直すブランチの元
内容は正しいが履歴がおかしい 今のブランチから新しく切る
内容も履歴も崩れてる・不安 元のブランチ(実例ではmain)から切り直すのが安全

迷ったら 元のブランチ(main,developなど) から切り直す方が安心です。
履歴を無理に修復するよりも、状態が正しいブランチで落ち着いて再構築した方がミスも少なく済みます。

まとめ

  • revert履歴ベースであることを忘れずに
  • 特に2回以上revertすると、履歴が干渉して「何も起きない」状態になりやすい
  • 慌てず履歴を確認し、必要なら別ブランチで落ち着いて対応する

失敗から学んだことを忘れないように、備忘録として残しておきます。
同じように悩んでいる人の参考になれば幸いです。

Discussion