1.5. 审视 Blob

未匹配的标注

让我们来看一下 blue.html 所对应的 blob 对象。使用的还是这个命令 git cat-file

复制前几位就可以了。

➜  plumbing-demo git:(main) git cat-file blob cf7bb0e
<!DOCTYPE html>
<html lang="en">
<head>
  <title>The Blue Page</title>
  <link rel="stylesheet" href="style.css" />
  <meta charset="utf-8" />
</head>
<body>
  <h1 style="color: #00F">The Blue Page</h1>
  <p>Blue is the color of the sky.</p>
  <p><a href="index.html">Return to home page</a></p>
</body>
</html>

可以看出它展示出了 blue.html 里面所有的内容。这就是一个普通的 HTML 文件,说明了 blob 确实是普通的数据文件。

注意,这个 blob 是纯内容的,它是不含有文件名的,也就是说blue.html 这个名字不是存储在这个 blob 文件里面的,而是存储在包括这个 blob 文件所在的 tree 里面的。

从前面基础,我们可以回忆到一个 SHA-1 校验和确保了一个对象的内容是绝对不会丢失的,除非你故意告诉Git,你要去把它删掉。校验和是通过对象的内容来产生一个唯一的字符串。它不仅可以作为一个 ID, 还可以保证一个对象不会被默默地损坏。一旦你更改了它的内容,就会产生一个不同的 ID。

对于 blob 对象来说,这种机制还有另外的好处,因为如果两个 blob 有同样的内容,那么他们就会有同样的 ID,而 Git 在不同的 tree 之间必须分享这些 blob。 比如 blue.html 这个文件从它创建开始之后就一直没有被修改过。所以我们的这个仓库就只有一个 blob 是跟它相连的。随后所有的这个 tree 都直接引用它,而不是对每一个 tree 对象都创建一个重复的 blob 。通过这种方式, git 就极大地减小了仓库的体积。有了这个认识之后,我们就可以将我们的 git 对象图改变为下面这个样子。

Commit, tree, and shared blob objects

从这个图上我们就可以看到一个 commit 对应的是一个 tree,一个 tree 下面有多个 blob 对象。但一个 blob 对象有可能是只属于一个 tree 也可能是属于多个 tree,在这种情况下面,这一个 blob 它是被多个 tree 所分享的,他们都只是通过一个指针指向这个 blob ,而并不是说每一个 tree 都包含了这个 blob 对象,这样的话就会大大减少仓库的体积。然而只要你在一个文件里面修改了一个字符, git 就会创建一个全新的 blob 对象,因为它的内容变化会产生一个新的 SHA-1 校验和。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~