git-filter-branch
Rewrite repository history
SYNOPSIS
git filter-branch [
PARAMETERS
--setup
Command to run once before filtering begins. Useful for setting up temporary directories or other prerequisites.
--subdirectory-filter
Extract only the history of a specific subdirectory from the repository.
--index-filter
Filter applied to the index after each checkout. Useful for adding, removing, or modifying files in the index.
--tree-filter
Filter applied to the checked-out tree after each checkout. Like index-filter, but operates on the working tree instead of the index.
--commit-filter
Filter applied to each commit message. Can be used to modify commit messages or skip commits entirely.
--msg-filter
A synonym for --commit-filter (modifies commit messages).
--parent-filter
Filter applied to the parent commits of each commit. Allows you to rewrite the parentage of commits, potentially creating new branches or removing commits.
--tag-name-filter
Filter applied to tag names. Can be used to rename or delete tags.
--prune-empty
Remove commits that become empty after filtering (e.g., because all files in a directory were removed).
--original
Create a backup of the original refs under the given namespace (default: refs/original).
--force
Override existing backup refs. Use with caution!
Options passed to git rev-list to select the commits to be filtered (e.g., branches, tags, commit ranges).
--
Limit the filtering to specific paths. Only commits that affect these paths will be processed.
DESCRIPTION
The git filter-branch command is a powerful, but potentially dangerous, tool for rewriting git history. It allows you to modify large portions of your project's history based on arbitrary filters. This includes rewriting commit messages, removing files, changing the directory structure, or even altering commit authorship.
Because it rewrites history, it should be used with extreme caution, and preferably only on local, non-shared branches. Using it on a shared branch can cause significant problems for collaborators, as their local repositories will diverge from the rewritten history. After using git filter-branch, you typically need to force-push the rewritten branch.
It's strongly recommended to back up your repository before using git filter-branch, as mistakes can be difficult to recover from. Consider using alternatives like git rebase or git commit --amend for simpler history modifications. Newer Git versions recommend using git-filter-repo instead for better performance and safety.
CAVEATS
Rewrites history; should be used with caution. Can cause problems for collaborators if used on shared branches. Back up your repository first. Consider git-filter-repo as a safer and faster alternative.
SAFETY CONSIDERATIONS
git filter-branch operates by creating new commits based on the filtered history. This means the original commits are still present in the repository (under the refs/original namespace, by default) unless explicitly garbage collected.
It is imperative to inform collaborators about the rewritten history and guide them on how to update their local repositories. Typically, this involves fetching the rewritten branch and resetting their local branch to match the new history using `git fetch && git reset --hard origin/
SCRIPTING FILTERS
The --index-filter, --tree-filter, --commit-filter, and --parent-filter options accept shell commands as arguments. These commands are executed for each commit being processed. It is vital that the shell command exits with code 0 to proceed with filtering. For complex operations consider scripting.
HISTORY
git filter-branch has been part of Git for a long time, offering powerful history rewriting capabilities. However, due to its complexity and potential for misuse, it's now considered somewhat legacy. The recommended alternative, git-filter-repo, is designed to be faster and safer, with a focus on large repositories and complex filtering scenarios. While still available, users are encouraged to explore git-filter-repo for new projects or complex history manipulations.