Git 分支管理基础
掌握 Git 分支的创建、切换和合并,学习如何使用分支进行并行开发
简介
分支 (Branch) 是 Git 最强大的功能之一。它允许你从主开发线上分离出来,在不影响主线的情况下进行工作。
想象一下:你正在开发一个网站,突然需要:
- 尝试一个新功能
- 修复一个紧急 bug
- 为不同客户定制版本
如果没有分支,你要么放弃当前工作,要么冒险直接在主代码上修改。有了分支,这些都不是问题!
什么是分支?
形象理解
把代码历史想象成一棵树:
main 分支
│
A ← B ← C ← D
↑
└─ E ← F (feature 分支)
main分支: 主干,稳定的代码feature分支: 从 B 点分出来,开发新功能- 两个分支可以独立发展,互不干扰
分支的本质
在 Git 中,分支只是指向某个提交的指针,非常轻量:
- 创建分支几乎是瞬间完成
- 切换分支也很快
- 可以创建成千上万个分支
为什么需要分支?
场景 1: 开发新功能
main: A ← B ← C
↑
└─ D ← E (feature/login 分支)
在 feature/login 分支上开发登录功能,不影响 main 分支。
场景 2: 修复 Bug
main: A ← B ← C
↑
└─ D (hotfix/cart-bug 分支)
在 hotfix/cart-bug 分支上修复紧急 bug,修复后立即合并到 main。
场景 3: 实验性开发
main: A ← B ← C
↑
└─ D ← E ← F (experiment/new-ui 分支)
在 experiment/new-ui 分支上尝试新设计。如果不满意,直接删除分支,不影响主代码。
基本命令
查看分支
查看所有分支:
git branch
输出:
* main
feature/login
hotfix/cart-bug
* 表示当前所在的分支
查看远程分支:
git branch -r
查看所有分支(本地+远程):
git branch -a
创建分支
创建新分支:
git branch 分支名
例如:
git branch feature/search
这会创建一个新分支,但不会切换到新分支。
切换分支
切换到指定分支:
git checkout 分支名
例如:
git checkout feature/search
新版本 Git (2.23+) 推荐使用:
git switch 分支名
创建并切换
一步到位:
git checkout -b 分支名
或者:
git switch -c 分支名
例如:
git checkout -b feature/search
# 等同于:
# git branch feature/search
# git checkout feature/search
删除分支
删除已合并的分支:
git branch -d 分支名
强制删除(包括未合并的):
git branch -D 分支名
完整实战演练
让我们通过一个完整的例子学习分支的使用。
初始状态
# 查看当前分支
$ git branch
* main
# 查看提交历史
$ git log --oneline
a1b2c3 初始提交
场景: 开发搜索功能
1. 创建功能分支
git checkout -b feature/search
输出:
Switched to a new branch 'feature/search'
2. 在新分支上工作
# 创建搜索功能文件
echo "function search() { ... }" > search.js
# 添加并提交
git add search.js
git commit -m "添加搜索功能的基本结构"
3. 继续开发
# 修改搜索功能
echo "// 改进搜索算法" >> search.js
git add search.js
git commit -m "优化搜索算法"
现在分支历史:
main: A
↑
└─ B ← C (feature/search)
- A: 初始提交
- B: 添加搜索功能的基本结构
- C: 优化搜索算法
4. 切换回 main 分支
git checkout main
你会发现 search.js 文件消失了! 不用担心,它还在 feature/search 分支里。
5. 查看不同分支的文件
# 在 main 分支
$ ls
index.html style.css
# 切换到 feature/search 分支
$ git checkout feature/search
$ ls
index.html style.css search.js
场景: 紧急修复 Bug
现在 main 分支发现了一个 bug,需要紧急修复。
1. 从 main 创建 hotfix 分支
git checkout main
git checkout -b hotfix/login-bug
2. 修复 Bug
# 修复 bug
echo "// 修复登录验证" >> index.html
git add index.html
git commit -m "修复登录验证 bug"
现在分支结构:
D (hotfix/login-bug)
↗
main: A
↖
B ← C (feature/search)
合并分支
当你在分支上完成工作,需要将代码合并回主分支。
基本合并流程
1. 切换到目标分支
git checkout main
2. 合并其他分支
git merge 要合并的分支名
实战: 合并 hotfix 分支
# 1. 切换到 main
git checkout main
# 2. 合并 hotfix
git merge hotfix/login-bug
输出:
Updating a1b2c3..d4e5f6
Fast-forward
index.html | 1 +
1 file changed, 1 insertion(+)
Fast-forward 合并: 因为 main 分支没有新的提交,Git 只是把指针向前移动。
3. 删除已合并的分支
git branch -d hotfix/login-bug
现在分支结构:
main: A ← D
↖
B ← C (feature/search)
实战: 合并 feature 分支
# 1. 切换到 main
git checkout main
# 2. 合并 feature
git merge feature/search
这次可能会看到:
Merge made by the 'recursive' strategy.
search.js | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 search.js
这是三方合并,因为两个分支都有新的提交,Git 创建了一个新的合并提交。
最终结构:
main: A ← D ← ─┐
↖ M (合并提交)
B ← C ─┘
合并冲突
当两个分支修改了同一个文件的同一部分,Git 无法自动合并,就会产生冲突。
制造一个冲突
1. 在 main 分支修改
git checkout main
echo "Version: 1.0" > version.txt
git add version.txt
git commit -m "添加版本号 1.0"
2. 在另一个分支修改同一行
git checkout -b feature/update-version
echo "Version: 2.0" > version.txt
git add version.txt
git commit -m "更新版本号到 2.0"
3. 尝试合并
git checkout main
git merge feature/update-version
输出:
Auto-merging version.txt
CONFLICT (content): Merge conflict in version.txt
Automatic merge failed; fix conflicts and then commit the result.
解决冲突
1. 查看冲突文件
$ cat version.txt
<<<<<<< HEAD
Version: 1.0
=======
Version: 2.0
>>>>>>> feature/update-version
解释:
<<<<<<< HEAD: 当前分支(main)的内容=======: 分隔符>>>>>>> feature/update-version: 要合并的分支的内容
2. 手动编辑文件
选择保留哪个版本,或者合并两者:
Version: 2.0
删除冲突标记,保存文件。
3. 标记为已解决
git add version.txt
4. 完成合并
git commit -m "合并 feature/update-version 分支,采用版本 2.0"
分支命名规范
好的命名让团队协作更高效:
常用前缀
-
feature/- 新功能feature/user-loginfeature/shopping-cart
-
bugfix/或fix/- Bug 修复bugfix/login-errorfix/payment-issue
-
hotfix/- 紧急修复hotfix/security-patch
-
refactor/- 重构refactor/database-layer
-
docs/- 文档docs/api-documentation
-
test/- 测试test/unit-tests
命名示例
✅ 好的命名:
feature/add-payment-gateway
bugfix/fix-cart-calculation
hotfix/patch-security-vulnerability
❌ 不好的命名:
my-branch
test
new-feature
fix-bug
分支策略
Git Flow
经典的分支管理模型:
main ─●─────●───────●─→ (生产环境)
↑ ↑ ↑
develop ─●─●─●─●─●─●─●─●─→ (开发环境)
↓ ↑ ↓ ↑
feature ──●───●───●───●──→ (功能开发)
main: 生产环境,只有稳定版本develop: 开发分支,集成所有功能feature: 功能分支,从 develop 分出
GitHub Flow
更简单的模型:
main ─●────●────●─→
↓ ↑
feature ──●────●────→
main: 永远可部署feature: 所有开发都在功能分支- 通过 Pull Request 合并
实用技巧
1. 查看分支图
git log --graph --oneline --all
输出:
* d4e5f6 (HEAD -> main) 合并功能分支
|\
| * c3d4e5 (feature/search) 优化搜索算法
| * b2c3d4 添加搜索功能
|/
* a1b2c3 初始提交
2. 比较分支差异
git diff main feature/search
3. 查看分支最后一次提交
git branch -v
输出:
* main d4e5f6 合并功能分支
feature/search c3d4e5 优化搜索算法
4. 重命名分支
git branch -m 旧名称 新名称
或者重命名当前分支:
git branch -m 新名称
常见问题
Q1: 切换分支时有未提交的修改怎么办?
方案 1: 提交修改
git add .
git commit -m "临时保存"
方案 2: 暂存修改(下节课学习)
git stash
git checkout 其他分支
# 工作完成后
git checkout 原分支
git stash pop
Q2: 误删了分支怎么办?
如果还记得提交的哈希值:
git checkout -b 分支名 哈希值
Q3: 如何撤销合并?
git reset --hard HEAD~1
⚠️ 警告: 这会丢失合并提交!
练习题
练习 1: 创建和切换分支
- 创建一个新分支
feature/about-page - 切换到这个分支
- 创建一个文件
about.html - 提交这个文件
- 切换回 main 分支
- 确认
about.html不存在
练习 2: 合并分支
- 在 main 分支合并
feature/about-page - 查看文件确认合并成功
- 删除
feature/about-page分支
练习 3: 解决冲突
- 在 main 分支创建并提交
config.txt - 创建新分支
feature/config-update - 在两个分支分别修改
config.txt的同一行 - 尝试合并,解决冲突
小结
今天我们学习了 Git 分支的核心内容:
-
分支基础
git branch- 查看分支git branch 名称- 创建分支git checkout 名称- 切换分支git checkout -b 名称- 创建并切换
-
合并分支
git merge 分支名- 合并分支- Fast-forward 合并 vs 三方合并
- 解决合并冲突
-
分支管理
- 删除分支
git branch -d - 查看分支历史
git log --graph - 分支命名规范
- 删除分支
分支让你可以:
- 并行开发多个功能
- 安全地尝试新想法
- 隔离 bug 修复
- 与团队高效协作
下一步
现在你已经掌握了分支管理,接下来学习:
继续努力! 🎉