从Git中删除旧的二进制修订版本,减小Git仓库的大小。

6

目前我遇到了一个非常棘手的问题,需要一些帮助来解决它,但是不能将二进制文件移动到CDN/dropbox等地方。请注意,在评估此问题时,请勿删除图像/pdf等内容并将其放入dropbox或其他外部存储中。

所以当前的问题是,我有几百个存储库,每个存储库有几千个提交,通常每个存储库有3个分支。在我的一个测试存储库中,如果我对存储库运行 du -sh 命令,它的大小约为13GB。而工作目录的大小约为800MB。因此,为了缩小大小,我尝试了以下方法:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch path/to/largest/files.pdf" HEAD
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune
git gc --prune=now --aggressive
git repack -a -d --depth=250 --window=250

在进行了所有测试后,使用du -sh命令检查仓库目录的大小仍显示为13GB。因此,我的下一个想法是删除所有二进制文件历史记录(如jpg / pdf / png等),只保留二进制文件的最新版本。但是我不确定如何完成这个任务,例如,我可以执行以下操作:
for i in find -name "*.pdf"; do git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $i" HEAD done
然而,我不确定这是否是最佳方法,因为这可能需要很长时间来完成所有不同类型的资产。本次操作的主要目标是通过仅保留二进制文件的1个版本来减小大小,以使pack文件更小。之前已删除的历史二进制文件也可以被移除,我完全同意这一点,但也不确定如何以自动化的方式实现。如有帮助将不胜感激。

这些文件是否可能仍然被其他分支引用?你有多少个分支呢? - mvp
通常我们会保留3个分支,以尽可能减少分支数量,因为这正是问题所在。我们使用master分支进行主线开发,然后将master分支合并到测试分支中,以评估其稳定性。最后,测试分支被合并到生产分支中。 - Will H
唯一的例外是,如果有一个新功能需要跨越多个迭代周期添加,那么就会创建一个额外的功能分支。然而,该分支最终会合并回主分支,并且该分支随后会被删除。 - Will H
2个回答

2

既然你有3个分支,为什么不在第一个 git filter-branch 命令中指定所有分支?

git filter-branch --index-filter \
"git rm -rf --cached --ignore-unmatch path/to/largest/files.pdf" -- --all

接下来,为了删除对refs/original的引用,我建议使用以下命令:

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d

1

我用过这些命令,有一定的成功。

git filter-branch \
  --index-filter "git rm --cached --ignore-unmatch '$1'" \
  --prune-empty --tag-name-filter cat -- --all || exit

# Cleanup and reclaming space
rm -r .git/refs/original
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

参考


1
与我的测试一样,这个方法可以工作,但它也会完全清除文件。目标是仅删除先前版本的二进制文件,但保留最新版本并在最终仅完全删除已删除的文件。 - Will H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接