blog

Welcome to my blog!

Git: Commit, Tree and Blob

ab's Avatar 2026-01-24 Tutorial

  1. 1. 引言
  2. 2. Git的核心
  3. 3. Practice
    1. 3.1. 查看第一次提交 (Commit 1)
    2. 3.2. 查看第一次提交的目录树 (Tree)
    3. 3.3. 查看文件内容 (Blob)
    4. 3.4. 查看第二次提交 (Commit 2)
    5. 3.5. 查看第二次提交的目录树 (Tree)
  4. 4. 最开始问题的解决方法

引言

我不小心将一个几GB的机器学习模型commit到了Github repo中,导致仓库的体积瞬间变大,git clone需要很久。即使随后删除了该模型并再次commit,github repo的体积仍然没有改变,由此我打算研究一下Git的逻辑

Git的核心

Commit:

  • 指向Tree对象
  • meta data: author、committer、message以及parent的哈希值
  • branch是Commit的引用

Tree:

  • 指向Blob对象或其他Tree对象
  • 代表某个时间点的目录结构

Blob: 存储文件的具体内容

Practice

查看第一次提交 (Commit 1)

  • 指令git cat-file -p 1ddf

  • 参数1ddf 是左侧 Git Graph 中 commit1 的哈希值前几位。

  • 输出解读

  • tree caae...:指向一个哈希为 caae 开头的 Tree 对象(目录树)。

  • commit1:这是提交时的备注信息。

  • 目的:找到这次提交对应的根目录树(Tree)。

查看第一次提交的目录树 (Tree)

  • 指令git cat-file -p caae

  • 参数caae 是上一步得到的 Tree 对象的哈希值。

  • 输出解读

  • blob 737c... text1:显示目录里有一个名为 text1 的文件,其内容存储在哈希为 737c 的 Blob 对象中。

  • 目的:找到文件名 text1 对应的具体文件内容对象(Blob)。

查看文件内容 (Blob)

  • 指令git cat-file -p 737c

  • 参数737c 是上一步得到的 Blob 对象的哈希值。

  • 输出解读

  • This is text1.%:这是文件的真实内容。

  • 目的:验证 Blob 对象存储的就是文件的原始内容快照。

查看第二次提交 (Commit 2)

  • 指令git cat-file -p 957c

  • 参数957c 是左侧 commit2 的哈希值。

  • 输出解读

  • tree a638...:指向一个新的 Tree 对象。

  • parent 1ddf...关键点,显示它的父提交是 commit1 (1ddf),形成了历史链条。

  • 目的:查看新提交的结构以及它与上一次提交的关系。

查看第二次提交的目录树 (Tree)

  • 指令git cat-file -p a638
  • 参数a638 是上一步得到的 Tree 对象哈希值。
  • 输出解读
  • blob 737c... text1重点,这里依然引用了旧的 Blob (737c),证明了 Git 复用了没有修改的文件。
  • blob e69d... text2:新文件 text2 指向了一个全新的 Blob (e69d)。

最开始问题的解决方法

1
2
git reset #之前git add 添加到暂存区的文件,会被移出暂存区,变回“未暂存”的状态
git gc --prune==now #检测到这个大文件的对象没有被任何提交引用,于是立即把它从磁盘上彻底删除,释放空间
本文最后更新于 天前,文中所描述的信息可能已发生改变