直接用git diff 可查看从commit1到commit2的累积净变化,即两提交树对象的最终差异,而非中间逐次变更叠加;顺序必须为旧→新,否则语义反转。

git diff 怎么对比两个 commit 之间的所有变更
直接用 git diff 就能看从 commit1 到 commit2(不含)之间所有提交引入的**净变化**——也就是累积差异。Git 自动合并中间所有 patch,输出的是起点和终点工作目录/暂存区的最终差异,不是逐个 diff 叠加。
注意:这个命令默认比较的是暂存区(index)与工作目录的差异,但传入两个 commit SHA 后,它会跳过暂存区,直接比这两个 commit 对应的树对象。
-
git diff a1b2c3 d4e5f6:显示从a1b2c3到d4e5f6的完整文件变更(增删改行数、内容) - 如果想包含未跟踪文件,加
--untracked;想忽略空格变化,加-w - 不推荐用
git diff a1b2c3..d4e5f6——双点语法在某些上下文(如log)有意义,但在diff中和空格写法等价,反而容易误写成三点
如何指定“连续多个版本”而不手动找 SHA
用 git rev-parse 或符号引用替代硬编码 SHA,更可靠。比如你想看最近 3 次提交(HEAD~2 到 HEAD)的累积变化:
git diff HEAD~2 HEAD
这里的 HEAD~2 表示“当前提交的祖父提交”,即倒数第 3 个 commit(HEAD 是第 1 个,HEAD~1 是第 2 个,HEAD~2 是第 3 个),所以 HEAD~2..HEAD 覆盖了 3 个连续版本的变更总和。
覆盖宏观策略、固收研究、行业公司深度分析、量化因子、大类资产配置、可转债、市场情绪、政策快评、行业景气度追踪等34项核心研究能力,证券研究员的全能数字助手。
-
HEAD~n是最常用方式,n从 0 开始计数:HEAD~0=HEAD,HEAD~1= 上一个,以此类推 - 如果分支有 merge,
HEAD~n只走第一父提交,不会跳进其他分支历史;需要遍历所有祖先时用HEAD^n!(高级用法,一般不用) - 别用
git log -n 3输出的 SHA 手动拼接——分支重写后这些 SHA 可能失效,而HEAD~n始终指向当前视图下的相对位置
git log -p 和 git diff 的关键区别在哪
git log -p 是把每个 commit 的 diff **逐条列出**,而 git diff A B 是算出**叠加后的最终差异**。二者语义完全不同,不能互相替代。
例如:A → B 修改了 line 5;B → C 又把 line 5 改回去了。那么 git log -p A..C 会显示两条相反的 patch;但 git diff A C 的输出里 line 5 完全不会出现——因为它没变。
- 查“到底哪些行最终被改了”,用
git diff A C - 查“过程中谁在什么时候改了什么”,必须用
git log -p A..C -
git diff A..C在 diff 命令中是非法语法,会报错fatal: ambiguous argument 'A..C': unknown revision or path not in the working tree;只有log、show等命令支持双点范围
遇到 submodule 或二进制文件时 diff 会怎样
默认情况下,git diff 对 submodule 只显示 commit SHA 的变更,对二进制文件(如图片、PDF)只提示 Binary files a/file.dat and b/file.dat differ,不展开内容。
- 要深入看 submodule 内部变化,得先进入子模块目录,再运行
git diff - 对二进制文件,可用
--text强制当文本处理(有风险,可能乱码),或配外部 diff 工具(如git config --global diff.tool vimdiff) - 大仓库中,
git diff默认不递归进入未 track 的子目录;确保目标文件都在 Git 索引中,否则差异会被忽略
实际用的时候,最常踩的坑是混淆了“过程 diff”和“结果 diff”的用途——想确认重构后行为是否一致,必须看 git diff old-head new-head 的净结果;想追 bug 修改路径,就得翻 git log -p。两者不可互相代替,也别指望一个命令同时满足。










