当 repo 已经非常接近 2GB 时,如何从所有 bitbucket git 历史记录中删除二进制文件?

How to remove binary files from all of the bitbucket git history, when the repo is already very close to 2GB?

Bitbucket git 存储库的大小限制为 2GB,现在我有一个存储库(我们称它为 bigsize 存储库)已经非常接近该限制了,由于有很多二进制文件(扩展名为 dllmsm 的文件)。它非常接近限制,我害怕涉及二进制文件的提交操作会将大小倾斜到超过 2GB,因此提交将失败并且无法继续。

现在,如何最好地减少 bigsize 存储库的大小?

我正在考虑使用 LFS feature,但是,LFS 有 1GB 的限制 space,恐怕不足以使用这个 repo(如回购大小的大部分来自我想存储在 LFS 中的二进制文件。

所以我正在考虑从存储库和历史记录中删除所有二进制文件(我不介意从源代码管理中丢失它们,因为它们在我的本地驱动器上),如何最好地做到这一点,考虑到我的 bigsize 存储库的当前大小?

我的攻击方案:

  1. 确保对于 bigsize repo 上的所有分支(是的,我在这个巨大的 repo 上有不止一个分支),我已经删除了所有二进制文件(通过提交 specifies *.dll in gitignore and use git rm -rf -cached command) . This is needed because "By default the BFG doesn't modify the contents of your latest commit on your master (or 'HEAD') branch, even though it will clean all the commits before it."
  2. 然后使用 BFG delete-files command 到 "rewrite the history" 以便减少 repo 大小。

该方法是否适用于非常接近 2GB 的存储库?我担心在第 1 步,当我使用 git rm 时,它会添加到历史记录中并将回购大小推到超过 2GB,因此失败。

重要细节:

  1. 我是存储库的唯一作者
  2. 现在我有多个活动分支。纵观历史有多个分支合并到主分支
  3. 我不使用 repo 进行讨论或代码审查,甚至不使用标签。我只是把它作为一个分支使用,偶尔分支和合并

git filter-branch or BFG 已过时

使用Git 2.22 或更高版本,使用git filter-repo:

git filter-repo --path your/big/file --invert-path

或:

git filter-repo --strip-blobs-bigger-than 10M

以下是我使用 BFG repo cleaner 解决问题的方法。写下来希望对以后遇到和我一样情况的人有帮助

甚至在开始之前,请确保您的所有分支都是 "clear",即:您需要的所有更改都已推送到各自的分支中。让我们将巨大的存储库命名为 big 存储库,并假设它位于 D:\MyCompany\big

此外,您可能想在实际处理生产回购之前在玩具回购上尝试一下。

  1. 将您的 big 存储库克隆到一个全新的文件夹 (git clone --mirror git@bitbucket.org:YourUserName/big.git),确保这个新文件夹不在您原来的 big 回购文件夹。您需要非常确定这与 D:\MyCompany\big 完全不同(因此您可以放心地对其进行试验)。假设这个文件夹是D:\big_work,你克隆后就能找到D:\big_work\big.git文件夹。
  2. big.git文件夹备份到另一个地方,让我们把它放在D:\backup
  3. 确定您的二进制文件确实超出了 bitbucket(或您的 repo 提供商)提供的 LFS 限制。就我而言,我需要确定我的二进制文件大小小于 1GB。为此,请通过 BFG 将 big.git 的 git 转换为 LFS。在命令行:

    3.1。 cd D:\big_work

    3.2。 java -jar <path to>bfg-x.x.x.jar --convert-to-git-lfs "*.{dll, msm}" --no-blob-protection big.git(确保在 D:\big_work 文件夹中执行此操作)

  4. 现在检查D:\big_work\big.git\lfs文件夹的大小,是否超过1GB?如果否,您可以继续从步骤 4 here 继续将二进制文件转换为 lfs。剩下的不用看了

  5. 如果 lfs 文件夹超过 1GB,那么您必须从您的存储库中删除二进制文件并重写历史记录。
  6. D:big_work 中删除 big.git 文件夹,并从 D:\backup 中恢复它(您在第 2 步中所做的备份)。
  7. 最重要的一步来了:真正的删除。许多指南都谈到为什么在执行此步骤之前首先确保提交是 clean(意思是,在当前的 repo 状态下没有更多二进制文件)很重要。但我确实觉得这样的建议是不必要的,而且会分散注意力。因为我们已经非常清楚我们想要什么——也就是说,从我们的仓库中删除所有的二进制文件,现在的和过去的,从所有分支中,合并的或未合并的,仓库应该看起来像在任何时候都不会被二进制文件污染——我们应该忽略这个警告。为此,我们使用核武器 no-blob-protection

    7.1。 cd D:\big_work

    7.2。 java -jar <path to>bfg-x.x.x.jar --delete-files "*.{dll,msm}" --no-blob-protection big.git

  8. cd D:\big_work\big.git

  9. git reflog expire --expire=now --all && git gc --prune=now --aggressive
  10. git push
  11. 现在转到您的 bitbucket big 存储库,您应该会发现所有的 dll 和 msms 都已从所有分支和所有历史记录中删除。这应该让您确信您已经做了正确的事情:正在删除二进制文件并保存您的存储库!
  12. 请记住,您的原始 big 存储库位于 D:\MyCompany\big 并且您的 sourcetree 书签指向此文件夹,因此您需要先删除 sourcetree 书签, 并将 D:\MyCompany\big 重命名为 D:\MyCompany\big_old。不要删除 big_old 文件夹,因为即使您不希望二进制文件位于存储库中,但您仍然希望它们位于您的硬盘上,并且 big_old 文件夹提供了一个自然的备份。您可以在以后某个时候删除 big_old 文件夹,当您确定它确实没有任何价值后。
  13. 您需要再次 克隆干净的存储库到您的硬盘。让我们将其克隆回 D:\MyCompany\big 文件夹以避免任何重大更改。
  14. 将 sourcetree big repo 书签重新指向 D:\MyCompany\big 文件夹。
  15. 根据需要,不时将您需要的二进制文件从 big_old 逐渐转移到 big 文件夹。
  16. 您可能需要 contact bitbucket support for them to run agarbage collection operation to reduce the size

主要参考文献:

  1. BFG for a Noob
  2. Use BFG to migrate a repo to Git LFS
  3. BFG repo cleaner