我有一个分支和主干的服务器存储库。分支是所有团队成员的存储库。我正在尝试使用 svn hooks
仅在我的分支下的 repo 中,但它似乎无法正常工作。以下是我尝试采取的步骤:
my_repo
来自远程服务器的branch/my_repo
my_repo
没有任何内容,我在本地创建了一个新的 svn 存储库并复制了所有内容,包括 /hooks
文件夹到 my_repo
. my_repo
中创建了一个空文件并添加了一行文字。然后svn add
这个文件。 my_repo/hooks/pre-commit.tmpl
文件并使其始终不通过,错误代码为 1。现在它看起来像:#!/bin/sh
1号导出
pre-commit.tmpl
预先提交并为自己添加预先提交的执行许可- 服务器
- 分支
- my_repo
- 我的文件
- Hook
- 预提交
- 汤姆的 repo
- 其他团队成员的 repo
- 树干
svn commit -m "dumb change"
现在从这里我应该无法提交,它应该给我一个代码 1 的错误,对吗?但我在任何地方都看不到它。
-服务器
- 分支机构
- my_repo
- 我的文件
- 汤姆的 repo
- 其他团队成员的 repo
- 树干
- Hook
- 预提交
但是,仍然无法正常工作。叹...
然而,在大卫的帮助下,我弄清楚了该怎么做以及出了什么问题:
1. 强调一下:hooks 文件夹的所有权应该和仓库的创建者相同。因此,我不得不要求所有者将 Hook 文件添加到服务器。我没有在服务器上创建存储库,因此这些文件在我的工作目录中是不可见的。
2.现在这是我尝试过的:
1)在我自己的Linux系统上,我`svnadmin create`一个新的存储库,可能称为test_server:其中有文件夹:confs,db,hooks,locks;文件:格式,readme.txt
2)在同一级别上,mkdir 一个新文件夹(称为working_dir)作为您的本地工作目录并从test_server checkout 。现在 working_dir 包含一个名为 test_server 的文件夹,它是空的。您在步骤 1 中看不到任何文件夹或文件
3) 如上所述修改 test_server 的 hooks 文件。
4)尝试添加一个文件并在working_dir/test_server文件夹中的文件中添加一个新行并提交。
5)现在您应该看到提交失败并显示消息:svn:提交被预提交 Hook (退出代码 1)阻止,没有输出。
非常感谢大卫和任何人早些时候发表评论!
最佳答案
运行 Hook 时,STDOUT(通常由 echo
语句生成)被禁用。这意味着您的脚本不能使用 STDOUT 打印出任何内容,即使它已被重定向到文件。
相反,您需要打开另一个文件描述符而不是使用 1
(标准输出)。您可以使用 exec
命令打开另一个文件描述符,然后将其通过管道传输到文件中:
exec 4> $my_file #Opening my_file for writing
echo "This is going to $my_file" >&4
STDERR 也被重定向。收集 STDERR 的输出并将其发送回调用客户端,但前提是 Hook 返回非零退出代码。这为您提供了一种与客户端沟通 Hook 失败原因的方法。您还必须小心,因为 Hook 运行的环境已被清除。偶
$PATH
一片空白。这些是钩子(Hook)脚本可以在命令行中正常运行的一些原因,但当它作为钩子(Hook)执行时则不行。
如果您不相信钩子(Hook)正在工作,只需将其设置为以非零退出代码退出。如果您从 Subversion 收到交易失败的消息,您就知道钩子(Hook)脚本已执行。
我还建议您至少使用
svnserve
充当 Subversion 服务器 - 即使您是唯一使用存储库的人。我从不使用 file://
即使我是唯一一个使用存储库的人。 svnserve
过程使用起来非常简单,而且相当轻量级。此外,切勿使用
svn
在钩子(Hook)脚本中。使用svnlook
反而。附录
我想非常非常清楚地说明这一点。我们需要同意一些定义:
svnadmin create foo
创建 foo
将充当存储库本身的目录。 svnadmin create
创建的目录。命令。这是存储库的服务器端。你会 不是 在此处查看您已 checkin Subversion 的所有文件。相反,您将看到 hooks
目录和 db
目录。这是服务器用来跟踪其更改的内容。 svn checkout
checkout 项目的特定版本。 svn
时获得的 REPOSITORY DIRECTORY 的虚拟 View 。像 svn ls
这样的命令或 svn log
或 svn co
.这不是存储库目录,而是存储库的 View 。 好的,现在我们解决了这个问题:
Hook 脚本存储在
hooks
下的 REPOSITORY DIRECTORY 中目录。创建存储目录时,已经有一个名为 hooks
的子目录。带有一些用于钩子(Hook)脚本的模板。这些将有 *.tmpl
后缀。要制作一个钩子(Hook),您需要用您的钩子(Hook)脚本替换其中一个脚本,然后删除它 *.tmpl
后缀。钩子(Hook)脚本必须具有可执行权限并且归运行 Subversion SERVER 进程的用户所有。 (用户在服务器上运行 httpd
或 svnserve
命令)。Hook 适用于整个存储库。您不能仅在特定分支受到影响时才告诉钩子(Hook)不要触发。但是,您的钩子(Hook)脚本可以查看文件所在的位置并据此采取行动。我有一个 pre-commit hook就是这样做的。它使用控制文件根据文件的位置确定需要采取的操作。然而,每次提交发生时,即使它不需要做任何事情,这个钩子(Hook)也会触发。
我希望这回答了你的问题。
关于SVN 钩子(Hook)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14966807/