我正在尝试为 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
与$i
。 expr
可以执行(基本)正则表达式:
expr "$match" : "${i}$" >/dev/null && return 0
将查看$match
(分支名称)是否与列表中的任何正则表达式匹配。 使用 ${i}$
的原因是expr
左锚定测试(类似于 Python 的re.match()
),但不右锚定,因此.*-dev
匹配x-devote
和x-dev
,这可能不是你的意思。 这样,您可以将hooks.foo
设置为 .*-dev
,例如(或将其包含在值列表中)。
对于外壳通配(普通/bin/sh
),请使用case
而不是test
/[
:
case "$match" in
$i) return 0;;
esac
在这里,您将hooks.foo
设置为 *-dev
,或包含 *-dev
的内容。