git diff 是什么
git diff 比较两个状态之间的差异,默认比较工作区与暂存区,所以它显示的是「改了但还没 add」的那部分。它是提交前自查的基本视角:改了什么、有没有顺手改到别处、有没有残留调试代码,读 diff 比逐个打开文件直接得多。
比较对象由参数决定
不带参数时是工作区对暂存区;加 HEAD 变成工作区对最近一次提交,能看到全部未提交的变化;加 --staged(等价 --cached)则是暂存区对 HEAD,也就是这次会提交什么;写两个提交名或分支名,就变成任意两个历史点之间的比较。三个视角合起来才能看清提交前后的全貌。
基本信息
| 适用平台 | Linux / macOS / Windows(Git 2.x) |
|---|---|
| 语法 | git diff [选项] [<提交>] [<提交>] [--] [路径] |
| 默认比较 | 工作区 vs 暂存区,只含未暂存部分 |
| 常用参数 | --staged 暂存区对 HEAD;--stat 摘要;--name-only 只列文件名 |
| 路径过滤 | 放在 -- 之后,可与分支名消歧 |
| 是否只读 | 只读操作,不修改仓库状态 |
典型使用场景
- 提交前自查:通读未暂存改动,确认没有多余内容
- 复核待提交:用 --staged 检查这次提交的实际内容
- 看整体差异:用 HEAD 视角确认相对上次提交的全部变化
- 评审前摸底:先 --stat 看规模,再安排阅读顺序
- 跨版本对比:比较两个标签或分支之间的差异
- 生成补丁:把 diff 输出存成文件,在另一处用 git apply 应用
常用示例
常用示例
git diff # 未暂存的改动(工作区对暂存区)
git diff HEAD # 全部未提交变化(工作区对最近提交)
git diff --staged # 这次提交会包含的内容
git diff --stat # 只给每个文件的增删摘要
git diff -- src/app.py # 只看某个文件的差异
git diff v1.4.0 v1.5.0 # 两个版本之间的差异
git diff --word-diff # 按词比较,适合文档与超长行
git diff > change.patch # 导出为补丁文件备用三种比较视角
| 命令 | 比较对象 | 用来回答什么 |
|---|---|---|
| git diff | 工作区 vs 暂存区 | 我改了但还没 add 的是什么 |
| git diff --staged | 暂存区 vs HEAD | 这次提交会带上哪些改动 |
| git diff HEAD | 工作区 vs HEAD | 相对上次提交我一共改了什么 |
| git diff A B | 任意两个提交之间 | 从 A 到 B 之间发生了什么 |
| git diff A..B | 与两个参数写法等价 | 最常用的比较写法 |
| git diff A...B | B 自共同祖先以来的改动 | 看分支相对主干新增了什么 |
提交前的固定组合:先 git diff 看还没暂存什么,再 git diff --staged 看这次会提交什么,两个视角都确认过再执行 commit。
文件只改了工作区、还没 add 时,git diff --staged 输出为空。看到空白不要以为改动丢了,用不带参数的 git diff 检查即可确认。
二进制文件(图片、压缩包、可执行文件)默认只显示一行摘要,无法逐行对比,需要专门的二进制比对工具,或先转成可读的文本格式。
diff 输出是标准补丁格式,可重定向保存后用 git apply 或 patch 应用到另一份代码上,跨环境迁移或临时同步改动时很方便。
补丁文本怎么读
diff 输出开头是文件路径与模式变化;每个修改块以 @@ 开头,括号里的数字表示新旧行号范围;减号开头是旧内容,加号开头是新内容,空格开头是未改动的上下文行。上下文默认显示三行,用 -U 可以调整:排查大范围改动时加 -U0 能让输出只剩真正的改动行,更容易扫读。
加 -w 可以忽略空白差异,加 --color-words 能按词高亮;文档与配置文件里整行重排的情况,用这两个选项能大幅减少噪声。