我正在编写.git / *文件的简单解析器。我几乎涵盖了所有内容,如对象,引用,打包文件等。但我有一个问题。假设我有一个300M的大型存储库(在一个包文件中),我想找出所有改变/ some / deep / inside / file文件的提交。我现在正在做的是:
我一遍又一遍地重复它,直到我第一次提交。
这个解决方案有效,但很糟糕。在更糟糕的情况下,首次搜索甚至可能需要3分钟(300M包)。
有没有办法加快速度?我试图避免在内存中放置如此大的对象,但是现在我没有看到任何其他方式。即便如此,初始内存负载将永远存在:(
欢迎并感谢您的帮助!
答案 0 :(得分:1)
这是git用于跟踪特定文件更改的基本算法。这就是为什么“git log - some / path / to / file.txt”是一个相对较慢的操作,与许多其他简单的SCM系统相比(例如在CVS中,P4等每个repo文件都是一个服务器文件,文件的历史。)
虽然评估不应该花这么长时间:你必须留在记忆中的数量非常少。您已经提到了要点:记住路径下的树ID,以快速消除甚至没有触及该子树的提交。树对象很少很大,就像文件系统上的目录一样(不出所料)。
您使用的是包装索引吗?如果你不是,那么你基本上必须打开整个包装才能找到它,因为树木可能位于长三角链的末端。如果你有一个索引,你仍然需要应用增量来获取你的树对象,但至少你应该能够快速找到它们。保留应用增量的缓存,因为树显然重用相同或类似的基础是很常见的 - 大多数树对象更改只是从前一个树对象更改20个字节。因此,如果为了获得树T1,你必须从对象T8开始并应用Td7来获得T7,T6 ......等等。这很可能会再次引用这些其他树T2-8。