This warning appears when running git filter-branch, indicating that the command is deprecated due to numerous safety and performance issues. Git recommends using git-filter-repo as a faster, safer alternative.
When you run `git filter-branch`, Git displays this warning because the command has been officially deprecated. The Git project has determined that git-filter-branch is "riddled with gotchas resulting in various ways to easily corrupt repos or end up with a mess worse than what you started with." The warning is not an error—your command will still run if you don't press Ctrl-C. However, Git is strongly advising you to use `git filter-repo` instead, which is a Python-based tool that was designed from the ground up to avoid filter-branch's problems. The issues with git-filter-branch are fundamental to its design and cannot be fixed in a backward-compatible way. It works by checking out every commit, running shell commands to transform the working copy, and then creating new commits. This approach is inherently slow (orders of magnitude slower than alternatives) and prone to subtle bugs based on your shell environment, OS, and special characters in filenames or author names.
The officially recommended replacement is git-filter-repo. Install it using your package manager or pip:
# Using pip (works on all platforms)
pip3 install git-filter-repo
# On macOS with Homebrew
brew install git-filter-repo
# On Ubuntu/Debian
sudo apt install git-filter-repo
# On Arch Linux
sudo pacman -S git-filter-repoVerify installation:
git filter-repo --versiongit-filter-repo requires a fresh clone as a safety measure. This prevents accidental corruption of your main working directory:
# Clone your repository fresh
git clone --mirror https://github.com/user/repo.git repo-filter
cd repo-filter
# Or if you have a local repo, create a fresh clone
git clone --no-local /path/to/original /path/to/fresh-clone
cd /path/to/fresh-cloneImportant: Never run history rewriting commands on your only copy of a repository.
Common conversions from filter-branch to filter-repo:
Remove a file from all history:
# Old (filter-branch)
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch path/to/file' \
--prune-empty -- --all
# New (filter-repo)
git filter-repo --invert-paths --path path/to/fileRemove a directory from all history:
# Old (filter-branch)
git filter-branch --force --index-filter \
'git rm -rf --cached --ignore-unmatch path/to/dir/' -- --all
# New (filter-repo)
git filter-repo --invert-paths --path path/to/dir/Change author email in all commits:
# New (filter-repo with mailmap)
echo "New Name <[email protected]> <[email protected]>" > .mailmap
git filter-repo --mailmap .mailmapFor the specific case of removing large files, BFG Repo-Cleaner is another excellent alternative:
# Download BFG (requires Java)
wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar
# Remove files larger than 100MB
java -jar bfg-1.14.0.jar --strip-blobs-bigger-than 100M repo.git
# Remove specific files by name
java -jar bfg-1.14.0.jar --delete-files "*.zip" repo.git
# Clean up and garbage collect
cd repo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressiveBFG is 10-720x faster than git-filter-branch and simpler for file removal tasks.
If you have a specific reason to continue using filter-branch (e.g., maintaining legacy scripts), you can suppress the warning:
# Set environment variable before running
export FILTER_BRANCH_SQUELCH_WARNING=1
git filter-branch ...
# Or inline with the command
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --tree-filter 'rm -f password.txt' HEADWarning: This doesn't fix any of filter-branch's problems—it just hides the warning. The command will still be slow and potentially unreliable.
After rewriting history with any tool, you need to force push and have collaborators sync:
# Push the rewritten history
git push origin --force --all
git push origin --force --tags
# Collaborators should re-clone or reset
git fetch origin
git reset --hard origin/mainImportant: Rewriting shared history affects everyone. Coordinate with your team before force pushing.
### Why filter-branch Has "a Glut of Gotchas"
The official Git documentation lists several fundamental problems with filter-branch:
1. Performance: It checks out every commit to disk, which is extremely slow for large repositories. A rewrite that takes hours with filter-branch might take minutes with filter-repo.
2. Cross-platform issues: Shell commands behave differently on BSD (macOS) vs GNU (Linux). A filter that works on your Mac might silently corrupt history on a colleague's Linux machine.
3. Encoding and special characters: Spaces in filenames, non-ASCII characters, unusual author names, and invalid timezones can all cause subtle, hard-to-detect corruption.
4. Error handling: Errors may not be visible, or may only appear after a long wait. You might not know your filter failed until the rewrite is complete.
5. Old/new history mixing: It's easy to accidentally merge old refs back into rewritten history, undoing your work and creating duplicate commits.
### Using filter-lamely as a Transition Tool
If you have many filter-branch scripts and need a quick performance boost without rewriting them, you can use filter-lamely—a compatibility shim that runs filter-branch syntax through filter-repo:
# Download filter-lamely from git-filter-repo repository
# Then replace 'git filter-branch' with 'filter-lamely' in your scriptsThis gives partial performance improvements but doesn't fix the safety issues.
### Removing Sensitive Data
If you're removing secrets, passwords, or API keys from history:
1. Rotate the credentials immediately—the secrets are already compromised if pushed publicly
2. Use git filter-repo --replace-text with a replacements file
3. Remember that GitHub/GitLab may cache old commits; contact support for full removal
4. Consider using tools like truffleHog or git-secrets to prevent future leaks
### Tags and Refs
git-filter-repo handles tags correctly by default. It rewrites tag objects to point to the new commits and updates the refs. filter-branch has documented bugs where multiple tags mapping to the same name are silently overwritten.
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git