跟踪大型二进制文件时,git非常慢


83

我的项目已经六个月大了,而git非常慢。我们跟踪大约30个文件,大小为5 MB到50 MB。这些是二进制文件,我们将其保存在git中。我相信这些文件会使git变慢。

有没有办法杀死存储库中所有大小> 5MB的文件。我知道我会丢失所有这些文件,我也可以。

理想情况下,我想要一个列出所有大文件(> 5MB)的命令。我可以看到列表,然后说可以,删除这些文件并使git更快。

我应该提到git不仅在我的机器上运行缓慢,而且在暂存环境中部署该应用程序大约需要3个小时。

因此,修复程序应该会影响服务器,而不仅影响存储库的用户。


4
您可以尝试使用git-bigfiles项目中的git
JakubNarębski10年

1
您可能想尝试使用git-annex之类的方法来管理二进制文件。git-annex.branchable.com
Jed Schneider

万一它对任何人都有用,让我补充一下,我的Cygwin版本的git挂在了rebase上。当我使用Git-Bash时,同一存储库没有问题。
Sridhar Sarnobat 2014年

我不知道情况是否仍然如此。我希望他们在压缩效果低于50%(或任何其他可选的X%)的情况下关闭压缩功能。在某些时候,速度显然超过了硬件空间!
Trilarion

Answers:


125

你有垃圾吗?

git gc

即使对于小型仓库,这也会在速度上产生重大差异。


8
当杂乱无章时,此操作会自动完成。我怀疑这是否会对OP有所帮助。
卡斯卡贝尔

@Jefromi,这是新的吗?昨天我刚刚升级到1.7.1,但是在此之前,我所使用的版本肯定不会自动运行gc
kubi

@kubi:嗯,它并没有永远存在,但是它并不是全新的-从caf9de2(2007年9月14日)或稳定版本v1.5.4(2008年2月1日)开始,它是通过commit,merge,am和rebase调用的。 )。
卡斯卡贝尔

1
再三考虑,git gc不可能调用commitmerge,否则git fsck --unreachable永远不会返回任何东西。
kubi 2010年

4
找到了。自动gc运行之前,默认的松散对象数为6700,这说明了为什么我从未见过这种情况。
kubi 2010年

79

说明

Git非常擅长处理小型文本文件,因为它可以有效地存储它们及其更改。同时,git对于二进制文件非常不利,并且会天真的存储文件的单独副本(至少默认情况下)。正如您所观察到的,存储库变得巨大,然后又变慢。

这是DVCS中的一个常见问题,每次克隆时您都会下载每个文件的每个版本(“整个存储库”),这一事实使情况更加恶化。Kiln的家伙正在开发一个插件,以将这些大文件更像Subversion,后者仅按需下载历史版本。

该命令将列出当前目录下所有文件,文件大小> = 5MB。

find . -size +5000000c 2>/dev/null -exec ls -l {} \;

如果要从存储库的整个历史记录中删除文件,则可以将此想法与git filter-branch历史记录一起使用,并摆脱大文件的所有痕迹。完成此操作后,存储库的所有新克隆都将变得更精简。如果要精简存储库而不进行克隆,请在手册页上找到说明(请参见“收缩存储库清单”)。

git filter-branch --index-filter \
    'find . -size +5000000c 2>/dev/null -exec git rm --cached --ignore-unmatch {} \;'

警告:这将使您的存储库与其他克隆不兼容,因为树和索引已签入不同的文件;您将无法再从中推拉。


4
注意:这是find的Unix / Linux版本,而不是Windows的find.exe。
Craig Trader

1
+1。可能想find先将输出发送到文件,检查列表,然后使用git rm,以防万一有任何误点击。或者,git status在删除大文件后进行检查,并用于git checkout HEAD <file>找回所有错误删除的文件。
卡斯卡贝尔

2
我认为您对git“默认情况下会存储单独的副本”的评论是对的。根据您链接到的电子邮件链(thread.gmane.org/gmane.comp.version-control.git/146957/…),默认情况下,git尝试对二进制文件进行比较-这就是造成此问题的原因;不是存储。
亚历山大·伯德

16

这是经过审查的修订版,旨在减少负面影响和煽动性:

对于不是逐行文本文件的文件,Git有一个众所周知的弱点。目前还没有解决方案,核心git团队也没有宣布解决此问题的计划。如果您的项目很小(例如100 MB左右),则有解决方法。git项目存在分支来解决此可伸缩性问题,但是这些分支目前尚不成熟。其他一些版本控制系统没有此特定问题。在决定是否选择git作为版本控制系统时,应该将这个问题视为众多因素之一。


8
“ Git有一个众所周知的弱点...”-需要引用
2014年

6
我知道。谁需要报价时才知道其实际的常识。只是不要将git用于二进制文件。使用perforce或专门的资产管理。
v.oddou 2014年

1
@ v.oddou好吧,“我知道”和“它的实际常识”之间是有区别的。事实是,并不是每个人都知道这一点,甚至可能不是完全正确的。因此,任何形式的引用都会改善此答案。没关系,但是肯定不是很出色,并且需要备份。
Trilarion 2015年

2
好吧,不是增加麻烦,但是如果您在Google中搜索“ git和二进制文件速度较慢”,则会发现许多链接,这些链接报告用户在git中管理二进制文件时遇到问题。另外,使用一种或另一种SCM的开发人员都知道每种系统的优缺点...因此,当将二进制文件放入存储库时,git的名声变得非常慢。
AhiyaHiya

在我使用过的所有介绍性资源中,git对于二进制文件是不好的。git-annex可以解决此问题。git很棒,但不适用于二进制数据。链接到添加二进制功能的fork会很好,这样人们就可以支持这项工作。
FuzzyTew

15

关于二进制文件和git处理它们的方式没有任何具体说明。将文件添加到git存储库时,将添加标头,并使用zlib压缩文件,并在SHA1哈希之后重命名。无论文件类型如何,这都是完全相同的。zlib压缩中没有任何内容使二进制文件有问题。

但是在某些时候(pushing,gc),Git开始考虑增量压缩内容的可能性。如果git找到相似的文件(文件名等),则将它们放在RAM中并开始将它们压缩在一起。如果您有100个文件,并且每个文件都说50Mb,它将尝试同时在内存中放入5GB。为此,您必须添加更多内容才能使工作正常。您的计算机可能没有此数量的RAM,并且它开始交换。该过程需要时间。

您可以限制增量压缩的深度,以使该进程不使用那么多的内存,但结果是压缩效率较低。(core.bigFileThreshold,delta属性,pack.window,pack.depth,pack.windowMemory等)

因此,有很多想法可以使git在大型文件中很好地工作。


4
请参阅此处以获取有关如何禁用这些“增量”尝试的说明。
亚历山大·伯德

6

一种加快速度的方法是使用该--depth 1标志。有关详细信息,请参见手册页。我不是一个很棒的git大师,但我相信这相当于ap4 get或an svn get,即它只给您提供最新文件,而不是“一直给我所有文件的所有修订”是什么git clone呢。


1
这不允许您从存储库中推送,因此用途有限。
马丁C.马丁

4

您是否告诉git这些文件是二进制文件?

例如,添加*.ext binary到您存储库的.gitattributes


我假设告诉git文件是二进制文件可以加快速度。
尼克·范德比尔特

如果git的启发式方法无法自动识别文件为二进制文件,则可能会出现这种情况。
sml 2010年


2

自2008年以来,我一直在Windows和GNU / linux上运行Git,我跟踪的大多数文件都是二进制文件。我的一些存储库有几个GB,其中包含Jpeg和其他媒体。我在家中和工作中都有许多运行Git的计算机。

我从未有过原始帖子所描述的症状。但是就在几周前,我在旧的Win-XP笔记本电脑上安装了MsysGit,几乎我所做的一切都使git停顿了下来。甚至只用两个或三个小文本文件进行测试的速度也非常慢。我们正在谈论10分钟以内添加小于1k的文件...看来git进程永远都活着。其他一切都在这台计算机上按预期工作。
我从最新版本降级到1.6时,问题消失了……
我有其他相同品牌的笔记本电脑,并且同一IT部门安装了Win-XP,形成了相同的映像,无论版本如何,Git都可以正常工作。 ..所以那台特定的计算机肯定有些奇怪。

我还对二进制文件和压缩进行了一些测试。如果您有一个BMP图片,并且对其进行了很小的更改并提交,则git gc将很好地压缩。因此,我的结论是,压缩不取决于文件是否为二进制文件。


-2

只需将文件设置为忽略即可。请参阅下面的链接:

http://help.github.com/git-ignore/


@Jefromi实际上,如果您查看我发布的链接,您会发现第二段中有说明告诉他在这种情况下的确切操作。
joshlrogers 2010年

14
真正。但是,答案的直接内容是“忽略文件”,而不是“从跟踪中删除文件然后忽略它们”。通常,在此处编写它比链接到另一个站点更好。
卡斯卡贝尔

-24

那是因为git无法扩展。

这是git倡导者淹没的git中的严重限制。搜索git邮件列表,您会发现数百名用户想知道为什么仅仅100 MB的图像(例如,用于网站或应用程序)就使git屈服。问题似乎在于,几乎所有的git都依赖于它们称为“打包”的优化。不幸的是,除了最小的文本文件(即源代码)以外,所有其他文件的打包效率都不高。更糟糕的是,随着历史的增长,它的效率越来越低。

这确实是git中一个令人尴尬的缺陷,被吹捧为“快速”(尽管缺乏证据),而git开发人员也很清楚。他们为什么不解决呢?您会在git邮件列表中找到来自git开发人员的回复,这些开发人员由于他们的Photoshop文档(* .psd)是专有格式而无法识别问题。是的,真的很糟糕。

结果如下:

将git用于您不希望为其建立单独的存储库的微型,仅源代码的项目。或对于小型源代码项目,您想利用git的分散式开发的“整个副本库”模型。或者,当您只是想学习一种新工具时。所有这些都是使用git的充分理由,学习新工具总是很有趣。

如果您有大量的代码库,二进制文件,庞大的历史记录等,请不要使用git。我们的存储库之一就是TB。Git无法处理。VSS,CVS和SVN可以很好地处理它。(不过,SVN膨胀了。)

另外,给git时间使其成熟。它仍然不成熟,但是势头很大。随着时间的推移,我认为Linus的实用性将克服OSS的纯粹主义者,而git最终将在更大的领域中可用。


15
这个答案确实过于消极和煽动性。是的,git二进制文件存在可伸缩性问题。它具有很好的可扩展性,并且可以快速实现代码。有足够的速度证明(尽管您的说法相反),甚至无视CVS / SVN需要网络访问而不是许多操作都需要磁盘访问这一事实。有很多使用git进行历史记录非常愉快的大型项目。
卡斯卡贝尔

8
还有...您在Photoshop上的表现如何?我不会浪费时间写详细的答复,但是如果阅读了整个线程,thread.gmane.org / gmane.comp.version-control.git / 146957 /…(也许您会因为约翰我是线程吗?),我看到了很多合理的回答,说明如何最好地使用当前git处理此问题,将来如何解决以及为什么它不是他们的首要任务。
卡斯卡贝尔

14
是的,我不认为您是对的。对于Linux内核,Git的工作方式太好了,不值得放弃,“不可扩展”。
Andres Jaan Tack

1
如果此评论具有链接或数据来备份,则将更可信。顺便说一句,您如何看待水银?
vy32 2010年

3
也许他没有表达民意,但我认为他的否定投票比OP的Answer更过分。我们应该鼓励持不同政见者,而不是仅仅因为有人不喜欢当年的版本控制风格而鼓励。GIT确实不适合跟踪二进制文件。但是它对于源代码非常有用,这是主要目的,这就是为什么它在linux内核中表现出色。
dyasta,2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.