1

我正在尝试向 git 的 post-recieve-email 挂钩添加一些功能,以忽略特定分支或仅在特定分支上发送电子邮件(显然这些选项将是互斥的)。我不想将分支列表硬编码到钩子本身中,而是使用存储库配置文件的 [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 的双括号方法。

4

1 回答 1

1

这更像是一个 shell 问题而不是 git 问题,但我已经写了这样的东西。这是功能:

# 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来做到这一点。

请注意,最新最好的 post-receive-email 挂钩现在是 Python 脚本而不是 shell 脚本。


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

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

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

对于 shell globbing(普通/bin/sh),使用case代替test/ [

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

在这里,您将设置hooks.foo*-dev,或包括*-dev.

于 2013-09-18T18:48:31.670 回答