git diff HEAD与git diff --staged有什么区别?

101

git diff HEADgit diff --staged有什么区别?我尝试了两种方式,但输出结果相同。


2
请查看此处:https://dev59.com/yHI-5IYBdhLWcg3w99oH - Viacheslav Kondratiuk
@Johnsyweb 抱歉;“完全”相同的输出 - vhd
3
--staged--cached 的同义词。这篇文章中的图表(https://dev59.com/yHI-5IYBdhLWcg3w99oH)解释了它们之间的区别。已标记为重复。 - Abizern
1
很快(Git 2.3.4+,2015年第二季度),git status -v -v将清楚地显示两个差异之间的区别:请参见我的答案 - VonC
5个回答

139

假设运行git status命令会产生如下输出:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   y
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   x
#

正如您所见,有一个文件被修改但未准备提交,还有一个新文件已经添加到待提交区域。

git diff --staged 只会显示“待提交”区域的文件更改。

git diff HEAD 将显示所有已跟踪文件的更改。如果您已将所有更改都准备好提交,则这两个命令将输出相同的结果。


难道应该不是已跟踪的文件而是未跟踪的文件吗?因为当我没有添加文件时执行git status,它将未暂存的文件显示为未跟踪的文件。 - vhd
如果这是一个你之前没有添加过的新文件,它将会被标记为未跟踪状态,并且不会出现在任何 git diff 变体中。如果这个文件之前已经被添加并提交过,而你对它进行了修改,那么它将会被标记为“未暂存的更改”。 - Carlos Campderrós
有没有一种方法可以在同一文件的暂存版本和未暂存版本之间进行“diff”更改? - Geremia
如果我理解正确的话,@geremia,git diff --staged命令可以实现这个功能。 - Carlos Campderrós
2
@CarlosCampderrós 噢,是的,只要您指定文件,它就会将其暂存 vs. 未暂存版本进行比较。 - Geremia

84
  • git diff 查看暂存区和工作目录的差异
  • git diff --staged 查看已暂存和最新提交(HEAD)的差异
  • git diff HEAD 查看最新提交(HEAD)与工作目录的差异

图片描述
img src

  • HEAD 表示当前检出分支上最近一次提交的版本。
  • “Staging area”、“stage”、“index” 都是指相同的东西。
  • 未暂存的更改存在于我们的工作目录中,但 Git 还没有将它们记录到版本历史中。
  • 暂存的更改很像未暂存的更改,只不过它们已被标记为下一次运行 git commit 时要提交的更改。

19
顶部图形对我有帮助。下部图形则不太行。 - Nick Weavers
@NickWeavers 我移除了图形,因为它们非常分散注意力,并且对答案没有帮助。 - episodeyang
有人知道制作顶部图形所使用的工具是什么吗? - creativemateriel
3
@creativemateriel 我认为使用了TikZ: https://www.overleaf.com/learn/latex/TikZ_package - 01F0
maint 是分支的名称吗? - variable
@Premraj 请问说git diff HEAD比较的是HEAD和工作目录,但不包括未跟踪的文件,这种说法也正确吗? - geronimo

10

在即将到来的Git 2.3.4+(2015年第二季度)中,您将更容易地看到两个差异之间的区别git status -v -v

请参见提交4055500,作者为Michael J Gruber mjg,它很好地解释了git diff HEADgit diff --staged之间的区别:

commit/status: 显示使用 -v -v 的索引-工作树差异

git commitgit status 以长格式显示 HEAD 和索引之间的差异,当给定 -v 时。这允许预览要进行的提交

它们还列出了具有未暂存更改但没有差异的已跟踪文件。

引入 '-v -v',它除了显示 HEAD 索引差异外,还显示索引和工作树之间的差异。这允许审查未暂存的更改,这些更改可能在提交中缺失

在 '-v -v' 的情况下,会添加额外的标题行。

Changes to be committed:
# and
Changes not staged for commit:

在状态部分之前插入了与差异相等的内容;后者由50个"-"引导,以使其更加突出。

2

另一个边缘情况的区别:在一个新创建的Git仓库中,只运行了git init命令,这时运行git diff HEAD将会导致致命错误(模棱两可的参数'HEAD'),而git diff --staged则不会有任何输出。


1
如果您在运行未成功合并的命令时,即未合并的路径上运行它们,也可以从两个diff命令中获得不同的输出。
我无法找出为什么会这样,但您可以在这里阅读更多相关信息。

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