如何比较工作树和提交?

maa*_*nus 31 git diff

我正在使用

git diff mycommit
Run Code Online (Sandbox Code Playgroud)

用于比较我的工作树mycommit,但它似乎忽略了当前索引中不存在的文件.您可以按如下方式重现它:

git init
echo A > A.txt; git add .; git commit -m A; git branch A
echo B > B.txt; git add .; git commit -m B; git branch B
git reset --hard A
echo BB > B.txt
git diff B
Run Code Online (Sandbox Code Playgroud)

输出(从git版本1.7.3.3开始)为空.使用--diff-filter=ACDMRTUXB显示错误的"已删除文件",因为该文件同时B.txt存在于工作树和提交中B.恕我直言,该文件应显示为已修改.令人惊讶的是,它在将文件添加到索引后起作用,尽管它不是比较的索引.没有它我怎么能得到正确的差异?

Abi*_*ern 70

一个简单的图形可能会有所帮助:

在此输入图像描述

所以你可以要求三种类型的差异:

  1. git diff --cached 这是索引中的内容与上次提交之间的区别.它向您显示将在下一次提交中进行的更改.

  2. git diff 这显示了索引和工作树之间的差异.这些是您上次将文件添加到索引后对文件所做的更改.这就是为什么我没有得到任何结果.我在索引和工作树之间没有任何变化.

  3. git diff HEAD 这显示了工作树中的文件与上次提交之间的差异.这里有一个问题:如果你做了更改,将它们添加到索引中,然后在工作树中撤消这些更改,你将得不到任何结果git diff HEAD(因为没有区别)但是你会获得输出git diff --cached因为索引仍有变化.

如果你想将它与之前的提交进行比较:

在此输入图像描述

这只是与之前的提交进行比较,但您可以替换HEAD~为提交的任何其他引用.

  • 这个问题的答案在哪里? (17认同)
  • 非常好的答案,图形真的有助于解释它,当然为我清除了一些东西. (2认同)

man*_*lds 8

问题是:我在工作树中添加了一些文件,存在于另一个提交中.为什么git diff <commit>不向我显示工作树中存在的文件内容与另一个提交中的文件内容之间的区别.

这是因为您添加的新文件未跟踪,因此,git不会跟踪它.

试着git diff HEAD你不会看到你在工作树中添加了B.txt.

基本上,diff不会考虑未跟踪的文件.这就是为什么你看到文件被删除,因为差异是相同的git diff B A

现在,如果您要添加文件,您将看到预期的结果,因为git现在正在跟踪它.

比如说,您提交了文件,然后修改工作树中的内容:

现在,git diff HEAD将显示工作树和HEAD之间的区别,显示您在工作树中对跟踪文件所做的更改.与...相同git diff B


maa*_*nus 6

manojlds 在他的回答中写道

基本上,diff 不考虑未跟踪的文件。这就是为什么你看到文件被删除,因为 diff 与 git diff BA 相同

这是真的,值得点赞,但它并不能令我满意,因为它既没有说“我如何比较它”,也没有给出背后更深层的原因。我仍然认为这是一个错误,所以我在 git 论坛上询问,并得到了一个肯定知道的人的长答案。对我来说重要的部分是:

这些句子中工作树中路径的定义不是“文件系统上的所有文件”,也不是“文件系统上的所有文件,使用忽略机制过滤”。它是“文件系统上索引中的所有文件”......

...这将为“git diff HEAD”提供清晰的语义:如果我此时说“git commit -a”,我会记录什么变化?