git log - git stash- git rebase - git filter-repo

Why git log Still Shows Your Secrets: Git Commit History Never Forgets

Why git log Exposes Secrets Even After They’re “Deleted`

Deleting a line from a file and committing the change doesn’t actually remove the sensitive data from your repo. If that secret, an API key, credential, or token, was ever committed, it lives in your Git history. Anyone running git log -p, git show, or inspecting diffs from past commits can still retrieve it.

Even if you overwrite a file or replace the value, git log preserves the full lineage of every change. This is by design. Git’s entire model is based on immutable commit history and distributed copies. So unless you explicitly rewrite history, your secrets are still there. Here’s a practical case:

git commit -m "Added config with AWS_SECRET_KEY"
# Realize mistake
git rm config.json
git commit -m "Removed secret file"

⚠️ Educational example, do not run in production

Too late. The git log still shows that key in the initial commit.

Misconceptions Around git stash and git rebase

Many devs assume git stash helps hide or clean secrets. Not true. git stash only shelves working directory changes temporarily; it never touches commit history. If a secret was ever committed, stashing changes afterward does nothing to clean it.

What about git rebase? While it can rewrite history, it must be done precisely. Just running git rebase -i and reordering or squashing commits doesn’t remove secrets unless you explicitly edit or drop them. And if even one clone or fork exists with the original commits, your secret lives on.

Even worse, rebasing without force-pushing correctly or re-coordinating with collaborators can reintroduce the exposed credentials via merges.

git commit -m "Added config with AWS_SECRET_KEY"

⚠️ Educational example, do not use in real environments

git rebase -i HEAD~3

⚠️ Educational example, do not run on production repos

Edit the commit containing the secret, but forget to remove it. Your git log might look cleaner, but the sensitive content is still recoverable.

Real-World Risks from Forgotten Credentials in Git History

This isn’t theoretical. Attackers actively scan public and private repos for secrets hiding in commit histories. GitHub forks, mirror repos, and cached CI/CD pipelines can all harbor those forgotten tokens.

  • A leaked API key from an old git log led to thousands in cloud billing for one startup.
  • OAuth tokens committed, then “deleted”, were used to hijack user accounts.
  • Secrets buried deep in forks of open source projects triggered major security incidents.

These problems scale in CI/CD. Every job that clones a repo runs git log under the hood, and every build artifact can potentially include traces of exposed secrets.

Cleaning Up Sensitive Data with git filter-repo

If the damage is done, the most reliable tool to clean it is git filter-repo. Unlike git rebase, which rewrites individual commits, git filter-repo can rewrite the entire commit history based on file paths, patterns, or content.

Example: to scrub all occurrences of config.json that might contain secrets:

pip install git-filter-repo

# Backup your repo first
cp -r my-repo my-repo-backup

cd my-repo
git filter-repo --path config.json --invert-paths

⚠️ Educational example, verify in a test repo before using in production

Or to remove all commits that include a specific string (e.g., AWS_SECRET_ACCESS_KEY):

git filter-repo --replace-text <(echo 'AWS_SECRET_ACCESS_KEY==REDACTED')

⚠️ Educational example, verify in a test repo before using in production

Be cautious: This will rewrite commit hashes. You’ll need to force-push and inform all collaborators. Any automation or deployment keys tied to commit hashes will break.

Also, tools like BFG Repo-Cleaner offer similar capabilities but are less flexible and are now considered outdated for complex cases.

Preventing Secret Leaks Before They Reach Git

Prevention beats cleanup. Here’s how to stop secrets from ever hitting git log:

1. Pre-commit Hooks

Use tools like pre-commit, gitleaks, or talisman to scan for secrets before commits:

# .pre-commit-config.yaml
- repo: https://github.com/zricethezav/gitleaks
rev: v8.15.0
hooks:
- id: gitleaks

2. CI/CD Pipeline Enforcement

Integrate secret detection into your CI jobs. Fail builds when secrets are found. Make this a policy.

3. Secrets Management

Never hardcode credentials. Use environment variables, vaults, or secret managers from day one.

4. Audit Dependencies

Don’t trust third-party packages blindly. Secrets can leak through npm, PyPI, or Docker layers.

Final Fix: Scrub Secrets with git filter-repo

Deleting secrets from code isn’t enough. git log keeps a full record unless you take deliberate action to rewrite history. Don’t rely on git stash or half-baked git rebase attempts. Use git filter-repo when you need a deep clean, and enforce policies and scanning before secrets reach your repository in the first place.

For proactive secret detection, consider using tools like Xygeni to secure your pipelines, enforce commit hygiene, and prevent costly leaks before they surface. Git never forgets, but you can make sure it never remembers your secrets in the first place.

sca-tools-software-composition-analysis-tools
Prioritize, remediate, and secure your software risks
7-day free trial
No credit card required

Secure your Software Development and Delivery

with Xygeni Product Suite