簡體中文 ▾ 主題 ▾ 最新版本 ▾ gitrepository-layout 上次更新於 2.49.0

名稱

gitrepository-layout - Git 倉庫佈局

概要

$GIT_DIR/*

描述

一個 Git 倉庫有兩種不同的形式:

  • 工作樹根目錄下的 .git 目錄;

  • 一個 <project>.git 目錄,它是一個 裸倉庫(即沒有自己的工作樹),通常用於透過推送和拉取來與他人交換歷史記錄。

注意:你也可以在你的工作樹根目錄有一個純文字檔案 .git,其中包含 gitdir: <path> 以指向實際的倉庫目錄。這種機制稱為 gitfile,通常透過 git submodulegit worktree 命令進行管理。它常用於子模組檢出的工作樹,以便你在包含的超級專案中 git checkout 一個不包含子模組的分支。這種 checkout 必須移除整個子模組工作樹,同時不丟失子模組倉庫。

這些事物可能存在於 Git 倉庫中。

objects

與此倉庫關聯的物件儲存。通常,物件儲存是自給自足的(即其中找到的任何物件所引用的所有物件也都在其中),但也有幾種情況會違反這一點。

  1. 你可以透過建立淺克隆來獲得一個不完整但本地可用的倉庫。參見 git-clone[1]

  2. 你可以使用 objects/info/alternates$GIT_ALTERNATE_OBJECT_DIRECTORIES 機制從其他物件儲存中“借用”物件。具有這種不完整物件儲存的倉庫不適合釋出供啞傳輸(dumb transports)使用,但只要 objects/info/alternates 指向它所借用的物件儲存,就沒問題。

    如果設定了 $GIT_COMMON_DIR,則此目錄將被忽略,轉而使用 "$GIT_COMMON_DIR/objects"。

objects/[0-9a-f][0-9a-f]

新建立的物件儲存在其自己的檔案中。物件被分散到 256 個子目錄中,使用 sha1 物件名稱的前兩個字元,以使 objects 目錄中的條目數量保持在可管理的範圍內。在此處找到的物件通常被稱為 未打包的(或 鬆散的)物件。

objects/pack

包(以壓縮形式儲存許多物件的檔案,以及允許隨機訪問的索引檔案)在此目錄中找到。

objects/info

關於物件儲存的附加資訊記錄在此目錄中。

objects/info/packs

此檔案用於幫助啞傳輸發現此物件儲存中可用的包。每當新增或移除包時,如果倉庫釋出供啞傳輸使用,則應執行 git update-server-info 以保持此檔案最新。git repack 預設會這樣做。

objects/info/alternates

此檔案記錄了此物件儲存借用物件的備用物件儲存的路徑,每行一個路徑名。請注意,不僅原生的 Git 工具在本地使用它,HTTP fetcher 也嘗試遠端使用它;如果你在 alternates 檔案中使用相對路徑(相對於物件資料庫,而不是倉庫!),這通常會奏效,但如果你使用絕對路徑,除非檔案系統和 Web URL 中的絕對路徑相同,否則將不起作用。另請參閱 objects/info/http-alternates

objects/info/http-alternates

此檔案記錄了此物件儲存借用物件的備用物件儲存的 URL,當透過 HTTP 拉取倉庫時使用。

refs

引用儲存在此目錄的子目錄中。git prune 命令知道要保留此目錄及其子目錄中找到的引用可到達的物件。如果設定了 $GIT_COMMON_DIR,則此目錄(除了 refs/bisect、refs/rewritten 和 refs/worktree)將被忽略,轉而使用 "$GIT_COMMON_DIR/refs"。

refs/heads/name

記錄分支 name 的樹尖(tip-of-the-tree)提交物件。

refs/tags/name

記錄任何物件名稱(不一定是提交物件,也不是指向提交物件的標籤物件)。

refs/remotes/name

記錄從遠端倉庫複製的分支的樹尖提交物件。

refs/replace/<obj-sha1>

記錄替換 <obj-sha1> 的物件的 SHA-1。這類似於 info/grafts,並由 git-replace[1] 內部使用和維護。此類引用可以在倉庫之間交換,而嫁接(grafts)則不能。

packed-refs

以更高效的方式記錄與 refs/heads/、refs/tags/ 等目錄相同的資訊。參見 git-pack-refs[1]。如果設定了 $GIT_COMMON_DIR,則此檔案將被忽略,轉而使用 "$GIT_COMMON_DIR/packed-refs"。

HEAD

指向 refs/heads/ 名稱空間的符號引用(參見詞彙表),描述當前活動的分支。如果倉庫未與任何工作樹關聯(即 裸倉庫),則其意義不大,但一個有效的 Git 倉庫 必須 有 HEAD 檔案;一些高層命令(porcelains)可能會使用它來猜測倉庫的指定“預設”分支(通常是 master)。如果指定的分支 name 尚未存在,這是合法的。在一些舊版設定中,它是一個指向當前分支的符號連結,而不是符號引用。

HEAD 也可以直接記錄特定的提交,而不是作為指向當前分支的符號引用。這種狀態通常被稱為 分離頭指標(detached HEAD)。有關詳細資訊,請參見 git-checkout[1]

config

倉庫特定的配置檔案。如果設定了 $GIT_COMMON_DIR,則此檔案將被忽略,轉而使用 "$GIT_COMMON_DIR/config"。

config.worktree

在多工作目錄設定中,主工作目錄的特定於工作目錄的配置檔案(參見 git-worktree[1])。

branches

一種已棄用的方式,用於儲存供 git fetchgit pullgit push 指定 URL 的簡寫。檔案可以儲存為 branches/<name>,然後可以將 name 傳遞給這些命令,以代替 repository 引數。有關詳細資訊,請參見 git-fetch[1] 中的 REMOTES 部分。此機制是舊版機制,在現代倉庫中不太可能找到。如果設定了 $GIT_COMMON_DIR,則此目錄將被忽略,轉而使用 "$GIT_COMMON_DIR/branches"。

Git 將在 Git 3.0 中停止從此目錄讀取遠端。

hooks

鉤子是各種 Git 命令使用的自定義指令碼。當執行 git init 時,會安裝少量示例鉤子,但預設情況下它們都被停用。要啟用它們,必須透過重新命名從檔名中移除 .sample 字尾。有關每個鉤子的更多詳細資訊,請閱讀 githooks[5]。如果設定了 $GIT_COMMON_DIR,則此目錄將被忽略,轉而使用 "$GIT_COMMON_DIR/hooks"。

common

當使用多個工作樹時,$GIT_DIR 中的大多數檔案是每個工作樹獨立的,除了少數已知例外。然而,common 下的所有檔案將在所有工作樹之間共享。

index

倉庫的當前索引檔案。通常在裸倉庫中找不到它。

sharedindex.<SHA-1>

共享索引部分,由 $GIT_DIR/index 和其他臨時索引檔案引用。僅在分離索引模式下有效。

info

有關倉庫的附加資訊記錄在此目錄中。如果設定了 $GIT_COMMON_DIR,則此目錄將被忽略,轉而使用 "$GIT_COMMON_DIR/info"。

info/refs

此檔案幫助啞傳輸發現此倉庫中可用的引用。如果倉庫釋出供啞傳輸使用,則每次建立或修改標籤或分支時,都應透過 git update-server-info 重新生成此檔案。這通常透過 hooks/update 鉤子完成,該鉤子由 git-receive-pack 命令在你 git push 到倉庫時執行。

info/grafts

此檔案記錄了偽造的提交祖先資訊,以假裝一個提交的父提交集合與實際建立該提交時不同。每行一個記錄描述一個提交及其偽父提交,透過列出它們 40 位元組的十六進位制物件名稱(用空格分隔並以換行符結尾)。

請注意,嫁接機制已過時,可能導致倉庫間物件傳輸出現問題;請參閱git-replace[1]以獲取更靈活和健壯的實現相同功能的系統。

info/exclude

按照高層命令(Porcelains)的慣例,此檔案儲存排除模式列表。.gitignore 是按目錄的忽略檔案。git statusgit addgit rmgit clean 會檢視它,但核心 Git 命令不會檢視它。另請參閱:gitignore[5]

info/attributes

定義要分配給路徑的屬性,類似於按目錄的 .gitattributes 檔案。另請參閱:gitattributes[5]

info/sparse-checkout

此檔案儲存稀疏檢出模式。另請參閱:git-read-tree[1]

remotes

儲存 URL 和預設引用名稱的簡寫,供透過 git fetchgit pullgit push 命令與遠端倉庫互動時使用。有關詳細資訊,請參見 git-fetch[1] 中的 REMOTES 部分。此機制是舊版機制,在現代倉庫中不太可能找到。如果設定了 $GIT_COMMON_DIR,則此目錄將被忽略,轉而使用 "$GIT_COMMON_DIR/remotes"。

Git 將在 Git 3.0 中停止從此目錄讀取遠端。

logs

對此引用的更改記錄儲存在此目錄中。有關更多資訊,請參見 git-update-ref[1]。如果設定了 $GIT_COMMON_DIR,則此目錄(除了 logs/HEAD)將被忽略,轉而使用 "$GIT_COMMON_DIR/logs"。

logs/refs/heads/name

記錄對名為 name 的分支尖端所做的所有更改。

logs/refs/tags/name

記錄對名為 name 的標籤所做的所有更改。

shallow

這類似於 info/grafts,但由淺克隆機制內部使用和維護。參見 git-clone[1]git-fetch[1]--depth 選項。如果設定了 $GIT_COMMON_DIR,則此檔案將被忽略,轉而使用 "$GIT_COMMON_DIR/shallow"。

commondir

如果此檔案存在,並且 $GIT_COMMON_DIR(參見 git[1])未顯式設定,則將其設定為此檔案中指定的路徑。如果指定的路徑是相對路徑,則它相對於 $GIT_DIR。帶有 commondir 的倉庫在沒有 "commondir" 所指向的倉庫時是不完整的。

modules

包含子模組的 Git 倉庫。

worktrees

包含連結工作樹的管理資料。每個子目錄包含連結工作樹中與工作樹相關的部分。如果設定了 $GIT_COMMON_DIR,則此目錄將被忽略,此時將使用 "$GIT_COMMON_DIR/worktrees"。

worktrees/<id>/gitdir

一個文字檔案,包含指向此處的 .git 檔案的絕對路徑。這用於檢查連結的倉庫是否已被手動移除,以及是否不再需要保留此目錄。此檔案的修改時間(mtime)應在每次訪問連結倉庫時更新。

worktrees/<id>/locked

如果此檔案存在,則連結的工作樹可能位於便攜裝置上且不可用。此檔案的存在阻止 worktrees/<id> 被自動或透過 git worktree prune 手動修剪。該檔案可能包含解釋倉庫為何被鎖定的字串。

worktrees/<id>/config.worktree

工作目錄特定的配置檔案。

Git 倉庫格式版本

每個 Git 倉庫都在其 config 檔案的 core.repositoryformatversion 鍵中標記有一個數字版本。此版本指定了在磁碟倉庫資料上操作的規則。不理解磁碟倉庫所宣傳的特定版本的 Git 實現 不得 在該倉庫上操作;這樣做不僅有產生錯誤結果的風險,而且實際上有資料丟失的風險。

由於此規則,版本升級應保持在絕對最小值。相反,我們通常傾向於以下策略:

  • 提升單個數據檔案(例如,索引、包檔案等)的格式版本號。這將不相容性僅限於這些檔案。

  • 引入新資料,這些資料在舊客戶端使用時可以優雅降級(例如,舊客戶端會忽略包點陣圖檔案,它們只是無法利用其提供的最佳化)。

整個倉庫格式的版本升級只應是無法獨立版本化更改的一部分。例如,如果有人要更改物件的觸達規則或鎖定引用的規則,這將需要提升倉庫格式版本。

請注意,這僅適用於直接訪問倉庫的磁碟內容。一個只理解格式 0 的舊客戶端仍然可以透過 git:// 連線到使用格式 1 的倉庫,只要伺服器程序理解格式 1 即可。

推出版本升級(無論是整個倉庫還是單個檔案)的首選策略是:教 Git 讀取新格式,並允許透過配置開關或命令列選項寫入新格式(用於實驗或不關心與舊 Git 版本向後相容的人)。然後,在允許讀取功能普及的長時間之後,我們可以預設切換到寫入新格式。

當前定義的格式版本為:

版本 0

這是 Git 初始版本定義的格式,包括但不限於倉庫目錄、倉庫配置檔案以及物件和引用儲存的格式。指定 Git 的完整行為超出了本文件的範圍。

版本 1

此格式與版本 0 相同,但有以下例外:

  1. 讀取 core.repositoryformatversion 變數時,支援版本 1 的 Git 實現 必須 同時讀取在配置檔案 extensions 部分中找到的任何配置鍵。

  2. 如果版本 1 倉庫指定了執行中的 Git 尚未實現的任何 extensions.* 鍵,則操作 不得 繼續。同樣,如果實現不理解任何已知鍵的值,則操作 不得 繼續。

請注意,如果在配置檔案中未指定任何擴充套件,則 core.repositoryformatversion 應該 設定為 0(將其設定為 1 沒有任何好處,並且會使倉庫與舊版 Git 實現不相容)。

已定義的擴充套件在 git-config[1]extensions.* 部分中給出。任何希望定義新擴充套件的實現都應在此處進行說明,以宣告其名稱。

GIT

Git[1] 套件的一部分

scroll-to-top