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