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

标签 python git

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

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

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

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

有什么办法可以加快速度吗?我试图避免将如此大的对象放入内存中,但现在我看不到任何其他方法。即便如此,初始内存加载也将永远持续:(

欢迎并感谢您的帮助!

最佳答案

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

不过,评估时间应该不会太长:您必须保留在内存中的数量非常小。您已经提到了 Gist :记住树 ID 向下到路径以快速消除甚至没有触及该子树的提交。树对象非常大的情况很少见,就像文件系统上的目录一样(不足为奇)。

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

关于python - git 如何获取与文件关联的提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2841863/

相关文章:

python - 从python中的文件中读取整数

javascript - nodejs 中类似 c 的互斥量

python - 在数据框中应用条件 lambda 语句

python - NumPy 通过 TypeError 进行 join_functions

python - 字符串连接性能

java - 忽略 Android 生成的文件,GIT

git - 我运行了 'git pull'但仍然无法自动 merge ?

S3 上的 Git 存储库(作为 "origin",而不是备份)

python - Pip 1.5 和 setup.py 中设置的 git 依赖项不能一起工作

git - Android Studio 中的扩展提交描述消息