11.3 分支、PR 与团队工作流


文档摘要

title: "11.3 分支、PR 与团队工作流" description: "用分支隔离实验,用 PR 审查代码,建立日常开发节奏" 11.3 分支、PR 与团队工作流 本节目标:理解分支的价值,掌握 Pull Request 工作流,建立多人协作的日常节奏。 "复制一份再改"的本能 小明想给"个人豆瓣"加一个"猜你喜欢"推荐功能。但他有点犹豫——评分系统好不容易跑稳了,万一改推荐功能的时候不小心动了评分的代码,又要花时间修。 他的第一反应是:把整个项目文件夹复制一份,在副本里折腾。改好了就用副本替换原来的,改坏了就删掉副本。 你一定也有过这种本能——想试个新方案但怕搞坏现有的,于是复制一份再改。这个思路是对的,只是方式太原始。

title: "11.3 分支、PR 与团队工作流" description: "用分支隔离实验,用 PR 审查代码,建立日常开发节奏"

11.3 分支、PR 与团队工作流

本节目标:理解分支的价值,掌握 Pull Request 工作流,建立多人协作的日常节奏。

"复制一份再改"的本能

小明想给"个人豆瓣"加一个"猜你喜欢"推荐功能。但他有点犹豫——评分系统好不容易跑稳了,万一改推荐功能的时候不小心动了评分的代码,又要花时间修。

他的第一反应是:把整个项目文件夹复制一份,在副本里折腾。改好了就用副本替换原来的,改坏了就删掉副本。

你一定也有过这种本能——想试个新方案但怕搞坏现有的,于是复制一份再改。这个思路是对的,只是方式太原始。Git 有一个更优雅的机制来做同样的事:分支(Branch)

分支:Git 版的"复制文件夹"

分支的本质就是"复制一份再改",但比复制文件夹高明得多。它不会真的复制所有文件——Git 只记录差异,创建一个分支几乎不占额外空间。你可以随时在"原版"和"副本"之间切换,改好了可以精确地合并回去,而不是整个文件夹替换。

复制文件夹的问题在于:你在副本里改了 10 个文件,原版里也改了 3 个文件(修了个紧急 bug),现在你想把副本的修改合并回原版——你得手动对比 13 个文件,确保不遗漏、不覆盖。Git 的分支帮你自动完成这件事。

你的项目默认有一个主分支,通常叫 main(有些旧仓库叫 master)。它代表"当前稳定可用的版本"。当你要开发新功能时,从 main 创建一个新分支,比如 feature/recommend,在这个分支上随便折腾。改坏了?切回 main,一切如初。改好了?合并到 main,功能上线。

main 分支就像你的"正式版",功能分支就像"草稿本"——你在草稿本上怎么涂改都不影响正式版,直到你确认满意了才把内容誊写过去。

小明告诉 Claude Code "创建一个分支来开发推荐功能",Claude Code 会创建 feature/recommend 分支并切换过去。从这一刻起,小明的所有修改都在这个分支上,main 分支纹丝不动。分支名通常用 feature/xxx 表示新功能,fix/xxx 表示修 bug,refactor/xxx 表示重构——这不是强制的,但能让你和协作者一眼看出这个分支在做什么。

完整的分支工作流

让我们跟着小明走一遍完整流程。这个流程是 GitHub 上最常见的协作方式,叫做 GitHub Flow。就像做菜有各种流派,但家常菜只需要一种最简单的套路就够了——GitHub Flow 就是这个最简单的套路,你接下来跟着小明走的流程就是它的全部。

小明从 main 创建了 feature/recommend 分支,开始开发推荐算法。他和 Claude Code 一起写了推荐逻辑、添加了新的 API 接口、调整了前端页面。每完成一个小步骤就提交一次——"添加推荐算法的数据模型""实现基于评分的推荐逻辑""前端展示推荐结果"。

与此同时,朋友在另一个分支 feature/user-profile 上开发用户个人主页。两个人各自在自己的分支上工作,互不干扰。小明的推荐功能改坏了不影响朋友的个人主页,朋友的个人主页出了 bug 也不影响小明的推荐功能。这就是分支的核心价值——隔离

开发到一个阶段,小明把分支推送到 GitHub。这样做有两个好处:代码有了云端备份,朋友也能看到他的进展。即使小明的电脑出了问题,分支上的代码也不会丢。

小明觉得推荐功能差不多了,但不想直接合并到 main——他想让朋友先看看代码有没有问题。于是他在 GitHub 上创建了一个 Pull Request(PR)

Pull Request:帮我看看再合并

为什么不直接把分支合并到 main

想想你写过的文档——如果别人不看就直接改了你的正文,你什么感觉?PR 就是"我改好了,你帮我看看再合并"。这个"看看"的过程叫 Code Review(代码审查),是团队协作中防止事故的关键环节。

你可能觉得"我们就两个人,还需要这么正式吗?"——需要的。不是因为流程本身有多重要,而是因为另一双眼睛真的能发现你自己看不到的问题。你写了三天的代码,脑子里全是实现细节,很容易对自己的代码产生"盲区"——你觉得逻辑没问题,但朋友一看就发现你漏了一个边界情况。

PR 的价值不只是"多一双眼睛"。朋友可能发现你遗漏的边界情况或潜在 bug——比如推荐算法没有处理用户没有评分记录的情况。通过 Review 别人的代码,朋友也了解了推荐功能的实现,这是知识共享——如果小明哪天不在,朋友也能维护推荐功能,因为他在 Review 的时候已经读过这些代码了。

所有关于这段代码的讨论都留在 PR 页面上,以后可以回溯"当时为什么这么写"。三个月后你看到一段奇怪的代码,不知道为什么要这么写,翻一下当时的 PR 讨论就能找到答案。

对于个人项目,PR 也有价值——它让你在合并前有一个"暂停、回顾"的机会。你可能在分支上连续开发了好几天,PR 的 diff 视图能帮你从全局视角审视这些修改,发现自己在细节中遗漏的问题。在发起 PR 之前,你还可以让 Claude Code 先做一轮 Self-Review——检查逻辑错误、安全隐患、性能问题。这样提交给朋友审查的代码质量更高,朋友也更愿意帮你 Review。

朋友打开 PR 页面,看到了小明改了哪些文件、每个文件具体改了哪几行。他可以在某一行代码下面留言:"这里的推荐算法没有处理用户没有评分记录的情况。"小明看到评论,修改代码,再次提交推送。PR 会自动更新,朋友可以看到新的修改。这个来回的过程可能会持续几轮——朋友提出问题,小明修改,朋友再看,直到双方都满意。这不是在浪费时间,而是在提高代码质量。很多 bug 就是在这个过程中被发现的,而不是上线之后被用户发现。

朋友确认没问题后,点击 Merge pull request。推荐功能的代码被合并到 main 分支,功能正式上线。合并后,GitHub 会提示你是否要删除这个分支。点击 Delete branch 就行——分支的使命已经完成,它的所有代码变更已经合并到了 main 里。别舍不得删,分支是廉价的,用完就扔。PR 页面上保留了所有代码变更和讨论记录,不会因为删除分支而丢失。以后你想回顾"推荐功能当时是怎么实现的",翻这个 PR 就行。

image-20260227003046255

完整流程图:

main ──────────────────────────────────────── main (包含推荐功能) │ ↑ └── feature/recommend ──→ 开发 ──→ PR ──→ Review ──→ Merge

GitHub PR 页面导览

第一次创建 PR,你需要知道页面上有什么。

image-20260227003217565

image-20260227003224983

创建 PR 时,你需要填写标题(简要描述这个 PR 做了什么)和描述(详细说明改了什么、为什么改),然后选择要合并到哪个分支(通常是 main)。标题写清楚就行,比如"添加基于评分的推荐功能"。描述可以写得详细一些——改了哪些模块、为什么选择这个方案、有没有已知的限制。好的 PR 描述能让 Reviewer 更快地理解你的意图,Review 效率也更高。你也可以让 Claude Code 帮你创建 PR——告诉它"在 GitHub 上创建一个 PR,把 feature/recommend 合并到 main",它会通过 GitHub CLI 完成创建,包括填写标题和描述。

PR 详情页有几个标签:Conversation 是 PR 的描述和所有讨论,Commits 是这个 PR 包含的所有提交,Files changed 是所有修改的文件对比——这是 Review 的主要工作区,你能看到每个文件的每一行变化。绿色背景的行是新增的,红色背景的行是删除的,没有颜色的行是上下文(帮你理解修改发生在代码的什么位置)。Review 通过后,页面底部会出现绿色的 Merge 按钮,点击即可合并。

如果你配置了 CI/CD(第十二章会讲),PR 页面还会显示自动化检查的结果——测试是否通过、构建是否成功。检查不通过时,Merge 按钮会变灰,防止有问题的代码被合并——就像你提交表单时必填项没填,提交按钮是灰色的、点不了。这是一道自动化的安全网,不需要人工盯着。即使你现在还没配置 CI/CD,知道 PR 页面有这个能力就行——等你的项目需要更严格的质量保障时,这个功能会非常有用。

个人项目也需要分支吗

你可能会想:我一个人开发,没有朋友 Review,还需要分支和 PR 吗?

答案是看情况。如果你只是在做一个小项目,直接在 main 上开发、提交、推送,完全没问题。很多个人项目从头到尾都在 main 上开发,也运行得很好。

但当你的项目开始变复杂——比如你想同时尝试两个不同的方案,或者你想在不影响线上版本的情况下做一次大重构——分支就变得有用了。

举个具体的场景:你的项目已经部署上线了(第十二章会讲部署),用户正在使用。你想加一个新功能,但这个功能需要改好几天。如果你直接在 main 上改,改到一半的代码可能会被部署上线——半成品的功能展示给用户,体验很差。但如果你在分支上开发,main 始终保持稳定可部署的状态,新功能开发完、测试通过后再合并到 main,用户看到的永远是完整的功能。

一个折中的做法:日常小修改直接在 main 上提交,大功能或实验性改动开分支。不需要一开始就严格执行完整的 PR 流程,等你和朋友开始协作时再引入。

Git 的工作流是渐进式的——先养成频繁提交和及时推送的习惯,等这两个习惯稳定了,再引入分支和 PR。不要试图一步到位,那样只会让你觉得 Git 很麻烦。

跨平台协作:Windows 遇上 Mac

小明用 Windows,朋友用 Mac。两个人协作时,踩到了几个经典的坑。

如果你用过 Windows 和 Mac 互传文件,一定遇到过乱码、文件名显示不对的问题。Git 协作中的跨平台问题本质上是同一类事——不同操作系统有不同的"方言",需要统一。

换行符差异是最常见的坑。Windows 用 CRLF(两个字符)表示换行,Mac/Linux 用 LF(一个字符)。这两个字符在屏幕上看起来完全一样——都是换行——但在文件的二进制层面是不同的。

如果不统一,Git 会认为整个文件都被修改了——明明只改了一行代码,diff 却显示每一行都有变化,因为每一行的换行符都从 LF 变成了 CRLF(或反过来)。这叫"假 diff",会让 Code Review 变得很痛苦,因为你根本看不出真正改了什么。

解决方案是告诉 Claude Code "配置 Git 统一使用 LF 换行符",它会在项目根目录创建一个 .gitattributes 文件,写入 * text=auto eol=lf,让 Git 在提交时自动把所有文本文件的换行符转换为 LF。配置一次,整个团队都受益,以后不管谁在什么系统上开发,提交到仓库的换行符都是统一的。

文件名大小写是另一个隐蔽的坑。Windows 不区分文件名大小写——Button.tsxbutton.tsx 在 Windows 看来是同一个文件,但在 Mac/Linux 上是两个不同的文件。

小明写了 import Button from './button',文件名叫 Button.tsx,在他的 Windows 上能跑,朋友的 Mac 上报错"找不到文件"。这种 bug 特别难排查,因为小明在自己电脑上怎么测都没问题,他会觉得"我这里明明能跑啊"。

更麻烦的是,Git 在 Windows 上默认也不跟踪大小写变更——你把 Button.tsx 重命名为 button.tsx,Git 可能根本不会检测到这个变化。解决方案是文件名统一用小写或统一用 PascalCase,团队约定好就行。

路径分隔符相对简单:Windows 用反斜杠 \,Mac/Linux 用正斜杠 /。在代码中永远使用正斜杠就行了。import { Button } from './components/Button' 在所有平台都能跑,import { Button } from '.\\components\\Button' 只在 Windows 上能跑。好消息是,大部分现代框架和打包工具已经帮你处理了路径分隔符的问题,你在代码里写正斜杠就行,不需要额外操心。

这些坑不需要你一个个记住。重要的是意识到它们的存在——当你和不同系统的朋友协作时遇到"明明代码一样但跑不起来"的情况,第一反应应该是"可能是跨平台兼容性问题",然后告诉 Claude Code 帮你排查。Claude Code 对这类问题很熟悉,通常能快速定位是换行符、大小写还是路径的问题。在项目初期就配好 .gitattributes 和文件命名规范,能省去后面很多麻烦。

日常开发节奏

当你和朋友的协作进入正轨,日常开发会形成一个固定的节奏。每天开始工作时先拉取最新代码,确保你的本地是最新的。然后创建功能分支,隔离你的工作。在分支上开发,小步快跑,频繁 commit。开发到一个阶段就推送到 GitHub,既是备份也是让朋友看到进展。功能完成后创建 PR,请求朋友审查。Review 通过后合并到主分支,最后删除功能分支保持整洁。

这个节奏不是死规矩。个人项目可以简化——不一定每次都开分支、创建 PR。但当你和别人协作时,这套流程能帮你避免大部分"代码打架"的问题。刚开始可能觉得步骤有点多,但用几次就会变成习惯。就像开车——刚学的时候觉得要同时注意方向盘、油门、刹车、后视镜,手忙脚乱。开熟了之后这些动作都是自动的,你甚至不会意识到自己在做这些事。Git 工作流也是一样,用熟了之后"pull → 分支 → 开发 → PR → 合并"就是你的肌肉记忆。

速查表

你想做什么 告诉 Claude Code
开始新功能 "从 main 创建一个分支来开发 xxx 功能"
保存进度 "提交当前的修改"
同步到云端 "推送到 GitHub"
获取最新代码 "拉取 main 分支的最新代码"
创建 PR "在 GitHub 上创建 Pull Request"
解决冲突 "帮我解决 Git 冲突"
撤销修改 "撤销对 xxx 文件的修改"
回退版本 "回到上一个能跑的版本"
删除分支 "删除 feature/xxx 分支"

::: tip 本节核心要点
分支让你安全地实验新功能,PR 让你在合并前获得审查,跨平台配置让不同系统的协作者能顺畅合作。这套工作流的核心不是记住命令,而是建立一个习惯:改之前开分支,合之前做 Review。
:::

下一章:代码在 GitHub 上了,怎么让用户访问到?第十二章:无服务器部署与 CI/CD 自动化 带你把项目部署上线。


发布者: 作者: 转发
评论区 (0)
U