开篇:什么是 Pull Request?
在深入操作之前,先搞清楚一个核心概念:Pull Request(简称PR)到底是什么?
用最通俗的话说,PR就是 “代码合并申请书”。你在某个分支上写完代码后,通过一份PR向仓库维护者提出请求:“我这边写好了,麻烦你审查一下,没问题的话请合并到主分支。”
PR不只是代码搬运工,它承担了四大职责:
- 代码对比(Diffs):清晰展示你改了哪些文件,增删了哪些行
- 分支指向:明确源分支(你的修改)和目的分支(要合入的地方)
- 审查协作:团队成员可以在具体代码行上留言、讨论、提出修改建议
- 质量闸门:PR会触发自动化测试(CI),只有全部通过才允许合并
理解了PR的本质,接下来就分两种场景,手把手走一遍完整流程。
阅读建议
- 团队协作者:重点阅读第一章(自己仓库PR)
- 开源贡献者:务必精读第二章(Fork仓库PR)
- 新手入门:建议按顺序通读全文
第一章:自己仓库的PR —— 团队协作与分支管理
适用场景:你和团队成员共同维护同一个仓库,大家都有直接的push权限。这时候PR主要用于代码审查和质量把控,而不是为了解决权限问题。
1.1 自己仓库PR的核心逻辑
在同一个仓库里,PR的本质是:“我在一个分支上写完了代码,请求合并到另一个分支”。
最常见的工作流是:
main或master作为生产环境分支,保持稳定- 每个开发者从
main切出功能分支(如feature/payment) - 开发完成后,发起PR将功能分支合并回
main
此时不需要Fork,也不需要 upstream,所有操作都在同一个远程仓库里完成。
1.2 标准操作流程
第一步:更新main分支并创建功能分支
1 | # 确保本地main是最新的 |
第二步:开发并推送
1 | git add . |
第三步:在GitHub网页发起PR
- 进入仓库页面,点击 Pull requests 标签
- 点击 New pull request
- base 选
main,compare 选feature/add-login - 填写PR标题和描述,指定审查人(Reviewers)
- 点击 Create pull request
第四步:审查通过后合并
审查人可以在PR页面对具体代码行留言。如果需要修改,你继续往 feature/add-login 推送即可,PR会自动更新。
1 | # 根据review意见修改后 |
当所有审查通过(Approve)且CI检查通过后,点击 Merge pull request 完成合并。
1.3 合并方式怎么选?(团队需要提前约定)
GitHub提供了三种合并选项,团队应根据自身规范选择:
| 合并方式 | 效果 | 适用场景 |
|---|---|---|
| Create a merge commit(普通合并) | 保留所有提交历史,生成一个合并提交 | 需要完整保留分支拓扑结构的团队 |
| Squash and merge(压缩合并) | 将PR中的所有提交压缩为1个提交 | 推荐:功能分支场景,一个PR对应一个提交,历史干净简洁 |
| Rebase and merge(变基合并) | 将提交线性应用到目标分支,不生成合并提交 | 追求线性历史的团队,但注意会改变提交哈希 |
团队建议:大多数团队推荐使用 Squash and merge,既保留了PR的完整性,又避免了功能分支里大量“修bug”、“改格式”等琐碎提交污染主分支历史。
1.4 合并后的清理工作
请务必在PR合并完成后,先执行 git pull origin main 将本地main更新为最新代码,再执行删除操作。
1 | # 先同步最新代码 |
1.5 自己仓库PR的核心注意事项
- 永远不要往main直接push:所有修改都走PR流程,这是团队协作的底线
- 一个PR只做一件事:解决单一问题,审查效率更高
- 养成习惯:每次切功能分支前,先执行
git checkout main && git pull origin main
第二章:Fork仓库的PR —— 开源贡献与跨仓库协作
适用场景:你想给别人的开源项目贡献代码,但没有直接push权限。这时候PR承担了 “跨仓库代码传输” 的功能,是GitHub开源协作的基石。
2.1 Fork仓库PR的核心逻辑
Fork的PR流程涉及三个仓库:
- 上游仓库(Upstream):原作者的项目,你没有写入权限
- 个人Fork仓库(Origin):你从上游Fork到自己账号下的副本,你有完整权限
- 本地仓库(Local):你电脑上的代码
PR的方向是:从你的Fork仓库的分支 → 上游仓库的目的分支。
2.2 完整操作流程
第一步:Fork并克隆到本地
在原作者仓库页面点击 Fork 按钮,然后克隆自己的副本:
1 | git clone https://github.com/你的用户名/仓库名.git |
第二步:添加上游仓库(关键)
1 | # 将原作者仓库添加为远程地址,命名为upstream |
第三步:同步上游最新代码(避开冲突的关键)
在切分支之前,先把上游的最新代码同步到本地:
1 | # 切换到main分支,拉取上游最新代码 |
第四步:切分支并开发
1 | git checkout -b feature/fix-bug |
第五步:发起跨仓库PR(最容易选错的地方)
推送成功后,去你的GitHub Fork仓库页面,点击 “Compare & pull request”。
重要提醒:GitHub 默认经常会打开 你的 Fork → 你的 Fork 的 PR 页面(即 base 和 head 都指向你自己的仓库)。请务必手动将 base repository 改为原作者仓库,否则原作者不会收到通知,也不会看到你的 PR。
在PR创建页面上,务必仔细检查以下四个下拉框的选择:
| 选项 | 正确选择 | 错误选择(后果) |
|---|---|---|
| base repository | 原作者仓库(如 octocat/Spoon-Knife) | 选成自己的仓库 → 自己给自己提PR,原作者看不到 |
| base branch | 上游的 main 或 dev 分支 | 选错分支 → 代码合并到了不对的分支上 |
| head repository | 你的Fork仓库(如 你的用户名/Spoon-Knife) | 选错 → 无法指向你的修改 |
| compare branch | feature/fix-bug | 选成 main → 会把主分支上的所有内容都带进去 |
确认无误后,填写PR描述(建议写清楚改了什么、为什么改、如何测试),点击 Create pull request。
第六步:响应审查并自动更新
审查人可能会在PR里提修改意见,你只需要在本地继续向 同一个分支 推送:
1 | # 修改代码后 |
关于同步上游的进阶建议:
在功能分支上同步上游最新代码时,社区更推荐使用 rebase 而非 merge:
1 | git fetch upstream |
为什么推荐 rebase? 它可以避免多余的 “Merge branch 'main'…” 合并提交,让PR历史更加干净线性。但注意:避免对已经推送到远程并被他人审查的分支做 rebase,因为这会改变提交哈希,可能导致协作冲突。如确需 rebase,建议先与审查者沟通。
第七步:PR合并后的同步清理
当原作者合并了你的PR后,你的Fork仓库就落后于上游了,及时同步:
1 | git checkout main |
2.3 Fork仓库PR的独有注意事项
| 事项 | 说明 |
|---|---|
| 每次PR前先同步upstream | 避免PR提示“无法自动合并”,被打回重做 |
| 一个PR只干一件事 | 开源项目审查严格,多个功能混在一起会被要求拆分 |
| CI检查必须通过 | 大部分开源项目要求所有自动化测试通过才会考虑合并 |
| 尊重项目规范 | 仔细阅读项目的 CONTRIBUTING.md 和代码风格指南 |
2.4 常见问题速查
问:为什么我的PR里出现了别人的提交?
答:因为你没有先同步上游,直接基于旧版 main 切了分支。
推荐做法:切回 feature/fix-bug 分支,执行:
1 | git fetch upstream |
若不熟悉 rebase,也可使用:
1 | git pull upstream main |
问:PR提交后,发现有冲突怎么办?
答:本地执行 git pull upstream main(或 git rebase upstream/main)解决冲突,然后 git push origin feature/fix-bug,PR会自动更新冲突状态。如果冲突较多,建议在提交信息中注明 “resolve conflicts with upstream/main”。
问:原作者把我的PR关闭了怎么办?
答:查看关闭理由,通常是因为重复(已有类似修复)、不符合项目方向、或需要大幅重构。可以礼貌地回复沟通,也可以关闭后另开新PR。
总结:两种PR场景的对比速查
| 对比维度 | 自己仓库PR | Fork仓库PR |
|---|---|---|
| 典型场景 | 团队内部协作 | 开源社区贡献 |
| 涉及仓库数 | 1个(共用仓库) | 3个(上游 + Fork + 本地) |
| 是否需要Fork | 不需要 | 必须 |
| 是否要配upstream | 不需要 | 必须 |
| PR的目的仓库 | 自己的仓库 | 原作者的仓库 |
| 合并权限 | 有写权限的成员均可合并 | 仅上游仓库维护者(Maintainer)可合并 |
| PR被合并后 | 直接同步即可 | 需从upstream拉取同步 |
一键命令速查
自己仓库PR:
1 | git checkout main && git pull origin main |
Fork仓库PR(新手版):
1 | git remote add upstream <原作者地址> |
Fork仓库PR(进阶版,使用rebase保持线性历史):
1 | git remote add upstream <原作者地址> |
AI
评论已关闭