如何在 Git 远程存储库上触发垃圾回收?

问题描述 投票:0回答:4

众所周知,我们可以定期运行

git gc
来打包
.git/objects
下的对象。

在远程中央 Git 存储库(裸露或非裸露)的情况下,经过多次推送后,

myproj.git/objects
下有很多文件;每次提交似乎都会在那里创建一个新文件。

如何打包这么多文件? (我的意思是远程中央裸存储库上的那些,而不是本地克隆存储库上的。)

git repository git-gc
4个回答
53
投票

远程存储库应配置为在提交后根据需要运行 gc。请参阅

gc.auto
git-gc
手册页中的
git-config
文档。

但是,远程存储库不需要那么多垃圾收集,因为它很少有悬空(无法访问)提交。这些通常是由分支删除和变基之类的事情造成的,这些通常只发生在本地存储库中。

所以需要更多的gc进行重新打包,这是为了节省存储空间而不是清除实际的垃圾。

gc.auto
变量足以解决这个问题。


2024 年更新:

GitHub 存储库中的垃圾现在很常见,因为典型的 PR 工作流程涉及大量的强制推送和变基。

但是,无论是否在 GitHub 上,您都无法影响远程存储库中的 GC。仅当您对托管存储库的远程系统具有 shell 访问权限时,才可以执行此操作。换句话说,垃圾收集必须是存储库所在计算机上的本地操作。

GitHub确实做了GC,但它是在无形中发生的。有时,如果不遵循最佳实践,就会产生不幸且令人惊讶的后果。例如,可以在另一个项目中基于源的依赖项中引用 PR 的提交哈希,同时等待 PR 被上游接受。如果该 PR 分支随后被重新设置基础,源依赖项将继续工作一段时间,因为如果已知其哈希值,仍然可以获取悬空提交。

但是,当 GH 确实在存储库上执行 GC 时,另一个项目的构建将突然因“缺少引用”错误而中断,因为依赖项的存储库中不再存在提交。这可能非常令人困惑,尤其是当设置源依赖项的人不再存在时。更重要的是,弄清楚丢失的哈希最初指的是什么可能非常困难,因为它不再是任何分支的一部分。

如果你很幸运,提交仍然存在于尚未被垃圾收集的存储库的某人克隆中,并且引用日志可用于找出提交最初位于哪个分支。然后源依赖关系可以可以更新为使用 PR 的重新基版本,或者如果 PR 现已合并,则可以完全删除。

这个故事的寓意:在 PR 中提及提交时要非常小心。它们不稳定,可能会在没有警告的情况下消失。


15
投票

虽然你应该有一些进程来定期、自动地处理这个问题,但运行是没有问题的

git gc

在裸存储库上

git@domU:/pix/git/repositories/abd.git$ ls -l

total 28
drwxrwxr-x   2 git git    6 2010-06-06 02:44 branches
-rw-rw-r--   1 git git   66 2010-06-06 02:44 config
-rw-r--r--   1 git git   23 2011-03-15 18:19 description
-rw-rw-r--   1 git git   23 2010-06-06 02:44 HEAD
drwxrwxr-x   2 git git 4096 2010-06-06 02:44 hooks
drwxrwxr-x   2 git git   20 2010-06-06 02:44 info
drwxrwxr-x 260 git git 8192 2010-09-01 00:26 objects
drwxrwxr-x   4 git git   29 2010-06-06 02:44 refs

$ git gc
Counting objects: 3833, done.
Compressing objects:  31% (1085/3500)...

6
投票

多次推送后,

myproj.git/objects

下有很多文件

git 2.11+(2016 年第 4 季度)和预接收挂钩不会有那么多。
在这种情况下,您根本不必触发

git gc

请参阅 commit 62fe0ebcommit e34c2e0commit 722ff7fcommit 2564d99commit 526f108(2016 年 10 月 3 日),作者:Jeff King (

peff
)
(由 Junio C Hamano --
gitster
--
合并于 commit 25ab004,2016 年 10 月 17 日)

receive-pack
:隔离对象直至预接收接受

为了让“git Push”的接收端检查接收到的历史记录并决定拒绝推送,从发送端发送的对象需要可供钩子和连接检查机制使用,这是传统上通过将对象存储在接收存储库中并让“

git gc
”使其过期来完成。

相反,将新接收到的对象存储在临时区域中,并仅在我们执行操作时重用备用对象存储机制来使它们可用。 决定我们是否接受检查,一旦我们决定,要么将它们迁移到存储库,要么立即清除它们。

该临时区域将由新的环境变量设置

GIT_QUARANTINE_ENVIRONMENT

这样,如果(大)推送被

pre-receive
钩子拒绝,这些大对象就不会闲置 90 天等待
git gc
清理它们。


2
投票

这个问题应该能让您了解应该多久运行一次垃圾收集。

最简单的选择是使用 Windows 中的计划任务或 Unix 中的 cron 作业来定期运行

git gc
。这样你就不需要考虑了。

© www.soinside.com 2019 - 2024. All rights reserved.