We've all been there when we've pushed something we shouldn't have. It's a horrible situation, and one that's difficult to fix solely on the Git side when it comes to sensitive data.
But at least we can delete those files and fix the situation on the Git side.
Why isn't it that simple?
Even if you delete the file in a new commit, it still lives on in your Git history forever. Unfortunately, to completely purge a file from every commit, branch, and tag, you need to rewrite your repository's history.
Instead of using old problematic tools like git filter-branch, I—and the Git project itself—recommend you to use git-filter-repo.
git-filter-repo is a CLI tool that can rewrite Git repository history. For example, it can remove sensitive files, large binaries, or specific directories from every past commit, tag, and branch. It's safer by design, since it prevents accidental data loss by requiring a fresh clone.
Let's see how we can use it
1. Install git filter-repo
While older tutorials might suggest git filter-branch, it is now considered legacy and unsafe. The official recommendation is git filter-repo.
- macOS (Homebrew):
brew install git-filter-repo - Python (Pip):
pip install git-filter-repo - Linux (apt):
sudo apt install git-filter-repo
2. Back up your repository
Rewriting history is destructive and permanent. Before touching anything, make a backup clone of your repository in another folder:
git clone <your-repo-url> my-repo-backup
3. Purge the file(s)
Navigate to your active repository and run git filter-repo, specifying the path to the file or directory you want to delete:
git filter-repo --path PATH/TO/YOUR/FILE --invert-paths
You can delete multiple files by repeating the --path flag:
git filter-repo --path file1.txt --path folder/file2.json --invert-paths
4. Re-link your remote
Running git filter-repo strips remote configuration for safety reasons. Check your remotes:
git remote -v
If no remote appears, add your repository URL back:
git remote add origin <your-repository-url>
5. Force push to remote
Because you have rewritten the commit timeline, your local and remote branches will differ. You must force push the cleaned history:
git push origin --force --all
git push origin --force --tags
What you should care about
Rewriting Git history is one of the most powerful—and potentially dangerous—operations you can perform in version control.
Before running these commands, keep the following risks in mind.
Exposed secrets are still compromised
Deleting a password or API key from Git does not make it secure again.
So... Crawlers and bots index public repositories in real-time. If a secret was pushed, assume it was scraped immediately.
What to do
Always revoke, rotate, or invalidate any leaked credentials immediately. Never rely solely on deleting the commit history to protect compromised keys.
Disruption for collaborators
Force-pushing rewritten history breaks the repository state for anyone else working on the project.
So... If collaborators pull from the updated remote, they will encounter merge conflicts and might accidentally re-commit the deleted files from their local history.
What to do
Warn your team before rewriting history. Once finished, instruct every collaborator to delete their local copies and re-clone the repository fresh.
Broken Pull Requests and commit SHA hash changes
Git identifies commits by their SHA-1/SHA-256 hashes. Changing history alters these hashes for every commit following the modification.
So... Open Pull Requests, references in commit messages, and links to specific commits in issue trackers or documentation will become broken or point to non-existent objects.
Cached data on hosting platforms
Platforms like GitHub, GitLab, and Bitbucket often cache commits, Pull Requests, and forks.
So... Even after force pushing, the deleted file may still be visible via direct commit URLs, PR histories, or fork networks.
What to do
For high-security leaks on GitHub or GitLab, contact support after force-pushing to request a manual purge of cached reflogs and orphan commits from their servers.
I really hope to have helped with your troubles.
As said, this won't fix every problem, but at least a part of them should be settled.
See you!