我不小心添加,提交并推送了一个巨大的二进制文件,其中包含我对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 :-(
答案 0 :(得分:111)
我在其他地方回答了这个问题,因为我为此感到骄傲,所以会在这里复制!
...而且不用多说,我可以向您展示这个有用的脚本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 "$@"
--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
我把所有这些放在一个脚本中,在这里:
答案 1 :(得分:25)
您的git reflog expire --all
不正确。它会删除早于过期时间的reflog条目,默认为90天。使用git reflog expire --all --expire=now
。
My answer针对类似的问题处理了从存储库中真正清除未使用对象的问题。
答案 2 :(得分:16)
1)从git repo(&而不是文件系统)中删除文件:
git rm --cached path/to/file
2)使用以下方法收缩回购:
git gc
,
或git gc --aggressive
git prune
或此问题中建议的上述内容的组合:Reduce git repository size
答案 3 :(得分:10)
removing sensitive data上的本指南可以使用相同的方法。您将重写历史记录以从其存在的每个修订版中删除该文件。这是破坏性的,并且会导致与任何其他签出的回购冲突,因此首先警告任何协作者。
如果你想让repo中的二进制文件可供其他人使用,那么就没有真正的方法来做你想要的了。它几乎全部或全部没有。
答案 4 :(得分:7)
我的关键是运行git repack -A -d -f
然后git gc
以减少我拥有的单个git包的大小。
答案 5 :(得分:6)
HY!
Git只接收克隆存储库时实际需要的对象(如果我理解正确的话)
因此,您可以修改上次提交删除错误添加的文件,然后将更改推送到远程存储库(使用-f选项覆盖服务器上的旧提交)
然后,当您对该repo进行新的克隆时,它的.git目录应该与提交的大文件之前一样小。
或者,如果您想从服务器中删除不必要的文件,则可以删除服务器上的存储库并推送新克隆的副本(具有完整历史记录)
答案 6 :(得分:4)
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all
请记住更改要从存储库中删除的Filename
。
答案 7 :(得分:4)
请参阅Pro Git书中的“删除对象”:
http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects
更新:另请参阅BFG回购清洁工:http://rtyley.github.io/bfg-repo-cleaner/
答案 8 :(得分:0)
在2020年,git-filter-branch的文档不鼓励使用它,并建议使用诸如git-filter-repo之类的替代方法。也可以使用instead of BFG。
请注意,git书中Rewriting History上的章节尚未更新。 GitHub's recommendation都没有删除敏感数据。