Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
-
2.49.0
2025-03-14
- 2.43.1 → 2.48.1 no changes
-
2.43.0
2023-11-20
- 2.37.1 → 2.42.4 no changes
-
2.37.0
2022-06-27
- 2.35.1 → 2.36.6 no changes
-
2.35.0
2022-01-24
- 2.33.1 → 2.34.8 no changes
-
2.33.0
2021-08-16
- 2.32.1 → 2.32.7 no changes
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 no changes
-
2.31.0
2021-03-15
- 2.29.1 → 2.30.9 no changes
-
2.29.0
2020-10-19
- 2.27.1 → 2.28.1 no changes
-
2.27.0
2020-06-01
- 2.23.1 → 2.26.3 no changes
-
2.23.0
2019-08-16
- 2.21.1 → 2.22.5 no changes
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 no changes
-
2.20.0
2018-12-09
- 2.18.1 → 2.19.6 no changes
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 no changes
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.15.4 no changes
-
2.14.6
2019-12-06
- 2.10.5 → 2.13.7 no changes
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.5.6 → 2.7.6 no changes
-
2.4.12
2017-05-05
-
2.3.10
2015-09-28
- 2.1.4 → 2.2.3 no changes
-
2.0.5
2014-12-17
概述
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)被设计为自成一体,这样它就可以在没有任何进一步信息的情况下被解包。因此,delta 所依赖的每个对象都必须存在于pack 中。
一个打包的索引文件(.idx)被生成,以便快速、随机地访问打包中的对象。将索引文件(.idx)和打包的归档文件(.pack)放在$GIT_OBJECT_DIRECTORY(或 $GIT_ALTERNATE_OBJECT_DIRECTORIES 上的任何一个目录)的 pack/ 子目录下,可以使 Git 从打包的归档文件中读取。
git unpack-objects 命令可以读取打包后的档案,并将打包后的对象扩展为 “一对一的文件 - 对象” 的格式;这通常是由 smart-pull 命令在即时创建打包时完成的,以便由它们的同行进行有效的网络传输。
选项
- 基础名
-
写入成对的文件(.pack 和 .idx),使用 <base-name> 来确定创建的文件名。 当使用该选项时,一对中的两个文件被写入 <base-name>-<SHA-1>.{pack,idx} 文件。 <SHA-1> 是一个基于 pack 内容的哈希值,会写入命令的标准输出中。
- --stdout
-
将包的内容(本来要写到 .pack 文件中的内容)写到标准输出中。
- --revs
-
从标准输入读取修订参数,而不是单个对象名称。 修订版参数的处理方式与带有
--objects
标志的 git rev-list 使用其commit
参数来建立其输出的对象列表相同。 结果列表上的对象被打包。 除了修订,还接受--not
或--shallow <SHA-1>
行。 - --unpacked
-
这暗指
--revs
。 当处理从标准输入读取的修订参数列表时,将打包的对象限制在那些尚未打包的对象。 - --all
-
这暗指
--revs
。 除了从标准输入中读取的修订参数列表外,还假设指定要包括 `refs/`下的所有引用。 - --include-tag
-
包括未被要求的注释标签,如果它们引用的对象被包含在结果的打包文件中。 这对于向本地 Git 客户端发送新的标签很有用。
- --stdin-packs
-
从标准输入中读取 packfiles(例如:
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=<近似值>
-
如果指定了,且对象的 mtime 超过
<approxidate>
,就会从 cruft 包中剔除。如果没有指定(并给出--cruft
),那么没有对象被淘汰。 - --window=<n>
- --depth=<n>
-
这两个选项影响了使用 delta 压缩法存储数据包中的对象的方式。 这些对象首先按照类型、大小和可选的名称进行内部排序,并与 --window 内的其他对象进行比较,看使用 delta 压缩是否节省了空间。 --depth 限制了最大的 delta 深度;使其过深会影响到解包方的性能,因为 delta 数据需要应用那么多次才能到达必要的对象。
--window 的默认值为 10,--depth 的默认值为 50。最大深度为 4095。
- --window-memory=<n>
-
这个选项在
--window
的基础上提供了一个额外的限制;窗口的大小将动态地缩小,以便不占用超过 <n> 字节的内存。 这对有大有小的对象的存储库很有用,它不会因为大窗口而耗尽内存,但仍然能够利用大窗口来处理小对象。 大小可以以 "k"、"m "或 "g "为后缀。--window-memory=0
使内存使用不受限制。 默认值取自`pack.windowMemory` 配置变量。 - --max-pack-size=<n>
-
在不寻常的情况下,你可能无法在你的文件系统上创建大于一定大小的文件,这个选项可以用来告诉命令将输出的 packfile 分割成多个独立的 packfile,每个 packfile 都不大于给定的大小。大小可以以 "k"、"m "或 "g "为后缀。允许的最小尺寸被限制为1 MiB。 默认是无限制的,除非配置变量`pack.packSizeLimit` 被设置。注意,这个选项可能会导致仓库变大变慢;参见 `pack.packSizeLimit`中的讨论。
- --honor-pack-keep
-
这个标志会使一个已经在本地打包的对象被忽略,即使它本来会被打包。
- --keep-pack=<包名>
-
这个标志使已经在给定包中的对象被忽略,即使它本来已经被打包。
<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
-
当在已有打包的版本库中创建一个打包的归档文件时,该命令会重用现有的三角洲。 这有时会导致一个稍微次优的打包。 这个标志告诉命令不要重用现有的 deltas,而是从头开始计算。
- --no-reuse-object
-
这个标志告诉命令不要重复使用现有的对象数据,包括非延迟对象,强迫重新压缩所有东西。 这意味着 --no-reuse-delta。只有在需要对打包的数据全盘执行不同的压缩级别的隐蔽情况下才有用。
- --compression=<n>
-
为生成的数据包中新压缩的数据指定压缩级别。 如果没有指定,数据包的压缩级别首先由 pack.compression 决定,然后由 core.compression 决定,如果两者都没有设置,则默认为 -1,即 zlib 默认值。 如果你想在所有的数据上强制使用统一的压缩级别,无论其来源如何,请添加 --no-reuse-object。
- --[no-]sparse
-
与 "--revs" 选项结合使用时,切换 "稀疏" 算法,以确定哪些对象应包含在数据包中。这种算法只行走那些出现在引入新对象的路径中的树。 当计算一个包来发送一个小的变化时,这可能有显著的性能优势。然而,如果所包含的提交包含某些类型的直接重命名,则可能会有额外的对象被添加到包文件中。如果不包括这个选项,它默认为
pack.useSparse
的值,除非另有规定,否则为真。 - --thin
-
通过省略发送方和接收方之间的共同对象来创建一个 "轻量" 包,以减少网络传输。这个选项只有在与 --stdout 一起使用时才有意义。
注意:轻量包由于省略了所需的对象而违反了打包的存档格式,因此如果不使其自成一体,Git 就无法使用。使用
git index-pack --fix-thin
( git-index-pack[1])来恢复自包含的属性。 - --shallow
-
优化将被提供给客户的浅克隆仓库的数据包。 这个选项和 --thin 结合起来,可以以速度为代价,产生一个更小的包。
- --delta-base-offset
-
打包后的归档文件可以用 20 字节的对象名称或流中的偏移量来表达 delta 的基础对象,但早期版本的 Git 不理解后者。 默认情况下,git pack-objects 只使用前一种格式,以提高兼容性。 这个选项允许该命令使用后者的格式以达到紧凑的目的。 根据 delta 链的平均长度,这个选项通常会将生成的 packfile 缩小 3-5%。
注意: 在现版本 Git 中,诸如
git gc
(参见 git-gc[1])、git repack
(参见 git-repack[1])之类的上层命令在将仓库中的对象放入打包文件时,默认会传递这个选项。 当git bundle
(参见 git-bundle[1])创建一个捆绑包时也会这样做。 - --threads=<n>
-
指定搜索最佳 delta 匹配时产生的线程数。 这要求 pack-objects 使用 pthreads 编译,否则该选项将被忽略并发出警告。 这样做的目的是在多处理器机器上减少打包时间。 然而,delta 搜索窗口所需的内存会乘以线程数。 指定 0 将导致 Git 自动检测 CPU 数量并相应设置线程数量。
- --index-version=<版本>[,<偏移>]
-
这是为测试套件准备的。它允许为生成的数据包索引强制选择版本,并对位于给定偏移量以上的对象强制选择 64 位索引条目。
- --keep-true-parents
-
通过这种方法,被移植物覆盖的父母还是会被打包。
- --filter=<过滤器定义>
-
从生成的包文件中省略某些对象(通常是 blob)。 有关有效的
<过滤规则>
形式,请参见 git-rev-list[1]。 - --no-filter
-
关闭之前的
--filter=
参数。 - --missing=<缺失行为>
-
一个调试选项,帮助未来的 "部分克隆 "开发。 这个选项指定了如何处理丢失的对象。
表格 --missing=error 请求在遇到丢失对象时以错误停止 pack-objects。 如果仓库是部分克隆,在宣布丢失之前会尝试获取丢失的对象。 这是默认行为。
形式 --missing=allow-any 将允许在遇到丢失对象时继续遍历对象。 不会获取丢失的对象。 缺少的对象将从结果中被静默省略。
形式 --missing=allow-promisor 类似于 allow-any,但只允许继续遍历预期 promisor 丢失的对象。 不会获取丢失的对象。 意外丢失的对象将引发错误。
- --exclude-promisor-objects
-
省略已知在远程 promisor 中的对象。 (该选项的目的是只对本地创建的对象执行操作,这样当我们重新打包时,仍然可以区分本地创建的对象 [不含 .promisor] 和来自远程 promisor [含 .promisor] 的对象)。 该选项与部分克隆一起使用。
- --keep-unreachable
-
除了标有 *.keep 文件的包中没有的可到达对象之外,用 --unpacked= 选项命名的包中的引用无法到达的对象也会被添加到生成的包中。这意味着`--revs`。
- --pack-loose-unreachable
-
打包不可达的松散对象(并移除它们的松散对应对象)。这意味着`--revs`.
- --unpack-unreachable
-
以松散的形式保存无法访问的对象。这意味着
--revs
。 - --delta-islands
-
根据 “岛屿” 限制增量匹配。请参阅下文的增量匹配。
- --name-hash-version=<n>
-
While performing delta compression, Git groups objects that may be similar based on heuristics using the path to that object. While grouping objects by an exact path match is good for paths with many versions, there are benefits for finding delta pairs across different full paths. Git collects objects by type and then by a "name hash" of the path and then by size, hoping to group objects that will compress well together.
The default name hash version is
1
, which prioritizes hash locality by considering the final bytes of the path as providing the maximum magnitude to the hash function. This version excels at distinguishing short paths and finding renames across directories. However, the hash function depends primarily on the final 16 bytes of the path. If there are many paths in the repo that have the same final 16 bytes and differ only by parent directory, then this name-hash may lead to too many collisions and cause poor results. At the moment, this version is required when writing reachability bitmap files with--write-bitmap-index
.The name hash version
2
has similar locality features as version1
, except it considers each path component separately and overlays the hashes with a shift. This still prioritizes the final bytes of the path, but also "salts" the lower bits of the hash using the parent directory names. This method allows for some of the locality benefits of version1
while breaking most of the collisions from a similarly-named file appearing in many different directories. At the moment, this version is not allowed when writing reachability bitmap files with--write-bitmap-index
and it will be automatically changed to version1
.
DELTA ISLANDS
在可能的情况下, pack-objects
尝试重用现有的磁盘上的 deltas,以避免临时搜索新的 deltas。这对于服务获取来说是一个重要的优化,因为它意味着服务器可以完全避免膨胀大多数对象,而只是直接从磁盘发送字节。当一个对象以 delta 的形式存储,而接收者并不拥有(而且我们也没有发送)这个基数时,这种优化就不起作用了。在这种情况下,服务器将 “中断” delta,并必须找到一个新的delta,这将产生很高的 CPU 成本。因此,磁盘上 delta 关系中的对象集必须与客户端获取的对象相匹配,这对性能非常重要。
在正常的仓库中,这往往是自动进行的。对象大多可以从分支和标签中获取,这也是客户端获取的内容。我们在服务器上发现的任何脱节都可能是客户端已经拥有或将要拥有的对象之间的脱节。
但在某些仓库设置中,您可能有几个相关但独立的引用提示组,客户端倾向于独立获取这些组。例如,假设你在一个共享对象存储空间中托管了多个版本库的 "fork",并通过`GIT_NAMESPACE`或使用替代机制的独立仓库让客户端将它们视为独立的仓库。天真的 repack 可能会发现,一个对象的最佳 delta 是针对只有在另一个 fork 中才能找到的基数。但是,当客户端获取时,他们将没有基础对象,我们将不得不临时找到一个新的 delta。
如果在 refs/heads/
和 refs/tags/
之外有许多指向相关对象的引用(例如,某些托管提供商使用的 refs/pull
或 refs/changes
),也可能存在类似的情况。默认情况下,客户端只获取 heads 和 tags,因此不能发送只在这些组中找到的对象的 deltas。
Delta 岛解决了这个问题,它允许您将您的引用分组为不同的 “岛”。Pack-objects 会计算哪些对象可以从哪些岛屿到达,并拒绝从对象 A
针对不存在于所有 A
岛屿中的基准进行 delta。这会导致数据包略微变大(因为我们错过了一些 delta 机会),但保证了对一个岛的取值不会因为跨越岛的边界而不得不重新计算 delta。
当使用 delta 岛重新打包时,delta 窗口往往会被配置禁止的候选对象堵塞。使用大的 --window 进行重新打包会有所帮助(而且不会像其他情况下花费那么长的时间,因为在对内容进行任何计算之前,我们可以根据岛拒绝一些对象对)。
岛是通过 pack.island
选项配置的,可以多次指定。每个值都是匹配 refnames 的左锚正则表达式。例如 :
[pack] island = refs/heads/ island = refs/tags/
将 heads 和 tags 放入一个 “岛” 中(其名称为空字符串;有关命名的更多信息,请参阅下文)。任何不匹配这些正则表达式的引用(例如 refs/pull/123
)都不在任何岛中。因此,任何只能从 refs/pull/
(而不能从 heads 或 tags) 访问的对象都不能作为 refs/heads/
的基础。
参考文件根据其 “名称” 分组,产生相同名称的两个 regex 被视为在同一个岛中。名称是通过连接 regex 中的任何捕获组和中间的 - 破折号来计算的。(如果没有捕获组,则名称为空字符串,如上例)。这允许您创建任意数量的岛屿。但最多只支持 14 个这样的捕获组。
例如,假设你在 refs/virtual/ID
中存储了每个 fork 的引用,其中 ID
是一个数字标识符。然后您可以配置 :
[pack] island = refs/virtual/([0-9]+)/heads/ island = refs/virtual/([0-9]+)/tags/ island = refs/virtual/([0-9]+)/(pull)/
这就将每个分叉的头和标签放在自己的岛(命名为 "1234" 或类似的名字)中,而每个分叉的拉动参考则放在自己的 "1234-pull "中。
请注意,我们为每个 regex 选择一个单独的岛,使用 "最后一个获胜" 的排序(这允许特定于仓库的配置优先于用户范围内的配置,等等)。
配置
各种配置变量会影响打包,参见 git-config[1] (搜索 "pack" 和 "delta")。
值得注意的是,delta 压缩不用于大于 core.bigFileThreshold
配置变量的对象和属性 delta
设置为 false 的文件。
GIT
属于 git[1] 文档