[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: dav COPY method

From: Greg Stein <gstein_at_lyra.org>
Date: 2001-10-30 04:39:47 CET

On Mon, Oct 29, 2001 at 05:26:39PM -0600, Ben Collins-Sussman wrote:
> So when the commit-driver adds a file "newpath", here's what ra_local
> does:
> if (copyfrom args supplied):
> svn_fs_copy(copyfrom_url, newpath);

It's a little more involved than that. First, you parse that URL to extract
the FS-relative path. Then, you first open a revision root for the
copyfrom_revision. Lastly, a copy is made from the revision root over to the
transaction at the new path.

The DAV stuff will basically have to do the same work, so the question
becomes getting the revision and the FS-relative path over to the server.

> And AFAIK, ra_dav currently does nothing in this situation but do a

Right. It totally ignores the copyfrom stuff right now.

> Now we have a situation where ra_dav needs to notice copyfrom args;
> you explained to me that somehow the copyfrom_url and
> copyfrom_revision need to be converted into a 'baseline' url, which is
> then provided as an argument to the COPY method. Want to elaborate?

The WebDAV COPY method takes two URLs: a source, and a destination. The
source needs to encode both the revision and the path. There are two URL
forms which can do this: a version resource, and a resource from within a
Baseline Collection. The former isn't exact enough, though, as a version
resource identifies a node, rather than a rev:path pair. Specifically,
revisions 100 thru 200 could all refer to the same version resource; thus,
you're throwing away the "requested" revision for the copy. (end result is
the same, but you can't tell the user what was logically copied)

Thus, we need a resource from a Baseline Collection (BC). BCs are
essentially entire trees corresponding to each revision in the repository.
Thus, if you refer to FOO in the BC for revision 5, then you know you're
copying 5:FOO into the destination.

Now... you can't just go and manufacture URLs into a BC. You must ask the
server for those. Thus, we make a few round trips.

Every resource in the "public" space (e.g. /repos/svn/...) has a property
called DAV:version-controlled-configuration. That points to a Version
Controlled Configuration (gee, imagine that :-). The VCC is essentially a
"selector", if you will. It selects which Baseline is being exposed in the
public space. In our setup, the VCC always refers to the HEAD; thus, the
HEAD is always exposed in the public space. From the VCC, we can query the
DAV:checked-in property to get the Baseline corresponding to HEAD. But we
can also get other baselines by using the Label: header, to select a
Baseline with a specific Label. SVN labels each baseline with the
corresponding revision number. So "Label: 5" will refer to the baseline for
revision 5.

Anyways... once we get the correct Baseline, then we ask *that* for the URL
to its Baseline Collection.

Way back at the start, when we asked the public resource for the VCC's URL,
we also asked the resource for its relative path within the BC. Once we get
the BC's URL, we combine the two parts to get a full URL to the resource
residing within the BC.

So we issue the DAV COPY method with the BC resource as the source. The
Destination: header in the copy will refer to the target location. That
location is in the Working Collection (the checked out parent), and the
appropriate child name in that working collection.

On the server, the source URL is automatically parsed apart in the
get_resource parsing/prep functions. The Destination header is also parsed
apart by some magic in mod_dav, so we end up with two parsed resources. One
referring to a REV:PATH pair, and one referring to a non-existent entry in a
working collection. (or possibly existing; if so, we need to supply the
Overwrite: header appropriately)

I believe there is also a nifty Neon function to do a copy in one fell
swoop. Simplify our code quite a bit.

One question: if add_directory() is called with copyfrom_* arguments, is the
copy recursive or not? Our current API for add_directory and fs_copy does
not specify that. (DAV can copy just the dir, the dir+children, or the whole
tree rooted at dir)

Back to the original question: how do you do this COPY stuff. Well, just
look at the new svn_ra_dav__get_baseline_info() to get you the BC and
relative path information for a given resource. However, it is important to
note that you will perform *two* PROPFIND calls each time you call that
(three if you do it for HEAD rather than copyfrom_revision). You can
optimize that down to one PROPFIND, but I won't tell you how yet. Stick to
simple, working first :-) (dropping to one is just about caching, so it can
be added later)


p.s. the above information will all be dumped into the webdav-design
document this week.

Greg Stein, http://www.lyra.org/
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:46 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.