monotone-devel
[Top][All Lists]
Advanced

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

Re: [Monotone-devel] Re: 3-way merge considered harmful


From: Brian Campbell
Subject: Re: [Monotone-devel] Re: 3-way merge considered harmful
Date: Tue, 3 May 2005 01:44:45 -0400

On May 2, 2005, at 7:21 PM, Florian Weimer wrote:

* Richard Levitte:

In message <address@hidden> on Sun, 1 May 2005 00:29:48 -0700, Nathaniel Smith <address@hidden> said:

njs> Here's another pathological case for 3-way merge:
njs>    A
njs>    |
njs>    B
njs>   / \
njs>  C   D
njs> Suppose that a file was added on the A->B edge, and then removed again njs> in B->C, while it was left alone on the B->D edge. We want to merge njs> C and D. Let's assume that for some reason we decide to use A as a njs> common ancestor. What will happen? Our file does not exist in either njs> A or C, so when comparing A and C 3-way merge will think that nothing njs> has happened. Our file _does_ exist in D, though, so when comparing A njs> and D, 3-way merge will decide that a file has been added. Therefore,
njs> says 3-way merge, this file should exist in the new merged node.
njs> But, this is obviously wrong; the file was deleted between B and C,
njs> and this delete should have caused a delete of D's copy as well.

I disagree with that conclusion.  It's quite possible the removal of
the file in the B->C edge is a mistake, and that the person leaving it
along in the B->D edge had it right.  Especially in a fairly loose
network of cooperating programmers, disagreements of that kind are
bound to happen (and have happened).  Others might call them "oopses"
rather than disagreements...


I think Nathaniel wanted to say that there is an implied conflict
which 3-way merge cannot detect, not that one choice is better than
the other.  The argument that there is a hidden conflict which should
be flagged as such is quite convincing (and, as a result, the "zombie
changeset" term is misleading).

But this isn't a conflict. It's a case of an actual change just being dropped completely. Say, in more concrete terms, the following happens:

I do a bunch of adds of various files, accidentally adding some text editor backup files to one directory (say I do monotone add foo.*, and there is a foo.c, foo.h, and foo.c~ in the directory). This is the A -> B change.

I realize what I've done, and drop foo.c~. This is the B -> C change.

Someone else does some unrelated work; say, edits bar.c. This is the B -> D change.

Now we do a 3-way merge, and for whatever reason, A is chosen as the ancestor. Now we completely lose the drop that I did in the B -> C change. This isn't a case of not catching a conflict; it's completely ignoring one of the changes that shouldn't have conflicted with anything. If I added foo.c in A -> B, and added foo.h in B -> C, and someone else edited bar.c in B -> D, you wouldn't say that the add of foo.h in B -> C conflicted with the edit of bar.c in B -> D, would you? Then why should a drop of foo.c~ in B -> C conflict with an edit of bar.c in B -> D? If we take the policy that whenever someone doesn't touch something, they meant it to stay that way, then every edit would become a conflict, and we wouldn't have to do any merging at all; the users would all do it by hand.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]