关于“如何从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
恢复磁盘空间?
感谢。
答案 0 :(得分:15)
正如Andrew C所建议的那样,在git gc
能够回收松散的对象之前,需要使用reflog来取消引用对象。因此,通过意外添加大文件来恢复磁盘空间的正确方法是:
git reflog expire --expire=now --all
git gc --aggressive --prune=now
这将删除所有reflog,因此请谨慎使用。
答案 1 :(得分:0)
使用Git 2.18(2018年第二季度)可以帮助避免任何拼写错误的一个提示是避免gc prune
使用不存在的引用(此处称为:" nonsense
")
" git gc --prune=nonsense
"花费很长时间重新包装,然后在基础" git prune --expire=nonsense
"无法解析其命令行。
这已经得到纠正。
commit 96913c9见Junio C Hamano (gitster
)(2018年4月23日)
帮助:Linus Torvalds (torvalds
)。
(由Junio C Hamano -- gitster
--合并于commit 3915f9a,2018年5月8日)
parseopt
:更好地处理格式错误的--expire
解析
--expire=<time>
命令行选项的一些命令表现出来 当给出无意义的输入时,sillily 例如$ git prune --no-expire Segmentation falut $ git prune --expire=npw; echo $? 129
两者都来自
parse_opt_expiry_date_cb()
。前者是因为该功能未准备好
arg==NULL
(对于&#34;--no-expire
&#34;,它是一种规范;&#34;--expire
& #34;在结束时 命令行可以通过NULL
,如果它被告知 论证是可选的,但我们不必担心,所以我们不必担心 那个案子)。后者是因为它不检查从返回的值
underlying parse_expiry_date()
。