提交補丁:將程式碼納入核心的基本指南

對於希望向 Linux 核心提交更改的個人或公司來說,如果不熟悉“系統”,這個過程有時可能會令人望而生畏。本文是建議的集合,可以大大增加您的更改被接受的機會。

本文件包含大量建議,格式相對簡潔。有關核心開發過程工作方式的詳細資訊,請參閱核心開發流程指南。此外,在提交程式碼之前,請閱讀Linux 核心補丁提交清單以獲取要檢查的專案列表。對於裝置樹繫結補丁,請閱讀提交裝置樹 (DT) 繫結補丁

本文件假定您正在使用git來準備補丁。如果您不熟悉git,建議您學習如何使用它,這將使您作為核心開發人員的生活以及總體上變得更加輕鬆。

某些子系統和維護者樹包含有關其工作流程和預期的額外資訊,請參閱Documentation/process/maintainer-handbooks.rst

獲取當前原始碼樹

如果您手頭沒有包含當前核心原始碼的倉庫,請使用git獲取一個。您會希望從主線倉庫開始,可以使用以下命令獲取:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

但是請注意,您可能不希望直接針對主線樹進行開發。大多數子系統維護者執行自己的樹,並希望看到針對這些樹準備的補丁。請參閱 MAINTAINERS 檔案中子系統的 T: 條目以找到該樹,如果該樹未列出,則直接詢問維護者。

描述您的更改

描述您的問題。無論您的補丁是一行錯誤修復還是 5000 行新功能,都必須有一個潛在問題促使您完成這項工作。說服評審者,這個問題值得修復,並且他們有理由閱讀第一段之後的內容。

描述使用者可見的影響。直接的崩潰和死鎖非常有說服力,但並非所有錯誤都如此明顯。即使在程式碼評審期間發現了問題,也要描述您認為它可能對使用者產生的影響。請記住,大多數 Linux 安裝執行的是來自輔助穩定樹或特定供應商/產品的核心,這些核心僅從上游挑選特定補丁,因此請包含任何有助於將您的更改路由到下游的資訊:觸發情況、dmesg 摘錄、崩潰描述、效能回退、延遲峰值、死鎖等。

量化最佳化和權衡。如果您聲稱在效能、記憶體消耗、堆疊佔用或二進位制大小方面有所改進,請附上支援這些宣告的數字。但也要描述不明顯的成本。最佳化通常不是免費的,而是 CPU、記憶體和可讀性之間的權衡;或者,當涉及到啟發式方法時,是不同工作負載之間的權衡。描述您的最佳化預期的缺點,以便評審者可以權衡成本與收益。

問題確定後,詳細描述您實際正在做的事情。用通俗易懂的語言描述更改很重要,以便評審者驗證程式碼的行為是否符合您的預期。

如果您以易於拉入 Linux 原始碼管理系統git作為“提交日誌”的形式編寫補丁描述,維護者會感謝您。請參閱標準補丁格式

每個補丁只解決一個問題。如果您的描述開始變得很長,那表明您可能需要拆分補丁。請參閱分離您的更改

當您提交或重新提交補丁或補丁系列時,請包含完整的補丁描述和理由。不要僅僅說這是補丁(系列)的第 N 個版本。不要指望子系統維護者會回溯到早期補丁版本或引用的 URL 來查詢補丁描述並將其放入補丁中。也就是說,補丁(系列)及其描述應該是獨立的。這有利於維護者和評審者。有些評審者可能甚至沒有收到補丁的早期版本。

以祈使語氣描述您的更改,例如“使 xyzzy 執行 frotz”,而不是“[此補丁] 使 xyzzy 執行 frotz”或“[我] 將 xyzzy 更改為執行 frotz”,就好像您正在命令程式碼更改其行為一樣。

如果您想引用特定的提交,請不要只引用提交的 SHA-1 ID。請同時包含提交的一行摘要,以便評審者更容易瞭解其內容。例如:

Commit e21d2170f36602ae2708 ("video: remove unnecessary
platform_set_drvdata()") removed the unnecessary
platform_set_drvdata(), but left the variable "dev" unused,
delete it.

您還應確保至少使用 SHA-1 ID 的前十二個字元。核心倉庫包含大量物件,因此與較短 ID 發生衝突的可能性很大。請記住,即使您的六字元 ID 現在沒有衝突,五年後情況也可能會改變。

如果相關的討論或更改背後的任何其他背景資訊可以在網上找到,請新增指向它們的“Link:”標籤。如果補丁是早期郵件列表討論或網上記錄的內容的結果,請指出它。

連結到郵件列表存檔時,最好使用 lore.kernel.org 訊息存檔服務。要建立連結 URL,請使用郵件的Message-ID郵件頭內容,不包括周圍的尖括號。例如:

Link: https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI

請檢查連結,確保它實際有效並指向相關訊息。

但是,請嘗試在沒有外部資源的情況下使您的解釋易於理解。除了提供郵件列表存檔或錯誤的 URL 外,還要總結導致提交補丁的討論的相關要點。

如果您的補丁修復了一個錯誤,請使用“Closes:”標籤,並附上引用郵件列表存檔或公共錯誤跟蹤器中報告的 URL。例如:

Closes: https://example.com/issues/1234

某些錯誤跟蹤器能夠在應用帶有此類標籤的提交時自動關閉問題。一些監控郵件列表的機器人也可以跟蹤此類標籤並採取某些操作。私人錯誤跟蹤器和無效 URL 是禁止的。

如果您的補丁修復了特定提交中的錯誤,例如您使用git bisect發現了一個問題,請使用“Fixes:”標籤,至少包含 SHA-1 ID 的前 12 個字元和一行摘要。不要將標籤分成多行,標籤不受“75 列換行”規則的限制,以簡化解析指令碼。例如:

Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")

以下git config設定可用於在git loggit show命令中輸出上述樣式的漂亮格式:

[core]
        abbrev = 12
[pretty]
        fixes = Fixes: %h (\"%s\")

一個示例呼叫

$ git log -1 --pretty=fixes 54a4f0239f2e
Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")

分離您的更改

將每個邏輯更改分成一個單獨的補丁。

例如,如果您的更改包括對單個驅動程式的錯誤修復和效能增強,請將這些更改分成兩個或更多補丁。如果您的更改包括 API 更新和使用新 API 的新驅動程式,請將它們分成兩個補丁。

另一方面,如果您對多個檔案進行單個更改,請將這些更改組合到一個補丁中。因此,單個邏輯更改包含在單個補丁中。

要記住的關鍵是每個補丁都應該進行易於理解的更改,並且可以由評審者驗證。每個補丁都應該有其自身的價值。

如果一個補丁依賴於另一個補丁才能完成更改,那沒關係。只需在您的補丁描述中註明“此補丁依賴於補丁 X”

將您的更改分成一系列補丁時,請特別注意確保核心在系列中的每個補丁之後都能正確構建和執行。使用git bisect來跟蹤問題的開發人員最終可能會在任何時候拆分您的補丁系列;如果您在中間引入錯誤,他們將不會感謝您。

如果您無法將補丁集濃縮為更小的補丁集,那麼每次只發布大約 15 個或更多,並等待評審和整合。

風格檢查您的更改

檢查您的補丁是否存在基本風格違規,詳細資訊可在Linux 核心編碼風格中找到。不這樣做只會浪費評審者的時間,並且您的補丁將被拒絕,可能甚至沒有被閱讀。

一個重要的例外是當代碼從一個檔案移動到另一個檔案時——在這種情況下,您不應在移動程式碼的同一補丁中修改移動的程式碼。這清楚地劃分了移動程式碼的行為和您的更改。這極大地有助於評審實際差異,並允許工具更好地跟蹤程式碼本身的歷史記錄。

在提交之前使用補丁風格檢查器(scripts/checkpatch.pl)檢查您的補丁。但是請注意,風格檢查器應被視為指導,而不是替代人工判斷。如果您的程式碼在存在違規的情況下看起來更好,那麼最好保持原樣。

檢查器報告三個級別:
  • ERROR:很可能錯誤的事項

  • WARNING:需要仔細評審的事項

  • CHECK:需要思考的事項

您應該能夠解釋補丁中所有剩餘的違規。

選擇補丁的接收者

您應始終將任何補丁抄送給其維護程式碼的相應子系統維護者和列表;查閱 MAINTAINERS 檔案和原始碼修訂歷史記錄以瞭解這些維護者是誰。scripts/get_maintainer.pl指令碼在此步驟中非常有用(將補丁路徑作為引數傳遞給scripts/get_maintainer.pl)。如果您無法找到您正在處理的子系統的維護者,Andrew Morton (akpm@linux-foundation.org) 將作為最後一道防線維護者。

linux-kernel@vger.kernel.org應預設用於所有補丁,但該列表的郵件量已導致許多開發人員將其忽略。但是,請不要向不相關的列表和不相關的人員傳送垃圾郵件。

許多與核心相關的列表託管在 kernel.org 上;您可以在https://subspace.kernel.org找到它們的列表。不過,也有在其他地方託管的與核心相關的列表。

Linus Torvalds 是所有被接受到 Linux 核心中的更改的最終仲裁者。他的電子郵件地址是 <torvalds@linux-foundation.org>。他收到很多電子郵件,而且,目前很少有補丁直接透過 Linus,所以通常您應該盡力 -避免- 給他發電子郵件。

如果您的補丁修復了可利用的安全漏洞,請將該補丁傳送到security@kernel.org。對於嚴重漏洞,可以考慮短暫的禁令,以允許分發商將補丁提供給使用者;在這種情況下,顯然,補丁不應傳送到任何公共列表。另請參閱安全漏洞

修復已釋出核心中嚴重錯誤的補丁應透過在補丁的簽名區域新增如下一行來發送給穩定版維護者:

Cc: stable@vger.kernel.org

到您的補丁的簽名區域(注意,不是電子郵件收件人)。您除了閱讀本文件外,還應該閱讀您想了解的關於 Linux -stable 版本的一切

如果更改影響使用者態-核心介面,請向 MAN-PAGES 維護者(在 MAINTAINERS 檔案中列出)傳送一個手冊頁補丁,或至少傳送更改通知,以便一些資訊能進入手冊頁。使用者空間 API 更改也應抄送給linux-api@vger.kernel.org

回應評審意見

您的補丁幾乎肯定會收到評審者關於如何改進補丁的評論,這些評論將以回覆您電子郵件的形式出現。您必須回覆這些評論;忽視評審者是反過來被忽視的好方法。您可以直接回復他們的電子郵件以回答他們的評論。那些不導致程式碼更改的評審評論或問題,幾乎肯定應該帶來一個評論或變更日誌條目,以便下一個評審者更好地理解正在發生的事情。

務必告訴評審者您正在進行的更改,並感謝他們的時間。程式碼評審是一個耗時且費力的過程,評審者有時會變得脾氣暴躁。即使在這種情況下,也要禮貌地回應並解決他們指出的問題。在傳送下一個版本時,請在封面信或單個補丁中新增一個patch changelog,解釋與之前提交的差異(參見標準補丁格式)。透過將他們新增到補丁的抄送列表中,通知對您的補丁發表評論的人有關新版本的資訊。

有關電子郵件客戶端和郵件列表禮儀的建議,請參閱Linux 電子郵件客戶端資訊

在電子郵件討論中使用修剪過的交叉回覆

在 Linux 核心開發討論中,強烈不鼓勵“頂層回覆”。交叉(或“內聯”)回覆使對話更容易跟蹤。欲瞭解更多詳情,請參閱:https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

正如郵件列表中經常引用的那樣:

A: http://en.wikipedia.org/wiki/Top_post
Q: Were do I find info about this thing called top-posting?
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

同樣,請修剪所有與您的回覆無關的不必要引用。這使得查找回復更容易,並節省了時間和空間。欲瞭解更多詳情,請參閱:http://daringfireball.net/2007/07/on_top

A: No.
Q: Should I include quotations after my reply?

不要氣餒——或不耐煩

提交更改後,請耐心等待。評審者都很忙,可能不會立即處理您的補丁。

曾幾何時,補丁常常無聲無息地消失,但現在開發過程更加順暢。您應該會在幾周內(通常是 2-3 周)收到評論;如果未發生這種情況,請確保您已將補丁傳送到正確的位置。在重新提交或“提醒”評審者之前,請至少等待一週——在合併視窗等繁忙時期可能需要更長時間。

也可以在幾周後重新發送補丁或補丁系列,並在主題行中新增“RESEND”字樣:

[PATCH Vx RESEND] sub/sys: Condensed patch summary

當您提交修改過的補丁或補丁系列版本時,不要新增“RESEND”——“RESEND”僅適用於與先前提交版本沒有任何修改的補丁或補丁系列的重新提交。

在主題中包含 PATCH

由於 Linus 和 linux-kernel 郵件列表的郵件流量很大,通常約定在主題行前加上 [PATCH]。這讓 Linus 和其他核心開發人員更容易將補丁與其他電子郵件討論區分開來。

git send-email將自動為您完成此操作。

簽署您的工作——開發者原創證書

為了更好地追蹤誰做了什麼,特別是對於那些可以透過多層維護者最終進入核心的補丁,我們引入了一個針對電子郵件傳輸補丁的“簽署”程式。

簽署是補丁解釋末尾的一行簡單文字,它證明了您編寫了它,或者以其他方式有權將其作為開源補丁進行傳遞。規則很簡單:如果您可以證明以下內容:

開發者原創證書 1.1

透過為本專案做出貢獻,我證明:

  1. 本貢獻全部或部分由我建立,我有權根據檔案中指明的開源許可提交它;或者

  2. 本貢獻基於先前的作品,據我所知,該作品受適當的開源許可保護,並且我有權根據該許可,在相同開源許可下(除非我被允許使用不同的許可)提交該作品及其修改(無論全部或部分由我建立),如檔案中所示;或者

  3. 本貢獻由其他已證明 (a)、(b) 或 (c) 的人直接提供給我,並且我未對其進行修改。

  4. 我理解並同意本專案和本貢獻是公開的,並且貢獻的記錄(包括我提交的所有個人資訊,包括我的簽署)將無限期維護,並可根據本專案或所涉及的開源許可進行再分發。

那麼您只需新增一行文字,表示:

Signed-off-by: Random J Developer <random@developer.example.org>

使用已知身份(抱歉,不接受匿名貢獻)。如果您使用git commit -s,這將自動為您完成。回滾也應包含“Signed-off-by:”。git revert -s會為您完成此操作。

有些人也會在末尾新增額外的標籤。這些標籤目前將被忽略,但您可以使用它們來標記內部公司程式或指出有關簽署的一些特殊細節。

任何在作者的 SoB 之後出現的其他 SoB (Signed-off-by:) 都來自處理和傳輸補丁的人員,但他們並未參與補丁的開發。SoB 鏈應反映補丁傳播到維護者並最終傳播到 Linus 的真實路徑,其中第一個 SoB 條目表示單個作者的主要作者身份。

何時使用 Acked-by:、Cc: 和 Co-developed-by:

Signed-off-by: 標籤表示簽署人參與了補丁的開發,或者他/她處於補丁的交付路徑中。

如果一個人沒有直接參與補丁的準備或處理,但希望表示並記錄他們對補丁的批准,那麼他們可以要求在補丁的變更日誌中新增 Acked-by: 行。

Acked-by: 旨在供以某種方式負責或參與受影響程式碼的人員使用。最常見的是,當維護者既沒有貢獻也沒有轉發補丁時,由維護者使用。

Acked-by: 也可由其他利益相關者使用,例如具有領域知識的人員(例如,被修改程式碼的原始作者)、核心 uAPI 補丁的使用者空間側評審者或功能的關鍵使用者。可選地,在這些情況下,新增“# Suffix”以闡明其含義會很有用:

Acked-by: The Stakeholder <stakeholder@example.org> # As primary user

Acked-by: 不如 Signed-off-by: 正式。它記錄了認可者至少已評審了補丁並表示接受。因此,補丁合併者有時會將認可者的“yep, looks good to me”手動轉換為 Acked-by:(但請注意,通常最好請求明確的認可)。

Acked-by: 也不如 Reviewed-by: 正式。例如,維護者可以使用它來表示他們同意補丁的落地,但他們可能沒有像提供 Reviewed-by: 那樣徹底地評審它。同樣,關鍵使用者可能沒有對補丁進行技術評審,但他們可能對總體方法、功能或使用者介面感到滿意。

Acked-by: 不一定表示對整個補丁的認可。例如,如果一個補丁影響多個子系統,並且有一個來自一個子系統維護者的 Acked-by:,那麼這通常表示只認可影響該維護者程式碼的部分。這裡需要進行判斷。如有疑問,應參考郵件列表存檔中的原始討論。在這種情況下,也可以使用“# Suffix”來澄清。

如果一個人有機會對補丁發表評論,但沒有提供此類評論,您可以選擇在補丁中新增一個Cc:標籤。此標籤記錄了潛在的利益相關方已參與討論。請注意,這是您在未經命名人員明確許可的情況下可以使用的三個標籤之一(有關詳細資訊,請參閱下文“標記人員需要許可權”)。

Co-developed-by: 表示補丁由多位開發人員共同建立;當多人共同處理一個補丁時,它用於為共同作者(除了透過 From: 標籤歸屬的作者)提供歸屬。由於 Co-developed-by: 表示作者身份,每個 Co-developed-by: 必須緊隨其後的是相關共同作者的 Signed-off-by:。標準簽署程式適用,即 Signed-off-by: 標籤的順序應儘可能反映補丁的時間歷史,無論作者是透過 From: 還是 Co-developed-by: 歸屬的。值得注意的是,最後一個 Signed-off-by: 必須始終是提交補丁的開發人員。

請注意,當 From: 作者也是電子郵件頭中的 From: 行中列出的人員(和電子郵件)時,From: 標籤是可選的。

由 From: 作者提交的補丁示例

<changelog>

Co-developed-by: First Co-Author <first@coauthor.example.org>
Signed-off-by: First Co-Author <first@coauthor.example.org>
Co-developed-by: Second Co-Author <second@coauthor.example.org>
Signed-off-by: Second Co-Author <second@coauthor.example.org>
Signed-off-by: From Author <from@author.example.org>

由 Co-developed-by: 作者提交的補丁示例

From: From Author <from@author.example.org>

<changelog>

Co-developed-by: Random Co-Author <random@coauthor.example.org>
Signed-off-by: Random Co-Author <random@coauthor.example.org>
Signed-off-by: From Author <from@author.example.org>
Co-developed-by: Submitting Co-Author <sub@coauthor.example.org>
Signed-off-by: Submitting Co-Author <sub@coauthor.example.org>

使用 Reported-by:、Tested-by:、Reviewed-by:、Suggested-by: 和 Fixes:

Reported-by 標籤用於表彰發現並報告錯誤的人員,並希望激勵他們在未來再次幫助我們。此標籤適用於錯誤;請不要用它來表彰功能請求。該標籤後應跟一個指向報告的 Closes: 標籤,除非報告在網路上不可用。如果補丁修復了所報告問題的一部分,則可以使用 Link: 標籤代替 Closes:。請注意,Reported-by 標籤是您在未經指定人員明確許可的情況下可以使用的三個標籤之一(有關詳細資訊,請參閱下文“標記人員需要許可權”)。

Tested-by: 標籤表示補丁已由指定人員(在某種環境下)成功測試。此標籤告知維護者已進行了一些測試,提供了一種在未來補丁中找到測試人員的方法,並確保對測試人員的功勞。

Reviewed-by: 則表示補丁已根據評審者宣告進行評審並被認為可接受。

評審者的監督宣告

透過提供我的 Reviewed-by: 標籤,我宣告:

  1. 我已對本補丁進行了技術評審,以評估其適合性和納入主線核心的準備情況。

  2. 任何與補丁相關的問題、疑慮或疑問都已反饋給提交者。我對提交者對我評論的回應感到滿意。

  3. 儘管本次提交可能還有改進之處,但我認為目前它(1)是對核心有價值的修改,並且(2)沒有已知的會反對其納入的問題。

  4. 儘管我已評審該補丁並認為其可靠,但我並不(除非另有明確說明)保證其能實現在任何給定情況下的既定目的或正常功能。

Reviewed-by 標籤是一種意見宣告,表示該補丁是對核心的適當修改,且沒有剩餘的嚴重技術問題。任何感興趣的評審者(已完成工作)都可以為補丁提供 Reviewed-by 標籤。此標籤用於表彰評審者,並告知維護者對補丁已進行的評審程度。由已知理解主題領域並進行徹底評審的評審者提供的 Reviewed-by: 標籤,通常會增加您的補丁被納入核心的可能性。

Tested-by 和 Reviewed-by 標籤,一旦從測試人員或評審者那裡透過郵件列表收到,作者在傳送下一個版本時應將其新增到適用的補丁中。但是,如果補丁在後續版本中發生了實質性變化,這些標籤可能不再適用,因此應將其刪除。通常,刪除某人的 Tested-by 或 Reviewed-by 標籤應在補丁變更日誌中提及(在“---”分隔符之後)。

Suggested-by: 標籤表示補丁的想法是由指定人員建議的,並確保對該想法的人員予以表彰:如果我們認真地表彰我們的想法報告者,他們有望在未來再次激勵我們提供幫助。請注意,這是您在未經指定人員明確許可的情況下可以使用的三個標籤之一(有關詳細資訊,請參閱下文“標記人員需要許可權”)。

Fixes: 標籤表示補丁修復了先前提交中的問題。它用於方便確定錯誤的來源,這有助於評審錯誤修復。此標籤還幫助穩定版核心團隊確定哪些穩定版核心版本應接收您的修復。這是指示補丁修復錯誤的推薦方法。有關更多詳細資訊,請參閱描述您的更改

注意:新增 Fixes: 標籤不會顛覆穩定版核心規則流程,也不會免除在所有穩定版補丁候選上抄送stable@vger.kernel.org的要求。有關更多資訊,請閱讀您想了解的關於 Linux -stable 版本的一切

最後,雖然提供標籤是受歡迎且通常非常受讚賞的,但請注意,簽署人(即提交者和維護者)可以酌情使用所提供的標籤。

標記人員需要許可權

在您的補丁中新增上述標籤時要小心,因為除了 Cc:、Reported-by: 和 Suggested-by: 之外的所有標籤都需要指定人員的明確許可。對於這三個標籤,如果該人員根據 lore 存檔或提交歷史記錄使用該名稱和電子郵件地址為 Linux 核心做出了貢獻——並且在 Reported-by: 和 Suggested-by: 的情況下公開進行了報告或建議——則隱式許可就足夠了。請注意,bugzilla.kernel.org 在此意義上是一個公共場所,但其中使用的電子郵件地址是私有的;因此,除非該人員在之前的貢獻中使用了它們,否則不要在標籤中暴露它們。

標準補丁格式

本節描述了補丁本身的格式。請注意,如果您的補丁儲存在git倉庫中,可以使用git format-patch獲得正確的補丁格式。然而,這些工具無法建立必要的文字,因此無論如何請閱讀以下說明。

主題行

標準補丁主題行是:

Subject: [PATCH 001/123] subsystem: summary phrase

標準補丁郵件正文包含以下內容:

  • 一行from,指定補丁作者,後跟一個空行(僅當傳送補丁的人不是作者時才需要)。

  • 解釋正文,行寬為 75 列,將複製到永久變更日誌中以描述此補丁。

  • 一個空行。

  • 上述Signed-off-by:行,也將進入變更日誌。

  • 一個僅包含---的標記行。

  • 任何不適合變更日誌的額外評論。

  • 實際補丁(diff輸出)。

主題行格式使得按主題行按字母順序對電子郵件進行排序非常容易——幾乎任何電子郵件閱讀器都支援這一點——因為序列號是零填充的,所以數字排序和字母排序是相同的。

電子郵件主題中的subsystem應標識正在打補丁的核心區域或子系統。

電子郵件主題中的summary phrase應簡潔地描述該電子郵件包含的補丁。summary phrase不應是檔名。不要對整個補丁系列中的每個補丁都使用相同的summary phrase(其中patch series是多個相關補丁的有序序列)。

請記住,您電子郵件的summary phrase成為該補丁的全球唯一識別符號。它一直傳播到git變更日誌。summary phrase以後可能會在引用該補丁的開發人員討論中使用。人們會希望透過谷歌搜尋summary phrase來閱讀有關該補丁的討論。當兩個或三個月後,他們使用gitkgit log --oneline等工具瀏覽數千個補丁時,它也將是他們可能迅速看到的唯一內容。

基於這些原因,summary長度必須不超過 70-75 個字元,並且必須描述補丁更改了什麼以及為什麼可能需要該補丁。既要簡潔又要具描述性是一項挑戰,但這正是編寫良好的摘要應該做到的。

summary phrase可以在前面加上方括號括起來的標籤:“Subject: [PATCH ...]

”。標籤不被視為摘要短語的一部分,但描述了應如何處理補丁。常用標籤可能包括版本描述符(如果針對評論傳送了多個版本的補丁,即“v1、v2、v3”),或“RFC”以表示徵求意見。

如果一個補丁系列中有四個補丁,則每個補丁可以這樣編號:1/4、2/4、3/4、4/4。這確保開發人員瞭解補丁的應用順序,並且他們已評審或應用了補丁系列中的所有補丁。

以下是一些好的主題示例:

Subject: [PATCH 2/5] ext2: improve scalability of bitmap searching
Subject: [PATCH v2 01/27] x86: fix eflags tracking
Subject: [PATCH v2] sub/sys: Condensed patch summary
Subject: [PATCH v2 M/N] sub/sys: Condensed patch summary

發件人行

from行必須是訊息正文的第一行,其格式為:

From: Patch Author <author@example.com>

from行指定誰將在永久變更日誌中被記為補丁的作者。如果from行缺失,則電子郵件頭中的From:行將用於確定變更日誌中的補丁作者。

作者可以透過在fromSoB行中新增組織名稱來表明其所屬或工作贊助商,例如:

From: Patch Author (Company) <author@example.com>

解釋正文

解釋正文將被提交到永久原始碼變更日誌中,因此對於一個有能力的讀者來說應該有意義,即使他早已忘記了可能導致此補丁的討論的即時細節。包含補丁解決的故障症狀(核心日誌訊息、oops 訊息等)對於可能正在搜尋提交日誌以查詢適用補丁的人特別有用。文字應詳細編寫,以便在數週、數月甚至數年後閱讀時,仍能為讀者提供理解為什麼建立此補丁所需的詳細資訊。

如果補丁修復了編譯失敗,可能不需要包含所有編譯失敗;只需包含足夠的資訊,以便搜尋補丁的人很可能找到它。就像在summary phrase中一樣,簡潔和具描述性都很重要。

提交訊息中的回溯資訊

回溯資訊有助於記錄導致問題的呼叫鏈。然而,並非所有回溯資訊都有用。例如,早期啟動呼叫鏈是獨一無二且顯而易見的。但是,逐字複製完整的 dmesg 輸出會新增分散注意力的資訊,例如時間戳、模組列表、暫存器和堆疊轉儲。

因此,最有用的回溯資訊應該從轉儲中提煉出相關資訊,這使得更容易關注實際問題。以下是一個修剪良好的回溯資訊的示例:

unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064)
at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20)
Call Trace:
mba_wrmsr
update_domains
rdtgroup_mkdir

評論

---標記行具有重要的作用,它為補丁處理工具標記了變更日誌訊息的結束位置。

---標記之後新增額外評論的一個好用途是提供diffstat,以顯示哪些檔案發生了更改,以及每個檔案插入和刪除的行數。diffstat對於較大的補丁特別有用。如果您要在---標記之後包含diffstat,請使用diffstat選項-p 1 -w 70,以便檔名從核心原始碼樹的頂部開始列出,並且不要佔用過多水平空間(輕鬆適應 80 列,可能有一些縮排)。(git預設生成適當的 diffstats。)

其他僅與當前時刻或維護者相關,不適合永久變更日誌的評論也應放在此處。此類評論的一個很好的例子可能是patch changelogs,它描述了補丁的 v1 和 v2 版本之間發生了什麼變化。

請將此資訊放在分隔變更日誌與補丁其餘部分的---之後。版本資訊不屬於提交到 git 樹的變更日誌。它是供評審者使用的額外資訊。如果放在提交標籤上方,則需要手動操作才能將其刪除。如果放在分隔線下方,則在應用補丁時會自動將其刪除。

<commit message>
...
Signed-off-by: Author <author@mail>
---
V2 -> V3: Removed redundant helper function
V1 -> V2: Cleaned up coding style and addressed review comments

path/to/file | 5+++--
...

有關正確補丁格式的更多詳細資訊,請參閱以下參考文獻。

顯式 In-Reply-To: 郵件頭

手動為補丁新增 In-Reply-To: 郵件頭(例如,當使用git send-email時)以將補丁與先前的相關討論關聯起來可能很有幫助,例如將錯誤修復連結到包含錯誤報告的電子郵件。但是,對於多補丁系列,通常最好避免使用 In-Reply-To: 連結到系列的舊版本。這樣,補丁的多個版本就不會在電子郵件客戶端中成為難以管理的引用森林。如果連結有幫助,您可以使用https://lore.kernel.org/重定向器(例如,在封面電子郵件正文中)連結到補丁系列的早期版本。

提供基礎程式碼樹資訊

當其他開發人員收到您的補丁並開始評審過程時,他們絕對需要知道您的工作所基於的基礎提交/分支是什麼,考慮到當前維護者樹的數量龐大。請再次注意上面解釋的 MAINTAINERS 檔案中的 T: 條目。

對於自動化 CI 流程而言,這一點更為重要,這些流程會嘗試執行一系列測試,以在維護者開始評審之前確定您提交的質量。

如果您正在使用git format-patch生成補丁,您可以透過使用--base標誌自動在提交中包含基礎樹資訊。使用此選項最簡單、最方便的方法是結合主題分支:

$ git checkout -t -b my-topical-branch master
Branch 'my-topical-branch' set up to track local branch 'master'.
Switched to a new branch 'my-topical-branch'

[perform your edits and commits]

$ git format-patch --base=auto --cover-letter -o outgoing/ master
outgoing/0000-cover-letter.patch
outgoing/0001-First-Commit.patch
outgoing/...

當您開啟outgoing/0000-cover-letter.patch進行編輯時,您會注意到它會在最底部包含base-commit:尾部資訊,這為評審者和 CI 工具提供了足夠的資訊,以便在不擔心衝突的情況下正確執行git am

$ git checkout -b patch-review [base-commit-id]
Switched to a new branch 'patch-review'
$ git am patches.mbox
Applying: First Commit
Applying: ...

有關此選項的更多資訊,請參閱man git-format-patch

注意

--base功能是在 git 2.9.0 版本中引入的。

如果您不使用 git 來格式化您的補丁,您仍然可以包含相同的base-commit尾部資訊來指示您的工作所基於的樹的提交雜湊。您應該將其新增在封面信或系列中的第一個補丁中,並且它應該放在---行下方或所有其他內容的底部,緊鄰您的電子郵件簽名之前。

確保基礎提交位於官方維護者/主線樹中,而不是僅對您可訪問的某個內部樹中——否則它將毫無價值。

工具鏈

此過程的許多技術方面可以使用 b4 自動化,文件可在 <https://b4.docs.kernel.org/en/latest/> 找到。這有助於跟蹤依賴項、執行 checkpatch 以及格式化和傳送郵件等。

參考文獻

Andrew Morton,“完美的補丁”(tpp)。

<https://www.ozlabs.org/~akpm/stuff/tpp.txt>

Jeff Garzik,“Linux 核心補丁提交格式”。

<https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html>

Greg Kroah-Hartman,“如何惹惱核心子系統維護者”。

<http://www.kroah.com/log/linux/maintainer.html>

<http://www.kroah.com/log/linux/maintainer-02.html>

<http://www.kroah.com/log/linux/maintainer-03.html>

<http://www.kroah.com/log/linux/maintainer-04.html>

<http://www.kroah.com/log/linux/maintainer-05.html>

<http://www.kroah.com/log/linux/maintainer-06.html>

核心Linux 核心編碼風格

Linus Torvalds 關於標準補丁格式的郵件

<https://lore.kernel.org/r/Pine.LNX.4.58.0504071023190.28951@ppc970.osdl.org>

Andi Kleen,“關於提交核心補丁”

提交困難或有爭議更改的一些策略。

http://halobates.de/on-submitting-patches.pdf