git diff和git diff-index有什么区别?

28

当我想获取git diff文件时,我发现有人使用了

git diff-index --cached  --diff-filter=AM --name-only  HEAD

如果我使用

git diff --cached --diff-filter=AM --name-only  HEAD 

可以获得相同的结果。 那么“git diff”和“git diff-index”之间有什么区别呢? 何时必须使用“git diff-index”,而不是“git diff”?

3个回答

18

git diff-index是对索引或工作树进行的差异比较:

它比较树对象中找到的blob的内容和模式与工作树中的相应跟踪文件,或与索引中的相应路径。

git diff更加灵活,可以比较两个文件、两个提交,或者(像diff-index一样)比较树和索引。

在您的情况下,diff HEAD确实会将HEAD与索引进行比较,这也是diff-index所做的。


警告:“{{link1:git diff --cached}}”man代码路径在fsmonitor知道文件是干净的时候没有填充必要的stat信息,结果表现得好像它不是干净的,这在Git 2.43(2023年第四季度)中已经得到了修正。
查看提交 6a044a2(2023年9月11日)由Josip Sokcevic(sokac完成。
(由Junio C Hamano -- gitster --提交 671eaaa中合并,2023年9月20日)

diff-lib:修复fsmonitor开启时的check_removed

签名:Josip Sokcevic

git diff-index(man) 在使用 fsmonitor 的存储库中可能会返回错误的删除条目。
这在 Mac 机器上可以观察到,但也可能影响所有其他支持的平台。
如果使用 fsmonitor,如果 cache_entry 设置了 CE_FSMONITOR_VALID,则不会初始化 stat *st
但是,之后有三个调用点依赖于 stat,这可能导致错误的结果。
此更改部分还原了 commit 4f3d6d0 ("fsmonitor: skip lstat deletion check during git diff-index", 2021-03-17, Git v2.32.0-rc0 -- merge listed in batch #4)。

1
什么是索引? - Will
5
索引是你准备下一次提交的地方。2005年制作Git时,Linux Torvalds需要一个工具,在其中可以添加多个更改并忽略其他更改,以便准备下一次Linux代码提交。了解更多信息:https://dev59.com/Cm855IYBdhLWcg3w6IzV#4086986 - VonC
git diff-index 不总是针对索引。正如文档所说:“将树与工作树或索引进行比较”。 - Droopycom
@Droopycom 同意。我已相应地编辑了答案。 - VonC

2
diff-index是一个较低级别的操作,它做的事情较少,但速度更快,因为它不查看内容,只检查元数据,如时间戳。只有在Linux上,您才能使用类似以下的方法进行验证:
  strace -f -e file -o diff-index.log git diff-index HEAD
  wc diff-index.log
  less diff-index.log

除非你需要解决一些 Git 性能问题,否则不要考虑 diff-index。

https://git-scm.com/docs/git-update-index#_using_assume_unchanged_bit

https://public-inbox.org/git/loom.20160331T143733-916@post.gmane.org/


1

在研究了这两个命令的区别后,我发现了奇怪的行为:

看起来 git diff-index 对文件是否被更改但内容没有变化敏感,而git diff在这种情况下不敏感。

换句话说,如果您想知道一个文件是否未更改,但不关心最近更改的时间戳是否有变化,请使用 git diff

  • 注意:我不确定自己的理解是否正确。

https://git.vger.kernel.narkive.com/3Xf875jB/diff-on-touched-files-bug-or-feature 讨论了 git diff-index 的这种特异性。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接