Hello,
In this letter I would like to describe some case I've encountered into. I have
a repository (dump)
attached. I checkout trunk and merge branch (simply "svn merge
file:///..../branches/branch") and
* with svn 1.6 I get "Target path '/branches/branch' does not exist",
* with svn 1.7 everything works fine.
The repository has the following history (of trunk and branch)
file
-----------------------x[5] [6]--------------
/ -----------------/ \
/ / \
[1]----[2]----[3]----[4]------------------[7]----[8]--?
+file -file +file
And at r8 of trunk file "/trunk/file" contains some svn:mergeinfo (actually
it's value doesn't matter,
it just should not include revisions [4,7] of the branch --- it should be just
to turn on the merge
tracking on that file) and "/trunk" also contains svn:mergeinfo.
Properties on '.':
svn:mergeinfo
/branches/branch:6-7
Properties on 'file':
svn:mergeinfo
/branches/branch/file:3
After some investigation for svn 1.6 I've found that the following code is
executed:
function "adjust_deleted_subtree_ranges" in libsvn_client/merge.c:
/* PRIMARY_URL@older_rev exists, so it was deleted at some
revision prior to peg_rev, find that revision. */
SVN_ERR(svn_ra_get_deleted_rev(ra_session, rel_source_path,
older_rev, younger_rev,
&revision_primary_url_deleted,
subpool));
older_rev=3 /* for svn_ra_get_deleted_rev this parameter should play role of
peg revision */
younger_rev=8
rel_source_path="file"
ra_session's url is "file:///..../branches/branch"
For that history this call is absolutely senseless because
file:///..../branches/branch@3 is
absolutely different branch than file:///..../branches/branch@HEAD which we
merge.
Moreover, file:///..../branches/branch@HEAD never contained "file" at all since
creation at r6.
As result "adjust_deleted_subtree_ranges" function leaves "4,8" value in
child->remaining_ranges,
and "diff" request fails.
Why svn 1.7 works fine?
"adjust_deleted_subtree_ranges" is called only from
"fix_deleted_subtree_ranges", and in svn 1.7 (but
no in svn 1.6) before "fix_deleted_subtree_ranges" invocation another method is
invoked:
/* Remove inoperative ranges from any subtrees' remaining_ranges
to spare the expense of noop editor drives. */
if (!is_rollback)
SVN_ERR(remove_noop_subtree_ranges(url1, revision1, url2, revision2,
ra_session,
notify_b, merge_b,
scratch_pool, iterpool));
/* Adjust subtrees' remaining_ranges to deal with issue #3067 */
SVN_ERR(fix_deleted_subtree_ranges(url1, revision1, url2, revision2,
ra_session, notify_b, merge_b,
scratch_pool, iterpool));
And this changes everything. "remove_noop_subtree_ranges" has simple logic:
1. Get log for URL@rev we merge (file:///..../branches/branch@HEAD) to form 2
lists: revisions that
actually have changes (operative_ranges), and revisions that have changes but
already merged
(merged_ranges). In my case operative_ranges=merged_ranges={[6,6]}
2. Create a range that shouldn't be merged [oldest_gap_rev, youngest_gap_rev].
In my case [3,8]
3. Exclude from it operative_ranges. In my case now it contains [3,5], [7,8].
4. Include into it merged_ranges. So now we have the list of all revisions that
shouldn't be
considered. In my case now it contains [3,8] again.
5. Remove all these revisions from child->remaining_ranges. For my case
child->remaining_ranges is
empty.
This optimization ("remove_noop_subtree_ranges") actually looks like a very
reasonable filter and
prevents this bug. The only thing that looks suspicious --- "if
(!is_rollback)" condition... I
didn't test but maybe with is_rollback=TRUE the problem can appear again.
Actually when I try to think how to replace "svn_ra_get_deleted_rev" with
something working I also
find that "log" should be called on URL@rev we merge and changed paths should
be analyzed.
As a conclusion:
Maybe the best one can do for svn 1.6 --- just add "remove_noop_subtree_ranges"
method from svn 1.7
and leave everything as is. For trunk maybe it's better to add some assertions
that
"remove_noop_subtree_ranges" has solved all problems instead of
"svn_ra_get_deleted_rev" (that
could be expected to be an unreachable code --- though here I'm not sure) and
to consider the case
is_rollback=FALSE.
I have a similar issue in SVNKit
http://issues.tmatesoft.com/issue/SVNKIT-305?projectKey=SVNKIT
Sorry for bothering if 1.6 bugs are not interesting or if you already know
about this bug.
--
Dmitry Pavlenko,
TMate Software,
http://subgit.com/ - git+svn on the server side
SVN-fs-dump-format-version: 2
UUID: 89316b2b-3901-0010-999b-a377ac2b9718
Revision-number: 0
Prop-content-length: 56
Content-length: 56
K 8
svn:date
V 27
2012-08-15T17:53:28.973000Z
PROPS-END
Revision-number: 1
Prop-content-length: 73
Content-length: 73
K 8
svn:date
V 27
2012-08-15T17:53:29.525000Z
K 7
svn:log
V 0
PROPS-END
Node-path: trunk
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
PROPS-END
Node-path: trunk/file
Node-kind: file
Node-action: add
Prop-content-length: 10
Text-content-length: 0
Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
Text-content-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
Content-length: 10
PROPS-END
Revision-number: 2
Prop-content-length: 73
Content-length: 73
K 8
svn:date
V 27
2012-08-15T17:53:29.633000Z
K 7
svn:log
V 0
PROPS-END
Node-path: trunk/file
Node-action: delete
Revision-number: 3
Prop-content-length: 73
Content-length: 73
K 8
svn:date
V 27
2012-08-15T17:53:29.674000Z
K 7
svn:log
V 0
PROPS-END
Node-path: branches
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
PROPS-END
Node-path: branches/branch
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 1
Node-copyfrom-path: trunk
Revision-number: 4
Prop-content-length: 73
Content-length: 73
K 8
svn:date
V 27
2012-08-15T17:53:29.722000Z
K 7
svn:log
V 0
PROPS-END
Revision-number: 5
Prop-content-length: 73
Content-length: 73
K 8
svn:date
V 27
2012-08-15T17:53:29.746000Z
K 7
svn:log
V 0
PROPS-END
Node-path: branches/branch
Node-action: delete
Revision-number: 6
Prop-content-length: 73
Content-length: 73
K 7
svn:log
V 0
K 8
svn:date
V 27
2012-08-15T17:53:29.791000Z
PROPS-END
Node-path: branches/branch
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 3
Node-copyfrom-path: trunk
Revision-number: 7
Prop-content-length: 73
Content-length: 73
K 8
svn:date
V 27
2012-08-15T17:53:29.846000Z
K 7
svn:log
V 0
PROPS-END
Node-path: trunk/file
Node-kind: file
Node-action: add
Node-copyfrom-rev: 1
Node-copyfrom-path: trunk/file
Text-copy-source-md5: d41d8cd98f00b204e9800998ecf8427e
Text-copy-source-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
Revision-number: 8
Prop-content-length: 100
Content-length: 100
K 7
svn:log
V 0
K 10
svn:author
V 6
dmit10
K 8
svn:date
V 27
2012-08-15T17:53:31.227000Z
PROPS-END
Node-path: trunk
Node-kind: dir
Node-action: change
Prop-content-length: 55
Content-length: 55
K 13
svn:mergeinfo
V 20
/branches/branch:6-7
PROPS-END
Node-path: trunk/file
Node-kind: file
Node-action: change
Prop-content-length: 58
Content-length: 58
K 13
svn:mergeinfo
V 23
/branches/branch/file:3
PROPS-END