根据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)。我错过了什么吗?
答案 0 :(得分:0)
经过互联网研究后,我发现根据this回答stackoverflow:
Git决定是否自动gc based on two criteria:
.idx
中的.git/objects/pack
是more than 50 files吗?.git/objects/17
吗?)如果由于某种原因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;可达")