Docs / Git History Protection

Git History Protection

Deleting a secret from a file doesn't remove it from git history. Every commit that ever contained the secret is still accessible in every clone. This page covers how to find, remove, and prevent secrets in git history.

slickenv git scan

Search your entire git commit history across all branches for secrets. Uses all 53 patterns and reports the commit hash, age, and which secret was found.

$ slickenv git scan

→ Scanning 1,847 commits across all branches...

✗ STRIPE_SECRET_KEY   sk_live_...  found in 3 commits  (oldest: 8 months ago)
✗ AWS_SECRET_KEY      AKIA...      found in 1 commit   (14 months ago)

2 secret types exposed in git history

slickenv git audit

Display a detailed visual timeline of every commit that contains secrets, including the author, date, commit hash, and which patterns matched.

$ slickenv git audit

slickenv git clean

Guided BFG Repo-Cleaner wrapper that permanently rewrites git history to remove secrets. Walks you through all four steps:

  1. Backup — Creates a full archive of the repository before any changes
  2. BFG clean — Removes all matching secret patterns from every commit
  3. git gc — Cleans up the git object store to remove orphaned objects
  4. Force-push instructions — Provides the exact commands with a clear warning about coordinating with your team
$ slickenv git clean

Step 1/4: Creating backup at ./repo-backup.tar.gz    ✓
Step 2/4: Running BFG Repo-Cleaner...               ✓  3 secrets removed
Step 3/4: Running git gc...                          ✓
Step 4/4: Ready for force-push

  git push --force --all
  git push --force --tags

  ⚠ All collaborators must re-clone after force-push

Prerequisite: BFG Repo-Cleaner must be installed. Install it with brew install bfg on macOS or download from rtyley.github.io/bfg-repo-cleaner.

slickenv git protect

Install a pre-commit hook at .git/hooks/pre-commit that blocks any commit containing secrets. Runs automatically before every git commit — no action required after installation.

$ slickenv git protect

✓ Pre-commit hook installed at .git/hooks/pre-commit
→ Blocks 53 secret patterns on every commit

The hook is stored in .git/hooks/ which is local to each clone and not committed to the repository. Every team member needs to run this command once per clone.

FAQ

Do I need to rotate secrets after cleaning history?

Yes. Always rotate any secret that was exposed before cleaning. Cleaning history prevents future exposure from the repository, but the secret was already visible to anyone who had access. Assume it was compromised and generate a new one.

Does force-pushing break pull requests or branches?

Yes. Force-pushing rewrites history on the remote, which means all open pull requests will reference commits that no longer exist. Close and re-open PRs after the force-push, and ensure all team members re-clone rather than trying to rebase.

What if I can't do a force-push (protected branch)?

Temporarily disable branch protection rules, perform the force-push, then re-enable them. This typically requires admin access to the repository.