所以我已经开始使用git
一段时间并逐渐了解它是如何工作的。我理解的一个要点是 - 每次进行新提交时都会创建一个快照。当然,快照只包含已更改的文件和指向未更改文件的指针。
根据Pro Git § 1.3 Getting Started - Git Basics
每次你在Git中提交或保存项目的状态时,它基本上都会记录当时所有文件的外观,并存储对该快照的引用。为了提高效率,如果文件没有改变,Git不会再次存储文件 - 只是指向它已存储的上一个相同文件的链接。
但是,让我说我的文件很大,例如2GB文本文件。我将该文件更改10次,因此每天进行10次提交,这是否意味着 - 我现在在我的计算机上有10个2GB文件?这对我来说似乎效率低下所以我相信情况可能并非如此。
有人可以澄清在这种情况下会发生什么吗?
答案 0 :(得分:8)
简短的回答是"是的,你现在有10个2GB文件"。但是:
"文件"在提交下存储为" blob"对象和所有 git对象(blob,tree,commits和annotated-tags)以zlib放气格式保存在内部。因此,2 GB的文本文件实际上是一个相当小的对象。
"松散"对象(所有这些对象)最终都会被打包#34;您可以使用git pack-objects
和git repack
手动执行此操作,但通常您只需让git自行执行此操作,作为标准"垃圾收集的一部分" (git gc
)。在一个包中,对象是针对类似对象的三角形压缩。 大多数文件的最终结果令人印象深刻。
所有这一切,git最终会失败,如果你喂它很多大的不可压缩的二进制文件(我不得不在以前的工作场所处理这个问题,我们将2GB的.tgz文件填充到repos中)。他们不会放气,他们通常不会进行三角形压缩,最终甚至包装格式都会崩溃。相对广泛使用至少有两种解决方案:git-annex和git-bup。请参阅Managing large binary files with git。
答案 1 :(得分:3)
我刚试过它。
首先,我创建了一个大文件(24 MB文本)并提交了它。我的.git目录现在大216 KB。 git使用压缩,我的文本文件很容易压缩。
然后我在文件的第一行做了一个小改动并提交了。我的.git目录现在大356 KB。 .git / objects现在包含两个对象,都是132 KB大。
132K ./.git/objects/8d
132K ./.git/objects/f7
运行git gc
后,这两个对象被压缩成一个只有68 KB的包文件。
因此,至少在某些情况下,git会将大文件的整个副本保留一段时间。