git文件存储原理理解

本文详细介绍了Git的工作流程,包括文件在工作区域、暂存区域和已提交区域的状态变化,以及Git如何通过内容寻址文件系统进行版本控制。通过实验演示,深入理解Git在每次提交时如何生成blob、tree和commit对象。

在理解原理之前,我们应该知道git使用流程。git有三个区域,分别是工作区域(Working Tree)、暂存区域(index/stage)、已提交区域(Repository),文件在这三个区域中也有着不同的状态

git文件状态

git文件状态分为四种 Untracked(未跟踪)、staged(已暂存)、modified(已修改)、committed(已提交)

各个状态之间的转换

Untracked状态git status显示

modified状态在工作区域和暂存区域时分别为不同表示

在工作区域时,状态为Changes not staged for commit

在暂存区域时,状态为Changes to be committed

git原理理解

git本质是一个内容寻址文件系统,所有提交的文件都是以文件对象的形式存储在.git/objects中

在git中有这几种文件对象:

tag:对应版本分支的tag

tree:对应文件目录

blob:对应每一个文件

commit:对应每一次提交,使用的链表,带有上一次提交的commit

.git目录结构如下:

当使用git add时git会将add的文件的文件内容生成一个以SHA-1哈希值作为文件内容的校验和的文件对象,哈希值前两位为子目录,后面28位作为文件名存储在子目录中,最终存储在.git/objects文件目录中。并且在暂存区中会记录这些文件对象的哈希值映射

当使用git commit时,git会根据暂存区中的哈希值映射的blob对象以及他们对应的路径生成tree对象,最终生成commit对象,并且将这些对象存储在.git/objects文件目录中。

实验演示

当前git目录下,有a.txt,b.txt文件内容相同并且文件状态都是Untracked

使用git add a.txt, git add b.txt命令之后,使用git ls-files --stage命令查看暂存区blob对象的哈希索引列表,然后在进入到.git/objects文件目录发现文件对象也已经存入到文件目录中,因为git是以文件内容生成SHA-1哈希值和文件名称无关,所以a.txt和b.txt都是使用的同一个文件

使用git commit -m 'new file'之后,接着进入到.git/objects文件目录发现tree对象和commit对象文件也已经存入到目录中

使用git log查看最后一次提交的commit id已经在4e中目录中存储了

使用git cat-file -p 4ee1bf88c39a533b4c9d1ad637a5f2afe816de0a可查看此commit对象中包含的tree对象和blob对象

接着进入到tree对象,可以发现我们刚刚commit的a.txt和b.txt

下面我们修改一下b.txt文件然后commit,查看git log找到commit id

然后使用git cat-file -p d938ddec31acbaaf291010452e2d750e8a7536d3 查看这个commit对象,发现他包含了一个parent对象,这个parent对象就是上一个commit,每个commit对象就是一个链表,其中包含了上一次提交的commit对象

 

总结

1、git add都会在.git/objects文件目录下生成blob文件对象文件,并且在暂存区记录着每一个blob文件对象的哈希索引,

git commit之后会根据暂存区中的哈希索引生成tree对象,最终会生成commit对象, commit对象包含了文件目录的tree对象和文件blob对象以及上一次提交的commit对象。每次提交都会生成这样一个commit对象,并且存储在.git/objects文件目录中。

2、当在当前分支创建一个分支时,也只是将.git/HEAD文件指向创建的分支,并且在.git\refs\heads中的创建分支分支文件指向了

当前分支的commit,并不会为每个分支存储对应的文件对象,每个分支的commit对象还是都会存储在.git/objects文件目录中,所以对于git来说创建分支基本是无消耗,相当快速的。

3、当暂存区某blob文件的哈希值和commit对象中对应的blob文件哈希值不同时,文件状态就会是Changes to be committed。

当工作区和暂存区某blob文件的哈希值不同时,文件状态就会是Changes not staged for commit。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值