原文: https://www.freecodecamp.org/news/git-diff-command/

嘿,朋友们,你是否曾经在 Git 中工作时,发现自己不知道是否要暂存(stage)正确的修改?

或者你想看看你要提交的改动与上次提交的改动相比有何不同。也许你想看看两个分支、提交或文件之间的差异。

这些都是使用版本控制系统时常见的问题和任务。幸运的是,你可以用 Git diff 命令来验证这一切。

我知道你的时间宝贵,所以我们直接开始吧。

别担心,我会用一个有趣的例子来教你每个命令。放宽心,开始阅读这篇文章吧。

git diff——通用的 diff 命令

git diff 列出了你的当前工作目录和暂存区域之间的变化

让我们举个例子。我创建了一个 Git 仓库,它是 cat_vs_dog。这不是一个正式的仓库,但它是相当严肃的。😉 然后我创建了 cat.txtdog.txt

它们的名字就是它们的介绍了——像这样:

kitty-1
puppy-1

然后我们用 git add cat.txt dog.txt 把这个改动移到暂存区。想确认一下吗?那就用 git status 吧,它可以显示哪些修改已经准备好提交了,如下图:

status

然后,假设我想对狗的名字做一些改动——比如我希望叫它 “pup” 而不是 “puppy”。

在此之前,如果我运行 git diff 命令,它没有显示什么。你能猜到为什么吗?如果你不能,那也完全没问题。在这上面停顿几秒钟,我们继续看下面的内容吧。

现在,我把 “puppy” 改为 “pup”。叫它 pup 很酷。

pup

在暂存它们之前,我希望看到我在当前工作目录(也就是当前工作文件夹)中的改动与暂存的改动相比较。

为了做到这一点,我运行了 git diff 命令。现在你可以看到它们的区别如下。

diff

这有点说得通,但也有点奇怪,对吗?别怕,我将教你了解每一行 diff 的结果。

之前,我们运行了 git diff 命令,它没有显示什么。因为 git diff 显示的是你的工作目录和暂存区的变化之间的差异。但是,我们在暂存修改之后,并没有在工作目录中修改任何东西。所以,与暂存区域相比,没有什么不同。我希望这么说,你能理解。

一行一行地理解 git diff 的结果

1-1

第 1 行——这是同一个文件的两个版本。Git 把第一个版本命名为 A,把第二个版本命名为 B

  • A - 文件的旧版本
  • B - 文件的新版本
2-2

第 2 行——关于文件的元数据,这对你的生活并不超级有用。前两个哈希值涉及到被比较的两个文件。100644 是一个内部文件模式标识符。

3-1

第 3 行——Git 给文件的 A 版分配了一个减号(-),给文件的 B 版分配了一个加号(+)。

4--

第 4 行——Git 通常显示被修改的一大块的行,而不是整个文件。

  • 以(-)符号开头的行来自 A 版本
  • 以(+)符号开始的行来自 B 版本

除了被修改的行,还包括该块前后的一些代码行,以显示上下文。

第 5 行——每个块都以一个块头(Chunk header)开始。块头将由 @@(在开始和结束时)来标识。然后,有两组数字。你能看到 -1+1 吗?

  • -1 意味着从 A 版文件中,从第 1 行开始提取一行。
  • +1 表示从 B 版文件中,从第 1 行开始提取一行。

如果这些集合是 -3,4 +3,2,那么:

  • -3,4 表示从 A 版文件中提取了从第 3 行开始的 4 行。
  • +3,2 表示从 B 版文件中提取了从第 3 行开始的 2 行。
endline

文件末尾没有换行——文本中说,在这些修改过的行之后没有行。这意味着,在上面的例子中,我只增加了一行,而且还修改了同一行。所以,在这之后就没有更多的行了。

这就是为什么在 diff 的结果中显示 “No newline at end of file”。希望你能明白我的意思。

庆祝时间

花一小会儿时间来庆祝你的努力,因为你已经有了 diff 的结果。现在,你有了一个坚实的基础,所以你可以开始微笑着学习更多的命令......

Tan-Round-Minimalist-Modern-Typography-Pretty-things-inside-Circle-Sticker--1-

如何在 Git 中比较已暂存的更改

在你提交修改之前,可以将暂存的修改与上次提交的修改进行比较。你可以通过添加一个标志 --staged--cached 来做到这一点。我喜欢 --staged,因为它很有意义。如果你喜欢 --cached,那也很好。

让我通过一个例子来解释。首先,我们在 cat_vs_dog 仓库中提交我们暂存的修改。如果你不记得我们暂存了什么,它们是 kitty 和 puppy。

在那里,我们想做一个改变——也就是说,我们希望把 “puppy” 改成 “pup”,这不是暂存的。

好吧,首先我们用 git commit -m "introduction to cat and dog 来提交已暂存的修改:

stage

现在,暂存从 “puppy” 到 “pup” 的变化。然后,运行 git diff --staged 命令,它列出了暂存区域和你最后一次提交之间的变化。

pup-1
  • A 版本——在 dog.txt 中包含行 my name is puppy 的最后一次提交
  • B 版本——与上次提交不同的暂存区,比如 dog.txt 中的 “puppy” 改为 “pup”。

从 diff 的结果来看,我们清除了我们修改和暂存的内容——A 版本中的 “my name is puppy” 和 B 版本中的 “my name is pup”。

我希望你现在能够通过看 diff 的结果来比较这些变化,并认识到我们改变了什么。diff 是一个超级强大的命令,它可以让你以很多方式来比较变化。

你需要知道的 4 个 Diff 比较

你可以运行 git diff HEAD 命令,将已暂存和未暂存的修改与你的最后一次提交进行比较。

你也可以运行 git diff <branch_name1> <branch_name2> 命令来比较第一个分支的改动和第二个分支的改动。在比较分支的时候,顺序确实很重要。所以 diff 的结果会因顺序不同而改变。

最重要的提示:分支比较只考虑提交的内容,它并不考虑暂存的和未暂存的修改。

你可以运行 git diff <commit_hash> <commit_hash> 命令来比较两个提交之间的变化。和分支比较一样,顺序在比较提交时也很重要。

你可以运行下面的命令来比较特定文件的变化:

  • git diff HEAD <file_name>
  • git diff <file_name>
  • git diff --staged <file_name> or  git diff --cached <file_name>,
  • git diff <branch_name1> <branch_name2> <file_name>
  • git diff <commit_hash> <commit_hash> <file_name>

总结

我希望这篇文章能帮助你使你的下一次提交或暂存更加准确。在使用 Git 命令时,你的心态很重要。充满信心地处理它,你就能从任何错误中学习。

如果你发现本教程中有什么需要更新的地方,请随时与我联系😜.