Git 的原理与使用(中)(二)

简介: Fast Forward 模式(ff模式)通常合并分支时,如果可以,Git 会采用 Fast forward 模式。

Git 的原理与使用(中)(一)+ https://developer.aliyun.com/article/1521951?spm=a2c6h.13148508.setting.14.439a4f0e3zzkc2


补充:查看分支合并的情况


用带参数的 git log 命令可以看到分支的合并情况:


命令:git log --graph --abbrev-commit



上图中,星号  *  代表的就是之前的“提交(commit)”。


最后,不要忘记dev1分支使用完毕后就可以删除了:git branch -d dev


8.分支管理策略


Fast Forward 模式(ff模式)


通常合并分支时,如果可以,Git 会采用 Fast forward 模式。


Fast forward 模式形成的合并结果:





在Fast forward模式下,当我们合并分支后查看分支历史时,分支历史的展示中会丢失部分分支信息,即看不出来最新的提交到底是merge进来的还是正常提交的




非Fast Forward模式(no-ff模式)

我们知道,当发生合并冲突时,在解决冲突问题后还需要再进行一次新的commit,然后才能得到最终状态:



这里就不是 Fast forward 模式了。


在非 Fast forward 模式中,从分支历史上是可以看出分支信息的。例如我们现在已经删除了在合并冲突部分创建的 dev1 分支,但依旧能看到 master 其实是由其他分支合并得到的:



如何在正常提交的时也选择no-ff模式呢?


Git支持我们强制禁用fast forward,那么就会在 merge 时生成⼀个新的 commit 。这样,从分⽀历史中就可以看出分支信息。


在执行 git merge 时添加 --no-ff 选项,就表示不使用ff模式。--no-ff选项表示的就是禁用 Fast forward 模式。禁用 Fast forward 模式后,在合并分支后会创建一个新的 commit ,所以要加上-m参数,把描述(message)也写进去:



由下面的图可知,在no-ff模式下生成一个新的commit,最终master也会指向一个新的提交:





ff模式和no-ff模式最大的区别是,用 git log --graph --abbrev-commit命令查看提交日志时,能否区别出git的master中的每个commit是merge进来的还是正常提交的。


(在企业实操中一般更建议使用no-ff模式。)


9.分支策略




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


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


干活都在dev分支上。(dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本)。


你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。





所以,团队合作的分支看起来就像这样:





10.bug分支


假设我们现在正在 dev2 分支上进行开发,开发到一半还没提交,突然发现 master 分支(即线上环境的代码)上有严重的 bug(如闪退之类的),需要马上解决。


直接在master主分支上编辑代码进行bug修复,这肯定是不可以的。


安全起见,必须遵守分支的策略,即在本地创建一个新的临时分支来修复,修复后,经过测试团队的测试后将稳定的代码合并到master分支,然后将临时分支删除。




可现在dev2的代码在工作区中开发了一半,还无法提交,而要修复master中的bug怎么办?


dev2中的修改都在工作区中,dev2在工作区中的做的修改会影响在其余分支的工作区进行工作。此时就需要先对dev2工作区中的内容进行保存。Git 提供了


git stash

命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来:



执行完git stash命令后,tree ./git,可以查看到当前git目录下多了一个stash目录,dev2的修改就被存储在这个stash目录中:



git stash后用git status查看工作区,工作区是干净的(除非有没有被 Git 管理的文件),因此可以放心地创建分支来修复bug:



注意,如果工作区还有没被 git 管理起来的文件,则该文件不能被暂存起来:



储藏dev2工作区之后,由于我们要基于master分支修复bug,所以需要切回分支,再新建临时分支来修复bug,示例如下:




修复完成后,切换回master主分支,并将bug分支合并到master分支,最后删除bug分支即可:




至此,针对master主分支上的bug修复工作(即:切回主分支,拉一个bug_fix新分支,在bug_fix上修复完bug后再合并到master这样的一系列操作)已经做完了,我们还要继续回到dev2分支进行一开始未完成的内容的开发。


切换回dev2分支:



在dev2分支下检查 git status会发现,工作区是干净的:


hyb@bite:~/gitcode$ git status
On branch dev2
nothing to commit, working tree clean

可以用git stash list查看stash存放哪些内容,使用


git stash pop


命令来恢复现场,恢复的同时会把stash中的内容删了,示例如下:



补充: 恢复现场除了 git stash pop, 也可以采⽤ git stash apply 。但是,用git stash apply恢复后,stash内容并不删除,需要我们自己调⽤ git stash drop 来删除。可以多次进行git stash,恢复的时候,先⽤ git stash list 查看,然后恢复指定的stash,⽤命令git stash apply stash@{0}即可。


再次查看stash中的内容,我们已经发现已经没有现场可以恢复了:  


hyb@bite:~/gitcode$ git stash list
# 没有内容显示

恢复完工作区的代码之后,我们便可以继续在dev2完成开发,开发完成后便可以进行提交:






但修复bug的内容并没有在 dev2 上显示。


为什么dev2下的ReadMe文件中,内容还是abcde而不是abcdef呢?这是因为创建dev2的时候,是基于还未修复的master的,也就是还有bug的master的。


此时的状态图为:



最终目的是要让 master 分支和 dev2 分支合并。正常情况下我们切回 master 分支,直接将dev2分支的内容合并到master中即可,但这样其实是有一定风险的。


因为在master分支与dev2分支合并时可能会发生冲突,而代码冲突需要我们手动解决(在 master 上解决)。我们无法保证对于冲突问题可以正确地一次性解决掉,因为在实际的项目中,代码冲突不只一两行那么简单,有可能几十上百行,甚至更多,解决的过程中难免手误出错,导致错误的代码被合并到 master 上。此时的状态为:


解决这个问题的一个好的建议是:先在自己的dev2分支上合并 master主分支,再让 master 去合并dev2分支。这样做的目的是,一旦有冲突可以在本地分支dev2上解决并进行测试,而不影响 master 。


此时的状态为:



实操演示如下:




最后执行 git branch -d ,将已经完成使命的dev2分支和bug_fix分支合并即可。


疑问解决


对于上述分支策略下的一系列操作,有的朋友可能会有疑问:dev2从master中拉出来的时候,ReadMe文件内容是abcde;但是master后来又拉了bug_fix分支,并把内容改成了 abcdef。如果工作区是共享的话,在bug_fix分支更改为abcdef的时候为什么没有影响到dev2分支呢?


原因:


abcdef已经提交了,属于版本库的内容,对于master来说,此时工作区是干净(clean)的,无变动。工作区是干净的,那么dev2分支的工作区也是干净的。git是基于提交来管理文件的,提交之前工作区共享。提交之后,提交的内容就已经被隔离了。


也就是说,如果bug_fix分支改成abcdef之后,没有进行add操作,那么bug_fix、master和dev2三个分支工作区的内容都会是abcdef;而如果bug_fix提交修改之后,工作区变成干净的,其他的分支的工作区也会变回原本的样子。


11.删除临时分支


软件开发中,总有无穷无尽的新的功能要不断添加进来。


添加一个新功能时,我们肯定不希望一些实验性质的代码把主分支搞乱了。所以,每添加一个新功能,最好新建一个分支,我们可以将其称之为 feature 分支。在feature 分支上进行开发,开发完成后再合并,最后删除该 feature 分支。


可是,如果我们今天正在某个 feature 分支上开发了一半,被产品经理突然叫停,说是要停止新功能的开发。虽然白干了,但是这个 feature 分支还是必须就地销毁,留着无用了。


这时使用原来的 git branch -d 命令删除分支的方法是不行的。


之前之所以有可以用git branch -d删除分支的情况,是因为当时已经把分支和master主分支merge过了。而如果当前分支没有和master主分支merge过、且已在当前分支进行过一些提交的时,git是会在删除时保护当前分支的(git认为只要分支被创建出来了且在上面有过提交,那么这个分支就是有用的,不能随便删除)。


使用


git branch -D

命令则可以强制删除:




12.分支小结


分支在实际中有什么用呢?


假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样既安全,又不影响别人工作。


并且 Git 无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。


六、远程操作


1.理解分布式版本控制系统


我们目前所说的所有内容(工作区,暂存区,版本库等等),都是在本地,也就是在你的笔记本或者计算机上。而我们的Git其实是分布式版本控制系统。什么意思呢?


可以简单理解为,我们每个人的电脑上都是一个完整的版本库,这样你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。






分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。


在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了。也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。有了这个“中央服务器”的电脑,这样就不怕本地出现什么故障了(比如运气差,硬盘坏了,上面的所有东西全部丢失,包括git的所有内容)。


Git 的原理与使用(中)(三)

+https://developer.aliyun.com/article/1521975?spm=a2c6h.13148508.setting.16.439a4f0eWJ4WIw


相关文章
|
7月前
|
Linux 网络安全 开发工具
1.Git使用技巧-基础原理
1.Git使用技巧-基础原理
69 0
|
Linux 网络安全 开发工具
【Git】Git 原理和使用
【Git】Git 原理和使用
420 4
|
7月前
|
存储 开发工具 git
Git的基本操作和原理
Git的基本操作和原理
|
4月前
|
存储 开发工具 数据库
Git的工作原理是什么
【8月更文挑战第24天】Git的工作原理是什么
57 0
|
6月前
|
前端开发 持续交付 开发工具
详细介绍Git的基本原理、在前端开发中的应用以及如何使用Git来优化团队协作
【6月更文挑战第14天】Git是前端开发中的必备工具,它通过分布式版本控制管理代码历史,支持分支、合并和冲突解决,促进团队协作。在前端开发中,Git用于代码追踪、版本控制、代码审查和持续集成部署,优化团队协作。制定分支策略、编写清晰提交信息、定期合并清理分支以及使用Git钩子和自动化工具能进一步提升效率。理解并善用Git,能有效提升前端项目的质量和开发效率。
84 3
|
7月前
|
运维 测试技术 开发工具
Git 的原理与使用(下)(二)
新特性或新功能开发完成后,开发人员需合到 develop 分支。
58 2
|
7月前
|
Java 网络安全 开发工具
Git 的原理与使用(中)(三)
别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。
48 1
|
7月前
|
安全 Java 开发工具
Git 的原理与使用(中)(一)
分支是Git的杀手级功能之一。
55 1
|
7月前
|
存储 算法 开发工具
Git 的原理与使用(上) (二)
如果直接将某个文件拷贝到 .git 文件的同级目录gitcode下,此时这个文件是不会被Git管理的。
59 1
|
7月前
|
Linux 开发工具 git
Git 的原理与使用(下)(一)
在完成origin/dev分支合并到origin/master分支的操作后,origin/dev分支对于我们来说就没用了,那么dev分支就可以被删除掉。
68 0