簡體中文 ▾ 主題 ▾ 最新版本 ▾ 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. 您可以透過建立淺克隆(shallow clone)來擁有一個不完整但本地可用的倉庫。請參閱 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 目錄本身的條目數量控制在可管理的範圍內。此處找到的物件通常稱為 *未打包(unpacked)*(或 *鬆散(loose)*)物件。

objects/pack

打包檔案(儲存許多壓縮物件的單個檔案,以及允許它們被隨機訪問的索引檔案)位於此目錄中。

objects/info

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

objects/info/packs

此檔案用於幫助“啞”傳輸發現此物件儲存中可用的打包檔案。每當新增或刪除打包檔案時,如果倉庫要透過“啞”傳輸釋出,則應執行 git update-server-info 來使此檔案保持最新。*git repack* 預設執行此操作。

objects/info/alternates

此檔案記錄了此物件儲存從其借用物件的備用物件儲存的路徑,每行一個路徑名。請注意,不僅本地 Git 工具會使用它,HTTP 獲取器也會嘗試在遠端使用它;通常,如果您在 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 的樹尖提交物件

refs/tags/name

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

refs/remotes/name

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

refs/replace/<obj-sha1>

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

packed-refs

以更有效的方式記錄與 refs/heads/、refs/tags/ 和其他引用相同的資訊。請參閱 git-pack-refs[1]。如果設定了 $GIT_COMMON_DIR,則會忽略此檔案,而將使用 "$GIT_COMMON_DIR/packed-refs"。

HEAD

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

HEAD 也可以直接記錄一個特定的提交,而不是作為一個符號引用指向當前分支。這種狀態通常稱為 *分離 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

Hooks 是 Git 各個命令使用的自定義指令碼。在執行 git init 時會安裝一些示例 hooks,但預設情況下它們都處於停用狀態。要啟用它們,需要透過重新命名移除檔名中的 .sample 字尾。有關每個 hook 的更多詳細資訊,請閱讀 githooks[5]。如果設定了 $GIT_COMMON_DIR,則會忽略此目錄,而將使用 "$GIT_COMMON_DIR/hooks"。

common

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

index

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

sharedindex.<SHA-1>

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

info

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

info/refs

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

info/grafts

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

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

info/exclude

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

info/attributes

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

info/sparse-checkout

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

remotes

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

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

logs

對 ref 所做的更改記錄儲存在此目錄中。有關更多資訊,請參閱 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 實現 **不得** 操作該倉庫;這樣做不僅可能產生錯誤的結果,甚至可能丟失資料。

由於此規則,版本升級應儘量減少。相反,我們通常傾向於以下策略:

  • 升級單個數據檔案(例如,索引、打包檔案等)的格式版本號。這會將不相容性限制在這些檔案中。

  • 引入新的資料,這些資料在被舊客戶端使用時能夠優雅地降級(例如,舊客戶端會忽略打包點陣圖檔案,而只是不利用它們提供的最佳化)。

整個倉庫格式版本升級應僅作為無法獨立版本化的更改的一部分。例如,如果要更改物件的連通性規則(reachability rules)或 ref 的鎖定規則,這將需要升級倉庫格式版本。

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

推出版本升級(無論是整個倉庫還是單個檔案)的首選策略是讓 git 能夠讀取新格式,並透過配置開關或命令列選項(用於實驗或不關心向後相容性)來允許寫入新格式。然後在很長一段時間內,以允許讀取能力普及,我們可能會預設切換到寫入新格式。

當前定義的格式版本是:

版本 0

這是由 git 的初始版本定義的格式,包括但不限於倉庫目錄的格式、倉庫配置檔案以及物件和 ref 的儲存。指定 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] 套件的一部分