代码之家  ›  专栏  ›  技术社区  ›  Shahar Hamuzim Rajuan

如何测试预接收挂钩?

  •  3
  • Shahar Hamuzim Rajuan  · 技术社区  · 7 年前

    我需要创建一个预接收钩子,拒绝来自任何非主分支的任何客户端的推送,因此我编写了以下脚本:

         #!/bin/bash
    
        refname="$0"
        oldrev="$1"
        newrev="$2"
    
        alowed_branch='master'
        current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
    
        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 repo上的“预提交”钩子上测试时,我得到了我想要的:

    enter image description here

    但是,当尝试按建议将其作为预推或预接收挂钩进行测试时,它不会产生任何效果,我可以在没有干扰的情况下提交和推送。

    有没有办法在GitHub上测试它?

    1 回复  |  直到 7 年前
        1
  •  3
  •   torek    7 年前

    测试钩子,特别是预接收钩子,是困难的:它们在不寻常的环境中运行。测试它们的好方法很少(主要的好方法是一两个牺牲性的存储库)。

    这里有许多相互交织的问题:

    refname="$0"
    

    无论怎样,这都是错误的,就像在shell脚本中一样, $0 指的是 脚本本身的名称 .

    current_branch=$(refname) 
    

    这也是错误的,您在编辑中删除了它:它试图运行命令 refname . 所以你换了它很好,但是:

    current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
    

    这是一个微妙的错误:如果您当前的分支被命名为 fixes/bug-123 它会凝固 current_branch bug-123 修复/错误-123

    获得 当前分行名称 refs/heads/ 零件,用途:

    current_branch=$(git symbolic-ref --short HEAD) || exit 1
    

    这个 --short 指导 git symbolic-ref 省略 参考/标题/ 部分,以及 || exit 1 指导 如果出现以下情况,则退出(具有故障状态) git符号参考 如果你有一个“超脱的头”, HEAD 一个符号ref,Git会对此抱怨 当前_分支 将设置为空字符串。

    现在,在这些问题上,你提到:

    ... 尝试将其作为预推或预接收挂钩进行测试。。。

    作为预推钩, $1 $2 oldrev newrev 标准输入 . 这一切都发生在客户端,在连接到另一个Git(远程)之后,但在发送任何内容之前。 (See the section on pre-push hooks in the githooks documentation.)

    作为预接收挂钩, $1 $2 什么都不做 (这没关系,因为你从来没有使用过变量)。这个 当前分支 将是当前分支 在远程的另一个Git中 . 预接钩,如预推钩,必须 读取其标准输入 ,一次一行,检查该行上提供的每组参数。如果钩子以非零返回退出,则拒绝整个推送(从服务器端)。

    在预推或预接收挂钩中检查引用名称时,请确保检查 全部的 引用:传入引用(在钩子中)或传出引用(在预推钩子中)可以引用标记,例如 refs/tags/v1.2 ,或名称中包含斜杠的分支,如 refs/heads/feature/tall . 不要只剪掉名字的最后一部分,也不要只剪掉前两部分而不看它们。而且,在任何一个钩子中,当前的分支名称通常都是完全不相关的:有人在运行 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
    

    例如。这些都不会成为 树枝 在目标上;只有一个是 从…起 源上的分支。

    (请注意,钩子可以用任何可以在安装了特定Git的机器上运行的语言编写。它们没有 要成为bash/sh脚本,尽管如果你有Git,你必须有一个shell,因为Git的部分是用shell编写的。始终注意硬编码路径:例如,bash可能位于 /usr/local/bin/bash 而不是 /bin/bash 在某些系统上。)