1 什么是git
git是一种版本控制系统(version control system),也是所有vcs的标准。vcs追踪了源码的更改,因此能帮你记录源码的历史。
2 git的数据模型
2.1 snapshot(快照)
snapshot就是你这个源码的最顶层的那个目录,也是一种tree。
git本质就是记录一系列snapshots来追踪源码的历史。
2.2 commit
commit才是git仓库(版本库)的单元,即版本库包括了一个一个的commit,每个commit就是一个版本的源码。commit包括parent数组(记录 commit的所有parent)、metadata(元数据,即用来描述这个commit的数据,如作者、提交时间等)、snapshot。
type commit = struct {
parents: array<commit>
author: string
message: string
snapshot: tree
}
2.3 怎么关联commit
关联方式不是一条链,而是有向无环图dag(directed acyclic grapg),即每一个commit可以有多个parent。
2.4 object
git的object(对象)有三种:tree、blob、commit
2.4.1 commit
2.4.2 tree
tree就是一个目录,一个目录下面可以包括目录、文件。
底层实现好像是map,即map<string, blob | commit>,其中string就是这个tree(目录)的名字。映射关系是
2.4.3 blob
blob就是文件,本质是一个字节数组。映射关系是文件名–>文件内容。
2.4.4 伪代码形式的三种object
// a file is a bunch of bytes
type blob = array<byte>
// a directory contains named files and directories
type tree = map<string, tree | blob>
// a commit has parents, metadata, and the top-level tree
type commit = struct {
parents: array<commit>
author: string
message: string
snapshot: tree
}
2.5 content-addressing(内容寻址)
每一个object都是通过SHA-1 hash来寻址的。
objects = map<string, object>
def store(object):
id = sha1(object)
objects[id] = object
def load(id):
return objects[id]
其中id是内存地址
2.6 reference(引用)
总不能每次都靠那么长的内存地址来找到object吧,为了方便使用就有了reference。reference就是起了一个名字,这个名字首先映射为id,通过id指向commit,最终这个名字会指向一个commit。如 “master’”在git中就是指向主分支的最新的commit。“HEAD”就是指向当前分支的所在的位置。
references = map<string, string>
def update_reference(name, id):
references[name] = id
def read_reference(name):
return references[name]
def load_reference(name_or_id):
if name_or_id in references:
return load(references[name_or_id])
else:
return load(name_or_id)
2.7 repositories(仓库、版本库)
版本库中就是object和热封rence,形象化就是这个DAG(有
)。
2.8 staging area(暂存区)
暂存区也是版本库里面的一块。先把修改的文件、新的文件加入到暂存区,然后提交,就形成了新的commit。