`git gc`和`git repack -ad之间有什么区别吗?git prune`?

Sud*_*oer 4 git git-gc

有什么区别git gc和git repack -ad; git prune?
如果是,将采取哪些额外步骤git gc(反之亦然)?
哪个更适合空间优化或安全?

Enr*_*lio 7

有什么区别git gc和git repack -ad; git prune?

不同之处在于,默认情况下git gc对于需要哪些内务处理任务非常保守.例如,git repack除非存储库中的松散对象数超过某个阈值(可通过gc.auto变量配置),否则它将不会运行.此外,git gc将运行更多的任务而不仅仅是git repack和git prune.

如果是,将采取哪些额外步骤git gc(反之亦然)?

根据文档,git gc运行:

  • git-prune
  • git-reflog
  • git-repack
  • git-rerere

更具体地说,通过查看(第338-343行)1的源代码,gc.c我们可以看到它最多调用以下命令:

  • pack-refs --all --prune
  • reflog expire --all
  • repack -d -l
  • prune --expire
  • worktree prune --expire
  • rerere gc

根据包的数量(第121-126行),它可以repack使用-A选项代替(第203-212 行):

* If there are too many loose objects, but not too many
* packs, we run "repack -d -l". If there are too many packs,
* we run "repack -A -d -l".  Otherwise we tell the caller
* there is no need.
if (too_many_packs())
    add_repack_all_option();
else if (!too_many_loose_objects())
    return 0;
Run Code Online (Sandbox Code Playgroud)

请注意函数的第211-212行need_for_gc,如果存储库中没有足够的松散对象,gc则根本不运行.

这在文档中进一步阐明:

如果存储库中有太多松散的对象或太多的包,则需要内务处理.如果松散对象的数量超过gc.auto配置变量的值,则使用将所有松散对象组合成单个包git repack -d -l.设置值gc.auto以0禁用松散对象的自动打包.

如果包的数量超过了值gc.autoPackLimit,则.keep使用-A选项of 将现有包(标记为文件的包)合并到单个包中git repack.

如您所见,git gc努力根据存储库的状态做正确的事情.

哪个更适合空间优化或安全?

一般来说,最好git gc --auto简单地运行,因为它将完成所需的最少工作量以保持存储库的良好状态 - 安全且不浪费太多资源.

但是,请记住,在某些命令之后可能已经自动触发了垃圾收集,除非通过将gc.auto配置变量设置为禁用此行为0.

从文档:

--auto
使用此选项,git gc检查是否需要管理; 如果没有,它退出而不执行任何工作.git gc --auto执行可能会创建许多松散对象的操作后,会运行一些git命令.

因此,对于大多数存储库而言,您不需要git gc经常显式地运行所有这些,因为它已经为您完成了.


1.截至a0a18312016-08-08 的承诺.