【看日记学Git】之十一

接下来的内容是以“之一~之十”的内容为基础的,内容将围绕对象数据库和索引文件展开,这是为了更好的理解git的工作机制和体系结构。

系列之十一将讲解“对象数据库(object database)”

1

为了讲清楚object database这个概念,我们先建立一个git仓库:

 

$ mkdir test-project
$ cd test-project
$ git init
$ echo ‘Hi,rocrocket’>file.txt
$ git add .
$ git commit -a -m “initial commit” //此处的-m选项表示“后面的参数是本次提交的历史记录”
$ echo ‘Hi,rocrocket!’>file.txt
$ git commit -a -m “add emphasis”
$ git log //使用log命令查看一下
Created commit d85012f: add emphasis
1 files changed, 1 insertions(+), 1 deletions(-)
[rocrocket@wupengchong test-project]$ git log
commit d85012f4d17a774c7286f4d7d022f022d3b90073
Author: rocrocket <wupengchong@gmail.com>
Date:   Fri Sep 26 10:58:15 2008 +0800
add emphasis
commit 241e0a4d2a5644f92737b7fba8b9eb19dcb0c345
Author: rocrocket <wupengchong@gmail.com>
Date:   Fri Sep 26 10:57:13 2008 +0800
initial commit

你可曾想过到底这些跟在commit字符串后面的一大长串(共40位)十六进制数字是干什么用的??

通过前十期的学习,我们知道这40位十六进制数是用来“标识一次commit”的名称。其实,这40位十六进制数是一个SHA1哈希数(Secure Hash Algorithm),它可以保证每次commit生成的名称都是唯一的且可以永远有效的。

2

执行下面命令:

[rocrocket@wupengchong test-project]$ git cat-file -t 241e //cat-file命令中-t选项表示列出相应ID的对象类型;241e是刚才commit后得出的SHA1码
commit //可以看到此ID对应的对象类型为一次commit
[rocrocket@wupengchong test-project]$ git cat-file commit 241e //此处的commit表示要查询的是一个对象类型为commit的对象,后面给出此对象的ID
tree 9a327d5e3aa818b98ddaa7b5b369f5deb47dc9f6
author rocrocket <wupengchong@gmail.com> 1222397833 +0800
committer rocrocket <wupengchong@gmail.com> 1222397833 +0800
initial commit

你应该可以注意到命令输出结果中包含了tree,tree的ID表示了一个BLOB对象(二进制对象),此对象对应着一个文件或另一个tree。你可以使用ls-tree命令来查询关于这个tree的更详细信息:

[rocrocket@wupengchong test-project]$ git ls-tree 9a327
100644 blob 7d4e0fa616551318405e8309817bcfecb7224cff file.txt
我们可以看到9a327这棵树上包括了一个file.txt文件,其ID为7d4e0f
[rocrocket@wupengchong test-project]$ git cat-file -t 7d4e0f
blob
[rocrocket@wupengchong test-project]$ git cat-file blob 7d4e0f
Hi,rocrocket

可以看到7d4e0f对应的对象的类型是blob,而其内容就是“Hi,rocrocket”

3

所有的对象信息都存储在.git/objects/目录下,使用find命令查看一下:

./objects
./objects/pack
./objects/24
./objects/24/1e0a4d2a5644f92737b7fba8b9eb19dcb0c345
./objects/fb
./objects/fb/4ec0f35525992eda56021f161f85f637837404
./objects/d8
./objects/d8/5012f4d17a774c7286f4d7d022f022d3b90073
./objects/7d
./objects/7d/4e0fa616551318405e8309817bcfecb7224cff
./objects/9a
./objects/9a/327d5e3aa818b98ddaa7b5b369f5deb47dc9f6
./objects/info
./objects/60
./objects/60/be00dabc677b196938758ef41457cc17b77b70

这些对象都是被压缩过的,其类型可以是blob,tree,commit或tag。其中包括了对象长度、对象类型和对象的内容。

4

在.git目录下的HEAD文件比较特殊,查看.git/HEAD文件:

[rocrocket@wupengchong .git]$ cat HEAD
ref: refs/heads/master
[rocrocket@wupengchong .git]$ cd ..
[rocrocket@wupengchong test-project]$ git branch
* master

可以看到HEAD文件指示出当前所在的分支名称是master。其实更引起我们兴趣的是HEAD文件中所指示的这个路径“refs/heads/master”,我们随着HEAD的思路走下去:

[rocrocket@wupengchong test-project]$ cat .git/refs/heads/master
d85012f4d17a774c7286f4d7d022f022d3b90073

这个文件的内容给出了一个对象ID,继续寻根溯源:

[rocrocket@wupengchong test-project]$ git cat-file -t d850
commit
[rocrocket@wupengchong test-project]$ git cat-file commit d850
tree fb4ec0f35525992eda56021f161f85f637837404
parent 241e0a4d2a5644f92737b7fba8b9eb19dcb0c345
author rocrocket <wupengchong@gmail.com> 1222397895 +0800
committer rocrocket <wupengchong@gmail.com> 1222397895 +0800
add emphasis

谜底揭开了。HEAD所指向的原来是最后一次commit的信息,而且经测试可知parent指的是上一次commit的信息。

5

到目前为止,我们应该已经知道了对象数据库是如何管理历史记录的了:

  • commit对象会指向一个tree对象,即在历史记录中当前结点的tree目录的镜像;也会指向父母(parent)commit,这是为了和之前的commit建立关联。
  • tree对象用于显示一个目录的状态,tree对象中包含了blob对象和子目录对象。
  • blob对象包含的是文件的数据。
  • 每个分支的HEAD会存储在.git/refs/heads中。同时,当前所在分支的头部会存储在.git/HEAD中。

转载请注明:Git中国 » 【看日记学Git】之十一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值