git diff三大核心场景:无参数比工作区与暂存区;--staged比暂存区与head;commit1 commit2比任意两版本,顺序决定“b相对于a的变更”。

直接用 git diff 就能解决绝大多数版本差异比较需求,但不同参数组合对应完全不同的比较对象——选错参数,看到的就不是你想要的“两个版本之间”的差异。
git diff 三个核心比较场景怎么选
命令长得像,行为差别大,关键看你要比什么:
-
git diff(无参数):只比工作目录和暂存区(index)之间的改动。改了文件但没git add?它能看见;git add之后再改?它只显示第二次改的部分。 -
git diff --staged(或git diff --cached):比暂存区和最后一次提交(HEAD)之间的差异。也就是“我准备好要提交的内容”和“上次提交”差在哪。 -
git diff commit1 commit2:真正在比两个任意历史版本。commit 可以是哈希、分支名、HEAD~2这类相对引用。注意顺序:git diff A B表示“B 相对于 A 做了哪些修改”,即从 A 到 B 的变更。
文件级精确对比:带路径和冒号的写法
想单独看某个文件在两个版本里的变化?别只靠 git diff branch1 branch2 然后手动翻——容易漏、难定位:
GInstall OneClick — 一键安装 GitHub 项目:规划、克隆、安装 Node 依赖、运行开发脚本。适用于想要获取 GitHubNode.js 项目的用户。
- 比两个提交中同一文件:
git diff commit1:src/utils.py commit2:src/utils.py。注意冒号前不能有空格,且路径是相对于仓库根目录的。 - 比当前工作目录和某次提交的某个文件:
git diff commit1:src/utils.py src/utils.py。左边是历史版本,右边是本地文件(可省略为.,但显式写更安全)。 - 错误示范:
git diff branch1 branch2 src/utils.py—— 这其实等价于git diff branch1..branch2 -- src/utils.py,只显示在 branch2 中有、branch1 中没有的提交所引入的该文件改动,不是“两个快照的直接对比”。
输出控制与算法选择:什么时候需要调参数
默认输出够用,但遇到以下情况就得动手:
- 上下文太少看不清逻辑?加
-U5把上下文行数提到 5 行:git diff -U5 HEAD~1 HEAD。 - 大文件重排版导致差异块巨大?试试
--histogram或--patience:git diff --histogram HEAD~1 HEAD。它们比默认的myers算法更擅长识别移动/重排代码块。 - 只想看改了哪些文件,不关心内容?用
--name-only或--stat:git diff --stat main feature/login。 - 导出补丁给同事审阅?加
--output=patch.diff:git diff --output=api-change.patch main feature/api-v2。
容易被忽略的边界点
这些细节不注意,结果会和预期严重不符:
-
git diff branch1..branch2和git diff branch1...branch2不是一回事:..是“branch2 相对于 branch1 的全部差异”,...是“branch1 和 branch2 分叉后各自独有的差异”,即三方比较,常用于 PR 审查前确认真正新增内容。 - 使用
git diff-tree时,它默认只处理树对象(tree),不自动解析 commit。想直接比两个 commit?得加-r(递归)或用git diff更稳妥。 - 所有
git diff命令默认忽略未跟踪文件(untracked)。如果想包含它们,必须显式加上-o(--others)或改用git status -u配合判断。










