如何閱讀 Diff 輸出:了解修補檔案與變更內容
Diff 輸出是版本控制系統的通用語言。每位開發者都會經常遇到 diff 輸出——在程式碼審查時、解決合併衝突時,或是在套用開源貢獻的修補檔案時。然而許多開發者從未學會有效地閱讀 diff 輸出。
本指南將說明如何閱讀最常見格式的 diff 輸出、修補檔案如何運作,以及如何自信地解讀變更內容。
什麼是 Diff 輸出?
Diff 輸出是兩個檔案或檔案集合之間差異的結構化表示。由 Douglas McIlroy 於 1970 年代在貝爾實驗室建立的 diff 工具,至今仍是 Git、Mercurial 和大多數其他版本控制系統的基礎。
當您執行 git diff 或任何 diff 命令時,輸出會精確顯示變更了什麼、在哪裡變更以及如何變更——以人類和機器都能讀取的格式呈現。
了解 Unified Diff 格式
Unified diff 格式是當今最廣泛使用的輸出格式。它將變更分組為 hunks,每個 hunk 前面有上下文行,幫助您在檔案中定位變更位置。
Hunk 標頭的結構
每個 hunk 以類似以下的標頭開始:
@@ -start,count +start,count @@
讓我們來拆解它:
| 部分 | 意義 |
|------|---------|
| @@ | 標記 hunk 開始的分隔符號 |
| -3,7 | 在原始檔案中,此 hunk 從第 3 行開始,跨越 7 行 |
| +3,8 | 在新檔案中,此 hunk 從第 3 行開始,跨越 8 行 |
| @@ | 結束分隔符號 |
標頭後面的上下文行(通常是函數名稱或附近的註解)可幫助您識別變更屬於檔案的哪個部分。
Hunk 中的行
Hunk 中的每一行都以單個字元為前綴:
上下文行(未變更)
-被刪除的行(存在於新檔案,舊檔案中不存在)
+新增的行(存在於新檔案,舊檔案中不存在)
- 上下文行以空格開頭。這些行在兩個版本中完全相同,提供參考點。
- 被刪除的行以減號(
-)開頭。這些行存在於舊檔案中但已被刪除。 - 新增的行以加號(
+)開頭。這些行在變更後的檔案中是新的。
實際範例
以下是顯示函數被修改的 diff:
@@ -5,7 +5,9 @@
def greet(name):
- print("Hello, " + name)
- print("Welcome!")
+ message = f"Hello, {name}!"
+ print(message)
+ print("We are glad to see you.")
+
if name == "admin":
print("You have admin privileges.")
解讀此 diff:
- 舊版本列印 "Hello, " 加上名稱,然後是 "Welcome!"。
- 新版本建立一個格式化訊息字串、列印它、新增一行額外的問候語,並保持管理員檢查不變。
- 兩行被刪除(
-行),三行被新增(+行),而空白的+行保留了空行以便閱讀。
修補檔案:可套用的 Diff
修補檔案就是將 diff 儲存到檔案中——通常使用 .patch 或 .diff 副檔名。修補檔案是一種可攜式的方式,用來分享變更而無需分享整個程式碼庫。
建立修補檔案
使用 Git,從最新提交建立修補檔案:
git format-patch HEAD~1
或從未提交的變更建立修補檔案:
git diff > my-changes.patch
套用修補檔案
將修補檔案套用到目標儲存庫:
git apply my-changes.patch
或使用傳統的 patch 命令:
patch -p1 < my-changes.patch
-p1 參數會從檔案路徑中剝離第一個目錄組件,以解決修補檔案建立者與套用者之間的目錄結構差異。
常見的 Diff 輸出格式
除了 unified diff 之外,您可能還會遇到以下格式:
Normal Diff
原始 diff 命令的預設輸出。變更以指令形式顯示,使用 a(新增)、c(變更)和 d(刪除)等命令來表示變更、新增或刪除行。
3c3
< Hello world
---
> Hello beautiful world
Context Diff
一種較舊的格式,在每個變更周圍提供三行上下文。使用驚嘆號來表示已變更的行。
並排 Diff
不是單一檔案格式——而是並排顯示兩欄。這在圖形化差異工具和線上差異檢查器中很常見。
在程式碼審查中閱讀 Diff 輸出
審查 pull request 時,關注以下元素:
- Hunk 標頭:它們告訴您哪些檔案和函數受到影響。
- 新增與刪除行的比例:關鍵檔案中有大量變更時需特別留意。
- 上下文行:它們顯示周圍的邏輯,幫助您評估變更是否正確。
- 僅空白字元的變更:許多差異工具以不同方式標示這些變更,因為它們可能使審查變得混亂。
解讀 Diff 的最佳實踐
- 從上到下、逐個檔案閱讀 diff——這符合變更的順序。
- 注意修改程式碼附近未變更的上下文行;它們揭示了新舊程式碼之間的結構關係。
- 使用支援在 diff 檢視中語法高亮的工具——顏色使模式更容易被發現。
- 審查大型 diff 時,從測試檔案開始,了解作者想要變更什麼行為。
了解 diff 輸出是協作開發的基礎技能。一旦您能夠熟練地閱讀 diff,您將更加自信地進行程式碼審查、解決合併衝突和處理修補檔案。