本文详叙了WebDAV怎样用于Subversion。特别是,客户端怎么用Neon生成WebDAV请求,以及服务器端怎么将WebDAV请求转变成Subversion代码仓库的操作。这里的服务器端是一个作为mod_dav功能后端的Apache 2.0模块。 本文大量引用了 Subversion设计文档和最新的 Delta-V协议草案。这两份文档的详细内容就不在本文中重复了。 注意:Subversion使用DeltaV来进行通信,但是Subversion客户端并不是一个通用的DeltaV客户端。实际 上,Subversion客户端依赖于服务器的一些专有特性。更进一步来说,Subversion服务器端也不是一个通用的DeltaV服务器。它只是实 现了DeltaV协议的一个子集。当且仅当只使用Subversion服务器端实现的这个子集的功能时,WebDAV或者DeltaV客户端才能正常的与 Subversion服务器端协作 Subversion的2.0版将会处理WebDAV协作性(包括与Class 1、Class 2和DeltaV)的问题。Subversion客户端需要的专有特性都会在DeltaV中提供一个替代方案,虽然替代方案不太高效。 Subversion的1.0版会支持只读的Class 1 WebDAV客户端。任何能够增强DeltaV协同性,且容易实现的功能都将被考虑。 基本概念Subversion使用一个基于树的格式来描述版本库的变更集。这个树是在客户端(通过在工作副本中“行走”)被构造用来描述变更。这个树作为被 应用于版本库一个线性序列的变更被编组到服务端。版本库可以以随机存取的方式接受变更,所以从树到一系列变化的映射对版本库来说非常容易。 Subversion为文件,目录甚至修订版本的抽象概念提供了属性。牵涉属性的每一个操作可以通过操作PROPFIND和PROPPATCH HTTP方法直接映射到WebDAV的属性。修订版本被建模为DeltaV基线,所以修订版本的属性可以通过基线的PROPFIND来获得。 Subversion服务端能够有效的计算两个版本之间的增量(这些增量是完整的树增量,不是 简单的文本增量)。Deltav没有直接模拟树增量概念。客户端可以通过在各种WebD{敏感词}上发送一系列PROPFIND请求发现变更,但是这个调用 多个请求将是一个耗时的操作。作为替代,Subversion将这个概念整理为一个自定义的WebDAV报告。使用这个报告,客户端可以了解工作副本中的 哪项过时并可以发送GET和PROPFIND方法获取新数据。 在Subversion中,分支和标签是简单的拷贝,是用WebDAV COPY处理的。
在某处需要讨论拷贝.需要讨论拷贝的历史如何被保存 (svn是自动处理的, 但是与其他服务端交互的时候可能需要我们在其他服务端设置一个自定义属性. Subversion中使用的Deltav概念
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | < tree-delta > < replace name = 'dir1' > < directory > < tree-delta > < replace name = 'dir2' > < directory ancestor = '/dir1/dir3' > (1) < tree-delta > < new name = 'file3' > (2) < file ancestor = '/dir1/dir2/file3' /> </ new > </ tree-delta > </ directory > </ replace > < delete name = 'dir3' /> (3) < new name = 'dir4' > (4) < directory ancestor = '/dir1/dir2' > < tree-delta > < delete name = 'file3' /> (5) </ tree-delta > </ directory > </ new > </ tree-delta > </ directory > </ replace > </ tree-delta > |
遍历此delta,我们列出了对应的WebDAV请求。上文delta的数字编号大致相当于下面的列表项编号。这种对应关系并不十分准确,因为一个特定的、既成的行为通常基于delta中的一组元素。
<directory ancestor="/dir1/dir3"> 指定我们用/dir1/dir3替换/dir1/dir2
CHECKOUT /dir1/dir2/
(返回该目录的一个当前工作资源URL)
COPY /dir1/dir3/
Destination: http://www.example.com/$svn/wrk/.../
Overwrite: T
/dir1/dir2/file3是新的(因为我们刚刚重写了原始的dir2目录),并来源于/dir1/dir2/file3。因此,我们只需要COPY文件到目标目录的当前工作资源:
COPY /dir1/dir2/file3
Destination: http://www.example.com/$svn/wrk/.../file3
CHECKOUT /dir1/dir3/
(返回该目录的一个当前工作资源URL)
DELETE /$svn/wrk/.../
我们将会在/dir1下创建新的子目录(dir4)。由于还没有检出/dir1,我们这样做:
CHECKOUT /dir1/
(返回该目录的一个当前工作资源URL)
现在我们把正确的目录复制到新的当前工作资源:
COPY /dir1/dir2/
Destination: http://www.example.com/$svn/wrk/.../dir4/
COPY在服务器上创建了完整的一组当前工作资源,我们只需删除不再需要的那部分:
DELETE: /$svn/wrk/.../dir4/file3