git 分支学习

git 分支主要用于在项目开发的过程中能够独立进行一些功能模块的开发,而不导致和主分支的项目有冲突,就好比你在本地开发一个ELK功能模块时,ELK环境是在本地环境中搭建的,不是在测试环境搭建,在这个开发过程中,开发过程中肯定少不了配置ES的连接,那这个时候配置的是本地环境的ip地址等,就会造成项目在启动过程会造成一些启动报错的问题。为了避免这种项目开发的冲突,这个时候可以在git本地仓库构建一个新的分支,这样就可以在新的分支中进行项目的开发,后期要进行功能模块的合成时这时候肯定测试环境或者生产环境是已经搭建好了的,就可以进行分支分支合成。这样就可以完成项目的分布式开发了。但这个时候也不一定就很完美,毕竟是分布式搭建,这还得对项目进行一下约定啥的,不然最后开发完成之后会造成项目中的文件会有冲突啥的。讲了那么多,下面我们还是来看一下啥是分支吧?

什么是分支?

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。为嘛会这样说呢?我们下面就创建一个test1分支来检测一下。

通过上面的图可以看到确实创建一个新的分支之后,新的分支的指针就指向了master分支,那这个我们也可以开检测一下,切换到其它分支时,在创建一个分支看一下,指针是否还是在master分支上。确实没有指向master分支,说明这个新分支的新建在哪个分支上新建指针就会指向对应的分支。那问题就来了,为嘛会这样呢?那这就确实说明这个分支和快照还真的有点关系的,那我们切换到test分支的情况下,这个时候快照都是test分支的,那指针怎么参照快照呢,肯定只能参照test分支下的。

了真正理解 Git 处理分支的方式,我们需要回顾一下 Git 是如何保存数据的。

 Git 保存的不是文件的变化或者差异,而是一系列不同时刻的 快照 

进行提交操作时,Git 会保存一个提交对象(commit object)。 知道了 Git 保存数据的方式,我们可以很自然的想到——该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。 首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象, 而由多个分支合并产生的提交对象有多个父对象,

为了更加形象地说明,我们假设现在有一个工作目录,里面包含了三个将要被暂存和提交的文件。 暂存操作会为每一个文件计算校验和(SHA-1 哈希算法),然后会把当前版本的文件快照保存到 Git 仓库中 (Git 使用 blob 对象来保存它们),最终将校验和加入到暂存区域等待提交:

$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'

当使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和, 然后在 Git 仓库中这些校验和保存为树对象。随后,Git 便会创建一个提交对象, 它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。 如此一来,Git 就可以在需要的时候重现此次保存的快照(这样就能够方便进行提交恢复)。

现在,Git 仓库中有五个对象:三个 blob 对象保存着(文件(README test.rb LICENSE)快照)、一个  对象 (记录着目录结构和 blob 对象索引)以及一个 提交 对象(包含着指向前述树对象的指针和所有提交信息)。

 那假如我们继续做些修改后再次提交,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针。为嘛会这样呢?无非就是快照吗?每次再建一个不就完了,为啥还要把上一个版本的提交对象作为父对象呢?其实这样的做的目的是为了回归版本来着吧,比如现在要提交一个版本,然后就把原有的版本信息全部覆盖了,那这个时候怎么回归到上一版本呢?那有人肯定会说记住上一次提交的commit id,或者记住上一版的commit 注释,这样也是可以的,但是这样找肯定也会出问题,这样存在父子关系,到时候就能够快速找到上一版,接着应该还有其它的作用之类的。暂时不太清楚,后期了解了再给增加上把。接着来看一下如何创建git 分支。

如何创建git分支?

 其实创建git 分支很简单,就一句命令执行就行。git branch <分支名> ,比如:git branch devloper.如果是在idea开发工具中进行分支的创建,直接点击左下角的git来进行创建,也是很方便。

点击git 会弹出一个菜单框,接着点击new branch 就行。这里需要注意的是,如果你有多个分支的话,这个时候你得选择你要在哪个分支进行新分支的创建,为嘛会这样说呢?因为你创建分支,说白了就是创建指针,指针得找到分支中上一次最后提交的快照。那么我们创建完分支是不是得检查一下分支创建完得指针是指向哪里的,因为这方便与我们在进行分支文件的开发的提交。可以通过执行

$ git log --oneline --decorate

 来查看分支的指针指向哪里。

分支创建完成之后,这个时候我们根本是没有进入到分支中的,那这时候就需要通过切换分支才能进入到创建的分支中。

如何切换分支?

要切换到一个已存在的分支,你只要使用 git checkout 命令。 就可以切换到新创建的 test分支去:

$ git checkout test

这样 HEAD 就指向 test 分支了。

那么接下来我们在新分支提交一个文件,提交完成之后我们看一下两个分支有啥变化,这时候我在test2分支下新建了一个cc.txt文件并提交了,这是发生变化了,指针往新提交的的快照上移动了。而test这个分支的指针却没有发生改变。

接着再在test2中新增一个cx.txt文件,可以进行add,但是不进行提交,我们再次进行分支的切换,接着看到的是在每个分支的暂存区中都可以看到,再来看看指针发生变化没,却都没发生任何变化。从这说明了一个问题,就是这个指针只能在提交的快照上进行移动,重点提示下,指针只能在提交的快照上进行移动。 那分支切换到底做了些什么呢?

分支切换实际做了两件事。 一是使 HEAD 指回切换分支的提交commit快照上,二是将工作目录恢复到分支所指向的快照内容。 也就是说,你现在做修改的话,项目将始于一个较旧的版本。 本质上来讲,忽略了上一个分支所做的修改,以便于向另一个分支进行开发。

分支切换会恢复到分支的目录下,那假如现在另外一个分支已经有相同的文件已经提交了,你在当前分支新建一个文件却没有提交,并且你想切换到另外一个分支,这时候是不能完成切换的,因为有相同的文件冲突了。

或者两个项目中都有相同的文件,然后两个开发者在相同的开发者在不太的分支都对同一个文件进行修改了,那这个时候在进行切换,也是切换不了的,这个时候就出现了分支交叉了。我们可以通过 git log --oneline --decorate --graph --all命令来进行查看。

好了,时间不早了,今天就分享那么多把,小弟不才,还望大家多指点,多评论,有啥错误的地方给小弟纠正下,谢谢。

原文地址:https://www.cnblogs.com/Hackerman/p/12549469.html