Reverting a merge

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the git category.

Last Updated: 2024-04-24

How to revert a merge?

Option A: If you have not pushed:

Option 1: git reset --hard ORIG_HEAD (more idiomatic)

The Git man page says this about ORIG_HEAD is created by commands that move your HEAD in a drastic way, to record the position of the HEAD before their operation, so that you can easily change the tip of the branch back to the state before you ran them.

Option 2: Use git reflog to see commit one prior to merge, then reset git reset --hard SHA.

Option B: If you have pushed:

Option 1: git revert -m 1 SHA

Danger zone: Imagine that the reverted merge was for a branch called feature. It has two commits that were originally merged into master. These broke master, thus the reason for wanting to revert the merge. The effect of this revert was to create a reverse patch (that we will call W) of bringing in these two commits. Now, work continues in both the feature and master branches, including a third commit in feature that fixes the bug. Now, when feature is merged into master again, unfortunately it will not include the previous two commits prior to the fix (since these were reverted by the merge commit W).

Why does this mess happen? Because while the revert undoes the data, it does not undo the history. Future merges will see the previous merge (even though it was later reverted) and view it as the last shared state. Therefore it is unwise to view a revert of a merge commit as an undo since it does not undo history.

What to do? When you want to bring the new branch in, you need to revert the revert (W), i.e. git revert W (creating commit Y). The overall effect means the history would be equivalent to to not having either W or Y in it at all => merging the feature branch again would bring in all three commits. For a better explanation read Linus Torvalds answer