Subversion提交后钩子



我有一些问题得到后提交钩子工作。当我向存储库提交更改后的文件时,Subversion似乎没有触发我的post-commit钩子。

我正在使用Subversion的TortoiseSVN和VisualSVN,我能够进入VisualSVN用户界面并在那里创建一个钩子,但是我想做的是在我的安装的钩子文件夹中使用提交后可执行钩子来执行我的钩子。

我已经将名称从post-commit.tmpl更改为post-commit.bat在我的存储库的/hooks文件夹中,我只是在批处理文件中做一个简单的更新:

"C:Program FilesTortoiseSVNbinsvn.exe" update "C:mypathmyworkingcopy"

当我自己运行批处理文件时,它会更新我的工作文件夹,所以我认为当我出于某种原因提交时它不会被触发。这似乎不是一个权限问题,因为一切都是在我的机器上本地完成的,但我已将其设置为作为网络服务运行,但仍然遇到同样的问题…有什么建议吗?

首先,所有的钩子都在SERVER上执行,而不是在各种客户端机器上执行。服务器上的是C:mypathmyworkingcopy吗?如果没有,它将不会被更新。

其次,在钩子中做任何可能花费太多时间的事情都是不好的形式。如果你的钩子需要比svnlook更多的东西,很可能你做错了。例如,更新工作副本需要多长时间?10秒?30秒?借我一分钟?这是开发人员不得不坐下来等待Subversion提交完成的额外时间。

使用一些可以响应提交事件的东西,让它在提交后钩子之外做一些事情,比如拷贝更新或部署到web服务器,这要好得多。我强烈推荐詹金斯做这份工作。Jenkins有几个很好的特性:

  • 它的成本效益(你不能打败免费)
  • 它得到了很好的支持(在Stackoverflow上发布问题并得到快速响应)。
  • 设置和使用很简单。

现在回到你的问题:

首先确保钩子正在运行。在批处理脚本的底部添加这一行:

 exit 2

这会让Subversion认为post-commit钩子已经失败,你应该在提交时得到一个错误消息。如果没有,则说明提交后脚本没有运行。确保脚本可以通过运行Subversion服务器的帐户执行。

如果您确实得到错误消息,则说明脚本正在运行。但是,svn命令可能不会返回由提交后进程拾取的错误。我通常不建议用Windows批处理编程语言编写钩子,因为它有局限性。使用Python、Perl或PowerShell。它们可以更好地检测错误条件,并且可以在检测到错误条件时退出脚本。

然后,一切都工作得很好,但是您正在查看错误的工作副本(您的机器上的副本而不是服务器上的副本)。当您在subversion服务器之外运行钩子进行测试时,请以运行服务器进程的subversion用户的身份在服务器上运行它们。

试试这些方法,看看是否能解决你的问题。


附加评论

我使用svnadmin create创建了一个存储库,并使用svnserve运行它。我更新了svnserve.conf以允许我签出和提交代码。

我进入hooks目录,将pre-commit.tmpl重命名为pre-commit.bat,并设置为:

set 1>&2
echo "Blocked my me!" 1>&2
exit 2

当我试图提交我的更改时,我得到:

Transmitting file data .svn: E165001: Commit failed (details follow):
svn: E165001: Commit blocked by pre-commit hook (exit code 2) with output:
[...]
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.RB;.RBW
PERL_JSON_BACKEND=JSON::XS
PERL_YAML_BACKEND=YAML
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 42 Stepping 7, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=2a07
[...]
"Blocked my me!"

钩子应该删除环境(包括PATH),但我猜这只适用于Unix而不是Windows。您可以看到PATHEXT的定义。

然后我将pre-commit.bat重命名为pre-commit.tmpl,并创建了post-commit.bat ',看起来像这样:

echo This post-commit hook shall fail! 1>&2
exit 2

在提交过程中,我得到了以下内容:

Transmitting file data .
Committed revision 3.
Warning: post-commit hook failed (exit code 2) with output:
This post-commit shall fail!

看起来一切都在按计划进行。我没有使用VisualSVN,也没有作为服务运行。我想知道你的PATHEXT环境变量是否有问题。

也许可以看看你运行Subversion服务器的帐户是如何设置的,看看.BAT是否在那里。

我一时想不出别的事来。

我几乎疯了,我的问题是,退出2,没有发送任何后提交到我的svn客户端。它在启动-提交,预提交中工作良好,但在提交后,我从未得到任何错误。所以我的主要问题是脚本本身的完整路径调用。

所以如果你觉得post-commit从来没有工作过,你在脚本中尝试了exit 1,你没有得到任何错误,尝试这样做:

#!/bin/sh
/bin/touch /home/folder/post_commit_works
  • 提供访问工作副本文件夹C:mypathmyworkingcopyC:Program FilesTortoiseSVNbinsvn.exe的网络服务帐户

  • 如果它不工作,那么让我们将钩子输出捕获到日志文件中,以获得关于根本原因的一些线索:

    1. 将当前post-commit.bat文件重命名为post-commit-run.bat。创建以下文件作为post-commit.bat文件:

      call "%~dp0post-commit-run.bat" %*> %1/hooks/post-commit.log 2>&1

    2. 提交到存储库并检查生成的日志文件。输出将为您提供有关根本原因的线索。

David回答的扩展版

  1. 检查,提交后钩子真正执行:添加到post-commit.bat echo ANYTHING和从CLI提交时,你必须看到任何输出屏幕(在TSVN的情况下,将在提交窗口)
  2. 如果钩子脚本执行(它必须是这样),你必须测试权限(对于工作复制目录)的帐户,在其中运行VisualSVN服务器- NetworkService可能没有足够的文件权限-我怀疑这一点,因为任何svn更新,即使是最新的WC,输出到stdout,你必须看到这个输出从你的提交后钩子

>svn up "z:wc"

Updating 'wc':

At revision 3.


编辑和修复

感谢David提到我愚蠢的错误和刷新记忆。虽然带有文件日志记录的bahrep版本可以工作,但这种类型的提交后钩子(在post-commit.bat中)

echo Running 1>&2
svn up "z:wc-auto" 1>&2
exit 2

在提交时将所有钩子的输出发送到屏幕

z:wc>svn ci -m "Testing hook"
Sending        file.txt
Transmitting file data .
Committed revision 13.
Warning: post-commit hook failed (exit code 2) with output:
Running
Updating 'Z:wc-auto':
U    Z:wc-autofile.txt
Updated to revision 13.

我在做post-commit.bat时也有同样的问题。我认为Subversion在Windows上运行后提交时,脚本有.exe作为扩展名。

尝试用Bat2Exe或bat2exe.net编译批处理提交后的可执行文件,看看是否运行。

最新更新