Merges to targets with non-inheritable ranges, or subtrees with the same, don't
work if the merge source and range being applied intersect with the
non-inheritable mergeinfo.
For example, say we merged to a target with switched subtrees and ended up with
a slew of non-inheritable mergeinfo, something like this (from merge_tests.py 50):
>svn st -v A_COPY
8 2 jrandom A_COPY
8 2 jrandom A_COPY\B
8 2 jrandom A_COPY\B\lambda
8 2 jrandom A_COPY\B\E
8 2 jrandom A_COPY\B\E\alpha
8 2 jrandom A_COPY\B\E\beta
8 2 jrandom A_COPY\B\F
8 2 jrandom A_COPY\mu
8 2 jrandom A_COPY\C
8 2 jrandom A_COPY\D
8 2 jrandom A_COPY\D\gamma
S 8 2 jrandom A_COPY\D\G
8 2 jrandom A_COPY\D\G\pi
S 8 2 jrandom A_COPY\D\G\rho
8 2 jrandom A_COPY\D\G\tau
8 2 jrandom A_COPY\D\H
8 2 jrandom A_COPY\D\H\chi
8 2 jrandom A_COPY\D\H\omega
S 8 2 jrandom A_COPY\D\H\psi
# No mergeinfo yet:
>svn pl -vR A_COPY
# Cherry harvest:
>svn merge %url50%/A A_COPY
--- Merging r3 through r8 into 'A_COPY\D\G':
U A_COPY\D\G\rho
--- Merging r2 through r8 into 'A_COPY\D\H':
U A_COPY\D\H\psi
U A_COPY\D\H\omega
--- Merging r2 through r8 into 'A_COPY':
U A_COPY\B\E\beta
# Each switched path and it's siblings get explicit mergeinfo
# describing the merge. The parent of each switched path
# gets the same but with non-inheritable mergeinfo:
>svn pl -vR A_COPY
Properties on 'A_COPY':
svn:mergeinfo : /A:2-8
Properties on 'A_COPY\D':
svn:mergeinfo : /A/D:2-8*
Properties on 'A_COPY\D\gamma':
svn:mergeinfo : /A/D/gamma:2-8
Properties on 'A_COPY\D\G':
svn:mergeinfo : /A/D/G:2-8*
Properties on 'A_COPY\D\G\pi':
svn:mergeinfo : /A/D/G/pi:2-8
Properties on 'A_COPY\D\G\rho':
svn:mergeinfo : /A/D/G/rho:2-8
Properties on 'A_COPY\D\G\tau':
svn:mergeinfo : /A/D/G/tau:2-8
Properties on 'A_COPY\D\H':
svn:mergeinfo : /A/D/H:2-8*
Properties on 'A_COPY\D\H\chi':
svn:mergeinfo : /A/D/H/chi:2-8
Properties on 'A_COPY\D\H\omega':
svn:mergeinfo : /A/D/H/omega:2-8
Properties on 'A_COPY\D\H\psi':
svn:mergeinfo : /A/D/H/psi:2-8
>svn ci -m ""
Sending A_COPY
Sending A_COPY\B\E\beta
Sending A_COPY\D
Sending A_COPY\D\H
Sending A_COPY\D\H\chi
Sending A_COPY\D\H\omega
Sending A_COPY\D\gamma
Sending A_COPY\D\G
Sending A_COPY\D\G\pi
Sending A_COPY\D\G\tau
Sending A_COPY\D\H\psi
Sending A_COPY\D\G\rho
Transmitting file data ....
Committed revision 9.
# Update before going on so no surprises with
# inheritance or elision:
>svn up
U A_COPY_2\D\G\pi
U A_COPY_2\D\G\tau
U A_COPY_2\D\G
UU A_COPY_2\D\H\psi
UU A_COPY_3\D\G\rho
Updated to revision 9.
# Let's say we don't like all that explicit subtree
# mergeinfo and want to revert the whole mess. If
# we reverse merge r8:1 that should get rid of *all*
# the explicit mergeinfo on A_COPY. It doesn't even
# reverse merge everything, let alone set the
# correct mergeinfo:
>svn merge %url50%/A A_COPY -r8:1
--- Reverse-merging r8 through r2 into 'A_COPY':
U A_COPY\B\E\beta
>svn st A_COPY
M A_COPY
M A_COPY\B\E\beta
M A_COPY\D
M A_COPY\D\gamma
M S A_COPY\D\G
M A_COPY\D\G\pi
M S A_COPY\D\G\rho
M A_COPY\D\G\tau
M A_COPY\D\H
M A_COPY\D\H\chi
M A_COPY\D\H\omega
M S A_COPY\D\H\psi
# Only beta is reverse-merged!?!? Paths either switched or
# in a switched subtree, rho, omega, and psi, are not reverse
# merged. Worse, the mergeinfo set looks like the full
# reverse merge did occur, but we end up with empty mergeinfo
# on the three switched paths:
>svn pl -vR A_COPY
Properties on 'A_COPY\D\G':
svn:mergeinfo :
Properties on 'A_COPY\D\G\rho':
svn:mergeinfo :
Properties on 'A_COPY\D\H\psi':
svn:mergeinfo :
This empty mergeinfo isn't overriding anything and really should elide. This is
because of the way we limit elision within sections of a subtree: Merge target T
has subtree S1 has subtree S2. We try to elide S1 to T, then S2 to S1 if it
still exists or T otherwise. Then finally T to the repos. But if S2 is
switched it can't elide up the WC so nothing happens. We probably need to make
an exception for switched subtrees and attempt to elide them right to the repos
as they are completely unrelated to the larger tree in terms of mergeinfo
inheritance and elision. If we don't, we can get these cases where we merge a
range, reverse merge the same range, but end up in a different state than we
started.
Note: This whole thing has me wondering if this restricted elision is even
necessary now, I'll look into that after this issue is fixed, I'm *certain*
there was a reason for this, but now I just don't see it...at any rate, it needs
to be documented in the code or removed.