如果你曾有機會在一個使用分佈式開發模型的大型代碼庫上工作過，你就應該聽說過類似下面的話，“Sue 剛發過來一個補丁patch”，“Rajiv 正在簽出checking out差異diff”, 可能這些詞（補丁、差異文件）對你而言很陌生，而你確定很想搞懂他們到底指什麼。開源軟件對上述提到的名詞有很大的貢獻，作為大型項目從 Apache web 服務器到 Linux 內核的開發模型，“基於補丁文件的開發” 這一模式貫穿了上述項目的始終。實際上，你可能不知道 Apache 的名字就來自“一系列的代碼補丁”（LCTT 譯註：Apache 英文發音和補丁的英文 patch 相似)，它們被一一收集起來並針對原來的 NCSA HTTPd server source code 進行了修訂。
你可能認為這只不過是些逸聞，但是一份早期的 Apache 網站的存檔中 聲稱 Apache 的名字就是來自於最早的“補丁”集合；即“打了補丁的APAtCHy”服務器，簡化為 Apache。
好了，言歸正傳，程序員嘴裡說的“差異”和“補丁”到底是什麼？
現在你對補丁和差異就了一個基本的概念，讓我們來看看軟件開發者是怎麼使用這些工具的。如果你還沒有使用過類似於 Git 或 subversion 這樣的源代碼版本控制工具的話，我將會一步步展示最流行的軟件項目是怎麼使用它們的。如果你將一個軟件的生命週期看成是一條時間線的話，你就能看見這個軟件的點滴變化，比如在何時源代碼加上了一個功能，在何時源代碼修復了一個功能缺陷。我們稱這些改變的點為“提交commit”，“提交”這個詞被當今最流行的源代碼版本管理工具 Git 所使用，當你想檢查在一個提交前後的代碼變化的話，（或者在許多個提交之間的代碼變化），你都可以使用工具來觀察文件差異。
如果你同樣在使用 Git 開發軟件的話，你可以在你的本地開發環境做些希望交給別的開發者的提交，以添加到他們的源代碼樹中。為了給別的開發者你的提交，一個方法就是創建一個你本地文件的差異文件，然後將這個“補丁”發送給和你工作在同一個源代碼樹的別的開發者。別的開發者在“打”了你的補丁之後，就能看到在你的代碼變樹上的變化。
在繼續我們的話題之前，我們當然不能忽略和補丁和差異這個概念相關的最流行的服務：GitHub。從它的名字就能猜想出 GitHub 是基於 Git 的，而且它還圍繞著 Git 對分佈式開源代碼開發模型提供了基於 Web 和 API 的工作流管理。（LCTT 譯註：即拉取請求Pull Request）。在 GitHub 上，分享補丁的方式不是像 Linux 內核社區那樣通過郵件列表，而是通過創建一個 拉取請求 。當你提交你自己的源代碼樹的改動時，你能通過創建一個針對軟件項目的共享倉庫的“拉取請求”來分享你的代碼改動（LCTT 譯註：即核心開發者維護一個主倉庫，開發者去“復刻fork”這個倉庫，待各自的提交後再創建針對這個主倉庫的拉取請求，所有的拉取請求由主倉庫的核心開發者批准後才能合入主代碼庫。）GitHub 被當今很多活躍的開源社區所採用，如 Kubernetes、Docker、容器網絡接口 (CNI)、Istio 等等。在 GitHub 的世界裡，用戶會傾向於使用基於 Web 頁面的方式來審核一個拉取請求裡的補丁或差異，你也可以直接訪問原始的補丁並在命令行上直接使用它們。
我們前面已經講了在流行的開源社區裡是怎麼應用補丁和差異的，現在看看一些例子。
……下面是 diff 命令的輸出：
如果你想找人來測試你的代碼改動，你可以將差異保存到一個補丁裡：
現在你有補丁 myfixes.patch 了，你能把它分享給別的開發者，他們可以將這個補丁打在他們自己的源代碼樹上從而得到和你一樣的代碼並測試他們。如果一個開發者的當前工作目錄就是他的源代碼樹的根的話，他可以用下面的命令來打補丁：
現在這個開發者的源代碼樹已經打好補丁並準備好構建和測試文件的修改了。那麼如果這個開發者在打補丁之前已經改動過了怎麼辦？只要這些改動沒有直接衝突（LCTT 譯註：比如改在同一行上），補丁工具就能自動的合併代碼的改動。例如下面的interest.go 文件，它有其它幾處改動，然後它想打上 myfixes.patch 這個補丁：
在這個例子中，補丁警告說代碼改動並不在文件原來的地方而是偏移了 15 行。如果你文件改動的很厲害，補丁可能乾脆說找不到要應用的地方，還好補丁程序提供了提供了打開“模糊”匹配的選項（這個選項在文檔裡有預置的警告信息，對其講解已經超出了本文的範圍）。
如果你使用 Git 或者 GitHub 的話，你可能不會直接使用補丁或差異。Git 已經內置了這些功能，你能使用這些功能和共享一個源代碼樹的其他開發者交互，拉取或合併代碼。Git 一個比較相近的功能是可以使用 git diff 來對你的本地代碼樹生成全局差異，又或者對你的任意兩次”引用“（可能是一個代表提交的數字，或一個標記或分支的名字，等等）做全局補丁。你甚至能簡單的用管道將 git diff 的輸出到一個文件裡（這個文件必須嚴格符合將要被使用它的程序的輸入要求），然後將這個文件交給一個並不使用 Git 的開發者應用到他的代碼上。當然，GitHub 把這些功能放到了 Web 上，你能直接在 Web 頁面上查看一個拉取請求的文件變動。在 Web 上你能看到所展示的合併差異，GitHub 還允許你將這些代碼改動下載為原始的補丁文件。
好了，你已經學到了”差異“和”補丁“是什麼，以及在 Unix/Linux 上怎麼使用命令行工具和它們交互。除非你還在像 Linux 內核開發這樣的項目中工作而使用完全基於補丁文件的開發方式，你應該會主要通過你的源代碼控制系統（如 Git）來使用補丁。但熟悉像 GitHub 這樣的高級別工具的技術背景和技術底層對你的工作也是大有裨益的。誰知道會不會有一天你需要和一個來自 Linux 世界郵件列表的補丁包打交道呢？