2012-02-21 103 views
22

当我通过我的Git存储库运行git gcgit repack时,它会在完成后输出“总计”行。这些数字意味着什么?git gc/git repack输出的“Total”行中的数字是什么意思?

从一个相当小仓库一对夫妇的例子:

$ git gc 
... 
Total 576 (delta 315), reused 576 (delta 315) 

$ git repack -afd --depth=250 --window=250 
... 
Total 576 (delta 334), reused 242 (delta 0) 

,一个来自一个更大的仓库:

$ git gc 
... 
Total 347629 (delta 289610), reused 342219 (delta 285060) 
... 

我可以猜测,第一个“总”号码是什么:数存储库中的Git对象(如提交,树和文件)。其他所有人都意味着什么?

我已经看过git-gc(1)git-repack(1)手册页,并仔细阅读了他们的“另请参见”,而我在Google上的尝试只会产生无关结果。

+0

http://github.com/git/git/blob/master/builtin/pack-objects.c – 2012-02-21 15:08:15

+0

@JoshLee我(现在)的代码抬头看了一眼,而不能轻松搞清楚发生了什么事。感谢您的指针,虽然:) – 2012-02-22 10:04:53

回答

22

我用dulwich做了一些工作,这是一个纯粹的Git的python实现。这里我要说的是反映了我与德威git实施的经验,而不是经典的git源,因此可能会有差异。

Git非常简单 - 我的意思是,它很简单,它混乱!这个名字非常适合它的设计,由于其愚蠢而非常聪明。

当你提交任何东西时,git会获取索引(staging区域)中的内容并创建SHA摘要项目,这样每个文件都会得到SHAed,并且每个目录中的文件都会被作为blob对象进行SHA处理,当然目录结构会获得SHAed树对象和所有绑定到同样具有SHA的提交对象的对象。 Git只是在处理提交时直接将它们引入.git/objects中的文件系统。如果它成功地将它们全部放在那里,它只是将最新的提交对象的SHA写入.git/refs/heads /中。

有时候提交可能会中途失败。如果某些东西无法写入.git/objects,git在那个时候没有清理。这是因为通常你会修复这个问题并重做提交 - 在这种情况下,git将从之前停止的地方重新开始,即通过提交的一半。

在此处,GIT中GC用武之地它简单地通过的.git /对象中的所有对象进行解析,标记了所有那些通过一个HEAD或BRANCH称为以某种方式。显然任何剩下的东西都是孤儿,与“重要”的东西无关,所以它可以被删除。这就是为什么如果你分支,在那个分支上做一些工作,但是后来放弃那个分支,并从你的git仓库中删除它的任何引用,运行的周期性的git gc将完全清除你的分支。这会让一些较早的VCS用户感到惊讶,除非它自己崩溃或损坏(通常是这样),否则CVS永远不会忘记任何东西。 (git-pack-objects)和git gc是完全不同的(就像git gc可能会调用git repack一样,单独的命令和操作也是如此)。正如我前面提到的,git只是将所有内容都引入自己的SHAed文件中。在进行光盘存储之前,它会对它们进行gzip,但显然这从长远来看并不节省空间。那么,git-pack-objects所做的就是检查一系列SHA对象,以便在数据跨修订版本进行复制的任何地方使用。它并不关心它是什么样的SHA对象 - 所有被认为是相等的包装。然后,它会生成有意义的二进制增量,并将整个批次作为.pack文件存储在.git/objects/pack中,从常规目录结构中除去所有打包对象。

请注意,通常git-pack对象会产生新的。打包文件,而不是替换现有的.pack文件,如果最新的包文件大小小于1Mb。因此,随着时间的推移,您会看到多个.pack文件出现在.git/objects/pack中。事实上,当你的Git获取,只要简单地请求远程回购收拾所有拆包物品以及发送该取回购没有给取回购协议.pack文件。 git repack只是简单地调用git-pack-objects,但会告诉它合并.pack文件,因为它认为合适。这意味着解压缩任何已更改的内容,重新生成二进制增量和重新压缩。

因此,要回答你的问题,总的线是指在GIT回购对象的总数。第一个德耳塔数是那些二进制增量对象的总对象数,即git决定的对象数与其他对象有很强的相似性,并且可以存储为二进制增量。重复使用的数字表示来自压缩源(即包文件)的多少对象正在被使用而没有被重新压缩以包括更近的改变。当你有多个包文件时,会发生这种情况,但是最近的SHA对象引用旧包文件中的某个项目作为其基础,然后对其应用deltas以使其变为现代。这让git可以使用先前压缩的旧数据修订版,而无需重新压缩以包含更多新增内容。请注意,git可能附加到现有的包文件而不重写整个包文件。

一般来说,高重用计数指示一些空间可以用一个完整的重新包装被回收(即一个git重新包装-a),这将始终返回重用为零。然而,一般git会默默地为你处理所有这些。另外,在做完整的重新包装,可能会迫使一些git的提取,因为包装不同,以从头开始 - 这取决于服务器设置(允许自定义的每个客户端包生成是在服务器CPU价格昂贵,所以一些大GIT网站禁用它)。

希望这回答了你的问题。真的,git非常简单,你一开始就会感到惊讶,然后当你把头围在它上面时,你会感到印象深刻。只有真正的天才程序员才能写出如此简单的东西,但效果非常好,因为他们可以看到大多数程序员只能看到复杂性的简单性。

尼尔

+0

根据该男子页,'git的gc'运行'git的repack',所以说两者是完全不同的,似乎关闭。另外,前两个例子(两者都有一个非零的“重用”计数)来自只有一个包的存储库,所以你的解释对我来说没有意义。 – 2012-02-27 15:13:37

+1

有git repack和git repack - git gc如果我记得做了一个“轻”重新包装。关于重复使用的计数,我根据我的回答追踪了一个在“这个包外部”参考文件没有得到满足并且德威进入无限循环的德威中的错误。我会毫不犹豫地承认我没有检查过git代码,以确保重用真的意味着我认为的意思。 – 2012-02-28 02:13:49

+0

关于重用计数不会为零,请尝试使用git repack -a强制重新打包。我编辑了我的答案,以澄清我的意思是“完全重新包装”。另外,在完全重新包装期间,请尝试增加窗口和深度(请参阅http://linux.die.net/man/1/git-repack)。对于大型回购站,可能会留下一些落在窗外的重复使用的物品。 – 2012-02-28 02:23:08