如何从git存储库中删除未使用的对象?

Jon*_* H. 81 git binary file object

我不小心添加,提交并推送了一个巨大的二进制文件,我最近提交了一个Git存储库.

如何让Git删除为该提交创建的对象,以便我的.git目录再次缩小到合理的大小?

编辑:谢谢你的回答; 我试过几个解决方案.没有用.例如,GitHub中的文件从历史记录中删除了文件,但.git目录大小没有减少:

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(
Run Code Online (Sandbox Code Playgroud)

Sam*_*ins 121

我在其他地方回答了这个问题,因为我为此感到自豪,所以我会在这里复制!

...而且没有进一步的麻烦,我可以向您呈现这个有用的脚本git-gc-all,保证删除所有git垃圾,直到它们可能出现额外的配置变量:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "$@"
Run Code Online (Sandbox Code Playgroud)

--aggressive选项可能会有所帮助.

注意:这将删除所有未引用的东西,所以如果您稍后决定要保留其中一些内容,请不要向我哭泣!

你可能还需要先运行这样的东西哦,亲爱的,git很复杂!

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n1 --no-run-if-empty git update-ref -d
Run Code Online (Sandbox Code Playgroud)

我把所有这些放在一个脚本中,这里:

http://sam.nipl.net/b/git-gc-all-ferocious

  • 优秀:D我通过克隆答案得到更多积分的邪恶计划已经奏效!! 1;) (16认同)
  • 102m至160k ..有效且具有破坏性 (4认同)
  • 非常感谢剧本!额外信息:由于无法识别的选项,`xargs`命令在OS X上产生错误.最简单的解决方案:通过自制软件"brew install findutils"安装GNU xargs,并用`gxargs`替换`xargs`. (3认同)
  • 如http://stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-repo/14728706#comment20614863_14728706,再次给你+1。 (2认同)

Jos*_*Lee 25

git reflog expire --all的不对.它会删除早于过期时间的reflog条目,默认为90天.使用git reflog expire --all --expire=now.

对类似问题的回答涉及从存储库中真正清除未使用对象的问题.


小智 17

1)从git repo(而不是文件系统)中删除文件:

  • git rm --cached path/to/file

2)使用以下方法收缩回购:

  • git gc,

  • 要么 git gc --aggressive

  • 要么 git prune

或者本问题中建议的上述组合:减少git存储库大小


Dae*_*yth 10

有关删除敏感数据的指南可以使用相同的方法.您将重写历史记录以从其存在的每个修订版中删除该文件.这是破坏性的并且将导致与任何其他签出的回购冲突,因此首先警告任何协作者.

如果你想让repo中的二进制文件可供其他人使用,那么就没有真正的方法来做你想做的事了.几乎全部或全部都没有.


And*_*ski 7

我的关键是运行git repack -A -d -f然后git gc减少我拥有的单个git包的大小.


小智 6

海兰!

Git只接收克隆存储库时实际需要的对象(如果我理解正确的话)

因此,您可以修改上次提交删除错误添加的文件,然后将更改推送到远程存储库(使用-f选项覆盖服务器上的旧提交)

然后,当您对该repo进行新的克隆时,它的.git目录应该与提交的大文件之前一样小.

(可选)如果要从服务器中删除不必要的文件,可以删除服务器上的存储库并推送新克隆的副本(具有完整历史记录)


Mar*_*tin 5

git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all
Run Code Online (Sandbox Code Playgroud)

请记住更改Filename要从存储库中删除的那个。


Cza*_*zak 5

请参阅Pro Git书中的“删除对象”:

http://git-scm.com/book/zh-CN/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects

更新:另请参见BFG回购清洁器:http : //rtyley.github.io/bfg-repo-cleaner/