Git: Git分支管理与并行开发
分支是Git最强大的特性之一。通过分支,团队可以并行开发不同功能,互不影响,最后再合并到一起。Git的分支创建成本极低,鼓励频繁使用分支。
1. 分支基础概念
(1) 什么是分支
在Git中,分支是指向某个提交的可移动指针。每次提交时,当前分支指针会自动向前移动,指向新的提交。
graph LR
C1[提交C1] --> C2[提交C2] --> C3[提交C3]
main[main分支] --> C3
HEAD[HEAD] --> main
style main fill:#d4edda
style HEAD fill:#fff3cd
(2) 分支的本质
Git的分支本质上是一个包含41字节的文件:
- 40字节的SHA-1哈希值
- 1字节的换行符
这就是为什么Git创建分支极快的原因。
BASH
# 查看分支文件
cat .git/refs/heads/main
# 输出:
# a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
(3) HEAD指针
HEAD是一个特殊指针,指向当前所在的分支:
graph TB
HEAD[HEAD] --> main[main分支]
main --> C3[提交C3]
C3 --> C2[提交C2]
C2 --> C1[提交C1]
style HEAD fill:#f8d7da
style main fill:#d4edda
(4) 分支的优势
- 并行开发:多人同时在不同分支工作
- 功能隔离:新功能开发不影响主分支
- 安全实验:在分支上实验,失败就删除
- 版本管理:不同版本使用不同分支维护
2. 查看分支
(1) 查看本地分支
▶ 示例:列出分支
BASH
# 查看本地分支
git branch
# 输出:
# * main
# develop
# feature
# * 表示当前所在分支
# 查看分支和最后一次提交
git branch -v
# 输出:
# * main a1b2c3d feat: 添加登录功能
# develop d4e5f6g Fix: 修复Bug
# feature h7i8j9k WIP: 新功能
# 查看详细的分支信息
git branch -vv
# 输出包含上游分支信息:
# * main a1b2c3d [origin/main] feat: 添加登录功能
(2) 查看所有分支
▶ 示例:查看远程分支
BASH
# 查看所有分支(本地+远程)
git branch -a
# 输出:
# * main
# develop
# remotes/origin/HEAD -> origin/main
# remotes/origin/main
# remotes/origin/develop
# remotes/origin/feature
# 只查看远程分支
git branch -r
# 输出:
# origin/HEAD -> origin/main
# origin/main
# origin/develop
# origin/feature
(3) 查看分支关系
▶ 示例:分支图形化显示
BASH
# 查看分支历史图
git log --oneline --graph --all
# 输出:
# * a1b2c3d (HEAD -> main) feat: 添加登录
# | * d4e5f6g (feature) WIP: 新功能
# |/
# * h7i8j9k Initial commit
# 查看分支包含的提交
git log --oneline --graph --decorate --all
# 查看分支分叉点
git merge-base main feature
3. 创建分支
(1) 创建新分支
▶ 示例:创建分支
BASH
# 创建分支(基于当前提交)
git branch feature
# 创建分支并指定起点
git branch feature a1b2c3d
# 基于某个标签创建分支
git branch v1.1-branch v1.0.0
# 创建分支并立即切换
git checkout -b feature
# 新语法(推荐)
git switch -c feature
# 基于远程分支创建
git checkout -b feature origin/feature
# 或者
git switch -c feature origin/feature
(2) 创建分支的工作流
graph TB
A[main分支] --> B[git branch feature]
B --> C[新分支feature]
C --> D[在feature上开发]
D --> E[提交修改]
E --> F[合并回main]
style A fill:#d4edda
style C fill:#fff3cd
style F fill:#c3e6cb
(3) 分支命名规范
▶ 示例:规范的分支命名
TEXT
📖 仅展示
功能分支:feature/user-auth
feature/shopping-cart
feature/payment-integration
修复分支:fix/login-error
fix/memory-leak
热修复分支:hotfix/critical-security-issue
hotfix/payment-failure
发布分支:release/v1.0.0
release/v2.1.0
开发分支:develop
主分支:main(或master)
4. 切换分支
(1) 切换分支命令
▶ 示例:切换分支
BASH
# 传统命令
git checkout feature
# 新命令(推荐)
git switch feature
# 切换到上一个分支
git switch -
# 切换到main分支
git switch main
# 创建并切换
git switch -c new-feature
# 输出:
# Switched to branch 'new-feature'
(2) 切换分支的原理
graph TB
A[切换分支前] --> B[更新HEAD指针]
B --> C[更新暂存区]
C --> D[更新工作区]
D --> E[切换完成]
style A fill:#fff3cd
style E fill:#d4edda
切换分支时,Git会:
- 更新HEAD指向新分支
- 更新暂存区为新分支的状态
- 更新工作区文件为新分支的内容
(3) 处理未提交修改
▶ 示例:切换分支前处理修改
BASH
# 查看当前状态
git status
# 方式1:提交修改
git add .
git commit -m "WIP: 临时保存"
git switch feature
# 方式2:暂存修改(stash)
git stash
git switch feature
# 完成其他工作后
git switch main
git stash pop
# 方式3:放弃修改
git restore .
git switch feature
# 方式4:携带修改切换(如果不会冲突)
git switch feature
# 如果修改和新分支不冲突,会保留修改
5. 删除分支
(1) 删除已合并分支
▶ 示例:安全删除分支
BASH
# 删除已合并的分支
git branch -d feature
# 输出:
# Deleted branch feature (was a1b2c3d).
# 删除多个分支
git branch -d feature1 feature2
# 删除已合并的远程分支
git push origin --delete feature
# 或者
git push origin :feature
(2) 强制删除分支
▶ 示例:强制删除未合并分支
BASH
# 尝试删除未合并的分支
git branch -d feature
# 输出错误:
# error: The branch 'feature' is not fully merged.
# If you are sure you want to delete it, run 'git branch -D feature'.
# 强制删除
git branch -D feature
# 输出:
# Deleted branch feature (was a1b2c3d).
(3) 清理远程分支
▶ 示例:清理已删除的远程分支
BASH
# 查看远程分支引用
git branch -r
# 删除本地的远程分支引用(远程已删除)
git fetch -p
# 或者
git remote prune origin
# 查看哪些远程分支引用需要清理
git remote prune origin --dry-run
6. 分支管理最佳实践
(1) 分支策略
常见的分支策略:
Git Flow:
graph TB
main[main 生产] --> release[release 发布]
release --> develop[develop 开发]
develop --> feature[feature 功能]
main --> hotfix[hotfix 热修复]
style main fill:#d4edda
style develop fill:#fff3cd
style feature fill:#e1f5ff
style hotfix fill:#f8d7da
GitHub Flow:
- main分支始终可部署
- 从main创建功能分支
- 开发完成后创建Pull Request
- 审查通过后合并到main
(2) 分支命名建议
▶ 示例:分支命名规范
BASH
# 功能分支
feature/user-authentication
feature/shopping-cart
feature/payment-integration
# Bug修复
fix/login-validation-error
fix/memory-leak-issue
# 热修复
hotfix/security-vulnerability
hotfix/critical-bug
# 发布
release/v1.0.0
release/v2.1.0
# 实验
experiment/new-architecture
spike/performance-optimization
(3) 分支工作流
▶ 示例:完整的分支工作流
BASH
# 1. 从main创建功能分支
git checkout main
git pull origin main
git checkout -b feature/user-auth
# 2. 在功能分支上开发
echo "auth code" > auth.js
git add auth.js
git commit -m "feat: 添加用户认证"
# 3. 保持与main同步
git fetch origin
git merge origin/main
# 或使用rebase
git rebase origin/main
# 4. 推送功能分支
git push -u origin feature/user-auth
# 5. 创建Pull Request(在GitHub上)
# 6. 合并后删除功能分支
git checkout main
git pull origin main
git branch -d feature/user-auth
git push origin --delete feature/user-auth
❓ 常见问题
Q 创建分支后,原分支会受影响吗?
A 不会。创建分支只是创建一个新指针,指向当前提交,原分支完全不受影响。两个分支可以独立发展。
Q 如何查看某个分支是从哪个分支创建的?
A 使用
git log --oneline --graph --all 查看分支历史图,或者使用 git merge-base <分支1> <分支2> 查看两个分支的分叉点。Q 删除分支后,提交会丢失吗?
A 如果提交已经被其他分支引用(如已合并到main),删除分支不会丢失提交。如果提交只存在于被删除的分支,删除后提交会丢失,但可以通过
git reflog 找回。Q checkout和switch有什么区别?
A
git switch 是Git 2.23引入的新命令,专门用于切换分支,语义更清晰。git checkout 功能更全面,可以切换分支、恢复文件、创建分支等。建议使用 git switch 切换分支。Q 如何在分支之间比较差异?
A 使用
git diff main feature 比较两个分支的差异,使用 git diff main...feature 查看feature分支相对于main的修改。📖 小节
- 分支是指向提交的可移动指针,创建成本极低
- 查看分支:
git branch列出本地分支,-a显示所有分支 - 创建分支:
git branch <name>或git switch -c <name>创建并切换 - 切换分支:
git switch <name>更新HEAD和工作区 - 删除分支:
git branch -d删除已合并分支,-D强制删除 - 分支策略:Git Flow、GitHub Flow等,选择适合团队的策略
📝 作业
-
基础题:创建一个Git仓库,创建多个分支(main、develop、feature),在不同分支上提交不同的修改,使用
git branch和git log --graph查看分支结构。 -
进阶题:模拟完整的分支工作流:从main创建功能分支,开发功能,保持与main同步,最后合并回main并删除功能分支。
-
挑战题:在一个实际项目中实施Git Flow分支策略,创建develop、feature、release、hotfix等分支,体验完整的分支管理流程。