2

It's simple to revert a commit with Git.

But what if I want to revert a commit from a merge to cancel it and merge it later?

master--\--------------/------revert-merge------/------------------
         \            /                        /  merge nothing                 
          \--branch--/----no-modification-----/------    

If I merge again after a first merge Git won't accept my changes because I already merged before and someone (me or someone else) reverted these line and Git don't know why.

Git see I already did a merge then reverted it so when I do the second merge it doesn't know the reason of the revert and Git consider there is no more change.

So actually I should't do a simple revert when I want to cancel a commit. What is the correct operation to cancel/postpone a merge?

This can help a lot https://www.git-scm.com/blog/2010/03/02/undoing-merges.html

Bastien Vandamme
  • 17,659
  • 30
  • 118
  • 200
  • Just revert the revert? – mkasberg Mar 20 '16 at 04:05
  • Yeah, actually it's what I did but when you work with a team and with several branches it is complicate to remember what you must revert when doing the next merge. My sample here is very simple. Where you can read -no-modification- it's actually never true in real projects. So when you will do the second merge and you forget to revert your revert you create bugs of course. Then you try to revert you revert after the second merge and you start to cry... – Bastien Vandamme Mar 20 '16 at 04:08
  • Use git reflog to get back to the point in the past where you want to be. – CodeWizard Mar 20 '16 at 04:11
  • I think the point of using a revert is to not rewrite history. Moving the branch pointer to a previous commit would modify the history of that branch. – mkasberg Mar 20 '16 at 04:17
  • Maybe `git reset --hard` to before the merge commit in master and run `git rebase master` from the branch so you can (hopefully) just fast-forward when merging in the future? Is this all local, or has the merge commit been pushed and is accessible to other devs? – J. Titus Mar 20 '16 at 04:22
  • @mkasberg I don't want to rewrite history of course. I just want to indicate to Git that i'm not doing a revert this changes/commit. I want to tell him I want to revert this changes and postpone them. Actually i'm not reverting a commit, I'm reverting a merge commit. – Bastien Vandamme Mar 20 '16 at 04:29
  • 1
    I found this https://www.git-scm.com/blog/2010/03/02/undoing-merges.html – Bastien Vandamme Mar 20 '16 at 04:29
  • FYI I tested this with Subversion (because come from Subversion) and actually it works. This is why for me and probably for many other users it's sometime complicate to understand Git. A revert of a merge in Subversion is a revert of a merge so when you merge later the merge works. A revert of a merge in Git is... actually I don't know how to explain this. You don't revert the merge, you revert the code. – Bastien Vandamme Mar 21 '16 at 07:16

2 Answers2

2

There's a great article from Linus (who wrote Git) about this scenario here.

To summarize, it boils down to 2 options:

Option 1 Make a bad merge, revert the merge, then later on, before merging the branch again, revert the revert. Reverting the revert means you get the bad changes back, and then you fix them by merging your branch again. The downsides to this method are, as you mentioned, you have to find the revert and remember to revert it before merging your branch again.

---o---o---o---M---x---x---W---x---Y---*
              /                       /
      ---A---B-------------------C---D

A and B are bad commits, M is the merge, W reverts M, Y reverts W.

Option 2 Make a bad merge, revert the merge, then make an entirely new branch (by redoing or possibly cherry-picking the changes). The downside to this option is you have to make another separate branch. But the upside is you don't have to remember to revert the revert.

---o---o---o---M---x---x---W---x---x
          /                 \
  ---A---B                   A'--B'--C'

A and B are bad commits, M is the merge, W reverts M.

Of course, probably the best option is to avoid merging stuff into master that isn't ready to be merged into master. Because none of the options for cleaning it up are really great.

mkasberg
  • 16,022
  • 3
  • 42
  • 46
0

It's simple to revert a commit with Git. But what if I want to revert a commit from a merge to cancel it to merge later ?

Few options:

git reflog

First you can use git reflog - read all about it here:
How to move HEAD back to a previous location? (Detached head)


git revert

Merge is a combination of multiple commits.
Each commit is named parent so merge has few parents (2 or more).
Lets assume the easy flow where you only have 2 parents.

What you can do in order to revert it is simply to revert the desired parent with a revert command

# Add the -m to the revert to indicate that you are reverting a merge
# (-m 1) - The number is the id of the parent (1-N)
# SHA-1 - optional SHA-1 to revert
git revert -m 1 SHA-1
Community
  • 1
  • 1
CodeWizard
  • 128,036
  • 21
  • 144
  • 167