git:找不到 blob - 想从包中删除它
Posted
技术标签:
【中文标题】git:找不到 blob - 想从包中删除它【英文标题】:git: can't find blob - want to get rid of it from pack 【发布时间】:2011-11-17 23:24:19 【问题描述】:我有一个大斑点,我想摆脱它!
我以为我使用此解决方案删除了文件:
http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/
(我使用 -- --all
而不是 HEAD
以便从所有分支中删除文件)
rm -rf .git/refs/original/ && git reflog expire --all &&
git gc --aggressive --prune
我通过Why is my git repository so big?查看了pack文件夹
$ git verify-pack -v .git/objects/pack/pack-*.idx | sort -k3n
... last 4 lines:
bc7ae9801052180b283cd81880753549f0f92587 blob 19464809 749446 305054873
acd5f09a35846bec25ebc324738139e5caabc50f blob 294278199 71381636 39607483
986d152935434b56cf182d8a32e24cb57af75ac3 blob 480385718 108184804 110989119
ba9d1d27ee64154146b37dfaf42ededecea847e1 blob 761172819 27430741 277589990
脚本git-find-blob
取自Which commit has this blob?
$ ./git-find-blob ba9d1d27ee64154146b37dfaf42ededecea847e1
但它什么也没找到。
任何想法如何从我的存储库中删除它?
【问题讨论】:
git status
的输出是否为空?有可能 blob 已添加到索引中,但从未提交。
如果您还包括git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
的输出以及没有--cache
的相同命令,这可能会很有用
感谢您对马克的持续关注;该 blob 在命令的两个变体中都列为“无法访问的 blob”。没有--cache
标志的变体中列出了 7 个(其他)额外无法访问的 blob。
ref 打包了吗?是否出现在git show-ref
?
@MarkLongair 谢谢!我想尽一切办法从我的存储库中清除 2GB 未引用的 blob,却没有意识到它们一直都在索引中! (暂缓删除)
【参考方案1】:
有同样的问题。发现我的麻烦 blob 被不可访问的树引用。添加到git-find-blob
脚本:
git fsck --full --unreachable | \
while read unreachable obj tree
do
if [[ ! $obj == "tree" ]]; then
continue
fi
if git ls-tree -r $tree | grep -q "$obj_name" ; then
echo "$unreachable $obj $tree"
fi
done
我能够使用 BFG Repo-Cleaner 删除 blob,但我会更乐意使用本机 git 命令解决问题。
【讨论】:
【参考方案2】:您想使用BFG Repo-Cleaner,它是git-filter-branch
的更快、更简单的替代方案,专为从 Git 存储库中删除大文件而设计。
下载the Java jar(需要Java 6或更高版本)并运行以下命令:
$ java -jar bfg.jar --strip-blobs-bigger-than 20M my-repo.git
任何大小超过 20M 的 blob(不在您的 最新 提交中)都将从您的存储库的历史记录中完全删除。然后您可以使用git gc
清除死数据:
$ git gc --prune=now --aggressive
BFG 通常比运行 git-filter-branch
快 10-50 倍,并且这些选项是围绕这两个常见用例量身定制的:
全面披露:我是 BFG Repo-Cleaner 的作者。
【讨论】:
【参考方案3】:您可以使用git repack -Ad
强制 git 重新构建您的包,并将任何无法访问的对象解包为松散的对象。此时您可以使用git gc --prune=now
丢弃无法访问的对象。
您还应该仔细检查您的 reflogs 确实已过期。我相信git reflog expire --all
将默认为 90 天(或者对于无法访问的对象为 30 天),因此您可能希望使用git reflog expire --expire-unreachable=now --all
代替(这需要在 repack+gc 之前完成)。
【讨论】:
谢谢,成功了! reflog 过期 unreachable=now 并且 gc --prune=now 在重新打包后就可以了。第一个清除了最后一个引用,第二个清除了对象本身。 太棒了!也为我工作。存储库从 80 MiB 变为 4.5 MiB。【参考方案4】:blob 不会出现在干净推送的另一侧,所以这将是我的解决方案(推送到新位置,然后从该位置克隆)。有更简单的方法吗?
【讨论】:
【参考方案5】:首先,在您的git gc
调用中,您应该使用--prune=now
,因为默认情况下会保留少于 2 周的对象。
其次,默认情况下您使用的git-find-blob
命令仅在HEAD
的历史记录中查找提交,因此如果 blob 在另一个分支上,则该脚本将错过它。尝试调用它:
./git-find-blob ba9d1d27ee64154146b37dfaf42ededecea847e1 --all
【讨论】:
我在git-find-blob
的 perl 和 bash 版本上都尝试了 --all
,但仍然没有骰子。我还在gc --aggressive
上尝试了--prune=now
,但blob 仍然存在!以上是关于git:找不到 blob - 想从包中删除它的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能从 VM 分离磁盘?它说这是因为它找不到存储。但是我已经删除了存储