三个被合并的 PR:开源贡献的质量比数量重要
从 20 个被关闭的 PR 到 3 个被合并的 PR,我学到了选对问题比写对代码更重要。
上一篇博客里我说”从零到两个合并的 PR”,现在可以更新标题了——三个了。
但这不是一篇”我好厉害”的炫耀文。恰恰相反,这是一个关于失败的故事。因为在拿到这三个 merged PR 之前,我有大约 20 个 PR 被关掉了。二十个。有的被 ignore,有的被 reject,有的干脆被 maintainer 一句 “not needed” 打发走。
所以当这三个 PR 在同一天之内先后被 merge 的时候,我的第一反应不是兴奋,而是——终于搞明白怎么回事了。
第一个:修别人不敢碰的 CI
MinionTech/vexilon #404 — 把废弃的 semgrep GitHub Action 迁移到官方 Docker 镜像。
这个项目的 CI 用的是 semgrep/semgrep-action@v1,但这个 Action 早就被官方废弃了。就像你家里那个用了十年的路由器,能用,但厂商已经不管安全更新了。
我的改动很纯粹:把 workflow YAML 里的 uses: semgrep/semgrep-action@v1 换成直接拉 semgrep/semgrep 官方镜像跑 CLI。扫描规则一个没动,SARIF 输出和 GitHub Security tab 的上传逻辑也原封不动。
维护者 DerekRoberts 直接 approve,还专门留了句感谢的话。
我学到了什么: CI/基础设施的维护是开源项目的盲区。大家都想写 feature,没人想修 pipeline。但安全扫描工具过期了是真·风险——这种 PR 虽然不性感,但维护者心里清楚它的价值。
第二个:删没人注意的死代码
sktime/sktime #10129 — 删除 tests/_config.py 里两条过期的测试排除配置。
sktime 是一个大型 ML 项目,测试配置文件里有两条排除规则,对应 SeriesToPrimitivesRowTransformer 和 SeriesToSeriesRowTransformer 这两个类。问题是——这两个类早就从代码库里删了。排除配置变成了幽灵,谁也不会去触发它,但谁也没注意到它还在那儿。
改动:删了 4 行。两条配置,两行注释。没了。
sktime 的核心维护者 fkiraly 的 review 只有两个词:
Good find.
两个字。但我盯着屏幕看了好久。
我学到了什么: 大型项目里,“清理残留”是一种被低估的贡献。代码库越大,这种死配置越容易被忽略。而能被 fkiraly 本人 approve,说明他们认可的不是代码量,是你读代码的细心程度。
第三个:9 行代码修一个会 crash 的 bug
Sakura520222/Sakura-AI-Reviewer #228 — 给 read_file 工具加了目录路径的防护。
这个项目有个 read_file 工具,底层调 GitHub API 的 get_contents() 读文件。但 get_contents() 有个坑:传文件路径返回单个文件对象,传目录路径返回一个 list。原代码只处理了文件的情况,直接调 content_file.size——一遇到目录就炸:'list' object has no attribute 'size'。
经典边界条件 bug。
我在已有的 null guard 后面加了一个 isinstance(content_file, list) 检查,如果是目录就返回明确的错误信息,提示用户用 list_directory。9 行代码,修了一个会 crash 的 bug。
项目的 AI reviewer 给了 9/10 分,项目作者也手动 approve。
我学到了什么: GitHub API 的返回类型不是你想的那样。get_contents() 对文件和目录返回不同类型,这种”隐式多态”是最容易被忽略的坑。而修复这种 bug 的性价比极高——改动小,影响大,谁都能看懂。
20 个被拒 PR 教会我的事
回头看那 20 个被关掉的 PR,原因各不相同,但归结起来就几类:
- 选错了项目。 有些项目根本不需要外部贡献,或者维护者有自己的 roadmap,你提的改动方向不对。
- 选错了问题。 改了个 typo,改了个格式,改了个”我觉得这样更好”——但维护者不觉得。
- 改动太大。 一口气重构了半个模块,reviewer 看了一眼就关了。
- 没读 CONTRIBUTING.md。 每个项目都有自己的规矩,不读就提交 = 白交。
而这三个被 merge 的 PR 有一个共同点:改动精准,解决真实问题,最小化修改。
不是”我觉得这样更好”,而是”这里有个 bug”或”这里有段死代码”。不是重构半个模块,而是删 4 行、加 9 行、改个 YAML。
给想开始开源的 CS 学生
如果你也在考虑给开源项目提 PR,我的建议是:
- 先当读者,再当作者。 花时间读 issue tracker,读已有的 PR,读 CONTRIBUTING.md。理解这个项目需要什么。
- 找 bug,不要找 feature。 Bug 是客观存在的,feature 是主观判断的。维护者很难拒绝一个合理的 bug fix。
- 最小化修改。 改得越少,review 越快,merge 概率越高。
- 接受被拒。 20 个被关的 PR 没有白费,每一个都让我更了解”什么不该做”。
开源贡献不是写代码比赛。它是关于理解一个项目、尊重维护者的时间、以及找到你能真正帮上忙的地方。
——Jiahao Ren, 2026 年 5 月