“自动打包存储库以获得最佳性能”是什么意思?

291

我在使用git仓库时遇到了问题。最近几天,每当我向服务器进行推送时都会出现以下信息:“为了获得最佳性能而自动压缩仓库”,并且似乎无法消失并返回shell。

我还尝试切换到新分支,然后对以前的分支进行变基,再使用 git gc 命令删除未使用的历史记录对象,但仍然出现上述信息。请告诉我我的仓库发生了什么问题。


git config gc.autoDetach 将禁用此行为。 - Bachsau
5个回答

375
简要版:它的意思就是它所说的,如果你让它完成,一切都会好起来。
在大多数可能会增加存储库中松散(未打包)对象数量的操作期间(包括推送),Git 会调用git gc --auto。如果有足够的松散对象(默认情况下至少为6700个),然后它将调用git repack -d -l来打包它们。如果有太多单独的 pack,则还会将它们重新打包成一个 Pack。
Pack 是包含大量对象的增量压缩单个文件。将对象存储在 Pack 中更有效率,但打包(压缩)对象需要时间,因此 Git 最初创建松散对象,然后通过自动调用 git gc --auto 定期打包它们。 如果你让 Git 完成重新打包,则一段时间内不会再次发生。 这确实需要一些时间,特别是如果你有很多大型二进制对象,但如果它触发了,那么它很可能会显着减少存储库占用的磁盘空间。如果你真的不想让它发生,可以更改配置参数gc.auto。如果你将其增加到远远大于6700的值,它将更不频繁地发生,但当它发生时需要更长时间。如果你将其减少,则仍然必须完成当前的重新打包,但随后会更频繁地发生并更快地完成。如果你将其设置为 0,则会禁用自动重新打包。
有关更多信息,请参见man git-gc(在--auto下)和man git-config(在gc.auto下)。

24
确实,这对我来说大约花了5分钟的时间,但最终完成了。非常棒的回答。 - Joshua Pinter
8
我们看到每一次的推送都会发生这种情况(让一个while循环变成几秒钟,呵呵)。 - user153275
3
在正常情况下不应该发生这种情况 - 一次推送中的对象数量不应该足以触发它(除非您的存储库非常大并且/或者您正在推送大量提交),因此一旦它成功完成(您确保它已经成功完成了,对吗?),它就不应该再次发生,直到再次达到极限。如果您无法解决问题,请提出单独的问题。 - Cascabel
8
如果你让Git完成,它就能把代码提交。但是如果出现“致命错误:内存不足,分配79610689字节失败”的提示,这意味着你试图把整个代码库放入一个Git仓库里。我猜我得关闭应用程序,手动强制重新打包。 - ruffin
12
每次执行git pull时都会遇到这个问题,我已经手动执行了git gc,但是每次pull仍然会出现这个问题。很奇怪。 - Barry Kelly
显示剩余9条评论

93

虽然Jefroni是对的,有时候自动打包只需要时间完成,但是如果像OP描述的那样自动打包消息在多个日子里持续存在,git清理掉悬空对象的功能可能失效了,正如这个问题所描述的。

为了查看悬空对象是否触发了关于自动打包正在进行的持续消息,请尝试运行git fsck。如果您得到了一个长列表的悬空提交,可以使用以下命令进行清理:

git gc --prune=now

当自动打包消息在单次拉取后未消失时,我通常需要每2-3个月在我的存储库上运行此命令。


14
虽然不是官方答案,但这正是我所需要的。在几天内每次执行 git pull 时都会收到提示信息,而 fsck 确实显示了大量的悬空提交。 - Jörn Zaefferer
2
引用一句经典台词:“这就是方法”。 - dkellner
4
提醒一下 - 如果要运行 git gc --prune=now,请确保所有的IDE、Git bash和Git UI程序都已关闭。否则,它将无法工作,因为资源/文件被“锁定”。我曾经因为忘记关闭我的GitKraken工具而遇到过这种情况。 - Han K

44

禁用一个项目:

cd your_project_dir
git config gc.auto 0

要全局禁用:

git config --global gc.auto 0

2
我想我找到了方法:进入.git文件夹,打开config文件,删除文本“auto = 0”,然后保存。这似乎重新启用了自动打包。 - Adrian Keister
19
git config --unset gc.auto 的意思是取消 git 的自动垃圾回收设置。 - jtatum

11

Git正在运行git-repack命令,将许多对象(即文件、提交和树)打包成一个包文件。Git有时会这样做,当启发式算法指出可能节省空间时(一个包文件包含压缩的对象增量,而objects / 目录中的每个文件都包含压缩的完整文件内容)。


2
希望现在(git 2.0.1,2014年6月25日),git gc --auto 步骤更加高效。
请参见由Nguyễn Thái Ngọc Duy (pclouds)提交的提交 62aad18

gc --auto: 不要在后台锁定引用

9f673f9 (gc: 在配置选项中运行--auto以减少用户等待时间-2014年2月8日,Git 2.0.0) 将 "gc --auto" 放在后台以减少用户的等待时间。
垃圾回收的一部分是打包引用和修剪 reflog。这些需要锁定某些引用,并可能会中止尝试锁定相同引用的其他进程。

如果在脚本的中间触发 gc --auto,则 gc 在后台持有锁可能会导致脚本失败,这在之前是不可能发生的。9f673f9

继续在前台运行pack-refs和"reflog --prune"以停止并行引用更新。剩下的后台操作(重新打包、修剪和rerere)不应影响正在运行的git进程。

Git 2.22(2019年第二季度)进一步优化了git gc


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