Rewriting Git History: Changing Commit Authors
Recently, I took a bit of a turn — new direction, new mindset, new goals. I dropped some services, cut a few habits, and doubled down on others. It’s not the first time — and definitely won’t be the last. Every time, same story: new alias, maybe a new URL, and off we go again.
This time, though, I wanted to change the authors of my Git commits — just to avoid looking like I’ve got multiple personalities committing to the same repo. You know, before someone starts suspecting schizophrenia.
Case 1: Replace all authors
If you want to replace every single author with one consistent identity:
git filter-repo --commit-callback '
commit.author_name = b"Votre Nom"
commit.author_email = b"email@exemple.com"
commit.committer_name = b"Votre Nom"
commit.committer_email = b"email@exemple.com"
' --force
This command walks through every commit and replaces both the author and committer.
Important notes: • Values must be Python bytes (b"…") • The –force flag is required to apply the changes (no confirmation prompt) • This operation recreates all commits, so their SHA hashes change
Case 2: Replace a specific author
If your repo has multiple authors but you only want to fix one of them, add a condition:
git filter-repo --commit-callback '
if commit.author_name == b"Ancien Nom":
commit.author_name = b"Nouveau Nom"
commit.author_email = b"nouvel@email.com"
commit.committer_name = b"Nouveau Nom"
commit.committer_email = b"nouvel@email.com"
' --force
Case 3: Replace only names or only emails
You can also apply more granular transformations. For example, replace names only:
git filter-repo --name-callback 'return b"Nouveau Nom"' --force
Or replace emails only:
git filter-repo --email-callback 'return b"nouvel@email.com"' --force
Full workflow: a practical example
Let’s say your commits are under “Tartanpion old@email.com” and you want to fix that mess.
- Check current authors
Before doing anything, list your contributors:
git log --format='%an <%ae>' | sort | uniq
That’ll show all unique authors in the repo.
2. Apply the filter
git filter-repo --commit-callback '
if commit.author_name == b"Tartanpion":
commit.author_name = b"DuN0Z"
commit.author_email = b"dunoz@porzh.me"
commit.committer_name = b"DuN0Z"
commit.committer_email = b"dunoz@porzh.me"
' --force
3. Verify the result
git log --format='%an <%ae>' | sort | uniq
Authors should now all show the updated identity.
4. Check repo integrity
git fsck
This ensures the repository is still consistent.
5. Force push the new history
Since you’ve rewritten the history, you’ll need to force push it to the remote:
git push origin master --force
Warning : –force overwrites history on the remote. Make sure that’s okay for your team — or in my case, it’s all personal stuff, so… who cares.
Common pitfalls
Refusing to run without –force: Git will refuse to rewrite history unless you explicitly allow it. Use –force consciously.
Old references sticking around: After filtering, Git keeps old references under .git/refs/original/. You can safely remove them:
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
Collaborators affected: If others work on this repo, they’ll need to re-clone or rebase their branches. Coordinate… or don’t — in my case, nobody else touches these repos. Like this blog, actually — I love throwing digital messages in bottles.
After the force push
Once pushed, the remote will now reflect your new commits. Old commits will stick around temporarily (until garbage collection), but they’ll fade away soon enough.
If someone else cloned the old history:
git fetch origin
git reset --hard origin/master
Conclusion
Rewriting Git history with git filter-repo is powerful — and should be used wisely. It’s great for fixing author mistakes, cleaning up legacy commits, or prepping a repo before publishing it publicly. Always double-check, and if in doubt, test on a copy first.
If you want to avoid this situation in the future, make sure your Git identity is configured properly:
git config --global user.name "Votre Nom"
git config --global user.email "email@exemple.com"
This is especially true if you use multiple machines — it gets messy fast. Or better yet, put everything under NixOS and import the same git.nix config everywhere. You know what caused my issue? The Mac. Classic karma.