团队协作
这一课你将能做到
- 解释为什么代码审查(Code Review)是技术成长最快的方式之一
- 在团队冲突发生时,正确执行
git merge --abort 或 git rebase --abort 并寻求帮助
- 理解维护者(Maintainer)、贡献者(Contributor)和审阅者(Reviewer)的职责边界
为什么要学
如果你认为 Git 只是一个文件历史管理工具,那你就错过了它真正的威力:团队协作与知识传承。一个优秀的开发者,不仅要能写出正确的代码,还要能看懂别人的代码,提出建设性的意见,并在分歧中找到共识。本课将带你走进真实的团队开发场景。
先建立图像
代码审查就像报纸的校对环节。记者写完文章(开发者写完代码),编辑(审阅者)会检查事实是否准确、文字是否通顺、排版是否美观。同样,代码审查会检查逻辑是否正确、是否符合规范、是否有潜在的安全隐患。没有经过审查的代码,就像没有校对过的报纸,错误百出。
开发者完成代码 → 创建 Pull Request → 自动触发 CI 测试 → 审阅者检查代码 →
通过审查 → 合并到主分支
跟着做
步骤 1:扮演审阅者(Reviewer)
假设你的同事提交了一个 Pull Request,请求合并一个用户登录功能。
首先,你需要通读整个 PR 的改动:
- 打开 PR 页面,阅读标题和描述,理解其改动意图。
- 切换到 "Files changed" 标签页,逐行阅读代码。
- 当你看到不理解的地方,点击行号旁边的 "+" 号,添加评论:
- "这里的变量名
x 是什么意思?能否改为更具描述性的名称,例如 userLoginCount?"
- "这个函数没有处理空指针异常,是否应该增加
try-catch 块?"
- 阅读完毕后,点击右上角的 "Review changes" 按钮,选择 "Request changes"。
步骤 2:处理审查意见(作为开发者)
你收到了审阅者的反馈,不要急着反驳,先深呼吸,然后:
- 逐条确认:对于每一条评论,思考其合理性。
- 修改代码:在本地根据意见修改代码。
- 回复评论:在 PR 页面对应的评论下回复,例如 "已修改,将变量名改为
userLoginCount" 或 "这是一个好建议,已添加空指针检查"。
- 重新提交:修改完成后,将新的提交推送到同一个远程分支。PR 会自动更新。
# 在本地修改代码
git add .
git commit -m "refactor: 根据审查意见优化变量命名和异常处理"
git push origin feature/login
步骤 3:解决合并冲突(Merge Conflict)
假设你的 PR 在等待审查期间,主分支 main 被其他人合并了新的代码,导致你的分支与 main 产生了冲突。
- 同步远程主分支:
git switch main
git pull origin main
- 切换回你的功能分支并合并主分支:
git switch feature/login
git merge main
- Git 会提示哪些文件存在冲突。打开这些文件,你会看到类似下面的标记:
<<<<<<< HEAD
int userCount = 0;
=======
int totalUsers = 10;
>>>>>>> main
- ,保留你需要的代码,并删除所有 , , 标记。
手动编辑文件
<<<<<<<
=======
>>>>>>>
标记冲突已解决并提交:
git add src/UserService.java
git commit -m "merge: 解决与 main 分支的冲突"
git push origin feature/login
步骤 4:优雅地拒绝或关闭 PR
如果你是项目的维护者(Maintainer),有时会遇到质量不达标或方向错误的 PR。
- 评论说明原因:不要直接关闭,先评论解释为什么,例如 "感谢贡献!但这个功能与我们的产品设计方向不符,我们计划用 OAuth 代替本地登录。"
- 提供替代方案:如果可能,引导贡献者去做其他任务,例如 "你可以看看 #42 这个 Issue,那个任务更适合当前阶段。"
- 关闭 PR:在沟通清楚后,点击 "Close pull request"。
讲清楚要点
- 审查是双向学习:作为开发者,你从审查者的意见中学习;作为审查者,你通过阅读他人代码学习新的思路。这是一个正向循环。
- 对事不对人:所有的审查意见都应该针对代码,而不是针对写代码的人。使用 "这个函数可以..." 而不是 "你应该..." 的句式。
- 小步快跑:一个 PR 的代码量越小,审查者越容易理解,发现问题也越快。尽量让一个 PR 只完成一个功能。
- 自动化优先:把代码风格检查(Linting)、单元测试等交给 CI(持续集成)自动完成,审查者只需关注业务逻辑和架构设计。
- 文档即代码:README、API 文档等也应该纳入版本控制和审查流程。
你可能会懵的地方
-
我的代码被否定了,是不是说明我很差?
绝对不是。代码审查的目的是提升代码质量,而不是评价个人。连 Linus Torvalds(Linux 之父)的代码也会被审查和拒绝。
-
审查者提出的意见我不认同怎么办?
礼貌地回复你的理由,展开技术讨论。例如 "感谢建议,但我认为这里使用 ArrayList 比 LinkedList 更合适,因为我们需要频繁地随机访问元素。" 真理越辩越明。
-
冲突解决后,如何确保没有破坏原有功能?
解决冲突后,务必在本地重新运行项目的测试套件。如果项目没有测试,至少手动验证你改动过的核心流程。
-
我不小心把别人的提交合并到我的分支里了,怎么办?
如果还没有推送到远程,可以使用 git reset --hard HEAD~1 回退到上一个提交。如果已经推送,可以使用 git revert 生成一个反向提交来撤销。
错法对照
| 错法 | 问题 | 正解 |
|---|
| 直接修改主分支(main) | 绕过审查,引入未经检验的代码 | 始终通过 Pull Request 合并代码 |
| 收到审查意见后消极对抗 | 阻碍团队协作,无法提升代码质量 | 积极沟通,有则改之无则加勉 |
| 一个 PR 包含多个不相关的功能 | 审查困难,回滚风险高 | 一个 PR 只做一件事 |
| 解决冲突时随意删除他人代码 | 破坏他人功能 | 仔细对比,与原作者沟通 |
| 合并代码后不删除远程功能分支 | 仓库分支混乱 | 合并后立即删除远程功能分支 |
卡点急救
- 冲突太复杂,我不敢动手:先执行
git merge --abort 或 git rebase --abort 回到冲突前的状态,然后寻求团队资深成员的帮助,一起屏幕共享解决。
- 我不小心把主分支 push 到了远程:立刻通知团队,不要擅自使用
git push --force 回滚。团队可以一起决定是用 git revert 生成反向提交,还是其他补救方案。
- 审查者一直不回复我的 PR:在工作沟通工具(如 Slack、飞书)上礼貌地 @ 相关同事,或者在 PR 下评论 "Hi @reviewer,这个 PR 已经准备好审查了,方便的时候请看一下,谢谢!"
面试常问
-
你如何看待 Code Review?
它是保证代码质量、促进知识共享和团队成长的重要环节。我会把审查意见看作学习的机会,而不是批评。
-
遇到合并冲突你会怎么做?
首先同步最新的主分支,然后在我的功能分支上执行合并。仔细对比冲突代码,与原作者沟通确认意图,解决后重新运行测试并推送。
-
如果你的 PR 被拒绝了,你会怎么处理?
首先感谢审查者花时间审查,然后仔细阅读拒绝原因。如果是代码问题,我会修改后重新提交;如果是方向问题,我会与团队讨论,理解产品和技术决策背后的逻辑。
自测三问
- 作为审查者,你发现代码中有一个明显的逻辑错误,你会如何写评论?
- 你的同事在审查中建议你使用一种你不熟悉的设计模式,你会怎么做?
- 解决合并冲突时,你发现冲突的代码是你和同事都修改过的,最佳实践是什么?
小结一句话
团队协作的核心是沟通与尊重:通过代码审查共同进步,通过规范流程规避风险,通过积极沟通解决分歧。
延伸