0

我将一些大的二进制文件签入到 git 存储库中。我注意到它变得非常缓慢。最多 4-5 秒响应git status .根目录中的一个。所以我决定用git filter-branch --tree-filter "rm -f web/libs/*.*jar" HEAD类似的命令清理存储库。但它们最多需要几个小时才能完成。

当这些命令正在运行时,我还能使用我的存储库吗?

4

2 回答 2

2

速度是你的问题,我写的BFG是为了更快。它几乎肯定会在不到半分钟的时间内完成,而不是几个小时。

您应该仔细按照使用说明进行操作,但核心部分是这样的:

$ java -jar bfg.jar --delete-files *.jar my-repo.git

这将删除存储库历史记录中当前未在最新提交中使用的所有 jar。

BFG 通常至少比running快10-50 倍git filter-branch,并且通常更易于使用。如果您决心使用git filter-branch,您可能希望看到我不久前写的关于如何让它更快一点的 SO 答案:https ://stackoverflow.com/a/16154016/438886

无论您使用git filter-branchBFG 还是 BFG,当历史被重写时,您真的不应该在存储库上工作 - 但是,对于 BFG,这段时间将只有几秒钟。

全面披露:我是 BFG Repo-Cleaner 的作者。

于 2014-06-27T10:22:25.433 回答
2

不要尝试在过滤器分支期间在您的存储库中工作

您可以通过将 filter-branch 进程发送到 shell 会话的后台来继续在 filter-branch 期间在您的 repo 中工作,或者打开另一个终端并以这种方式继续使用您的 repo,但我强烈建议您不要这样做,您可以如果您尝试过,会在您的回购中引起很多问题。

再说一次,Git 可能会在过滤器分支期间锁定某些文件(例如索引),因此如果您在过滤器分支期间尝试非过滤器分支操作,它可能会抛出一堆错误。

解决方案 1:使用 index-filter

不要为此使用树过滤器,正如您所见,它非常慢,因为它必须将每个提交检出到工作副本中。按照 filter-branch 文档中的建议,使用 index-filter 代替,因为它不需要检查每个提交,因此它运行得更快:

git filter-branch --index-filter '
  git rm --cached --ignore-unmatch web/libs/*.*jar
' HEAD

您还可以通过传递导致 HEAD 的一系列提交来加速过滤器分支,而不是过滤所有提交。例如,以下将过滤最后 20 或 21 个提交:

git filter-branch --index-filter '
  git rm --cached --ignore-unmatch web/libs/*.*jar
' HEAD~20..HEAD

文档

选项

--index-filter <command>

这是用于重写索引的过滤器。它类似于树过滤器,但不检查树,这使得它更快。经常与 一起使用git rm --cached --ignore-unmatch ...,请参见下面的示例。对于多毛的情况,请参阅git-update-index(1)

例子

使用--index-filterwithgit rm会产生一个明显更快的版本。与 using 一样,如果文件不在提交树中rm filename,则会失败。git rm --cached filename如果你想“完全忘记”一个文件,它何时进入历史并不重要,所以我们还添加--ignore-unmatch

git filter-branch --index-filter '
  git rm --cached --ignore-unmatch filename
' HEAD

解决方案 2:使用 BFG

或者您可以尝试使用 BFG 工具,如 VonC 推荐的那样。

于 2014-06-27T08:09:26.387 回答