Git,对所有分支使用filter-branch

60
3个回答

85

解决方案很简单:

git filter-branch [选项] -- --all

注意-- --all中的四个破折号(两组双破折号之间有一个空格)。

如果查看git-filter-branch的文档,就会发现:

git filter-branch [--env-filter <command>] [--tree-filter <command>]
    [--index-filter <command>] [--parent-filter <command>]
    [--msg-filter <command>] [--commit-filter <command>]
    [--tag-name-filter <command>] [--subdirectory-filter <directory>]
    [--prune-empty]
    [--original <namespace>] [-d <directory>] [-f | --force]
    [--] [<rev-list options>…]

通读文档后,开头说:“通过重新编写中提到的分支,在每个修订版本上应用自定义过滤器,让您重写git修订历史记录。”

因此检查rev-list的文档会给出:

< rev-list options >……用于git rev-list的参数。由这些选项包括的所有正引用都将被重写。您也可以指定诸如--all之类的选项,但必须使用--将它们与git filter-branch选项分隔开。

git-rev-list的文档则说明:

--all
Pretend as if all the refs in refs/ are listed on the command line as <commit>.

11
需要翻译的内容:just to clarify, normally filter-branch is listed with HEAD at the end, -- --all replaces HEAD为了澄清,通常 filter-branch 命令会在最后跟上 HEAD 参数,而使用 -- --all 选项可以替代 HEAD 参数。 - EoghanM
我该如何在PowerShell(Windows)中使其工作?它一直出错并显示“filter-branch”的帮助消息。我已尝试按照Paul的答案更改为双引号,但我无法在那里转义双引号(请参见我的评论)。 - ADTC
2
我通过使用管道(在PowerShell函数中)解决了上述问题。基本上,使用以下命令:git rev-list --all | git filter-branch [options](末尾没有rev-list),而不是git filter-branch [options] -- --all - ADTC

8

正如@ben-lee的答案所解释的那样,--all是重写所有分支所必需的。如果您的存储库中有标签,您将想要清除所有标签和分支,以便获得尺寸减小的好处,这将需要一个额外的--tag-name-filter cat咒语。

虽然问题指定使用git filter-branch,但提问者想要“从我的存储库中删除一些大文件和目录”,因此值得一提的是,实际上最好的工具是The BFG Repo Cleaner,它是一个更简单、更快速的替代方案git filter-branch。例如:

$ bfg --strip-blobs-bigger-than 10M

这个工具可以移除所有大于10MB的blob(不包括最新提交中的),并且可以在您的仓库的所有分支和标签上运行。

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


1
没问题 @EoghanM - 你可能会觉得这个演示视频很有趣 - 这是 git filter-branch 和 The BFG(在树莓派上运行)之间的比赛... http://www.youtube.com/watch?v=Ir4IHzPhJuI - Roberto Tyley

6

我按照在Windows操作系统上的所有指示进行操作,但一直遇到错误,直到我停止使用单引号,改用双引号才成功。

我的动机是我不小心检入了我的 vagrant 环境。这里是从所有分支中删除 vagrant 文件夹的命令:

git filter-branch --tree-filter "rm -rf vagrant" -f HEAD --all

只需将vagrant替换为您的目录名称,它就会从所有分支中删除该目录。


遇到了这个问题。谢谢!另外,如果您的命令包含双引号(例如 ' rm -rf "vagrant" '),请使用两个双引号进行转义(例如 " rm -rf ""vagrant"" ")。 - ADTC
实际上那并不起作用。当然,这对于PowerShell是有效的,但是 git 简单地报错了。 - ADTC
Windows上有一个git bash是有原因的。使用它,迟早你会发现从cmd中使用git会遇到问题。 - GiM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接