🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### Subversion和DeltaV 所以Subversion与其他DeltaV的兼容性如何?两个字:不好,至少在Subversion 1.0还不好。 当libsvn_ra_dav发送DeltaV到服务器,Subversion客户端*不是*一个普通目的的DeltaV客户端。实际上,它希望服务器一些自定义的特性(特别是通过自定义的`REPORT`请求)。更进一步,mod_dav_svn*不是*一个普通目的的DeltaV服务器,它只实现了DeltaV的一个严格子集,一个更加普通的WebDAV或DeltaV客户端可能与之很好的交互工作,但是只有在服务器非常窄的已经实现的特性范围之内。Subversion开发团队计划会设法在以后的版本中完成普通的WebDAV交互性。 ### 影射Subversion到DeltaV 这里是多种Subversion客户端如何使用DeltaV操作的一个非常“高级别”描述。在很多种情况下,这些解释过于粗略,这*不*能作为阅读Subversion源代码和与开发者交谈的替代。 svn checkout/list 对集合执行一个深度为1的`PROPFIND`来得到直接孩子的列表,对每个孩子执行一个`GET`(也可能是一个`PROPFIND`),递归到集合并且重复。 svn commit 使用`MKACTIVITY`创建一个活动,然后对每个修改项目执行一个`CHECKOUT`,紧跟一个对新数据的`PUT`。最终,一个`MERGE`请求导致一个隐含的对所有工作资源的`CHECKIN`。 svn update/switch/status/merge/diff 发送一个自定义的描述工作拷贝混合修订版本(和混合URL)状态的`REPORT`请求,服务器发送一个描述需要更新的项目和文件内容增量数据的响应。解析响应,对于update和switch,在工作拷贝安装新数据,对于diff和merge,与工作拷贝的数据比较,应用修改作为本地修改。 ### 自动版本化支持 在写作的时候,有一个事实就是这个世界只有很少的DeltaV客户端;RFC 3253一直是相对比较新。然而用户有一些“普通的”客户端,因为几乎所有的现代操作系统现在拥有集成的基本WebDAV客户端,因为这一点,Subversion开发者认识到如果Subversion 1.0可以支持DeltaV自动版本化这一交互特性会是最好的方法。 为了激活mod_dav_svn的自动版本化,使用`httpd.conf``Location`区块的`SVNAutoversioning`指示,例如: ~~~ <Location /repos> DAV svn SVNPath /absolute/path/to/repository SVNAutoversioning on </Location> ~~~ 通常情况下,如果一个原始的WebDAV客户端尝试`PUT`到你的版本库位置的一个路径,mod_dav_svn会直接拒绝这个请求。(通常只允许对于DeltaV“活动”里面的对于“工作资源”的操作。)通过打开`SVNAutoversioning`,无论何时,服务器会把`PUT`请求转化为内部的`MKACTIVITY`、`CHECKOUT`、`PUT`和`CHECKIN`。一个普通的日志信息是自动生成的,并且创建一个新的文件系统修订版本。 因为有这样多的操作系统已经集成了WebDAV能力,这个特性的用例近似于空想:想象一个普通用户运行Microsoft Windows或Mac OS的办公室,每个电脑“装配”了一个Subversion版本库,作为一个普通的网络共享。他们向普通目录一样操作服务器:从服务器打开文件,修改并且保存回服务器。但在这个幻想中,服务器自动版本化所有的事情,之后,一个系统管理员可以使用Subversion客户端来查找和检索所有旧的版本。 这个幻想是现实吗?完全不是,主要的障碍是Subversion 1.0不支持WebDAV的`LOCK`方法`UNLOCK`,大多数操作系统的DAV客户端尝试`LOCK`一个直接从DAV装配的网络共享的资源,到目前为止,用户必须要把文件从DAV共享拷贝到本地磁盘,编辑文件,然后再拷贝回去。没有理想的自动版本化,但还是可行的。 ### 选择mod_dav_lock Apache模块mod_dav是一个复杂的野兽:它理解和解析所有的WebDAV和DeltaV方法,然而它依赖于后端“提供者”来访问资源本身。 在最简单的化身里,一个用户可以使用mod_dav_fs可以作为mod_dav的提供者,mod_dav_fs使用普通的文件系统来存放文件和目录,只理解平凡的WebDAV方法,不是DeltaV。 在另一方面,Subversion使用mod_dav_svn作为mod_dav的提供者,mod_dav_svn理解除了`LOCK`以外的所有WebDAV方法,并且理解相当大的DeltaV方法子集,它访问Subversion版本库的数据,而不是真实的文件系统。Subversion 1.0不支持锁定,因为这会非常难于实现,因为Subversion使用拷贝-修改-合并模型。 在Apache httpd-2.0里,mod_dav可以通过追踪私有数据库的锁来支持`LOCK`方法,假定提供者会乐于接受这一点。在Apache httpd-2.1或以后的版本,这个锁定支持会拆到一个独立的模块,mod_dav_lock。它允许任何mod_dav提供者利用锁数据库的好处,包括mod_dav_svn,即使mod_dav_svn实际上不理解锁定。 感到困惑? 简言之,你可以使用Apache httpd-2.1(或更晚的)的mod_dav_lock来创建一个错觉,也就是mod_dav_svn负责了`LOCK`操作。确定mod_dav_lock已经编译到httpd或已经在`httpd.conf`中加载,然后只需要在`Location`简单的添加如下的`DAVGenericLockDB`指示: ~~~ <Location /repos> DAV svn SVNPath /absolute/path/to/repository SVNAutoversioning on DavGenericLockDB /path/to/store/locks </Location> ~~~ 这个技术是一个有危险的业务;在一些情况,mod_dav_svn现在已经接近WebDAV客户端,它宣称接受`LOCK`请求,但是实际上锁并不是在所有的级别上强制执行。如果第二个WebDAV客户端尝试`LOCK`锁住同样的资源,然后mod_dav_lock会注意到并且正确的拒绝这个请求,但是完全没有办法来防止一个普通的Subversion客户端使用**svn commit**来修改文件!如果你使用这个技术,你给用户权利来践踏其他人的修改,更具体一点,一个WebDAV客户端会不小心覆盖普通Subversion客户端提交的修改。 在另一方面,如果你小心设置你的环境变量,你会减轻这个风险,例如,如果*所有*用户使用WebDAV客户端(而不是Subversion客户端),然后事情变得美好了。 Subversion可能有一天会开发一个保留检出的锁定模型,可以与拷贝-修改-合并和平相处,但是可能不会立刻发生。