Git学习笔记4
4 Git 分支理论
4.1 Git 主干
Git是以时间为主线对版本进行管理的,而这条时间主线就是Git主干。主干上的每一个节点就是一个版本,即一次commit提交。在主干上可以定义多个指针,指向不同的节点。Gi默认会创建一个名称为master的指针。默认情况下用户操作的是master指针,但用户通过命令对操作的指针进行切换。用户每次提交一次,就会形成一个新的节点,当前操作的指针就会向前移动一次。
4.2 Git 分支
为了更加形象的描述指针的移动轨迹,称某一个指针的移动轨迹为一个分支。这样的话,一个指针就代表了一个分支,可以使用不同的指针操作不同的分支。
master指针的移动轨迹与Git的主干是重合,所以称为master主分支。
Git中还有一个特殊的指针叫HEAD,代表当前版本。其总是指向当前分支的当前版本,即总是指向当前分支指针所指向的节点(版本)。Git创建一个分支是很快,例如,创建一个新的分支dev,就是创建一个dev指针。而分支的切换就是修改HEAD指针的指向。一旦切换到另外一个分支dev,那再往向的提交commit都是提交到新支付dev上了,即dev指针向后移动,但是master指针是不动的。当前,在多分支下,可以在各个分支间任意切换,切换后均可进行各自的提交,而各自的提交与其它分支是无关的。
4.3 分支合并
当前dev分支上的工作完成后,需要将其合并到主分支master上。合并过程其实很快,只需要将master指针指向dev指针指向的节点,然后再将HEAD指针指向master指针指向的节点即可。即分支的合并就是修改了两个指针的指向而已。对于合并的较形象的理解是,合并就是将原来在dev分支上的节点,全部投射到master分支上,即全部合并到master分支上。
4.4 合并后的删除
将dev分支合并到master分支修改的仅仅是master与HEAD指针,而dev指针并未修改。即仅仅是将dev上的节点投射到master分支上,并未将master分支上的节点投射到dev分支上。所以合并后,dev分支中的节点会少于master分支上的节点,即dev分支上的文件版本低于master分支的。例如上图中的最后一个紫色的节点,其为master分支上的节点,表示master分支修改并提交了某文件,但dev分支上并未修改该文件,所以合并后dev分支的该文件版本低于master分支上该文件的版本。合并后的dev分支不仅无用,它的存在还会引起不必要的麻烦
4.5 分支基本操作
4.5.1 创建并切换分支
git checkout -b 分支名称
命令:创建并切换到dev分支:git checkout -b dev
该命令等价于两条命令:
git branch dev:新建分支
devgit checkout dev:切换到分支dev
4.5.2 查看系统分支
该命令会列出当前系统中存在的所有分支,且当前分支前会显示 *
4.5.3 切换分支命令
git checkout 分支名称
4.5.4 删除分支命令
git branch -d分支名称
若要删除某分支,必须要保证当前分支不能是要被删除的分支。
4.5.5 合并分支命令
git merge
对于分支的合并需要注意,如果要将分支B合并到分支A上,首先要将当前分支切换到A分支上,然后再运行合并命令。下面演示合并过程:当前处理dev分支,在该分支下为hello.html文件添加一行新内容 five Line。然后add添加并commit提交,此时commit到的是dev分支,而非master分支。查看dev和master分支中的hello.html文件内容
在dev分支中给hello.html文件添加一行“five line”内容
再切换到master分支,查看hello.html文件内容,发现并没有新添加的five line内容。这是为什么呢?因为两个分支指针指向的分支节点是不同的。
将dev分支合并到master分支。必须要确保当前牌master分支。
在dev分支新添加 six line, master分支不merge dev分支,可以看到 git log 是不一样的
4.5.6 分支合并与冲突
Git的冲突检测单位是文件,即当不同分支对同一个文件进行修改后进行合并,就会产生冲突。这是与SVN不同的。SVN检测冲突是文件中的列
若两个分支修改的不是同一个文件,合并时肯定不会产生冲突;但若修改的是同一个文件上的不同行的内容,合并时也不会产生冲突;若修改的是同一个文件上同一行上的不同列,在合并的时候也不会产生冲突。只有两个分支修改的是同一个文件同一行中同列数据的时候,在合并时才会产生冲突.
(一)产生冲突的合并
A.查看两分支下的文件内容查看master与dev两分支下的hello.html文件内容:两文件内容一致
B.修改dev分支下的文件
在dev分支下使用vim编辑器修改hello.html文件,将第二行的”two Line”改为“2 line”,然后添加add并提交commit.
C.修改master分支下的文件
在master分支下使用vim编辑器修改hello.html文件,将第三行“three line”改为“3 line”,然后添加add并提交commit。
D.合并后出现冲突
由于dev分支下修改的结果是,第二行内容为“2 line”,第三行内容为“three line”;Master分支修改结果是,第二行内容为“two line”,第三行内容为“3 line”。合并后到底第二行和第三行内容应该是什么?这就是冲突。冲突将导致合并失败。
查看git状态:给出合并没有成功的提示
在master分支下,查看hello.html文件内容:可以看到发生冲突的提示内容
=======为冲突内容分隔线;
<<<<<<< HEAD到分隔线的内容表示:当前分支中的内容
分隔线到>>>>>>> dev的内容表示:合并来的dev分支的内容
E.解决冲突
解决冲突的方法就是手工修改冲突内容,然后add添加并commit提交。内容可以任意修改,例如本例是将修改内容合了一行。
F.查看冲突解决后两分支文件内容
需要注意,冲突解决后提交的最终版本,即合并后的版本,仅仅是master分支中的版本,dev分支中的版本仍然是合并前的版本。即对于解决冲突后的master中的版本要超前于dev中的版本。
由于合并的本意是将dev分支上完成或阶段性完成的工作提交到master分支中,dev分支的工作就暂告一个段落。后面dev分支上的工作再开始时,要与master分支的内容保持一致,从master分支内容开始,所以一般在合并后,会立即将dev分支删除。再开始时,重新创建dev分支。查看master分支中的版本,为解决冲突后合并的最终版本。
G.查看历史版本中的合并显示
以最普通的方式查看历史版本,并体现不出合并的发生。
可以在命令后添加—graph选项,以图形化的形式显示出合并的出现。可以看出该文件发生过两次合并。
该方式下的commit-id显示的是全长度id,可以以简写的commit-id显示,只需要添–abbrev-commit。abbrev是缩写,简写
合并后将dev分支删除