Re: Implicit keep-alive after reintegrate merge
From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Wed, 11 Jan 2012 12:43:11 +0000 (GMT)
Hi Paul. Thanks for your thoughts.
Paul Burba wrote:
> Julian Foad wrote:
Actually, I don't think we need to be concerned about the "mixture of merges and new changes" scenario, and here's why. As we know, merging is not a deterministic operation, and requires user input in general . When the user does a merge and commits the resulting working copy, the result is tracked as a merge. There's no conceptual way Subversion could distinguish the two kinds of change without the user telling it. The way to tell Subversion about two separate changes is by putting them in two separate revisions .
So, "Don't commit new changes with a merge" is a rule we have to embrace if we want to make progress in defining more useful merge behaviour. Or rather the rule is a bit softer: "You shouldn't commit new changes with a merge, because Subversion won't track the new changes separately but will assume they are part of the merge conflict resolution."
In fact the only cases in which Subversion's behaviour will actually be affected by this rule are multi-path or cyclic merges, that is the cases where we want to avoid merging a change to a branch that already has "it".
The only form of cyclic merge we've supported up till now has been the reintegrate merge, and that is a special case because it is limited to cases where it doesn't need to track individual changes, it simply compares at the entire states of the two branches. The effect is that it doesn't matter whether the user included new changes along with any merges into the source (child) branch.
In a multi-path merge, such as the third step of A->B, A->C, B->C, we don't yet support automatically skipping any changes coming via B that have already been merged directly from A to C. Subversion will still try to merge that whole change from B to C, and the already-merged part of it will conflict (logically if not physically). The user's options are to avoid merging that specific revision from B to C (perhaps by record-only merging it), or to deal with that conflict. If a new change had been committed along with that A->B merge, neither option successfully merges that new change to C.
So the reintegrate merge doesn't care if you have mixed a merge with a new change, and for the multi-path scenario the user already needs to keep merges separate from new changes.
Now, what about the case I'm addressing? That is, the sync merge into a branch that has already been reintegrated. If the user wants to carry on using the branch in this way, up till now it has been the user's responsibility to tell Subversion to ignore the reintegrate merge commit, by the record-only merge known as the "keep-alive dance". If there had been a new change mixed up with that reintegration, the user would be telling Subversion to ignore it. So here again we already had the rule that you have to keep new changes separate.
 Of course we have automatic text merge tools which give the user a good guess at a likely
 I don't believe it would be productive to invent a mechanism for
>> We need to look more closely. That's what I'm currently working on.
There are two potential kinds of "other" changes. New changes mixed in with the merge are against the rules, as explained above. Other merges mixed in with that merge are, I think, legitimate.
If we can calculate that r40 contains nothing but changes merged directly from branch B, then the Right Thing is to skip it. If it contains other changes (or if we can't determine for sure), then we can tell the user what's happening (that it would be wrong to try to merge this change because it contains "...") and we can either skip it or stop the merge.
My contention is that that would be better than what we do today. Note that what we do today is unconditionally *attempt* to merge r40 even though (with my new code) we could know for sure that it will conflict logically (and will probably but not necessarily conflict physically).
Another way of looking at it is that when we merge a revision that will logically conflict with the target, today the default action is to attempt to merge it anyway, and my proposed action is to tell the user what's happening and allow them to take corrective action in advance. The user could choose a different merge source, or perhaps realize that they were trying to merge into the wrong target branch, or something else.
Does that make sense?
This is an archived mail posted to the Subversion Dev mailing list.