章节 ▾ 第二版

10.1 Git 内部原理 - 底层命令与高层命令

你可能从更早的章节直接跳到本章,也可能一路按顺序读到这里——无论哪种情况,本章都会深入探讨 Git 的内部工作原理和实现。我们发现理解这些信息对于理解 Git 的强大和实用性至关重要,但也有人认为这对于初学者来说可能令人困惑且不必要地复杂。因此,我们将这一讨论放在本书的最后一章,以便你可以在学习过程中选择早点阅读或稍后阅读。我们由你决定。

既然你已经来到这里,那我们开始吧。首先,如果还不清楚的话,Git 本质上是一个内容寻址的文件系统,上面编写了一个 VCS 用户界面。你稍后会更深入地了解这意味着什么。

在 Git 的早期(大部分是 1.5 版本之前),用户界面要复杂得多,因为它更强调文件系统而不是一个完善的 VCS。在过去几年中,UI 经过了精炼,变得像任何其他系统一样清晰易用;然而,关于早期 Git UI 复杂且难以学习的刻板印象仍然存在。

内容寻址的文件系统层非常酷,所以我们会在本章中首先介绍它;然后,你将了解传输机制和仓库维护任务,这些是你最终可能需要处理的。

底层命令与高层命令

本书主要介绍了如何使用 Git 的大约 30 个子命令,例如 checkoutbranchremote 等等。但是由于 Git 最初是一个版本控制系统的工具包,而不是一个完整的用户友好型 VCS,所以它有许多执行底层工作的子命令,这些子命令被设计成 UNIX 风格的链式调用或者从脚本中调用。这些命令通常被称为 Git 的“底层命令”(plumbing commands),而更用户友好的命令则被称为“高层命令”(porcelain commands)。

正如你现在已经注意到的,本书的前九章几乎完全处理高层命令。但在本章中,你将主要处理较低层的底层命令,因为它们让你能够访问 Git 的内部工作原理,并帮助演示 Git 如何以及为何如此运行。其中许多命令并非旨在手动在命令行中使用,而是作为构建新工具和自定义脚本的构建块。

当你在新目录或现有目录中运行 git init 时,Git 会创建 .git 目录,Git 存储和操作的几乎所有内容都位于其中。如果你想备份或克隆你的仓库,将此目录复制到其他地方就可以得到你几乎需要的一切。本章基本上都围绕着你在此目录中可以看到的内容。以下是一个新初始化的 .git 目录的典型样子:

$ ls -F1
config
description
HEAD
hooks/
info/
objects/
refs/

根据你的 Git 版本,你可能会在那里看到一些额外的内容,但这是一个全新的 git init 仓库——这是你默认看到的内容。description 文件仅由 GitWeb 程序使用,所以不用担心它。config 文件包含你项目特定的配置选项,info 目录保存一个全局排除文件,用于你不想在 .gitignore 文件中跟踪的忽略模式。hooks 目录包含你的客户端或服务器端钩子脚本,这些在Git 钩子中详细讨论。

这剩下四个重要的条目:HEAD 和(尚未创建的)index 文件,以及 objectsrefs 目录。这些是 Git 的核心部分。objects 目录存储数据库的所有内容,refs 目录存储指向该数据中提交对象的指针(分支、标签、远程等),HEAD 文件指向你当前检出的分支,而 index 文件是 Git 存储暂存区信息的地方。现在你将详细查看这些部分中的每一个,以了解 Git 的操作方式。