[cvsnt] Re: Branch merging - this seems wrong...

Andreas Krey a.krey at gmx.de
Wed Jun 7 14:10:46 BST 2006


On Wed, 07 Jun 2006 12:59:32 +0000, Tony Hoyle wrote:
...
> Full revisions only exist in the sandbox - when you're talking about 
> revisions in the repository it's important to remember that cvs (and all 
> version control systems AFAIK) work with diffs exclusively.

It is completely irrelevant whether they store them as diffs, as full
text each, as lists of pointers to shared common lines or whatever.
That is a detail of the rcs file format that is (supposedly) underlying
cvs and cvsnt.

> Merging would be impossible if you didn't work like that - you wouldn't 
> be able to isolate changes and apply them in the right order.

Of course I could. As long as the SCM is able to retrieve any revision
of a file I can simply run diff to recreate the differences. But anyway
the merge is not working by applying the individual diffs but rather by
one diff3 run. Using diffs in the rcs file was just to keep the files small.

...
> No, B2 is just the changes required to incorporate A3 into the branch. 

Please don't intermix implementation with user-visible behaviour. When
I'm saying 'cvs update -p -rB2 myfile' I get the contents of revision
B2, not some diff.

> B2 does not include any part of B1 unless the merge requires a change to 
> B1 to work.

You seem to have a major misunderstanding here. I don't care what
lines actually appear in the internal diff stored in the rcsfile.

I do care, however, how cvsnt selects the base version for a merge.

...
> >No. The mergepoint declares that B2 is the result of the
> >merge of A3 and B1. A3 and B2 differ by everything that
> >has been done on the branch before, they are *not* equivalent
> 
> From cvs' point of view they are equivalent..

Not even that: 'cvs diff -rA3 -rB2' will show a difference.

> an alternative way of 
> viewing a mergepoint is a point of equivalence in the tree - it's a 
> point that you don't have to worry about earlier revisions so can 
> simplify the merge.

It does not just simplify it; observing the merge points is the
only way to do the merges correctly (without massive tagging and
the two-'-j' form of update).

...

> You can also think of it as moving the branchpoint, but that gets 
> ambiguous,

No, it is just right. The original

    A
    |
    A1------>B0    # Set branch B on version A1 (B0 is the same as A1)
    |        |
    A2       |     #
    |        B1    # Independent work
    A3       |     #
    |        |  
    *------->B2    # Merge A up to A3 into B (and commit)
    |        |
    A4       B3    # More independent work

is (for the contents of the named revisions) the same as creating
a new branch from the trunk and then merging the old branch in there:

    A
    |
    A1------------>B0   # Set branch B on version A1 (B0 is the same as A1)
    |              |
    A2             |    #
    |              B1   # Independent work
    A3             |    #
    |              |  
    *------>X      |    # Create new branch from A
    |       |      |
    |       B2<----*    # Merge in B.
    |       |
    A4      B3    # More independent work

Although all revisions are the same, and B2 is again the merge of
A3 (alias X) and B1 with A1 as basis, no one would now think of
using A1 (instead of A3) as basis of a backmerge from the new
branch to A.

I haven't completely figured out the general cases, but merging
back and forth between two branches using merge points is trivially
possible as long as the merge arrows do not actually cross (which
would require simultaneous merges in both directions).

> and doesn't really describe what's going on.

For how revisions are stored in the rcs file: true.
But that's not the point of discussion.

Andreas

-- 
np: 4'33



More information about the cvsnt mailing list