跳转至

GIT BASIC

Git基本概念说明,其实这个网站就够了。

数据模型

Git 将顶级目录中的文件和文件夹作为集合,并通过一系列快照来管理其历史记录。在 Git 的术语里,文件被称作 Blob 对象(数据对象),也就是一组数据。目录则被称之为“树”,它将名字与 Blob 对象或树对象进行映射(使得目录中可以包含其他目录)。快照则是被追踪的最顶层的树。所有的 git 命令都对应着对提交树的操作,例如增加对象,增加或删除引用。

// 文件就是一组数据
type blob = array<byte>

// 一个包含文件和目录的目录
type tree = map<string, tree | blob>

// 每个提交都包含一组父辈,元数据和顶层树
type commit = struct {
    parents: array<commit>
    author: string
    message: string
    snapshot: tree
}
  1. 对于普通提交,通常只有一个父提交(数组长度为1)
  2. 对于合并提交(merge commit),会有两个或更多的父提交(数组长度≥2)
  3. 对于初始提交(initial commit),没有父提交(数组长度为0)

对象,内存寻址

Git 中的对象可以是 blob、树或提交:

type object = blob | tree | commit

Git 在储存数据时,所有的对象都会计算它们的SHA1哈希值,作为地址。

objects = map<string, object>

//计算“地址”
def store(object):
    id = sha1(object)
    objects[id] = object

//通过地址取出对象
def load(id):
    return objects[id]

Blobs、树和提交都一样,它们都是对象。当它们引用其他对象时,它们并没有真正的在硬盘上保存这些对象,而是仅仅保存了它们的哈希值作为引用。

可以通过SHA1寻址,如git cat-file -p 4448adbf7ecd394f42ae135bbeed9676e894af85

也可以给SHA1赋予别名(可读性强的),如下references便是别名和哈希值的映射。其中master,main这种都是别名,而HEAD是特殊的别名,指向当前的位置。

references = map<string, string>

// 添加别名
def update_reference(name, id):
    references[name] = id

// 通过别名寻找SHA1哈希值
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)

暂存区