我正在使用
git diff mycommit
用于将我的工作树与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
输出(从git版本1.7.3.3开始)为空。使用--diff-filter=ACDMRTUXB
显示“已删除的文件”也是错误的,因为文件B.txt
同时存在于工作树和提交B
中。恕我直言,该文件应显示为已修改。令人惊讶的是,它在将文件添加到索引后起作用,尽管它不是比较的索引。没有它我怎么能得到正确的差异?
答案 0 :(得分:68)
简单的图形可能会有所帮助:
因此,您可以要求三种类型的差异:
git diff --cached
这是索引中的内容与上次提交之间的区别。它向您显示将在下次提交中进行的更改。
git diff
这显示了索引和工作树之间的差异。这些是您上次将文件添加到索引后对文件所做的更改。这就是为什么我没有得到任何结果。我在索引和工作树之间没有任何变化。
git diff HEAD
这显示了工作树中的文件与上次提交之间的差异。这里有一个问题:如果你做了更改,将它们添加到索引中,然后在工作树中撤消这些更改,那么git diff HEAD
就没有结果(因为没有区别)但是您将获得git diff --cached
的输出,因为索引中仍有变化。
如果你想将它与之前的提交进行比较:
这只是与之前的提交进行比较,但您可以将HEAD~
替换为对提交的任何其他引用。
答案 1 :(得分:7)
问题是:我在工作树中添加了一些文件,存在于另一个提交中。为什么git diff <commit>
没有向我显示工作树中存在的文件内容与另一个提交中的文件内容之间的区别。
这是因为您添加的新文件未跟踪,因此,git不会跟踪它。
尝试git diff HEAD
您不会在工作树中看到已添加B.txt。
基本上,diff不会考虑未跟踪的文件。这就是为什么你看到文件被删除的原因,因为差异与git diff B A
现在,如果你要添加文件,你会看到预期的结果,因为git现在正在跟踪它。
说,您提交了该文件,然后修改了工作树中的内容:
现在,git diff HEAD
将显示工作树和HEAD之间的区别,显示您在工作树中对跟踪文件所做的更改。与git diff B
答案 2 :(得分:3)
基本上,diff不会考虑未跟踪的文件。这就是为什么你看到文件被删除的原因,因为diff与git diff B A
相同
这是真实的,值得支持,但它并不能让我满意,因为它既没有说“我怎么能比较它”,却没有给出更深层次的理由。我仍然认为这是一个bug,所以我在git论坛上问了一个肯定知道的人long answer。对我来说重要的部分是:
这些句子中工作树中路径的定义不是“文件系统上的所有文件”,或“文件系统上的所有文件,使用忽略机制过滤”。它是“文件系统中索引中的所有文件”......
和
...这将为“git diff HEAD”提供一个干净的语义:如果我在这一点上说“git commit -a”,我会记录什么变化?
答案 3 :(得分:0)
如果您只需要将工作树中的更改还原为分支/提交 B ,则可以执行以下操作:
git diff B | git apply -R
这将在 B 和工作树之间创建差异,并将其反向应用。