小巧。快速。可靠。
三选二。
为什么SQLite不使用Git

1. 简介

SQLite不使用Git版本控制系统。SQLite使用Fossil,这是一种专门为支持SQLite而设计和编写的版本控制系统。

人们经常想知道为什么SQLite不像其他人一样使用Git版本控制系统。本文试图回答这个问题。此外,在第3节中,本文为Git用户提供了一些提示,说明他们如何轻松访问SQLite源代码。

本文不是Fossil和Git之间的比较。请参阅https://fossil-scm.org/fossil/doc/trunk/www/fossil-v-git.wiki以了解这两个系统的比较。还有其他第三方比较可用 - 使用搜索引擎查找它们。

本文建议您将项目从Git切换出去。您可以使用任何您想要的版本控制系统。如果您对Git非常满意,那么请继续使用Git。但是,如果Git对您不起作用,或者您想知道是否可以改进它,或者是否有更好的东西,那么也许尝试理解下面提出的观点。利用由此获得的见解来查找或编写一个不同且更好的版本控制系统,或者只是对Git本身进行改进。

1.1. 编辑记录

本文已多次修订,以期提高清晰度,解决问题和疑虑,并修复错误。此文档的完整编辑历史记录可在https://sqlite.ac.cn/docsrc/finfo/pages/whynotgit.in中查看。(使用提示:点击图中的任意两个节点以查看差异。顺便问一下,是否有任何Git网页界面提供类似的功能?)

2. SQLite不使用Git的几个原因

2.1. Git没有提供良好的情境感知

当我想查看SQLite上发生了什么时,我会访问时间线,并在一个屏幕上看到所有分支的最新更改摘要。只需点击几下,我就可以深入到我想要的任何细节。我甚至可以从手机上执行此操作。

GitHub和GitLab没有提供可比的功能。我找到的最接近的是网络图,它渲染速度很慢(除非已缓存),没有提供太多细节,并且在手机上几乎无法使用。提交视图提供了更多细节,渲染速度很快,并且可以在手机上使用,但每次只显示一个分支,因此我无法轻松地知道是否已经查看了所有最近的更改。即使GitHub/GitLab确实提供了更好的界面,但两者都是第三方服务。它们不是Git的核心部分。因此,使用它们会将另一个依赖项引入项目中。

我被告知,Git用户通常会安装Git的第三方图形查看器,其中许多查看器在显示项目的最新活动方面做得更好。这很好,但这些仍然是必须单独安装和管理的第三方应用程序。许多是特定于平台的。(例如,其中一个比较好的,GitUp,仅适用于Mac。)所有这些都需要您首先同步本地存储库,然后在桌面上打开其图形界面。即使有了所有这些,我仍然无法在没有多次点击的情况下看到我通常想要看到的内容。在办公室外使用手机检查项目状态不是一种选择。

2.2. Git难以找到某个提交的后继版本(后代)

Git允许您向后查看历史,但不能向前查看。给定某个历史提交,您可以看到它之前发生了什么,但很难看到接下来发生了什么。

相比之下,Fossil提供了有用的显示,例如https://sqlite.ac.cn/src/timeline?df=major-release,以显示从最近的主要版本派生的所有提交。

在Git中找到某个提交的后代并非不可能。只是比较困难。例如,有一个Stack Overflow页面显示了在Unix中查找某个提交的后代的命令序列

git rev-list --all --parents | grep ".\{40\}.*.*" | awk '{print $1}'

但这并非完全相同。上面的命令给出了一个后代列表,但没有显示分支结构,而分支结构对于理解发生了什么非常重要。并且该命令仅在您拥有存储库的本地克隆时才有效;查找某个提交的后代不是您可以在GitHub或GitLab等网页界面上执行的操作。

这不仅仅是偶尔查找某个提交的后代。Fossil中后代易于访问的事实意味着该信息遍布Fossil提供的网页。一个例子:每个Fossil提交信息页面(示例)显示了该提交的直接前驱和后继的小型“上下文”图。这有助于用户保持更好的情境感知,并提供有用的功能,例如能够在序列中点击到下一个提交。另一个例子:Fossil可以轻松显示特定提交周围的上下文(示例),这再次有助于提高情境感知和对代码中发生情况的更深入理解。在Fossil文档中有一个完整的其他示例页面

以上所有内容从理论上讲在Git中都是可能的,前提是使用正确的扩展和工具以及正确的命令。但这并不容易,因此很少有人这样做。因此,开发人员对代码中发生的情况的了解较少。

2.3. Git的心智模型过于复杂

Git的复杂性分散了对正在开发的软件的注意力。Git用户需要牢记以下所有内容

  1. 工作目录
  2. “索引”或暂存区
  3. 本地分支头
  4. 远程分支头的本地副本
  5. 实际的远程分支头

Git有命令(或命令选项)用于在所有这些位置之间移动和比较内容。

相比之下,Fossil用户只需要考虑他们的工作目录和他们正在处理的提交。这减少了60%的干扰。每个开发人员都有有限数量的脑容量。Fossil需要更少的脑容量来操作,从而释放出智力资源专注于正在开发的软件。

一位同时使用Git和Fossil的用户在HN上写道

Fossil让我安心,我知道所有内容……都已使用单个命令同步到服务器……我从未在git中获得过这种安心感。

2.4. Git不跟踪历史分支名称

Git保留了提交序列的完整DAG。但是分支标签是本地信息,在分支关闭后不会同步也不会保留。这使得审查历史分支变得乏味。

例如,假设客户问您:“两年前的‘prefer-coroutine-sort-subquery’分支后来怎么样了?”您可能会尝试通过查询版本控制系统中的历史记录来回答,如下所示

Fossil视图清楚地显示该分支最终合并回主干。它显示了分支的起始位置,并显示了主干上的更改合并到分支中的两个场合。GitHub没有显示任何这些信息。实际上,GitHub显示在尝试弄清发生了什么事情时几乎毫无用处。

许多读者推荐了各种Git的第三方GUI,这些GUI可能在显示历史开发活动方面做得更好。也许其中一些确实比原生Git和/或GitHub工作得更好,尽管它们都会受到Git不会跨同步保留历史分支名称这一事实的阻碍。即使其他工具更好,也必须转向第三方工具才能获取所需信息这一事实也并不能说明核心系统很好。

2.5. Git需要更多管理支持

Git是复杂的软件。需要某种安装程序才能将Git安装到开发人员的工作站上,或升级到更新版本的Git。建立Git服务器并非易事,因此大多数开发人员使用第三方服务(如GitHub或GitLab),从而引入了其他依赖项。

相比之下,Fossil是一个单一的独立二进制文件,可以通过将其放入$PATH中来安装。该二进制文件包含核心Git以及GitHub和/或GitLab的所有功能。它管理带有wiki、错误跟踪和论坛的社区服务器,为消费者提供打包下载,登录管理等,无需任何额外的软件。为Fossil建立一个社区服务器只需几分钟。并且Fossil效率很高。Fossil服务器可以在每月5美元的VPS或树莓派上正常运行,而GitLab等则需要更强大的硬件。

更少的管理意味着程序员可以花更多时间在软件(在本例中为SQLite)上工作,而花更少时间在版本控制系统上纠结。

2.6. Git的用户体验不佳

以下https://xkcd.com/1597/漫画是一种夸张,但却切中要害

让我们现实一点。很少有人会否认Git提供了次优的用户体验。许多底层实现都体现在用户界面中。界面非常糟糕,甚至有一个模拟网站生成伪造的git手册页

设计软件很困难。这需要很多专注。一个好的版本控制系统应该为开发人员提供帮助,而不是带来挫败感。Git在过去十年中在这方面有所改进,但仍有很长的路要走。

3. Git用户访问SQLite源代码指南

如果您是忠实的Git用户,您仍然可以轻松访问SQLite。本节提供了一些提示说明如何做到这一点。

3.1. 官方GitHub镜像

截至2019年3月20日,现在在GitHub上有一个SQLite源代码的官方Git镜像

该镜像是SQLite的规范Fossil存储库的增量导出。一个cron作业每小时更新一次GitHub存储库。这是一个单向的、只读的代码镜像。不会通过GitHub接受拉取请求或更改。GitHub存储库仅复制Fossil存储库中的内容。所有更改都是通过Fossil输入的。

用于标识 Git 镜像上的检入和文件的哈希值与 Fossil 中的哈希值不同。这有很多原因,其中最主要的是 Fossil 使用 SHA3-256 哈希,而 Git 使用 SHA1 哈希。在导出期间,每个检入的原始 Fossil 哈希值会作为页脚添加到检入注释中。为避免混淆,在引用 SQLite 检入时,始终使用原始的 Fossil 哈希值,而不是 Git 哈希值。

3.2. Web 访问

SQLite Fossil 代码库(https://sqlite.ac.cn/src/timeline)包含用于下载 Tarball、ZIP 归档文件或 SQLite 归档文件 的链接,这些文件对应于 SQLite 的任何历史版本。这些下载的 URL 非常简单,可以轻松地整合到自动化工具中。格式如下:

https://sqlite.ac.cn/src/tarball/VERSION/sqlite.tar.gz

只需将VERSION替换为要下载的版本的描述即可。VERSION可以是特定检入的加密哈希名称的前缀,也可以是分支的名称(在这种情况下,将获取分支的最新版本),或者像“version-3.23.1”这样的特定检入的标签。

https://sqlite.ac.cn/src/tarball/version-3.23.1/sqlite.tar.gz

要获取最新版本,请使用“release”作为VERSION,如下所示:

https://sqlite.ac.cn/src/tarball/release/sqlite.tar.gz

要获取最新的主干检入,请使用“trunk”作为VERSION

https://sqlite.ac.cn/src/tarball/trunk/sqlite.tar.gz

依此类推。对于 ZIP 归档文件和 SQLite 归档文件,只需将“/tarball/”元素更改为“/zip/”或“/sqlar/”,并可能将下载文件的名称更改为具有“.zip”或“.sqlar”后缀。

3.3. Fossil 访问

Fossil 易于安装和使用。以下是 Unix 系统的步骤。(Windows 系统类似。)

  1. https://fossil-scm.org/fossil/uv/download.html 下载自包含的 Fossil 可执行文件,并将可执行文件放在 $PATH 中的某个位置。
  2. mkdir ~/fossils
  3. fossil clone https://sqlite.ac.cn/src ~/fossils/sqlite.fossil
  4. mkdir ~/sqlite; cd ~/sqlite
  5. fossil open ~/fossils/sqlite.fossil

此时,您已准备好键入“./configure; make”(或在使用 MSVC 的 Windows 系统上键入“nmake /f Makefile.msc").

要将您的检出更改为 Fossil 的不同版本,请使用“update”命令:

fossil updateVERSION

使用“trunk”作为VERSION以获取 SQLite 的最新主干版本。或者使用加密哈希名称的前缀,或某个分支或标签的名称。有关VERSION可以使用哪些名称的更多建议,请参阅 https://fossil-scm.org/fossil/doc/trunk/www/checkin_names.wiki

在 ~/sqlite 检出目录中使用“fossil ui”命令可以打开网站的本地副本。

有关 Fossil 的其他文档可以在 https://fossil-scm.org/fossil/doc/trunk/www/permutedindex.html 找到。

不要害怕探索和实验。如果没有登录,您将无法推送您所做的任何更改,因此您无法损坏项目。

3.4. 验证源代码完整性

如果您需要验证您拥有的 SQLite 源代码是否真实且未以任何方式修改(例如,被攻击者修改),则可以使用一些简单的命令行工具来完成此操作。在 SQLite 源代码树的根目录中有一个名为“manifest”的文件。该清单文件包含源代码树中每个其他文件的名称,以及该文件的 SHA1 或 SHA3-256 哈希值。(SHA1 用于较旧的文件,SHA3-256 用于较新的文件。)您可以编写一个脚本来提取这些哈希值,并针对源代码文件进行验证。检入的哈希名称只是“manifest”文件本身的 SHA3-256 哈希值,如果最后一行以“# Remove this line...”开头,则可能省略最后一行。

4. 另请参阅

其他讨论 Fossil 和 Git 的页面包括:

此页面上次修改于 2023-02-27 02:07:35 UTC