git-gc
清理不必要的文件并优化本地仓库
概要
'git gc' [--aggressive] [--auto] [--[no-]detach] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]描述
在当前仓库中运行许多维护任务,例如压缩文件修订(以减少磁盘空间并提高性能)、删除可能由先前 'git add' 调用创建的不可达对象、打包引用、修剪 reflog、rerere 元数据或过时的工作树。还可能更新辅助索引(如 commit-graph)。
当创建对象的常见 porcelain 操作运行时,它们将检查自上次维护以来仓库是否大幅增长,如果是,则自动运行 git gc。有关如何禁用此行为,请参阅下面的 gc.auto。
仅在不经常运行此类 porcelain 命令的情况下向仓库添加对象、进行一次性仓库优化或清理次优的批量导入时,才需要手动运行 git gc。有关导入情况的更多详细信息,请参阅 git-fast-import(1) 中的"包文件优化"部分。
选项
--aggressive- 通常 'git gc' 运行非常快,同时提供良好的磁盘空间利用率和性能。此选项将使 'git gc' 以花费更多时间为代价更积极地优化仓库。此优化的效果大多是持久的。有关详细信息,请参阅下面的"激进"部分。--auto- 使用此选项,'git gc' 检查是否需要任何维护;如果不执行任何工作则退出。有关此启发式如何工作的信息,请参阅下面"配置"部分中的gc.auto选项。 一旦维护因超过gc.auto和gc.autoPackLimit等配置选项的限制而触发,所有其他维护任务(例如 rerere、工作树、reflog...)也将被执行。--detach,--no-detach- 如果系统支持,在后台运行。此选项覆盖gc.autoDetach配置。--cruft,--no-cruft- 过期不可达对象时,将它们单独打包到 cruft 包中而不是作为松散对象存储。--cruft默认开启。--max-cruft-size=<n>- 将不可达对象打包到 cruft 包时,将新 cruft 包的大小限制为最多<n>字节。覆盖通过gc.maxCruftSize配置指定的任何值。--expire-to=<dir>- 将不可达对象打包到 cruft 包时,将包含已修剪对象(如果有)的 cruft 包写入目录<dir>。此选项仅在与--cruft一起使用时有效。--prune=<date>- 修剪比日期更旧的松散对象(默认为 2 周前,可由配置变量gc.pruneExpire覆盖)。--prune=now 修剪所有松散对象而不考虑其存在时间,如果另一个进程正在同时写入仓库,则增加损坏的风险;请参阅下面的"备注"。--prune 默认开启。--no-prune- 不修剪任何松散对象。--quiet- 禁止所有进度报告。--force- 强制git gc运行,即使此仓库上可能有另一个git gc实例正在运行。--keep-largest-pack- 除了最大的非 cruft 包、任何标记有.keep文件的包和任何 cruft 包外,所有包都合并为单个包。使用此选项时,gc.bigPackThreshold被忽略。
激进
当提供 --aggressive 选项时,将调用 git-repack(1) 并带有 -f 标志,这反过来会将 --no-reuse-delta 传递给 git-pack-objects(1)。这将丢弃任何现有的增量并重新计算它们,代价是花费更多时间进行重新打包。
此效果大多是持久的,例如当包和松散对象合并到一个包中时,该包中的现有增量可能会被重用,但也有各种情况我们可能会从较新的包中选择次优的增量。
此外,提供 --aggressive 将调整传递给 git-repack(1) 的 --depth 和 --window 选项。请参阅下面的 gc.aggressiveDepth 和 gc.aggressiveWindow 设置。通过使用更大的窗口大小,我们更有可能找到更优的增量。
在给定的仓库上使用此选项可能不值得,除非对其进行定制的性能基准测试。它需要更多时间,结果的空间/增量优化可能值得也可能不值得。对于大多数用户及其仓库,根本不使用这是正确的权衡。
配置
本节中此行以下的内容是从 git-config(1) 文档中选择性包含的。内容与其中的相同:
gc.aggressiveDepth- 'git gc --aggressive' 使用的增量压缩算法中使用的深度参数。默认为 50,这是--aggressive未使用时--depth选项的默认值。gc.aggressiveWindow- 'git gc --aggressive' 使用的增量压缩算法中使用的窗口大小参数。默认为 250,这比默认的--window10 更激进。gc.auto- 当仓库中大约有超过此数量的松散对象时,git gc --auto将打包它们。一些 Porcelain 命令使用此命令不时执行轻量级垃圾回收。默认值为 6700。 将此设置为 0 不仅禁用基于松散对象数量的自动打包,还禁用git gc --auto用于确定是否有工作要做的任何其他启发式方法(如gc.autoPackLimit)。gc.autoPackLimit- 当仓库中未标记有*.keep文件的包超过此数量时,git gc --auto将它们合并为一个更大的包。默认值为 50。将此设置为 0 可禁用它。将gc.auto设置为 0 也会禁用它。gc.autoDetach- 使git gc --auto立即返回并在系统支持时在后台运行。默认为 true。此配置变量在未设置maintenance.autoDetach时作为后备。gc.bigPackThreshold- 如果非零,当运行git gc时,所有大于此限制的非 cruft 包将被保留。这与--keep-largest-pack非常相似,只是所有满足阈值的非 cruft 包都被保留,而不仅仅是最大的包。默认为零。支持常见的单位后缀 'k'、'm' 或 'g'。gc.writeCommitGraph- 如果为 true,则在运行 git-gc(1) 时 gc 将重写 commit-graph 文件。使用git gc --auto时,如果需要维护,commit-graph 将被更新。默认为 true。gc.logExpiry- 如果文件 gc.log 存在,则git gc --auto将打印其内容并以状态零退出,除非该文件超过 'gc.logExpiry'。默认为 "1.day"。gc.packRefs- 在仓库中运行git pack-refs使其无法通过 HTTP 等哑传输由 1.5.1.2 之前的 Git 版本克隆。此变量决定 'git gc' 是否运行git pack-refs。这可以设置为notbare以在所有非裸仓库中启用,或设置为布尔值。默认为true。gc.cruftPacks- 将不可达对象存储在 cruft 包中(参见 git-repack(1))而不是作为松散对象。默认为true。gc.maxCruftSize- 重新打包时限制新 cruft 包的大小。当与--max-cruft-size一起指定时,命令行选项优先。gc.pruneExpire- 运行 'git gc' 时,它将调用 'prune --expire 2.weeks.ago'(以及如果通过gc.cruftPacks或--cruft使用 cruft 包,则调用 'repack --cruft --cruft-expiration 2.weeks.ago')。使用此配置变量覆盖宽限期。值 "now" 可用于禁用此宽限期并始终立即修剪不可达对象,或 "never" 可用于禁止修剪。gc.worktreePruneExpire- 运行 'git gc' 时,它调用 'git worktree prune --expire 3.months.ago'。此配置变量可用于设置不同的宽限期。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 天。gc.recentObjectsHook- 考虑是否删除对象时(无论是生成 cruft 包还是将不可达对象存储为松散对象),使用 shell 执行指定的命令。将其输出解释为对象 ID,Git 将视为"最近的",无论其存在时间如何。gc.repackFilter- 重新打包时,使用指定的过滤器将某些对象移动到单独的包文件中。gc.repackFilterTo- 重新打包并使用过滤器时,指定的位置将用于创建包含过滤出的对象的包文件。警告:指定的位置应该可访问(例如使用 Git 备用机制),否则 Git 可能认为仓库损坏。gc.rerereResolved- 您先前解决的冲突合并的记录在运行 'git rerere gc' 时保留此天数。默认为 60 天。gc.rerereUnresolved- 您未解决的冲突合并的记录在运行 'git rerere gc' 时保留此天数。默认为 15 天。
备注
'git gc' 非常努力地不删除仓库中任何地方引用的对象。特别是,它不仅保留当前分支和标签集引用的对象,还保留索引、远程跟踪分支、reflog(可能引用后来被修改或回绕的分支中的提交)以及 refs/* 命名空间中的任何其他内容引用的对象。请注意,附加到对象的注释(由 'git notes' 创建的那种)不会有助于保持对象存活。如果您期望某些对象被删除但它们没有被删除,请检查所有这些位置并确定在您的情况下删除这些引用是否有意义。
另一方面,当 'git gc' 与另一个进程并发运行时,存在删除另一个进程正在使用但尚未创建引用的对象的风险。这可能只会导致另一个进程失败,或者如果另一个进程稍后添加对已删除对象的引用,可能会损坏仓库。Git 有两个功能可以显著缓解此问题:
- 修改时间比
--prune日期更新的任何对象都会被保留,以及从它可达的所有内容。 - 大多数向数据库添加对象的操作都会更新对象的修改时间(如果已存在),以便 #1 适用。
但是,这些功能并不构成完整的解决方案,因此并发运行命令的用户必须承受一些损坏的风险(在实践中似乎很低)。
钩子
'git gc --auto' 命令将运行 'pre-auto-gc' 钩子。有关更多信息,请参阅 githooks(5)。
另请参阅
git-prune(1)git-reflog(1)git-repack(1)git-rerere(1)
Git
git(1) 套件的一部分
