######################################## ######## SVN 服务器搭建 ######################################## 首先删除系统自带安装的软件包 rpm -qa|grep httpd rpm -qa|grep subversion rpm -qa|grep apr rpm -qa|grep apr-util 查出以上软件包以后删除 rpm -qa|grep httpd | xargs rpm -e --nodeps error: "subversion-1.4.2" specifies multiple packages 解决: rpm -qa|grep subversion |xargs rpm -e --nodeps --allmatches 或:rpm -e --allmatches subversion-1.4.2 注意下面安装的软件必须要一致,不然后面会有些小问题; ####### arp 安装 ####### tar jxf apr-1.4.6.tar.bz2 cd apr-1.4.6 ./configure --prefix=/opt/apr make make install ####### apr-util 安装 ####### tar jxf apr-util-1.3.12.tar.bz2 cd apr-util-1.3.12 ./configure --prefix=/opt/apr-util --with-apr=/opt/apr make make install 加入系统动态链接库配置 echo '/opt/apr/lib' >> /etc/ld.so.conf echo '/opt/apr-util/lib' >> /etc/ld.so.conf ldconfig ####### neon-安装 ####### (前提 libxml 2.x) 支持https 需要添加--with-ssl --with-libs=/usr/local/ssl ### tar zxf neon-0.29.6.tar.gz cd neon-0.29.6 ./configure --prefix=/opt/neon make make install ####### sqlite-amalgamation 安装 ####### tar zxf sqlite-autoconf-3071401.tar.gz cd sqlite-autoconf-3071401 ./configure --prefix=/opt/sqlite make make install ####zlib 安装##### yum install -y zlib-devel #####open ssl安装############ tar zxf openssl-1.1.0a.tar.gz cd openssl-1.1.0a ./config -fPIC make depend ; make install ####### apache 安装 ####### tar jxf httpd-2.2.23.tar.bz2 cd httpd-2.2.23 ./configure --prefix=/opt/apache --enable-dav --enable-rewrite --enable-so --enable-maintainer-mode --enable-mods-shared=all --with-apr=/opt/apr/bin/apr-1-config --with-apr-util=/opt/apr-util/bin/apu-1-config --enable-dav-fs --enable-dav-lock --enable-ssl --with-ssl=/usr/local/ssl --with-zlib ---有SSL时需要加--with-ssl make make install #报错 configure: error: ... Error, SSL/TLS libraries were missing or unusable 解决: 执行如下一句设置环境变量: export LDFLAGS=-ldl ######################## 加入到系统服务里面: cp /opt/apache/bin/apachectl /etc/rc.d/init.d/httpd 修改httpd 在文件头部加入如下内容,去除/bin/bash: ### # Comments to support chkconfig on Fedora Linux # chkconfig: 2345 90 90 # description:http server ### chkconfig --add httpd chkconfig --level 345 httpd on ####### subversion 安装 ####### #yum install expat expat-devel #### tar jxf subversion-1.6.19.tar.bz2 cd subversion-1.6.19 mkdir sqlite-amalgamation cp ../sqlite-autoconf-3071401/sqlite3.c ./sqlite-amalgamation ./configure --prefix=/opt/subversion --with-apxs=/opt/apache/bin/apxs --with-apr=/opt/apr --with-apr-util=/opt/apr-util --with-neon=/opt/neon --with-zlib=/usr/include --enable-maintainer-mode --without-berkeley-db ############# https需要加上--with-ssl ############## make make install 在configure的时候可能会报错:configure: WARNING: we have configured without BDB filesystem support 。You don't seem to have Berkeley DB version 4.0.14 解决: 也可以加 ./configure -–prefix=/usr/local/svn --without-berkeley-db 该参数以svnserve方式运行,不加apache编译参数。以fsfs格式存储版本库,不编译berkeley-db 安装 Berkeley DB tar zxf db-5.2.36.tar.gz cd build_unix/ ../dist/configure --prefix=/opt/Berkeley(可以不加路劲) ###### 安装PHP (可选) ####### 安装该软件包是为了方便通过apache+PHP页面来更改SVN内的用户和密码 ./configure --prefix=/opt/phpsvn --with-apxs2=/opt/apache/bin/apxs --with-mysql=/opt/mysql --with-mysqli=/opt/mysql/bin/mysql_config --with-xml --with-png --with-jpeg --with-zlib --with-freetype --with-gd --enable-mbstring=all --可以不用加上mysql相关的参数,因为SVN没有与mysql结合,加上无妨; 或者采用 禅道的编译: ./configure --prefix=/opt/phpsvn --with-apxs2=/opt/apache/bin/apxs --with-mysql=/opt/mysql --with-mysqli=/opt/mysql/bin/mysql_config --enable-mbstring=all --with-zlib 安装报错:php-5.2.11/main/output.c:440: undefined reference to `php_ob_gzhandler_check 解决该错误是在安装时:在最后加上 --with-zlib make && make install cp php.ini-recommended /opt/phpsvn/etc/php.ini ####### 创建SVN版本库 ####### 创建SVN系统账户和相关目录 groupadd svn -g 800 useradd -u 800 -g svn svnroot su - svnroot mkdir /home/svnroot/repository mkdir /home/svnroot/repository/conf svn存储版本数据也有2种方式: 1.bdb; 2.fsfs。 因为bdb方式在服务器中断时,有可能锁住数据,所以还是fsfs方式更安全一点,我也选择这种方式 /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/sourcecode /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/workspace 将目录 repository目录拥有者修改为 svnroot 用户: chown -R svnroot.svn /home/svnroot/repository ####### 导入新项目文件夹 ####### svn import -m "initial import" /root/01-web/ file:///home/svnroot/repository/sourcecode/ ####### 配置apache ####### 修改apache的用户和组,如下: User svnroot Group svn 找到: LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so LoadModule php5_module modules/libphp5.so 在下面添加: DAV svn SVNParentPath /home/svnroot/repository/ AuthzSVNAccessFile /home/svnroot/repository/conf/authz.conf AuthType Basic AuthName "Subversion.Zone" AuthUserFile /home/svnroot/repository/conf/authfile Require valid-user Alias /m/ "/home/svnroot/m/" ---这段配置是给web管理用户的页面使用的,详解在下方 Options Indexes FollowSymLinks AllowOverride All Order allow,deny Allow from all AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps --配置PHP,后面更改用户使用 DirectoryIndex index.html index.php 注: SVNParentPath /home/svnroot/repository/ (此处配置你的版本库根目录) --注意这里不要是svnpath AuthType Basic (连接类型设置 基本验证) AuthName "Hello welcome to here" (此处字符串内容修改为提示对话框标题) AuthUserFile /home/svnroot/repository/conf/authfile(此处修改为访问版本库用户的文件, 用apache 的htpasswd命令生成) AuthzSVNAccessFile /home/svnroot/repository/conf/authz.conf (此处修改为访问版本库权限的文件) Require valid-user ("Require valid-user"告诉apache在authfile中所有的用户都可以访问。 如果没有它,则只能第一个用户可以访问新建库) ####### 创建SVN账户 ####### /opt/apache/bin/htpasswd -c -m /home/svnroot/repository/conf/authfile admin 测试时建立的密码:1!qwert 注 第一次创建用户时,要带参数-c ,以后新增用户不必用-c ,否则将会清除以前用户,-m 表示以md5码加密  -c 创建一个加密文件   -n 不更新加密文件,只将apache htpasswd命令加密后的用户名密码显示在屏幕上   -m 默认apache htpassswd命令采用MD5算法对密码进行加密   -d apache htpassswd命令采用CRYPT算法对密码进行加密   -p apache htpassswd命令不对密码进行进行加密,即明文密码   -s apache htpassswd命令采用SHA算法对密码进行加密   -b 在apache htpassswd命令行中一并输入用户名和密码而不是根据提示输入密码   -D 删除指定的用户 eg: 如新增用户user /opt/apache/bin/htpasswd -m /home/svnroot/repository/conf/authfile user 修改user用户密码 /opt/apache/bin/htpasswd -m /home/svnroot/repository/conf/authfile luhzh 删除用户 /opt/apache/bin/htpasswd -D /home/svnroot/repository/conf/authfile luhzh --同时也可以去文件中直接删除 ####### SVN账户权限配置 ####### 修改home/svnroot/repository/conf/authz.conf配置文件 [groups] /*这个表示群组设置 Admin=usr1,user2 /*这个表示admin群组里的成员 user1,user2 Develop=u1, u2 /*这个表示Develop群组里的成员 u1,u2 WebProgrammer=user5,user6 [www:/] /*这表示,仓库www的根目录下的访问权限 user1 = rw /*www仓库user1用户具有读和写权限 user2 = r /* www仓库userl用户具只有读权限 @develop=rw /*这表示 群 develop的成员都具有读写权限 [/] /*这个表示在所有仓库的根目录下 * = r /*这个表示对所有的用户都具有读权限 注意:在编辑authz.conf文件时,所有行都必须要顶头写,不能有缩行出现,否则会报错:"Access denied: ''user1'' ",里面的内容可以根据自己的需要自行添加,不必与我上面所写的相同! [sourcecode:/01-Web] * = @Admin = rw @develop = r @WebProgrammer = rw [sourcecode:/03-Mobile/02-Android/03-107Plan/branches/dev] * = @MobileProgrammer = rw @Admin = rw 访问方式: http://ip/svn/sourcecode 用户名和密码 ##### 通过web页面管理用户 ##### vim /home/svnroot/m/svnpwd.php 内容已保存 vim /home/svnroot/m/.htaccess ---添加如下内容 AuthUserFile /home/svnroot/m/.htpasswd AuthGroupFile /dev/null AuthName EnterPassword AuthType Basic require valid-user /opt/apache/bin/htpasswd -c /home/svnroot/m/.htpasswd admin 输入密码:生成.htpasswd文件 这下访问 https://ip/m/svnpwd.php --就需要输入用户名和密码了 ########################################## ######### SVN 自动同步到测试环境 ######### ########################################## svn服务器上的数据通过svn复制更新到本地某个文件夹,利用svn checkout创建,并且利用svn update来更新。 其中更新是通过hook/post-commit自动完成同步 再通过rysnc+inotify来实现服务器之间数据实时同步。inotify检测指定文件夹变化,出现变化后调用rysnc从而实现自动同步 其中第一步利用钩子函数post-commit调用svn update来更新,由于更新的权限是svnroot(svn用户),所以默认导出更新的数据所有者是svnroot。如果直接同步到web服务器,由于web server权限不对,会出现无法通过web访问的情况。所以需要将数据的所有者改为web server拥有的用户(例:apache)。此时需要在post-commit脚本中执行su - apache命令后再执行svn update。但无法在su命令后手工输入密码。所以需要通过安装expect来执行。 ##### expect 的安装 ##### rpm -qa | grep tcl tcl-devel ---检查系统,看tcl是否已经安装。默认tcl安装,tcl-devel没有安装 yum install tcl -y yum install tcl-devel -y #.首先确定tcl开发包安装的位置 #rpm -ql tcl-devel-8.4.13-3.fc6.i386.rpm|more #tar zxf expect5.45.tar.gz #./configure --with-tcl=/usr/lib --with-tclinclude=/usr/include/tcl-private/generic #make #makeinstall yum install expect -y --建议使用yum 安装避免在运行脚本时,找不到库文件; useradd www -G svn passwd www mkdir -p /opt/hm12345/ mkdir -p /opt/www/ mkdir -p /opt/analysis.kaifu.com chown -R www.www /opt/hm12345/ chown -R www.www /opt/www/ chown -R www.www /opt/analysis.kaifu.com chmod -R 755 /home/svnroot --更改SVN家目录的权限,方便在www下支持svn update时有权限; ln -s /opt/subversion/bin/svn /usr/bin/svn svn list file:///home/svnroot/repository/sourcecode/ svn checkout file:///home/svnroot/repository/sourcecode/01-Web/16-hm12345/ /opt/hm12345/ --初始化,为后面的svn update做准备,svn命令已添加到$PATH中; svn checkout file:///home/svnroot/repository/sourcecode/01-Web/08-ISY/trunk /opt/www/ svn checkout file:///home/svnroot/repository/sourcecode/01-Web/14-Analysis/trunk/analysis.kaifu.com/ /opt/analysis.kaifu.com/ ###### 创建后台触发脚本 ###### post-commit触发后执行的脚本 vim /home/svnroot/sh/autosu.sh #!/usr/bin/expect -f spawn su - www expect ":" send "www\r" #expect "$" send "/home/www/sh/trigger.sh\r" expect "$" send "exit\r" interact chmod +x /home/svnroot/sh/autosu.sh autosu.sh主要用于调用expect切换用户为www,并执行脚本trigger.sh ###### 创建 www 执行脚本 ###### su - www mkdir /home/www/sh touch /home/www/sh/trigger.sh chmod +x /home/www/sh/trigger.sh vim /home/www/sh/trigger.sh #!/bin/sh #LANG="zh_CN.GB18030" /usr/bin/svn update /opt/www/ /usr/bin/svn update /opt/analysis.kaifu.com/ /usr/bin/svn update /opt/hm12345 #export LANG="en_US.UTF-8 优化语句:可以通过 svnlook 只更新有更新的数据 ### svn update ISY### for dir in `svnlook dirs-changed /home/svnroot/repository/sourcecode/|grep '01-Web' | awk -F '/' '{print $2}' |awk -F '-' '{print $2}' |uniq` do if [ $dir=ISY ]; then /usr/bin/svn update /opt/www fi done ###### 创建 SVN 勾子函数文件 ###### vim /home/svnroot/repository/sourcecode/hooks/post-commit #!/bin/sh REPOS="$1" REV="$2" /home/svnroot/sh/autosu.sh chmod 777 post-commit apachel restart --可以重启下apache 调用过程 调用 调用 post-commit --------------> autosu.sh -------------->trigger.sh (commit后自动触发) (利用expect解决用户切换) (执行更新) 注意赋予以上脚本执行权限 #################### #### rsync+ inotify促发自动更新 ##### #################### server:192.168.0.251 web服务器 client: 192.168.0.250 svn服务器,rsync客户端; rsync server端配置,已配置好 rsycn client简单配置 vim /etc/rsync-client.pass passwd --此处password与server端一致 chmod 600 /etc/rsyncd.secrets 测试: /usr/bin/rsync -zrtopg --progress --password-file=/etc/rsync-client.pass /opt/www/ svnuser@192.168.0.251::kaifu ########## 安装配置 inotify ########## wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz tar zxf inotify-tools-3.14.tar.gz cd inotify-tools-3.14 ./configure --prefix=/usr/local/inotify make && make install 如果遇到以下错误: inotifywait: error while loading shared libraries: libinotifytools.so.0: cannot open shared object file: No such file or directory 解决方法: 32位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib/libinotifytools.so.0 64位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0 innotify 触发rsync更新脚本 #!/bin/sh SRC=/opt/hm12345/ DST=192.168.0.251::hm12345 USER=svnuser /usr/local/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T%w%f' -e modify,delete,move,create,attrib $SRC | while read file do /usr/bin/rsync -zrtopg --progress --password-file=/etc/rsync-client.pass $SRC $USER@$DST done 后台运行: nohup /root/sh/svn_www_rsync.sh & 添加到rc.local中 echo "/root/sh/svn_www_rsync.sh &" >> /etc/rc.local 案例: 新添加一个同步项目,web服务器是192.168.0.251 svn服务器为:192.168.0.250 在测试服务器251上要做的: 1、创建好目录,如 /opt/www/hm12345 2、在/etc/rsyncd.conf里添加同步的目标目录的配置,如[hm12345] path = /opt/www/hm12345 secrets file=/etc/rsync.pass 复制代码在SVN服务器250上要做的: 1、创建同步源目录,如 /opt/hm12345 2、初始化,如/usr/bin/svn checkout http://192.168.0.250/svn/sourcecode/01-Web/16-hm12345/ /opt/hm12345/ svn checkout file:///home/svnroot/repository/code/02-sfbrush /opt/www/sfbrush 复制代码3、配置以下文件 /home/www/sh/trigger.sh 添加一行/usr/bin/svn update /opt/hm12345 复制代码4、添加以下文件 /root/sh/svn_hm12345_rsync.sh 内容(如果测试服务器251上有自己产生的数据不能被删除,请去掉同步命令行中的--delete): #!/bin/sh SRC=/opt/hm12345/ DST=192.168.0.251::hm12345 /usr/local/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T%w%f' -e modify,delete,move,create,attrib $SRC | while read file do /usr/bin/rsync -zrtopg --progress --password-file=/etc/rsync-client.pass --delete $SRC $DST done 复制代码5、后台执行 nohup /root/sh/svn_hm12345_rsync.sh & 6、把下面行假如到/etc/rc.local文件中/root/sh/svn_hm12345_rsync.sh & ########################################## ######### SVN sync备份详解 ######### ########################################## http://www.blogjava.net/jasmine214--love/archive/2010/09/28/333223.html --参考 1.在备份机上创建一个空库: /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/sourcecode /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/workspace 2.更改该库的钩子脚本pre-revprop-change(因为svnsync要改这个库的属性,也就是要将源库的属性备份到这个库,所以要启用这个脚本): cd /home/svnroot/repository/sourcecode/hooks cp pre-revprop-change.tmpl pre-revprop-change chmod 755 pre-revprop-change vim pre-revprop-change --直接改为下面语句的即可 #!/bin/sh exit 0; 3.初始化,此时还没有备份任何数据: 当版本库有内容时,是不能再进行初始化的,即使把内容删除了也不能初始化,只能重新 建 一个干净的库; svnsync init file:///home/svnroot/repository/sourcecode/ http://192.168.0.250/svn/sourcecode/ svnsync init file:///home/svnroot/repository/workspace/ http://192.168.0.250/svn/workspace/ 语法是:svnsync init {你刚创建的库url} {源库url} 4.开始同步 svnsync sync file:///home/svnroot/repository/sourcecode/ 这个时候可能属性被锁了,删掉属性: svn propdel svn:sync-lock --revprop -r0 file:///home/backup/svn/svnsync/SMP 删除成功后,再试一遍基本就可以了。 如果反复操作都是同样错误的话,有可能是你的svn安装的有问题,重新安装一遍就好了,俺就是这样。 可能报错二、 svnsync: REPORT request failed on 'http://svn1.subversion.com/repos/Relevance' svnsync: The requested report is unknown. 这是因为你源库的版本太低了,svnsync所需要的函数Report是svn1.4后加入的。没办法,对你的库进行升级后才能备份。 5.同步脚本 #/bin/sh /opt/subversion/bin/svnsync sync file:///home/svnroot/repository/sourcecode --source-username admin --source-password s4dagjR0 --no-auth-cache #/opt/subversion/bin/svnsync --non-interactive sync file:///home/svnroot/repository/sourcecode --source-username admin --source-password s4dagjR0 或者 #!/bin/bash while (:) do svnsync sync file:///svn_bak/svnbak/ if [ $? != 0 ] then svn propdel svn:sync-lock --revprop -r0 file:///svn_bak/svnbak/ fi sleep 60 done 查看SVN的库的UUID svn info file:///home/svnroot/repository/sourcecode/ svnlook uuid /home/svnroot/repository/sourcecode/ svnlook uuid /home/svnroot/repository/sourcecode/ svnadmin setuuid /home/svnroot/repository/sourcecode/ ddcc9b5c-3266-44c7-8b69-f4f9afd7bf35 设置一个新的UUID svn info --username admin --password s4dagjR0 http://192.168.0.250/svn/sourcecode/ svn switch --relocate http://192.168.0.250/svn/sourcecode/ http://192.168.0.242/svn/sourcecode/ 测试未通过,重新定位URL ###### SVN 强制备注 ####### vim /home/svnroot/repository/sourcecode/hooks/pre-commit.tmpl SVNLOOK=/opt/subversion/bin/svnlook LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA]Z0-9]" | wc -c` if [ "$LOGMSG" -lt 6 ]; then echo -e "\n请填写.次svn提交的备注信息,最少为6个字符!" 1>&2 exit 1 fi ################################################ ######### SVN hotcopy备份+rsync异地备份 ######## ################################################ 简单的脚本,还需要优化 #!/bin/sh export LANG=C export LC_ALL=C export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/subversion/bin/ runtime=`date +%Y%m%d%H%M` deltime=`date -d '2 days ago' +%Y%m%d` svndatadir=/home/svnroot/repository backdir=/data_bak/SVNServer mkdir $backdir/$runtime cp -RP $svndatadir/conf $backdir/$runtime /opt/subversion/bin/svnadmin hotcopy $svndatadir/workspace /$backdir/$runtime/workspace /opt/subversion/bin/svnadmin hotcopy $svndatadir/sourcecode /$backdir/$runtime/sourcecode cd $backdir rm -rf $deltime* vim /etc/crontab ### back SVN 30 0 * * * root /root/sh/SVN_back.sh >>/root/sh/SVN_back.log 2>&1 再配置rsnync 一定同步 该脚本在异地备份服务器上 #!/bin/bash export LANG=C export LC_ALL=C export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin pwdfile=/etc/rsync_client.secrets authuser=svnuser source_addr=192.168.0.250::svnback backdir=/data_bak/SVNServer/ deltime=`date -d "7 days ago" +%Y%m%d` /usr/bin/rsync -zrtopg --password-file=$pwdfile $authuser@$source_addr $backdir #/usr/bin/rsync -avz --password-file=$pwdfile $authuser@$source_addr $backdir cd $backdir rm -rf $deltime* ########################################## ######### SVN 常用命令 ######### ########################################## ###### 导入项目 ###### svn import -m "initial import" /root/01-web/ file:///home/svnroot/repository/sourcecode/ 真实服务器 ###### 导出项目:###### svn checkout file:///home/svnroot/repository/sourcecode/ /root/chechkout/ svn checkout URL[@REV]... [PATH] 别名:co 描述:检出 访问库:否 eg:svn checkout file:///var/svn/repos/test file:///var/svn/repos/quiz working-copies eg:svn checkout -r 2 file:///var/svn/repos/test mine ##check out 版本号为2的项目 svn export file:///home/svnroot/repository/sourcecode/ /root/exportsvn/ --force 注意:如果svn: 目的目录已存在;请删除目录或用 --force 来覆盖目录 ###### 查看内部已存在的项目: ###### svn list file:///home/svnroot/repository/sourcecode/ svn list --verbose file:///home/svnroot/repository/sourcecode ##--verbose参数表示显示详细信息。 ###### 对文件进行添加 改名和删除 ###### svn del -m "del file" file:///home/svnroot/repository/sourcecode/web1.txt svn mv -m "mv dir" file:///home/svnroot/repository/sourcecode/03-web2 file:///home/svnroot/repository/sourcecode/04-web2 svn mkdir -m "add diractory" file:///home/svnroot/repository/sourcecode/03-web3 ###### 如何去除SVN中保存的用户授权密码 ##### 在Subversion安装目录下找到auth/svn.simple目录,将下面的文件删除即可。 如果在乌龟中,可以setting->saved data->Authentication Data 点 clear 即可。 ####### SVN的备份、恢复 ####### 备份恢复: 方法1: 备份 svnadmin dump /home/svnroot/repository/sourcecode > /data_bak/sourcecode 恢复 svnadmin create /home/svnroot/repository/sourcecode svnadmin load /home/svnroot/repository/sourcecode < /data-bak/sourcecode 方法2(我们当前用的方法): 备份 svnadmin hotcopy /home/svnroot/repository/sourcecode /data_bak/sourcecode 恢复 svnadmin hotcopy /data_bak/sourcecode /home/svnroot/repository/sourcecode 用dump和hotcopy方式的区别参看http://liyaoyi.blog.51cto.com/442933/797158 ####### SVN的同步 ####### 在目标机器上创建版本库 svnadmin create --fs-type fsfs /home/svnroot/repository/sourcecode 修改目标机器上版本库的脚本 vi /home/svnroot/repository/sourcecode/hooks/pre-revprop-change.tmpl 删除里面的所有内容后保存,改名为pre-revprop-change(去掉.tmpl),并赋予执行权限 同步前的初始化 svnsync init file:///home/svnroot/repository/sourcecode http://192.168.0.250/svn/sourcecode ########################################## ######### SVN 命令总结 ######### ########################################## 以下是svn客户端常用命令一览: svn add [path] 别名:无 描述:添加文件或目录到你的wc,打上新增标记。这些文件会在下一次你提交wc的时候提交到svn服务器。 在提交前,你也可以用svn revert撤销新增的文件。 访问库:否 eg: svn add file.cpp svn blame Target[@REV] 别名:praise,annotate,ann 描述:显示某个已受控文件的每一行的最后修改版本和作者 访问库:是 eg: svn blame file.cpp eg: svn blame --xml file.cpp ##加上xml参数可以以xml格式显示每一行的属性。 svn cat TARGET[@REV] 别名:无 描述:输出指定目标的内容,这里的目标一般是文件。 访问库:是 eg:svn cat file.cpp eg:svn cat file.cpp -r 2 ##显示版本号为二的file.cpp内容。 eg:svn cat file.cpp --revision HEAD ##显示最新版本的file.cpp内容。 svn changelist CLNAME TARGET... svn changelist --remove TARGET 别名:cl 描述:可以将wc中的文件从逻辑上分组. 访问库:否 eg:svn cl clName file.cpp file2.cpp file3.cpp ##将file.cpp等三个文件加入名叫clName的changelist eg:svn commit --changelist clName -m "ci" ##将clName下的所有文件提交 svn checkout URL[@REV]... [PATH] 别名:co 描述:检出 访问库:否 eg:svn checkout file:///var/svn/repos/test file:///var/svn/repos/quiz working-copies eg:svn checkout -r 2 file:///var/svn/repos/test mine ##check out 版本号为2的项目 svn cleanup [PATH...] 别名:无 描述:递归的清理WC中过期的锁和未完成的操作。 访问库:否 eg:svn cleanup 问题解决 svn: Working copy '/opt/www/bbs' locked svn: run 'svn cleanup' to remove locks 解决 svn cleanup /opt/www/ svn commit [PATH...] 别名:ci 描述:把你WC的更改提交到仓库 访问库:是 eg:svn commit -m "added howto section." ##默认情况下提交必须提供log message svn copy SRC[@REV]... DST 别名:cp 描述:copy操作可以从WC到WC;WC到URL;URL到WC;URL到URL。现在SVN只支持同一个仓库内文件的拷贝,不允许跨仓库操作。 访问库:是 eg:svn copy -r 11 file:///var/svn/repos/test/trunk \ file:///var/svn/repos/test/tags/0.6.32-prerelease \ -m "Forgot to tag at rev 11" ##copy命令是创建分支和标记的常用方式。copy到url的操作隐含了提交动作,所以需要提供log messages。 svn delete PATH... 别名:del,remove,rm 描述:删除 访问库:如果PATH是库地址时会,删除WC内的文件不会。 eg:svn del localfile.cpp ##删除WC里的文件,在下一次提交WC的时候才会真正在仓库里将对应文件删除。 eg: svn del file:///var/svn/repos/test/yourfile ##删除仓库里的文件 svn diff 别名:di 描述:用来比较并显示修改点。 访问库: eg:svn diff ##最常用的方式,用来显示WC基于最近一次更新以后的所有的本地修改点。 eg:svn diff -r 301 bin ## 比较WC和版本301中的bin目录的修改点 eg:svn diff -r 3000:3500 file:///var/svn/repos/myProject/trunk ##比较库里主干3000版和3500版的差异。 eg:svn diff --summarize --xml http://svn.red-bean.com/repos/test@r2 http://svn.red-bean.com/repos/test ##--summarize --xml 参数将差异情况以xml文档的方式显示出来。 svn export [-r REV] URL[@PEGREV] [PATH] svn export [-r REV] PATH1[@PEGREV] [PATH2] 别名:无 描述:导出一个干净的目录树,不包含所有的受控信息。可以选择从URL或WC中导出。 访问库:如果访问的是URL则会。 eg:svn export file:///var/svn/repos my-export ##导出到my-export目录。 svn help — Help! 别名:?,h 描述:不用解释了 访问库:否。 svn import [PATH] URL 别名:无 描述:导入本地一个目录到库中。但是导入后,本地的目录并不会处于受控状态。 访问库:是。 eg:svn import -m "New import" myproj http://svn.myProject.com/repos/trunk/misc svn info [TARGET[@REV]...] 别名:无 描述:显示指定WC和URL信息。 访问库:仅当访问的是库路径时。 eg:svn info --xml http://svn.myProject.com/repos/test ##将信息以xml格式显示。 svn list [TARGET[@REV]...] 别名:ls 描述:显示目标下的文件和目录列表。 访问库:如果访问的是库地址就会。 eg:svn list --verbose file:///var/svn/repos ##--verbose参数表示显示详细信息。 svn lock TARGET... 别名:无 描述:对目标获得修改锁。如果目标已被其他用户锁定,则会抛出警告信息。用--force参数强制从其他用户那里获得锁。 访问库:是 eg:svn lock --force tree.jpg svn log [PATH] svn log URL[@REV] [PATH...] 别名:无 描述:从库中显示log消息。log消息代码 A :added D:deleted M:modified R:replaced 访问库:是 eg:svn log -v http://svn.myProject.com/repos/test/ foo.c bar.c ##详细显示指定URL的库中foo.c和bar.c所有版本的log信息。 eg:svn log -r 14:15 ##显示当前WC的14和15版本log信息。 eg:##如果版本号不连续,只能采用如下方式。 $ svn log -r 14 > mylog $ svn log -r 19 >> mylog $ svn log -r 27 >> mylog svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH] svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH] svn merge [[-c M]... | [-r N:M]...] [SOURCE[@REV] [WCPATH]] 别名:无 描述:合并两个受控源的不同之处,存放到一个WC里。 访问库:只有当访问库地址时。 eg:svn merge --reintegrate http://svn.example.com/repos/calc/branches/my-calc-branch ##合并分支上的改变项到WC,往往用于分支合并到主干。 eg:svn merge -r 156:157 http://svn.example.com/repos/calc/branches/my-calc-branch ##将制定URL版本156到157的所有更新合并到WC。 svn mkdir PATH... svn mkdir URL... 别名:无 描述:在WC或库路径创建目录 访问库:只有当访问库地址时。 eg:svn mkdir newdir svn move SRC... DST 别名:mv, rename, ren 描述:等同于svn copy命令跟个svn delete命令。WC到URL的重命名是不被允许的。 访问库:只有当访问库地址时。 eg:svn move foo.c bar.c ##将foo.c改名成bar.c。 svn propdel PROPNAME [PATH...] svn propdel PROPNAME --revprop -r REV [TARGET] 别名:pdel, pd 描述:从受控文件,目录等删除属性。第二种是删除某个指定版本上的附加属性。 访问库:只有当访问库地址时。 eg:svn propdel svn:mime-type someFile ##从someFile上移除svn:mime-type这个属性。 svn propedit PROPNAME TARGET... svn propedit PROPNAME --revprop -r REV [TARGET] 别名:pedit, pe 描述:编辑属性 访问库:只有当访问库地址时。 eg:svn propedit svn:keywords file.c ##修改file.c上的svn:keywords属性。 svn propget PROPNAME [TARGET[@REV]...] svn propget PROPNAME --revprop -r REV [URL] 别名:pget,pg 描述:从文件,目录或版本取得指定属性的值。 访问库:只有当访问库地址时。 eg:svn propget svn:keywords file.c ##从file.c中取得svn:keywords属性的值 svn proplist [TARGET[@REV]...] svn proplist --revprop -r REV [TARGET] 别名:plist, pl 描述:列出文件、目录或版本上的所有附加属性 访问库:只有当访问库地址时。 eg:svn proplist --verbose file.c svn propset PROPNAME [PROPVAL | -F VALFILE] PATH... svn propset PROPNAME --revprop -r REV [PROPVAL | -F VALFILE] [TARGET] 别名:pset,ps 描述:给文件、目录或版本附加属性并赋值 访问库:只有当访问库地址时。 eg:svn propset svn:mime-type image/jpeg file.jpg ##给file.jpg附加属性svn:mime-type 其值为image/jpeg eg:svn propset --revprop -r 25 svn:log "Journaled about trip to New York." ##给版本25补上log message eg:svn propset svn:ignore '.classpath' . ##在本地忽略掉.classpath文件 svn resolve PATH... 别名:无 描述:将冲突的文件标记为已解决,并且删掉冲突产生的临时文件。注意这个命令并不是能把冲突解决,解决冲突还是得靠人工。 访问库:否 eg:svn resolve --accept mine-full foo.c ##1.5版本后,加上--accept参数,尝试自动处理冲突。 svn resolved PATH... 别名:无 描述:已过时,被resolve --accept取代。去除冲突的状态和冲突临时文件。 访问库:否 svn revert PATH... 别名:无 描述:还原WC中所有的本地更改。 访问库:否 eg:svn revert --depth=infinity . ##将整个目录所有文件还原 svn status [PATH...] 别名:stat, st 描述:输出WC中文件和目录的状态。如果WC提交,这些状态就会同步到库里。 一般状态有 ' ' 没有修改 'A' 新增 'D' 删除 M' 修改 'R' 替代 'C' 冲突 'I' 忽略 '?' 未受控 '!' 丢失,一般是将受控文件直接删除导致 访问库:加上--show-updates参数时会 eg:svn status wc svn switch URL[@PEGREV] [PATH] svn switch --relocate FROM TO [PATH...] 别名:sw 描述:将WC转向一个其他的库地址同步 访问库:是 eg:svn sw http://svn.myProject.com/repos/trunk/vendors . ##将当前WC切换到另一个URL svn unlock TARGET... 别名:无 描述:解锁 访问库:是 eg:svn unlock somefile svn update [PATH...] 别名:up 描述:更新WC,更新反馈有如下几种分类。 A 新增 B 锁破坏 D 删除 U 更新 C 冲突 G 合并 E 存在的 访问库:是 eg:svn up -r22 ##更新到一个指定版本 ps:如何去除SVN中保存的用户授权密码 在Subversion安装目录下找到auth/svn.simple目录,将下面的文件删除即可。 如果在乌龟中,可以setting->saved data->Authentication Data 点 clear 即可。 ######################################## ##### SVN Master-Slave主从架构 ##### ######################################## http://heylinux.com/archives/1708.html --参考 通过Apache Write-through proxy实现SVN Master-Slave主从架构 参考资料: http://svnbook.red-bean.com/en/1.5/svn.serverconfig.httpd.html#svn.serverconfig.httpd.extra.writethruproxy 背景/环境: 目前有一台SVN服务器供全公司使用,但由于分公司数量的增加,且处于不同的地理区域的网络中,造成了以下问题: 1.部分分公司的网络状况不佳,每次更新和提交代码的时候都非常慢; 2.SVN服务器的压力越来越大; 同时,很多分公司的领导都提出,希望能在本地建立一台总部SVN服务器的镜像,提升访问速度; 方案/设计: 通过Apache的Write-through proxy使SVN服务器实现与MySQL Master-Slave类似的一主多从的架构。 如下图所示: 安装与配置: 1.安装配置Apache与Subversion - Master&Slave 注:以下操作需要在Master与Slave上进行 首先,需要安装和集成Apache与Subversion,具体的步骤可以参考我的这篇文章: http://heylinux.com/archives/917.html 其中 第1段 和 第3段 分别讲述了Apache与Subversion的安装与配置方法。 2.检查Apache是否加载proxy与proxy_http模块 - Master&Slave 注:以下操作需要在Master与Slave上进行 # grep proxy /opt/apache2/conf/httpd.conf 如果出现以下内容,则表明加载成功: LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so 如果没有出现,则需要通过以下方式添加: 进入Apache源码包的modules目录 # cd httpd-2.2.18/modules # /opt/apache2/bin/apxs -c -i -a proxy/mod_proxy.c proxy/proxy_util.c # /opt/apache2/bin/apxs -c -i -a proxy/mod_proxy_http.c 然后重启Apache使模块生效 # /opt/apache2/bin/apachectl restart 3.配置读写分离 - Slave 注:以下操作仅需要在Slave上进行 进入仓库的主目录 # cd /data/svn_repo 删除在第1步中创建的仓库 # rm -rf project1 创建新的空白仓库 # /opt/subversion/bin/svnadmin create project1 更改仓库目录的属主 # chown -R apache:apache project1/ 创建pre-revprop-change钩子文件 # cd project1/hooks/ # cp -p pre-revprop-change.tmpl pre-revprop-change # chmod +x pre-revprop-change # vim pre-revprop-change 删除以下部分内容: 1 if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi 2 3 echo "Changing revision properties other than svn:log is prohibited" >&2 4 exit 1 更改Apache配置文件 # vim /opt/apache2/conf/extra/httpd-svn.conf 01 02 DAV svn 03 SVNListParentPath On 04 SVNParentPath /data/svn_repo 05 SVNMasterURI http://master.heylinux.com/svn ##将master.heylinux.com替换为Master服务器的IP地址或域名 06 AuthType Basic 07 AuthName "Subversion Repository" 08 AuthUserFile /opt/subversion/conf/svn_passwdfile 09 AuthzSVNAccessFile /opt/subversion/conf/svn_accessfile 10 Require valid-user 11 12 13 14 DAV svn 15 SVNListParentPath On 16 SVNParentPath /data/svn_repo 17 Order deny,allow 18 Deny from all 19 Allow from 192.168.203.133 ##将192.168.203.133替换为Master服务器的IP地址 20 配置详解: 首先,在>Location /svn>中加入 SVNMasterURI http://master.heylinux.com/svn 指定主SVN服务器的URL; 然后,创建一个新的>Location /svn-proxy-sync>,取消认证功能,并加入地址验证,仅允许来自Master的请求;这样,Master就可以通过 http://slave.heylinux.com/svn-proxy-sync/project1将代码同步到Slave中去,避免了直接提交到http://slave.heylinux.com/svn/project1后会产生死循环的问题; 虽然,我们平时使用的是Slave - http://slave.heylinux.com/svn/project1,但在commit的时候,代码会通过代理自动提交到Master - http://master.heylinux.com/svn/project1,然后再由Master同步到Slave中; 也就是说,我们在commit的时候,速度依然会受到与总公司Master服务器之间网络的影响,但是本着80%与20%的读写比例原理,大多数时间下,我们都是以update为主,而在执行Update动作的时候,我们的请求只会在Slave上,因此速度会很快。 4.配置镜像同步 - Master 注:以下操作仅需要在Master上进行 进入仓库的主目录 # cd /data/svn_repo 创建pre-revprop-change钩子文件 # cd project1/hooks/ # cp -p pre-revprop-change.tmpl pre-revprop-change # chmod +x pre-revprop-change # vim pre-revprop-change 删除以下部分内容: 1 if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi 2 3 echo "Changing revision properties other than svn:log is prohibited" >&2 4 exit 1 初始化镜像 # /opt/subversion/bin/svnsync init http://slave.heylinux.com/svn-proxy-sync/project1 file:///data/svn_repo/project1 执行后显示以下信息则表明成功: Copied properties for revision 0. 注意:如果是绝对路径,file://后面还要加一个斜杠/,因此总共是三个斜杠,否则会出现以下错误: svnsync: Unable to open an ra_local session to URL svnsync: Local URL 'file://data/svn_repo/project1' contains unsupported hostname 进行初次同步 # /opt/subversion/bin/svnsync sync http://slave.heylinux.com/svn-proxy-sync/project1 执行后显示以下信息则表明成功: Transmitting file data ......... Committed revision 1. 创建 post-commit 钩子文件 # cd /data/svn_repo/project1/hooks # vim post-commit 1 #!/bin/sh 2 # Post-commit script to replicate newly committed revision to slaves 3 /opt/subversion/bin/svnsync sync http://slave.heylinux.com/svn-proxy-sync/project1 > /dev/null 2>&1 更新 pre-revprop-change 钩子文件 # vim pre-revprop-change 1 #!/bin/sh 2 # Post-revprop-change script to replicate revprop-changes to slaves 3 4 REV=${2} 5 /opt/subversion/bin/svnsync copy-revprops http://slave.heylinux.com/svn-proxy-sync/project1 ${REV} > /dev/null 2>&1 更改钩子文件的属主与权限 # chmod +x post-commit pre-revprop-change # chown apache:apache post-commit pre-revprop-change 5.测试 配置完成,接下来便可以通过以下步骤检查是否搭建成功。 a. 从Slave上checkout - 从Master上checkout - 向Slave上commit - 到Master上update b. 向Master上commit - 从Slave上udpate 如果向Slave提交的代码可以从Master上update下来,则表明Write-through proxy代理配置成功; 如果向Master提交的代码可以从Slave上update下来,则表明镜像同步配置成功; 6.其它 该文章中仅配置了一个Slave,如果在实际情况中需要配置多个Slave的话,只需要重复以上步骤并将Slave全部添加到Master的post-commit和pre-revprop-change钩子文件中即可。 ####################################### ###### 5楼 APP禅道和SVN 迁移 数据同步步骤 ####################################### http://192.168.0.242/svn/svntest/ http://192.168.0.227/svn/svntest/ #### SVN数据同步 步骤 #### 方法一:(采用该种方式) 1.在备份机上创建一个空库: /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/sourcecode /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/workspace 2.更改该库的钩子脚本pre-revprop-change cd /home/svnroot/repository/sourcecode/hooks cp pre-revprop-change.tmpl pre-revprop-change chmod 755 pre-revprop-change vim pre-revprop-change --直接改为下面语句的即可 #!/bin/sh exit 0; chown -R svnroot.svn /home/svnroot/repository/sourcecode/ chown -R svnroot.svn /home/svnroot/repository/workspace/ 3.初始化,此时还没有备份任何数据: svnsync init file:///home/svnroot/repository/sourcecode/ http://192.168.0.250/svn/sourcecode/ svnsync init file:///home/svnroot/repository/workspace/ http://192.168.0.250/svn/workspace/ 语法是:svnsync init {你刚创建的库url} {源库url} 4.开始同步 /opt/subversion/bin/svnsync sync file:///home/svnroot/repository/sourcecode --source-username admin --source-password s4dagjR0 --no-auth-cache /opt/subversion/bin/svnsync sync file:///home/svnroot/repository/workspace --source-username admin --source-password s4dagjR0 --no-auth-cache svnsync sync file:///home/svnroot/repository/sourcecode/ 方法二: 具体实现方法是在新的 5楼 SVN(临时IP:192.168.0.228)机器里面自动 读取 0.250的新备份,然后再恢复到 新的SVN 在 192.168.0.250 上修改rsync的配置文件 vim /etc/rsyncd.conf [svnnew] comment = backup the svn to diff disk path = /data_bak/SVNServer/testdir --testdir必须要改变成当天的备份目录; auth users = svnuser 在新的svn(IP:192.168.0.228)操作 vim /etc/rsync_client.secrets 添加 svnuser chmod 600 /etc/rsync_client.secrets /usr/bin/rsync -zrtopg --password-file=/etc/rsync_client.secrets svnuser@192.168.0.250::svnnew /data_bak/SVNServer/ 恢复 rm -rf /home/svnroot/repository/sourcecode /opt/subversion/bin/svnadmin create --fs-type fsfs /home/svnroot/repository/sourcecode svnadmin hotcopy /data_bak/sourcecode /home/svnroot/repository/sourcecode svn import -m "test svn" /root/svntest/ file:///home/svnroot/repository/sourcecode/ svn list file:///home/svnroot/repository/sourcecode/ --查看 svn del -m "del file" file:///home/svnroot/repository/sourcecode/web1.txt --删除 #### 禅道和邮件同步 步骤 #### a.禅道同步 192.168.0.252(研发禅道服务器) 同步到192.168.0.224 (5楼,新禅道) 0.252 sync已经配置好 [zentao] comment = zentao path = /usr/local/nginx/html/zentaopms/ auth users = rsyncback read only = no #write only = no list = false 0.224 新服务器里面配置 vim /etc/rsync_client.conf rsyncback /usr/bin/rsync -zrtopg --password-file=/etc/rsync_client.secrets rsyncback@192.168.0.252::zentao /usr/local/nginx/html/zentaopms/ chown -R www.www /usr/local/nginx/html/zentaopms/ 恢复数据库 /usr/local/mysql/bin/mysqldump -h127.0.0.1 -uroot -p --default-character-set=utf8 --master-data=2 --quote-names -R --opt zentao | gzip >/root/databack/zentao.sql.gz mysql -uroot -p --default-character-set=utf8 zentao < zentao.sql scp -P 22 root@192.168.0.252:/root/databack/20130712_0120_zentao.sql.gz /root/mvdata/ http://192.168.0.224/zentaopms/www/ b.邮件同步 步骤 0.252 sync已经配置好 [mailbox] comment = postfix_mailbox path = /var/mailbox/ auth users = rsyncback [mailhttp] comment = postfix_mailbox path = /usr/local/apache/htdocs/extsuite/ auth users = rsyncback /usr/bin/rsync -zrvtopg --password-file=/etc/rsync_client.secrets rsyncback@192.168.0.252::mailbox /var/mailbox/ /usr/bin/rsync -zrvtopg --password-file=/etc/rsync_client.secrets rsyncback@192.168.0.252::mailhttp /usr/local/apache/htdocs/extsuite/ chown -R vuser.vgroup /var/mailbox/ chown -R vuser.vgroup /usr/local/apache/htdocs/extsuite 恢复数据库 /usr/local/mysql/bin/mysqldump -h127.0.0.1 -uroot -p --default-character-set=utf8 --quote-names --master-data=2 -R --opt extmail >/root/extmail.sql mysql -uroot -p --default-character-set=utf8 extmail< extmail.sql scp -P 22 root@192.168.0.252:/root/extmail.sql . gzip -d extmail.sql.gz mysql -uroot -p --default-character-set=utf8 extmail< extmail.sql http://192.168.0.224:8888/extman/cgi/index.cgi ############################################################ ###### svn hotcopy与svnsync实现SVN镜像的快速搭建 ###### ############################################################ 背景/需求: 在我的上一篇文章中,我详细介绍了如何实现SVN主从架构的方法; 但在实际的应用环境中,却面临着另一个难题,现有的主SVN服务器上的数据量太大,超过10G以上,而svnsync却需要先初始化一个空库,然后再从0开始一直同步到相同的版本; 而主从服务器之间存在的网络状况并不理想,因此需要耗费非常多的时间且很可能出现同步中断等不稳定的情况。 方案/设计: 转换一种思路,试想MySQL的复制过程与svnsync非常相似,但是MySQL就可以通过初次导入完整库的数据,然后再指定其Position的值来实现增量同步,从而完成整个主从的搭建; 那么,我们也可以试着用这样的方式来操作svnsync,通过hotcopy将整个SVN主库完整备份下来,再压缩打包后传送到从服务器上,解开之后,修改相关的配置文件使svnsync认为从服务器上的库已经是经过了初始化并同步过的,从而实现增量同步,快速完成整个主从的搭建。 配置过程: 1. 通过hotcopy将SVN主库进行一次完整备份 - Master 注:以下操作需要在Master上进行 # cd /data/svn_repo/ # /opt/subversion/bin/svnadmin hotcopy project1 /opt/backups/project1 # cd /opt/backups/ # tar cjvf project1-master.tar.bz2 project1/ 2. 将备份文件传送到从服务器上 - Master 3. 在从服务器上创建一个空库 - Slave 注:以下操作需要在Slave上进行 # cd /data/svn_repo/ # /opt/subversion/bin/svnadmin create project1 # chown -R apache:apache project1/ # cd project1/hooks/ # cp -p pre-revprop-change.tmpl pre-revprop-change # chmod +x pre-revprop-change # vim pre-revprop-change 删除以下部分内容: 1 if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi 2 3 echo "Changing revision properties other than svn:log is prohibited" >&2 4 exit 1 4. 在主服务器上通过svnsync初始化仓库 - Master 注:以下操作需要在Master上进行 # /opt/subversion/bin/svnsync init http://slave.heylinux.com/svn-proxy-sync/project1 file:///data/svn_repo/project1 5. 在从服务器上备份初始化过后的空库 - Slave 注:以下操作需要在Slave上进行 # cd /data/svn_repo/ # mv project1 /opt/backups/ 6. 解压从主服务器过来的完整备份文件,并进行“调包”的过程 - Slave 注:以下操作需要在Slave上进行 # cd /data/svn_repo # tar xjvf /opt/backups/project1-master.tar.bz2 替换钩子文件 # cd project1/hooks # cp -p /opt/backups/project1/hooks/pre-revprop-change . 替换uuid # cd ../db/ # cp -p /opt/backups/project1/db/uuid . 替换初始版本日志 # cd revprops/0/ # cp -p /opt/backups/project1/db/revprops/0/0 . 更改仓库目录属主 # chown -R apache:apache /data/svn_repo/project1/ 6.复制sync-last-merged-rev(最后一次同步)版本号 - Master 注:以下操作需要在Master上进行 获取当前版本号,例如:40482 # cat /data/svn_repo/project1/db/current 将当前版本号复制到从服务器 # /opt/subversion/bin/svn propset --revprop -r0 svn:sync-last-merged-rev 40482 http://slave.heylinux.com/svn-proxy-sync/project1 执行一次同步 # /opt/subversion/bin/svnsync sync http://slave.heylinux.com/svn-proxy-sync/project1 7. 镜像搭建完成 8. 经验总结 通过上面的“调包”操作,svnsync成功的被我们“欺骗”了,可以直接在完整库的基础上利用svnsync进行增量同步了; 这样就不必傻乎乎的非得等svnsync从0开始同步到目前的版本,这种思路也可以用于今后SVN服务器Crash的情况以及修复主从同步。 贴一些报错信息方便搜索引擎定位: svnsync: Destination HEAD (40482) is not the last merged revision (0); have you committed to the destination without using svnsync? svnsync: Destination repository has not been initialized. svnsync: Error setting property 'sync-lock':could not remove a property. svnsync: DAV request failed;