### 第7章高级主题 **目录** 如果你是从头到尾按章节阅读本书,你一定已经具备了使用Subversion客户端执行大多数不同的版本控制操作足够的知识,你理解了怎样从Subversion版本库取出一个工作拷贝,你已经熟悉了通过**svn commit**和**svn update**来提交和接收修改,你甚至也经常下意识的使用**svn status**,无论目的是什么,你已经可以正常使用Subversion了。 但是Subversion的特性集可不只是“一般的版本控制操作”。 本章重点介绍一些Subversion不常用的特性,在这里,我们会讨论Subversion的属性(或者说“元数据”)支持,和如何通过更改运行配置区来改变Subversion的缺省行为方式,我们会描述怎样使用外部定义来指导Subversion从多个版本库得到数据,我们会覆盖一些Subversion分发版本附加的客户端和服务器端的工具的细节。 在阅读本章之前,你一定要熟悉Subversion对文件和目录的基本版本操作能力,如果你还没有阅读这些内容,或者是需要一个复习,我们建议你重读[第2章 *基本概念*]和[第3章 *指导教程*],一旦你已经掌握了基础知识和本章的内容,你会变成Subversion的超级用户! ### 运行配置区 Subversion提供了许多用户可以控制的可选行为方式,许多是用户希望添加到所有的Subversion操作中的选项,为了避免强制用户记住命令行参数并且在每个命令中使用,Subversion使用配置文件,并且将配置文件保存在独立的Subversion配置区。 Subversion*配置区*是一个双层结构,保存了可选项的名称和值。通常,Subversion配置区是一个保存*配置文件*的特殊目录(第一层结构),目录中保存了一些标准INI格式的文本文件(文件中的“section”形成第二层结构)。这些文件可以简单用你喜欢的文本编辑器编辑(如Emacs或vi),而且保存了客户端可以读取的指示,用来指导用户的一些行为选项。 ### 配置区布局 **svn**命令行客户端第一次执行时,会创建一个用户配置区,在类Unix系统中,配置区位于用户主目录中,名为`.subversion`。在Win32系统,Subversion创建一个名为`Subversion`的目录,这个目录通常位于用户配置目录(顺便说一句,通常是一个隐藏目录)的`Application Data`子目录下。然而,在Win32平台上,此目录的具体位置在不同的系统上是不一样的,由Windows注册表决定。 我们以Unix下的名字`.subversion`来表示用户配置区。 除了用户配置区,Subversion也提供了系统配置区,通过系统配置区,系统管理员可以为某个机器的所有用户建立缺省配置值。注意系统配置区不会规定强制性的策略―每个用户配置区都可以覆盖系统配置区中的配置项,而**svn**的命令行参数决定了最后的行为。在类Unix的平台上,系统配置区位于`/etc/subversion`目录下,在Windows平台上,系统配置区位于`Application Data`(再说一次,是由Windows注册表决定的)的`Subversion`目录中。与用户配置区不同,**svn**不会试图创建系统配置区。 目前,Subversion的配置区包含三个文件―两个配置文件(`config`和`servers`),和一个INI文件格式的`README.txt`描述文件。配置文件创建的时候,Subversion的选项都设置为默认值。配置文件中的选项都按功能划分成组,大多数选项还有详细的文字描述注释,说明这些选项的值对Subversion的主要影响。要修改选项,只需用文本编辑器打开并编辑配置文件。如果想要恢复缺省的配置,可以直接删除(或者重命名)配置目录,并且运行一些如**svn --version**之类的无关紧要的**svn**命令,一个包含缺省值的新配置目录就会创建起来。 用户配置区也缓存了认证信息,`auth`目录下的子目录中缓存了一些Subversion支持的各种认证方法的信息,这个目录需要相应的用户权限才可以访问。 ### 配置和Windows注册表 除了基于INI文件的配置区,运行在Windows平台的Subversion客户端也可以使用Windows注册表来保存配置数据。注册表中保存的选项名称和值的含义与INI文件中相同,“file/section”在注册表中表现为注册表键树的层级,使得双层结构得以保留下来。 Subversion的系统配置值保存在键`HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion`下。举个例子,`global-ignores`选项位于`config`文件的`miscellany`小节,在Windows注册表中,则位于`HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Config\Miscellany\global-ignores`。用户配置值存放在`HKEY_CURRENT_USER\Software\Tigris.org\Subversion`下。 基于注册表的配置项在基于文件的配置项*之前*解析,所以其配置项的值会被配置文件中相同配置项的值覆盖,换句话说,在Windows系统下配置项的优先级是: 1. 命令行选项 1. 用户INI配置文件 1. 用户注册表值 1. 系统INI配置文件 1. 系统注册表值 此外,虽然Windows注册表不支持“注释掉”这种概念,但是Subversion会忽略所有以井号(`#`)开始的字符,这允许你快速的取消一个选项而不需要删除整个注册表键,明显简化了恢复选项的过程。 **svn**命令行客户端不会尝试写Windows注册表,也不会在注册表中创建默认配置区。不过可以使用**REGEDIT**创建所需的键。此外,还可以创建一个`.reg`文件,并在文件浏览器中双击这个文件,文件中的数据就会合并到注册表中。 **例7.1.注册表条目(.reg)样本文件。** ~~~ REGEDIT4 [HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Servers\groups] [HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Servers\global] "#http-proxy-host"="" "#http-proxy-port"="" "#http-proxy-username"="" "#http-proxy-password"="" "#http-proxy-exceptions"="" "#http-timeout"="0" "#http-compression"="yes" "#neon-debug-mask"="" "#ssl-authority-files"="" "#ssl-trust-default-ca"="" "#ssl-client-cert-file"="" "#ssl-client-cert-password"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\auth] "#store-auth-creds"="no" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\helpers] "#editor-cmd"="notepad" "#diff-cmd"="" "#diff3-cmd"="" "#diff3-has-program-arg"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\miscellany] "#global-ignores"="*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store" "#log-encoding"="" "#use-commit-times"="" "#template-root"="" "#enable-auto-props"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\tunnels] [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\auto-props] ~~~ 上面例子里显示的`.reg`文件中,包含了一些最常用的配置选项和它们的缺省值。注意,上面的例子中不仅包含了系统设置(关于网络代理相关的选项),也包含了用户设置(指定的编辑器程序,是否保存密码,以及其它选项)。同时要注意的是,所有选项都注释掉了,要启用其中的选项,只需删除该选项名称前面的井号(`#`),然后设置相应的值就可以了。 ### 配置选项 本节我们会详细讨论Subversion目前支持的运行配置选项。 #### 服务器 `servers`文件保存了Subversion关于网络层的配置选项,这个文件有两个特别的小节:`groups` 和`global`。`groups`小节是一个交叉引用表,其中的关键字是`servers`文件中其它小节的名字,值则是一个可以包含通配符的字符序列,对应于接收Subversion请求的主机名,称为glob。 ~~~ [groups] beanie-babies = *.red-bean.com collabnet = svn.collab.net [beanie-babies] … [collabnet] … ~~~ 当通过网络访问Subversion服务器时,客户端会设法匹配正在尝试连接的服务器名字和`groups`小节中的glob名称,如果发现匹配,Subversion会在`servers`文件中查找对应于这个glob名称的小节,并从该小节中去读取真实的网络配置设置。 如果没有能够匹配到`groups`中的glob名称,`global`小节中的选项就会发生作用。`global`小节中的选项与其他小节一样(当然是除了`groups`小节),这些选项是: `http-proxy-host` 代理服务器的详细主机名,是HTTP为基础的Subversion请求必须通过的,缺省值为空,意味着Subversion不会尝试通过代理服务器进行HTTP请求,而会尝试直接连接目标机器。 `http-proxy-port` 代理服务器的详细端口,缺省值为空。 `http-proxy-username` 代理服务器的用户名,缺省值为空。 `http-proxy-password` 代理服务器的密码,缺省为空。 `http-timeout` 等待服务器响应的时间,以秒为单位,如果你的网络速度较慢,导致Subversion的操作超时,你可以加大这个数值,缺省值是`0`,意思是让HTTP库Neon使用自己的缺省值。 `http-compression` 这说明是否在与设置好DAV的服务器通讯时使用网络压缩请求,缺省值是`yes`(尽管只有在这个功能编译到网络层时压缩才会有效),设置`no`来关闭压缩,如调试网络传输时。 `neon-debug-mask` 只是一个整形的掩码,底层的HTTP库Neon用来选择产生调试的输出,缺省值是`0`,意思是关闭所有的调试输出,关于Subversion使用Neon的详细信息,见[第8章 *开发者信息*]。 `ssl-authority-files` 这是一个分号分割的路径和文件列表,这些文件包含了Subversion客户端在用HTTPS访问时可以接受的认证授权(或者CA)证书。 `ssl-trust-default-ca` 如果你希望Subversion可以自动相信OpenSSL携带的缺省的CA,可以设置为`yes`。 `ssl-client-cert-file` 如果一个主机(或是一些主机)需要一个SSL客户端证书,你会收到一个提示说需要证书的路径。通过设置这个路径你的Subversion客户端可以自动找到你的证书而不会打扰你。没有标准的存放位置;Subversion会从任何你指定的路径得到这个文件。 `ssl-client-cert-password` 如果你的SSL客户端证书文件是用密码加密的,Subversion会在每次使用证书时请你输入密码,如果你发现这很讨厌(并且不介意把密码存放在`servers`文件中),你可以设置这个参数为证书的密码,这样就不会再收到密码输入提示了。 #### config 其它的Subversion运行选项保存在`config`文件中,这些运行选项与网络连接无关,只是一些正在使用的选项,但是为了应对未来的扩展,也按小节划分成组。 `auth`小节保存了Subversion相关的认证和授权的设置,它包括: `store-passwords` 这告诉Subversion是否缓存服务器认证要求时用户提供的密码,缺省值是`yes`。设置为`no`可以关闭在存盘的密码缓存,你可以通过**svn**的`--no-auth-cache`命令行参数(那些支持这个参数的子命令)来覆盖这个设置,详细信息请见[“客户端凭证缓存”一节]。 `store-auth-creds` 这个设置与`store-passwords`相似,不过设置了这个选项将会保存*所有*认证信息,如用户名、密码、服务器证书,以及其他任何类型的可以缓存的凭证。 `helpers`小节控制完成Subversion任务的外部程序,正确的选项包括: `editor-cmd` Subversion在提交操作时用来询问用户日志信息的程序,例如使用**svn commit**而没有指定`--message`(`-m`)或者`--file`(`-F`)选项。这个程序也会与**svn propedit**一起使用―一个临时文件跳出来包含已经存在的用户希望编辑的属性,然后用户可以对这个属性进行编辑(见[“属性”一节]),这个选项的缺省值为空,如果这个选项没有设置,Subversion会依次检查环境变量`SVN_EDITOR`、`VISUAL`和`EDITOR`(这个顺序)来找到一个编辑器命令。 `diff-cmd` 这个命令是比较程序的绝对路径,当Subversion生成了“diff”输出时(例如当使用**svn diff**命令)就会使用,缺省Subversion会使用一个内置的比较库―设置这个参数会强制它使用外部程序执行这个任务。 `diff3-cmd` 这指定了一个三向的比较程序,Subversion使用这个程序来合并用户和从版本库接受的修改,缺省Subversion会使用一个内置的比较库―设置这个参数会导致它会使用外部程序执行这个任务。 `diff3-has-program-arg` 如果`diff3-cmd`选项设置的程序接受一个`--diff-program`命令行参数,这个标记必须设置为`true`。 `tunnels`小节允许你定义一个**svnserve**和`svn://`客户端连接使用的管道模式,更多细节见[“SSH认证和授权”一节]。 `miscellany`小节是一些没法归到别处的选项。 在本小节,你会找到: `global-ignores` 当运行**svn status**命令时,Subversion会和版本化的文件一样列出未版本化的文件和目录,并使用``字符(见see [“**svn status**”一节](# "svn status"))标记,有时候察看无关的未版本化文件会很讨厌―比如程序编译产生的对象文件―的显示出来。`global-ignores`选项是一个空格分隔的列表,用来描述Subversion在它们版本化之前不想显示的文件和目录,缺省值是`*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store`。 就像**svn status**,**svn add**和**svn import**命令也会忽略匹配这个列表的文件,你可以用单个的`--no-ignore`命令行参数来覆盖这个选项,关于更加细致的控制忽略的项目,见[“`svn:ignore`”一节]。 `enable-auto-props` 这里指示Subversion自动对新加的或者导入的文件设置属性,缺省值是`no`,可以设置为`yes`来开启自动添加属性,这个文件的`auto-props`小节会说明哪些属性会被设置到哪些文件。 `log-encoding` 这个变量设置提交日志缺省的字符集,是`--encoding`选项(见[“**svn**选项”一节])的永久形式,Subversion版本库保存了一些UTF8的日志信息,并且假定你的日志信息是用操作系统的本地编码,如果你提交的信息使用别的编码方式,你一定要指定不同的编码。 `use-commit-times` 通常你的工作拷贝文件会有最后一次被进程访问的时间戳,不管是你自己的编辑器还是用**svn**子命令。这通常对人们开发软件提供了便利,因为编译系统通常会通过查看时间戳来决定那些文件需要重新编译。 在其他情形,有时候如果工作拷贝的文件时间戳反映了上一次在版本库中更改的时间会非常好,**svn export**命令会一直放置这些“上次提交的时间戳”放到它创建的目录树。通过设置这个config参数为`yes`,**svn checkout**、**svn update**、 **svn switch**和**svn revert**命令也会为它们操作的文件设置上次提交的时间戳。 `auto-props`小节控制Subversion客户端自动设置提交和导入的文件的属性的能力,它可以包含任意数量的键-值对,格式是`PATTERN = PROPNAME=PROPVALUE`,其中`PATTERN`是一个文件模式,匹配一系列文件名,此行其它两项为属性和值。如果一个文件匹配多次,会导致有多个属性集;然而,没有手段保障自动属性不会按照配置文件中的顺序应用,所以你可以一个规则“覆盖”另一个。你可以在`config`文件找到许多自动属性的用法实例。最后,如果你希望开启自动属性,不要忘了设置`miscellany`小节的`enable-auto-props`为`yes`。 `APPDATA`环境变量指向`Application Data`目录,所以你可以通过`%APPDATA%\Subversion`引用用户配置区目录。 就是一个大杂烩?