Git分支

目录​​​​​​​

一、分支是什么

二、查看、创建分⽀(git branch)

查看分支

创建分支

三、切换分支(git checkout,git checkout -b)

四、合并分支(git merge、git log查看合并情况)

五、删除分支(git branch -d [])

六、合并冲突(git log)

七、分支管理策略(Fast forward、--no--ff、git log --graph --pretty=oneline --abbrev-commit)

八、分支策略

九、bug分支(git stash、git stash list、git stash pop)

十、删除临时分支


一、分支是什么

在版本回退⾥,每次提交,Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分⽀。截⽌到⽬前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即master分⽀。

再来理解一下HEAD,HEAD严格来说不是指向提交,而是指向master。

每次提交,master分⽀都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越来越⻓,⽽ HEAD只要⼀直指向master分⽀即可指向当前分⽀。

通过查看当前的版本库,我们也能清晰的理出思路:

二、查看、创建分⽀(git branch)

Git⽀持我们查看或创建其他分⽀,在这⾥我们来创建第⼀个⾃⼰的分⽀dev,对应的命令为:

查看分支

git branch 

创建分支

git branch [分支名]

例:

当我们创建新的分⽀后,Git新建了⼀个指针叫dev,*表示当前HEAD指向的分支是master分支。

同时,通过目录结构也可以发现,新的dev分支。

发现⽬前dev和master指向同⼀个修改。并且也可以验证下HEAD⽬前是指向master的。

总结:

三、切换分支(git checkout,git checkout -b)

git checkout

可以发现HEAD已经指向了dev,就表⽰已经成功的切换到了dev上!
接下来,在dev 分⽀下修改test⽂件,新增⼀⾏内容,并进⾏⼀次提交操作:

再切换回master,查看分支

会发现新增内容不见了,此时可以看看master分支指向,发现两者指向的提交不一样:

因为在dev上进行的提交,而master分支的提交点并没有发生改变,此时的状态:

git checkout -b []创建分支并切换到新的分支上

四、合并分支(git merge、git log查看合并情况)

为了在master主分⽀上能看到新的提交,就需要将dev 分⽀合并到master 分⽀,⽰例如下:

git merge命令⽤于合并指定分⽀到当前分⽀。合并后,master就能看到dev分⽀提交的内容了。此时的状态如图所示:

Fast-forward代表“快进模式”,会直接把master指向dev的当前提交,所以合并速度⾮常快。

并不是每次合并都能Fast-forward。

五、删除分支(git branch -d [])

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

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

六、合并冲突(git log)

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

例:

现在mater和dev分支都有各自新的分支了,因为都进行了提交。(可以对比第三点和第四点进行查看)

这种情况下,Git只能试图把各⾃的修改合并起来,但这种合并就可能会有冲突,如下所⽰:

我们再来查看一下test

发现⽂件有冲突后,Git会⽤<<<<<<<,=======, >>>>>>>来标记出不同分⽀的冲突内容。

此时我们必须要⼿动调整冲突代码,并需要再次提交修正后的结果!!(再次提交很重要,切勿忘 记)

到这⾥冲突就解决完成,此时的状态变成了

git log

⽤带参数的git log也可以看到分⽀的合并情况:

最后,不要忘记dev分⽀使⽤完毕后就可以删除了:

七、分支管理策略(Fast forward、--no--ff、git log --graph --pretty=oneline --abbrev-commit)

通常合并分⽀时,Git会采⽤Fast forward 模式。采⽤ Fast forward 模式之后,形成的合并结果是? 

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

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

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

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

git merge --no-ff -m "" [分支名]

注意--no--ff,表示禁用Fast forward模式。禁用Fast forward后合并会创建一个新的commit,所以加上-m参数,把描述写进去。

合并后,查看分⽀历史:

git log --graph --pretty=oneline --abbrev-commit

可以发现,不使用Fast  forward模式merge后会像这样:

所以在合并分⽀时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾经做过合并,⽽ fast forward 合并就看不出来曾经做过合并。

八、分支策略

在实际开发中,应该按照⼏个基本原则进⾏分⽀管理:

⚠️⾸先,master分⽀应该是⾮常稳定的,也就是仅⽤来发布新版本,平时不能在上⾯⼲活;

建议干活都在分支上进行,也就是说dev分支没有那么稳定,等稳定版本出来后,再把dev合并到master上。在实际项目中,每个人都有自己的分支,时不时往一个分支合并就行。

九、bug分支(git stash、git stash list、git stash pop)

假如现在正在dev分⽀上进⾏开发,开发到⼀半,突然发现 master 分⽀上⾯有bug,需要解决。在Git中,每个bug都可以通过⼀个新的临时分⽀来修复,修复后,合并分⽀,然后将临时分⽀删除。

可是现在dev的代码在工作区中只进行开发了一半,还是不能提交:

可以看见checkout到master显示test修改了(modify)

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

而存储位置则是在:

多了一个stash,再看工作区就是干净的,(除⾮有没有被Git管理的⽂件),因此可以放⼼地创建分⽀来修复bug。

储藏 dev ⼯作区之后,由于我们要基于master分⽀修复bug,所以需要切回 master 分⽀,再新

建临时分⽀来修复bug,⽰例如下:

前面说git branch可以创建分支,那么这里顺带演示前面第三点所说的git checkout -b[]创建并切换到该分支

修复完成后,切换到master分⽀,并完成合并,最后删除fix_bug分⽀:

⾄此,bug的修复⼯作已经做完了,我们还要继续回到dev 分⽀进⾏开发。切换回dev 分⽀:

可以发现工作区是干净的,那么刚才的工作内容呢?(git stash list命令)

⼯作现场还在,Git把stash内容存在某个地⽅了,需要恢复⼀下,可以使
⽤git stash pop 命令,恢复的同时会把stash也删了,⽰例如下:

再次查看的时候,我们已经发现已经没有现场可以恢复了

另外,恢复现场也可以采⽤git stash apply 恢复,但是恢复后,stash内容并不删除,你需要
⽤git stash drop 来删除;
你可以多次stash,恢复的时候,先⽤git stash list 查看,然后恢复指定的stash,⽤命令
git stash apply stash@{0} 。
恢复完代码之后我们便可以继续完成开发,开发完成后便可以进⾏提交。

但我们注意到了,修复bug的内容,并没有在dev 上显⽰。此时的状态图为:

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

我们的最终⽬的是要让 master 合并 dev分⽀的,那么正常情况下我们切回master 分⽀直接合并即可,但这样其实是有⼀定⻛险的。是因为在合并分⽀时可能会有冲突,⽽代码冲突需要我们⼿动解决(在 master 上解决)。我们⽆法保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只⼀两⾏那么简单, 有可能⼏⼗上百⾏,甚⾄更多,解决的过程中难免手误出错,导致错误的代码被合并到master上。此时的状态为:

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

对应的实操演示如下:

首先dev合并master,会发现发生了冲突

解决冲突重新提交,再切回master,再进行合并分支,最后删除分支

十、删除临时分支

软件开发中,总有⽆穷⽆尽的新的功能要不断添加进来。 添加⼀个新功能时,不希望因为⼀些实验性质的代码,把主分⽀搞乱了,所以,每添加⼀个新功能,最好新建⼀个分⽀,我们可以将其称之为feature 分⽀,在上⾯开发,完成后,合并,最后,删除该 feature 分⽀。

可是,如果我们今天正在某个feature分⽀上开发了⼀半,被突然叫停,说是要停⽌新功能的开发。虽然⽩⼲了,但是这个feature 分⽀还是必须就地销毁,留着⽆⽤了。这时使⽤传统的 git branch -d 命令删除分⽀的⽅法是不⾏的。演⽰如下:

创建并切换到feature分支,开发新功能

提交后被叫停,准备切回主分支删除feature分支

就会发现常规方法删不了,需要使用git branch -D

上一篇:(JVM)我们该如何认识 Java的内存模型(Java Memory Model(JMM))? 本篇文章告诉你答案 !带你全面了解JMM


下一篇:react useRef