1 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns=
"http://www.w3.org/1999/xhtml">
5 <style type=
"text/css"> /* <![CDATA[ */
6 @import
"branding/css/tigris.css";
7 @import
"branding/css/inst.css";
9 <link rel=
"stylesheet" type=
"text/css" media=
"print"
10 href=
"branding/css/print.css"/>
11 <script type=
"text/javascript" src=
"branding/scripts/tigris.js"></script>
12 <title>Use of WebDAV in Subversion
</title>
18 <h2>Use of WebDAV in Subversion
</h2>
21 This document details how WebDAV is used within the
22 <a href=
"http://subversion.tigris.org/">Subversion
23 product
</a>. Specifically, how the client side interfaces with
24 <a href=
"http://www.webdav.org/neon/">Neon
</a> to generate
25 WebDAV requests over the wire, and what the
26 server must do to map incoming WebDAV requests into operations
27 against the Subversion repository. Note that the server side is
29 <a href=
"http://httpd.apache.org/">Apache
2.0</a> module,
30 operating as a back-end for its mod_dav functionality.
33 This document heavily refers to the
34 <a href=
"http://subversion.tigris.org/files/documents/15/17/svn-design.html">Subversion
35 design document
</a> and the
36 <a href=
"http://www.webdav.org/deltav/">latest Delta-V protocol
37 draft
</a>. Details of those documents will
<em>not
</em> be
41 <table width=
"70%" border=
"0" cellspacing=
"0" cellpadding=
"10"
42 style=
"background-color: #ff0000; color: white;
43 margin-left: auto; margin-right: auto">
46 <strong>NOTE:
</strong> Subversion uses DeltaV for its
47 communication, but the Subversion client is
48 <strong>not
</strong> a general-purpose DeltaV client. In
49 fact, it expects some custom features from the
50 server. Further, the Subversion server is
51 <strong>not
</strong> a general-purpose DeltaV server. It
52 implements a strict
<strong>subset
</strong> of the
53 DeltaV specification. A WebDAV or DeltaV client may very
54 well be able to interoperate with it, but only if that
55 client operates within the narrow confines of those
56 features the server has implemented.
61 Version
2.0 of Subversion will address WebDAV
62 interoperability (Class
1, Class
2, and DeltaV
63 features). Each of the custom features expected by the
64 client actually has an alternate mechanism available in
65 DeltaV, but in a much less efficient form.
70 It is expected that Version
1.0 will support read-only,
71 Class
1 WebDAV clients. Any
"low-hanging fruit" to
72 increase DeltaV interoperability will be considered.
79 <h3>Basic Concepts
</h3>
81 Subversion uses a tree-based format to describe a change set
82 against the repository. This tree is constructed on the client
83 side (by
"walking" over the working copy) to describe the
84 change. The tree is marshalled to the server as a linear
85 sequence of changes to be applied to the repository. The
86 repository can accept changes in a random-access manner, so the
87 mapping from a tree to a set of changes works very well for the
91 Subversion provides properties on files, directories, and even
92 the abstract concept of a revision. Each of the operations
93 involving properties are mapped directly to WebDAV properties,
94 which are manipulated with the
<span
95 class=
"method">PROPFIND
</span> and
<span
96 class=
"method">PROPPATCH
</span> HTTP methods. Revisions are
97 modeled as DeltaV
<span class=
"term">baselines
</span>, so
98 revision properties are available through a
<span
99 class=
"method">PROPFIND
</span> on the baseline.
102 The Subversion server can efficiently compute deltas between two
103 revisions (these deltas are complete
<span class=
"term">tree
104 deltas
</span>, not simple text deltas). DeltaV does not have a
105 direct analogue for the tree delta concept. A client could
106 discover changes by issuing a sequence of
<span
107 class=
"method">PROPFIND
</span> requests on the various WebDAV
108 resources, but this would be a time-consuming operation,
109 involving many requests. Instead, Subversion marshals this
110 concept as a custom WebDAV
<span
111 class=
"term">report
</span>. Using this report, the client learns
112 which items in the working copy are out of date and can issue
113 <span class=
"method">GET
</span> and
<span
114 class=
"method">PROPFIND
</span> methods to fetch the new data.
117 Tags and branches are simple copies in Subversion, which are
118 handled with the WebDAV
<span class=
"method">COPY
</span>.
120 <blockquote class=
"comment">
121 <p>need to talk about copies somewhere. need to discuss how copy
122 history is retained (svn does it automatically, but interop with
123 other servers may require us to set a custom property on those
127 <h3>DeltaV Concepts Used by Subversion
</h3>
129 Subversion uses many of the DeltaV concepts, as listed
130 below. Note that many of these concepts are not fully
131 implemented by Subversion; we have implemented enough to meet
132 our needs, but little more.
137 <span class=
"comment">further info to come...
</span><p></p>
142 <span class=
"comment">further info to come...
</span><p></p>
145 <dt>Version Resource
</dt>
147 <span class=
"comment">further info to come...
</span><p></p>
150 <dt>Version-Controlled Configuration
</dt>
152 <span class=
"comment">further info to come...
</span><p></p>
155 <dt>Baseline Collection
</dt>
157 <span class=
"comment">further info to come...
</span><p></p>
160 <dt>Version-Controlled Resource
</dt>
162 <span class=
"comment">further info to come...
</span><p></p>
165 <dt>Working Resource (Feature)
</dt>
167 <span class=
"comment">further info to come...
</span><p></p>
170 <dt>Merge Feature
</dt>
172 <span class=
"comment">further info to come...
</span><p></p>
175 <dt>Label Feature
</dt>
177 <span class=
"comment">further info to come...
</span><p></p>
180 <dt>Version-Controlled-Collection Feature
</dt>
182 <span class=
"comment">further info to come...
</span><p></p>
187 <h3>Subversion Projects as URLs
</h3>
189 The very first concept to define is how a project is exposed to
190 the client. Subversion will expose all projects as URLs on a
191 server. The files and subdirectories under this project will be
192 exposed through the URL namespace.
195 For example, let us assume that we have a project named
196 "example". And let us say that this project will be exposed at
198 <span class=
"url">http://subversion.tigris.org/repos/example/
</span>.
201 This mapping is set up through a set of configuration
202 parameters for the Apache HTTP Server (which is hosting the
203 Subversion code and the particular project in question). The
204 configuration could look like:
207 <pre><Location /repos/example
>
209 SVNPath /home/svn-projects/example
210 </Location
></pre>
213 Files and directories within the project will be directly mapped
214 into the URL namespace. For example, if the project contains a
215 file
"file.c" in a subdirectory
"sub", then the URL for that
217 <span class=
"url">http://subversion.tigris.org/repos/example/sub/file.c
</span>.
220 <h3>Initial Checkout
</h3>
222 When the user performs the initial checkout of a Subversion
223 project, the client will issue a series of
<span
224 class=
"method">PROPFIND
</span> and
<span
225 class=
"method">GET
</span> requests. These requests will traverse
226 the repository, pick up some necessary metadata, and then fetch
230 describe the OPTIONS request for fetching the activity
231 collection set. describe the sequence of PROPFINDs to reach the
235 <i>(moved here from below; need to rewrite)
</i><br/>
236 When the initial checkout was performed, Subversion fetched
237 the
<span class=
"prop">DAV:activity-collection-set
</span> value
238 and stored it as a property on each directory in the working copy.
240 collection. This property lists all of the locations on the
241 server where an activity may be created. The first of these
242 locations will be stored on the client for use during the commit
246 Should probably describe the metadata we fetch, and how a
247 checkout of
"not the latest" (e.g. by date or revision) will
251 <h3>Committing a Change
</h3>
253 Subversion commits are modeled using the
"activity" concept from
254 DeltaV. An activity can be viewed as a transaction for a set of
258 <h3>Creating the activity
</h3>
260 At commit time, the Subversion client will retrieve the stored
261 <span class=
"prop">DAV:activity-collection-set
</span> value to
262 know where it should create the activity. Next,
263 the client will generate a UUID (a unique value) to use for the
264 activity's location. Finally, the client will issue a
265 <span class=
"method">MKACTIVITY
</span> method request, where the Request-URL is
266 composed from the activity location and the UUID. This request
267 will construct an activity to hold all of the changes for the
270 <p>Abbreviated summary:
</p>
272 <dt>At checkout time:
</dt>
274 <div>Request:
<span class=
"method">OPTIONS
</span> for
275 <span class=
"prop">DAV:activity-collection-set
</span></div>
277 class=
"url">http://www.example.com/repos/foo/$svn/act/
</span></div>
279 <dt>At commit time:
</dt>
281 <div>Request:
<span class=
"method">MKACTIVITY
</span>
282 <span class=
"url">http://www.example.com/repos/foo/$svn/act/
01234567-
89ab-cdef-
0123-
456789abcdef
</span></div>
283 <div>Response:
201 (Created)
</div>
287 The
<span class=
"method">CHECKOUT
</span> method can specify an
288 activity to use upon checkout. This feature is used to associate
289 all items with the newly-created activity.
292 <h3>Storing the commit message
</h3>
294 talk about checking out the baseline and applying a PROPPATCH to
295 the working baseline.
298 <h3>Mapping changes to WebDAV
</h3>
300 A change set in Subversion is specified with a
"tree delta" (see
301 the SVN design for more details on the changes that can be
302 placed into a tree delta). The tree delta will be unravelled
303 into a set of requests. These requests will be one of the
307 <dt>Delete file or directory
</dt>
309 These changes are mapped onto a
<span
310 class=
"method">DELETE
</span> operation. The version resource
311 of the target's parent collection is checked out using the
312 <span class=
"method">CHECKOUT
</span> method (into the current
313 activity). The target (name) is then deleted from the
314 resulting working collection using the
<span
315 class=
"method">DELETE
</span> method.
322 This is modeled by performing a
<span
323 class=
"method">CHECKOUT
</span> of the version resource of the
324 target's parent collection. The new file is created within the
325 resulting working collection using a
<span
326 class=
"method">PUT
</span> request. Properties are applied
327 using
<span class=
"method">PROPPATCH
</span>.
332 <dt>Add directory
</dt>
334 This is modeled by performing a
<span
335 class=
"method">CHECKOUT
</span> on the version resource of the
336 target's parent collection. The new directory is created
337 within the resulting working collection with a
<span
338 class=
"method">MKCOL
</span> request. Properties are applied
339 using
<span class=
"method">PROPPATCH
</span>.
344 <dt>Add file or directory, with previous ancestory (a copy)
</dt>
346 <span class=
"comment">need to fix this section
</span>
349 A tree delta can specify that a file/directory originates as
350 a copy of another file/dir. This copy may be further
351 modified by additional elements the tree delta.
354 This change will be modeled by performing a
355 <code>CHECKOUT
</code> on the version resource of the parent
356 collection which will contain the new resource. The
357 <code>VERSION-CONTROL
</code> method will create a new
358 version-controlled resource (VCR) within the working
359 collection, with the VCR's
<code>DAV:checked-in
</code>
360 property referring to the ancestor's version resource.
363 <p><strong>Note:
</strong> it appears that we will use
364 <code>COPY
</code> to copy the appropriate resource into the
365 working collection. This will create a new version history
366 which is then placed into the working collection. The
367 version history will use the
<code>DAV:precursor-set
</code>
368 property to specify the version resource of the ancestor.
</p>
371 Because a version resource does not specify the revision,
372 it will not be possible to
<code>COPY
</code> a version
373 resource into the working collection -- it will not tell
374 us what revision was copied. Instead, we will most likely
375 copy a version resource out of the appropriate
376 baseline. This implies the client must be able to map from
377 a URL/revision pair to a baselined version resource URL.
380 The second issue is whether/how we set the
381 <code>DAV:precursor-set
</code> property of the version
382 history. Or, more precisely, how we synthesize the value
383 from information stored in the repository. This is still
389 <dt>Replace file/dir by another file/dir
</dt>
391 This change does not have a WebDAV modeling because tree
392 deltas model it as two, sequential operations: a
393 <em>delete
</em>, followed by an
<em>add
</em>.
398 <dt>Moving a file or directory
</dt>
400 This change does not have a WebDAV modeling because tree
401 deltas model it as two, distinct operations: a
402 <em>delete
</em>, and an
<em>add
</em> with previous ancestry.
407 <dt>Replace file
</dt>
409 This is modeled with a
<span class=
"method">CHECKOUT
</span> on
410 the target's version resource, followed by a
<span
411 class=
"method">PUT
</span> to the resulting working resource.
416 <dt>Replace directory
</dt>
418 In Subversion terms,
"replace directory" means that additions,
419 deletions, and other changes will occur
<em>within
</em> the
420 directory. Each of these changes are modeled individually, and
421 the change to the directory is performed
422 implicitly. Therefore, this
"change" has no particular mapping
428 <dt>Property delta
</dt>
430 A property delta (against a file or directory) maps directly
431 to a
<span class=
"method">PROPPATCH
</span> in WebDAV
432 terms. The target's version resource will be checked out using
433 <span class=
"method">CHECKOUT
</span> and the
<span
434 class=
"method">PROPPATCH
</span> will be applied to the
435 resulting working resource.
439 <h3>Final Commit
</h3>
441 The final action of the commit process is to issue a
<span
442 class=
"method">MERGE
</span> request to the Subversion server,
443 specifying that the activity (created earlier) be checked in and
444 the corresponding version-controlled resources be updated to
445 refer to the new version resources.
448 the comment below is not quite right. talk about the working
449 baseline, and how that is used to create a new baseline (with
450 the commit message on it)
453 The version-controlled resources are also baseline-controlled,
454 which means that updates to them will automatically create a new
455 baseline. In essence, the commit will create a new baseline
456 corresponding to the new Subversion revision.
461 <strong>Warning:
</strong> this section has not been updated to
462 reflect some recent changes to the SVN-to-DAV mapping. Consider
463 it out of date until this warning is removed.
466 Consider the following set of operations and its corresponding
467 tree delta (taken from the SVN design document):
470 <li>rename
<code>/dir1/dir2
</code> to
<code>/dir1/dir4
</code>,
</li>
471 <li>rename
<code>/dir1/dir3
</code> to
<code>/dir1/dir2
</code>, and
</li>
472 <li>move
<code>file3
</code> from
<var>/dir1/dir4
</var> to
<var>/dir1/dir2
</var>.
</li>
474 <pre><tree-delta
>
475 <replace name='dir1'
>
478 <replace name='dir2'
>
479 <directory ancestor='/dir1/dir3'
> (
1)
481 <new name='file3'
> (
2)
482 <file ancestor='/dir1/dir2/file3'/
>
487 <delete name='dir3'/
> (
3)
488 <new name='dir4'
> (
4)
489 <directory ancestor='/dir1/dir2'
>
491 <delete name='file3'/
> (
5)
502 Walking through this delta, we map out the WebDAV requests
503 listed below. The numbers in the above delta roughly correspond
504 to the numbered entries below. The correspondence is not exact
505 because a specific, resulting behavior is typically based on a
506 combination of a few elements in the delta.
510 The
<code><directory
ancestor=
"/dir1/dir3"></code>
511 specifies that we are overwriting
<code>/dir1/dir2
</code> with
512 <code>/dir1/dir3
</code>.
514 <code>CHECKOUT
/dir1/dir2/
</code><br/>
515 <i>(returns a working resource URL for the directory)
</i>
518 <code>COPY
/dir1/dir3/
</code><br/>
519 <code>Destination:
http://www.example.com/$svn/wrk/.../
</code><br/>
520 <code>Overwrite:
T
</code>
524 <code>/dir1/dir2/file3
</code> is new (since we just overwrote
525 the original
<code>dir2
</code> directory), and originates from
526 <code>/dir1/dir2/file3
</code>. Thus, we simply
527 <code>COPY
</code> the file into the target directory's working
530 <code>COPY
/dir1/dir2/file3
</code><br/>
531 <code>Destination:
http://www.example.com/$svn/wrk/.../file3
</code>
536 <code>CHECKOUT
/dir1/dir3/
</code><br/>
537 <i>(returns a working resource URL for the directory)
</i>
540 <code>DELETE
/$svn/wrk/.../
</code>
544 We are going to creating a new subdirectory (
<code>dir4
</code>) in the
545 <code>/dir1
</code> directory. Since we don't have
546 <code>/dir1
</code> checked out yet, we do so:
548 <code>CHECKOUT
/dir1/
</code><br/>
549 <i>(returns a working resource URL for the directory)
</i>
552 And now we copy the right directory into the new working
556 <code>COPY
/dir1/dir2/
</code><br/>
557 <code>Destination:
http://www.example.com/$svn/wrk/.../dir4/
</code>
561 The
<code>COPY
</code> created a complete set of working
562 resources on the server, so we simply delete the part that we
565 <code>DELETE:
/$svn/wrk/.../dir4/file3
</code>
572 The Subversion server exposes repositories at user-defined
573 URLs. For example, the
"foo" repository might be located at
575 class=
"url">http://www.example.com/repos/foo/
</span>. However,
576 the server also requires a number of other resources to be
577 exposed for proper operation. These additional resources will be
578 associated with each repository in a location under the main
579 repository URL. By default, this location is
"<span
580 class="url
">$svn</span>". It may be changed by using the
581 <code>SVNSpecialURI
</code> directive:
584 <pre><Location /repos/foo
>
586 SVNPath /home/svn-projects/foo
587 SVNSpecialURI .special
588 </Location
></pre>
591 Underneath the location specified by
<code>SVNSpecialURI
</code>,
592 we will expose several collections. Assuming we use the default
593 of
"<span class="url
">$svn</span>", the collections are:
596 <dt><span class=
"url">$svn/act/
</span></dt>
598 This area is where activity resources are created. The client
599 will pick a unique name within this collection and issue a
600 <span class=
"method">MKACTIVITY
</span> for that URL. The client will then use
601 the activity in further interactions.
603 No methods are allowed on the
<span class=
"url">$svn/act/
</span>
607 <p>Note: actually, we may want to allow a
<code>PROPFIND
</code>
608 with a
<code>Depth:
1</code> header to allow clients to
609 enumerate the current activities.
</p>
612 Only a subset of methods are allowed on the activities
613 within the collection. They are:
<span class=
"method">PROPFIND
</span>,
614 <span class=
"method">MERGE
</span> (commit the activity), and
615 <span class=
"method">DELETE
</span> (abort the activity).
618 Per the Delta-V specification, all activity resources will
619 have a
<span class=
"prop">DAV:resourcetype
</span> of
620 <span class=
"prop">DAV:activity
</span>.
624 <dt><span class=
"url">$svn/his/
</span></dt>
626 <span class=
"comment">do something with this section; we
627 actually don't use version history resources. in the future,
628 they might be modeled like this
</span>
631 This collection contains the version history resources for
632 files and directories in a project. Its internal layout is
633 completely server-defined. Clients will receive URLs into
634 this collection (or a subcollection) from various responses.
637 No methods are allowed on the
<span class=
"url">$svn/his/
</span>
641 Internally, the URL namespace is laid out with URLs of the
644 <blockquote class=
"url">
645 <p>$svn/his/
<var>node-id
</var></p>
648 The
<var>node-id
</var> is an internal value
649 that Subversion uses to reference individual files and
650 directories. This
<var>node-id
</var> is a single integer
651 defined by the Subversion repository. Note that this is an
652 undotted node id, which is the base for the entire history
653 of a given node in the repository.
656 The
<span class=
"prop">DAV:resourcetype
</span> of the
<var>node-id
</var>
657 collection is
<span class=
"prop">DAV:version-history
</span>.
659 <blockquote class=
"comment">
660 <p><strong>Note:
</strong> the above information is probably not
661 quite correct. The issue of linking one version history to
662 another is still open. Further, I think that node
73 and
663 node
73.4.1 are each version histories (where the latter is
664 linked to the former).
73.x and
73.4.1.x are the versions
665 within the version history.
</p>
669 <dt><span class=
"url">$svn/ver/
</span></dt>
671 This collection contains the version resources for the
675 No methods are allowed on the
<span class=
"url">$svn/ver/
</span>
679 The layout of this collection is internal to the server. For
680 reference purposes here (and to describe the
681 implementation), it is laid out as:
683 <blockquote class=
"url">
684 <p>$svn/ver/
<var>node-id
</var>/
<var>path
</var></p>
687 Only read-only methods are allowed against these resources
688 (e.g.
<span class=
"method">GET
</span>,
<span class=
"method">PROPFIND
</span>,
689 <span class=
"method">REPORT
</span>); all other methods are illegal.
692 The
<span class=
"prop">DAV:resourcetype
</span> of a version resource is
693 simply the value of the resource at checkin time
694 (e.g.
<code><D:resourcetype/
></code> or
695 <code><D:resourcetype
><D:collection/
></D:resourcetype
></code>).
699 <dt><span class=
"url">$svn/wrk/
</span></dt>
701 This collection contains working resources for the resources
702 that have been checked out with the
<span class=
"method">CHECKOUT
</span>
703 method. The form and construction of this collection is
704 server-defined, but is also well-defined so that clients may
705 interact properly with collection versions that have been
708 No methods are allowed on the
<span class=
"method">$svn/wrk/
</span>
712 For reference purposes, the working resource URLs are
715 <blockquote class=
"url">
716 <p>$svn/wrk/
<var>activity
</var>/
<var>path
</var></p>
719 Any method is allowed on the working resources, but no
720 methods are allowed on any of its parents.
723 The
<span class=
"prop">DAV:resourcetype
</span> of the working resources
724 follows normal resource typing:
725 <code><D:resourcetype/
></code> for regular working
727 <code><D:resourcetype
><D:collection/
></D:resourcetype
></code>
728 for working collections.
732 <dt><span class=
"url">$svn/vcc/
</span></dt>
734 <span class=
"comment">This section is not yet complete.
</span>
737 version-controlled configuration...
741 <code>$svn/vcc/root
</code> as a singleton.
745 <dt><code>$svn/bln/
</code></dt>
747 <span class=
"comment">This section is not yet complete.
</span>
754 <code>$svn/bln/
<var>rev
</var>/
</code>
758 <dt><code>$svn/wbl/
</code></dt>
760 <span class=
"comment">This section is not yet complete.
</span>
767 <dt><code>$svn/bc/
</code></dt>
769 <span class=
"comment">This section is not yet complete.
</span>
772 baseline collection...
777 <h3>Property Management (and History/Log Reporting)
</h3>
779 this section needs to be reworked. the properties occur on the
780 FS revisions (and exposed via baselines).
783 As mentioned before, Subversion properties map onto WebDAV
784 properties. For history/log reporting, the following WebDAV
785 properties will be applied to each baseline (a Subversion
786 revision) and to each version resource created by the
787 revision. Since these resources are all version resources, the
788 properties below are read-only.
791 <dt><code>DAV:comment
</code></dt>
793 This is the standard (dead) property for specifying a checkin
797 <dt><code>DAV:creator-displayname
</code></dt>
799 This is a (dead) property that is generated from Subversion's
800 concept of the
"user" who made a particular change.
803 <dt><code>DAV:creationdate
</code></dt>
805 This is a read-only live property created by the server at
810 The history for a specified file will be generated using the
811 <code>REPORT
</code> method and a
812 <code>DAV:property-report
</code> report. A typical history will
813 fetch the three properties mentioned above for each version of
817 Based on the client design, it may be important to specify other
818 read-only live properties for information about versions. For
819 example, how many lines were added/removed in a particular
820 checkin for a file? Creating these live properties will be quite
821 straight-forward, and driven by the client design over time.
824 <p>Note: if we do this, however, then we'd end up tying the client
825 to the server. Of course, if the client were run against another
826 DeltaV server which didn't report these properties, then we'd
827 simply not display them in the UI. (e.g. graceful degradation of
831 <h3>Fetching Status and Updates
</h3>
833 After the initial checkout, the client can request a status
834 report (what has been changed on the client, pending a commit;
835 what has been changed on the server, pending an update). The
836 update process is similar, except that we also fetch the changes
840 The local changes can be handled entirely on the client
841 side. The Working Copy library can easily handle the detection
842 and reporting of these changes. We're concerned with efficiently
843 detecting what has changed on the server.
846 While it would be possible to traverse the repository, fetching
847 the current state, and comparing that to the client state, it
848 would not be efficient. The Subversion design enables the server
849 to easily compute what has changed (relative to the client), if
850 it is given a description of the client state.
853 The core of the
<em>status
</em> and
<em>update
</em> commands is
854 based on a custom Subversion-specific WebDAV report. This custom
855 report will transmit the state of the working copy to the
856 server, and the server response will specify which resources
857 will need to be updated (fetched).
860 The request is a standard
<code>REPORT
</code> request, with a
861 custom XML body. The body will use the standard Subversion
862 technique of reporting a top-level revision number, and then
863 only reporting children that have different revisions. The
864 result of the report will use the same technique of reporting
865 only the resources where a change is found. If a change is
866 found, the server will provide a URL to the version resource to
867 fetch for the changed resource. The server will also report the
868 current revision number.
870 <blockquote class=
"comment">
871 <p>The XML DTDs for the request and response are TBD.
</p>
875 The custom report will tie the client to only those servers
876 which support the report, but a future version of the software
877 will contain a fallback codepath, a graceful degradation, to
878 support other DeltaV servers.
882 When an updated is performed, the client will fetch each of the
883 URLs (using
<code>GET
</code> requests) provided in the server
887 <code>GET
</code> (and
<code>PUT
</code>) operations will transfer
888 content in a
"diff" format when possible. The mechanics of this
889 will follow the Internet Draft, titled
890 <a href=
"http://www.ietf.org/internet-drafts/draft-mogul-http-delta-10.txt">Delta Encoding in HTTP
</a>.
893 <h3>Entity Tags (etags)
</h3>
895 Etags are required to be unique across all versions of a
896 resource. Luckily, this
897 is very easy for a version control system. Each etag will be
898 simply be the repository's
<em>node-id
</em> for the resource.
901 Etags are used to generate diffs, following the guidelines in
902 the aforementioned draft:
903 <a href=
"http://www.ietf.org/internet-drafts/draft-mogul-http-delta-10.txt">Delta Encoding in HTTP
</a>.
904 The problem then becomes how to get the etag for each file
905 stored on the client (we don't need etags for directories since
906 we never fetch them). During a
<em>checkout
</em> or
907 <em>update
</em> process, this is easy: the etag is provided in
908 the HTTP response headers for each file retrieved.
911 The other part of the problem is getting the etag after a
912 <em>commit
</em> has occurred. The
<code>MERGE
</code> response
913 provides a way to request properties from the version resources
914 which are created as part of the checkin of the activity. The
915 etag (and other properties) can be fetched using that mechanism.
918 <h3>Tags and Branches
</h3>
920 Tags and branches within Subversion are performed by copying
921 from one area to another. For example:
925 [.../src/my-project]$ svn cp trunk tags/
1.0.3-rc4
926 [.../src/my-project]$ svn commit
930 In the above example,
<code>tags/
1.0.3-rc4
</code> should now be
931 considered readonly and will always reflect the status of
935 These copies are handled just like a regular commit. An activity
936 is created with
<span class=
"method">MKACTIVITY
</span>, a
937 working resource is created via
<span
938 class=
"method">CHECKOUT
</span> (for the target directory;
939 <code>tags/
</code> in our example above), and then a
<span
940 class=
"method">COPY
</span> is performed. The activity is then
941 merged back into the repository with a
<span
942 class=
"method">MERGE
</span> request.
945 <h3>Server Requirements
</h3>
947 <strong>Warning:
</strong> this section is out of date. The
948 DeltaV draft has gone through a number of revisions, and our use
949 of DeltaV has changed some.
954 The server will need to implement the following WebDAV methods
955 for proper operation:
958 <li><span class=
"method">OPTIONS
</span></li>
959 <li><span class=
"method">GET
</span></li>
960 <li><span class=
"method">DELETE
</span></li>
961 <li><span class=
"method">COPY
</span></li>
962 <li><span class=
"method">PROPPATCH
</span></li>
963 <li><span class=
"method">PROPFIND
</span></li>
965 <li><span class=
"method">MKACTIVITY
</span></li>
966 <li><span class=
"method">CHECKOUT
</span></li>
967 <li><span class=
"method">MERGE
</span></li>
968 <li><span class=
"method">REPORT
</span></li>
971 The following methods are not required by Subversion at this
975 <li><span class=
"method">CHECKIN
</span></li>
976 <li><span class=
"method">UNCHECKOUT
</span></li>
977 <li><span class=
"method">UPDATE
</span></li>
978 <li><span class=
"method">LABEL
</span></li>
979 <li><span class=
"method">VERSION-CONTROL
</span></li>
980 <li><span class=
"method">BASELINE-CONTROL
</span></li>
981 <li><span class=
"method">MKWORKSPACE
</span></li>
984 <h3>DAV Properties
</h3>
986 The following DeltaV properties will be implemented:
989 <!-- resource properties -->
990 <li><span class=
"prop">DAV:comment
</span></li>
991 <li><span class=
"prop">DAV:creator-displayname
</span></li>
992 <li><span class=
"prop">DAV:supported-method-set
</span></li>
993 <li><span class=
"prop">DAV:supported-live-property-set
</span></li>
994 <li><span class=
"prop">DAV:supported-report-set
</span></li>
995 <li><span class=
"prop">DAV:version-controlled-configuration
</span></li>
997 <!-- version-controlled resource properties -->
998 <li><span class=
"prop">DAV:checked-in
</span></li>
1000 <span class=
"prop">DAV:auto-version
</span> is a readonly,
1001 empty element (auto versioning not supported).
1004 <!-- checked-out resource properties -->
1005 <li><span class=
"prop">DAV:checked-out
</span></li>
1007 <span class=
"prop">DAV:predecessor-set
</span>
1009 Note: the Subversion design document is not clear on the
1010 mechanics of how multiple predecessors are merged to create
1011 a single, new revision. When this clarifies, then
1012 <code>DAV:predecessor-set
</code> may end up containing more
1013 than zero or one predecessor URLs
1017 <!-- version resource properties -->
1018 <!-- predecessor-set -->
1020 <span class=
"prop">DAV:version-name
</span> is simply the
1021 (global) revision number.
1023 <li><span class=
"prop">DAV:checkout-fork
</span></li>
1024 <li><span class=
"prop">DAV:checkin-fork
</span></li>
1026 <!-- checked-out (working resource) properties -->
1027 <!-- checkout-fork, checkin-fork -->
1028 <li><span class=
"prop">DAV:auto-update
</span></li>
1030 <span class=
"prop">DAV:subbaseline-set
</span> is a readonly,
1031 empty property (sub-baselines not supported).
1034 <span class=
"prop">DAV:unreserved
</span> is set to
1038 <!-- vcc properties -->
1039 <li><span class=
"prop">DAV:baseline-controlled-collection
</span></li>
1041 <!-- baseline properties -->
1042 <!-- subbaseline-set -->
1043 <li><span class=
"prop">DAV:baseline-collection
</span></li>
1045 <!-- activity properties -->
1047 <span class=
"prop">DAV:subactivity-set
</span> is a readonly,
1048 empty property (sub-activities not supported).
1051 <!-- version-controlled collection properties -->
1053 <span class=
"prop">DAV:eclipsed-set
</span> is always empty
1054 (internal members can never be eclipsed).
1059 Contrary to the DeltaV specification, the following required
1060 properties will not be implemented:
1064 <span class=
"prop">DAV:successor-set
</span> - this may be an
1065 expensive operation to synthesize this value.
1068 <span class=
"prop">DAV:checkout-set
</span> - we do not record
1069 what has actually been checked out, but use the working
1070 resource URL to provide the necessary information; thus we
1071 have no record of the data to populate this property.
1074 <span class=
"prop">DAV:merge-set
</span> - our
<span
1075 class=
"method">MERGE
</span> method is solely to support a
1076 commit. It doesn't really support the arbitrary merging
1077 defined within the spec.
1080 <span class=
"prop">DAV:auto-merge-set
</span> - same as for
1081 <span class=
"prop">DAV:merge-set
</span>.
1084 <span class=
"prop">DAV:activity-version-set
</span> -
1085 activities are only used for working resources, so versions
1086 cannot be part of an activity.
1087 <div><i>maybe this should be defined as the empty set?
</i></div>
1090 <span class=
"prop">DAV:activity-checkout-set
</span>
1091 activities are only used for working resources, and we do not
1092 record what working resources
"exist".
1095 <span class=
"prop">DAV:activity-set
</span> -
1096 activities are only used for working resources, so versions
1097 cannot be part of an activity.
1098 <div><i>maybe this should be defined as the empty set?
</i></div>
1101 <span class=
"prop">DAV:version-controlled-binding-set
</span> -
1102 we do not have version history resources to include in the
1109 The
<span class=
"method">OPTIONS
</span> request will signal that
1110 it supports the following DAV features:
1113 <li><code>1</code></li>
1114 <li><code>2</code></li>
1115 <li><code>version-control
</code></li>
1116 <li><code>checkout
</code></li>
1117 <li><code>working-resource
</code></li>
1118 <li><code>merge
</code></li>
1119 <li><code>baseline
</code></li>
1120 <li><code>activity
</code></li>
1121 <li><code>version-controlled-collection
</code></li>
1126 The
<span class=
"prop">DAV:supported-report-set
</span> property
1127 will signal support for the following reports:
1130 <li>svn:update-report
</li>
1131 <li>svn:log-report
</li>
1134 These reports are available only on the
"public" resources (the
1135 VCRs). They are not available on the resources within the
1136 <span class=
"url">$svn/
</span> area.
1139 <h3>Notes, reminders
</h3>
1141 Discuss timeouts and auto-purge of activities (and the related
1144 Discuss the activity database maintained by mod_dav_svn.
1146 Discuss other implementation details of ra_dav and mod_dav_svn.
1149 <h3><a name=
"rationale">Appendix A: Rationale
</a></h3>
1151 Several times, people have asked,
"Why choose
1152 HTTP/WebDAV/DeltaV? That seems awfully bloated and
1153 ill-suited. Why didn't you design a custom, well-tuned protocol?
1154 Or maybe use the CVS protocol?" Listed below are a number of
1155 reasons for our choice of WebDAV as our network protocol.
1160 While this list could certainly be expanded with more reasons
1161 (and to be fair, with a list of reasons why WebDAV was a poor
1162 choice), it certainly demonstrates the basic reasons for our
1169 Note: this list came from an email note, so the tone and point
1170 of view might be a bit off. Further word-smithing is
1175 <h3>Builtin web browsing of the repository
</h3>
1177 <p>For example, take a
1179 <a href=
"http://svn.collab.net/repos/svn/trunk/README">http://svn.collab.net/repos/svn/trunk/README
</a>
1180 (that's the HEAD right there; we also have URLs for every
1181 previous revision of every file)
</p>
1184 <h3>DAV-based browsing
</h3>
1186 <p>Use Web Folders or WebDrive or somesuch on
1187 your Windows box (or Windows XP's native DAV mounts) to browse
1188 the SVN repository with Windows Explorer. Mac OS X has builtin
1189 DAV server mounting. Nautilus has DAV capabilities. Then you
1190 have your Open Source tools such as cadaver, Goliath, etc.
</p>
1193 <h3>People can use existing libraries
</h3>
1195 <p>I couldn't even begin to count the number of HTTP tools and
1196 libraries available. If we had designed our own protocol, then
1197 we would have /none/ of those benefits. Heck, two HTTP library
1198 implementors (Joe Orton of Neon, and Daniel Stenberg of CURL)
1199 are regulars here. we wouldn't get that benefit. I've used
1200 Python's httplib (and a davlib of my own) to do a lot of testing
1201 of our server. No need to go and roll new protocol libraries.
</p>
1204 <h3>Existing tools
</h3>
1206 <p>One word: Ethereal :-) When we capture network traces, Ethereal
1207 already knows about HTTP. It's quite nice, but I know there are
1208 even better ones out there. But we also have other tools like
1209 squid and other (caching) proxies (see the next item).
</p>
1212 <h3>Caching proxies
</h3>
1214 <p>Subversion will work great with caching proxies. There is no
1215 longer a need for specialized tools like
"cvsup". Just drop in a
1216 caching proxy, and you've already got your distributed read-only
1217 repository. That European dev team can just drop in the cache
1218 between them and the US server and their checkouts/updates will
1219 get cached for the benefit of the other team members. Commits
1220 will flow through, back to the US-based server.
</p>
1223 <h3>Sophisticated and broad-choice authentication
</h3>
1225 <p>We don't have to reimplement an authentication scheme for a new
1226 protocol. We can use all of the various schemes that have been
1227 defined for HTTP. Ever look at the CVS protocol? Ever see the
"I
1228 Love You" or
"I Hate You" lines? :-) That is all part of
1229 creating a new authentication scheme. But we get to use SSL and
1230 certificate-based auth if we want. Kerberos. NTLM. or even just
1231 simple Basic or Digest. And our users can come from text files,
1232 database, LDAP, or PAM. We don't have to reinvent the wheel cuz
1233 it is all available for Apache already.
</p>
1236 <h3>Awesome network server
</h3>
1238 <p>We don't have to worry about how to portably set TCP_CORK for
1239 optimal network packets. We don't have to worry about when
1240 sendfile() makes sense, or if it is available. We don't have to
1241 worry about dropped client connections, how to best use threads
1242 and processes to scale, request management, monitoring, logging,
1243 etc. Apache gives us all of that and a ton more. I *really*
1244 would not want to do that through xinetd. I mean... setting
1245 TCP_CORK on stdout? freaky :-)
</p>
1248 <h3>Well-defined on-wire compression
</h3>
1250 <p>We already have on-wire compression, similar to CVS's
"-z#"
1251 switch. And we didn't do anything. The client library and server
1252 that we use just support it automatically for us, according to
1256 <h3>Future interoperability
</h3>
1258 <p>In the future, we'll be able to interoperate with a multitude of
1259 IDEs and other WebDAV/DeltaV clients. As DeltaV becomes more
1260 prevalent, IDEs could very well use it for source code
1261 management, and we'll be right there without needing to write
1262 some MS/SCC library to interface to the tool.
</p>
1266 <address><a href=
"mailto:gstein@lyra.org">Greg Stein
</a></address>
1267 <!-- Created: Thu Aug 10 19:14:20 PDT 2000 -->
1268 <!-- hhmts start -->
1269 Last modified: Fri Jan
25 12:
54:
20 PST
2002