你真的会用 Git 吗?Git 中的数据结构与对应伪代码

Git 拥有一个经过精心设计的模型,这使其能够支持版本控制所需的所有特性,例如维护历史记录、支持分支和促进协作。然而,通过自顶向下的方式(从命令行接口开始)学习 Git 可能会让人感到非常困惑。一旦出现问题,就只能将当前工作保存下来,然后重新复制一份工作,继续进行处理了。如果我们能够先对其底层的数据结构有所了解,在接触命令行接口时,就会更加得心应手。

快照

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

历史记录建模:关联快照

在 Git 中,历史记录是一个由快照组成的有向无环图。每个快照都有一系列的“父辈”,也就是其之前的一系列快照。注意,快照可能同时有多个“父辈”,例如,经过合并后的两条分支。

o <-- o <-- o <-- o <---- o
            ^            /
             \          v
              --- o <-- o

数据模型及其伪代码表示

通过伪代码的表示,能够更加清晰的了解 Git 的数据模型。

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

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

// 每个提交都包含一个父辈,元数据和顶层树
type commit = struct {
    parent: array<commit>
    author: string
    message: string
    snapshot: tree
}

对象和内存寻址

Git 中的对象可以是 blob、树或提交:type object = blob | tree | commit,所有的对象都会通过 SHA-1 哈希进行寻址。

objects = map<string, object>

def store(object):
    id = sha1(object)
    objects[id] = object

def load(id):
    return objects[id]

引用

给这些哈希值赋予人类可读的名字,也就是引用(reference)。引用是指向提交的指针。与对象不同的是,它是可变的(引用可以被更新,指向新的提交)。例如,master 引用通常会指向主分支的最新一次提交。

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)

在 Git 中,我们当前的位置有一个特殊的索引,它就是 “HEAD”。

参考链接:
https://missing-semester-cn.github.io/2020/version-control/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值