Paul Burba wrote on 27 March 2012:
> Julian Foad wrote:
>>  The check for switched subtrees:  I think we should enable this by default.
>> 
>>  I suppose the issue here must be that we don't have a compelling use 
>> case for supporting such a merge, and so we haven't defined and don't 
>> want to spend the effort of trying to define what such a merge should
>> mean.  We  can explain what the merge code *does* in such a case, we
>> just can't give a  requirements-based reason for *why* it does what it
>> does.  Paul or anyone,  please enlighten me if that's not the case.
> 
> There are two "whys" to consider here:
> 
> First, "why" does a user merge into a WC with switched subtrees?  On
> that I agree with you, I've never seen a compelling case is.  The few
> users I've come across who did it usually did so by mistake or were
> merging changes that they knew would not touch the switched subtree.

OK; nor me.  (I can see it could sometimes be convenient to merge into a WC 
with switched subtrees when the user knows that the merge will not touch the 
switched subtrees, but even so, that doesn't necessarily mean it's a good idea.)

> Regardless of why users do it, they do it and it was something we
> allowed merge to do pre-1.5 (i.e. pre-mergetracking), so I tried to
> support it.
> 
> Second: Why does the merge code do what it does when faced with a
> switched subtree.  I'm guessing you see this "what" the code does, 
> but
> that makes it sound as if the current behavior is somehow arbitrary.

Sorry, I did indeed imply it may be a bit unfounded, as I felt I had no point 
of reference for the "why".  But I agree it makes sense to behave as you 
described below...

> The "why" of the current behavior is tied to the fact that by default
> svn:mergeinfo is inheritable.  [...]:
> 
>    WC-Root('/SRC:N')
>       |
>      SSP('/SRC:N*')
>       | \
>       |  \
>       |   SSS('/SRC:N')
>       |
>      SS('/SRC:N')
> 
> a) Non-inheritable mergeinfo is recorded on the parent [...]
> 
> b) Normal inheritable mergeinfo is recorded on the root [...]
> 
> c) Normal inheritable mergeinfo is recorded on siblings [...]
> 
> d) If the WC-Root isn't the parent [it gets normal mergeinfo ...]
[...]
> [1] There are other reasons a subtree might be missing [...]
> mergetracking behavior and reasoning for this behavior is the same in
> all these cases, though a bit simpler in the non-switched cases
> because the subtree is really missing and not "replaced" by something
> else.

This description would make a superior replacement for the
 first two bullet points of 
<http://svn.apache.org/repos/asf/subversion/trunk/notes/merge-tracking/func-spec.html#switched-paths>,
 would it not?

There is an implied logic for the question "Why behave like this?" that seems 
pretty intuitive; let's see if I can actually capture it in words:

[[[
  If a subtree (SS) is switched, that means the user has chosen for
  the time being to work with a substitute for the original subtree
  (SS@BASE), knowing that any modifications made in SS can be
  committed only to the repository location of SS and the original
  subtree SS@BASE remains hidden and unaffected.

  The general semantics of a merge is to apply local modifications
  to the working copy and record the merge as having been applied
  to the tree that is represented by the working copy.

  Merge tracking should ensure that the subtree of the merge that
  goes into SS is recorded as being applied to SS, while the
  subtree SS@BASE should be recorded as not having received that
  merge.

  Since the working copy represents parts of two different branches,
  two parts of the merge are thus applied to the two different
  branches, and recorded as such when the user commits the result.

  If the user is doing a merge that may affect SS, it is reasonable
  to assume that SS is an alternative variant of SS@BASE rather than
  some totally unrelated item.  So, in terms of Subversion's loose
  branching semantics, SS is a 'branch' of SS@BASE.  If the user
  chooses to merge when the assumption is false and SS doesn't have
  a sensible branching relationship with SS@BASE, the result will be
  nonsensical or, in concrete terms, there will be merge conflicts.

  Note:  Many typical branching policies would forbid committing to
  two branches at once, let alone committing merges to two branches
  at once.  However, the user may have reasons for doing this merge
  without intending to commit the result as-is.
]]]


Your description cover cases where the merge may or may not affect the inside 
of the subtree.  One case not made explicit is where the merge deletes the 
switched subtree.  Would the rule there be:

   * If the incoming change deletes the path SS, then it is interpreted as 
deleting the entry SS from SSP's list of children.  Therefore SS is removed 
from the WC, and so is no longer a switched path, and the mergeinfo change can 
be recorded normally on SSP without any need for non-inheritable or subtree 
mergeinfo.  And as for the repository path that SS represented while it was 
still switched, we do not want to record any mergeinfo change on that path at 
all (nor on that path's repository-parent path, nor anything to do with it).

?

- Julian

Reply via email to