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

如何比較文字檔案:Diff 工具與技巧

比較文字是開發者的日常工作。無論是審查程式碼變更、除錯組態差異,還是合併文件,理解 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 工具

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