2

I'm trying to learn Fugitive with a live project, particularly resolving a merge conflict as I find doing this manually pretty tedious. I don't know if this is a valid question, because I cannot reproduce the effect outside of the repo I'm working with and I've otherwise never seen it before.

Anyway, Git is reporting a merge conflict. However, when I go to edit the file that contains the conflict, I scroll to the annotations that Git adds to mark the conflict (what are these called, by the way?) and they are identical. Something like this:

<<<<<<< HEAD
These are identical
=======
These are identical
>>>>>>> merge-branch

They are completely identical. There's no anomalous whitespace in one or the other, no weird Unicode characters that look the same, etc. Byte-for-byte identical. As such, Fugitive/vimdiff doesn't work: The only difference it detects are those in-band annotations and so doing a :diffget or :diffpull just removes the annotation. Because the annotations are suitably separated, they're treated separately, so one has to do each one individually and you eventually end up with this obviously incorrect result:

These are identical
These are identical

At first I thought that the annotations had been accidentally committed into one of the branches -- that's the only explanation I could come up with -- but no, they're nowhere to be seen. The files are not exactly the same in each branch, but they don't have conflicting differences.

It seems obvious that Git (2.28.0) is incorrectly marking a conflict and Vim/Fugitive are working fine. What is going wrong here?

Xophmeister
  • 8,884
  • 4
  • 44
  • 87
  • 1
    they are simply called "conflict markers" – LeGEC Aug 12 '20 at 14:01
  • Thanks :) I've heard "changesets" and "diffsets", but I think they refer to the entire set of changes/differences, rather than the specific annotations – Xophmeister Aug 12 '20 at 14:02
  • Yes, this conflict looks bogus. To diagnose it properly we'd need a reproducer (perhaps the actual repository itself) though. – torek Aug 13 '20 at 04:07

1 Answers1

1

What you describe is weird indeed, I think some explanation is missing in the elements that triggered the conflict.

I would suggest to inspect the "diff left" and "diff right" to look further in what could possibly create this conflict.

When a conflict is triggered on file foo, git actually keeps 3 references to copies of that file :

  • the file in the 'merge-base' commit : git show :1:foo
  • the file in the 'ours' commit : git show :2:foo
  • the file in the 'theirs' commit : git show :3:foo

Inspect git diff :1:foo :2:foo and git diff :1:foo :3:foo to see if you spot something that could trigger the conflict you see.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • Those two sets of diffs are different, in the sense that the way in which they're being split up into new/removed lines is different; this is because, I presume, in `:3:` there are more significant changes earlier on in the file, so the changes that Git is reporting a conflict over are offset by quite a bit. However, despite the different splitting, the end result looks to be the same. – Xophmeister Aug 12 '20 at 14:48
  • `vimdiff <(git show :1:foo) <(git show :2:foo) <(git show :3:foo)` makes it clearer, rather than just eye-balling it. My best guess would be that the locality of the changes have differed by enough such that it can't reconcile them. However, I didn't think diff algorithms worked like that. – Xophmeister Aug 12 '20 at 14:59
  • ok, make sure to put the 'base' (`:1:`) version at the right place. I know that `meld`, for example, would expect 'base' as the second argument : `meld :2:foo :1:foo :3:foo`, as in `merge LOCAL BASE REMOTE` – LeGEC Aug 12 '20 at 15:33