如何测试我的预接收挂钩?
How can I test my pre-receive hook?
我需要创建一个预接收钩子来拒绝来自任何非主分支的任何客户端的推送,所以我写了这个脚本:
#!/bin/bash
refname="[=10=]"
oldrev=""
newrev=""
alowed_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),,')
if [ $alowed_branch = $current_branch ]
then
echo "you are pushing to master branch"
exit 0
else
echo Branch $current_branch is Locked.
exit 1
fi
现在我不知道如何测试它...
在我的本地 git 存储库的 'pre-commit' 挂钩上进行测试时,我得到了我想要的:
但是当尝试按照建议将其作为预推送或预接收挂钩进行测试时,它没有任何效果,我可以在不受干扰的情况下提交和推送。
有没有办法在 GitHub 上测试它?
测试挂钩,尤其是预接收挂钩,很困难:它们 运行 在不寻常的环境中。测试它们的好方法很少(主要的好方法是牺牲一两个存储库)。
你这里有很多相互交织的问题:
refname="[=10=]"
无论如何这都是错误的,因为在 shell 脚本中,[=15=]
指的是 脚本本身的名称 .
current_branch=$(refname)
您在编辑中删除的这个也是错误的:它尝试 运行 命令 refname
。所以你更换它很好,但是:
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),,')
这是一个微妙的错误:如果您当前的分支名为 fixes/bug-123
,它将 current_branch
设置为 bug-123
,而不是 fixes/bug-123
。
要获取 当前分支名称 作为减去 refs/heads/
部分的符号引用,请使用:
current_branch=$(git symbolic-ref --short HEAD) || exit 1
--short
指示git symbolic-ref
省略refs/heads/
部分,|| exit 1
指示shell 退出(失败状态)如果 git symbolic-ref
本身失败,它可以:如果你有一个 "detached HEAD",HEAD
是 而不是 一个符号ref,并且 Git 会抱怨并且 current_branch
将被设置为空字符串。
现在,除了这些,你提到:
... trying to test it as a pre-push or pre-receive hook ...
作为预推送挂钩,</code> 和 <code>
(您存储在 oldrev
和 newrev
中)实际上将设置为名称和 URL的遥控器!旧的和新的修订 ID,以及旧的和新的引用名称,作为它的 标准输入 传递给那个钩子。这一切都发生在客户端,在连接到另一个 Git (远程)之后但在发送任何内容之前。 (See the section on pre-push
hooks in the githooks documentation.)
作为预接收挂钩,</code> 和 <code>
根本不会设置任何值(这没关系,因为您从不使用无论如何变量)。 当前分支 将是远程 上另一个Git 中的当前分支。预接收挂钩,如预推挂钩,必须读取其标准输入,一次一行,检查该行提供的每组参数。如果挂钩以非零 return 退出,则整个推送将被拒绝(从服务器端)。
在预推或预接收挂钩中检查引用名称时,请务必检查 整个 引用:传入引用(在任一挂钩中)或传出引用 (在 pre-push 挂钩中)可以引用一个标签,例如 refs/tags/v1.2
,或者名称包含斜杠的分支,如 refs/heads/feature/tall
。除了名称的最后一部分,不要只砍掉名称的最后一部分,也不要在不看的情况下砍掉前两个部分。而且,在任一挂钩中,当前分支名称通常是完全不相关的:某人 运行ning git push
在命令行上指定 要推送 的引用:
git push origin \
refs/heads/master:refs/for/master \
refs/tags/v1.2:refs/tags/v1.2 \
refs/notes/commits:refs/notes/commits \
refs/peculiar-ref:refs/even-stranger/master
例如。 None 个将进入目标的 分支 ;只有一个是来自源上的一个分支。
(请注意,挂钩可以用任何可以 运行 在安装了特定 Git 的机器上编写的语言编写。它们 没有 成为 bash / sh 脚本——虽然如果你有 Git 你必须有一个 shell,因为 Git 的部分是写在 shell 中的。总是当心硬编码路径:例如,bash 在某些系统上可能位于 /usr/local/bin/bash
而不是 /bin/bash
。)
我需要创建一个预接收钩子来拒绝来自任何非主分支的任何客户端的推送,所以我写了这个脚本:
#!/bin/bash
refname="[=10=]"
oldrev=""
newrev=""
alowed_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),,')
if [ $alowed_branch = $current_branch ]
then
echo "you are pushing to master branch"
exit 0
else
echo Branch $current_branch is Locked.
exit 1
fi
现在我不知道如何测试它...
在我的本地 git 存储库的 'pre-commit' 挂钩上进行测试时,我得到了我想要的:
但是当尝试按照建议将其作为预推送或预接收挂钩进行测试时,它没有任何效果,我可以在不受干扰的情况下提交和推送。
有没有办法在 GitHub 上测试它?
测试挂钩,尤其是预接收挂钩,很困难:它们 运行 在不寻常的环境中。测试它们的好方法很少(主要的好方法是牺牲一两个存储库)。
你这里有很多相互交织的问题:
refname="[=10=]"
无论如何这都是错误的,因为在 shell 脚本中,[=15=]
指的是 脚本本身的名称 .
current_branch=$(refname)
您在编辑中删除的这个也是错误的:它尝试 运行 命令 refname
。所以你更换它很好,但是:
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),,')
这是一个微妙的错误:如果您当前的分支名为 fixes/bug-123
,它将 current_branch
设置为 bug-123
,而不是 fixes/bug-123
。
要获取 当前分支名称 作为减去 refs/heads/
部分的符号引用,请使用:
current_branch=$(git symbolic-ref --short HEAD) || exit 1
--short
指示git symbolic-ref
省略refs/heads/
部分,|| exit 1
指示shell 退出(失败状态)如果 git symbolic-ref
本身失败,它可以:如果你有一个 "detached HEAD",HEAD
是 而不是 一个符号ref,并且 Git 会抱怨并且 current_branch
将被设置为空字符串。
现在,除了这些,你提到:
... trying to test it as a pre-push or pre-receive hook ...
作为预推送挂钩,</code> 和 <code>
(您存储在 oldrev
和 newrev
中)实际上将设置为名称和 URL的遥控器!旧的和新的修订 ID,以及旧的和新的引用名称,作为它的 标准输入 传递给那个钩子。这一切都发生在客户端,在连接到另一个 Git (远程)之后但在发送任何内容之前。 (See the section on pre-push
hooks in the githooks documentation.)
作为预接收挂钩,</code> 和 <code>
根本不会设置任何值(这没关系,因为您从不使用无论如何变量)。 当前分支 将是远程 上另一个Git 中的当前分支。预接收挂钩,如预推挂钩,必须读取其标准输入,一次一行,检查该行提供的每组参数。如果挂钩以非零 return 退出,则整个推送将被拒绝(从服务器端)。
在预推或预接收挂钩中检查引用名称时,请务必检查 整个 引用:传入引用(在任一挂钩中)或传出引用 (在 pre-push 挂钩中)可以引用一个标签,例如 refs/tags/v1.2
,或者名称包含斜杠的分支,如 refs/heads/feature/tall
。除了名称的最后一部分,不要只砍掉名称的最后一部分,也不要在不看的情况下砍掉前两个部分。而且,在任一挂钩中,当前分支名称通常是完全不相关的:某人 运行ning git push
在命令行上指定 要推送 的引用:
git push origin \
refs/heads/master:refs/for/master \
refs/tags/v1.2:refs/tags/v1.2 \
refs/notes/commits:refs/notes/commits \
refs/peculiar-ref:refs/even-stranger/master
例如。 None 个将进入目标的 分支 ;只有一个是来自源上的一个分支。
(请注意,挂钩可以用任何可以 运行 在安装了特定 Git 的机器上编写的语言编写。它们 没有 成为 bash / sh 脚本——虽然如果你有 Git 你必须有一个 shell,因为 Git 的部分是写在 shell 中的。总是当心硬编码路径:例如,bash 在某些系统上可能位于 /usr/local/bin/bash
而不是 /bin/bash
。)