什么是真正的单体仓库?深入解析技术架构与实现

本文深入探讨了单体仓库的技术本质,分析了原子提交、统一目录结构、单一版本规则等核心概念,比较了Google与LinkedIn的不同实现方式,为技术团队选择适合的代码管理策略提供实践指导。

什么是真正的单体仓库?

在软件公司中,经常会有关于是否应该采用"单体仓库"的讨论,即"公司所有代码都存放在一个版本控制仓库中"。通常,人们基于Google存储代码的方式来做出这个决定。

我在拥有非常先进单体仓库的公司(Google)和拥有非常先进多仓库系统的公司(LinkedIn)都工作过,我必须告诉你:人们与单体仓库关联的大多数有价值特性,与你拥有多少个源代码仓库毫无关系。

事实上,人们(和Google)认为的单体仓库实际上是多个不同的概念:

  • 跨项目的原子提交(因此有一个原子的"头"提交,所有代码都原子性地向前移动)
  • 统一的目录层次结构和所有源代码的单一视图
  • 检出或提交代码的单一位置(包括所有读取或写入内容的工具)
  • (有时)检出、提交和依赖的最小单位是文件
  • (通常)没有项目的概念,只有目录和文件的概念
  • (有时)单一版本规则:任何时候仓库中任何依赖只能有一个版本
  • 要求库维护者解决他们引起的问题的能力

跨项目的原子提交

假设我们有两个独立的项目A和B。我们想要做一个影响这两个项目的更改。“单体仓库"的一部分是保证你可以同时原子性地提交到这两个项目。不存在项目A处于提交#1而项目B处于提交#2的仓库视图。

当你想要进行更改,而如果项目A或B没有同时更改就会被破坏时,这一点尤其重要。

这个特性最依赖于将内容放在单个源代码仓库中,因为实际上"仓库"的定义是"你可以原子性地提交多个文件的位置,它跟踪这些原子提交,并且你可以从该原子提交历史中的任何点检出”。

这个特性还意味着整个仓库有一个单一的"头"(最新提交)定义。这一点很重要,因为当开发人员从仓库中检出时,他们通常在"头"处检出。

标准化的跨项目目录结构

单体仓库中的所有代码都被认为处于单个目录结构中。这在开发时和浏览代码时都有优势。

开发期间:检出是标准化的

在开发期间,如果项目A存储在仓库中的/path/to/project/A,项目B存储在仓库中的/path/to/project/B,当我同时检出它们时,它们将位于彼此相邻的目录中。

统一的代码浏览方式

由于你有单一的目录结构,在代码搜索工具中浏览目录相对简单,并且可以有一个搜索该单一仓库的单一代码搜索工具。

单一的检出和提交位置

单体仓库的价值之一是不必思考"我应该从哪个仓库检出?“相反,开发人员只需要考虑他们需要检出什么代码。类似地,所有提交都进入同一个仓库。

这也意味着你对整个历史的所有提交有一个单一的视图,这有时会很有帮助。

最后,所有工具只需要担心访问单个仓库——它们只需要关心目录和文件名。

文件是检出、提交和依赖的最小单位

在大多数单体仓库中,你可以提交的、由版本控制系统跟踪的最小东西是文件。系统知道"一个文件"是改变的内容。

在一些单体仓库中,你还可以在不检出整个仓库的情况下检出单个文件。事实上,如果仓库变得非常大,这就成为一个非常重要的生产力特性。

此外,在一些单体仓库中(特别是Google的),依赖的最小单位是文件。这意味着构建系统可以知道一个文件依赖于另一个文件。

没有项目的概念

由于所有内容都在同一个仓库中,没有固有的概念认为不同目录的集合可以代表一个单一的"项目”。构建系统可能知道某些目录被编译在一起以产生特定的工件,但没有通用的方法可以通过查看目录结构等轻松看到这一点。

单一版本规则

通常,单体仓库会强制规定任何给定软件在仓库中同时只能存在一个版本。如果你签入一个库,在整个仓库中你只能签入该库的一个版本。

这样做有多个原因。

首先,它使得推理系统行为更加容易。你总是理解你将获得依赖的哪个版本。

但也许这样做最重要的原因是,大多数编程语言强制规定在最终程序中任何特定依赖只能存在一个版本。否则,当你包含同一事物的多个版本时,它们在运行时会出现奇怪的行为。

让库维护者解决他们引起的问题

在单体仓库的世界中,如果你拥有一个库,你可以通过签入与那些项目不兼容的内容来破坏每个依赖你的项目的构建。

这主要是公司政策的问题,但在你可以实际执行它的世界中,以及存在某种系统在库开发人员给他人造成痛苦时也会让他们感到痛苦的世界中,这样做要容易得多。

总结

你可以看到,“单体仓库"实际上远不止是将所有东西放在一个源代码仓库中。有些人已经将所有这些事情归为一组,因为上面基本上是对Google单体仓库的描述,大多数人在谈论"单体仓库"时似乎都在考虑那个系统。但分离这些概念很重要,因为它们中的许多可以在你今天拥有的系统中实现。此外,也许并非所有这些事情实际上都是好的,你应该有意识地选择要在业务中采用哪些。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计