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


Reply via email to