On Tue, Jan 23, 2018 at 3:52 AM, Edward Thomson
<ethom...@edwardthomson.com> wrote:
> Indeed, when I added merge to libgit2, we put the higher-level conflict
> analysis into application code because there was not much interest in it
> at the time.  I've been meaning to add this to `git_status` in libgit2,
> but it's not been a high priority.

That sounds pretty cool.  I'm actually dealing with a similar problem
in git itself with my replacement merge strategy; since I try to
perform the merge in-core, and then only try to update the index and
working copy if there'd be no loss of information (no overwriting of
dirty or untracked content), there's a delay between when a conflict
is detected and when I can report it, meaning that I have to store
information about the conflict somehow, and then report later.  So
that means I have to go through the trouble of storing this
information internally, which naturally raises the question of whether
I want to provide this information to the user in some fashion other
than just simple "CONFLICT: ..." messages printed out to the user.

>> This which
>> leaves it unclear what exactly the conflict was, at which point any
>> user (read: porcelain developer) will end up having to recreate some
>> merge logic to figure out what went wrong. And if merge-tree starts
>> doing rename detection, the user might then have to emulate that as
>> well.
>
> That's not a good idea.  Trying to figure out what merge did would be
> painful at best, and likely impossible, since a rename conflict is
> recorded in the main index without any way to piece it together.  eg:
>
> 100644 deadbeefdeadbeefdeadbeefdeadbeefdeadbeef 1       bar.c
> 100644 cafec4fecafec4fecafec4fecafec4fecafec4fe 2       bar.c
> 100644 c4cc188a892898e13927dc4a02e7f68814b874b2 1       foo.c
> 100644 71f5af150b25e3aaaad2d67ff46759311401036f 2       foo.c
> 100644 351cfbdd55d656edd2c5c995aae3caafb9ec11fa 3       rename1.c
> 100644 e407c7d138fb457674c3b114fcf47748169ab0c5 3       rename2.c
>
> This is the main index that results when bar.c has a rename/edit
> conflict, and foo.c also has a rename/edit conflict.  One was renamed
> to rename1.c and the other to rename2.c.  Trying to determine which is
> which _after the fact_ would be regrettable.  Especially since rename
> detection is not static - you would need to know the thresholds that
> were configured at the time merge was performed and try to replay
> the rename detection with that.
>
> libgit2 records a `NAME` section in the index that pairs the rename
> detection decisions that it performed so that you can analyze them
> and display them after the fact.

Ooh, I like that idea.  Could we do the same in git itself?  Having
not messed with the index format at all, what commands do users use to
view this supplementary info?

Also, if you have this NAME section, you could make other commands
smarter.  For example, if you had a normal content conflict on some
file without rename detection being involved, you'd expect the index
to look something like

100644 deadbeefdeadbeefdeadbeefdeadbeefdeadbeef 1       file.c
100644 cafec4fecafec4fecafec4fecafec4fecafec4fe 2       file.c
100644 ba5eba11ba5eba11ba5eba11ba5eba11ba5eba11 3       file.c

and then when you do a 'git add file.c' you expect all the higher
stages to go away, i.e.

100644 5ca1ab1e5ca1ab1e5ca1ab1e5ca1ab1e5ca1ab1e 0       file.c

With your NAME section trick, could one expect 'git add rename1.c' to
delete not only the higher stage for rename1.c but also the two for
whichever of bar.c or foo.c is relevant?

Elijah

Reply via email to