原文地址:https://www.ibm.com/developerworks/cn/opensource/os-cn-git-and-github-1/index.html

Git的基础特性

 

  • 克隆一次即可获得代码库的完整副本

这个特性是所有分布式版本控制系统的特性之一,Git也不例外。

 

  • 直接记录快照而非差异比较

版本控制系统中采用何种策略来管理文件的历史版本是系统的核心技术之一,因为既然是用于软件版本的跟踪,那么相应的各个文件的历史版本就是关注的重点。目前很多传统的版本控制系统如SVN、Perforce等采用基于增量的方式来记录每次变更。每次变更产生后就生成一个差异对象,最终最新版本的文件可以由最初的基础文件和这个文件所累积的差异来组成。给一个初始值,再记录每次新版本变化与上一个版本的差异,最后将初始值和所有的差异对象组合起来就可以得到最新版本,这就是以增量的方式来记录每次变更

而Git中采用的是类似于快照流Stream of Snapshot的方式来存储数据。Git在一个文件发生修改时会生成一个新的完整的文件对象,当然旧的文件对象也会保留下来作为历史版本。对于未发生更改的文件,Git在新版本的代码库中只是保留了一个链接,指向之前存储的文件。例如下图,对 A 文件和 C 文件都进行了修改,Git 生成了两个新的完整的文件对象 A1 和 C1,而 B 文件未发生更改,那么版本 2 中就只记录了一个指向 B 文件的链接。基于文件对象 A1 和 C1 以及连接 B,Git 就生成了一个版本 2 的快照。

图中灰色虚线框圈起来的是链接。因为SoS方式只要当前版本的某文件相对于上一个版本中的相应的文件没有发生变更,那么在当前版本中,就使用一个链接来指向之前已经存储过的相应的文件,因为没有发生变更,所以就不用再浪费存储空间来存储文件,只需要使用链接来指向已经存储过的文件就够了

所谓的快照,就是由文件和指向某个已存储文件的链接组成的当前版本。因为有的文件没有发生变更所以在新版本中使用的是指向相应文件之前存储的文件,而不是使用真正的文件,所以这也是称为快照的原因

代码库的存储和复制并非版本控制系统的瓶颈所在,分析文件的差异、查看代码库的各历史版本常常是真正的瓶颈所在。基于这种快照流的设计,Git可以快速地获取到某一时刻的代码库的所有文件,同时可以快速地进行文件各个历史版本的差异比对,甚至是各历史版本或者各分支的代码库整体差异比对。相信一下如果是传统的增量存储方式,一个代码库经过长期的开发,假设代码库已经有10万个文件,每个文件平均经历了100次修改,那么要检索最新的代码库和原始的代码库的差异,就需要检索出1000万个增量才能最终成功比对,这需要难以想象的时间成本。而Git就不存在这个问题,Git只需要检索出最新的代码库快照和原始代码库快照直接比对即可,再依托于Git的diff算法(Myers算法),Git可以高效快速地检索出二者的差异来。

总结一下,就是如果想要获取当前版本和历史版本的代码库的差异,采用增量存储方式,就需要将所有文件的所以的差异组合起来,当代码库中文件数目多且文件修改次数增多时这个过程的时间成本就会很高;而使用快照流存储方式,因为各个版本的代码库都是以文件和链接组成的,所以只需要将需要进行差异比对的代码库直接对比即可,在依赖相应的算法就可以高效快速地检索出二者的差异。

 

  • 本地执行

Git另一个非常高效的原因是它几乎所有的操作都是在本地执行的,除了几个极少数的需要跟服务器同步代码的操作(push、pull、fetch)。这种本地执行的能力正是来自于克隆一次即获得代码库的完整副本这一特性。

然而类似SVN和Perforce一类的集中式分布系统,当没有网络连接时我们依然可以对本地代码进行修改,但却无法提交代码,更不用说查询提交历史、比对版本差异(因为历史版本都存放在中央服务器当中,而断网后无法从中央服务器中获取历史版本,也就无法进行版本差异比对,因为版本差异比对是需要历史版本的)。在日常的开发工作中,修改代码只是工作的一部分,还有很大部分工作需要不断与代码库各历史版本进行交互。在集中式分布系统中,当发生网络异常时,这类工作就几乎无法进行,从而很可能导致开发中断。即使是网络正常的情况下,集中式分布系统的工作效率也远低于Git的本地化执行。

 

  • 使用SHA-1哈希值保证完整性

Git中所有数据对象(详见下文)在存储前都会计算SHA-1校验和,生成一个40位的十六进制哈希值字符串。基于此校验和,就不可能在Git不知情的情况下更改任何文件内容。

 

  • Git一般只添加数据

这个特性指的是,正常情况下我们执行的Git操作几乎只往Git里增加数据。因此很难让Git执行任何不可逆的操作,或者让它以任何方式清除数据(因为是增加数据,而不是修改数据。增加了可以删除,但是修改了可能就难以恢复了)。同其他版本控制系统一样,没有提交的更新有可能出现丢失的情况,但是一旦我们将更改提交到Git中后,就很难在丢失数据。

这个特性使得我们可以放心且愉悦地使用Git,我们可以尽情地做任何尝试。即使误操作出现数据丢失,我们也可以通过各种手段将其进行快速恢复。

 

  • 三种状态

Git中文件一般有三种状态:已提交Committed、已修改Modified、已暂存Staged。

 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐