【1.业务需求】
为部门的SVN服务器添加一项commit控制:即用户在提交改变时必须写注释,且不得低于10个字符。
【2.基本思路】SVN本身并不提供这种强制写log的功能,而是通过一系列的钩子程序(我们称为hook脚本),在提交之前(pre-commit),提交过程中(start-commit),提交之后(post-commit),调用预定的钩子程序来完成一些附加的功能。
本次我们要实现的是在提交到版本库之前检查用户是否已经写了注释,当然要使用pre-commit这个钩子程序。我们打开SVN的repository下的hook目录,可以发现有好几个文件,其中一个是“pre-commit.tmpl”。这个文件是一个模板文件,它告诉了我们如何实现提交前控制。打开该模板文件,我们看到如下一段说明:
# The pre-commit hook is invoked before a Subversion txn is
# committed. Subversion runs this hook by invoking a program
# (script, executable, binary, etc.) named 'pre-commit' (for which
# this file is a template), with the following ordered arguments:
#
# [1] REPOS-PATH (the path to this repository)
# [2] TXN-NAME (the name of the txn about to be committed)
#
# The default working directory for the invocation is undefined, so
# the program should set one explicitly if it cares.
#
# If the hook program exits with success, the txn is committed; but
# if it exits with failure (non-zero), the txn is aborted, no commit
# takes place, and STDERR is returned to the client. The hook
# program can use the 'svnlook' utility to help it examine the txn.
我们看到在一个提交事务执行之前,该hook脚本会被调用。然后向该脚本传递两个参数:REPOS-PATH和TXN-NAME,一个是用户要提交的URL,一个是本次事务的一个事务号。如果提交成功则返回0,否则返回其它非0结果。那么我们的钩子程序是要在事务提交之前,拦截这些请求,然后通过svnlook命令来检查是否已经写了log。
【3.示例代码】下面这段代码是网上直接拷贝的一段代码:
@echo off
setlocal
set REPOS=%1
set TXN=%2
rem check that logmessage contains at least 10 characters
svnlook log "%REPOS%" -t "%TXN%" | findstr "." > nul
if %errorlevel% gtr 0 goto err
exit 0
:err
echo Empty log message not allowed. Commit aborted! 1>&2
exit 1
下面解析一下绿色高亮处代码的作用:
①set REPOS=%1
set TXN=%2
还记得我们前面提到的但事务提交时,会传递两个参数吗?这里是分别用来接收URL和事务号的
②svnlook log "%REPOS%" -t "%TXN%" | findstr ".........." > nul
这句是核心程序。首先svnlook log是用来查看某个版本库某次提交的log的,那么我们怎么知道这两个
参数呢?答案是我们前面已经保存的REPOS和TXN参数。
它的作用是查看%REPOS%这个URL第%TXN%次提交的log信息,那么| findstr ".........."呢?细心
的读者会发现这里有10个圆点号,即表示10个字符。
整句的作用是先获取当前提交的log内容,然后判断是否有10个字符以上
③echo Empty log message not allowed. Commit aborted! 1>&2
这句话的作用是当提交检查失败时,输出的提示信息
【4. 运行测试及错误解决】到这里我们应该可以正常运行了吧?下面我们把上面这个程序保存为pre-commit.bat,保存到hook目录下。启动SVN,随意修改一个文件后,不写注释提交。看看下面的结果: 居然提示我们找不到svn repository目录下的format文件:
Svnlook:不能打开文件”C:pengOther ewRepofom…” The system cannot find The path specified.
真郁闷!这是什么原因。仔细检查文件,没有发现语法错误。从SVN的官网上下了一份同样内容的bat文件,测试通过!那会不会是文件的格式原因呢?我试着比较了这两份文件的字符数,发现居然不一样。会不会是一些控制字符的原因。
于是打开旧的文件,重新整理格式,发现每一行后面都多了一个中文的换行符。删除这些换行符再测试,测试通过!
教训:从网页上直接拷贝代码有时会带有特殊字符,诸如控制字符会中文空格等,这些字符有时会引起一些不必要的错误。