How to Change the User for All Your Git Commits

Over the course of a long-lasting project, your author information may change and the associations to a user profile on GitHub or GitLab may become broken. This is the ultimate guide for how to change the entire commit history.

Matt Hagemann
Apr 16 · 4 min read
Image for post
Image for post
Photo by on

You should only do this in repositories that are not widely used yet. The changes are rather intrusive, but easily manageable in a one-person project or within a small team. In any other case, use it when all team members are coordinating this together.

No matter how we change the information of past commits, we are effectively rewriting the commit history. You will create new commit objects in this process. An altered history can become a serious problem for collaborators if they already have work based on some of the original commits.

Rewrite All Affected Commits

Rewriting commits is done with git filter-brand to filter the history. The following terminal command will iterate through every commit in your history and update the author information wherever its email address equals OLD_EMAIL. Be sure to replace OLD_EMAIL, NEW_NAME and NEW_EMAIL.

It allows you to batch-process a large number of commits with a script inside the command. Changes are re-committed. By using --env-filter, we alter the environment in which the re-committing statement takes place. The script checks if a commit was made with the email you want to replace. Upon match, the environment is altered by exporting environment variables used to recommit the changes.

We also use the additional --tag-name-filter to take care of tags referencing commits.

The last option --all defines all refs to be processed. It needs to be separated from the filter-branch options with a double-dash.

$ git filter-branch --env-filter '
OLD_EMAIL="old@example.com"
NEW_NAME="New Example"
NEW_EMAIL="new@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
export GIT_COMMITTER_NAME="$NEW_NAME"
export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ] then
export GIT_AUTHOR_NAME="$NEW_NAME"
export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

Check the Updated Log

You can use the git log command to review above changes done locally. To navigate the log, press the space bar for next page or q to exit the view. If you discover yet more outdated author information, you have to run through the entire process below first before you can repeat it with another email address change.

Push Rewritten History

To push the rewritten repository, the --force option needs to be added in order to rewrite the history of the remote repository.

$ git push origin --force --all

The following command is optional and needed only if you use tags. It will additionally force push the tags to the remote server:

$ git push origin --force --tags

Common Issue in GitLab

In GitLab, I encountered the error “You are not allowed to push code to protected branches on this project.” whenever I did this forced push.

You can easily resolve it in your repository’s Settings > Repository > Protected Brances to unprotect the master branch.

Image for post
Image for post
Unprotect master branch in the GitLab repository settings.

Update All Clone Repositories

Now the repository has been filtered, the commit history has been rewritten, and changes were force pushed to the remote server.

In the next step, every clone of this repository has to be updated (including the one you’ve been altering). This cannot be done with the usual git pull alone. Use these commands:

$ git fetch origin 
$ git reset --hard origin/master
$ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
$ git reflog expire --expire=now --all
$ git gc --prune=now

Multiple Author Changes in Commit History

If your author information has changed multiple times throughout history, you’ll have to repeat the above process for each modification.

If you forgot to fetch from origin, you may encounter this error message when trying to do a 2nd round:

Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

Always remember to perform a new fetch after pushing the changed commit history by running the commands listed above.

Remember to Set Author Information

It’s needless to say that you should update the author information on your terminal. This will avoid future commits with the wrong email or name again. Either set them for the local repository or globally.

The below command, when executed inside the repository directory, changes the author’s name and email address used to commit:

$ git config user.name "New Example"
$ git config user.email "new@example.com"

When --global is added to the above commands, the settings are set globally rather than just for the current repository. A globally set name and email address are used as long as there is no name or email set in the repository itself.

Conclusion

You should now have updated all your commits with the correct author information that you wanted. This is especially useful if you want to ensure that your contributions are correctly linked to your GitHub or GitLab profile. If your profiles match the author’s email address, you should see all commits correctly linked.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store