「Git 内核」对象模型

「这是我参与11月更文挑战的第 12 天,活动详情查看:2021最后一次更文挑战


虽然很多程序员都熟悉使用git,但我更想深入了解git是如何实现的。git采用了许多巧妙的点子来优化常见的版本控制操作。学习git应该是不断练习而不是阅读大量文档,所谓纸上谈兵。所以这也是我写这篇文章的原因。

本篇文章是用 rust remake git,但你可以找到很多其他语言的git实现(比如: go)。

对象模型

这个系列并不是对git的介绍。网上有很多关于如何使用git的好的解释。但我确实想回顾一下git的几个核心概念,因为它们对理解git的工作原理很重要。

版本控制

git 是许多 "版本控制软件" 的软件之一,不过它是目前最流行的(Linus NB)。尽管这些VCS的实现在细节上有所不同,但它们有许多相同的核心思想。

版本控制的目的不仅仅是存储一组文件的当前状态,还包括这些文件随时间变化的历史。

这个历史可以被浏览、更新和共享,这使得版本控制在编辑历史很重要的应用中成为一个非常有用的工具,特别是在软件开发中。

提交

git 将其历史存储为一个快照的集合,称为 "commit"。你可以浏览任何提交的文件状态;这个操作被称为 "检查" 提交。

你可以把提交看作是你的代码的一系列备份,尽管我们后面会看到git有一些技巧来减少所有这些备份所需的存储空间。

每个提交都建立在先前的提交之上,这些提交被称为其 "父级" 提交。

在最简单的情况下,提交历史是 "线性" 的(也就是说成为一条直线),即每个提交都有一个父级和子级(除了第一个和最后一个提交)。

例如,可能有三个提交,依次是 A、B、C。下面我们可以用一个提交图来说明这一点:

A --- B --- C
复制代码

然而,即使在小项目中,提交历史也很少是完全线性的。git允许提交历史的 "分支",即多个提交建立在同一个父提交之上。 这很有用,比如说,当开发人员在并行开发功能时,不希望在他们的功能最终完成之前影响对方的代码。这可能会导致如下的提交图:

A --- B --- C --- D
        \
         E --- F --- G
复制代码

**提交历史也可以 "合并",即一个提交合并多个父提交。**在上面的例子中,提交G可能被合并到D,产生一个新的提交H。

A --- B --- C --- D --- H
        \             /
         E --- F --- G
复制代码

分支和标签

每个提交都有一个ID,叫做 "提交hash"(待会看到这个哈希值的来源)。尽管我们可以用哈希值来指代任何一个提交,但给提交命名往往是很方便的。

分支和标签就是完成上述的两种方法。两者都是对提交的引用。

不同的是,在分支上提交会更新分支,使其指向新的提交,而标签则始终指向同一个提交。

传统的做法是用主分支指向最新的可生产的提交,用 feature/xyz、fix/xyz 等来跟踪添加功能或修复错误的进展。标签主要用于标记对应于特定版本的发布。

Guess you like

Origin juejin.im/post/7032260938208116772
Git