git内部原理—换个角度看本质

Git的常见命令虽然不多,但是,想要更加深刻理解这些命令,掌控每条命令的具体操作,了解Git的内部原理还是很有必要。

首先,我想说两个便于理解我后续解释的概念:

  1. 同一个事物有不同表现形式,但其实质是一个东西,它们可以相互转换。比如,原始文件和压缩后的文件。
  2. 两个事物有确定的映射关系,便可以从一个事物找到另一个事物。比如,通过文件名找文件内容,通过一段数据的hash值来找这段数据。

然后,从功能上来看,Git最核心的就是将文件夹存入仓库中,并且可以随时取出。此处的文件夹指文件夹下所有文件(文件内容、名称、权限等)和子文件夹。只不过存入Git仓库中的文件夹不可以再改变,相当于一个快照。接下来,我们来看Git库中的文件和文件夹的表现形式。

 

数据对象和树对象

对于Git而言,存入库中的文件和文件夹的另一种形式就是数据对象(blob)和树对象(tree)。数据对象就是将文件压缩,同时计算它的hash摘要,从而对它进行索引。树对象就是文件名、权限等和文件(hash摘要)之间的对应关系。

<<树对象和数据对象.vsdx>>

因此,每一个tree对象,都可以转换为一个文件夹。唯一的不同就是tree对象对应的文件夹保存后不再变化,工作空间的文件夹可以动态改变。

 

提交对象

Git每次commit一个版本,其实最主要就是保存了这样一个tree对象,下次便可以直接通过tree复原保存时的文件夹。除此之外,Git还保存了commit时的一些额外信息,比如作者、时间、备注等,由此,便设计出了第三种Git对象:提交对象(commit)。

<<提交对象.vsdx>>

 

暂存区

暂存区(index)其实就是一个临时tree对象。每次commit的时候可以直接把当前工作空间的文件夹直接转换为一个tree对象,并使commit对象指向它。但是,有时候我们的一些临时改动不想存入库中,因此,便加入一个暂存区。

所以,这里有三个文件夹,暂存区和仓库中是tree对象的形式存在。刚开始,三个文件夹内容一致,我们可以直接修改工作空间的文件夹。然后通过命令(git add/rm)可以将想要提交的修改合并到暂存区中的tree对象上。最后通过命令(git commit)才会将暂存区中的tree保存到库中,并生成一个commit对象指向这个tree对象。

<<暂存区.vsdx>>

 

引用

我们复原一个文件夹的时候,先要找到commit对象,然后通过commit对象找到tree对象进行复原。但是,在创建commit对象时,我们得到的索引方式是一串hash值,并不会指定一个名称。引用便是一个名称到hash值得映射关系,这样我们便可以直接从便于记忆的名称找到commit对象。

<<引用.vsdx>>

 

  • 分支:可以随着提交(commit)发生改变的引用
  • 标签:创建后不再改变的引用
  • HEAD:当提交暂存区tree,新建一个提交commit时,这个commit对象的父指针指向HEAD所指向的commit对象。
  • 远程引用:标记远程仓库分支的引用。当和远程仓库同步时(git fetch/push)时,会同时改变。

 Pro Git v2 中文版 - v1.0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值