guide/whitespace-options.md

忽略空白选项的区别 — diff -b、-w、-B、-Z 与 git 的对应选项

结合 GNU diff、git 选项和示例,比较忽略行尾空白、忽略空白数量(-b)、忽略所有空白(-w)、忽略空行(-B)、忽略大小写之间的确切区别。

最后更新: 2026-09-23

两个文件“内容明明一样”,diff 却报出一大堆差异,很多时候是空白造成的:编辑器删掉了行尾空格、把制表符换成了空格,或者改了缩进宽度。diff 工具提供了忽略这类差异的选项,但每个选项忽略的范围各不相同,需要准确了解后再用。

GNU diff 的空白相关选项

选项长选项名忽略的内容
-Z--ignore-trailing-space行尾的空白
-E--ignore-tab-expansion制表符展开为空格造成的差异
-b--ignore-space-change空白数量的变化、行尾空白
-w--ignore-all-space所有空白
-B--ignore-blank-lines只新增或删除空行的变更
-i--ignore-case大小写
--strip-trailing-cr输入行末尾的 CR 字符

git diff 的对应选项

git 文档的说明如下:

-b 与 -w 的关键区别

这两个选项经常被混淆。关键在于是否区分空白“有/没有”。

左侧右侧-b(忽略空白数量)-w(忽略所有空白)
a ba b相同相同
a bab不同相同
x = 1x=1不同相同
if (a) + 行尾空白if (a)相同相同
用 1 个制表符缩进用 4 个空格缩进相同相同

-b 是把每段连续空白压缩成一个空格来看,-w 则是把空白全部删掉来看。所以 -w 会认为 x = 1x=1 相同,甚至 int ainta 也相同。

缩进有语法意义时的风险

在 Python、YAML、Makefile 这类缩进属于语法的文件中,忽略空白的选项可能会掩盖真正的修改。

if ready:
    start()
    notify()
if ready:
    start()
notify()

在第二段中,notify() 被移出了 if 语句,行为已经改变;但用 -w 比较时空白被全部删除,差异就消失了。-b 则能发现它,因为行首空白从“有”变成了“没有”。不过,如果缩进从 4 个空格变成 8 个空格、代码被移进了更深一层的代码块,那只是空白的数量变了,-b 也看不出来。

稳妥的做法是:对缩进很重要的文件,关闭空白选项再比较。空白选项用来确认“是否只是整理了格式”,最终检查则养成不加选项的习惯,这样更安全。

忽略空行(-B)的范围

-B 和 git 的 --ignore-blank-lines 会隐藏仅由空行构成的变更。如果新增的空行与其他实际修改位于同一个 hunk 中,这些空行仍可能照常显示。这对调整了段落间空行数量的文档,或代码格式化工具调整了函数间空行的情况很有用。

本站选项对照表

本站相近的 GNU diff相近的 git diff
空白:按原样比较(无选项)(无选项)
空白:忽略行尾空白-Z--ignore-space-at-eol
空白:忽略空白数量-b-b
空白:忽略所有空白-w-w
忽略大小写-i(无对应)
忽略空行类似 -B(空行不参与比较)类似 --ignore-blank-lines
统一换行符--strip-trailing-cr + 忽略结尾换行符类似 --ignore-cr-at-eol

本站的“忽略空行”会把空行完全排除在比较之外,只用浅色显示。此外,忽略选项同样作用于行内高亮:开启“忽略空白数量”后,只有空格数量不同的部分不会被高亮。

在本工具中试一试

把上表中的例子放进 文本对比工具,逐个切换空白选项,就能立刻看到区别。行尾的 CR、文件末尾换行符等“看不见的差异”请参阅 换行符与看不见的差异,把结果当作 patch 阅读的方法请参阅 unified diff 阅读指南

前往文本对比工具