Skip to main content

Scan GitHub orgs and user profiles for a committed email address and rewrite it out of history.

Reason this release was yanked:

Injection email security

Project description

git-scrub

PyPI version Python versions License: MIT

CLI tool to scan GitHub organizations and user profiles for a committed email address, then rewrite it out of history across every affected repo.


Why this exists

git filter-repo handles the local rewriting step well, but provides no tooling to:

  • Discover which repos across a GitHub org or user profile contain a given email
  • Clone, rewrite, and force-push each one automatically
  • Verify the result via the GitHub API after each push
  • Report a clean summary across dozens or hundreds of repos

git-scrub automates the entire workflow. Point it at an org or a username, give it the old and new email, and it handles the rest.

Common use case: you've left a job or graduated, and you want to scrub your old institutional email (you@university.edu) from every repo you've ever touched — replacing it with your personal GitHub no-reply address.


How it works

1. Discover   →  list every repo in the target org(s) / user profile(s)
2. Scan       →  check each repo's commit history for the old email
                 (both author and committer fields)
3. Report     →  show a table of dirty repos and commit counts
4. Rewrite    →  for each dirty repo: clone → git filter-repo → force-push
5. Verify     →  confirm via the GitHub API that the email is gone
6. Clean up   →  temp clone is deleted after each repo

Steps 4–6 only run with --fix. Everything up to step 3 is always safe.


Prerequisites

  • Python 3.9+
  • git-filter-repo
    brew install git-filter-repo
    # or
    pip install git-filter-repo
    
  • GitHub CLI (gh) authenticated or a GITHUB_TOKEN env var with repo scope

Installation

pipx install git-scrub   # recommended
# or
pip install git-scrub

Usage

Scan (dry-run, always safe)

# Scan a whole org
git-scrub --old-email old@work.edu --org my-org

# Scan all repos under a GitHub username (public + private)
git-scrub --old-email old@work.edu --user myusername

# Multiple targets at once
git-scrub --old-email old@work.edu --org org1 --org org2 --user myusername

# Target a single specific repo
git-scrub --old-email old@work.edu --repo owner/repo-name

# Scan a non-default branch
git-scrub --old-email old@work.edu --org my-org --branch develop

Rewrite and push (--fix)

git-scrub \
  --old-email old@work.edu \
  --new-email 123456+myusername@users.noreply.github.com \
  --org my-org \
  --fix

# Skip per-repo confirmation prompts
git-scrub ... --fix --yes

JSON output (for scripting / CI)

git-scrub --old-email old@work.edu --org my-org --json
{
  "scanned": 42,
  "dirty": [
    { "repo": "my-org/some-repo", "commits": 7 }
  ]
}

Token

# Via env var (useful in CI)
GITHUB_TOKEN=ghp_... git-scrub ...

# Via flag
git-scrub --token ghp_... ...

If neither is provided, git-scrub calls gh auth token automatically.


Options

Flag Description
--old-email Email to find (required)
--new-email Replacement email (required with --fix)
--org GitHub org to scan. Repeatable.
--user GitHub username to scan all their repos. Repeatable.
--repo Specific owner/repo to target. Repeatable.
--branch Branch to scan (default: each repo's default branch)
--fix Rewrite history and force-push
--dry-run Explicit scan-only mode (already the default)
--yes / -y Skip per-repo confirmation prompts
--json Output results as JSON
--token GitHub token (or set GITHUB_TOKEN)
-V / --version Print version and exit

Notes

  • Dry-run is the default. Nothing is written without --fix.
  • Both author and committer email fields are checked and rewritten.
  • The scan checks each repo's default branch (or --branch). git filter-repo rewrites all branches and tags when fixing, so the full history is cleaned regardless.
  • Force-pushing rewrites history for all collaborators on a repo — coordinate with your team before running on shared repos.
  • GitHub's commit attribution UI may take a short time to update after a push.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

git_scrub-0.1.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

git_scrub-0.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file git_scrub-0.1.0.tar.gz.

File metadata

  • Download URL: git_scrub-0.1.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for git_scrub-0.1.0.tar.gz
Algorithm Hash digest
SHA256 576725a1321d8a6225b3943ab0875d92e36615ac7260fa86dae83f1e6a24e43d
MD5 69920a8ab969690529a9ca6dc049183b
BLAKE2b-256 7009c5565ab0186c7d84ecab07a851fa791a1e554c54a94658a5544e7c4d4cdd

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_scrub-0.1.0.tar.gz:

Publisher: publish.yml on tabato/git-scrub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file git_scrub-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: git_scrub-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for git_scrub-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4572ffa452c0c8f095332520267079bf6d0b7adf479acc78f235263c03e16664
MD5 e8012a1000d8a9a191cf49015a0e4ed6
BLAKE2b-256 705d4a99c68f957759afccbcd2f608d969154c018ccf08ce26d84baa89251ecc

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_scrub-0.1.0-py3-none-any.whl:

Publisher: publish.yml on tabato/git-scrub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page