2

请您指导我如何svnlook在下面工作。我想将其包含在一个挂钩中,以防止在以下标签中提交/tags

$SVNLOOK changed -t "$TXN" "$REPOS" | grep "^U\W.*\/tags\/" && /bin/echo "Cannot commit to tags!" 1>&2 && exit 1
4

2 回答 2

1

如果 Subversion 预提交钩子返回退出代码为0. 否则,预提交钩子将失败,提交将不会被处理。

$SVNLOOK changed -t "$TXN" "$REPOS"显示在$REPOS中发生的变化$TXN。shell 变量必须由您设置。如果您查看pre-commitSubversion 附带的脚本,您会看到:

$TXN=$1
$REPO=$2

svnlook changed命令的输出如下所示:

$ $SVNLOOK changed -t $TXN $REPOS
A   trunk/vendors/deli/
A   trunk/vendors/deli/chips.txt
A   trunk/vendors/deli/sandwich.txt
A   trunk/vendors/deli/pickle.txt
U   trunk/vendors/baker/bagel.txt
_U  trunk/vendors/baker/croissant.txt
UU  trunk/vendors/baker/pretzel.txt
D   trunk/vendors/baker/baguette.txt

第一列是某项内容是否被U prated、A dded 或D删除。第二列是指属性。

其余的是被操作的文件的名称。您可以看到它baguette.txt已被删除,并且属性 oncroissant.txt已更改,但文件本身并未更新。

假设有人试图更改标签。的输出svnlook changed将如下所示:

$SVNLOOK changed -t $TXN $REPOS
U   tags/4.2.1/vendors/baker/bagel.txt

grep 命令是这样的:

grep "^U\W.*\/tags\/" 

这正在寻找以^U它是更新的含义开头的行。然后,它查找以 开头的字符串/tags。嗯……这可能是个问题。它与命令的输出不匹配svnlook changed

也许应该是:

grep -q "^U.[[\s+tags/"

这将匹配任何以 开头的字符串U,可能后跟另一个字符,然后是空格,然后是单词tags/

您可能想要验证该表达式。

&&一个列表运算符。如果左边的表达式&&执行成功(即返回零退出代码),右边的语句将被执行。否则,右边的语句不会被执行。

因此,如果您grep匹配的模式看起来像是有人更新了标签,那将是真的。右侧的语句&&将被执行。

因此,

/bin/echo "Cannot commit to tags!" 1>&2

将被执行。这被发送到 STDERR,STDERR 将被发送到 Subversion 客户端,但前提是 pre-commit 钩子的退出代码为零。

因此,如果成功,exit 1将执行下一个列表运算符命令。/bin/echo(可能不会,但通常会)。这样,预提交钩子以非零退出代码退出,钩子失败,并将Cannot commit to tags!发送到 SVN 客户端供用户查看。

世界上绝对没有理由让这个声明看起来像这样。这几乎是等价的,并且更容易理解:

if $SVNLOOK changed -t $TXN $REPOS | grep -q "^U.[[\s+tags/"
then
    /bin/echo "Cannot commit to tags!" 1>&2"
    exit 1
fi
exit 0

毕竟,您需要将它放在一个pre-commit无论如何调用的 shell 脚本中,并设置 shell 变量$SVNLOOK,$REPOS$TXN无论如何设置。

这不完全等效的原因是即使失败也会使提交/bin/echo失败。


如果你正在寻找一个 pre-commit 钩子来控制标签,你应该看看的。这已经在数百个站点上进行了测试,并且可以让您更好地控制存储库并进行更好的错误检查。

此挂钩使用控制文件来控制对存储库的访问。例如,您可能希望能够让自己在必要时更改标签。

[file You are allowed to create a new tag, but you may not make any changes to it]
file = /tags/**
access = read-only
users = @ALL

[file You are allowed to create a new tag, but you may not make any changes to it]
file = /tags/
access = add-only
users = @ALL

[file I can modify and delete tags]
file = /tags/**
access = read-write
users = jazzr

看看钩子。它适用于标准 Perl 5.8.8 安装及更高版本。它不需要其他模块。但是,如果您使用 LDAP 或 Active Directory 进行 Subversion 访问控制,则可以安装Net::LDAPPerl 模块并在预提交挂钩中使用 LDAP 或 Active Directory 组进行访问控制。

于 2014-01-08T19:31:14.623 回答
0

$SVNLOOK changed -t "$TXN" "$REPOS"打印所有更改的路径。有关参数的更多信息,请参见此处:http: //svnbook.red-bean.com/en/1.7/svn.ref.svnlook.c.changed.html

接下来,更改的路径列表将通过管道传输到 grep 中,该 grep 正在检查路径中是否有任何具有“/tags/”的更改,| grep "^U\W.*\/tags\/".

&& 是 shell 中的 AND 运算符。如果 grep 命令找到匹配项,则返回状态码 0,在这种情况下相当于“TRUE”,&& 后面的命令将执行,否则不执行。

&& 之后的部分/bin/echo "Cannot commit to tags!" 1>&2运行 echo 命令并将消息从 1(标准输出)写入标准错误 &2。如果此操作成功,则命令以状态码 1 退出exit 1。这将导致您的钩子脚本以非零状态代码返回,并且您的提交将无法返回“无法提交到标签!” 给用户的消息。

于 2014-01-08T18:42:03.580 回答