
Bitcoin Core 貢獻者指南從提交補丁到 Peer Review 的完整工作流【免費下載鏈接】bitcoinBitcoin Core integration/staging tree項目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin本文以 Bitcoin Core 倉庫根目錄的 CONTRIBUTING.md 為主體完整梳理該項目開放貢獻者模型下的協(xié)作規(guī)范如何提交原子化的 commit、如何撰寫符合規(guī)范的 Pull RequestPR標題與正文、squash 與 rebase 的實操命令、Peer Review 的術(shù)語體系Concept (N)ACK / Approach (N)ACK / ACK BRANCH_COMMIT以及合并判定、共識級補丁的額外要求和 backport 元數(shù)據(jù)格式。讀完本文你可以按項目維護者的標準獨立完成一個可被合并的 PR并理解其背后的 git 歷史衛(wèi)生原則。一、開放貢獻者模型沒有特權(quán)開發(fā)者Bitcoin Core 采用開放貢獻者模型open contributor model任何人都可以通過同行評審peer review、測試和補丁三種形式參與開發(fā)。項目并不存在特權(quán)開發(fā)者的概念——開源社區(qū)通常是靠貢獻者隨時間贏得信任而自然形成的 meritocracy賢者政治。但從實踐管理角度仍需要一定的層級結(jié)構(gòu)倉庫維護者repository maintainers負責(zé)合并 pull request、執(zhí)行發(fā)布周期release cycle見 發(fā)布流程和社區(qū)管理。這意味著貢獻入口對所有開發(fā)者平等但代碼進入master的最后一公里由維護者把關(guān)評審與測試正是普通貢獻者影響這個把關(guān)過程的主要渠道。1.1 新貢獻者的最佳切入點文檔明確指出深入的評審和測試是整個項目的瓶頸也是任何人開始貢獻時最有效的方式。相比直接開 PR先做評審和測試能讓你對代碼和流程學(xué)到更多還可能幫助你發(fā)現(xiàn)相關(guān)問題和后續(xù)可以貢獻代碼的跟進點。開始貢獻前建議先熟悉 Bitcoin Core 的構(gòu)建系統(tǒng)和測試體系。當(dāng)前倉庫中對應(yīng)的資料與代碼位置內(nèi)容倉庫位置開發(fā)者編碼規(guī)范C 風(fēng)格、測試結(jié)構(gòu)、加鎖約定等doc/developer-notes.md單元測試Boost.Testsrc/test/約 300 個 .cpp 文件功能測試Python 集成測試test/functional/300 測試腳本規(guī)范見 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 社區(qū)活動1.2 AI 工具使用政策如果貢獻過程中使用了 AI 工具必須閱讀并遵守 AI 政策。核心要求包括禁止用 AI 生成與維護者/其他貢獻者交流的評論評論必須由人撰寫疑似 AI 生成的評論可能被 moderation提交 PR 的前提是你了解代碼所用語言、你自己有能力寫出這段代碼、理解周邊既有代碼和所提議變更的影響必須能用自己的話解釋 PR 的變更包括 PR 正文和對 reviewer 提問的回復(fù)不得復(fù)制 AI 的回答去回復(fù) reviewer 的提問項目要求有人在環(huán)human author in the loopPR 不應(yīng)由自主 Agent 打開或驅(qū)動commit 中也不要把 agent 列為作者或共同作者違反此條的 PR 可能被無預(yù)警關(guān)閉。二、溝通渠道圍繞 Bitcoin Core 開發(fā)的溝通主要通過以下渠道進行IRCLibera Chat 的#bitcoin-core-dev頻道是開發(fā)討論的主要場所有 web 客戶端可直接參與也有第三方聊天歷史存檔可查GitHub issues 與 pull requests代碼庫改進的討論在此進行bitcoindev 郵件列表復(fù)雜的或有爭議的共識規(guī)則consensus或 P2P 協(xié)議變更在動手寫補丁之前應(yīng)先在此列表上討論列表有公開存檔。渠道選擇的實踐含義是普通的 bugfix、重構(gòu)走 GitHub 即可一旦你的改動觸碰共識規(guī)則未先在郵件列表充分討論的補丁很難通過評審詳見第六節(jié)的決策流程。三、貢獻者工作流fork → 分支 → 提交 → PR代碼庫采用contributor workflow維護所有人無一例外都通過 pull request 提交補丁提案。這種方式便于社會化協(xié)作、測試和同行評審。3.1 基本流程Fork 倉庫僅在第一次貢獻時創(chuàng)建主題分支topic branch提交補丁committing patches見 3.3 節(jié)將變更推送到你的 fork創(chuàng)建 pull request見 3.4 節(jié)。對 PR 作者有三條硬性要求來自文檔原文的歸納必須完全且有把握地理解自己的變更并且已經(jīng)測試過應(yīng)說明哪些測試覆蓋了本次變更或列出你用于確認變更的手動步驟應(yīng)準備好清晰地說明并解釋變更的動機若評審者有疑慮PR 可能被直接關(guān)閉。3.2 monotreeGUI 與 Node 倉庫的劃分當(dāng)前 Bitcoin Core 采用monotree單樹多倉庫組織GUI 相關(guān)的問題或 PR 使用bitcoin-core/gui倉庫其余所有問題和 PR 使用bitcoin/bitcoinnode倉庫兩個倉庫的master分支內(nèi)容完全一致。默認判據(jù)只修改src/qt的改動屬于 GUI-only PR。但有以下三個例外全局重構(gòu)或其他橫向transversal改動 → 走 node 倉庫GUI 相關(guān)的構(gòu)建系統(tǒng)改動 → 走 node 倉庫因為這類變更需要構(gòu)建系統(tǒng) reviewer 的評審對應(yīng)本倉庫中的 CMakeLists.txt、cmake/ 等文件修改src/interfaces的變更 → 走 node 倉庫因為這些接口可能影響錢包等其他組件對應(yīng)本倉庫的 src/interfaces/、src/common/interfaces.cpp。對于同時包含構(gòu)建系統(tǒng)與接口改動的大型 GUI 變更推薦的分步策略是先在 GUI 倉庫開 PR 達成方向共識再把構(gòu)建系統(tǒng)與接口的變更提交到 node 倉庫。項目編碼規(guī)范必須遵循 developer notes。3.3 提交補丁Committing Patches原子性與可讀性。commit 應(yīng)當(dāng)是原子的atomic commit conventiondiff 應(yīng)當(dāng)易讀。因此不要把格式修復(fù)、代碼移動與真正的代碼改動混在同一個 commit 里每個單獨的 commit 必須是衛(wèi)生的hygienic能獨立構(gòu)建成功無警告、無錯誤、無回歸、無測試失敗。commit 結(jié)構(gòu)中的測試歸屬文檔引用 developer notes 的 Commit Structure for Tests 一節(jié)其具體規(guī)則是若已有測試覆蓋了被修改的行為應(yīng)在同一 commit 中更新這些測試diff 同時記錄新舊期望值簡單的功能或 bugfix 沒有既有覆蓋時變更與測試通常可以在同一個 commit非平凡的 refactor若相關(guān)不變量還沒有自動化測試先在單獨的測試 commit中加入覆蓋refactor commit 本身就不需要改動測試期望對既有行為的非平凡修改若無覆蓋考慮加一個前置的 characterization test commit并用TODO注釋標記那些期望值會隨行為改變而變化的斷言。commit message 規(guī)范默認應(yīng)詳盡短標題行最長 50 字符 空行 詳細的解釋性段落例外僅當(dāng)標題本身就自解釋時如 Correct typo in init.cpp單行標題即可消息要面向未來讀代碼的人解釋你做各項決策的理由若某個 commit 關(guān)聯(lián)其他 issue請加上引用例如refs #1234或fixes #4321。使用fixes或closes關(guān)鍵字會在 PR 合并時自動關(guān)閉對應(yīng) issuecommit message 中永遠不要出現(xiàn)提及username。PR 之外的兩個實操技巧來自 生產(chǎn)力筆記與 squash 工作流直接相關(guān)# 在 dummy rebase 上用 autosquash 收納 fixup commit # 而不必在更新的 master 上 rebase避免引入無關(guān)沖突 git rebase -i --autosquash $(git merge-base master HEAD) # 對自 diverge 點以來每個 commit 自動跑構(gòu)建與單測 git rebase -i --exec cmake --build build ctest --test-dir build $(git merge-base master HEAD)3.4 創(chuàng)建 Pull Request標題前綴必須標明 PR 影響的組件或區(qū)域。合法的 area 前綴完整列表如下前綴適用范圍consensus共識關(guān)鍵consensus critical代碼變更doc文檔變更qt或guibitcoin-qt 變更log日志消息變更mining挖礦代碼變更net或p2pP2P 網(wǎng)絡(luò)代碼變更refactor不改變行為的重構(gòu)rpc、rest或zmqRPC、REST 或 ZMQ API 變更contrib或cli腳本和工具變更test、qa或ci單元測試、QA 測試或 CI 代碼變更util或lib工具庫utils或庫變更wallet錢包代碼變更buildCMake 變更guixGuix 可復(fù)現(xiàn)構(gòu)建變更官方給出的標題示例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正文要求必須充分描述補丁做了什么更要為什么并給出理由與論證應(yīng)引用相關(guān)討論其他 issue 或郵件列表討論新建 PR 的正文中不得包含任何提及。原因PR 描述在合并時會并入 merge commit 的 commit message每個 fork 該 commit 時被提及的用戶都會被反復(fù)通知。用戶名提及應(yīng)放在 PR 的后續(xù)評論中。翻譯變更翻譯不應(yīng)以 PR 形式提交。流程見 翻譯流程翻譯通過 Transifex 管理src/qt/locale/下的源文件由自動化腳本更新如用cmake --preset dev-mode構(gòu)建后--target translate重新生成bitcoin_en.ts普通 PR 不應(yīng)包含翻譯源文件的更新以避免合并沖突并在發(fā)布前留出翻譯時間。WIP 與 RFC 標記若 PR 暫不考慮合并標題前加[WIP]或在正文中使用 GitHub 的 Tasks Lists 標記待辦任務(wù)。3.5 處理評審反饋PR 提交后應(yīng)預(yù)期收到其他貢獻者的評論與評審。你可以本地新增 commit 并推送到 fork從而給 PR 追加 commit。在 PR 被合并前你被期望回復(fù)所有評審評論你可以修改代碼也可以不同意反饋而拒絕但必須在回復(fù)中明確表達若存在懸而未決的反饋而你未在處理PR 可能被關(guān)閉。3.6 Squash Commits若 PR 中含有 fixup commit反復(fù)修改同一行代碼的 commit或粒度過細的 commit可能在你獲得評審之前就被要求先 squash。官方給出的基本工作流git checkout your_branch_name git rebase -i HEAD~n # n 通常是 PR 中 commit 的數(shù)量。 # 將第一行之外的 commit 從 pick 改為 squash保存并退出。 # 在下一個屏幕上編輯/潤色 commit message。 # 保存并退出。 git push -f # (force push 到 GitHub)Squash 后如需更新 commit message應(yīng)使其讀起來像一條連貫的消息——大多數(shù)情況下意味著不是簡單羅列中間 commit。注意若分支中含 merge commit上述工作流可能不生效需要先移除 merge commit見下一節(jié)的 rebase。另外兩條紀律不要為同一變更開多個 PR用已打開或更早創(chuàng)建的 PR 來修正變更這保留了針對該變更集的既有討論與評審Peer review 所需時間不可預(yù)測因 PR 而異。3.7 Rebase Changes當(dāng) PR 與目標分支沖突時可能被告知其 rebase 到當(dāng)前目標分支頂部git fetch https://github.com/bitcoin/bitcoin # Fetch the latest upstream commit git rebase FETCH_HEAD # Rebuild commits on top of the new base生產(chǎn)力筆記 提供了單 PR 的更精細做法不必拉全量數(shù)據(jù)# 單獨 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復(fù)核。生產(chǎn)力筆記 中介紹的git range-diff工具Git 2.19用于diff of diffs當(dāng)貢獻者 rebase 或修改非頭部的 commit 后 force pushreviewer 無法僅憑 commit hash 判斷之前的評審是否仍然有效git range-diff master previously-reviewed-head new-head可以直接對比新舊兩個 commit 范圍的 patch 差異從而高效完成復(fù)核。為避免無謂的評審損耗review churn維護者通常會優(yōu)先合并那些獲得最多評審關(guān)注的 PR。3.8 干凈的 git 歷史與簽名驗證項目追求干凈的 git 歷史代碼變更只出現(xiàn)在非 merge commit中。這簡化了可審計性——merge commit 可以假定不攜帶任意代碼變更merge commit 必須簽名且其產(chǎn)生的 git tree hash 必須是確定且可復(fù)現(xiàn)的。倉庫中 contrib/verify-commits/ 的腳本負責(zé)檢查這一點。其 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導(dǎo)入受信密鑰一個重要安全細節(jié)不能用不受信的腳本來驗證自身——先 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 是否干凈應(yīng)用要求至少 git v2.38.0。四、PR 哲學(xué)聚焦避免超大 PR補丁集patchset應(yīng)當(dāng)始終聚焦一個 PR 可以加功能、修 bug、或做重構(gòu)但不能三者混雜。同時要避免super pull requests——試圖做太多、過大或過于復(fù)雜的 PR因為其評審難度極高。4.1 新功能增加新功能必須考慮其長期技術(shù)債與維護成本。提議一個需要維護的新功能前先考慮你是否愿意維護它包括修 bug。如果未來某個功能成為孤兒無人維護它可能被倉庫維護者移除。4.2 重構(gòu)重構(gòu)是項目演進不可避免的一部分規(guī)范將其分為三類代碼移動code-only moves代碼風(fēng)格修復(fù)code style fixes代碼重構(gòu)code refactoring。三條鐵律重構(gòu) PR不應(yīng)混合這三類活動以便評審容易且無爭議任何情況下重構(gòu) PR 都不得改變代碼行為bug 必須原樣保留bugs must be preserved as is維護者追求對重構(gòu) PR 的快速周轉(zhuǎn)因此盡量短、不復(fù)雜、易驗證新貢獻者不應(yīng)提交重構(gòu)類 PR——判斷代碼該放在哪并理解全部影響包括對其他打開 PR 的 rebase 代價需要一定經(jīng)驗明顯瑣碎、或沒有清晰收益的重構(gòu) PR維護者可能直接關(guān)閉以減輕評審負擔(dān)。五、Peer Review術(shù)語體系與評審深度任何人可以參與 peer review評審以 PR 評論表達。reviewer 通常檢查明顯的錯誤、實際跑一遍補丁集、并對技術(shù)價值發(fā)表意見。維護者在判斷是否達到合并共識時會綜合考慮 peer review注意討論可能分散在 GitHub、郵件列表和 IRC 三處。5.1 評審成本的經(jīng)濟學(xué)代碼評審是繁重但重要的一環(huán)因此某類 PR 會被直接拒絕一般地如果改進的收益不足以抵消所需的評審成本PR 被拒絕的概率很高。PR 作者有責(zé)任說服 reviewer 變更值得這份評審成本若 reviewer 在概念上 NACK你的 PR作者可能需要擺出論據(jù)、甚至做研究來支撐自己的提議。此外若有合理理由懷疑 PR 作者不完全理解自己提交的變更或明顯自己都沒做過基本測試PR 可能被立即關(guān)閉。5.2 概念評審Conceptual Review兩種表達Concept (N)ACK我不同意這個 PR 的總體目標Approach (N)ACKConcept ACK但我不同意這個變更的實現(xiàn)路徑。NACK必須附帶理由解釋為什么該變更不值得做沒有理由的 NACK 可被忽視。5.3 代碼評審Code Review在概念達成一致后才開始代碼評審。評審以ACK BRANCH_COMMIT開始其中BRANCH_COMMIT是 PR 分支的頂部 commit隨后附評審者說明自己如何完成的評審。PR 評論中的慣用語I have tested the code除了跑單元/功能/fuzz 測試外還做了變更相關(guān)的手動測試若手動測試方式不明顯應(yīng)描述出來I have not tested the code, but I have reviewed it and it looks OK, I agree it can be merged只做了代碼審讀而未實際運行測試nit瑣碎的、通常非阻塞的問題。評審權(quán)重規(guī)則維護者保留用常識判斷權(quán)衡各評審意見的權(quán)利也可以基于 merit貢獻深度加權(quán)隨時間展現(xiàn)出更深的投入與理解、或有明確領(lǐng)域?qū)iL的 reviewer其意見自然更重——這是所有行業(yè)的常態(tài)觸碰共識關(guān)鍵代碼包括對共識關(guān)鍵代碼的重構(gòu)的補丁集討論與 peer review 門檻會大幅提高因為錯誤對更廣泛社區(qū)的代價可能極高提議改變 Bitcoin 共識的補丁集必須已在郵件列表和 IRC 充分討論、有被廣泛討論的編號 BIP、并且維護者判斷社區(qū)對這是一個有價值的變更形成了普遍的技術(shù)共識。5.4 找不到 reviewer 怎么辦多數(shù) reviewer 本身也是有自己項目的開發(fā)者評審過程可能相當(dāng)漫長需要耐心。若 PR 數(shù)月無人問津文檔給出五種排查思路可能正值 feature freeze臨近發(fā)布的特性凍結(jié)期期間只考慮 bug fix新功能 PR 不會優(yōu)先處理——等發(fā)布結(jié)束即可變更本身可能不受歡迎與其沉默如雷thundering silence相對nit 和批評反而說明有人在認真對待你的貢獻。沉默是對變更的普遍輕度不喜歡的良好信號。不要個人化而是重新審視自己的提議是否改動太多、太寬泛、不符合 developer notes、危險或不安全、寫得凌亂。找出并解決這些問題后可以在 IRC 上請人評價概念本身代碼可能太復(fù)雜以至于只有少數(shù)人懂而他們甚至不知道這個 PR 存在用 GitHub 的 Git Blame 功能查最后修改你正在改的代碼的人找到并禮貌地輕推nudge他們——但不要不停刷屏最后兜底直接在 IRC 或別處請求有人看一眼你的 PR。若你認為等待了不合理的時長比如超過一個月且沒有特別原因如只改了幾行代碼這么做完全沒問題。同時當(dāng)別人請求反饋你的代碼時記得還人情社區(qū)會自我平衡等待期間最好的事是去給別人做評審。六、決策流程Decision Making Process以下規(guī)則適用于 Bitcoin Core 項目以及相關(guān)項目如 libsecp256k1的代碼變更不要將其與比特幣網(wǎng)絡(luò)層面的協(xié)議共識變更混淆。PR 是否合并由項目 merge 維護者決定他們綜合考慮補丁是否符合項目總體原則、是否達到入庫的最低標準、以及貢獻者群體的普遍共識。所有 PR 必須滿足有清晰的使用場景修復(fù)可復(fù)現(xiàn)的 bug或服務(wù)項目整體利益例如面向模塊化的重構(gòu)經(jīng)過良好的 peer review在適用處具備單元測試、功能測試和 fuzz 測試對應(yīng)本倉庫的 src/test/、test/functional/ 與 fuzz 目標fuzz 構(gòu)建與運行見 doc/fuzzing.md遵循代碼風(fēng)格規(guī)范C 風(fēng)格見 developer notes功能測試風(fēng)格見 test/functional/README.md不破壞既有測試套件修復(fù) bug 時在可能處應(yīng)有展示該 bug 的單元測試并證明修復(fù)有效以防止回歸行為變化時同步更新相關(guān)注釋與文檔。共識規(guī)則變更遠比普通補丁復(fù)雜因為它影響整個生態(tài)系統(tǒng)必須先經(jīng)過郵件列表的大量討論并配有編號 BIP每種情況都不同但應(yīng)當(dāng)預(yù)期付出比其他方式更多的時間與精力評審與共識構(gòu)建要求都更高。七、Backport回移植的元數(shù)據(jù)規(guī)范安全修復(fù)與 bug fix 可以從master回移植backport到 release 分支。維護者會批量執(zhí)行回移植并在需要時使用正確的Needs backport (...)標簽原作者無需操心。backport commit 的正文必須包含以下元數(shù)據(jù)Github-Pull: #PR number Rebased-From: commit hash of the original commit此外官方還提到可參考歷史 backport PR 實例以及 bitcoin-maintainer-tools 倉庫中的backport.py腳本位于項目外部的 maintainer 工具倉庫本文不展開。八、版權(quán)與許可證向本倉庫貢獻即表示同意除非 contrib/debian/copyright 或文件頂部另有說明否則你的作品以MIT 許可證授權(quán)對應(yīng)倉庫根的 COPYING 文件。凡由你貢獻但并非原創(chuàng)的作品必須包含其許可證頭注明原作者與來源。這與全倉庫源碼文件頭部普遍出現(xiàn)的Distributed under the MIT software license, see the accompanying file COPYING注釋保持一致。九、快速核對清單Pre-Submission Checklist把以上規(guī)范壓縮成提交前的自檢清單改動是否單一聚焦格式化/移動與行為變更是否拆開了每個 commit 獨立可構(gòu)建、無警告、無測試失敗commit 標題 ≤50 字符、正文解釋了為什么、無提及測試按 developer notes 的 commit 結(jié)構(gòu)規(guī)則放對了位置PR 標題帶了正確的 area 前綴對照第三節(jié)的 14 類前綴表正文說明了 what why 測試依據(jù)且無提及只改src/qt之外還碰了構(gòu)建系統(tǒng)或src/interfaces→ 確認應(yīng)走 node 倉庫。若等待 rebasegit fetchgit rebase FETCH_HEADforce push 后用 range-diff 幫助 reviewer 復(fù)核若需 squash按git rebase -i HEAD~n工作流合并并改寫連貫的 commit message。涉及共識關(guān)鍵代碼或共識規(guī)則→ 先確認已有郵件列表討論與 BIP評審門檻相應(yīng)提高。若使用了 AI 工具確認符合 AI_POLICY.md所有對外溝通均為人工撰寫commit 作者中無 agent。以上流程與倉庫中的實際工程設(shè)施CMake 構(gòu)建體系、ci/test/ 的多平臺測試矩陣、contrib/verify-commits/ 的簽名驗證、doc/productivity.md 的評審效率工具共同構(gòu)成了 Bitcoin Core 高質(zhì)量協(xié)作的完整閉環(huán)貢獻者按原子 commit 與聚焦 PR 提交社區(qū)按 Concept/Approach/Code 三層評審過濾維護者按可復(fù)現(xiàn)的簽名歷史合并最終形成一條每個 merge commit 都可審計的master分支。【免費下載鏈接】bitcoinBitcoin Core integration/staging tree項目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考