-
A1. 附录 A: 在其它环境中使用 Git
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 Git 在 PowerShell 中使用 Git
- A1.9 总结
-
A2. 附录 B: 在你的应用中嵌入 Git
- A2.1 命令行 Git 方式
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. 附录 C: Git 命令
10.1 Git 内部原理 - 底层命令与上层命令
无论是从之前的章节直接跳到本章,还是读完了其余章节一直到这——你都将在本章见识到 Git 的内部工作原理和实现方式。 我们认为学习这部分内容对于理解 Git 的用途和强大至关重要。不过也有人认为这些内容对于初学者而言可能难以理解且过于复杂。 因此我们把这部分内容放在最后一章,在学习过程中可以先阅读这部分,也可以晚点阅读这部分,这取决于你自己。
无论如何,既然已经读到了这里,就让我们开始吧。 首先要弄明白一点,从根本上来讲 Git 是一个内容寻址(content-addressable)文件系统,并在此之上提供了一个版本控制系统的用户界面。 马上你就会学到这意味着什么。
早期的 Git(主要是 1.5 之前的版本)的用户界面要比现在复杂的多,因为它更侧重于作为一个文件系统,而不是一个打磨过的版本控制系统。 不时会有一些陈词滥调抱怨早期那个晦涩复杂的 Git 用户界面;不过最近几年来,它已经被改进到不输于任何其他版本控制系统地清晰易用了。
内容寻址文件系统层是一套相当酷的东西,所以在本章我们会先讲解这部分内容。随后我们会学习传输机制和版本库管理任务——你迟早会和它们打交道。
底层命令与上层命令
本书主要涵盖了 checkout
、branch
、remote
等约 30 个 Git 的子命令。
然而,由于 Git 最初是一套面向版本控制系统的工具集,而不是一个完整的、用户友好的版本控制系统,
所以它还包含了一部分用于完成底层工作的子命令。
这些命令被设计成能以 UNIX 命令行的风格连接在一起,抑或藉由脚本调用,来完成工作。
这部分命令一般被称作“底层(plumbing)”命令,而那些更友好的命令则被称作“上层(porcelain)”命令。
你或许已经注意到了,本书前九章专注于探讨上层命令。 然而在本章中,我们将主要面对底层命令。 因为,底层命令得以让你窥探 Git 内部的工作机制,也有助于说明 Git 是如何完成工作的,以及它为何如此运作。 多数底层命令并不面向最终用户:它们更适合作为新工具的组件和自定义脚本的组成部分。
当在一个新目录或已有目录执行 git init
时,Git 会创建一个 .git
目录。
这个目录包含了几乎所有 Git 存储和操作的东西。
如若想备份或复制一个版本库,只需把这个目录拷贝至另一处即可。
本章探讨的所有内容,均位于这个目录内。
新初始化的 .git
目录的典型结构如下:
$ ls -F1
config
description
HEAD
hooks/
info/
objects/
refs/
随着 Git 版本的不同,该目录下可能还会包含其他内容。
不过对于一个全新的 git init
版本库,这将是你看到的默认结构。
description
文件仅供 GitWeb 程序使用,我们无需关心。
config
文件包含项目特有的配置选项。
info
目录包含一个全局性排除(global exclude)文件,
用以放置那些不希望被记录在 .gitignore
文件中的忽略模式(ignored patterns)。
hooks
目录包含客户端或服务端的钩子脚本(hook scripts),
在 Git 钩子 中这部分话题已被详细探讨过。
剩下的四个条目很重要:HEAD
文件、(尚待创建的)index
文件,和 objects
目录、refs
目录。
它们都是 Git 的核心组成部分。
objects
目录存储所有数据内容;refs
目录存储指向数据(分支、远程仓库和标签等)的提交对象的指针;
HEAD
文件指向目前被检出的分支;index
文件保存暂存区信息。
我们将详细地逐一检视这四部分,来理解 Git 是如何运转的。