我在项目中有几个 .json 文件,其中包含多个键(key)。这些键不应该被版本控制所记录。为了避免在持续集成过程中出现构建失败的情况,我用虚假的键替换了这些实际键。
然而,开发人员需要在测试应用程序之前将这些文件复制/粘贴到他们的笔记本电脑上。
现在的问题是,开发人员可能会忘记并错误地将它们提交到 git 中。我想运行一个 pre-commit
脚本,检查修改后的文件,并在其中添加一个文件时取消提交操作。
有没有办法可以做到这一点呢?
通过使用 pre-commit
钩子,在开发者端防止此类问题的出现。请注意,git commit --no-verify
将绕过此安全机制。
下面的代码会禁止对文件 dir/key1.json
和 key2.json
进行任何更改。
#!/bin/sh
# full paths from the repo root separated by newlines
MUST_NOT_CHANGE='dir/key1.json
key2.json'
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
exec 1>&2
if git diff --cached --name-only $against |
grep --quiet --line-regexp --fixed-strings "$MUST_NOT_CHANGE"
then
echo Commit would modify one or more files that must not change.
exit 1
else
exit 0
fi
pre-receive
钩子必须安装在你的中央仓库上,它会拒绝任何试图修改受保护文件的推送。#!/bin/sh
# full paths from the repo root separated by newlines
MUST_NOT_CHANGE='dir/key1.json
key2.json'
z40=0000000000000000000000000000000000000000
while read old_value new_value ref_name
do
if [ "$old_value" = $z40 ]; then
# New branch: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
else
against=$old_value
fi
if git diff --name-only $against..$new_value |
grep --quiet --line-regexp --fixed-strings "$MUST_NOT_CHANGE"
then
echo "$ref_name" may commit key, rejected ... >&2
exit 1
fi
done
实际应用中:
$ git push origin master
Counting objects: 10, done.
Delta compression using up to 40 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (10/10), 820 bytes | 410.00 KiB/s, done.
Total 10 (delta 1), reused 0 (delta 0)
remote: refs/heads/master may commit key, rejected ...
To '<URL>'
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to '<URL>'
FILES_PATTERN='<regexp_to_match_file_names>'
if git diff --cached --name-only | grep -qE $FILES_PATTERN; then
exit 1;
else
exit 0;
fi
!git diff --cached --name-only | grep -qE $FILES_PATTERN
将git diff
检查压缩成一行。 - ahong
against
和第二个块中的z40
是什么?应该硬编码还是以某种方式检索? - Hesamagainst
处理分支尚不存在的情况,但git diff
需要 某些东西 以进行差异比较。pre-receive
的 githooks 文档解释了由四十个零组成的虚拟 SHA1 表示该引用尚不存在。 - Greg Bacon