版本库的创建和配置
最后更新于:2022-04-02 05:56:51
### 版本库的创建和配置
创建一个 Subversion 版本库出乎寻常的简单。 Subversion 提供的**svnadmin** 工具,有一个执行这个功能的子命令。要建立一个新的版本库,只需要运行:
~~~
$ svnadmin create /path/to/repos
~~~
这个命令在目录`/path/to/repos`创建了一个新的版本库。这个新的版本库会以修订版本版本0开始其生命周期,里面除了最上层的根目录(`/`),什么都没有。刚开始,修订版本0有一个修订版本属性`svn:date`,设置为版本库创建的时间。
在 Subversion 1.1中,版本库默认使用Berkeley DB后端存储方式来创建。在以后的发行版中这个行为会被改变。不管怎样,存储类型可以使用`--fs-type`参数明确说明。:
~~~
$ svnadmin create --fs-type fsfs /path/to/repos
$ svnadmin create --fs-type bdb /path/to/other/repos
~~~
### 警告
不要在网络共享上创建Berkeley DB版本库―它不能存在于诸如NFS, AFS或Windows SMB的远程文件系统中,Berkeley 数据要求底层文件系统实现严格的POSIX锁定语义,几乎没有任何网络文件系统提供这些特性,假如你在网络共享上使用Berkeley DB,结果是不可预知的――许多错误可能会立刻发现,也有可能在几个月之后才能发现
假如你需要多台计算机来访问,你需要在网络共享上创建FSFS版本库,而不是Berkeley DB的版本库。或者更好的办法,你建立一个真正的服务进程(例如Apache或**svnserve),把版本库放在**服务器能访问到的本地文件系统中,以便能通过网络访问。详情请参看[第6章 *配置服务器*]( "第6章配置服务器")
你可能已经注意到了,**svnadmin**命令的路径参数只是一个普通的文件系统路径,而不是一个**svn**客户端程序访问版本库时使用的URL。**svnadmin**和**svnlook**都被认为是服务器端工具―它们在版本库所在的机器上使用,用来检查或修改版本库,不能通过网络来执行任务。一个Subversion的新手通常会犯的错误,就是试图将URL(甚至“本地”`file:`路径)传给这两个程序。
所以,当你运行**svnadmin create**命令后,就会在运行目录创建一个崭新的Subversion版本库,让我们看一下在这个目录创建中创建了什么。
~~~
$ ls repos
conf/ dav/ db/ format hooks/ locks/ README.txt
~~~
除了`README.txt`和`format`文件,版本库目录就是一些子目录了。就像Subversion其它部分的设计一样,模块化是一个很重要的原则,而且层次化的组织要比杂乱无章好。下面是对新的版本库目录中各个项目的简要介绍:
conf
一个存储版本库配置文件的目录。
dav
提供给Apache和mod_dav_svn的目录,让它们存储自己的数据。
db
你所有的受版本控制数据的所在之处。这个目录或者是个Berkeley DB环境(满是数据表和其他东西),或者是一个包含修订版本文件的FSFS环境。
format
包含了用来表示版本库布局版本号的整数。
hooks
一个存储钩子脚本模版的目录(还有钩子脚本本身, 如果你安装了的话)。
locks
一个存储Subversion版本库锁定数据的目录,被用来追踪对版本库的访问。
README.txt
这个文件只是用来告诉它的阅读者,他现在看的是 Subversion 的版本库。
一般来说,你不需要手动干预版本库。**svnadmin**工具应该足以用来处理对版本库的任何修改,或者你也可以使用第三方工具(比如Berkeley DB的工具包)来调整部分版本库。不过还是会有些例外情况,我们会在这里提到。
### 钩子脚本
所谓*钩子*就是与一些版本库事件触发的程序,例如新修订版本的创建,或是未版本化属性的修改。每个钩子都会被告知足够多的信息,包括那是什么事件,所操作的对象,和触发事件的用户名。通过钩子的输出或返回状态,钩子程序能让工作继续、停止或是以某种方式挂起。
*默认情况下,钩子的子目录中包含各种版本库钩子模板。*
~~~
$ ls repos/hooks/
post-commit.tmpl pre-revprop-change.tmpl
post-revprop-change.tmpl start-commit.tmpl
pre-commit.tmpl
~~~
对每种Subversion版本库支持的钩子的都有一个模板,通过查看这些脚本的内容,你能看到是什么事件触发了脚本及如何给传脚本传递数据。同时,这些模版也是如何使用这些脚本,结合Subversion支持的工具来完成有用任务的例子。要实际安装一个可用的钩子,你需要在`repos/hooks`目录下安装一些与钩子同名(如 **start-commit**或者**post-commit**)的可执行程序或脚本。
在Unix平台上,这意味着要提供一个与钩子同名的脚本或程序(可能是shell 脚本,Python 程序,编译过的c语言二进制文件或其他东西)。当然,脚本模板文件不仅仅是展示了一些信息―在Unix下安装钩子最简单的办法就是拷贝这些模板,并且去掉.tmpl扩展名,然后自定义钩子的内容,确定脚本是可运行的。Windows用文件的扩展名来决定一个程序是否可运行,所以你要使程序的基本名与钩子同名,同时,它的扩展名是Windows系统所能辨认的,例如`exe`、`com`和批处理的`bat`。
### 提示
由于安全原因,Subversion版本库在一个空环境中执行钩子脚本―就是没有任何环境变量,甚至没有`$PATH`或`%PATH%`。由于这个原因,许多管理员会感到很困惑,它们的钩子脚本手工运行时正常,可在Subversion中却不能运行。要注意,必须在你的钩子中设置好环境变量或为你的程序指定好绝对路径。
目前Subversion有已实现了五种钩子:
`start-commit`
它在提交事务产生前已运行,通常用来判定一个用户是否有权提交。版本库传给该程序两个参数:到版本库的路径,和要进行提交的用户名。如果程序返回一个非零值,会在事务产生前停止该提交操作。如果钩子程序要在stderr中写入数据,它将排队送至客户端。
`pre-commit`
在事务完成提交之前运行,通常这个钩子是用来保护因为内容或位置(例如,你要求所有到一个特定分支的提交必须包括一个bug追踪的ticket号,或者是要求日志信息不为空)而不允许的提交。版本库传递两个参数到程序:版本库的路径和正在提交的事务名称,如果程序返回非零值,提交会失败,事务也会删除。如果钩子程序在stderr中写入了数据,也会传递到客户端。
Subversion的分发版本包括了一些访问控制脚本(在Subversion源文件目录树的`tools/hook-scripts`目录),可以用来被**pre-commit**调用来实现精密的写访问控制。另一个选择是使用Apache的httpd模块**mod_authz_svn**,可以对单个目录进行读写访问控制(见[“每目录访问控制”一节]( "每目录访问控制"))。在未来的Subversion版本中,我们计划直接在文件系统中实现访问控制列表(ACLs)。
`post-commit`
它在事务完成后运行,创建一个新的修订版本。大多数人用这个钩子来发送关于提交的描述性电子邮件,或者作为版本库的备份。版本库传给程序两个参数:到版本库的路径和被创建的新的修订版本号。退出程序会被忽略。
Subversion分发版本中包括**mailer.py**和**commit-email.pl**脚本(存于Subversion源代码树中的`tools/hook-scripts/`目录中)可以用来发送描述给定提交的email(并且或只是追加到一个日志文件),这个mail包含变化的路径清单,提交的日志信息、日期和作者以及修改文件的GNU区别样式输出。
Subversion提供的另一个有用的工具是**hot-backup.py**脚本(在Subversion源代码树中的tools/backup/目录中)。这个脚本可以为Subversion版本库进行热备份(Berkeley DB数据库后端支持的一种特性),可以制作版本库每次提交的快照作为归档和紧急情况的备份。
`pre-revprop-change`
因为Subversion的修订版本属性不是版本化的,对这类属性的修改(例如提交日志属性`svn:log`)将会永久覆盖以前的属性值。因为数据在此可能丢失,所以Subversion提供了这种钩子(及与之对应的`post-revprop-change`),因此版本库管理员可用一些外部方法记录变化。作为对丢失未版本化属性数据的防范,Subversion客户端不能远程修改修订版本属性,除非为你的版本库实现这个钩子。
这个钩子在对版本库进行这种修改时才会运行,版本库给钩子传递四个参数:到版本库的路径,要修改属性的修订版本,经过认证的用户名和属性自身的名字。
`post-revprop-change`
我们在前面提到过,这个钩子与`pre-revprop-change`对应。事实上,因为多疑的原因,只有存在`pre-revprop-change`时这个脚本才会执行。当这两个钩子都存在时,`post-revprop-change`在修订版本属性被改变之后运行,通常用来发送包含新属性的email。版本库传递四个参数给该钩子:到版本库的路径,属性存在的修订版本,经过校验的产生变化的用户名,和属性自身的名字。
Subversion分发版本中包含**propchange-email.pl**脚本(在Subversion源代码树中的`tools/hook-scripts/`目录中),可以用来发送修订版本属性修改细节的email(并且或只是追加到一个日志文件)。这个email包含修订版本和发生变化的属性名,作出修改的用户和新属性值。
### 警告
不要尝试用钩子脚本修改事务。一个常见的例子就是在提交时自动设置`svn:eol-style`或`svn:mime-type`这类属性。这看起来是个好主意,但它会引起问题。主要的问题是客户并不知道由钩子脚本进行的修改,同时没有办法通告客户它的数据是过时的,这种矛盾会导致出人意料和不能预测的行为。
作为尝试修改事务的替代,我们通过检查`pre-commit`钩子的事务,在不满足要求时拒绝提交。
Subversion会试图以当前访问版本库的用户身份执行钩子。通常,对版本库的访问总是通过Apache HTTP服务器和mod_dav_svn进行,因此,执行钩子的用户就是运行Apache的用户。钩子本身需要具有操作系统级的访问许可,用户可以运行它。另外,其它被钩子直接或间接使用的文件或程序(包括Subversion版本库本身)也要被同一个用户访问。换句话说,要注意潜在的访问控制问题,它可能会让你的钩子无法按照你的目的顺利执行。
### Berkeley DB配置
Berkeley DB环境是对一个或多个数据库、日志文件、区域文件和配置文件的封装。Berkeley DB环境对许多参数有自己的缺省值,例如任何时间里可用的锁定数目、日志文件的最大值等。Subversion文件系统会使用Berkeley DB的默认值。 不过,有时候你的特定版本库与它独特的数据集合和访问类型,可能需要不同的配置选项。
Sleepycat(Berkeley DB的制造厂商)的人们清楚不同的数据库有不同的需求,所以他们提供了在运行中覆盖Berkeley DB环境配置参数的机制。Berkeley在每一个环境目录中检查是否存在一个名叫`DB_CONFIG`的文件,然后解析其中的参数成为Berkeley环境所用的选项。
你的版本库的Berkeley配置文件位于`db`目录的`repos/db/DB_CONFIG`, Subversion在创建版本库时自己创建了这个文件。这个文件初始时包含了一些默认选项,也包含了Berkeley DB在线文档,使你能够了解这些选项是做什么的。当然,你也可以为你的`DB_CONFIG` 文件添加任何Berkeley DB支持的选项。需要注意到,虽然Subversion不会尝试读取并解析这个文件,或使用其中的设置,你一定要避免会导致Berkeley DB按照Subversion代码不习惯的方式工作的修改。另外,`DB_CONFIG`的修改在复原数据库环境(用**svnadmin recover**)之前不会产生任何效果。
';