如何使用 BFG Repo-Cleaner

Soc*_*rro 3 java git github bfg-repo-cleaner

有人建议我使用 BFG Repo-Cleaner 作为我想要推送的本地存储库,其中包含的文件太大而无法推送到 GitHub。这些文件(大约 50MB 以上)我不介意它们是否被删除,而且我不久前不小心提交了它们。

关于在线说明: https: //rtyley.github.io/bfg-repo-cleaner/

它建议我应该使用 --mirror 标志克隆我的存储库的新副本(这似乎是在线版本,而不是本地版本)。然后执行 Java -jar bfg.jar ... 命令。然后将其cd回在线存储库的本地镜像副本,然后将信息推送回来。

我不太明白这如何适用于本地副本。对于太大而无法推送的本地副本,我应该这样做:

git clone --mirror /Users/me/myrepo

java -jar bfg.jar --strip-blobs-bigger-than 100M /Users/me/myrepomirror.git

然后我也不明白接下来的步骤如何:

cd /Users/me/myrepomirror.git git reflog expire --expire=now --all && git gc --prune=now --aggressive git Push

将解决与我的非镜像本地存储库有关的任何问题:

/用户/我/myrepo

我不确定他们是否暗示我应该在这之后做:

java -jar bfg.jar --strip-blobs-bigger-than 50M my-repo.git

我再次不知道这如何解决我想要修剪的实际存储库(不是镜像或在线版本),以便我可以推送它。

也许我有点迟钝?对于可能有用的东西,该文档似乎不是很明确/广泛。这里的任何帮助都会很棒。谢谢!

小智 5

我以前从未使用过 BFG。如果您遇到需要删除大文件的情况,这听起来很有用。不过,我会尽力解释我所理解的整个过程。

在我们开始之前,请注意 BFG 将重写远程存储库的历史记录,并且推送它将要求团队中的每个人重新克隆存储库并将其仅本地分支转移过来。

根据 git 的文档,git clone --mirror

设置源存储库的镜像。这意味着--裸露。与 --bare 相比,--mirror 不仅将源的本地分支映射到目标的本地分支,它还映射所有引用(包括远程跟踪分支、注释等)并设置 refspec 配置,以便所有这些引用被目标存储库中的 git 远程更新覆盖。

这意味着克隆将在您的计算机上创建远程存储库的精确副本。正如 BFG 文档所说,您应该创建此克隆的备份,以备以后需要。

java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
Run Code Online (Sandbox Code Playgroud)

将针对您创建的克隆git clone --mirror,并清除包含 > 100M 的文件的所有提交,除了最近的提交(如 BFG 文档中所述)。BFG不会自动删除旧数据。它会停止,让您确认一切看起来都不错,然后让您清理其余部分。

cd /Users/me/myrepomirror.git 
Run Code Online (Sandbox Code Playgroud)

将导航到裸存储库。您可能必须相应地更改路径。

git reflog expire --expire=now --all && git gc --prune=now --aggressive
Run Code Online (Sandbox Code Playgroud)

让我们将该命令分为两个逻辑部分:

  1. git reflog expire --expire=now --all
    • expire 子命令将删除旧的引用日志条目。reflog 是 HEAD 指向的 refs 的日志。--expire=now告诉 git 使当前时间之前的所有引用日志过期。
    • --all意味着跨越所有参考文献。如果没有 --all,过期只会发生在您当前所在的分支上,而不是所有分支上。
  2. git gc --prune=now --aggressive
    • git gc 处理 git 的垃圾收集。通常,它会在后台自行运行,但有时能够运行它很有用。
    • --prune=now告诉 git gc 删除当前时间之前的松散对象。
    • --aggressive将导致 git gc 花费更多时间清理存储库中不必要的文件并提供更大的优化。该git gc文档有一些额外的信息。

一旦完成所有这些,git push将用新清理的分支覆盖所有分支的远程版本。

您现在必须将存储库重新克隆到不同的目录中才能git clone获得非裸版本。

本质上,我们在此过程中所做的就是创建远程存储库的副本,删除有问题的文件并重写该过程中的提交历史记录,推送重写的远程并覆盖之前的内容,并克隆该存储库的新副本以便我们继续工作。

预防措施

我建议采取一些预防措施,以避免不断删除这些文件。BFG不应频繁运行,因为它会重写存储库的历史记录。

不幸的是,.gitignore 不支持忽略大于给定大小的文件。然而,无论如何,您可能有一些选择。

  1. 如果所有这些大文件都有特定的文件扩展名或位于特定目录中,只需将它们添加到 .gitignore 文件中即可防止 git 跟踪它们。
  2. 创建一个预提交挂钩,这将阻止添加超过一定大小的文件。似乎有一个脚本(我还没有测试过)来响应这个 SO post
    • 这是一个客户端 githook,这意味着它需要分发给团队中的其他开发人员。

  • 使用 BFG 的次数比我愿意提及的次数还要多 - 这正是如何做到这一点。 (2认同)