Git
英语 ▾ 主题 ▾ 最新版本 ▾ git-pack-objects 最后更新于 2.43.0

名称

git-pack-objects - 创建对象的打包存档

概要

git pack-objects [-q | --progress | --all-progress] [--all-progress-implied]
	[--no-reuse-delta] [--delta-base-offset] [--non-empty]
	[--local] [--incremental] [--window=<n>] [--depth=<n>]
	[--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
	[--cruft] [--cruft-expiration=<time>]
	[--stdout [--filter=<filter-spec>] | <base-name>]
	[--shallow] [--keep-true-parents] [--[no-]sparse] < <object-list>

描述

从标准输入读取对象列表,并使用指定的基名称将一个或多个打包存档写入磁盘,或将打包存档写入标准输出。

打包存档是在两个仓库之间传输一组对象以及访问高效的存档格式的有效方式。在打包存档中,对象要么存储为压缩的整体,要么存储为与其他对象的区别。后者通常被称为增量。

打包存档格式 (.pack) 被设计为自包含的,以便可以在没有任何其他信息的情况下解包。因此,增量依赖的每个对象都必须存在于包中。

为打包存档中的对象生成一个打包索引文件 (.idx),以实现快速、随机的访问。将索引文件 (.idx) 和打包存档 (.pack) 放入 $GIT_OBJECT_DIRECTORY 的 pack/ 子目录(或 $GIT_ALTERNATE_OBJECT_DIRECTORIES 上的任何目录)中,使 Git 能够从打包存档中读取。

git unpack-objects 命令可以读取打包存档并将打包中包含的对象扩展为“一个文件一个对象”格式;这通常由智能拉取命令在为其对等体创建用于高效网络传输的包时进行。

选项

基名称

写入成对的文件 (.pack 和 .idx),使用 <base-name> 来确定所创建文件的名称。当使用此选项时,一对中的两个文件将写入 <base-name>-<SHA-1>.{pack,idx} 文件。<SHA-1> 是基于包内容的哈希,并写入命令的标准输出。

--stdout

将包内容(本应写入 .pack 文件的内容)写入标准输出。

--revs

从标准输入读取修订参数,而不是单个对象名称。修订参数的处理方式与 git rev-list 使用 --objects 标志使用其 commit 参数来构建其输出的对象列表相同。结果列表上的对象被打包。除了修订之外,还接受 --not--shallow <SHA-1> 行。

--unpacked

这表示 --revs。在处理从标准输入读取的修订参数列表时,将打包的对象限制为尚未打包的对象。

--all

这表示 --revs。除了从标准输入读取的修订参数列表外,还假装所有 refs/ 下的引用都被指定为包含在内。

--include-tag

如果它们引用的对象包含在结果打包文件中,则包含未请求的带注释的标签。这对于向原生 Git 客户端发送新标签很有用。

--stdin-packs

从标准输入读取打包文件的基名称(例如,pack-1234abcd.pack),而不是对象名称或修订参数。生成的包包含包含在包含的包中列出的所有对象(不以 ^ 开头的对象),排除包含在排除的包中列出的任何对象(以 ^ 开头的对象)。

--revs 或表示 --revs 的选项(如 --all)不兼容,但 --unpacked 除外,该选项是兼容的。

--cruft

将不可达对象打包到一个单独的“cruft”包中,通过 .mtimes 文件的存在来表示。通常由 git repack --cruft 使用。调用者提供一个包名称列表,并指示哪些包将保留在存储库中,哪些包将被删除(以 - 前缀表示)。cruft 包的内容是所有未包含在存活的包中的对象,并且它们未超过宽限期(见下面的 --cruft-expiration),或者超过了宽限期,但可以从尚未超过宽限期的另一个对象中到达。

当输入列出一个包含所有可达对象的包(并将所有其他包列为待删除)时,相应的 cruft 包将包含所有不可达对象(mtime 新于 --cruft-expiration),以及 mtime 老于 --cruft-expiration 的任何不可达对象,但可以从 mtime 新于 --cruft-expiration 的不可达对象中到达。

--unpack-unreachable--keep-unreachable--pack-loose-unreachable--stdin-packs 以及任何其他表示 --revs 的选项不兼容。

--cruft-expiration=<approxidate>

如果指定,则如果对象的 mtime 老于 <approxidate>,则将从 cruft 包中消除这些对象。如果未指定(并且给定 --cruft),则不会消除任何对象。

--window=<n>
--depth=<n>

这两个选项会影响打包中包含的对象如何使用增量压缩进行存储。对象首先在内部按类型、大小和可选名称排序,然后与 --window 中的其他对象进行比较,以查看使用增量压缩是否节省空间。--depth 限制增量深度的最大值;使其过于深会影响解包方面的性能,因为需要多次应用增量数据才能获得必要的对象。

--window 的默认值为 10,--depth 的默认值为 50。最大深度为 4095。

--window-memory=<n>

此选项在 --window 的基础上提供额外的限制;窗口大小将动态缩小,以便在内存中不占用超过 <n> 字节的空间。这对于具有大小混合的对象的存储库非常有用,可以避免在窗口很大时出现内存不足,但仍然能够利用大型窗口处理较小的对象。大小可以后缀为“k”、“m”或“g”。--window-memory=0 使内存使用不受限制。默认值取自 pack.windowMemory 配置变量。

--max-pack-size=<n>

在非寻常情况下,您可能无法在您的文件系统上创建大于特定大小的文件,可以使用此选项告诉命令将输出包文件拆分为多个独立的包文件,每个包文件不超过给定大小。大小可以后缀为“k”、“m”或“g”。允许的最小大小限制为 1 MiB。默认情况下不受限制,除非设置了配置变量 pack.packSizeLimit。请注意,此选项可能会导致更大的存储库并且速度更慢;请参阅 pack.packSizeLimit 中的讨论。

--honor-pack-keep

此标志会导致已经存在于具有 .keep 文件的本地包中的对象被忽略,即使它原本会被打包。

--keep-pack=<pack-name>

此标志会导致已存在于给定包中的对象被忽略,即使它原本会被打包。<pack-name> 是包文件名,不带前导目录(例如 pack-123.pack)。该选项可以多次指定以保留多个包。

--incremental

此标志会导致已存在于包中的对象被忽略,即使它原本会被打包。

--local

此标志会导致从备用对象存储中借用的对象被忽略,即使它原本会被打包。

--non-empty

仅在打包存档将包含至少一个对象时创建它。

--progress

当标准错误流连接到终端时,默认情况下会报告进度状态,除非指定了 -q。此标志即使标准错误流未定向到终端,也会强制显示进度状态。

--all-progress

当指定了 --stdout 时,在对象计数和压缩阶段会显示进度报告,但在写入阶段会被抑制。原因是在某些情况下,输出流直接链接到另一个命令,该命令可能希望在处理传入的包数据时显示自己的进度状态。此标志类似于 --progress,只是它即使使用 --stdout,也会强制在写入阶段报告进度。

--all-progress-implied

这用于在激活进度显示时隐式地使用 --all-progress。与 --all-progress 不同,此标志本身不会实际强制任何进度显示。

-q

此标志使命令不在标准错误流上报告其进度。

--no-reuse-delta

在创建包含现有包的存储库的打包存档时,该命令会重用现有的增量。这有时会导致稍微次优的包。此标志告诉命令不要重用现有的增量,而是从头开始计算它们。

--no-reuse-object

此标志告诉命令完全不要重用现有对象数据,包括非增量对象,强制重新压缩所有内容。这意味着 --no-reuse-delta。仅在需要对打包数据强制执行不同压缩级别的罕见情况下才有用。

--compression=<n>

指定生成的包中新压缩数据的压缩级别。如果未指定,包压缩级别首先由 pack.compression 确定,然后由 core.compression 确定,如果两者均未设置,则默认为 -1(zlib 默认值)。如果要对所有数据强制执行统一的压缩级别,无论来源如何,请添加 --no-reuse-object。

--[no-]sparse

切换“稀疏”算法以确定要包含在包中的对象,当与 --revs 选项结合使用时。此算法只遍历出现在引入新对象的路径中的树。这在计算要发送的小更改的包时可以显着提高性能。但是,如果包含的提交包含某些类型的直接重命名,则可能会将额外对象添加到包文件中。如果未包含此选项,则默认为 pack.useSparse 的值,除非另有说明,否则该值为 true。

--thin

通过省略发送方和接收方之间的公共对象来创建“瘦”包,以减少网络传输。此选项仅与 --stdout 结合使用才有意义。

注意:瘦包通过省略必需的对象违反了打包存档格式,因此在没有使其自包含的情况下,Git 无法使用它。使用 git index-pack --fix-thin(请参阅 git-index-pack[1])来恢复自包含属性。

--shallow

优化将提供给具有浅层存储库的客户端的包。此选项与 --thin 结合使用,可以以速度为代价创建更小的包。

--delta-base-offset

打包存档可以将增量的基础对象表示为 20 字节的对象名称或流中的偏移量,但旧版本的 Git 不理解后者。默认情况下,git pack-objects 仅出于更好的兼容性原因使用前者格式。此选项允许命令使用后者格式以实现紧凑性。根据平均增量链长度,此选项通常会将生成的 packfile 缩小 3-5%。

注意:瓷器命令(如 git gc(请参阅 git-gc[1])、git repack(请参阅 git-repack[1])在将存储库中的对象放入包文件时,默认情况下会传递此选项。git bundle(请参阅 git-bundle[1])在创建捆绑包时也是如此。

--threads=<n>

指定在搜索最佳增量匹配时要生成的线程数。这需要 pack-objects 用 pthreads 编译,否则此选项将被忽略并发出警告。这旨在减少多处理器机器上的打包时间。但是,增量搜索窗口所需的内存量会乘以线程数。指定 0 将导致 Git 自动检测 CPU 数并相应地设置线程数。

--index-version=<version>[,<offset>]

这仅用于测试套件。它允许强制生成包索引的版本,并强制对位于给定偏移量以上的对象使用 64 位索引条目。

--keep-true-parents

使用此选项,即使被嫁接隐藏的父项也会被打包。

--filter=<filter-spec>

从生成的包文件中省略某些对象(通常是 blob)。请参阅 git-rev-list[1] 以了解有效的 <filter-spec> 形式。

--no-filter

关闭任何以前的 --filter= 参数。

--missing=<missing-action>

一个调试选项,有助于未来的“部分克隆”开发。此选项指定如何处理缺失的对象。

形式 --missing=error 请求 pack-objects 在遇到缺失的对象时停止并报错。如果存储库是部分克隆,则在声明它们缺失之前,将尝试获取缺失的对象。这是默认操作。

形式 --missing=allow-any 将允许对象遍历在遇到缺失的对象时继续。不会获取缺失的对象。缺失的对象将从结果中静默省略。

形式 --missing=allow-promisor 类似于 allow-any,但只允许对 EXPECTED promisor 缺失对象继续对象遍历。不会获取缺失的对象。意外的缺失对象将引发错误。

--exclude-promisor-objects

省略已知存在于 promisor 远程的的对象。(此选项的目的是仅对本地创建的对象进行操作,以便在重新打包时,我们仍然保持本地创建的对象 [没有 .promisor] 和来自 promisor 远程的对象 [有 .promisor] 之间的区别。)这与部分克隆一起使用。

--keep-unreachable

除了使用 --unpacked= 选项命名的包中未包含的可到达对象外,还将使用 --unpacked= 选项命名的包中未包含的可到达对象添加到生成的包中。这意味着 --revs

--pack-loose-unreachable

打包无法访问的松散对象(以及它们的松散对应项被删除)。这意味着 --revs

--unpack-unreachable

以松散形式保留无法访问的对象。这意味着 --revs

--delta-islands

根据“岛屿”限制增量匹配。请参阅以下 DELTA ISLANDS。

DELTA ISLANDS

pack-objects 在可能的情况下,会尝试重用现有的磁盘上的增量,以避免必须在运行时搜索新的增量。对于服务获取来说,这是一个重要的优化,因为它意味着服务器可以避免完全膨胀大多数对象,而只需直接从磁盘发送字节。当对象存储为针对接收方没有(并且我们尚未发送)的基础的增量时,此优化无法正常工作。在这种情况下,服务器会“破坏”增量,并且必须找到一个新的增量,这会导致很高的 CPU 成本。因此,对于性能来说,磁盘上增量关系中的对象集与客户端将获取的对象集匹配非常重要。

在正常存储库中,这往往会自动进行。对象大部分可以从分支和标签访问,这就是客户端获取的内容。我们在服务器上找到的任何增量都可能是客户端拥有或将拥有的对象之间的增量。

但在某些仓库设置中,您可能拥有多个相关但独立的引用提示组,客户端倾向于独立获取这些组。例如,假设您在一个共享对象存储中托管了同一个仓库的多个“分支”,并通过 `GIT_NAMESPACE` 或使用备用机制的独立仓库让客户端将它们视为独立的仓库。一个简单的重新打包可能发现,对象的最优增量是针对只在另一个分支中找到的基础进行的。但是,当客户端获取时,他们将没有基础对象,我们将不得不动态找到新的增量。

如果您在 `refs/heads/` 和 `refs/tags/` 之外有许多指向相关对象的引用(例如,某些托管提供商使用的 `refs/pull` 或 `refs/changes`),则可能会出现类似的情况。默认情况下,客户端只获取头部和标签,并且针对仅在其他组中找到的对象的增量无法按原样发送。

增量岛通过允许您将引用分组到不同的“岛屿”来解决这个问题。Pack-objects 计算哪些对象可以从哪些岛屿访问,并拒绝从对象 `A` 到未出现在 `A` 的所有岛屿中的基础的增量。这会导致打包略微变大(因为我们错过了一些增量机会),但保证一个岛屿的获取不会因为跨越岛屿边界而不得不动态重新计算增量。

当使用增量岛重新打包时,增量窗口往往会因配置禁止的候选对象而堵塞。使用大的 `--window` 重新打包会有所帮助(并且不会像预期的那样花费太多时间,因为我们可以在进行任何内容计算之前根据岛屿拒绝一些对象对)。

岛屿通过 `pack.island` 选项配置,该选项可以指定多次。每个值都是一个左锚定正则表达式,匹配引用名称。例如

[pack]
island = refs/heads/
island = refs/tags/

将头部和标签放入一个岛屿(其名称为空字符串;有关命名详情请参见下文)。任何不匹配这些正则表达式的引用(例如,`refs/pull/123`)都不在任何岛屿中。因此,任何只能从 `refs/pull/`(但不能从头部或标签)访问的对象,都不适合用作 `refs/heads/` 的基础。

引用根据其“名称”分组到岛屿中,两个产生相同名称的正则表达式被认为在同一个岛屿中。名称通过连接正则表达式中的任何捕获组(组之间用 `-` 连接)来计算。(如果没有任何捕获组,则名称为空字符串,如上例所示)。这允许您创建任意数量的岛屿。不过,只支持最多 14 个这样的捕获组。

例如,假设您将每个分支的引用存储在 `refs/virtual/ID` 中,其中 `ID` 是一个数字标识符。然后您可能配置

[pack]
island = refs/virtual/([0-9]+)/heads/
island = refs/virtual/([0-9]+)/tags/
island = refs/virtual/([0-9]+)/(pull)/

这将把每个分支的头部和标签放在它们自己的岛屿中(命名为“1234”或类似),并且每个分支的拉取引用将放在它们自己的“1234-pull”中。

请注意,我们为每个正则表达式选择一个岛屿,使用“最后一次获胜”的顺序(这允许特定于仓库的配置优先于用户范围的配置,依此类推)。

配置

各种配置变量会影响打包,请参见 git-config[1](搜索“pack”和“delta”)。

值得注意的是,对大于 `core.bigFileThreshold` 配置变量的对象以及将属性 `delta` 设置为 false 的文件,不会使用增量压缩。

Git

git[1] 套件的一部分

scroll-to-top