开篇:什么是 Pull Request?

在深入操作之前,先搞清楚一个核心概念:Pull Request(简称PR)到底是什么?

用最通俗的话说,PR就是 “代码合并申请书”。你在某个分支上写完代码后,通过一份PR向仓库维护者提出请求:“我这边写好了,麻烦你审查一下,没问题的话请合并到主分支。”

PR不只是代码搬运工,它承担了四大职责:

  • 代码对比(Diffs):清晰展示你改了哪些文件,增删了哪些行
  • 分支指向:明确源分支(你的修改)和目的分支(要合入的地方)
  • 审查协作:团队成员可以在具体代码行上留言、讨论、提出修改建议
  • 质量闸门:PR会触发自动化测试(CI),只有全部通过才允许合并

理解了PR的本质,接下来就分两种场景,手把手走一遍完整流程。

阅读建议

  • 团队协作者:重点阅读第一章(自己仓库PR)
  • 开源贡献者:务必精读第二章(Fork仓库PR)
  • 新手入门:建议按顺序通读全文

第一章:自己仓库的PR —— 团队协作与分支管理

适用场景:你和团队成员共同维护同一个仓库,大家都有直接的push权限。这时候PR主要用于代码审查质量把控,而不是为了解决权限问题。

1.1 自己仓库PR的核心逻辑

在同一个仓库里,PR的本质是:“我在一个分支上写完了代码,请求合并到另一个分支”

最常见的工作流是:

  • mainmaster 作为生产环境分支,保持稳定
  • 每个开发者从 main 切出功能分支(如 feature/payment
  • 开发完成后,发起PR将功能分支合并回 main

此时不需要Fork,也不需要 upstream,所有操作都在同一个远程仓库里完成。

1.2 标准操作流程

第一步:更新main分支并创建功能分支

1
2
3
4
5
6
# 确保本地main是最新的
git checkout main
git pull origin main

# 切出功能分支
git checkout -b feature/add-login

第二步:开发并推送

1
2
3
git add .
git commit -m "feat: 增加手机号登录功能"
git push origin feature/add-login

第三步:在GitHub网页发起PR

  1. 进入仓库页面,点击 Pull requests 标签
  2. 点击 New pull request
  3. basemaincomparefeature/add-login
  4. 填写PR标题和描述,指定审查人(Reviewers)
  5. 点击 Create pull request

第四步:审查通过后合并

审查人可以在PR页面对具体代码行留言。如果需要修改,你继续往 feature/add-login 推送即可,PR会自动更新。

1
2
3
4
# 根据review意见修改后
git add .
git commit -m "fix: 根据审查意见调整变量命名"
git push origin feature/add-login # PR页面自动同步

当所有审查通过(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
2
3
4
5
6
7
8
9
# 先同步最新代码
git checkout main
git pull origin main

# 再删除本地功能分支
git branch -d feature/add-login

# 最后删除远程功能分支
git push origin --delete feature/add-login

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
2
git clone https://github.com/你的用户名/仓库名.git
cd 仓库名

第二步:添加上游仓库(关键)

1
2
3
4
5
6
7
8
9
10
# 将原作者仓库添加为远程地址,命名为upstream
git remote add upstream https://github.com/原作者用户名/仓库名.git

# 确认两个远程地址都已配置
git remote -v
# 输出应该包含:
# origin https://github.com/你的用户名/仓库名.git (fetch)
# origin https://github.com/你的用户名/仓库名.git (push)
# upstream https://github.com/原作者用户名/仓库名.git (fetch)
# upstream https://github.com/原作者用户名/仓库名.git (push)

第三步:同步上游最新代码(避开冲突的关键)

在切分支之前,先把上游的最新代码同步到本地:

1
2
3
4
5
6
# 切换到main分支,拉取上游最新代码
git checkout main
git pull upstream main

# 同步到你的GitHub Fork仓库
git push origin main

第四步:切分支并开发

1
2
3
4
5
git checkout -b feature/fix-bug
# 修改代码...
git add .
git commit -m "fix: 修复登录超时bug"
git push origin 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上游的 maindev 分支选错分支 → 代码合并到了不对的分支上
head repository你的Fork仓库(如 你的用户名/Spoon-Knife)选错 → 无法指向你的修改
compare branchfeature/fix-bug选成 main → 会把主分支上的所有内容都带进去

确认无误后,填写PR描述(建议写清楚改了什么、为什么改、如何测试),点击 Create pull request

第六步:响应审查并自动更新

审查人可能会在PR里提修改意见,你只需要在本地继续向 同一个分支 推送:

1
2
3
4
# 修改代码后
git add .
git commit -m "fix: 根据review意见优化代码"
git push origin feature/fix-bug # PR页面自动更新,无需任何额外操作

关于同步上游的进阶建议

在功能分支上同步上游最新代码时,社区更推荐使用 rebase 而非 merge

1
2
3
git fetch upstream
git rebase upstream/main
# 如有冲突:解决冲突 → git add . → git rebase --continue

为什么推荐 rebase? 它可以避免多余的 “Merge branch 'main'…” 合并提交,让PR历史更加干净线性。但注意:避免对已经推送到远程并被他人审查的分支做 rebase,因为这会改变提交哈希,可能导致协作冲突。如确需 rebase,建议先与审查者沟通。

第七步:PR合并后的同步清理

当原作者合并了你的PR后,你的Fork仓库就落后于上游了,及时同步:

1
2
3
4
5
git checkout main
git pull upstream main
git push origin main
git branch -d feature/fix-bug # 删除本地分支
git push origin --delete feature/fix-bug # 删除远程分支

2.3 Fork仓库PR的独有注意事项

事项说明
每次PR前先同步upstream避免PR提示“无法自动合并”,被打回重做
一个PR只干一件事开源项目审查严格,多个功能混在一起会被要求拆分
CI检查必须通过大部分开源项目要求所有自动化测试通过才会考虑合并
尊重项目规范仔细阅读项目的 CONTRIBUTING.md 和代码风格指南

2.4 常见问题速查

问:为什么我的PR里出现了别人的提交?

答:因为你没有先同步上游,直接基于旧版 main 切了分支。

推荐做法:切回 feature/fix-bug 分支,执行:

1
2
git fetch upstream
git rebase upstream/main

若不熟悉 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场景的对比速查

对比维度自己仓库PRFork仓库PR
典型场景团队内部协作开源社区贡献
涉及仓库数1个(共用仓库)3个(上游 + Fork + 本地)
是否需要Fork不需要必须
是否要配upstream不需要必须
PR的目的仓库自己的仓库原作者的仓库
合并权限有写权限的成员均可合并仅上游仓库维护者(Maintainer)可合并
PR被合并后直接同步即可需从upstream拉取同步

一键命令速查

自己仓库PR:

1
2
3
4
5
git checkout main && git pull origin main
git checkout -b feature/xxx && git push origin feature/xxx
# 去网页提PR → 合并后清理
git checkout main && git pull origin main
git branch -d feature/xxx && git push origin --delete feature/xxx

Fork仓库PR(新手版):

1
2
3
4
5
6
7
git remote add upstream <原作者地址>
git checkout main && git pull upstream main && git push origin main
git checkout -b feature/xxx && git push origin feature/xxx
# 去网页提PR(记得改 base repository!)
# 合并后:同步 upstream 并清理分支
git checkout main && git pull upstream main && git push origin main
git branch -d feature/xxx && git push origin --delete feature/xxx

Fork仓库PR(进阶版,使用rebase保持线性历史):

1
2
3
4
5
6
7
git remote add upstream <原作者地址>
git checkout main && git pull upstream main && git push origin main
git checkout -b feature/xxx
# 开发过程中同步上游
git fetch upstream && git rebase upstream/main
git push origin feature/xxx
# 去网页提PR → 合并后清理同上
AI