BNB Smart Chain 提交信息规范:读懂 docs/lint/commit.md 与 commitlint 落地实践
2026/9/18 19:37:29 网站建设 项目流程

BNB Smart Chain 提交信息规范:读懂 docs/lint/commit.md 与 commitlint 落地实践

【免费下载链接】bscA BNB Smart Chain client based on the go-ethereum fork项目地址: https://gitcode.com/GitHub_Trending/bs/bsc

本文是 BSC(BNB Smart Chain,基于 go-ethereum 的客户端)仓库内 docs/lint/commit.md 的完整解读与实践指南。该文档定义了 BSC 社区统一的 Git Commit 信息格式要求,配套 .github/commitlint.config.js 在 CI 中自动校验,并配合 .github/generate_change_log.sh 自动生成 CHANGELOG.md。读完本文,你将掌握 BSC 的提交信息格式规则、多 scope 与大变更(BEP/feat/fix)的命名约定、以及如何在本仓库中查看和验证这些规范。

一、为什么 BSC 需要 Commit 格式规范

BSC 客户端是一个规模庞大的代码库,覆盖共识(consensus/parlia、ethash、clique)、核心状态机(core/state)、EVM(core/vm)、P2P 网络(p2p)、RPC(rpc)等数十个模块。大量并行开发与频繁合入,如果没有统一的提交信息格式,会带来三个直接问题:

  • 代码评审成本高:维护者无法从标题快速判断变更涉及的模块与意图;
  • CHANGELOG 生成困难:BSC 的版本发布依赖 generate_change_log.sh 从提交记录中提取变更说明,格式不统一会直接污染发布记录;
  • 跨版本回溯困难:当需要定位某个硬分叉(如 BEP-130 并行 EVM)或某个 bug 修复引入的提交时,规范化的标题是唯一的检索线索。

因此,BSC 在仓库中同时维护了三份相互配合的文件:规则文档 docs/lint/commit.md、自动化校验配置 .github/commitlint.config.js 以及发布脚本 .github/generate_change_log.sh。

二、核心规则:标题行与 scope : subject 结构

按照 docs/lint/commit.md 的定义,BSC 的提交信息遵循以下要求:

1. 标题行长度限制

标题行不得超过 72 个字符。

注意这里与 commitlint 配置的差异:docs/lint/commit.md规定 72 字符,而 .github/commitlint.config.js 中的header-max-length被配置为[2, 'always', 80],即 CI 实际执行的上限是 80 字符。文档规定的 72 字符是推荐上限,工具强制的 80 字符是硬上限——编写提交信息时,建议以更严格的 72 字符为准则,确保在绝大多数终端与 GitHub 界面中不被截断。

2. 标题行的组成结构

标题行由scope : subject组成。

即提交标题必须包含两个部分:

  • scope(范围):指明本次变更影响的模块,如evmrpccoredbconsensus等;
  • subject(主题):用一句话描述本次变更做了什么。

文档给出的单 scope 示例:

evm: optimize opcode mload

这条提交表示:本次变更作用于 EVM 模块,内容是优化MLOAD操作码的执行。scopesubject之间用冒号(半角:)分隔,冒号后跟一个空格。对照仓库中的实际模块结构,evm对应 core/vm(其中包含 opcode 相关的 core/vm/opcodes.go 等实现);rpc对应 rpc 目录。

从 .github/commitlint.config.js 的解析器配置可以看到其底层逻辑:

parserOpts: { headerPattern: /^(.*):.*/, }

该正则将标题行在第一个冒号处切分,冒号前的内容被解析为type(即 scope),冒号后的内容作为subject。同时配置了'subject-empty': [2, 'always']'scope-empty': [2, 'always']两条规则,强制要求 scope 和 subject 均不能为空——也就是说,": something""core: "这类残缺提交信息会在 CI 中直接报错。

三、多 Scope 语法与边界建议

1. 多 scope 的写法

BSC 的一个显著特点是支持一个提交同时影响多个模块,多个 scope 之间用空格分隔:

rpc core db: refactor the interface of trie access

这条示例表示一次提交同时重构了 RPC、core 与数据库三层对 trie 访问接口的调用。这是跨层重构(refactor)的典型场景:修改 core/state 的 trie 访问逻辑必然牵动 rpc 与 ethdb 的使用方。

2. 数量与长度的建议值

文档给出的建议(非强制):

  • scope 数量建议 ≤ 3 个
  • 单个 scope 长度建议 ≤ 20 个字符

这两项均为软性建议。但请留意:虽然 commitlint 配置中type-enum被设置为[2, 'never'](即不启用枚举限制,scope 名称可以自由定义),但header-max-length(80 字符)与function-rules/type-case仍然是硬性约束。当 scope 数量过多或过长时,留给 subject 的空间会被压缩,很容易撞上 80 字符上限。因此「≤3 个 scope、每个 ≤20 字符」是保证标题可读性与通过校验的实际经验边界。

四、禁止使用的关键字:R4R 与 WIP

文档第 4 条是最重要的硬性规则:

关键字如R4RWIP不允许出现在 scope 中,无论大小写。

  • WIP:Work In Progress(进行中)的缩写,表示提交尚未完成;
  • R4R:Ready for Review 的常见缩写(用于标注"待评审"状态)。

这类标记会让"提交信息"失去描述真实变更的能力,且会在历史中残留大量无法归类的条目,破坏 CHANGELOG 生成质量。因此 BSC 明确禁止将其写入 scope,且大小写均不允许wipWipr4rR4r等变体同样违规)。

该规则的落地实现在 .github/commitlint.config.js 的validateTypeNums函数中:

const validateTypeNums = (parsedCommit) => { const mergePrefix = "Merge pull request" if (parsedCommit.raw.startsWith(mergePrefix)) { console.log('this is a merge commit:' + parsedCommit.raw) return [true, ''] } if (!parsedCommit.type) { return [false, 'invalid commit message, should be like "name: descriptions.", yours: "' + parsedCommit.raw + '"'] } const types = parsedCommit.type.split(' ') for (var i = 0; i < types.length; i++) { if ((types[i].toLowerCase() == "wip") || (types[i].toLowerCase() == "r4r")) { return [false, 'R4R or WIP is not acceptable, no matter upper case or lower case'] } } return [true, ''] }

从源码可以看出三点关键逻辑:

  1. merge 提交豁免:以Merge pull request开头的合并提交直接放行(return [true,'']),GitHub 的 squash/merge 操作产生的默认提交信息不会因此失败;
  2. 缺失 scope 报错:没有 scope 的提交会返回错误信息,提示正确格式应为"name: descriptions."
  3. 大小写归一化检查:将每个 scope(按空格切分)转小写后与wipr4r比对,大小写变体一网打尽。

五、大变更的 scope 命名约定:bep / feat / fix

当一次变更太大、影响多个 scope 时,scope1 scope2 scope3的罗列方式会变得不可读。文档给出了专门的应对策略:

如果变更太大、影响多个 scope,scope 名称可以使用bepfeatfix

官方示例:

bep130: implement parallel evm feat: implement parallel trie prefetch fix: stack overflow on GetCommitState

三个保留 scope 的适用场景:

scope适用场景仓库佐证
bep<N>实现某条 BSC 进化提案(BEP)对应的功能CHANGELOG.md 中大量记录,如 BEP-130 并行 EVM、BEP-341 验证人连续出块、BEP-619 短区块间隔等
feat独立的新功能,不适合归入单一模块CHANGELOG.md 中 "feat: support bid block size check for BEP-655" 等条目
fix跨模块的缺陷修复,如栈溢出、数据竞态CHANGELOG.md 中的修复类条目

以文档示例fix: stack overflow on GetCommitState为例:GetCommitState是状态层的重要接口(在 trie/committer.go 等文件中可见相关实现),栈溢出问题往往涉及 EVM、trie、state 多层调用栈,因此直接用fix作为 scope 比罗列多个模块更清晰。

特别说明bepscope 的命名:注意示例写的是bep130(即 "bep" 直接拼接 BEP 编号,无空格、无连字符),而不是bep-130。结合 CHANGELOG.md 中的记录(如 BEP-341、BEP-619、BEP-655 等),可以推断:当提交与某条 BEP 提案强绑定、需要后续按提案编号检索时,优先采用bep<N>作为 scope;而 .github/commitlint.config.js 中type-enum: [2, 'never']也确认了这类自定义 scope 不会被枚举规则拦截。

六、规则在 CI 与发布流程中的闭环

规范的最终价值体现在自动化上。BSC 仓库通过 .github/commitlint.config.js 在 CI 中对每次提交执行校验,校验失败会返回形如invalid commit message, should be like "name: descriptions."的明确错误。同时,该配置文件还设定了:

extends: ['@commitlint/config-conventional'], plugins: ['commitlint-plugin-function-rules'],

即基于社区流行的@commitlint/config-conventional预设,并引入commitlint-plugin-function-rules插件实现自定义校验函数。另外值得注意的是,header-max-length实际为 80 字符,subject-emptyscope-empty均为强制规则(等级 2)。

在发布侧,.github/generate_change_log.sh 会按版本号从 CHANGELOG.md 中截取变更段落(遇到下一个## v版本标题即停止),并生成包含 MetaInfo、Changelog 与各平台二进制 SHA256 校验和的发布说明。规范化、可检索的提交标题,正是这份自动生成发布记录的输入质量保障——提交信息若乱写,最终进入 CHANGELOG 的条目就会失去可读性。

七、快速自查清单

编写提交信息时,可以对照以下清单逐项自检:

  1. 标题行长度是否 ≤ 72 字符(工具硬上限 80 字符);
  2. 是否遵循scope : subject结构,scope 与 subject 均非空;
  3. 多 scope 时是否以空格分隔,且数量 ≤ 3 个、单个长度 ≤ 20 字符;
  4. scope 中是否出现wip/r4r(任意大小写);
  5. 大变更是否恰当使用了bep<N>featfix作为 scope;
  6. 合并提交(Merge pull request开头)无需修改,CI 会自动豁免。

遵循这套规范,你的提交将更容易通过 BSC 的 commitlint 校验,也更容易在 CHANGELOG.md 的发布历史中被准确定位——这也是在大型区块链客户端项目中提交高质量代码的基本功。

【免费下载链接】bscA BNB Smart Chain client based on the go-ethereum fork项目地址: https://gitcode.com/GitHub_Trending/bs/bsc

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询