[Top][All Lists]

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

Re: Rephrasing: question about merging branches

From: David Wood
Subject: Re: Rephrasing: question about merging branches
Date: Tue, 4 Nov 2003 22:37:04 -0500

I am not sure about something.

> |>If branch A and branch B in your example don't branch form the same
> |>point on the trunk, a merge from point 2 to point 4 into the trunk 
> |>still not do what you want.  If branch B branched first, then 2->4 may
> |>back out changes made to the trunk between the base of B and the base 
> |>A.  If A branched first, then 2->4 will attempt to remerge changes 
> |>to the trunk between the base of A and the base of B, causing the same
> |>sort of spurious conflicts you were attempting to avoid.

Assume B is branched first. A merges to the trunk. Then A merges to B. 
Then B merges to the trunk as well. 

I think the trick here is what happens when A merges to B. If you do that 
merge like this:

(in B's working dir):
cvs update -j branchA_CREATED -j 3

(3 == where A merges to B) then you are correct. This merge will be 
missing changes from between the start of B and A - ALREADY! In other 
words, with respect to B, part of A was left out, since it was created 
before "branchA_CREATED" - on the trunk. But I think this is really the 
"wrong way" to merge A into B.

The "right" way is to do it would be to say:

cvs update -j branchB_CREATED -j 3

Then branch B does indeed end up incorporating "everything" from branch A. 
In other words, the changes on the trunk after B was created until A 
starts, and then all then all the changes in A. So when doing that kind of 
merge, always use the newest common ancestor (in this case, the start of 

Now let's look at your other scenario. When A is created before B, 
everything else being equal, I did not receive spurious conflicts doing 
that last merge in a single step (2-4, Jamie's way) after all! You say 
there should be, because that I am "remerging changes made to the trunk 
between the base of A and the base of B." But I can't see where the 
redundancy should come from. 

The changes between the start of A and the start of B are not in A, and 
they are inherent in B.

So goes my theory. Perhaps we are making different assumptions?

> |>The only clean way to do this in the general case is to tag branch B
> |>before and after your merge from A at point 3 and merge B back into 
> |>trunk as two merges:
> |>
> |>~    cvs up -j 1 -j pre-3
> |>~    cvs up -j post-3 -j 4
> Oops, yes, you are correct.  What I said was correct if point 2 & 3 were
> the same (at point 2 all of branch A was merge to both the trunk and
> branch B).  A clean merge to the trunk without conflicts from a repeated
> merge with distinct points 2 & 3 would require the two commands I listed
> above and a third merge:
> ~    cvs up -j 2 -j 3

So if I understand you all correctly, a generalized merge formula would 

cvs update -j start-of-branchB -j pre-3'
cvs update -j 2 -j 3
cvs update -j post-3' -j 4

in that order?

What if branchB had made changes that would conflict with branchA's 
changes, and the merge from A to B is to correct that conflict and bring B 
into sync _before_ it merges with the trunk?

Following this pattern, I will still get that conflict between B and the 
trunk on the first command - even though those conflicts had already been 
resolved "post-3'". Nothing subsequent would work without manually 
duplicating the conflict resolution already present in B...

reply via email to

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