|
用户名:killerz 笔名:killerz 地区: 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
欢迎访问fengfeng的博客
配置httpd,Apache的HTTP Subversion服务器
Apache的HTTP服务器是一个Subversion可以利用的“重型”网络服务器,通过一个自定义模块,httpd可以让Subversion版本库通过WebDAV/DeltaV协议在客户端前可见,WebDAV/DeltaV协议是HTTP 1.1的扩展(见http://www.webdav.org/来查看详细信息)。这个协议利用了无处不在的HTTP协议是广域网的核心这一点,添加了写能力—更明确一点,版本化的写—能力。结果就是这样一个标准化的健壮的系统,作为Apache 2.0软件的一部分打包,被许多操作系统和第三方产品支持,网络管理员也不需要打开另一个自定义端口。 [这样一个Apache-Subversion服务器具备了许多svnserve没有的特性,但是也有一点难于配置,灵活通常会带来复杂性。
下面的讨论包括了对Apache配置指示的引用,给了一些使用这些指示的例子,详细地描述不在本章的范围之内,Apache小组维护了完美的文档,公开存放在他们的站点http://httpd.apache.org。例如,一个一般的配置参考位于http://httpd.apache.org/docs-2.0/mod/directives.html。
同样,当你修改你的Apache设置,很有可能会出现一些错误,如果你还不熟悉Apache的日志子系统,你一定需要认识到这一点。在你的文件httpd.conf里会指定Apache生成的访问和错误日志(CustomLog和ErrorLog指示)的磁盘位置。Subversion的mod_dav_svn使用Apache的错误日志接口,你可以浏览这个文件的内容查看信息来查找难于发现的问题根源。
为了让你的版本库使用HTTP网络,你基本上需要两个包里的四个部分。你需要Apache httpd 2.0和包括的mod_dav DAV模块,Subversion和与之一同分发的mod_dav_svn文件系统提供者模块,如果你有了这些组件,网络化你的版本库将非常简单,如:
配置好httpd 2.0,并且使用mod_dav启动,
为mod_dav安装mod_dav_svn插件,它会使用Subversion的库访问版本库,并且
配置你的httpd.conf来输出(或者说暴露)版本库。
你可以通过从源代码编译httpd和Subversion来完成前两个项目,也可以通过你的系统上的已经编译好的二进制包来安装。最新的使用Apache HTTP的Subversion的编译方法和Apache的配置方式可以看Subversion源代码树根目录的INSTALL文件。
一旦你安装了必须的组件,剩下的工作就是在httpd.conf里配置Apache,使用LoadModule来加载mod_dav_svn模块,这个指示必须先与其它Subversion相关的其它配置出现,如果你的Apache使用缺省布局安装,你的mod_dav_svn模块一定在Apache安装目录(通常是在/usr/local/apache2)的modules子目录,LoadModule指示的语法很简单,影射一个名字到它的共享库的物理位置:
LoadModule dav_svn_module modules/mod_dav_svn.so
注意,如果mod_dav是作为共享对象编译(而不是静态链接到httpd程序),你需要为它使用使用LoadModule语句,一定确定它在mod_dav_svn之前:
LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so
在你的配置文件后面的位置,你需要告诉Apache你在什么地方保存Subversion版本库(也许是多个),位置指示有一个很像XML的符号,开始于一个开始标签,以一个结束标签结束,配合中间许多的其它配置。Location指示的目的是告诉Apache在特定的URL以及子URL下需要特殊的处理,如果是为Subversion准备的,你希望可以通过告诉Apache特定URL是指向版本化的资源,从而把支持转交给DAV层,你可以告诉Apache将所有路径部分(URL中服务器名称和端口之后的部分)以/repos/开头的URL交由DAV服务提供者处理。一个DAV服务提供者的版本库位于/absolute/path/to/repository,可以使用如下的httpd.conf语法:
<Location /repos> DAV svn SVNPath /absolute/path/to/repository </Location>
如果你计划支持多个具备相同父目录的Subversion版本库,你有另外的选择,SVNParentPath指示,来表示共同的父目录。举个例子,如果你知道你会在/usr/local/svn下创建多个Subversion版本库,并且通过类似http://my.server.com/svn/repos1,http://my.server.com/svn/repos2的URL访问,你可以用后面例子中的httpd.conf配置语法:
<Location /svn> DAV svn # any "/svn/foo" URL will map to a repository /usr/local/svn/foo SVNParentPath /usr/local/svn </Location>
使用上面的语法,Apache会代理所有URL路径部分为/svn/的请求到Subversion的DAV提供者,Subversion会认为SVNParentPath指定的目录下的所有项目是真实的Subversion版本库,这通常是一个便利的语法,不像是用SVNPath指示,我们在此不必为创建新的版本库而重启Apache。
请确定当你定义新的位置,不会与其它输出的位置重叠,例如你的主要DocumentRoot是/www,不要把Subversion版本库输出到<Location /www/repos>,如果一个请求的URI是/www/repos/foo.c,Apache不知道是直接到repos/foo.c访问这个文件还是让mod_dav_svn代理从Subversion版本库返回foo.c。
在本阶段,你一定要考虑访问权限问题,如果你已经作为普通的web服务器运行过Apache,你一定有了一些内容—网页、脚本和其他。这些项目已经配置了许多在Apache下可以工作的访问许可,或者更准确一点,允许Apache与这些文件一起工作。Apache当作为Subversion服务器运行时,同样需要正确的访问许可来读写你的Subversion版本库。(见
你会需要检验权限系统的设置满足Subversion的需求,同时不会把以前的页面和脚本搞乱。这或许意味着修改Subversion的访问许可来配合Apache服务器已经使用的工具,或者可能意味着需要使用httpd.conf的User和Group指示来指定Apache作为运行的用户和Subversion版本库的组。并不是只有一条正确的方式来设置许可,每个管理员都有不同的原因来以特定的方式操作,只需要意识到许可关联的问题经常在为Apache配置Subversion版本库的过程中被疏忽。
此时,如果你配置的httpd.conf保存如下的内容
<Location /svn> DAV svn SVNParentPath /usr/local/svn </Location>
这样你的版本库对全世界是可以“匿名”访问的,直到你配置了一些认证授权政策,你通过Location指示来使Subversion版本库可以被任何人访问,换句话说,
任何人可以使用Subversion客户端来从版本库URL取出一个工作拷贝(或者是它的子目录),
任何人可以在浏览器输入版本库URL交互浏览的方式来查看版本库的最新修订版本,并且
任何人可以提交到版本库。
最简单的客户端认证方式是通过HTTP基本认证机制,简单的使用用户名和密码来验证一个用户所自称的身份,Apache提供了一个htpasswd工具来管理可接受的用户名和密码,这些就是你希望赋予Subversion特别权限的用户,让我们给Sally和Harry赋予提交权限,首先,我们需要添加他们到密码文件。
$ ### First time: use -c to create the file $ ### Use -m to use MD5 encryption of the password, which is more secure $ htpasswd -cm /etc/svn-auth-file harry New password: ***** Re-type new password: ***** Adding password for user harry $ htpasswd -m /etc/svn-auth-file sally New password: ******* Re-type new password: ******* Adding password for user sally $
下一步,你需要在httpd.conf的Location区里添加一些指示来告诉Apache如何来使用这些密码文件,AuthType指示指定系统使用的认证类型,这种情况下,我们需要指定Basic认证系统,AuthName是你提供给认证域一个任意名称,大多数浏览器会在向用户询问名称和密码的弹出窗口里显示这个名称,最终,使用AuthUserFile指示来指定使用htpasswd创建的密码文件的位置。
添加完这三个指示,你的<Location>区块一定像这个样子:
<Location /svn> DAV svn SVNParentPath /usr/local/svn AuthType Basic AuthName "Subversion repository" AuthUserFile /etc/svn-auth-file </Location>
这个<Location>区块还没有结束,还不能做任何有用的事情,它只是告诉Apache当需要授权时,要去向Subversion客户端索要用户名和密码。我们这里遗漏的,是一些告诉Apache什么样客户端需要授权的指示。哪里需要授权,Apache就会在哪里要求认证,最简单的方式是保护所有的请求,添加Require valid-user来告诉Apache任何请求需要认证的用户:
<Location /svn> DAV svn SVNParentPath /usr/local/svn AuthType Basic AuthName "Subversion repository" AuthUserFile /etc/svn-auth-file Require valid-user </Location>
一定要阅读后面的部分(
需要警惕:HTTP基本认证的密码是用明文传输,因此非常不可靠的,如果你担心密码偷窥,最好是使用某种SSL加密,所以客户端认证使用https://而不是http://,为了方便,你可以配置Apache为自签名认证。 [23] 参考Apache的文档(和OpenSSL文档)来查看怎样做。
auth/中,缓存后,Subversion会自动记住在以后的交流中信任这个证书。商业应用需要越过公司防火墙的版本库访问,防火墙需要小心的考虑非认证用户“吸取”他们的网络流量的情况,SSL让那种形式的关注更不容易导致敏感数据泄露。
如果Subversion使用OpenSSL编译,它就会具备与Subversion服务器使用https://的URL通讯的能力,Subversion客户端使用的Neon库不仅仅可以用来验证服务器证书,也可以必要时提供客户端证书,如果客户端和服务器交换了SSL证书并且成功地互相认证,所有剩下的交流都会通过一个会话关键字加密。
怎样产生客户端和服务器端证书以及怎样使用它们已经超出了本书的范围,许多书籍,包括Apache自己的文档,描述这个任务,现在我们可以覆盖的是普通的客户端怎样来管理服务器与客户端证书。
当通过https://与Apache通讯时,一个Subversion客户端可以接收两种类型的信息:
一个服务器证书
一个客户端证书的要求
如果客户端接收了一个服务器证书,它需要去验证它是可以相信的:这个服务器是它自称的那一个吗?OpenSSL库会去检验服务器证书的签名人或者是核证机构(CA)。如果OpenSSL不可以自动信任这个CA,或者是一些其他的问题(如证书过期或者是主机名不匹配),Subversion命令行客户端会询问你是否愿意仍然信任这个证书:
$ svn list https://host.example.com/repos/project Error validating server certificate for 'https://host.example.com:443': - The certificate is not issued by a trusted authority. Use the fingerprint to validate the certificate manually! Certificate information: - Hostname: host.example.com - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT - Issuer: CA, example.com, Sometown, California, US - Fingerprint: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b (R)eject, accept (t)emporarily or accept (p)ermanently?
这个对话看起来很熟悉,这是你会在web浏览器(另一种HTTP客户端,就像Subversion)经常看到的问题,如果你选择(p)ermanent选项,服务器证书会存放在你存放那个用户名和密码缓存(见
你的运行中servers文件也会给你能力可以让Subversion客户端自动信任特定的CA,包括全局的或是每主机为基础的,只需要设置ssl-authority-files为一组逗号隔开的PEM加密的CA证书列表:
[global] ssl-authority-files = /path/to/CAcert1.pem;/path/to/CAcert2.pem
许多OpenSSL安装包括一些预先定义好的可以普遍信任的“缺省的”CA,为了让Subversion客户端自动信任这些标准权威,设置ssl-trust-default-ca为true。
当与Apache通话时,Subversion客户端也会收到一个证书的要求,Apache是询问客户端来证明自己的身份:这个客户端是否是他所说的那一个?如果一切正常,Subversion客户端会发送回一个通过Apache信任的CA签名的私有证书,一个客户端证书通常会以加密方式存放在磁盘,使用本地密码保护,当Subversion收到这个要求,它会询问你证书的路径和保护用的密码:
$ svn list https://host.example.com/repos/project Authentication realm: https://host.example.com:443 Client certificate filename: /path/to/my/cert.p12 Passphrase for '/path/to/my/cert.p12': ******** …
注意这个客户端证书是一个“p12”文件,为了让Subversion使用客户端证书,它必须是运输标准的PKCS#12格式,大多数浏览器可以导入和导出这种格式的证书,另一个选择是用OpenSSL命令行工具来转化存在的证书为PKCS#12格式。
再次,运行中servers文件允许你为每个主机自动响应这种要求,单个或两条信息可以用运行参数来描述:
[groups] examplehost = host.example.com [examplehost] ssl-client-cert-file = /path/to/my/cert.p12 ssl-client-cert-password = somepassword
一旦你设置了ssl-client-cert-file和 ssl-client-cert-password参数,Subversion客户端可以自动响应客户端证书请求而不会打扰你。 [24]
例 6.1. 匿名访问的配置实例。
<Location /repos>
DAV svn
SVNParentPath /usr/local/svn
# our access control policy
AuthzSVNAccessFile /path/to/access/file
</Location>
例 6.2. 一个认证访问的配置实例。
<Location /repos>
DAV svn
SVNParentPath /usr/local/svn
# our access control policy
AuthzSVNAccessFile /path/to/access/file
# only authenticated users may access the repository
Require valid-user
# how to authenticate a user
AuthType Basic
AuthName "Subversion repository"
AuthUserFile /path/to/users/file
</Location>
例 6.3. 一个混合认证/匿名访问的配置实例。
<Location /repos>
DAV svn
SVNParentPath /usr/local/svn
# our access control policy
AuthzSVNAccessFile /path/to/access/file
# try anonymous access first, resort to real
# authentication if necessary.
Satisfy Any
Require valid-user
# how to authenticate a user
AuthType Basic
AuthName "Subversion repository"
AuthUserFile /path/to/users/file
</Location>
关闭路径为基础的检查例 6.4. 关闭所有的路经检查
<Location /repos>
DAV svn
SVNParentPath /usr/local/svn
SVNPathAuthz off
</Location>
额外的糖果版本库浏览其它特性附录 C, WebDAV和自动版本化来得到更多细节。此刻,你已经配置了认证,但是没有配置授权,Apache可以要求用户认证并且确定身份,但是并没有说明这个身份的怎样允许和限制,这个部分描述了两种控制访问版本库的策略。
最简单的访问控制形式是授权特定用户为只读版本库访问或者是读/写访问版本库。
你可以通过在<Location>区块添加Require valid-user指示来限制所有的版本库操作,使用我们前面的例子,这意味着只有客户端只可以是harry或者sally,而且他们必须提供正确的用户名及对应密码,这样允许对Subversion版本库做任何事:
<Location /svn> DAV svn SVNParentPath /usr/local/svn # how to authenticate a user AuthType Basic AuthName "Subversion repository" AuthUserFile /path/to/users/file # only authenticated users may access the repository Require valid-user </Location>
有时候,你不需要这样严密,举个例子,Subversion自己在http://svn.collab.net/repos/svn的源代码允许全世界的人执行版本库的只读操作(例如检出我们的工作拷贝和使用浏览器浏览版本库),但是限定只有认证用户可以执行写操作。为了执行特定的限制,你可以使用Limit和LimitExcept配置指示,就像Location指示,这个区块有开始和结束标签,你需要在<Location>中添加这个指示。
在Limit和LimitExcept中使用的参数是可以被这个区块影响的HTTP请求类型,举个例子,如果你希望禁止所有的版本库访问,只是保留当前支持的只读操作,你可以使用LimitExcept指示,并且使用GET,PROPFIND,OPTIONS和REPORT请求类型参数,然后前面提到过的Require valid-user指示将会在<LimitExcept>区块中而不是在<Location>区块。
<Location /svn>
DAV svn
SVNParentPath /usr/local/svn
# how to authenticate a user
AuthType Basic
AuthName "Subversion repository"
AuthUserFile /path/to/users/file
# For any operations other than these, require an authenticated user.
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
</LimitExcept>
</Location>
这里只是一些简单的例子,想看关于Apache访问控制Require指示的更深入信息,可以查看Apache文档中的教程集http://httpd.apache.org/docs-2.0/misc/tutorials.html中的Security部分。
也可以使用Apache的httpd模块mod_authz_svn更加细致的设置访问权限,这个模块收集客户端传递过来的不同的晦涩的URL信息,询问mod_dav_svn来解码,然后根据在配置文件定义的访问政策来裁决请求。
如果你从源代码创建Subversion,mod_authz_svn会自动附加到mod_dav_svn,许多二进制分发版本也会自动安装,为了验证它是安装正确,确定它是在httpd.conf的LoadModule指示中的mod_dav_svn后面:
LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so
为了激活这个模块,你需要配置你的Location区块的AuthzSVNAccessFile指示,指定保存路径中的版本库访问政策的文件。(一会儿我们将会讨论这个文件的格式。)
Apache非常的灵活,你可以从三种模式里选择一种来配置你的区块,作为开始,你选择一种基本的配置模式。(下面的例子非常简单;见Apache自己的文档中的认证和授权选项来查看更多的细节。)
最简单的区块是允许任何人可以访问,在这个场景里,Apache决不会发送认证请求,所有的用户作为“匿名”对待。
在另一个极端,你可以配置为拒绝所有人的认证,所有客户端必须提供证明自己身份的证书,你通过Require valid-user指示来阻止无条件的认证,并且定义一种认证的手段。
第三种流行的模式是允许认证和匿名用户的组合,举个例子,许多管理员希望允许匿名用户读取特定的版本库路径,但希望只有认证用户可以读(或者写)更多敏感的区域,在这个设置里,所有的用户开始时用匿名用户访问版本库,如果你的访问控制策略在任何时候要求一个真实的用户名,Apache将会要求认证客户端,为此,你可以同时使用Satisfy Any和Require valid-user指示。
一旦你的基本Location区块已经配置了,你可以创建一个定义一些授权规则的访问文件。
访问文件的语法与svnserve.conf和运行中配置文件非常相似,以(#)开头的行会被忽略,在它的简单形式里,每一小节命名一个版本库和一个里面的路径,认证用户名是在每个小节中的选项名,每个选项的值描述了用户访问版本库的级别:r(只读)或者rw(读写),如果用户没有提到,访问是不允许的。
具体一点:这个小节的名称是[repos-name:path]或者[path]的形式,如果你使用SVNParentPath指示,指定版本库的名字是很重要的,如果你漏掉了他们,[/some/dir]部分就会与/some/dir的所有版本库匹配,如果你使用SVNPath指示,因此在你的小节中只是定义路径也很好—毕竟只有一个版本库。
[calc:/branches/calc/bug-142] harry = rw sally = r
在第一个例子里,用户harry对calc版本库中/branches/calc/bug-142具备完全的读写权利,但是用户sally只有读权利,任何其他用户禁止访问这个目录。
当然,访问控制是父目录传递给子目录的,这意味着我们可以为Sally指定一个子目录的不同访问策略:
[calc:/branches/calc/bug-142] harry = rw sally = r # give sally write access only to the 'testing' subdir [calc:/branches/calc/bug-142/testing] sally = rw
现在Sally可以读取分支的testing子目录,但对其他部分还是只可以读,同时,Harry对整个分支还继续有完全的读写权限。
也可以通过继承规则明确的的拒绝某人的访问,只需要设置用户名参数为空:
[calc:/branches/calc/bug-142] harry = rw sally = r [calc:/branches/calc/bug-142/secret] harry =
在这个例子里,Harry对bug-142目录树有完全的读写权限,但是对secret子目录没有任何访问权利。
有一件事需要记住的是需要找到最匹配的目录,mod_authz_svn模块首先找到匹配自己的目录,然后父目录,然后父目录的父目录,就这样继续下去,更具体的路径控制会覆盖所有继承下来的访问控制。
缺省情况下,没有人对版本库有任何访问,这意味着如果你已经从一个空文件开始,你会希望给所有用户对版本库根目录具备读权限,你可以使用*实现,用来代表“所有用户”:
[/] * = r
这是一个普通的设置;注意在小节名中没有提到版本库名称,这让所有版本库对所有的用户可读,不管你是使用SVNPath或是SVNParentPath。当所有用户对版本库有了读权利,你可以赋予特定用户对特定子目录的rw权限。
星号(*)参数需要在这里详细强调:这是匹配匿名用户的唯一模式,如果你已经配置了你的Location区块允许匿名和认证用户的混合访问,所有用户作为Apache匿名用户开始访问,mod_authz_svn会在要访问路径的定义中查找*值;如果找不到,Apache就会要求真实的客户端认证。
访问文件也允许你定义一组的用户,很像Unix的/etc/group文件:
[groups] calc-developers = harry, sally, joe paint-developers = frank, sally, jane everyone = harry, sally, joe, frank, sally, jane
组可以被赋予通用户一样的访问权限,使用“at”(@)前缀来加以区别:
[calc:/projects/calc] @calc-developers = rw [paint:/projects/paint] @paint-developers = rw jane = r
...并且非常接近。
mod_dav_svn模块做了许多工作来确定你标记为“不可读”的数据不会因意外而泄露,这意味着需要紧密监控通过svn checkout或是svn update返回的路径和文件内容,如果这些命令遇到一些根据认证策略不是可读的路径,这个路径通常会被一起忽略,在历史或者重命名操作时—例如运行一个类似svn cat -r OLD foo.c的命令来操作一个很久以前改过名字的文件 — 如果一个对象的以前的名字检测到是只读的,重命令追踪就会终止。
所有的路径检查在有时会非常昂贵,特别是svn log的情况。当检索一列修订版本时,服务器会查看所有修订版本修改的路径,并且检查可读性,如果发现了一个不可读路径,它会从修订版本的修改路径中忽略(可以查看--verbose选项),并且整个的日志信息会被禁止,不必多说,这种影响大量文件修订版本的操作会非常耗时。这是安全的代价:即使你并没有配置mod_authz_svn模块,mod_dav_svn还是会询问httpd来对所有路径运行认证检查,mod_dav_svn模块没有办法知道那个认证模块被安装,所以只有询问Apache来调用所提供的模块。
在另一方面,也有一个安全舱门允许你用安全特性来交换速度,如果你不是坚持要求有每目录授权(如不使用 mod_authz_svn和类似的模块),你就可以关闭所有的路径检查,在你的httpd.conf文件,使用SVNPathAuthz指示:
SVNPathAuthz指示缺省是打开的,当设置为“off”时,所有的路径为基础的授权都会关闭;mod_dav_svn停止对每个目录调用授权检查。
我们已经覆盖了关于认证和授权的Apache和mod_dav_svn的大多数选项,但是Apache还提供了许多很好的特性。
一个非常有用的好处是使用Apache/WebDAV配置Subversion版本库时可以用普通的浏览器察看最新的版本库文件,因为Subversion使用URL来鉴别版本库版本化的资源,版本库使用的HTTP为基础的URL也可以直接输入到Web浏览器中,你的浏览器会发送一个GET请求到URL,根据访问的URL是指向一个版本化的目录还是文件,mod_dav_svn会负责列出目录列表或者是文件内容。
因为URL不能确定你所希望看到的资源的版本,mod_dav_svn会一直返回最新的版本,这样会有一些美妙的副作用,你可以直接把Subversion的URL传递给文档作为引用,这些URL会一直指向文档最新的材料,当然,你也可以在别的网站作为超链使用这些URL。
你通常会在版本化的文件的URL之外得到更多地用处—毕竟那里是有趣的内容存在的地方,但是你会偶尔浏览一个Subversion的目录列表,你会很快发现展示列表生成的HTML非常基本,并且一定没有在外观上(或者是有趣上)下功夫,为了自定义这些目录显示,Subversion提供了一个XML目录特性,一个单独的SVNIndexXSLT指示在你的httpd.conf文件版本库的Location块里,它将会指导mod_dav_svn在显示目录列表的时候生成XML输出,并且引用你选择的XSLT样式表文件:
<Location /svn> DAV svn SVNParentPath /usr/local/svn SVNIndexXSLT "/svnindex.xsl" … </Location>
使用SVNIndexXSLT指示和创建一个XSLT样式表,你可以让你的目录列表的颜色模式与你的网站的其它部分匹配,否则,如果你愿意,你可以使用Subversion源分发版本中的tools/xslt/目录下的样例样式表。记住提供给SVNIndexXSLT 指示的路径是一个URL路径—浏览器需要阅读你的样式表来利用它们!
Apache作为一个健壮的Web服务器的许多特性也可以用来增加Subversion的功能性和安全性,Subversion使用Neon与Apache通讯,这是一种一般的HTTP/WebDAV库,可以支持SSL和Deflate压缩(是gzip和PKZIP程序用来“压缩”文件为数据块的一样的算法)之类的机制。你只需要编译你希望Subversion和Apache需要的特性,并且正确的配置程序来使用这些特性。
Deflate压缩给服务器和客户端带来了更多地负担,压缩和解压缩减少了网络传输的实际文件的大小,如果网络带宽比较紧缺,这种方法会大大提高服务器和客户端之间发送数据的速度,在极端情况下,这种最小化的传输会造成超时和成功的区别。
不怎么有趣,但同样重要,是Apache和Subversion关系的一些特性,像可以指定自定义的端口(而不是缺省的HTTP的80)或者是一个Subversion可以被访问的虚拟主机名,或者是通过代理服务器访问的能力,这些特性都是Neon所支持的,所以Subversion轻易得到这些支持。
最后,因为mod_dav_svn是使用一个半完成的WebDAV/DeltaV方言,所以通过第三方的DAV客户端访问也是可能的,几乎所有的现代操作系统(Win32、OS X和Linux)都有把DAV服务器影射为普通的网络“共享”的内置能力,这是一个复杂的主题;察看
充分发掘Subversion的资源库共享功能
在上一篇文章《用Subversion构建版本控制环境》中,我们就Subversion的特性、安装以及如何通过各种客户端来操作资源库进行了详细的介绍。文章中Subversion是以独立的服务方式运行,我们必须借住一些特定的客户端,例如Subvresion本身提供的客户端命令行程序、Eclipse插件以及集成在Windows资源管理器的TortoiseSVN工具。这些工具对于开发者而言当然是必须的,但是当我们有需要将资源库发布在互联网上的时候,就会让我们的用户操作起来非常不方便,用户可能仅仅是需要浏览一下项目,却要他安装一堆程序,这难免让人觉得繁琐。
怎么让我们的用户可以通过一些常用的程序例如资源管理器或者是浏览器就可以方便的浏览Subversion的资源库呢?因此本文将充分的发掘Subversion在资源库共享方面的功能,同时对Subversion在权限控制方面的内容进行详细的介绍,同时也将详细介绍如何将已有的CVS资源库转到Subversion上来。
我们曾经提到过Subversion相比较而言在共享方面的功能是大大的超过了CVS系统,它可以通过Apache服务器提供基于WebDAV/DeltaV协议的支持。有了它你就可以通过资源管理器或者浏览器对资源库进行浏览以及操作。接下来我们将详细介绍如何安装并使用这个功能。(本文的所有软件的安装都是在Windows系统下进行)
1. 安装Apache HTTP服务器
到http://httpd.apache.org下载最新的Apache服务器2.0.54版本的Windows安装程序apache_2.0.54-win32-x86-no_ssl.msi,下载完毕直接安装,使用默认设置进行安装即可,安装过程不再累赘。安装完毕后使用浏览器打开网址http://localhost 检查安装是否成功完成。
如果Apache无法启动请检查是否机器上已经装有IIS,把IIS停掉后再启动Apache服务进行测试。
2. 安装Subversion
Subversion的安装已经在上一篇文章中详细的介绍过了,如果你还不知道怎么安装Subversion请参照《用Subversion构建版本控制环境》。请确保将{subversion}\bin目录是否在系统的PATH变量中存在,如果不存在请加上。
有一点需要说明的是,使用跟Apache HTTP服务器结合的方式,你无需再启动SVNService服务。
3. 配置Apache HTTP服务器
首先在Subversion的安装目录下的bin子目录找到这样两个文件mod_dav_svn.so和mod_authz_svn.so,将这两个文件复制到Apache安装目录下的modules子目录,另外还有四个文件分别是intl3_svn.dll、libdb43.dll、libeay32.dll、ssleay32.dll,把这四个文件拷贝到subversion的bin目录或者是modules目录。
打开Apache的配置文件httpd.conf,我们需要在该配置文件中通过LoadModule指令来加载Subversion的DAV模块,例如下面一行信息。
LoadModule dav_svn_module modules/mod_dav_svn.so
需要注意的是,因为Apache本身带有mod_dav模块,如果你的Apache中这个模块是动态 加载的而不是直接编译进Apache的可执行文件中的话,你应该确保上面的指令在mod_dav模块后面进行加载,默认的情况下mod_dav模块是不启用的,你需要把它前面的注释去掉,如下:
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
同时另外一个模块mod_authz_svn模块也需要进行加载,可以把它放置在mod_dav_svn后,例如:
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
接下来我们必须告诉Apache我们的资源库所在的路径,可以通过Location指令来完成这个设置。因为不希望为每个单独的项目都进行单独的设置,所以我们把所有项目都存放在统一的资源库目录,那么可以使用SVNParentPath指令来指定存放所有项目的路径。在httpd.conf文件最后添加下面配置:
DAV svn
SVNParentPath d:/svn/repository
这样我们就可以通过http://myhost/svn/<项目名> 来访问存放于资源库d:/svn/repository中的指定项目。当然有可能你并不希望某个项目提供这样一种访问方式,这时候你可以使用SVNPath为每个项目进行单独的设置,SVNPath的使用方法如下:
DAV svn
SVNPath d:/svn/repository/project1
同样把这段配置放在httpd.conf最后,重启Apache HTTP服务即可通过http://myhost/svn/project1 来访问project1项目的资源库。
应该提醒的是,所有的这些访问都是匿名的,任何用户只要能访问这台机器都可以访问你所设定的资源库,他可以对项目进行浏览、检出或者是提交,我相信你肯定不希望发生这样的事情,接下来我们将介绍如何做好访问的权限控制。
现在我们先试着用Subversion自带的客户端提交一个项目以便于接下来的测试,随便弄一个项目,执行下列命令将项目加到资源库中。
输入:svn import . http://localhost/svn -m "test"
输出:svn: PROPFIND request failed on '/svn'svn: PROPFIND of '/svn': 403 Forbidden (http://localhost)
怎么回事?403 Forbidden?原因是我们必须先给项目创建资源库,D:\svn\repository只是我们存放所有项目的目录,我们必须在这个目录下创建要提交项目的资源库。使用下面命令先给项目创建好资源库
svnadmin create d:\svn\repository\project1
再次执行import命令后,就可以成功的导入项目。打开浏览器输入网址:http://localhost/svn/project1 看看你刚提交了什么:)

现在我们回顾一下新建一个项目的过程:首先必须使用svnadmin工具创建项目的资源库,然后再导入项目文件。
4. 访问用户的身份验证
在确定对访问用户的权限控制之前,你必须规划好是对整个资源库中的所有项目还是单独的某一个项目进行统一的身份验证, 也就是我们前面讲到的是使用SVNParentPath还是SVNPath的问题。
最简单的身份验证方式是使用Basic HTTP Authentication机制,该方式通过用户名和口令对访问用户进行身份验证。我们可以直接通过Apache提供的支持进行设置。Apache提供一个htpasswd工具来管理用户名和口令。接下来我们利用这个工具来添加两个用户。
在命令行窗口中转到Apache所在的目录,假设是 D:\Apache\bin,执行下列命令
说明:创建用户liudong1
输入:htpasswd –cm D:\svn\svn_auth_passwd liudong1
说明:使用-c参数来创建一个passwd文件
输出:
New password: *****
Re-type new password: *****
Adding password for user liudong1
说明:创建用户liudong2
输入:htpasswd –m D:\svn\svn_auth_passwd liudong2
说明:passwd文件已经创建,无需再使用-c参数
输出:
New password: *****
Re-type new password: *****
Adding password for user liudong2
打开D:\svn\svn_auth_passwd文件,密码使用MD5加密过了,而且同样的密码加密出来的内容却不相同,估计跟用户名也是有一点关系,内容如下:
liudong1:$apr1$5G3.....$x5jgK.sGp/Y3EFSXGMtoE.
liudong2:$apr1$cG3.....$IM5m73cqw8N8ZsMcJnKeX.
接下来我们必须告诉Apache服务器如何使用这个passwd文件,打开httpd.conf找到刚才我们添加的Location配置的位置,修改如下:
DAV svn
SVNParentPath d:/svn/repository
AuthType Basic
AuthName "Subversion repository"
AuthUserFile d:/svn/svn_auth_passwd
Require valid-user
重新启动Apache HTTP服务器,使用浏览器打开 http://localhost/svn/project1 你将会看到要求登录的对话框如下图所示(我所使用的是Opera 8浏览器),输入你刚设置的用户名和口令即可。

这就是利用Basic HTTP Authentication机制对用户进行访问控制的方法。你还可以使用SSL证书管理来加强Subversion的安全性(HTTPS的配置属于Apache HTTP服务器的范畴,请参照Apache的文档),甚至你可以对设置对某些操作才需要验证用户的身份以及赋予不同用户对不同目录的操作权限,以及如何使用Windows的域帐号进行身份的验证。这些内容可以参考Subversion提供的文档svn-book.pdf的第六章——服务器配置。
以上介绍的是Subversion跟Apache结合提供基于HTTP方式的共享功能以及如何对用户进行身份的验证。接下来我们介绍大部分CVS用户非常关系的——如何将现有的CVS资源库移植到Subversion下。
我们可以通过一个cvs2svn的工具来将CVS资源库转到Subversion服务器上。Cvs2svn是一个用Python写的转换脚本,它的作用是用来一次性的从CVS转到Subversion,你不要指望它帮你同步CVS和Subversion资源库。如果你并不需要项目的一些历史修改信息,那么你最好先从CVS获取最新版本,然后提交到Subversion资源库中,这是最简单直接而有效的方法。如果你需要保留CVS意见的所有修改记录,那么接下来我们就是介绍如何通过cvs2svn来转换你的资源库。
首先我们需要安装Python,因为cvs2svn是用Python写的一些脚本。到 http://www.python.org/download/ 下载最新版本的Python for Windows的安装程序python-2.4.1.msi,按照默认的方式安装Python,假设安装目录是C:\Python。接下来下载cvs2svn,下载地址是:http://cvs2svn.tigris.org/servlets/ProjectDocumentList?folderID=2976,用WinRAR解压到任一个目录下。打开命令行窗口转到cvs2svn所在的目录先测试一下python,执行C:\python\python cvs2svn,这时候会输出cvs2svn的帮助信息。
由于cvs2svn用到了GUN sort工具,因此我们还必须到http://unxutils.sourceforge.net/ 下载UnxUtils.zip,把该压缩包下的usr/local/wbin/sort.exe文件解压到cvs2svn目录中;同时我们还需要下载RCS的一个工具co.exe,到http://www.cs.purdue.edu/homes/trinkle/RCS/ 下载rcs57pc1.zip,把该压缩包中的bin/win32下的rcslib.dll以及co.exe这两个文件同样解压到cvs2svn目录中。
接下来我们开始转换资源库,输入以下命令
C:\Python\python cvs2svn –s d:\svn\repository\project1
其中我们假设project1是原有CVS资源库中的一个项目。
下面是在我的机器上转换完毕后cvs2svn显示详细的统计信息:
cvs2svn Statistics:
------------------
Total CVS Files: 7
Total CVS Revisions: 7
Total Unique Tags: 0
Total Unique Branches: 0
CVS Repos Size in KB: 2261
Total SVN Commits: 2
First Revision Date: Sat Sep 03 15:05:26 2005
Last Revision Date: Sat Sep 03 15:05:27 2005
------------------
Timings:
------------------
pass 1: 0 seconds
pass 2: 0 seconds
pass 3: 0 seconds
pass 4: 0 seconds
pass 5: 0 seconds
pass 6: 0 seconds
pass 7: 0 seconds
pass 8: 1 second
total: 3 seconds
转换完毕后我们用浏览器打开 http://localhost/svn/project1 即可看到

点击trunk链接就可以看到项目的所有文件,接下来可以把你需要转换的项目重复执行上面的步骤即可。
以上是本文要介绍的内容,涉及实际应用中经常要面临的问题。以独立服务方式运行的Subversion其守护端口是3690,我们通过其跟Apache HTTP服务器结合使之可以方便的在互联网上进行资源库的发布;同时对于现在正在使用CVS的用户来讲可以通过cvs2svn来转换已有的资源库到Subversion上,这可打消CVS用户在考虑移植时候的顾虑。
参考资料
《用Subversion构建版本控制环境》
http://www-128.ibm.com/developerworks/cn/opensource/os-subversion/
Subversion的官方网站 http://subversion.tigris.org/
CVS2SVN http://cvs2svn.tigris.org/
Apache网站 http://httpd.apache.org/
Python官方网站 http://www.python.org/
Windows域用户验证模块 http://tortoisesvn.tigris.org/mod_auth_sspi.zip
用Subversion+eclipse 构建版本控制环境
|
|
|











SVN学习笔记
Subversion 系统 多年来,并发版本系统(CVS)一直是在Linux上管理代码或者文本的标准。作为基于RCS上建立但却允许多用户协作的系统而言,CVS记录所有文件的修改信息。这对于程序开发者、网络设计者和系统管理员而言,是非常有用的。 然而,CVS逐渐显示出它的衰老,出现了相似的源代码管理软件。然而大多这种东西都是以牟利为主要目的的。 Subversion就是一种相对新鲜的源代码管理系统。虽然事实上它还在不断的反展之中,但是Subversion已经是一个非常稳定而且成熟的产品。它是一个全新的系统,其功能可以和CVS媲美,同时,它要比CVS更直观,更容易操作。本文就Subversion的安装和一些特殊功能作一个介绍。 安装服务器端 下载Apache和SVN源码包 从官方网站台下载httpd-2.0.52.tar.gz,subversion-1.1.1.tar.gz (因为redhat 9默认安装的Apache没有并包含--enable-so选项,所以无法产生mod_dav_svn.没有这个模块,SVN就无法采用http方式运行,所以必须重新编译新的Apache) 以root身份执行: #tar zxvf httpd-2.0.52.tar.gz #cd httpd-2.0.52 #./configure --enable-dav --enable-so --enable-maintainer-mode #make #make install 此时会产生/usr/local/apache2目录,接着执行: #tar zxvf subversion-1.1.1.tar.gz #./configure --with-apxs=/usr/local/apache2/bin/apxs # rm /usr/local/lib/libsvn* # make clean && make && make install 此时会自动在/usr/local/apache2/conf/httpd.conf添加 LoadModule dav_svn_module modules/mod_dav_svn.so 安装完成后,运行svnserver --version确认版本为1.1.1。 SVN服务器安装结束. 安装客户机端 window客户机: 直接安装TortoiseSVN-1.1.1-UNICODE_svn-1.1.1.msi,方法同一般软件安装相同。 Linux客户机: 方法舆安装服务器相同。 (注意redhat 9默认安装的SVN版本为0.17.1,它的客户端命令svn无法舆新的SVN服务器通讯,必须重新安装) 建立仓库Repository Subversion 的档案库是个中央仓储, 用来存放任意数量项目的受版本控管资料,建立方法很简单 #svnadmin create path/to/repos 举个例子: #svnadmin create /home/mysvn #chown –R nobody /home/mysvn 运行服务器 Subversion服务器有两种运行方式,一是可以作为Apache 2.0的一个模块, 以WebDAV/DeltaV协议与外界连通;另外,也可使用Subversion 自带的小型服务器程序svnserve。该程序使用的是自带的通讯协议,可以很容易地透过SSH以 以http方式运行 在/usr/local/apache2/conf/httpd.conf中加入: <Location /svn/repository> DAV svn SVNPath /home/mysvn </Location> 在服务器的浏览器中输入网址: http://localhost/svn/repository/ 这时候,你会看到这样的显示: 这表明服务器已经以http方式正常运行了. 以svnserve方式运行 这种方式的运行又可以分为以下两种(这和vsftp有些相似) 1) standalone mode 直接运行 #svnserve –d 运行 lsof -i :3690可以看到SVN服务器已经在运行 2) xinetd mode 在/etc/xinetd.d/下生成svnserve文件,内容如下 service svnserve { disable = no socket_type = stream protocol = tcp wait = no user = apache server = /usr/local/bin/svnserve server_args = -i } 编辑 /etc/services 檔,加入底下两行: svnserve 3690/tcp # Subversion svnserve svnserve 3690/udp # Subversion svnserve 重启xinetd服务,运行 lsof -i :3690可以看到SVN服务器已经在运行 客户机访问 客户机的访问方法舆服务器的运行方式有直接关系 window客户机: 1) 服务器以http方式运行 安装完TortoiseSVN-1.1.1-UNICODE_svn-1.1.1.msi后,在你想工作的目录下点击右键,执行checkout,按上图输入即可。 2) 服务器以svnserve方式运行 同上的区别只是URL of repository变为 svn://svn服务器ip/home/mysvn 或者 svn+ssh://svn服务器ip/home/mysvn (注意不是//svn服务器ip//svn/repository) linux客户机: 1) 服务器以http方式运行 执行 #svn checkout http: //svn服务器ip/svn/repository 2) 服务器以svnserve方式运行 执行 #svn checkout svn://svn服务器ip/home/mysvn 或者 #svn checkout svn+ssh://svn服务器ip/home/mysvn 客户认证机制 这舆服务器的运行方式有关 服务器以http方式运行 比如我们想给 Sally 与 Harry 送交存取档案库的权限. 首先, 我们必须把它们加入到密码档案. # ### 第一次: 以 -c 建立档案 # htpasswd -c /etc/svn-auth-file harry New password: ***** Re-type new password: ***** Adding password for user harry # htpasswd /etc/svn-auth-file sally New password: ******* Re-type new password: ******* Adding password for user sally # 接着,在/usr/local/apache2/conf/httpd.conf的加入: <Location /svn/repository > DAV svn SVNPath /home/mycvs AuthType Basic AuthName "Subversion repository" AuthUserFile /etc/svn-auth-file Require valid-user </Location> 重新激活 Apache后,如果有人要访问SVN服务器,系统会要求他输入用户名和密码。 只有输入Sally 或Harry的用户名和相应的密码,才可以对档案库进行修改和访问 服务器以svnserve方式运行 默认下客户可以以匿名方式通过svn://方式任意访问档案库,为了限制其权限,比如只允许读操作,可以通过修改档案库conf子目录中的svnseve.conf文件来实现。 #vi /home/mysvn/conf/svnseve.conf 修改[general]字段下内容为: anon-access = read 如果设为anon-access = none,则匿名用户不可以通过svn://方式访问档案库 为了实现用户认证,我们一般采用svn+ssh://访问机制。 首先在svnseve.conf文件设置anon-access = none禁止匿名用户通过svn://方式访问档案库,然后在其后加入 auth-access = write auth-access 是限制有援权的使用者(使用svn+ssh:// 来登入) 的存取权限,我们设为是可以读写。 当用户通过svn+ssh://访问时,服务器会自动激活ssh认证机制,要求用户输入密码,对于window用户来说还需要安装第三方软件openssh,才可以采用这种机制 Hook scripts 挂勾 (hook) 是改动档案库时所触发的程序, 比如当你提交更动前,会先触发pre-commit,提交更动后,则会触发post-commit,我们可以利用hook来实现一些自动控制。档案库的hook 子目录中, 预设是放置各个档案库挂勾的模板: post-commit.tmpl pre-revprop-change.tmpl post-revprop-change.tmpl start-commit.tmpl pre-commit.tmpl 如果要使用这些hook,就必须把它的后缀名.tmpl去掉,拷贝为 post-commit pre-revprop-change post-revprop-change start-commit pre-commit 这里主要介绍pre-commit和post-commit(事实上它们就是在特定的情况下被触发的普通的shell程序,至于shell的内容由用户自己随意编写,但是要保证名称不能改动) pre-commit 本挂勾执行的时间为异动完成之后, 送交之前.档案库会传递两个自变量给这个程序: 档案库的路径, 以及准备送交的异动名称. 如果程序传回一个非零的结束值, 送交会被中止, 而异动会被删除. 如何应用pre-commit我们不妨举个例子: 假如有一个项目由Mail Team,Login Team和PHP Team三个Team共同通过SVN系统开发完成。当项目准备发布的时候,PM人员发现Mail功能方面存在一些 bug,需要Mail Team去修改,为了防止其它Team的人员修改系统,我们可以在任何改动档案库的企图之前用pre-commit去检查log message信息,(因为任何更动档案库的操作都必须提供log message信息,PM可以事先舆Mail Team约定好一个log message),如果舆pre-commit中设定的log message不相符,则不能提交更动。 pre-commit源程序如下: #!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/local/bin/svnlook $SVNLOOK log -t "$TXN" "$REPOS" | \ grep –w "bug1234" > /dev/null || exit 1 exit 0 本例中的log message为”bug1234”,任何人想要提交更动就必须用 –m “bug1234”参数,采用-m “bug123”,-m “bug12345”都会提交失败。 post-commit 本挂勾执行的时间是在异动送交, 新修订版被建立之后. 大多数的人用这个挂勾来寄出关于本次送交的电子邮件, 或是建立档案库的备份. 档案库会传递两个自变量给这个程序: 档案库的路径, 以及新建立的修订版号. 本程序的结束码会被忽略. Subversion 源码树的 tools/hook-script 目录中包含了一个 commit-email.pl 命令,可以用来寄送包含描述指定送交的电子邮件. 这个邮件包含了更动路径列表, 该送交所对应的记录讯息, 使用者, 送交的日期,以及一个以 GNU diff 样式表示的本次更动差异. 我们可以将这个程序舆post-commit这个hook搭配起来使用来实现档案库更动后自动mail给相关人员的功能。 post-commit源程序如下: #!/bin/sh REPOS="$1" REV="$2" commit-email.pl "$REPOS" "$REV" PM@yourdomain.com ##需要指明commit-email.pl的绝对路径 特殊性质 除了对你的目录与档案进行版本控制之外, Subversion 还提供了一个接口, 可用来新增, 修改, 以及移除已纳入版本控制的目录与档案的版本控制描述资料. 我们称这个描述资料为性质,在这里我主要介绍以下几个比较重要的特殊性质 svn:mime-type svn:mime-type 性质在 Subversion 中有很多作用. 除了作为储存档案的多用途网际网络邮件延伸语法 (MIME) 分类之外, 这个性质的内容还会决定几项 Subversion 的行为特征. 举个例子, 如果 svn:mime-type 性质设为文字的 MIME 类别 , Subversion 会假设该档的内容是二进制(也就是人类看不懂的资料). Subversion 提供的功能中, 其中一项是在从服务器收到工作档的更新中, 依文字内容与文字列进行合并. 但是对含有二进制资料的档案, 根本就没有 “文字列” 的概念. 因此, Subversion 对这些档案在更新时, 不会试着进行内文合并. 它改用另一种方式。 一般来说Subversion 在执行 svn import 与 svn add 子命令时, 会使用二进制侦测运算法的方式来协助使用者.但是如果 Subversion 猜错了, 或是你希望将 svn:mime-type 设定成更为明确的值(可能是 image/png)你都可以移除或是手动编辑这个性质. svn:ignore svn:ignore 性质包含了档案样式的列表, Subversion 处理时会忽略. 它可以与执行时期设定的 global-ignores 选项一起工作, 以便在类似 svn status 的命令中过滤掉未纳入版本控制的目录与档案. 我们知道新增的文件和目录必须透过 svn add 命令, 才会被纳入 Subversion 的管理. svn status 命令会将工作复本中未纳入版控制目录与档案显示出来. $ svn status calc M calc/button.c ? calc/calculator ? calc/data.c ? calc/debug_log ? calc/debug_log.1 在这个范例中, 用?标注出来的文件就是未纳入版控制的档案.如果你不想每次执行 svn status 时, 都看到这些档案, 那幺svn:ignore 性质就是解决方案。你可以透过 svn propedit svn:ignore calc 对 calc 目录加上一些忽略样式. 举个例子,将以下的值作为 svn:ignore 性质的新内容: calculator debug_log* 加上这个性质后再执行你的 svn status 输出便会不同: $ svn status M calc M calc/button.c ? calc/data.c 现在, 所有不想看到的东西都从输出中消失了! svn:keywords Subversion 具有取代关键词(有关纳入版本控制档案的有用信息)进入档案内容的功能. 举个例子, 假设你有个文件, 想要在里面显示最近一次修改的日期. 你可以把这个负担加诸文件的作者身上, 让他们每一次送交更动之前, 顺便添加最近一次修改日期的部份. 但是迟早有人会忘记这件事. 换个方式, 只要叫 Subversion 对 LastChangedDate 关键词进行关键词取代即可. Subversion 定义了可用来进行取代的关键词列表. 这个列表包含了以下五个关键词: LastChangedDate LastChangedRevision LastChangedBy HeadURL Id 如果只把关键词定位锚加进档案里的话, 什幺事也不会发生.要告诉 Subversion 是否该对某一个档案进行关键词取代,得使用svn:keywords这个性质。当它被设定时, 它会控制该档案哪个关键词应该被取代. 举个例子, 假设你有一个纳入版本控制的档案, 名为 weather.txt, 看起来像这样: Here is the latest report from the front lines. $LastChangedDate$ $Rev$ Cumulus clouds are appearing more frequently as summer approaches. 如果没有设定该档案的 svn:keywords 性质, Subversion 什幺事也不会作. 让我们开启关键词 LastChangedDate 的内容取代. $ svn propset svn:keywords "LastChangedDate Author" weather.txt property `svn:keywords' set on 'weather.txt' $ 在你送交了这个性质更动之后, Subversion 会显示为: Here is the latest report from the front lines. $LastChangedDate: 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002) $ $Rev$ Cumulus clouds are appearing more frequently as summer approaches. 这样不管谁提交这个文件,都会在里面显示最近一次修改的日期。 svn:eol-style 除非另外指定版本控制档案的 svn:mime-type 性质, Subversion 会假设档案包含人类可读的资料.这对于列尾符号 (EOL) 是很不幸地, 因为不同的操作系统会使用不同的符号来表示一列的结尾. 举个例子, 一般用在 Windows 平台上的列尾符号是两个 ASCII 控制字符 :返回字符 (CR) 与换行字符 (LF). 但是 Unix 软件就只使用 LF 字符来表示一列的结尾.这样以来window客户提交的档案中的CR 字符在 linux客户端会显示成 ^M, 而linux客户提交的档案中CR 字符在 Windows 客户端会被忽略。结果将档案里的所有文字列合并成一个超长的文字列, 这是因为没有返回CRLF字符组合的存在来表示一个换行。 解决的方法是 svn:eol-style 性质. 当这个性质设定为native时, Subversion 会根据系统的类型来决定是否对该档案的结尾进行自动处理。. svn:externals 有的时候, 一个工作复本可能包含了数个不同来源的工作复本. 举个例子, 你可能想要有数个不同的目录, 各来自不同的档案库.我们可以通过svn:externals 性质来宣告这一对对应关系。内容是子目录对应至 Subversion 档案库 URL 的多行表格. $ svn propget svn:externals calc third-party/sounds http://sounds.red-bean.com/repos third-party/skins http://skins.red-bean.com/repositories/skinproj third-party/skins/toolkit http://svn.red-bean.com/repos/skin-maker 当有人取出 calc 目录的工作复本, Subversion 还会继续取出在外部定义里的项目. $ svn checkout http://svn.example.com/repos/calc A calc A calc/Makefile A calc/integer.c A calc/button.c Checked out revision 148. Fetching external item into calc/third-party/sounds A calc/third-party/sounds/ding.ogg A calc/third-party/sounds/dong.ogg A calc/third-party/sounds/clang.ogg Checked out revision 14. Fetching external item into calc/third-party/skins … 小结 Subversion有一份很好的文檔——《Version Control with Subversion》(http://svnbook.red-bean.com/)。它提供了有关Subversion的各方面内容,如使用、管理和开发等。 经过数年的开发,以替代CVS为目标的Subversion,相信以其强大的功能,对CVS良好的继承性,一定会有很好的发展 |
IceSword-高级进程管理器介绍