設定與配置
取得與建立專案
基本快照
分支與合併
分享與更新專案
檢查與比較
修補
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
-
2.47.0
10/06/24
- 2.36.1 → 2.46.2 無變更
-
2.36.0
04/18/22
- 2.35.1 → 2.35.8 無變更
-
2.35.0
01/24/22
- 2.34.1 → 2.34.8 無變更
-
2.34.0
11/15/21
- 2.32.1 → 2.33.8 無變更
-
2.32.0
06/06/21
- 2.30.1 → 2.31.8 無變更
- 2.30.0 無變更
- 2.25.1 → 2.29.3 無變更
-
2.25.0
01/13/20
- 2.20.1 → 2.24.4 無變更
-
2.20.0
12/09/18
Git 物件目錄包含一個 pack 目錄,其中包含 packfile(副檔名為 ".pack")和 pack-index(副檔名為 ".idx")。pack-index 提供了一種查詢物件並導航到它們在 pack 中的偏移量的方式,但它們必須與 packfile 成對出現。這種配對取決於檔案名稱,因為 pack-index 僅在副檔名上與其 pack 檔案不同。雖然 pack-index 為每個 packfile 提供快速查詢,但隨著 packfile 數量的增加,這種效能會下降,因為縮寫需要檢查每個 packfile,並且我們更有可能在我們最近使用的 packfile 上錯失。對於一些大型儲存庫,由於儲存空間或過長的重新打包時間,重新打包成單個 packfile 是不可行的。
多包索引(簡稱 MIDX)儲存了物件列表及其在多個 packfile 中的偏移量。它包含
-
packfile 名稱列表。
-
排序後的物件 ID 列表。
-
第 i 個物件 ID 的中繼資料列表,包含
-
一個值 j,指向第 j 個 packfile。
-
物件在第 j 個 packfile 中的偏移量。
-
-
如果需要大偏移量,我們會使用另一個類似於版本 2 pack-index 的大偏移量列表。
-
pseudo-pack 順序中物件的可選列表(與 MIDX 位圖一起使用)。
-
因此,我們可以為任何數量的 packfile 提供 O(log N) 的查詢時間。
設計細節
-
MIDX 儲存在 .git/objects/pack 目錄下名為 multi-pack-index 的檔案中。這可以儲存在備用目錄的 pack 目錄中。它僅參考同一目錄中的 packfile。
-
core.multiPackIndex 設定必須開啟(預設為開啟)才能使用 MIDX 檔案。將其設定為
false
會阻止 Git 讀取 MIDX 檔案,即使該檔案存在。 -
檔案格式包含物件 ID 雜湊函數的參數,因此未來雜湊演算法的變更不需要變更格式。
-
MIDX 每個物件 ID 僅保留一條記錄。如果一個物件出現在多個 packfile 中,則 MIDX 會選擇首選 packfile 中的副本,否則會從最近修改的 packfile 中選擇。
-
如果 pack 目錄中存在未在 MIDX 中註冊的 packfile,則這些 packfile 會載入到
packed_git
列表和packed_git_mru
快取中。 -
pack-index(.idx 檔案)保留在 pack 目錄中,因此我們可以刪除 MIDX 檔案、將 core.midx 設定為 false 或降級,而不會遺失任何資訊。
-
MIDX 檔案格式使用基於區塊的方法(類似於 commit-graph 檔案),允許新增選用資料。
增量多包索引
隨著儲存庫規模的增長,撰寫包含所有 packfile 的多包索引 (MIDX) 的成本會越來越高。「增量多包索引」功能旨在解決此問題,允許組合多包索引的「鏈」。
鏈的每個單獨組件只需要包含少量 packfile。附加到鏈不會使鏈的早期部分失效,因此儲存庫可以透過確定 MIDX 鏈中每一層的包數來控制更新 MIDX 鏈所花費的時間。
設計狀態
目前,增量多包索引功能缺少兩個重要的組件
-
重新撰寫 MIDX 鏈早期部分的能力(即,將相鄰 MIDX 層的某些集合「壓縮」為單個 MIDX)。目前,縮減 MIDX 鏈的唯一支援方式是從頭重新撰寫整個鏈,而不使用
--split
旗標。沒有任何根本的限制會妨礙實作此功能。為了降低複雜性,它在初始實作中被省略,但稍後會新增。
-
支援可達性位圖。傳統的單個 MIDX 實作確實支援可達性位圖(有關詳細資訊,請參閱 gitformat-pack[5] 中標題為「多包索引反向索引」的部分)。
如上所述,沒有任何根本的限制會妨礙擴展增量 MIDX 格式以支援可達性位圖。下面的設計特別考慮到了這一點,並且將在未來的修補程式系列中新增對可達性位圖的支援。由於與上述相同的原因,它在目前的實作中被省略。
簡而言之,為了支援增量 MIDX 功能的可達性位圖,pseudo-pack 順序的概念會跨增量 MIDX 鏈的每一層擴展,以形成串聯的 pseudo-pack 順序。此串聯的順序與鏈本身的順序相同(換句話說,鏈
{$H1, $H2, $H3}
的串聯 pseudo-pack 順序將是$H1
的 pseudo-pack 順序,後跟$H2
的 pseudo-pack 順序,然後是$H3
的 pseudo-pack 順序)。然後,將擴展版面配置,以便增量 MIDX 鏈的每一層都可以寫入
*.bitmap
。每一層位圖中的物件會根據鏈的前一層中的物件數量進行偏移。
檔案版面配置
增量 MIDX 不儲存單個 multi-pack-index
檔案(在 $GIT_DIR/objects/pack
中具有可選的 .rev
和 .bitmap
副檔名),而是儲存在以下版面配置中
$GIT_DIR/objects/pack/multi-pack-index.d/ $GIT_DIR/objects/pack/multi-pack-index.d/multi-pack-index-chain $GIT_DIR/objects/pack/multi-pack-index.d/multi-pack-index-$H1.midx $GIT_DIR/objects/pack/multi-pack-index.d/multi-pack-index-$H2.midx $GIT_DIR/objects/pack/multi-pack-index.d/multi-pack-index-$H3.midx
multi-pack-index-chain
檔案包含鏈中增量 MIDX 檔案的列表,依序排列。上面的範例顯示了一個鏈,其 multi-pack-index-chain
檔案會包含以下行
$H1 $H2 $H3
multi-pack-index-$H1.midx
檔案包含多包索引鏈的第一層。multi-pack-index-$H2.midx
檔案包含鏈的第二層,依此類推。
當同時存在增量 MIDX 和非增量 MIDX 時,始終會先讀取非增量 MIDX。
未來工作
-
多包索引允許許多 packfile,尤其是在重新打包成本高昂(例如非常大的儲存庫)或無法接受意外維護時間(例如高需求的建置機器)的情況下。但是,多包索引每次都需要完全重新撰寫。我們可以擴展格式以實現增量,以便寫入速度更快。透過儲存指向大型「基礎」MIDX 檔案的小型「提示」多包索引,我們可以保持寫入速度快,同時減少物件查詢所需的二元搜尋次數。
-
如果擴展多包索引以儲存「穩定物件順序」(對於給定的雜湊,即使在多包索引更新時也是常數的函數 Order(hash) = 整數),則 MIDX 位圖可以獨立於 MIDX 進行更新。
-
可以使用空檔案將 packfile 標記為「特殊」,這些空檔案共用初始名稱,但將 ".pack" 替換為 ".keep" 或 ".promisor"。我們可以向多包索引新增一個可選的資料區塊,其中記錄有關 packfile 的資訊旗標。這允許新的狀態,例如 重新打包 或 重新增量化,有助於多包環境中的 pack 維護。按物件類型(commit、tree、blob 等)組織 packfile,並使用此中繼資料來協助維護也可能會有所幫助。
相關連結
[0] https://bugs.chromium.org/p/git/issues/detail?id=6 Chromium 針對多包索引 (MIDX) 的工作項目
[2] https://lore.kernel.org/git/alpine.DEB.2.20.1803091557510.23109@alexmv-linux/ Git Merge 2018 貢獻者高峰會筆記(包含 MIDX 的討論)