1

I'm using git revert on a very basic use case, in order to learn how it really works, but I'm facing the following issue. I've read a couple of posts on similar scenarios, but none has provided a clear answer to this in my opinion. I've surf the internet and even superficially read part of the Git documentation on reset/revert command, but still can't figure out what is going on here. Any help preciated.

These are the exact steps I'm executing, in the below order:

  1. Create a ~/gittest directory and create a testfile file inside it.
  2. Add the following line to testfile : commit 1
  3. Execute git add testfile; git commit -m 'commit 1'
  4. Add the following line to testfile : commit 2
  5. Execute git add testfile; git commit -m 'commit 2'
  6. Add the following line to testfile : commit 3
  7. Execute git add testfile; git commit -m 'commit 3'

At this point I execute git log --oneline and this is the output:

ba1810 (HEAD -> master) commit 3
88bc443 commit 2
802d820 commit 1

Now the testfile looks like this:

commit 1
commit 2
commit 3

What I'm trying to acomplish is to revert commit 88bc443 and therefore expecting for the line saying commit 2 to disapear, so testfile ends up looking like this:

commit 1
commit 3

Before attempting the revert operation I execute git status and indeed my working tree is clean:

On branch master
nothing to commit, working tree clean

So when I execute git revert 88bc443 I get the following error:

Auto-merging test
CONFLICT (content): Merge conflict in test
error: could not revert 88bc443... commit 2
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add ' or 'git rm '
hint: and commit the result with 'git commit'

These are the git indicators on the tesfile after the error prompts:

commit 1
<<<<<<< HEAD
commit 2
commit 3
=======
>>>>>>> parent of 88bc443... commit 2

I haven't done any merge at all. The above are the sole instructions I have execute on the terminal. I have read how revert is suposed to work between branches after/before merging, but I don't see where would the conflict exist in this case, since there is no overriding of the line I'm trying to revert by any subsequent commit. I'm working on a single file, not even between branches or remote repositories.

Git version: 2.25.1
Operative System: Linux Mint 20.2

j6t
  • 9,150
  • 1
  • 15
  • 35
ankaAJ
  • 47
  • 8

1 Answers1

1

Internally, git revert does perform a merge operation.

The merge algorithm needs three versions of a file:

  • A base version; that is the version after the commit that is reverted, which is

    commit 1
    commit 2
    
  • their version; that is the version before the commit that is reverted, which is

    commit 1
    
  • and our version; that is the version onto which the reverted commit is made, which is

    commit 1
    commit 2
    commit 3
    

As you can see, in the transition from base to theirs the line commit 2 was removed, but in the transition from base to ours, a line commit 3 was appended after the line commit 2.

Even though you might think that line commit 3 is independent from the line commit 2, the (authors of the) merge algorithm did not think the same. Rather, it is considered a noteworthy event when changes occur in adjacent lines, and for this reason the situation is flagged as a conflict.

j6t
  • 9,150
  • 1
  • 15
  • 35
  • 1
    So the conflict consists in trying to remove (revert) a line wich a subsequent adjacent line depends on, right? But wouldn't that be the case on most situations while trying to revert changes on a file, given that there is probably going to be always an adjacent subsequent line depending on the line one is trying to revert? So is there an standart way to deal with this, rather than manually resolving the conflict? Thanks in advanced. – ankaAJ Jan 04 '22 at 17:16
  • 1
    @AlejandroRivera No, that is by far not always the case. When the to-be-reverted change inserts or deletes or modifies a line, and another commit modifies the file at a distant location, no conflict occurs. The conflict only occurs because the modifications in the two commits occur on adjacent lines. If there is at least one unmodified line between the edits, no conflict occurs. – j6t Jan 04 '22 at 18:25
  • 1
    I can see how it would not always be the case, but in this particular situation I posted, where I'm modifying a single local file, by only adding lines to it, any new commit I make would inevitably end up being a line adjacent to a previous commited line, wouldn't it? Is there a way to deal with this apart from just fixing the file manually? A git option I might bemissing maybe. – ankaAJ Jan 04 '22 at 20:51
  • 2
    @AlejandroRivera There is no option in stock Git that could automatically resolve the conflict in the posted case. You have to resolve it manually. – j6t Jan 04 '22 at 21:43
  • 1
    I see. Thank you, this was clarifying. – ankaAJ Jan 06 '22 at 04:30