Why do I get conflicts when I do git revert?

CrazySynthax picture CrazySynthax · Sep 18, 2017 · Viewed 8.1k times · Source

I use Git, and I know that:

git revert <hash-code>

is used to create a new commit that will be identical to the past commit in the hash-code.

For example, I have the following commits:

1f74a0e second commit
e72d8b8 first commit  

I wanted to revert the first commit, so I used:

git revert 1f74a0e

Still, I got the following error:

error: could not revert 1f74a0e... first commit hint: after resolving the conflicts, mark the corrected paths hint: with 'git add ' or 'git rm ' hint: and commit the result with 'git commit'

As for the conflicts, I type:

$ git diff --name-only --diff-filter=U
file.txt

When I open file.txt I see no signs for conflicts.

Of course there will be conflicts. I expect git to take the "first commit" and copy it on top of the second commit. How can I do it?

Answer

Edward Thomson picture Edward Thomson · Sep 18, 2017

That's actually not what revert does. Revert doesn't "take you back to" that commit and pretend that subsequent commits didn't happen. It applies a logical negation of a single commit - and that commit alone - leaving subsequent commits in place.

Let's say you have some initial commit of some file - let's call it commit #1 for simplicity - and the file looks like this:

One
Two
Three
Four

Now let's say you have a commit #2 that changes one line:

One
2
Three
Four

And finally, commit #3 that changes a different line:

One
2
Three
4

If you try to revert commit #2, it will undo only the line changed in that commit, and leave the changes introduced in commit #3, so the result will be:

One
Two
Three
4

Now, if there was a subsequent commit that had changed the same line as the commit that you're trying to revert, then you'll have a conflict. For example, let's say you have a commit #4 that also changed the second line:

One
TWO
THREE
4

Now if your HEAD is commit #4 and you try to revert commit #2, you will have a conflict. Revert expects to take second line back - to undo the changes made in commit #2. So it expects the second line to currently be 2, and it will then revert it to what it was in the previous commit, setting it to Two.

However, that expectation was invalidated, since commit #4 had also changed it. So you have a conflict.

If your goal isn't to revert at all, but to get back to commit #1 and ignore all the changes that have gone on since then, then you want to reset instead of revert.

git reset --hard 1