176

With SVN it is easy to reverse-merge a commit, but how to do that with Git?

3
  • 1
    Duplicate of Revert to a previous Git commit Commented Jul 16, 2014 at 21:55
  • 1
    I don't think this is what is meant by the question. A reverse-merge in SVN also reverts the changes from the commit to local changes, so you can edit them and commit again. Commented Sep 26, 2016 at 10:53
  • 1
    Possible duplicate of How to revert a merge commit that's already pushed to remote branch? Commented Nov 26, 2019 at 16:44

6 Answers 6

166

To revert a merge commit, you need to use: git revert -m <parent number>. So for example, to revert the recent most merge commit using the parent with number 1 you would use:

git revert -m 1 HEAD 

To revert a merge commit before the last commit, you would do:

git revert -m 1 HEAD^ 

Use git show <merge commit SHA1> to see the parents, the numbering is the order they appear e.g. Merge: e4c54b3 4725ad2

git merge documentation: http://schacon.github.com/git/git-merge.html

git merge discussion (confusing but very detailed): http://schacon.github.com/git/howto/revert-a-faulty-merge.txt

Sign up to request clarification or add additional context in comments.

7 Comments

How can you get the 'number' associated with the parent? Do branches have an intrinsic numerical 'id'?
Use git show <merge commit SHA1> to see the parents, the numbering is the order they appear e.g. Merge: e4c54b3 4725ad2
example: git revert -m 1 SHA1 That command worked for me to revert a merge commit that was several merge commits prior to head and had many commits underneath.
This still doesn't provide enough info about how the results of git show relate to parent numbers. Is the "order they appear" 1-based? 0-based? In this example specifically, what is the SHA1 of parent 1? e4c54b3 or 4725ad2?
@cowlinator running git help revert and looking at the -m flag says: This option specifies the parent number (starting from 1) of the mainline and allows revert to reverse the change relative to the specified parent. Although be careful b/c it also says: Reverting a merge commit 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.
|
154

To create a new commit that 'undoes' the changes of a past commit, use:

$ git revert <commit-hash> 

It's also possible to actually remove a commit from an arbitrary point in the past by rebasing and then resetting, but you really don't want to do that if you have already pushed your commits to another repository (or someone else has pulled from you).

If your previous commit is a merge commit you can run this command

$ git revert -m 1 <commit-hash> 

See schacon.github.io/git/howto/revert-a-faulty-merge.txt for proper ways to re-merge an un-merged branch

5 Comments

You would probably need to supply -m <parent number> option to git revert to specify which change to revert. If you want to undo a merge of non-published history, use git reset --hard HEAD^1.
Jakub: that's true if you are reverting a merge commit, but in Subversion terminology, "reverse-merge" is actually simply the name for reverting any kind of commit.
Do note that using -m means a future merge from the un-merged branch will not include the changes from before that merge! See schacon.github.com/git/howto/revert-a-faulty-merge.txt for proper ways to re-merge an un-merged branch.
The hyperlink is broken. Should've future proofed the answer.
updated link: schacon.github.io/git/howto/revert-a-faulty-merge.txt (user-controlled Github Pages were moved to github.io to avoid risks of sharing cookies with github.com)
5

If I understand you correctly, you're talking about doing a

svn merge -rn:n-1 

to back out of an earlier commit, in which case, you're probably looking for

git revert 

Comments

3
git reset --hard HEAD^ 

Use the above command to revert merge changes.

1 Comment

This throws away the merge commit, which doesn't do what the original poster is asking. The OP is trying to do a reverse patch to undo previous changes, not erase the history of the previous changes altogether.
3

git revert -m hash
-m means mainline.
A merge has two parents.
If you merge branch A to branch B, B is parent 1 and A is parent 2.
Basically you specify, I want to revert the commit hash, which changes based on parent B, then you say
$ git revert -m 1 hash.

If you git log, you will see the merge commit as

commit <hash> Merge: <parent 1> <parent 2> Author: Author <[email protected]> Date: Mon Oct 24 21:54:00 2022 +0000 comment message 

You check what the <parent 1> and <parent 2> are in the log, you will know which parent/base you want to revert this commit to.

1 Comment

Proper explanation, thanks
-1

If you don't want to commit, or want to commit later (commit message will still be prepared for you, which you can also edit):

git revert -n <commit> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.