Skip to content

filter-branch Git Command Guide

The git filter-branch command is used to rewrite Git revision history by applying custom filters to each revision. It can modify trees, commit information, and branch structure. WARNING: This command is deprecated and not recommended. Use git filter-repo instead.

Terminal window
git filter-branch [--subdirectory-filter <directory>] [--env-filter <command>] [--tree-filter <command>] [--index-filter <command>] [--msg-filter <command>] [--commit-filter <command>] [--prune-empty] [-d <directory>] [-f | --force] [--] [<rev-list-options>...]
OptionDescription
—subdirectory-filter Extract subdirectory history
—env-filter Modify environment variables
—tree-filter Rewrite tree contents (slow)
—index-filter Rewrite index (faster than tree filter)
—parent-filter Rewrite parent relationships
—msg-filter Rewrite commit messages
—commit-filter Perform custom commit creation
—tag-name-filter Filter tag names
—prune-emptyRemove commits with no changes
-d Use custom temp directory
-f, —forceOverwrite existing refs
—original Store original refs in namespace
ParameterDescription
[]Git revision list options for target refs
Terminal window
git filter-branch --subdirectory-filter my-subdir HEAD

Rewrite history to contain only the my-subdir directory.

Terminal window
git filter-branch --tree-filter 'rm -f large-file.dat' HEAD

Remove large-file.dat from all trees (very slow operation).

Terminal window
git filter-branch --index-filter 'git rm --cached --ignore-unmatch big-file.zip' HEAD

Remove big-file.zip from index in all commits (faster than tree-filter).

Terminal window
git filter-branch --env-filter '
if [ "$GIT_AUTHOR_EMAIL" = "old@email.com" ]; then
GIT_AUTHOR_EMAIL=new@email.com
GIT_AUTHOR_NAME="New Name"
fi' HEAD

Change author email for all commits.

Terminal window
git filter-branch --prune-empty HEAD

Remove commits that become empty after filtering.

Terminal window
git filter-branch -d /tmp/git-filter --tree-filter 'rm large-files/*' HEAD

Use /tmp/git-filter for temporary files to improve performance.

How can I extract a subdirectory as a new project root?

Section titled “How can I extract a subdirectory as a new project root?”

To extract a subdirectory as a new project root, use —subdirectory-filter:

Terminal window
git filter-branch --subdirectory-filter <subdir> HEAD

How do I remove large files from Git history?

Section titled “How do I remove large files from Git history?”

To remove large files from Git history, use —tree-filter (slow) or —index-filter (faster):

Terminal window
git filter-branch --index-filter 'git rm --cached large-file.dat' HEAD

How can I change author information for all commits?

Section titled “How can I change author information for all commits?”

To change author information, use —env-filter:

Terminal window
git filter-branch --env-filter 'GIT_AUTHOR_EMAIL=new@email.com' HEAD

How do I remove empty commits after filtering?

Section titled “How do I remove empty commits after filtering?”

To remove empty commits, use —prune-empty:

Terminal window
git filter-branch --prune-empty HEAD

git filter-branch is deprecated because it is very slow, error-prone, and has many pitfalls. It should not be used in new scripts; use git filter-repo instead.

How can I speed up filter-branch operations?

Section titled “How can I speed up filter-branch operations?”

To speed up filter-branch operations, use -d to specify a temp directory on fast storage (like tmpfs) and prefer —index-filter over —tree-filter when possible.

How do I recover from a failed filter-branch?

Section titled “How do I recover from a failed filter-branch?”

If filter-branch fails or produces unexpected results, original refs are stored in refs/original/. You can restore them manually if needed.

Applications of the git filter-branch command

Section titled “Applications of the git filter-branch command”
  1. Extracting subdirectories as independent projects (use git filter-repo instead)
  2. Removing large files from repository history (use git filter-repo instead)
  3. Rewriting author information across all commits (use git filter-repo instead)
  4. Cleaning up repository history (use git filter-repo instead)
  5. Legacy script maintenance (migrate to git filter-repo)