A Collabnet customer (using 1.6.6) is having a problem where they follow the
standard reintegrate procedure (i.e. sync merge all available revisions from
trunk to branchX then reintegrate branchX back to trunk) but they get an error
stating the prior sync merge was not complete, e.g.:
>svn merge ^^/branches/branch02 trunk --reintegrate
svn: Reintegrate can only be used if revisions 160 through 180 were
previously merged from %ROOT_URL%/trunk to the reintegrate source, but
this is not the case:
branches/branch02/www/index.html
Missing ranges: /trunk/www/index.html:160-170
...but of course they *just* did the sync merge. Further, the "missing" sync
ranges (e.g. r160-170) are inoperative on the specified subtree.
They demonstrated for me the failed reintegrate merge and a subsequent re-sync
from trunk to the branch; after which the reintegrate merge still failed. They
were working around the situation by doing subtree merges for the missing
revisions (which were inoperative except for the fact that the set mergeinfo on
the subtree describing the merge).
This workaround is extremely cumbersome for them because unlike the example
above, their failed reintegrates feature 10's of subtrees with "missing" sync
ranges. This reintegrate failure also happens quite frequently on many of their
branches. Needless to say, they are justifiably unhappy.
The customer was doing several things merge-wise that seemed to contribute to
the problem:
1) They delete their feature branches once they are reintegrated
and then recreate new feature branches reusing the same name
as the old branch for subsequent feature work.
2) They do subtree merges (mostly at the file level) and so have
lots of subtree mergeinfo.
3) They do cyclic cherry pick merges from branches back to trunk.
Neither the customer nor myself could come up with a simple reproduction recipe.
It wasn't immediately obvious what was wrong beyond the fact that the sync
merge was not recording itself fully on all the subtrees.
Now I know what you are thinking, "1.5.x-1.6.x always records mergeinfo on every
subtree right?" Yes, that is one of the things people hate about merge tracking
and I worked to fix in 1.7: http://svn.haxx.se/dev/archive-2009-08/0045.shtml
Not so fast...
...Then it all came back to me, a bit of code I removed from
libsvn_client/merge.c:get_mergeinfo_walk_cb() while working on the
subtree-mergeinfo branch might be the culprit:
http://svn.apache.org/viewvc?view=revision&revision=876855.
That bit of code, dating back to the dawn of merge tracking, ignored subtrees
with explcit mergeinfo in the merge target if:
A) The explicit mergeinfo didn't naively match the merge source
(e.g. if you are merging from /trunk to /branch/01 and
/branch/01/www/index.html has mergeinfo, but that mergeinfo
doesn't have /trunk/www/index.html:* among its merge sources).
and
B) The path in the source corresponding to the target doesn't
exist at the start of the requested merge (e.g. continuing
the above example, if we are merging -r100:200 from /trunk,
then if /trunk/www/index.html doesn't exist at r100 then
/branches/01/www/index.html's mergeinfo is ignored).
I sent the customer a patch against 1.6.x@951045 with no functional changes, but
with some printfs producing output when subtrees were added/dropped from
consideration by the merge-tracking logic. Sure enough, dozens of subtrees met
criteria A and B above and were being dropped from consideration during the sync
merge and thus never had their mergeinfo updated and caused the subsequent
reintegrate to fail.
I merged r876855 ^/subversion/branches/subtree-mergeinfo@876855 into
1.6.x@951045 and sent the resulting patch to the customer to build. Trying the
sync merge/reintegrate combo again, the reintegrate failed, but this time only
one subtree was reported as unsynced (this appears to be be a completely
different issue).
I still wanted to come up with a reproduction recipe. That proved a *bit*
challenging, but I finally have a test that reproduces the problem. Committing
that shortly.