"分支是 Git 的杀手级特性。它极其轻量,鼓励你为每一个小想法都开一个分支。"
1. 分支基本操作#
基于 Git 00 的理解,分支只是一个“指针”。
创建与切换
# 现代方式 (推荐,Git 2.23+)
git switch -c feature/example # 创建并切换到新分支
git switch master # 切换回 master
# 传统方式 (依然有效)
git checkout -b feature/example
git checkout master查看与删除
git branch # 列出本地所有分支 (* 号表示当前所在)
git branch -v # 查看每个分支的最后一次提交
git branch -d feature/example # 删除已合并的分支
git branch -D feature/example # 强制删除未合并的分支 (慎用)2. 合并的两种模式:Merge#
当你把 feature 分支合并回 master 时,Git 会根据提交历史的拓扑结构采取不同的策略。
A. Fast-forward (快进合并)
如果 master 在分叉后没有新提交,Git 会直接挪动指针。
- 特点:没有新的合并提交,历史呈完美直线。
B. Three-way Merge(三方合并)
双方已经分叉时,Git 基于共同祖先和两端内容进行三方合并,正常完成后生成合并提交。当前常用两头合并策略为 ort;历史资料中的 recursive 不等于三方合并的通用名称。
进阶:强制产生合并提交 (--no-ff)
为什么需要?:Fast-forward 会丢失“这里曾经有一个功能分支”的信息。在工程中,我们常使用 git merge --no-ff feature/example 来强制保留分支存在的痕迹,方便后续代码审计。
3. 冲突处理:当 Git 无法抉择#
重叠内容无法自动合并时会停下要求解决;修改/删除、重命名等也可能冲突,并不限于同一行。
冲突标识符
Git 会在冲突文件中插入标记:
<<<<<<< HEAD
这是你在当前分支 (master) 修改的内容
=======
这是你要合并进来的分支 (feature) 修改的内容
>>>>>>> feature/example解决步骤
- 手动编辑:删除标记,保留你想要的代码。
- 标记解决:执行
git add <file>,告诉 Git 冲突已搞定。 - 完成合并:执行
git commit。
4. 现场保存:git stash#
场景:正在写功能,突发 Bug 需切换分支,但当前代码还没写完。
git stash # 保存已追踪文件的改动
git stash -u # 【重要】包含未追踪的新文件 (include-untracked)
git stash list # 查看所有存档
git stash pop # 应用最顶层存档;成功后删除,冲突时通常保留存档5. 分支策略:Merge vs. Rebase#
这是 Git 中最持久的争论。虽然 Rebase 的具体用法在 Git 04 详述,但这里必须理解其哲学差异。
| 特性 | Merge (合并) | Rebase (变基/衍合) |
|---|---|---|
| 底层逻辑 | 快进时仅移动引用,否则可创建合并点。 | 把当前分支的修改在目标分支顶部“重演”。 |
| 历史感 | 真实性:记录了分支交汇的确切时刻。 | 整洁性:历史是一条直线,看起来没分过叉。 |
| 冲突处理 | 一次性处理所有冲突。 | 每一层重演都可能需要处理冲突。 |
| 适用场景 | 团队协作、公共分支。 | 个人分支、清理提交历史、保持 upstream 最新。 |
6. 功能分支工作流 (Feature Branching)#
核心原则:
- 以保持 master/main 可用为团队目标:不要直接在上面写代码。
- 每个功能一个分支:
feature/login,fix/issue-101。 - 合并前进行 Review:在 master 保持领先时,通过合并确保功能分支在合并回主干前是健康的。
保留现场的边界
普通 stash 保存已追踪的工作区和暂存修改;-u 也纳入未追踪文件,忽略文件仍需另行考虑。可先 git stash apply 检查恢复结果,再明确 git stash drop;需要恢复原暂存状态时检查 --index 的适用条件。合并、切换和删除分支前先检查状态;branch -D 会删除恢复引用,但不是删除所有旧对象。
参考与延伸
根据技术笔记重新整理,示例使用通用名称。