一片带你熟练Git分支管理


📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持


请添加图片描述


目录

  • 1.理解分支
  • 2.创建分支
  • 3.切换分支
  • 4.合并分⽀
  • 5.删除分支
  • 6.合并冲突
  • 7.分支管理策略
  • 8.分支策略
  • 9.bug分支
    • git stash
    • git stash list
    • git stash pop
  • 10.删除临时分支
    • 创建新分支,进行开发并实现提交
    • 此时被叫停打算删除
  • 11.总结


1.理解分支

本章开始介绍 Git 的杀⼿级功能之⼀(注意是之⼀,也就是后⾯还有之⼆,之三……):分⽀。分⽀就是科幻电影⾥⾯的平⾏宇宙,当你正在电脑前努⼒学习 C++ 的时候,另⼀个你正在另⼀个平⾏宇宙⾥努⼒学习 JAVA。
如果两个平⾏宇宙互不⼲扰,那对现在的你也没啥影响。不过,在某个时间点,两个平⾏宇宙合并了,结果,你既学会了 C++ ⼜学会了 JAVA!
在这里插入图片描述
在版本回退⾥,你已经知道,每次提交,Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分⽀。截⽌到⽬前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即 master 分⽀。
再来理解⼀下HEAD,HEAD 严格来说不是指向提交,⽽是指向master,master才是指向提交的,所以,HEAD 指向的就是当前分⽀。
那么分支在git仓库里面是如何体现出来的呢?
在这里插入图片描述
其中间的关系就是
HEAD指向master
master指向最新一次的提交
在这里插入图片描述
我们的git的所有提交可以串成一条线
在这里插入图片描述

这个提交时间线就相当于我们的分支


2.创建分支

在创建分支之前,我们先来看看我们仓库是有哪些分支存在的
我们可以使用branch命令,他是可以显示出我们当前仓库有哪些分支的
这里可以看到我们有且只有一个分支,那就是master分支
在这里插入图片描述
在我们创建git仓库的时候,master分支就会默认创建

在这里我们解释一下我们之前讲过的HEAD指针
不是一直讲的都是HEAD指针指向master指针吗?
HEAD指针其实可以指向其它分支的,被指向的分支就是当前正在工作的分支
就是因为我们只有master分支所以HEAD只能指向master

我们接下来来创建我们的第一个分支
我们使用

git branch dev

就可以创建一个dev分支出来了
在这里插入图片描述
当我们创建新的分⽀后,Git 新建了⼀个指针叫 dev, * 表⽰当前 HEAD 指向的分⽀是 master 分⽀。
我们再来看一下git目录下的文件
在这里插入图片描述
我们会发现git里refs文件下heads里不在只有我们的master文件了,还有我们新创建的dev

另外,可以通过⽬录结构发现,新的 dev 分⽀:
在这里插入图片描述
发现⽬前 dev 和 master 指向同⼀个修改。并且也可以验证下 HEAD ⽬前是指向 master 的。
用图来帮忙我们理解:
在这里插入图片描述

3.切换分支

我们想要在我们的dev上操作,那我们就需要把我们的HEAD指向dev,这样才能把dev变成我们的当前的工作分支
那么我们如何做呢?
使⽤ git checkout 命令即可完成切换,⽰例如下:
在这里插入图片描述
我们来验证一下我们的HEAD指针
在这里插入图片描述
我们发现 HEAD 已经指向了 dev,就表⽰我们已经成功的切换到了dev 上!
接下来,在 dev 分⽀下修改 ReadMe ⽂件,新增⼀⾏内容,并进⾏⼀次提交操作:
在这里插入图片描述

在这里插入图片描述在这里插入图片描述
现在,dev 分⽀的⼯作完成,我们就可以切换回 master 分⽀:
在这里插入图片描述
在这里插入图片描述
切换回 master 分⽀后,发现ReadMe⽂件中新增的内容不见了!!!
为什么会出现这个现象呢?我们来看看 dev 分⽀和 master 分⽀指向
在这里插入图片描述
这个时候我们可以看到两个指针指向的commit ID已经不在相同了
我们对dev指向的commit ID进行查看,可以看到记录就是我们刚刚对readme文件进行的修改操作,而且这里的parent指向的commit ID就是刚才刚出创建时的commit ID

因为我们是在dev分⽀上提交的,⽽master分⽀此刻的提交点并没有变,此时的状态如图如下所⽰。
在这里插入图片描述
当切换到 master 分⽀之时,HEAD 就指向了 master,当然看不到提交了!


4.合并分⽀

为了在 master 主分⽀上能看到新的提交,就需要将 dev 分⽀合并到 master 分⽀
git提供了merge指令
在这里插入图片描述
Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。
当然,也不是每次合并都能 Fast-forward,我们后⾯会讲其他⽅式的合并。
我们来查看一下master指针的指向有没有改变
在这里插入图片描述
发生了改变,已经指向了我们在dev分支上对readme的修改
git merge 命令⽤于合并指定分⽀到当前分⽀。合并后,master 就能看到 dev 分⽀提交的内容了。此时的状态如图如下所⽰。
在这里插入图片描述

5.删除分支

其实我们在将dev与master分支合并后,dev分支就可以丢弃了,它已经完成它的任务了
那我们怎么进行删除呢?
在这里插入图片描述

注:我们在这里只能除了dev分支之外的分支对dev分支进行删除

因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和直接在master分⽀上⼯作效果是⼀样的,但过程更安全。

6.合并冲突

我们在合并两个分支的时候有可能会出现冲突的
比如说
我们在a分支上对readme文件进行了添加文件
同时b分支也没有闲着,也对readme文件进行了修改
当我们合并的时候,git如何知道这两个操作哪个保留下来呢?
这个问题就是合并冲突问题
话不多说,我们进行实操

在这里我们引入一个新的操作,可以将创建以及能转换分支变成一行代码
我们前面需要先git branch dev
然后再checkout dev
这样才完成了我们创建以及更换当前分支的行为
我们使用checkout -b可以直接进行创建且更换当前分支
在这里插入图片描述
我们来对readme文件进行一下修改
在这里插入图片描述
我们照常进行add以及commit操作
在这里插入图片描述
接下来我们切换到master分支再次进行操作
我们在master对readme文件添加一行为add aaaaaaa
在这里插入图片描述
进行add以及commit操作
在这里插入图片描述
这个时候我们git仓库的状态是这样的
在这里插入图片描述
我们这个时候来进行合并,通过我们上面的说辞是会发生冲突的
在这里插入图片描述
这里确实是爆出了错误,说自动合并失败,readme文件的合并出现了矛盾,我们需要改变一下结果并重新提交
我们进入readme文件编辑界面查看
在这里插入图片描述
发现多了不少东西
这些符号里面的就是我们的冲突代码
git无法帮我们进行操作,我们只能自己进行人为操作,谁去谁留
我们要想保留在dev修改的,那我们自己进行删除
将其余行都删掉
在这里插入图片描述
修复之后我们还要进行提交操作

在这里插入图片描述
我们在master最后进行的提交是对最终修改的提交
所以我们的master会指向我们刚刚合并后最后的提交,dev会指向在dev分支上的提交
这也很好理解

git log指令是可以看到我们对分支的操作情况的
在这里插入图片描述
最左边有一个小图可以看到我们对于分支的操作

7.分支管理策略

通常合并分⽀时,如果可能,Git 会采⽤ Fast forward 模式。还记得如果我们采⽤ Fast forward 模式之后,形成的合并结果是什么呢?回顾⼀下
在这里插入图片描述
在这种 Fast forward 模式下,删除分⽀后,查看分⽀历史时,会丢掉分⽀信息,看不出来最新提交到底是 merge 进来的还是正常提交的
但在合并冲突部分,我们也看到通过解决冲突问题,会再进⾏⼀次新的提交,得到的最终状态为:
在这里插入图片描述
那么这就不是 Fast forward 模式了,这样的好处是,从分⽀历史上就可以看出分⽀信息。
我们先创建一个分支dev1
再对readme文件进行修改操作以及add和commit操作
然后再对dev1和master进行合并
在这里插入图片描述
在这里插入图片描述
上面我们在合并的时候可以看到我们的模式是fast-forward模式
我们使用git log --graph --abbrev-commit
我们可以看到在这个模式下我们无法看到我们分支合并的相关操作
在这里插入图片描述
有的仅仅是一条最后合并的操作
–no-ff代表的是我们强制禁止fast-forward模式,后面的-m

我们输入

git merge --no-ff -m “merge dev1” dev1

请注意 --no-ff 参数,表⽰禁⽤ Fast forward 模式。禁⽤ Fast forward 模式后合并会创建⼀个新的 commit ,所以加上 -m 参数,把描述写进去。
可以看到,不使⽤ Fast forward 模式,merge后就像这样
在这里插入图片描述
所以在合并分⽀时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾
经做过合并,⽽ fast forward 合并就看不出来曾经做过合并。

8.分支策略

在实际开发中,我们应该按照⼏个基本原则进⾏分⽀管理:
⾸先,master分⽀应该是⾮常稳定的,也就是仅⽤来发布新版本,平时不能在上⾯⼲活
那在哪⼲活呢?⼲活都在dev分⽀上,也就是说,dev分⽀是不稳定的,到某个时候,⽐如1.0版本发布
时,再把dev分⽀合并到master上,在master分⽀发布1.0版本
你和你的⼩伙伴们每个⼈都在dev分⽀上⼲活,每个⼈都有⾃⼰的分⽀,时不时地往dev分⽀上合并就
可以了。
在这里插入图片描述
所以,团队合作的分⽀看起来就像这样:

在这里插入图片描述

9.bug分支

假如我们现在正在 dev2 分⽀上进⾏开发,开发到⼀半,突然发现 master 分⽀上⾯有 bug,需要解决。在Git中,每个 bug 都可以通过⼀个新的临时分⽀来修复,修复后,合并分⽀,然后将临时分⽀删除。
我们创建一个dev2分支
在这里插入图片描述
在dev2分支上对readme文件进行添加数据
在这里插入图片描述
假设我们在开发过程中出现了bug
我们一开始的需求是在dev2上进行一系列的开发,并且我们的开发并没有完成,所以我们不能进行提交也就是add以及commit操作
同时不能在这个分支上解决bug
现在我们就需要另开一个分支来帮助解决bug
我们移动到master分支
在这里插入图片描述
这里也显示了,我们对readme文件有所修改
这个也是因为我们在dev2分支对readme文件修改后没有进行add以及commit操作
所以我们对于readme的修改是对所有分支都会有影响的,因为没有提交所以git没有对这个修改进行管理
我们在master分支上也可以看到
在这里插入图片描述

git stash

Git 提供了 git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时间恢复出来。
在这里插入图片描述
那我们这个分支被保存在哪里呢?
我们可以看到在refs文件里多了一个stash文件,这就是储存地点
在这里插入图片描述
⽤ git status 查看⼯作区,就是⼲净的(除⾮有没有被 Git 管理的⽂件),因此可以放⼼地创建分⽀来修复bug。
在这里插入图片描述
储藏 dev2 ⼯作区之后,由于我们要基于master分⽀修复 bug,所以需要切回 master 分⽀,再新建临时分⽀来修复 bug
我们在master分支里看readme文件和原来的没有修改过的是一样的
在这里插入图片描述
我们在master分支新建分支
在这里插入图片描述
我们假设发现是readme文件里少了一个s
在这里插入图片描述
我们给加上
在这里插入图片描述
bug已经修复完毕了
将分支删除
在这里插入图片描述
我们还要接着进行开发
切换到dev2分支
我们需要将其隐藏的恢复出来

git stash list

我们可以先使用git stash list
查看我们的stash里面存储了哪些信息
这里只有我们刚刚对于readme进行的修改信息
在这里插入图片描述

git stash pop

我们将隐藏信息释放
指令为 git stash pop
在这里插入图片描述
我们打开看我们刚才修复的bug
在这里插入图片描述
但我们注意到了,修复 bug 的内容,并没有在 dev2 上显⽰
这是因为我们在创建这个分支的时候是没有加上那个s的
此时的状态图为:
在这里插入图片描述
Master 分⽀⽬前最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们在 dev2 中当然看不⻅修复 bug 的相关代码。
我们的最终⽬的是要让 master 合并 dev2 分⽀的,那么正常情况下我们切回 master 分⽀直接合并即可,但这样其实是有⼀定⻛险的。
是因为在合并分⽀时可能会有冲突,⽽代码冲突需要我们⼿动解决(在 master 上解决)。我们⽆法保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只⼀两⾏那么简单,有可能⼏⼗上百⾏,甚⾄更多,解决的过程中难免⼿误出错,导致错误的代码被合并到 master 上。
此时的状态为:
在这里插入图片描述
解决这个问题的⼀个好的建议就是:最好在⾃⼰的分⽀上合并下 master ,再让 master 去合并dev ,这样做的⽬的是有冲突可以在本地分⽀解决并进⾏测试,⽽不影响 master 。此时的状态为:
在这里插入图片描述
在这里插入图片描述
对应的实操演⽰如下,要说明的是,以下演⽰的merge操作,没有使⽤ --no-ff ,但上述的图⽰是
禁⽤ Fast forward 了模式后得出的,主要是为了⽅便解释问题
我们的开发完成了
在这里插入图片描述
再进行add以及commit操作
在这里插入图片描述
解决冲突并提交

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
切回master,并合并(这个时候就不会出现冲突)
在这里插入图片描述
最后删除开发的分支因为任务已经完成
在这里插入图片描述

10.删除临时分支

软件开发中,总有⽆穷⽆尽的新的功能要不断添加进来。
添加⼀个新功能时,你肯定不希望因为⼀些实验性质的代码,把主分⽀搞乱了,所以,每添加⼀个新功能,最好新建⼀个分⽀,我们可以将其称之为 feature 分⽀,在上⾯开发,完成后,合并,最后,删除该 feature 分⽀。
可是,如果我们今天正在某个 feature 分⽀上开发了⼀半,被产品经理突然叫停,说是要停⽌新功能的开发。虽然⽩⼲了,但是这个 feature 分⽀还是必须就地销毁,留着⽆⽤了。这时使⽤传统的 git branch -d 命令删除分⽀的⽅法是不⾏的。演⽰如下:

创建新分支,进行开发并实现提交

在这里插入图片描述

此时被叫停打算删除

我们切回master并删除
在这里插入图片描述
这个时候根据提示无法进行删除,需要使用git branch -D dev3
在这里插入图片描述

11.总结

分⽀在实际中有什么⽤呢?假设你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50%的代码,如果⽴刻提交,由于代码还没写完,不完整的代码库会导致别⼈不能⼲活了。如果等代码全部写完再⼀次提交,⼜存在丢失每天进度的巨⼤⻛险。
现在有了分⽀,就不⽤怕了。你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀上,这样,既安全,⼜不影响别⼈⼯作。
并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成!⽆论你的版本库是1个⽂件还是1万个⽂件。

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

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

相关文章

如何快速记忆小鹤双拼键位图?

记忆方法:韵母表 图形 最常用字 韵母表:双拼的基础 图形:帮助新手快速联想回忆 最常用字:快速打字基础 一、单韵母(紫色方块) 一一对应如下表: 单韵母aoeiu、AOEIV 二、复韵母—箭矢型&am…

几种常见编码器优缺点

目录 光电编码器 磁性编码器 编码器在运动控制类产品中比较常见,旋转编码器都是组成运动控制反馈回路的关键元器件,包括工业自动化设备和过程控制、机器人技术、医疗设备、能源、航空航天等。 作为将机械运动转换为电信号的器件,编码器可为…

ASP.NET Core 使用 SignalR 的简单示例

写在前面 ASP.NET SignalR 是一个开源代码库,简化了Web实时通讯方案,可以实时地通过服务端将信息同步推送到各个客户端,可应用于 需要从服务器进行高频更新的应用:包括游戏、社交网络、投票、拍卖、地图和GPS应用; 仪…

excel中去掉单元格中两个数字之间的空格

excel中去掉单元格中两个数字之间的空格 使用公式:SUBSTITUTE(A1," “,”") 解释:将A1单元格中的空格查找出来并去掉。

python_蓝桥杯刷题记录_笔记_入门2

前言 现在正式进入蓝桥杯的刷题啦,用python来做算法题,因为我之前其实都是用C来做题的,但是今年的话我打算换python来试试,很明显因为也才这学期接触python 加上之前C做题也比较菜,所以我打算用python重新来做题&#…

Nginx 部署指定文件夹下的项目(本地测试)

1、配置 vue.config.js,指定生成环境的包 //部署生产环境和开发环境下的URLpublicPath: process.env.NODE_ENV production ? "/marketing" : "/",///npm run build 或 varn build 生成文件的日录名称(要利baseUrl的牛产环境路一致)(默认dist…

每日一言正能量句子,心灵鸡汤之励志文案

1、相信自我是成功的基石,完善自我是成功的阶梯,突破自我是成功的钥匙,合谋共处是成功的翅膀,确立目标是成功的起点,付注行动是成功的号角! 2、所有的努力,不是为了让别人觉得你了不起&#xf…

C系列-自定义类型:结构体

🌈个人主页: 会编程的果子君 ​💫个人格言:“成为自己未来的主人~” 结构体类型的声明 前面我们在学习操作符的时候,已经学习了结构体的知识,这里我们稍微复习一下。 结构体回顾 结构是一些值的集合,这些值称为成员…

【linux】磁盘相关命令fdisk/lsblk和file

1. fdisk 磁盘分区,查看系统分区。 fdisk 的意思是 固定磁盘(Fixed Disk) 或 格式化磁盘(Format Disk),它是命令行下允许用户对分区进行查看、创建、调整大小、删除、移动和复制的工具。它支持 MBR、Sun、SGI、BSD 分区表,但是它不支持 GUI…

Docker 数据管理、容器互联、网络与资源控制

一、docker数据管理 管理 Docker 容器中数据主要有两种方式:数据卷(Data volumes)和数据卷容器(Datavolumes containers)。 1、数据卷 数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立…

Prometheus 容器化部署

实验部署 工作中是基于kube-api的自动发现 1、创建账户绑定集群 kubectl create serviceaccount monitor -n monitor-sa #创建账户 kubectl create clusterrolebinding monitor-clusterrolebinding -n monitor-sa --clusterrolecluster-admin --serviceaccountmonitor-sa:…

FileViewer纯前端预览项目Vue2 demo

FileViewer 项目Vue2 demo 本demo基于vue-clijsvue2.x构建,如果您需要vue3版本的demo,请前往main分支。 适用于Vue2 Webpack,本集成方法要求最低Webpack版本为5,也就是Vue Cli Service 5.0.0以上,当然,if…

13.前端--CSS-盒子模型

1.盒子模型的组成 CSS 盒子模型本质上是一个盒子,封装周围的 HTML 元素,它包括:边框、外边距、内边距、和 实际内容 2.边框(border) 2.1 边框的使用 1、border设置元素的边框。边框有三部分组成:边框宽度(粗细) 边框…

国网四川宜宾供电公司:基于“RPA+AI”融合技术的电网设备隐患缺陷智能化识别应用

推荐单位:国网四川省电力公司宜宾供电公司 本文作者:杨鑫、唐龙、钟睿、李小航、孙雪冬 摘 要:为推进电力企业生产业务数字化转型,提高基层班组数字化运维水平。本文通过一线班组对变电站视频巡视、设备故障判断应用场景需求分析…

C++-内存管理(1)

1. C/C内存分布 首先我们需要知道,在C中的内存分为5个区。 1. 栈 又叫堆栈 -- 非静态局部变量 / 函数参数 / 返回值等等,栈是向下增长的。 2. 内存映射段 是高效的 I/O 映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建…

【2023地理设计组一等奖】基于GIS的桥梁隧道三维建模与可视化

作品介绍 1 设计背景和意义 随着我国基础建设规模不断扩大和深入,构建桥梁可视化管理模型,全面推动智慧桥梁,已成为现代隧道桥梁建设行业的发展趋势。传统的桥梁建模工作需要复杂的算法设计并需要熟练编程实践技能,实现周期长。开发自主知识版权的桥梁建模软件系统或专用插…

在线mockjson

在线mockjson体验地址 在调一个问题的时候,但是问题的数据可能并不能随着想到的场景就变化,譬如说又个数组长度的情况,可能默认的情况下是返回4个元素,但是想要返回为空的时候,如果联系服务给改一下,那么流…

防火墙知识普及详解,使用TOR Router把TOR作为默认网关,增加隐私/匿名性

防火墙知识普及详解,使用TOR Router把TOR作为默认网关,增加隐私/匿名性。 #################### 免责声明:工具本身并无好坏,希望大家以遵守《网络安全法》相关法律为前提来使用该工具,支持研究学习,切勿用于非法犯罪活动,对于恶意使用该工具造成的损失,和本人及开发者…

Abp 从空白WebApplication开始

开发环境:VS2022、.NET6 1、创建项目:BasicAspNetCoreApplication 2、NuGet添加:Volo.Abp.AspNetCore.Mvc和Volo.Abp.Autofac,如下图所示: 3、开始写代码,目录如下图所示: 3.1、添加启动模块Ap…

使用make_grid多批次显示网格图像(使用CIFAR数据集介绍)

背景介绍 在机器学习的训练数据集中,我们经常使用多批次的训练来实现更好的训练效果,具体到cv领域,我们的训练数据集通常是[B,C,W,H]格式,其中,B是每个训练批次的大小,C是图片的通道数,如果是1…