Git';s&x2018;日志文件名’;内部实施

Git';s&x2018;日志文件名’;内部实施,git,Git,我知道Git不会将数据存储为一系列变更集或增量,而是存储为一系列快照。因此,一个文件的两个版本之间没有直接关系,如图所示: 当我使用命令时: git log test.txt Git如何在其文件系统中找到“版本1和版本2”日志 我认为: Git将遍历所有提交对象(带有父引用),然后遍历树等,以获取特定文件的每个日志信息 但是,这似乎不是很有效;Git是否有一些特定的算法来提取日志信息或存储一些额外的信息来获取日志信息?您的假设是正确的。对于最简单的情况(通过路径名限制日志输出),其工作原理与

我知道Git不会将数据存储为一系列变更集或增量,而是存储为一系列快照。因此,一个文件的两个版本之间没有直接关系,如图所示:

当我使用命令时:

git log test.txt
Git如何在其文件系统中找到“版本1和版本2”日志

我认为:

Git将遍历所有提交对象(带有父引用),然后遍历树等,以获取特定文件的每个日志信息


但是,这似乎不是很有效;Git是否有一些特定的算法来提取日志信息或存储一些额外的信息来获取日志信息?

您的假设是正确的。对于最简单的情况(通过路径名限制日志输出),其工作原理与此完全相同:

  • 从提交中获取树
  • 路径是否存在于树中
  • 与此路径关联的blob的SHA1是否与上一次提交不同? ->输出它
  • 获取下一个(父)提交。重复一遍

这比你想象的要有效得多。由于git写包的方式,这些东西的实际数据只需很少的I/O就可以读入——大小相似的东西是相邻的,因此每个树的历史很可能是按顺序存储的,并且由于位置的原因,压缩得非常好。I/O比解压缩慢得多,这是一个胜利。然后,由于树的SHA是树本身及其所有子树的SHA,git可以很容易地检测到子树何时与其父树完全相同,并去掉早期的树。这种情况经常发生,因为很少有文件会在每次提交时更改


总之,它的速度足够快,在实践中不成问题。

您考虑过下载git源代码并查看吗?源代码可以在这里找到:它有什么低效的地方?例如,与在三个不同目录中查找文件
test.txt
v1/test.txt
v2/test.txt
v3/test.txt
@torek相比,如果我有1000次提交,但一个文件只更改三次,那么遍历1000次日志树文件以获得文件的三个快照足够真实是低效的。那么,您多久检查数千次提交以确定其中是否有一个特定文件发生了更改?是否值得优化此特定案例?就这点而言,您将如何着手优化它?(注意:我并不是说这是答案,我是说这些是应该首先回答的问题。:-)