Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git, filter-branch on all branches

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/

Why is my git repository so big?

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

like image 694
EoghanM Avatar asked Sep 15 '11 12:09

EoghanM


3 Answers

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>.
like image 111
Ben Lee Avatar answered Nov 19 '22 19:11

Ben Lee


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.

like image 35
Roberto Tyley Avatar answered Nov 19 '22 20:11

Roberto Tyley


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.

like image 5
Paul Preibisch Avatar answered Nov 19 '22 20:11

Paul Preibisch