GIT系列——“01”GIT简介

GIT是什么

首先了解下版本管理系统(VCS)。它是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。

这意味着你可以将某个文件回溯到之前的状态。通过比较文件的变化细节,查出最后是谁修改了什么地方,就算你乱来一气把整个项目中的文件删除,也照样可以轻松恢复到原先的样子,但额外增加的工作量却微乎其微。

本地版本控制系统

本地版本控制的思路是通过复制整个项目目录的方式来保存不同的版本。我问过一位UI同事如何进行版本控制,他的回答是:“初版,第二版,第三版,第四版……最终版,最终版2,最终版3…… 都存”。这让我想到:
在这里插入图片描述
这种方式的好处就是简单,但是特别容易犯错。有时候会混淆所在的工作目录,一不小心会写错文件。

为了解决这个问题,人们就开发了许多种本地版本控制系统,大多采用某种简单的数据库来记录文件的历次更新差异。其中最流行的一种叫做 RCS。它的工作原理是在硬盘上保存补丁集(补丁是指文件修订前后的变化),通过应用所有的补丁,可以重新计算出各个版本的文件内容。

在这里插入图片描述

集中化的版本控制系统

后来为了让在不同系统上的开发者协同工作,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。这类系统,诸如 CVS、Subversion 以及 Perforce 等都有一个单一的集中管理的服务器保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
在这里插入图片描述
其好处在于每个人都可以看到项目中的其他人正在做些什么,而管理员也可以分配开发者的权限,集中管理一个 CVCS。其缺点是中央服务器的单点故障会导致所有人员无法进行协同。而且如果中心数据库所在的磁盘损坏会导致数据,包括项目的变更历史的丢失,只剩下人们在各自机器上保留的单独快照,而且很难将不同开发者的快照结合起来复原整个项目。

分布式版本控制系统

为了解决集中化版本控制系统的缺陷,人们开发出了分布式版本控制系统(Distributed Version Control System,简称 DVCS)在这类系统中,客户端是把代码仓库完整地镜像下来,任何一处协同工作用的服务器发生故障,都可以用任何一个镜像出来的本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。而且这类系统都可以和若干不同的远端代码仓库进行交互。
在这里插入图片描述
在同一个项目中,可以分别和不同工作小组的人相互协作,快速进行切换。你可以根据需要设定不同的协作工作流,这在以前的集中式系统中是无法实现的。

Git就是一个分布式版本控制系统,此外还包括了Mercurial、Bazaar、Darcs等。Git可以对软件开发项目中的版本进行管理,协调数位工作人员共同开发

GIT基本原理

Git是一个内容寻址文件系统,其中的细节十分丰富,在此进行粗略介绍。

git的核心结构就在.git(隐藏文件夹)里面,其中需要关注objects文件夹,refs文件夹,HEAD文件,index文件。

我们需要事先知道git中有三种对象。blob对象commit对象tree对象。这三种对象都保存在objects文件夹中。

git最的常用命令是git addgit commit,现在通过这2个命令对git处理流程进行梳理。git项目里面新增文件或者修改文件的时候,通过git add命令,将改变状态后的文件内容放入缓存区中(index),并生成该文件的blob对象并放入objects。然后将文件的数据外加一个头部信息(header)一起做 SHA-1 校验运算而得的长度为40的字符串,前两个字符用于命名子目录,余下的38个字符则用作文件名。
在这里插入图片描述
然后进行git commit提交,此时会以项目的根目录(与.git同一级)为起点,生成一个tree对象,将文件目录和文件目录下的文件对应的blob对象组织起来,tree对象类似于 UNIX 文件系统,其中tree对象对应了 UNIX 中的目录项,blob对象对应了inodes,一个tree对象可能包含了一条或多条tree对象记录(从根文件开始往下遍历出来的其他子文件夹生成的tree对象),tree结构中记录的是一个指向blob对象或者子tree对象的 SHA-1 指针,以及相应的模式、类型、文件名信息。

以根目录生成的tree对象维护的就是当前项目快照。tree对象也会被放入了objects中。于此同时,会生成一个用于组织tree对象的commit对象,其储存了表示项目快照的tree对象的SHA-1指针,还有提交时间,直接父级commit对象(如果是首次提交则没有父commit对象),作者,提交信息。commit对象也会生成40位签名并存入objects。
在这里插入图片描述

这样git就按照每次提交,将历史快照组织起来。且每次add后都为变化后的文件生成一个blob对象存入objects。

所以git保存了文件所有修改版本。其他版本管理系统(例如SVN)保存的是改变的变量,找历史版本需要进行大量计算。而git采取用空间换时间的方式,将所有改变的文件全量保存,找历史版本就是找文件而已。

这种机制带来的好处极大支持了分支操作。分支就是一个指向某一系列提交之首的指针或引用,即最新的commit对象,分支的引用存于refs/heads文件夹里面。

每创建一个分支就会生成一个文件,文件的内容就是分支对应的commit对象的SHA-1值,当前工作范围信息由HEAD文件维护,HEAD 文件是一个符号引用(symbolic reference),指向目前所在的分支,HEAD文件的内容类似这样:ref: refs/heads/develop。

切换分支,即修改当前项目的工作范围,只需要修改HEAD文件,然后从objects查询对应的commit对象 -> tree对象(项目快照)-> blob对象,没有复杂的计算,所以说git的核心部分是一个简单的键值对数据库(key-value data store)。
在这里插入图片描述

后续

细节很丰富,后面的文章会陆续介绍git其他设计细节,感受人民群众在实践过程中创造的魅力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值