Pull Request 全流程
从开分支到合并进主干——GitHub 协作的核心载体
PR 不是技术,是一种工作礼仪直接推主干?
你改完代码想提交,但团队不允许直接动 main 分支
一人项目随便推
你自己写作业,commit 直接 push 到 main,没问题。但只要超过一个人,这么干迟早撞车。
多人直接推的灾难
A 和 B 同时改 main,互相覆盖;有人推了没测过的代码,全组项目跑不起来;出了问题不知道是谁干的。没有审查,就没有质量。
想知道 PR 是啥
你听人说「提个 PR」,但不知道那具体是什么。它和 branch 什么关系?和 commit 什么关系?
PR 是 GitHub 上一切团队协作的基础,也是后续 04-06 章的前置知识。
开始之前
适合谁
- 会 push/pull,但没开过 PR
- 想参与需要 PR 的开源或团队项目
- 被「分支、合并、冲突」吓到过的人
你将学会
- feature branch 工作法的完整节奏
- 在 GitHub 上开 PR、写描述、做 review
- 选择 Merge / Squash / Rebase 三种合并策略
- 处理合并冲突(网页端 + 命令行)
本章暂不覆盖
- 分支保护规则(第 05 章)
- fork 模型的 PR(第 06 章)
- CI 自动检查(第 07 章)
PR 是什么
Pull Request = 「请把我的分支拉进去合并」的申请

图:PR 的本质
【AI 生图提示词】请生成一张中文技术示意图,风格简洁、配色柔和、适合教学: - 画面主体:两条分支线。上方是「main 主干」,下方是「feature/login 功能分支」。feature 分支从 main 某点分出,前进几个 commit 后,用一个箭头指回 main - 各元素关系:分出处标「开分支」,feature 上的圆点标「commit 1/2/3」,箭头指回 main 处标「Pull Request:请求合并」 - 关键标注:main 旁注「受保护,不能直接推」,feature 旁注「你的工作区,随便改」 - 配色建议:浅灰背景,main 用深蓝色粗线,feature 用橙色线,合并箭头用绿色 - 画面比例:16:9 - 避免:3D 效果、过多文字、复杂装饰
分支工作法
feature branch——每做一个改动就开一条专属分支
# 1. 确保在 main 上且是最新
$ git checkout main
$ git pull
# 2. 开一条新分支,名字说清要干嘛
$ git checkout -b feature/add-login
# 3. 在新分支上正常改代码、commit
$ git add .
$ git commit -m "添加登录页面"
# 4. 推送新分支到远程
$ git push -u origin feature/add-login
功能/简述 格式,如 feature/login、fix/typo、docs/readme。别人一看就知道这条分支是干嘛的。
在网页开 PR
推送分支后,GitHub 会提示你创建 Pull Request
入口
- 推送分支后,终端会显示一个
Create a pull request链接 - 或仓库页面 →
Pull requests标签 →New pull request
关键设置
- base:合并到哪(通常
main) - compare:你的功能分支
- 标题:一句话说清做了什么
- 描述:改了什么、为什么改、怎么测
PR 描述模板
一个清晰 PR 描述的骨架,照着填就行
## 改动说明
添加了用户登录页面,支持邮箱+密码登录。
## 改动类型
- [x] 新功能
- [ ] bug 修复
- [ ] 重构
## 关联 issue
Closes #12
## 如何测试
1. 启动项目 `npm start`
2. 访问 /login
3. 用 test@example.com / 123456 登录
## 截图
(如有 UI 改动,贴截图)
Closes #12 是关键字联动:合并这个 PR 时,第 12 号 issue 会自动关闭。第 04 章 Issues 会详细讲这个机制。
PR 界面导览
一个 PR 页面有四个关键标签
| 标签 | 看什么 | 用途 |
|---|---|---|
| Conversation | 讨论、状态、合并按钮 | 整体协调与最终合并 |
| Commits | 这个 PR 含哪些提交 | 看工作过程 |
| Files changed | 逐行 diff 对比 | code review 主战场 |
| Checks | CI 自动测试结果 | 第 07 章 Actions 产出 |
90% 的 review 工作发生在 Files changed 标签里。
做 code review
在 Files changed 标签里逐行审查代码
三种评论方式
- 鼠标悬停某行 → 点蓝色
+图标加单行评论 - 拖选多行 → 对一段代码整体评论
- 评论框右下角选类型:Comment(普通)、Suggest change(建议改法)
Suggestion 的妙用
用 ```suggestion 代码块写建议改法,作者点一下「Apply」就能直接采纳,不用手动改。这是最高效的 review 方式。
四种审查动作
review 完成时,你要做一个明确的表态
| 动作 | 含义 | 何时用 |
|---|---|---|
| Comment | 仅评论,不表态 | 有疑问但不阻塞合并 |
| Approve | 同意合并 | 代码没问题,可以进主干 |
| Request changes | 要求修改 | 有问题必须改才能合并 |
| (不操作) | 静默同意 | 没意见就不点,让有权限的人合并 |
被 request changes 后,作者改完代码会自动清除「需修改」状态,重新等待 review。
合并策略
PR 通过审查后,有三种方式把它并进主干

图:三种合并策略对历史的影响
【AI 生图提示词】请生成一张中文技术示意图,风格简洁、配色柔和、适合教学: - 画面主体:三组分支示意图,横向排列,分别标注「Merge commit」「Squash」「Rebase」 - 各元素关系: 第一组「Merge commit」:feature 分支的 3 个圆点保留,main 上多出一个紫色「merge commit」把两条线连起来,形成菱形 第二组「Squash」:feature 的 3 个圆点被压成 1 个,main 上只新增 1 个提交,历史是直线 第三组「Rebase」:feature 的 3 个提交被重新排在 main 末端,无合并提交,历史是直线但保留了 3 个 commit - 关键标注:每组下方标特点,如「保留全部历史」「历史最干净」「线性且保留提交」 - 配色建议:浅灰背景,main 用深蓝,feature 用橙色,merge commit 用紫色 - 画面比例:16:9 - 避免:3D 效果、过多文字说明
Merge commit
最传统的方式:保留分支的所有提交,额外加一个合并节点
优点
- 完整保留分支历史和工作过程
- 能看出「哪些提交是一起做的」
- 大项目、多人协作的默认选择
缺点
- 历史图会分叉再合并,复杂
- 主干混入大量小提交
- feature 分支上的「wip」「修 typo」也进历史
适合:大型长期项目、想完整保留协作轨迹的团队。
Squash 合并
把分支上的所有提交压成一个,再并进主干
优点
- 主干历史是干净的直线
- 每个 PR 对应主干一个提交
- 回退整个功能很容易
缺点
- 丢失分支内的细粒度提交历史
- 原始 commit hash 改变
本教程网站自己的提交历史就是 Squash 风格。
Rebase 合并
把分支提交「搬到」主干末端,线性排列,不加合并节点
优点
- 历史是干净的直线
- 保留分支上的每个提交
- 适合提交本身就有意义的项目
缺点
- 历史图虽线性但提交多
- 提交顺序可能和实际工作顺序不符
合并冲突
当你的分支和主干改了同一处代码,Git 无法自动合并
<<<<<<< HEAD
这是你分支上的版本
=======
这是主干上的版本
>>>>>>> main
冲突标记三段
<<<<<<<到=======:你的改动(HEAD)=======到>>>>>>>:对方的改动- 你需要手动决定保留哪个,或合并两者
网页端解冲突
小冲突直接在 GitHub 网页上改,不用开终端
何时能用
点 Merge pull request 时,如果 GitHub 检测到冲突且冲突文件不多,会出现 Resolve conflicts 按钮。
操作步骤
- 点
Resolve conflicts - 网页编辑器显示带冲突标记的文件
- 手动删掉
<<</===/>>>标记,保留正确代码 - 点
Mark as resolved→Commit merge - 回到 PR 页面继续合并
命令行解冲突
复杂冲突在本地解决,掌控力最强
# 1. 把最新主干拉进你的分支
$ git fetch origin
$ git merge origin/main
# 2. Git 提示冲突文件
# Auto-merging app.js
# CONFLICT (content): Merge conflict in app.js
# 3. 打开 app.js,手动解决冲突标记
# 4. 标记已解决
$ git add app.js
# 5. 完成合并
$ git commit
$ git push
放弃合并
冲突太复杂、改到一半想重来——随时可以退出
# 合并进行中,想放弃
$ git merge --abort
# 回到合并前的干净状态,仿佛什么都没发生
什么时候用
- 冲突太多,一次性理不清
- 改到一半发现方向错了
- 想先去请教别人再回来处理
--abort 不会丢失你之前的 commit,只是取消这次没完成的合并操作。你的工作都在。
合并之后
PR 合并了,善后工作别忘
# 1. 切回主干并拉取最新(含你刚合并的改动)
$ git checkout main
$ git pull
# 2. 删除已合并的本地功能分支
$ git branch -d feature/add-login
# 3. 删除远程的功能分支(GitHub 合并时通常自动提示删)
$ git push origin --delete feature/add-login
-d(小写)是安全删除——只允许删已合并的分支,未合并的要用 -D 强删。
好 PR 的习惯
让 reviewer 爱上你的 PR
小而专一
一个 PR 只解决一件事。别把「加登录」和「改 README」塞进同一个 PR。小 PR 审得快,合并快。
标题就是结论
「添加邮箱登录功能」比「update」好一万倍。标题要让别人扫一眼 PR 列表就知道干了啥。
描述说清 why
代码已经展示了「怎么改」,描述要解释「为什么改」。reviewer 需要上下文。
自测再提交
开 PR 前自己先跑通。把未完成的、跑不起来的代码丢给别人审,是对别人时间的不尊重。
排错:PR 不见分支
开了 PR,但 Files changed 显示「There isn't anything to compare」
原因
你的功能分支和主干没有差异——可能是你忘记在功能分支上 commit,或 commit 后忘记 push。
检查清单
# 确认在功能分支
$ git branch
# 确认有新提交
$ git log main..HEAD
# 确认推到了远程
$ git status
git status 显示 ahead of origin 说明还没 push。
动手试一试
完整走一遍 PR 全流程
你的任务
任务:在自己的仓库里,通过 PR 修改 README。
要求:
- 开 feature 分支
docs/improve-readme - 在 README 里加一段「项目结构」说明
- commit 并 push 该分支
- 在 GitHub 开 PR,写清楚描述
- 自己 review 一遍,选 Squash 合并
- 合并后清理本地和远程分支
提示
- 一个人也能走完 PR——你就是作者也是 reviewer
- 合并后记得
git pull把合并结果拉回本地 main
小结
你已经掌握 GitHub 协作的核心——PR 全流程
本章要点
- feature branch 工作法:开分支 → commit → push → 开 PR
- PR 四标签:Conversation / Commits / Files changed / Checks
- 三种合并策略:Merge commit(完整)/ Squash(干净)/ Rebase(线性)
- 冲突可在网页解(小)或命令行解(大),随时可 abort
- 合并后清理分支,保持仓库整洁