如何清理我的 .git 文件夹?清理了我的项目目录,但 .git 仍然很大

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5277467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:20:20  来源:igfitidea点击:

How can I clean my .git folder? Cleaned up my project directory, but .git is still massive

git

提问by light24bulbs

The .git/objectsin my rails project directory is still massive, after deleting hundreds of Megabytes of accidentally generated garbage.

在删除了数百兆字节的意外生成的垃圾后,我的 rails 项目目录中的.git/objects仍然很大。

I have tried git add -A, as well as other commands to update the index and remove nonexistent files. I gather, perhaps incorrectly, that the files with two character names in the directory are blobs. I have tried rolling back to previous commits, but no luck.

我已经尝试过git add -A,以及其他命令来更新索引和删除不存在的文件。我认为目录中具有两个字符名称的文件是 blob,这可能是错误的。我试过回滚到以前的提交,但没有运气。

What can I do to clean this directory?

我该怎么做才能清理这个目录?

回答by Josh Lee

  • If you added the files and then removed them, the blobs still exist but are dangling. git fsckwill list unreachable blobs, and git prunewill delete them.

  • If you added the files, committed them, and then rolled back with git reset --hard HEAD^, they're stuck a little deeper. git fsckwill not list any dangling commits or blobs, because your branch's reflogis holding onto them. Here's one way to ensure that only objects which are in your history proper will remain:

    git reflog expire --expire=now --all
    git repack -ad  # Remove dangling objects from packfiles
    git prune       # Remove dangling loose objects
    
  • Another way is also to clone the repository, as that will only carry the objects which are reachable. However, if the dangling objects got packed (and if you performed many operations, git may well have packed automatically), then a local clone will carry the entire packfile:

    git clone foo bar                 # bad
    git clone --no-hardlinks foo bar  # also bad
    

    You must specify a protocol to force git to compute a new pack:

    git clone file://foo bar  # good
    
  • 如果添加文件然后删除它们,则 blob 仍然存在但悬空。git fsck将列出无法访问的 blob,git prune并将删除它们。

  • 如果您添加文件,提交它们,然后使用 回滚git reset --hard HEAD^,它们会卡得更深一些。git fsck不会列出任何悬而未决的提交或 blob,因为您的分支的reflog正在保留它们。这是确保仅保留历史记录中的对象的一种方法:

    git reflog expire --expire=now --all
    git repack -ad  # Remove dangling objects from packfiles
    git prune       # Remove dangling loose objects
    
  • 另一种方法也是克隆存储库,因为它只会携带可访问的对象。但是,如果悬空对象被打包(并且如果您执行了许多操作,git 很可能会自动打包),那么本地克隆将携带整个打包文件:

    git clone foo bar                 # bad
    git clone --no-hardlinks foo bar  # also bad
    

    你必须指定一个协议来强制 git 计算一个新的包:

    git clone file://foo bar  # good
    

回答by ryanprayogo

Have you tried the git gccommand?

你试过git gc命令吗?

回答by cat

Sparkleshare created 13GB of tmp_pack_ files in my git after failing to pull many times a huge images checkin. The only thing that helped was ...

Sparkleshare 在多次拉取大量图像签入失败后,在我的 git 中创建了 13GB 的 tmp_pack_ 文件。唯一有帮助的是......

rm -f .git/objects/*/tmp_*

'git gc' did not remove those files.

'git gc' 没有删除这些文件。

回答by sehe

If you still have a large repo after pruning and repacking (gc --aggressive --prune=tomorrow...) then you can simply go looking for the odd one out:

如果您在修剪和重新打包 ( gc --aggressive --prune=tomorrow...)后仍然有一个大的 repo,那么您可以简单地寻找奇怪的一个:

git rev-list --objects --all |
    while read sha1 fname
    do 
        echo -e "$(git cat-file -s $sha1)\t$\t$fname"
    done | sort -n

This will give you a sorted list of objects in ascending size. You could use git-filter-branch to remove the culprit from your repo.

这将为您提供按升序排列的对象的排序列表。您可以使用 git-filter-branch 从您的回购中删除罪魁祸首。

See "Removing Objects" in http://progit.org/book/ch9-7.htmlfor guidance

有关指导,请参阅http://progit.org/book/ch9-7.html 中的“删除对象”

回答by Marcelo Grebois

Recursively:

递归地:

find ./ -iname '*.!*' -size 0 -delete
for i in */.git; do ( echo $i; cd $i/..; git gc --aggressive --prune=now --force; ); done