Bitcoin Core 贡献者指南:从提交补丁到 Peer Review 的完整工作流 Bitcoin Core 贡献者指南从提交补丁到 Peer Review 的完整工作流【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin本文以 Bitcoin Core 仓库根目录的 CONTRIBUTING.md 为主体完整梳理该项目开放贡献者模型下的协作规范如何提交原子化的 commit、如何撰写符合规范的 Pull RequestPR标题与正文、squash 与 rebase 的实操命令、Peer Review 的术语体系Concept (N)ACK / Approach (N)ACK / ACK BRANCH_COMMIT以及合并判定、共识级补丁的额外要求和 backport 元数据格式。读完本文你可以按项目维护者的标准独立完成一个可被合并的 PR并理解其背后的 git 历史卫生原则。一、开放贡献者模型没有特权开发者Bitcoin Core 采用开放贡献者模型open contributor model任何人都可以通过同行评审peer review、测试和补丁三种形式参与开发。项目并不存在特权开发者的概念——开源社区通常是靠贡献者随时间赢得信任而自然形成的 meritocracy贤者政治。但从实践管理角度仍需要一定的层级结构仓库维护者repository maintainers负责合并 pull request、执行发布周期release cycle见 发布流程和社区管理。这意味着贡献入口对所有开发者平等但代码进入master的最后一公里由维护者把关评审与测试正是普通贡献者影响这个把关过程的主要渠道。1.1 新贡献者的最佳切入点文档明确指出深入的评审和测试是整个项目的瓶颈也是任何人开始贡献时最有效的方式。相比直接开 PR先做评审和测试能让你对代码和流程学到更多还可能帮助你发现相关问题和后续可以贡献代码的跟进点。开始贡献前建议先熟悉 Bitcoin Core 的构建系统和测试体系。当前仓库中对应的资料与代码位置内容仓库位置开发者编码规范C 风格、测试结构、加锁约定等doc/developer-notes.md单元测试Boost.Testsrc/test/约 300 个 .cpp 文件功能测试Python 集成测试test/functional/300 测试脚本规范见 test/functional/README.mdFuzz 测试文档libFuzzer / AFL / Honggfuzzdoc/fuzzing.mdCI 测试脚本容器化测试矩阵ci/test/、ci/README.mdLint 检查rust-based linter 等ci/lint/、test/lint/PR 评审俱乐部官方组织的 PR Review ClubBitcoin Core 社区活动1.2 AI 工具使用政策如果贡献过程中使用了 AI 工具必须阅读并遵守 AI 政策。核心要求包括禁止用 AI 生成与维护者/其他贡献者交流的评论评论必须由人撰写疑似 AI 生成的评论可能被 moderation提交 PR 的前提是你了解代码所用语言、你自己有能力写出这段代码、理解周边既有代码和所提议变更的影响必须能用自己的话解释 PR 的变更包括 PR 正文和对 reviewer 提问的回复不得复制 AI 的回答去回复 reviewer 的提问项目要求有人在环human author in the loopPR 不应由自主 Agent 打开或驱动commit 中也不要把 agent 列为作者或共同作者违反此条的 PR 可能被无预警关闭。二、沟通渠道围绕 Bitcoin Core 开发的沟通主要通过以下渠道进行IRCLibera Chat 的#bitcoin-core-dev频道是开发讨论的主要场所有 web 客户端可直接参与也有第三方聊天历史存档可查GitHub issues 与 pull requests代码库改进的讨论在此进行bitcoindev 邮件列表复杂的或有争议的共识规则consensus或 P2P 协议变更在动手写补丁之前应先在此列表上讨论列表有公开存档。渠道选择的实践含义是普通的 bugfix、重构走 GitHub 即可一旦你的改动触碰共识规则未先在邮件列表充分讨论的补丁很难通过评审详见第六节的决策流程。三、贡献者工作流fork → 分支 → 提交 → PR代码库采用contributor workflow维护所有人无一例外都通过 pull request 提交补丁提案。这种方式便于社会化协作、测试和同行评审。3.1 基本流程Fork 仓库仅在第一次贡献时创建主题分支topic branch提交补丁committing patches见 3.3 节将变更推送到你的 fork创建 pull request见 3.4 节。对 PR 作者有三条硬性要求来自文档原文的归纳必须完全且有把握地理解自己的变更并且已经测试过应说明哪些测试覆盖了本次变更或列出你用于确认变更的手动步骤应准备好清晰地说明并解释变更的动机若评审者有疑虑PR 可能被直接关闭。3.2 monotreeGUI 与 Node 仓库的划分当前 Bitcoin Core 采用monotree单树多仓库组织GUI 相关的问题或 PR 使用bitcoin-core/gui仓库其余所有问题和 PR 使用bitcoin/bitcoinnode仓库两个仓库的master分支内容完全一致。默认判据只修改src/qt的改动属于 GUI-only PR。但有以下三个例外全局重构或其他横向transversal改动 → 走 node 仓库GUI 相关的构建系统改动 → 走 node 仓库因为这类变更需要构建系统 reviewer 的评审对应本仓库中的 CMakeLists.txt、cmake/ 等文件修改src/interfaces的变更 → 走 node 仓库因为这些接口可能影响钱包等其他组件对应本仓库的 src/interfaces/、src/common/interfaces.cpp。对于同时包含构建系统与接口改动的大型 GUI 变更推荐的分步策略是先在 GUI 仓库开 PR 达成方向共识再把构建系统与接口的变更提交到 node 仓库。项目编码规范必须遵循 developer notes。3.3 提交补丁Committing Patches原子性与可读性。commit 应当是原子的atomic commit conventiondiff 应当易读。因此不要把格式修复、代码移动与真正的代码改动混在同一个 commit 里每个单独的 commit 必须是卫生的hygienic能独立构建成功无警告、无错误、无回归、无测试失败。commit 结构中的测试归属文档引用 developer notes 的 Commit Structure for Tests 一节其具体规则是若已有测试覆盖了被修改的行为应在同一 commit 中更新这些测试diff 同时记录新旧期望值简单的功能或 bugfix 没有既有覆盖时变更与测试通常可以在同一个 commit非平凡的 refactor若相关不变量还没有自动化测试先在单独的测试 commit中加入覆盖refactor commit 本身就不需要改动测试期望对既有行为的非平凡修改若无覆盖考虑加一个前置的 characterization test commit并用TODO注释标记那些期望值会随行为改变而变化的断言。commit message 规范默认应详尽短标题行最长 50 字符 空行 详细的解释性段落例外仅当标题本身就自解释时如 Correct typo in init.cpp单行标题即可消息要面向未来读代码的人解释你做各项决策的理由若某个 commit 关联其他 issue请加上引用例如refs #1234或fixes #4321。使用fixes或closes关键字会在 PR 合并时自动关闭对应 issuecommit message 中永远不要出现提及username。PR 之外的两个实操技巧来自 生产力笔记与 squash 工作流直接相关# 在 dummy rebase 上用 autosquash 收纳 fixup commit # 而不必在更新的 master 上 rebase避免引入无关冲突 git rebase -i --autosquash $(git merge-base master HEAD) # 对自 diverge 点以来每个 commit 自动跑构建与单测 git rebase -i --exec cmake --build build ctest --test-dir build $(git merge-base master HEAD)3.4 创建 Pull Request标题前缀必须标明 PR 影响的组件或区域。合法的 area 前缀完整列表如下前缀适用范围consensus共识关键consensus critical代码变更doc文档变更qt或guibitcoin-qt 变更log日志消息变更mining挖矿代码变更net或p2pP2P 网络代码变更refactor不改变行为的重构rpc、rest或zmqRPC、REST 或 ZMQ API 变更contrib或cli脚本和工具变更test、qa或ci单元测试、QA 测试或 CI 代码变更util或lib工具库utils或库变更wallet钱包代码变更buildCMake 变更guixGuix 可复现构建变更官方给出的标题示例consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG net: Automatically create onion service, listen on Tor qt: Add feed bump button log: Fix typo in log message正文要求必须充分描述补丁做了什么更要为什么并给出理由与论证应引用相关讨论其他 issue 或邮件列表讨论新建 PR 的正文中不得包含任何提及。原因PR 描述在合并时会并入 merge commit 的 commit message每个 fork 该 commit 时被提及的用户都会被反复通知。用户名提及应放在 PR 的后续评论中。翻译变更翻译不应以 PR 形式提交。流程见 翻译流程翻译通过 Transifex 管理src/qt/locale/下的源文件由自动化脚本更新如用cmake --preset dev-mode构建后--target translate重新生成bitcoin_en.ts普通 PR 不应包含翻译源文件的更新以避免合并冲突并在发布前留出翻译时间。WIP 与 RFC 标记若 PR 暂不考虑合并标题前加[WIP]或在正文中使用 GitHub 的 Tasks Lists 标记待办任务。3.5 处理评审反馈PR 提交后应预期收到其他贡献者的评论与评审。你可以本地新增 commit 并推送到 fork从而给 PR 追加 commit。在 PR 被合并前你被期望回复所有评审评论你可以修改代码也可以不同意反馈而拒绝但必须在回复中明确表达若存在悬而未决的反馈而你未在处理PR 可能被关闭。3.6 Squash Commits若 PR 中含有 fixup commit反复修改同一行代码的 commit或粒度过细的 commit可能在你获得评审之前就被要求先 squash。官方给出的基本工作流git checkout your_branch_name git rebase -i HEAD~n # n 通常是 PR 中 commit 的数量。 # 将第一行之外的 commit 从 pick 改为 squash保存并退出。 # 在下一个屏幕上编辑/润色 commit message。 # 保存并退出。 git push -f # (force push 到 GitHub)Squash 后如需更新 commit message应使其读起来像一条连贯的消息——大多数情况下意味着不是简单罗列中间 commit。注意若分支中含 merge commit上述工作流可能不生效需要先移除 merge commit见下一节的 rebase。另外两条纪律不要为同一变更开多个 PR用已打开或更早创建的 PR 来修正变更这保留了针对该变更集的既有讨论与评审Peer review 所需时间不可预测因 PR 而异。3.7 Rebase Changes当 PR 与目标分支冲突时可能被告知其 rebase 到当前目标分支顶部git fetch https://github.com/bitcoin/bitcoin # Fetch the latest upstream commit git rebase FETCH_HEAD # Rebuild commits on top of the new base生产力笔记 提供了单 PR 的更精细做法不必拉全量数据# 单独 fetch 某个 PR git fetch upstream pull/number/head # fetch 并切到本地分支 git fetch upstream pull/number/head:pr-number git switch pr-numberRebase 后评审者被鼓励对 force push 进行 sign-off复核。生产力笔记 中介绍的git range-diff工具Git 2.19用于diff of diffs当贡献者 rebase 或修改非头部的 commit 后 force pushreviewer 无法仅凭 commit hash 判断之前的评审是否仍然有效git range-diff master previously-reviewed-head new-head可以直接对比新旧两个 commit 范围的 patch 差异从而高效完成复核。为避免无谓的评审损耗review churn维护者通常会优先合并那些获得最多评审关注的 PR。3.8 干净的 git 历史与签名验证项目追求干净的 git 历史代码变更只出现在非 merge commit中。这简化了可审计性——merge commit 可以假定不携带任意代码变更merge commit 必须签名且其产生的 git tree hash 必须是确定且可复现的。仓库中 contrib/verify-commits/ 的脚本负责检查这一点。其 README 说明了配套机制verify-commits.py是一个 Python 3 脚本对照trusted-keys受信 PGP 指纹列表验证 commit 签名配置文件包括trusted-git-root信任根第一个未签名 commit 的哈希、trusted-sha512-root-commit、trusted-keys、allow-revsig-commits因签名密钥过期/吊销而需豁免的 commit 列表使用前需先用gpg导入受信密钥一个重要安全细节不能用不受信的脚本来验证自身——先 checkout 代码再对HEAD跑verify-commits.py是不安全的脚本本身可能已被植入后门。正确的顺序是先 fetch用受信版本的verify-commits.py验证origin/master再 checkout例如git fetch origin \ ./contrib/verify-commits/verify-commits.py origin/master \ git checkout origin/master除非指定--clean-merge 0verify-commits.py还会验证每个 merge commit 是否干净应用要求至少 git v2.38.0。四、PR 哲学聚焦避免超大 PR补丁集patchset应当始终聚焦一个 PR 可以加功能、修 bug、或做重构但不能三者混杂。同时要避免super pull requests——试图做太多、过大或过于复杂的 PR因为其评审难度极高。4.1 新功能增加新功能必须考虑其长期技术债与维护成本。提议一个需要维护的新功能前先考虑你是否愿意维护它包括修 bug。如果未来某个功能成为孤儿无人维护它可能被仓库维护者移除。4.2 重构重构是项目演进不可避免的一部分规范将其分为三类代码移动code-only moves代码风格修复code style fixes代码重构code refactoring。三条铁律重构 PR不应混合这三类活动以便评审容易且无争议任何情况下重构 PR 都不得改变代码行为bug 必须原样保留bugs must be preserved as is维护者追求对重构 PR 的快速周转因此尽量短、不复杂、易验证新贡献者不应提交重构类 PR——判断代码该放在哪并理解全部影响包括对其他打开 PR 的 rebase 代价需要一定经验明显琐碎、或没有清晰收益的重构 PR维护者可能直接关闭以减轻评审负担。五、Peer Review术语体系与评审深度任何人可以参与 peer review评审以 PR 评论表达。reviewer 通常检查明显的错误、实际跑一遍补丁集、并对技术价值发表意见。维护者在判断是否达到合并共识时会综合考虑 peer review注意讨论可能分散在 GitHub、邮件列表和 IRC 三处。5.1 评审成本的经济学代码评审是繁重但重要的一环因此某类 PR 会被直接拒绝一般地如果改进的收益不足以抵消所需的评审成本PR 被拒绝的概率很高。PR 作者有责任说服 reviewer 变更值得这份评审成本若 reviewer 在概念上 NACK你的 PR作者可能需要摆出论据、甚至做研究来支撑自己的提议。此外若有合理理由怀疑 PR 作者不完全理解自己提交的变更或明显自己都没做过基本测试PR 可能被立即关闭。5.2 概念评审Conceptual Review两种表达Concept (N)ACK我不同意这个 PR 的总体目标Approach (N)ACKConcept ACK但我不同意这个变更的实现路径。NACK必须附带理由解释为什么该变更不值得做没有理由的 NACK 可被忽视。5.3 代码评审Code Review在概念达成一致后才开始代码评审。评审以ACK BRANCH_COMMIT开始其中BRANCH_COMMIT是 PR 分支的顶部 commit随后附评审者说明自己如何完成的评审。PR 评论中的惯用语I have tested the code除了跑单元/功能/fuzz 测试外还做了变更相关的手动测试若手动测试方式不明显应描述出来I have not tested the code, but I have reviewed it and it looks OK, I agree it can be merged只做了代码审读而未实际运行测试nit琐碎的、通常非阻塞的问题。评审权重规则维护者保留用常识判断权衡各评审意见的权利也可以基于 merit贡献深度加权随时间展现出更深的投入与理解、或有明确领域专长的 reviewer其意见自然更重——这是所有行业的常态触碰共识关键代码包括对共识关键代码的重构的补丁集讨论与 peer review 门槛会大幅提高因为错误对更广泛社区的代价可能极高提议改变 Bitcoin 共识的补丁集必须已在邮件列表和 IRC 充分讨论、有被广泛讨论的编号 BIP、并且维护者判断社区对这是一个有价值的变更形成了普遍的技术共识。5.4 找不到 reviewer 怎么办多数 reviewer 本身也是有自己项目的开发者评审过程可能相当漫长需要耐心。若 PR 数月无人问津文档给出五种排查思路可能正值 feature freeze临近发布的特性冻结期期间只考虑 bug fix新功能 PR 不会优先处理——等发布结束即可变更本身可能不受欢迎与其沉默如雷thundering silence相对nit 和批评反而说明有人在认真对待你的贡献。沉默是对变更的普遍轻度不喜欢的良好信号。不要个人化而是重新审视自己的提议是否改动太多、太宽泛、不符合 developer notes、危险或不安全、写得凌乱。找出并解决这些问题后可以在 IRC 上请人评价概念本身代码可能太复杂以至于只有少数人懂而他们甚至不知道这个 PR 存在用 GitHub 的 Git Blame 功能查最后修改你正在改的代码的人找到并礼貌地轻推nudge他们——但不要不停刷屏最后兜底直接在 IRC 或别处请求有人看一眼你的 PR。若你认为等待了不合理的时长比如超过一个月且没有特别原因如只改了几行代码这么做完全没问题。同时当别人请求反馈你的代码时记得还人情社区会自我平衡等待期间最好的事是去给别人做评审。六、决策流程Decision Making Process以下规则适用于 Bitcoin Core 项目以及相关项目如 libsecp256k1的代码变更不要将其与比特币网络层面的协议共识变更混淆。PR 是否合并由项目 merge 维护者决定他们综合考虑补丁是否符合项目总体原则、是否达到入库的最低标准、以及贡献者群体的普遍共识。所有 PR 必须满足有清晰的使用场景修复可复现的 bug或服务项目整体利益例如面向模块化的重构经过良好的 peer review在适用处具备单元测试、功能测试和 fuzz 测试对应本仓库的 src/test/、test/functional/ 与 fuzz 目标fuzz 构建与运行见 doc/fuzzing.md遵循代码风格规范C 风格见 developer notes功能测试风格见 test/functional/README.md不破坏既有测试套件修复 bug 时在可能处应有展示该 bug 的单元测试并证明修复有效以防止回归行为变化时同步更新相关注释与文档。共识规则变更远比普通补丁复杂因为它影响整个生态系统必须先经过邮件列表的大量讨论并配有编号 BIP每种情况都不同但应当预期付出比其他方式更多的时间与精力评审与共识构建要求都更高。七、Backport回移植的元数据规范安全修复与 bug fix 可以从master回移植backport到 release 分支。维护者会批量执行回移植并在需要时使用正确的Needs backport (...)标签原作者无需操心。backport commit 的正文必须包含以下元数据Github-Pull: #PR number Rebased-From: commit hash of the original commit此外官方还提到可参考历史 backport PR 实例以及 bitcoin-maintainer-tools 仓库中的backport.py脚本位于项目外部的 maintainer 工具仓库本文不展开。八、版权与许可证向本仓库贡献即表示同意除非 contrib/debian/copyright 或文件顶部另有说明否则你的作品以MIT 许可证授权对应仓库根的 COPYING 文件。凡由你贡献但并非原创的作品必须包含其许可证头注明原作者与来源。这与全仓库源码文件头部普遍出现的Distributed under the MIT software license, see the accompanying file COPYING注释保持一致。九、快速核对清单Pre-Submission Checklist把以上规范压缩成提交前的自检清单改动是否单一聚焦格式化/移动与行为变更是否拆开了每个 commit 独立可构建、无警告、无测试失败commit 标题 ≤50 字符、正文解释了为什么、无提及测试按 developer notes 的 commit 结构规则放对了位置PR 标题带了正确的 area 前缀对照第三节的 14 类前缀表正文说明了 what why 测试依据且无提及只改src/qt之外还碰了构建系统或src/interfaces→ 确认应走 node 仓库。若等待 rebasegit fetchgit rebase FETCH_HEADforce push 后用 range-diff 帮助 reviewer 复核若需 squash按git rebase -i HEAD~n工作流合并并改写连贯的 commit message。涉及共识关键代码或共识规则→ 先确认已有邮件列表讨论与 BIP评审门槛相应提高。若使用了 AI 工具确认符合 AI_POLICY.md所有对外沟通均为人工撰写commit 作者中无 agent。以上流程与仓库中的实际工程设施CMake 构建体系、ci/test/ 的多平台测试矩阵、contrib/verify-commits/ 的签名验证、doc/productivity.md 的评审效率工具共同构成了 Bitcoin Core 高质量协作的完整闭环贡献者按原子 commit 与聚焦 PR 提交社区按 Concept/Approach/Code 三层评审过滤维护者按可复现的签名历史合并最终形成一条每个 merge commit 都可审计的master分支。【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考