Git 分支管理基础

掌握 Git 分支的创建、切换和合并,学习如何使用分支进行并行开发

⏱️ 20 分钟📊 入门📅 2024/1/3
分支合并工作流

简介

分支 (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-login
    • feature/shopping-cart
  • bugfix/fix/ - Bug 修复

    • bugfix/login-error
    • fix/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: 创建和切换分支

  1. 创建一个新分支 feature/about-page
  2. 切换到这个分支
  3. 创建一个文件 about.html
  4. 提交这个文件
  5. 切换回 main 分支
  6. 确认 about.html 不存在

练习 2: 合并分支

  1. 在 main 分支合并 feature/about-page
  2. 查看文件确认合并成功
  3. 删除 feature/about-page 分支

练习 3: 解决冲突

  1. 在 main 分支创建并提交 config.txt
  2. 创建新分支 feature/config-update
  3. 在两个分支分别修改 config.txt 的同一行
  4. 尝试合并,解决冲突

小结

今天我们学习了 Git 分支的核心内容:

  • 分支基础

    • git branch - 查看分支
    • git branch 名称 - 创建分支
    • git checkout 名称 - 切换分支
    • git checkout -b 名称 - 创建并切换
  • 合并分支

    • git merge 分支名 - 合并分支
    • Fast-forward 合并 vs 三方合并
    • 解决合并冲突
  • 分支管理

    • 删除分支 git branch -d
    • 查看分支历史 git log --graph
    • 分支命名规范

分支让你可以:

  • 并行开发多个功能
  • 安全地尝试新想法
  • 隔离 bug 修复
  • 与团队高效协作

下一步

现在你已经掌握了分支管理,接下来学习:

  1. 远程分支与协作
  2. Git Stash 暂存修改
  3. Rebase vs Merge

继续努力! 🎉

这篇教程有帮助吗?