贡献与 PR
维护者合并一个 PR,等于承诺长期维护这段代码。理解这一点,很多写法就自然了。
先读规范
CONTRIBUTING.md 通常规定分支命名、提交格式、测试要求、review 流程和发布节奏。照着做不会让改动变好,但能让它进入可评审的状态。
- 从文档、拼写、测试这类小改动起步,先熟悉流程
- 大改动先开 issue 对齐方向,避免写完被拒
- 用项目指定的格式化工具和 lint 配置
- 不认识的流程直接问,比猜更快
- 看
good first issue标签找入口
小改动也有价值:它让你在没有内容争议的情况下走完一遍 CI、review 和合并流程。
许可证决定了后果
你提交的代码会自动按项目现有的许可证授权。动手前确认许可证类型,尤其是公司项目里碰 copyleft 代码。
| 许可证 | 类型 | 影响 |
|---|---|---|
| MIT | 宽松 | 保留版权声明即可 |
| Apache-2.0 | 宽松加专利授权 | 需保留 NOTICE,专利条款更明确 |
| GPL-3.0 | copyleft | 衍生作品分发时也要开源 |
| AGPL-3.0 | 网络 copyleft | 提供网络服务也可能触发开源义务 |
不确定时查 choosealicense.com,或直接问法务。有些项目还要求签署 CLA,或者用 git commit -s 添加 Signed-off-by 表示 DCO 同意。
PR 的形状
一个 PR 只解决一个问题。重构、功能、无关修复混在一起,reviewer 无法判断哪一行导致了行为变化,回滚时也会带走不相关的东西。
如果多个改动共同支撑一个功能,可以放在同一个 PR,但每个提交要能独立阅读,让维护者可以选择逐提交评审。
git commit -s # 附上 Signed-off-by
gh pr create --draft --base main # 早期对齐用草稿
git range-diff origin/main pr-v1 pr-v2 # 对比改写前后PR 描述要写 why,不只写 what。主动标出需要重点看的文件、做过的取舍、怎么验证;在描述里写 Fixes #123 可以在合并时自动关闭对应 issue。
上游优先
优先向原项目提 PR。fork 应该留给原项目范围之外的改动,或者上游已经停止维护的情况;fork 之后要注明来源和许可证。
AI 让生成看起来合理的 PR 变得很容易,但这不免除你理解代码的责任。提交自己讲不清的代码,等于把审查和维护成本转给已经超载的维护者。
- 改动前确认它属于项目范围,不是只有你需要
- 主动补测试和文档,别让维护者替你补
- 合并后继续跟进回归,而不是消失
- 被拒绝时问清方向,换项目比争论更快
收到反馈时记住代码不等于人。不同意就问清楚,可能你学到东西,也可能对方改变看法。
沟通渠道
issue、聊天和 PR 评论各有用途。设计讨论放 issue,方便后来人搜索;紧急阻塞用聊天;具体代码意见留在对应行,别搬到私聊。
公开渠道的讨论会变成项目历史。把结论从聊天搬回 issue,是给下一个遇到同样问题的人省时间。
评审之后
收到评论后逐条回应:改了的说明改在哪,没改的说明理由。沉默会让 reviewer 无法判断你是没看到还是不认同。
- 用
git commit --fixup=<sha>生成补丁,再rebase -i --autosquash归位 - 跨多轮修改时保持 PR 描述最新,别让它描述旧方案
- 强制推送用
--force-with-lease,避免覆盖别人的提交 - 合并后删除远端分支,保持分支列表干净
- 不认同的意见先问依据,再决定是否坚持
- 提交前跑一遍项目要求的测试与格式化命令
- 改动公开 API 时同步更新文档和类型标注
评审意见针对代码,不针对你。把「他否定了我的方案」换成「他的约束和我不一样」,讨论会容易很多。
如果维护者明确说这个改动不适合项目方向,接受结论比继续争论更省时间。方向判断属于维护者,实现质量才属于你。