How to Rewrite Email Addresses in Git Commit History

3 minutes

Imaging you have published something on GitHub and you realize you used an email address which should be kept private?

Git offers a very powerful sub-command git filter-branch. It can be used to rewrite your entire commit history, and it can be used to replace an email address. In this blog article, I provide a script which is easy to use for everyone who is familiar with git commands.

Reason to rewrite git history

The git commit history ensures the integrity of a software project. Also, it helps to understand how source code evolves over time. All good reasons why it should not be touched and why it requires to good reason to rewrite a git commit history.

From my point of view a good reason is to rewrite a git commit history when a wrong email address was used. The risk is too high that it ends up with tons of spam in the inbox folder.

Technically, every commit must have an email address. The consequence is that there is no option to have a git history without any email address.

Usually, I use the proposed email address of GitHub. I prefer GitHub’s approach because this email address is still assigned to my GitHub account, and therefore I can use certain features of that platform.

Using git filter-branch

I started to write a simple bash script. It is easy to adapt in case there is a small edge case. Enjoy, using it if it looks helpful for you!

  1. Open your terminal and navigate to your git repository.

  2. Run the following script, replacing OLD_EMAIL, CORRECT_NAME, and CORRECT_EMAIL with the actual values:

     1#!/bin/sh
     2
     3git filter-branch --env-filter '
     4
     5OLD_EMAIL="[old_email_address]"
     6CORRECT_NAME="Correct Name"
     7CORRECT_EMAIL="correct_email_address"
     8
     9if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
    10then
    11    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    12    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
    13fi
    14if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
    15then
    16    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    17    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
    18fi
    19' --tag-name-filter cat -- --branches --tags
  3. After running the script, all commits with the old email will be rewritten with the new email and name.

  4. Force push the changes to your remote repository:

    1git push --force --all

Other Ways of Rewriting Git History

Another tools for this use case is git-filter-repo. It is written in python. Therefor it is easy to install via pipx.

1pipx install git-filter-repo

I haven’t tried that tool yet because my approach just works well. Anyhow, if you are facing for example performance issues, give it a try and let me know. Just drop be a comment below.

More Use Cases of git filter-branch

This Git sub-command is very powerful. There are many more use cases for which it can be used for. The project page of Git offers more examples. One case, which is worthy to mention is when a file needs to be removed from the repository. A reason could be a leak of confidential information (for example an API key), compliance issues, or copyright violation.

This command git filter-branch --tree-filter 'rm filename' HEAD removes the specific file from your entire repository. Of course, the commit hash is changed on all commits afterward. This cannot be avoided.

Summary

This little shell script works pretty well in my case. It helped me in the past already when I accidentally used a wrong email address. What are your favorite tricks with Git? How are you protecting yourself from getting too much spam when you publish a project with Git? I would highly appreciate it if you drop a comment below.