设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

在Subversion中使用WebDAV

2014-12-5 13:35| 发布者: joejoe0332| 查看: 4367| 评论: 0|原作者: douxingxiang, donhui, 倚天屠龙之金毛狮王, f4f|来自: oschina

摘要: 本文详叙了WebDAV怎样用于Subversion。特别是,客户端怎么用Neon生成WebDAV请求,以及服务器端怎么将WebDAV请求转变成Subversion代码仓库的操作。这里的服务器端是一个作为mod_dav功能后端的Apache 2.0模块。 ...

  本文详叙了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概念

  Subversion使用了许多Deltav概念, 列表如下. 注意这些概念中有很多并没有被Subversion完全实现; 我们已经实现了足够的概念以满足我们的需要,但是比较少.

  • 基线

  • 活动

  • 版本资源

  • 版本控制配置

  • 基线集合

  • 版本控制的资源

  • 工作资源(功能)

  • 合并功能

  • 标签功能

  • 版本控制集合功能


Subversion项目表现为URL形式

  第一个要定义的概念是项目是如何显示给客户端的。 在服务端Subversion将所有项目表现为URL的形式。 这个项目下的文件或子目录将通过URL命名空间被表现。


  例如,假设我们有一个叫做“example”的项目。并且我们说,这个项目将被表现为这个URL: http://subversion.tigris.org/repos/example/。

这个映射通过Apache HTTP Server(在问题中托管Subversion代码和特定项目)的一系列配置参数被设置。配置可能像下面这样:

<Location /repos/example>
    DAV svn
    SVNPath /home/svn-projects/example
</Location>

  这个项目下的文件或目录将直接被映射到URL命名空间。例如,如果这个项目在一个子目录“sub”中包含一个文件“file.c”,那么那个文件的URL将是:      http://subversion.tigris.org/repos/example/sub/file.c。


初始检出

  当用户执行一个Subversion项目的初始检出操作,客户端将发出一连串的PROPFINDGET请求。这些请求将遍历版本库,获得一些所需的元数据, 然后获得最新的修订版本号.描述获取活动集合的OPTIONS请求。描述到达基线集合的一系列PROPFIND请求。


  (从下面移到这里,需要被重写)


  当初始化检出操作被执行后, Subversion获取到DAV:活动集合给定值并在工作副本的每个目录中将其存储为属性。每个集合都有属性。属性列出了服务端活动被创建的位置。第一个位置被存储在客户端用来在提交过程中使用。


  或许应该描述我们获取元数据后,检出“非最新的”(如日期或修订版本号)如何工作。


提交变更

  Subversion提交使用Deltav的“活动”概念来建模。一个活动能够被看做是一次传输一系列资源。


创建活动

  在提交的时候, Subversion客户端将读取存储的DAV:DAV:activity-collection-set用来了解应该在哪里创建活动。 接下来,客户端将为活动的位置生成一个UUID(惟一值) 。最后客户端发送一个MKACTIVITY方法请求, 请求的URL从活动位置和UUID被表现。zh

简短总结:

  • 在检出时:

  • 请求: OPTIONS for DAV:activity-collection-set

    响应:http://www.example.com/repos/foo/$svn/act/

  • 在提交时:

  • 请求: MKACTIVITY http://www.example.com/repos/foo/$svn/act/01234567-89ab-cdef-0123-456789abcdef 

    响应: 201 (Created)

  CHECKOUT方法能够指定一个活动用来检出。 这个功能用于关联所有的条目和新创建的活动。


存储提交信息

检出基线,并对工作基线应用PROPPATCK方法。

将变更映射到WebDAV

Subversion的变更集用tree delta表示(查看SVN的设计细节以确定那些变更可以放进tree delta)。tree delta会被拆成请求集,其中请求是以下几种形式之一:

  • 删除文件或目录
    这些变更被映射成DELETE操作。目标父集的版本资源使用CHECKOUT方法检出(到当前活动)。目标(名称)随后被DELETE方法从结果工作集删除。    

  • 添加文件
    这种变更会映射为对目标父集的版本资源进行CHECKOUT操作。新文件被使用PUT请求创建于结果工作集。属性使用PROPPATCH设置。    

  • 添加目录
    这种变更被映射为对目标父集的版本资源进行CHECKOUT操作。新目录被使用MKCOL请求创建于结果工作集。属性通过PROPPATCH设置。   

  • 添加指向前代祖先(副本)的文件或目录(这种文件或目录类似linux的文件链接?)
    需要更新本节
    tree delta可以指定文件或目录为其他文件或目录的一份副本。这个副本可被其他元素的tree delta修改。
    这种变更被映射为,对包含新资源的父集的版本资源进行CHECKOUT操作。VERSION-CONTROL方法会在当前工作集内创建新的版本控制资源(VCRs),VCR的DAV:checked-in属性指向其祖先的版本资源。

  • 提示:看起来我们应该使用COPY把正确资源拷入当前工作集。这将会创建一个新的版本历史(随后被放入当前工作集),该版本历史使用DAV:precursor-set属性指定其祖先的版本资源。

    由于版本资源不指定修订版,不可能COPY一个版本资源到当前工作集,此举不会通知我们究竟是哪个修订版被拷贝。相反,我们最好从正确的基线中拷出版本资源。这表明,客户端可以把一个URL/修订版对映射为基线的版本资源URL。   
    第二个问题时,我们如何设置版本历史的   DAV:precursor-set属性。或者,更详细点,我们如何根据存储在仓库的信息提取该值。这仍需要研究。 
  • 用文件/目录替换另一个文件/目录
    这种变更不能对应WebDAV的任何操作,因为tree delta会映射为两个连续的操作:先delete然后add   

  • 移动文件或目录
    这种变更不能对应WebDAV的任何操作,因为tree delta会映射为两个不同的操作:先delete然后add前代祖先。    

  • 替换文件
    映射为对目标的版本资源进行CHECKOUT操作,然后PUT到结果工作集。   

  • 替换目录
    在Subversion的术语中,“替换目录”意味着目录内的添加、删除及其他操作。每个变更会单独映射,而且对目录的变更是隐式操作的。     

  • 属性delta
    属性delta(与文件或目录相对)直接被映射为WebDAV术语中的PROPPATCH。目标的版本资源使用CHECKOUT检出,PROPPATCH会应用于结果工作集。


最终提交

  最后的提交动作将会向Subversion服务器生成一个MERGE请求,指定检入的活动(之前创建),以及被更新的指向新版本资源的相应版本控制资源。


  关于当前工作基线,以及如果用其创建新的基线(包含提交信息),下文的评论(?)并不正确。


  版本控制资源也是基线控制的,即对它的更新会自动创建一个新基线。本质上,提交会相应于新的Subversion修订版创建一个新基线。


例子

警告: 本节没有更新到最新对SVN-to-DAV的映射的变更,在此警告移除前,暂认为本节已过期。

考虑下以下一组操作,以及相应的tree delta(摘自SVN的设计文档):

  1. 重命名/dir1/dir2为/dir1/dir4,

  2. 重命名/dir1/dir3为/dir1/dir2, 并且

  3. 把file3从/dir1/dir4移动到/dir1/dir2.

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中的一组元素。

  1. <directory ancestor="/dir1/dir3"> 指定我们用/dir1/dir3替换/dir1/dir2

    CHECKOUT /dir1/dir2/
     (返回该目录的一个当前工作资源URL) 

    COPY /dir1/dir3/
     Destination: http://www.example.com/$svn/wrk/.../
     Overwrite: T

  2. /dir1/dir2/file3是新的(因为我们刚刚重写了原始的dir2目录),并来源于/dir1/dir2/file3。因此,我们只需要COPY文件到目标目录的当前工作资源:

    COPY /dir1/dir2/file3
     Destination: http://www.example.com/$svn/wrk/.../file3

  3. CHECKOUT /dir1/dir3/
     (返回该目录的一个当前工作资源URL) 

    DELETE /$svn/wrk/.../

  4. 我们将会在/dir1下创建新的子目录(dir4)。由于还没有检出/dir1,我们这样做:

    CHECKOUT /dir1/
     (返回该目录的一个当前工作资源URL) 

    现在我们把正确的目录复制到新的当前工作资源:

    COPY /dir1/dir2/
     Destination: http://www.example.com/$svn/wrk/.../dir4/

  5. COPY在服务器上创建了完整的一组当前工作资源,我们只需删除不再需要的那部分:

    DELETE: /$svn/wrk/.../dir4/file3



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部