Git 分支管理实战:从创建到合并的完整指南

Git 分支管理实战:从创建到合并的完整指南

学会了 commit 之后,你掌握了 Git 的"存档"功能。分支则是 Git 的"平行宇宙"功能——在同一个项目里同时推进多条互不干扰的开发线,最后再合并到一起。


为什么需要分支

假设你在做一个网站,现在要加一个用户登录功能。这个功能需要三天时间,期间你要改好几个文件。

如果没有分支,你改了一半的代码就留在工作区里。这时候老板说有个紧急 bug 要修,你怎么办?把登录功能的代码先删掉,修完 bug 再重新写一遍?太痛苦了。

有了分支,你可以新建一个 login 分支,在上面安心做登录功能。修 bug 切回 main 分支,两边互不干扰。做完了再合并回去。这就是分支的日常价值。

Git 的分支实现得非常高效——创建一个分支只是创建一个41字节的指针文件,指向某个提交。几乎不占空间,不需要复制任何文件。这也是 Git 和其他版本控制系统(如SVN)最大的区别之一。SVN 的分支需要复制整个目录,又慢又占空间;Git 的分支则是"秒建"。


基本操作

查看当前有哪些分支

git branch

输出中当前分支前面有个星号标记,绿色高亮。

创建新分支

git branch login

这只是在本地创建了一个叫 login 的分支,远程仓库上还没有。

切换到新分支

git checkout login

注意:切换分支前确保当前工作区是干净的(改动都已提交或 stash),否则未提交的改动会被带到新分支上。

创建并切换到新分支(常用,比上面两步快):

git checkout -b login

用新语法(Git 2.23+ 推荐):

git switch -c login

在 login 分支上正常修改、提交,这些操作只影响 login 分支,main 分支的提交历史完全不受影响。这就是"平行宇宙"的含义——两个分支各自独立推进,互不知道对方的存在。

做完了,切回 main 分支

git checkout main

把 login 分支合并进来

git merge login

合并之后,main 分支就有了 login 分支的所有改动。如果合并顺利,Git 会打开编辑器让你写一条合并提交说明,保存退出就完成了。


合并冲突

合并并不总是顺利的。如果 main 分支和 login 分支都改了同一个文件的同一行代码,Git 就不知道该听谁的,这时候会提示"冲突"(CONFLICT)。

打开冲突文件,你会看到这样的标记:

<<<<<<< HEAD
这是 main 分支的内容
=======
这是 login 分支的内容
>>>>>>> login

<<<<<<< HEAD======= 之间是当前分支(main)的内容,=======>>>>>>> login 之间是要合并分支(login)的内容。你需要手动决定保留哪部分,或者把两部分都保留/删掉任意一方。解决方式:

  1. 手动编辑文件,删掉冲突标记,保留你想要的内容
  2. 保存文件
  3. git add 冲突文件
  4. git commit

冲突就解决了。

减少冲突的实用技巧

冲突是 Git 里最让人头疼的部分。但仔细想想,冲突其实是好事——它说明 Git 发现了潜在的问题,让你自己决定而不是随便选一个。减少冲突的几个技巧:

  • 频繁合并:如果你一周才合并一次,积累的改动多,冲突概率就高。每天或每半天从 main 拉一次最新代码,冲突小步解决比集中大爆发容易处理
  • 分工明确:团队内避免多个人同时修改同一个文件的同一区域
  • 善用 rebase:在提交 PR 前先 git rebase main,把 main 的最新改动提前消化掉
  • 用 mergetool:如果冲突很复杂,可以用可视化合并工具(如 VSCode 自带的对比界面、Beyond Compare 等),比纯文本标记直观得多

merge vs rebase

合并分支有两种主要方式,merge 和 rebase,它们代表了两种不同的历史哲学。

merge 是保留完整的历史记录。它创建一个新的"合并提交"来连接两条分支线。优点:历史真实,保持了代码实际发展的时间线。缺点:如果分支很多,历史图中会有大量交叉的合并线,看起来很复杂。

main:    A -- B -- M (merge commit)
              \   /
login:        C -- D

rebase 是把你当前分支的提交"移植"到目标分支的最新提交之后。优点:最终历史是一条直线,非常干净、易读。缺点:改写了提交历史(重新计算了提交ID),在公共分支上 rebase 可能导致其他人的工作基础对不上。

main:    A -- B
                \
login:          C' -- D' (C和D被"重播"到B之后)

黄金法则:自己的开发分支用 rebase 保持干净,合并到 main 分支用 merge 保留清晰的合并记录。永远不要在公共分支(main、develop)上执行 rebase——那会让所有基于这些提交工作的人的历史记录全部错位。

rebase 操作示例

# 假设你在 login 分支,main 分支有了新提交
git checkout login
git rebase main

这会把 login 分支上的提交逐个"重播"到 main 最新提交的后面。如果在重播某个提交时遇到冲突,解决后 git rebase --continue 继续即可。如果中途想放弃,git rebase --abort 回到操作前的状态。

交互式 rebase 还可以在重播过程中修改、合并、重排、删除提交——这在整理零散提交后用。


删除分支

合并完之后,login 分支就没用了,删掉它:

git branch -d login

-d 是安全删除——如果分支还没合并(改动还没被纳入 main),Git 会提醒你并拒绝删除。如果想强制删除(确定不要了),用 -D

git branch -D login

删除本地分支后,如果远程仓库上有同名分支,也需要手动删除:

git push origin --delete login

养成及时清理已合并分支的习惯,否则分支列表会越来越长。一个实用的工作流是:完成一个功能的合并后立刻删掉对应分支。


实际开发中的分支策略

实际项目中,一般不是随便建分支,而是有一套命名和管理规则。

最简单的策略(适合个人或两人小项目)

  • main 分支永远是稳定的,可随时部署到生产环境
  • 开发新功能就建 feature/功能名 分支,做完合并回 main 并删掉
  • 修 bug 就建 hotfix/问题描述 分支,修完合并回 main 并删掉

Git Flow(适合项目版本节奏明确的中大型团队)

main(生产环境)
  └── develop(每日开发基线)
        ├── feature/*(功能开发)
        ├── release/*(发版准备)
        └── hotfix/*(线上紧急修复)
  • main:生产环境代码,只接受来自 release 或 hotfix 的合并
  • develop:每日开发基线,所有功能的起点和终点
  • feature/*:从 develop 出发,做完合并回 develop
  • release/*:从 develop 出发准备发版,只修 bug 不加功能,发版后同时合并到 main 和 develop
  • hotfix/*:从 main 出发修线上 bug,修完合并回 main 和 develop

GitHub Flow(适合持续交付的敏捷团队)

比 Git Flow 更简单:

  1. main 分支永远可部署
  2. 新功能从 main 拉出分支
  3. 开发完成后提 PR,经过 code review 后合并到 main

一条核心规则

永远不要直接在 main 分支上改代码。main 分支只接受来自其他分支的合并,不接受直接提交。这样 main 永远是可部署的、稳定的。如果每个人都顺手在 main 上改两行,main 很快就变成了一堆没有经过 review 的草稿代码。


一个实用的 stash 技巧

有时候你正在写代码,突然要切换到另一个分支(比如同事让你帮忙看一个 main 分支的问题),但当前分支的修改还不想提交(因为还没做完、commit 不完整)。

这时候用 git stash:

git stash

它会把当前工作区的改动和暂存区的改动"藏"起来(存到一个栈结构里),工作区恢复到干净状态。你可以放心切到别的分支工作。

切回来之后恢复改动:

git stash pop

改动就回来了——并且从 stash 栈中弹出(pop 弹出,peek 只查看不弹出)。如果你存了多个 stash,用 git stash list 查看列表,git stash apply stash@{2} 恢复特定的那一条。

一个实用的 stash 场景:写了一半功能,突然要紧急修复线上 bug。先 stash 当前工作 → 切 main 分支修 bug → 修完提交 → 切回原分支 → stash pop 恢复。整个过程不超过两分钟,不用担心工序混乱。


最后

分支是 Git 最核心的功能,也是团队协作的基础。理解了分支,你就理解了 Git 设计哲学的一半。

刚开始用分支可能会觉得麻烦,尤其是冲突解决。但用熟了之后你会发现,没有分支根本没法做稍微复杂一点的项目。建议从今天开始,每接触一项新 Git 命令或操作,都先从 git log --oneline --graph --all 查看当前分支的历史图,直观感受每一次操作对分支历史的影响。

一句话总结:分支是平行宇宙,合并是宇宙交汇。用好了平行宇宙,你的开发效率会上一个台阶。