大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
分支工作流
这一课你将能做到
- 画出 Git Flow 与 GitHub Flow 的分支模型图,说出各自适用场景
- 按 Feature 分支工作流完成「从 main 切出 → 开发 → 合回」的完整节奏
- 用规范的分支命名(feature/xxx、fix/xxx、hotfix/xxx)让团队一眼看懂
为什么要学
学会了分支操作,不等于会用分支。实际开发中最容易出问题的不是命令不会敲,而是「分支乱」:不知道该在哪改、往哪合、什么时候删。分支工作流(Branching Workflow)就是一套「章法」——告诉团队每种分支的职责、生命周期和合并方向。
面试问「你们项目用的什么分支模型」,答「Git Flow 太重、我们 GitHub Flow」比支支吾吾强一百倍。
先建立图像
两种主流模型对比:
【GitHub Flow(轻量,适合持续部署)】
main ──●──●──────────────●──●───●────────> (永远可发布)
\ / \
feature/x ───● feature/y ────●
(短生命周期,PR 合回即删)
【Git Flow(重量级,适合有版本发布的项目)】
main ──●────────────────────●──────────> (只放发布版)
\ /
release ────●──●──●──────────● (发布准备)
\ /
develop ──●──●──●──●──●──●───●──────────> (集成分支)
\ \
feature ────● hotfix ──● (从 main 紧急修)
本站 java-nav 用的是 GitHub Flow 风格:main 永远可发布,所有改动通过短生命周期的 feature 分支 + PR 合回。
跟着做
步骤 1:从 main 切出功能分支
git switch main
git pull # 确保 main 最新
git switch -c feature/course-search
分支命名规范(团队约定):
feature/xxx新功能fix/xxx修 bughotfix/xxx紧急修复(从 main 直接切)docs/xxx纯文档refactor/xxx重构
步骤 2:在功能分支上开发并小步提交
# 改代码...
git add src/search/SearchController.java
git commit -m "feat(search): 新增课程搜索接口"
# 再改一些...
git add src/search/SearchService.java
git commit -m "feat(search): 实现搜索结果高亮"
# 再改...
git commit -m "test(search): 补充搜索接口单元测试"
原则:小步提交,每个 commit 只做一件事。这样既方便 review,也方便出问题时二分定位。
步骤 3:定期同步 main(避免冲突爆炸)
功能开发了几天,main 上别人合了新代码,你要及时同步:
git switch main
git pull
git switch feature/course-search
git merge main # 把 main 合进功能分支
# 解决冲突(如果有)...
git add .
git commit
也可用 git rebase main(历史更干净,但初学者先用 merge 更稳妥)。
步骤 4:推送并发起 PR
git push -u origin feature/course-search
然后去 GitHub 发 PR,等 review 通过后合并。
步骤 5:合并后清理
git switch main
git pull # 拉到刚合并的最新 main
git branch -d feature/course-search # 删本地分支
git push origin --delete feature/course-search # 删远程分支
GitHub PR 页面合并后也有「Delete branch」按钮,点一下就删了远程分支。
讲清楚要点
- main 永远保持可发布:任何改动都通过 PR 进入 main,不允许直接 push。这是所有工作流的共同底线。
- 功能分支生命周期要短:理想是 1-3 天。分支活得越久,和 main 的差异越大,合并冲突越痛苦。
- GitHub Flow vs Git Flow:GitHub Flow 只有 main + feature 两种分支,简单直接,适合 Web 持续部署;Git Flow 有 develop/release/hotfix 多套分支,适合需要同时维护多个版本的传统软件(如手机 ROM、桌面软件)。
- 同步 main 用 merge 还是 rebase:merge 保留分叉历史、安全;rebase 把历史拉直、干净但改写历史。团队规则优先,个人分支上可用 rebase。
- 分支命名即文档:
feature/course-search一看就知道干嘛的,zhangsan-dev三个月后没人知道是啥。
你可能会懵的地方
-
我应该选 Git Flow 还是 GitHub Flow? 90% 的互联网项目选 GitHub Flow。只有当你需要同时维护 v1.x、v2.x 多条发布线时才考虑 Git Flow。学习阶段直接 GitHub Flow。
-
功能分支没开发完,能被合进 main 吗? 不应该。如果实在要拆小步上线,用「特性开关」(Feature Flag):代码合进去但通过配置关闭。
-
hotfix 和 fix 有什么区别? hotfix 是从 main 紧急切出的修复(生产环境出 bug 必须立刻修),修完直接合回 main;fix 是普通 bug 修复,走正常 develop/feature 流程。GitHub Flow 里通常都叫 fix。
-
rebase 会丢 commit 吗? 不丢,但会生成新 commit(哈希变了),相当于「重放」。已 push 的分支不要 rebase,否则队友 pull 时历史错乱。
-
多人同时在同一功能分支上开发怎么办? 不推荐。功能分支是个人工作区,多人协作应该拆成更小的子分支,或者提前合并。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 直接在 main 上提交 | 污染主干,无法回滚 | 永远开功能分支 + PR |
| 分支活了半个月 | 合并时几十个冲突 | 小步快走,1-3 天合回 |
分支名叫 test、dev1 | 看不出在做什么 | feature/xxx 等规范命名 |
| 合并后忘了删分支 | 仓库里堆几十条死分支 | PR 合并后立即删除 |
| 在已 push 分支上 rebase | 队友 pull 报冲突 | 只 rebase 未推送的本地分支 |
卡点急救
- merge main 时冲突太多想放弃:
git merge --abort回到合并前状态,然后分段合并(先把 main 前几个 commit 合进来,再合剩余的)。 - 分支名起错了:
git branch -m 旧名 新名重命名本地分支,然后git push origin :旧名 新名更新远程。 - PR 还没合,main 又有新功能要先上:不要等,先把当前分支合 main(merge 一下),再让别人基于新 main 开分支。
面试常问
-
Git Flow 和 GitHub Flow 的区别? GitHub Flow:只有 main + feature 两种分支,main 永远可发布,feature 通过 PR 合回,简单适合持续部署。Git Flow:main(发布)、develop(集成)、feature、release、hotfix 五类分支,结构严谨适合多版本并行的传统软件。现代互联网项目主流用 GitHub Flow 或其变体。
-
merge 和 rebase 的区别? merge 生成合并 commit 保留分叉历史,不改写已有 commit,安全;rebase 把当前分支的 commit 在目标分支顶部「重放」,历史是直线更干净,但会生成新 commit(哈希变化),已 push 的分支 rebase 会坑队友。公共分支用 merge,个人分支整理历史可用 rebase。
-
如何避免合并冲突? 小步提交+频繁同步 main:分支活得越短、差异越小,冲突越少。团队约定「同一时间不要两人改同一文件」;把公共代码抽成模块减少交叉。
自测三问
- 为什么功能分支的生命周期越短越好?
- Git Flow 里的 develop 分支在 GitHub Flow 里被什么取代了?
- 已 push 的功能分支,应该 merge main 还是 rebase main?为什么?
小结一句话
分支工作流的本质是「main 永稳定 + 短分支快走 + PR 守门口」,掌握 GitHub Flow 就能应对 90% 的团队协作场景。
延伸
- GitHub Flow 官方指南
- 下一课:Pull Request——把 PR 写出专业水准,学会 review 与被 review。