It happens: .env, an API key, a database password ends up in a commit. The fix is the same every time, and the order matters.
1. Rotate the secret first#
Deleting the file from git does nothing while the key still works. Assume anything committed is public, even in a private repo: clones, forks and CI caches all copy it. Revoke or rotate the credential at the provider before touching the repository.
2. Scrub the history#
Once the old key is dead, remove it from history so the repo stops carrying it. git filter-repo is the tool that works:
pip install git-filter-repo
git filter-repo --path .env --invert-paths
This rewrites every commit, so force-push and have the team re-clone. A commit hash they still hold can resurrect the file.
3. Stop it happening again#
.gitignorethe file and commit a.env.examplewith the keys but no values.- Laravel reads real values from the environment, so nothing secret needs to be in the repo at all.
- Turn on your host’s push protection or run a pre-commit scan so a key gets caught before it lands.
The short version#
A scrubbed repo with a live key is still a breach. A rotated key with an ugly history is just housekeeping. Rotate first.
Share this post
Keep reading
A First CI Pipeline for a Laravel Project
Install, lint, test, build - four jobs that run on every pull request and turn 'works on my machine' into a check everyone can see.
A Staging Environment Worth Having
Staging only catches what it shares with production. Same deploy path, same services, sanitized data - and a clear rule for what it is for.
Branch Naming Conventions That Scale Past Three People
Branch names are a user interface for your team's work. The conventions that survive growth, the ones that collapse, and why boring always wins.