git, filter-branch on all branches

GitGit Filter-BranchGit Rewrite-History

Git Problem Overview


I'm using the following sources to expunge some large files and directories from my repository:

http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/

https://stackoverflow.com/questions/1029969/why-is-my-git-repository-so-big/1036595#1036595

git filter-branch only seems to work on the current branch - is there a way to apply it to all branches at once?

Git Solutions


Solution 1 - Git

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 - Git

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 - Git

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEoghanMView Question on Stackoverflow
Solution 1 - GitBen LeeView Answer on Stackoverflow
Solution 2 - GitRoberto TyleyView Answer on Stackoverflow
Solution 3 - GitPaul PreibischView Answer on Stackoverflow