Git step by step 13 之Git对象

        Git中有几种对象,像commit、tree、blob、tag,所有这些对象都存放于工作目录中.git/objects/下的各个文件夹中。

举个例子:
        当创建一个文件 touch file,然后进行git add file时,上面所说的目录中就会生成一个文件夹(两个英文字符命名的,这里假设是ac),那么在ac目录下会有一个一串(38个)字符命名的文件(假设是8516aa0d9ea6b86d3830f2e179864992f527ad),而ac与8516aa0d9ea6b86d3830f2e179864992f527ad合起来(即:ac8516aa0d9ea6b86d3830f2e179864992f527ad)就是我们刚git add之后,所创建的一个blob对象名,该对象名是一个SHA-1值(40个字符组成,前两个用作目录名,后38个用于文字名),而该blob对象中所存的内容即为file文件的内容。
所以一个文件对应一个blob对象。

        而tree对象对应的是目录,其内容是目录中的子目录或文件的名称。
举个例子:
        假设工作目录(根目录)里有dir/一个目录,和一个file文件,而dir/目录下又有file1和file2两个文件。那么进行 git add(add all)之后,生成的是三个blob对象(我试了下,当文件中没有内容时,不会生成blob对象,这就是说Git是针对文件中的内容进行SHA-1哈希的),对应这三个文件。此外,还会生成两个 tree 对象,对应工作目录的根目录以及dir/目录。

        commit对象是在每次git commit时所生成的,而tag对象是在建立里程碑时所生成的。

Ps:在.git/objects中的所有对象,在不手工(进入该目录,rm -r XXX)进行删除时,这些对象都会一直存在着,这也是为什么在git reset之后,还可以还原的,不过,从那么多对象文件中找出想要还原的commit,犹如大海捞针。但是总是有方法找到的,或许git reflog可以帮助走得更进一步。

        理解Git中的对象,能更好的理解分支、HEAD、master等。


        前面讲过,用git cat-file -p HEAD:file可以查看HEAD所指向的提交中file的内容,其实,这只是一个小的应用。
        所有对象都可以用git cat-file来查看,其中 git cat-file -t <object> 是查看该对象的类型 ,git cat-file -p <object> 是查看该对象的内容, git cat-file -s <object> 是查看该对象的大小。

举个例子:
$ git cat-file -p 6bb994 //(这个是一个commit对象的名字的前5位,不必打出全名,可区别于其他即可)
tree 8fc7e4efa8c47c058272663dc3cafcad52229b9d
parent c2456fcf8fcb8715704d4d4e4e8342c83e344b3e
author kevin <[email protected]> 1366773192 +0800
committer kevin <[email protected]> 1366773192 +0800

        可以看出,该commit对象中记录了它所对应的tree对象,前一次提交生成的commit对象(即它的父提交),提交人信息、对该 commit的描述。

        最后补充一条很重要的,Git在处理提交时,会把每次提交的文件全部内容(snapshot)都记录下来。
        举个例子:file在修改之后,再进行提交时,会新建一个完整地对应于它的blob对象,而不是覆盖掉之前提交时所产生的,也不是只对修改的部分(例如:添加了某些行)建立blob对象。

more:
GIT对象模型(推荐)
《Pro Git》

猜你喜欢

转载自songkang666.iteye.com/blog/1852751