大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Pull Request
这一课你将能做到
- 写出让审查者乐意合并的 PR 描述(标题+动机+改动点+测试方式+截图)
- 在 GitHub PR 页面审查他人代码,会提具体评论、请求修改、最终批准
- 处理 PR 中的 review 反馈:本地修改后更新同个 PR,以及正确解决合并冲突
为什么要学
PR 不只是「请求合并」,它是现代团队的质量门禁——设计评审、代码审查、CI 检查、自动化测试,全部发生在 PR 阶段。一个写得好的 PR 能让审查者 30 秒看懂你在干嘛;一个写得烂的 PR,审查者直接跳过、bug 溜进生产环境。
对初学者来说,PR 也是最佳学习窗口:你的代码会被更有经验的人逐行点评,进步速度比闷头写快十倍。
先建立图像
PR 的生命周期:
1. 推送功能分支 2. 创建 PR
3. CI 自动跑测试 4. 审查者审阅
5. 修正反馈(可能多轮) 6. 合并进 main
分支: feature/xxx ──────────────────> PR ──────────────────> main
│ │
│ commit 1 ← 修正 ← 审查者评论 │
│ commit 2 │
│ commit 3 │
└───────────────────────────────────────────────────────┘
跟着做
步骤 1:推送功能分支
git switch -c fix/login-redirect
git add . && git commit -m "fix(auth): 登录后重定向到正确页面"
git push -u origin fix/login-redirect
步骤 2:创建 PR
在 GitHub 页面点「Compare & pull request」,按以下模板填写:
## 改动动机
修复 #42:用户登录后跳转到了 404 页面。
## 做了什么
- 在 LoginService.java 第 58 行把默认重定向 URL 从 `/home` 改为 `/dashboard`
- 补充了重定向的单元测试
## 怎么验证
1. 运行 `mvn test`
2. 本地启动,访问 `/login` 用 test/test 登录
3. 确认跳转到 `/dashboard`
## 截图(如有 UI 改动)
[此处贴截图]
## 涉及 Issue
Closes #42
Closes #42 是 GitHub 魔法关键词,PR 合并后会自动关闭对应 Issue。
步骤 3:审查别人 PR
在 PR 页面切换到「Files changed」标签:
- 点某行左侧的
+号添加评论 - 提出具体意见:
第 34 行应该用 Optional.ofNullable 避免空指针 - 提完意见点「Request changes」让对方修改
- 全部满意后点「Approve」
步骤 4:收到审查意见后修改
git switch fix/login-redirect
# 按审查意见改代码...
git add .
git commit -m "fix: 改用 Optional 处理空指针(review 反馈)"
git push # 自动追加到原 PR
不需要重新开 PR,push 后原 PR 会自动更新。
步骤 5:解决合并冲突
如果 PR 提示「This branch has conflicts」:
git switch fix/login-redirect
git merge main # 把最新 main 合进来
# Git 会在冲突文件里标记 <<<<<<< HEAD ======= >>>>>>> main
# 手动打开文件,选择保留的版本,删掉冲突标记
git add 冲突文件
git commit # 提交合并
git push # PR 自动更新
讲清楚要点
- PR 是「对话」不是「通知」:审查者花时间帮你找问题,你要认真回应每一条评论,哪怕只是回复「已修改」或「这里我这样设计是因为...」。
- 小而快的 PR 最容易合:一次 PR 改动不超过 400 行(Google 工程实践推荐),审查者能在 30 分钟内看完。
- CI 红(测试失败)就不要求 review:先自己把测试跑绿,再找人审,是对别人时间的尊重。
- PR 描述是给未来看的:合并后描述会留在 git history,好的描述能让半年后的你快速定位 bug 引入点。
- Squash merge vs Rebase merge vs Merge commit:Squash 把功能分支所有 commit 压成一个合进 main(历史干净);Rebase 重放 commit(历史线性);Merge commit 保留分叉(有合并点)。团队统一一种即可。
你可能会懵的地方
-
别人提了「Request changes」我下一步做什么? 在自己的功能分支上按意见修改、commit、push。PR 页面会自动更新,审查者收到通知再复查。多轮很正常,不要觉得被针对。
-
PR 里已有 5 个 commit,合并时应该选哪种策略? 看团队约定。大多数团队选 Squash and merge(把一条功能分支压成单个 commit),main 历史就是一条干净直线。
-
为什么 CI 跑了 10 分钟才通过? CI(持续集成)在云端跑测试、构建、代码风格检查。你的 PR 通过了这些自动化门槛,审查者才敢放心合。等 CI 是常态。
-
审查者一直没回复怎么办? 超过一天礼貌 @ 提醒,或私聊提醒。PR 卡在 review 是团队效率最大的浪费。
-
我的 PR 被关了(Close)是什么意思? 可能是审查者认为不需要这个改动,或方向有问题。不要沮丧,问清原因,下次改进。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| PR 标题只写「修复 bug」 | 不知道改了什么 | fix(auth): 登录后跳转 404 |
| PR 描述空白 | 审查者无从下手 | 填动机、改动点、验证步骤 |
| 一个 PR 改 20 个文件 | 审查无法聚焦 | 拆成多个小 PR |
| 不回应 review 评论直接改 | 审查者不知道你改了没 | 每条评论回个「Done」或解释 |
| CI 红着就找人 review | 浪费别人时间 | 自己先本地 mvn test 跑绿 |
卡点急救
- 冲突标记怎么清理? 打开冲突文件,找到
<<<<<<< HEAD到>>>>>>> main之间的区域,保留你要的版本,删掉全部标记行(含<<<<<<</=======/>>>>>>>),然后git add+git commit。 - 改完 push 了但 PR 没变:检查 push 的分支名和 PR 的分支名是否一致。误推到同名但不同上游的远程会导致。
- PR 合并后想回滚:立刻在 PR 页面点「Revert」按钮,GitHub 会自动生成反向 commit 撤销全部改动。
面试常问
-
为什么要做 Code Review? 三重用意:知识共享(让团队熟悉不同模块)、质量保证(第二双眼睛找 bug)、风格统一(确保代码库风格一致)。
-
Squash merge 和 Merge commit 的区别? Squash 把分支上 N 个 commit 压成 1 个合进 main,历史干净但丢失开发细节;Merge commit 保留 N 个 commit 和一个合并节点,历史完整但可能分叉。团队选一个统一策略,主流倾向 Squash + 描述完整的 PR 标题。
-
PR 和 CI/CD 的关系? PR 是「入口门禁」:任何代码进入 main 前必须通过 PR 审查 + CI 自动化测试;合入 main 后触发 CD 自动部署。这是现代 DevOps 的「左移」思想。
自测三问
- PR 描述里为什么要写「怎么验证」?
- 审查者点了 Request changes,你在本地做什么?
- Squash merge 对 main 历史有什么影响?
小结一句话
PR 是代码进入主干的最后关卡:写好描述是尊重审查者的时间,认真回应 review 是尊重自己的成长。
延伸
- GitHub 文档:关于拉取请求
- 下一课:Issues 管理——需求追踪与缺陷报告的标准姿势。