> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Managing Sensitive Commits

> Guide for responding to accidentally committed secrets by revoking credentials, rewriting Git history, force pushing cleaned repository, requesting GitHub garbage collection, and enabling secret scanning to prevent leaks

When a developer accidentally pushes a password, private key, or API key to a public repo, every second matters. This guide provides a concise incident-runbook you can follow to revoke the credential, scrub Git history, and purge cached artifacts so the secret is removed as fully as possible.

Imagine discovering that you or one of your developers has committed a production database password or private key to your repository.

![A slide titled "One Accidental Commit" showing a developer icon on the left and a key/lock icon in the center with a callout listing "Private key" and "Production DB password." It illustrates accidentally committing sensitive secrets from a developer to a repository.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/accidental-commit-private-key-production-db.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=312be3332cae755dddebcc8105982c9e)

It’s a high-pressure situation. As a GitHub administrator (or incident responder), you need a repeatable, ordered runbook — what to do first, what to do next, and how to bring the repository back to a safe state.

![The slide titled "From Panic to a Plan" contrasts a "Pure Panic" scenario where a secret is exposed to the web with a resolved state labeled "GitHub Administrator." An arrow links the left box showing a leaked secret icon to the right box showing a user/GitHub administrator icon.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/panic-to-plan-secret-github-admin.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=a404a8a90a603831ce415a3f7c927fcd)

First principle — neutralize the credential immediately.

Do not try to rewrite history before revoking the exposed credential. Assume compromise and go straight to the provider (AWS, Azure, Stripe, etc.) to rotate or delete the key. This prevents further damage while you prepare a safe repository cleanup.

Revoke credentials at the source (rotate API keys, delete the secret, enforce new credentials) before attempting repository cleanup.

![A slide titled "Revoke the Credential First" showing a central green checkmark between a client icon and three source-provider cards (AWS, Azure, Stripe), each labeled "Revoked." Arrows indicate the revocation flow from the providers back to the client.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/revoke-credential-first-aws-azure-stripe.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=920bdb81d69a68552c18463fb753f184)

Why revocation first? Because simply deleting a file or committing a fix does not remove the secret from Git history. Git preserves past commits, so the secret may still be accessible from earlier revisions.

Example of an accidentally committed secrets file:

```text theme={null}
# config/secrets.env
AWS_ACCESS_KEY_ID=
AKIA3F9K2LQ7XZVB6NOW
```

Even if you remove this file in a later commit, the value is still present in earlier commits. To remove it entirely you must rewrite the repository history.

Tools that can perform history rewrites

* git-filter-repo — modern, maintained, and flexible ([git-filter-repo on GitHub](https://github.com/newren/git-filter-repo))
* BFG Repo-Cleaner — simpler wrapper for common tasks ([BFG Repo-Cleaner docs](https://rtyley.github.io/bfg-repo-cleaner/))

Both tools scan every commit, branch, and tag and can remove files or replace secrets across the entire history.

![A presentation slide titled "Rewrite the Story" showing two tools—git filter-repo and BFG Repo-Cleaner—and a simplified Git branch diagram (main, feature/checkout, release/v2.0). Several commits are marked with orange key icons and a vertical blue line indicating the history-rewrite point.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/rewrite-story-git-filter-repo-bfg.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=77e31b20b3c959e791ae1b788af4fa3f)

Practical examples

* git-filter-repo: remove a file from all commits

```bash theme={null}
# create a full mirrored clone to include all refs and tags
git clone --mirror https://github.com/your-org/your-repo.git
cd your-repo.git

# remove a specific path from all commits
git filter-repo --path config/secrets.env --invert-paths
```

* git-filter-repo: replace specific secret strings using a mapping file

Create `replacements.txt`:

```text theme={null}
# replacements.txt
AKIA3F9K2LQ7XZVB6NOW==>REMOVED_AWS_KEY
```

Run the replacement:

```bash theme={null}
git filter-repo --replace-text replacements.txt
```

* BFG Repo-Cleaner: delete a file from history

```bash theme={null}
git clone --mirror https://github.com/your-org/your-repo.git
bfg --delete-files config/secrets.env your-repo.git
cd your-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
```

Important operational notes:

* Always operate on a mirrored clone (`--mirror`) so you capture all refs, branches, and tags.
* Test the workflow on a disposable copy or run a dry run first. Mistakes in history rewriting are destructive.
* After rewriting history locally, you must push the rewrites to GitHub with force pushes.

History-rewriting and force-pushing are destructive: notify your team, coordinate a maintenance window, and ensure you have backups before you proceed.

![An illustration titled "Force GitHub to Accept It" comparing two panels: a green "Local — Rewritten" view with clean, rewritten branch timelines (main, feature/checkout, release/v2.0) and an orange "GitHub — Old History" view showing the original, differing commit histories with conflict markers.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/local-rewritten-vs-github-old-history.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=849ebda966ba4364b093716c8969e167)

Force-push the rewritten history to GitHub

```bash theme={null}
# push rewritten branches and tags back to origin
git push --force --all origin
git push --force --tags origin
```

Notify collaborators: after a forced history rewrite, local clones will diverge. Provide clear instructions for recovery. Two safe options:

* Re-clone (simplest and safest):

```bash theme={null}
git clone https://github.com/your-org/your-repo.git
```

* If a collaborator must preserve local work: create patches or branches, then reset to the new remote

```bash theme={null}
git fetch origin
git checkout -B my-work origin/main
# re-apply any local changes from a patch or branch
```

One commonly missed step: GitHub may retain cached references to the old commits in closed pull requests, activity logs, or internal caches. To try to eliminate these remnants, request GitHub to run repository garbage collection.

![A clean slide titled "Ask GitHub Support" showing buttons labeled "GitHub support" and "Run garbage collection." Below is a rounded purple header that reads "Lingering cached fragments" above an empty white content area.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/ask-github-support-lingering-fragments.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=5e58bcb20f253d9399031923eb6304cf)

When you contact GitHub Support, include:

* Repository name and URL
* Timestamp and clear description of the sensitive-data exposure
* Confirmation that you have force-pushed rewritten history
* A request that GitHub run garbage collection and purge cached fragments

Prevent future leaks

The most effective control is to stop secrets from entering your repo. Enable secret scanning and push protection so that pushes containing recognized secret patterns are blocked before they land on the server.

![A slide titled "Prevent It Entirely" showing a flow where a code push containing a password is intercepted by secret scanning and push protection, triggering "Upload blocked — password detected." The result shown is the repository stays clean.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/Governance-and-Roles/Managing-Sensitive-Commits/prevent-it-entirely-secret-scanning-blocked.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=9c7110ac1bd92884d5dc3555b4d9770d)

Resources

* GitHub Secret Scanning & Push Protection: [https://docs.github.com/en/code-security/secret-scanning/secret-scanning-and-push-protection/about-secret-scanning-and-push-protection](https://docs.github.com/en/code-security/secret-scanning/secret-scanning-and-push-protection/about-secret-scanning-and-push-protection)
* git-filter-repo: [https://github.com/newren/git-filter-repo](https://github.com/newren/git-filter-repo)
* BFG Repo-Cleaner: [https://rtyley.github.io/bfg-repo-cleaner/](https://rtyley.github.io/bfg-repo-cleaner/)
* GitHub Support: [https://support.github.com/](https://support.github.com/)

Quick reference — runbook summary

| Step | Action | Key commands / links |
| - | - | - |
| 1 | Revoke the credential at the source (rotate/delete) | Provider console (AWS/Azure/Stripe) |
| 2 | Rewrite repository history to remove secrets | `git clone --mirror …` + `git filter-repo` or `bfg` |
| 3 | Force-push rewritten branches & tags to GitHub | `git push --force --all origin` `git push --force --tags origin` |
| 4 | Ask GitHub Support to run garbage collection | `https://support.github.com/` |
| 5 | Ensure collaborators reset or re-clone and rotate remaining creds | `git clone https://github.com/your-org/your-repo.git` |

Following this ordered runbook — revoke first, rewrite history carefully on a mirrored clone, force-push, and follow up with GitHub Support and team coordination — minimizes exposure and restores a clean repository state.

> [card] [Watch Video](https://learn.kodekloud.com/user/courses/github-administration-certification/module/e4b7bd78-3fb5-4c1c-94d8-e528b0b60484/lesson/b94c8cf2-2924-45a1-a803-ea5d18649166)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.