创建一个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 DB需要底层文件系统实现严格的POSIX锁机制,更重要的是,直接把文件映射到进程内存中的能力。几乎没有哪个网络文件系统 提供这样的特性。如果你企图在一个网络共享上使用Berkeley DB,结果是不可预计的——你可能会立即看到奇怪的错误,或者几个月后 发现你的资料库数据库被轻微的破坏了。
如果你需要多个计算机来访问资料库,你可以在网络共享上创建一个FSFS资料库,而不是Berkeley DB资料库。或者更好的办法是 设置一个真正的服务器进程(比如Apche或者svnserve),把资料库保存在服务器进程能访问的本地文件系统上, 使资料库通过网络共享。第 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文件,资料库目录是一个子目录的集合。如同在
Subversoin设计的其它领域,模块化受到高度关注,倾向于层次化组织不是一片混乱。以下是对你在你的新的资料库目录看到的
所有条目的简要描述:
保存资料库配置文件的目录。
提供给Apache和mod_dav_svn来保存它们私有的管理数据的目录。
你所有的版本化数据保存的地方。这个目录是一个Berkeley DB环境(充满了DB表和其它东西),或者是一个保存修订版文件的FSFS环境。
一个内容为一个整数的文件,指出了资料库布局的版本号。
放满了钩子脚本模板的目录(一旦你安装了一些钩子脚本的话,也包括它们本身)。
保存资料库锁数据的目录,用来跟踪资料库的访问者。
这个文件只是用来通知它的读者他正在看的是一个Subversion资料库。
一般而言, 你不应该“手工”擅改你的资料库。对你资料库的任何必要的修改用svnadmin工具都足够了。 或者你可以找一些第三方的工具(比如 Berkeley DB 的工具包)来对资料库做细部的调整。但也有一些例外,我们将在这里讨论它们。
钩子(hook)是能被某些资料库事件触发的程序,比如一个新修订版的创建或者一个非版本化属性的修改。 每个钩子都能得到足够的信息来分辨这是个什么事件,它的操作目标是什么,触发这个事件的人的名字。根据这个钩子的输出或返回的 状态,钩子程序可能继续这个动作,停止它,或用某些方式挂起它。
缺省情况下,hooks子目录保存各种资料库钩子的模版。
$ 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跟踪程序的许可号码,或者引入的日志消息必须是非空的)。资料库传递两个参数给这个程序: 资料库的路径,和将被提交的事务的名字。如果你的程序返回一个非零值,提交将被取消并且事务将被删除。如果钩子程序在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/ 目录),它们可以用来发送带给定提交的描述(和/或附加一个日志文件)的邮件。
这个邮件包含被修改的路径的列表,附加于这个提交的日志消息,这个提交的作者和日期,也包括以GNU diff风格显示的作为提交的一部分的
对各个文件的修改。
另一个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
钩子将在一个修订版属性刚被修改后运行,通常用来发送包含修改后属性的新值的邮件。资料库传递四个参数给这个钩子:资料库的路径,将被修改的属性存在的修订版,
被授权进行这个修改的人的用户名和属性本身的名字。
Subversion分发版包括一个propchange-email.pl脚本(位于Subversion 源代码树的tools/hook-scripts/目录),它可以用来发送包含修订版属性修改细节的邮件(和/或附加一个日志文件)。这个邮件包含修订版和
修改的属性名,做修改的用户和新的属性值。
不要试图用钩子脚本修改事务。常见的例子是用来在提交过程中自动设置如 svn:eol-style 和
svn:mime-type这样的属性。虽然这可能看起来是个好主意,但是它会引起问题。
主要的问题是客户端不知道钩子脚本作的修改,也没有可以通知客户端它过时的办法。这种不一致会导致奇怪的和不期望的行为。
更好的用法是在pre-commit钩子中检查事务,并在它不满足要求的情况下否决它
,而不是试图修改事务。
Subversion将尝试用拥有访问Subversion资料库的进程的用户来执行钩子。在大部分情况下,资料库通过Apache HTTP服务器和mod_dav_svn被 访问,因此这个用户是运行Apache的那个用户。钩子本身需要在操作系统一级被配置为允许用户执行它们。这也意味着被钩子直接或间接访问 的任何文件和程序(包括Subversion资料库本身)都是由相同的用户访问的。换句话说,要提防潜在的权限相关问题,它们可能会导致钩子无法完成你写它来完成的任务。
一个Berkeley DB环境封装了一个或多个数据库,日志文件,region文件和配置文件。Berkeley DB环境有它自己的一套缺省配置值,比如在给定时间被允许取得的锁的数量,或者最大的日志文件大小等等。Subversion的文件系统代码额外选择了一些Berkeley DB选项的缺省值。 然而,有时你特定的资料库,拥有自己独一无二的数据集和访问模式,可能需要不同的配置选项值集合。
在Sleepycat(Berkeley DB的出品者)的人们明白不同的数据库有不同的需求,因此他们为Berkeley DB环境提供了在运行时替换许多配置值
的机制。Berkeley 检查在每个它的环境目录中名为DB_CONFIG的文件,解析在其中发现的选项以用于那个特定的Berkeley环境。
你资料库的Berkeley 配置文件位于db环境目录,就是 repos/db/DB_CONFIG。Subversion自己在创建资料库的时候创建了这个文件。最初,这个文件包含了一些缺省选项,也包括对Berkeley DB在线文档的指向,以使你能读到这些选项
怎么用。当然,你可以任意添加被支持的Berkeley DB选项到你的DB_CONFIG文件。只要知道虽然Subversion从不尝试
去读或解释这个文件的内容,也不会利用其中设置的选项,但是你要避免任何可能导致 Berkeley DB 以其它Subversion代码所不希望的方式
来运行的配置修改。并且,对DB_CONFIG的修改在你恢复你的数据库环境(使用svnadmin
recover)后才会生效。