第 2 章 · 02 分支、合并与历史管理 本节摘要:分支是 Git 协作的核心。本节先讲四种分支策略与分支的内部机制(分支只是一个指向提交的指针),再覆盖合并与冲突解决、reset 与 revert、rebase 与 squash、恢复文件与删除远程分支。学完本节,你能主导一个多分支协作流程,并能在历史管理上收放自如。 学习目标 说出四种分支策略的差异与适用场景。 解释分支在内部是什么(.git/HEAD 与 update-ref)。 完成一次合并冲突的解决流程。 区分 reset 与 revert、merge 与 rebase。 说出 squash、删除远程分支、恢复文件的命令。
本节摘要:分支是 Git 协作的核心。本节先讲四种分支策略与分支的内部机制(分支只是一个指向提交的指针),再覆盖合并与冲突解决、reset 与 revert、rebase 与 squash、恢复文件与删除远程分支。学完本节,你能主导一个多分支协作流程,并能在历史管理上收放自如。
| 策略 | 核心思想 | 适用 |
|---|---|---|
| Git Flow | main + develop + feature + release + hotfix 多分支体系 | 大型/发布周期化项目 |
| GitHub Flow | 只有 main + 短命 feature 分支,PR 合入 | 持续部署的互联网产品 |
| Trunk-based | 所有人频繁合入主干,特性开关控制发布 | 追求高发布频率 |
| GitLab Flow | GitHub Flow + 环境分支(如 pre-production) | 需要环境门禁 |
小知识:分支本质上就是指向某条工作线头部(最新提交)的指针/引用。
git branch <BRANCH> # 创建分支
背后发生了什么?Git 执行 update-ref,把当前分支最新提交的 SHA-1 写入新分支引用。Git 怎么知道最新提交的 SHA-1?读 .git/HEAD 文件——它指向当前分支(refs/heads/some_branch)。
git checkout some_branch 时,Git 把 .git/HEAD 更新为 refs/heads/some_branch(True)。git checkout main git pull git checkout devel git merge main # 把 main 合入 devel
保持分支同步的推荐动作序列:切到 main → pull → 切回 devel → merge main。
<<<<<<< / ======= / >>>>>>>);git add <file> 标记已解决;git rebase --continue(或 git commit 完成 merge 提交)。| 策略 | 说明 |
|---|---|
| recursive | 默认策略,适合两个分支合并 |
| resolve | 简单两路合并 |
| ours / theirs | 直接取一方(丢弃另一方) |
| octopus | 多分支合并的默认策略,主要用于把多个主题分支捆在一起 |
| 命令 | 行为 | 对历史的影响 |
|---|---|---|
git revert |
新建一个提交来撤销上一次提交的更改 | 保留原历史,安全,适合已推送 |
git reset |
移动分支头指针/修改暂存区 | 改写历史,谨慎 |
日常用法:
git revert <commit> # 撤销某提交(新增反向提交) git reset HEAD~1 # 移除最近一个提交(改动保留在工作目录) git reset --hard HEAD~1 # 移除提交且丢弃改动(危险) git checkout -- <file> # 丢弃工作目录中某文件未提交的改动
删除远程分支:
git push origin :<branch_name>
rebase(变基):把当前分支的提交重新应用到另一个基之上。典型场景:feature 分支开发完成后,rebase 到 main 上,使历史呈线性,再合并进 main——避免"合并泡"污染历史。
squash(压缩提交):把多个提交合并为一个。典型场景:feature 分支上一堆"wip"提交,合入前压缩成一个有意义的提交。
git rebase -i HEAD~2 # 交互式变基,可 reword/squash 最近两个提交 git checkout HEAD~1 -- <file> # 把某文件恢复到上一个提交的版本
.git 目录(等于删除全部历史);下一节预告:进阶性能与 Git 内部机制——monorepo 为什么慢、怎么提速、git status 背后做了什么,外加三个动手练习。