解释 Git 中的 BLOB 对象和树对象。
Git 使用一系列 BLOB 和树来存储项目工作目录的内容。每当我们执行提交操作时,Git 都会在内部创建一系列树和 BLOB,它们是提交时项目文件夹结构的二进制表示。
什么是 BLOB?
BLOB 代表二进制大对象。Git 中文件的每个版本都表示为一个 BLOB。BLOB 保存文件的数据,但不包含任何有关文件的元数据,甚至不包含文件的名称。
为了理解 BLOB,让我们看一个例子。
创建三个文件"file1.txt"和"file2.txt"和 “file3.txt” 文本文件。前两个文件包含相同的内容,第二个文件包含不同的内容。
$ git init // 初始化一个仓库 $ echo hello>file1.txt // 创建一个文件并输入一些内容 $ echo hello>file2.txt // 创建一个文件并输入相同的内容 $ echo hello world>file3.txt // 创建一个文件并输入一些内容
让我们将这些文件添加到暂存区。暂存这些文件将在 “.git\objects” 文件夹下创建 BLOB 文件。在本例中,我们将列出 “.git\objects” 文件夹中的内容。每次暂存文件时,都会创建一个新的文件夹。
$ git add file1.txt // 暂存文件 $ ls .git/objects/ // 列出内容 $ git add file2.txt $ ls .git/objects/ $ git add file3.txt $ ls .git/objects/
ls 命令的输出如下所示。
dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ git add filel.txt dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ Is .git/objects/ ce/ info/ pack/ dell@DESKTOP-N96LNR5 MINGW64 /e/tut_repo (master) $ git add file2.txt dell@DESKTOP-N961NR5 MINGw64 /e/tut_repo (master) $ Is .git/objects/ ce/ info/ pack/ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ git add file3.txt dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ Is .git/objects/ 3b/ ce/ info/ pack/
暂存 “file1.txt” 和 “file3.txt” 文件时,会创建名为 ‘ce’ 和 ‘3b’ 的文件夹。然而,暂存 “file2.txt” 文件时,不会创建新文件夹。这是因为 “file1.txt” 和 “file2.txt” 文件内容相同。
现在让我们看看文件夹 ‘ce’ 的内容。和"3b"。
$ ls .git/objects/ce $ ls .git/objects/3b
输出显示文件夹包含以 SHA1 哈希值表示的 BLOB 对象。
dell@DESKTOP-N961NRS MINGW64 /e/tut_repo (master) $ Is .git/objects/ce 013625030ba8dba906f756967f9e9ca394464a dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ Is .git/objects/3b 18e512dba79e4c8300dd08aeb37f8e728b8dad
现在让我们验证文件的类型及其内容。
$ git cat−file −t ce01 $ git cat−file −p ce01 $ git cat−file −t 3b18 $ git cat−file −p 3b18
从输出结果可以清楚地看出,尽管我们添加了 3 个文件,但 Git 创建了 2 个 BLOB。这是因为前两个文件的内容相同。从输出结果可以清楚地看出,BLOB 只存储文件的内容,不存储文件名。
//cat−file −t ce01 的输出 blob //cat−file −p ce01 的输出 hello //cat−file −t 3b18 的输出 blob //cat−file −p 3b18 的输出 hello world
什么是树?
树就像一个目录。Git 中的每个提交都指向一个树对象,而该树对象又引用了 BLOB。树对象记录以下内容。
BLOB 标识符
路径名
该目录中所有文件的元数据
树可以递归引用其他树对象或子树。因此,树构建了文件和子目录的完整层次结构。与 BLOB 一样,树可以在 “.git/objects” 文件夹下查看。
让我们通过前面的示例来理解树。我们创建了三个文件并将它们全部添加到暂存区。让我们使用 git status 命令来验证这一点。让我们将所有更改提交到存储库。
$ git status -s // 验证状态 $ git commit -m 'initial commit' // 提交到仓库
状态显示已暂存 3 个文件。执行 git commit 命令后,将创建一个哈希值为"84a00db"的提交。
dell@0ESKTop-N961NR5 MINGW64 /e/tut_repo (master) $ git status -s A fiIe1.txt A file2.txt A file3.txt dell@DESKTOP-N961NR5 MINGW64 /e/tut—repo (master) $ git commit -m 'initial commit' [master (root-commit) 84aOOdb) initial commit 3 files changed, 3 insertions(+) create mode 100644 file1. txt create mode 100644 file2. txt create mode 100644 file3.txt
我们示例的内部结构可以用下面的 − 表示。

上图显示提交"84a0"指向一棵树,该树是项目的根文件夹。根文件夹包含 3 个以 BLOB 形式存储的文件。前两个文件指向同一个 BLOB,因为它们的内容相同。树对象保存对所有 BLOB 的引用。如果我们在当前项目中创建新文件夹,则这些文件夹将被创建为根项目树"e115"的子树。
让我们验证对象文件夹,看看是否创建了任何提交对象或树对象。您可以使用 ls 命令查看。
$ ls .git/objects $ ls .git/objects/84 $ ls .git/objects/e1
输出显示文件夹"84"代表一个提交,"e1"将是与其关联的树。这些文件夹包含一个由 SHA1 哈希值表示的指针文件。
dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ Is .git/0bjects/84 aOOdb87bb5c69926b3343a564db1b3a96a389d dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master) $ Is .git/objects/el 1588b4a639bb90b18268b7e26f243ba31706fd
现在让我们使用 cat-file 命令验证这些指针文件中的内容。
$ git cat−file −p 84a0 $ git cat−file −p e115
从输出结果可以清楚地看出,提交 (84a0) 指向的是项目的根文件夹树。
tree e11588b4a639bb90b18268b7e26f243ba31706fd author Kiran 1612777422+0530 committer Kiran 1612777422+0530 initial commit
项目的根文件夹包含三个以 BLOB 形式存储的文件。
dell@DESKTop-N961NR5 MINGW64 /e/tut_repo (master) $ git cat −file −p e115 100644 blob ce013625030ba8dba906f756967f9e9ca394464a file1.txt 100644 blob ce013625030ba8dba906f756967f9e9ca394464a file2.txt 100644 blob 3b18e5L2dba79e4c8300dd08aeb37f8e728b8dad file3.txt
相关文章
有用资源
linux 参考教程 - 该教程包含有关 linux 的更多信息:https://www.cainiaomax.com/linux/

