Changing author info in existing Git commits

If you are not setting the author info correctly or just want to use another email to prevent it from being exposed, you may want to change the author name and/or email of the existing commits. In the post, you will learn how to do that.

Take care to do that if you have pushed these commits to the remote server and there are other members who have access to that repository. Because the other members may have did some work based on your commits.

Change author info of the last commit

If you only want to change author info of the last commit, you can amend it to use new name and email.

# Change the last commit to use new author and email.

# Use --author option to specify the new author and email.
$ git commit --amend --no-edit --author "john <john@noreply.email.com>"

# Or
# Update the user info in configureation first, then amend the commit to
# use the new configured info.

$ git config user.name john
$ git config user.email john@noreply.email.0
# --reset-author, use the current user info.
$ git commit --amend --no-edit --reset-author

Note:

What git commit --amend does is replacing the tip of the current branch by creating a new commit., therefore it renew the commit date as well.

Change author info of multiple existing commits

To change the name and/or email of some specific existing commits, you can use rebase in an interactive mode which allows you to change the commit one by one. Then in the process you can use git commit --amend used above to do the change. See Git book: rewrite history for more details. Below is an example (for messy history, don’t use this method for inconsistent issue that may cause):

# Change the last two commits.
$ git rebase -i HEAD~2
# Action: change "pick" to "edit" in the prompted script for commits
# that you want to change
$ git commit --amend --no-edit --author "john "
$ git rebase --continue
$ git commit --amend --no-edit --author "john "
$ git rebase --continue

To change the name and/or email of the entire history, of course filter-branch can do that as GitHub: changing author info mentioned. In that guide it provides a script that use filter-branch command to rewrite the name and email if the commit email equals some value. However there are issues with filter-branch, there have been some alternatives to replace this command such as git-filter-repo.

If you run the script mentioned in GitHub: changing author info, the Git bash (v2.28.0) will give below warning:

$ ./change-author.sh
WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites.  Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as 'git filter-repo'
         (https://github.com/newren/git-filter-repo/) instead.  See the
         filter-branch manual page for more details; to squelch this warning,
         set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

Cannot rewrite branches: You have unstaged changes.

Here we use git-filter-repo command rather than filter-branch according the suggested way in above warning. Before you start, make your working directory clean.

First download git-filter-repo command (it requires Python3) and put the git-filter-repo file to a location on the PATH.

Then write a mailmap file in which you specify the name and/or email. Here we name it as my-mailmap and put below content that specifies to replace both the name and the email of a commit matching the specified commit email address:

john <john@noreply.email.com> <john@gmail.com>

Finally, run filter-repo with the mailmap you created:

$ git filter-repo --mailmap my-mailmap

About mailmap file

The --mailmap option needs a mailmap file of format accepted by git shortlog. Other forms of mailfile:

Replace name of a commit matching the specified commit email address:

Proper Name 

Replace only the email part of a commit matching the specified commit email address:

 

Replace both the name and the email of a commit matching the specified commit email address:

Proper Name  

Replace both the name and the email of a commit matching both the specified commit name and email address:

Proper Name  Commit Name 

Troubleshooting

# If your repository are not a fresh cloned one, use --force
$ git filter-repo --mailmap my-mailmap
Aborting: Refusing to destructively overwrite repo history since
this does not look like a fresh clone.
  (expected at most one entry in the reflog for HEAD)
Please operate on a fresh clone instead.  If you want to proceed
anyway, use --force.

# If it prompts below error, change "python3" to "python" in the git-filter-repo file
$ git filter-repo --mailmap my-mailmap
/usr/bin/env: ‘python3’: No such file or directory

Resources

git-filter-branch

  • Git book: rewriting history

  • GitHub: changing author info

    If you insist to use filter-branch command, run the script like below and wait a few seconds. Then the script will be executed if you don’t interrupt it with ctrl+c.

    $ ./change-author
    WARNING: git-filter-branch has a glut of gotchas generating mangled history
           rewrites.  Hit Ctrl-C before proceeding to abort, then use an
           alternative filtering tool such as 'git filter-repo'
           (https://github.com/newren/git-filter-repo/) instead.  See the
           filter-branch manual page for more details; to squelch this warning,
           set FILTER_BRANCH_SQUELCH_WARNING=1.
    Proceeding with filter-branch...
    
    Rewrite 6f5fae28ee6591861813c4a428379c752217dffe (1/1) (0 seconds passed, remaining 0 predicted)
    Ref 'refs/heads/master' was rewritten
    
    

git-filter-repo

  • git-filter-repo user manual

    Filtering of names & emails

    --mailmap

    ​ Use specified mailmap file (see git-shortlog(1) for details on the format) when rewriting author, committer, and tagger names and emails. If the specified file is part of git history, historical versions of the file will be ignored; only the current contents are consulted.

    --use-mailmap

    ​ Same as: –mailmap .mailmap

  • git-shortlog(1)