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

2022-12-01 04:21:27 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

我一遍又一遍地重复,直到我达到第一个承诺。你知道吗

这个解决方案可行,但很糟糕。在更糟糕的情况下,第一次搜索甚至需要3分钟(对于300米背包)。你知道吗

有没有办法加快速度?我尽量避免把这么大的对象放在内存中,但现在我看不到任何其他方法。即便如此,最初的内存加载也需要很长时间:(

欢迎并感谢您的帮助!你知道吗


Tags: 文件对象内存git目录文件夹解析器内容方式somefilecommitdeepinside父树
1条回答
网友
1楼 · 发布于 2022-12-01 04:21:27

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

不过,评估不需要太长时间:你必须记住的东西很少。您已经提到了要点:请记住树id向下延伸到路径以快速消除甚至没有触及该子树的提交。树对象很少非常大,就像文件系统上的目录一样(毫不奇怪)。你知道吗

你在用背包指数吗?如果你没有,那么你基本上必须打开整个包来找出这个问题,因为树可能在一个长三角链的末端。如果有索引,仍然需要应用delta来获取树对象,但至少应该能够快速找到它们。保留应用的delta的缓存,因为显然树重用相同或相似的基是非常常见的-大多数树对象的更改只是从以前的树对象更改了20个字节。因此,如果要得到树T1,必须从对象T8开始,应用Td7得到T7,T6。。。。等等。完全有可能这些其他树T2-8会再次被引用。你知道吗