并非所有的比对都发生在 Git 仓库中。配置文件会手动编辑。API 响应会被粘贴到 Slack 线程中。SQL 查询会在电子表格中跨版本进行调整。当你需要查看两段文本之间确切的变更时,你需要一个差异工具——但不一定非得是 Git。
如何选择合适的工具。
需要在 Git 之外进行差异比对的情况
Git 的差异功能是当你管理文件版本时集成到工作流中的。但有许多情况并不属于这种情况:
- 配置文件 — 比较
nginx.conf变更前后的状态,尤其是当文件不在仓库中时 - API 响应快照 — 发现一周前捕获的两个 JSON 数据包之间的差异
- SQL 查询 — 比较开发环境与生产环境运行的查询
- 文档 — 审查手动编辑过的文档,再将其交付给他人
在这些情况下,你希望获得一个干净的比对结果,而无需提交或暂存文件。
Unix diff 命令:重要标志
如果你使用 Linux 或 macOS, diff 已经安装。基本用法如下:
diff file1.txt file2.txt
但默认输出较为简略。这些标志使其更易读:
# Unified format (same as Git's diff output — most familiar)
diff -u file1.txt file2.txt
# Side-by-side comparison
diff -y file1.txt file2.txt
# Ignore whitespace differences (useful for formatting changes)
diff -w file1.txt file2.txt
# Combine: unified format, ignore whitespace
diff -uw file1.txt file2.txt
示例统一输出:
--- file1.txt 2026-03-01 10:00:00
+++ file2.txt 2026-03-05 14:30:00
@@ -1,4 +1,4 @@
server {
- listen 80;
+ listen 443;
server_name example.com;
}
以 - 已被移除, + 已被添加。没有前缀的行是未变更的上下文。
三方差异:当你有三个版本时
标准差异比对两个文件。三方差异则处理第三个版本——即共同祖先。这是合并冲突解决的底层机制,即使在 Git 之外也适用。
这 diff3 命令可以处理这种情况:
diff3 mine.txt base.txt theirs.txt
这显示了 mine.txt vs base.txt中的变更,以及 theirs.txt vs base.txt 中的变更——并标记任何冲突。当两个人独立编辑同一初始文档,且需要在没有 Git 合并的情况下协调时非常有用。
程序化差异比对:Python 和 Node.js
当你需要在脚本中进行差异比对——或在应用程序中构建差异输出时,使用库而不是调用 diff.
Python — difflib:
import difflib
text1 = open("file1.txt").readlines()
text2 = open("file2.txt").readlines()
diff = difflib.unified_diff(text1, text2, fromfile="file1.txt", tofile="file2.txt")
print("".join(diff))
difflib 还包含 HtmlDiff 用于生成并排的 HTML 输出,以及 SequenceMatcher 用于计算两个字符串之间的相似度比值——这对模糊匹配非常有用。
Node.js — diff 包:
npm install diff
const Diff = require('diff');
const one = 'SELECT id, name FROM users WHERE active = 1;';
const two = 'SELECT id, name, email FROM users WHERE active = 1 LIMIT 100;';
const changes = Diff.diffWords(one, two);
changes.forEach(part => {
if (part.added) process.stdout.write('\x1b[32m' + part.value + '\x1b[0m');
else if (part.removed) process.stdout.write('\x1b[31m' + part.value + '\x1b[0m');
else process.stdout.write(part.value);
});
这 diff 库支持字符、单词、行、句子、JSON 和 CSS 的差异比对,无需额外配置。
何时使用在线工具
如果两个文件已存在于磁盘上,CLI 工具运行速度很快。但当你需要比对从两个不同来源复制的文本——例如 Slack 线程、两个 API 响应、剪贴板内容——打开终端并创建临时文件就显得过于繁琐。
基于浏览器的文本比对工具是以下情况的最快路径:
- 一次性比对,无需磁盘文件
- 与不使用终端的人共享差异比对结果
- 无需设置即可检查粘贴内容的前后变更
IO Tools 文本比对 直接在浏览器中处理,支持语法高亮,无需文件上传。粘贴两个文本,立即查看差异。
结构化数据的差异比对:JSON 和 YAML 有所不同
纯文本差异比对是逐行进行的。JSON 和 YAML 具有结构——以及格式差异(缩进、键顺序)会在标准差异中产生无意义的噪音。
对于 JSON,首先进行规范化:
jq --sort-keys . file1.json > file1_normalized.json
jq --sort-keys . file2.json > file2_normalized.json
diff -u file1_normalized.json file2_normalized.json
这会去除格式变化,仅显示真实内容的变更。对于 YAML,工具如 dyff 理解其结构,并以语义方式而非逐行报告差异。
| 使用场景 | 最佳工具 | 笔记 |
|---|---|---|
| 纯文本文件 | diff -u | 标准,适用于所有平台 |
| 终端中的并排显示 | diff -y | 宽输出,适合短文件 |
| 合并冲突(无需 Git) | diff3 | 三方比对 |
| 脚本或自动化差异比对 | Python difflib 或 Node diff | 可集成到管道或应用程序中 |
| 快速粘贴比对 | IO Tools 文本比对 | 基于浏览器,无需设置 |
| JSON 中存在格式噪音 | jq 规范化 + diff | 排序键,然后进行比对 |
| YAML | dyff, yamldiff | 结构感知,提供更准确的信号 |
何时选择哪种工具
- 两个磁盘文件 →
diff -u - 需要忽略空白字符 →
diff -uw - 需要协调三个版本 →
diff3 - 构建管道或脚本 →
difflib或diffnpm 包 - 在浏览器中比对两个粘贴内容 → IO Tools 文本比对
- 比对 JSON → 使用
jq进行规范化,然后diff - 比对 YAML → 使用
dyff
最快的方法是根据你的起点选择合适的工具。如果文本已经存在于剪贴板中,浏览器差异工具比任何终端流程都快。如果文本在文件中, diff 已经安装在你的机器上。
