如何为 git 钩子创建黑名单或分支列表



我正在尝试为 git 的接收后电子邮件钩子添加一些功能,以忽略特定分支或仅在特定分支上发送电子邮件(显然这些选项将是互斥的)。 我不想将分支列表硬编码到钩子本身中,而是使用存储库配置文件的 [hooks] 部分。

我正在努力保持 shell bourne shell 兼容,同时仍然能够查看分支名称是否属于白名单或黑名单的一部分。

我认为我可以做这样的事情:

whitelist=$(git hooks.branch_whitelist)
while read oldrev newrev refname
do
  branch_name=${refname#refs/heads/}
  for wl_branch in $whitelist
  do
    if [ $branch_name = $wl_branch ] 
      ... send email ...
      break # prevents multiple emails on malformed whitelist string
  done
done

出于某种原因,上述内容似乎都是错误的。 有没有人有更好的方法来检查字符串是否是列表的成员(如果我理解正确,不是 bourne 中支持的数据结构)?

编辑:能够进行部分字符串匹配(例如将所有 -dev 分支列入黑名单)也很好,但我一遍又一遍地找到的唯一答案是 bash 的双括号方法。

这与其说是 git 问题,不如说是一个 shell 问题,但我已经写了这样的东西。 函数如下:

# Is $1 in a list?
in_list()
{
        local match i
        match="$1"
        shift
        set -- $(echo "$@" | sed 's/,/ /g')
        for i do
                [ "$i" = "$match" ] && return 0 # i.e., "true"
        done
        return 1 # i.e., "false"
}

以及使用它的示例:

if in_list $branch_name $(git config --get hooks.foo); then ...

列表的形式是空格和/或逗号分隔的条目:

git config hooks.foo eh,bee,sea,de,e

或:

git config hooks.foo 'eh bee sea de e'

(或两者的任意混合)。

如果你想支持某种正则表达式或 shell 通配,应该很明显1 如何修改in_list来做到这一点。

请注意,最新和最好的后接收电子邮件钩子现在是 Python 脚本而不是 shell 脚本。


1如果毕竟不明显:[实际上是一个命令(也拼写为 test ),因此您可以运行任何命令来比较$match$iexpr可以执行(基本)正则表达式:

expr "$match" : "${i}$" >/dev/null && return 0

将查看$match(分支名称)是否与列表中的任何正则表达式匹配。 使用 ${i}$ 的原因是expr左锚定测试(类似于 Python 的re.match()),但不右锚定,因此.*-dev匹配x-devotex-dev,这可能不是你的意思。 这样,您可以将hooks.foo设置为 .*-dev ,例如(或将其包含在值列表中)。

对于外壳通配(普通/bin/sh),请使用case而不是test/[

case "$match" in
$i) return 0;;
esac

在这里,您将hooks.foo设置为 *-dev ,或包含 *-dev 的内容。

最新更新