git索引中的ctime和mtime是什么?

时间:2018-07-10 21:44:22

标签: git git-index

第一次将文件添加到索引时,文件的创建时间戳记存储在索引记录的ctime中,而文件的当前修改时间戳记存储在mtime字段中。

>

更改后添加文件后,mtime会以文件的当前时间戳进行更新。

检出文件时,它不使用mtime 这些时间戳在git的世界中有什么用?

查看对索引的引用,它们似乎就在那里。也许他们有一些未曾实现的未来目标?

$ git ls-files --debug readme.txt
readme.txt
  ctime: 1531246924:79161700
  mtime: 1531258019:669963000
  dev: 0        ino: 0
  uid: 0        gid: 0
  size: 13      flags: 0

1 个答案:

答案 0 :(得分:1)

索引具有三个名称:“索引”(您在此处使用的名称),临时区域(从某种意义上讲,它更好地描述了它的功能)和缓存。这是在这里适用的姓氏。

使索引成为索引或缓存(而不只是暂存区)的原因在于,它索引并缓存了工作树的内容。缓存的目的是加快处理速度。但是缓存总是存在问题:在某些时候,缓存中的部分或全部数据变为无效。提供对真实,实际,正确数据的快速/快捷访问的缓存不再反映实际情况。缓存必须丢弃或重新填充正确的数据。

现在,Git的索引在工作树中保存了或至少在git checkout时间的文件的副本 1 如果您已经以某种方式更改了文件,Git怎么知道缓存的副本无效?

Git的答案是与缓存的副本一起存储有关该文件的某些stat信息 ,包括文件的大小和您观察到的两个时间戳。如果您以某种方式修改文件(甚至只是更改其模式而不会影响文件内容(因此大小和mtime保持不变)),那么ctime时间戳将被更新,并且Git会知道某些内容改变了。当然,如果您修改内容或更改大小,Git也会知道。


1 从技术上讲,索引包含文件的清除副本,可供提交。如果您具有行尾设置和/或污迹和/或清洁过滤器,则清洁后的副本实际上可能与工作树副本不匹配。


您注意到:

  

检出文件后,它不会将mtime用于[此处未完成的想法]

我认为您所观察到的是Git的其他优化之一。如果您在空状态下(例如,第一次克隆操作检出)运行git checkout <commit-specifier>,则Git必须首次完全填充索引和工作树。不过,一旦完成此操作,如果现在运行不同 git checkout来检出一些 other 提交,则Git可以优化检出:

  • 索引包含存储在工作树中的当前提交的所有文件。
  • 您要签出的新提交包含许多与当前提交100%相同的文件。
  • 因此,Git只需要替换索引和工作树中的差异文件

结果,工作树中两次提交之间文件的mtime保持不变,因为这些文件根本没有被触及。

这只是缓存进行缓存的另一个方面。但是,它确实可以切换分支,同时在索引和/或工作树中进行一些修改。有关详细信息,请参见Checkout another branch when there are uncommitted changes on the current branch