Git原理

Git文件夹

1.配置文件
2.钩子(hooks)
3.缓存区(index)
4.对象数据库(objct database)

object database

object database 存放四种文件:1.blob 2.tree 3.commit 4.tag

object database中存放2种格式的文件一种是松散格式,也就是进行了hash-1计算得到的格式,另一种是.pack.idx的打包格式

blob对象的hash计算 content = (type + cotent.size + \0)(header指针) + coetent 将加入了指针内容的文件内容进行hash-1计算

git gc

同一个文件修改了很少的内容,用git gc对其打包生成.pack文件,.idx文件,将每次修改的文件进行压缩放入到.pack文件中,idx文件存放指向不同版本的指针

blob对象

tree对象

tree对象的hash = (tree + cotent.size + \0) + inode信息(mode + type + 块指针) + 文件名

commit对象

commit指向的是项目顶级目录下的tree

commit对象 hash = (commit + cotent.size \0) + content

parent指针作用是指向上一个commit tree指针指向的是当前版本下的顶级tree位置

当前版本只可能指向一个tree文件,因为commit只可能指向顶级tree,但当前commit可能指向多个父commit,因为合并后的分支是多个

tag对象

tag对象 hash = (tag + cotent.size \0) + content

object指针 通常指向被打标签对象commit type 表明被打标签对象的文件类型

指针文件夹refs

切回版本只要改掉指向另一个commit的hash值即可

每次commit时,如果文件有变化就会生成新的hash,指针会自动指向新的hash

切换工作树,实际只要找到当前的commit版本号,把blob文件回写到文件中即可

本地仓库

每个版本都是一个快照,图中总共有6个文件,其中有4个不同的文件A1,B1,A,B,为了避免重复这4个文件也要使用一个方法将其只保存一份,sha-1算法

使用sha-1算法

SHA-1将文件中的内容通过通过计算生成一个 40 位长度的hash值。特点:1.由文件内容算出hash值2.hash值相同文件内容相同

echo 'test content' | git hash-object --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

文件内容相同,hash值相同

graph LR
A --> A

d6704 --> d6704

hashid文件复用

利用sha-1生成的id,我们就可以用这个id来复用文件,当文件没有变动的时候,我们就复用这个hash,当文件变动时,那我们就重新生成新的hash,给后一个版本引用

.git/object 对象数据库

使用hash-1前2位创建文件夹,后38位作为文件名

obj文件分类

分为4类 blob,tree,commit,tag

类型 作用
blob 首先 A、A1、B、B1 就是 blob 类型的 obj。blob: 用来存放项目文件的内容,但是不包括文件的路径、名字、格式等其它描述信息。项目的任意文件的任意版本都是以blob的形式存放的
tree 用来表示目录。我们知道项目就是一个目录,目录中有文件、有子目录。因此 tree 中有 blob、子tree,且都是使用 sha-1值引用的。这是与目录对应的。从顶层的 tree 纵览整个树状的结构,叶子结点就是blob,表示文件的内容,非叶子结点表示项目的目录,顶层的 tree 对象就代表了当前项目的快照。
commit 表示一次提交,有parent字段,用来引用父提交。指向了一个顶层 tree,表示了项目的快照,还有一些其它的信息,比如上一个提交,committer、author、message 等信息

暂存区

.git/index

当我们提交(commit)时,git 会使用暂存区的这些信息生成tree对象,也就是项目快照,永久保存到数据库中。因此也可以说暂存区是用来构建项目快照的区域。

$  git ls-files --stage

描述
2 第二列就是sha-1 hash值,相当于内容的外键,指向了实际存储文件内容的blob。
3 第三列是文件的冲突状态
4 第四列是文件的路径名。

results matching ""

    No results matching ""