我的SVN钩子脚本----- pre-commit.bat有什么问题?

时间:2014-11-03 01:56:14

标签: svn batch-file hook visualsvn

我为在Windows上运行的SVN编写了一个预提交钩子脚本(.bat)。

主要目的是:

  1. 检查还原日志长度;
  2. 阻止普通用户删除[repo]/trunk/文件夹;
  3. 阻止普通用户删除[repo]/trunk/xxx/个文件夹;
  4. 但SVN总是说:

    command syntax not correct (exitcode 255)
    

    代码在这里:

    @echo off
    :: Stops commits that have empty log messages.
    @echo off
    
    setlocal
    
    set REPOS=%1
    set TXN=%2
    
    Rem Check log length.
    svnlook log -t "%TXN%" "%REPOS%" | findstr ".........." > nul
    if %errorlevel% gtr 0 goto NoLog
    
    @echo off
    set Drop=No
    
    Rem Check Delete operation on trunk
    svnlook changed -t "%TXN%" "%Repos%" | findstr "^D[ ]*trunk//$"
    if %ERRORLEVEL% == 0 (set Drop=Yes)
    
    Rem Check Delete operation on subdirectory of Trunk
    svnlook changed -t "%TXN%" "%Repos%" | findstr "^D[ ]*trunk/[.]*//$"
    if %ERRORLEVEL% == 0 (set Drop=Yes)
    
    if Drop == Yes
    (goto DropTrunk)
    else
    (exit 0)
    
    :NoLog
    echo You must inpu reversion log, and not less than 10 characters! 1>&2
    exit 1
    
    :DropTrunk
    echo Only admin can delete the trunk directory and its subdirectory! 1>&2
    exit 1
    

2 个答案:

答案 0 :(得分:1)

也许你只需要告诉你的钩子脚本在哪里找到svnlook命令。来自SVN书:

  

默认情况下,Subversion使用空环境执行钩子脚本 - 也就是说,根本没有设置环境变量,甚至不是$ PATH(或Windows下的%PATH%)。因此,许多管理员在他们的钩子程序手动运行时感到困惑,但是在Subversion调用时不起作用。管理员历来通过在脚本本身中手动设置钩子脚本所需的所有环境变量来解决这个问题。

来自:http://svnbook.red-bean.com/en/1.8/svn.reposadmin.create.html#svn.reposadmin.hooks.configuration

答案 1 :(得分:1)

错误的核心问题是if Drop == Yes查询的语法。除非出现左括号,否则命令解释程序不知道行if Drop == Yes在下一行中继续。

所以声明必须是:

if Drop == Yes (
    goto DropTrunk
) else (
    exit 0
)

或作为一行:

if Drop == Yes (goto DropTrunk) else (exit 0)

在命令提示符窗口中键入if /?,以查看正确的if / else语法。

但还有另一个问题:if Drop == Yes将文字字符串DropYes进行比较,当然,这绝不会是真的。要比较变量Drop的值,您需要将其更改为:

if %Drop% == Yes (
    goto DropTrunk
) else (
    exit 0
)

或:

if %Drop% == Yes (goto DropTrunk) else (exit 0)

为了比较这样的字符串,我会在字符串周围加上引号以避免一些特殊字符或空字符串的麻烦,我还会使用/I开关进行不区分大小写的比较:< / p>

if /I "%Drop%"=="Yes" (
    goto DropTrunk
) else (
    exit 0
)

或:

if /I "%Drop%"=="Yes" (goto DropTrunk) else (exit 0)

无论如何,我会采用不同的方式完成整个方法,如下所示:

@echo off
set "Drop="

Rem Check Delete operation on trunk
svnlook changed -t "%TXN%" "%Repos%" | findstr "^D[ ]*trunk//$" > nul
if %ErrorLevel% EQU 0 (set "Drop=Yes")

Rem Check Delete operation on subdirectory of Trunk
svnlook changed -t "%TXN%" "%Repos%" | findstr "^D[ ]*trunk/[.]*//$" > nul
if %ErrorLevel% EQU 0 (set "Drop=Yes")

if defined Drop (
    goto DropTrunk
) else (
    exit 0
)

如您所见,我通过仅检查变量Drop是否已定义来避免字符串比较,并且我最初将其清除,而不是将其设置为No

此外,我将ErrorLevel检查的比较运算符从==(字符串比较)更改为EQU(数字比较)。