10.2 Git 内部原理 - Git 对象

Git 对象

Git 是一个内容寻址文件系统,听起来很酷。但这是什么意思呢? 这意味着,Git 的核心部分是一个简单的键值对数据库(key-value data store)。 你可以向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键,通过该键可以在任意时刻再次取回该内容。

可以通过底层命令 git hash-object 来演示上述效果——该命令可将任意数据保存于 .git/objects 目录(即 对象数据库),并返回指向该数据对象的唯一的键。

首先,我们需要初始化一个新的 Git 版本库,并确认 objects 目录为空:

$ git init test
Initialized empty Git repository in /tmp/test/.git/
$ cd test
$ find .git/objects
.git/objects
.git/objects/info
.git/objects/pack
$ find .git/objects -type f

可以看到 Git 对 objects 目录进行了初始化,并创建了 pack 和 info 子目录,但均为空。 接着,我们用 git hash-object 创建一个新的数据对象并将它手动存入你的新 Git 数据库中:

$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

在这种最简单的形式中,git hash-object 会接受你传给它的东西,而它只会返回可以存储在 Git 仓库中的唯一键。 -w 选项会指示该命令不要只返回键,还要将该对象写入数据库中。 最后,--stdin 选项则指示该命令从标准输入读取内容;若不指定此选项,则须在命令尾部给出待存储文件的路径。

此命令输出一个长度为 40 个字符的校验和。 这是一个 SHA-1 哈希值——一个将待存储的数据外加一个头部信息(header)一起做 SHA-1 校验运算而得的校验和。后文会简要讨论该头部信息。 现在我们可以查看 Git 是如何存储数据的:

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

如果你再次查看 objects 目录,那么可以在其中找到一个与新内容对应的文件。 这就是开始时 Git 存储内容的方式——一个文件对应一条内容, 以该内容加上特定头部信息一起的 SHA-1 校验和为文件命名。 校验和的前两个字符用于命名子目录,余下的 38 个字符则用作文件名。

一旦你将内容存储在了对象数据库中,那么可以通过 cat-file 命令从 Git 那里取回数据。 这个命令简直就是一把剖析 Git 对象的瑞士军刀。 为 cat-file 指定 -p 选项可指示该命令自动判断内容的类型,并为我们显示大致的内容:

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

至此,你已经掌握了如何向 Git 中存入内容,以及如何将它们取出。 我们同样可以将这些操作应用于文件中的内容。 例如,可以对一个文件进行简单的版本控制。 首先,创建一个新文件并将其内容存入数据库:

$ echo 'version 1' > test.txt
$ git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30

接着,向文件里写入新内容,并再次将其存入数据库:

$ echo 'version 2' > test.txt
$ git hash-object -w test.txt
1f7a7a472abf3dd9643fd615f6da379c4acb3e3a

对象数据库记录下了该文件的两个不同版本,当然之前我们存入的第一条内容也还在:

$ find .git/objects -type f
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

现在可以在删掉 test.txt 的本地副本,然后用 Git 从对象数据库中取回它的第一个版本:

$ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
$ cat test.txt
version 1

或者第二个版本:

$ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值