On Tue, Jul 17, 2012 at 1:28 PM, Julian Foad <[email protected]> wrote:
> There are some merge scenarios for which it's not clear whether the user
> should specify '--reintegrate' or not. We need to decide what the
> 'symmetric' (i.e. automatically-choosing) code should do in those cases.
>
> The following example is adapted from merge_symmetric_tests.py 18,
> subtree_to_and_fro(), "reintegrate considers source subtree mergeinfo":
>
> reintegrate 'everything'
> |
> A ------o-s--------------x
> \ \ /
> \ \ /
> B o-----s----s----s---
> |
> merge the subtree 'D' only
What does 's' represent in this diagram? In
merge_symmetric_tests.py's key 's' represents 'a subtree merge', but
that's not the case here, AFAICT.
> In terms of commands (assume a commit after each step):
>
> svn cp A B
> edit A
> edit A/D
> edit B/D svn merge ^/A/D B/D
> edit B/D
> svn merge --reintegrate ^/B A
>
> The output from "merge --reintegrate" is:
>
> svn: E195016: Reintegrate can only be used if
> revisions 2 through 8 were previously merged [...]
>
> But why did the user choose a 'reintegrate' merge in this example, when there
> has been no merge of the branch root in the A->B direction?
No, but we could easily have had such a merge,
reintegrate 'everything'
|
A -----o----o------------x
\ \ \ /
\ \ \ /
B o----x-----s----s---
| |
| merge the subtree 'D' only
|
merge 'everything'
and still be facing the same problem.
> Or, from another angle, what if we have this similar scenario?
>
> merge 'everything'
> |
> A o-o-s--------------x
> / \ /
> / \ /
> B ----------s----s----s---
>
> Given this example, it looks like a non-reintegrate merge might be the user's
> choice for the final merge (and for the intermediate merge... either a
> reintegrate or non-reintegrate); but all that's changed in this example is
> which branch was branched from which, and that shouldn't make any difference.
> AFAIK we don't document a rule for whether '--reintegrate' should be used;
> it's ambiguous.
>
> We have three possible results when we request a merge:
>
> (1) a correct merge
> (2) a wrong merge, with spurious conflicts
> (3) bail out
>
> Currently, 'merge' gives (2), 'merge --reintegrate' gives (3), and 'merge
> --symmetric' gives (2).
>
> The subtree_to_and_fro() test expects 'merge --symmetric' to give result (3),
> but the symmetric merge currently sees that case as one in which a
> *non-reintegrate* merge is needed, and goes ahead to produce a merged result
> (with a conflict):
>
> --- Merging r2 through r8 into 'A':
> U A/D/gamma
> C A/D/H/psi
> [...]
>
> Is the symmetric merge 'broken'? This test claims so, on the basis of
> expecting it to behave like a reintegrate merge. However, we can't be
> strictly backward-compatible with both the reintegrate and the
> non-reintegrate behaviours if we have to pick one, because they differ. What
> do we want to see here?
>
> I think it depends what the user is thinking. If the user is thinking "just
> help me merge everything that needs to be merged", then the user probably
> would have used the plain 'merge' command in 1.7, and would prefer a wrong
> merge with spurious conflicts, given that we haven't yet implemented a
> correct merge. If the user is thinking "this is a reintegration, and I
> believe my branch was sync'd with the trunk recently", then the user probably
> would prefer this merge to bail out like 'reintegrate' does.
>
> It almost goes without saying that if and when we have implemented a correct
> merge then that is the right thing to do, and that will resolve the
> ambiguity. (When we do that, there is still the possibility of giving the
> user an option to make Subversion detect and report whether the required
> merge has anything complex about it -- subtrees, cherry-picked revisions, and
> so on -- because the user might want the mental security of confirming that
> in fact the merge is as simple as the user expects it to be. But that is
> another topic.)
>
> Our options for what 'symmetric' merge will do, in cases like this [1], are:
>
> (1) Implement correct merging.
> (2) Merge wrongly, with spurious conflicts, like plain 1.7 'merge'.
> (2a) (2) by default, with an option to check and bail out like (3).
> (3) Bail out like 1.7 'reintegrate'.
> (3a) (3) by default, with an option to force the merge to proceed like (2).
>
> If we choose (2), then we break strict compatibility with 1.7 'reintegrate'
> merge. If we choose (3), then we break strict compatibility with 1.7
> 'non-reintegrate' merge.
>
> I'd like to do (1), but, in the meantime, would we be happy with one of the
> alternatives?
#1 would be awesome :-) but in the meantime...
I take your points about user intent but if the symmetric merge code
is meant to do away with the --reintegrate option, I think we should
take the more cautious approach and assume the user intends a
reintegrate, so IMO (3a) is the best choice.
--
Paul T. Burba
CollabNet, Inc. -- www.collab.net -- Enterprise Cloud Development
Skype: ptburba
> - Julian
>
>
> [1] At the moment, 'cases like this' means cases where the specified merge
> root node was last merged in the same direction as the current merge, or was
> never merged before. That is, the symmetric merge code chooses whether to do
> a reintegrate style of merge or a non-reintegrate style of merge based on the
> direction of this merge relative to the direction of the last merge of the
> specified root node, not based on any merges that may have been done to
> subtrees. That does NOT mean it doesn't handle subtrees; it handles them
> just the same as
> 1.7 (reintegrate or plain) merge does. It just means subtrees don't affect
> the decision of which style of merge it uses.
>
>
> --
> Certified & Supported Apache Subversion Downloads:
> http://www.wandisco.com/subversion/download