Git 预提交客户端挂钩。通过强制强制添加文件

Git pre-commit client-side hook. Enforce adding file via force

我们在 git 中有一个文件,它很大,大约 1GB。但是,此文件是在引擎内生成的,需要数小时的完整使用 CPU 才能生成。因此,我们希望将其推至 git 并对其进行维护。但是,不需要经常推送它。事实上,除非我们正在构建分发,否则我们几乎不想推送此文件。

现在有几次,有人不小心将此文件推送上来,它使用了大量的 LFS 带宽和存储空间。我希望能够添加一个 git 预提交挂钩,以确保该文件被强制添加到提交中,或者只是通过某种方式来仔细检查文件的添加。

我从来没有制作过挂钩脚本,有什么方法可以使用预提交挂钩来实现此功能?我正在努力寻找有关创建这些脚本以及我可以访问哪些属性的常规文档。另外,如果有更简单的方法来完成我想要的,那将不胜感激!

你不能用 pre-commit 钩子真正做到这一点。请记住,每个 Git 提交包含每个文件(它包含),以及一个git checkoutgit switch 操作首先使用散列 H 提取一些提交 删除 当前在 Git 的索引和您的工作树中的任何文件,因为您当前 check-out 的提交 G(除 H 之外的其他哈希 ID),其中确实存在某些文件,而提交 H.

中不存在该文件

因此,大文件要么在每个 提交中,要么在没有 提交中:没有真正的中间立场。 Git 确实通过 re-using identical-content 文件来优化事情,所以如果 100 次提交包含大文件的版本 1,而接下来的 100 次提交包含大文件的版本 2,那么有存储库中的大文件实际上只有两个副本,每个副本在 100 次提交中共享。

A git push 发送一个新的提交,re-uses 现有的大文件不会 re-send 大文件,因为接收 Git 会宣布它当您的 Git 发送新提交 N 时,已有提交 E,然后您的 Git 将看到 large-file 副本 NE 中的 large-file 副本相匹配,因此不需要使用新提交 N 发送文件。所以听起来你真正想要的是——虽然你没有意识到——是一种检测git push是否会发送新的和不同的大文件的方法,接收 Git 当前缺少。

你无法完美地检测到这个,但你可以在 pre-push 钩子中轻松地找到它(而不是 pre-commit 钩子)。 Git 在您的 Git 联系他们的 Git 后运行 pre-push 挂钩,并找出什么哈希 ID 与他们拥有的您要求他们更新的任何现有参考相匹配。 pre-push 挂钩可以从其标准输入中读取您的 Git 提议发送给他们的 Git 的参考和哈希 ID 的完整列表,以及它们在下面的哈希 ID无论您的 Git 提议他们更新什么名称。

使用此信息,您可以看到,例如,您的 Git 提议将可从您的分支提示 develop 访问的提交发送给他们的 Git哈希 ID a123456...。此时,作为他们他们develop的分支提示,他们有一个哈希ID为b976543...的提交。在您自己的存储库中查找此提交,您会发现 b976543 确实包含大文件,其内容的哈希 ID 为 deadcab...,并且您自己的 b976543..a1234567 中的所有提交的内容存储库,它们都包含具有相同哈希 ID 的大文件:在这种情况下,您不会发送大文件的新副本。或者,也许您 没有 b976543,或者 b976543 有一个大文件,其中 deadcab... 作为其 blob 散列但 a123456...将发送内容散列到 feeddad... 的大文件。所以这次你的Git可能发送大文件,你可以强制用户,例如,设置一个环境变量I_REALLY_MEANT_TO_DO_THAT=yes

整个系统非常笨拙,据我所知,没有人这样做过。相反,大文件被视为“构建资产”并存储 存储库外部 ,连同告诉您构建资产的这个特定副本是否适合您的构建的信息。您首先检查验证信息:如果正确,则使用 pre-built 资产,如果不正确,则花时间构建它(然后也可以选择将其交付到资产服务器)。