《开源 PR 实战》系列(三):22 个 PR 之后,批量提 PR 的打法

上一篇写的是单个 PR 从提交到落定的评审,里面攒了 27 条记录。两周过去,台账变成了 38 条:已合并 22 个、在途 9 个、停止 7 个。数量一上来,问题就变了------不再是"这一个 PR 怎么过评审",而是"怎么让找机会、修代码、回评审、记台账这整条线一直转下去"。这一篇就讲这条线:批量提 PR 的打法,以及跑这条线时撞上的 5 个新坑。

文章目录

为什么做这个

单打独斗提 PR 靠的是手感,批量提靠的是流程。手感会累,流程不会。过去这两周,我每天早上先扫一遍新机会,够分的才动手;动手前过五查防撞车;修完先写失败测试再提;评审来了逐条回;状态一变就更新台账。22 个合并就是这么一个一个攒出来的,没有哪一个是撞大运。

先说清口径:本文的数字全部来自我自己维护的 PR 台账(提交、评审、修复、合并、关闭逐条记录,含每轮的提交记录与测试结果);项目与 PR 编号都可公开检索,结论以台账记录为准。系列(二)里讲过的评审故事,这里只在总账里一句话带过,不重讲。

先看总账:38 条记录

结局 数量 说明
已合并 22 系列(二)成文时 12 个,之后两周又合了 10 个
在途 9 深度评审 1、草稿待排队 2、正面评审待合 1、静默等待 5
已停止 7 防撞车主动停 4、被关闭 1、通道不通 1、权限测试件 1
合计 38 另有 1 个候选在等仓库协作者邀请

三节的计数不是手填的,是直接从台账文件里数出来的:

新合并的 10 个(2026-10-24 → 11-02),逐个列出:

PR 合并日期 维护者动作
Cygnux-Labs/Tracekit#357 10-24 维护者 LoopGlitch26 亲手合并,关联 issue #344 同步关闭;合并时附打分评论:server pack 36/57 有害被拦截、strict 41/57,缺口(数据库客户端 10/15 漏、破坏性操作 7/13 漏)转新规则 issue 跟进
Cygnux-Labs/Tracekit#374 10-25 维护者补推一个修复提交(把 Vercel 项目删除放进拦截清单等)后亲手合并,issue #360 同步关闭;合并时 Windows 上 Python 3.9 的一项检查还红着,其余 31 项绿灯或跳过
Cygnux-Labs/Tracekit#373 10-25 维护者先并主干(#374、#378 之后)并补推剩余规则项,亲手合并,issue #359 同步关闭
Cygnux-Labs/Tracekit#377 10-25 维护者亲手合并,留言只有一句「Merged, thanks.」,issue #349 同步关闭
reticlehq/reticle#1875 10-26 维护者 divshekhar 批准后走合并队列合并;中途曾因状态检查失败短暂出队,随即重新入队,issue #1710 同步关闭
existence-master/Sentient#487 10-27 系列(二)里那场七笔攻防收尾:维护者 itsskofficial 批准后走合并队列合并,issue #443 同步关闭,维护者留言致谢六轮评审补上的漏洞
repowise-dev/repowise#4343 10-27 维护者 Raghav Chamadiya 批准后亲手合并;合并前他先并主干解了一个测试文件冲突,issue #3430 同步关闭;CI 是 9 项通过加 1 项跳过
dolev31/lasagna#23 10-31 维护者 dolev31 批准并合并,issue #22 同步关闭;合并后他给出三条后续建议:#22 下的第二个 PR(另一组后端的同类竞态加启动路径审计)、文件描述符上限的 PR、更多向量后端的支持
doobidoo/mcp-memory-service#1726 11-02 维护者 Henry Krupp 亲手补完最后两轮 greptile 评审的修复(迁移重编号、接口回转保留状态字段、日期边界补到微秒末尾、同步基线与接收端携带时间戳字段),留言确认 CI 全绿并表示马上合并,半小时内亲手合并,issue #1724 同步关闭
HelpCode-ai/anythingmcp#1373 11-02 维护者 helpcodeai 亲手合并;留言说 Pipefy 适配器(6 只读工具)会随下一次更新进入官方目录;关联 issue #982 是 11 月 4 日由维护者以另一项完成为由关闭的

10 个里 9 个的关联 issue 在合并时同步关闭,只有 #982 是之后另行关闭的。在途的 9 个是:lasagna 的 3 个(#29 在等 5 点评审收尾,#63、#64 按维护者要求保持草稿、一次只走一个)、distilly #215、ParseBench #213、anatomy #120 和 #121、MaiBot #2218 和 #2220。停止的 7 个是:五查拦下的 4 个重复机会(Chisle #24、Easel #73、traceroot #2658、obsidian-second-brain #351)、被维护者关闭的 MaiBot #2219、对方只接受维护者登记的 harness-sdk、权限测试用的 magpie#1。

怎么做的

整条线分六步:机会雷达、五查防撞车、修复、评审、合并、台账同步。每一步都有检查点,检查点越多,单个 PR 的翻车成本越低,批量才成立。

机会雷达:每天早上扫一遍

每天早上扫一遍 AI 与大数据领域的新 issue,只找能产出 PR 的机会------纯验证汇报类的 issue 直接淘汰,不进候选。每个机会按四个档位打分(时效、含金量、匹配度、难度),够分才汇报;推荐前直读 issue 的最新状态做最终确认,汇报前再做一次防撞车终查。

雷达的价值不在"找得多",在"筛得狠"。一个 issue 就算看起来再合适,只要状态变了(被人认领了、已经有同范围 PR 在途了),就直接划掉。批量提 PR 最怕的不是没活干,是把工时砸进一个已经有人在做的坑里。

五查防撞车:动手前的最后一道门

提 PR 之前过五查:issue 仍开放、无人认领、无已关联的在途 PR、无同范围在途 PR、时间线无新动静。五项全过才动手,任何一项不过就停下,停下的机会留证据存档。

这两周五查拦下 4 个,两个值得细说。traceroot 那个机会,终查发现已经有两个在途 PR 覆盖同一修复,两位作者之间甚至已经达成了"谁先走"的让路共识。终查的原始记录长这样:

obsidian 那个更险:有人早上 08:35 在 issue 里留言认领,08:47 就开了 PR,覆盖范围与 issue 要求完全重合------我查的时候离他开 PR 只差几个小时。五查拦下的每个机会都留了证据:终查结果、已存在的 PR 编号、让路共识的截图式记录。算一笔账:这 4 次停下省下的是四份完整的"复现、修复、测试、写描述"工时,更重要的是维护者的评审带宽------那是整个开源生态里最稀缺的资源。不提,有时和提一样是贡献。

修复:先写一个会失败的测试

动手修之前先确认一件事:这个仓库让不让外部人开 PR。有的仓库设置了"仅协作者可开 PR",修复全做完才发现开不出 PR,一整天白干------这是系列(二)里的坑一,顺序记死:权限检查是第 0 步。

修的顺序固定四步:诊断、写复现脚本或一个会失败的测试(先跑出失败)、本地修、跑通测试。提 PR 之前必须自己验证过------验证要真跑起来(本地部署、单测、真实环境抓包都算,选能覆盖改动的最强手段),没验证通过不许提 PR;验证手段如实写进 PR 正文,不夸大。

lasagna #23 是这套顺序的标准样本:集合创建的竞态问题,先用 Docker 起 Qdrant 跑压力测试,主干 50 轮里 50 轮都复现出 bug,修完的分支 50 轮全过,才敢提 PR。维护者后来给的三条后续建议,等于把下一轮的活也指出来了------这种"提一个、带出一串"的 PR,是批量打法里最划算的一种。

评审:机器人与维护者是两轮不同的仗

评审分两轮,严肃程度不分彼此,但每轮的期待不一样。机器人评审抓形态与已知模式:两轮 greptile 评审在 #1726 里补了迁移编号、接口回转、日期边界这些细节;CodeRabbit 在 MaiBot 的 PR 里连着三轮给可执行意见,每轮都修完逐条回复。机器人那关过了,不等于维护者这关过了------前者只是后者的入场券。

维护者评审抓架构与信任边界。#1373 的维护者在 10 月 30 日给了 changes-requested,4 项全修完才在 11 月 2 日合并。#1726 收尾阶段是维护者本人下场,亲手补完最后两轮 greptile 评审的修复才合并。回复纪律只有一条:每一轮都逐条对应、附测试数字与证据,集中在一条回复里讲清,不连环刷屏;测不了的如实写明是环境限制还是权限够不着------评审者对"诚实标注的未测"宽容,对"假装测过"零容忍。

合并之后:台账同步三步

状态一变就更新台账,三步缺一不可:移表(在途移到已合并或已停止)、同步节标题里的计数(已合并 22、在途 9、已停止 7)、在"更新记录"里加一行日期加动作。38 条记录能随时拿出来对账,靠的就是这条纪律。台账不是记给别人看的,是批量打法的仪表盘:哪个 PR 卡在哪一步、哪个仓库的维护者回应最快、哪类 issue 最容易撞车,全从台账里读出来。

踩过的坑

坑 1:PR 描述里写 closes,GitHub 会替你关 issue。 lasagna #23 的描述里我写了一句"a follow-up PR, which closes #22",主语明明是 follow-up PR。10 月 31 日合并时,GitHub 照样把 #22 自动关了------只要描述里出现 closes/fixes/resolves 加编号,不管主语是谁,合并就触发关闭。维护者亲手把 #22 重开,才没酿成事故。教训:只有本 PR 真要关那个 issue 才用 closes/fixes/resolves;指代其他 PR 或未来动作时用纯引用(see #22)或非关键字动词(address #22,"address" 不在 GitHub 的关键字表里)。

坑 2:把 draft 摘掉,正规接口有三条弯路。 lasagna #29 要从草稿转正式评审,第一条路是改 draft 字段的接口,调过去没报错、也没生效------GitHub 静默忽略;第二条路是现成的 ready_for_review 接口,经代理调过去报 404;第三条路是直接调 GraphQL 的 markPullRequestReadyForReview,2026 年 10 月 31 日一次成功,返回 isDraft:false。教训:摘 draft 别绕路,直接走 GraphQL 的这一个方法;接口"没报错"不等于"生效了",改完要读回状态确认。

坑 3:fork 同步报 404,先问 merge-upstream。 系列(二)里写过一次这个坑的简版,这次补上当时没写全的两个细节。有次同步 fork,写操作一律报 404,像仓库凭空消失。最后调 merge-upstream 接口,它返回 422 并写明真实原因:上游新增了一个工作流文件(.github/workflows/pr-maintainer-edits.yml),而我的令牌没有 workflow 权限范围,GitHub 对这类权限问题一律用 404 掩盖。解法是改走网页端手动点同步,一次解决。教训:fork 写操作莫名报 404,一律先调 merge-upstream 拿真实原因;平时给令牌加权限范围时,把 workflow 也算进去。

坑 4:新仓库搜不到,先别怀疑自己。 11 月 6 日新建了一个仓库,6 分钟后用 user: 搜索查创建者名下的仓库,返回 0 条。第一反应是"是不是建失败了",其实是 GitHub 搜索 API 有索引延迟,刚建几分钟的仓库搜不到是常态。教训:查 fork 或仓库是否存在,必须直接打开仓库地址验证,不能只信搜索结果。

坑 5:lint 全绿不等于 CI 全绿,描述里的 Evidence 小节本身就是一道门。 lasagna #29 在 11 月 3 日被 5 点评审卡住,跟进时 lint 已经全绿,但 CI 还有一项失败------原因是 PR 描述里缺了 Evidence 小节,CI 有一项检查就是核对描述模板。教训:lint 只是 CI 的一部分,描述模板里的必填小节(Evidence、复现步骤、测试结果)缺一项就可能单独挂一项;提 PR 前按模板逐项自查,提交后先看 CI 全量结果再等评审。

注意事项

  • 一次只走一个:lasagna 的 #63、#64 按维护者要求保持草稿、按顺序等待,不要并行推------维护者明确要 one-at-a-time,抢跑只会让他多花精力协调顺序。
  • 认领权也要防守:lasagna 的 issue #30 有人另开了一个撞车 PR #75,维护者直接关闭了 #75 并在 issue 里留言,认领权稳固。认领之后不是万事大吉,定期看一眼 issue 时间线,有撞车苗头早处理。
  • 监控列表随新增及时补:后来加进台账的几条(lasagna #29、#63、#64、anythingmcp #1373)一度不在监控列表里,只能手动逐个调接口核验状态。台账加新 PR 的同时,把监控列表也补上,别等漏报才发现。
  • 认领池会关:anythingmcp 的 #982 在 11 月 4 日因另一项完成被维护者关闭,认领池实质关闭。认领池不是长期开放的,看到想认领的适配器要趁早;关了就换下一个目标,别在已关闭的池子里等。

复盘

做对了三件事

第一,机会雷达让"找活"从碰运气变成流水线。每天早上扫一遍、够分才动手,活不断流,也不会把工时砸进已经有人做的坑里。第二,五查加证据存档让"不提"也有记录。4 个停下的机会每一项都有终查结果和已存在 PR 的编号,复盘时不用凭感觉。第三,台账同步三步让 38 条记录随时可对账。数字全有出处,写文章时直接从台账里取,不用翻聊天记录拼凑。

做错了什么

PR 描述的 closes 关键字是最不该犯的一个------规则就写在 GitHub 文档里,是我写描述时顺手用了"which closes #22"这个句式。mark ready 也走了两条弯路才找到 GraphQL 的方法,说明"接口没报错"这个信号我一开始就信错了。监控列表没及时补新增 PR,核验一度只能靠手动逐个调接口,这三处都是流程里的补漏点,已经记进检查清单。

核心收获

批量提 PR 的本质不是"提得多",是"每一步都有检查点":雷达筛、五查拦、复现验、评审改、台账对账。检查点越多,单个 PR 的翻车成本越低,批量才成立。反过来,任何一个检查点漏了,代价都会在后面加倍还回来------一个没做五查的 PR,可能浪费的是维护者一次评审;一个没验证的 PR,浪费的是整个评审轮次的信任。

总结

  • 38 条记录可对账:已合并 22、在途 9、停止 7,两周新合 10 个,关联 issue 9 个同步关闭
  • 批量打法是六步流水线:机会雷达、五查防撞车、修复、评审、合并、台账同步,每步都有检查点
  • 修复的顺序是诊断、先写会失败的测试、本地修、跑通测试,没验证通过不许提 PR
  • GitHub 有三处"静默"行为要记牢:closes 关键字不管主语照关 issue、改 draft 字段静默忽略、缺 workflow 权限的 404 是掩码
  • 评审回复逐条对账、测不了的如实披露;监控列表与认领池都要随状态及时跟进

以上,全文完。

这篇对你有帮助的话,欢迎留言交流你的做法,也欢迎提出不同看法。

最后认识一下,我是黎羽,一名 AI 实践爱好者,会不定期记录我的学习过程,期待你的关注和分享。

相关推荐
Hone3 小时前
juejin-skills 系列 ②:我把「看掘金热榜」也做成了 Agent 技能
开源·node.js·ai编程
fthux4 小时前
总想着“忙完再休息”?让 Tick Rest 提醒你,先歇一会儿
开源·github·mac·swift·提醒·消息提醒·tick rest·tick rest for mac·消息提醒app
dong_junshuai5 小时前
每天一个开源项目#156 Astryx:主题编译、异步按钮与源码接管
github
SL_staff5 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc
一知半解仙6 小时前
乌镇2026:当“智能互联网”第一次被数据照进现实
人工智能·物联网·机器人·开源
逛逛GitHub7 小时前
把你的 AirPods 当鼠标用,这 3 个黑科技 GitHub 开源项目有趣。
github
徐小夕10 小时前
开源Vector-Graph-RAG:向量+图谱双引擎,打破纯向量RAG的效果天花板
前端·vue.js·github
GitHub实测笔记10 小时前
zoxide 本机实测:一万条记查询中 5.7ms0.10 版 import --from
github
复杂网络与机器学习10 小时前
数学建模七件武器:把现实翻译成能算的模型,再证明它靠得住
数学·开源