使用git命令有一段时间了,但是一直没明白git的存储原理。花了点时间,简单的观察了下git存储过程。
具体观察步骤:
1.新建一个目录Workspace1,
进入目录后初始化一个git仓库。
输入Workspace1>git int
这时会发现Workspace1中生产了一个.git目录。
.git目录中
hooks/ (git命令用到的定制脚本的样例,这里都是关闭状态,除非删除.sample后缀)
info/ (附加信息)
object (对象信息,包括commit, tree, blob)
objects/info/ (对象存储的附加信息)
object/pack/
refs/
refs/heads (记录分支的commit对象)
refs/tags (记录指向commit对象的tag对象)
config (配置文件)
description (仓库的描述信息)
HEAD (当前活跃分支)
2.在仓库中新建一个helloworld.cpp文件,写上helloworld程序。
输入Workspace1>gitadd .
这时会产生2个文件(黄色部分):
这到底是2个什么样的文件呢?
输入Workspace1>git-files –stage (此命令用于读取index中stage的内容)
输出为:
这时会发现输出的哈希码正是objects下的15/da7f10b2…(即新生成的目录名加文件名)
输入Workspace1>git cat-file –p 15da7f10 (此命令用于读取da7f10b2文件的内容)
输出为helloworld的源码。
输入Workspace1>git cat-file –t 15da7f10
输出为:
blob
3.输入Workspace1>git ci –m “commit first time” ,
观察。
输入Workspace1>git cat-file –t 072b7e
输出为: commit
输入Workspace1>gitcat-file –t 074cff
输出为: tree
再观察object中各文件内容
输入Workspace1>gitcat-file –p 072b7e
输出为: tree的哈希码和commit信息。
输入Workspace1>gitcat-file –p 074cff
输出为:blob的哈希码和 helloworld文件。
观察下ref/head/master中文件内容,为commit的哈希码。
从这里我们可以得出个结论:
master->commit->tree->blob->源码。
其它:
COMMIT_EDITMSG中为commit注释。
logs文件中为commit信息。(git log命令显示的内容大概由此而来吧)
4.再次修改helloworld文件,然后add,最后commit,观察。
当输入Workspace1>git add .后,
index文件会更新为新的blob的哈希码。
查看新生成blob的内容,为最新的helloworld的源码内容。
当输入Workspace1>git ci –m “commit first time”后,
会生成新的commit, tree。
refs/head/master中文件内容,为新commit的哈希码。
logs文件中将叠加记录新commit信息。
…...
这里就不再继续往下研究了,从上述内容可以得出结论:
1).git的每一次stage/commit都会对当前版本数据(commit,tree, blob)全保存(快照就是这个意思吧),而不是增量信息。
2).commit的哈希码是对外的版本信息,想检索具体内容的路径为commit->tree->blob->源码。