Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

git-identity-rewriter

Why does this exist?

You know the feeling. You use one laptop for everything — work projects, personal side-projects, open-source contributions. You've got your josh@megacorp.com work email and your cooldev42@gmail.com personal email, and Git doesn't care which one you meant to use. It just grabs whatever's in your global config and stamps it on every commit.

Then one day you look at your commit history and realize:

  • Your personal email is plastered across 3 months of commits on your company's private repo
  • Your work email is the author on half the commits in your personal open-source project
  • That weekend hackathon project? Yeah, that's got your corporate identity all over it

Manually fixing this is a nightmare. You'd need to run git filter-repo or git filter-branch in every single repo, write mailmap files, snapshot and restore remotes (because filter-repo deletes them), hope you didn't mess anything up, and then force-push everything. For each repo. No thanks.

git-identity-rewriter does all of that for you. Point it at a directory, tell it the wrong identity and the right one, and it'll find every affected repo, back everything up, rewrite the history, restore your remotes, and optionally force-push — all in one interactive session.

What does it actually do?

  1. Scans a directory (recursively) for Git repos that have commits with the wrong name/email
  2. Lets you pick which repos to fix via an interactive checkbox UI
  3. Backs up each selected repo as a verified zip archive before touching anything
  4. Rewrites the Git history using git filter-repo --mailmap
  5. Restores remotes that filter-repo would normally delete
  6. Optionally force-pushes the corrected history to origin

The whole thing is interactive — no config files, no flags to memorize. Just run it and follow the prompts.

Getting started

You'll need:

  • Python 3.10+
  • Git on your PATH
  • git-filter-repo:
    pip install git-filter-repo

Then install the tool itself:

cd git-identity-rewriter
pip install .

For development:

pip install -e .

Usage

git-identity-rewriter

That's it. The tool walks you through everything interactively. Here's what to expect:

Phase 0 — Preflight

Quick sanity check: makes sure git and git-filter-repo are installed and reachable. If something's missing, it'll tell you exactly what to install.

Phase 1 — Discovery

You pick a target directory (defaults to wherever you are), enter the old identity you want to replace, and the tool recursively scans for Git repos with matching commits. You'll see a table showing every repo it found, how many commits match, and any warnings.

Phase 2 — Selection

An interactive checkbox menu pops up with all the discovered repos. Pick the ones you want to fix, or hit "Select All eligible" to grab everything. Repos that can't be rewritten (shallow clones, bare repos, active merge/rebase) are shown but disabled so you know why they're skipped.

If any selected repo has uncommitted changes, you'll get a heads-up and a chance to back out.

Phase 3 — Backup

Before anything gets rewritten, every selected repo is zipped up into a timestamped backup folder. Each zip is verified after creation. If a backup fails (unreadable files, disk issues), that repo is automatically skipped from the rewrite — no backup, no rewrite.

Phase 4 — Confirmation

You'll see a summary panel: how many repos, how many commits, total backup size. One last Y/N prompt before the rewrite happens. This is your "are you really sure?" moment.

Phase 5 — Rewrite

The actual history rewrite runs via git filter-repo --mailmap. For each repo, the tool creates a temporary mailmap file, runs the rewrite, counts remaining old-identity commits (should be zero), and restores all remotes. You get a per-repo results table when it's done.

Phase 6 — Push (optional)

After the rewrite, you're asked if you want to auto-push to origin. If yes, the tool refreshes tracking refs first (git fetch origin --prune), then uses --force-with-lease for branches and --force for tags. If a push fails for one repo, the others still go through.

Dry-run mode

Not ready to commit? (pun intended.) Enable dry-run when prompted and the tool will scan, let you select repos, and create backups — but skip the actual rewrite. Everything up to Phase 4 runs normally, so you can verify the backup process and see exactly what would be rewritten.

Backups & safety

This tool rewrites Git history, which is inherently destructive. So safety is baked into every step:

  • Backups are created before any rewrite happens. Each repo gets its own verified zip archive.
  • Backup verification — every zip is tested after creation. If verification fails, that repo is skipped.
  • No rewrite without a backup. Period.
  • Ctrl+C at any point exits cleanly, and any backups already created are preserved.
  • JSON audit log — a rewrite-log.json is written to the backup folder with full details of what happened.

Backups live here:

<target-dir>/.git-rewrite-backups/<timestamp>/
├── repo-name-<path-hash>.zip
├── another-repo-<path-hash>.zip
└── rewrite-log.json

Zips include the full repo (minus node_modules, __pycache__, .venv, build, dist, and similar artifact directories). If the target directory is itself a Git repo, the backup folder is automatically added to .git/info/exclude so it won't clutter your git status.

Rolling back

If something goes sideways:

  1. Delete (or rename) the rewritten repo folder
  2. Unzip the corresponding backup archive
  3. Move it back to the original location

That's it — you're back to exactly where you started.

Pushing your changes

If you chose not to auto-push in Phase 6 (or if auto-push failed for a repo), you can always push manually after verifying the rewrite looks correct:

cd <repo-path>
git push --force-with-lease origin --all
git push --force-with-lease origin --tags

Heads up: force-pushing overwrites remote history. If other people work on the same repo, give them a heads-up first so they can rebase or re-clone. Don't be that person who silently force-pushes on a Friday afternoon.

Edge cases

The tool handles a bunch of tricky situations so you don't have to think about them:

Situation What happens
Uncommitted changes You'll get a warning and a confirmation prompt — proceed at your own risk
Shallow clones Blocked from selection — filter-repo can't rewrite partial history
Active merge or rebase Blocked — finish your merge/rebase first
.git/index.lock exists Warning shown — usually means another Git process is running
Bare repositories Blocked — bare repos aren't supported
Submodules Warning shown — submodule state might need manual attention
Git worktrees Handled correctly — the tool resolves .git file references
Backup fails That repo is skipped from rewrite — safety first
Rewrite fails Logged with details, other repos continue normally
Ctrl+C Clean exit, backups are preserved

License

Private tool — not licensed for redistribution.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages