提交补丁:将代码融入内核的必要指南

对于希望向 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/[email protected]

请检查链接以确保其正常工作并指向相关消息。

但是,请尽量使您的解释无需外部资源即可理解。除了提供邮件列表存档或错误的 URL 之外,还要总结导致提交补丁的讨论的相关要点。

如果您的补丁修复了一个错误,请使用带有 URL 的 “Closes:” 标签来引用邮件列表存档或公共错误跟踪器中的报告。例如:

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

当应用带有此类标签的提交时,一些错误跟踪器能够自动关闭问题。一些监控邮件列表的机器人也可以跟踪此类标签并采取某些措施。禁止使用私人错误跟踪器和无效的 URL。

如果您的补丁修复了特定提交中的错误,例如您使用 git bisect 发现了一个问题,请使用带有 SHA-1 ID 的前 12 个字符和单行摘要的 “Fixes:” 标签。请勿将标签拆分到多行,为了简化解析脚本,标签不受 “在 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。对于严重的错误,可以考虑进行短暂的禁运,以便分发者可以将补丁发布给用户;在这种情况下,显然不应将补丁发送到任何公共列表。另请参阅安全漏洞

修复已发布内核中的严重错误的补丁应通过在补丁的签名区域中添加如下行来定向到稳定维护者(请注意,不是电子邮件接收者)。

您还应该阅读 关于 Linux -stable 发布的您想知道的一切 以及本文档。

如果更改影响到用户空间-内核接口,请将 MAN-PAGES 维护者(如 MAINTAINERS 文件中列出的)发送一个 man-pages 补丁,或者至少发送一个更改通知,以便一些信息进入手册页。用户空间 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 周);如果未发生这种情况,请确保您已将补丁发送到正确的位置。在重新提交或 ping 审阅者之前,请至少等待一周,在合并窗口等繁忙时段可能需要等待更长时间。

在几周后重新发送补丁或补丁系列也是可以的,并在主题行中添加“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 <[email protected]>

使用已知的身份(抱歉,不接受匿名贡献。)如果您使用 git commit -s,这将自动为您完成。还原也应包含“Signed-off-by”。 git revert -s 会为您执行此操作。

有些人还在末尾添加额外的标记。这些标记现在将被忽略,但您可以执行此操作来标记公司内部程序或仅指出有关签名的某些特殊细节。

作者签名后的任何进一步的 SoB(Signed-off-by:)都来自处理和传输补丁的人,但他们没有参与其开发。SoB 链应反映补丁在传播给维护者并最终传播给 Linus 的过程中所采用的真实路径,第一个 SoB 条目表示单个作者的主要作者身份。

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

Signed-off-by: 标记表示签名者参与了补丁的开发,或者他在补丁的交付路径中。

如果一个人没有直接参与补丁的准备或处理,但希望表示并记录他们对补丁的批准,那么他们可以要求在补丁的更改日志中添加 Acked-by: 行。

当受影响代码的维护者既没有贡献也没有转发补丁时,通常使用 Acked-by:。

Acked-by: 不如 Signed-off-by: 正式。它记录了审核者至少已经审阅过该补丁并表示接受。因此,补丁合并者有时会手动将审核者的“是,我看可以”转换为 Acked-by: (但请注意,通常最好请求明确的 ack)。

Acked-by: 不一定表示对整个补丁的确认。例如,如果一个补丁影响多个子系统,并且有一个子系统维护者的 Acked-by:,则通常表示仅确认了影响该维护者代码的部分。这里应该运用判断。如有疑问,人们应参考邮件列表存档中的原始讨论。

如果一个人有机会对补丁发表评论,但没有提供此类评论,您可以选择在补丁中添加 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 <[email protected]>
Signed-off-by: First Co-Author <[email protected]>
Co-developed-by: Second Co-Author <[email protected]>
Signed-off-by: Second Co-Author <[email protected]>
Signed-off-by: From Author <[email protected]>

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

From: From Author <[email protected]>

<changelog>

Co-developed-by: Random Co-Author <[email protected]>
Signed-off-by: Random Co-Author <[email protected]>
Signed-off-by: From Author <[email protected]>
Co-developed-by: Submitting Co-Author <[email protected]>
Signed-off-by: Submitting Co-Author <[email protected]>

使用 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: 标签不会破坏稳定内核规则流程,也不会破坏在所有稳定补丁候选者上 Cc: stable@vger.kernel.org 的要求。有关更多信息,请阅读您想了解的有关 Linux -stable 版本的一切

规范的补丁格式

本节介绍补丁本身应如何格式化。请注意,如果您将补丁存储在 git 存储库中,则可以使用 git format-patch 获得适当的补丁格式。但是,该工具无法创建必要的文本,因此请阅读下面的说明。

规范的补丁主题行是

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

规范的补丁消息正文包含以下内容

  • 指定补丁作者的 from 行,后跟一个空行(仅当发送补丁的人不是作者时才需要)。

  • 解释的正文,在 75 列处换行,它将被复制到永久变更日志以描述此补丁。

  • 一个空行。

  • 上面描述的 Signed-off-by: 行,它也将进入变更日志。

  • 一个仅包含 --- 的标记行。

  • 任何不适合变更日志的附加评论。

  • 实际的补丁(diff 输出)。

主题行格式使得按主题行字母顺序对电子邮件进行排序非常容易 - 几乎任何电子邮件阅读器都支持此操作 - 因为序列号是零填充的,所以数值和字母排序相同。

电子邮件主题中的 子系统 应标识正在修补的内核的哪个区域或子系统。

电子邮件主题中的 摘要 短语 应简洁地描述该电子邮件中包含的补丁。摘要 短语 不应是文件名。不要在整个补丁系列(其中 补丁 系列 是多个相关补丁的有序序列)中的每个补丁使用相同的 摘要 短语

请记住,您的电子邮件的 摘要 短语 将成为该补丁的全局唯一标识符。它会一直传播到 git 变更日志中。摘要 短语 稍后可能会在引用该补丁的开发人员讨论中使用。人们会想在 Google 上搜索 摘要 短语 以阅读有关该补丁的讨论。当人们在两三个月后使用 gitkgit log --oneline 等工具查看成千上万个补丁时,它也将是人们可能会快速看到的唯一内容。

由于这些原因,摘要 的长度不得超过 70-75 个字符,并且它必须描述补丁更改的内容以及补丁可能必要的理由。既要简洁又要具有描述性具有挑战性,但这就是一个写得好的摘要应该做的。

summary phrase(摘要短语)可以带有方括号括起来的标签前缀,格式如下:“主题:[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: 补丁作者 <author@example.com>

from 行指定在永久变更日志中将谁记为补丁的作者。如果缺少 from 行,则会使用电子邮件头中的 From: 行来确定变更日志中的补丁作者。

解释正文将提交到永久源代码变更日志中,因此对于那些早已忘记了可能导致此补丁的讨论的细节的读者来说,应该是有意义的。包括补丁所解决的故障症状(内核日志消息、Oops 消息等)对于那些可能在提交日志中搜索适用补丁的人来说尤其有用。文本应编写得足够详细,以便在数周、数月甚至数年后阅读时,读者可以掌握**为什么**创建此补丁的原因所需的详细信息。

如果补丁修复了编译失败,则可能没有必要包含_所有_的编译失败;只需足够让搜索补丁的人能够找到它即可。与 summary phrase(摘要短语)中一样,重要的是既要简洁又要具有描述性。

--- 标记行对于补丁处理工具来说至关重要,它标记了变更日志消息的结束位置。

--- 标记之后的其他注释的一个很好的用途是 diffstat,用于显示哪些文件发生了更改,以及每个文件插入和删除的行数。diffstat 对于较大的补丁尤其有用。如果你打算在 --- 标记之后包含 diffstat,请使用 diffstat 选项 -p 1 -w 70,以便文件名从内核源代码树的顶部列出,并且不会占用太多水平空间(可以轻松地放入 80 列,可能有一些缩进)。(git 默认会生成合适的 diffstat。)

其他只与当时或维护者相关的评论,不适合永久变更日志,也应该放在这里。此类评论的一个很好的例子可能是 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+++--
...

有关正确补丁格式的更多详细信息,请参阅以下参考资料。

提交消息中的回溯

回溯有助于记录导致问题的调用链。但是,并非所有回溯都有用。例如,早期的启动调用链是唯一的和显而易见的。但是,逐字复制完整的 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

显式 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/[email protected]>

Andi Kleen,“关于提交内核补丁”

一些使困难或有争议的更改得以实施的策略。

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