Git 分支管理

前言: 本文将简单介绍一下Git的分支管理

1. 为什么需要分支

在 Git 中,每一次提交都会生成一个新的提交对象,提交之间通过父子关系串成一条历史线。我们平时说的"分支",本质上就是指向某个提交的可移动指针。

设想你身处于一个洪荒背景的村庄, 打算参加一场村内演武比赛从而迎娶村长女儿, 你和你的对手处于竞争关系且初始实力相近,为了获胜,你决心苦练一门武功, 但是藏经阁内武功共享且学习能力相近. 为了成功迎娶村长女儿, 你该如何抉择?

但是如果你偶见间坠崖获生, 偶然间学会了一气化三清, 你就可以进行分身操作, 这个分身就是分支, 分身从创建时刻会继承创建人的知识以及记忆,这是你就可以让分身去另外学一门武功,到时候收回分身,定要打得对方一个落花流水口呀~~

而GIT就可以起到创建这样一个和"分身"类似的分支,那分支有什么功能呢?

分支最直接的价值是隔离工作:

  • 开发新功能时,可以在自己的分支上频繁提交,不影响主分支的稳定性。
  • 修复 bug 时,可以从稳定分支临时拉出一个修复分支,修完再合并回去。
  • 尝试实验性代码时,可以大胆修改;如果方案废弃,直接删除分支即可。

如果没有分支,试想一下你的老板突然要求为项目追加一个新功能, 如果项目已经上线了, 直接在主分支上操作的话, 一个未完成的新功能可能会污染主分支;如果迟迟不提交,又有丢失进度的风险。分支刚好解决了这两个问题:既能保存开发过程,又不影响别人或主线代码。

2. HEAD、master/main 与分支指针

理解 Git 分支,关键是理解三个概念:

  • commit:一次提交,代表仓库在某一时刻的快照。
  • 分支名:例如 master、main、dev,本质是一个指向 commit 的指针。
  • HEAD:指向"当前所在分支"的指针。

讲义中使用的是 master 作为主分支名。现在很多新仓库默认主分支名是 main,但原理完全一致。

可以通过下面的文件观察 Git 内部状态:

bash 复制代码
cat .git/HEAD
cat .git/refs/heads/master

如果 .git/HEAD 内容类似:

text 复制代码
ref: refs/heads/master

说明当前 HEAD 指向 master 分支。每次在当前分支提交后,当前分支指针都会向前移动到最新提交。

3. 创建、查看与切换分支

查看本地分支

bash 复制代码
git branch

输出中带 * 的分支表示当前所在分支:

text 复制代码
  dev
* master

创建分支

bash 复制代码
git branch dev

这会创建一个名为 dev 的分支。刚创建时,dev 和当前分支通常指向同一个提交。

需要注意:git branch dev 只创建分支,不会自动切换过去。

切换分支

bash 复制代码
git checkout dev

现代 Git 也可以使用语义更清晰的写法:

bash 复制代码
git switch dev

切换分支后,HEAD 会改为指向新分支,工作区文件也会切换成该分支对应提交的状态。

创建并切换分支

常用快捷命令:

bash 复制代码
git checkout -b dev1

等价于:

bash 复制代码
git branch dev1
git checkout dev1

现代写法是:

bash 复制代码
git switch -c dev1

4. 在分支上开发并提交

切换到 dev 分支后,可以正常修改、暂存、提交:

bash 复制代码
git checkout dev
vim ReadMe
git add .
git commit -m "modify ReadMe"

此时新的提交只属于 dev 分支。切回 master 后,可能会发现刚才修改的内容"不见了",这是正常现象。

原因是:

  • 在 dev 上提交后,dev 指针向前移动。
  • master 指针还停留在原来的提交。
  • 切回 master 时,工作区会恢复到 master 所指向的版本。

这正是分支隔离的效果。

5. 合并分支

如果希望主分支获得 dev 上的修改,需要把 dev 合并到当前分支。就像想要提高本体战力,赢得比武大赛, 最终也要把化三清的分身回收, 共享功法

一般先切回目标分支,再执行合并:

bash 复制代码
git checkout master
git merge dev

git merge dev 的意思是:把 dev 分支的修改合并到当前分支。

如果 master 从创建 dev 后没有产生新提交,Git 通常会执行 Fast-forward 合并。所谓快进合并,就是直接把 master 指针移动到 dev 当前指向的提交上。

快进合并的优点是简单、快速;缺点是历史记录中看不出曾经发生过一次分支合并。

6. 删除分支

当功能分支已经合并完成后,可以删除它:

bash 复制代码
git branch -d dev

不能删除当前所在分支,所以删除前通常要先切回其他分支:

bash 复制代码
git checkout master
git branch -d dev

-d 是安全删除:如果该分支还有未合并的提交,Git 会拒绝删除,防止误删工作成果。

7. 合并冲突

实际开发中,两个分支可能修改了同一个文件的同一部分。例如:

  • dev1 把某一行改成 bbb
  • master 把同一行改成 ccc

这时执行:

bash 复制代码
git merge dev1

Git 无法判断应该保留哪一份修改,就会产生冲突:

text 复制代码
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.

可以用 git status 查看冲突文件:

bash 复制代码
git status

冲突文件中会出现类似标记:

text 复制代码
<<<<<<< HEAD
当前分支的内容
=======
被合并分支的内容
>>>>>>> dev1

解决冲突的标准流程是:

  1. 打开冲突文件,手动编辑成最终想要的结果。
  2. 删除 <<<<<<<、=======、>>>>>>> 这些冲突标记。
  3. 重新暂存文件。
  4. 提交一次合并结果。

对应命令:

bash 复制代码
vim ReadMe
git add .
git commit -m "merge ReadMe"

这里的最后一次提交很重要。冲突解决不是只改文件就结束,必须提交,Git 才会认为这次合并完成。

可以用下面的命令查看分支合并历史:

bash 复制代码
git log --graph --pretty=oneline --abbrev-commit

8. Fast-forward 与 --no-ff 合并策略

默认情况下,只要条件允许,Git 会使用 Fast-forward 模式合并。

例如:

bash 复制代码
git checkout master
git merge dev

如果 master 没有分叉,Git 只是把 master 指针移动到 dev 的最新提交上。这样历史很简洁,但删除 dev 后,从日志里不容易看出这个提交曾经来自一个独立分支。

这该如何 理解呢? 最开始我也有这样的困惑, 既然都创建出了dev分支,那么master 不是一定会分叉吗, 使用快进合并为什么会看不出来提交的来源呢?

其实这里我们要弄清楚一点,我们创建出一个dev分支这个操作,虽然在现实里我们可能会将其理解为从一个树干上产生分支 ,但是实际上只是创建了一个dev标签,当我们创建出dev分支切换到dev中,进行了一系列修改,add. commit 操作之后. 再回到master分支, 由于master分支在此期间没有任何修改操作, 以上在dev分支上的操作就像是和master分支在同一直线之上,并未产生分叉这样的场景, 既然是dev和master都位于同一直线之上, 即使我们在master主分支上进行了merge 合并操作, 就像是把一条直线上的dev这个节点给抹除掉, 虽然master会新增一些从dev中合并得到的内容,但是master无法得知是从哪合并过来的

以上情况是在合并前,master 没有修改操作时,使用的默认快进合并, 但是如果master有commit操作呢 ,那基于master的commit,会有两种情况产生

    1. master修改的文件和dev中修改文件不一致, 则在分支树就就像是master在不同的方向延伸了一个树枝,最后在merge合并时,会自动把这两个不同修改杂糅在一块,dev重新汇拢到master上
    1. master 修改的文件和dev中相同,则会发生冲突, 具体表现就是出现上文图片中的的==== , <<<< ,>>>>这样的符号,需要我们手动处理冲突

如果希望保留"发生过一次合并"的历史,可以禁用快进模式:

bash 复制代码
git merge --no-ff -m "merge with no-ff" dev

--no-ff 会强制生成一个新的 merge commit。就像是强行留痕. 这样做的好处是分支脉络更清楚,适合团队协作和需要保留功能开发痕迹的项目。

简单对比:

合并方式 特点 适合场景
Fast-forward 历史线性、简洁 小改动、个人开发、临时分支
--no-ff 保留合并节点,能看出分支历史 团队协作、功能分支、发布前合并

9. 常见分支策略

一种常见的分支管理方式是:

  • master 或 main:稳定分支,只放可发布版本。
  • dev:开发主线,日常开发结果先合并到这里。
  • feature/*:功能分支,用来开发具体需求。
  • fix/* 或 bugfix/*:修复分支,用来处理线上或主分支 bug。

典型流程:

bash 复制代码
# 从 dev 拉出功能分支
git checkout dev
git checkout -b feature-login

# 开发并提交
git add .
git commit -m "add login feature"

# 回到 dev 合并功能
git checkout dev
git merge --no-ff -m "merge feature-login" feature-login

# 删除功能分支
git branch -d feature-login

主分支应该尽量保持稳定,不建议把日常半成品直接提交到主分支。

10. 使用 stash 临时保存工作现场

开发中经常遇到一种情况:当前功能写到一半,还不能提交,但突然需要切换分支去修 bug。

如果工作区有未提交修改,直接切换分支可能会失败,或者把半成品带到另一个分支中。此时可以使用 git stash 临时保存工作现场。

bash 复制代码
git stash

执行后,当前工作区会变干净:

bash 复制代码
git status

然后就可以切换到主分支,创建修复分支:

bash 复制代码
git checkout master
git checkout -b fix_bug

修复完成后合并回主分支:

bash 复制代码
git add .
git commit -m "fix bug"

git checkout master
git merge --no-ff -m "merge fix_bug branch" fix_bug
git branch -d fix_bug

回到原来的开发分支后,可以查看 stash 列表:

bash 复制代码
git stash list

恢复现场并删除 stash:

bash 复制代码
git stash pop

如果只想恢复但保留 stash 记录,可以用:

bash 复制代码
git stash apply

之后再手动删除:

bash 复制代码
git stash drop

多个 stash 可以指定恢复:

bash 复制代码
git stash apply stash@{0}

11. 先在开发分支合并主分支,降低主分支风险

当 master 修复了 bug,而 dev 还在继续开发时,dev 可能看不到 master 上的新修复。

最终当然可以让 master 直接合并 dev,但如果冲突很复杂,就会在主分支上解决冲突,风险较高。

更稳妥的做法是:先在自己的开发分支上合并主分支,把冲突解决并测试通过,再让主分支合并开发分支。

流程如下:

bash 复制代码
# 在开发分支上吸收 master 的最新修改
git checkout dev2
git merge master

# 如果有冲突,先在 dev2 上解决并提交
git add .
git commit -m "merge master"

# 测试通过后,再回到 master 合并 dev2
git checkout master
git merge dev2

这样即使冲突解决过程出错,也主要影响开发分支,不会直接污染稳定主分支。

12. 强制删除未合并分支

如果某个功能分支已经开发了一部分,但需求被取消了,这个分支可能没有合并回主分支。

此时使用安全删除:

bash 复制代码
git branch -d dev3

Git 会提示该分支尚未完全合并,拒绝删除。

如果确认这个分支不再需要,可以强制删除:

bash 复制代码
git branch -D dev3

-D 要谨慎使用,因为它会丢弃这个分支上尚未合并的提交引用。除非确认代码不要了,否则优先使用 -d。

13. 分支管理命令速查

目标 命令
查看本地分支 git branch
创建分支 git branch dev
切换分支 git checkout dev / git switch dev
创建并切换分支 git checkout -b dev / git switch -c dev
合并分支到当前分支 git merge dev
禁用快进合并 git merge --no-ff -m "message" dev
安全删除分支 git branch -d dev
强制删除分支 git branch -D dev
查看状态 git status
查看图形化提交历史 git log --graph --pretty=oneline --abbrev-commit
暂存工作现场 git stash
查看 stash git stash list
恢复并删除 stash git stash pop
恢复但保留 stash git stash apply
删除 stash git stash drop

14. 一个推荐的日常工作流

个人或小团队可以先掌握下面这套流程:

bash 复制代码
# 1. 从开发分支创建功能分支
git checkout dev
git checkout -b feature-demo

# 2. 在功能分支上开发
git add .
git commit -m "add demo feature"

# 3. 开发过程中同步 dev 的最新变化
git checkout feature-demo
git merge dev

# 4. 解决冲突并测试通过后,合并回 dev
git checkout dev
git merge --no-ff -m "merge feature-demo" feature-demo

# 5. 删除功能分支
git branch -d feature-demo

如果中途要临时修主分支 bug:

bash 复制代码
git stash
git checkout master
git checkout -b fix-bug

# 修复并提交
git add .
git commit -m "fix bug"

git checkout master
git merge --no-ff -m "merge fix-bug" fix-bug
git branch -d fix-bug

# 回到原开发分支继续工作
git checkout feature-demo
git stash pop

15. 小结

Git 分支管理的核心不是背命令,而是理解"分支是指针,HEAD 指向当前分支"这个模型。

创建分支,就是新建一个指针;切换分支,就是让 HEAD 指向另一个分支;提交时,当前分支指针向前移动;合并时,Git 尝试把另一条提交线整合到当前分支。

实际开发中需要重点掌握:

  • 用分支隔离新功能和实验代码。
  • 合并前确认自己在哪个分支上。
  • 遇到冲突时,手动解决后必须重新提交。
  • --no-ff 可以保留分支合并历史。
  • git stash 适合临时保存未完成工作。
  • 删除分支优先用 -d,确认废弃后才用 -D。

一句话概括:分支让 Git 不只是"保存历史",还可以"组织开发过程"。掌握分支管理后,Git 才真正成为团队协作和复杂项目开发中的高效工具。

相关推荐
AC赳赳老秦10 小时前
OpenClaw 与 FineBI 联动方案:公开数据自动采集与实时业务分析看板实践
大数据·开发语言·python·php·finebi·deepseek·openclaw
计算机毕业设计杰瑞10 小时前
【2027最新原创大数据】基于大数据的无人机自主导航数据分析与可视化,附源码_数据可视化_数据分析_数据挖掘_Hadoop_spark_文档指导_毕设指导
大数据·信息可视化·数据挖掘·课程设计
卷毛迷你猪10 小时前
快速实验篇(B12)异常流量与刷单识别(方法论演示)
大数据·hive·hadoop·数据挖掘·聚类
龙亘川10 小时前
探索智慧文化服务:建设初衷、整体架构、技术支撑、发展现状与实践影响
大数据·数据库·架构
计算机毕业编程指导师10 小时前
【Python毕设选题推荐】基于Hadoop+Django的奥斯卡奖获奖数据可视化分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·毕业设计·课程设计·奥斯卡奖
计算机毕业编程指导师11 小时前
【大数据毕设选题】基于Spark的电信网络诈骗话术语义特征挖掘分析系统源码 毕业设计 选题推荐 数据分析 机器学习 深度学习
大数据·hadoop·python·spark·毕业设计·课程设计·网络诈骗
计算机毕业编程指导师11 小时前
计算机大数据毕设怎么选?基于Spark的个体肥胖健康风险评估的数据分析与可视化系统带你通关 源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·spark·毕业设计·肥胖风险
shjita11 小时前
几个hadoop中运行mapreduce的错误记录一下。
大数据·hadoop·eclipse
奈落2411 小时前
【RAG 深度修炼】专栏 · 第 9 期(收官):安全专题与生产 Checklist 总集——从能跑的 Demo 到睡得着觉的生产系统
大数据·网络·人工智能·安全·ai编程
IT研究室11 小时前
最新大数据毕业设计选题推荐-基于大数据的单位招聘岗位信息分析与可视化-大数据-Spark-Hadoop-Bigdata
大数据·spark·课程设计