简体   繁体   English

Git预提交挂钩:防止更改特定文件的提交

[英]Git pre-commit hook: Prevent commits that change particular files

I have a few .json files under my project that contain several keys. 我的项目下有几个.json文件,其中包含多个键。 These keys must not be under version control. 这些密钥不得受版本控制。 I replaced those actual keys with fake ones in my project in order to prevent build fails on continuous integration. 为了防止在持续集成中构建失败,我在项目中将这些实际密钥替换为伪密钥。

However, developers need to copy/paste these files on their laptop before they are able to test the app. 但是,开发人员需要先在笔记本电脑上复制/粘贴这些文件,然后才能测试该应用程序。

Now, the problem is a developer might forget and mistakenly commit them into git. 现在,问题是开发人员可能会忘记并将它们错误地提交到git中。 I want to run a pre-commit script that checks modified files and fails the commit if one of them is being added. 我想运行一个pre-commit脚本,该脚本检查修改后的文件,如果添加了其中一个,则提交失败。

Is there any way I can do that? 有什么办法可以做到吗?

You can do something like this in pre-commit hook: 您可以在预提交挂钩中执行以下操作:

FILES_PATTERN='<regexp_to_match_file_names>'
if git diff --cached --name-only | grep -qE $FILES_PATTERN; then
    exit 1;
else
    exit 0;
fi

The idea is based on these references: 该想法基于以下参考:

Beware that I did not test this. 请注意,我没有对此进行测试。

Prevent it on the developer side with a pre-commit hook. 使用pre-commit挂钩防止它在显影剂侧pre-commit Note that git commit --no-verify will bypass this safety mechanism. 请注意, git commit --no-verify将绕过此安全机制。

The code below blocks any changes at all to files dir/key1.json and key2.json . 以下代码完全阻止了对文件dir/key1.jsonkey2.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

The pre-receive hook below that must be installed on your central repository rejects any push that would modify the protected files. 必须在中央存储库中安装的以下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

In action: 实际上:

$ 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>'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM