术语表

最后更新于:2022-04-02 06:00:33

### 术语表 ### A administrative subdirectory (管理目录) 通常是工作目录中的`.svn`目录,保存了帮助Subversion工作的文件。 administrative area (管理区域) 管理目录的一种更抽象的说法。 authentication challenge (认证请求) 服务器向客户端发出要求提供认证信息的动作叫做认证请求。 ### B Branch (分支) 分支是一种特殊的版本形式,我们可以对文件或项目分出一个并行开发的版本,对这个并行开发的版本进行修改,然后将分支版本的修改合并到主干上来。 ### C check in (检入) 文件的检入是指将自己的工作拷贝提交到配置管理系统的文件库中,使得他人可以从文件库中获取你的最新修改版本。 check out(检出) 文件的检出是指从配置管理系统的文件库中取出一个副本作为自己的工作拷贝,并在这个工作拷贝上进行自己的工作。 ### D delta(增量) 提交时只提交区别,也就是增量的模式。 directive(指示) Apache配置文件中的配置选项。 dump format(转储格式) 从版本库里导出的文件的一种格式。 ### P porting changes(搬运修改) 合并两个分支的行为称作搬运修改。 pristine copy(原始拷贝) Subversion在管理区域为每个文件保留了一个备份,这是上一个版本(叫做“BASE”版本)没有修改的(没有关键字扩展,没有行结束翻译,没有任何其他区别)拷贝。 ### R Repository(版本库) 存储所有修订版本历史记录的地方。 Revision(修订版本) 文件的版本和项目的版本是不同的,对于文件来说,每次修改后提交都会产生一个新的修订版本号,从版本控制系统中可以找到从文件创建到最后一次提交的每一个版本,对于文本格式的文件,通过一些比较工具(版本控制系统中的或第三方的)可以比较每一个版本之间的不同。 ### U unified diff format(标准区别格式) 标示文件区别的一种格式。 *U*niversal *U*nique *ID*entifier(全局唯一标示) 每一个版本库都有唯一的UUID。 ### V Vendor branches(卖主分支) 当开发软件时有这样一个情况,你版本控制的数据可能关联于或者是依赖于其他人的数据,为此建立的分支叫做卖主分支。 ### W work copy(工作拷贝) 从配置管理系统的文件库中取出的保存在本地的文件副本。
';

Subversion和DeltaV

最后更新于:2022-04-02 06:00:31

### 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`指示,例如: ~~~ DAV svn SVNPath /absolute/path/to/repository SVNAutoversioning on ~~~ 通常情况下,如果一个原始的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`指示: ~~~ DAV svn SVNPath /absolute/path/to/repository SVNAutoversioning on DavGenericLockDB /path/to/store/locks ~~~ 这个技术是一个有危险的业务;在一些情况,mod_dav_svn现在已经接近WebDAV客户端,它宣称接受`LOCK`请求,但是实际上锁并不是在所有的级别上强制执行。如果第二个WebDAV客户端尝试`LOCK`锁住同样的资源,然后mod_dav_lock会注意到并且正确的拒绝这个请求,但是完全没有办法来防止一个普通的Subversion客户端使用**svn commit**来修改文件!如果你使用这个技术,你给用户权利来践踏其他人的修改,更具体一点,一个WebDAV客户端会不小心覆盖普通Subversion客户端提交的修改。 在另一方面,如果你小心设置你的环境变量,你会减轻这个风险,例如,如果*所有*用户使用WebDAV客户端(而不是Subversion客户端),然后事情变得美好了。 Subversion可能有一天会开发一个保留检出的锁定模型,可以与拷贝-修改-合并和平相处,但是可能不会立刻发生。
';

自动版本化交互性

最后更新于:2022-04-02 06:00:29

### 自动版本化交互性 在这个小节,我们会描述最普通的原始WebDAV客户端(写作的时刻),和它们是如何与使用`SVNAutoversioning`指示的mod_dav_svn服务器的运作。RFC 2518是一个有点大,并且有一点太灵活。每个WebDAV客户端的行为都有些许区别,并且产生许多不同的小问题。 ### Win32网络文件夹 Windows 98、2000和XP有一个集成的WebDAV客户端叫做“网络文件夹”,在Windows 98,这个特性需要明确安装;如果提供,一个“网络文件夹”就会出现在我的电脑,在Windows 2000和XP,只需要简单得打开我的网络位置,运行添加网络位置图标。当出现提示,输入一个WebDAV的URL,我的网络位置中就会出现一个共享文件夹。 大多数写操作对于自动版本化的mod_dav_svn服务器工作正常,但是有一些问题: - 如果一个Windows XP电脑是一个NT域的成员,它看起来不能连接到WebDAV共享,重复提示要输入用户名和密码,即使Apache服务器没有要求进行认证!如果这个机器不是NT域的一部分,这个共享可以成功装载。 这个问题源于Windows XP创建网络文件夹快捷方式(`.lnk`文件)的方法的bug。它有时候会使用“UNC” (Universal Naming Convention) 路径来代替WebDAV共享URL,这导致资源管理器尝试使用SMB而不是HTTP来进行连接。 这个问题的解决方法是在Windows 2000创建`.lnk`快捷方式,然后拷贝到Windows XP电脑,如果有人可以逆转`.lnk`文件的格式,也可以使用十六进制编辑器来“修正”快捷方式。 - 一个文件不可以直接在共享中打开编辑;它可能一直是只读的。mod_dav_lock技术也无能为力,因为网络文件夹根本不使用`LOCK`方法,前面提到的“拷贝、编辑和再拷贝”根本不工作。在共享中的文件可以成功的被本地修改的拷贝覆盖。 ### Mac OS X Apple的OS X操作系统也集成了WebDAV客户端,从Finder选择Go菜单的“Connect to Server”,输入一个WebDAV的URL,它会作为一个磁盘在桌面出现,就像任何文件服务器。 很不幸,客户端拒绝与一个自动版本化的mod_dav_svn工作,因为它缺乏`LOCK`支持,Mac OS X在初始化HTTP的`OPTIONS`特性交换时会发现缺失了`LOCK`能力,因而决定以只读方式装配Subversion版本库,之后,不可以进行写操作。为了将版本库按照读写方式装配,你*必须*使用前面讨论的mod_dav_lock技巧。一旦锁定看起来工作了,共享会运作良好:文件可以直接以读/写模式打开,尽管每次存储操作会导致客户端对临时位置执行一个`PUT`,对原文件的`DELETE`操作和把临时资源`MOVE`到原文件。每次存盘会产生三个新的Subversion修订版本! 还要警告一点:OS X的WebDAV客户端可以对HTTP重定向完全敏感,如果你不能装配版本库,你可以在`httpd.conf`开启`BrowserMatch`指示: ~~~ BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully ~~~ ### Unix: Nautilus 2 Nautilus是GNOME桌面的官方文件管理器/浏览器,它的主页在`http://www.gnome.org/projects/nautilus/`,只需要在Nautilus窗口中输入一个WebDAV的URL,DAV共享就会像本地磁盘一样出现。 通常情况下,Nautilus 2与自动版本化的mod_dav_svn一起工作相当的好,只是有下面一些警告: - 任何在共享里直接打开的文件是只读的,即使mod_dav_lock的技巧也看起来无效。Nautilus看起来从没有关注过`LOCK`方法,“本地拷贝、编辑和拷贝回去”的技巧还可以工作,但是很不幸,Nautilus的覆盖旧文件是通过首先`DELETE`进行的,这创建了一个额外的修订版本。 - 当覆盖或创建一个文件,Nautilus首先`PUT`一个空文件,然后使用第二个`PUT`覆盖它,这创建了两个Subversion文件系统修订版本,而不是一个。 - 当删除了一个集合,它对每个独立的孩子而不是集合本身发出HTTP的`DELETE`操作,这会创建一系列新的修订版本。 ### Linux davfs2 Linux davfs2是一个Linux内核的文件系统模块,它的开发位于`http://dav.sourceforge.net/`。一旦安装,一个WebDAV网络共享可以使用普通的Linux的**mount**命令装配。 一个公开的秘密就是DAV客户端不会与mod_dav_svn的自动版本化完全工作正常,即使一个单独对服务器的写尝试需要`LOCK`请求作为前提,而这是mod_dav_svn不支持的。此时,还没有数据表明是否可以使用mod_dav_lock解决这个问题。 Unix用户也可以运行**mount -t webdav URL /mountpoint**。
';

附录C.WebDAV和自动版本化

最后更新于:2022-04-02 06:00:26

### 附录C.WebDAV和自动版本化 **目录** WebDAV是HTTP的一个扩展,作为一个文件共享的标准不断发展。当今的操作系统变得极端的web化,许多内置了对装配WebDAV服务器导出的“共享”的支持。 如果你使用Apache/mod_dav_svn作为你的Subversion网络服务器,某种程度上,你也是在运行一个WebDAV服务器。这个附录提供了这种协议一些背景知识,Subversion如何使用它,Subversion如何和认识WebDAV的软件交互工作。 ### WebDAV基本概念 这个小节提供了对WebDAV背后思想的一个非常简短和普通的总体看法,为理解WebDAV在客户端和服务器之间的兼容性问题打下基础。 ### 仅是平常的WebDAV RFC 2518为HTTP 1.1定义了一组概念和附加扩展方法来把web变成一个更加普遍的读/写媒体,基本思想是一个WebDAV兼容的web服务器可以像普通的文件服务器一样工作;客户端可以装配类似于NFS或SMB的WebDAV“共享”。 然而,必须注意到RFC 2518并*没有*提供任何版本控制模型,尽管DAV中有“V”。基本的DAV客户端和服务器只是假定每个文件或目录只有一个版本存在,可以重复的覆盖。 这是基本的WebDAV引入的新概念和方法: 新的写方法 超出了标准HTTP的`PUT`方法(用来创建和覆盖web资源),WebDAV定义了新的`COPY`和`MOVE`方法用来复制或重新组织资源。 集合 这是一个简单的WebDAV术语用来表示一组资源(URI),在大多数情况下,你可以说以“/”结尾的东西是一个集合,文件资源可以使用`PUT`方法写或创建,而集合资源使用`MKCOL`方法创建。 属性 这与Subversion中是同一个思想―附加在文件和集合上的元数据,一个客户端可以使用新方法`PROPFIND`列出或检索附加在一个资源上的属性,也可以使用`PROPPATCH`方法修改这些属性。一些属性是完全由用户控制的(例如,一个“color”属性),还有一些是WebDAV服务器创建和控制的(例如,一个保存文件最后修改时间的属性)。前一种叫做“dead”属性,后一种叫做“live”属性。 锁定 WebDAV服务器可以决定为客户端提供一个锁定特性―这部分的规范是可选的,尽管大多数WebDAV服务器提供了这个特性。如果提供这个特性,客户端可以使用新的`LOCK`和`UNLOCK`方法来调节访问资源的过程,在大多数情况下是使用独占写锁(在[“锁定-修改-解锁 方案”一节]讨论的),尽管共享写锁也是可以的。 ### DeltaV扩展 因为RFC 2518漏下了版本概念,另一个小组留下来负责撰写RFC 3253来添加WebDAV的版本化。WebDAV/DeltaV客户端和服务器经常叫做“DeltaV”客户端和服务器,因为DeltaV暗含了基本的WebDAV。 DeltaV引入了完全的新的首字母缩写,但并不是被逼迫的。想法相当的直接,如下是DeltaV引入的新概念和方法: 每资源的版本化 像CVS和其他版本控制系统,DeltaV假定每个资源有一个潜在的无穷的状态,一个客户端可以使用`VERSION-CONTROL`放置一个版本控制之下的资源,这创建了一个新的版本控制资源(VCR),每次你修改VCR(通过`PUT`、`PROPPATCH`等),这个资源的新状态就会创建,叫做一个版本资源(Version Resource,VR)。VCR和VR还是普通的web资源,使用URL定义,特定的VR也会拥有易读的名字。 服务器端的工作拷贝模型 一些DeltaV服务器支持在服务器创建虚拟“工作区”,所有的工作在这里执行。客户端使用`MKWORKSPACE`方法来创建私有区域,然后他们说明修改特定的VCR,“把它们检出到”工作拷贝,编辑,然后再次“检入”。在HTTP术语里,方法的顺序可能是`CHECKOUT`、`PUT`、`CHECKIN`,会创建一个新的VR,每个VCR也有一个“历史”资源用来追踪和排序它的各种VR状态。 客户端工作拷贝模型 一些DeltaV服务器也支持客户端可以有完全特定VR的私有工作拷贝的思想,(这就是CVS和Subversion的工作原理。)当客户端希望提交修改到服务器,它通过使用`MKACTIVITY`方法创建一个临时服务器事务(叫做一个活动)开始。然后客户端在每个希望修改的VR上执行一个`CHECKOUT`操作,这在活动里创建了一些临时“工作资源”,然后可以使用`PUT`和`PROPPATCH`方法修改。最后,客户端对每个工作资源执行一个`CHECKIN`,在每个VCR创建了一个VR,并且整个活动会被删除。 配置 DeltaV允许你定义叫做“配置”的灵活的VCR集合,不需要对应特定的目录,每个VCR的内容可以使用`UPDATE`方法指向特定的VR。一旦配置是理想的,客户端可以创建一个整个配置的“快照”,叫做“基线”。客户端使用`CHECKOUT`和`CHECKIN`方法捕捉特定的配置状态,很像它们使用这些方法创建VCR的特定VR状态。 扩展性 DeltaV定义了新方法`REPORT`,允许客户端和服务器执行自定义的数据交换。客户端发送一个带有包含自定义数据的完全标记的XML主体的`REPORT`请求;假定服务器理解特定的报告类型,它使用一个等同的XML主体来响应,这个技术与XML-RPC很类似。 自动版本化 对大多数,这是DeltaV的“杀手”特性,如果DeltaV服务器支持这个特性,然后基本的WebDAV客户端(例如,那些不知道版本化的客户端)仍然可以对服务器进行写操作,服务器可以悄无声息的执行版本操作。在最简单的例子里,一个从基本的WebDAV客户端发送的无知的`PUT`可能会被服务器转化为`CHECKOUT`、`PUT`、`CHECKIN`。 因为这个原因,一些人开玩笑说WebDAV的客户端是“WebDA”客户端!
';

转化CVS版本库到Subversion

最后更新于:2022-04-02 06:00:24

### 转化CVS版本库到Subversion 或许让CVS用户熟悉Subversion最好的办法就是让他们的项目继续在新系统下工作,这可以简单得通过平淡的把CVS版本库的导出数据导入到Subversion完成,或者是更加完全的方案,不仅仅包括最新数据快照,还包括所有的历史,从一个系统到另一个系统。这是一个非常困难的问题,包括推导保持原子性的修改集,转化两个系统完全不同的分支政策。但是我们还是有许多工具声称至少部分具备了的转化已存在的CVS版本库为Subversion版本库的能力。 其中一个工具是cvs2svn(`http://cvs2svn.tigris.org/`),是一个Python脚本,最初是Subversion自己的开发社区的成员编写的。其他的如Chia-liang Kao的Subversion的VCP工具(`http://svn.clkao.org/revml/branches/svn-perl/`)转化器插件,还有Lev Serebryakov的RefineCVS(`http://lev.serebryakov.spb.ru/refinecvs/`)。这些工具具备不同程度的完成性,也许会具备完全不同的处理CVS历史的方法。无论你决定使用哪个工具,确定要执行尽可能多的验证来确定你可以接受转化结果―毕竟,你曾经努力创建这些历史! 关于最新的转化工具链接列表,可以访问Subversion的网站(`http://subversion.tigris.org/project_links.html`)。
';

认证

最后更新于:2022-04-02 06:00:22

### 认证 通过CVS的pserver,你需要在读写操作之前“登陆”到服务器―即使是匿名操作。Subversion版本库使用Apache的**httpd**或**svnserve**作为服务器,你不需要开始时提供认证凭证―如果一个操作需要认证,服务器会要求你的凭证(不管这凭证是用户名与密码,客户证书还是两个都有)。所以如果你的工作拷贝是全局可读的,在所有的读操作中不需要任何认证。 相对于CVS,Subversion会一直在磁盘(在你的`~/.subversion/auth/`目录)缓存凭证,除非你通过`--no-auth-cache`选项告诉它不这样做。 这个行为也有例外,当使用SSH管道的**svnserve**服务器时,使用`svn+ssh://`的URL模式这种情况下,**ssh**会在通道刚开始时无条件的要求认证。
';

版本化的模块

最后更新于:2022-04-02 06:00:20

### 版本化的模块 不像CVS,Subversion工作拷贝会意识到它检出了一个模块,这意味着如果有人修改了模块的定义(例如添加和删除组件),然后一个对**svn update**的调用会适当的更新工作拷贝,添加或删除组件。 Subversion定义了模块作为一个目录属性的目录列表:见[“外部定义”一节](# "外部定义")。
';

二进制文件和转化

最后更新于:2022-04-02 06:00:17

### 二进制文件和转化 在大多数情况下,Subversion比CVS更好的处理二进制文件,因为CVS使用RCS,它只可以存储二进制文件的完整拷贝,但是,从内部原理上讲,Subversion使用二进制区别算法来表示文件的区别,而不管文件是文本文件还是二进制文件。这意味着所有的文件是以微分的(压缩的)形式存放在版本库,小的区别会通过网络传输。 CVS用户需要使用`-kb`选项来标记二进制文件,防止数据的混淆(因为关键字解释和行结束转化),他们有时候会忘记这样做。 Subversion使用更加异想天开的方法:第一,如果你不明确的告诉它(详情见[“`svn:keywords`”一节](# "svn:keywords")和[“`svn:eol-style`”一节](# "svn:eol-style"))这样做,它不会做任何关键字或行结束转化的操作,缺省情况下Subversion会把所有的数据看作字节串,所有的储存在版本库的文件都处于未转化的状态。 第二,Subversion维护了一个内部的概念来区别一个文件是“文本”还是“二进制”文件,但这个概念*只*在工作拷贝非常重要,在**svn update**,Subversion会对本地修改的文本文件执行上下文的合并,但是对二进制文件不会。 为了检测一个上下文的合并是可能的,Subversion检测`svn:mime-type`属性,如果没有`svn:mime-type`属性,或者这个属性是文本的(例如`text/*`),Subversion会假定它是文本的,否则Subversion认为它是二进制文件。Subversion也会在**svn import**和**svn add**命令时通过运行一个二进制检测算法来帮助用户。这些命令会做出很好的猜测,然后(如果可能)设置添加文件的`svn:mime-type`属性。(如果Subversion猜测错误,用户可以删除或手工编辑这个属性。)
';

冲突解决

最后更新于:2022-04-02 06:00:15

### 冲突解决 CVS使用内联“冲突标志”来标记冲突,并且在更新时打印`C`。历史上讲,这导致了许多问题,因为CVS做得还不够。许多用户在它们快速闪过终端时忘记(或没有看到)`C`,即使出现了冲突标记,他们也经常忘记,然后提交了带有冲突标记的文件。 Subversion通过让冲突更明显来解决这个问题,它记住一个文件是处于冲突状态,在你运行**svn resolved**之前不会允许你提交修改,详情见[“解决冲突(合并别人的修改)”一节](# "解决冲突(合并别人的修改)")。
';

元数据属性

最后更新于:2022-04-02 06:00:13

### 元数据属性 Subversion的一个新特性就是你可以对文件和目录任意附加元数据(或者是“属性”),属性是关联在工作拷贝文件或目录的任意名称/值对。 为了设置或得到一个属性名称,使用**svn propset**和**svn propget**子命令,列出对象所有的属性,使用**svn proplist**。 更多信息见[“属性”一节](# "属性")。
';

分支和标签

最后更新于:2022-04-02 06:00:11

### 分支和标签 Subversion不区分文件系统空间和“分支”空间;分支和标签都是普通的文件系统目录,这恐怕是CVS用户需要逾越的最大心理障碍,所有信息在[第4章 *分支与合并*](# "第4章分支与合并")。 ### 警告 因为Subversion把分支和标签看作普通目录看待,一直要记住检出项目的`trunk`(`http://svn.example.com/repos/calc/trunk/`),而不是项目本身的(`http://svn.example.com/repos/calc/`)。如果你错误的检出了项目本身,你会紧张的发现你的项目拷贝包含了所有的分支和标签。[[45](#)] [[45](#)] 如果在检出完成之前没有消耗完磁盘空间的话。
';

区分状态和更新

最后更新于:2022-04-02 06:00:08

### 区分状态和更新 在Subversion,我们已经设法抹去**cvs status**和**cvs update**之间的混乱。 **cvs status**命令有两个目的:第一,显示用户在工作拷贝的所有本地修改,第二,显示给用户哪些文件是最新的。很不幸,因为CVS难以阅读的状态输出,许多CVS用户并没有充分利用这个命令的好处。相反,他们慢慢习惯运行**cvs update**或**cvs update -n**来快速查看区别,如果用户忘记使用`-n`选项,副作用就是将还没有准备好处理的版本库修改合并到工作拷贝。 对于Subversion,我们通过修改**svn status**的输出使之同时满足阅读和解析的需要来努力消除这种混乱,同样,**svn update**只会打印将要更新的文件信息,而*不是*本地修改。 **svn status**打印所有本地修改的文件,缺省情况下,不会联系版本库,然而这个命令接受一些选项,如下是一些最常用的: `-u` 联系版本库来确定,然后显示,过时的信息。 `-v` 显示*所有*版本控制之下的条目。 `-N` 非递归运行(不传递到子目录)。 **status**命令有两种输出格式,缺省是“简短”格式,本地修改看起来是这样: ~~~ % svn status M ./foo.c M ./bar/baz.c ~~~ 如果你指定`--show-updates`(`-u`),输出会使用比较长的格式: ~~~ % svn status -u M 1047 ./foo.c * 1045 ./faces.html * - ./bloo.png M 1050 ./bar/baz.c Status against revision: 1066 ~~~ 在这个例子里,有两个新列,如果文件或目录已经过期了,第二列会显示星号。第三列显示工作拷贝项目的修订版本号,在上面的例子里,星号表示`faces.html`会在更新时更新,而`bloo.png`是在版本库新加的文件。(`bloo.png`前面的`-`表示它不曾存在与工作拷贝。) 最后,你会想看一个常见状态码的快速总结: ~~~ A 资源预定要添加 D 资源预定要删除 M 资源有本地修改 C 资源发生冲突(修改不能完全在版本库和 工作拷贝之间合并) X 资源在工作拷贝之外(来自其他版本库, 见“ ~~~ svn:externals ~~~ ”一节) 资源不在版本控制之下 ! 资源丢失或者不完整(被Subversion以外的工具删除) ~~~ Subversion合并了CVS的`P`和`U`代码为`U`,当一个合并或冲突发生,Subversion只会简单得打印`G`或`C`,而不是一段完整的描述语句。 关于**svn status**的详细讨论见[“**svn status**”一节]( "svn status")。
';

更多离线操作

最后更新于:2022-04-02 06:00:06

### 更多离线操作 近些年来,磁盘空间变得异常便宜和丰富,但是网络带宽还没有,因此Subversion工作拷贝为紧缺资源进行了优化。 `.svn`管理目录维护者与`CVS`同样的功能,除了它还保存了只读的文件“原始”拷贝,这允许你做许多离线操作: **svn status** 显示你所做的本地修改(见[“**svn status**”一节](# "svn status")) **svn diff** 显示修改的详细信息(见see [“**svn diff**”一节](# "svn diff")) **svn revert** 删除你的本地修改(见[“**svn revert**”一节](# "svn revert")) 另外,原始文件的缓存允许Subversion客户端在提交时只提交区别,这是CVS做不到的。 列表中最后一个子命令是新的;它不仅仅删除本地修改,也会取消如增加和删除的预定操作,这是恢复文件推荐的方式;运行**rm file; svn update**还可以工作,但是这样侮辱了更新操作的作用,而且,我们在这个主题…
';

目录的版本

最后更新于:2022-04-02 06:00:04

### 目录的版本 Subversion会记录目录树的结构,不仅仅是文件的内容。这是编写Subversion替代CVS最重要的一个原因。 以下是对你这意味着什么的说明,作为一个前CVS用户: - **svn add**和**svn delete**现在也工作在目录上了,就像在文件上一样,还有**svn copy**和**svn move**也一样。然而,这些命令*不*会导致版本库即时的变化,相反,工作的项目只是“预定要”添加和删除,在运行**svn commit**之前没有版本库的修改。 - 目录不再是哑容器了;它们也有文件一样的修订版本号。(更准确一点,谈论“修订版本5的目录`foo/`”是正确的。) 让我们再讨论一下最后一点,目录版本化是一个困难的问题;因为我们希望允许混合修订版本的工作拷贝,有一些防止我们滥用这个模型的限制。 从理论观点,我们定义“目录`foo`的修订版本5”意味着一组目录条目和属性。现在假定我们从`foo`开始添加和删除文件,然后提交。如果说我们还有`foo`的修订版本5就是一个谎言。然而,如果说我们在提交之后增加了一位`foo`的修订版本号码,这也是一个谎言;`foo`还有一些修改我们没有得到,因为我们还没有更新。 Subversion通过在`.svn`区域偷偷的纪录添加和删除来处理这些问题,当你最后运行**svn update**,所有的账目会到版本库结算,并且目录的新修订版本号会正确设置。*因此,只有在更新之后才可以真正安全地说我们有了一个“完美的”修订版本目录。*在大多数时候,你的工作拷贝会保存“不完美的”目录修订版本。 同样的,如果你尝试提交目录的属性修改会有一个问题,通常情况下,提交应该会提高工作目录的本地修订版本号,但是再一次,这还是一个谎言,因为这个目录还没有添加和删除发生,因为还没有更新发生。*因此,在你的目录不是最新的时候不允许你提交属性修改。* 关于目录版本的更多讨论见[“修订版本混合的限制”一节](# "修订版本混合的限制")。
';

附录A.Subversion对于CVS用户

最后更新于:2022-04-02 06:00:01

### 附录A.Subversion对于CVS用户 **目录** 这个附录可以作为CVS用户开始使用Subversion的指南,实质上就是鸟瞰这两个系统之间的区别列表,在每一小节,我们会尽可能提供相关章节的引用。 尽管Subversion的目标是接管当前和未来的CVS用户基础,需要一些新的特性设计来修正一些CVS“不好的”行为习惯,这意味着,作为一个CVS用户,你或许需要打破习惯―忘记一些奇怪的习惯来作为开始。 ### 修订版本号现在不同了 在CVS中,修订版本号是每文件的,这是因为CVS使用RCS作为后端;每个文件都在版本库有一个对应的RCS文件,版本库几乎就是根据项目树的结构创建。 在Subversion,版本库看起来像是一个单独的文件系统,每次提交导致一个新的文件系统;本质上,版本库是一堆树,每棵树都有一个单独的修订版本号。当有人谈论“修订版本54”时,他们是在讨论一个特定的树(并且间接来说,文件系统在提交54次之后的样子)。 技术上讲,谈论“文件`foo.c`的修订版本5”是不正确的,相反,一个人会说“`foo.c`在修订版本5出现”。同样,我们在假定文件的进展时也要小心,在CVS,文件`foo.c`的修订版本5和6一定是不同的,在Subversion,`foo.c`可能在修订版本5和6之间*没有*改变。 更多细节见[“修订版本”一节].
';

mod_dav_svn Configuration Directives

最后更新于:2022-04-02 05:59:59

### 名称 `mod_dav_svn` Configuration Directives ― Apache通过Apache HTTP服务器用来维护Subversion版本库配置指示。 ### 描述 这个小节主要描述了Subversion Apache配置的每个指示,关于Apache配置Subversion的更多信息见[“httpd,Apache的HTTP服务器”一节](# "httpd,Apache的HTTP服务器")。 ### Directives `DAV svn` 这个指示必须包含在所有Subversion版本库的`Directory`或`Location`块中,它告诉httpd使用Subversion的后端,用mod_dav来处理所有的请求。 `SVNPath` 这个指示指定Subversion版本库文件文件系统的位置,在一个Subversion版本库的配置块里,必须提供这个指示或`SVNParentPath`,但不能同时存在。 `SVNSpecialURI` 指定特定Subversion资源的URI部分(命名空间),缺省是“`!svn`”,大多数管理员不会用到这个指示。只有那些必须要在版本库中放一个名字为`!svn`的文件时需要设置。如果你在一个已经使用中的服务器上这样修改,它会破坏所有的工作拷贝,你的用户会拿着叉子和火炬追杀你。 `SVNReposName` 指定Subversion版本库在`HTTP GET`请求中使用的名字,这个值会作为所有目录列表(当你用web浏览器察看Subversion版本库时会看到)的标题,这个指示是可选的。 `SVNIndexXSLT` 目录列表所使用的XSL转化的URI,这个指示可选。 `SVNParentPath` 指定子目录会是版本库的父目录在文件系统的位置,在一个Subversion版本库的配置块里,必须提供这个指示或`SVNPath`,但不能同时存在。 `SVNPathAuthz` 控制开启和关闭路径为基础的授权,更多细节见[“关闭路径为基础的检查”一节]。
';

svnversion

最后更新于:2022-04-02 05:59:57

### 名称 svnversion ― 总结工作拷贝的本地修订版本。 ### 概要 ~~~ svnversion [OPTIONS] WC_PATH [TRAIL_URL] ~~~ ### 描述 **svnversion**是用来总结工作拷贝修订版本混合的程序,结果修订版本号或范围会写到标准输出。 如果提供TRAIL_URL,URL的尾端部分用来监测是否WC_PATH本身已经跳转(监测WC_PATH的跳转不需要依赖TRAIL_URL)。 ### 选项 像**svnserve**,**svnversion**没有子命令,只有选项。 `--no-newline` (`-n`) 忽略输出的尾端新行。. `--committed` (`-c`) 使用最后修改修订版本而不是当前的(例如,本地存在的最高修订版本)修订版本。 `--help` (`-h`) 打印帮助摘要。 `--version` 打印**svnversion**,如果没有错误退出。 ### 例子 如果工作拷贝都是一样的修订版本(例如,在更新后那一刻),会打印修订版本: ~~~ $ svnversion . 4168 ~~~ 添加TRAIL_URL来展示工作拷贝不是从你希望的地方跳转过来的: ~~~ $ svnversion . /repos/svn/trunk 4168 ~~~ 对于混合修订版本的工作拷贝,修订版本的范围会被打印: ~~~ $ svnversion . 4123:4168 ~~~ 如果工作拷贝包含修改,后面会紧跟一个"M": ~~~ $ svnversion . 4168M ~~~ 如果工作拷贝已经跳转,后面会有一个"S": ~~~ $ svnversion . 4168S ~~~ 因此,这里是一个混合修订版本,跳转的工作拷贝包含了一些本地修改: ~~~ $ svnversion . 4212:4168MS ~~~ 如果从一个目录而不是工作拷贝调用,**svnversion**假定它是一个导出的工作拷贝并且打印"exported": ~~~ $ svnversion . exported ~~~
';

svnserve

最后更新于:2022-04-02 05:59:55

### **svnserve** **svnserve**允许Subversion版本库使用`svn`网络协议,你可以作为独立服务器进程运行svnserve,或者是使用其它进程,如**inetd**、**xinetd**或**sshd**为你启动进程。 一旦客户端已经选择了一个版本库来传递它的URL,**svnserve**会读取版本库目录的`conf/svnserve.conf`文件,来检测版本库特定的设置,如使用哪个认证数据库和应用怎样的授权策略。关于`svnserve.conf`文件的详情见[“svnserve,一个自定义的服务器”一节](# "svnserve,一个自定义的服务器")。 ### **svnserve**选项 不象前面描述的例子,**svnserve**没有子命令―**svnserve**完全通过选项控制。 `--daemon` (`-d`) 导致**svnserve**以守护进程方式运行,**svnserve**维护本身并且接受和服务svn端口(缺省3690)的TCP/IP连接。 `--listen-port`=*`PORT`* 在守护进程模式时导致svnserve监听*`PORT`*端口。 `--listen-host`=*`HOST`* **svnserve**监听的*`HOST`*,可能是一个主机名或是一个IP地址。 `--foreground` 当与`-d`一起使用,会导致**svnserve**停留在前台,主要用来调试。 `--inetd` (`-i`) 导致**svnserve**使用标准输出/标准输入文件描述符,更准确的是使用**inetd**作为守护进程。 `--help` (`-h`) 显示有用的摘要和选项。 `--version` 显示版本信息,版本库后端存在和可用的模块列表。 `--root`=*`ROOT`* (`-r`=*`ROOT`*) 设置**svnserve**服务的版本库的虚拟根,客户端提供的URL中显示的路径会解释为这个根的相对路径,不会允许离开这个根。 `--tunnel` (`-t`) 导致**svnserve**以管道模式运行,很像**inetd**操作的模式(服务于一个标准输入/标准输出的连接),除了连接是用当前uid的用户名预先认证过的这一点。这个选项在客户端使用如**ssh**之类的管道时使用。 `--tunnel-user NAME` 与`--tunnel`选项结合使用;告诉svnserve假定NAME就是认证用户,而不是svnserve进程的UID用户,当希望多个用户通过SSH共享同一个系统帐户,但是维护各自的提交标示符时非常有用。 `--threads` (`-T`) 当以守护进程模式运行,导致**svnserve**为每个连接产生一个线程而不是一个进程,**svnserve**进程本身在启动后会一直在后台。 `--listen-once` (`-X`) 导致**svnserve**在svn端口接受一个连接,维护完成它退出。这个选项主要用来调试。
';

svnlook youngest

最后更新于:2022-04-02 05:59:52

### 名称 svnlook youngest ― 打印最年轻的修订版本号。 ### 概要 ~~~ svnlook youngest REPOS_PATH ~~~ ### 描述 打印一个版本库最年轻的修订版本号。 ### 例子 这显示了在实例版本库显示最年轻的修订版本: ~~~ $ svnlook youngest /tmp/repos/ 42 ~~~
';

svnlook uuid

最后更新于:2022-04-02 05:59:50

### 名称 svnlook uuid ― 打印版本库的`UUID`。 ### 概要 ~~~ svnlook uuid REPOS_PATH ~~~ ### 描述 打印版本库的`UUID`,UUID是版本库的*U*niversal *U*nique *ID*entifier(全局唯一标示),Subversion客户端可以使用这个标示区分不同的版本库。 ### 例子 ~~~ $ svnlook uuid /usr/local/svn/repos e7fe1b91-8cd5-0310-98dd-2f12e793c5e8 ~~~
';