You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Nik Clayton <ni...@ngo.org.uk> on 2006/01/28 10:07:50 UTC

Differences between WC->WC copy, URL->URL copy, and $dirent->created_rev()

[ Originally sent to users@, members of #svn-dev suggested I send it here. ]

Hello,

I'm not (yet) subscribed to this list -- I'd be grateful for a cc: on any
replies.

I've run in to an anomaly in the way SVN handles copies when they're WC ->
WC copies compared to when they're URL -> URL copies.  This might be an
actual problem, or it might be down to a lack of understanding of the API on
my part.

I'm looking at converting an application that currently uses SVN::Repos (and
therefore has to run on the same host that holds the repository files) to
use SVN::Ra.  FWIW, the app is SVN::Web.

One of the things the app needs to do is, given a repo, a filename, and
optionally a revision number, find the most recent interesting revision of
the file.

With SVN::Repos I do this:

     my $path = '/path/in/repo';
     my $fs   = $repo->fs();               # $repo is an opened repo
     my $rev  = $fs->youngest_rev();
     my $root = $fs->revision_root($rev);
     my $hist = $root->node_history($path);
     my $irev;                             # interesting revision

     $hist = $hist->prev(0);
     $irev = ($hist->location())[1];       # 2nd item returned by location()

With SVN::Ra I was trying this approach.

     my $path = '/path/in/repo';
     my $rev  = $ra->get_latest_revnum(); # $ra is an SVN::Ra object
     my $ent  = $ra->stat($path, $rev);
     my $irev;

     $irev = $ent->created_rev();

Which seems to work in most cases.

However, there's a case where it doesn't work.

Suppose your repo looks like this:

     Entry			Created in
     /trunk			  1
     /branches                     1

     /trunk/foo                    2
     /trunk/bar                    2

     /branches/test1               3   Copied from trunk:2, WC -> WC
     /branches/test1/foo           3
     /branches/test1/bar           3

     /branches/test1/bar           4   Modified, and committed

     /branches/test2               5   Copied from trunk:4, URL -> URL
     /branches/test2/foo           5
     /branches/test2/bar           5

     /branches/test2/bar           6   Modified, and committed

In this case, and given the code above, you would expect both approaches to
agree on what is the interesting revision for each file.

That's only the case with WC -> WC copy.  Both approaches agree that the
interesting revision for /branches/test1/foo is 4.

However, with a URL -> URL copy, they differ.

Using SVN::Repos, it tells me that the youngest interesting revision for
/branches/test2/foo is 5.  This seems to make sense -- it's the revision at
which this file appeared in the repository.

Using SVN::Ra, it tells me that the youngest interesting revision for
/branches/test2/foo is 2 -- i.e., the revision in which it was last modified
on /trunk.

This difference is also reflected in the 'svn log' output.

With the WC -> WC copy you see this from 'svn log'

     ...
     Changed paths:
       A /branches/test1 (from /trunk:1)
       A /branches/test1/bar (from /trunk/bar:2)
       A /branches/test1/foo (from /trunk/foo:2)
     ...

With the URL -> URL copy you see this:

     ...
     Changed paths:
       A /branches/test2 (from /trunk:4)
     ...

Notice that there's no 'A' line for /branches/test2/bar or /branches/test2/foo.

This situation persists until the file is affected by a later commit.  At
which point $ent->created_rev() returns the correct value.  So in the
example above, both ::Ra and ::Repos agree that the youngest interesting
revision for /branches/test2/bar is 6.

This doesn't seem right.  Is this a bug, or am I using the API incorrectly?
If I am using the API incorrectly, could someone indicate what the correct
approach is?  I'm currently using Subversion 1.3.0 rc4.

Attached are two files.

mkrepo.sh is a shell script that, given a path, will create a repo in that
path that mirrors the one described here.

     sh mkrepo.sh /tmp/repo

for example.  test.pl is a small Perl program that uses SVN::Ra and
SVN::Repos to access the repo and see whether or not the two approaches
agree on which is the youngest interesting revision.  To run it,

     perl test.pl /tmp/repo

I get this output:

1..7
ok 1 - ra/repos agree on youngest rev
ok 2 - ra/repos agree on interesting rev for /trunk/foo
ok 3 - ra/repos agree on interesting rev for /trunk/bar
ok 4 - ra/repos agree on interesting rev for /branches/test1/foo
ok 5 - ra/repos agree on interesting rev for /branches/test1/bar
not ok 6 - ra/repos agree on interesting rev for /branches/test2/foo
#   Failed test 'ra/repos agree on interesting rev for /branches/test2/foo'
#   in test.pl at line 30.
#          got: '2'
#     expected: '5'
ok 7 - ra/repos agree on interesting rev for /branches/test2/bar
# Looks like you failed 1 test of 7.

As you can see, for /branches/test2/foo ::Ra says the youngest interesting
rev is 2, ::Repos says it's 5.

Any advice gratefully received.

N

Re: Differences between WC->WC copy, URL->URL copy, and $dirent->created_rev()

Posted by Philip Martin <ph...@codematters.co.uk>.
Nik Clayton <ni...@ngo.org.uk> writes:

> With the WC -> WC copy you see this from 'svn log'
>
>      ...
>      Changed paths:
>        A /branches/test1 (from /trunk:1)
>        A /branches/test1/bar (from /trunk/bar:2)
>        A /branches/test1/foo (from /trunk/foo:2)

You copied a mixed revision working copy.

>      ...
>
> With the URL -> URL copy you see this:
>
>      ...
>      Changed paths:
>        A /branches/test2 (from /trunk:4)

You copied a single revision URL.

>      ...
>
> Notice that there's no 'A' line for /branches/test2/bar or
> /branches/test2/foo.

That's the intended behaviour.

-- 
Philip Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org