差异对比与提交引用

diff 用于回答“哪里变了”。Git 里要先区分三层状态:工作区、暂存区、最近一次提交。

工作区和暂存区差异

git diff

git diff

用途:查看工作区中尚未暂存的修改。

适用场景:

  • git add 前先检查自己改了什么。
  • 修改代码后快速确认局部差异。

git diff --staged

git diff --staged

用途:查看已经暂存、即将进入下一次提交的修改。

等价常见写法:

git diff --cached

适用场景:

  • git commit 前复查提交内容。
  • 使用 git add -p 后确认选择是否正确。

git diff HEAD

git diff HEAD

用途:查看从最近一次提交到当前工作树的已跟踪路径差异,包括已暂存和未暂存内容。普通未跟踪文件不会出现在这里,仍需用 git status --short 检查。

适用场景:

  • 想一次性看“当前目录相对上次提交到底变了什么”。
  • 提交前做总览。

提交之间的差异

git show <commit>

git show HEAD~1

用途:查看某个提交的元信息和它相对父提交引入的差异。

适用场景:

  • 复查某个 commit 实际改了什么。
  • code review 前理解一条提交的具体内容。

git diff <commit> <commit>

git diff main feature/demo

用途:比较两个提交之间的内容差异。

示例:

git diff main feature-branch
git diff HEAD~3 HEAD

注意:前后顺序会影响显示方向。通常可以理解为“从第一个提交变到第二个提交”。

git diff <commit> -- <file>

git diff HEAD~1 -- README.md

用途:查看某个文件从指定提交到当前状态的变化。

适用场景:

  • 只关心一个文件,而不是整个仓库。
  • 想确认某个配置或文档相对旧版本的变化。

git diff <commit> --stat

git diff HEAD~1 --stat
git show HEAD~1 --stat

用途:查看差异摘要,而不是完整 patch。

适用场景:

  • 快速判断变更规模。
  • 交付说明中概览触及了哪些文件。

<commit> 可以怎么写

在命令中看到 <commit> 时,可以使用多种引用方式。

写法含义示例
分支名该分支当前指向的提交main
标签名某个发布或标记位置v0.1
提交 ID某次提交的哈希前缀或完整哈希3e887ab
远程分支远程跟踪分支当前位置origin/main
HEAD当前检出的提交HEAD
HEAD^当前提交的父提交HEAD^
HEAD~3当前提交往前数 3 个父提交HEAD~3

说明:

  • HEAD^^^ 和 HEAD~3 都常用来表示向前追溯 3 代父提交。
  • 合并提交有多个父提交时,^ 可以带数字选择父分支,例如 HEAD^2。
  • 使用不熟悉的引用前,可以先用 git log --oneline --graph --decorate 看图确认。
  • -- 明确分隔提交/选项与路径,可避免分支名和文件名重名时产生歧义。

最小自测

  1. git diff、git diff --staged、git diff HEAD 分别比较哪两层?
  2. 为什么 git diff HEAD~1 -- README.md 中应保留 --?
  3. 合并提交的 HEAD^1 与 HEAD^2 为什么可能指向不同父提交?