深入探索 Git Diff

GitGitBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

欢迎来到 Git 探索之旅!今天,我们将深入探讨 Git 中最强大且最常用的功能之一:git diff 命令。如果你曾经想知道你对文件做了哪些具体的更改,或者需要比较代码的不同版本,git diff 就是你一直在寻找的工具。

git diff 命令就像是你代码更改的显微镜。它允许你查看仓库中不同状态之间的精确差异,无论是工作目录中的更改、暂存区中的更改、提交之间的差异,甚至是分支之间的差异。

在本实验中,我们将探索如何:

  1. 比较工作目录与暂存区
  2. 比较暂存区与最后一次提交
  3. 比较不同的分支
  4. 比较特定文件
  5. 使用外部 diff 工具进行更直观的比较

通过本实验,你将成为 git diff 专家,能够精确而自信地审查你的更改。这项技能对于审查你的工作、准备提交以及与他人有效协作至关重要。

让我们开始探索 git diff 的强大功能吧!


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("`Git`")) -.-> git/SetupandConfigGroup(["`Setup and Config`"]) git(("`Git`")) -.-> git/BasicOperationsGroup(["`Basic Operations`"]) git(("`Git`")) -.-> git/BranchManagementGroup(["`Branch Management`"]) git/SetupandConfigGroup -.-> git/config("`Set Configurations`") git/SetupandConfigGroup -.-> git/init("`Initialize Repo`") git/BasicOperationsGroup -.-> git/add("`Stage Files`") git/BasicOperationsGroup -.-> git/commit("`Create Commit`") git/BasicOperationsGroup -.-> git/diff("`Compare Changes`") git/BranchManagementGroup -.-> git/branch("`Handle Branches`") subgraph Lab Skills git/config -.-> lab-387489{{"`深入探索 Git Diff`"}} git/init -.-> lab-387489{{"`深入探索 Git Diff`"}} git/add -.-> lab-387489{{"`深入探索 Git Diff`"}} git/commit -.-> lab-387489{{"`深入探索 Git Diff`"}} git/diff -.-> lab-387489{{"`深入探索 Git Diff`"}} git/branch -.-> lab-387489{{"`深入探索 Git Diff`"}} end

设置你的工作区

在我们开始比较之前,让我们先设置一个包含一些文件和提交的工作区,以便进行比较。我们将创建一个新目录,初始化一个 Git 仓库,并添加一些文件并进行多次提交。

打开你的终端并输入以下命令:

cd ~/project
mkdir git-diff-lab
cd git-diff-lab
git init

现在,让我们创建一些文件并进行一系列提交,复制并粘贴以下命令:

echo "## Git Diff Lab" > README.md
git add README.md
git commit -m "Initial commit"

echo "function greet(name) {" > greet.js
echo "  return 'Hello, ' + name + '!';" >> greet.js
echo "}" >> greet.js
git add greet.js
git commit -m "Add greet function"

echo "const numbers = [1, 2, 3, 4, 5];" > numbers.js
echo "console.log(numbers);" >> numbers.js
git add numbers.js
git commit -m "Add numbers array"

让我们分解一下刚刚的操作:

  1. 我们创建了一个 README 文件并进行了初始提交。
  2. 我们创建了一个包含问候函数的 JavaScript 文件并提交了它。
  3. 我们创建了另一个包含数字数组的 JavaScript 文件并提交了它。

现在,我们有了一个包含一些历史记录的仓库,可以开始探索了!

比较工作目录和暂存区

git diff 最基本的用途是查看工作目录中尚未暂存的更改。让我们来探索一下。

首先,我们对 greet.js 文件做一些修改:

echo "function farewell(name) {" >> greet.js
echo "  return 'Goodbye, ' + name + '!';" >> greet.js
echo "}" >> greet.js

现在,我们使用 git diff 来查看这些更改:

git diff

你应该会看到类似以下的输出:

diff --git a/greet.js b/greet.js
index 95f5574..a3641f6 100644
--- a/greet.js
+++ b/greet.js
@@ -1,3 +1,7 @@
 function greet(name) {
   return 'Hello, ' + name + '!';
 }
+function farewell(name) {
+  return 'Goodbye, ' + name + '!';
+}

让我们分解一下这个输出:

  • 第一行显示了正在比较的文件。
  • +++--- 行显示了正在比较的文件版本(a/ 是原始版本,b/ 是新版本)。
  • @@ 行提供了更改在文件中的位置上下文。
  • + 开头的行表示添加的内容,而 - 则表示删除的内容。

这个 diff 显示我们在 greet.js 中添加了三行新内容。

q 退出 diff 视图。

现在,让我们暂存这些更改:

git add greet.js

如果你再次运行 git diff,你将看不到任何输出。这是因为默认情况下,git diff 只显示未暂存的更改。要查看已暂存的更改,你需要使用 git diff --staged,我们将在下一步中介绍。

记住,不带任何参数的 git diff 会比较你的工作目录和暂存区。这是在暂存更改之前审查更改的好方法。

比较暂存区和最后一次提交

现在我们已经暂存了更改,让我们学习如何比较暂存区和最后一次提交。这对于审查下一次提交中将包含哪些更改非常有用。

要查看暂存区与最后一次提交之间的差异,请使用:

git diff --staged

你应该会看到与上一步类似的输出,显示添加了 farewell 函数。

当你随着时间的推移暂存了多个更改,并希望审查下一次提交中将包含的所有内容时,这个命令特别有用。

让我们再做一个更改并暂存它,看看它是如何工作的:

echo "console.log(greet('World'));" >> greet.js
git add greet.js

现在,当你运行 git diff --staged 时,你会看到 farewell 函数和新的 console.log 行。

记住,git diff --staged(或 git diff --cached,它们是同义词)会显示当前暂存区中的更改与最后一次提交之间的差异。这是在提交之前再次检查暂存更改的好方法。

比较分支

git diff 在比较不同分支时也非常有用。当你在一个功能分支上工作,并希望查看它与主分支的差异时,这一点尤其有帮助。

让我们创建一个新分支并进行一些更改:

git checkout -b feature-branch
echo "const PI = 3.14159;" >> numbers.js
git add numbers.js
git commit -m "Add PI constant"

现在,让我们将这个分支与主分支进行比较:

git diff master feature-branch

你应该会看到输出显示在 numbers.js 中添加了 PI 常量。

这个命令显示了 master 分支和 feature-branch 分支的尖端之间的差异。它的意思是“显示 feature-branch 中有哪些更改是 master 中没有的”。

你也可以通过省略第一个分支名称来将当前分支与另一个分支进行比较:

git diff master

这将比较当前分支(feature-branch)与 master 分支。

记住,在比较分支时:

  • 第一个分支(或省略时的当前分支)中有但第二个分支中没有的更改将显示为删除(以 - 表示)。
  • 第二个分支中有但第一个分支中没有的更改将显示为添加(以 + 表示)。

这个功能在准备合并分支或查看功能分支引入了哪些更改时非常有用。

比较特定文件

有时,你只想查看特定文件或一组文件的更改。git diff 可以轻松实现这一点。

让我们对多个文件进行更改:

echo "function multiply(a, b) { return a * b; }" >> greet.js
echo "const doubledNumbers = numbers.map(n => n * 2);" >> numbers.js

现在,如果我们只想查看 greet.js 的更改,可以使用:

git diff greet.js

这将仅显示对 greet.js 所做的更改。

你也可以比较分支之间的特定文件:

git diff master feature-branch -- numbers.js

这将显示 master 分支和 feature-branch 分支之间 numbers.js 的差异。

上述命令中的 -- 用于将文件路径与分支名称分开。虽然并非总是必要,但使用它是一个好习惯,以避免歧义,尤其是在文件名可能与分支名称混淆的情况下。

记住,你可以将文件路径与我们学过的任何 diff 命令一起使用。这在大型项目中特别有用,因为你可能跨多个文件进行了更改,但只想关注其中的几个文件。

使用外部 Diff 工具

虽然 Git 内置的 diff 功能非常强大,但有时你可能希望以更直观的方式查看更改。许多开发者为此使用外部 diff 工具。

一个流行的工具是 vimdiff。让我们配置 Git 以使用 vimdiff

git config --global diff.tool vimdiff
git config --global difftool.prompt false

现在,你可以使用 git difftool 代替 git diff

git difftool

这将在 vimdiff 中打开每个修改过的文件。你可以使用 :n 切换到下一个文件,使用 :prev 切换到上一个文件。要退出 vimdiff,请使用 :qa!

还有许多其他可用的 diff 工具,例如 Beyond Compare、KDiff3 或 P4Merge。工具的选择通常取决于个人偏好和操作系统。

记住,虽然可视化 diff 工具非常有用,尤其是在处理较大的更改时,但它们并非总是必要的。许多开发者对标准的 git diff 输出非常熟练,并喜欢其在日常使用中的速度和简洁性。

总结

恭喜你,diff 侦探!你已经深入探索了 git diff 的世界。让我们回顾一下我们涵盖的关键概念:

  1. 比较工作目录和暂存区:你学会了如何查看工作目录中未暂存的更改。
  2. 比较暂存区和最后一次提交:你发现了如何在提交前审查暂存的更改。
  3. 比较分支:你了解了如何比较不同的分支以查看它们的分歧。
  4. 比较特定文件:你学会了如何将 diff 聚焦于你感兴趣的特定文件。
  5. 使用外部 Diff 工具:你探索了如何使用可视化 diff 工具以不同的视角查看更改。

git diff 命令是你 Git 工具包中的一个强大工具。它允许你精确地检查更改,无论你是在准备提交、审查同事的工作,还是试图理解项目的历史。

记住,熟练掌握 git diff 需要练习。如果一开始输出看起来晦涩难懂,请不要气馁——随着时间的推移,你将能够快速高效地阅读 diff。

在你继续 Git 之旅时,请继续探索 git diff 的各种选项和用例。这是一个多功能的命令,可以与许多其他 Git 功能结合使用,为你提供对项目更改的深入洞察。

祝你 diff 愉快,愿你的代码更改始终清晰且有意为之!

您可能感兴趣的其他 Git 教程