本文的主要围绕着下面这个问题展开的,在阅读之前可以先自己思考一下问题的答案是什么?
- git 是如何管理项目每次变更记录的?
当我们创建一个仓库的时候,在仓库的根目录下,除了项目文件,还有一个.git
文件夹。.git
文件夹中的内容就与版本控制相关。
在探秘 git 如何记录修改记录之前,我们先看看.git
下的一些文件用途:
.git/config
:主要是当前项目的git配置信息.git/logs/
:此文件夹主要记录每个分支的每次修改的日志.git/HEAD
:记录工作区中指向哪一个分支.git/refs/heads/
:此文件夹下存放的文件对应每一个分支,文件中存放的是commit对应的版本号
.git/HEAD
和.git/refs/heads/
组合起来正好表示工作区的项目在哪个分支的哪次提交上面做修改。
接着看一下 git 资源库的对象,首先我们要借助一个命令git cat-file
,这个可以查看资源库对象的内容或类型和大小信息。
git cat-file -t
:查看资源库对象的类型git cat-file -p
:查看资源库对象的内容
每一次的 commit 都会仓库中的文件产生一些改变,这时候会生成一个记录,会有一个对应的修订号,这就像对当时的项目文件做一次快照处理,这个是通过资源库的对象保存的。
首先查看仓库的提交记录:
接着我们选取一次修订号,查看这个对象的类型和内容
git cat-file -t 2f001c07fee6d3357da689b0fce
git cat-file -p 2f001c07fee6d3357da689b0fce
从这个对象内容的,我们可以看出来一个commit对象,主要包含一下几部分
tree
:修改的文件路径,这里指向一个文件夹parent
:上一次提交代码时的修订号,对应日志中上一次的提交记录author
:修改文件的作者committer
:提交修改的人,提交人和修改人可以是不同的人
我们可以通过 commit 对象里面的内容接着往下查看,先查看一下tree
里面的内容
这个对象里面包含两个blob
类型的对象,通过行末信息我们可以发现这是之前添加的a.txt
和b.txt
文件。
如果我们在a.txt
同级目录创建一个test
文件夹,里面添加一个文件c.txt
,那么git会怎么存储呢?
1、添加一个新的文件,提交记录会改变,我们需要查看最新的提交记录
2、查看最新的提交记录的对象的内容
3、接着去查询对应tree
对象内容,可以发现其中除了文件,还指向了另外一个tree
,对应的是test
文件夹,
4、接着查看test
文件夹对应的tree
对象,这里面存放着c.txt
文件
5、如果我们接着往下走,查看这个blob对应的修订号,会发现里面就是c.txt
文件中的内容
此时,对Git中的文件存放方式可以有一个大概的了解了,每次 commit 对应一个对象,里面存放一些提交相关的信息,并且指向了上次提交记录和一个tree
,tree表示一个文件夹,commit
中的这个tree
这个文件夹更像是整个项目的根目录。
一个tree
中可能存在tree
,也可能存在blob
,blob
表示目录中的文件,tree
表示这个目录中的目录。简直就是套娃操作。
示例项目可以参考下图