Git分支
Git对象
简单了解下git对象,有助于对分支的理解,在git系统中共有四种对象:blob对象,commit对象,tree对象,tag对象
这四种对象存储数据的格式相同,格式如下:

content:表示存储的数据内容
head:表示对象的头部信息                
   object type:表示对象类型,为字符串,取值为"blob","commit","tree","tag"  
   whitespace:一个空格
   content byte size:content的大小
   NUL:空字符'\0'
Git按照这种数据格式存储对象,并使用SHA1摘要算法对整个对象提取出40个字符,并以前两个字符作为文件夹名称,
后38个字符作为对象的文件名存储在文件夹中,git所有的对象全部存放在./git/objects/下,例如:

- blob对象:用来存储Git仓库中的文件快照
- tree对象:用来管理文件或者目录, 它记录了若干个blob对象或者其它的tree对象
- commit对象:包含着指向树对象的指针和作者,时间,提交信息
- tag对象:包括一个对象名(SHA1签名)对象类型、标签名、标签创建人的名字, 如果是附注标签,则还有标签信息
查看对象:
git cat-file 对象ID
常用参数选项:-t表示查看对象类型, -p表示查看对象内容
例:查看某次提交后,git各种对象的组织结构:


因为1.txt和2.txt都为空文件,所以这两个文件被同一个blob对象表示
现在我修改这个两个文件,然后在提交:


可以看出commit对象之间以链表的形式组织起来,当前的提交对象中记录了上次提交对象的SHA1校验和
另外在git命令行中有如下的高亮显示:

这里master是一个分支,在我们执行git init时,git会默认创建一个master分支,HEAD始终指向本地当前的分支
分支操作
- 
创建分支 git branch 分支名称 例:创建一个名为Testing的分支 
 ![gitbranching.png]() 从例子中可以看出新创建的分支指向最近一次的commit对象 
 可以使用git log --decorate命令来查看当前所有分支指向的对象:
 ![查看当前所有分支所指对象.png]() 
 修改文件然后提交,在查看所有分支所指对象:
 ![修改后当前所有分支所指对象.png]() 
 Testing分支和master分支指向不同的提交对象
- 
切换分支 git checkout 分支名称 例:切换到Testing分支 
 ![切换分支.png]() 
 可以看出HEAD已经指向Testging分支当前处于Testing分支下,现在在做一个有意思的测试,先查看一个文本文件的内容: 
 ![2txtbeforecheckout.png]() 
 然后修改这个文件内容为"Learning git",然后在提交修改,然后把分支切到master:
 ![2txtafter.png]() 
 可以看出切换分支后,2.txt的文件内容被恢复到master分支最后一次提交时的内容可以使用git log命令简单查看下各分支的提交历史以及分叉情况: 
 ![各分支提交情况.png]() 
- 
合并分支 git merge 分支名称 - 
无分歧合并 
 如果不知道本地当前用的是哪个分支,则可以使用:git branch 来查看: 
 ![gitbranch.png]() 
 git branch命令列出了所有的分支,前面带有"*"的表示本地当前使用的分支现在切回master分支,在创建另一个新的分支Test1并切换到这个分支: 
 ![Test1branch.png]() 
 此时2.txt文件中的内容如下:
 ![2txt的内容.png]() 
 紧接着修改2.txt内容如下:
 ![修改2txt内容如下.png]() 
 然后提交修改,那么此时所有分支结构图如下图:
 ![Test1所有分支结构图.png]() 
 此时切到master分支,使用合并分支命令,将Test1合并到master分支:
 ![gitmergeTest1.png]() 
 此时2.txt内容如下:
 ![mergeresult.png]() 而此时的分支结构如下: 
 ![mergeTest1struct.png]() 
 ![MergeTest1Struct1.png]() 当Git在合并master和Test1分支时,从Test1分支出发可以找到master分支最后一次commit对象时,此时 
 Git只是将master的指向前移,使其指向Test1即可;在这种情况下没有需要解决的分歧,所以也可以成为
 无分歧合并(也称快进)
 
- 
- 
删除分支 git branch -d 分支名称 master和Test1合并后,也就不需要Test1分支了,此时可以删除它: 
 ![gitdelbranch.png]() 
- 
有分歧的分支合并 
 经过上面一通操作后,本地所有分支结构如下:
 ![删除分支后的结构.png]() 此时Testing分支和master之间无法通过一个分支找到另一个分支,第二次提交是两个分支公共的祖先,Git会使用 
 Testing分支和master分支的最后一次提交已经公共的第二次提交做一个三方合并,并生成一个新的提交对象,因
 为当前处于master分支并执行git merge Testing命令,所以master指向这个新的提交对象:
 ![mergeconflict.png]() 
 but....,合并时遇到了冲突,不要慌,这很正常,因为两个分支中2.txt的第一行内容不同,所以Git合并时会有冲突
 ,所以Git不会为此次合并创建一个合并提交对象,此时执行git status命令查看状态:
 ![gitmergeconflict.png]() 在查看下2.txt内容: 
 ![conflictcontent.png]() 可以看出Git已经将有冲突的内容写入到2.txt中,并使用"======="分割开来,但是Git并没有将其添加到暂存区, 
 这时候需要我们手动修改2.txt,然后对冲突文件使用git add 命令将其标记为冲突已经解决,当然也可以不做任
 何修改,直接暂存:
 ![commitServed.png]() 
- 
分支管理 
 查看分支列表git branch 例: 
 ![branchlist.png]() 
 分支前面有"*"则表示该分支是当前正在使用的分支
 查看每个分支最后一次提交:git branch -v 例: 
 ![20190718153617.png]() 
 查看当前分支已经合并的分支:git branch --merged ![mergedlist.png]() 
 前面有"*"表示已经当前分支,没有"*"的表示已经被合并的分支
 查看没有被合并的分支 git branch --no-merged 由于当前仓库就两个分支,而且Testing分支已经被合并,所以这里新建一个分支,并修改文件内容,然后提交修改: 
 ![20190718162317.png]() 切换到Test1分支后master就是未合并分支,为合并分支使用-d参数无法删除: 
 ![unmergeerror.png]() 
 可以使用-D参数强行删除
 
                    
                     
                    
                 
                    
                



























 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号