介绍
SVN是subversion的缩写,是一个开放源代码的版本控制系统,特点是集中式管理,即一个远程主干分支,多个本地分支。同一时刻只能有一个用户commit,适用于中小型项目,方便快捷。
一、SVN服务端搭建
1.安装
#svn安装
yum -y install subversion
#检测是否安装成功
svnserve --version
--下面的命令,有需要再使用-----------------------------------------------
#检测svn安装路径(感兴趣可以查看下)
rpm -ql subversion
# 设置开机启动svn服务端
systemctl enable svnserve
# 关闭开机启动svn服务端
systemctl disable svnserve
2.创建svn根目录以及项目仓库
# 创建svn根目录
mkdir -p /data/svn
# 创建第一个项目仓库目录,即project1
mkdir -p /data/svn/project1
# 创建svn project1项目版本仓库
svnadmin create /data/svn/project1
进入/data/svn/project1查看:
?3.配置project1项目仓库管理信息,先进入conf目录
cd /data/svn/project1/conf
1)修改svnserve.conf文件。把以下注释打开即可
anon-access = none #匿名用户可读
auth-access = write #授权用户可写
password-db = passwd #使用哪个文件作为账号文件
authz-db = authz #使用哪个文件作为权限文件
2)修改passwd文件,增加用户,如:
?3)修改authz文件,管理用户权限,如:
[groups]??分组管理权限,灵活运用可方便管理用户 [repository:/baz/fuz]??其中repository可以省略,[repository:/]或[/]表示该项目仓库根目录,[/foo/bar]表示仓库下/foo/bar目录。可以配置多项目录管理权限,以便针对不同目录的权限管理。
PS:所有配置文件,每项配置最前面一定不要有空格,而且尽量在centos下编辑,若在windows下编码会不一样。
4.开启svn服务端版本库:
# 说明:-d 守护进程 ; -r 后接版本库根目录
svnserve -d -r /data/svn ?--listen-port=3690
# 检查svn是否开启成功
netstat -antlp | grep svnserve
PS:要注意,/data/svn是svn服务端版本库根目录,不涉及具体项目,因为svn就是通过感知这个根目录从而管理其下所有项目仓库。
5.开放端口
firewall-cmd --zone=public --add-port=3690/tcp --permanent
firewall-cmd --reload
PS:如果经常提示需要输入用户账号和密码,可以设置svn客户端保存登录过的用户信息:
cd ~/.subversion/
vim config
# 修改此字段为yes
store-passwords = yes
二、使用svn客户端上传代码
如果需要把现成的项目上传版本库,可以使用import命令。这里展示的是空目录创建文件并提交
1.拉取目录
# 创建一个目录用于拉取项目
mkdir -p /data/svnTest
cd /data/svnTest
# 拉取版本库中的内容
# 方法一:根目录就是project1
svn co svn://127.0.0.1/project1 --username zgq --password 123456 --non-interactive
或
# 方法二,根目录是project1_1,替代了版本库中的project1名称
svn co svn://127.0.0.1/project1 project1_1 --username zgq --password 123456 --non-interactive
先使用方法一,使用默认目录即可。
2.进入/data/svnTest/project1,创建一些内容并提交:
内容是:一个main.c文件,一个design目录,design目录中一个item.lua文件
提交到项目版本库(切回到project1目录下):
# 把文件和目录纳入版本控制
svn add *
# 前面checkout时设置了用户名和密码,这里一般不用。如果需要,加上一样的参数即可,或者等待提示再输入
# 提示认证域明文,键入yes即可。
# svn commit ./* -m "first commit" [--username zgq --password 123456 --non-interactive]
如果以下报错,请检查svnserve.conf等配置是否按要求修改了。检查修改后重启(通过ps aux | grep?svnserve 找到进程id,执行kill pid(或者直接 plill svnserve),再执行svnserve -d -r /data/svn --listen-port=3690)
至此,svn客户端拉取项目并提交新增内容介绍完毕。读者可自行拉取另一个目录进一步操作熟悉svn的命令。
3.小Tips
在随便一个checkout出来的项目下,都可以使用svn相关指令。svn客户端所有命令可以通过svn help查看,想了解具体的某个命令可以通过svn help cmd,如svn help add。习惯使用help查看各种命令的详细手册,有助于快速掌握svn命令行操作。
三、hook应用
项目版本库hooks目录(如前面的project1版本仓库:/data/svn/project1/hooks)下有以下文件,默认情况下它们是不被执行的:
pre-lock | 文件加锁前执行,不常用 | post-lock | 文件加锁后执行,通常用来发送锁定事件通知,需要传递两个参数给hooks脚本,按照顺序依次为:1.版本库路径,2.锁定路径的认证用户名 | per-unlock | 文件解锁前执行,不常用 | post-unlock | 文件解锁后执行,通常用来发送解锁事件通知,需要传递两个参数给hooks脚本,按照顺序依次为:1.版本库路径,2.解锁路径的认证用户名 | start-commit | 开始提交时执行,在pre-commit之前,通常用来确定用户是否有提交权限 | pre-commit | 提交之前执行,在start-commit之后,通常用来对提交内容的检查,例如我们后边要介绍的利用pre-commit做提交log的合规性检查,需要传递两个参数给hooks脚本,按照顺序依次为:1.版本库路径,2.提交事务的名称 | post-commit | 提交完成后执行,这应该是使用最广的hooks之一,通常用来在提交之后发送提交通知,甚至是利用它来做自动化的CI/CD等操作,需要传递两个参数给hooks脚本,按照顺序依次为:1.版本库路径,2.提交创建的修订版本号 | pre-revprop-change | 在修改revision属性之前执行,不常用 | post-revprop-change | 在修改revision属性之后执行,不常用 |
1.模拟一个项目下某目录更新后,自动同步到另一个项目下的某个目录
源svn项目仓库:/data/svn/project1
目标svn项目仓库:/data/svn/project2
实现原理:分别拉取一个project1和project2的本地分支,当project1有内容更新,通过hook触发update到project1本地分支,project1本地分支同步数据到project2本地分支(可通过cp或者rsync命令同步),最后由project2本地分支commit到project2仓库
1)再创建project2版本仓库:
mkdir -p /data/svn/project2
svnadmin create /data/svn/project2
参考前面设置好三个配置文件
楼主增加了一个 data 用户,并给于读写权限:
2)另外需要拉取三份项目仓库数据
project1_sync? 拉取project1仓库,用于同步数据到project2的本地分支project2_commit
project2? 拉取project2仓库,用于查看是否同步成功
project2_commit??拉取project2仓库,把project1_sync同步过来的内容commit到project2仓库
cd /data/svnTest
svn co svn://127.0.0.1/project1 project1_sync --username config --password 123456 --non-interactive
svn co svn://127.0.0.1/project2 --username data --password 123456 --non-interactive
svn co svn://127.0.0.1/project2 project2_commit --username data --password 123456 --non-interactive
3)先在project2本地分支创建data目录并commit,再更新project2_commit本地分支:
cd /data/svnTest/project2
mkdir data
svn add *
svn commit -m "mkdir data" --username data --password 123456 --non-interactive
cd /data/svnTest/project2_commit
svn up
PS:此步目的是准备好目标data目录
4)修改hook文件,即post-commit
# 修改hook文件(post-commit):
cd /data/svn/project1/hooks
mv post-commit.tmpl post-commit
chmod 755 post-commit
-------------------------------------------------------------------------
vim post-commit
# 注释掉 mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf
# 增加以下代码(命令一定要使用绝对路径):
cd /data/svnTest/project1_sync/design
/usr/bin/svn up --username config --password 123456 --non-interactive
/usr/bin/rsync -azP --exclude=".." --exclude="." --exclude=".svn" --delete ./ /data/svnTest/project2_commit/data
cd /data/svnTest/project2_commit/data
/usr/bin/svn add * --username data --password 123456 --non-interactive
/usr/bin/svn commit ./* -m "auto commit" --username data --password 123456 --non-interactive
5)测试验证
# 在project1/design 增加一个文件
cd /data/svnTest/project1/design
echo return {} > equip.lua
svn add *
# 提交
svn commit ./ -m "add equip.lua"
---------------------------------------------
# 到project2/data 更新查看是否有对应文件
cd /data/svnTest/project2/data
svn up
PS:如果在需要同步的目录下新增了目录,则需要修改脚本,下面以project1/design 举例:
cd /data/svnTest/project1/design
mkdir face
cd /data/svnTest/project1/design/face
echo return {} > face1.lua
# 请注意,hook脚本中源目录是到design
cd /data/svnTest/project1/design
svn add *
svn commit ./ -m "add face dir"
-------------------------------------------------
cd /data/svnTest/project2/data
# 可以看到,design 新的一级子目录是成功
svn up
-------------------------------------------------
# 但是第二次,在design/face 继续增加文件,则没办法提交了
cd /data/svnTest/project1/design/face
echo return {} > face2.lua
cd /data/svnTest/project1/design
# 此时没办法直接把face2.lua加入版本控制
svn add *
-------------------------------------------------
# 解决方法一(不建议,但是目录改变不大情况下可使用,毕竟简单),确认到错误后,在post-commit文件中,commit前增加下面脚本指令:
/usr/bin/svn add ./face/* --username data --password 123456 --non-interactive
#解决方法二,通过python等编写同步脚本,python可以获取目录并执行add,而且使用python还可以把日志也一起同步,使用shell相对没那么方便。python在运维工具领域,还是很好用很强的。
过程有点复杂,但此功能在项目中比较常用。
PS:
1.在新增目录方面需要注意,在shell脚本作为主要同步工具时,需要看下第一次是否需要在本地分支手动操作或者修改脚本。最好还是确定目录结构,不要随便增加目录结构。或者使用python脚本作为同步工具,它更加强大,比如上面同步配表的例子,使用python还可以很方便把log也一并同步到目标仓库。
2.可以看到shell脚本中并没有commit delete内容的指令(虽然rsync做了处理,但是这只是本地分支做了同步,并没有通过svn commit到project2版本库)。主要是使用shell实现较麻烦,所以还是建议使用python。
|