3

I have a file that in the beginning looked like this

asd
bnm
cvb

Then I added three commits:

1.

asd feature1 c1
bnm
cvb

2.

asd feature1 c1
bnm feature1 c2
cvb

3.

asd feature1 c1
bnm feature1 c2
cvb feature1 c3

Now when I want to revert commit number two by doing

git revert HEAD^

I get an error message like this

error: could not revert 2222222... feature 1 commit 2
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

and my file looks like this

<<<<<<< HEAD
bnm feature1 c2
cvb feature1 c3
=======
bnm
cvb
\>>>>>>> parent of 2222222... feature 1 commit 2

And I just don't understand why. My assumption is that it would work like Edwar Thomson explains it in his answer to this question: git revert: Why do I get conflicts? I didn't edit line 2 twice and should not get a conflict. What am I missing?

I expect the result to be

asd feature1 c1
bnm
cvb feature1 c3

without any conflicts.

IwantToKnow
  • 351
  • 1
  • 5
  • 18

1 Answers1

1

What is missing here is that a revert, like a cherry-pick, is only applying a patch (here the negative image of a past commit).
It is not merging.

That means, as I described in "Git cherry-pick causes merge conflict while merging does not", it has no notion of common ancestor.

The problem is the context of the patch computed by a git revert: see "Conflicts from apply and stash".

The revert (negative diff between 2 and 1) tries to cancel line 2 (reverting bnm feature1 c2 to bnm, before a third line cvb) on a HEAD content which has not cvb as a third line.
When applying that patch, Git doesn't know what to do with the third line: should it leave it alone, or modify it to cvb.

See another example in "Why does this cherry-pick have a conflict?".

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Interesting answer, but according to https://stackoverflow.com/a/37151159 revert *does* use a 3-way merge. To verify that the conflict occurs when there is a common ancestor, check out a new branch pointing at commit 2, revert commit 2, then merge this new branch into commit 3 (it should conflict). – tom Feb 17 '18 at 10:42
  • I'm a bit confused by the link provided: 'Git cherry-pick causes merge conflict while merging does not' It's pointing to ' https://stackoverflow.com/questions/33063296/cant-change-username-and-password-from-git/33063731#33063731 ' Is this intended? – IwantToKnow Feb 17 '18 at 11:45
  • No, probably a typo, I will fix the link when I go back – VonC Feb 17 '18 at 11:46
  • Technically both revert and cherry-pick use the parent of the commit being picked or reverted as the common ancestor when running the 3-way merge. There is a way to apply a commit as "pure patch" (rather than merge), using `git apply`, and you can do forward or reverse here. If you have an `index` with blob hashes, and use `-3`, the apply will *fall back* to doing a 3-way merge if the straightforward "apply patch" part fails. – torek Feb 17 '18 at 16:59