GIT 数据结构

本文深入探讨Git如何通过快照方式管理版本控制,介绍commit、tree和blob对象间的关系,并通过实例展示Git如何处理文件和文件夹的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

Git doesn’t think of or store its data this way. Instead, Git thinks of its data more like a series of snapshots of a miniature filesystem. With Git, every time you commit, or save the state of your project, Git basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot. To be efficient, if files have not changed, Git doesn’t store the file again, just a link to the previous identical file it has already stored. Git thinks about its data more like a stream of snapshots.

Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流

 

git内部commit, tree, blob 三者的关系如下

 

 

 

 

 

需要用到的命令:

  • 查看“blob”对象:git show + 对象名(SHA1哈希值)
  • 查看“tree”对象:git show + 对象名 / git ls-tree + 对象名
  • 查看“commit”对象:git show / git log + -s + --pretty=raw +对象名
  • 查看“tag”对象:git cat-file tag v1.5.0

实例:

$ cd D:\playspace\git\git-study
$ git init

在该文件夹下新建三个txt,分别是a.txt ,b.txt, c.txt ,然后文件的内容分别写上 a, b, c

 

$ git add *

"暂存操作会为每一个文件计算校验和(使用我们在 起步 中提到的 SHA-1 哈希算法),然后会把当前版本的文件快照保存到 Git 仓库中(Git 使用 blob 对象来保存它们),最终将校验和加入到暂存区域等待提交"

 引用自 https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B

 

$ git commit -m "first commit"

"当使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和,然后在 Git 仓库中这些校验和保存为树对象。 随后,Git 便会创建一个提交对象,它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。如此一来,Git 就可以在需要的时候重现此次保存的快照。"

引用自 https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B

 

$ git log
commit 33c92d3c005e1697725d5b91687a9ce6fa2f93dc
Author: 408657544 <408657544@qq.com>
Date:   Tue May 29 14:23:12 2018 +0800
$ git ls-tree HEAD
100644 blob 2e65efe2a145dda7ee51d1741299f848e5bf752e    a.txt
100644 blob 63d8dbd40c23542e740659a7168a0ce3138ea748    b.txt
100644 blob 3410062ba67c5ed59b854387a8bc0ec012479368    c.txt
或
$ git ls-tree 33c92
100644 blob 2e65efe2a145dda7ee51d1741299f848e5bf752e    a.txt
100644 blob 63d8dbd40c23542e740659a7168a0ce3138ea748    b.txt
100644 blob 3410062ba67c5ed59b854387a8bc0ec012479368    c.txt

可见上面git ls-tree 这个命令,是将哈希值为33c92d的这个commit对象对应的tree对象显示了出来,而这个tree对象含有3个blob

 

假设增加一个文件d.txt,对将其add后提交,然后再来看看git ls-tree HEAD的情况

$ git log
commit ff2151f2f05f0f5fd3d136705ef0112f8520ba43
Author: 408657544 <408657544@qq.com>
Date:   Tue May 29 16:25:35 2018 +0800

    add d.txt

commit 33c92d3c005e1697725d5b91687a9ce6fa2f93dc
Author: 408657544 <408657544@qq.com>
Date:   Tue May 29 14:23:12 2018 +0800

    first commit


$ git ls-tree HEAD
100644 blob 2e65efe2a145dda7ee51d1741299f848e5bf752e    a.txt
100644 blob 63d8dbd40c23542e740659a7168a0ce3138ea748    b.txt
100644 blob 3410062ba67c5ed59b854387a8bc0ec012479368    c.txt
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    d.txt

 可见 a.txt, b.txt 和 c.txt 的哈希值在新的tree对象里面并没有发生改变,新的commit对应的tree对象里对于没有修改过的文件,只保存了指针

 也可以看出,每个commit对应的版本,也就是快照,是包含了全部的文件的

 

但是有个疑问,现在一个文件是对应一个blob,如果是一个文件夹呢,是一个blob呢,还是文件夹里每个文件一个blob呢,来试一下,根目录下增加一个文件夹folder1,里面增加两个文件a.txt和b.txt然后提交,然后再看看git ls-tree的结果

$ git ls-tree HEAD
100644 blob 2e65efe2a145dda7ee51d1741299f848e5bf752e    a.txt
100644 blob 63d8dbd40c23542e740659a7168a0ce3138ea748    b.txt
100644 blob 3410062ba67c5ed59b854387a8bc0ec012479368    c.txt
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    d.txt
040000 tree 4e2fd0b481a785eb99cab80ec1c582e1caf6cb44    folder1

 看来是一个文件夹对应一个blob

 

使用git show,可以看到这个文件夹blob包含的内容

git show 4e2fd0b
tree 4e2fd0b

a.txt
b.txt

使用git ls-tree来看这个blob,发现这个blob包含了两个blob...

git ls-tree 4e2fd0b
100644 blob 2e65efe2a145dda7ee51d1741299f848e5bf752e    a.txt
100644 blob 63d8dbd40c23542e740659a7168a0ce3138ea748    b.txt

看来blob是可以包含blob的,blob既可以是文件夹,也可以是文件

转载于:https://www.cnblogs.com/heben/p/9104844.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值