git internal 三个主要对象

1、blob object

创建一个空目录,不是空的也行,但这个目录之前没有被git管理过,即没有.git目录。
在这里插入图片描述
执行命令:

cd gitlearn && git init .

利用tree命令查看.git目录结构:图不对,因为我原来用的;不是&&,除了这张图后边的都改过来了。
在这里插入图片描述
执行命令查看objects目录:

find .git/objects
find .git/objects -type f

在这里插入图片描述
在这里我们不在工作目录创建文件,而是直接手动创建一个BLOB object,并且手动的将它存储到git database。

echo ‘test content' | git hash-object -w --stdin

d670460b4b4aece5915caf5c68d12f560a9fe3e4在这里插入图片描述The -w option then tells the command to not simply return the key, but to write that object to the database. Finally, the --stdin option tells git hash-object to get the content to be processed from stdin; otherwise, the command would expect a filename argument at the end of the command containing the content to be used.
这里生成了40 character的SHA-1的hash。
用下面的命令查看:

find .git/objects -type f

在这里插入图片描述40位的hash,前2位做目录。
一旦你的git database有这些东西,就可以用git cat-file查看文件内容:

git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4

在这里插入图片描述
当然你能在终端上看到文件内容,也就可以利用管道把内容输出到文件中,进行保存。
接着再创建2个BLOB object, 不过这次我们是在工作目录中创建一个文本文件:

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

83baae61804e65cc73a7201a7252750c76066a30
在这里插入图片描述

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

1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
在这里插入图片描述
然后我们看下objects目录下面的内容:

find .git/objects -type f
root@wgg-MacBookPro:/home/wgg/gitlearn# find .git/objects -type f
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

这个时候就算你在工作目录删除了test.txt文件,没关系,你可以从object database中恢复某个版本的内容到文件中。

root@wgg-MacBookPro:/home/wgg/gitlearn# rm -rf test.txt
droot@wgg-MacBookPro:/home/wgg/gitlearn# ll
dtotal 12
drwxr-xr-x 3 root root 4096 7月 11 11:14 ./
drwxr-x— 34 wgg wgg 4096 7月 11 00:38 …/
drwxr-xr-x 7 root root 4096 7月 11 00:38 .git/
root@wgg-MacBookPro:/home/wgg/gitlearn# git cat-file -p 83baae61804e65cc73a7201a7252750c76066a3 > test.txt
root@wgg-MacBookPro:/home/wgg/gitlearn# cat test.txt
version 1

如果要根据对象的名字也就是hash值,确定对象的类型,可以使用如下命令:

git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
root@wgg-MacBookPro:/home/wgg/gitlearn# git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
blob

到这里第一部分就结束了,但是说个东西,SHA-1产生的40 character的值:

The output from the above command is a 40-character checksum hash. This is the SHA-1 hash — a checksum of the content you’re storing plus a header, which you’ll learn about in a bit. Now you can see how Git has stored your data:

可以用Ruby去模拟这个过程:

We mentioned earlier that there is a header stored with every object you commit to your Git object database. Let’s take a minute to see how Git stores its objects. You’ll see how to store a blob object — in this case, the string “what is up, doc?” — interactively in the Ruby scripting language.

在这里插入图片描述
这个hash到底对不对可以通过git hash-object来相互比较一下:
在这里插入图片描述
hash值是一样的。
然后还没完,目前只是通过header + content,得到了一个hash值,那么git如何将这些内容保存在文件系统中的呢?

Git compresses the new content with zlib, which you can do in Ruby with the zlib library

在这里插入图片描述

Finally, you’ll write your zlib-deflated content to an object on disk.In Ruby, you can use the FileUtils.mkdir_p() function to create the subdirectory if it doesn’t exist. Then, open the file with File.open() and write out the previously zlib-compressed content to the file with a write() call on the resulting file handle:

在这里插入图片描述
最后检查一下文件的内容:就是没有换行的

root@wgg-MacBookPro:/home/wgg/gitlearn# git cat-file -p bd9dbf5aae1a3862dd1526723246b20206e5fc37
what is up, doc?root@wgg-MacBookPro:/home/wgg/gitlearn# 

All Git objects are stored the same way, just with different types – instead of the string blob, the header will begin with commit or tree. Also, although the blob content can be nearly anything, the commit and tree content are very specifically formatted.

git add会将这些hash表示的文件名写入到.git/objects。

2、tree object

先来看下经过第一部分的修改之后,.git目录是什么样子:
在这里插入图片描述

You can fairly easily create your own tree. Git normally creates a tree by taking the state of your staging area or index and writing a series of tree objects from it. So, to create a tree object, you first have to set up an index by staging some files.

可以这样在index中创建一条entry:

git update-index --add --cacheinfo 100644 \ 83baae61804e65cc73a7201a7252750c76066a30 test.txt

这样你的index中就生成了:在这里插入图片描述

我们是在index中添加了一条entry,而不是working directory中,这个注意下。working directory中有test.txt,但不是这个版本的。

Now, you can use git write-tree to write the staging area out to a tree object. No -w option is needed — calling this command automatically creates a tree object from the state of the index if that tree doesn’t yet exist:

在这里插入图片描述
working directory中新建一个文件new.txt,然后用plumbing command去更新我们的index or staging area,git update-index干了两件事情: 更新index, 在.git/objects生成相应的blob对象。
在这里插入图片描述
直觉上可以看到index和working directory之间的关系。
在这里插入图片描述
将index生成一次快照(snapshot),即一个tree对象。
在这里插入图片描述

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值