alltools.one
Development
2025-07-02
7 min
alltools.one Team
DiffText ComparisonGitCode ReviewMerge

如何比较文本文件:差异对比工具与技术

文本比较是开发者的日常工作。无论是审查代码更改、调试配置偏差还是合并文档,理解 diff 输出都至关重要。本指南涵盖了有效文本比较的算法、工具和技术。

理解 Diff 输出

经典的统一 diff 格式显示两个文件之间的更改:

--- original.txt
+++ modified.txt
@@ -1,5 +1,6 @@
 Line 1: unchanged
-Line 2: removed text
+Line 2: modified text
+Line 2.5: added line
 Line 3: unchanged
 Line 4: unchanged
-Line 5: also removed
  • - 开头的行被删除(来自原始文件)
  • + 开头的行被添加(在修改后的版本中)
  • (空格)开头的行是未更改的上下文
  • @@ 标记显示受影响的行号

Diff 算法

Myers 算法

Git 和大多数 diff 工具使用的默认算法。它寻找最短编辑脚本——将一个文件转换为另一个文件所需的最少插入和删除次数。对于大多数内容,它能产生干净、可读的 diff。

Patience Diff

对于源代码等结构化文本效果更好。它不是寻找最短编辑,而是先匹配两个文件中都出现的唯一行,然后再对它们之间的部分进行 diff。这通常能产生更有意义的 diff,与逻辑代码块对齐。

git diff --patience

Histogram Diff

Patience Diff 的改进版,自 2.x 版本以来成为 Git 的默认算法。它更好地处理重复行,对于有重大结构变化的文件产生更干净的输出。

在线文本比较

如需快速比较而无需安装工具,我们的文本差异对比工具可直接在浏览器中提供并排和内联 diff 视图。粘贴两段文本,即刻看到高亮显示的更改——所有处理均在本地完成。

命令行 Diff 工具

diff (POSIX)

经典的 Unix 工具:

# Unified format (most readable)
diff -u file1.txt file2.txt

# Side-by-side
diff -y file1.txt file2.txt

# Ignore whitespace
diff -w file1.txt file2.txt

# Recursive directory comparison
diff -r dir1/ dir2/

git diff

即使在 Git 仓库之外,git diff 也能提供更优质的输出:

# Compare two files
git diff --no-index file1.txt file2.txt

# Word-level diff (highlights changed words, not whole lines)
git diff --word-diff

# Stat summary (files changed, insertions, deletions)
git diff --stat

colordiff / delta

用于彩色终端输出:

# colordiff: drop-in replacement for diff
colordiff file1.txt file2.txt

# delta: modern diff viewer for Git
git diff | delta

用于代码审查的 Diff

有效的代码审查取决于可读的 diff。以下是提高 diff 质量的技术:

1. 保持提交聚焦

跨越数百行的大型 diff 难以审查。每个提交应只关注一个问题:

  • 将格式更改与逻辑更改分开
  • 将大型重构拆分为增量步骤
  • 在一个提交中移动文件,在另一个提交中修改

2. 使用单词级 Diff

当一行中有一个小修改隐藏在长字符串中时,行级 diff 会隐藏实际的更改:

# Shows only the changed words, not entire lines
git diff --word-diff

3. 在审查中忽略空白

格式更改给有意义的 diff 增加了噪音:

git diff -w        # Ignore all whitespace changes
git diff -b        # Ignore whitespace amount changes

4. 带上下文审查

更多的上下文行有助于理解周围的代码:

git diff -U10      # Show 10 lines of context (default is 3)

处理合并冲突

当 Git 遇到冲突的更改时,它会在文件中标记冲突:

<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 10000;
>>>>>>> feature-branch

解决步骤:

  1. 理解两个更改——各自为什么要这样改?
  2. 决定保留哪个版本,或将它们合并
  3. 删除冲突标记
  4. 测试结果

对于复杂的合并,使用三向合并工具,它可以在两个版本旁边显示共同祖先。

比较非文本内容

JSON Diff

标准文本 diff 在处理 JSON 时效果不佳,因为键顺序和格式更改会产生噪音。语义 JSON diff 比较的是实际数据结构。查看我们的 JSON Diff 工具进行结构化比较。

CSV Diff

表格数据需要列感知的比较。标准 diff 将每行视为字符串,会遗漏单元格级别的更改。

二进制文件

Diff 无法有效比较二进制文件。对于图像,使用可视化 diff 工具。对于文档,先转换为文本或使用格式特定的比较工具。

自动化中的 Diff

CI/CD 流水线

在测试中使用 diff 验证预期输出:

command_under_test > actual_output.txt
diff expected_output.txt actual_output.txt
# Exit code 0 = identical, 1 = different

配置偏差检测

将生产配置与预期状态进行比较:

diff deployed_config.yaml expected_config.yaml

文档变更追踪

追踪文档中的更改以供审查:

git diff --stat HEAD~5..HEAD -- docs/

常见问题

diff 输出中的"hunk"是什么意思?

hunk 是 diff 中一个连续的更改块。每个 @@ 行开始一个新的 hunk。Git 将相近的更改分组到单个 hunk 中——如果两个更改在 3 行之内(默认上下文),它们会出现在同一个 hunk 中。可以使用 git add -p 独立暂存各个 hunk。

如何在 Git 中比较两个分支?

使用 git diff branch1..branch2 查看两个分支之间的所有差异。添加 --stat 获取摘要,或使用 -- path/to/file 比较特定文件。要比较分支自分叉以来添加的内容,使用三个点:git diff branch1...branch2

相关资源

Published on 2025-07-02
How to Compare Text Files: Diff Tools and Techniques | alltools.one