git like a pro: rewrite author history

In this little post I am going to show you why you sometimes need to rewrite the author or committer history, how you do it and where it will not work as expected.

Article series
Git like a pro

  1. Git like a pro
  2. Sort git tags by date
  3. Rewrite author history


The complete source including command-generation can be found at github:
cytopia/git-rewrite-author cytopia

Latest Stable Version

Why would I rewrite the git author history?

First things first, why would you ever want to rewrite the git author history? Think of the following scenario:

You are going to do a very urgent fix directly on the server deployed git repository. It seems to work fine and you commit it to the local repository and push it to remote. But wait… You totally forgot that you acted as root and when you issue a git log it will show the following:

commit a0925c315107fcdcfb7a3b2dcd435995c8216ad2
Author: root <root@localhost>
Date:   Sat Oct 10 21:39:43 2015 +0200

    fixed xss on index.php

Damn’ that was a mistake. You should have taken the time and have done it on your local machine, pushed to remote and checked out on the server as your seniors always told you. Don’t worry, this can be fixed.

Rewriting the author history

This time you better do it locally. Make sure your local repository is up to date with the remote and quickly list all git authors:

$ git log --pretty=full | grep  -E '(Author|Commit): (.*)$' | sed 's/Author: //g' | sed 's/Commit: //g' | sort -u

Junior Dev <>
Senior Dev <>
root <root@localhost>

OK, you need to get rid of root and rewrite it to your git account Junior Dev. The command for this case will look like this:

$ git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_EMAIL" = "root@localhost" ]; then
        export GIT_COMMITTER_NAME="Junior Dev"
        export GIT_COMMITTER_EMAIL=""
    if [ "$GIT_AUTHOR_EMAIL" = "root@localhost" ]; then
        export GIT_AUTHOR_NAME="Junior Dev"
        export GIT_AUTHOR_EMAIL=""
' --tag-name-filter cat -f -- --all

OK, you have done it, let’s double check by listing the authors again:

$ git log --pretty=full | grep  -E '(Author|Commit): (.*)$' | sed 's/Author: //g' | sed 's/Commit: //g' | sort -u

Junior Dev <>
Senior Dev <>

OK, its gone. Now get it to the remote.

Rewriting the remote author history

Once you have rewritten the local git author history, you will only have to make a forced push of all refs including tags:

$ git push --force --tags origin 'refs/heads/*'

That’s it.

Where does it come short?

Be aware that if any of the commits or tags of an author you want to change are signed, it will mess up the commit message in the history. It will take the gpg signature of the commit and prepend it to the commit message and will look something like this:

commit 4ac785bf03d4b4f814fa9d139db9b9c7b53df733
Author: cytopia <>
Date:   Fri Jul 10 16:03:09 2015 +0200

     -----END PGP SIGNATURE-----

    Redirect Errors and Warnings to stderr

The rewriting has created an unsigned multiline commit of the previously signed single-line commit.

Keep that in mind before going to rewrite signed commits.


Leave a Reply

Your email address will not be published.