[cvsnt] Mergepoint issues on b2382

Michael Wojcik Michael.Wojcik at microfocus.com
Fri Jan 12 18:34:19 GMT 2007

> From: cvsnt-bounces at cvsnt.org 
> [mailto:cvsnt-bounces at cvsnt.org] On Behalf Of Andreas Krey
> Sent: Friday, 12 January, 2007 12:05
> To: cvsnt at cvsnt.org
> Subject: Re: [cvsnt] Mergepoint issues on b2382
> On Fri, 12 Jan 2007 16:22:18 +0000, Tony Hoyle wrote:
> > Andreas Krey wrote:
> > 
> > > This is not what the patch does, obviously. It chooses the diff
> > > 1.2 to to be merged into the head. You need to used the
> > > of the last merge arrow as the base version for the merge, not the
> > 
> > But 1.2 is *not* an ancestor of,
> It has become one by inserting the merge arrow. contains
> the changes made in 1.2 as well as the head, so it is effectively
> the ancestor.

No, Tony's right.  There's no guarantee that " contains the
changes made in 1.2"; in particular, CVSNT can't guarantee that. will only contain all the changes from 1.2 if the person
performing the merge resolves conflicts in a lossless fashion, and
doesn't otherwise modify the results of the merge.

That's not guaranteed; in fact, it's not even desirable in all cases.
Consider the case where ongoing development in the trunk has included
both fixes and substantial new features.  Now perhaps the fixes need to
be merged into the branch, but the new features should not be, or even
cannot be (eg due to external dependencies).  The developer working on
the branch might well discard some conflicts, and even manually back out
merged-in changes, on the branch before it's merged back to the trunk.

> Merge arrows are no thinner than the other lines
> in the revision graph.

That metaphor isn't meaningful.  1.2 is not an ancestor of
That's all there is to it.  CVSNT knows that real common ancestors
really are common; it can't assume that for any other revisions.

> > so the merge is bogus.
> But it happens to yield the correct result. And that is not a
> coincidence.

It's not a coincidence, but it does require assuming that the merge to
the branch was done in a lossless fashion.

That's fundamentally different from a normal merge operation, since it
operates under an additional assumption.

Perhaps what we need is another option to update, used in place of -j,
which says "if there's a mergepoint from the destination branch to the
source branch, then act as if the tail of that mergepoint was the
closest common ancestor".  So instead of

	cvs update -jtmp-ak-test-br t4.txt

in Andreas' example, people who want this "bidirectional" functionality
would use something like

	cvs update -Jtmp-ak-test-br t4.txt

which would perform the way the patched CVSNT does - it would look back
on the default branch (here the trunk) and find that there was a merge
from 1.2 to, so it would use 1.2 as the common ancestor and
merge diff(1.2: into 1.2, creating 1.3.

Hopefully it would also produce a message along the lines of "Warning:
Assuming 1.2 is a common ancestor - changes could be lost" in the
process.  And that would suggest to the developer that doing a diff
before committing might be a good idea.

There's always some risk in merging, of course; even a conflict-free
merge can obviously make changes that the developer didn't expect and
doesn't want, because our mental model of what's in the files on the two
branches doesn't always exactly match what's actually there.  I could
decide to remove something from a branch but keep it on the trunk, and
then forget and merge that branch back into the trunk.  But that's why
we have change management, after all.

So the best compromise, in my opinion, is to make this behavior
available, but not the default.  People with a process like Andy's will
have to change their process slightly (they could actually hide that, by
wrapping their CVS clients, but I wouldn't recommend it), but not

Michael Wojcik
Principal Software Systems Developer, Micro Focus

More information about the cvsnt mailing list