Scott
Scott

Reputation: 715

Why does git revert produce conflicts?

I have the following commits

dd9e52bafac5fa427ed64c5d9cf08015fa804ed4 Added Line 3
a000427a4c70781d0bed7b31f56f290ac1d636b7 Added Line 2
20baa578ae205768639620749f53bd318e329e73 Added Line 1
7c043a104394ba4ba5a2fb29d4526de50b7d12be Created file.txt

At commit dd9e the file.txt now reads

Line 1
Line 2
Line 3

Head and master are pointing at the last commit (dd9e).

If I run the git command

git revert 20baa

I am told

error: could not revert 20baa57... Added Line 1
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'

I don't understand why there is a conflict.

When viewing the conflict in VS Code it shows the following git conflict

What I want to happen

I want to undo the changes that were done in commit 20baa (i.e. remove line 1 from the file). I realise I could just do this manually and then commit the changes but I thought git revert was meant to undo the changes?

Am I misunderstanding what git revert does?

Upvotes: 5

Views: 1284

Answers (2)

Rory O&#39;Kane
Rory O&#39;Kane

Reputation: 30388

git revert looks at the changes made in the original commit, generates a diff with the opposite changes, and tries to apply it. In your case, Git is trying to apply this diff:

-Line 1
 <nothing else in the file>

When trying to apply a change to a line from any diff, Git will raise a conflict if that line or its two neighboring lines have changed since then. That's the heuristic Git uses to guess whether a change in the same file is important enough to bother you with. With this heuristic, the above diff conflicts with the latest state of the file, which is this:

Line 1
Line 2
Line 3

It refuses to just remove Line 1 because the next line used to be nothing, but now it is Line 2. Git thinks that might that affected the meaning of Line 1. It won't let you remove Line 1 without confirming that the later addition of Line 2 didn't make Line 1 more important and worth keeping after all.

Upvotes: 4

jsageryd
jsageryd

Reputation: 4633

git revert <commit> creates a new commit that does the inverse of the commit given. In the above case it tries to apply the patch generated by git diff -R 20baa57^..20baa57.

If the change cannot be cleanly applied in reverse, there will be a conflict. You can either resolve the conflict (fix, add, commit), or you can abort the reversion and perform the change manually.

Depending on the type of conflict, you may have better luck providing a different merge strategy (--strategy) or strategy option (-X).

See man git-revert for more info.

Upvotes: 2

Related Questions