假设SVN已经搭建成功,版本库根目录为/opt/svn/repos

找到版本库下面./hook/目录,一共9个文件,简单介绍一下


文件 说明
1 pre-commit.tmpl 提交之前被执行
2 pre-lock.tmpl 版本库锁定之前被执行
3 pre-revprop-change.tmpl 版本库增删改之前被执行
4 pre-unlock.tmpl 版本库解除锁定之前被执行
5 post-commit.tmpl 提交之后被执行
6 post-lock.tmpl 版本库锁定之后被执行
7 post-revprop-change.tmpl 版本库增删改之后被执行
8 post-unlock.tmpl 版本库解除锁定之后被执行
9 start-commit.tmpl 提交之前被执行

其中start-commit和pre-commit的区别在于:

start-commit在提交事务发生之前执行,通常用于判断用户是否拥有提交权限.

pre-commit在提交事务执行完之前执行,通常用于保护版本库的内容或者文件位置.


本文只涉及提交注释的控制,只针对pre-commit进行说明,其他的脚本将不在本文进行说明

原pre-commit.tmpl文件中起作用的部分

REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
$SVNLOOK log -t "$TXN" "$REPOS" | \
   grep "[a-zA-Z0-9]" > /dev/null || exit 1

该脚本接受2个参数

REPOS="$1" /opt/svn/repos  表示svn仓库的绝对路径值

TXN="$2"    表示最新的一个版本的事务ID,不是版本号


注:如果想按照版本号进行查看执行一下命令

svnlook log -r $ID /opt/svn/repos/

svnlook在这里的作用是打印本次提交的注释(svnlook log)并且查找其中的字母和数字(grep "[a-zA-Z0-9]"),但是不进行输出(> /dev/null),如果执行失败进行异常退出(exit 1)


接下来,我们对这个钩子进行改造,改造部分的脚本如下:

SVNLOOK=/usr/bin/svnlook
# anothor way
# LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | wc -c`
LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS" | wc -c)
if [ "$LOGMSG" -lt 10 ]; then
echo -e "######################################\nWARNING: Commit must be written comments, commit fail.\n######################################" 1>&2
exit 1
fi

其中LOGMSG为注释的长度

如果需要进行格式验证,这里可以进行一些改动

LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS" | egrep '^(BUG|TASK)-([0-9]+)-(.{5,})' | wc -c)
if [ "$LOGMSG" -eq 0 ]; then
  echo -e "请按照格式 BUG(或TASK)-任务号-注释(不少于5个字)进行提交" 1>&2
  exit 1
fi

wc命令: -c 统计字节数 -l 统计行数 -w 统计字数(一个单词算一个字)

判断: -eq 等于 -gt 大于 -lt 小于

echo 错误提示重定向到stderr (0:stdin 1:stdout 2:stderr)


注释掉下面的

# commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1

如果需要执行这个脚本,需要将对应的commit-access-control.pl文件复制到当前目录(hooks)


这里保存钩子需要将文件的后缀名去掉

并赋予执行权限 chmod 755 pre-commit


如果错误提示写的是中文,如:“本次提交失败”

客户端提交有可能提示

[Error output could not be translated from the native locale to UTF-8.]

需要将系统的语言设置成en_US.UTF-8

export LANG=en_US.UTF-8

如果修改全局变量,别忘了还有/etc/sysconfig/i18n这个文件。