4、Git分支管理:分支的概念、git branch、git checkout、git merge、解决合并冲突、分支策略(Git Flow、GitHub Flow)
好,咱们进入正题。分支管理,说白了就是Git最核心的协作能力。没有分支,你想想看,大家全挤在一条主线上改代码,那画面太美我不敢看。我在ADAS团队里见过太多因为分支混乱导致的“惨案”,所以这一章,我希望能帮你把分支玩明白。
4.1 分支的概念:为什么我们需要“平行宇宙”?
分支是什么?我习惯把它理解成“平行宇宙”。主分支(比如main或master)是现实世界,你创建一个分支,就等于创造了一个平行宇宙。在这个宇宙里,你可以随便改代码、做实验,就算搞砸了,也不会影响现实世界。
在ADAS开发中,这个能力太重要了。举个例子,我们团队同时要开发车道保持和自动泊车两个功能。如果都在一条线上改,车道保持的代码还没测完,自动泊车的人一提交,整个系统可能就崩了。有了分支,各玩各的,互不干扰。
核心思想:分支的本质是一个可移动的指针,指向某个提交。创建分支就是创建一个新的指针,切换分支就是移动HEAD指针。
4.2 git branch:管理你的“平行宇宙”
git branch 这个命令,我每天至少用十几次。它负责创建、查看、删除分支。
常用操作:
- 查看分支:
git branch列出所有本地分支,当前分支前面有个星号。 - 创建分支:
git branch <branch-name>创建一个新分支,但不会自动切换过去。 - 删除分支:
git branch -d <branch-name>删除已合并的分支。如果分支没合并,用-D强制删除。
# 查看所有分支
git branch
# 创建一个叫 feature/lane-keeping 的分支
git branch feature/lane-keeping
# 删除一个已经合并的分支
git branch -d feature/lane-keeping
我的小习惯:分支命名一定要规范。我一般用 feature/功能名、bugfix/问题描述、hotfix/紧急修复 这种格式。别用“test1”、“aaa”这种名字,三个月后你自己都看不懂。
4.3 git checkout & git switch:在平行宇宙间穿梭
创建了分支,怎么过去?用 git checkout。不过Git 2.23之后,官方推荐用 git switch,语义更清晰。
# 切换到 feature/lane-keeping 分支
git checkout feature/lane-keeping
# 或者用新命令
git switch feature/lane-keeping
# 创建并切换(一步到位)
git checkout -b feature/auto-park
# 等价于
git switch -c feature/auto-park
这里有个坑,我踩过好几次。切换分支前,一定要确保工作区是干净的。如果你有未提交的修改,Git会拒绝切换,或者把修改带到目标分支,造成混乱。
避坑指南:我曾经在切换分支时忘了提交,结果把调试代码带到了主分支,导致CI构建失败。后来我养成了习惯:切换前先 git status 看一眼,或者用 git stash 暂存当前工作。
4.4 git merge:合并平行宇宙
功能开发完了,测试通过了,怎么把代码合回主分支?用 git merge。
合并有两种常见情况:
- 快进合并(Fast-forward):目标分支没有新提交,直接把指针往前移。简单、干净。
- 三方合并(Three-way merge):两个分支都有新提交,Git会找一个共同祖先,然后合并两个分支的修改。
# 先切到目标分支(比如 main)
git checkout main
# 把 feature/lane-keeping 合并进来
git merge feature/lane-keeping
我个人习惯在合并时加 --no-ff 参数,强制生成一个合并提交。这样能保留分支的历史痕迹,方便以后回溯。
git merge --no-ff feature/lane-keeping
4.5 解决合并冲突:ADAS工程师的必修课
合并冲突,说白了就是两个人改了同一块代码,Git不知道听谁的。在ADAS团队里,这太常见了。比如你改了传感器融合的参数,我也改了同一行,合并时就会冲突。
冲突长什么样?
<<<<<<< HEAD
// 当前分支的代码
float confidence = 0.85;
=======
// 要合并进来的代码
float confidence = 0.92;
>>>>>>> feature/lane-keeping
解决步骤:
- 找到冲突文件,Git会告诉你哪些文件有冲突。
- 打开文件,手动编辑冲突区域。删掉
<<<<<<<、=======、>>>>>>>这些标记。 - 保留你想要的代码,或者跟同事商量一下怎么改。
- 保存文件,然后
git add标记为已解决。 - 最后
git commit完成合并。
我的经验:解决冲突时,别光顾着删标记。要理解两边的代码逻辑。有一次我图省事,直接用了我的版本,结果把同事修的一个关键bug给覆盖了。嗯,后来我学乖了,遇到冲突先跟当事人沟通一下。
4.6 分支策略:Git Flow vs GitHub Flow
分支策略,就是团队约定怎么用分支。没有规矩不成方圆,尤其是ADAS这种多人协作、多版本并行的项目。
Git Flow:重型武器,适合复杂项目
Git Flow定义了五种分支:
| 分支类型 | 命名示例 | 用途 |
|---|---|---|
| main | main | 生产环境代码,只接受合并 |
| develop | develop | 日常开发的主分支 |
| feature | feature/xxx | 新功能开发,从develop分出 |
| release | release/1.0 | 发布前准备,修bug、更新文档 |
| hotfix | hotfix/xxx | 紧急修复生产问题,从main分出 |
我在做ADAS量产项目时,用的就是Git Flow。因为我们要同时维护多个版本(比如1.0、1.1),还要处理紧急的OTA修复。Git Flow的分支模型很清晰,适合这种场景。
注意:Git Flow比较复杂,小团队慎用。我见过3个人的团队硬套Git Flow,结果光管理分支就花了一半时间,得不偿失。
GitHub Flow:轻量级,适合快速迭代
GitHub Flow就简单多了,只有两个核心概念:
- main分支:永远保持可部署状态。
- feature分支:从main分出,开发完通过Pull Request合并回main。
没有develop、没有release,一切通过PR和Code Review来保证质量。我现在的团队就用这个,配合CI/CD,效率很高。
GitHub Flow的工作流:
- 从main创建feature分支。
- 在feature分支上开发、提交。
- 发起Pull Request,邀请同事Review。
- 通过Review后,合并到main。
- 立即部署或触发CI。
怎么选?我个人建议:如果是做ADAS量产、需要维护多个版本的项目,用Git Flow。如果是做原型验证、快速迭代的项目,用GitHub Flow。别纠结,选适合团队节奏的就行。
好了,分支管理这块就聊到这儿。记住一句话:分支是廉价的,但混乱的代价是昂贵的。用好分支,你的ADAS团队协作效率能翻一倍。