在线工具集

文本对比 diff 完全指南:行级 / 词级 / 三方合并

经典 diff 算法(Myers 1986 LCS 最长公共子序列)、统一 diff 格式、字符级 vs 词级 vs 行级差异、两人协作版本对比、HTML 渲染红绿对照、三方合并冲突。

✍️ XTechTools 编辑团队 · 📅 发布 2026-04-29 · 🔄 更新 2026-06-14 · ⏱ 约 9 分钟阅读 ·→ 立即使用 文本对比

Diff(文本差异对比)是版本管理、代码审查、文档追踪的基础工具。从 Git commit 到 GitHub Pull Request,从法律合同到论文修订,每处都需要快速定位两个版本的差异在哪。但 diff 看起来简单,背后涉及复杂的算法选择:行级还是词级?字符级粒度如何权衡?三方合并冲突怎么解决?本指南讲清楚 Myers 1986 算法原理、统一 diff 格式、多粒度对比应用、Git 集成关系、冲突解决策略全套知识。

经典 diff 算法:Myers 1986

Diff 问题的本质是找两个文本的「最长公共子序列」(LCS, Longest Common Subsequence),然后推断出编辑操作(增、删、改)。最著名的高效算法是 1986 年 Eugene Myers 提出的。

LCS 的思想

文本 A:"cat" → 文本 B:"car"

最长公共子序列是 "ca"(2 个字符),说明第 3 个字符不同。从这个差异可以推断:删除 "t",插入 "r"。

Myers 算法的优势 - 时间复杂度 O((N+M)*D),其中 N、M 是两文本长度,D 是编辑距离。当差异少时快速。 - 产生更「直观」的 diff 结果:优先找最小变化集。 - Git、GNU diff、很多在线 diff 工具都用这个算法或其变种。

算法的限制 - 无法理解「语义」。改变变量名、重新排列函数顺序,算法只看到字符层面的变化。 - 对某些格式(如 JSON、XML)效果不如专用解析器。

实用认识:不需要理解算法细节,但要知道:diff 是基于「最小编辑操作」的启发式匹配,不是完美的「语义理解」。

统一 diff 格式(Unified Diff)

Unified diff 是最通用的 diff 格式,由 GNU diff 推广,成为了事实标准。

格式示例

--- a/file.txt
+++ b/file.txt
@@ -1,5 +1,6 @@
 line 1
 line 2
-line 3 old
+line 3 new
+line 3.5 inserted
 line 4
 line 5

字段说明 - --- a/file.txt:源文件标记 - +++ b/file.txt:目标文件标记 - @@ -1,5 +1,6 @@:修改范围(源文件第 1 行起 5 行,目标文件第 1 行起 6 行) - line(行首空格):不变行 - -line old:删除行 - +line new:新增行

优点 - 紧凑(相比 side-by-side 节省空间)。 - 包含上下文(默认前后各 3 行),便于人工审查。 - 大多数工具都支持导入导出。

缺点 - 删除和新增分开显示,对于整行替换的场景不如红绿对照直观。 - 对二进制文件无效。

字符级 vs 词级 vs 行级对比

同一个差异,在不同粒度下呈现方式完全不同。选择合适的粒度至关重要。

行级对比(Line-based)

例如改变一行的一个变量名:

-const userName = "Alice";
+const username = "Alice";

整行都被标记为删除 + 新增,虽然只改了一个字符。行级对比是 Git diff 的默认模式,优点是: - 简单、快速。 - 对代码改动够用(函数、块级修改)。 - 大文件处理高效。

词级对比(Word-based)

Git 提供 --word-diff 选项:

const user{name→ username} = "Alice";

高亮显示单词级的替换,更直观。适合: - 文档修订(论文、合同)。 - 变量重命名(看清楚变了什么)。 - 需要高精度审查的代码。

字符级对比(Character-based)

最细粒度,逐字符对比:

const user[nameusername] = "Alice";

某些在线 diff 工具(如本站 diff 工具)支持。优点: - 对单词拼写修正特别有用。 - 对配置文件的细微改动一目了然。

缺点: - 可能过度细粒度(如 HTML 标签变化显示得很碎)。 - 本站工具提供三种粒度切换。

选择建议:代码默认行级;文档改动用词级;配置文件和数据用字符级。

两人协作的版本对比与 Git diff

在团队协作中,Git diff 是最标准的版本对比工具。本站 diff 工具的差异和相似:

本站 diff 工具的优势 - 在线粘贴,无需 Git 命令行。 - 支持多种粒度(行/词/字符)切换。 - 实时对比,无延迟。 - 清晰的红绿 HTML 渲染。 - 支持大文本(某些场景超过 Git 的性能)。

本站工具的局限 - 无上下文(Git log、commit 信息)。 - 无法追踪文件移动、重命名。 - 不支持二进制 diff。 - 只比对内容,不涉及版本管理逻辑。

Git diff 的优势 - 集成整个版本历史。 - git diff HEAD~1 看前一次 commit;git diff branch1..branch2 看分支差异。 - 支持 patch 应用和分阶段提交。 - 配合 --stat 显示改动统计,--word-diff 词级对比。

实战选择 - 快速对比临时文本(如两份 API 响应、两个配置版本):用本站工具。 - 代码审查和版本历史追踪:用 Git diff 和 GitHub PR。 - 法律合同、论文修订稿的精细对比:用词级本站工具或 Word Track Changes。

互补关系,不是竞争。

三方合并与冲突解决

当两个分支都修改了同一文件时,需要「三方合并」(three-way merge)来自动尽量地合并,剩余冲突由人工解决。

三方合并的逻辑

假设 base(合并基点)、ours(我的版本)、theirs(他人版本)三个版本:

base:    "Hello World"
ours:    "Hello Bob"
theirs:  "Hi World"

Git 会分析: - "Hello" vs "Hi":第一个词在 theirs 改了。 - "World" vs "Bob":第二个词在 ours 改了。 - 两处改动互不影响,Git 可以自动合并为 "Hi Bob"。

冲突的情况

base:    "Hello World"
ours:    "Hello Bob"
theirs:  "Hello Alice"

两个版本都改了第二个词,Git 无法决定该选哪个,标记为冲突:

<<<<<<<< HEAD
Hello Bob
========
Hello Alice
>>>>>>>> feature-branch
  1. 接受当前变更(ours):保留我的版本,丢弃他人的。
  2. 接受传入变更(theirs):保留他人的,丢弃我的。
  3. 合并两者:如果能有意义地结合,如:"Hello Bob and Alice"。
  4. 手动编辑:选择代码片段的最佳组合,或重写。

现代 IDE(VS Code、JetBrains)提供可视化的冲突编辑器,比命令行舒适。

最佳实践 - 频繁 rebase 或 merge,避免分支偏离太远。 - 分支粒度要小(一个功能一个分支)。 - 在团队中约定:谁负责解决这个文件的冲突。 - 冲突解决后务必本地测试(compile + test),确保合并逻辑正确。

常见问题

Diff 工具生成的结果为什么有时候看起来不合理?

因为 diff 是基于行级的最小编辑距离算法,不理解代码语义。比如把 5 行函数挪到另一处,diff 会显示删除 5 行 + 添加 5 行。如果想看结构性变化,用 IDE 的「代码导航」功能或 AST diff 工具(如 comby)。

本站 diff 工具和 git diff 可以互换吗?

不能。本工具适合快速对比两个文本片段;git diff 适合版本历史和分支对比。如果需要完整的版本追踪和 log,必须用 Git。

词级对比和行级对比哪个更准确?

都不是「更准确」,而是粒度不同。词级看得更细,但可能过度细分;行级简洁但丢失细节。选择应该基于使用场景,而不是粒度多少。

三方合并失败了怎么办?

说明 Git 无法自动合并,需要人工干预。用 IDE 或 `git mergetool` 打开冲突编辑器,选择保留哪部分代码。合并后一定要编译 + 测试,确保功能正确。

能对比两个很大的文件吗?

理论上可以,但取决于工具的内存和算法。本站工具支持几 MB 的文本;超过这个量建议用 Git 的 `--stat` 看改动统计,或分块对比。

有办法让 diff 忽略空白符或注释吗?

Git 支持 `-w` 选项忽略所有空白,`-b` 忽略空白变化。本工具暂不支持,但可以手动删除不关心的行后再对比。