git revert <commit_hash>
alone won\'t work. -m
must be specified, and I\'m pretty confused about it.
Anyone experienced this before?
git revert <commit_hash>
alone won\'t work. -m
must be specified, and I\'m pretty confused about it.
Anyone experienced this before?
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 <ben@example.com>
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 commit -m \"Reverting the last commit which messed the repo.\"
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 commit ...
line essentially commits your changes while the third 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 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.
git checkout development
copy the commit hash (i.e. id of the commit immediately before the wrong commit) from git log
git log -n5
output:
commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 \"Merge branch \'wrong-commit\' into \'development\'\"
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)
git status
to show all the changes that were part of the wrong commit.git reset --hard
to revert all those changes.git push -f origin development
git revert -m 1 <merge-commit>
To keep the log clean as nothing happened (with some downsides with this approach (due to push -f)):
git checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>
\'commit-hash-before-merge\' comes from the log (git log) after merge.
Sometimes the most effective way to rollback is to step back and replace.
git log
Use the 2nd commit hash (full hash, the one you want to revert back to, before the mistake listed) and then rebranch from there.
git checkout -b newbranch <HASH>
Then delete the old branch, copy the newbranch over in its place and restart from there.
git branch -D oldbranch
git checkout -b oldbranch newbranch
If its been broadcast, then delete the old branch from all repositories, push the redone branch to the most central, and pull it back down to all.
I found creating a reverse patch between two know end-points and applying that patch would work. This presumes that you have created snapshots (tags) off of your master branch or even a back up of your master branch say master_bk_01012017.
Say the code branch you merged into master was mycodebranch.
git diff --binary master..master_bk_01012017 > ~/myrevert.patch
git apply --check myrevert.patch
git am --signoff < myrevert.patch
git branch mycodebranch_fix
git checkout mycodebranch_fix
git revert [SHA]
The correctly marked answer worked for me but I had to spend some time to determine whats going on.. So I decided to add an answer with simple straightforward steps for cases like mine..
Lets say we got branches A and B.. You merged branch A into branch B and pushed branch B to itself so now the merge is part of it.. But you want to go back to the last commit before the merge.. What do you do?
git log
You will see the history of recent commits - the commits have commit/author/date properties while the merges also have a merge property - so you see them like this:
commit: <commitHash>
Merge: <parentHashA> <parentHashB>
Author: <author>
Date: <date>
Use git log <parentHashA>
and git log <parentHashB>
- you will see the commit histories of those parent branches - the first commits in the list are the latest ones
<commitHash>
of the commit you want, go to your git root folder and use git checkout -b <newBranchName> <commitHash>
- that will create a new branch starting from that last commit you\'ve chosen before the merge.. Voila, ready!As Ryan mentioned, git revert
could make merging difficult down the road, so git revert
may not be what you want. I found that using the git reset --hard <commit-hash-prior-to-merge>
command to be more useful here.
Once you have done the hard reset part, you can then force push to the remote branch, i.e. git push -f <remote-name> <remote-branch-name>
, where <remote-name>
is often named origin
. From that point you can re-merge if you\'d like.