如何在post-commit钩子中执行命令?

时间:2012-12-02 12:27:55

标签: svn post-commit svn-hooks

每当提交SVN子目录mycommand时,我希望我的SVN服务器执行特定命令svn-rep/myfolder

我该怎么做?我知道有预挂钩的钩子目录。但是我该如何制作一个自定义钩子呢? SVN如何知道何时调用哪个钩子 - 是否基于文件名?如果提交更改svn-rep/myfolder中的某些文件,我将如何限制挂钩才能执行?

要明确:命令永远不会改变,它只是引用位于服务器某处的另一个脚本。

编辑:我刚刚实现了post-commit并且出于测试目的,它应该将SVN目录的修订号附加到已经存在的(并且对于每个人都可写):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from subprocess import Popen, PIPE

dirRevisionCmd  = 'svn info /var/www/main | grep -i "Letzte geänderte Rev"

process = Popen(headRevisionCmd, shell=True, stdout=PIPE, stderr=PIPE)
out, err = process.communicate()

with open("/var/lib/svn/rep/hooks/testfile", "a") as testfile:
    testfile.write("err:" + err.strip() + "\n")
    testfile.write("out:" + out.strip() + "\n")

每次提交后都会产生空标准输出:

www-data
err:
out:

如果我手动执行post-commit,则“out”行包含一些文本。那为什么它不适用于SVN?

1 个答案:

答案 0 :(得分:6)

服务器上的Subversion存储库内部是一个名为hooks的目录。里面是 示例 钩子脚本。它们都以.tmpl后缀结尾。他们真的是占位符。没有比这更好的了。

如果某个程序或脚本名为post-commit,Subversion将在有人提交后执行它。无论这是可执行文件,Windows Batch程序还是Unix shell脚本都无关紧要。 Subversion将在提交发生后执行它。脚本的作用并不重要。这真的很简单。

如果已经有一个名为post-commit的程序怎么办?你必须修改它。正如我所说,默认存储库中没有挂钩 - 只需要一堆模板,如果需要,可以使用它们。如果有post-commit程序,那么某人必须已添加该程序。

因此,只需将您的命令放在hooks目录中,确保它是可执行的,并将其命名为post-hook。 Subversion将在有人提交后执行它。


您从未指定要执行此命令的内容,因此我无法提供任何进一步的建议。但是,通常有一些指导程序来挂钩脚本:

  1. 钩子脚本的执行时间不应超过几毫秒。当钩子脚本执行时,它会绑定提交者的机器,直到钩子脚本完成。例如,一个常见问题是如何通过提交后脚本进行部署。这是个坏主意,因为它会长时间占用提交者的计算机。有更好的方法可以做到这一点。
  2. Hook脚本在服务器上运行,提交在客户端计算机上进行。这意味着:
    1. 钩子脚本无法访问客户端的环境。
    2. 钩子脚本无法查询客户端。
    3. 钩子脚本无法修改提交。
    4. 钩子脚本无法搜索客户端的工作目录。
      • 这也意味着除了接受或拒绝提交之外,预提交挂钩不能执行任何操作。
    5. 钩子脚本不应该导致新的提交。首先是一个提交钩子导致提交导致自己在循环中再次运行的问题。其次,它使刚刚完成提交的人有一个过时的工作目录。此外,这意味着您的日志历史记录的50%只是您自己的提交钩子。
  3. 最后,Hook脚本有一个非常简单的方式与客户端交谈:
    1. Hook脚本无法访问客户端的STDINSTDOUT。实际上,钩子脚本无法访问STDIN或STDOUT。
    2. Hook脚本通过退出值为零来显示成功。它们通过执行非零的退出值来显示失败。
    3. 如果钩子以非零值退出,则钩子脚本生成的STDERR将被发送到客户端,但不会发送到子进程。这样,您就可以向客户端解释钩子脚本失败的原因。
  4. 正如其他人所说:阅读在线的fine manual。它一步一步地完成。创建一个测试存储库并使用钩子脚本。他们真的很简单。你可以看一下我写的post-commit hook。它附带安装说明。也许这会有所帮助。


    响应

      

    如果我手动执行post-commit,'out'行包含一些文本。那为什么它不适用于SVN?

    我按列表重新编号,使其成为数字列表。看一下第3.1点: Hook脚本无法访问STDOUT 。我不是Python程序员,但看起来你正在尝试使用STDOUT将输出传递给另一个进程。钩子脚本吃STDOUT,并且该输出无法发送到另一个进程。此外,STDERR被捕获,但不通过管道发送。而是收集STDERR并将其发送到执行提交的客户端。这样,您就可以向客户端发送错误描述。

    您可以打开子流程并发送文本,但不能通过管道发送。