Git挂钩拒绝文件包含特定字符串的提交

时间:2014-11-10 02:52:10

标签: git

我正在Guard使用Rspec;我使用focus: true强制它只运行我正在进行的测试。但有时我会忘记删除focus: true,这会让我未来的自我和与之合作的人分心。

我想创建一个git钩子来检查spec文件夹,以确保除focus: true之外的测试文件中没有spec/rails_helper.rb并将其保存在Repository中。

我已经阅读了这个答案Putting git hooks into repository,猜测它必须有点尴尬。

如何根据文件内容阻止提交?

更新

这是我现在拥有的但是它不起作用,即使没有匹配,git拒绝提交。

FILES_PATTERN='\.rb(\..+)?$'
FORBIDDEN="(\, focus: true|binding\.pry)"
git diff --cached --name-only | egrep "$FILES_PATTERN" | xargs egrep --with-filename -n "$FORBIDDEN" && echo "Commit reject, found $FORBIDDEN reference, please remove" && exit 1
exit 0

3 个答案:

答案 0 :(得分:7)

git-scm上有一本很好的信息来源。

你想要预提交钩子。要返回非零值(从而中止提交),您需要这些内容:

FILES_PATTERN='\.rb(\..+)?$'
FORBIDDEN='focus: true'
git diff --cached --name-only | \
  grep -spec/ | \
  grep -E $FILES_PATTERN | \
  xargs grep --with-filename -n $FORBIDDEN && echo "COMMIT REJECTED Found '$FORBIDDEN' references. Please remove them before commiting" && exit 1

这是从rather good tips site解除的。我还没有测试过我做过的调整。

答案 1 :(得分:0)

以现有答案为基础,这是我使用的支持多个字符串的版本。

#!/bin/sh

declare -a arr=("This is the first string." "This is the second string.")

for i in "${arr[@]}"
do
    git diff --cached --name-only | xargs grep --with-filename -n $i && echo "COMMIT REJECTED! Found '$i' references. Please remove them before commiting." && exit 1
done

exit 0

答案 2 :(得分:0)

服务器端Git挂钩

我想出了这个示例来说明代码格式化的用例,但是如果您仅用grep -r 'bad-thing'代替Prettier的用法,它应该也可以正常工作

ref_name=$1
new_rev=$3

# only check branches, not tags or bare commits
if [ -z $(echo $ref_name | grep "refs/heads/") ]; then
  exit 0
fi

# don't check empty branches
if [ "$(expr "${new_rev}" : '0*$')" -ne 0 ]; then
  exit 0
fi

# Checkout a copy of the branch (but also changes HEAD)
my_work_tree=$(mktemp -d -t git-work-tree.XXXXXXXX) 2>/dev/null
git --work-tree="${my_work_tree}" --git-dir="." checkout $new_rev -f >/dev/null

# Do the formatter check
echo "Checking code formatting..."
pushd ${my_work_tree} >/dev/null
prettier './**/*.{js,css,html,json,md}' --list-different
my_status=$?
popd >/dev/null

# reset HEAD to master, and cleanup
git --work-tree="${my_work_tree}" --git-dir="." checkout master -f >/dev/null
rm -rf "${my_work_tree}"

# handle error, if any
if [ "0" != "$my_status" ]; then
  echo "Please format the files listed above and re-commit."
  echo "(and don't forget your .prettierrc, if you have one)"
  exit 1
fi

对此有一些限制,所以我建议您也参考“更完整”的版本:

它的要旨...

如果要在服务器端进行操作,则将使用裸存储库(最有可能的),因此,您需要做一些额外的工作来创建一个临时位置来进行检查(如上所示) )。

基本上,这是过程:

  • 使用服务器端update挂钩(类似于pre-receive
  • 检查分支并提交
  • 将裸仓库签出到临时文件夹
  • 运行检查特定字符串(grep -r 'bad-thing' .
  • 如果存在违规文件,则退出非零值

我本来可以调整脚本来进行grep编写,但是已经晚了(或相当早),而且我不相信自己不会因为打错而打错所有文字,简单”的更改。我知道上面的方法有效(因为我已经用过了),所以我将继续讨论。

HTH(不是OP本身,而是将来的OP-也许是我自己)