SVN挂钩不起作用 [英] SVN hooks not working

查看:282
本文介绍了SVN挂钩不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分支和主干的服务器存储库。分支是所有团队成员的资料库。我试图仅在分支下的回购中使用 svn钩子,但这似乎无法正常工作。以下是我尝试执行的步骤:

I have a server repository of branch and trunk. The branch is all team members' repositories. I'm trying to use svn hooks only in my repo under branch, but it doesn't seem to work fine. In the following are the steps I tried to approach:


  1. 已签出 my_repo 来自远程服务器的 branch / my_repo

,因为本地存储库 my_repo 没有任何内容,我在本地创建了一个新的svn存储库,并将包括 / hooks 文件夹在内的所有内容复制到 my_repo

since the local repo my_repo doesn't have any content, I created a new svn repo locally and copied over everything including the /hooks folder to my_repo.

我在 my_repo 中创建了一个空文件,并添加了一行文字。然后 svn添加此文件。

I created an empty file in my_repo and added a line of text. Then svn add this file.

修改了 my_repo / hooks / pre -commit.tmpl 文件,并使其始终不以错误代码1传递。现在看起来像这样:

modified the my_repo/hooks/pre-commit.tmpl file and make it always not pass with error code 1. Now it looks like:




#!/bin/sh
exit 1




  1. 复制 pre-commit.tmpl 进行预提交,并向自己添加预提交的执行许可

  1. copy the pre-commit.tmpl to pre-commit and add execute permit of pre-commit to myself

服务器包含其他人,现在服务器的结构类似于:

The server contains other people's now the server's structure is like:




- server
    - branch
        - my_repo
            - myfile
            - hooks
                - pre-commit
        - Tom's repo
        - other team member's repo
    - trunk




  1. 在已签出的仓库中,我使用以下命令提交了更改: svn commit -m傻瓜更改

  1. in the checked out repo I committed the changes using: svn commit -m "dumb change"

现在从这里我不应该能够提交,它应该给我一个错误,代码1正确?但我在任何地方都看不到。

Now from here I should not be able to commit and it should give me an error with code 1 right? But I don't see it anywhere.


  1. 然后我尝试将hooks文件夹放在顶层,并与分支和主干位于同一级别。即结构看起来像:




-server
    - branches
        - my_repo
            - myfile
        - Tom's repo
        - other team member's repo
    - trunk
    - hooks
        - pre-commit

但是,仍然无法正常工作。感叹……

But, still not working. sigh...

但是,在David的帮助下,我弄清楚了该怎么做和出了什么问题:
1.强调:钩子的所有权文件夹应与创建存储库的人相同。因此,我不得不要求所有者将挂钩文件添加到服务器。我没有在服务器上创建存储库,因此文件在我的工作目录中不可见。
2.现在,这是我尝试的方法:

HOWEVER, with David's help, I figured out what to do and what was wrong: 1. To highlight: the ownership of the hooks folder should be the same as who created to repository. Thus I had to ask the owner to add the hooks files to the server. I didn't create the repository on the server, thus the files are invisible in my working directory. 2. now here's what I tried:


  1) on my own Linux system, I `svnadmin create` a new repository, maybe called test_server: in that there is folders: confs, db, hooks, locks; files: format, readme.txt
  2) on the same level, mkdir a new folder (called working_dir) as your local working directory and checkout from the test_server. Now the working_dir contains a folder called test_server and it's empty. You can't see any of the folders or files in step 1
  3) modify the test_server's hooks file as described above. 
  4) try to add a file and add a new line to the file in the working_dir/test_server folder and commit. 
  5) now you should see commit failed with message: svn: Commit blocked by pre-commit hook(exit code 1) with no output. 

非常感谢David和任何人早些发表评论!

Thank you so much David and anyone put comments earlier!

推荐答案

运行钩子时,STDOUT(通常由 echo 语句产生的)被禁用。这意味着即使将脚本重定向到文件,您的脚本也无法使用STDOUT打印任何内容。

When you run a hook, the STDOUT (what normally is produced by an echo statement) is disabled. This means your script cannot use STDOUT to print out anything, even if it has been redirected to a file.

相反,您需要打开另一个文件描述符而不是使用 1 (STDOUT)。您可以使用 exec 命令打开另一个文件描述符,然后将其通过管道传输到文件中:

Instead, you need to open another file descriptor instead of using 1 (STDOUT). You can use the exec command to open another file descriptor, and then pipe that into a file:

exec 4> $my_file  #Opening my_file for writing
echo "This is going to $my_file" >&4

STDERR也被重定向。收集STDERR的输出,并将其发送回调用方客户端,但是仅当挂钩返回非零退出代码时才如此。这样,您就可以与客户端进行通信,说明挂钩失败的原因。

STDERR is also redirected. The output of STDERR is collected and sent back to the calling client, but only when a hook returns a non-zero exit code. This gives you a way to communicate with the client why a hook failed.

您还必须小心,因为清理了挂钩运行所在的环境。甚至 $ PATH 也为空。

You also must be careful because the environment that the hook runs in is scrubbed. Even $PATH is null.

这些是从命令行运行钩子脚本的一些原因,但不是

These are some of the reasons why a hook script will run fine from the command line, but not when it is executed as a hook.

如果您不相信钩子在起作用,只需对其进行设置,使其以非零的退出代码退出。如果您从Subversion收到一条消息,说明事务失败,那么您就知道该钩子脚本已执行。

If you don't believe a hook is working, just set it so it exits with a non-zero exit code. If you get a message back from Subversion that the transaction failed, you know the hook script executed.

我还建议您至少使用 svnserve 充当Subversion服务器-即使您是唯一使用存储库的服务器。即使我是使用存储库的唯一人,我也从不使用 file:// svnserve 的过程非常简单,而且非常轻巧。

I also recommend that you use, at a minimum, svnserve to act as a Subversion server -- even if you're the only one using the repository. I never use file:// even if I'm the only one using the repository. The svnserve process is pretty simple to use and it's fairly lightweight.

此外,请不要使用 svn 在挂钩脚本中。改用 svnlook

Also, never use svn in hook scripts. Use svnlook instead.

我要要对此非常非常清楚。我们需要同意一些定义:

I want to be very, very clear on this. We need to agree with some definitions:


  • SERVER是运行Subversion存储库的机器。您使用命令 svnadmin create foo 创建一个将用作存储库本身的 foo 目录。

  • 存储库目录是由 svnadmin create 命令在服务器上创建的目录。这是资源库的SERVER SIDE。您将 在此处看到您已签入Subversion的任何文件。相反,您将看到一个 hooks 目录和一个 db 目录。这就是服务器用来跟踪其更改的内容。

  • 工作目录是您执行 svn结帐进行结帐的目录

  • 存储库是使用各种 svn 命令时获得的存储库目录的虚拟视图。例如 svn ls svn日志 svn co <​​/ code>。这不是存储库目录,而是存储库的视图。

  • The SERVER is the machine which is running the Subversion repository. You used the command svnadmin create foo to create a foo directory that will act as the repository itself.
  • The REPOSITORY DIRECTORY is the directory on the server created by the svnadmin create command. This is the SERVER SIDE of the repository. You will not see any files you've checked into Subversion here. Instead, you will see a hooks directory and a db directory. This is what the server uses to track its changes.
  • The WORKING DIRECTORY is the directory you've done a svn checkout to checkout a particular revision of your project.
  • The REPOSITORY is the VIRTUAL view of the REPOSITORY DIRECTORY you get when you use the various svn commands like svn ls or svn log or svn co. This is NOT the REPOSITORY DIRECTORY but a view of the repository.

好的,现在我们解决了:

Okay, now we have this settled:

挂钩脚本存储在钩子目录下的存储库目录中。创建存储库目录时,将已经有一个名为 hooks 的子目录,其中包含一些用于挂钩脚本的模板。这些将具有 *。tmpl 后缀。要创建一个钩子,您需要用钩子脚本替换其中一个脚本,并删除后缀 *。tmpl 。挂钩脚本必须具有可执行权限,并且必须由运行Subversion SERVER进程的用户拥有。 (用户在服务器上运行 httpd svnserve 命令)。

Hook scripts are stored in the REPOSITORY DIRECTORY under the hooks directory. When you create the REPOSITORY DIRECTORY, there will already be a sub-directory called hooks with some templates for hook scripts. These will have a *.tmpl suffix. To make a hook, you need to replace one of these scripts with your hook script, and remove that *.tmpl suffix. The hook script has to have executable permission and be owned by the user that is running the Subversion SERVER process. (The user running httpd or the svnservecommand on the server).

挂钩适用于整个存储库。您不能告诉钩子仅在特定分支受到影响时才触发。但是,您的挂钩脚本可以查看文件的位置,并据此采取措施。我有一个预提交钩子就是这样做的。它使用控制文件来根据文件的位置确定需要执行的操作。但是,每次执行提交时,即使不需要执行任何操作,该钩子也会触发。

Hooks are for the entire repository. You can't tell a hook not to fire only when a particular branch is affected. However, your hook script can see where a file is located and take action based upon that. I have a pre-commit hook that does just that. It uses a control file to determine the action it needs to take based upon the location of a file. However, every time a commit happens, this hook will fire even if it doesn't have to do anything.

我希望这能回答您的问题。

I hope this answers your questions.

这篇关于SVN挂钩不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆