问题 git gc --aggressive --prune = all不会从存储库中删除大文件


关于“如何从repo中删除意外添加的大文件”有许多SO问题,其中许多建议使用 git gc 命令。但是,我发现它不适合我,我不知道出了什么问题。

这是我做的:

$ git init
Initialized empty Git repository in /home/wzyboy/git/myrepo/.git/
$ echo hello >> README
$ git add README 
$ git commit -a -m 'init commit'
[master (root-commit) f21783f] init commit
 1 file changed, 1 insertion(+)
 create mode 100644 README
$ du -sh .git
152K    .git
$ cp ~/big.zip .
$ git add big.zip 
$ git commit -a -m 'adding big file'
[master 3abd0a4] adding big file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 big.zip
$ du -sh .git
77M .git
$ git log --oneline 
3abd0a4 adding big file
f21783f init commit
$ git reset --hard f21783f
HEAD is now at f21783f init commit
$ git log --oneline 
f21783f init commit
$ git gc --aggressive --prune=all
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 0 (delta 0)
$ git gc --aggressive --prune=now
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 6 (delta 0)
$ du -sh .git
77M .git
$ git version
git version 2.2.2

在上面的控制台输出中,我创建了一个新的git repo,添加了一个小文本文件和 .git 目录是152K的大小,到目前为止一直很好。然后我在repo中添加了一个大文件,目录膨胀到77M。但是,在我尝试删除大文件后(git reset --hard 要么 git rebase -i),我无法恢复大文件声称的磁盘空间,无论我如何运行 git gc 有不同的选择。

任何人都可以告诉我为什么 git gc 在我的情况下不起作用?我该怎么做才能恢复磁盘空间?是否可以使用恢复磁盘空间 git gc 代替 git filter-branch

谢谢。


9836
2018-02-04 02:19


起源

git reflog expire --expire=now --all - Andrew C
@AndrewC它的作品!谢谢! - Zhuoyun Wei


答案:


正如Andrew C所建议的那样,之前需要使用reflog来解除引用对象 git gc 能够回收松散的物体。因此,通过意外添加大文件来恢复磁盘空间的正确方法是:

git reflog expire --expire=now --all
git gc --aggressive --prune=now

这将删除所有reflog,因此请谨慎使用。


13
2018-02-05 02:17





使用Git 2.18(2018年第二季度)的一个提示可以帮助避免任何拼写错误 gc prune 没有现成的参考(在这里称为:“nonsense“)

git gc --prune=nonsense“花了很长时间重新包装,然后在潜在时默默地失败”git prune --expire=nonsense“未能解析其命令行。
这已得到纠正。

看到 提交96913c9 (2018年4月23日)by Junio C Hamano(gitster
帮助-方式: Linus Torvalds(torvalds
(合并 Junio C Hamano - gitster  -  在 提交3915f9a,2018年5月8日) 

parseopt:处理格式错误 --expire 争论更好

一些解析的命令 --expire=<time> 命令行选项表现   愚蠢的时候给出无意义的输入。
  例如

$ git prune --no-expire
Segmentation falut
$ git prune --expire=npw; echo $?
129

两者都来自 parse_opt_expiry_date_cb()

前者是因为功能没有准备好看 arg==NULL (对于“--no-expire“,这是一种常态;”--expire“在结束时   命令行可以通过 NULL,如果它被告知   参数是可选的,但我们不这样做,我们不必担心   那个案子)。

后者是因为它不检查从返回的值    underlying parse_expiry_date()


0
2018-05-20 23:34