Git
English ▾ 主题 ▾ 最新版本 ▾ git-gc 最后更新于 2.47.0

名称

git-gc - 清理不必要的文件并优化本地仓库

概要

git gc [--aggressive] [--auto] [--[no-]detach] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]

描述

在当前仓库中运行一系列的维护任务,例如压缩文件修订版(以减少磁盘空间并提高性能)、删除可能由之前 git add 调用创建的不可到达的对象、打包引用、修剪 reflog、rerere 元数据或陈旧的工作树。还可以更新辅助索引,例如提交图。

当运行创建对象的常用瓷器操作时,它们会检查自上次维护以来仓库是否大幅增长,如果是,则自动运行 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.autogc.autoPackLimit)的限制触发维护任务,所有其他维护任务(例如 rerere、工作树、reflog……)也将执行。

--[no-]detach

如果系统支持,则在后台运行。此选项会覆盖 gc.autoDetach 配置。

--[no-]cruft

在过期不可到达的对象时,将它们分别打包到一个 cruft 包中,而不是将它们存储为松散对象。默认情况下 --cruft 为开启状态。

--max-cruft-size=<n>

将不可到达的对象打包到 cruft 包中时,将新 cruft 包的大小限制为最多 <n> 字节。覆盖通过 gc.maxCruftSize 配置指定的任何值。有关更多信息,请参阅 git-repack[1]--max-cruft-size 选项。

--prune=<date>

修剪比日期旧的松散对象(默认是 2 周前,可由配置变量 gc.pruneExpire 覆盖)。--prune=now 修剪松散对象,无论其年龄如何,并且如果另一个进程正在同时写入仓库,则会增加损坏的风险;请参阅下面的“NOTES”。默认情况下 --prune 为开启状态。

--no-prune

不修剪任何松散对象。

--quiet

抑制所有进度报告。

--force

强制 git gc 运行,即使可能存在另一个在该仓库上运行的 git gc 实例。

--keep-largest-pack

除了最大的非 cruft 包、任何用 .keep 文件标记的包和任何 cruft 包之外的所有包都合并到一个包中。当使用此选项时,会忽略 gc.bigPackThreshold

积极

当提供 --aggressive 选项时,将使用 -f 标志调用 git-repack[1],这反过来又会将 --no-reuse-delta 传递给 git-pack-objects[1]。这将丢弃任何现有的增量并重新计算它们,代价是花费更多时间进行重新打包。

这些效果大多是持久的,例如,当包和松散对象合并到另一个包中时,该包中现有的增量可能会被重用,但也有各种情况,我们可能会从较新的包中选择一个次优增量。

此外,提供 --aggressive 将调整传递给 git-repack[1]--depth--window 选项。请参阅下面的 gc.aggressiveDepthgc.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

当仓库中大约有超过这么多松散对象时,git gc --auto 将打包它们。一些瓷器命令使用此命令不时执行轻量级垃圾回收。默认值为 6700。

将其设置为 0 不仅会禁用基于松散对象数量的自动打包,还会禁用 git gc --auto 否则将用于确定是否有工作要做的任何其他启发式方法,例如 gc.autoPackLimit

gc.autoPackLimit

当仓库中有多于这么多未用 *.keep 文件标记的包时,git gc --auto 会将它们合并成一个更大的包。默认值为 50。将其设置为 0 会禁用它。将 gc.auto 设置为 0 也会禁用它。

请参阅下面的 gc.bigPackThreshold 配置变量。启用时,它会影响自动包限制的工作方式。

gc.autoDetach

使 git gc --auto 立即返回并在系统支持的情况下在后台运行。默认为 true。如果未设置 maintenance.autoDetach,则此配置变量充当后备。

gc.bigPackThreshold

如果非零,则运行 git gc 时会保留大于此限制的所有非 cruft 包。这与 --keep-largest-pack 非常相似,只是所有满足阈值的非 cruft 包都会保留,而不仅仅是最大的包。默认为零。支持 kmg 的常用单位后缀。

请注意,如果保留的包数量超过 gc.autoPackLimit,则会忽略此配置变量,所有包(基础包除外)都将重新打包。在此之后,包的数量应该低于 gc.autoPackLimit,并且 gc.bigPackThreshold 应该再次被尊重。

如果估计用于 git repack 顺利运行的内存不可用并且未设置 gc.bigPackThreshold,则最大的包也将被排除(这相当于使用 --keep-largest-pack 运行 git gc)。

gc.writeCommitGraph

如果为 true,则当运行 git-gc[1] 时,gc 将重写提交图文件。使用 git gc --auto 时,如果需要维护任务,则会更新提交图。默认为 true。有关详细信息,请参阅 git-commit-graph[1]

gc.logExpiry

如果文件 gc.log 存在,那么 git gc --auto 将打印其内容并以状态零退出,而不是运行,除非该文件比 gc.logExpiry 旧。默认值为 "1.day"。有关指定其值的更多方法,请参阅 gc.pruneExpire

gc.packRefs

在存储库中运行 git pack-refs 会导致 Git 1.5.1.2 之前的版本无法通过诸如 HTTP 之类的哑传输进行克隆。此变量确定 git gc 是否运行 git pack-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> 匹配的 refs。

gc.reflogExpireUnreachable
gc.<pattern>.reflogExpireUnreachable

git reflog expire 删除早于此时间段且当前尖端无法访问的 reflog 条目;默认为 30 天。值 "now" 会立即过期所有条目,而 "never" 会完全抑制过期。在中间使用 "<pattern>"(例如“refs/stash”)时,该设置仅适用于与 <pattern> 匹配的 refs。

这些类型的条目通常是使用 git commit --amendgit rebase 产生的结果,并且是进行修订或变基之前的提交。由于这些更改不是当前项目的一部分,因此大多数用户希望更快地使它们过期,这就是默认值比 gc.reflogExpire 更激进的原因。

gc.recentObjectsHook

在考虑是否删除对象(在生成残余包或将不可达对象存储为松散对象时)时,使用 shell 执行指定的命令。将它们的输出解释为 Git 将视为“最近”的对象 ID,无论其年龄如何。通过将它们的 mtimes 视为“now”,无论其真实年龄如何,输出中提到的任何对象(及其后代)都将保留。

输出必须每行包含一个十六进制对象 ID,并且不包含其他内容。存储库中找不到的对象将被忽略。支持多个钩子,但所有钩子都必须成功退出,否则操作(生成残余包或解包不可达对象)将停止。

gc.repackFilter

重新打包时,使用指定的过滤器将某些对象移动到单独的 packfile 中。请参阅 git-repack[1]--filter=<filter-spec> 选项。

gc.repackFilterTo

重新打包并使用过滤器时,请参阅 gc.repackFilter,指定的 location 将用于创建包含过滤掉对象的 packfile。**警告:**指定的 location 应该是可访问的,例如使用 Git alternates 机制,否则 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 非常努力地避免删除存储库中任何位置引用的对象。特别是,它不仅会保留当前分支和标签集引用的对象,还会保留索引、远程跟踪分支、reflog(可能引用后来已修订或回滚的分支中的提交)以及 refs/* 命名空间中的任何其他内容引用的对象。请注意,附加到对象的注释(由 git notes 创建的注释)不会有助于保持对象存活。如果您期望删除某些对象但它们没有被删除,请检查所有这些位置,并确定在您的情况下删除这些引用是否有意义。

另一方面,当 git gc 与另一个进程同时运行时,存在删除另一个进程正在使用但尚未创建引用的对象的风险。这可能只会导致另一个进程失败,或者如果另一个进程稍后向已删除的对象添加引用,则可能会损坏存储库。Git 有两个功能可以大大降低此问题的风险

  1. 修改时间晚于 --prune 日期的所有对象都将保留,以及从此对象可访问的所有内容。

  2. 大多数将对象添加到数据库的操作都会更新对象的修改时间(如果该对象已存在),以便应用 #1。

但是,这些功能还不能完全解决问题,因此同时运行命令的用户必须承担一定的损坏风险(在实践中似乎很低)。

钩子

git gc --auto 命令将运行 pre-auto-gc 钩子。有关更多信息,请参阅 githooks[5]

GIT

git[1] 套件的一部分

scroll-to-top