本篇主要总结的是Git中的分支管理
分支是什么
在Git中,一个强大的功能就是分支
由前面的学习可以知道,当我们每次进行commit
的时候,Git都会把这些commit
的操作穿成一个时间线,而这个时间线就可以理解为是一个分支,在我们前面的操作中,只有一个时间线,换而言之,只有一个分支,这个分支就叫做主分支,也叫做master
分支
上一篇在介绍Git的基本操作中讲到,Git中含有HEAD
指针,可以借助它来完成对于版本的回退,这里再次明确概念,这个HEAD
指针所指向的内容是master
而不是具体的commit记录,而master
所指向的内容才是提交的内容,也就是说,HEAD
指向的是当前分支,而分支指向的是具体的master
提交记录,用下面一张图来表示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/32c88bd9daa641d8bfa9dc1b034bb5f9.png)
提交线上的每一个圆圈,代表的都是每一次提交,而master
指向的是最新的一次提交,用户本身利用HEAD
指针就可以通过master
的指向回退或快进到某一个版本,随着不断提交,这个分支会不断变长,但只要HEAD
一直指向的是master
分支就可以指向当前的分支
下面通过一些实验来看上面的理论:
![在这里插入图片描述](https://img-blog.csdnimg.cn/e160ec28e8a24cd7bc3ef3a625b93905.png)
上图中使用了一些命令来查看当中的commit
相关信息,从中可以看出每一次提交的信息都有记录,并且也会记录它的上一次提交的相关信息,依据这些信息都可以在这条master
分支线中找到相应的信息
创建分支
既然分支是Git中的一大重要操作,那么创建多分支并使用多分支进行管理项目也是必不可少的操作,那么如何新建分支?
这里提供两个命令
# 查看本地所有分支
git branch
# 新建分支dev
git branch dev
![在这里插入图片描述](https://img-blog.csdnimg.cn/1a06d21096ed44f9b674e98b18b0d83b.png)
其中,*
表示的内容是,当前Git所控制的分支,以上图为例,当前HEAD
所指向的分支其实是master
,同时上面也表明了在Git中如何创建一个分支
下图表示了分支的存在证明:
![在这里插入图片描述](https://img-blog.csdnimg.cn/037f42d818224ecb844261e44ad95084.png)
在我们创建了分支后,此时的refs
路径下heads
所包含的内容就不仅仅是master
了,换句话说,HEAD
可以指向其他内容了
分支切换
在Git中提供了切换分支的操作:
# dev表示要切换的分支名称
git checkout dev
利用上面的命令,将Git的分支实现了切换,下图为实践图
![在这里插入图片描述](https://img-blog.csdnimg.cn/d4016fd5cd0c4f398886d4311ec006c7.png)
而切换分支的操作,实际上就是将HEAD
指针所指向的分支做修改的一个过程:
![在这里插入图片描述](https://img-blog.csdnimg.cn/eca8b7a31db64faa9a4c84ea2c96cebb.png)
从上图中可能还有疑问,为什么dev
创建后的分支默认是指向最新提交处?后面会进行实验证明
那么切换完分支后,就可以进行一些操作验证分支的特性了
![在这里插入图片描述](https://img-blog.csdnimg.cn/506aa80b545e4f34b47d383ad0bf9446.png)
从上图的实验中可以看出,在没有进行合并分支的前提下,在不同的分支下进行的commit
操作是不可以互通的,都是单独的时间线,也就是单独的分支,从commit id
的视角下观察这个结论
![在这里插入图片描述](https://img-blog.csdnimg.cn/719557b8f5be4e188946b0f08e22a1c4.png)
从上面的实验中可以几点:新建的分支确实是在当前所指分支的开始新建的,并且新建后的分支内容和旧的分支内容并不互通,也就是说,此时的状态可以用下面的状态图表示
![在这里插入图片描述](https://img-blog.csdnimg.cn/d03cc1e1f8dd4b7a852aa3159aae938b.png)
合并分支
那么如何进行分支合并?Git中也提供了相关的命令:
# 要切换到master分支下
git merge dev
![在这里插入图片描述](https://img-blog.csdnimg.cn/ba050fb1ca574f56816f6bed8b2ef2ae.png)
当在master
分支下使用指令合并分支后,test
中的内容就被合并到master
中了,此时master
就重新指向了最新的分支节点
![在这里插入图片描述](https://img-blog.csdnimg.cn/1ec989a3a01848718fe7b7036b7ef80c.png)
Fast-forward
代表快进模式,也就是直接把master
指向dev
的当前提交
删除分支
分支使用后要进行删除,避免占用过多资源:
git branch -d dev
![在这里插入图片描述](https://img-blog.csdnimg.cn/e682a529e16b465f9d2872b92ddeff48.png)
此时就删除掉了分支:
![在这里插入图片描述](https://img-blog.csdnimg.cn/b09ff6867ab2493891347c98c037ce54.png)
那创建分支合并分支删除分支有什么作用?
Git建议使用分支后再删除,这样比较安全
合并冲突
看下面的场景:
![在这里插入图片描述](https://img-blog.csdnimg.cn/88011e785a0a4a7fa4ab6f5bd91dc2e4.png)
上面所演示的过程就是合并冲突的原理,两个分支都进行了一些操作,此时想要进行合并Git不知道该如何合并,该合并哪个部分,因此Git给出的解决方案是两个版本都进行保留,由用户自己来决定如何管理
![在这里插入图片描述](https://img-blog.csdnimg.cn/5b0cb0ad868949559ba2a0e592e2de04.png)
用下图来表示这个冲突的过程:
![在这里插入图片描述](https://img-blog.csdnimg.cn/b10ba071c6254f3cb5708f27669d4858.png)
因此,当手动删除了部分内容后并进行提交,就可以解决这个冲突问题,此时就可以把状态转换为:
![在这里插入图片描述](https://img-blog.csdnimg.cn/8449114353d245ecad3a6dd200e543d2.png)
Git的可视化流程图
在Git命令中也是可以把上面的这个流程图进行可视化的,使用到的命令是git log
git log --graph --pretty=oneline --abbrev-commit
![在这里插入图片描述](https://img-blog.csdnimg.cn/6c2a94f5e6e24564859dd1f82aab3c97.png)
合并模式
在merge
的过程中,有两种合并模式,前面已经提到过一种合并模式是Fast-forward
模式,这个模式的特点是直接将dev
分支中的信息合并到master
分支内,但如果这里我想在合并的这个过程也产生一次commit
来表示,这里确实发生过一次merge
该如何处理?Git中也提供了对应的命令选项:
# branch表示合并的分支名称
git merge --no-ff -m "merge with no-ff" [branch]
那么下面用实验来对比一下这两个方法合并模式对应的效果演示
首先看fast-forward
模式
![在这里插入图片描述](https://img-blog.csdnimg.cn/41aaf5a55a5047949e408896e43d7cfd.png)
上面演示的就是fast-forward
下的各项操作,下面演示no fast-forward
的操作结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/933795e165dc4a8fa8b0afc68970513d.png)
从中可以看出,使用no-ff
模式下的合并方法可以显示出merge
的具体commit id
等信息,这样有利于在追溯代码的时候找到在哪里产生问题等,在实际开发中也多建议使用no-ff
模式而不是ff
模式
![在这里插入图片描述](https://img-blog.csdnimg.cn/7ce0614783674f159391e66fbc3859dc.png)
分支策略
在实际开发中,进行分支管理应该要遵循下面的几个原则
-
master
版本是一个非常稳定的版本,这个分支是主分支,上面只是用来发布新的版本,在平时的开发过程中应该要自己创建分支,在自己的分支上完成操作
- 在自己的
dev
分支上完成自己的工作任务后,每个人都有自己的分支,完成后向master
分支合并就可以了
因此整个合并的流程可以表示为下面的图
![在这里插入图片描述](https://img-blog.csdnimg.cn/c3577f61125a41a8a7415cf097d28933.png)
每个人都有自己的分支,分支写好后统一合并到master
分支上,以确保master
分支上都是稳定的代码
bug分支
现在有这样的场景,假设你正在dev
的分支上进行开发,突然,master分支上发现了一个bug
,现在这种修改master
分支上的bug
,应该如何解决?
在Git中,每一个bug
都可以通过一个新的临时分支来进行修复,修复后合并分支,再将临时分支删除即可,但是对于上面的情况,dev
的代码正在开发,但是master
有问题,现在还无法提交,对于这种情况该如何解决?
![在这里插入图片描述](https://img-blog.csdnimg.cn/4a3ea511f92042a48dc440e2ca4a8252.png)
针对这种情况,在Git中提供了一种叫做git stash
的命令,这个命令的作用就是可以让当前的工作区的信息进行存储,在未来的某个时刻再把信息拿出来
git stash
![在这里插入图片描述](https://img-blog.csdnimg.cn/b859976cd0c24990800d47bd7289ae5e.png)
使用该指令可以让工作区中的代码暂时存起来,因此使用stash
指令查看就会发现此时工作区中是没有内容的,此时就可以单独拉一条fix_bug
专用的分支进行修复代码,修复后的代码再提交到master
分支内,此时master
分支就是一个稳定的,没有bug
的一份代码
那么下面就要解决的问题是,如何把我写了一半的代码和新的没有bug
的代码合在一起
![在这里插入图片描述](https://img-blog.csdnimg.cn/03343a21ccfc40d78ce17394f00b6092.png)
此时就完成了基本目标:既把master
分支的bug
改完了,又把dev
分支下的内容更新完,并且dev
下的内容是没有bug
的,那么如何把dev
的文件上传到master
主线上?其实直接上传即可,但这里不推荐这样,原因如下:
原因是,解决合并冲突的时候,是由dev
的用户自己进行手动的删除解决的,这当中可能会出现一些问题,因此这样的方法是有可能会出现错误的:
![在这里插入图片描述](https://img-blog.csdnimg.cn/5410198e13bf43898c4d3fea9d2fc1ba.png)
那么最标准的方法是,应该先拉取master
上的代码与dev
合并,在dev
分支下看看能不能正常运行,如果可以再将代码整体合并到master
分支上,以确保master
分支上都是可跑的,没问题的代码
![在这里插入图片描述](https://img-blog.csdnimg.cn/4419238b1e894215ade61104ddae8084.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/57a578b450cd417fbf0e7ec795434b32.png)
强制删除分支
Git默认的删除分支的前提是路径要进行合并后才能进行删除,但如果是没有进行合并,只是单纯想把路径删除?
Git中提供了对应的选项
# dev表示要删除的分支
git branch -D dev