首页 > 解决方案 > Git 预提交挂钩以检查更改的文件数量

问题描述

我们的存储库具有根据我们更改的文件数量触发的自定义状态检查。如果单个 PR 中更改的文件数量很大,这些状态检查可以降低下游依赖关系。(在这些状态检查中有对服务的请求)。我不是在这里争论这些状态检查以及为什么它们首先存在,在这个时候我们不能改变它或扩展服务来处理这样的负载。

控制这些大更改的想法是在预提交时添加一个 git 钩子,它基本上可以获取当前分支和远程 master 尖端之间不同的文件数量。然后,如果这些文件的数量大于某个数量,我们想要出错。

基本上我要解决的方法是在 git hook 中使用以下命令


# Refresh local reference to origin/HEAD
git fetch

# Get the diff between the tip of current branch and the tip of origin/HEAD and count them
git diff --name-only --cached origin/HEAD | wc -l

... 

这似乎可行,但我有几个问题: 1. 这些方法是否有任何隐藏的陷阱?我想确保我涵盖了所有可以防止打开拉取请求的情况,其差异跨越文件数> X。 2. 在 git 挂钩中调用 git fetch 是否安全?我需要一些方法来确保本地参考原点/HEAD 不会过时,否则钩子不会失败,但如果本地主机已过时,拉取请求仍可能有非常大的差异。

标签: gitgithooks

解决方案


是的,这里隐藏的问题是该服务在开发人员机器上运行,这意味着您的 CI 系统的完整性基于开发人员安装pre-commit钩子而不是覆盖它的意愿和能力。正如之前在这里和其他地方所提到的,不可能依赖pre-commit钩子来执行策略,因为开发人员机器不受信任。

最好将它放在 CI 脚本中,如果更改数量很大,则尽早失败。您的 CI 系统是制定策略决策的正确位置,即使这些策略决策是放弃并且不运行其余的 CI 作业。或者,如果您的 Git 服务器支持pre-receive钩子,您可以在那里完成工作。

此外,pre-commit像这样的钩子使高级用户难以创建一系列逻辑提交,甚至难以创建修复提交以压缩到较旧的提交中。作为这样的用户,如果每次我想添加一些提交时都必须等待获取,我会非常--no-verify不高兴,并且我希望您的用户会删除钩子或强制使用.

话虽如此,它不会破坏pre-commit挂钩中的任何内容,尽管您会发现这样做会破坏用户对 . 的使用git push --force-with-lease,以及可能令人困惑的编辑器集成。


推荐阅读