首页 > 其他分享 >探索Git内部原理

探索Git内部原理

时间:2022-12-04 12:12:02浏览次数:35  
标签:文件 Git 探索 object git 原理 txt 目录

image

Git是一个开源的分布式版本控制系统,是目前主流的版本控制系统,很多软件项目都会用它做源代码管理。Git的常用操作想必很多人都会,但是可能了解Git内部原理的人并不多。了解一些底层的东西,可以更好的帮你理清思路,遇到问题的时候也可以更好的去解决。

准备工作

在介绍Git如何存储数据之前,我们先做一些准备工作。
首先新建一个目录git-test,然后在这个目录右键,打开Git Bash,

image

然后,在Git Bash,分别执行以下命令,

$ git init  
$ echo 'a' > a.txt
$ echo 'b' > b.txt
$ git add .

至此,准备工作完成。我们可以看到,git-test目录下现在有一个.git目录,以及两个txt文件(a.txt、b.txt)。

image

Git如何存储数据

.git目录是git init后在当前目录生成的一个管理git仓库的目录,这里包含所有git操作所需要的东西。其中objects目录下存放所有的git对象。经过上面的操作后,objects目录是这样的,

image

其中info和pack目录是执行git init以后就已经有的,而78和61目录分别对应着a.txt和b.txt文件,这两个目录是创建了a.txt和b.txt,并执行git add .命令后才生成的。

78目录下有一个文件,查看一下这个文件的内容,执行以下命令,

$ cat .git/objects/78/981922613b2afb6025042ff6bd878ac1994e85

image

我们看到文件的内容是一串乱码,这是因为Git将信息压缩成二进制文件。Git提供了一个能够帮助探索objects的命令:git cat-file [-t] [-p], -t可以查看object的类型,-p可以查看object储存的具体内容。分别执行以下命令,

$ git cat-file -t 7898  
$ git cat-file -p 7898

image

blob类型的object

7898就是目录名加上文件名的前两位。可以看到,这个object是一个blob类型的对象,而这个对象存储的内容,就是我们写入到a.txt的文本。因此,上面的乱码其实就是a.txt的内容,也就是说,这个object存储着a.txt文件的内容。

blob类型的object储存的是一个文件的内容。然后,git根据这个文件的内容经过SHA1哈希算法得到对应的哈希值(981922613b2afb6025042ff6bd878ac1994e85),作为这个object在Git仓库中的唯一id。现在的git存储是这样子的,如图:

image

tree类型的object

接着执行下一个命令,

$ git commit -m '第一次提交'

执行git commit命令后,objects目录下又多出了两个object,如图:

image

首先,用git cat-file -t命令查看f4目录下的文件,如图:

image

可以看到,这个object的类型是tree,利用git cat-file -p命令查看这个object的内容,如图:

image

可以看到,tree类型的object存储了一个目录结构的快照,从左到右分别显示了每个文件的权限、类型、object的id(SHA1值)、以及文件名。现在的Git仓库是这样子的,如图:

image

commit类型的object

用同样的方法,查看3c目录下的文件,如图:

image

这是一个commit类型的object,而这个object存储了一个tree类型的object的id,以及提交的一些信息。现在的Git仓库是这样子的,如图:

image

分支

实际做项目都会有很多分支,git的分支信息就存储在/.git/refs/heads目录下,如图:

image

因为现在只有一个master分支,所以只有一个master文件。直接打开master这个文件,可以看到这个文件存储了3c0acd6df4df30074678a2b97967a82efd9c8acf这样一串字符串,这正是上面的commit类型object的id。现在的Git仓库是这样子的,如图:

image

HEAD

在/.git/HEAD这个文件下,记录内容如下:

ref: refs/heads/master

这个内容告诉Git当前修改的内容是基于哪个分支上的,我们可以理解为这是一个指针。现在的Git仓库是这样子的,如图:

image

至此,一个完整的Git存储结构就出来了。

Git的三个分区

Git有3个分区,分别是工作区、暂存区和版本库。

工作区: 就是项目所在目录(除去.git目录),所有代码开发编辑都在这上面完成。

暂存区: 英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。

Git仓库: 由Git object记录着每一次提交的快照,以及链式结构记录的提交变更历史。

有了3个分区,整个结构如下图:

image

Git的内部运作

现在,我们尝试修改a.txt文件,如图:

image

这时候,除了工作目录下的a.txt文件内容有变化,暂存区和Git仓库都是没有变化的。接着,执行git add a.txt命令,这时/.git/objects目录下又多了一个对象,如图:

image

这个新增的object也是blob类型,对应着新修改的a.txt文件。这时,整个结构如下图:

image

最后,我们执行git commit -m '修改a.txt'命令,不出意外,/.git/objects目录会生成两个object,根据上面的介绍,这两个object分别是tree和commit类型,如图:

image

这时,整个结构如下图:

image

从上图可以看到,master分支已经指向新的commit object,并且新的commit object记录着它的parent object,也就是旧的那个commit object,这使得我们可以查看Git的提交历史。

标签:文件,Git,探索,object,git,原理,txt,目录
From: https://www.cnblogs.com/ayic/p/16678252.html

相关文章

  • 容斥原理学习笔记
    定义集合两个集合的交集:集合\(A\)与\(B\)的交集可以表示为:\[A\capB=\{x:x\inA\landx\inB\}\]两个集合的并集:集合\(A\)与\(B\)的并集可以表示为:\[A\c......
  • 基于jenkins+kubernetes的cicd流程实践一:环境搭建及方案原理
    1.基础环境:Centos7.9,kubernetes:v1.21.5node-1@112(master):docker,containerd,harbornginx(80),git,etcdnode-2@109(master/worker):docker,containerd,ingress_nginx(80),etcd,glusterfs......
  • git-lab安装
    进入官网https://packages.gitlab.com/gitlab/gitlab-ce/选择相应的版本下载  安装相关的依赖yuminstallcurlopenssh-serveropenssh-clientspostfixpolicyc......
  • git合入代码过程中问题记录
    问题一、对远端仓库没有操作权限ERROR:Repositorynotfound.fatal:Couldnotreadfromremoterepository.定位思路1.检查git代码仓的公钥是否存在在github上仓......
  • 路由原理
    1.<路由表里没有原地址> 路由选路,顺序最长掩码>优先级>开销值(数字越小优先级越高)【目标网络号+掩码】【Proto:协议】【Pre:优先级】(Cost:开销值metric度量值)【NextHop:......
  • git
     gitbranch-fmainC6gitcheckoutHEAD^//gitcheckoutHEAD~1gitbranch-f bugFixHEAD~1  题目要求是撤销local和pushed的最近一次提交 local是本......
  • Jenkins+GitLab实现构建JAVA代码
    目录一、前置环境配置二、创建一个maven任务需要提前部署完成Jenkins+GitLab+maven可以参考我的其他文章进行部署一、前置环境配置1、安装MavenIntegration插件Jenki......
  • Github最受欢迎的TOP 10开源RTSP流媒体项目
    Github选出 TOP10开源免费的RTSP流媒体项目,以下是具体排名及星星数。  1、Easydarwin星星数:4,307Easydarwin是国内团队开发的开源流媒体框架。它是基于Go语......
  • #yyds干货盘点# 名企真题专题:小米Git
    1.简述:描述Git是一个常用的分布式代码管理工具,Git通过树的形式记录文件的更改历史(例如示例图),树上的每个节点表示一个版本分支,工程师经常需要找到两个分支的最近的分割点。......
  • 使用Git对项目进行分支管理,更加方便项目的协作开发!
    在项目的开发过程中,很多时候都会使用Git托管工具进行项目文件或者代码的管理,方便团队成员之间的协作开发。使用Git进行项目管理目前也是越来越受到欢迎,除了Git还有很多的其......