How do I revert a merge commit that has already been pushed to remote?
Categories:
Reverting a Pushed Merge Commit in Git

Learn how to safely undo a merge commit that has already been pushed to a remote repository, understanding the implications and best practices.
Reverting a merge commit in Git can be a tricky operation, especially when it has already been pushed to a remote repository and potentially shared with other collaborators. Unlike regular commits, a merge commit has two or more parent commits, which complicates a simple git revert
operation. This article will guide you through the process of safely reverting a pushed merge commit, explaining the different scenarios and the commands required.
Understanding Merge Commits and Reverts
A merge commit is a special type of commit that combines the history of two or more branches. When you revert a regular commit, Git creates a new commit that undoes the changes introduced by the specified commit. For a merge commit, Git needs to know which parent's history to 'undo' relative to. This is where the -m
or --mainline
option comes into play with git revert
.
flowchart TD A[Feature Branch] --> M(Merge Commit) B[Main Branch] --> M M --> R[Revert Commit] subgraph Original History A B M end subgraph Reverted History M --> R end style Original History fill:#f9f,stroke:#333,stroke-width:2px style Reverted History fill:#ccf,stroke:#333,stroke-width:2px
Conceptual flow of a merge commit and its revert.
Identifying the Mainline Parent
When reverting a merge commit, you must specify which parent is the 'mainline' or the branch you want to keep the changes from. The other parent's changes will be undone. Git numbers the parents starting from 1. Typically, parent 1 is the branch you were on when you performed the merge (e.g., main
or develop
), and parent 2 is the branch being merged in (e.g., a feature
branch).
You can inspect the merge commit to determine its parents using git show <merge-commit-hash>
.
git show <merge-commit-hash>
Viewing details of a merge commit to identify parents.
Look for lines starting with Merge:
to see the parent hashes. The first hash listed is parent 1, the second is parent 2, and so on.
Performing the Revert
Once you've identified the merge commit hash and the mainline parent, you can perform the revert. The command will look like this:
git revert -m <parent-number> <merge-commit-hash>
For example, if you want to undo the changes from the merged feature branch (parent 2) and keep the main
branch's history (parent 1), you would use -m 1
.
# Example: Revert merge commit 'abcdef1' keeping parent 1's changes
git revert -m 1 abcdef1
Command to revert a merge commit, specifying the mainline parent.
Pushing the Revert to Remote
After successfully creating the revert commit locally, you need to push it to the remote repository. Since this is a new commit that undoes previous changes, it's a standard push operation.
git push origin <your-branch-name>
Pushing the revert commit to the remote repository.
What if the Reverted Branch is Merged Again?
A common pitfall with git revert
of merge commits is when the same feature branch is merged again after being reverted. Git sees that the changes from the feature branch were already applied and then reverted, so it might not re-apply them correctly in a subsequent merge, leading to missing code.
To avoid this, if you need to re-introduce the changes from the feature branch, you should either:
- Revert the revert commit (creating a new commit that re-applies the original merge's changes).
- Rebase the feature branch onto the current
main
(ordevelop
) and then merge the rebased feature branch.
sequenceDiagram participant DevA as Developer A participant DevB as Developer B participant Remote as Remote Repository DevA->>Remote: Push Feature Branch DevB->>Remote: Merge Feature into Main Remote-->>DevB: Main updated DevB->>Remote: Push Main (with merge) Note over DevA,Remote: Realizes merge was incorrect DevA->>DevA: git pull origin main DevA->>DevA: git revert -m 1 <merge-commit-hash> DevA->>Remote: git push origin main Note over DevA,Remote: Main branch now without feature changes DevB->>DevB: git pull origin main DevB->>DevB: (Sees revert commit) DevB->>DevB: git checkout feature-branch DevB->>DevB: git rebase main DevB->>Remote: Push rebased feature-branch DevB->>Remote: Merge rebased feature-branch into Main Remote-->>DevB: Main updated DevB->>Remote: Push Main (with new merge)
Sequence of reverting a merge and then re-merging the feature branch safely.
Summary of Revert Options
Here's a quick recap of the options for reverting a merge commit:
1. Identify the Merge Commit
Use git log
or git reflog
to find the hash of the merge commit you want to revert.
2. Inspect the Merge Commit
Run git show <merge-commit-hash>
to determine the parent commits. Parent 1 is usually the branch you merged into, and Parent 2 is the branch you merged from.
3. Perform the Revert
Execute git revert -m <parent-number> <merge-commit-hash>
. Choose 1
if you want to undo the changes from the merged branch, or 2
if you want to undo the changes from the branch you were on (less common).
4. Push the Revert
After the revert commit is created locally, push it to the remote repository using git push origin <your-branch-name>
.
5. Communicate
Inform your team about the revert to avoid confusion and potential conflicts.