Git 对象类型
Git 对象有如下四种:
- blob
- tree
- commit
- tag
blob 对象
blob 只是一个字节块,可以用来存储文件、源代码或者图片等等。
tree 对象
tree 就像文件系统目录。一个 tree 可以指向或者包含:
- blob 对象,就像文件系统目录包含文件一样
- tree 对象,就像文件系统目录有子目录一样
commit 对象
每次执行 git commit 成功后,就会创建一个新的 commit 对象。一个 commit 对象至少包含:
- 提交 commit 的人的相关信息,比如名字和邮箱,以及提交 commit 的时间
- 与 commit 相关的评论信息
- tree 的哈希值,这个 tree 表示提交这个 commit 后的 git 仓库
一个 commit 对象还有可能包含父 commit,除了初始 commit 不包含父 commit 外,其它 commit 都含有父 commit 的哈希值。如果一个 commit 有不止1个父 commit,那么肯定有 git merge 行为。
tag 对象
一个 tag 对象指向一个 commit 对象,可以用来引用某个特定的 tree.
一个 tag 对象包括:
- tag 的名字
- tag 所指向的 commit 对象
- tag 评论信息
- 打 tag 的人的名字和邮箱,以及打 tag 的时间
相关命令
## 打 tag
git tag -m 'tag message' tag-name [commit-hash-value]
## 查看 tag 信息
git cat-file -p tag-name
## 列出所有 tag
git tag -l
## checkout tag
git checkout tag-name
git add 做了什么
当执行如下命令时,git 对象存储发生了什么变化呢?
git add filename
- 计算文件内容的SHA1哈希值
- 在 .git/objects 目录中创建子目录,子目录名字即为上述哈希值的前两个字符
- 在子目录中创建一个 blob 对象,blob 对象包含了 filename 文件的内容,blob 的名字即为上述哈希值的后38个字符
- 把文件名 filename 及上述哈希值加到 .git/index 索引文件中
假如 filename 文件内容的SHA1哈希值是4b5fa63702dd96796042e92787f464e28f09f17d,那么子目录的名字为4b,blob 的名字为5fa63702dd96796042e92787f464e28f09f17d。因此,blob 的完整路径为 .git/objects/4b/5fa63702dd96796042e92787f464e28f09f17d
相关命令
## 查看文件的哈希值
git hash-object filename
## 根据哈希值查看文件内容
git show blob-hash-value
blob 对象的存储结构
blob 对象是这样构造的:
- 文件头,由对象类型(即 blob)、被 add 文件的大小、一个 null 字节构成
- 文件头后接着是被 add 文件的内容
- 然后 zlib 压缩整个文件得到 blob 对象
tree 对象的存储结构
tree 对象的存储结构类似于文件系统中目录的存储结构,tree 和目录对应,而 blob 和文件对应。tree 对象中的每一条记录由如下三个字段组成:
- 对象类型,tree 或者 blob
- 对象哈希值
- 目录或者文件的名字
相关命令
## 查看最近一次 commit 的信息
git cat-file -p HEAD
## 查看 tree 的内容
git ls-tree tree-hash-value