Subversion的Repository列表完美解决方案

我的SVN项目都放在h:/svn下,在Apache中只是把这个目录设置成了虚拟目录,这样我可以方便的通过http://localhost/svn/project1访问这个目录下的所有Repository,但如果我想访问http://localhost/svn/,是得不到所有Repository列表的,只是一个403 Forbidden错误,在TortorseSVN的帮助中有这么一篇文章中提到了解决的方法,下面是我的具体实施和一点心得。

SVN在Apache中的配置段一般都用<Location>,我尝试过使用<Directory>,好像也可以,但不管用那个,在配置中无法使用AllowOverride指令,也就是说.htaccess文件无法使用。因此,若想把http://localhost/svn/转向到调用其它文件,只能使用Rewrite module,并且必须写在<Location>段之外。我就是在这里试了N久 :(。

(Apache一般配置和PHP、Rewrite module安装略过)

为了方便管理,用于显示Repository列表的PHP文件放在了h:/svn/svntools/目录,也就是在SVN的根目录下 :-)。因此,Apache中的这段配置如下:

Alias /svntools "h:/svn/svntools"
RewriteEngine on
RewriteRule ^/svn/$ /svntools/svn_index.php [PT]
<Location /svn>
DAV svn
SVNParentPath h:/svn
</Location>

先用Alias定义到h:/svn/svntools的虚拟目录,这样就可以访问到svn_index.php文件了,然后打开RewriteEngine,使用RewriteRule将到/svn/的访问重定向到/svntools/svn_index.php文件,通过执行这个文件就会产生Repository列表了;最后是SVN虚拟目录的配置。

Subversion初体验

Subversion是新一代的版本控制系统,其设计目的是为了替代CVS,并且同样是免费的协议,贡献给开源社区。

The goal of the Subversion project is to build a version control system that is a compelling replacement for CVS in the open source community. The software is released under an Apache/BSD-style open source license.

现在正在使用CVS,计划转移到Subversion下,因此要先试一试。和它配套的客户端软件不再是Wincvs了,而是TortoiseSVN,从官方网站的域名看,似乎是一家人。

目前的最新版本是Subversion 1.2.0,TortoiseSVN 1.2.0.3602,我的安装平台是WinXP sp2。

安装前需要安装Apache和Python,这些我好像都有了:-)。

安装Subversion

这里下载了Win下ZIP版的文件,直接解压到h盘。解压就OK了?没几个文件啊,看了看安装说明,应该是这样,说明中还讲了如何更新svn:

svn co http://svn.collab.net/repos/svn/trunk svn

这个命令会将最新的svn源文件下载到svn目录中。试着更新了一次,下来很多文件,我的水平是看不懂了,只知道里面有Python、C、Html文件什么的。

创建Subversion服务器

建立Repository目录

md h:/svn

创建Repository

svnadmin create h:/svn/Fwolf

接下来就可以导入、导出项目了

svn import h:/temp/project file:///h:/svn/Fwolf -m "项目初始化"

svn checkout file:///h:/svn/Fwolf h:/project

这个是针对h:/temp/project目录下的所有项目(一个目录一个项目)的导入、导出,而我则想从CVS导入项目。

导入CVS服务器的内容

这里下载cvs2svn,这是一个Python编写的工具,用于把CVS的Repository转换成SVN的Repository,但并非是在两者之间进行同步。目前的版本是1.2.1。

cvs2svn有多种转换方式,在这里我选择全盘转换。其它的使用方式还有诸如不转换TAG和BRANCH、不要LOG等等。

cvs2svn需要RCS `co`或者CVS才能正常工作,谁知道这两个是什么东西,看起来好像和CVS采用的文档格式解析有关系,我选用了RCS,它也有Windows下的Bin包(里面的一个rcslib.dll文件也要解压,co.exe需要这个文件)。还需要GNU sort,刚开始我不知道,结果在pass 3就出现了错误:

—– pass 3 —–
Sorting CVS revisions…
输入文件指定了两次。

Command failed: "sort -T . ./cvs2svn-data.c-revs > ./cvs2svn-data.s-revs"

GNU sort的Win32二进制版本可以在http://unxutils.sourceforge.net/找到。sort.exe只有38k,但为了下载它却需要下载3M多的UnxUtils.zip。

执行以下命令进行Repository的转换:

c:/python23/python h:/cvs2svn-1.2.1/cvs2svn –existing-svnrepos -s h:/svn/Fwolf h:/cvsroot/Fwolf

需要注意的是,在原CVS的Repository中不能有中文的文件名,否则转换会出错。–encoding=ENC参数是解决这个问题的,但不知道怎么用,也不知道是否支持中文。经过一段时间的等待,转换终于成功完成了:

cvs2svn Statistics:
——————
Total CVS Files: 650
Total CVS Revisions: 2343
Total Unique Tags: 11
Total Unique Branches: 3
CVS Repos Size in KB: 445396
Total SVN Commits: 794
First Revision Date: Wed Apr 02 16:14:39 2003
Last Revision Date: Mon Jun 13 22:27:01 2005
——————
Timings:
——————
pass 1: 3 seconds
pass 2: 0 seconds
pass 3: 0 seconds
pass 4: 0 seconds
pass 5: 2 seconds
pass 6: 0 seconds
pass 7: 0 seconds
pass 8: 192 seconds
total: 199 seconds

接下来,要把SVN配置到Apache中

拷贝mod_dav_svn.so、mod_authz_svn.so、libdb43.dll、libeay32.dll、intl3_svn.dll、ssleay32.dll到Apache的modules目录,在httpd.conf中增加:

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

然后重启Apache,注意前两句涉及的模块是Apache的自带模块。我在这里的时候一开始总是Apache重启出错,提示

The Apache service named reported the following error:
>>> Cannot load H:/server/Apache2/modules/mod_dav_svn.so into server: 找不到指定的程序。

The Apache service named reported the following error:
>>> Cannot load H:/server/Apache2/modules/mod_dav_svn.so into server: xd5xd2xb2xbbxb5xbdxd6xb8xb6xa8xb5xc4xb3xccxd0xf2xa1xa3

在这么炎热的夏天,我鼓捣了一下午才发现问题之所在,第一个错误信息是Apache 2.0.48的,第二个错误信息是Apache 2.0.52的,这两个版本的mod_dav.so可能有些问题,更新到2.0.54就可以了,当然那几个DLL文件也要复制的。如果还提示缺少 libhttpd.dll,这个文件在Apache的bin目录下,自己找就可以了。相信很多人和我一样卡在这里:-(。

(后来又想,是否还有另外一种可能导致Apache出错,那就是前两个版本我都是直接复制的文件,而最后那个是使用MSI进行安装的,是否由于这个原因导致mod_dav出了问题呢?)

在Apache中添加虚拟目录的映射

在httpd.conf中增加:

<Location /svn/project1>
DAV svn
SVNPath h:/svn/project1
</Location>

其中project1是一个Repository的目录名,这样就可以使用网址http://localhost/svn/project1/来访 问SVN文件了。还有一种方式是直接将SVN的根目录定义为Apache的虚拟目录,这样它下面的每个Repository都可以通过类似上面的URL来 访问了,不用一个一个的重复定义,类似:

<Location /svn>
DAV svn
SVNParentPath h:/svn
</Location>

这样我同样可以使用http://localhost/svn/project1/来访问Repository。(但这样的话,http://localhost/svn/无法访问,403 Forbidden错误,不知如何解决。)

“DAV svn”不能变,它是用来说明“说明Apache会使用svn这个module来解析这个虚拟目录”,其余的可以根据具体情况调整。

这篇就到这里吧,关于SVN的使用、虚拟目录的权限设定网上都有很多文章了。

另外一点就是,由于在Repository中每个Revision都会形成一个文件,所以我担心Revision多了之后,存取文件的效率会降低,因此,我认为采用每个项目在单独的一个Repository中存储的方式会更好些。

(pLog无法输入反斜杠,因此在DOS命令中我只能输入/来代替)