前程摘要
上一章我们学了如何创建一个简单的本地 Git 仓库,也学会了如何将一个文件添加到暂存区以及如何标记为 tracked 状态。最后,我们更是学会了至关重要的 commit 命令。并且在结尾提到了 Git 对象中的某个类型:blob。后续会如何呢?让我们一起继续深入吧!
Git 的对象组成
基本三大类:
commit(对应一个 commit 记录)tree(简单理解为文件夹)blob(简单理解为文件)
那么,它们三者之间的关系是怎么样的呢?我们不妨从一个 commit 对象入手。因为我们已经创建了一个 commit 记录。
我们在上一章节学会了使用 gitk --all 命令打开图形化界面来查看 commit 记录(其实查看 commit 记录并非图形化界面主要功能卖点(笑)),实际上,使用 git log 命令才是正儿八经的查看 commit 记录的打开方式。我们先简单用 git log 命令查看 commit 记录,以后还会对该命令作深入的讲解。

解释:
- 我们可以看到 commit 后面跟着一大串 hash 字符串,其实这个是 commit 对象的 ID 号,标识着该 commit 对象的唯一身份。
- Author 后面跟着用户名和邮箱,这个使我们上一章节配置的
- Date 后面是我们提交的具体日期和时间。
- 最后面一行则是我们提交时候写的备注信息。
事实上,我在上述解释的过程中,也在描述了 commit 对象的一些基本属性。并且,眼尖的
同学们也留意到,hash 串后面跟着 (HEAD -> master) ,在这里我们先留一个悬念,以后会作深入讲解。你只要知道
master 代表着当前分支,HEAD 表示当前分支下最新的 commit。
我们截取该 commit 对象 hash 串的前面一部分(无所谓截取多少,只要它能唯一标识即可),输入以下命令,来查看该对象的类型:

嗯!这是一个 commit 对象类型,这是我们想要的。趁热打铁,继续查看该 commit 对象中有什么?

解释:
我们可以看到,author 和 committer 竟然分离成两个属性。这是因为 author 对应的是第一个 commit 的用户,committer 对应的是之后发起修改(patch)的用户。他们可能不是同一个人。
在这里,我们看到 commit 对象下有一个 tree 对象,难道一个 commit 对象就只对应一个 tree 吗?答案是肯定的,这个 tree 其实就是我们项目的根目录,因此,这个 tree 对象下面肯定还有其他东西。我们继续查看:

tree 下面有一个 blob 类型的对象,这个对象就是我们根目录下唯一的一个文件,也是被我们提交到本地仓库中的。这就印证了我们的猜想,一个 commit 只对应一个 tree,而这个 tree 就是我们项目的根目录。
我们再创建一个 commit 记录,然后继续探索一番:

解释:
我们在根目录下创建了一个 b 文件夹,然后在 b 文件夹下创建了 b.txt 文件,添加到暂存区然后提交到本地仓库中。
现在,我们来查看最新的这个 commit 里面到底有什么?

解释:
我们可以看到,这个 commit 多了一个 parent 属性,后面跟着一个 hash 串,这个 parent 对应的其实就是我们上一个提交的 commit,它们之间是父子的关系。

而且,可以看到,HEAD 已经指向现在这个最新的 commit 了。
我们继续点看这个 tree 查看:

小结:
到这里,我们对 commit 对象、tree 对象、blob 对象 这个三个主要的 git 对象之间的关系就有一个基本的理解了。commit 对象对应一个 tree 对象,这个 tree 对象就是我们本地仓库的根目录,一个 tree 对象下面,可能还有更多的 tree 对象或者 blob 对象。
Git log 命令详解
我们之前只是简单的使用 git log 命令来查看 commit 历史记录,那么 git log 还有多少种用法呢?
- git log(查看 commit 记录)
- git log --all (查看所有的 commit 记录)
- git log <branch_name>(查看特定分支的 commit 记录)
- git log -<num 或 git log -n<number(具体查看几行 commit 记录)
- git log --oneline(简约版本)
- git log --graph (分支图谱版本)
tips:
它们之间可以组合使用,例如:
git log --graph master -2
这将会列出分支图谱版本的 master 分支最新的 2 行记录:
