章節 ▾ 第二版

10.1 Git 內部命令和外部命令

您可能從之前的某個章節直接跳到了這一章,也可能是一路順讀到這裡的——無論哪種情況,這一章將介紹 Git 的內部工作原理和實現。我們認為理解這些資訊對領會 Git 的實用性和強大功能至關重要,但也有人認為這對初學者來說會令人困惑且不必要地複雜。因此,我們將這一章放在了本書的最後,您可以選擇早讀或晚讀。決定權在您。

現在您已經到了這裡,讓我們開始吧。首先,如果還不清楚,Git 本質上是一個內容可定址的檔案系統,其頂部覆蓋了一個版本控制系統(VCS)的使用者介面。您很快就會更深入地瞭解這意味著什麼。

在 Git 的早期(主要是 1.5 版本之前),使用者介面更加複雜,因為它更側重於檔案系統本身,而不是一個完善的版本控制系統。在過去的幾年裡,UI 已經得到了改進,變得像任何其他系統一樣簡潔易用;然而,關於早期 Git UI 複雜難學的刻板印象依然存在。

內容可定址的檔案系統層非常酷,我們將在本章首先介紹它;然後,您將學習到您最終可能需要處理的傳輸機制和倉庫維護任務。

內部命令和外部命令

本書主要介紹瞭如何使用 Git 的大約 30 個子命令,如 checkoutbranchremote 等。但由於 Git 最初是一個版本控制系統的工具集,而不是一個完整的使用者友好型版本控制系統,它包含許多執行底層工作的子命令,這些命令設計為可以像 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 Hooks 中詳細討論。

這就剩下四個重要的條目:HEAD 檔案、(尚未建立的)index 檔案,以及 objectsrefs 目錄。這些是 Git 的核心部分。objects 目錄儲存了您的資料庫的所有內容,refs 目錄儲存了指向該資料中提交物件的指標(分支、標籤、遠端倉庫等),HEAD 檔案指向您當前檢出的分支,index 檔案是 Git 儲存暫存區資訊的地方。接下來,我們將詳細探討這些部分,以瞭解 Git 的工作方式。