10.1 开源协作的特殊性
给海外开源项目贡献,与公司内 PR 协作有几个根本不同:
- 你是请求者,maintainer 没义务回应你。 Maintainer 多数是无偿志愿者,PR 入队列后什么时候被看是他们的安排。
- 沟通门槛比合并门槛低。 任何人都能开 issue 评论,但合不合代码是 maintainer 决定。
- 跨文化敏感度极高。 大型项目有来自全球的贡献者,对礼貌、性别代词、CoC(Code of Conduct)的标准远高于公司内部。
- 留痕永久公开。 你 5 年前的傲慢评论会被新的雇主搜到。
所以开源沟通的英语不是"标准协作英语" + 一点礼貌——它是另一个语体,需要更软、更耐心、更明显地承认对方的工作。
10.2 第一次提 PR 的礼貌话术
第 0 步:先看 CONTRIBUTING.md
大部分项目根目录有 CONTRIBUTING.md 或 .github/CONTRIBUTING.md,规定了贡献流程、commit 规范、CI 要求。读完再开 PR 是基本礼仪。如果你跳过:
# Maintainer 会发的回复(典型)
"Thanks for the PR! Could you read CONTRIBUTING.md first?
We require <X> before we can review."
开篇礼貌话术
提交前,特别是较大改动,先开个 issue 沟通:"Is this approach acceptable?" 比直接甩 PR 礼貌得多。
# 试探性 issue
"Hey @maintainer, I noticed <problem> and I'd like to take a stab
at fixing it. Before I start, would you be open to an approach
that does <A>? Or do you have a different direction in mind?
Happy to discuss before I write any code."
# 直接 PR 时的开篇
"Hi! First-time contributor here. This PR addresses #1234.
I tried to follow the existing patterns in <related-file> — let
me know if I missed any conventions. Looking forward to your
feedback!"
说明限制
# 提前告知缺口
"This is a draft. The implementation is complete but the test
coverage is only ~70% — I wanted to get directional feedback
before adding more tests."
"I haven't been able to test on Windows. If you can run the CI
on a Windows runner, that would catch any platform issues."
"This is my first time touching this part of the codebase, so
please be brutal in review."
请求 review
# Tag 时礼貌
"Whenever you have a chance, would love a review on this. No rush
— I know the team is heads-down on the v3 release."
"@maintainer would you be the right person to look at this, or
should I tag someone else?"
"Hi @maintainers — bumping this gently. Happy to make any
adjustments needed. If now's not a good time, just let me know
and I'll come back later."
10.3 被 reject 时的回应
被 reject 是开源协作的常态。你的代码 50% 概率不会被合——即使写得很好。Maintainer 拒绝可能是因为:
- 方向不符合项目规划
- 引入新依赖 / 增加 surface area
- 已有人在做类似工作
- maintainer 看完觉得 "增加的复杂度 > 用户价值"
被 reject 时要做的不是争论,而是:
- 感谢 maintainer 花时间看。
- 表达理解。
- 询问是否有不同的方向可以贡献。
- 不要把 PR 留在那里 "万一改主意"。
拒绝接受模板
# 完全接受
"Thanks for the explanation — totally makes sense. I appreciate
you taking the time to look at this. I'll close the PR. If a
different approach would help, let me know."
# 接受但保留意见
"Understood, and I appreciate the explanation. I do think <X>
might still be valuable, but I respect that it's not aligned
with where the project is going. Closing this for now."
# 不完全理解,请求澄清
"Thanks for looking at this. Could you help me understand the
concern with <X>? I want to make sure I take the right lesson
from this for future contributions."
# 提议 follow-up
"Got it. Out of curiosity, would a smaller PR that just <Y> have
a better chance? Happy to scope down."
不要因为一次 reject 就在 issue 里抱怨 / 在 Twitter / 微博上吐槽 maintainer。开源圈是小圈子,一次抱怨可能让你以后所有 PR 都被打上"难合作"的标签。
10.4 报告 bug:MRE / MCVE
MRE = Minimal Reproducible Example
MCVE = Minimal, Complete, Verifiable Example
开源 maintainer 收到的 90% bug 报告都缺少 MRE。能写出 MRE 的报告自动跳到处理队列前列。
MRE 三原则
- Minimal:删掉所有不影响 bug 的代码。一个公司项目的 1000 行复现脚本不是 minimal。
- Complete:从
npm install或git clone开始的人能跑起来。不要省略 import / setup / config。 - Verifiable:你自己跑过这份代码确认 bug 能复现。
MRE 模板
### Bug summary
<一句话>
"Calling foo({ x: undefined }) in v2.4 throws, but worked in v2.3."
### Steps to reproduce
```bash
git clone https://github.com/me/repro
cd repro
npm install
npm test
```
The repro repo contains:
- package.json (pinning the affected version)
- index.js (5 lines, the failing call)
- test.js (one test that asserts the failure)
### Expected behavior
foo({ x: undefined }) should return null.
### Actual behavior
TypeError: Cannot read properties of undefined.
Full stack trace at <link to gist>.
### Environment
- <package> version: 2.4.1
- node: 20.11.0
- OS: macOS 14.3 (also reproduces on Ubuntu 22.04 in CI)
### Bisect
git bisect identifies commit abc123 ("refactor: ...") as the
first bad commit. Reverting that commit fixes the issue.
"Bisect" 这一段是黄金加分项——你已经替 maintainer 缩小了搜索空间到一个具体 commit。
10.5 Mailing list 的语体
Linux kernel、Postgres、Python、GCC、LLVM 等"老派"项目仍以 mailing list 为主要协作媒介。Mailing list 的英文比 GitHub Issue 更正式:
开篇 / 称呼
# 正式
"Hi all,"
"Hi $maintainer,"
"Dear $maintainer,"
# 较随意但仍合适
"Hello,"
"Greetings,"
主体段落
# 描述更完整,少缩写
(GitHub)"AFAICT this breaks BC."
(mailing) "As far as I can tell, this change breaks backwards
compatibility because ..."
# 引用上文用 > 标记(plain text email 传统)
On Mon, Apr 8, 2024 at 10:23 PM Alice <alice@example.com> wrote:
> I think we should add a flag for this.
>
> The flag would default to off.
I'd push back on adding a new flag here. We've been trying to
reduce config surface area in 2.x ...
结尾署名
# 最常见
Best,
Your Name
# Linux 风
Thanks,
--
Your Name
# 完整签名(含组织 / 角色)
Best regards,
Your Name
Senior Engineer, Some Company
your@email.com
Subject line 的传统
# Linux kernel 风格 (含子系统标签)
[PATCH v2 3/5] mm: vmscan: don't watermark boost on swap-full
# Postgres 风格
[PATCH] Fix double-free in transam during recovery
# Python 风格
PEP 729: Typing governance process
# 回复用 Re:
Re: [PATCH v2 3/5] mm: vmscan: don't watermark boost ...
10.6 Code of Conduct (CoC) 术语
大部分知名项目都采纳了 Contributor Covenant 或类似 CoC。常见术语:
| 术语 | 含义 |
|---|---|
| Code of Conduct (CoC) | 行为准则 |
| contributor | 贡献者 |
| maintainer | 维护者 |
| community | 社区 |
| harassment | 骚扰 |
| doxxing | 人肉搜索 |
| trolling | 故意挑衅 |
| bad faith | 恶意 |
| good faith | 善意 |
| marginalized groups | 边缘化群体 |
| inclusive language | 包容性语言 |
| warning / strike | 警告 |
| temporary ban | 临时封禁 |
| permanent ban | 永久封禁 |
需要避免的语言
以下用词在现代开源圈被认为不合适,主流项目已系统替换:
| 避免 | 替代 |
|---|---|
| master / slave | main / primary, replica / secondary |
| blacklist / whitelist | denylist / allowlist, blocklist / safelist |
| guys (指代群体) | everyone, folks, team, all |
| he / him 默认假设 | they / them |
| man-hours | person-hours, engineer-hours |
| sanity check | quick check, smoke test |
| dummy variable | placeholder, stub |
| crazy / insane | wild, surprising |
这些不是"政治正确"——是项目维护成本。Inclusive language 让更多人愿意贡献,对项目长期健康有实际收益。GitHub、Linux kernel、Python 等都已经做了批量重命名(master → main 等)。
10.7 跨时区异步沟通
时区话术
# 告知你的时区
"I'm in UTC+8 / China time, so my replies during your evening
will be slow. I'll get back to you within 12-18 hours."
"For context: I'm based in Shanghai. The fastest sync would be
your morning / my evening."
# 安排会议
"Could we find a time that works across <regions>? I have a
fairly flexible schedule between 0:00–10:00 UTC."
"Suggested slots (in UTC):
Tue 14:00 / Wed 14:00 / Thu 23:00
What works for you?"
常用异步术语
# 时间相关
EOD (end of day) - 当天结束前
EOW (end of week) - 周末前
COB (close of business) - 下班前
SOD (start of day) - 当天上班后
ETA - estimated time of arrival
RSVP - 请回复(参会)
# 状态
afk (away from keyboard) - 暂离
ooo (out of office) - 不在
on-call - 值班
heads down - 专注工作中
# 沟通
ping - 找一下
nudge / bump - 轻轻提醒
loop in - 拉某人进对话
cc - 抄送
fwiw - for what it's worth, 仅供参考
异步消息模板
# 提问 + 默认动作
Hi @maintainer,
I'm working on issue #4321. Two implementation paths I'm considering:
A. <描述>
B. <描述>
If I don't hear back by Friday EOD UTC, I'll go with option A
(simpler, but slightly less flexible).
Thanks!
# 状态更新
Quick update on #5678:
- Implementation: 80% done
- Tests: 50% done
- ETA: PR by next Tuesday
Will ping again when it's ready for review.
# 请求帮助 + 优雅退路
Stuck on this part — looking for hints, not a solution. If
nobody has time this week, no worries; I'll keep digging.
10.8 真实开源贡献流程
下面是从 0 到 PR 合并的标准流程:
Step 1: 找一个 "good first issue" 标签的 issue
↓
Step 2: 评论占坑
"I'd like to take this on, if no one else is working on it."
↓
Step 3: Fork + clone
$ gh repo fork owner/repo --clone
↓
Step 4: 读 CONTRIBUTING.md
↓
Step 5: 写代码 + 测试
↓
Step 6: 跑 lint / test / format
$ make lint test fmt
↓
Step 7: Commit (Conventional Commits)
$ git commit -m "fix(parser): handle UTF-16 BOM"
↓
Step 8: Push + 开 PR
↓
Step 9: 等 CI + 等 review
↓
Step 10: 回应 review 评论
↓
Step 11: 被合并 / 被关闭 / 收到 nudge
↓
Step 12: 致谢 maintainer,并继续找下一个 issue
10.9 与 maintainer 建立长期关系
偶尔贡献一两个 PR 收益小;持续给一个项目贡献 6-12 个月,回报巨大(job referral、行业声誉、技术深度)。
建立关系的 7 个动作
- 持续在同一个项目贡献。Maintainer 会逐渐记住你的名字。
- 积极在 issue 区帮其他人。回答其他用户的问题,maintainer 会感激。
- 主动 review 别人的 PR。Maintainer 时间紧,外部 reviewer 是宝贵的。
- 写好 release notes / changelog 条目。这是 maintainer 经常忘记的脏活。
- 修文档 typo。看起来微小,但显示你"在用心"。
- 不催 review。每周一次 nudge 是上限。
- 合并后致谢。"Thanks for the thorough review!" 让 maintainer 觉得有被看见。
"开源不是慈善,是声誉投资。" 持续贡献 6-12 个月,你的 GitHub profile 比简历更有说服力。
10.10 真实场景模板库
1. 第一次 issue
Hi! Loving the project. Bumped into <issue> with v2.4.1.
<描述 + MRE>
Happy to work on a fix if you'd accept a PR for this.
2. 主动接 issue
I'd like to take a stab at this if no one's actively working on it.
Plan: <3 sentences>. Will open a draft PR within a week.
3. PR 收到 review 但没人合并
Friendly nudge — anything blocking this from merging? Happy to
make further changes if needed.
4. PR 被静默 30 天
Hi @maintainers, gently bumping this PR. If now's not a good time
to review, no worries — please let me know if I should close it
and re-open later.
5. 自己改方向
Update: I dug deeper and realized my original approach was wrong.
The actual fix needs to happen in <another module>. Closing this
PR; will open a new one against that module.
6. 答其他贡献者的问题
Not a maintainer, but I had the same issue last week. Solution
was <X>. Hope this helps until someone official can confirm.
7. 提议成为 maintainer
I've been contributing here for ~9 months now (12 PRs merged).
If you're open to expanding the maintainer team, I'd be happy
to take on triage / first-line review duties. No pressure if
the team is happy as is.
10.11 本章小结
- 开源协作是请求关系,不是同事关系。语气要更软、更耐心、更显感激。
- 第一次 PR:试探性 issue → CONTRIBUTING.md → draft PR → 礼貌请求 review。
- 被 reject 时不争论,致谢 + 关闭 + 询问其他贡献机会。
- Bug 报告必须有 MRE(minimal / complete / verifiable)。
- Mailing list 比 GitHub 更正式,注意主题前缀和 quote 风格。
- 避免有歧视隐喻的术语:master/slave、blacklist/whitelist、guys 等。
- 跨时区沟通明确时区 + 默认动作。
- 持续贡献 6-12 个月才能积累信誉,开源是声誉投资。
下一章我们攻克最高强度的英语场景——技术面试。