【问题标题】:Subversion Post-Commit HooksSubversion 提交后挂钩
【发布时间】:2013-04-16 14:51:59
【问题描述】:

我在让 post-commit 挂钩工作时遇到了一些问题。当我将更改的文件提交到我的存储库时,Subversion 似乎没有触发我的提交后挂钩。

我将 TortoiseSVN 和 VisualSVN 与 Subversion 一起使用,我能够进入 VisualSVN 用户界面并在其中创建一个有效的挂钩,但是我想做的是使用 hooks 文件夹中的提交后可执行挂钩我的安装来执行我的钩子。

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

"C:\Program Files\TortoiseSVN\bin\svn.exe" update "C:\mypath\myworkingcopy"

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

【问题讨论】:

  • 这个问题应该在 ServerFault, AFAIK 提出。
  • 为什么是 ServerFault 而不是 StackOverflow?
  • 如果有帮助,您可以接受和/或投票赞成答案。谢谢!

标签: svn visualsvn-server post-commit svn-hooks


【解决方案1】:

首先,所有的钩子都是在SERVER上执行的,而不是在不同的客户端机器上。是服务器上的C:\mypath\myworkingcopy 吗?如果没有,它不会得到更新。

其次,在钩子中做任何可能需要太多时间的事情都是不好的形式。如果您的钩子需要的不仅仅是svnlook,那么您可能做错了。例如,更新该工作副本需要多长时间? 10秒? 30秒?一分钟?这是开发人员必须坐下来等待 Subversion 提交完成的额外时间。

使用可以响应提交事件并在提交后挂钩之外执行诸如工作副本更新或部署到 Web 服务器之类的事情要好得多。我强烈推荐Jenkins 做这份工作。 Jenkins 有几个不错的功能:

  • 它具有成本效益(你不能免费)
  • 得到很好的支持(在 Stackoverflow 上发布问题并获得快速回复)。
  • 设置和使用非常简单。

现在回到你的问题:

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

 exit 2

这会让 Subversion 认为 post-commit 钩子失败了,你应该在提交时收到一条错误消息。如果没有,您的提交后脚本没有运行。确保脚本可由运行 Subversion 服务器的帐户执行。

如果您确实收到错误消息,则脚本正在运行。但是,svn 命令可能不会返回提交后进程发现的错误。我通常不推荐使用 Windows 批处理编程语言编写钩子,因为它的局限性。使用 Python 或 Perl 或 PowerShell。这些更适合检测错误情况,并且您可以在检测到时退出脚本。

再一次,一切运行良好,但您查看的工作副本有误(您机器上的那个,而不是服务器上的那个)。当您在 subversion 服务器之外运行 hooks 进行测试时,请以运行服务器进程的 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 是否在其中。

我想不出其他任何事情。

【讨论】:

  • “首先确保钩子正在运行。将这一行添加到批处理脚本的底部” - 不是理想的想法。 1 - 不提供信息 2 - 不可调试。 Echo inside hook 将帮助更多
  • @LazyBadger 在挂钩内回显将不起作用,除非挂钩失败。 Subversion 吃掉 STDOUT 并且只有在 hook 失败时才打印 STDERR。在底部添加exit 2 会让你知道钩子是否正在运行。请记住,这是一个单线钩子。回声不会告诉你太多。我想让这个尽可能简单。
  • 目前我正在开发机器上进行测试,所以我的客户端和服务器是同一个,所以是的,我的工作副本在服务器上。我尝试添加“exit 2”没有错误,所以它根本没有运行。我可以根据您的建议调用外部任务来完成更新,我同意这可能是一个好主意,但是问题仍然是调用外部任务的钩子仍然必须运行。最初我让“每个人”都能够修改此文件夹,但只是为了确保没有权限问题,我已明确授予“网络服务”修改权限,但仍未运行钩子。
  • @mgrenier 我也很怀疑。假设您的存储库位于C:\svn_repo。 hooks 目录位于C:\svn_repo\hooks。到此为止吧?在该目录中有一个post-commit.tmpl 文件。您将其重命名为 post-commit.bat。正确的?那应该是正在执行的文件。
  • @mgrenier 您正在使用 VisualSVN,因此您正在使用 Apache httpd,并且您使用 http://https:// 作为您的协议。一切应该工作。这是一种可能性:Subversion 总是调用post-commit 作为程序的名称。 Windows 很神奇地发现程序应该被称为post-commit.bat。这是通过 PATHEXT 环境变量完成的。我想知道这个变量是否未设置或已设置并且正在调用其他东西......
【解决方案2】:

我几乎为此发疯,我的问题是出口 2,在提交后没有向我的 svn 客户端发送任何内容。它在开始提交,预提交中运行良好,但在提交后,我从未收到任何错误。所以我的主要问题只是脚本本身的完整路径调用。

因此,如果您认为 post-commit 永远无法正常工作,并且您尝试了脚本中的 exit 1 并且没有收到任何错误,请尝试以下操作:

#!/bin/sh
/bin/touch /home/folder/post_commit_works

【讨论】:

    【解决方案3】:
    • 为网络服务帐户提供对工作副本文件夹C:\mypath\myworkingcopyC:\Program Files\TortoiseSVN\bin\svn.exe 的访问权限。

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

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

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

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

    【讨论】:

    • 我尝试了“捕获输出”技术,但没有创建文件...由于某种原因,post-commit.bat 挂钩似乎从未被触发
    • @mgrenier aww,我忽略了C:\Program Files\TortoiseSVN\bin\svn.exe 部分。你在服务器机器上安装了 TortoiseSVN 吗?为什么不执行%VISUALSVN_SERVER%bin\svn.exe
    • 我已经尝试使用 TortoiseSVN 路径和 VisualSVN 路径到 svn.exe,但都不起作用...我只是尝试使用 %VISUALSVN_SERVER%,但它似乎没有解决我的问题
    • 不需要日志:“任何打印到 stderr 的钩子都将被编组回客户端,从而更容易诊断钩子故障”和 Win stderr = stdout
    【解决方案4】:

    大卫回答的扩展版

    1. 检查,post-commit 钩子确实执行了:添加到 post-commit.bat echo ANYTHING 并在从 CLI 提交时,您必须看到任何输出到屏幕(如果 TSVN 输入将在提交窗口中)
    2. 如果执行了钩子脚本(必须如此),您必须测试运行 VisualSVN 服务器的帐户的权限(对于工作副本目录) - NetworkService 可能对文件的权限不足 - 我怀疑这一点,因为任何 svn 更新,即使是最新的 WC,都会输出到标准输出,您必须从提交后挂钩中看到此输出

    >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
    

    在提交时将所有 hook 的输出传输到屏幕

    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-auto\file.txt
    Updated to revision 13.
    

    【讨论】:

    • 如果回显,则必须echo something 1>&2,然后在钩子底部添加exit 2。否则,您将看不到消息。 Subversion 从不显示 STDOUT,只有在 hook 失败时才会显示 STDERR。
    【解决方案5】:

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

    尝试使用Bat2Exebat2exe.net 将您的批处理后提交编译成可执行文件,看看是否可以运行。

    【讨论】:

    猜你喜欢
    • 2019-10-02
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    相关资源
    最近更新 更多