Git分支

Git对象

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

  • blob对象:用来存储Git仓库中的文件快照
  • tree对象:用来管理文件或者目录, 它记录了若干个blob对象或者其它的tree对象
  • commit对象:包含着指向树对象的指针和作者,时间,提交信息
  • tag对象:包括一个对象名(SHA1签名)对象类型、标签名、标签创建人的名字, 如果是附注标签,则还有标签信息

查看对象:

git cat-file 对象ID

常用参数选项:-t表示查看对象类型, -p表示查看对象内容
例:查看某次提交后,git各种对象的组织结构:
一次提交后对象的组织结构.png

objectStruct.png
因为1.txt和2.txt都为空文件,所以这两个文件被同一个blob对象表示

现在我修改这个两个文件,然后在提交:
第二次提交后.png
第二次提交后对象结构.png

可以看出commit对象之间以链表的形式组织起来,当前的提交对象中记录了上次提交对象的SHA1校验和
另外在git命令行中有如下的高亮显示:
HEAD_MASTER.png
这里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参数强行删除

原文地址:https://www.cnblogs.com/UnknowCodeMaker/p/11208209.html