【问题标题】:Even when I push to remote, gc doesn't appear to run即使我推送到远程,gc 似乎也没有运行
【发布时间】:2017-10-12 14:39:15
【问题描述】:

根据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 时,commit C 仍然可见。即使提交 C 超过 30 天,情况仍然如此。我认为git push 自动运行git gc,我认为git gc 删除了无法访问的提交(在本例中为C)。我错过了什么吗?

【问题讨论】:

  • 您希望提交从哪个仓库消失? git push 将执行git gc 远程仓库
  • 你也可以在这里遇到 heisenbug 问题:我相信 reflog 本身可以代表对提交的引用。

标签: git garbage-collection


【解决方案1】:

在互联网上进行了一些研究后,我发现根据stackoverflow上的this答案:


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

  1. 包太多了吗? (从字面上看,.git/objects/pack 中有 more than 50 files.idx 吗?)
  2. 是否有太多松散的对象? (字面意思,有more than 27 files in .git/objects/17吗?)

如果由于某种原因 Git 无法合并打包文件或删除该目录中的松散对象,它会认为下次需要再次自动 gc。


但是,根据this book 所说的,我们有:

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

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

• 推送到远程存储库

• 在一些可能引入许多松散对象的命令之后

• 当某些命令如 git reflog 过期时明确请求它

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

无论如何,这本书清楚地表明你是对的,并且在推送后触发了这个命令,但是我在任何地方都找不到确认。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 但即使是超过 30 天的无法访问的提交也不会被删除。我有超过一年的提交仍然留在回购中!抱歉,应该在我的问题中提到这一点。
    【解决方案3】:

    您可以这样做以从本地 repo 中删除无法访问的提交

     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 本身保留对无法访问的提交的引用(从而使它们“可访问”)

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 2023-04-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      • 2015-09-22
      相关资源
      最近更新 更多