原理: 基于subversion的钩子,即hook。在subversion执行一个操作时,那会相应的首先去调用相关的钩子程序(如果存在的话)。那么实现一个同步的测试服务器,我们只需要在一个用户执行完毕一个commit操作之后,让钩子程序去自动更新测试服务器的文件即可。通过这个思路,我们需要作的就是建立一个post-commit的钩子。
钩子文件在你的svn源目录下,即存放subversion版本数据的文件夹。以前面我写的两篇文章中的情况为例,
文一(win)的钩子文件应该在 E:\svn2\hooks
文二(Linux)的钩子文件应该在 /var/svn/hooks
文件夹内已经存在有一些.tmpl文件,这些只是一些模板(TeMPLate)或者说是示例文件。它们不会被执行。
先以linux为例,来讲讲如何构建一个同步的测试服务器127.0.0.2(在Ubuntu 6.10, apache2.0.55,subversion1.3.1下调试通过。2007/1/18)
我们假设你已经建立好了一个apache+subversion的环境。
0.准备工作
为同步服务器建立访问subversion版本的权限,清参考以前的文章
sudo htpasswd2 /etc/apache2/dav_svn.passwd server
1. 使用checkout建立一个工作复本
cd /var/www
sudo mkdir /var/www/127.0.0.2 #建立测试服务器站点根目录
sudo chown www-data.www-data 127.0.0.2 #更改用户所有者
sudo su www-data #切换到www-data,需要使用sudo,因为超级权限可以使用任何用户,而不需要密码,执行后会发现命令提示符可能会有变化
svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.2 #取出subversion上的文件,可能需要密码
# 请保证执行checkout语句的用户是www-data,否则在以后钩子调用update时会出现无法创建或修改文件的错误
exit #退出www-data用户
说明:我们必须把/var/www/127.0.0.2目录的所有者设置成apache的运行者(www-data), 他必须对文件夹具有完全的可读写操作权限。我使用
sudo chown www-data www
sudo su www-data
这样的方式来避免把/var/www/127.0.0.2目录设置成777的权限。
另外可以执行下面的代码实现相同的功能:
cd /var/www
sudo mkdir /var/www/127.0.0.2 #建立测试服务器站点根目录
sudo svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.2 #取出subversion上的文件,可能需要密码
sudo chown -R www-data.www-data 127.0.0.2/ #把文件用户修改成apache的执行用户
之后使用
ls -Al 127.0.0.2
应该可以得到
drwxr-xr-x 7 www-data www-data 4096 2007-01-17 10:21 .svn
...一些其他的文件
2。设置apache,把你需要的域名指向这个文件夹。
sudo gedit /etc/apache2/sites-available/127.0.0.2
输入以下文字
<VirtualHost 127.0.0.2>
ServerAdmin rollenc@localhost.com
ServerName localhost
DocumentRoot /var/www/127.0.0.2
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/127.0.0.2>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
# Uncomment this directive is you want to see apache2's
# default start page (in /apache2-default) when you go to /
#RedirectMatch ^/$ /apache2-default/
</Directory>
ErrorLog /var/log/apache2/127.0.0.2_error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/127.0.0.2_access.log combined
ServerSignature On
</VirtualHost>
启用他
sudo ln -s /etc/apache2/sites-available/127.0.0.2 /etc/apache2/sites-enabled/127.0.0.2
重启apache。
sudo apache2 -k restart
在浏览器上使用http://127.0.0.2可以浏览到你subversion上最新版本
3。建立钩子
现在是关键的一步,我们需要使我门的测试服务器127.0.0.2进行同步更新:
在/var/svn/hooks/目录下建立post-commit文件
cd /var/svn/hooks/
sudo gedit post-commit
输入以下内容
#!/bin/sh
REPOS="$1"
REV="$2"
svn update /var/www/127.0.0.2 --username server --password serverpassword
#echo `whoami`,$REPOS,$REV >> /home/rollenc/svn_hook_var.txt
#svn update /var/www/127.0.0.2 --username server --password serverpassword 2>/home/rollenc/svn_hook_log.txt
说明:REPOS即第一个变量$1是subversion数据库的地址,REV即第二的变量$2是commit之后的版本号。
编辑完毕后设置文件权限为可执行:
sudo chmod 755 post-commit
搞定。
下面来试一下,同步有没有成功。
再建立一个工作副本,然后添加或者修改一些东西,最后上传。
以下的操作是在客户端中进行了,不需要在服务器断进行。
cd /var/www
svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.6 #取出subversion上的文件作为你的工作副本,你的工作以后就在这个文件夹内展开。
#所以,不需要sudo,但要保证有127.0.0.6文件夹存在,而且可写
echo '<?php phpinfo(); ?>' > phpinfo.php #建立一个phpinfo文件
svn add phpinfo.php #把phpinfo加入版本库
svn commit #提交
在浏览器中你设定的同步服务器地址http://127.0.0.2/phpinfo.php,愿上帝保佑你的成果一切正常。可以看到phpinfo的信息。
如果不正常你可以稍微修改上面使用#注释掉的命名,使其输出的文件目录符合你的系统。
去掉#,重新运行,并通过查看上面设置的txt来获得一些信息。
第一句[#echo ...]是获取当前的执行用户(如果正常应该与apache的执行用户和测试服务器文件所有者相同),$REPOS,$REV是获得的两个参数
第二句[#svn...]是把update的获取update的结果,一般错误信息在这里可以得到。
在Windows下我使用同样的方法试图建立钩子,
以下是方法和代码,在windows XP下测试成功。
1,2步很类似,不再重复了
经过1,2步的操作之后,DIR的值E:/htddocs/testserver.lab.rollenc.com 为测试服务器的根目录。如果是win2003,你可能还需要参照ubuntu的方法设置一些权限。
第三步的中的钩子程序名称需要改为:post-commit.bat写成如下:
@echo off
SET REPOS=%1
SET USER=%2
SET SVN="D:/subversion/bin/svn.exe"
SET DIR="E:/htddocs/testserver.lab.rollenc.com"
(call %SVN% update %DIR% --username server --password serverpassword --non-interactive)
SET REPOS=%1
SET REV=%2
SET svn="D:/subversion/bin/svn.exe"
SET DIR="E:/htdocs/testserver.lab.rollenc.com"
%svn% update %DIR%
按理说,和linux的执行是一样的,但就是出错。
如commit一个test文件,则显示错误信息为:
Modified: E:\htdocs\testcopy\test.php
Sending content: E:\htdocs\testcopy\test.php
Error: Commit failed (details follow):
Error: MERGE request failed on '/lab.rollenc.com/trunk'
Error: MERGE of '/lab.rollenc.com/trunk': 200 OK (http://127.0.0.10)
而此时,test.php已经commit成功,在subversion数据库中已经存在有本次记录,但E:\htdocs\testcopy工作复本还是显示为没有commit。需要同步的E:/htdocs/testserver.lab.rollenc.com也没有update。
我个人压根不懂windows下的编程,以上代码是边google边学来的。所以还是希望有达人帮忙,好让我完成这篇blog,我也好给大家一个完整的交待。
最终参考了一些文档,还是没能解决win下的问题,我把测试和输出结果放下面:
@echo off
echo "" > E:/hookLog.txt
echo "1" >> E:/hookLog.txt
SET REPOS=%1
echo "2" >> E:/hookLog.txt
SET USER=%2
echo "3" >> E:/hookLog.txt
echo %REPOS%, %USER% >> E:/hookLog.txt
SET SVN="D:/subversion/bin/svn.exe"
echo "4" >> E:/hookLog.txt
SET DIR="E:/htdocs/testserver.lab.rollenc.com"
echo "5" >> E:/hookLog.txt
REM call %SVN% update %DIR% >> E:/hookLog.txt
REM SET PATH=D:/subversion/bin/
REM svn update "E:/htdocs/testserver.lab.rollenc.com" >> E:/hookLog.txt
(call %SVN% update "E:/htdocs/testserver.lab.rollenc.com") >> E:/hookLog.txt
echo "6" >> E:/hookLog.txt
REM是注释,REM掉了我使用的很多种测试,切换REM可以运行其它的一些测试,但是全部无效。
以下是上面代码的输出:
""
"1"
"2"
"3"
E:/svn2, 54
"4"
"5"
"6"
1-6全部正常输出,惟一的是 svn update这一句没有输出任何东西。
完全放弃!等待达人。。。。
------------以上内容已删除-----------------
有问题也欢迎在下面贴出,乐意帮忙:)



0 Trackbacks