Using .mailmap - sympy/sympy GitHub Wiki

Background

Each commit in a repo has an Author field on which is listed the author's name and email address: "Author: name ". Sometime a single author has entries that are given under different email addresses or names. There are times when it would be nice to merge all duplicates together or to modify the name or address when a command that queries git authors is used. Two such commands are git shortlog which reports, for a given author, the commits made. Another is the formatted log command such as git log --format='<%aE> %aN' in which the 'aE' and 'aN' (instead of 'ae' and 'an') stand for the author email and name after being filtered through .mailmap. Without a .mailmap file, even variations in case will indicate a unique author to git so Foo <e@mail> will be a different author than foo <e@mail>.

Is a .mailmap entry needed?

Here are some commands that can be run to detect when entries are needed for the .mailmap file.

The first one is important: it tells which authors are known to git (after being filtered through the current .mailmap) have different names but the same email address. This happens for two reasons: someone modified their email name on the same account after making some commits or different people used a default email address on their system like 'devnull@localhost'.

git log --format='<%aE> %aN' | sort -u | awk -F'>' \
'{print }' | uniq -c | grep -v '^ *1 '

To get the same information without using .mailmap, replace the E and N with e and n:

 git log --format='<%ae> %an' | sort -u | awk -F'>' \
 '{print $1}' | uniq -c | grep -v '^ *1 '

And to just see the raw authors without counts shorten that to

 git log --format='<%ae> %an' | sort -u

The second command that can indicate when a .mailmap entry might be needed is the one that sees if a given name has more than one email address associated with it:

 git log --format='%aN <%aE>' | sort -u | awk -F'<' \
'{print $1}' | uniq -c | grep -v '^ *1 '

Making .mailmap entries

Entries in .mailmap are made for two reasons: to merge git authors that are one in the same or to simply change how the name and/or address of an author appears. Either can be done with an entry to this file like

Proper Name <Proper@email> commit name <commit@email>
\-----------+------------/ \----------+-------------/
            |                         |
         replace                     find

The email (or name and email) in the "find" part of the entry will be used in a case-insensitive way to identify a git author and replace it with whatever is included in the "replace" part:

author                           author
before    .mailmap entry         after
--------- ---------------------- -----------
          Foo <Email>
A <Email> ---------------------> Foo <Email>
B <eMAIL> ---------------------> Foo <eMAIL>

          <Email> <email>
A <Email> ---------------------> A <Email>
B <eMAIL> ---------------------> B <Email>

          Foo <Email> <email>
A <Email> ---------------------> Foo <Email>
B <eMAIL> ---------------------> Foo <Email>

          Foo <EMAIL> b <email>
A <Email> ---------------------> same
B <Email> ---------------------> Foo <EMAIL>
b <eMAIL> ---------------------> Foo <EMAIL>

          Foo <Email> b <email>
          Foo <Email> <liame>
A <Liame> ---------------------> Foo <Email>
B <Email> ---------------------> Foo <Email>
b <eMAIL> ---------------------> Foo <Email>
c <eMAIL> ---------------------> same

Any of the .mailmap entries can be tested on user-specified authors without regard to the repo by using 'git check-mailmap "name ". So if any of the above are added to a new or existing .mailmap file you can test that the "after" output is obtained from the "before" input.

    .mailmap file
    +----------------------+
    |Foo <Email> b <email> |
    |Foo <Email> <liame>   |
    |                      |
    +----------------------+

    $ git check-mailmap 'A <Liame>'
    Foo <Email>

Fine print

The pattern author name <address> commit name does nothing but it is a way to show, without inserting a comment, the nickname of someone.

The pattern <address> name does nothing.

Long patterns are .mailmap entries that give the commit name AND address after the author name and/or address. They are needed to disambiguate email addresses that are the same (ignoring case) that are used by different authors. So if someone makes a commit with a dummy email address that is (or is likely to be) the same as someone else's, a long entry should be made in the .mailmap file. (For example, there are over a dozen authors in SymPy whose address is 'devnull@localhost'.)

if multiple long patterns have the same commit name and address,
only the last one in the .mailmap file will be used and each entry
will start by assuming the name and address are those of the author
being tested

long
patterns     A <B> <-starting author

<c> a <b>    A <c>
c <b> a <B>  c <b>
<d> a <B>    A <d> <-ending author

Short patterns are .mailmap entries that give only a commit address. They can be used whenever only one person uses a given email address. (If anyone else uses an address associated with an author then a long .mailmap entry must be used if any change needs to be made to that new author's name or email address.)

if multiple short patterns have the same commit address
they will *successively replace* the commit name and address
with whatever is provided in the pattern

short
patterns   A <B> <-starting author

a <b> <b>  a <b>
<C> <b>    a <C>
B <b>      B <C> <-final author

Gotchas

When copying accented characters from one screen and pasting them into another window, be sure the window supports the accented characters or else they may be lost silently.

SymPy

In SymPy we keep track of the authors in a file named AUTHORS. These are the names and addresses of authors as modified by .mailmap. That file is automatically updated with the script in bin/authors_update.py. The script bin/mailmap_update.py can be used before updating AUTHORS to check whether .mailmap entries are needed, automatically doing the tests described above and also checking for the case where two email address are the same except for case.

See Also

Official git help for .mailmap is here.

⚠️ **GitHub.com Fallback** ⚠️