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

在删除了数百兆字节的意外生成的垃圾之后,我的 Railsproject 目录中的 < strong > . git/Objects 仍然非常庞大。

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

我可以做些什么来清理这个目录?

74761 次浏览

Have you tried the git gc command?

  • If you added the files and then removed them, the blobs still exist but are dangling. git fsck will list unreachable blobs, and git prune will 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 fsck will not list any dangling commits or blobs, because your branch’s reflog is 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
    

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:

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.

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

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 ...

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

'git gc' did not remove those files.

Recursively:

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