git, filter-branch on all branches
Solution 1:
The solution is simple:
git filter-branch [options] -- --all
Note the four dashes (two sets of double dashes with a space in between) in -- --all
.
If you look at the docs for git-filter-branch
, it says this:
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>…]
Reading on, the beginning of the docs say: "Lets you rewrite git revision history by rewriting the branches mentioned in the <rev-list options>, applying custom filters on each revision."
So checking the docs for rev-list
gives:
< rev-list options >… Arguments for git rev-list. All positive refs included by these options are rewritten. You may also specify options such as --all, but you must use -- to separate them from the git filter-branch options.
And the docs for git-rev-list
say:
--all
Pretend as if all the refs in refs/ are listed on the command line as <commit>.
Solution 2:
As @ben-lee's answer explains, --all
is required for rewriting all branches. If you have tags in your repo, you'll want to clean all those, as well as the branches, in order get the benefits of reduction in size, and that will require an additional --tag-name-filter cat
incantation.
Although the question specifies using git filter-branch
, the questioner wants to 'expunge some large files and directories from my repository', so it's worth mentioning that the best tool for doing that is actually The BFG Repo Cleaner, a simpler, faster alternative to git filter-branch
. For instance:
$ bfg --strip-blobs-bigger-than 10M
...removes all blobs bigger than 10MB (that aren't in your latest commit), and works on all branches & tags in your repo.
Full disclosure: I'm the author of the BFG Repo-Cleaner.
Solution 3:
I followed all the instructions for doing this on my Windows box, but I kept getting an error, until I stopped using single quotes and used double quotes instead.
My motivation was that I accidentally checked in my vagrant
environment. Here's the command to remove the vagrant
folder from all branches:
git filter-branch --tree-filter "rm -rf vagrant" -f HEAD --all
Just replace vagrant
with your directory name, and it'll remove this directory from all branches.