设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
-
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创建的无法访问的对象、打包引用、修剪引用日志、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、暂存区、引用日志……)也将被执行。 - --detach
- --no-detach
-
如果系统支持,则在后台运行。此选项将覆盖
gc.autoDetach配置。 - --cruft
- --no-cruft
-
在过期无法访问对象时,将它们单独打包到 cruft pack 中,而不是作为松散对象存储。
--cruft默认启用。 - --max-cruft-size=<n>
-
在将无法访问的对象打包到 cruft pack 时,将新的 cruft pack 的大小限制在最多 <n> 字节。将覆盖通过
gc.maxCruftSize配置指定的任何值。有关更多信息,请参阅 git-repack[1] 的--max-cruft-size选项。 - --expire-to=<dir>
-
在将无法访问的对象打包到 cruft pack 时,将包含已修剪对象(如果有)的 cruft pack 写入目录 <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
-
除了最大的非 cruft pack、任何带有
.keep文件的 pack 以及任何 cruft pack(s) 之外,所有 pack 都会被合并到一个 pack 中。使用此选项时,将忽略gc.bigPackThreshold。
AGGRESSIVE
当提供了 --aggressive 选项时,git-repack[1] 将以 -f 标志调用,该标志又会将 --no-reuse-delta 传递给 git-pack-objects[1]。这将丢弃任何现有的 delta 并重新计算它们,代价是花费更多时间重新打包。
这些优化的效果大部分是持久的,例如,当 pack 和松散对象合并到另一个 pack 时,该 pack 中现有的 delta 可能会被重用,但在某些情况下,我们可能会从较新的 pack 中选择一个次优的 delta。
此外,提供 --aggressive 将调整传递给 git-repack[1] 的 --depth 和 --window 选项。请参阅下面的 gc.aggressiveDepth 和 gc.aggressiveWindow 设置。通过使用更大的窗口大小,我们更有可能找到更优的 delta。
在对给定仓库运行定制的性能基准测试之前,使用此选项可能不值得。它花费的时间更长,并且产生的空间/delta 优化可能值得,也可能不值得。大多数用户及其仓库选择不使用此选项是正确的权衡。
配置
本节中以下所有内容均从 git-config[1] 文档中选择性地包含。内容与彼处相同:
- gc.aggressiveDepth
-
git gc --aggressive 使用的 delta 压缩算法的深度参数。默认值为 50,当未使用
--aggressive时,这是--depth选项的默认值。有关更多详细信息,请参阅 git-repack[1] 中
--depth选项的文档。 - gc.aggressiveWindow
-
git gc --aggressive 使用的 delta 压缩算法的窗口大小参数。默认值为 250,这是一个比默认的
--window10 更具侵略性的窗口大小。有关更多详细信息,请参阅 git-repack[1] 中
--window选项的文档。 - gc.auto
-
当仓库中存在大约多于此数量的松散对象时,
gitgc--auto会将它们打包。一些外部命令会使用此命令来不时执行轻量级的垃圾回收。默认值为 6700。将其设置为 0 不仅禁用了基于松散对象数量的自动打包,还禁用了
gitgc--auto将用于确定是否有工作要做的任何其他启发式方法,例如gc.autoPackLimit。 - gc.autoPackLimit
-
当仓库中存在多于此数量的未被
*.keep文件标记的 pack 时,gitgc--auto会将它们合并为一个更大的 pack。默认值为 50。将其设置为 0 将禁用它。将gc.auto设置为 0 也会禁用此项。参阅下面的
gc.bigPackThreshold配置变量。当使用时,它将影响自动 pack 限制的工作方式。 - gc.autoDetach
-
使
gitgc--auto立即返回并在系统支持的情况下在后台运行。默认值为 true。此配置变量充当回退,以防maintenance.autoDetach未设置。 - gc.bigPackThreshold
-
如果非零,则在运行
gitgc时,所有大于此限制的非 cruft pack 都将被保留。这与--keep-largest-pack非常相似,只是所有符合阈值的非 cruft pack 都被保留,而不仅仅是最大的 pack。默认为零。支持 k、m 或 g 的常用单位后缀。请注意,如果保留的 pack 数量超过 gc.autoPackLimit,则将忽略此配置变量,除了基本 pack 之外的所有 pack 都将重新打包。之后,pack 的数量应低于 gc.autoPackLimit,并且将再次尊重 gc.bigPackThreshold。
如果估计的
gitrepack顺利运行所需的内存量不可用且未设置gc.bigPackThreshold,那么最大的 pack 也将被排除(这相当于使用--keep-largest-pack运行gitgc)。 - gc.writeCommitGraph
-
如果为 true,则 gc 在 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会使其被 Git 版本早于 1.5.1.2 的通过哑传输(如 HTTP)克隆。此变量决定 git gc 是否运行gitpack-refs。可以将其设置为notbare以在所有非裸仓库中启用它,或者可以将其设置为布尔值。默认值为true。 - gc.cruftPacks
-
将无法访问的对象存储在 cruft pack 中(请参阅 git-repack[1]),而不是作为松散对象。默认值为
true。 - gc.maxCruftSize
-
重新打包时限制新的 cruft pack 的大小。当与
--max-cruft-size一起指定时,命令行选项优先。请参阅 git-repack[1] 的--max-cruft-size选项。 - gc.pruneExpire
-
当运行 git gc 时,它将调用 prune --expire 2.weeks.ago(如果使用 cruft pack(通过
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 会删除早于此时间(默认为 90 天)的引用日志条目。值“now”会立即过期所有条目,“never”会完全抑制过期。在中间使用“<pattern>”(例如“refs/stash”)时,设置仅适用于匹配 <pattern> 的引用。
- gc.reflogExpireUnreachable
- gc.<pattern>.reflogExpireUnreachable
-
git reflog expire 会删除早于此时间且无法从当前尖端到达的引用日志条目(默认为 30 天)。值“now”会立即过期所有条目,“never”会完全抑制过期。在中间使用“<pattern>”(例如“refs/stash”)时,设置仅适用于匹配 <pattern> 的引用。
这些类型的条目通常是使用
gitcommit--amend或gitrebase的结果,并且是发生在修改或 rebase 之前的提交。由于这些更改不是当前项目的一部分,大多数用户希望更早地过期它们,因此默认设置比gc.reflogExpire更具侵略性。 - gc.recentObjectsHook
-
在考虑是否删除某个对象时(无论是生成 cruft pack 还是将无法访问的对象存储为松散对象),使用 shell 执行指定的命令。将其输出解释为 Git 将视为“最近”的对象 ID,无论其年龄如何。通过将它们的 mtime 视为“现在”,任何在输出中提及的对象(及其后代)都将被保留,而不管其真实年龄。
输出必须每行包含一个十六进制对象 ID,并且别无其他。仓库中找不到的对象将被忽略。支持多个 hook,但所有 hook 都必须成功退出,否则操作(生成 cruft pack 或解包无法访问的对象)将中止。
- gc.repackFilter
-
在重新打包时,使用指定的过滤器将某些对象移动到单独的 packfile 中。请参阅 git-repack[1] 的
--filter=<filter-spec> 选项。 - gc.repackFilterTo
-
在重新打包并使用过滤器(请参阅
gc.repackFilter)时,指定的目录将用于创建包含过滤掉的对象(即被过滤出去的对象)的 packfile。警告: 指定的目录应可访问,例如使用 Git 的 alternate 机制,否则 Git 可能会将仓库视为已损坏,因为它可能无法访问该 packfile 中的对象。请参阅 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 会尽最大努力不删除在您的仓库中任何地方被引用的对象。特别地,它不仅会保留由您当前分支和标签集引用的对象,还会保留由索引、远程跟踪分支、引用日志(可能引用后来被修改或回滚的分支中的提交)以及 refs/* 命名空间中的任何其他内容引用的对象。请注意,附加到对象的注释(由 git notes 创建的类型)不会影响对象的生命周期。如果您期望某些对象被删除但未删除,请检查所有这些位置,并决定在您的场景下删除这些引用是否有意义。
另一方面,当 git gc 与另一个进程并发运行时,存在删除另一个进程正在使用但尚未创建引用的对象的风险。这可能会导致另一个进程失败,或者如果另一个进程稍后向已删除对象添加引用,则可能导致仓库损坏。Git 有两个功能可以显著缓解此问题:
-
任何修改时间比
--prune日期新的对象,以及从它可达的所有对象,都将被保留。 -
大多数将对象添加到数据库的操作会更新对象(如果它已存在)的修改时间,以便应用 #1。
然而,这些功能并未提供完整的解决方案,因此并发运行命令的用户必须承担一定的损坏风险(尽管在实践中风险似乎很低)。
钩子
git gc --auto 命令将运行 pre-auto-gc hook。有关更多信息,请参阅 githooks[5]。