设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.53.0 → 2.55.0 无变更
-
2.52.0
2025-11-17
- 2.49.1 → 2.51.2 无更改
-
2.49.0
2025-03-14
- 2.47.1 → 2.48.2 无变更
-
2.47.0
2024-10-06
- 2.43.1 → 2.46.4 无变更
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 无更改
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 无更改
-
2.41.0
2023-06-01
- 2.38.1 → 2.40.4 无更改
-
2.38.0
2022-10-02
- 2.37.1 → 2.37.7 无更改
-
2.37.0
2022-06-27
- 2.31.1 → 2.36.6 无变更
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 无更改
-
2.30.0
2020-12-27
- 2.24.1 → 2.29.3 无变更
-
2.24.0
2019-11-04
- 2.22.1 → 2.23.4 无更改
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 无更改
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 无更改
-
2.20.0
2018-12-09
- 2.19.1 → 2.19.6 无更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 无更改
-
2.18.0
2018-06-21
- 2.13.7 → 2.17.6 无更改
-
2.12.5
2017-09-22
-
2.11.4
2017-09-22
- 2.10.5 无更改
-
2.9.5
2017-07-30
- 2.7.6 → 2.8.6 无更改
-
2.6.7
2017-05-05
- 2.5.6 无更改
-
2.4.12
2017-05-05
- 2.1.4 → 2.3.10 无更改
-
2.0.5
2014-12-17
概要
git gc [--aggressive] [--auto] [--[no-]detach] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]
描述
在当前仓库内运行一系列内务处理任务,例如压缩文件版本(以减少磁盘占用并提高性能)、移除可能由先前执行 git add 所产生的不可达对象、打包引用、修剪引用日志 (reflog)、rerere 元数据或陈旧的工作区。也可能会更新辅助索引,如提交图 (commit-graph)。
当运行常见的会创建对象的常规操作(瓷器命令)时,它们会检查自上次维护以来仓库是否显著增长,如果是,则会自动运行 git gc。请参阅下方的 gc.auto 以了解如何禁用此行为。
仅当在未定期运行此类常规操作的仓库中添加对象,或者进行一次性仓库优化,又或者例如清理次优的批量导入时,才需要手动运行 git gc。有关导入情况的更多详细信息,请参阅 git-fast-import[1] 中的“PACKFILE OPTIMIZATION”一节。
选项
- --aggressive
-
通常 git gc 运行速度很快,同时能提供良好的磁盘空间利用率和性能。此选项将导致 git gc 以牺牲更多时间为代价,对仓库进行更激进的优化。这种优化的效果大多是持久的。详细信息请参阅下方的“AGGRESSIVE”一节。
- --auto
-
使用此选项,git gc 会检查是否需要进行任何内务处理;如果不需要,它将直接退出而不执行任何工作。
请参阅下方“CONFIGURATION”部分中的
gc.auto选项,了解此启发式算法的工作原理。一旦因超出
gc.auto和gc.autoPackLimit等配置选项的限制而触发内务处理,所有其他内务任务(例如 rerere、工作区、reflog……)也将被执行。 - --detach
- --no-detach
-
如果系统支持,则在后台运行。此选项会覆盖
gc.autoDetach配置。 - --cruft
- --no-cruft
-
在过期处理不可达对象时,将它们单独打包进一个残余包 (cruft pack) 中,而不是将它们存储为松散对象。
--cruft默认开启。 - --max-cruft-size=<n>
-
将不可达对象打包进残余包时,限制新残余包的大小最大为 <n> 字节。该选项会覆盖通过
gc.maxCruftSize配置指定的任何值。更多信息请参阅 git-repack[1] 的--max-cruft-size选项。 - --expire-to=<dir>
-
将不可达对象打包进残余包时,将包含已修剪对象(如果有)的残余包写入目录 <dir>。此选项仅在与
--cruft一起使用时有效。更多信息请参阅 git-repack[1] 的--expire-to选项。 - --prune=<date>
-
修剪早于指定日期的松散对象(默认为 2 周前,可被配置变量
gc.pruneExpire覆盖)。--prune=now 会立即修剪松散对象,无论其存在时间长短,如果此时有其他进程正在并发写入仓库,会增加损坏风险;请参阅下方的“NOTES”。--prune 默认开启。 - --no-prune
-
不修剪任何松散对象。
- --quiet
-
禁止所有进度报告。
- --force
-
即使该仓库中可能已有另一个
gitgc实例在运行,也强制运行gitgc。 - --keep-largest-pack
-
除最大的非残余包、标记有
.keep文件的包以及任何残余包之外的所有包,都将被合并成一个单独的包。使用此选项时,gc.bigPackThreshold将被忽略。
AGGRESSIVE
当提供 --aggressive 选项时,git-repack[1] 将以 -f 标志被调用,这会向 git-pack-objects[1] 传递 --no-reuse-delta。这将丢弃任何现有的增量并重新计算它们,代价是花费更多时间在重新打包上。
这种操作的效果大多是持久的,例如当包和松散对象合并到另一个包时,该包中现有的增量可能会被重用,但也有多种情况是我们可能会选择从较新的包中提取次优的增量。
此外,提供 --aggressive 将会调整传递给 git-repack[1] 的 --depth 和 --window 选项。请参阅下方的 gc.aggressiveDepth 和 gc.aggressiveWindow 设置。通过使用更大的窗口大小,我们更有可能找到更优的增量。
除非在特定仓库上运行过量身定制的性能基准测试,否则可能不值得使用此选项。它需要花费更多的时间,且由此带来的空间/增量优化可能并不一定值得。对于大多数用户及其仓库来说,完全不使用此选项是正确的权衡。
配置
本节中以下所有内容均从 git-config[1] 文档中选择性地包含。内容与彼处相同:
- gc.aggressiveDepth
-
git gc --aggressive 使用的增量压缩算法中的深度参数。默认为 50,这也是未使用
--aggressive时--depth选项的默认值。更多详细信息,请参阅 git-repack[1] 中关于
--depth选项的文档。 - gc.aggressiveWindow
-
git gc --aggressive 使用的增量压缩算法中的窗口大小参数。默认为 250,这比默认的
--window(大小为 10)要激进得多。更多详细信息,请参阅 git-repack[1] 中关于
--window选项的文档。 - gc.auto
-
当仓库中的松散对象数量大约超过此数值时,
gitgc--auto将会对它们进行打包。一些常规操作命令会使用此命令不时执行轻量级垃圾回收。默认值为 6700。将其设置为 0 不仅会禁用基于松散对象数量的自动打包,还会禁用
gitgc--auto用于确定是否需要执行工作的任何其他启发式检查(例如gc.autoPackLimit)。 - gc.autoPackLimit
-
当仓库中未标记
*.keep文件的包数量超过此数值时,gitgc--auto会将它们合并为一个更大的包。默认值为 50。设置为 0 则禁用此功能。将gc.auto设置为 0 也会禁用此功能。请参阅下方的
gc.bigPackThreshold配置变量。当使用它时,会影响自动打包限制的工作方式。 - gc.autoDetach
-
如果系统支持,使
gitgc--auto立即返回并在后台运行。默认为 true。此配置变量在未设置maintenance.autoDetach时作为回退项。 - gc.bigPackThreshold
-
如果非零,当运行
gitgc时,所有大于此限制的非残余包都将被保留。这与--keep-largest-pack非常相似,不同之处在于所有满足阈值的非残余包都会被保留,而不仅仅是最大的包。默认为零。支持常用的单位后缀 k, m 或 g。注意,如果被保留的包数量超过了 gc.autoPackLimit,则会忽略此配置变量,除基准包之外的所有包都将被重新打包。在此之后,包的数量应该会低于 gc.autoPackLimit,并且 gc.bigPackThreshold 将再次被遵循。
如果预估
gitrepack平稳运行所需的内存不足,且未设置gc.bigPackThreshold,则最大的包也会被排除(这相当于运行带有--keep-largest-pack选项的gitgc)。 - gc.writeCommitGraph
-
如果为 true,则在运行 git-gc[1] 时会重写 commit-graph 文件。使用
gitgc--auto时,如果需要进行内务处理,也会更新 commit-graph。默认为 true。详情请参阅 git-commit-graph[1]。 - gc.logExpiry
-
如果 gc.log 文件存在,
gitgc--auto将打印其内容并以状态零退出,而不执行操作,除非该文件距今已超过 gc.logExpiry 的时间。默认为 "1.day"。有关如何指定其值的更多方法,请参阅gc.pruneExpire。 - gc.packRefs
-
在仓库中运行
gitpack-refs会导致 1.5.1.2 之前的 Git 版本无法通过 HTTP 等哑传输协议进行克隆。此变量决定 git gc 是否运行gitpack-refs。可以将其设置为notbare以在所有非裸仓库中启用它,或者设置为布尔值。默认值为true。 - gc.cruftPacks
-
将不可达对象存储在残余包中(参见 git-repack[1])而不是存储为松散对象。默认值为
true。 - gc.maxCruftSize
-
重新打包时限制新残余包的大小。当除了
--max-cruft-size之外还指定了此配置时,命令行选项优先。请参阅 git-repack[1] 的--max-cruft-size选项。 - gc.pruneExpire
-
当运行 git gc 时,它将调用 prune --expire 2.weeks.ago(如果通过
gc.cruftPacks或--cruft使用残余包,则调用 repack --cruft --cruft-expiration 2.weeks.ago)。使用此配置变量可以覆盖此宽限期。值 "now" 可用于禁用此宽限期并立即修剪不可达对象,或者使用 "never" 来禁止修剪。此功能有助于防止 git gc 与其他正在写入仓库的进程并发运行时产生损坏;请参阅 git-gc[1] 的“NOTES”一节。 - gc.worktreePruneExpire
-
当运行 git gc 时,它会调用 git worktree prune --expire 3.months.ago。此配置变量可用于设置不同的宽限期。值 "now" 可用于禁用宽限期并立即修剪
$GIT_DIR/worktrees,或者使用 "never" 来禁止修剪。 - gc.reflogExpire
- gc.<pattern>.reflogExpire
-
git reflog expire 会移除早于此时间的 reflog 条目;默认为 90 天。值 "now" 会立即过期所有条目,"never" 则完全禁止过期。中间加上 "<pattern>"(例如 "refs/stash")时,此设置仅适用于匹配该 <pattern> 的引用。
- gc.reflogExpireUnreachable
- gc.<pattern>.reflogExpireUnreachable
-
git reflog expire 会移除早于此时间且无法从当前分支顶端到达的 reflog 条目;默认为 30 天。值 "now" 会立即过期所有条目,"never" 则完全禁止过期。中间加上 "<pattern>"(例如 "refs/stash")时,此设置仅适用于匹配该 <pattern> 的引用。
此类条目通常是使用
gitcommit--amend或gitrebase后产生的,是修改或变基发生之前的提交。由于这些更改不属于当前项目,大多数用户希望尽快使它们过期,这就是默认值比gc.reflogExpire更激进的原因。 - gc.recentObjectsHook
-
在考虑是否移除一个对象(无论是生成残余包还是将不可达对象存为松散对象)时,使用 shell 执行指定的命令。将其输出解释为对象 ID,Git 将无论其实际年龄多大都将其视为“最近的”。通过将其修改时间视为“现在”,输出中提到的任何对象(及其后代)都将被保留,无论其真实年龄如何。
输出必须每行包含一个十六进制对象 ID,且不能包含其他内容。仓库中找不到的对象将被忽略。支持多个 hook,但所有 hook 必须成功退出,否则操作(无论是生成残余包还是解包不可达对象)将被中止。
- gc.repackFilter
-
重新打包时,使用指定的过滤器将某些对象移动到单独的包文件中。请参阅 git-repack[1] 的
--filter=<filter-spec> 选项。 - gc.repackFilterTo
-
重新打包并使用过滤器(参见
gc.repackFilter)时,指定的路径将被用于创建包含被过滤出对象的包文件。警告:指定的路径应该是可访问的(例如使用 Git alternates 机制),否则仓库可能会被 Git 视为损坏,因为它可能无法访问该包文件中的对象。请参阅 git-repack[1] 的--filter-to=<dir> 选项以及 gitrepository-layout[5] 中的objects/info/alternates一节。 - gc.rerereResolved
-
当运行 git rerere gc 时,您之前解决的合并冲突记录会被保留指定天数。您也可以使用更具可读性的 "1.month.ago" 等。默认值为 60 天。请参阅 git-rerere[1]。
- gc.rerereUnresolved
-
当运行 git rerere gc 时,您尚未解决的合并冲突记录会被保留指定天数。您也可以使用更具可读性的 "1.month.ago" 等。默认值为 15 天。请参阅 git-rerere[1]。
注意事项
git gc 会竭尽全力不删除仓库中任何地方引用的对象。特别是,它不仅会保留当前分支和标签引用的对象,还会保留索引、远程追踪分支、reflog(可能引用后来被修改或回退的分支中的提交)以及 refs/* 命名空间中的任何其他内容所引用的对象。请注意,附加到对象上的备注(如 git notes 创建的那种)对于保持对象存活没有贡献。如果您预期某些对象应该被删除但它们没有被删除,请检查所有这些位置,并决定在您的情况下移除这些引用是否有意义。
另一方面,当 git gc 与另一个进程并发运行时,存在删除另一个进程正在使用但尚未创建引用的对象的风险。这可能只会导致另一个进程失败,或者如果另一个进程稍后添加了对已删除对象的引用,则可能导致仓库损坏。Git 有两个显著缓解此问题的特性:
-
任何修改时间晚于
--prune日期的对象都会被保留,连同其可达的所有内容。 -
大多数向数据库添加对象的操作,如果对象已存在,则会更新其修改时间,以便应用第 1 点。
然而,这些特性离完全的解决方案还有距离,因此并发运行命令的用户不得不承担一定的损坏风险(但在实际操作中风险似乎很低)。
钩子
git gc --auto 命令将运行 pre-auto-gc hook。更多信息请参阅 githooks[5]。