Day17|【Git】存在 .git 目录里的东西 - Blob 物件与 Tree 物件(上)

Git 有四种 type (类型) 的物件:blob、tree、commit 和 tag。

本篇主要先来讲解 Blob 物件与 Tree 物件。

本篇会使用到两个过去没使用的指令:git hash-objectgit cat-file -t
未来有机会可以介绍!


Blob 物件(Binary large object)

说明:Git 将档案内容转成二进制,并产生 SHA-1 编号後储存的物件。

产生时机:git add 加至暂存区时,在 .git 目录里产生一个 Blob 物件,并依照规则摆放在它的目录里。

用途:存放档案的「内容」。

⚠️ 注意:此处指的是档案里面的内容,即可能编辑的东西,而非档案本身。

🛠 实际操作|建立 Blob 物件 - 建立一个档案并加入至 Git 控管

  1. 首先先建立一个工作目录,并进行 Git 版本控制,执行 git init 初始储存库。

    $ git init # 初始化储存库
    

    https://ithelp.ithome.com.tw/upload/images/20211001/201410108WR3rCgkSL.png

    初始化新的数据库时,Git 会在 .git 目录中初始化 objects 目录,并在里面建立 pack 和 info 子层的空目录。

    https://ithelp.ithome.com.tw/upload/images/20211001/201410107ucHA3TYIz.png

  2. 假设今天我们建立了一个 demo.html 档案,并在档案里加上内容是 " hello world ! " 字串

    $ touch index.html # 新增一个 index.html 档案
    

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010tjt12TrVQt.png

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010duzU02Fm9m.png

    前几篇的文章我们可以知道,目前档案还没有被 Git 控管,因此我们可以透过指令将档案加至暂存区。

  3. 输入指令执行将档案加至暂存区,并检查状态

    $ git add . # 将所有档案加入暂存区
    $ git status # 检查档案状态
    

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010AdXHrswM3k.png

    👉 这时候,Git 会在 .git 目录下建立 blob 物件用来储存档案内容。

    可以从 objects 目录中发现,多了两个资料夹。更进一步查看会发现是个 38 字元的档案。

    资料夹的 2 个字元与档案的 38 个字元合起来代表这个 Blob 物件的 SHA-1 值,它是透过「规则」计算出来的。

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010wwlaVZG0xk.png

  4. 也可以透过手动执行 git hash-object 指令来计算

    $ echo 'hello world!' | git hash-object -w --stdin # 将资料储存在 .git 目录中,并取得 SHA-1 编号
    

    -w 参数

    将物件加入 .git/objects 目录内,并输出相对应的 SHA-1 值

    如果没有加上 -w 参数,只会输出 SHA-1 值,并不会储存物件

    --stdin 参数

    从 stdin 读取内容(stdin - standard input, 标准输入)

    如果没有使用 --stdin 参数,hash-object 指令预设会从档案中读取,因此需要在指令後面加上指定的档案路径。

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010affI4NFovp.png

    https://ithelp.ithome.com.tw/upload/images/20211001/201410105djOKAl4LN.png

    执行hash-object 指令後,会出现 40 个字元,这就是 SHA-1 值,是由储存的内容和 header 资讯所计算出来的。

    目录规则:

    子目录 - 前 2 个字元

    档名 - 剩余的 38 字元

💡 使用 2 个字元作为子目录,是避免让 .git/objects 目录因为档案过多而降低效能。

  1. 这个档案内容因为已经被压缩过,所以我们如果使用一班的文字编辑器是无法得知内容,不过可以使用 git cat-file 指令察看物件资讯

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010DMXJ3UVVSO.png

    $ git cat-file -t a0423 # 查看物件资讯(型态)
    

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010iuwcc9pHaN.png

    -t 参数,代表要查看的是内容的物件型态,因此得到的回馈会是 blob 物件

    如果想要看这个物件的内容的话,可以改用 -p 参数。

    $ git cat-file -p a0423 # 查看物件资讯(内容)
    

    https://ithelp.ithome.com.tw/upload/images/20211001/20141010cMWZmqnDVq.png

    这时候 Git 的回报就是当初我手动储存的文字内容啦!

总结上述操作得知:

  1. 使用 git add 将档案加至暂存区後,会建立一个 Blob 物件,并根据物件的内容计算出 SHA-1 值。
  2. SHA-1 值前 2 个字元作为子目录名称,剩余 38 个字元作为档案名称。
  3. 档案内容为 Git 压缩演算法後,将内容压缩之後的结果。

Blob 物件的档名由 SHA-1 演算法决定;Blob 的内容则是压缩演算法决定。


Tree

有了 Blob 物件可以存内容之後,Git 也提供了可以存档名、资料夹名称的物件,此物件及为「Tree 物件」。

关於 Tree 物件的说明:

  • 储存档案的名称、资料夹名称、档案权限等
  • 透过 Tree,找到子目录、子子目录的档案内容、名称

Tree 物件与 Blob 物件相同,都是以 SHA-1 杂凑值作为档名,储存二进制内容。但两着的差异在於,Blob 物件主要是储存我们的档案「内容」,而 Tree 物件则是储存「档名」,而 Tree 物件里不一定只有包着 Blob 物件,同时也可以包含另一个 Tree 物件。

了解 Tree 物件的内容後,我们大致可以了解 Tree 可以帮助我们储存档案的名称目录的名称档案权限,也因为 Tree 物件同时可以纪录 Tree 物件与 Blob 物件之间的关联性,因此我们可以透过 Tree 物件来找到子目录以下的一些档案内容或档名。

下图说明 Tree 物件与 Blob 物件之间的关联性:

https://ithelp.ithome.com.tw/upload/images/20211001/20141010hE96j1i606.png


总结整理:

Blob 储存档案「内容」、Tree 储存档案「名称」


<<:  同步与非同步

>>:  Day17 Vue Component(元件)

Day9 - 2D渲染环境基础篇 V[Canvas动画概论] - 成为Canvas Ninja ~ 理解2D渲染的精髓

OK, 我们终於来到了基础篇最後的部分,也就是Canvas动画~!(撒花) 在这个部分,我们会介绍:...

进击的软件工程师之路-软件战斗营 第二周

学习进度 第一周的练习小考与检讨 课後练习与习题检讨 继承、多型与介面 继承(extends)原则与...

自动化 End-End 测试 Nightwatch.js 之踩雷笔记:select option

相信 E2E 一定有做过遇到这种需要选择的部分,结构大致上会长这样 <select class...

TailWind CSS 使用套件还是可以轻松客制化样式

这次2021 iThome铁人赛得奖名单出炉啦,看了 @搋兔 写的排版神器 Tailwind CSS...

The field that fears with

In my career path, there is one type of job that I...