Ship internal tools in hours, not weeks. Real auth, users, jobs, audit logs, and cohesive UI included. Early access $249 $499 → [Get it now]

How to rewrite Git history with git filter-repo

git filter-repo is the modern replacement for git filter-branch, rewriting repository history up to 50 times faster while providing a cleaner, safer interface with better defaults. As the creator of CoreUI with 25 years of open-source development experience, I switched all projects to git filter-repo the moment it became the officially recommended tool in Git documentation. It is not bundled with Git — install it separately — but its performance and safety features make it the clear choice for any history rewriting task. Always work on a fresh clone before running it, as the operation cannot be undone once complete.

Install git filter-repo and remove a specific file from all history.

# Install (macOS)
brew install git-filter-repo

# Install (pip)
pip install git-filter-repo

# Verify
git filter-repo --version
# Clone a fresh copy first (filter-repo refuses to run on repos with a remote unless forced)
git clone --no-local original-repo clean-repo
cd clean-repo

# Remove a specific file from entire history
git filter-repo --path secrets.env --invert-paths

--path secrets.env selects the file. --invert-paths inverts the selection — keep everything EXCEPT the specified path. The result is a repository where secrets.env never existed in any commit.

Remove a Directory from History

Delete an entire folder from every commit.

# Remove the dist/ directory from all commits
git filter-repo --path dist/ --invert-paths

# Remove multiple paths at once
git filter-repo \
  --path dist/ \
  --path node_modules/ \
  --path coverage/ \
  --invert-paths

Listing multiple --path options removes all of them in a single pass. This is much faster than running filter-branch separately for each path.

Remove Files by Pattern

Delete files matching a glob or regex.

# Remove all .env files
git filter-repo --path-glob '*.env' --invert-paths

# Remove all files matching a regex
git filter-repo --path-regex '.*\.(log|tmp|bak)$' --invert-paths

--path-glob uses shell glob syntax. --path-regex uses Python regex syntax. These are useful for removing all files of a certain type without listing each one individually.

Update Author Email Across History

Replace incorrect committer emails globally.

git filter-repo --email-callback '
  return email if email != b"[email protected]" else b"[email protected]"
'

The --email-callback receives and returns bytes. Python’s conditional expression a if condition else b makes the replacement concise. Similar callbacks exist for --name-callback, --message-callback, and --commit-callback for full control over every commit attribute.

Push the Rewritten History

Force-push all branches and tags after rewriting.

# Re-add the remote (filter-repo removes it by default)
git remote add origin https://github.com/user/repo.git

# Push all branches
git push origin --force --all

# Push all tags
git push origin --force --tags

git filter-repo removes all configured remotes as a safety measure to prevent accidental pushes. Re-add the remote explicitly and force-push after verifying the rewritten history looks correct with git log --oneline.

Best Practice Note

After pushing rewritten history, all collaborators must re-clone the repository — their local branches diverge from the rewritten history and cannot be cleanly merged. Coordinate with your team before running this operation. For the legacy approach when git filter-repo is not available, see how to rewrite Git history with filter-branch. For removing sensitive data specifically, GitHub and GitLab may also cache content in pull request diffs — contact their support to purge those caches after cleaning your history.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to loop inside React JSX
How to loop inside React JSX

How to Disable Right Click on a Website Using JavaScript
How to Disable Right Click on a Website Using JavaScript

How to validate an email address in JavaScript
How to validate an email address in JavaScript

8 Best Free Bootstrap Admin Templates for 2026 - Comparison & Reviews
8 Best Free Bootstrap Admin Templates for 2026 - Comparison & Reviews

Answers by CoreUI Core Team