(解决,见问题正文的底部)
现在寻找这个,我现在拥有的是:
几乎相同的方法,但它们都将对象留在包文件中...坚持。
我尝试了什么:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc
包里还有文件,这就是我所知道的:
git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
而且:
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune
同样......
尝试git clone
技巧,它删除了一些文件(约3000个),但最大的文件仍在那里......
我在存储库中有一些大型遗留文件,大约200M,我真的不希望它们在那里......而且我不想将存储库重置为0 :(
解: 这是摆脱文件的最短路径:
refs/remotes/origin/master
行用于远程存储库,删除它,否则git不会删除这些文件git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
- 检查最大的文件git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98
- 检查这些文件是什么git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names'
- 从所有版本中删除文件rm -rf .git/refs/original/
- 删除git的备份git reflog expire --all --expire='0 days'
- 使所有松散的物品失效git fsck --full --unreachable
- 检查是否有任何松动的物品git repack -A -d
- 重新包装git prune
- 最终删除这些对象答案 0 :(得分:64)
我无法确定无法访问您的存储库数据,但我相信在运行git filter-branch
之前,可能还有一个或多个打包的引用仍引用旧提交。这可以解释为什么git fsck --full --unreachable
不会将大blob称为无法访问的对象,即使你已经使你的reflog过期并删除了原始(未压缩的)refs。
以下是我要做的事情(git filter-branch
和git gc
完成后):
1)确保原始引用消失:
rm -rf .git/refs/original
2)使所有reflog条目失效:
git reflog expire --all --expire='0 days'
3)检查旧的打包参考
这可能很棘手,具体取决于您拥有多少个打包的裁判。我不知道任何自动执行此操作的Git命令,因此我认为您必须手动执行此操作。备份.git/packed-refs
。现在编辑.git/packed-refs
。检查旧引用(特别是,查看它是否包含来自.git/refs/original
的任何引用)。如果您发现任何旧版本不需要,请删除它们(删除该参考的行)。
清理完packed-refs
文件后,查看git fsck
是否注意到无法访问的对象:
git fsck --full --unreachable
如果有效,并且git fsck
现在报告您的大blob无法访问,则可以继续执行下一步。
4)重新包装您的打包存档
git repack -A -d
这将确保解压缩无法访问的对象并保持解压缩。
5)修剪松散(无法到达)的对象
git prune
那应该这样做。 Git真的应该有更好的方法来管理打包引用。也许有一种我不了解的更好的方式。如果没有更好的方法,手动编辑packed-refs
文件可能是唯一的方法。
答案 1 :(得分:14)
我建议使用BFG Repo-Cleaner,这是git-filter-branch
的一种更简单,更快的替代方案,专门用于重写Git历史记录中的文件。它让你的生活更轻松的一种方式是它实际上默认处理所有引用(所有标签,分支,refs / remotes / origin / master之类的东西等),但它也是{{3更快。
您应该在这里仔细按照以下步骤操作:10-50x - 但核心位是这样的:下载http://rtyley.github.com/bfg-repo-cleaner/#usage(需要Java 6或更高版本)并运行此命令:
$ java -jar bfg.jar --delete-files file_name my-repo.git
任何名为file_name
的文件(不在最新提交中)都将从存储库的历史记录中完全删除。然后,您可以使用git gc
清除死数据:
$ git gc --prune=now --aggressive
BFG的使用通常比git-filter-branch
简单得多 - 这些选项围绕这两种常见用例进行了定制:
完全披露:我是BFG Repo-Cleaner的作者。
答案 2 :(得分:6)
我发现这对于删除整个文件夹非常有帮助,因为上面的内容对我没有帮助:https://help.github.com/articles/remove-sensitive-data。
我用过:
git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
答案 3 :(得分:5)
我试图摆脱历史上的一个大文件,而上述答案在某种程度上有效。关键是:如果你有标签,它们就不起作用。如果可以从标记访问包含大文件的提交,那么您需要调整filter-branches命令:
git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
答案 4 :(得分:2)
请参阅:How do I remove sensitive files from git’s history
如果文件在转速中不存在,则上述操作将失败。在这种情况下,' - ignore-unmatch'开关将修复它:
git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD
然后,将所有松散的物品从废物箱中取出:
git gc --prune='0 days ago'
答案 5 :(得分:1)
git gc
之后,由于does not remove all loose objects,您有多种原因可以获得仍然很大的git仓库大小。
我在“reduce the git repository size”
中详述了这些原因但是,在你的情况下测试的一个技巧是clone your "cleaned" Git repo并查看克隆是否具有合适的大小。
(''clean“repo'是您应用filter-branch
,然后gc
和prune
)
答案 6 :(得分:1)
这应该由Git Extras中的git obliterate
命令(https://github.com/visionmedia/git-extras)涵盖。
git obliterate <filename>
答案 7 :(得分:0)
我遇到了同样的问题,我在github上发现了一个很棒的tutorial,它逐步解释了你如何摆脱意外提交的文件。
以下是Cupcake建议的程序的一点概述。
如果您要从历史记录中删除名为file_to_remove
的文件:
cd path_to_parent_dir
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch file_to_remove' \
--prune-empty --tag-name-filter cat -- --all