Change the author name and email on multiple Git commits

Correct author information with git filter-repo or interactive rebase, distinguish author from committer, and plan a coordinated history rewrite.

Best practices
Illustration of Git branches and version history

Use git filter-repo for a repository-wide identity correction, or interactive rebase for a small sequence of recent commits. Both rewrite commit objects, changing the affected commit IDs and those of their descendants. Work in a fresh clone, keep an untouched backup, and coordinate any rewrite of published history.

If you only need reports to display a consistent identity, consider a .mailmap first. It can normalize names in commands that support mailmaps without replacing the stored commits.

Replace an identity with filter-repo

git-filter-repo is a separately installed tool. Install it in your chosen Python tooling environment, for example:

python3 -m pip install git-filter-repo

In a fresh disposable clone, use exact matches rather than substring replacement:

git filter-repo \
  --email-callback 'return b"new@example.com" if email == b"old@company.com" else email' \
  --name-callback 'return b"New Name" if name == b"Old Name" else name'

These callbacks operate independently. The name callback changes every matching name, regardless of email; use a mailmap or a commit callback when the name change must be tied to a specific email. Email and name callbacks cover author, committer, and tagger identities. A commit callback is needed for conditions such as dates or particular commit IDs.

Change a short recent sequence

For a linear branch with at least five commits before its current tip:

git rebase -i HEAD~5 \
  --exec 'git commit --amend --author="New Name <new@example.com>" --no-edit'

This changes the author on each replayed commit. The committer becomes your currently configured identity, so check user.name and user.email first. Review the todo list: merges and commits omitted by rebase require deliberate handling. Use --root instead of HEAD~5 if you need to include the root commit.

Review and publish deliberately

Inspect both identities:

git log --format='%h author=%an <%ae> committer=%cn <%ce>'
git remote -v

A full filter-repo rewrite normally removes origin to reduce accidental mixing of old and new history. Re-add the verified destination only when ready. Update the affected branches and tags under a coordinated plan; do not blindly force-push every ref. For each branch, an explicit lease can protect the exact remote tip you reviewed:

# Replace OLD_REMOTE_COMMIT with the recorded, reviewed full commit ID.
git push --force-with-lease=refs/heads/main:OLD_REMOTE_COMMIT origin main:main

Changing a signature-covered object invalidates its signature. Collaborators must avoid merging old history back in; a fresh clone is often simplest, but carefully migrating unpublished work is also possible.

FAQ

Should I use filter-branch instead?

Git's documentation recommends alternatives such as filter-repo because filter-branch has correctness and performance pitfalls. filter-repo still needs careful review; “safer tooling” does not make a history rewrite risk-free.

Can I change only selected commits?

Use rebase for a small contiguous sequence or a conditional commit callback for more selective changes. An email-only callback cannot inspect commit dates.

Why does GitHub still show the old identity?

Confirm the rewritten refs were pushed and inspect the author and committer fields. GitHub account association and contribution credit have additional email and repository requirements; changing an address does not guarantee all contribution statistics will change.

See git-filter-repo, git-rebase, git-commit, and git-push.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting