Re: RFC: How to handle merge-recursive corner cases?

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

 



Hi Elijah,

Elijah Newren wrote:

> #      B   D
> #      o---o
> #     / \ / \
> #  A o   X   ? F
> #     \ / \ /
> #      o---o
> #      C   E
> In other words, there
> 
> Let's start with a simple though very contrived case that will
> illustrate issues later, namely a repository with exactly one file
> named 'file', with the following contents at different points in
> history:
> 
> Commit A: file has contents 'A\n'
> Commit B: file has contents 'B\n'
> Commit C: file has contents 'C\n'
> Commit D: file has contents 'D\n'
> Commit E: file has the following 5 lines in it:
> <<<<<<< Temporary merge branch 1
> C
> =======
> B
> >>>>>>> Temporary merge branch 2
> 
> Now, if we try to merge D & E, clearly there should be a conflict.
> But git merges cleanly, giving file the contents 'D\n'.

Funny.  A different problem is that with a less unusual history (i.e.
no conflict hunks committed) with "[merge] conflictstyle=diff3", if
there are conflicts in an early stage of recursive merge, we get
nested conflict hunks, leaving rerere and humans confused.

I have wondered: why doesn't merge-recursive implicitly use the union
merge driver for its in-core merge of ancestors?  The resulting
diff3-style conflict hunks from the final 3-way merge would be more
readable, but now you've provided an answer: coincidences of matching
content like you describe would become more likely.

[...]
> It's wrong, but the only way to fix it is to somehow have an entry in
> the virtual ancestor tree where the conflict region(s) of file are
> guaranteed to not match the corresponding content locations of file
> for either D or E.  (Perhaps by adding random content on the line
> after the ='s?)

Random content does not provides a guarantee.

Maybe merge_recursive()/merge_trees() could steal a flag bit from
struct object for "conflicted"?  No, that would give only one bit
for the entire tree, and we need one bit per path.

How about using index entries for this?

>From the signature of git_merge_trees(1, ...) it is not obvious
to me where it reports conflicts.  From the start to
write_tree_from_memory() I would guess it does not at all.

[...]
> Possibility 1: Virtual ancestor somehow contains both 'a' and 'a/file'
> (currently impossible in git, since this virtual ancestor is written
> as a tree
[...]
> The only way out of this that I see (and I'm hoping I'm just missing
> something), is a modification of possibility 1: make the virtual
> ancestor contain both 'a' and 'a/file'

Hmm, D/F is a little harder than the content conflict case, I guess.
;-)  But I think in general, the thing to do is to keep something
other than a tree.

Thanks for the food for thought.
Jonathan
--
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]