为了避免错误合并,我为git钩子制作了这个bash脚本。
在工作中,我们使用git-extension并预填充分支名称,如果您忘记为分支名称加上refs / for或refs / drafts前缀,那么您的提交将绕过代码审查在远程仓库中合并。
这只会发生在拥有合并权的人身上。但是有时候拥有合并权的人会犯这个错误。
#!/bin/sh
if [[ `grep 'refs/for'` ]]; then
echo "push to refs/for/ authorized"
elif [[ `grep 'refs/drafts/'` ]]; then
echo "push to refs/drafts/ authorized"
else
echo "PUSH DENIED, MERGE DETECTED, please merge using gerrit 'submit' button only"
exit 1
fi
如果我按refs/for/v1.1.x
,它将得到push to refs/for/ authorized
但是如果我按refs/drafts/v1.1.x
,我会得到PUSH DENIED, MERGE DETECTED, please merge using gerrit 'submit' button only
这怎么可能,条件语法完全相同。
谢谢。
答案 0 :(得分:1)
与Anthony Sottile commented一样,您的第一个grep命令读取所有输入,并检查refs/for
。您的第二个grep
读取其余的输入;自您的第一个读取输入的 all 以来,没有剩下的。因此,第二个从没找到任何东西。
您可以用许多不同的方式来处理。一种是将stdin复制到可以重复读取的临时文件中。另一个方法是构造挂钩,以便您仅读取一次输入,并针对每种情况检查每一行。第二种方法显然更有效,尽管这种“显而易见性”只是一种幻想,具体取决于我在这里不打算讨论的细节。
无论如何,我的写法是:
#! /bin/sh
summary_status=0 # assume all OK initially
while read lref lhash rref rhash; do
case $rref in
refs/for/*|refs/draft/*) echo "push to $rref ok";;
*) echo "push to $rref not ok"; summary_status=1;;
esac
done
exit $summary_status
此变体不需要bash功能(因此/bin/sh
行中的/bin/bash
而不是#!
);如果将其更改为可更改的名称,请确保更改#!
行。它只读取一次输入。它还会验证您没有运行,例如:
git push remote master:refs/for/master develop
您现有的脚本所允许的(因为一个可以,而另一个不能)。