在“版本库开发策略”一节,我们我们看了一些在创建和配置Subversion版本库之前需要做的重要决定,现在我们最终要干活了!在本小节,我们要看看如何真实的创建一个Subversion版本库,并配置它在特定版本库事件执行自定义动作。
创建一个 Subversion 版本库出乎寻常的简单。 Subversion 提供的svnadmin 工具,有一个执行这个功能的子命令(create
)。
$ svnadmin create /path/to/repos
这样在目录/path/to/repos
使用默认数据存储方式创建了一个新的版本库。在Subversion 1.2之前,缺省值是Berkeley DB;而现在是FSFS。你可以通过--fs-type
参数明确地指定文件系统类型,可选的值包括fsfs
和bdb
。
$ # Create an FSFS-backed repository $ svnadmin create --fs-type fsfs /path/to/repos $
# Create a Berkeley-DB-backed repository $ svnadmin create --fs-type bdb /path/to/repos $
运行这个命令之后,你有了一个Subversion版本库。
你可能已经注意到了,svnadmin命令的路径参数只是一个普通的文件系统路径,而不是一个svn客户端程序访问版本库时使用的URL。svnadmin和svnlook都被认为是服务器端工具—它们在版本库所在的机器上使用,用来检查或修改版本库,不能通过网络来执行任务。一个Subversion的新手通常会犯的错误,就是试图将URL(甚至“本地”file:
路径)传给这两个程序。
这个命令在目录/path/to/repos
创建了一个新的版本库。这个新的版本库会以修订版本版本0开始其生命周期,里面除了最上层的根目录(/
),什么都没有。刚开始,修订版本0有一个修订版本属性svn:date
,设置为版本库创建的时间。
现在你有了一个版本库,可以用户化了。
一般来说,版本库除了一小部分—例如配置文件和钩子脚本,你不要(也不需要)手动干预版本库。svnadmin工具应该足以用来处理对版本库的任何修改,或者你也可以使用第三方工具(比如Berkeley DB的工具包)来调整部分版本库。不要尝试通过处理版本库数据存储文件手工修改版本控制历史,
钩子是通过版本库事件触发,例如新版本的创建或一个未版本化属性的修改。一些钩子(叫做“pre hooks”)在事件发生前运行,可以用来报告发生了什么以及防止它发生。还有一些钩子(“post hooks”)在版本库事件之后发生,只是用来报告。每个钩子能够获得事件的足够信息,例如提出的(或完成的)版本库修改细节,还有触发事件的用户名。
默认情况下,hooks
子目录中包含各种版本库钩子模板。
$ ls repos/hooks/ post-commit.tmpl post-unlock.tmpl pre-revprop-change.tmpl post-lock.tmpl pre-commit.tmpl pre-unlock.tmpl post-revprop-change.tmpl pre-lock.tmpl start-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会试图以当前访问版本库的用户身份执行钩子。通常,对版本库的访问总是通过Apache HTTP服务器和mod_dav_svn进行,因此,执行钩子的用户就是运行Apache的用户。钩子本身需要具有操作系统级的访问许可,用户可以运行它。另外,其它被钩子直接或间接使用的文件或程序(包括Subversion版本库本身)也要被同一个用户访问。换句话说,要注意潜在的访问控制问题,它可能会让你的钩子无法按照你的目的顺利执行。
Subversion版本库有9种钩子实现,你可以在“版本库钩子”一节获得每个的信息。作为一个版本库管理员,你需要决定你要实现的钩子(通过提供家当名称和执行许可的程序)类型和方法,这种决策需要对版本库的部署非常熟悉。例如,如果你使用服务器配置方式,通过版本库检测用户名称和权限,你不需要通过钩子系统实现访问控制。
在Subversion社区和其他地方都不缺Subversion钩子,这些脚本覆盖了广泛的工具—基本的访问控制,政策相关检查,问题追踪集成,email或提交通知等等。关于最常用的钩子程序的讨论,可以看附录 D, 第三方工具,如果你希望写你自己的,可以看第 8 章 嵌入Subversion。
尽管经过调整钩子脚本可以作任何事情,但钩子脚本的作者仍会受到一些限制:不要修改使用钩子脚本修改提交事务,因为使用钩子脚本自动修改错误或提交文件的政策违例的尝试会导致问题。Subversion会在客户端缓存对应的版本库数据,如果你这样修改了提交事务,这些缓存就进入了未知的状态,这种不一致会导致令人吃惊和预想不到的行为。作为对事物修改的替换,你可以简单的在pre-commit
确认事物信息并且拒绝提交,如果这样满足不了需求,作为额外的奖赏,你的用户会学会小心顺从的工作习惯。
Berkeley DB环境是对一个或多个数据库、日志文件、区域文件和配置文件的封装。Berkeley DB环境对许多参数有自己的缺省值,例如任何时间里可用的数据库锁定数目、日志文件的最大值等。Subversion文件系统会使用Berkeley DB的默认值。 不过,有时候你的特定版本库与它独特的数据集合和访问类型,可能需要不同的配置选项。
你的版本库的Berkeley配置文件位于db
目录的db/DB_CONFIG
, Subversion在创建版本库时自己创建了这个文件。这个文件初始时包含了一些默认选项,也包含了Berkeley DB在线文档,使你能够了解这些选项是做什么的。当然,你也可以为你的DB_CONFIG
文件添加任何Berkeley DB支持的选项。需要注意到,虽然Subversion不会尝试读取并解析这个文件,或使用其中的设置,你一定要避免会导致Berkeley DB按照Subversion代码不习惯的方式工作的修改。另外,DB_CONFIG
的修改在复原数据库环境(用svnadmin recover)之前不会产生任何效果。