从存储库历史中删除大型文件后,Git repo仍然庞大

从存储库历史中删除大型文件后,Git repo仍然庞大,git,git-rewrite-history,Git,Git Rewrite History,我有一个代码库(直到现在)使用git存储其依赖项。存储库本身(警告:太大了)。不用说,我需要从存储库历史中删除依赖项,以便将其缩减到合理的大小 我首先使用从历史记录中删除lib目录。然而,即使这样做了,存储库仍然超过3亿。发布git prune和git repack有帮助,但仍然超过1.8亿 为了找到任何肿胀的斑点,我发布了 git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head 根

我有一个代码库(直到现在)使用git存储其依赖项。存储库本身(警告:太大了)。不用说,我需要从存储库历史中删除依赖项,以便将其缩减到合理的大小

我首先使用从历史记录中删除
lib
目录。然而,即使这样做了,存储库仍然超过3亿。发布
git prune
git repack
有帮助,但仍然超过1.8亿

为了找到任何肿胀的斑点,我发布了

git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head
根据这些结果:

105526b5d3d398b9989d88c2f9fc2d1dc96a85b8 blob 35685609 33600527 31978828 d296935e6ac5f3f58b50c789394c9769116e9c34水滴35658016 33593241 112485744 50636F931180A32764EDAD854968A971A083F8A水滴2836029025897864233390 b9e4dd37428e879a258f297b7f5bcfb9ba869695水滴13108002 11640713 66661788 08d2720b2414aa07ce419b17d5f80c333c7313b7 blob 12551621 11124009 89231035 6197a478a461275a0396f20c28487e9ae619a5f9 blob 11975135 11058259 148211988 1 50636f931180a32764edadd854968a971a083f8a 549eb0c73776fd0ede27a2fcb03366f76f45a13c blob 9136086 8166649 166451273 5bc0a0f04a7004bc16cfab1c091c6b369fb74049 blob 9072616 8270262 80951514 741480238a6a6ce612cf089245dd46d6890fba9f blob 8858569 8080252 101294029 744226651C55B14C1A8AFFB78FBA4FDF02B577C blob 7412220 6766404 186825167

这就是我被困的地方。我可以
git显示这些blob,并看到它们看起来非常像jar文件,但我不明白为什么它们仍然在repo中

各种尝试都失败了


git-repack-a
git-repack-ad
git-repack-ad
似乎都没有效果。

你试过运行
git-gc

您需要在存储库中的每个分支上运行脚本,以确保从所有分支中删除引用

$ du -sh ./BIG
299M ./BIG
$ cd BIG
$ git checkout master
$ git-remove-history REMOVE_ME
....
$ git checkout branch2
$ git-remove-history REMOVE_ME
...
$ cd ../SMALL
$ git init
$ git remote add origin ../BIG
$ git fetch --all
$ git checkout master
$ cd ..
$ du -sh ./SMALL ./BIG
26M ./SMALL
244M ./BIG
然后,如在进一步讨论中所述,使用
git init
初始化一个新存储库,然后从原始存储库中
git pull
,或者
git remote add origin
,然后提取所有分支

$ du -sh ./BIG
299M ./BIG
$ cd BIG
$ git checkout master
$ git-remove-history REMOVE_ME
....
$ git checkout branch2
$ git-remove-history REMOVE_ME
...
$ cd ../SMALL
$ git init
$ git remote add origin ../BIG
$ git fetch --all
$ git checkout master
$ cd ..
$ du -sh ./SMALL ./BIG
26M ./SMALL
244M ./BIG
在git gc上使用
--prune=now
虽然您已经成功地从历史记录中写入了不需要的对象,但看起来这些不需要的对象没有被删除,因为它们太年轻,无法在默认情况下进行删除(有关更多详细信息,请参阅on
git gc
)。使用
git-gc--prune=now
应该可以处理这个问题,或者您可以查看更核心的选项

虽然这可以解决最后一个问题,但一个潜在的问题是,使用
git filter branch
,很难找到大的blob来删除它们,对此我要说:

…不要使用git筛选器分支
git-filter-branch
用于这样的任务很痛苦,有一个更好的、不太知名的工具叫做,专门为从git-repos中删除大文件而设计

删除大文件的核心命令如下所示:

$ bfg  --strip-blobs-bigger-than 10MB  my-repo.git
任何大小超过10MB的blob(不在您最近的提交中)都将从存储库的历史记录中完全删除—您不必自己手动查找文件,并且受保护的提交中的文件将被删除

然后可以使用
git gc
清除死数据:

$ git gc --prune=now --aggressive
BFG通常在大型回购上运行
git filter branch
,选项是围绕以下两种常见用例定制的:

  • 删除疯狂的大文件
  • 删除密码、凭据和其他私人数据

完全披露:我是BFG回购清理器的作者。

我意外地在git中存储了大量的
.jpa
备份-

git筛选器分支--删除空--索引筛选器'git rm-rf--cached--忽略取消匹配我的\u BIG\u目录\u或\u文件'--标记名筛选器cat--all

用有问题的文件夹重新设置MY_BIG_DIRECTORY_或_FILE
,以完全重写您的历史记录,包括标记

资料来源:


是的,
git-gc——侵略性——事实上是删减。这是大卫·安德希尔(David Underhill)脚本的一部分,我也在其他各种错误尝试之间分别运行了它。把你想要的分支机构从一个回购协议推到另一个干净的回购协议怎么样?这很有效,谢谢!我必须
git init
重新回购,然后
git拉入我想要的分支机构。我不知道你可以拉入一个非克隆。@Aaron:这可能意味着你的blob对于仍在重录中的提交是必需的,即使它们不在任何分支上。(默认情况下,Reflogs会持续90天。)Git会尝试确保它不会删除任何重要的内容。有关如何覆盖的信息,请参见
git reflog
git gc
手册页。是的,你总是可以进行空回购,因为“无历史记录”总是与任何有效的历史记录保持一致。
git ls tree-r——long HEAD | cut-d”“-f4-| sort-r
可能会对你有所帮助。将HEAD for替换为历史记录中的每个提交,并剪切最大的文件(可能会过滤掉lib/中的文件),这应该会给您一个线索。可能不相等,但至少相似,并且比
--prune=now
更正式(参见手册页)
--prune=all
(git 1.9.1)