我怎么知道`git gc --auto`是否做了什么?

时间:2017-07-31 22:31:58

标签: git

我正在运行git gc --auto作为自动保存脚本的一部分。如果git gc --auto做了什么,我想进一步清理,但如果git gc --auto不觉得需要做什么,我想免除麻烦。有没有办法检查git gc --auto的返回值,或事先检查是否有必要运行它?

2 个答案:

答案 0 :(得分:2)

在Git 2.30(Q1 2021),“ git maintenanceman中,“ git gc({ man中的{3}})不断发展。

它比git gc更精确,并且如OP中所要求的那样,在2.30版本中引入的选项允许知道它何时完成了某些工作。

请参见the previous answercommit e841a79commit a13e3d0commit 52fe41fcommit efdd2f0commit 18e449fcommit 3e220e6,{{3} }(2020年9月25日)通过commit 252cfb7
(由commit 28cb5e6Derrick Stolee (derrickstolee)中合并,2020年10月27日)

Junio C Hamano -- gitster --:添加增量重新打包任务

签名人:Derrick Stolee

之前的更改使用可以在后台安全运行的“松散对象”清除了松散的对象。添加类似的作业,以对打包文件执行类似的清理操作。

运行'commit 52b8c8c maintenance'的一个问题是,它旨在将所有打包文件重新打包为单个打包文件。尽管这是存储对象数据的最节省空间的方法,但它并不节省时间或内存。如果仓库如此之大,以至于用户难以在其磁盘上存储包的两个副本,这将变得非常重要。

相反,通过将一些小的压缩文件收集到一个新的压缩文件中来执行“增量”重新压缩。自从在git repack中添加'man git multi-pack-index expire'(“ multi-pack-index:实现' expire'子命令”,2019-06-10,Git v2.23.0-rc0-man中列出的19575c7和'merge batch #6)< / sup>'已在git multi-pack-index repack中添加(“ midx:实现midx_repack()”,2019年6月10日,Git v2.23.0-rc0-man在{ {3}})。

'incremental-repack'任务运行以下步骤:

  1. 'ce1e4a1 merge'如果不存在则创建一个多包索引文件,否则将更新多包索引文件。指数 自上次写入以来出现的任何新的打包文件。这个 与后台提取作业特别相关。

    当multi-pack-index看到同一对象的两个副本时,它会 将偏移数据存储到较新的打包文件中。这意味着 一些旧的打包文件可能会变成“未引用”,我将使用 意思是“该文件的打包文件列表中的一个打包文件 多重包装索引,但多重包装索引中没有任何对象 请参考该打包文件中的位置。”

  2. 'batch #6 git multi-pack-index write'删除所有未引用的打包文件并更新multi-pack-index以将这些打包文件从 清单。这是安全的,因为并发的Git进程会看到 多重包装索引,在寻找对象时不打开那些包装 内容。 (类似于“松散对象”工作,有一些Git 不管multi-pack-index如何打开包文件的命令, 但很少使用。此外,用户自行选择 使用后台操作可能会避免使用那些 命令。

  3. 'man git multi-pack-index expire'收集在multi-pack-index中列出的一组压缩文件,并创建 一个新的打包文件,其中包含列出了偏移量的对象 通过multi-pack-index在那些对象中。套装- 通过修改打包文件,贪婪地选择文件 时间,然后将打包文件添加到集合中(如果其“预期大小”为 小于批次大小,直到 所选的打包文件至少为批处理大小。 “预期 大小”是通过将打包文件的大小除以 乘以压缩文件中对象的数量并乘以 multi-pack-index中具有偏移量的对象数 打包文件。预期大小大约是多少 打包文件将有助于最终打包文件的大小。的 目的是使生成的打包文件大小接近 到提供的批次大小。

    下次运行增量重新打包任务将删除这些 在“过期”步骤中重新打包文件。

    在此版本中,批量大小设置为“ 0”,而忽略了 选择压缩文件时的大小限制。相反 选择所有打包文件并将所有打包对象重新打包到一个 单个打包文件。它将在下一次更改中更新,但是 它需要进行一些更好的隔离计算 单独的更改。

这些步骤基于man中类似的后台维护步骤。对于Windows OS系统信息库的用户而言,这非常有效。 在为Git存储库使用同一VFS一年后,一些用户拥有成千上万个打包文件,这些打包文件最多可合并250 GB数据。我们注意到一些用户遇到了打开文件描述符限制(部分原因是git multi-pack-index repack --bacth-size=<size>(“ midx:将包添加到packed_git链表”,2019-04-29,Git v2.22.0-rc1-man)。

这些打包文件很小,因为它们包含在给定小时内被推送到原始位置的提交和树。 GVFS协议包括一个“预取”步骤,该步骤要求通过时间戳获取包含提交和树的预先计算的打包文件。每天一次将这些压缩文件分组为“每日”压缩文件,最多30天。如果用户在30天内未请求预取包,则他们将在新的大型包文件中获取提交和树的全部历史记录。这导致大量打包文件的增量压缩不佳。

通过每天运行一次此包文件维护步骤,这些存储库中包含成千上万个跨越200+ GB的包,而下降到数十个跨越30-50 GB的包文件。所有这些操作都无需从系统中删除对象,并且使用2 GB的恒定批大小。一旦完成了将压缩文件减小到较小大小的工作,批处理大小为2 GB,这意味着并非每次运行都会触发重新打包操作,因此后续运行不会使压缩文件过期。这使这些存储库保持“干净”状态。

git maintenance现在包含在其Scalar (and VFS for Git)中:

incremental-repack

incremental-repack作业重新打包了对象目录 使用multi-pack-index功能。为了防止种族 在并发Git命令的情况下,它遵循两个步骤 处理。首先,它调用git multi-pack-index expire进行删除 multi-pack-index文件未引用的pack文件。第二个 呼叫git multi-pack-index repack以选择几个小 打包文件,然后重新打包成更大的文件,然后更新 multi-pack-index个条目引用了小包装文件, 请参阅新的打包文件。这将准备那些小包装文件 在下次运行git multi-pack-index expire时删除。 小包文件的选择应符合预期 大文件包的大小至少为批处理大小;看到 --batch-size子命令中的repack选项 af96fe3。预设的批次大小为零, 这是一种特殊情况,试图重新打包所有打包文件 打包成单个文件。

并且:

merge:添加增量重新包装自动条件

签名人:Derrick Stolee

incremental-repack任务通过删除已被新包替换的包文件,然后将一批小包文件重新打包为较大的包文件来更新multi-pack-index。这种增量重新打包比重写所有对象数据快,但比其他一些维护活动慢。

maintenance.incremental-repack.auto”配置选项指定在运行步骤之前应在multi-pack-index之外存在多少个打包文件。
这些打包文件可以通过'man page git multi-pack-index'命令创建,也可以通过松散对象任务创建。
默认值为10。

将该选项设置为零会禁用带有'--auto'选项的任务,而负值会使该任务每次运行。

git config现在包含在其maintenance中:

maintenance.incremental-repack.auto

此整数配置选项控制incremental-repack的频率 任务应作为git maintenance run --auto的一部分运行。如果为零 那么incremental-repack任务将不会与--auto一起运行 选项。负值将强制任务每次运行。 否则,正值表示命令应在以下情况下运行: 不在multi-pack-index中的打包文件数至少等于 maintenance.incremental-repack.auto中的。默认值为10。


在Git 2.30(Q1 2021)中,添加了部分“ git fetchman以便于为其编写crontab条目(以及其他调度系统配置)。

请参见man pagegit maintenanceman(2020年10月15日),commit 0016b61commit 61f7a38commit a4cb1a2commit 2fec604 (2020年9月11日)和commit 0c18b70(2020年8月28日)之前为commit 4950b2a
(由commit b08ff1fcommit 1942d48中合并,2020年11月18日)

Derrick Stolee (derrickstolee):向文档添加故障排除指南

帮助者:Junio C Hamano
签名人:Derrick Stolee

'Junio C Hamano -- gitster -- commit 7660da1'子命令锁定对象数据库,以防止并发进程争用资源。这是防止存储库损坏和数据丢失的重要安全措施。

如果用户不了解此功能,则可能导致混乱的行为。在“ maintenance git maintenance run内置文档中添加一个“疑难解答”部分,以讨论这些折衷。

此部分的简短版本是Git不会破坏您的存储库,但是如果计划任务列表花费的时间超过一个小时,则由于该对象数据库冲突,某些计划任务可能会被丢弃。
例如,在午夜长时间运行的“每日”任务可能会阻止“每小时”任务在凌晨1点运行。

相反的情况也是可能的,但是只要“每小时”任务比“每日”和“每周”任务快得多,可能性就较小。

git maintenance现在包含在其man中:

故障排除


git maintenance命令旨在简化存储库 维护模式,同时最大程度地减少了Git命令期间的用户等待时间。 有多种配置选项可用于自定义 处理。默认维护选项侧重于完成的操作 甚至在大型存储库上也能快速完成。

用户可能会发现某些情况下,计划的维护任务无法按以下方式运行 经常按预期进行。每个git maintenance run命令都会锁定 存储库的对象数据库,这可以防止其他并发 git maintenance run个命令在同一存储库上运行。不带 在这种保护措施下,竞争过程可能会将存储库留在 不可预测的状态。

后台维护计划运行git maintenance run个流程 每小时一次。每次运行都会执行“每小时”任务。在午夜, 该过程还执行“每日”任务。第一天的午夜 在一周中,该过程还将执行“每周”任务。一个 流程遍历每个注册的存储库,执行计划的 该频率的任务。视注册数量而定 存储库及其大小,此过程可能需要一个多小时。 在这种情况下,多个git maintenance run命令可以在同一条命令上运行 同时存储库,碰撞对象数据库锁。这个 导致两个任务之一无法运行。

如果您发现某些维护时间超过一小时 完成,然后考虑降低维护的复杂性 任务。例如,gc任务比 incremental-repack任务。但是,这需要付出一点代价 较大的对象数据库。考虑移动要运行的更昂贵的任务 不太频繁。

专家用户可以考虑使用以下工具计划自己的维护任务: 与git maintenance start提供的时间表不同,并且 Git配置选项。这些用户应注意该对象 数据库锁定以及并发git maintenance run命令的行为。 此外,git gc命令不应与 git maintenance run命令。 git gc修改对象数据库 但不会以与git maintenance run相同的方式进行锁定。如果 可能的话,请使用git maintenance run --task=gc而不是git gc

答案 1 :(得分:0)

如果您正在监视git gc --auto退出状态(例如,用于检测故障),则该返回值已在Git 2.20中更改:

请参见commit 3029970Jonathan Nieder (artagnon)(2018年7月17日)。
帮助者:Jeff King (peff)
(由Junio C Hamano -- gitster --commit 993fa56中合并,2018年10月16日)

  

gc:失败时以状态128退出

     

-1返回的cmd_gc gets的值传播到exit(),导致退出状态为255。
  改为使用die以获得更清晰的错误消息和受控的退出。

您现在有了:而不是“ error: The last gc run reported the following.

fatal: The last gc run reported the following
相关问题