Re: Rename conflicts in the index

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Edward Thomson <ethomson@xxxxxxxxxxxxx> writes:

> Junio C Hamano [mailto:gitster@xxxxxxxxx] wrote:
>> We do not gratuitously break existing implementations.  If no conflict is stored
>> as higher-stage index entries in an index that has your index extension, no
>> existing implementation can read a conflicted index written by your
>> implementation and have users resolve conflicts.
>
> I'm not suggesting that anybody stop writing >0 stage entries.

Ah, OK, then I misread your original message.  You said

> Having a single canonical location is preferable - if the index
> contains a CONF section (and the client supports it), it would use
> that.  Otherwise, the client would look at stage >0 entries.

which I read as "an index with this extension would not have higher
stage entries, an index without the extension records higher stage
entries".  As long as the format will be backward compatible to
allow existing users use existing tools to deal with cases the
existing tools can handle, then that is OK.  I didn't get that
impression which is where my "non starter" came from.

> What you've described is true only for a certain class of rename conflicts,
> for example the rename/edit conflict you've described above.

As you asked me to explain why it was a non starter, I only
illustrated with a "renamed trivially, with content level conflict"
example that shows why dropping higher-stage entries in the main
index would not be acceptable.  The previous message did not even
mean to cover any cases the *new* feature you have in mind is trying
to address.  Again, if it hurts existing users handling cases
existing tools used to handle, that makes it a non starter.

How new feature is designed, and extension is added to help that new
feature, is a different matter.  My original "That's a non starter"
message didn't even go that far.

In any case, the principle of "always record the state 'merge'
stopped to ask for help as higher stage entries to give existing
tools and users a chance to manually resolve, and augment with
optional extension to record additional information that might help,
but do not gratiutously waste bytes on redundant information" would
apply to other exotic cases you would want to tackle with the new
feature, I would think.

If one branch moves path A in the original to path B and the other
one moved it to path C, for example, we can record it in different
ways, even in the main index.

 * Path A may have only stage #1, while path B and C has only stage
   #2 and stage #3 (the user would have to notice these three
   correspond to each other, and resolve manually).

   You would want to annotate "B at stage #2 seems to have been at A
   in the original" (similarly for C#3) if you choose to do so.

 * You can choose to favor "our" choice, and have path B with three
   stages (if we guessed wrong and the user wants to move it to C,
   the user can resolve and then "git mv" the path).

   You would want to annotate "the other side wanted to have B at
   stage #3 at C" in that case.

 * Or you may want to have in the main index both B and C (but not
   A) with all three stages (the user would have to choose which
   one survives, but discarding the other side with "git rm" would
   be easy).

   You would want to annotate the origin of the stage #1 for path B
   and C (these were originally at A), stage #2 for B (the other
   branch wants to have it at C), stage #3 for C (we want to have it
   at B).

There may be other ways, and I do not offhand know what the current
merge-recursive implementation does, but both of the latter two
sound equally usable and reasonable ways, even without the
annotation.  And with your annotation that records different paths,
the conflict may become even easier to resolve.

I still do not need to duplicate <mode, SHA-1> in the extensions to
do the above, or do I?

If the original path A was removed and a new path B was added, with
contents that are modified from A beyond recognition, at the merge
time you wouldn't know where B it came from or where A went, so
annotating A at stage #1 to say "it went to B" is a nonsense.  If
you have algorithm to do so [*1*], you would be better off detecting
it as a rename.


[Footnote]

*1* Instead of a three-way merge that inspects only the endpoints,
    you might get a better rename trail if you looked at the
    histories of both branches.  It would be a lot more expensive
    than the simple three-way, but burning CPU cycles is better than
    burning human neurons.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]