如何保护免受在git中推送大型二进制文件的影响?

6
我有一个中央git仓库,我和几个协作者经常从中推送和拉取。过去我不小心提交了一个大的二进制blob,需要变基才能完全删除,这对每个人来说都很麻烦,所以我想防止将来出现这种情况。是否可以在远程存储库中设置钩子,检查正在推送的文件大小(无论是新增文件还是更新现有文件),并拒绝超过阈值大小(比如2MB)的文件推送?
重要的是,我希望已经大于2MB但未更改的现有文件仍能被容忍(因此,如果仓库中已经存在一个2MB的文件,推送不应该被拒绝,只有当推送添加一个2MB的文件或将现有文件增加到2MB时才会被拒绝)。此外,我希望钩子在远程端执行,这样我不必担心客户端是否需要设置钩子。
编辑:由于一个推送可以包含多个提交,即使只有一个包含大文件的提交也会把它卡在仓库里,所以我想防止包含/任何提交/的推送增加或扩展一个>=2MB的文件。
1个回答

5
看起来pre-receive hook是进行此检查的正确位置。此钩子在推送的服务器端执行,并且具有足够的信息可供您实现文件大小检查。

此钩子由远程存储库上的git-receive-pack调用,当本地存储库上执行git push时会发生这种情况。在开始更新远程存储库上的引用之前,将调用pre-receive hook。它的退出状态确定更新的成功或失败。


pre-receive钩子发生在“更新引用”之前,这是否意味着它足够早,如果我有一个非零退出,则存储库的大小不会增加,或者仅仅是不应用提交,使得blob仍然存在以供克隆?我认为我读到了后者,但我找不到链接了 :/ - Joseph Garvin
如果您未能通过预提交钩子,那么该 blob 仍将存在于服务器上,但这并不意味着它会被自动克隆。它将无法从服务器的任何引用中访问,因此 Git 将基本忽略它。最终,Git 的垃圾回收将删除未引用的 blob。 - Greg Hewgill
你知道如何确定push的大小吗?这会让答案更完整。我有一个pre-receive脚本从stdin读取行,并且可以找到与objects/$FIRST_OBJECT_CHAR$SECOND_OBJECT_CHAR/$REST_OF_CHARS中的对象相关联的文件,但我不确定是否可以只使用较新对象的文件大小或其他什么方法。 - Joseph Garvin
似乎可以使用“git cat-file -p”命令来获取oldref和newref sha哈希值的树哈希值,然后在树哈希值上执行相同操作以获取blob哈希值,最后在blob哈希值上执行“git cat-file -s”命令来获取它们的大小。但是我仍在研究如何处理多个提交和文件... - Joseph Garvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接