git diff 命令(千字长文)

git diff 命令:你代码变更的“显微镜”

在日常开发中,你有没有遇到过这样的场景:改完代码提交后,突然发现某个功能没按预期运行?或者同事提交的代码让你一头雾水,不知道到底改了什么?这时候,git diff 命令就是你最可靠的“显微镜”——它能让你清晰地看到文件之间的差异,帮助你快速定位问题、理解变更内容。

git diff 命令是 Git 中最基础但最实用的工具之一。它不改变任何代码或提交历史,只是展示当前工作区、暂存区与提交历史之间的差异。掌握它,等于掌握了代码审查的第一步。


什么是 git diff 命令?它的核心作用是什么?

简单来说,git diff 是用来比较两个版本之间文件内容差异的命令。它能告诉你:

  • 哪些代码被添加了?
  • 哪些代码被删除了?
  • 哪些代码被修改了?

想象一下,你正在写一份重要报告。你先写了一个初稿,然后修改了部分内容,最后又做了润色。git diff 就像是你对比“初稿”和“最终稿”的时候,用荧光笔标出所有改动的地方。它不会替你改,但能让你一眼看清变化。

在 Git 中,git diff 主要用于以下三个场景:

  1. 比较工作区与暂存区的差异(未 git add 的改动)
  2. 比较暂存区与最新提交的差异(已 git add 但未 commit
  3. 比较两个提交之间的差异(比如 git diff HEAD~1 HEAD

查看工作区与暂存区的差异:未提交的修改

当你在编辑文件但还没执行 git add 时,这些改动只存在于你的工作区(working directory),尚未进入 Git 的追踪体系。这时,运行:

git diff

就会显示工作区与暂存区之间的差异。换句话说,它告诉你:当前你改了什么,但还没准备提交。

举个例子,假设你有一个 index.html 文件,内容如下:

<!DOCTYPE html>
<html>
<head>
    <title>我的网站</title>
</head>
<body>
    <h1>欢迎访问我的网站</h1>
    <p>这是第一段内容。</p>
</body>
</html>

你修改了它,加入了一个新的 <p> 标签:

<!DOCTYPE html>
<html>
<head>
    <title>我的网站</title>
</head>
<body>
    <h1>欢迎访问我的网站</h1>
    <p>这是第一段内容。</p>
    <p>这是新增的第二段内容。</p>  <!-- 新增行 -->
</body>
</html>

此时,你还没运行 git add,直接运行:

git diff

输出结果会是:

diff --git a/index.html b/index.html
index 1a2b3c4..5d6e7f8 100644
--- a/index.html
+++ b/index.html
@@ -7,3 +7,4 @@
     <p>这是第一段内容。</p>
+    <p>这是新增的第二段内容。</p>
 </body>
</html>

💡 注释

  • diff --git a/index.html b/index.html 表示比较的是同一个文件(a 是原版本,b 是新版本)
  • index 1a2b3c4..5d6e7f8 是文件的哈希值,用于内部追踪
  • @@ -7,3 +7,4 @@ 表示从第 7 行开始,原文件有 3 行内容,新文件多了 4 行
  • + 开头的行表示新增内容,- 开头的行表示删除内容

这个输出清晰地告诉你:你新增了一行 <p>这是新增的第二段内容。</p>


查看暂存区与提交历史的差异:准备提交前的“预览”

当你执行了 git add 之后,文件的修改就进入了暂存区(staging area)。此时,如果你再运行 git diff,它会不再显示工作区的改动,因为这些改动已经“被暂存”了。

但如果你想查看暂存区和上一次提交之间的差异,就要用:

git diff --cached

或者等价的写法:

git diff --staged

这两个命令效果完全一样。它们能让你在 commit 之前,预览你即将提交的内容

假设你已经执行了 git add index.html,然后又修改了 app.js 文件,加入了一个新函数:

// app.js
function greetUser(name) {
    console.log(`Hello, ${name}!`);
}

// 新增函数
function calculateSum(a, b) {
    return a + b;
}

此时运行:

git diff --cached

输出会显示 index.html 中的改动(因为它是被暂存的),但不会显示 app.js 的改动(因为它还没被 add)。

关键点
git diff → 工作区 vs 暂存区
git diff --cached → 暂存区 vs 最近提交

这就像你把要寄出的信件放进信封(add),但还没贴邮票(commit)。git diff --cached 就是让你打开信封,看看里面写了什么。


比较两个提交之间的差异:版本回溯的利器

git diff 不仅能看当前状态,还能帮你回溯历史变更。例如,你想知道上一个提交和再上一个提交之间有哪些改动,可以这样写:

git diff HEAD~1 HEAD
  • HEAD:当前最新提交
  • HEAD~1:上一个提交(即 HEAD 的父提交)

这个命令会输出两个提交之间所有文件的差异。

如果你用了更直观的命名方式,比如:

git diff master~2 master

就是比较 master 分支上倒数第三和倒数第二的提交之间的差异。

在实际项目中,这常用于:

  • 审查某个功能模块的完整变更
  • 修复某个 Bug 时,确认修改范围
  • 回顾某次发布版本的改动内容

📌 提示
你也可以用提交哈希来代替 HEAD~1,比如 git diff abc123 def456,效果一样。


常用选项与实用技巧:让 git diff 更高效

git diff 支持多种选项,下面是一些高频使用场景和技巧:

选项 作用 实际示例
--stat 只显示统计信息,不显示具体行 git diff --stat
--word-diff 以单词为单位显示差异 git diff --word-diff
-u--unified=3 显示上下文行(默认行为) git diff -u
--color=always 强制显示颜色 git diff --color=always
--name-only 只显示被修改的文件名 git diff --name-only

例如,运行:

git diff --stat

输出可能类似:

 index.html | 1 +
 app.js     | 2 ++
 2 files changed, 3 insertions(+)

这让你快速了解:改了 2 个文件,共增加了 3 行代码。适合在提交前快速检查。

再比如,想看到更精细的改动,比如一个单词被替换,可以使用:

git diff --word-diff

输出会用颜色高亮显示单词级别的修改,比如:

- 你好世界
+ 你好,世界!

这种显示方式特别适合审查文案、注释等文本内容。


实战场景:如何用 git diff 修复 Bug?

假设你在开发一个用户登录功能,发现登录失败。你怀疑是 auth.js 文件的某个函数出了问题。

  1. 先运行 git diff auth.js 查看最近的改动
  2. 发现某行代码被误删了:
- const token = generateToken(user);
+ // const token = generateToken(user);
  1. 你立刻意识到:这行是关键逻辑,被注释掉了。
  2. 你恢复代码,重新测试,问题解决。

整个过程只用了 git diff 一次,就定位到了问题根源。这就是它作为“代码显微镜”的价值。


总结:git diff 命令的使用建议

  • 每次提交前,用 git diff 检查改动内容,避免误提交
  • git diff --cached 预览将要提交的变更,确保逻辑正确
  • 结合 --stat--name-only 快速了解变更范围
  • 遇到问题时,用 git diff HEAD~1 HEAD 回溯变更历史

git diff 命令虽小,但功能强大。它不是用来“改代码”的工具,而是“看代码”的工具。掌握它,你就能在复杂代码中游刃有余,提升开发效率与代码质量。

记住:你写代码,但要先学会“看”代码git diff 就是你最贴心的助手。