打开控制台,在Repository属性中,找到hooks,添加 pre-commit 的 hook 处理
示例:
下面内容,对用户提交的内容进行检查,如果提交列表中有 pom.xml ,.project等文件,取消操作,显示提示信息。
如果当前提交者是 admin ,则允许。
@echo off
setlocal
set REPOS=%1
set REV=%2
set path="C:\Program Files\VisualSVN Server\bin\";%path%
for /f %%k in ('svnlook author %REPOS% -t %REV%') do set user=%%k
if "%user%" == "admin" goto admin
for /f %%k in ('svnlook changed %REPOS% -t %REV% ^| find /c /i "pom.xml"') do @set /a count=%%k
if NOT %count% == 0 (
echo 请不要提交 "pom.xml" >& 2
exit 1
)
for /f %%k in ('svnlook changed %REPOS% -t %REV% ^| find /c /i ".project"') do @set /a count=%%k
if NOT %count% == 0 (
echo 请不要提交 ".project" >& 2
exit 2
)
for /f %%k in ('svnlook changed %REPOS% -t %REV% ^| find /c /i ".classpath"') do @set /a count=%%k
if NOT %count% == 0 (
echo 请不要提交 ".classpath" >& 2
exit 3
)
for /f %%k in ('svnlook changed %REPOS% -t %REV% ^| find /c /i "target"') do @set /a count=%%k
if NOT %count% == 0 (
echo 请不要提交 "target" >& 2
exit 4
)
for /f %%k in ('svnlook changed %REPOS% -t %REV% ^| find /c /i ".settings"') do @set /a count=%%k
if NOT %count% == 0 (
echo 请不要提交 ".settings" >& 2
exit 4
)
:admin
exit 0
这是 windows batch 批处理脚本。相关语句说明:
1、@echo off
echo off是关闭回显,不显示命令内容。举例:如果你有一个test.bat,内容只有一行:dir,那执行后,输出的内容可能是:
C:\>test
C:\>dir
驱动器 C 中的卷是 WINXP
卷的序列号是 8C4E-88D3
C:\ 的目录
2011-04-28 08:55 <DIR> Documents and Settings
2011-12-14 09:32 <DIR> Intel
2012-03-03 10:26 <DIR> Oracle
2012-03-19 13:22 <DIR> Program Files
2011-12-14 09:34 2,122 RHDSetup.log
2012-03-24 15:26 6 test.bat
2012-03-09 16:44 <DIR> WINDOWS
2 个文件 2,128 字节
5 个目录 41,156,255,744 可用字节
如果你在最前面加上echo off,那输出的内容可能是:
C:\>test
C:\>echo off
驱动器 C 中的卷是 WINXP
卷的序列号是 8C4E-88D3
C:\ 的目录
2011-04-28 08:55 <DIR> Documents and Settings
2011-12-14 09:32 <DIR> Intel
2012-03-03 10:26 <DIR> Oracle
2012-03-19 13:22 <DIR> Program Files
2011-12-14 09:34 2,122 RHDSetup.log
2012-03-24 15:28 17 test.bat
2012-03-09 16:44 <DIR> WINDOWS
2 个文件 2,139 字节
5 个目录 41,156,255,744 可用字节
两者对比,你可以发现,dir这个命令在下面的示例中不再显示。
然而,由于加了一条语句 echo off,而这条语句在生效前,还是会回显的,所以你看到输出中有 c:\>echo off,是否有办法让这条语句也不显示呢?
可以,我们只要在 echo off 前加上 @ 就可以了。
那这样,我们的 test.bat 内容如下:
@echo off
dir
这回执行的结果可能是:
C:\>test
驱动器 C 中的卷是 WINXP
卷的序列号是 8C4E-88D3
C:\ 的目录
2011-04-28 08:55 <DIR> Documents and Settings
2011-12-14 09:32 <DIR> Intel
2012-03-03 10:26 <DIR> Oracle
2012-03-19 13:22 <DIR> Program Files
2011-12-14 09:34 2,122 RHDSetup.log
2012-03-24 15:31 18 test.bat
2012-03-09 16:44 <DIR> WINDOWS
2 个文件 2,140 字节
5 个目录 41,156,255,744 可用字节
2、setlocal
加上这条命令,避免批处理中对环境的改变影响到系统环境。如PATH
3、for 循环
for /f %%k in ('svnlook author %REPOS% -t %REV%') do set user=%%k
上面这句,要分解一下
for /f %%k in (‘command’) do stat
/f 是指定循环类型,这是迭代,用得最多的循环。
%%k 是变量,每次取出的值都会保存在里面。
'command' 用单引号指明要执行的命令,命令处理后,在控制台输出的内容会被 for 命令一行行取出处理。
stat 要执行的处理,如果有多条,可以用()包含多行命令。
再来看一下命令 svnlook author %REPOS% -t %REV%
svnlook 是 visual svn 安装后,在其 bin 目录下的管理工具,可以查看 Repository 的相关信息,如目录,日志等。具体可使用 svnlook help 查看帮助。
author 是查看用户名。
%REPOS% 是hook 传过来的 Repository 路径,如 C:\myRepository\projectA
-t %REV% %REV% 是 hook 传过来的事务ID号,如果不加参数 -t 则可以指定版本号。
使用这条命令,我们可以提取出当前提交者的用户名。
4、if "%user%" == "admin" goto admin
这是条件判断,如果用户名是 admin,使用 goto 语句,跳转到标签为 :admin 的地方,这在批处理的最后定义了。
5、for /f %%k in ('svnlook changed %REPOS% -t %REV% ^| find /c /i "pom.xml"') do @set /a count=%%k
这条语句与前面的 for 语句差不多,主要是 'command' 不同。
svnlook changed,这里可以列出所有提交的更新文件列表。
find /c /i "pom.xml 这是搜索语句,查找 pom.xml,/c 表示只显示搜索结果的条数, /i 表示不区分大小写
在这两条语句的中间,是管道符 |,表示将前者输出的内容,作为后者处理的输入内容,也就是将所有提交的文件列表,交给 find 去搜索,并统计有多少个 pom.xml
在管道符的前面,有个转义符 ^,其作用是将这特殊的字符当前普通字符串,而不是命令。如果没加这个转义符,那这个 'command' 就不是一个整体了,以至语法出错。这里是将其作为字符串,而 for 命令则将这个字符串再作为命令来处理,避免语法嵌套,解析错误。(这一点,之前不知道,总是提示语法错误,花了我不少时间才找出问题所在。)
5、取消 commit
要取消commit ,只要返回非0的结果代码即可。
如:exit 1
6、echo 请不要提交 "target" >& 2
前面没问题,是普通的 echo,后面是一个重定向。将输出的内容发送到错误输出的 stderr。
0 标准输入 stdin,键盘输入
1 标准信息输出 stdout,输出到控制台
2 标准错误输出 stderr,输出到控制台
如果不加 >& 2,那svn客户端是看不到提示信息的,必须要输出到 2
另外,如果提示说:Failed to start 'xxx/pre-commit.cmd' hook,可能需要有控制面板,高级,服务里,将visual svn的用户改为本地用户。