git对象(数据对象)
git核心是键值对数据库,向该数据库插入任意数据,它会返回一个键值,可以通过该键值再次索引该内容。
向数据库写内容,并返回键值
git hash-object -w 文件路径
-w
选项指示git hash-object命令存储对象,若没有则只是返回键值
-- stdin
选项指示从标准输入读取内容,若没有则从文件路径读取
根据键值拉取内容
git cat-file -p 键值
查看类型
git cat-file -t 键值
git对象是key:val组成的键值对(key是val对应的hash),键值在git内部是一个blob类型
对一个文件进行简单的版本控制
从这里能看出git是对文件全量的版本管理,且到这里git并没有保存文件名,只是保存文件内容(树对象来解决),当前操作都在本地数据库进行操作,不涉及暂存区
tree对象(数对象)
树对象解决文件名保存的问题,它将多个文件组织到一起,一个树对象包含一条或多条记录(每条记录含有一个指向git对象或者子树对象的sha1指针以及相应模式、类型、文件名信息)树对象也可以包含另一个树对象。
构建树对象
通过update-index;write-tree;read-tree
来构建树对象
1.利用update-index
为a.txt文件首个版本创建一个暂存区并通过write-tree
生成树对象
git ls-files -s #查看暂存区内容
git update-index --add --cacheinfo 100644 哈希值 a.txt
git write-tree
文件模式 100644 普通文件
100755可执行文件
120000符号链接
--add
此前该文件不在暂存区,通过add加入
--cacheinfo
因为将要添加的文件位于数据库中,而不是当前目录下,所以需要--cacheinfo
2.新增new.txt,将new.txt和a.txt文件的第二个版本塞入暂存区,并通过git write-tree
生成树对象
echo "new file v1">new.txt
git hash-object -w new.txt
git update-index --cacheinfo 100644 哈希值 a.txt
git update-index --add --cacheinfo 100644 哈希值 new.txt
git write-tree
再用git read-tree
把之前的tree对象作为子目录加入到这个tree中
最终形成3个tree,入下图
commit对象(提交对象)
tree对象解决文件名的问题,而且必须记住哈希值来找内容,且没有记录何时、何人、为什么保存这些快照,commit对象就是解决这个问题。
用git commit-tree
来创建commit对象
最终效果如下