git diff不加参数时只对比工作区与暂存区;加--cached看暂存区与head差异;用git diff head查看工作区+暂存区与最近一次commit的全部差异。

直接看差异,用 git diff 就够了;但不同场景下它默认行为不同,不加参数容易漏改、误判。
git diff 不加参数时只对比工作区和暂存区
这是最常被忽略的前提:没 git add 过的修改,git diff 才会显示;一旦 git add 了,这些改动就进了暂存区,git diff 就“看不见”它们了。
- 想看“还没暂存的修改”,直接运行
git diff - 想看“已暂存但还没 commit 的修改”,得加
--cached(或--staged):git diff --cached - 想看“工作区 + 暂存区 和最近一次 commit 的全部差异”,用
git diff HEAD
对比两个 commit 或分支用 git diff commit1..commit2
注意双点 .. 是标准写法,单点或空格容易出错。Git 会把右边 commit 当作基准,左边当作目标,显示“从右到左”的变更。
- 比较当前分支和
main分支的差异:git diff main..HEAD - 比较两个具体 commit:
git diff a1b2c3d..e4f5g6h - 如果只写
git diff main,Git 默认理解为git diff HEAD..main,即“当前分支相对于 main 的变化”——这和多数人直觉相反,容易看反
只看某个文件或目录的差异
git diff 支持路径限定,但要注意路径必须是 Git 跟踪的文件,且不能用通配符自动展开(shell 展开后可能出错)。
- 看单个文件:
git diff path/to/file.js - 看整个目录(含子目录):
git diff src/(末尾斜杠非必需,但加上更清晰) - 想排除某些类型文件(比如 .log),得配合
git config设置diff.ignoreSubmodules或用外部工具,git diff本身不支持 --exclude - 如果提示 “fatal: ambiguous argument”,通常是路径名和分支名冲突(比如有分支叫
config,又有文件叫config.js),加--显式分隔:git diff -- config.js
常用实用技巧和易踩坑点
日常高频操作里,几个小参数能省大量时间,但错用会导致信息过载或遗漏关键变更。
- 只看变动行号和函数名(方便快速定位):
git diff -p --summary,其中-p是默认行为,--summary会额外显示重命名、模式变更等元信息 - 忽略空格变化(合并 PR 前快速确认逻辑是否真变了):
git diff -w,但注意-w会同时忽略所有空白符,包括有意义的缩进调整 - Windows 用户遇到换行符警告(CRLF/LF),先检查
core.autocrlf设置,别直接用--ignore-cr-at-eol掩盖问题 -
git diff默认不递归显示子模块变更,要加--submodule才能看到子模块内 commit 变动
真正麻烦的不是命令记不住,而是搞不清“当前对比的是哪两层状态”。每次执行前,花三秒想想:我是在比工作区 vs 暂存区?还是暂存区 vs HEAD?还是两个历史节点?这个前提错了,后面所有输出都不可信。











