【问题标题】:git: can't find blob - want to get rid of it from packgit:找不到 blob - 想从包中删除它
【发布时间】: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,却没有意识到它们一直都在索引中! (暂缓删除)

标签: git git-rewrite-history


【解决方案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 仍然存在!
        猜你喜欢
        • 1970-01-01
        • 2021-02-02
        • 1970-01-01
        • 1970-01-01
        • 2017-01-02
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        • 2015-11-30
        相关资源
        最近更新 更多