为什么在git diff或git status之后git diff-index HEAD结果会改变被触摸的文件?

时间:2016-01-15 09:28:27

标签: git

如果我在git仓库中跟踪了一个文件touch并运行git diff-index HEAD,它将打印输出M,表明文件已被修改。例如,

$ touch foo
$ git diff-index HEAD
:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0000000000000000000000000000000000000000 M  foo

我不确定这是否有意义,但这不是问题。问题是,如果我运行git diff HEADgit status,为什么输出会改变(无差异)?

$ touch foo
$ git diff-index HEAD
:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0000000000000000000000000000000000000000 M  foo
$ git diff                  # no output
$ git diff-index HEAD       # no output

我希望结果,无论它是什么,在不应该改变任何东西的命令中保持不变。

1 个答案:

答案 0 :(得分:10)

让我们先来看一下输出的含义:

:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0000000000000000000000000000000000000000 M  foo

The manual从左到右说明以下内容:

  
      
  1. 冒号。
  2.   
  3. 模式为" src&#34 ;;如果创建或未合并,则为000000。
  4.   
  5. 一个空间。
  6.   
  7. 模式为" dst&#34 ;;如果删除或未合并,则为000000。
  8.   
  9. 一个空间。
  10.   
  11. sha1 for" src&#34 ;; 0 {40}如果创建或未合并。
  12.   
  13. 一个空间。
  14.   
  15. sha1 for" dst&#34 ;; 0 {40}如果创建,未合并或"查看工作树"。
  16.   
  17. 一个空间。
  18.   
  19. 状态,然后是可选"得分"号。
  20.   
  21. 使用-z选项时的制表符或NUL。
  22.   
  23. " src"
  24. 的路径   
  25. 使用-z选项时的制表符或NUL;仅适用于C或R.
  26.   
  27. 路径为" dst&#34 ;;仅适用于C或R.
  28.   
  29. 使用-z选项时的LF或NUL,以终止记录。
  30.   

有趣的是第8点:

  

sha1 for" dst&#34 ;; 0 {40}如果创建,未合并或"查看工作树"。

所以在你的情况下,你得到40个零,所以这意味着“创造”,“未合并”或“看工作树”。由于您只触摸了文件,并且已经跟踪过,因此您可以删除前两个选项。这让我们看到“看工作树”

如果你这样做,使用git diff(它将尝试为所有更改生成实际内容差异,并且实际上看文件内容),然后Git显然发现毕竟没有变化,所以后续的电话不再对此发表任何意见。

这一观察结果让我相信默认情况下git diff-index只会快速查看文件,而不会实际比较任何内容。由于您修改了文件日期,Git认为它“可能已更改”,需要更详细的外观才能正确识别它。

如果您使用一个选项运行git diff-index,要求它更全面地查看文件,那么它也不会发现任何更改,例如使用-p选项生成补丁时(这是git diff所做的那种)。

因此,如果文件修改日期发生更改,则可能只是进行性能优化以假设文件可以更改,而不会对其进行实际声明;相反,它只是留下了“稍后再看”标记。