When I started using git I just did a git init
and started calling add
and commit
. Now I am starting to pay attention and I can see that my commits are showing up as cowens@localmachine
, rather than the address I want. It appears as if setting GIT_AUTHOR_EMAIL
and GIT_COMMITTER_EMAIL
will do what I want, but I still have those old commits with the wrong email address/name. How can I correct the old commits?

- 2,053
- 2
- 21
- 24
-
4For our future readers: Questions about using `git` for purposes similar to this are better asked on [so]. – Michael Hampton Jul 19 '14 at 19:51
-
[Here is the closest question](http://stackoverflow.com/a/870367/210945) on stackoverflow.com. – naught101 Sep 01 '14 at 05:23
4 Answers
You can go back and fix all your commits with a single call to git filter-branch. This has the same effect as rebase, but you only need to do one command to fix all your history, instead of fixing each commit individually.
You can fix all the wrong emails with this command:
git filter-branch --env-filter '
oldname="(old name)"
oldemail="(old email)"
newname="(new name)"
newemail="(new email)"
[ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
[ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
[ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
[ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
' HEAD
More information is available from the git docs
-
13well, git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="foo@example.com";GIT_AUTHOR_NAME="Foo"' is a lot simpler, thanks. This would be the accepted answer if I could change it (it looks like there is a bug with Server Fault). – Chas. Owens May 27 '09 at 18:07
-
@Chas. Owens - Try click on the checkmark beside my answer to deselect it and then select andy's – Chealion May 27 '09 at 18:12
-
@Chealion That is what I was trying (I have been on Stack Overflow for a couple months now), but it wasn't working. I just tried it again and it worked. Odd. – Chas. Owens May 27 '09 at 18:14
-
7Note that the export lines should NOT have spaces on either side of the equals sign. I.e. they should look like this: export GIT_AUTHOR_EMAIL="(correct email)" ; – Andy Balaam Nov 03 '09 at 12:12
-
1
-
2@Deckard: save the script to a text file such as fixcommits.sh, then run Git Bash and run the script. I put the script file in the root of my repo, then navigated to that folder in Git Bash, then I ran the script with ./fixcommits.sh – Avalanchis Apr 30 '12 at 00:20
-
this is easily extensible to address multiple incorrect emails, simply cut&paste to extend the if/fi statement & you're done! – dch May 21 '12 at 20:22
-
1This is really helpful. But don't forget that, as with every instance of rewriting history in Git, it'll cause other people's repos to blow up when they try to pull it. I ended up just checking out a clean copy since I only had a copy on my other machine, but if you have collaborators you'll have trouble. – Robert Feb 09 '13 at 23:46
-
2**Addendum 1** This command format was not working for me, but if/then did: `if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi` – Josh M. Apr 14 '15 at 17:02
-
How do I apply this to my other branches? And why does my master branch now contain two entries for each commit (one with the old email and one with the new one)? After applying this `git filter-branch` , I tried to push my local master to a remote stash repo, but git told me to first pull the remote master because supposedly it was one commit ahead. I did this and then pushed the local master back to the remote (origin). Now both the remote and my local master contain two commits for each original commit. How can I address these two issues? – ikaerom Jul 29 '15 at 23:01
-
The correct command for me was: `git filter-branch --env-filter ' oldname="(old name)" oldemail="(old email)" newname="(new name)" newemail="(new email)" [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail" [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail" [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname" [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname" ' HEAD ` Note the spaces being removed in the `[]` if clauses. – Gunnar Jun 13 '16 at 18:07
-
Adding a one line command for windows. Regretfully, I am forced to be less structured, but this works even if no gitbash is present (as was my case): `git filter-branch --env-filter "[ \"$GIT_AUTHOR_EMAIL\"=\"old@domain.com\" ] && GIT_AUTHOR_EMAIL=\"new@domain.com\" && [ \"$GIT_COMMITTER_EMAIL\"=\"old@domain.com\" ] && GIT_COMMITTER_EMAIL=\"new@domain.com\" && [ \"$GIT_AUTHOR_NAME\"=\"New Name\" ] && GIT_AUTHOR_NAME=\"Old Name\" && [ \"$GIT_COMMITTER_NAME\"=\"New Name\" ] && GIT_COMMITTER_NAME=\"Old Name\"" HEAD` – Boris Strandjev Sep 30 '17 at 11:17
Git's filter-branch command is powerful, but it's horribly unwieldy to use for anything non-trivial, like for example, if you have more than one author to correct.
Here's an alternative I found useful, which uses the .mailmap feature described in the git-shortlog manpage. This provides an author mapping mechanism we can use with git log's formatting facility. We can use it to generate the commands to pick and amend amend a named sequence of commits.
For example, suppose you want to correct the authorship on a branch $BRANCH, starting at a commit $START.
You need to create a .mailmap file in the top directory of your repository which maps the existing author names to he correct ones. You can get a list of the existing author names with:
git shortlog -se
You need to end up with a .mailmap file like this (say):
You <you@somewhere.org> cowens@localmachine
You <you@somewhere.org> root@localmachine
Now you can use git log's formatting feature to generate the commands to rewrite $BRANCH as $BRANCH2.
git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh -
The first command creates a new empty branch sprouting from the commit $START. For each commit between $START and then end of $BRANCH, the second command cherry picks the original commit on to the end of the current branch $BRANCH2, and amends it to set the author correctly.
This is also generally applicable - put this in your ~/.gitconfig:
[alias]
# git reauthor $START..$END
reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H && git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '
So when you need to correct authors, now you just then need to generate a .mapfile and do:
git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH
The original branch ref can be reassigned to the new one, and the new one deleted:
git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2

- 381
- 3
- 3
Combining the answer from How do I fix the metainformation on the first commit in git?
### Fix the first commit ###
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root

- 2,053
- 2
- 21
- 24
-
Got me on the right track, but needed command from: http://stackoverflow.com/a/28536828/307 instead of the --author usage – Brett Veenstra Oct 03 '15 at 03:19
To follow jedberg's answer: You can use rebase -i
and choose to edit the commits in question. If you use git commit --amend --author <AUTHOR DETAILS>
and then git rebase continue
you can go through and fix the history.

- 5,733
- 28
- 29