Git是如何保存文件名和目录关系的---树对象

简介: 本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 树对象(tree)—— 保存文件名和目录关系 树对象主要解决2个问题,:文件名的保存和文件目录关系的保存 就像下面这样 下面我们就来模拟一下构建上面这颗树,也就是模拟保存这3个文件,其中的"bak"是一个目录,下面有一个文件 首先可以看到,我们一共需要保存的是3个文件,new.txt 、 内容为version 2的 test.txt 和内容为version 1的 test.txt。

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

树对象(tree)—— 保存文件名和目录关系

树对象主要解决2个问题,:文件名的保存和文件目录关系的保存

就像下面这样

image

下面我们就来模拟一下构建上面这颗树,也就是模拟保存这3个文件,其中的"bak"是一个目录,下面有一个文件

首先可以看到,我们一共需要保存的是3个文件,new.txt 、 内容为version 2的 test.txt 和内容为version 1的 test.txt。其中我们上面已经把version 1的 test.txt写入到Git仓库了。

Git是怎么创建树对象的呢?

Git 根据某一时刻暂存区(即 index 区域)所表示的状态创建并记录一个对应的树对象,如此重复便可依次记录(某个时间段内)一系列的树对象。而暂存区里保存就是我们add进去的文件和目录。

而我们之前的text.txt是直接存入到Git数据库里面了,没有在暂存区,所以先要把这个文件读到暂存区里来

我们可以用 update-index 命令更新暂存区(跟我们做git add 操作是一样的道理)

git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
  • add :表示写入,因为文件不在暂存区中
  • cacheinfo:表示是从Git数据库中取文件,因为我们的文件不在工作目录,而是在Git数据库中
  • 100644:表示是普通文件,此外还有100755,表示一个可执行文件;120000,表示一个符号链接
  • 后面就是文件的SHA-1值和文件名

好的,现在我们已经把前面的内容更新到暂存区了。

然后我们就可以用 write-tree 命令生成一个树对象

git write-tree
//输出
d8329fc1cc938780ffdd9f94e0d364e0ea74f579

我们可以验证一下它确实是一个树对象(git cat-file -t命令可以查看对象的类型):

git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579
//输出
tree

经过上面的步骤,我们就把右边的那个树对象创建完毕了。

实际上,上面已经解决了一个问题,就是文件名的保存。

git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
//输出
100644 blob 83baae61804e65cc73a7201a7252750c76066a30    test.txt

这里我们再快速创建剩下的部分,直接新建new.txt和更新text.txt,然后用git add添加到暂存区并生成一个新的树对象

echo 'new file' > new.txt
echo 'version 2'> text.txt
git add .
git write-tree

下面我们来看看怎么解决目录保存的问题,也就是树和树关联起来

//首先把前面的把那个树对象写入到暂存区,其中bak就表示目录名
git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
//然后生成一个新的树对象
git write-tree
//输出
9f2f42e85a6648e5b5f48e1a6f154999e06b9a31

然后我们就可以来看看这个新的树对象了:

git cat-file -p 9f2f42e85a6648e5b5f48e1a6f154999e06b9a31
//输出
040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579    bak
100644 blob fa49b077972391ad58037050f2a75f74e3671e92    new.txt
100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a    text.txt

可以看到,目录就对应一个树对象,这样保存目录的问题就解决了。

数据对象和树对象用于保存数据和文件名和目录,我们还需要记录是谁保存的这些数据以及时间和原因等信息,而这些信息就需要第三个对象——提交对象。下一次我们就来看看提交对象


欢迎关注我的微信公众号,和我一起每天进步一点点!
AntDream

目录
相关文章
|
8月前
|
存储 Unix 开发工具
15分钟了解Git对象和引用(2)
15分钟了解Git对象和引用
62 0
|
8月前
|
存储 算法 Unix
15分钟了解Git对象和引用(1)
15分钟了解Git对象和引用
89 0
|
9月前
|
开发工具 git
vscode编辑器里怎么显示.git隐藏文件夹到目录里
vscode编辑器里怎么显示.git隐藏文件夹到目录里
120 0
|
2月前
|
存储 算法 开发工具
深入剖析Git对象底层原理
Git 在中间做了什么,它如何存储不同的文件和内容,以及如何区分不同分支下的文件版本呢?日常操作对这些自动的操作都是无感的。 但是如果哪天一旦上述操作中出现了错误,需要找回自己的代码时,如果不懂 Git 其内部存储原理,是没法找回的,因此为了避免这种情况,就有必要去了解其内部的存储——Git 对象的原理。
20 0
深入剖析Git对象底层原理
|
9月前
|
存储 开发工具 git
.git 目录中有什么?
.git 目录中有什么?
41 2
|
8月前
|
存储 运维 安全
15分钟了解Git对象和引用(3)
15分钟了解Git对象和引用
71 0
|
9月前
|
存储 开发工具 git
git中怎样忽略.idea/文件和目录
git中怎样忽略.idea/文件和目录
98 0
|
10月前
|
开发工具 git
将本地目录推送到Git远程仓库
将本地目录推送到Git远程仓库
|
开发工具 git
git 排除已经提交的文件目录
如果你已经把一个文件夹提交到了 Git 仓库中,但是后来发现这个文件夹不应该被提交,可以按照以下步骤排除已提交的文件夹: 在文件夹的根目录下创建一个名为 .gitignore 的文件。 编辑 .gitignore 文件,添加需要排除的文件夹的名称,以及其他需要排除的文件或文件类型,每个名称占一行。 执行以下命令,将 .gitignore 文件提交到 Git 仓库中:
476 0
|
存储 开发工具 文件存储
Git托管项目的.git目录下都有什么?
我们在使用`git`托管项目代码时,如果是新建项目需要通过`git init`命令在项目根目录下初始化`.git`目录来实现后续的代码托管管理,如果直接从代码仓库拉取代码则会自动创建`.git`目录与远程仓库进行绑定。