svn钩子的功能:

svn钩子是一个脚本,它的具体写法和linux操作系统中shell脚本的写法并没有什么不同,通俗来说,svn钩子的功能就是当某种版本库事件(删除文件、上传文件、修改文件名称等等)被触发,以脚本定义的方式继续该事件的执行。

钩子的类型:

常用的钩子脚本

钩子脚本说明
post-commit提交完成时触发事务:在提交完成成功创建版本之后执行该钩子,提交已经完成,不可更改,本脚本的返回值被忽略,提交完成时触发事件
pre-commit提交完成前触发事务
start-commit提交前触发事务:在客户端还没有向服务器提交数据之前,即还没有建立subversion transaction(缩写为txn)之前,执行该脚本(提交前触发事务)

不常用的钩子脚本

钩子脚本说明
pre-revprop-change版本属性修改前触发事务:在修改revision属性之前,执行该脚本
post-revprop-change版本属性修改后触发事务:在修改revision属性之后,执行该脚本,因为修改稿已经完成,不可更改,因此本脚本的返回值被忽略(不过实际上的实现似乎是该脚本的正确执行与否影响属性修改)
pre-unlock对文件进行解锁操作之前执行脚本
post-unlock对文件进行解锁操作之后执行脚本
pre-lock对文件进行加锁操作之前执行脚本
post-lock对文件进行教唆操作之后执行脚本

【注意事项:】

在使用svn钩子的时候,必须要在钩子脚本中设置好环境变量和命令的绝对路径,因为svn是在一个没有任何环境变量的环境中运行的,甚至都没有$PATH这个变量。

下面通过两个小实验来演示svn钩子的功能

hooks一般放置在如下目录,有许多的模板

wKioL1k-Q6ihbjfjAABWgyekbV4656.png

第一个钩子:自动同步项目库文件到另外一台主机

从源码库下载一个项目库

[root@svn-server data]# svn co http://svn.test.com/svn/abc /data/web/svn_master/abc
  • 写一个钩子脚本  (观察日志里钩子执行用户,切到执行用户下运行此脚本)

#!/bin/bash

export LANG="en_US.UTF-8"
REPOS="$1"
REV="$2"
SVN="/usr/bin/svn"
USER="qsh"
PASSWD="qshtest"
SVN_URL="http://svn.test.com/svn/"
SVN_PATH="/data/web/svn_master/abc"
LOGPATH="/data/logs/svn"

[ ! -d ${LOGPATH} ]  && mkdir ${LOGPATH} -p
echo "$(date) User: $(whoami)" >>${LOGPATH}/svn_update.log

${SVN} update --username ${USER} --password ${PASSWD} ${SVN_PATH} >>${LOGPATH}/svn_update.log
if [ $? -eq 0 ];then
     sudo /usr/bin/chown -R www:www ${SVN_PATH}
     sudo /usr/bin/rsync  -avzP --delete -e 'ssh -p 1212' --exclude ".svn" ${SVN_PATH}/ root@10.10.10.162:/data/service/abc/  >>${LOGPATH}/svn_update.log
fi
  • 赋予执行权限

[root@svn-server hooks]# chmod +x post-commit
  • 重启svnserve

systemctl restart svnserve.service
  • 配置免密码认证

[root@svn-server hooks]# ssh-keygen 
[root@svn-server hooks]# ssh-copy-id root@192.168.83.132
  • 上传一个测试文件测试,在client上验证是否已经同步文件

wKioL1k-UV3z9B31AAAUwJsvxvI612.png

第二个钩子:限制文件大小以及文件的类型,上传需要输入备注

[root@svn-server hooks]# vim pre-commit
#!/bin/bash
REPOS="$1"
TXN="$2"
MAX_SIZE=10240000
FILTER='\.(zip|rar|o|obj|tar|gz)$'
SVNLOOK=/usr/bin/svnlook
#LOGMSG=`$SVNLOOK log -t "$TXN""$REPOS" |grep "[a-zA-Z0-9]" | wc -c`
LOGMSG=`$SVNLOOK log -t "$TXN""$REPOS" | wc -c`
 
if [ "$LOGMSG" -lt 9 ]
then
   echo -e"error:can not be empty,you must enter at least 8 characters"1>&2
   exit 1
fi
 
files=$($SVNLOOK changed -t $TXN $REPOS |awk '{print$2}')
 
for f in $files
do
#check file type
if echo $f|tr A-Z a-z|grep -Eq $FILTER
then
   echo"File $f is not allow ($FILTER) file" >&2
   exit 1
fi
#check file size
filesize=$($SVNLOOK cat -t $TXN $REPOS $f|wc -c)
if [ "$filesize" -gt "$MAX_SIZE" ]
then
   echo"file $f is too large(must 
   exit 1
fi
done
 
#all checks passed,so allow commit
exit 0
  • 赋予执行权限

[root@svn-server hooks]# chmod +x pre-commit
  • 测试

一开始没有输入备注

输入备注之后提示不允许的文件类型

更改文件类型并且输入备注,提示大小超出限制