引言
我不小心将一个几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 | git reset #之前git add 添加到暂存区的文件,会被移出暂存区,变回“未暂存”的状态 |