开源贡献
fork 模型、upstream 同步——给真正的开源项目提交代码
你的第一个 upstream PR,就在本章想贡献却卡住
你用着一个开源库,发现 bug,想帮忙改——然后呢
没权限直接改
你想改别人的仓库,但没有推送权限。clone 下来改完,怎么把改动送回去?
fork 是什么
听说要「先 fork」,但 fork 之后呢?自己的 fork 和原仓库什么关系?origin 和 upstream 又怎么区分?
不知从何下手
大项目几百个 issue,哪个适合新人?怕改得不好被拒,干脆不贡献了。
学完这章,你就有能力给任何开源项目贡献代码了。
开始之前
适合谁
- 会 PR,但只在自己的项目里做过
- 想给开源项目贡献,却没迈出第一步
- 被 fork / upstream / origin 绕晕过
你将学会
- 理解 fork 模型和两份仓库的关系
- 同步 upstream 保持 fork 最新
- 读懂 CONTRIBUTING 和行为准则
- 用 good first issue 找到合适的入门任务
- 提交一个规范的 upstream PR
本章暂不覆盖
- 开源协议选择(法律范畴)
- 维护自己的开源项目(进阶)
- GitHub Sponsors 赞助
fork 是什么
把别人的仓库「复印」一份到你自己的账号下

图:fork 模型与两个 remote
【AI 生图提示词】请生成一张中文技术示意图,风格简洁、配色柔和、适合教学: - 画面主体:三个仓库框横向排列。左「upstream 原作者仓库」(如 octocat/Project),中「origin 你的 fork」(你/Project),右「本地仓库」 - 各元素关系:upstream → origin 之间标「fork 复制」;origin ↔ 本地 之间双向箭头标「push / pull」;upstream → 本地 单向虚线箭头标「fetch 拉取上游更新」 - 关键标注:upstream 框标「你无权直接推」,origin 框标「你完全控制」,本地框标「你的开发环境」 - 配色建议:浅灰背景,upstream 用蓝色,origin 用橙色,本地用绿色 - 画面比例:16:9 - 避免:3D 效果、过多文字、复杂图标
origin,你能 push),一份是原作者的(upstream,你只能 fetch)。你的改动推到 origin,再从 origin 向 upstream 提 PR。
怎么 fork
在原仓库页面点一个按钮就行
操作步骤
- 打开你想贡献的仓库页面(如
github.com/原作者/项目) - 右上角点
Fork按钮 - 选择 fork 到你的账号下
- 几秒后,你的账号下出现
github.com/你/项目
fork 之后
这个 fork 是你自己的副本,你可以随便改、随便推,不会影响原仓库。
原仓库页顶会显示「forked from 原作者/项目」。
克隆你的 fork
注意:clone 的是你自己的 fork,不是原仓库
# clone 你的 fork(origin 自动指向它)
$ git clone https://github.com/你/项目.git
$ cd 项目
# 查看当前 remote
$ git remote -v
origin https://github.com/你/项目.git (fetch)
origin https://github.com/你/项目.git (push)
一定要 clone 你自己账号下的那份 fork。地址里应该是你的用户名。
关联上游
手动添加原仓库为 upstream,方便后续同步
# 添加原作者仓库为 upstream(名字可自定义,约定叫 upstream)
$ git remote add upstream https://github.com/原作者/项目.git
# 现在有两个 remote
$ git remote -v
origin https://github.com/你/项目.git (fetch/push)
upstream https://github.com/原作者/项目.git (fetch)
为什么需要 upstream
原作者会持续更新仓库。你的 fork 不会自动同步。要定期从 upstream 拉更新,否则你的 fork 越来越旧,提 PR 时容易冲突。
注意:upstream 只有 fetch 权限(只读),你无法 push 到 upstream。
同步上游
把原作者的最新改动拉到你的本地,再推到你的 fork
# 1. 拉取 upstream 的最新内容(只下载,不合并)
$ git fetch upstream
# 2. 切到 main 并确保是最新
$ git checkout main
$ git merge upstream/main
# 3. 把同步后的 main 推到你的 fork(origin)
$ git push origin main
GitHub 网页也有一键同步按钮:你的 fork 页面 →
Sync fork。
贡献全流程
从开分支到提 upstream PR 的完整节奏

图:开源贡献的完整步骤
【AI 生图提示词】请生成一张中文技术示意图,风格简洁、配色柔和、适合教学: - 画面主体:一条横向流程图,6 个步骤的圆角矩形从左到右排列,用箭头连接 - 各元素关系:① 同步 upstream(拉最新)→ ② 开 feature 分支 → ③ 改代码并 commit → ④ push 到 origin(你的 fork)→ ⑤ 在 GitHub 向 upstream 开 PR → ⑥ 等待 review 并合并 - 关键标注:第 5 步框下方注「base 选 upstream/main,head 选你的 fork 分支」,第 6 步框下方注「可能要改几轮」 - 配色建议:浅灰背景,步骤框用浅橙色渐变,箭头用深色,关键标注用小字 - 画面比例:16:9 - 避免:3D 效果、过多文字、装饰性图标
动手前
改代码之前,先做这两件事
同步上游
确保你的 fork 基于最新代码:
$ git checkout main
$ git fetch upstream
$ git merge upstream/main
$ git push origin main
开专属分支
从最新 main 开分支,名字说清改什么:
$ git checkout -b fix/typo-in-readme
不要在 main 上直接改。每个贡献一条独立分支。
CONTRIBUTING
贡献指南——告诉你这个项目要怎么提交
在哪看
- 仓库根目录的
CONTRIBUTING.md - 或仓库页
Contributing链接(部分项目)
里面通常写明
- 如何搭建开发环境
- 代码风格规范
- 提交 PR 前要跑的测试
- commit 消息格式
- 分支命名约定
行为准则
Code of Conduct——开源社区的礼仪公约
它规范什么
- 如何友善地交流
- 哪些行为不被容忍(人身攻击、歧视等)
- 违反了怎么举报
对你意味着
在 issue、PR、讨论里保持尊重和专业。技术分歧可以争,但不攻击人。这是参与开源的基本前提。
找入门任务
good first issue——专为新人准备的简单任务
怎么找
仓库 → Issues → 搜索框输入:
label:"good first issue"
或 GitHub 全局搜索:github.com/issues?q=label:good-first-issue
其他友好标签
help wanted:维护者欢迎帮忙documentation:文档类,门槛低beginner-friendly:类似 good first issue
先沟通再动手
大改动前先在 issue 里说一声——避免白干
小改动
修 typo、改文档、明显的 bug——直接做,提 PR 即可。不用预先沟通。
大改动
新功能、重构——先在 issue 里描述方案,等维护者认可再写代码。
否则可能花一周写完被拒绝「我们不想要这个功能」。
提 upstream PR
push 到你的 fork 后,向原仓库发起 PR
# push 你的 feature 分支到 fork(origin)
$ git push -u origin fix/typo-in-readme
关键:base 和 head
- base:选
原作者/项目/main(合并目标) - head:选
你/项目/fix/typo-in-readme(你的改动)
跨仓库的 PR,GitHub 会自动识别 fork 关系。
PR 描述要点
开源 PR 的描述要更完整——维护者不认识你
## 改动说明
修复 README 安装步骤中的 typo,把 `npm intsall` 改为 `npm install`。
## 关联 issue
Closes #45
## 改动类型
- [x] 文档修复
## 检查清单
- [x] 已阅读 CONTRIBUTING.md
- [x] 改动只涉及文档,不影响代码
- [x] 本地已预览渲染效果
维护者是陌生人,给他们足够的上下文,你的 PR 才会被快速审阅。
回应 review
维护者要求修改是常态——不是否定
正确心态
- request changes 是协作的一部分,不是批评
- 维护者比你了解项目,意见通常有道理
- 有不同想法可以礼貌讨论
怎么响应
- 在同一分支上继续 commit 修改
- push 后 PR 自动更新
- 每条意见回复一下:「已改」「这个我有不同看法,因为...」
- 别 squash 掉讨论痕迹,保留对话历史
合并之后
你的贡献正式成为开源项目的一部分
会发生什么
- 你的头像出现在仓库的 Contributors 列表
- 你的 GitHub 头像绿了对应日期(贡献图)
- 这是你简历上能写的真实开源经历
清理工作
- 删除本地的 feature 分支
- 同步 upstream(现在含你的改动)
- 你的 fork 上保留分支即可,GitHub 会提示删
从哪开始
适合第一次贡献的途径
你正在用的工具
你最熟悉的库/工具是最好的起点。你了解它的用法,容易发现问题。边用边贡献,动机最强。
聚合网站
goodfirstissue.dev:汇集 good first issueup-for-grabs.net:友好开源项目列表firsttimersonly.com:新人指南
文档类起步
修 typo、补说明、翻译文档——门槛最低、最容易被合并。适合建立第一次信心。
动手试一试
完成你的第一次 fork-PR 流程
你的任务
任务:fork 一个开源仓库,走完整的贡献流程(可以不合并,重点是练手)。
要求:
- fork
octocat/Spoon-Knife(GitHub 官方练手仓库) - clone 你的 fork 到本地
- 添加 upstream remote
- 开 feature 分支,改一个文件(如 README 加一行)
- push 到 origin,向 upstream 提 PR
- 体验完整流程,之后可自行关闭 PR
提示
- Spoon-Knife 是专为练习 fork/PR 设计的仓库
- 提 PR 时确认 base 是 octocat/Spoon-Knife
小结
你已经具备给任何开源项目贡献代码的能力
本章要点
- fork = 复印别人的仓库到自己账号,你有完全控制权
- 两个 remote:origin(你的 fork,可推)、upstream(原仓库,只读)
- 定期从 upstream 同步,保持 fork 最新
- 贡献前读 CONTRIBUTING,大改动先沟通
- good first issue 是新人的最佳入口