简体中文 ▾ 主题 ▾ 最新版本 ▾ git-pack-objects 最后更新于 2.49.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]
	[--name-hash-version=<n>] < <object-list>

描述

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

打包归档是一种在两个仓库之间高效传输一组对象的方式,也是一种访问高效的归档格式。在打包归档中,一个对象要么作为压缩的整体存储,要么作为与其他一些对象的差异存储。后者通常被称为增量(delta)。

打包归档格式(.pack)被设计为自包含的,以便无需任何额外信息即可解包。因此,增量所依赖的每个对象都必须存在于包中。

将生成一个包索引文件(.idx),以便快速、随机访问包中的对象。将索引文件(.idx)和打包归档(.pack)都放在 $GIT_OBJECT_DIRECTORY(或 $GIT_ALTERNATE_OBJECT_DIRECTORIES 中的任何目录)的 pack/ 子目录中,Git 就可以从包归档中读取数据。

git unpack-objects 命令可以读取打包归档并将其包含的对象扩展为“一文件一对象”格式;智能拉取(smart-pull)命令通常在它们的对等方为了高效网络传输而即时创建包时执行此操作。

选项

base-name

写入一对文件(.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 仅使用前一种格式以获得更好的兼容性。此选项允许命令使用后一种格式以实现紧凑性。根据平均增量链长度,此选项通常会将生成的包文件缩小 3-5%。

注意:像 git gc(参见 git-gc[1])、git repack(参见 git-repack[1])这样的瓷器命令在现代 Git 中将对象放入仓库的包文件时,默认会传递此选项。当 git bundle(参见 git-bundle[1])创建捆绑包时也是如此。

--threads=<n>

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

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

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

--keep-true-parents

使用此选项,被嫁接(grafts)隐藏的父提交仍将被打包。

--filter=<filter-spec>

从生成的包文件中省略某些对象(通常是二进制大对象)。有关有效的 <filter-spec> 形式,请参见 git-rev-list[1]

--no-filter

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

--missing=<missing-action>

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

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

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

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

--exclude-promisor-objects

省略已知存在于承诺者远程(promisor remote)中的对象。(此选项的目的是仅对本地创建的对象进行操作,这样当我们重新打包时,我们仍然可以区分本地创建的对象[不带 .promisor]和来自承诺者远程的对象[带 .promisor]。)这与部分克隆一起使用。

--keep-unreachable

除了不在标有 *.keep 文件的包中的可达对象外,使用 --unpacked= 选项命名的包中不可达的引用也将添加到生成的包中。这意味着 --revs

--pack-loose-unreachable

打包不可达的松散对象(并删除其松散对应物)。这意味着 --revs

--unpack-unreachable

以松散形式保留不可达对象。这意味着 --revs

--delta-islands

根据“孤岛”限制增量匹配。请参阅下面的 DELTA ISLANDS。

--name-hash-version=<n>

在执行增量压缩时,Git 会根据启发式方法(使用对象的路径)将可能相似的对象分组。虽然按精确路径匹配进行对象分组对于具有许多版本的路径很有用,但跨不同完整路径查找增量对也有好处。Git 按类型、然后按路径的“名称哈希”、最后按大小收集对象,希望将能够很好地一起压缩的对象分组。

默认名称哈希版本是 1,它通过将路径的最后字节视为对哈希函数提供最大幅度来优先考虑哈希局部性。此版本擅长区分短路径和查找跨目录的重命名。但是,哈希函数主要依赖于路径的最后 16 个字节。如果仓库中有很多路径具有相同的最后 16 个字节,而仅在父目录上有所不同,则此名称哈希可能导致过多的冲突并导致结果不佳。目前,在使用 --write-bitmap-index 写入可达性位图文件时,需要此版本。

名称哈希版本 2 具有与版本 1 相似的局部性特征,但它单独考虑每个路径组件并使用移位叠加哈希值。这仍然优先考虑路径的最后字节,但也使用父目录名称对哈希的低位进行“加盐”。此方法允许版本 1 的一些局部性优势,同时打破了许多不同目录中出现同名文件造成的大多数冲突。目前,在使用 --write-bitmap-index 写入可达性位图文件时不允许此版本,它将自动更改为版本 1

增量孤岛

在可能的情况下,pack-objects 会尝试重用现有磁盘上的增量,以避免在运行时搜索新增量。这对于提供 fetch 服务来说是一项重要的优化,因为它意味着服务器可以完全避免解压大多数对象,而直接从磁盘发送字节。当对象作为增量存储时,如果接收方没有其基础对象(并且我们尚未发送该基础对象),则此优化将无法奏效。在这种情况下,服务器会“打破”该增量,并且必须寻找一个新的增量,这会带来很高的 CPU 开销。因此,为了性能,磁盘上增量关系中的对象集必须与客户端将要 fetch 的对象集匹配,这一点非常重要。

在正常的仓库中,这通常会自动工作。对象大多可以从分支和标签中访问,而这正是客户端 fetch 的内容。我们在服务器上找到的任何增量都可能在客户端拥有或将要拥有的对象之间。

但在某些仓库设置中,您可能拥有几个相关但独立的引用指针组,而客户端倾向于独立 fetch 这些组。例如,想象您在单个共享对象存储中托管了仓库的几个“分支”,并允许客户端通过 GIT_NAMESPACE 或使用 alternates 机制将它们视为单独的仓库。简单的 repack 可能会发现某个对象的最佳增量是针对仅在另一个分支中找到的基础。但是当客户端 fetch 时,它们将没有该基础对象,我们将不得不在运行时寻找新的增量。

如果您有许多在 refs/heads/refs/tags/ 之外指向相关对象的引用(例如,一些托管服务提供商使用的 refs/pullrefs/changes),也可能存在类似情况。默认情况下,客户端只 fetch 头和标签,而针对仅在这些其他组中找到的对象的增量无法按原样发送。

增量孤岛通过允许您将引用分组为不同的“孤岛”来解决此问题。pack-objects 计算哪些对象可以从哪些孤岛访问,并拒绝将对象 A 的增量与不在 A 的所有孤岛中的基础对象关联。这会导致包略微增大(因为我们错过了一些增量机会),但保证 fetch 一个孤岛时不会因为跨越孤岛边界而需要在运行时重新计算增量。

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

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

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

将 heads 和 tags 放入一个孤岛中(其名称为空字符串;有关命名的更多信息,请参见下文)。任何不匹配这些正则表达式的引用(例如,refs/pull/123)都不在任何孤岛中。因此,任何仅从 refs/pull/ 可达(但不是 heads 或 tags)的对象都不会被用作 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)/

这将把每个分支的 heads 和 tags 放入它们自己的孤岛中(命名为“1234”或类似名称),每个的 pull refs 将进入它们自己的“1234-pull”。

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

配置

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

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

GIT

Git[1] 套件的一部分

scroll-to-top