AlgoMaster Logo

git filter branch

10 min readUpdated December 6, 2025
Listen to this chapter
Unlock Audio

Using git filter-branch can feel like a double-edged sword. On one hand, it offers powerful tools for rewriting history, but on the other, it can lead to confusion or even disaster if misused.

Understanding how it works, what it does behind the scenes, and when to use it will empower you to manipulate your Git repository with confidence.

What is git filter-branch?

git filter-branch is a command that allows you to rewrite the history of a Git repository by applying a filter to each commit. It can be used for various purposes, including:

  • Removing sensitive data from the commit history
  • Modifying commit messages
  • Splitting or merging branches
  • Changing authorship information

When you run git filter-branch, it operates on the repository's commit history and creates new commits with the specified changes. This means your original history remains intact, but it is effectively replaced by a new one in the process.

How it Works

At its core, git filter-branch takes each commit and applies a specified filter, producing new commits as necessary. The original commits are not deleted immediately; instead, they are retained as "dangling commits." This allows you to recover them if something goes wrong.

The command operates on the following Git objects:

  • Commits: The actual records of changes made in the repository.
  • Trees: The hierarchical structure of the contents of commits.
  • Blobs: The file contents stored in the repository.

When you run a filter, it rewrites these objects, creating new commit hashes and trees, while keeping the original objects as backups.

Basic Syntax

The basic syntax for git filter-branch is as follows:

  • options: Various flags that modify the behavior of the command.
  • filter: The filter you want to apply, such as a specified --tree-filter, --env-filter, or --index-filter.
  • commit_range: The range of commits you want to operate on (e.g., HEAD, master, or a..b).

Common Use Cases

Understanding practical scenarios where git filter-branch shines can help you grasp its potential.

Remove Sensitive Information

Imagine you accidentally committed an API key or password into your repository. To remove this information from your entire commit history, you could use the following command:

Here’s what each part does:

  • --force: Bypasses safety checks and allows rewriting.
  • --index-filter: Efficiently modifies the index without checking out files.
  • git rm --cached --ignore-unmatch: Removes the specified file from the index while keeping it in the working directory.
  • --prune-empty: Removes empty commits that might result from the filter.
  • --tag-name-filter cat: Updates tags to point to the new commits.
  • -- --all: Applies the filter to all branches.

This command effectively rewrites history, removing the sensitive file from all previous commits.

Modify Commit Messages

You might need to change commit messages for consistency or correction. Here’s how to prepend "WIP:" to every commit message:

The --msg-filter option allows you to modify commit messages. The sed command adds "WIP: " to the beginning of each message.

Change Author Information

Sometimes, you may need to change the author details for a series of commits. This can be done with:

This --env-filter allows you to change the author and committer information based on certain conditions.

Performance Considerations

While git filter-branch is powerful, it can be slow, especially on large repositories with many commits. The command creates new commits and updates references, which can take time.

Using --prune-empty

Whenever you use git filter-branch, consider the --prune-empty flag. It helps to clean up the history by removing any commits that become empty after applying the specified filter. This keeps the commit graph neat and manageable.

Backup Your Data

Before running git filter-branch, always create a backup of your repository. Use the following command to create a backup branch:

This way, you can easily recover your original history if something goes wrong.

Performance Boosting Techniques

To enhance performance during filtering:

  • Use --index-filter instead of --tree-filter. The former does not check out files, making it faster.
  • Be specific in your commit range. Instead of --all, use a more constrained range like master~10..master to limit the scope of filtering.

Troubleshooting Common Issues

Even seasoned developers can run into challenges with git filter-branch. Here are some common issues and how to resolve them.

Dangling Commits

After running git filter-branch, you may find that your original commits are still accessible. They become "dangling" and can be viewed with:

If you need to access them, you can find the commit hashes by using:

References Not Updated

Sometimes, references may not point to the newly created commits. You can run:

To check if your branches are pointing to the correct commits.

Cleaning Up

After a successful filter, clean up the repository by running:

This command runs garbage collection and removes the old dangling commits, freeing up space.

Alternatives to git filter-branch

While git filter-branch is a robust tool, it’s essential to know that there are alternatives, especially for specific use cases.

Using git filter-repo

Git has introduced git filter-repo, a more efficient and flexible tool for rewriting history. It is often recommended over git filter-branch due to its speed and ease of use. git filter-repo can perform many of the same operations but with a simpler syntax and better performance.

For example, to remove a file, you could use:

This command is much faster and safer, making it a better choice for most scenarios.

When to Stick with git filter-branch

There are some situations where git filter-branch might still be relevant, especially if you are working with older repositories that do not support git filter-repo. Understanding both tools gives you a broader toolkit for managing your Git history.

Now that you understand how to effectively use git filter-branch, you are ready to explore the newer and more efficient git filter-repo. In the next chapter, we will dive into its features and capabilities, providing you with an even more powerful way to manage your Git history.