即使我推送到遥控器,gc似乎也无法运行

时间:2017-10-12 14:39:15

标签: git garbage-collection

根据an answer of “How often should you use git-gc?”,每次推送到远程时都会自动运行git gc

我对答案发表评论但从未得到回应,所以我在这里问。

  

我的树中有无法访问的提交(由于git commit --amend)。这可以通过git log --reflog进行验证。我将一个分支推送到远程存储库并再次检查我的树;无法访问的提交仍然存在。显然git gc在发生这种推动时没有运行。    ......?

示例:

$ git commit -m 'commit A'
$ git commit -m 'commit B'
$ git commit -m 'commit C'
$ git commit --amend -m 'commit D'
$ git commit -m 'commit E'
$ git commit -m 'commit F'
$ git push origin master
$ git log --reflog
* commit F (HEAD -> master, origin/master)
* commit E
* commit D (an amendment of C)
|
| * commit C
|/
* commit B
* commit A

当我将master推送到远程并运行git log --reflog时,提交C仍然可见。即使提交C超过30天,情况仍然如此。我以为git push会自动运行git gc,我认为git gc会删除无法访问的提交(在本例中为C)。我错过了什么吗?

3 个答案:

答案 0 :(得分:0)

经过互联网研究后,我发现根据this回答stackoverflow:

Git决定是否自动gc based on two criteria

  1. 包装太多了吗? (从字面上看,.idx中的.git/objects/packmore than 50 files吗?
  2. 是否有太多松散的物体? (从字面上看,有more than 27 files in .git/objects/17吗?)
  3. 如果由于某种原因Git无法合并包文件或删除该目录中的松散对象,它会认为下次需要再次自动gc。

    然而,根据this书中我们所说的那样:

      

    如果出现以下情况,Git会自动运行垃圾回收:

         

    •存储库中有太多松散的对象

         

    •推送到远程存储库

         

    •一些可能引入许多松散物体的命令之后

         

    •某些命令(例如git reflog)明确请求它

    但我无法找到 WHICH 命令实际上在任何地方触发此命令。我的猜测是,规范并没有真正定义它,它取决于你使用的实现/版本。

    无论如何,这本书清楚地表明你是对的,并且在推动此命令被触发后,但我无法在任何地方找到确认。

    我在git push文档here中找到了一个示例,其中除非您在git gc之后运行git push,否则将无法访问提交。

答案 1 :(得分:0)

您假设提交将立即被垃圾收集,但git实际上将等待30 days by default,直到它删除无法访问的提交。可以使用gc.reflogExpireUnreachable配置设置更改此行为。

答案 2 :(得分:0)

您可以执行此操作以从本地存储库中删除无法访问的提交

 git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \                                                                      (release-branch|✔) 17:49:31
    -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"

this answer for more information。我怀疑你的问题源于git reflog本身保留对无法访问的提交的引用(从而使它们#34;可达")