git如何获取与文件关联的提交?

时间:2010-05-15 21:40:02

标签: python git

我正在编写.git / *文件的简单解析器。我几乎涵盖了所有内容,如对象,引用,打包文件等。但我有一个问题。假设我有一个300M的大型存储库(在一个包文件中),我想找出所有改变/ some / deep / inside / file文件的提交。我现在正在做的是:

  • 获取最后一次提交
  • 通过以下方式查找文件:
    • 获取父树
    • 找到里面的一棵树
    • 递归重复,直到我进入文件
    • 另外我正在检查每个子文件夹的哈希值。如果其中一个与之前的提交相同,我认为该文件未被更改(因为它的父目录没有改变)
  • 然后我存储文件的哈希并获取父提交
  • 再次查找文件并检查是否发生了哈希更改
    • 如果是,那么原始提交(即父母之前的一个)正在更改文件

我一遍又一遍地重复它,直到我第一次提交。

这个解决方案有效,但很糟糕。在更糟糕的情况下,首次搜索甚至可能需要3分钟(300M包)。

有没有办法加快速度?我试图避免在内存中放置如此​​大的对象,但是现在我没有看到任何其他方式。即便如此,初始内存负载将永远存在:(

欢迎并感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

这是git用于跟踪特定文件更改的基本算法。这就是为什么“git log - some / path / to / file.txt”是一个相对较慢的操作,与许多其他简单的SCM系统相比(例如在CVS中,P4等每个repo文件都是一个服务器文件,文件的历史。)

虽然评估不应该花这么长时间:你必须留在记忆中的数量非常少。您已经提到了要点:记住路径下的树ID,以快速消除甚至没有触及该子树的提交。树对象很少很大,就像文件系统上的目录一样(不出所料)。

您使用的是包装索引吗?如果你不是,那么你基本上必须打开整个包装才能找到它,因为树木可能位于长三角链的末端。如果你有一个索引,你仍然需要应用增量来获取你的树对象,但至少你应该能够快速找到它们。保留应用增量的缓存,因为树显然重用相同或类似的基础是很常见的 - 大多数树对象更改只是从前一个树对象更改20个字节。因此,如果为了获得树T1,你必须从对象T8开始并应用Td7来获得T7,T6 ......等等。这很可能会再次引用这些其他树T2-8。