Rewrite commit author and committer identity for one email address.
git-change-author rewrites history so commits that used an old author email use a new name and email. It updates both author and committer fields, then rewrites branches and tags.
Use it when a repository was committed under the wrong address and every matching commit should show the corrected identity.
With Homebrew:
brew tap the-lupaxa-project/tap
brew trust the-lupaxa-project/tap
brew install git-change-authorOr run the script from a clone: ./src/git-change-author --help.
./src/git-change-author -S \
-o old@example.com -e new@example.com -N "New Name" # plan only — no changes
./src/git-change-author -n -L \
-o old@example.com -e new@example.com -N "New Name" # dry-run, local only
./src/git-change-author -y \
-o old@example.com -e new@example.com -N "New Name" # rewrite, then force-pushThis rewrites history. Prefer --summary or -n first.
With the required identity flags and no mode flags, the script will:
- Require a Git working tree (or
--git-dirtogether with--work-tree) - Refuse to run if
--old-emailis not already in the history - Print an action plan
- Ask you to type
CHANGEbefore rewriting - Run
git filter-branchso matching author and committer emails are replaced on all branches and tags - Force-push every branch and tag to
originwhen that remote exists
--local-only skips the push. --yes (and --force) skips the confirmation. --summary prints the plan and exits.
| Flag | Purpose |
|---|---|
-o, --old-email EMAIL |
Email address to replace (matched case-insensitively) |
-e, --new-email EMAIL |
Email address to write in its place |
-N, --new-name NAME |
Name to write for the new author and committer |
-r, --remote NAME |
Remote to force-push (default: origin) |
-L, --local-only |
Rewrite locally and do not touch the remote |
-n, --dry-run |
Simulate commands without changing anything |
-S, --summary |
Print a detailed plan based on all options and exit |
-y, --yes |
Skip the interactive CHANGE confirmation |
-f, --force |
Same as --yes |
-d, --git-dir PATH |
Path to the repository .git directory |
-w, --work-tree PATH |
Path to the working tree (use with --git-dir) |
-V, --version |
Print version and exit |
-h, --help |
Show help and exit |
./src/git-change-author --helpPreview what a rewrite would do:
./src/git-change-author --summary \
--old-email emmett.brown@example.com \
--new-email marty.mcfly@example.com \
--new-name "Marty McFly"Rewrite the current repository and leave the remote alone:
./src/git-change-author --local-only --yes \
--old-email emmett.brown@example.com \
--new-email marty.mcfly@example.com \
--new-name "Marty McFly"Rewrite a repository that is not the current directory, then force-push origin:
./src/git-change-author \
--git-dir /path/to/repo/.git \
--work-tree /path/to/repo \
--old-email emmett.brown@example.com \
--new-email marty.mcfly@example.com \
--new-name "Marty McFly" \
--remote origin \
--yes--dry-runprints the action plan and simulates commands without asking forCHANGE.- Real runs require typing
CHANGEunless you pass-y/--yes(or-f/--force). --summaryresolves the repository and prints the plan only — no rewrite is run.- A missing old email fails before any rewrite. Commits that already use a different email are left unchanged.
- Force-push runs after a successful rewrite, unless you pass
--local-onlyor the repository has no remote. - Collaborators, forks, and clones must fetch the rewritten history and rebase local work onto it.