分支管理策略
2026/3/20大约 14 分钟
分支管理策略
深入理解 Git 分支模型与最佳实践
分支概念
什么是分支?
在 Git 中,分支本质上是指向某个提交对象的可移动指针。默认分支名是 main(或 master)。每次提交时,当前分支指针会自动向前移动。
分支图示
说明:创建
feature分支后在其上提交 F、G,main仍指向 E,HEAD跟随feature移动到 G。
分支基本操作
创建分支
# 创建分支(不切换)
git branch feature-login
# 创建并切换分支
git checkout -b feature-login
git switch -c feature-login # Git 2.23+ 推荐
# 基于特定提交创建分支
git branch feature-login abc1234
git checkout -b feature-login abc1234
git switch -c feature-login abc1234
# 基于远程分支创建
git checkout -b feature-login origin/feature-login
git switch -c feature-login origin/feature-login
# 基于标签创建
git checkout -b release-1.0 v1.0.0
# 创建孤儿分支(无历史)
git checkout --orphan new-branch
git switch --orphan new-branch
查看分支
# 列出本地分支
git branch
# 列出远程分支
git branch -r
# 列出所有分支
git branch -a
# 显示分支详情(最后提交)
git branch -v
# 显示分支详情(包含上游分支)
git branch -vv
# 显示已合并到当前分支的分支
git branch --merged
# 显示未合并到当前分支的分支
git branch --no-merged
# 显示包含特定提交的分支
git branch --contains abc1234
# 按模式筛选
git branch --list "feature-*"
# 显示分支的上游分支
git branch -vv | grep '\[origin'
切换分支
# 切换分支
git checkout feature-login
git switch feature-login # Git 2.23+ 推荐
# 切换到上一个分支
git checkout -
git switch -
# 切换并丢弃本地修改
git checkout -f feature-login
git switch -f feature-login
# 分离 HEAD(检出特定提交)
git checkout abc1234
git checkout v1.0.0
git switch --detach abc1234
重命名分支
# 重命名当前分支
git branch -m new-name
# 重命名指定分支
git branch -m old-name new-name
# 强制重命名(即使目标名已存在)
git branch -M new-name
# 重命名远程分支(需要删除旧的,推送新的)
git push origin :old-name
git push origin new-name
git push origin -u new-name
删除分支
# 删除已合并的本地分支
git branch -d feature-login
# 强制删除本地分支(无论是否合并)
git branch -D feature-login
# 删除远程分支
git push origin --delete feature-login
git push origin :feature-login
# 清理已删除远程分支的本地跟踪分支
git remote prune origin
git fetch -p
# 批量删除已合并的分支
git branch --merged main | grep -v "main" | xargs git branch -d
# 批量删除匹配模式的分支
git branch | grep "feature-" | xargs git branch -d
合并分支
git merge - 合并
# 合并分支到当前分支
git merge feature-login
# 带消息合并
git merge feature-login -m "Merge feature-login into main"
# 不使用快进合并(总是创建合并提交)
git merge --no-ff feature-login
# 使用快进合并(如果可能)
git merge --ff feature-login
# 只允许快进合并
git merge --ff-only feature-login
# 压缩合并(不保留分支历史)
git merge --squash feature-login
git commit -m "Add login feature"
# 中止合并
git merge --abort
# 继续合并(解决冲突后)
git merge --continue
合并策略对比
| 策略 | 命令 | 结果 |
|---|---|---|
| Fast-forward | git merge feature | 线性历史,无合并提交 |
| No-ff | git merge --no-ff | 保留分支历史,有合并提交 |
| Squash | git merge --squash | 压缩为单个提交 |
Fast-forward 合并
No-ff 合并
Squash 合并
处理合并冲突
# 查看冲突文件
git status
# 查看冲突详情
git diff
# 使用工具解决冲突
git mergetool
# 接受我们的版本
git checkout --ours file.txt
# 接受他们的版本
git checkout --theirs file.txt
# 解决后标记为已解决
git add file.txt
# 完成合并
git commit
# 放弃合并
git merge --abort
冲突文件格式
<<<<<<< HEAD
这是当前分支的内容
=======
这是要合并分支的内容
>>>>>>> feature-branch
手动编辑后删除标记,保留需要的内容,然后 git add 并提交。
变基操作
git rebase - 变基
变基是将一系列提交"移动"到另一个基点上,产生线性历史。
# 基本变基
git checkout feature
git rebase main
# 或者一步完成
git rebase main feature
# 交互式变基
git rebase -i HEAD~3
git rebase -i main
# 变基到远程分支
git rebase origin/main
# 保留合并提交
git rebase --rebase-merges main
# 中止变基
git rebase --abort
# 解决冲突后继续
git rebase --continue
# 跳过当前提交
git rebase --skip
变基过程图示
执行:
git checkout feature && git rebase main
D' 和 E' 是 D 和 E 的副本,基于 C
交互式变基
git rebase -i HEAD~5
编辑器打开后显示:
pick abc1234 First commit
pick def5678 Second commit
pick ghi9012 Third commit
pick jkl3456 Fourth commit
pick mno7890 Fifth commit
# Commands:
# p, pick = 使用提交
# r, reword = 使用提交,但编辑提交信息
# e, edit = 使用提交,但停下来修改
# s, squash = 使用提交,但合并到前一个提交
# f, fixup = 类似 squash,但丢弃提交信息
# x, exec = 使用 shell 执行命令
# d, drop = 删除提交
交互式变基示例
# 合并最近3个提交为一个
git rebase -i HEAD~3
# 将第2、3个提交改为 squash 或 fixup
# 修改某个历史提交
git rebase -i HEAD~5
# 将目标提交改为 edit
# 修改后: git commit --amend
# 继续: git rebase --continue
# 重新排序提交
git rebase -i HEAD~5
# 调整 pick 行的顺序
# 拆分提交
git rebase -i HEAD~3
# 将目标提交改为 edit
# git reset HEAD^
# git add 第一部分 && git commit
# git add 第二部分 && git commit
# git rebase --continue
merge vs rebase
merge vs rebase 对比
| 特性 | merge | rebase |
|---|---|---|
| 历史 | 非线性(保留分支结构) | 线性(清晰简洁) |
| 安全性 | 安全(不改写历史) | 需谨慎(改写历史) |
| 冲突解决 | 一次性解决 | 可能多次解决 |
| 可追溯性 | 保留完整上下文 | 丢失分支上下文 |
| 适用场景 | 公共分支、团队协作 | 个人分支、保持历史整洁 |
⚠️ 黄金法则:不要对已推送到远程的提交进行变基
推荐使用 merge 的场景:
- 合并功能分支到主分支
- 需要保留完整的开发历史
- 团队协作的公共分支
推荐使用 rebase 的场景:
- 更新个人功能分支到最新主分支
- 在推送前整理本地提交
- 保持提交历史清晰线性
Cherry-pick
git cherry-pick - 挑选提交
# 挑选单个提交
git cherry-pick abc1234
# 挑选多个提交
git cherry-pick abc1234 def5678 ghi9012
# 挑选一系列提交
git cherry-pick abc1234..def5678 # 不包含 abc1234
git cherry-pick abc1234^..def5678 # 包含 abc1234
# 不自动提交(只应用更改)
git cherry-pick -n abc1234
git cherry-pick --no-commit abc1234
# 编辑提交信息
git cherry-pick -e abc1234
# 追加签名
git cherry-pick -x abc1234 # 添加 "(cherry picked from commit ...)"
git cherry-pick -s abc1234 # 添加 Signed-off-by
# 处理合并提交
git cherry-pick -m 1 merge-commit-hash # 选择第一个父提交
# 中止
git cherry-pick --abort
# 继续
git cherry-pick --continue
# 跳过当前提交
git cherry-pick --skip
Cherry-pick 使用场景
热修复回移示例:
# main: A ← B ← C ← FIX ← D
# release: A ← B ← X ← Y
git checkout release
git cherry-pick FIX
# 结果: release: A ← B ← X ← Y ← FIX'
分支管理模型
Git Flow
最经典的分支管理模型,适合有计划发布周期的项目。
Git Flow 分支说明:
| 分支类型 | 命名规范 | 说明 |
|---|---|---|
| main | main | 生产分支,只接受合并,每个合并打标签 |
| develop | develop | 开发分支,日常开发的集成分支 |
| feature/* | feature/* | 功能分支,从 develop 创建,完成后合并回 develop |
| release/* | release/* | 发布分支,从 develop 创建,用于发布准备 |
| hotfix/* | hotfix/* | 热修复分支,从 main 创建,修复后合并到 main 和 develop |
适用场景:
- 有明确版本发布周期的项目
- 需要同时维护多个版本
- 团队规模较大
Git Flow 命令
# 初始化 Git Flow
git flow init
# 功能分支
git flow feature start login
git flow feature finish login
# 发布分支
git flow release start 1.0.0
git flow release finish 1.0.0
# 热修复分支
git flow hotfix start fix-login
git flow hotfix finish fix-login
手动实现 Git Flow
# 创建功能分支
git checkout develop
git checkout -b feature/login
# 完成功能
git checkout develop
git merge --no-ff feature/login
git branch -d feature/login
# 创建发布分支
git checkout develop
git checkout -b release/1.0.0
# 发布
git checkout main
git merge --no-ff release/1.0.0
git tag -a v1.0.0 -m "Release 1.0.0"
git checkout develop
git merge --no-ff release/1.0.0
git branch -d release/1.0.0
# 热修复
git checkout main
git checkout -b hotfix/fix-login
# 修复后
git checkout main
git merge --no-ff hotfix/fix-login
git tag -a v1.0.1 -m "Hotfix 1.0.1"
git checkout develop
git merge --no-ff hotfix/fix-login
git branch -d hotfix/fix-login
GitHub Flow
简化的工作流,适合持续部署的项目。
GitHub Flow 工作流程:
核心原则:
- main 分支始终可部署
- 使用描述性的分支名
- 经常推送,保持可见性
- 使用 PR 进行代码审查
- 合并后立即部署
适用场景:持续部署的 Web 应用、小型敏捷团队、简单的发布流程
GitHub Flow 实践
# 1. 创建功能分支
git checkout main
git pull origin main
git checkout -b feature/add-login
# 2. 开发并提交
git add .
git commit -m "feat: add login form"
git push origin feature/add-login
# 3. 创建 Pull Request(在 GitHub 网页上)
# 4. 代码审查后合并
# 5. 清理
git checkout main
git pull origin main
git branch -d feature/add-login
GitLab Flow
结合了 Git Flow 和 GitHub Flow 的优点。
环境分支模式:
版本分支模式:
核心原则:
- 上游优先(Upstream First)
- 环境分支反映部署状态
- 合并请求驱动开发
Trunk-Based Development
主干开发,适合高度自动化的团队。
特点:
- 开发者直接向主干提交(或通过短期分支)
- 分支生命周期极短(小时或 1-2 天)
- 依赖特性开关(Feature Flags)控制发布
- 需要强大的 CI/CD 和测试体系
- 适合成熟的敏捷团队
| 维度 | 说明 |
|---|---|
| 优势 | 减少合并冲突、快速集成反馈、简化分支管理 |
| 要求 | 高度自动化测试、持续集成、特性开关系统、团队纪律 |
分支命名规范
常用命名约定
| 类型前缀 | 说明 | 示例 |
|---|---|---|
feature/ | 新功能 | feature/user-login |
feat/ | 新功能(简写) | feat/add-payment |
fix/ | Bug 修复 | fix/login-error |
bugfix/ | Bug 修复 | bugfix/header-overflow |
hotfix/ | 紧急修复 | hotfix/security-patch |
release/ | 发布准备 | release/1.0.0 |
docs/ | 文档更新 | docs/api-reference |
refactor/ | 代码重构 | refactor/auth-module |
test/ | 测试相关 | test/add-unit-tests |
chore/ | 杂项任务 | chore/update-deps |
experiment/ | 实验性功能 | experiment/new-algorithm |
命名规则:
- 使用小写字母
- 使用连字符分隔单词
- 包含问题编号(可选):
feature/JIRA-123-user-login - 简洁但有描述性
- 避免特殊字符
好的示例 ✅:feature/add-oauth-login、fix/PROJ-456-null-pointer、release/v2.1.0
不好的示例 ❌:Feature/Add_Login(大写和下划线)、my-branch(无类型前缀)、fix(太笼统)
分支保护
GitHub 分支保护规则
CODEOWNERS 文件
# .github/CODEOWNERS
# 默认审查者
* @default-reviewer
# 特定目录
/src/auth/ @auth-team
/src/api/ @api-team @tech-lead
/docs/ @docs-team
# 特定文件类型
*.js @frontend-team
*.py @backend-team
# 特定文件
package.json @npm-admin
.github/ @devops-team
高级分支技巧
比较分支
# 查看两个分支的差异
git diff main..feature
git diff main...feature # 三点表示共同祖先以来的差异
# 查看 feature 有而 main 没有的提交
git log main..feature
# 查看两个分支各自独有的提交
git log main...feature --left-right
# 统计差异
git diff main..feature --stat
git shortlog main..feature
查找分支基点
# 找到两个分支的共同祖先
git merge-base main feature
# 查看分支从哪个提交分出
git log --oneline main..feature
跟踪分支
# 设置上游分支
git branch -u origin/feature feature
git branch --set-upstream-to=origin/feature feature
# 推送时设置上游
git push -u origin feature
# 查看跟踪关系
git branch -vv
# 删除上游跟踪
git branch --unset-upstream
工作树(Worktree)
# 在新目录检出另一个分支
git worktree add ../feature-worktree feature-branch
# 列出所有工作树
git worktree list
# 删除工作树
git worktree remove ../feature-worktree
# 清理过时的工作树信息
git worktree prune
工作树允许你同时在多个分支上工作,无需来回切换。
分支策略建议
选择合适的模型
| 项目特点 | 推荐模型 |
|---|---|
| 持续部署、Web 应用 | GitHub Flow |
| 定期发布、多版本维护 | Git Flow |
| 多环境部署 | GitLab Flow(环境分支) |
| 开源项目 | GitHub Flow + Fork |
| 高频集成、成熟团队 | Trunk-Based Development |
| 小团队、简单项目 | GitHub Flow |
| 大团队、复杂发布 | Git Flow 或 GitLab Flow |
核心原则:
- main 分支始终保持可部署状态
- 使用功能分支进行开发
- 通过 PR/MR 进行代码审查
- 小而频繁的提交
- 定期同步上游变更
- 及时删除已合并的分支