Skip to main content

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

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.1.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.1-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: git_scrub-0.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 92645bd10a5ff99338689bb6fcbc0da0b4d3555ce80e5dbc51ca5274deabf99b
MD5 098d12eff2d5679fe8fd5c5ec7b654d5
BLAKE2b-256 791944ccafedc582ef6777ca14373a7a7b11b3e86c59ab57c9248f836b263b55

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_scrub-0.1.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: git_scrub-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e24a408f14e9e03a794394bacbf4a355671381a97dedbdd63d3babec003bec31
MD5 87e9b0a4813a924971ac96d94665ad67
BLAKE2b-256 0d965f5dbd99dc6eeaec5158802f881734cd07cf098de60fe8349de0165ae920

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_scrub-0.1.1-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