状況整理(仮定)
- **ブランチA(マージ元)**でいくつかのファイルを追加・変更。
- **ブランチB(マージ先)**に対してマージを実施。
- ブランチBでマージコミットを
git revert -m 1
などでリバート。 - その後、ブランチAでさらに変更が加えられた状態で、再度ブランチA → Bへマージ。
- しかし、リバート前に追加されたファイルの一部がBに現れなかった。
原因の可能性
この現象は、Gitのマージとリバートの仕組みによるもの
🔁 git revert -m
は「マージコミットを打ち消す」けれど、「ブランチ間の差分関係」は変わらない
- リバートはあくまで「履歴に逆操作を積む」だけで、Gitのマージアルゴリズムが追う「差分」には反映されません。
- つまり、「A→Bにマージして、そのマージをBでリバート」しても、Gitから見ると「AとBの差分は減っていない」。
- その後のA→Bのマージでは、「既にマージされた」とみなされてしまい、差分が適用されないことがあります。
特に「リバート前に追加されたファイル」が再度出てこない理由
- Gitはファイル単位ではなく、差分の履歴とベースの共通祖先でマージを判断します。
- 最初のマージでファイルが追加されていても、リバートでその状態が見えなくなると、「A→Bの差分」に再登場しない可能性がある。
解決方法
1. --no-ff
オプション付きで強制的にマージ
git merge --no-ff origin/ブランチA
→ 差分を無視して全体をマージコミットとして作成。うまくいくことがあります。
2. cherry-pick
で個別コミットを拾う
→ ブランチAで必要なコミットを選んで、Bに直接 cherry-pick
する。
3. リバート後のBブランチを、新たに作り直す
→ 一度リバートでおかしくなった履歴をリセットする。
対策やコツ
- マージ後のリバートは慎重に行う。代わりに revert したブランチを新ブランチとして扱う ことを考慮。
- マージ後に取り消したい場合は、
revert
ではなく、reset --hard
やreflog
を使って履歴を巻き戻すのも一手(チームルールに注意)。