【Git】--- 分支管理

 Welcome to 9ilk's Code World

       

(๑•́ ₃ •̀๑) 个人主页:       9ilk

(๑•́ ₃ •̀๑) 文章专栏:     Git


   本篇博客我们来介绍Git的一个重要功能之一 ---- 分支。我们将讲解关于分支的各种操作,以及如何帮助我们进行开发。


🏠 理解分支

假设你处于一个平行宇宙,主时间线里你按部就班的学者C++,OS,另一个时间线的里学着Java,到达某一个时间点时两个时空合并,此时相当于你在一段时间掌握的技能增加了,这里平行时空2相当于是在当前分支基础上创建一个新分支,到达某一个时间点,我们再将两个分支合并

head与master

在版本回退里,每次提交,Git都会把他们串成一条时间线,这条时间线可以理解为是一个分支。截止到目前,我们只有一条时间线,在Git里,这个分支叫主分支,即master分支

再来理解一下,HEAD指针严格来说不是指向提交,而是指向mastermaster才是指向提交所以HEAD(默认)指向的是当前分支

每次提交,master分支都会向前移动一步,随着你的不断提交,master分支的线也越来越长,而HEAD只要一直指向master分支即可指向当前分支。通过查看当前的版本库,我们也能清晰的观察:拿到master分支,我们就能通过parent依次拿到该分支下之前的一个个提交。

🏠 创建、切换、合并分支

当我们创建本地仓库时,Git会自动给我们创建master分支,如果我们想查看本地有哪些分支,我们可以使用 git branch 命令

  • * 表示当前正在master分支工作。
  • HEAD不仅可以指向master分支,也可以指向其他分支,其中被HEAD指向的分支就是我们当前的工作分支。

创建分支

git branch + 分支名

创建完一个新的分支之后,我们可以使用git branch验证一下是否创建了新分支:

还可以在.git目录树上验证:

由于我们创建dev分支是基于master分支创建的,所以创建出来之后会指向最近的一次提交:

时间线图如下:

切换分支

我们之前说HEAD所指向分支为当前工作分支,那如何切换当前工作分支呢?我们可以使用命令git checkout + 分支名

git checkout + 分支名

使用git branch操作验证下是否切换成功:

切换后的时间线如图:

合并分支

由于当前dev分支只是刚基于master分支创建,合并没什么意义,我们对dev分支做一次提交

修改ReadMe文件:

两板斧提交:

zhuang@VM-8-14-ubuntu:~/gitcode$ git add ReadMe
zhuang@VM-8-14-ubuntu:~/gitcode$ git commit -m "md ReadMe"
[dev 3165a96] md ReadMe1 file changed, 2 insertions(+), 1 deletion(-)
zhuang@VM-8-14-ubuntu:~/gitcode$ git status
On branch dev
nothing to commit, working tree clean

此时我们切换到master分支观察变化:

此时我们切换到dev分支:

为什么切换到master分支下我们没有观察到变化,而在dev分支上内容还在呢? 

这是因为我们是在dev分支上提交的,而master分支此刻的提交点没有变,即没有在master分支上master进行提交,时间线不会延长,此时状态如图:

当切换到master分支时,HEAD指向了master,此时自然看不到提交。

此时如果我们想让我们之前修改的信息能在master分支上能查看到,此时需要合并两个分支,但是注意master合并dev,需要先切换到master,再合并

git checkout + 要合并到的分支
git merge + 要合并的分支

此时我们就能在master分支上查看到我们之前修改的信息了:

  • Fast-forward表示快进模式(快速提交),直接把master的指向指向dev的最新提交,合并起来很快

合并后的时间线图如下:

合并之后如果我们在master分支下再进行一次提交会发生什么?

合并之后并不是指dev分支等同于master分支了,而是将dev时间线的各个版本与master分支进行合并,往后他们各自还是独立的:

🏠 删除分支

将master分支和dev分支合并完之后,dev的使命基本结束了,此时我们需要把它删除,那怎么删除一个分支呢?

git branch -d + 要删除的分支名

注意:要删除一个分支时,需要先切换到其他分支,否则会报错

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全

🏠 合并冲突

合并分支不是说能随便合并的,合并时也可能出现冲突:

假设master分支上已经有aaa on branch的提交,我们模拟剩下的内容:

(1)在dev分支上提交 ccc on branch

zhuang@VM-8-14-ubuntu:~/gitcode$ git checkout -b dev1
Switched to a new branch 'dev1'

补充选项git checkout的-b选项帮我们完成两件事:先帮我们创建新分支,再切换到新分支上

zhuang@VM-8-14-ubuntu:~/gitcode$ vim ReadMe
zhuang@VM-8-14-ubuntu:~/gitcode$ git add ReadMe
zhuang@VM-8-14-ubuntu:~/gitcode$ git commit -m "bb ReadMe"
[dev1 700c7b6] bb ReadMe1 file changed, 1 insertion(+), 1 deletion(-)

(2)在master分支上提交ccc on branch

zhuang@VM-8-14-ubuntu:~/gitcode$ git checkout master
Switched to branch 'master'
zhuang@VM-8-14-ubuntu:~/gitcode$ vim ReadMe
zhuang@VM-8-14-ubuntu:~/gitcode$ git add ReadMe
zhuang@VM-8-14-ubuntu:~/gitcode$ git commit -m "cc ReadMe"
[master a5c1371] cc ReadMe1 file changed, 1 insertion(+), 1 deletion(-)

(3)合并分支

我们打开ReadMe文件查看冲突内容,Git会用<<<<<<<,=======, >>>>>>>来标记出不同分支的冲突内容:

此时我们需要自己决策,手动调整冲突代码,并需要再次提交修正后的结果!

此时的时间线图如下:

如果我们想查看分支的合并情况,也可以使用git log命令带上 --graph  --abrev-commit选项

🏠 合并模式

Fast-forward 模式

这里我们创建新分支dev2,提交一次之后与master分支进行合并,我们git log看看结果:

在这种Fast forward模式下,删除分支之后,查看分支历史时,会丢掉分支信息,看不出来最新提交到底时merge进来的还是正常提交的。

no-ff模式

在合并冲突部分,我们也看到通过解决冲突问题,会再进⾏⼀次新的提交,得到的最终状态为:

那么这就不是 Fast forward 模式了,而是no-ff模式,这样的好处是,从分⽀历史上就可以看出分⽀信息。例如我们现在已经删除了在合并冲突部分创建的 dev1 分⽀,但依旧能看到master其实是由其他分⽀合并得到。

Git⽀持我们强制禁⽤ Fast forward 模式(带上--no-ff选项),那么就会在merge时⽣成⼀个新的 commit ,这样,从分⽀历史上就可以看出分⽀信息:

在dev2分支上提交:

使用no-ff模式,此时需要一次新的提交,需要带上-m选项:

用git log查看:

此时时间线图如下:

🏠 分支策略

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布
时,再把dev分支合并到master上,在master分支发布1.0版本;(类似王者荣耀更新版本);你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。所以,团队合作的分支看起来就像这样:

🏠 Bug分支

线上环境不是百分百稳定,master主分支也可能有bug,我们应该单独创建一个专门修复master分支bug的分支再合并,不能直接在master分支上修改bug有可能改出一个更大bug

我们要模拟的场景如下:

(1)dev2分支正在开发(I am coding)

(2) 暂存dev2分支工作区内容

由于dev2分支开发时只是对工作区进行修改并未提交所以会影响master,此时我们可以使用git stash命令先将工作区内容暂存起来

此时我们发现在.git目录下多了个stash分区:

注意 git stash命令只能存储之前被追踪管理过的文件内容

(3) 创建bug分支修改分支

假设bug为:

创建fix_bug分支修改bug提交之后然后与master分支合并:

(4) 修复完bug切回dev2分支继续开发

git stash list展示stash里存了什么

git stash pop将stash内容放出来

我们将内容恢复然后在dev2分支上进行提交

此时我们注意到,bug修复的内容在dev2分支上没有显示,这是因为master分支目前最新的提交,是要领先于新建dev2时基于的master分支的提交的。

我们最终目的是让master合并dev2分支,但是这样是有风险的,这是因为在合并分支时可能会有冲突,而代码冲突需要我们手动解决(在master分支上解决),我们无法保证对于冲突问题可以正确地一次性解决,实际开发中,代码冲突不只一行两行那么简单,解决过程出错难免,导致错误的代码合并到master分支上。此时状态为:

解决这个问题的一个好的建议就是:最好在自己的分支上(dev2)合并下master,再让master去合并dev2,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响master。此时的状态为:

演示:

dev2合并master

再将dev2合并到master

最后删除fix_bug和dev2

zhuang@VM-8-14-ubuntu:~/gitcode$ git branchdev2fix_bug
* master
zhuang@VM-8-14-ubuntu:~/gitcode$ git branch -d dev2 fix_bug
Deleted branch dev2 (was 1714a31).
Deleted branch fix_bug (was dffd15d).

🏠 强制删除分支

我们之前git branch -d删除分支的前提是merge,git认为只要你创建分支不能随便删,此时我们确定该分支可以删,只需改选项-D表示强行删除

git branch -D 分支名


总结分支相关操作:

1. 创建分支 : git branch

2. 切换分支 : git checout 

3. 创建 + 切换分支 : git checkout -b 

4. 合并分支 : git merge 

5. 删除分支 : git branch -d 

6. 查看分支情况 : git log --graph  --abrev-commit

7. no-ff模式合并 : git merge --no-ff -m "message" 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

纯血鸿蒙:中国操作系统自主创新的里程碑

引言&#xff1a;破局者登场 2024 年 10 月&#xff0c;搭载纯血鸿蒙操作系统&#xff08;HarmonyOS NEXT&#xff09;的华为 Mate 70 系列正式发布&#xff0c;首日预约量突破 330 万。这场现象级热度的背后&#xff0c;不仅是消费者对硬件创新的期待&#xff0c;更是中国科技…

二造考试的备考过程中如何保持良好的心态?

在二级造价师考试的备考过程中&#xff0c;保持良好的心态至关重要&#xff0c;以下是一些有效的方法&#xff1a; 树立正确的考试观念 )认识到二级造价师考试是职业生涯中的一个重要环节&#xff0c;但不是唯一的决定因素。把它看作是提升自己专业能力、丰富知识储备的机会&am…

Vue3前端开发:组件化设计与状态管理

Vue3前端开发&#xff1a;组件化设计与状态管理 一、Vue3组件化设计 组件基本概念与特点 是一款流行的JavaScript框架&#xff0c;它支持组件化设计&#xff0c;这意味着我们可以将页面分解成多个独立的组件&#xff0c;每个组件负责一部分功能&#xff0c;通过组件的嵌套和复用…

动手学深度学习11.9. Adadelta-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;72 优化算法【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&#xff1a;11.9. Adadelta —…

Android Audio基础(13)——audiomixer

在 Android 平台上&#xff0c;音频混合器 AudioMixer 主要用在 AudioFlinger 里&#xff0c;将多路音频源数据混音&#xff08;包括混音、音量处理、重采样及处理声道等&#xff09;。位于 framework 的音频处理模库 libaudioprocessing&#xff08;frameworks/av/media/libau…

【React】使用Swiper报错`Swiper` needs at least one child

问题 聊天页面的表情面板&#xff0c;滑动效果使用了ant design mobile的Swiper。 原代码中&#xff0c;Swiper 组件在 isShow 为 false 时渲染的是 <></>&#xff08;空元素&#xff09;&#xff0c;控制台警告Swiper needs at least one child&#xff0c;Swip…

Matlab教程001:软件介绍和界面使用

1.1 软件介绍 1.1.1 Matlab的介绍 MATLAB&#xff08;MATrix LABoratory&#xff09;是一款由 MathWorks 公司开发的高级编程语言和交互式环境&#xff0c;广泛用于 科学计算、数据分析、机器学习、工程建模、仿真和信号处理 等领域。 1.1.2 主要应用领域 数据分析与可视化…

蓝桥杯算法实战分享:算法进阶之路与实战技巧

引言 蓝桥杯作为国内极具影响力的程序设计竞赛&#xff0c;为众多编程爱好者和专业人才提供了展示自我的舞台。参与蓝桥杯不仅能检验自身编程水平&#xff0c;还能拓宽技术视野&#xff0c;为未来职业发展积累宝贵经验。本文将结合历年真题与参赛经验&#xff0c;全面分享蓝桥…

Android Compose 层叠布局(ZStack、Surface)源码深度剖析(十三)

Android Compose 层叠布局&#xff08;ZStack、Surface&#xff09;源码深度剖析 一、引言 在 Android 应用开发领域&#xff0c;用户界面&#xff08;UI&#xff09;的设计与实现一直是至关重要的环节。随着技术的不断演进&#xff0c;Android Compose 作为一种全新的声明式…

MongoDB 面试备战指南

MongoDB 面试备战指南 一、基础概念 1. MongoDB是什么类型的数据库&#xff1f;和关系型数据库有什么区别&#xff1f; 答案&#xff1a; MongoDB是文档型NoSQL数据库&#xff0c;核心区别&#xff1a; 数据模型&#xff1a;存储JSON-like文档&#xff08;动态schema&#xf…

毫米波雷达标定(2)

1. 前言 前面文章中介绍了产线上毫米波雷达的标定原理和流程,这篇文章则主要介绍其在线标定方法。相对于产线标定,在线标定具备使用自然场景而不是依赖特定标靶的优点,但因此其标定精度会相对差一点。在线标定一般应用于售出产品的维护场景,如果其标定结果精度可以满足使用…

Linux fority source和__builtin_xxx

这段代码是用于启用和配置 GCC/Clang 的 Fortify Source 安全机制的预处理指令。Fortify Source 主要用于在编译时增强对缓冲区溢出等内存安全问题的检查。以下是对每一部分的详细解释&#xff1a; 1. 最外层条件编译 # if CONFIG_FORTIFY_SOURCE > 0目的&#xff1a;检查…

SQL GROUP BY 自定义排序规则

在 SQL 中&#xff0c;GROUP BY 子句用于将结果集按一个或多个列进行分组。默认情况下&#xff0c;GROUP BY 会按照列的自然顺序&#xff08;如字母顺序或数字顺序&#xff09;进行排序。如果你需要按照自定义的排序规则对结果进行分组&#xff0c;可以使用 ORDER BY 子句结合 …

语言模型理论基础-持续更新-思路清晰

1.预训练 相似的任务A、B&#xff0c;任务A已经用大数据完成了训练&#xff0c;得到模型A。 我们利用-特征提取模型的-“浅层参数通用”的特性&#xff0c;使用模型A的浅层参数&#xff0c;其他参数再通过任务B去训练&#xff08;微调&#xff09;。 2.统计语言模型 通过条件…

ResNet与注意力机制:深度学习中的强强联合

引言 在深度学习领域&#xff0c;卷积神经网络&#xff08;CNN&#xff09;一直是图像处理任务的主流架构。然而&#xff0c;随着网络深度的增加&#xff0c;梯度消失和梯度爆炸问题逐渐显现&#xff0c;限制了网络的性能。为了解决这一问题&#xff0c;ResNet&#xff08;残差…

【C++】——C++11新特性

目录 前言 1.初始化列表 2.std::initializer_list 3.auto 4.decltype 5.nullptr 6.左值引用和右值引用 6.1右值引用的真面目 6.2左值引用和右值引用比较 6.3右值引用的意义 6.3.1移动构造 6.4万能引用 6.5完美转发——forward 结语 前言 C&#xff0c;这门在系统…

【C++网络编程】第5篇:UDP与广播通信

一、UDP协议核心特性 1. UDP vs TCP ​特性 ​UDP​TCP连接方式无连接面向连接&#xff08;三次握手&#xff09;可靠性不保证数据到达或顺序可靠传输&#xff08;超时重传、顺序控制&#xff09;传输效率低延迟&#xff0c;高吞吐相对较低&#xff08;因握手和确认机制&…

MOSN(Modular Open Smart Network)是一款主要使用 Go 语言开发的云原生网络代理平台

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFABoot-00-sofaboot 概览 SOFABoot-01-蚂蚁金服开源的 s…

微信小程序日常开发问题整理

微信小程序日常开发问题整理 1 切换渲染模式1.1 WebView 的链接在模拟器可以打开&#xff0c;手机上无法打开。 1 切换渲染模式 1.1 WebView 的链接在模拟器可以打开&#xff0c;手机上无法打开。 在 app.json 中看到如下配置项&#xff0c;那么当前项目就是 keyline 渲染模式…

【Altium Designer】铜皮编辑

一、动态铜皮与静态铜皮的区分与切换 动态铜皮&#xff08;活铜&#xff09;&#xff1a; 通过快捷键 PG 创建&#xff0c;支持自动避让其他网络对象&#xff0c;常用于大面积铺铜&#xff08;如GND或电源网络&#xff09;。修改动态铜皮后&#xff0c;需通过 Tools → Polygo…