美文网首页
git原理探索(二)

git原理探索(二)

作者: 若兮缘 | 来源:发表于2018-12-11 19:59 被阅读170次

    git对象

    每一个git对象都由3部分组成:类型(type)、大小(size)和内容(content)
    大小就是内容的大小,内容取决于对象的类型,主要有4种类型 - blobtreecommittag
    使用git cat-file -t hash值可以查看文件类型

    blob对象

    用于存储文件数据。它通常是一个文件,注意它只包含文件内容并不包含文件名

    tree对象

    基本上就类似一个目录,它引用了一堆其他的tree对象或者blob对象,其实就是包含一些子目录及子文件

    commit对象

    指向一个tree对象,它标记着项目在某个时间点的状态,即代表着项目的一个版本历史,多个commit对象就形成了版本历史链条。
    它包含了项目的一些元信息,比如时间戳、自上一次提交后所作更改的作者信息,一个指向上一次提交对象(parent)的指针

    对象示意图
    对象关系图

    圆形代表commit对象,commit对象指向tree对象,而tree对象又指向了其他的tree对象和blob对象。
    多个commit对象形成了一个有向无环图(DAG)

    tag对象

    通常用于标记一个特定的项目版本,它指向了一个commit对象,并且指针不会移动,与commit对象完全绑定,通过tag标记对象可以将某个重要版本提取出来作为展示,也可以回退到该版本进行开发。
    tag分为两种:
    一种轻量级的对象,只指明当前tag名称,通过执行git tag "name"命令,它实际上只生成了一个指针文件,保存在.git/refs/tags目录中。
    另一种重量级的tag对象,可以为当前tag指定一些说明信息,通过执行git tag -a "name" -m "msg"命令,它实际上也会生成一个指针文件,同时在objects目录下生成了一个tag对象,并且tags目录的指针文件指向了该tag对象

    对象 & 引用

    GIT对象是不可变的,也就是说它们永远不会被改变,对于文件的修改会以创建新的对象形式体现。
    GIT中也包含了一些引用,与对象不同,引用可以不断变化,它们是指向特定commit对象的简单指针,类似tag,但是很容易移动,这些引用包含了Branches(分支)、HEADRemote branches(远程分支)

    对象与引用关系图

    如图remotebranch分别代表远程分支引用,本地分支引用,分支引用都指向了一个commit对象,但是指针可以移动。
    HEAD引用则指向了一个本地分支,tag引用/对象始终与某个commit对象绑定,不会移动。
    事实上我们可以将一个commit对象和其引用的treeblob对象看作一个整体,方面从宏观上理解分支,如右图所示。

    HEAD引用

    使用cat命令查看HEAD文件的内容,显示引用了refs目录下的一个master文件,refs目录下保存了heads和tags目录,这两个目录都是保存指向数据引用的文件,而文件保存的内容就是一个hash值,该hash值对应的是一个commit对象

    HEAD代表了当前活动分支的引用,当前工作分支是哪个HEAD就指向谁,一旦切换分支HEAD又会移动到新的工作分支,
    在我们初始化git仓库时,默认就会有一个master分支,所以HEAD初始会指向master分支,即refs下的master文件。
    使用git checkout -b "name"命令创建并切换到指定分支后,再次查看HEAD就指向了新的分支。

    演示git对象

    一次提交操作

    创建一个文件,执行git add操作和git commit操作,在此过程中git分别做了什么,创建了哪些对象?

    1. 新建目录demo,新建readme.txt文件,随便写入一些内容。然后执行git init初始化本地仓库。
      执行git add操作,会对文件进行hash取值,将hash值前两个字符作为目录,后38个字符作为文件名,存放在git目录下的objects目录中,该文件仅仅保存文件内容,然后会在git目录下生成一个index文件,该文件就代表了暂存区,通过cat命令可以看出暂存区保存了文件相关信息比如文件名。
    1. 执行git commit操作,首先会创建一个tree对象,它指向了刚才创建的blob对象,然后创建一个commit对象,用于记录版本历史,它指向了刚才创建的tree对象,即 commit --> tree --> blob
    查看对象内容

    blob保存文件内容,tree包含了blob对象hash值及文件名、权限等,commit包含了commit对象和tree对象的hash值及提交作者和提交信息等。
    查看blob对象:git show hash值
    查看tree对象:git ls-tree hash值
    查看commit对象:git show -s --pretty=raw hash值
    命令中的hash值不用输入全部,只要能唯一区分就行

    多级目录操作

    有如下目录结构,根目录 - 2个子目录 - 3个子文件,文件都是有内容的且各不相同

    执行git add .git commit -m操作后,一共生成了7个对象,其中1个commit对象,3个tree对象,3个blob对象

    它们的关系图如下

    相关文章

      网友评论

          本文标题:git原理探索(二)

          本文链接:https://www.haomeiwen.com/subject/icbehqtx.html