如何从我的git回购中删除未引用的blob

我有一个GitHub仓库,它有两个分支 - master和release。

发行版分支包含二进制分发文件,这些文件有助于实现非常大的回购大小(> 250MB),所以我决定清理干净。

首先我通过git push origin :release删除远程发布分支

然后我删除了本地发布分支。 首先我尝试了git branch -d release ,但是git说:“错误:分支'release'不是你当前HEAD的祖先。” 这是真的,所以然后我做了git branch -D release强制它被删除。

但是我的存储库大小,无论是在本地还是在GitHub上,仍然很大。 然后我跑过了通常的git命令列表,比如git gc --prune=today --aggressive ,没有运气。

按照Charles Bailey在SO 1029969的指示,我能够获得最大斑点的SHA1列表。 然后,我使用SO 460331的脚本来查找斑点......并且最大的五个斑点不存在,尽管找到了更小的斑点,所以我知道该脚本正在工作。

我认为这些博客是发布分支的二进制文件,并且在删除该分支之后,它们不知何故被留下。 什么是摆脱他们的正确方法?


...并且不用再做了,我可以向你展示这个有用的脚本, 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 "$@"

你可能还需要先运行这些东西,哦,亲爱的,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

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

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

编辑:您可能还需要删除一些标签,谢谢Zitrax:

git tag | xargs git tag -d

如此处所述,只需使用

git reflog expire --expire-unreachable=now --all
git gc --prune=now

git reflog expire --expire-unreachable=now --all删除reflog中所有不可达提交的reflog

git gc --prune=now会自行删除提交。

注意 :只有使用git gc --prune=now才会起作用,因为这些提交仍然在reflog中引用。 因此,清除reflog是强制性的。


正如在这个回答中提到的, git gc实际上可以增加回购的大小!

另请参阅此主题

现在git有一个安全机制,在运行' git gc '时不会立即删除未引用的对象。
默认情况下,未引用的对象将保留2周。 这样可以让您轻松恢复意外删除的分支或提交,或者避免一个刚刚创建的对象在正在创建但尚未引用的对象可以被并行运行的“ git gc ”进程删除。

因此,为了将宽限期放在包装但未引用的对象中,重新包装过程会将未包含的对象从包装中拉出,形成松散的形式,以便它们能够老化并最终被修剪。
对象变得未被引用通常不是那么多。 拥有404855个未引用的对象相当多,并且首先通过克隆发送这些对象是愚蠢的,并且完全浪费了网络带宽。

无论如何...为了解决你的问题,你只需要运行带有--prune=now参数的' git gc '来禁用这个宽限期,并立即摆脱那些未被引用的对象(只有在没有其他git活动正在在工作站上应该容易确保的同时放置)。

顺便说git gc --aggressive ,在后面的git版本(或' git repack -a -f -d --window=250 --depth=250 ')中使用' git gc --aggressive '

同样的线索提到:

 git config pack.deltaCacheSize 1

这将delta缓存大小限制为一个字节(有效禁用它),而不是默认的0,这意味着无限制。 因此,我可以在具有4GB RAM的x86-64系统上使用上面的git repack命令并使用4个线程(这是一个四核)重新包装该存储库。 尽管如此,居民内存使用增长到接近3.3GB。

如果你的机器是SMP,并且你没有足够的RAM,那么你可以将线程数量减少到只有一个:

git config pack.threads 1

另外,你可以通过--window-memory argument进一步限制内存使用,以' git repack '。
例如,使用--window-memory=128M应该对增量搜索内存使用情况保持合理的上限,但如果回购包含大量大文件,则可能导致较少的最佳增量匹配。


在过滤器分支前面,您可以考虑(谨慎)此脚本

#!/bin/bash
set -o errexit

# Author: David Underhill
# Script to permanently delete files/folders from your git repository.  To use 
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2

if [ $# -eq 0 ]; then
    exit 0
fi

# make sure we're at the root of git repo
if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD

# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune
链接地址: http://www.djcxy.com/p/45175.html

上一篇: How to remove unreferenced blobs from my git repo

下一篇: Remove a directory permanently from git