Git 如何将工作树与提交进行比较?

Git 如何将工作树与提交进行比较?,git,diff,Git,Diff,我正在使用 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

我正在使用

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
中。IMHO,该文件应显示为已修改。令人惊讶的是,它在将文件添加到索引后工作,尽管比较的不是索引。如果没有它,我如何获得正确的差异?

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

因此,您可以要求三种类型的差异:

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

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

  • git差异头
    这显示了工作树中的文件与上次提交的文件之间的差异。这里有一个问题:如果您进行了更改,将它们添加到索引中,然后在工作树中撤消这些更改,那么对于
    git diff HEAD
    (因为没有差异)将不会得到任何结果,但是对于
    git diff--cached
    ,您将得到输出,因为索引中仍然有更改

  • 如果要将其与以前的提交进行比较:


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

    问题是:我在工作树中添加了一些文件,这些文件存在于其他提交中。为什么
    git diff
    没有显示我的工作树中存在的文件内容与其他提交中存在的文件内容之间的差异

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

    尝试
    git diff HEAD
    您将不会看到在工作树中添加了B.txt

    基本上,diff不考虑未跟踪的文件。这就是您看到文件被删除的原因,因为diff与git diff B A相同

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

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


    现在,
    git diff HEAD
    将显示工作树和HEAD之间的差异,显示您在工作树中对跟踪文件所做的更改。manojlds在他的回答中写道,与git diff B相同

    基本上,diff不考虑未跟踪的文件。这就是您看到文件被删除的原因,因为diff与git diff B A相同

    这是真的,值得一提,但它并没有让我满意,因为它既没有说“我怎么能比较它”,也没有给它背后更深的原因。我仍然认为这是一个bug,所以我在git论坛上询问,并得到了一个肯定知道的人的回复。对我来说,重要的部分是:

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

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


    这个问题的答案在哪里?非常好的答案,这张图片确实有助于解释它,当然为我澄清了一些事情。只需一个澄清。我不知道,也许自答案发布之日起(目前我使用的是2.17.0版)发生了一些变化。根据答案,如果我在工作树中编辑某个内容,不要将其添加到索引中并使用
    git diff a_file.xyz
    ,我应该不会得到任何结果。相反,我得到的结果与使用
    git diff HEAD a_file.xyz
    得到的结果相同。所以,现在看起来,如果索引是空的(或者,至少,您试图获取差异的文件不在索引中),git会自动显示工作树和头部之间的差异。您的评论是“您似乎不理解OP提出的问题”。如果那是真的,你也一样,因为我说的和你完全一样。@BenLee-你可能是同一个意思,但我不认为你说的是同一件事。我怎么说的有什么不同?我就是这么说的。该文件在工作树中不存在(git状态显示为“未跟踪”),但如果添加它,它将显示差异。这就是我所说的。你也是这么说的。
    但如果你加上它,它会显示差异。
    -我还没说完。我开始修改工作树中的跟踪文件,这就是
    git diff B
    要显示的内容。另外,请看我对您答案的评论。我不知道您添加的内容如何添加OP不知道的内容。但你知道,我放弃了。我明白这是怎么回事,不需要向你证明,我不值得再花时间争论了。