設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.50.1 → 2.52.0 無更改
-
2.50.0
2025-06-16
- 2.47.1 → 2.49.1 無更改
-
2.47.0
2024-10-06
- 2.36.1 → 2.46.4 無更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 無更改
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 無更改
-
2.34.0
2021-11-15
- 2.32.1 → 2.33.8 無更改
-
2.32.0
2021-06-06
- 2.30.1 → 2.31.8 無更改
- 2.30.0 無更改
- 2.25.1 → 2.29.3 無更改
-
2.25.0
2020-01-13
- 2.20.1 → 2.24.4 無更改
-
2.20.0
2018-12-09
Git 物件目錄包含一個 pack 目錄,其中包含包檔案(字尾為 ".pack")和包索引(字尾為 ".idx")。包索引提供了一種查詢物件及其在包內偏移量的方法,但這些必須與包檔案成對出現。這種配對取決於檔名,因為包索引與包檔案僅在後綴上有所不同。雖然包索引為每個包檔案提供快速查詢,但隨著包檔案數量的增加,這種效能會下降,因為摘要需要檢查每個包檔案,並且我們更有可能在最近使用的包檔案中發生未命中。對於某些大型倉庫,由於儲存空間或過多的打包時間,將其重新打包成單個包檔案是不可行的。
多包索引(簡稱 MIDX)儲存物件列表及其在多個包檔案中的偏移量。它包含:
-
包檔名列表。
-
物件 ID 的排序列表。
-
第 i 個物件 ID 的元資料列表,包括:
-
一個值 j,指向第 j 個包檔案。
-
物件在第 j 個包檔案中的偏移量。
-
-
如果需要大偏移量,我們使用另一個大偏移量列表,類似於版本 2 包索引。
-
物件在偽包順序中的可選列表(與 MIDX 點陣圖一起使用)。
-
因此,我們可以為任意數量的包檔案提供 O(log N) 的查詢時間。
設計細節
-
MIDX 儲存在 .git/objects/pack 目錄中名為 multi-pack-index 的檔案中。這可以儲存在備用目錄的包目錄中。它僅引用同一目錄中的包檔案。
-
必須啟用 core.multiPackIndex 配置設定(這是預設設定)才能使用 MIDX 檔案。將其設定為
false會阻止 Git 讀取 MIDX 檔案,即使它存在。 -
檔案格式包含物件 ID 雜湊函式的引數,因此將來更改雜湊演算法不需要更改格式。
-
MIDX 每個物件 ID 只保留一條記錄。如果一個物件出現在多個包檔案中,則 MIDX 會選擇首選包檔案中的副本,否則從最近修改的包檔案中選擇。
-
如果包目錄中存在未在 MIDX 中註冊的包檔案,那麼這些包檔案將被載入到
packed_git列表和packed_git_mru快取中。 -
包索引(.idx 檔案)保留在包目錄中,以便我們可以刪除 MIDX 檔案,設定 core.midx 為 false,或降級而不會丟失任何資訊。
-
MIDX 檔案格式使用基於塊的方法(類似於 commit-graph 檔案),允許新增可選資料。
增量多包索引
隨著倉庫規模的增長,編寫包含所有包檔案的多包索引(MIDX)變得更加昂貴。為了適應這一點,“增量多包索引”功能允許組合一個多包索引的“鏈”。
鏈中的每個單獨元件只需要包含少量包檔案。向鏈中新增內容不會使鏈的早期部分失效,因此倉庫可以透過確定 MIDX 鏈的每一層中的包數量來控制更新 MIDX 鏈所花費的時間。
設計狀態
目前,增量多包索引功能缺少兩個重要元件:
-
重寫 MIDX 鏈早期部分的能力(即,將一些相鄰的 MIDX 層“壓縮”成一個 MIDX)。目前,縮小 MIDX 鏈的唯一支援方法是從頭開始重寫整個鏈,而不使用
--split標誌。這方面沒有根本性的限制。它被省略在最初的實現中是為了降低複雜性,但將在以後新增。
-
支援可達性點陣圖。經典的單 MIDX 實現支援可達性點陣圖(有關更多詳細資訊,請參見 gitformat-pack[5] 中“multi-pack-index reverse indexes”部分)。
如上所述,將增量 MIDX 格式擴充套件到支援可達性點陣圖沒有任何根本性的限制。下面的設計特別考慮了這一點,並且將在將來的補丁系列中新增對可達性點陣圖的支援。出於同樣的原因,它被省略在當前實現中。
簡而言之,為了支援增量 MIDX 功能的可達性點陣圖,偽包順序的概念被擴充套件到增量 MIDX 鏈的每個層,形成一個連線的偽包順序。這種連線以鏈本身的順序進行(換句話說,鏈
{$H1,$H2,$H3}的連線偽包順序將是$H1的偽包順序,然後是$H2的偽包順序,然後是$H3的偽包順序)。然後將佈局擴充套件,以便增量 MIDX 鏈的每一層都可以寫入一個
*.bitmap檔案。每一層點陣圖中的物件都透過鏈中先前圖層的物件數量進行偏移。
檔案佈局
增量 MIDX 不再將單個 multi-pack-index 檔案(帶有可選的 .rev 和 .bitmap 副檔名)儲存在 $GIT_DIR/objects/pack 中,而是採用以下佈局:
$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 的物件位置
在原始的多包索引設計中,我們透過物件 ID 在倉庫的單個多包索引中的字典序位置來引用物件。在增量多包索引設計中,我們透過物件在 MIDX 鏈中每個元件的連線字典序排序中的索引來引用物件。
如果 objects_nr() 是一個返回給定 MIDX 層中物件數量的函式,那麼位於字典序位置 i 的物件在(例如)$H3 中的索引定義為:
objects_nr($H2) + objects_nr($H1) + i
(在 C 實現中,這通常計算為 i + m->num_objects_in_base)。
增量 MIDX 的偽包順序
多包可達性點陣圖的原始實現定義了 gitformat-pack[5] 中的偽包順序(參見“multi-pack-index reverse indexes”部分),大致如下:
簡而言之,MIDX 的偽包是 MIDX 儲存的包中物件的去重連線,按包順序排列,包按 MIDX 順序排列(首選包在前)。
在增量 MIDX 設計中,我們將此定義擴充套件到包含來自 MIDX 鏈多個層中的物件。增量 MIDX 的偽包順序是透過按順序連線 MIDX 鏈的每個層的偽包順序來確定的。形式上,兩個物件 o1 和 o2 的比較如下:
-
如果
o1出現在 MIDX 鏈的較早層而不是o2,則o1排在o2之前。 -
否則,如果
o1和o2出現在同一個 MIDX 層,並且該 MIDX 層沒有基礎,那麼如果pack(o1) 和pack(o2) 中的一個被首選而另一個不是,那麼首選的排在非首選的前面。如果存在基礎層(即 MIDX 層不是鏈中的第一層),那麼如果pack(o1) 出現在該 MIDX 層的包順序中更早,則o1排在o2之前。同樣,如果pack(o2) 出現在更早,則情況相反。 -
否則,
o1和o2出現在同一個包中,因此在同一個 MIDX 層中。按它們在包含的包檔案中的偏移量對o1和o2進行排序。
請注意,首選包是 MIDX 鏈的屬性,而不是單獨的層。從根本上說,我們可以引入每個層的首選包,但這現在不太相關了,因為我們可以跨 MIDX 中的包集執行多包重用。
可達性點陣圖和增量 MIDX
增量 MIDX 鏈的每一層都可以用自己的 *.bitmap 檔案表示其物件(以及同一 MIDX 鏈中任何先前層的物件)。
屬於增量 MIDX 鏈的 *.bitmap 檔案的結構與非增量 MIDX 點陣圖或經典單包點陣圖相同。由於物件被新增到增量 MIDX 的偽包順序的末尾(見上文),因此可以在 MIDX 鏈的末尾附加點陣圖。
(注意:也可以將連續的 MIDX 增量層及其 *.bitmap 檔案壓縮成一個層和 *.bitmap,但這尚未實現。)
使用的物件位置在偽包順序中是全域性的,因此後續層將在其四個型別的點陣圖中具有例如 m->num_objects_in_base 個 0 位。這是因為我們只為點陣圖對應的層中的物件編寫型別點陣圖條目)。
另請注意,在可達性查詢中,只有增量 MIDX 鏈中最新層的點陣圖用於儲存有趣和不有趣物件的 P 可達性資訊。較早的點陣圖層僅用於查詢該層中的提交和偽合併點陣圖,以及該層中物件的型別級別點陣圖。
為了簡化實現,型別級別點陣圖被同時迭代,並且將它們的結果 OR 起來,以避免遞迴呼叫內部點陣圖函式。
未來工作
-
如果多包索引被擴充套件以儲存“穩定的物件順序”(一個對於給定雜湊來說是常數的函式 Order(hash) = integer,即使多包索引被更新),那麼 MIDX 點陣圖可以獨立於 MIDX 進行更新。
-
可以透過空檔案將包檔案標記為“特殊”,這些檔案共享初始名稱,但將 ".pack" 替換為 ".keep" 或 ".promisor"。我們可以向多包索引新增一個可選資料塊,該資料塊記錄有關包檔案的資訊標誌。這允許新的狀態,例如 repacked 或 redeltified,這有助於在多包環境中進行包維護。按物件型別(提交、樹、blob 等)組織包檔案並使用這些元資料來幫助維護也可能很有用。
相關連結
[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 討論)