前言:
Git分支管理是一种强大的版本控制策略,它允许开发者在不影响主代码库的情况下,进行并行开发和实验。以下是Git分支管理的简单文字介绍:
Git分支是代码库中的一条独立路径,每个分支都包含了项目的完整历史记录和文件。通过创建分支,开发者可以在不影响主分支(通常称为
main
或
master
)的情况下,进行新功能的开发或错误的修复。
开发者通常会在开始一个新功能或修复时,从主分支创建一个新的特性分支。在这个分支上,他们可以自由地进行开发、测试和提交更改。一旦特性完成并经过测试,它就可以被合并回主分支,从而成为项目的一部分。
除了特性分支外,开发者还可能使用开发分支来集成多个特性分支,进行进一步的测试,并最终准备发布。开发分支通常包含了所有即将发布的功能,但可能还需要进行一些调整和优化。
有时,开发者可能还需要创建热修复分支来处理主分支上的紧急问题。这些分支通常是从主分支直接创建的,并在修复完成后尽快合并回主分支和开发分支。
在Git分支管理中,合并分支是一个重要的操作。它允许你将一个分支的更改合并到另一个分支中。在合并之前,Git会自动进行冲突检测和解决,以确保合并后的代码是正确和一致的。
那么现在,就进入分支的简单讲解部分。
理解分支
学习分支管理之前,我们总得知道什么是分支吧?
我们不妨拿高考举例子,我们一共有6条学习路线,分别学习语数英,物化生,这六条分支学习加起来,构成了最后高考的我们。
从这个例子,我们可以看出分支管理的强大,即各个分支之间不影响,并且如果一个分支完备了,就变成了我们最后项目的一个部分,这是分支的简单理解。
创建 合并 删除初体验
前文提及,版本库里面的HEAD指针指向的就是分支,版本回退是通过改变master的指向快速实现的。
而当我们第一次创建.git文件的时候,就会默认生成master分支:
使用命令cat-file -p可以查看该分支最近一次的commit:
现在先记住这两个commit id,85e0 7bfe。
首先要创建分支,我们就应该查看有哪些分支:
指令git branch就知道目前的分支有哪些,并且*master就是代表目前指向的分支是哪个。
查看之后,我们需要创建分支同样使用命令git branch [branchname]即可:
此时分支就创建成功了,创建之后,我们如何删除该分支呢?使用命令git branch -d即可删除,但是这里要注意的是不能在当前分支删除当前分支,所以我们如何进行切换呢?
分支切换本质就是修改HEAD指针的朝向就可以了,使用命令git checkout dev即可,在上文的撤销操作上面的git checkout -- [filename]是用来删除工作区的内容的,这里不用加--,只需要checkout分支就可以了:
此时分支切换成功,同时,我们不妨看看该分支有没有内容:
我们返回最开始打印master分支的时候,出现的两个git对象也是这个,所以dev分支实际上是基于最近一次commit创建的分支,不然这两个commit id也不会一样。
此外,切换之后,我们可以使用git branch查看是否切换成功:
*的改动也就代表了确实修改成功了。
好了,我们目前切换到了dev分支,那么我们在该分支尝试删除dev分支,看是否可行呢:
不出意外的报错了,那么我们就只有切换回去删除了。
此时,删除成功了。
那么我们再重新创建一下:
我们再看看git分支状态下,对于一个文件的修改所发生的现象,目前我们在master分支下修改一下file1:
此时切换到dev分支下并查看:
会神奇的发现没有我们刚才修改的代码了,这就是因为没有合并,此时,我们就需要合并才能让两个分支统一了,合并使用的指令是git merge,在master合并就是git merge dev:
那么里面的Fast-forward就是代表快进,因为dev分支是基于最近的一次分支创建的,所以相当于直接让master分支快进到该主线的下一步了。
这是创建 合并 删除的初体验。
值得一提的是,如果是没有add commit,其他分支是能看到该分支修改的文件的(前提是都拥有同一个文件)
合并冲突/模式
首先我们介绍合并冲突,冲突就像,两个分支修改同一份文件,并且都add commit了,那么比如master分支将文件修改为aaa,dev分支将文件修改为bbb,那么合并的时候,就会冲突,因为git它自己是不知道要保存哪份文件的,所以合并冲突我们都是只能通过自己来解决,那么我们先来看看现象。
对于创建分支来说,我们可以git checkout -b,即创建新分支的同时将HEAD指针的指向改到为新分支上面去:
我们就现在dev分支下完成对file1的修改并且add commit了:
现在切换分支,然后在master分支下对file1进行修改并add commit:
此时,merge冲突的基本要素已经有了,我们merge一下:
也是不出意外的报错了,那么如何解决合并冲突呢?
我们只需要将冲突的文件手动修改一下就可以了:
此时打开file1是这样的,<<<到===中间,====到>>>>中间代表的就是冲突的修改,那么我们想要保存哪个就将另一个删除即可:
此时我们不能直接合并,我们需要将文件add并且commit,git会自动将文件合并的,此时就解决了。
那么对于合并的具体图,我们使用log的指令就可以:
git log --graph --abbrev-commit
git log --graph --abbrev
使用上面的命令就是commit id会变得简短,下面的更加全面:
此时的图形化界面就是这样的。
那么合并之后,dev分支还在合并之前的,master是在合并之后,我们不妨看看:
这是合并冲突。
那么对于合并模式来说,我们前文提到的,Fast-forward模式来说,是快进模式,还存在一种模式是非Fast-forward模式:
先来看现象,第一个红线,是Fast-forward模式下的merge,而有两条线的是no-ff下的merge,也就是非快进模式,那么,为什么存在两种方式呢?
如果是fast模式,提交的时候缺失了一条分支信息,但是这是不利于开发的,所以存在了非快进模式,可以保证分支信息的完整,即便是我们删除了dev分支,我们依旧能在提交信息上看到对应的分支修改信息。
指令为:
git merge --no--ff -m "xxx" [the other branch]
一般都是推荐非快进模式作为合并模式。
这里简单引入分支策略。
实际开发过程中,master分支应该是非常稳定的,也就是新版本发布是在上面发布,而不能在上面进行开发,所以平常的开发都是在分支上进行开发,比如dev分支等:
最上面的是master分支,平常开发的时候更多的时候就像这样,如果master分支上面开发,该软件或该网站八成都是要崩溃的,毕竟谁开发没有bug呢?
那么如果发现了bug,如何解决呢?是在master主分支上直接解决吗?当然是不可以的,肯定是需要在其他分支上解决,并且合并的,那么用来专门解决bug的分支就叫做bug分支。
比如master分支上出现了bug,但是分支dev的工作区内容并没有开发好,所以不能merge,此时就需要将工作区的内容暂时存储,并且重新创建一个新的分支用于bug修复,存储目前工作区的内容是git stash:
对于dev来说,新增的工作区的内容是This is test bug,那么我们需要将该代码进行临时存储:
工作区的临时内容就已经存储上了。
那么我们需要创建临时的分支用于解决该bug,但是为什么不直接在dev分支上解决呢?类似于一种备份,我们不能确保在dev上一次性能解决bug,可能改着改着改出来了更多的Bug?创建新分支的意义是确保开发的安全性。
创建bug修复分支,应该回到master分支上创建,而不是在开发分支dev上创建:
此时创建好了,我们应该打开file1删除修改对应的Bug:
假设对应的Bug是多出来的aaabbbccc那句话,删除之后,add commit然后no ff合并:
此时合并完成,bug修改成功,我们看看结构图:
可是现在有一个问题是,dev分支怎么办?dev里面的bug还没有修改。
这个我们先别急,我们不是使用了stash命令吗?我们看看.git:
.git存在了stash,也就是我们存储的内容,我们可以看看存储了什么:
既然有对应的commit id,所以:
这就是存储的内容,那么我们可以通过stash pop放出我们的代码:
此时就放出来了,但是Bug依旧存在,这里的一个好习惯是在dev分支下和master分支合并,而不是在master分支上合并dev分支,这肯定是不行的,所以:
但是肯定是合并之后,才放出工作区的代码:
放出来之后的情况就是合并冲突的情况,我们合并一下,add就可以了:
那么fix_branch用完了我们删除了就是。
那么这里的一个小场景是,如果上午开发了一个功能,在新分支上,突然产品经理说不要了,那么此时没有merge是不能直接删除的,需要使用git branch -D才能删除。
对于合并介绍这么多,倘若有错误的地方,欢迎指正。
感谢阅读!
版权归原作者 _lazy. 所有, 如有侵权,请联系我们删除。