近日,Linux 领袖 Linus Torvalds 在邮件列表上对 Rust 代码格式检查表达了强烈不满,引发开源社区对自动化工具、代码风格与内核维护流程的广泛讨论。事件起因于最近针对 DRM 子系统的补丁合并请求,在审阅其中为 Linux 6.18 引入的 Rust 代码时,Torvalds 既对补丁的文本排版表示不悦,也对 rustfmtcheck 的自动格式化决策提出严厉批评。此事不仅呈现了风格偏好之争,更暴露出自动化格式化工具在大型项目协作中的权衡与挑战。本文将从事件细节、技术根源、对内核维护的影响、可行的改进方向等角度做深入解析,帮助开发者和项目维护者理解问题并找到务实的解决思路。 事件回顾与核心争议 在一次针对 DRM 子系统的合并请求评审中,Torvalds 首先指出补丁描述文本的排版混乱,认为提交者在编辑或粘贴时丢失了多级缩进,导致说明难以阅读。随后他把视角转向 Rust 代码本身,特别是关于 use 导入语句的格式化处理。
原补丁中,代码作者将多个独立的导入写为多行的单独 use crate::xyz; use crate::abc;,为了方便后续添加与维护,某些地方又被组织为多行的大括号形式 use crate::{ xyz, abc, };。Torvalds 本意是统一并使之更便于扩展,但在运行 rustfmtcheck 后,工具却把很多内容压缩为单行形式 use crate::{xyz, abc};,这种不稳定且看似随机的折行策略令他感到极度恼火,并称之为"完全疯狂"的格式检查。 核心争议并非单纯的好恶之争,而在于自动化工具采用的启发式规则在长期维护与合并冲突处理方面带来的真实成本。Torvalds 指出,当工具在不同情况下采取不同合并或折行策略时,代码历史会包含大量格式调整的噪音,给补丁合并、冲突解决与未来维护带来额外负担。简单地说,工具在"瞬时正确"与"长期可维护"之间做了令维护者难以接受的选择。 自动格式化的利弊与本质权衡 自动格式化工具在现代软件开发中极为普遍,其核心价值在于消除风格争议、统一代码风格、降低审查时对排版细节的关注,从而把注意力集中到设计与逻辑上。
rustfmt 对 Rust 代码的广泛应用正是基于这一理念:统一风格可以提高可读性,并且通过 CI 强制执行可以避免个人风格引起的无谓争论。 然而,任何自动化工具都需要做出规则选择,规则本身不可避免会包含启发式判断。对于 import 语句的合并策略,工具要在简洁性与可扩展性的目标之间取舍。将多个导入合并为花括号形式通常能减少重复前缀,记录更紧凑;而将导入拆成独立行则在对单一导入的添加或删除时只会影响一行,diff 更清晰、冲突更易处理。rustfmt 的默认行为在某些场景下选择了紧凑格式,这对于追求简短代码的人来说是有利的,但对于维护大型、频繁变动的内核代码库,Torvalds 认为更倾向于可扩展且易于维护的多行单独导入。 为何内核项目与 rustfmt 的冲突较为敏感 Linux 内核是一个高度模块化、贡献者众多、补丁频繁的项目。
其开发流程依赖于清晰的补丁历史、最小化的合并冲突和可预测的维护模式。任何会导致大量格式变更的自动化规则在内核环境中代价都极高:合并时会出现大量"纯格式"变更的冲突,代码审查中也会被淹没在格式差异中,降低审查效率。 更重要的是,内核代码里有大量自动生成、频繁重构或跨团队编辑的文件,导入语句频繁变化。对于这类场景,维持"每行一个导入"能够最大限度降低合并冲突带来的人工调解成本,而自动化工具如果不遵循这种原则,反而会把便利性变成长期负担。Torvalds 的反应正是基于这种宏观维护成本的考虑。 rustfmt 的可配置性与潜在解决方案 针对 rustfmt 的行为,Rust 社区提供了 rustfmt.toml 来定制化格式化规则。
通过配置文件,项目可以设置诸如导入分组、合并粒度、换行风格等选项,从而让自动化格式化更贴近项目的维护习惯。在原则上,Linux 内核团队完全可以通过统一的 rustfmt.toml 来强制一种对内核友好的导入策略,从而在 CI 中运行 rustfmtcheck 时获得一致且可预测的结果。 具体可配置项可能包括禁止将多个导入合并为单行、优先保持每行一个导入、调整导入合并的阈值以及关闭某些导致随机折行的启发式规则。通过在仓库根目录或子项目中提供明确的 rustfmt 配置,并在开发文档与提交模板中强调在提交前运行工具,项目可以同时拥有格式一致性和可维护性。 流程与文化层面的改进 技术配置之外,流程和文化是解决这类冲突的关键。首先,内核维护团队需要尽早达成 Rust 代码风格的共识,并把可执行规则写入到开发指南和 CI 管道。
合并前在小范围内实验新的 rustfmt 配置并观察其对历史提交和合并冲突的影响,是一种务实的做法。其次,自动化检查应该以降低噪音为目标,CI 报告应提供清晰的修复建议或可应用的自动修复补丁,而不是产生让维护者难以理解的随机差异。 教育与工具链整合也很重要。要求贡献者在本地运行 rustfmt 并提供格式化后的补丁,结合提交钩子或预提交脚本,可以把格式化决策统一到贡献流程的早期,避免在后期审查时才暴露大量差异。对于长期维护的内核仓库,建议维护者把 rustfmt 配置作为项目合同的一部分,对外宣告"我们的 Rust 风格就是这样",从而减少反复讨论。 折衷之道:统一风格但保证可维护性 在开源社区里,完美的方案往往不存在。
理想的折衷是:采用统一且可执行的格式化规则,但是优先考虑长期维护成本。对内核而言,这意味着在 rustfmt 的配置中明确以降低合并冲突和保留清晰 diff 为优先级,比如保持导入语句在多行形式,或者在合并时只在有限条件下才压缩为单行。 同时可以在工具层面加入"智能"策略:在小规模更改或新增导入时,优先保持文件现有的导入风格;仅在整文件格式化或在维护者明确要求时,才进行批量风格变更。这样的策略能够减少因工具行为改变而导致的大规模格式波动,同时仍旧保留自动化格式化带来的统一性优势。 开放对话与社区协作的必要性 Linus 的公开批评虽然语气强烈,但也为社区提供了一个机会:通过对话来协调 Rust 工具与内核维护的需求。Rust 社区与内核维护者之间可以开展协作,评估 rustfmt 的默认启发式规则是否适合内核环境,或者是否需要为内核场景定义一套更适配的配置文件。
社区间的沟通可以推动 rustfmt 引入更可配置或者更透明的导入合并策略,让大型项目更容易找到共同点。 此外,维护者之间的内部共识也很关键。内核子系统的负责人可以决定是否在其子树中强制某一格式,并以补丁公告、贡献指南和 CI 检查来贯彻这一决定。通过可执行且公开的规则,贡献者可以在提交前就知道如何格式化代码,避免在邮件列表上产生无谓的争执。 结语:以用户与维护者的共同利益为导向 Linus Torvalds 对 rustfmtcheck 的批评揭示了一个普遍问题:自动化工具在节省人力与统一风格方面带来了诸多优势,但如果工具的决策逻辑与大型项目的维护模式脱节,就会变成新的累赘。解决之道不是一味拒绝自动化,而是在规则制定、配置管理和团队协作上做功课,确保自动化工具服从于维护者与项目长期可持续发展的需要。
对于 Linux 内核及其他大型开源项目而言,务实的步骤包括统一 rustfmt 配置、在 CI 中提供清晰的格式化反馈、在贡献指南里明确格式化流程,以及与上游工具作者保持沟通,推动工具在可配置性和对大型项目友好性方面持续改进。通过这样的方法,社区既能享受自动化带来的便利,又能避免因格式化规则引发的维护负担,让代码更易读、更可维护、也更利于合作。 Linus 的愤怒提醒我们,自动化不是魔法,规则不是一成不变。在软件工程尤其是内核这样长期演化的项目中,工具应该被视为服务于维护目标的手段,而非独立的裁判。只有当工具与团队的工作流、维护哲学相契合时,自动化才能真正提升效率,而不是制造新的摩擦。 。