SVN钩子无法正常工作

cur*_*nny 3 svn hook commit

我有分支和主干的服务器存储库.该分支是所有团队成员的存储库.我试图svn hooks只在我的分支下使用repo,但它似乎没有正常工作.以下是我试图接近的步骤:

  1. my_repo从远程服务器检出branch/my_repo

  2. 由于本地仓库my_repo没有任何内容,我在本地创建了一个新的svn仓库并复制了包括/hooks文件夹在内的所有内容my_repo.

  3. 我创建了一个空文件my_repo并添加了一行文本.然后svn add这个文件.

  4. 修改了my_repo/hooks/pre-commit.tmpl文件并使其始终没有通过错误代码1.现在它看起来像:

#!/bin/sh
exit 1
  1. 复制pre-commit.tmpl到预先提交并添加预先提交的执行许可给自己

  2. 服务器现在包含其他人的服务器结构如下:

- server
    - branch
        - my_repo
            - myfile
            - hooks
                - pre-commit
        - Tom's repo
        - other team member's repo
    - trunk
  1. 在签出的回购中,我使用以下方式提交了更改: svn commit -m "dumb change"

现在从这里我不能提交它应该给我一个错误的代码1对吗?但我在任何地方都看不到它.

  1. 然后我尝试将hooks文件夹放在顶层和分支和主干的同一级别.即结构如下:
-server
    - branches
        - my_repo
            - myfile
        - Tom's repo
        - other team member's repo
    - trunk
    - hooks
        - pre-commit

但是,仍然没有工作.叹...

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

  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. 

非常感谢大卫和任何人提前发表评论!

Dav*_* W. 6

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

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

exec 4> $my_file  #Opening my_file for writing
echo "This is going to $my_file" >&4
Run Code Online (Sandbox Code Playgroud)

STDERR也被重定向.收集STDERR的输出并将其发送回调用客户端,但仅当挂钩返回非零退出代码时.这为您提供了一种与客户端进行通信的方法,即钩子失败的原因.

您还必须小心,因为钩子运行的环境被擦除.甚至$PATH是空的.

这些是钩子脚本从命令行运行良好的一些原因,但不是当它作为钩子执行时.

如果你不相信一个钩子工作,只需设置它以使它退出时使用非零退出代码.如果从Subversion收到一条消息,说明事务失败,则表示已执行钩子脚本.

我还建议您至少使用svnserveSubversion服务器 - 即使您是唯一使用存储库的人.file://即使我是唯一一个使用存储库的人,我也从未使用过.这个svnserve过程使用起来非常简单,并且相当轻巧.

此外,永远不要svn在钩子脚本中使用.请svnlook改用.


附录

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

  • SERVER是运行Subversion存储库的机器.您使用该命令svnadmin create foo创建了一个foo充当存储库本身的目录.
  • REPOSITORY DIRECTORY是svnadmin create命令创建的服务器上的目录.这是存储库的SERVER SIDE.你不会在这里看到任何你在Subversion中检查过的文件.相反,您将看到hooks目录和db目录.这是服务器用于跟踪其更改的内容.
  • WORKING DIRECTORY是您svn checkout检查项目特定修订版的目录.
  • 存储库是当你使用的各种资源库目录的虚拟视图你得到svn命令,如svn lssvn logsvn co.这不是REPOSITORY DIRECTORY,而是存储库的视图.

好的,现在我们已经解决了这个问题:

钩子脚本存储在目录下的REPOSITORY DIRECTORY中hooks.当您创建REPOSITORY DIRECTORY时,将会有一个子目录hooks,其中包含一些用于钩子脚本的模板.这些将有一个*.tmpl后缀.要创建一个钩子,您需要用钩子脚本替换其中一个脚本,并删除该*.tmpl后缀.钩子脚本必须具有可执行权限,并且由运行Subversion SERVER进程的用户拥有.(用户正在运行httpdsvnserve服务器上的命令).

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

我希望这回答了你的问题.