I would like to revert a pushed merge into a base branch to the state it was right before the merge. How can I do this?
-
possible duplicate of http://stackoverflow.com/questions/9529078/how-do-i-use-git-reset-hard-head-to-revert-to-a-previous-commit – Ranjith's Jul 19 '16 at 15:05
-
@Ranjith's: No, it's not. I know how to revert to a previous commit. What I'm looking for is how to find what the last commit on a base branch was before another branch was merged into it, so that I can revert to it. – carlspring Jul 19 '16 at 15:11
-
ohkk, you try using `git log` to see what commits are made to base branch.. – Ranjith's Jul 19 '16 at 15:14
-
@Ranjith's: I am well aware of `git log`. However, when you have 100 commits on your feature branch and merge it into the master, then you have these 100 new commits (100 being a figurative number) and it's hard to immediately spot this from the commit log. Hence I'm looking for the exact command which displays this. – carlspring Jul 19 '16 at 15:16
-
Is your question about reverting the merge changes (as the question says) or about finding the commit to revert to (as your last comment says)? – lucash Jul 19 '16 at 15:35
-
Well, ultimately, the goal is to: find the revision before the merge and then revert to it. – carlspring Jul 19 '16 at 16:33
-
`git log --all --graph` and `gitk` come to mind... – twalberg Jul 19 '16 at 16:33
2 Answers
Assuming that you know the merge commit to be reverted and only need to find the base of the merge, as I understand from your comments:
First there is a visual way which shows the parent commits. This might help to understand and make sure you get the right commit:
git show [commit]
(and git log
too) will print information about your merge commit in this form:
commit [commit]
Merge: [parent1] [parent2]
Author: [author]
Date: Tue Jul 19 12:00:00 2016
Where parent2 is the merged commit while parent1 is the commit is has been merged to.
Thus this example (git rev-parse
in this case shows the hash of the given branch):
$ git branch
master
$ git rev-parse master
hasha
$ git rev-parse develop
hashb
$ git merge develop
Will result in a commit like this one:
commit newhash
Merge: hasha hashb
Author: [author]
Date: Tue Jul 19 12:00:00 2016
You can also get the respective commits using the ^ shortcut. master^1
(which is the same as master^
) will get you the first parent (hasha in the example above), while master^2
will give you the second parent (hashb). So you can also use these for your revert (in your case you would want to revert to master^1 if your branch were master). You might want to try them out calling git show master^
to watch which commit is found this way.

- 1,982
- 17
- 25
Besides lucash's answer (which is correct and I've upvoted), if you truly want to identify the merge base commit(s), you can use git merge-base
on the parent commits.
For instance, suppose that the merge in question is commit a123456
(after being shortened to 7 characters). As lucash said the two parents are a123456^1
and a123456^2
(assuming there are only two parents—for an octopus merge, where there are three or more parents, just keep adding more parent specifiers, e.g., a123456^3
through a123456^99
or whatever). Note that, as the git merge-base
documentation says, you need the --all
flag to show all merge bases, in the case where there is more than one merge base.
(If there is more than one merge base, the default recursive merge strategy will merge them to produce a single "virtual merge base", which is not actually contained in the repository. You will need the parameters of the merge in order to repeat this process, if you wish to view the virtual merge base result by creating it as an actual physical merge. While general idea should be pretty obvious, the details are beyond the scope of this answer.)
Note that there is a specific gitrevisions
syntax for listing "all parents of a merge": a123456^@
is equivalent to listing a123456^1 a123456^2 ... a123456^99
in the hypothetical case of our 99-parent merge commit a123456
. Hence, if the name master
currently points to the merge commit you just made, you can simply run:
git merge-base --all master^@
to see the hashes of the merge base(s) of the current merge commit.
All that said, if you truly want to revert a merge, you generally just want to use git revert -m <number> <mergecommit>
; and if you want to review the two sides that went in, you generally want something like:
git rev-list --left-right --cherry-mark --boundary master^1...master^2
(note the three dots), or the same with rev-list
replaced with log
or log --oneline
or similar (incidentally, note that git log
and git rev-list
are really almost the same command, just with different output formats). The --boundary
option tells Git to include the merge bases themselves (but not their parents), marking them with a leading -
(which goes well with the --left-right
and --cherry-mark
options). If you want to exclude the merge bases, omit the --boundary
flag. See the (very long) git rev-list
documentation for more details.