How to revert a merge commit that's already pushed to remote branch?
The -m
option specifies the parent number. This is because a merge commit has more than one parent, and Git does not know automatically which parent was the mainline, and which parent was the branch you want to un-merge.
When you view a merge commit in the output of git log
, you will see its parents listed on the line that begins with Merge
:
commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <[email protected]>
Date: Wed Aug 17 22:49:41 2011 +0100
Merge branch 'gh-pages'
Conflicts:
README
In this situation, git revert 8f937c6 -m 1
will get you the tree as it was in 8989ee0
, and git revert -m 2
will reinstate the tree as it was in 7c6b236
.
To better understand the parent IDs, you can run:
git log 8989ee0
and
git log 7c6b236
Here's a complete example in the hope that it helps someone:
git revert -m 1 <commit-hash>
git push -u origin master
Where <commit-hash>
is the commit hash of the merge that you would like to revert, and as stated in the explanation of this answer, -m 1
indicates that you'd like to revert to the tree of the first parent prior to the merge.
The git revert ...
line essentially commits your changes while the second line makes your changes public by pushing them to the remote branch.
Ben has told you how to revert a merge commit, but it's very important you realize that in doing so
"...declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want." (git-merge man page).
An article/mailing list message linked from the man page details the mechanisms and considerations that are involved. Just make sure you understand that if you revert the merge commit, you can't just merge the branch again later and expect the same changes to come back.
You could follow these steps to revert the incorrect commit(s) or to reset your remote branch back to correct HEAD/state.
- checkout the remote branch to local repo.
git checkout your_branch_name
- copy the commit hash (i.e. id of the commit immediately before the wrong commit) from git log
git log -n5
should show something like this:
commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 "Merge branch 'wrong-commit' into 'your_branch_name'"
commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 "this is a wrong commit" commit 3779ab50e72908da92d2cfcd72256d7a09f446ba "this is the correct commit"
- reset the branch to the commit hash copied in the previous step
git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
- run the
git status
to show all the changes that were part of the wrong commit. - simply run
git reset --hard
to revert all those changes. - force-push your local branch to remote and notice that your commit history is clean as it was before it got polluted.
git push -f origin your_branch_name
Note: Apply this solution only for your own branch not for a shared branch.
git revert -m 1 <merge-commit>