设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.46.1 → 2.52.0 无更改
-
2.46.0
2024-07-29
描述
本文档旨在描述与 Git 打包相关的进阶概念。
目前许多概念分散在各种 Git 命令的手册页中,包括 git-pack-objects[1]、git-repack[1] 等,以及 gitformat-pack[5],还有 Documentation/technical 目录中的部分内容。
Git 中有许多打包方面的内容并未包含在此文档中,而是存在于上述区域。随着时间的推移,这些分散的内容可能会整合到本文档中。
伪合并位图
|
注意
|
伪合并位图被视为一项实验性功能,因此其配置和许多想法都可能发生变化。 |
背景
当我们在遍历的起始点之一或多个点上存储了磁盘上的位图时,可达性位图效率最高。出于这个原因,Git 倾向于为 ref 的尖端(tips)存储位图,因为遍历通常从这些点开始。
但是,如果您有大量的 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”参数设置了单个组的伪合并提交数的上限。
与“稳定”相关的参数控制“稳定”伪合并组,这些组由固定数量的提交组成,这些提交早于配置的“稳定阈值”值,并可能按年龄顺序组合成“stableSize”的块。
伪合并的确切配置如下:
|
注意
|
bitmapPseudoMerge.* 中的配置选项被视为实验性(EXPERIMENTAL),并且可能在未来发生更改或完全移除。有关伪合并位图功能的更多信息,请参阅 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将导致第nthgroupbe1/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”中的标签)。