为了更近一步的学习和理解Git的理念,这一节介绍一下Git中的一些基本概念。
Git的版本库就是一个简单的数据库,其中包含所有用来维护和管理项目的修订版本和历史的信息。
Git不仅提供版本库中所有文件的副本,还提供了版本库本身的副本。
Git在每个版本库里维护一组配置值,这个我们在上一篇文章中已经有所提及,比如版本库的用户名和email地址。当把一个版本库进行克隆的时候,会复制文件数据以及其他的一些版本库的元数据,但是不会复制配置设置。
Git维护两个主要的数据结构:对象库和索引。所有这些数据都存放在.git隐藏目录内。
对象库包含原始数据文件、所有的日志消息、作者信息、日期、以及其他用来重建项目任意版本或分支的信息。
Git放在对象库里的对象只有4种类型:块(blob)、目录树(tree)、提交(commit)、标签(tag)
A、块:
文件的每一个版本被表示为一个blob。一个blob保存一个文件的数据,但不包含任何关于这个文件的元数据,甚至文件名。
B、目录树(tree):
一个目录树对象代表一层目录信息。它记录了blob标识符、路径名和在一个目录里所有文件的一些元数据。
C、提交(commit):
一个提交对象保存版本库中每一次变化的元数据:作者、提交者、提交日期、日志消息。每一个提交对象指向一个目录树对象,除了根提交,大多数提交都有一个父提交。
D、标签(tag):一个标签对象分配一个任意的可读的名字给一个特定对象(通常是一个提交对象)。
目前来说,感觉这个概念不太好解释。
索引是一个临时的、动态的二进制文件,它描述整个版本库的目录结构。
我的认识是,索引是介于工作区和对象库之间的一个缓冲区。工作区里的变化会最早在这里有所体现,最后由索引将所有的变动提交到对象库中。
Git对象库被组织及实现为一个内容寻址的存储系统。对象库中的每一个对象都有一个唯一的名称,这个名称是向对象的内容应用SHA1得到的散列值。
首先,Git追踪的是基于对象内容计算出的散列值,而不关心文件名或目录名。如果两个文件的内容相同,那么不管是否在同样的目录,Git在对象库中只保存一份blob形式的内容副本。
其次,当文件从一个版本变到下一个版本的时候,Git的内部数据库会有效的存储每一个文件的每个版本,而不仅仅是差异。
当然,你或许已经发现,上面说的这种存储方式效率很低,因为每一个都要保存副本。这个会在后面打包文件的地方进行说明。
Git仅仅记录每个文件名,并且确保能通过它的内容精确的重建文件和目录。
好吧。。。我还是感觉无法理解作者的意思。
回到上面提出的问题:直接存储每个文件每个版本的完整内容是否太低效了?
Git使用了一种叫做打包文件的存储机制。要创建一个打包文件,Git首先定位内容非常相似的全部文件,然后为它们之一存储整个内容。之后计算相似文件之间的差异并且只存储差异。
原文:http://www.cnblogs.com/tq03/p/5008664.html