Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
add comment

4 Answers

up vote 48 down vote accepted

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

share|improve this answer
7  
well, 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
4  
Note 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 3 '09 at 12:12
1  
Now, how would I do this on Windows? –  Deckard Mar 9 '12 at 21:56
1  
@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 0:20
show 3 more comments

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
share|improve this answer
    
This is awesome. I'd bounty you if I had more rep. Thanks :) –  pistache Dec 10 '12 at 8:32
add comment

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"
# 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"
# 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
share|improve this answer
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.