The changes made to 1.7 to stop updating subtree mergeinfo when a given subtree
was unaffected by the merge (ss
http://svn.haxx.se/dev/archive-2009-08/0045.shtml and
http://svn.apache.org/viewvc?view=revision&revision=878767) have an unintended
side-effect: When doing merges at operational depth=immediates, the mergeinfo
recorded to describe the merge is incorrect.
For example, say we have this simple repos:
trunk@947072>svn log -v -r1:HEAD ^^/
------------------------------------------------------------------------
r1 | jrandom | 2010-05-21 15:26:18 -0400 (Fri, 21 May 2010) | 1 line
Changed paths:
A /A
A /A/B
A /A/B/E
A /A/B/E/alpha
A /A/B/E/beta
A /A/B/F
A /A/B/lambda
A /A/C
A /A/D
A /A/D/G
A /A/D/G/pi
A /A/D/G/rho
A /A/D/G/tau
A /A/D/H
A /A/D/H/chi
A /A/D/H/omega
A /A/D/H/psi
A /A/D/gamma
A /A/mu
A /iota
Log message for revision 1.
------------------------------------------------------------------------
r2 | jrandom | 2010-05-21 15:26:20 -0400 (Fri, 21 May 2010) | 1 line
Changed paths:
A /A_COPY (from /A:1)
log msg
------------------------------------------------------------------------
r3 | jrandom | 2010-05-21 15:26:21 -0400 (Fri, 21 May 2010) | 1 line
Changed paths:
A /A/B/E/newfile
M /A/B/lambda
log msg
------------------------------------------------------------------------
Our WC is the entire repos@3 at depth=infinity (i.e. nothing is missing):
trunk@947072>svn st -v
3 3 jrandom .
3 3 jrandom A
3 1 jrandom A\mu
3 3 jrandom A\B
3 3 jrandom A\B\lambda
3 3 jrandom A\B\E
3 1 jrandom A\B\E\alpha
3 3 jrandom A\B\E\newfile
3 1 jrandom A\B\E\beta
3 1 jrandom A\B\F
3 1 jrandom A\C
3 1 jrandom A\D
3 1 jrandom A\D\gamma
3 1 jrandom A\D\G
3 1 jrandom A\D\G\rho
3 1 jrandom A\D\G\pi
3 1 jrandom A\D\G\tau
3 1 jrandom A\D\H
3 1 jrandom A\D\H\chi
3 1 jrandom A\D\H\omega
3 1 jrandom A\D\H\psi
3 2 jrandom A_COPY
3 2 jrandom A_COPY\mu
3 2 jrandom A_COPY\B
3 2 jrandom A_COPY\B\lambda
3 2 jrandom A_COPY\B\E
3 2 jrandom A_COPY\B\E\alpha
3 2 jrandom A_COPY\B\E\beta
3 2 jrandom A_COPY\B\F
3 2 jrandom A_COPY\C
3 2 jrandom A_COPY\D
3 2 jrandom A_COPY\D\gamma
3 2 jrandom A_COPY\D\G
3 2 jrandom A_COPY\D\G\rho
3 2 jrandom A_COPY\D\G\pi
3 2 jrandom A_COPY\D\G\tau
3 2 jrandom A_COPY\D\H
3 2 jrandom A_COPY\D\H\chi
3 2 jrandom A_COPY\D\H\omega
3 2 jrandom A_COPY\D\H\psi
3 1 jrandom iota
There is no explicit mergeinfo:
trunk@947072>svn pg svn:mergeinfo -vR
Now we merge r3 from A to A_COPY at operational depth immediates:
trunk@947072>svn merge ^^/A/B A_COPY/B -c3 --depth immediates
--- Merging r3 into 'A_COPY\B':
U A_COPY\B\lambda
--- Recording mergeinfo for merge of r3 into 'A_COPY\B':
U A_COPY\B
That looks about right, we only expect immediate children of the merge target to
be affected, and that is what we get:
trunk@947072>svn st
M A_COPY\B
M A_COPY\B\lambda
But, the mergeinfo recorded makes it appear that r3 was fully merged into A_COPY:
trunk@947072>svn pg svn:mergeinfo -vR
Properties on 'A_COPY\B':
svn:mergeinfo
/A/B:3
Obviously this isn't the case, because A_COPY/B/E/newfile was not added. This
mergeinfo prevents a repeat merge-tracking aware merge from ever being able to
get the rest of r3 merged into A_COPY:
trunk@947072>svn merge ^^/A/B A_COPY/B -c3 --depth infinity
--- Recording mergeinfo for merge of r3 into 'A_COPY\B':
G A_COPY\B
Prior to r878767 the merge would have recorded non-inheritable mergeinfo on all
of the merge target's immediate directory children:
pre-r878767-client>svn pg svn:mergeinfo -vR
Properties on 'A_COPY\B\E':
svn:mergeinfo
/A/B/E:3*
Properties on 'A_COPY\B\F':
svn:mergeinfo
/A/B/F:3*
Properties on 'A_COPY\B':
svn:mergeinfo
/A/B:3
This is certainly accurate, because now it is clear that r3 hasn't been merged
under A_COPY/B/[E|F]. But the fact that we set mergeinfo on A_COPY/B/F, which
is unaffected by r3, doesn't fit with the post-r878767 behavior of not updating
subtree mergeinfo unaffected by the merge.
What is happening on trunk is that the subtree-mergeinfo logic sees that
A_COPY/B/E and A_COPY/B/F were unaffected by the merge, so it doesn't set any
mergeinfo on them. If A_COPY/B/E and A_COPY/B/F had explicit mergeinfo prior to
the merge, then this wouldn't be a problem, since that mergeinfo would override
the mergeinfo set on A_COPY/B.
Ideally we would have this mergeinfo after the merge (Nothing on A_COPY/B/F, it
could safely inherit r3 from A_COPY\B since that rev is inoperative on F):
Properties on 'A_COPY\B':
svn:mergeinfo
/A/B:3
Properties on 'A_COPY\B\E':
svn:mergeinfo
/A/B/E:3*