ljkwy 2019-06-26
相信大家或多或少都在工作中用过svn,git之类的版本控制工具。不过,svn和git都是怎样存储数据的?svn和git存储数据有什么差别呢?
1.本地化版本管理-rcs
他的原理就是在客户端本地保存并管理文件布丁。因为所有的版本信息都在客户端本地,所以他的缺点也是显而易见的:多人无法协同合作。
2.集中化版本管理-svn
他的原理是有一个集中的管理服务器,在该服务器保存了所有的文件修订版本。所有人都可以聪这个服务器存取文件。当然,它相对于上一个本地化版本管理,已经解决了多人无法协同合作的问题。但是,服务器一旦宕机或者发生故障,则版本信息就会不安全了,这样其实没有太大的保障性。
3.分布式版本管理-git
他的核心原理是去中心化。就像下图所示,它不仅会在服务器保存版本信息。客户端不仅提取了最新版本文件快照,还会把代码仓库完整镜像下来。用户可以在无网的情况下,随意在本地进行版本提交。上面提到的集中化版本管理就没有这样的优势。
如下两图分别是svn及git存储的原理图。
a.svn存储存储的是文件的差异化。如图中,版本2和版本1。文件A和文件C有修改,则在版本2的时候存储该两文件变化的部分。不管文件存储了多少次,都是一份原始文件+多份差异文件的累积。
b.git存储存储的是文件快照。所谓的文件快照类似与文件本身,不过git会进行压缩等操作。如图中,在版本2和版本1。文件A和文件C有修改,则在版本2的时候会重新存储已经变化的文件,而不是变化部分。实际上,git在版本管理的时候记录的是指针。文件有变化时,会新建指针指向新的文件。而文件B没有变化,则还是原始版本的指针指向原来的文件。这里的原理会在稍后部分进行详细解析。
当然,git这样存储文件,而不是diff。当我们需要查看某个版本时,只要加载对应的文件即可,不需要再merge。是一种以空间换时间的策略。
git的每一次提交都会有3个blob文件,一个树对象,一个提交对象,如下图所示。
树对象(绿色部分)存储目录结构及blob文件的索引。可以看到树对象里面有3个blob标示,分别对应5b1d3/911e7/cba0a三个blob文件。而提交对象指向树对象的指针及所有的提交信息。下图的提交对象98ca9里有一个tree的标示指向了92ec2,当然它还包含了作者等等提交信息。
而很多次的提交则会有很多次上述的提交对象,他们之间是怎样连接的呢。其实在提交对象里面还有一个parent的标示。如下图所示,34ac2的parent是98ca9。但是因为98ca9是首次提交则parent属性是空。
如下图所示。其实,git每次的提交不仅仅会有上面说的提交对象的概念,在提交对象之上,还会有分支的概念。git默认会有一个master分支。如下图所示,我们也可以新建一个v1.0的分支。但是,现在有两个分支,我们怎么知道我们在哪个分支工作呢。其实有一个HEAD的指针,该指针指向哪个分支,目前的工作分支就是哪个。如果我们需要切换分支,用git checkout xxx即可。
关于git的工作区域,文件类型,具体的指令,开发流程等等,将在另外一片文章详细介绍~