3、Git进阶:分支管理策略、合并与变基、解决冲突、Git Flow工作流
分支管理,说白了就是团队协作的交通规则。没有规则,大家乱开,早晚撞车。我见过不少团队,刚开始用 Git 时觉得分支越多越酷,结果到了合并那天,冲突多到让人想砸键盘。嗯,今天我们就来聊聊怎么把分支管好。
3.1 分支管理策略:别让代码变成一团乱麻
分支策略没有银弹,但有几个经过实战检验的模式。我个人习惯是:主分支永远可部署。这条红线不能碰。
| 策略名称 | 核心原则 | 适用场景 |
|---|---|---|
| Git Flow | 多分支并行,严格角色 | 大型项目、版本发布频繁 |
| GitHub Flow | 只有 main,功能分支 + PR | 持续部署、小团队 |
| GitLab Flow | 环境分支 + 功能分支 | 有预发布/生产环境隔离 |
| Trunk-Based | 所有人往主干合,短命分支 | CI/CD 成熟、高频发布 |
我的建议: 刚开始别追求花哨。先定死一条规则——
main 分支只能通过 PR/MR 合并,禁止直接 push。这条规矩能救你无数次。
3.2 合并与变基:两种合并方式,两种哲学
合并(merge)和变基(rebase)都能把两个分支的改动合到一起,但结果完全不同。你想想看,merge 保留历史,rebase 重写历史。选哪个?
3.2.1 合并(Merge)
合并会创建一个新的合并提交,保留两条分支的完整时间线。好处是「发生了什么」一目了然,坏处是历史图会变得像蜘蛛网。
# 切换到目标分支
git checkout main
# 合并功能分支
git merge feature/login
# 生成一个 merge commit
什么时候用 merge? 当你需要保留「谁在什么时候合并了什么」的完整记录时。比如公共分支、长期分支。
3.2.2 变基(Rebase)
变基会把当前分支的提交「移植」到目标分支的最新提交之后。历史变成一条直线,干净漂亮。但代价是——提交的哈希值变了。
# 在功能分支上执行
git checkout feature/login
git rebase main
# 此时 feature/login 的基点是 main 的最新提交
千万不要对公共分支执行 rebase! 我曾经见过一个同事对
develop 分支做了 rebase,结果其他 5 个人的本地仓库全部乱掉。那次事故让我记住了:rebase 只用于本地或私有分支。
3.2.3 Merge vs Rebase 对比
| 维度 | Merge | Rebase |
|---|---|---|
| 历史记录 | 保留完整分支结构 | 线性历史,更简洁 |
| 提交哈希 | 不变 | 重新生成 |
| 冲突处理 | 一次解决 | 每个提交都可能冲突 |
| 安全性 | 安全,可追溯 | 危险,不可对公共分支用 |
| 适用场景 | 公共分支、长期分支 | 本地开发、PR 前整理 |
3.3 解决冲突:别慌,这是常态
冲突不是 bug,是多人协作的正常现象。我刚开始带团队时,每次冲突都紧张得要命,后来发现——冲突其实是 Git 在保护你的代码。
3.3.1 冲突长什么样?
当你执行 merge 或 rebase 时,Git 发现同一文件的同一区域被两个人改了不同内容,就会停下来,告诉你:
Auto-merging src/config.js
CONFLICT (content): Merge conflict in src/config.js
Automatic merge failed; fix conflicts and then commit the result.
打开冲突文件,你会看到这样的标记:
<<<<<<< HEAD
const API_URL = 'https://api.prod.com';
=======
const API_URL = 'https://api.staging.com';
>>>>>>> feature/staging-config
<<<<<<< HEAD到=======之间是当前分支的内容=======到>>>>>>> feature/staging-config是合并进来的分支的内容
3.3.2 解决步骤
- 手动编辑文件:保留你想要的内容,删掉冲突标记
- 保存文件
- 标记为已解决:
git add <file> - 完成合并:
git commit(merge 会自动生成提交,rebase 需要git rebase --continue)
小技巧: 使用可视化工具能大幅降低冲突解决的心智负担。我个人喜欢用
git mergetool,配置好 Beyond Compare 或 Meld,三栏对比一目了然。
3.3.3 避坑指南
我曾经犯过的错: 有一次解决冲突时,我直接把整个文件替换成了自己的版本,结果把同事的改动全丢了。后来花了两个小时才从 reflog 里找回来。记住:解决冲突不是「赢」,而是「合」。双方代码都要看,该留的留,该改的改。
3.4 Git Flow 工作流:经典但别滥用
Git Flow 是 2010 年 Vincent Driessen 提出的模型。说实话,现在很多团队觉得它太重了,但如果你做的是有版本周期的产品(比如移动 App、嵌入式固件),它依然很能打。
3.4.1 分支角色
| 分支类型 | 命名示例 | 作用 | 生命周期 |
|---|---|---|---|
| main | main / master | 生产就绪代码 | 永久 |
| develop | develop | 日常开发集成分支 | 永久 |
| feature | feature/user-auth | 新功能开发 | 临时,开发完合并到 develop |
| release | release/1.2.0 | 版本发布准备 | 临时,从 develop 拉,合并到 main 和 develop |
| hotfix | hotfix/critical-bug | 生产环境紧急修复 | 临时,从 main 拉,合并到 main 和 develop |
3.4.2 核心流程
- 从
develop拉出feature分支开发新功能 - 功能开发完,合并回
develop - 准备发布时,从
develop拉出release分支,只修 bug,不加新功能 release分支测试通过后,合并到main并打 tag,同时合并回develop- 生产出紧急 bug,从
main拉hotfix分支修复,修复后合并到main和develop
核心原则:
main 永远可部署,develop 永远可集成。任何分支都不能直接往 main 上 push,必须走 PR/MR + Code Review。
3.4.3 Git Flow 流程图
3.4.4 什么时候用 Git Flow?
- 适合: 有固定发布周期(如每月一个版本)、需要同时维护多个版本、有严格的测试和发布流程
- 不适合: 每天发布多次的 Web 服务、小团队(3-5 人)、还在快速迭代的 MVP 阶段
我的经验: 嵌入式固件开发用 Git Flow 很合适。因为固件有明确的版本号,需要同时维护旧版本的 hotfix,还要开发新版本的功能。但如果你做的是 SaaS 服务,GitHub Flow 可能更轻量。
3.5 本章小结
分支管理不是技术问题,是协作问题。选什么策略不重要,重要的是团队所有人都遵守同一套规则。我个人建议:
- 先定规矩:主分支保护、PR 流程、命名规范
- 再选工具:根据发布节奏选 Git Flow 还是 GitHub Flow
- 最后练手:冲突解决是熟练工,多来几次就习惯了
嗯,Git 进阶的内容就到这里。记住,工具是死的,人是活的。找到适合你们团队的节奏,比追求「最先进」的流程重要得多。