Featured image of post Undoing Merge Commits Safely using git revert -m Featured image of post Undoing Merge Commits Safely using git revert -m

Undoing Merge Commits Safely using git revert -m

Learn to execute git revert -m on wrong merges and understand re-merging mechanics afterward.

Directly after merging a feature branch into your primary release branch (main), you might discover a severe bug that requires you to immediately roll back the integration.

With standard commits, you can easily undo changes using git revert <commit-hash>. However, attempting to revert a merge commit directly results in a Git error: fatal: commit <hash> is a merge but no -m option was given.

In this guide, we’ll explain why merge reverts require special handling, walk through using the git revert -m option, and reveal the hidden trap of re-merging reverted features later.


1. Why Does Git Need the -m Option?

A typical commit has only one parent commit (its immediate predecessor). Reverting it is straightforward because Git knows exactly what to subtract.

In contrast, a merge commit has two or more parent commits (representing the branch being merged into and the branch being merged). Git does not know which parent should be treated as the “mainline” history. Without instruction, Git cannot determine which branch’s changes should be kept and which should be discarded.

The -m (or --mainline) option tells Git which parent path to keep.


2. Step-by-Step Merge Reversion

Step 1: Examine the Merge Commit Parents

First, inspect the target merge commit:

git show <merge-commit-hash>

At the top of the output, locate the Merge: line:

commit a1b2c3d4e5f6...
Merge: 9e8d7c6 5a4c3d2

These hashes represent the parent commits:

  • Parent 1 (9e8d7c6): The branch receiving the merge (e.g., main).
  • Parent 2 (5a4c3d2): The branch that was merged in (e.g., feature).

Step 2: Execute the Revert with Parent 1 Specified

To preserve the history of the main branch (Parent 1) and roll back the incoming changes, run:

git revert -m 1 a1b2c3d4e5f6

Git will open your editor to finalize the commit message. Save it to execute the reversion.


3. The Re-Merging Trap

The trickiest aspect of reverting a merge commit occurs when you try to merge the same feature branch back into main after fixing the bug.

If you attempt a simple merge, Git will only import the new bug fixes. The bulk of your original feature code will be missing.

Why does this happen?

Git keeps track of the fact that the original feature branch commits were already merged into main. The revert operation you ran didn’t delete those commits; it simply added a new commit that undoes their modifications. Therefore, Git assumes the feature commits are already present and ignores them during the second merge.

The Solution (Reverting the Revert):

To successfully re-apply the feature branch, do not merge the branch itself. Instead, revert the original revert commit.

# Reverts the revert commit, re-enabling the original changes
git revert <revert-commit-hash>

This brings back all of your original feature changes, allowing you to merge subsequent bug fixes without losing your code.


Conclusion

Reverting a merge is a critical recovery skill. Remember:

  1. Specify -m 1 to designate the target mainline branch.
  2. Understand that a revert is a new commit adding changes, not a deletion of history.
  3. Bring back reverted features by reverting the revert commit rather than re-merging.

Understanding these mechanics ensures you can manage release rollbacks with confidence.