设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
修补
调试
电子邮件
外部系统
服务器管理员
指南
管理
底层命令
- 2.46.1 → 2.47.0 无更改
- 2.46.0 07/29/24
描述
本文档旨在描述与 Git 中打包相关的一些高级概念。
许多概念目前散布在各种 Git 命令的手册页中,包括 git-pack-objects[1]、git-repack[1] 和其他命令,以及 gitformat-pack[5],以及 Documentation/technical
树的部分内容。
Git 中打包的许多方面未在本文档中介绍,而是位于上述区域。随着时间的推移,这些分散的部分可能会合并到本文档中。
伪合并位图
注意
|
伪合并位图被认为是实验性功能,因此配置和许多想法可能会发生变化。 |
背景
当我们对遍历的一个或多个起点有磁盘存储的位图时,可达性位图效率最高。出于这个原因,Git 优先存储提交在 ref 顶部的位图,因为遍历往往从这些点开始。
但是,如果您有大量 ref,则不可能为每个 ref 顶点存储位图。它占用空间,并且将所有这些位图一起进行 OR 操作成本很高。
我们可以处理此问题的一种方法是创建表示 ref组的位图。当遍历询问整个组时,我们可以使用此单个位图,而不是单独考虑每个 ref。因为这些位图表示在所有提交的假设合并中可以达到的对象集,所以我们称它们为伪合并位图。
概述
“伪合并位图”用于指代一对位图,如下所示
当遍历的两侧都列出了给定伪合并的所有提交时(无论是直接列出(通过显式请求作为 HAVES
或 WANTS
的一部分)还是间接列出(在填充遍历期间遇到它们)),伪合并位图可以加速位图遍历。
用例
例如,假设存在一个具有大量提交的伪合并位图,所有这些提交都列在某个位图遍历查询的 WANTS
部分中。启用伪合并位图时,位图机制可以快速确定是否存在一个伪合并满足查询两侧的某些所需对象子集。然后,我们可以膨胀 EWAH 压缩的位图,并将其 OR
到结果位图中。相反,如果没有伪合并位图,我们将必须对可能数量巨大的单个位图重复解压缩和 OR
步骤,这可能需要花费成比例更多的时间。
当存在以下组合时,伪合并的另一个好处出现:(a)大量引用,(b)位图覆盖率差,以及(c)深度嵌套的树,这使得填充遍历相对昂贵。例如,假设有足够数量的标签,使得单独对每个标签进行位图处理是不可行的。如果没有伪合并位图,计算例如 git rev-list --use-bitmap-index --count --objects --tags
的结果可能需要大量的填充遍历。但是,当大量这些标签一起存储在一个伪合并位图中时,位图机制可以利用我们只关心所有这些标签可达的对象的联合这一事实,并更快地回答查询。
配置
引用提示根据两个标准分组到不同的伪合并组中。引用名称匹配一个或多个定义的伪合并模式,并且可选地匹配该模式中的一个或多个捕获组,这些捕获组进一步对组进行分区。
在组内,提交可以根据其年龄被认为是“稳定的”或“不稳定的”。这些是通过分别设置 bitmapPseudoMerge.<name>.stableThreshold
和 bitmapPseudoMerge.<name>.threshold
配置值来调整的。
所有稳定提交都分组到大小相等的伪合并中(bitmapPseudoMerge.<name>.stableSize
)。如果 stableSize
配置设置为例如 100,则第一个 100 个提交(按提交者日期排序)且早于 stableThreshold
值的提交将形成一个组,接下来的 100 个提交将形成另一个组,依此类推。
在不稳定提交中,伪合并机制将尝试将较旧的提交组合成较大的组,而不是将较新的提交组合成较小的组。这是基于这样的启发式方法:指向较旧提交的引用的修改可能性小于指向较新提交的引用的修改可能性。
组的大小由幂律衰减函数确定,衰减参数大致对应于 f(n) = C*n^(-k/100)
中的“k”,其中 f(n)
描述了第 n
个伪合并组的大小。采样率控制被视为候选者的合格提交的百分比。阈值参数指示最小年龄(以便避免在伪合并组中包含过新的提交,从而使其不太可能有效)。“maxMerges”参数设置单个组的伪合并提交数量的上限
与“stable”相关的参数控制“stable”伪合并组,该组包含固定数量的提交,这些提交早于配置的“stable threshold”值,并且可以按年龄顺序以“stableSize”的块进行分组。
伪合并的确切配置如下
注意
|
bitmapPseudoMerge.* 中的配置选项被认为是实验性的,将来可能会发生更改或完全删除。有关伪合并位图功能的更多信息,请参阅 gitpacking[7] 的“伪合并位图”部分。 |
- bitmapPseudoMerge.<name>.pattern
-
用于匹配引用名称的正则表达式。指向匹配此模式的引用(并满足以下条件,如
bitmapPseudoMerge.<name>.sampleRate
和bitmapPseudoMerge.<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
-
确定在参考提示中选定的非位图提交(用于包含在不稳定的伪合并位图中)的比例。必须在
0
和1
(包含)之间。默认值为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] 套件的一部分