名稱

gitpacking - 與 Git 打包相關的高階概念

概要

gitpacking

描述

本文件旨在描述與 Git 打包相關的一些高階概念。

許多概念目前分散在各種 Git 命令的手冊頁中,包括 git-pack-objects[1]git-repack[1] 等,以及 gitformat-pack[5]Documentation/technical 樹的一部分。

Git 中打包的許多方面未在本文件中涵蓋,而是存在於上述區域。隨著時間的推移,這些分散的內容可能會合併到本文件中。

偽合併點陣圖

注意
偽合併點陣圖被視為實驗性功能,因此配置和許多概念可能會發生變化。

背景

當有磁碟上儲存的點陣圖用於遍歷的一個或多個起點時,可達性點陣圖效率最高。因此,Git 更傾向於為引用尖端的提交儲存點陣圖,因為遍歷通常從這些點開始。

但是,如果引用數量很大,為*每個*引用尖端儲存點陣圖是不可行的。這會佔用空間,並且僅僅將所有這些點陣圖進行 OR 運算也代價高昂。

解決這個問題的一種方法是建立表示引用*組*的點陣圖。當遍歷查詢整個組時,我們可以使用這個單一的點陣圖,而不是單獨考慮每個引用。因為這些點陣圖代表了所有提交的假設合併中可達的物件集合,所以我們稱之為偽合併點陣圖。

概述

“偽合併點陣圖”用於指代一對點陣圖,如下所示

提交點陣圖

一個位圖,其設定位描述了偽合併的“合併”點陣圖(如下所示)中包含的提交集合。

合併點陣圖

一個位圖,其設定位描述了偽合併的“提交”點陣圖(如上所示)中提交集合的可達性閉包。對於與提交點陣圖中描述的父級集合相同的八爪魚合併,將生成相同的點陣圖。

當給定偽合併的所有提交都列在遍歷的任一側時,偽合併點陣圖可以加速點陣圖遍歷,無論是直接(透過在 HAVESWANTS 中明確請求它們)還是間接(在填充遍歷期間遇到它們)。

用例

例如,假設存在一個包含大量提交的偽合併點陣圖,所有這些提交都列在某個點陣圖遍歷查詢的 WANTS 部分中。當啟用偽合併點陣圖時,點陣圖機制可以快速確定存在一個偽合併,它滿足查詢任一側所需物件的一個子集。然後,我們可以解壓縮 EWAH 壓縮點陣圖,並將其 OR 運算到結果點陣圖中。相比之下,如果沒有偽合併點陣圖,我們將不得不對可能大量單獨的點陣圖重複解壓縮和 OR 運算步驟,這可能會花費更多的時間。

偽合併的另一個好處出現在 (a) 大量引用,(b) 點陣圖覆蓋率差,以及 (c) 深層巢狀樹相結合,使得填充遍歷相對昂貴的情況。例如,假設有足夠多的標籤,單獨為每個標籤生成點陣圖是不可行的。如果沒有偽合併點陣圖,計算諸如 git rev-list --use-bitmap-index --count --objects --tags 的結果可能需要大量的填充遍歷。但是,當大量這些標籤一起儲存在偽合併點陣圖中時,點陣圖機制可以利用我們只關心所有這些標籤可達物件的並集這一事實,從而更快地回答查詢。

配置

引用尖端根據兩個標準分組到不同的偽合併組中。引用名稱匹配一個或多個已定義的偽合併模式,並且可選地匹配該模式內的一個或多個捕獲組,這些捕獲組進一步劃分了該組。

在一個組內,提交可以根據其年齡被視為“穩定”或“不穩定”。這些透過分別設定 bitmapPseudoMerge.<name>.stableThresholdbitmapPseudoMerge.<name>.threshold 配置值進行調整。

所有穩定提交都分組為大小相等的偽合併(bitmapPseudoMerge.<name>.stableSize)。如果 stableSize 配置設定為例如 100,則早於 stableThreshold 值的前 100 個提交(按提交者日期排序)將形成一個組,接下來的 100 個提交將形成另一個組,依此類推。

在不穩定提交中,偽合併機制將嘗試將較舊的提交組合成大組,而不是將較新的提交顯示在較小的組中。這是基於以下啟發式方法:指向較舊提交的引用比指向較新提交的引用更不容易被修改以指向不同的提交。

組的大小由冪律衰減函式確定,衰減引數大致對應於 f(n) = C*n^(-k/100) 函式中的“k”,其中 f(n) 描述了第 n 個偽合併組的大小。取樣率控制符合條件的提交中有多少百分比被視為候選。閾值引數表示最小年齡(以避免將太新的提交包含在偽合併組中,從而降低其有效性)。“maxMerges”引數設定了單個組中偽合併提交數量的上限

“穩定”相關引數控制“穩定”偽合併組,這些組由固定數量的提交組成,這些提交早於配置的“穩定閾值”值,並且可以按年齡順序以“stableSize”的塊進行分組。

偽合併的具體配置如下

注意
bitmapPseudoMerge.* 中的配置選項被認為是實驗性的,將來可能會更改或完全刪除。有關偽合併點陣圖功能的更多資訊,請參閱 gitpacking[7] 的“偽合併點陣圖”部分。
bitmapPseudoMerge.<name>.pattern

用於匹配引用名稱的正則表示式。由匹配此模式(並滿足以下條件,如 bitmapPseudoMerge.<name>.sampleRatebitmapPseudoMerge.<name>.threshold)的引用指向的提交將被考慮包含在偽合併點陣圖中。

提交被分組到偽合併組中,其依據是是否有任何指向給定提交的引用匹配該模式,該模式是一個擴充套件正則表示式。

在偽合併組內,提交可以根據模式中的捕獲組進一步分組到子組中。這些子分組是透過將正則表示式中的任何捕獲組用一個 *-* 連字元連線起來形成的。

例如,如果模式是 refs/tags/,那麼所有標籤(如果它們滿足以下條件)都將被視為同一偽合併組的候選。但是,如果模式是 refs/remotes/([0-9])+/tags/,那麼來自不同遠端的標籤將根據遠端編號分組到不同的偽合併組中。

bitmapPseudoMerge.<name>.decay

確定連續偽合併點陣圖組大小減小的速率。必須是非負數。此引數可以被視為函式 f(n) = C * n^-k 中的 k,其中 f(n) 是第 `n` 個組的大小。

將衰減率設定為 0 將導致所有組大小相同。將衰減率設定為 1 將導致第 n 個組的大小是初始組的 1/n。衰減率越高,連續組收縮的速度越快。預設值為 1

如果所有組大小相同,則包含較新提交的組可能比早期組使用頻率更低,因為指向較新提交的引用比指向舊提交的引用更有可能被更頻繁地更新。

bitmapPseudoMerge.<name>.sampleRate

確定未點陣圖化提交(在引用尖端中)中被選中包含在不穩定偽合併點陣圖中的比例。必須在 01 之間(包含)。預設值為 1

bitmapPseudoMerge.<name>.threshold

確定未點陣圖化提交(如上所述,在引用尖端中)的最小年齡,這些提交是包含在不穩定偽合併點陣圖中的候選。預設值為 1.week.ago

bitmapPseudoMerge.<name>.maxMerges

確定提交可以分佈到的偽合併提交的最大數量。

對於其模式不包含任何捕獲組的偽合併組,此設定適用於所有匹配正則表示式的提交。對於具有一個或多個捕獲組的模式,此設定適用於每個不同的捕獲組。

例如,如果您的捕獲組是 refs/tags/,那麼此設定會將所有標籤分佈到最多 maxMerges 個偽合併提交中。但是,如果您的捕獲組是例如 refs/remotes/([0-9]+)/tags/,那麼此設定將單獨應用於每個遠端的標籤集。

必須是非負數。預設值為 64。

bitmapPseudoMerge.<name>.stableThreshold

確定提交(如上所述,在引用尖端中,但即使已透過點陣圖覆蓋,穩定提交仍被視為候選)的最小年齡,這些提交是穩定偽合併點陣圖的候選。預設值為 1.month.ago

將此閾值設定為較小的值(例如,1.week.ago)將導致生成更多穩定組(這會產生一次性生成成本),但這些組可能會隨著時間而過時。使用較大的值會帶來相反的代價(更少的穩定組,但更有用)。

bitmapPseudoMerge.<name>.stableSize

確定穩定偽合併點陣圖的大小(以提交數量計)。預設值為 512

示例

假設您有一個包含大量引用的倉庫,並且您希望有一個最基本的偽合併點陣圖配置,以增強 refs/ 名稱空間的點陣圖覆蓋率。您可以從以下配置開始

[bitmapPseudoMerge "all"]
	pattern = "refs/"
	threshold = now
	stableThreshold = never
	sampleRate = 100
	maxMerges = 64

這將為所有引用建立偽合併點陣圖,無論其年齡如何,並將它們分組到 64 個偽合併提交中。

如果您想在生成偽合併提交時將標籤與分支分開,您可以改為使用捕獲組定義模式,如下所示

[bitmapPseudoMerge "all"]
	pattern = "refs/(heads/tags)/"

相反,假設您正在一個分叉網路倉庫中工作,每個分叉由某個數字 ID 指定,並且其引用位於網路中的 refs/virtual/NNN/(其中 NNN 是與某個分叉對應的數字 ID)。在這種情況下,您可以改為編寫類似以下內容

[bitmapPseudoMerge "all"]
	pattern = "refs/virtual/([0-9]+)/(heads|tags)/"
	threshold = now
	stableThreshold = never
	sampleRate = 100
	maxMerges = 64

這將生成類似“1234-heads”和“5678-tags”的偽合併組識別符號(分別對應分叉“1234”中的分支和遠端“5678”中的標籤)。

GIT

Git[1] 套件的一部分

scroll-to-top