我可以在git filter-branch期间使用我的存储库吗?

时间:2014-06-27 07:47:36

标签: git version-control git-filter-branch git-rewrite-history

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

我可以继续使用我的存储库,而这些命令正在运行吗?

2 个答案:

答案 0 :(得分:2)

在过滤器分支

期间,不要尝试在存储库中工作

通过将过滤器分支进程发送到shell会话的后台,或者打开另一个终端并继续使用您的回购方式,您可以可能在过滤器分支期间继续使用您的回购,但我强烈反对,如果你尝试过,你可能会在你的回购中造成很多问题。

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

解决方案1:使用index-filter

不要使用树形过滤器,正如您所见,它非常慢,因为它必须将每个提交签出到工作副本中。使用索引过滤器,而不是recommended in the filter-branch documentation,因为它不需要检查每个提交,因此它运行得更快:

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

您还可以通过传递一系列提交到HEAD的提交来加速filter-branch,而不是过滤所有提交。例如,以下内容将过滤最后20或21次提交:

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

文档

The options

--index-filter <command>
     

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

The example

  

--index-filtergit rm一起使用会产生明显更快的版本。与使用rm filename一样,如果提交树中没有该文件,git rm --cached filename将失败。如果您想“完全忘记”某个文件,它在输入历史记录时无关紧要,因此我们还会添加--ignore-unmatch

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

解决方案2:使用BFG

或者您可以尝试使用BFG工具as VonC recommended

答案 1 :(得分:2)

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

你应该仔细遵循usage instructions,但核心部分就是这样:

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

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

BFG通常比运行git filter-branch至少10-50x快,并且通常更容易使用。如果您决定使用git filter-branch,您可能希望看到我之前写过的关于如何让它更快一点的回答:https://stackoverflow.com/a/16154016/438886

无论您使用git filter-branch还是BFG,在历史记录被重写时,您确实不应该在存储库上工作 - 但是,使用BFG,那段时间将只有几秒钟。

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