up vote 28 down vote favorite
17
share [g+] share [fb]

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?

link|improve this question

50% accept rate
feedback

5 Answers

up vote 22 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.

I think you could fix all the wrong emails with this line:

    git filter-branch --env-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "(wrong email)" ];
      then
          export GIT_AUTHOR_EMAIL="(correct email)";
      fi
      if [ "$GIT_COMMITTER_EMAIL" = "(wrong email)" ];
      then
          export GIT_COMMITTER_EMAIL="(correct email)";
      fi
      ' HEAD

(Warning: that above script is untested)

More information is available from the git docs

link|improve this answer
2  
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
@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
3  
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
feedback

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
link|improve this answer
feedback

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
link|improve this answer
feedback

You need to use git rebase. Here is a tutorial:

http://jointheconversation.org/history.html

link|improve this answer
feedback

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.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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