当前位置:   article > 正文

Git分支管理

Git分支管理

 

目录

写在前面的话

Git分支管理

理解分支

创建分支

切换分支

合并分支

删除分支

合并冲突

bug分支

强制删除分支


写在前面的话

     上一章我也提到了git的重要性,并把git的一些基本概念和一些基础操作讲清楚了,但依然存在着上一章没有解决的问题,例如add到暂存区后,然后再commit,这个commit具体到哪呢?这些都是如何操作的呢?本章将详细讲解关于git的分支管理。

下一章将讲述git远程仓库等相关内容。

Git分支管理

理解分支

        本章开始介绍Git的杀⼿级功能之⼀:分支。分⽀就好像科幻电影⾥⾯的平行宇宙,当你正在电脑前努⼒学习C++的时候,另⼀个平⾏宇宙里的你⾥努⼒学习JAVA。然后最后所有宇宙的你合并到一起,造就了一个即会C++又会JAVA的你。(当然以上我都是我瞎编的,主要理解意思).

        又或者这样的例子,你们村里举办武林大会,赢的人可以获得黄金万两并且抱得美人归。假设武林大会还有3个月开始,此时有两个人:你和你的对手,你们基本功差不多,需要在这三个月里努力修行,获得更多技能以赢得比赛。

        假设第一个月你们都是在练习基本功,一个月过去了,你们都将基本功修行的差不多,能力不相上下.

        第二个月你在山上偶然帮助了一个老头,却没想到该老头是个武林大师,听闻了你的经过后,点化了你。于是你学会了一门新技能:分身术。这个分身术不是普通的分身,在分身期间该分身所学习的技能,在与你重新合并的时候,都会转化为你所有。 于是你在第二个月,你本体学习降龙十八掌,分身学习辟邪剑法,等第二个月结束后,分身合体,你同时掌握了这两种技能。而你的对手却只会了降龙十八掌.

        第三个月你们参见比赛,不出意外,你凭借多学的一门技术轻松战胜了对手。

如下:

以上你本体学习的所有内容称之为主线(master主分支),你的分身学习的 称之为支线. 

这是上一章那个图片:

 上一章我们也说了,这里不做过多赘述,就是HEAD指针指向了master,而master指向了master主分支上最新一次的提交,如下:

 

而有分支的提交如下:

 具体是如何做的,以及会有一些什么问题,请继续向下看.


创建分支

刚才一直在说HEAD指针,它指向了master,而master又指向了master主分支上最新一次的提交.

同时也说明1.HEAD指针指向的分支就是我们正在工作的分支。

2.而且HEAD可以指向其他分支,代表此时在该分支上工作。

如当我们创建一个分支时,假设分支名为dev-1,当我们切到该分支上时,HEAD指针便不再指向master,而是指向dev-1,而dev-1指向了dev-1分支上的最新一次提交。

如何创建一个分支呢?

命令如下:

git branch [分支名]

该命令可以创建一个分支。

同时,我们可以使用下面的命令查看当前所有的分支。

git branch

如下:

其中 * 代表当前所处的分支。可以看到我已经创建了一个名为dev-1的分支。


注意:dev分支是基于当前分支最新一次提交的版本上创建的。         

此时我们再查看一下.git中refs/heads下两个分支的内容:

可以发现两者的commit id是完全相同的,即我创建的dev-1分支是在当前master主分支上最新一次提交的基础上创建的.

如下:(图中的分支名是dev,我写的是dev-1,不一样,但不影响,只是名字不同)


切换分支

我们虽然刚才创建了dev-1分支,但是我们通过git branch发现,我们当前所处的分支还是在master分支上:

我们该如何切换到dev-1分支呢?

使用命令:

git checkout [分支名]

即可切换到制定分支。

此时我们发现已经切换到dev-1分支上,并且HEAD指针已经指向了dev-1,说明我此时已经在dev-1上开始工作了, 所以此时的分支关系如下:

 


合并分支

当我们切换到dev-1分支上后,我们先对ReadMe文件进行修改:添加一行"test on dev-1"

然后我们退出保存,然后add 到暂存区,并且commit提交:

此时我们再切换回到master主分支上,再次查看ReadMe内容:

 我们发现,我们在dev-1分支上添加的那一行不存在,这是什么原因呢?

我们再来看一下刚创建dev-1分支完成时的状态:

 此时master和dev-1重合,因为是刚创建,dev-1指向master最新一次提交。

当在dev-1分支上添加一行内容,并且add 和commit后,此时状态成为了这样:

此时master主分支已经落后于dev-1分支的一个提交了,所以master之所以看不到新添加的一行,是因为master分支还没有更新,即还没有与dev-1分支进行合并

所以此时我们需要切换到主分支上,然后合并dev-1分支,分支合并命令如下:

git merge [分支名]

该命令会使指定分支 合并到当前分支。

合并完成后,新增加的一行我们也就能看到了:

Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。
当然,也不是每次合并都能 Fast-forward,也会其他⽅式的合并,这里不再多说。

此时的状态如下:


 

删除分支

合并完成后, dev 分⽀对于我们来说就没⽤了,那么dev分⽀就可以被删除掉,注意如果当前正处于某分⽀下,就不能删除当前分⽀。

使用如下命令删除分支:

git branch -d [分支名]

可以发现dev-1分支已经被删除掉了。

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


合并冲突

        可是,在实际分⽀合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。

        冲突主要是发生在这样的场景:在当前master主分支上 新建了一个dev分支,然后dev分支commit提交后,master主分支此时并没有直接合并,而是也对dev分支上修改的文件 也做了修改,此时master主分支再合并,就会出现问题,因为git也不知道是保留dev分支上的修改还是master主分支上的修改。所以需要我们手动解决冲突。

下面做一个演示:

教大家一个命令,可以直接创建并且切换到该新建的分支

git checkout -b [分支名]

切换到新分支dev1上上之后,我添加了如下一行:

在commit提交后,我切回到master主分支上,此时由于我还没有合并,所以刚才添加的那一行并没有显示,我也在相同的位置添加上如下一行:

 

此时我commit后,再在master分支上,再进行合并,便会出现下面的合并冲突问题:

 此时我们打开冲突的文件:

蓝色框,即HEAD指针指向的分支上(当前分支)的修改是modify on master 

粉色框,即dev分支上的修改是 modify on dev1

我们此时有三种选择:

1.保留HEAD的更改

2.保留dev1的更改

3.保留HEAD和dev1的更改.

此时我决定只保留HEAD的更改,于是我把出HEAD指向的那一行以外的内容全部删除,如下:

退出保存后,我们再次add和commit提交,(再次提交很重要,切勿忘记)冲突便成功解决了:

此时我们分支的状态如下:


bug分支

        假设我们现在正在dev2分支上进行开发,还没有开发完成,突然发现master主分支上有bug需要解决。在Git中,每个bug都可以通过在master分支上开一个临时分支进行解决,修复后,合并分支,再将临时分支删除。

        因此我们需要先回到master分支上,开一个bug分支然后解决完后,再回到dev2分支进行工作,但问题是我现在dev2还没有开发完,如果直接切回master,那内容就会丢失 ,所以我们需要现将dev2工作区中的内容保存起来。

Git 提供了 git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时
间恢复出来.

同样拿一个示例演示:

在dev2分支下,我在ReadMe文件中,加入以下一行代码:

此时由于master分支上出现了bug,我需要将当前dev2分支上的内容保存起来,然后切回到master分支:

然后我在开一个分支用来修复bug,假设在ReadMe文件中该行少了三个叹号:

然后修复完成后,我们add并commit提交,切换到master分支,与该分支进行合并:

此时master分支上的bug修复完毕了,我们需要继续回到dev2分支上工作。

切换到dev2分支上后,首先需要恢复我们上次工作区的修改变动,

使用

git stash pop

恢复的同时会把 stash 也删了.

 可以发现ReadMe内容恢复了,但是修复bug后的内容,并没有在dev2中显示,此时的状态图为:

        Master 分⽀⽬前最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们在 dev2 中当然看不见修复bug的相关代码。 

当我们完成dev2的开发工作时,我们add并commit提交后,

我们此时能切回到master分支然后直接合并吗?

答案是可以,但是是有风险的,这是因为dev2和master在合并分⽀时可能会有冲突,而代码冲突需要我们手动解决(在 master 上解决)。我们无法保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只⼀两⾏那么简单,有可能几十上百行,甚⾄更多,解决的过程中难免⼿误出错,导致错误的代码被合并到 master 上。得不偿失,如果这么做,此时的状态图如下:

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

对应的代码:

 

 

 对应代码:

这样不仅在开发dev2期间修复了bug,最后也顺利的完成了dev2的开发工作并合并到master分支中,一切便大功告成了。


强制删除分支

我们刚才说了一个删除分支的命令

git branch -d [分支名]

这个删除有一个前提条件,就是在你已经提交并且已经别master分支合并之后,才能删除,如果没有被合并,则不可以被删除。

那么我就是想删除这个分支强制删除,确定这个分支上的内容已经彻底没用了,不用合并了,那么我们只需要把-d 改成 -D即可:

git branch -D [分支名]

 演示一下:

这样便完成了强制删除某个分支。一般用于开发某个需求时,突然这个需求被抛弃需要删除这个分支,便使用到了这个功能. 

git分支管理的内容到此就结束了,如果有疑问或者不懂地方,欢迎评论留下哦~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/163132
推荐阅读
相关标签
  

闽ICP备14008679号