Git Basics: Preview Author Identity Mappings Without Rewriting History
Contribution reports can split one author across old email addresses. A mailmap lets supporting Git commands display a canonical identity without replacing existing commits. Test a mapping with deliberately fictional identities first.
Prepare a scratch directory
Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need Bash, Git, a text editor, and standard mktemp, rm, rmdir, cat, head, wc, and sed utilities. Run from an ordinary shell without repository-selection variables such as GIT_DIR, GIT_WORK_TREE, or GIT_INDEX_FILE set. The script isolates global and system Git configuration and uses fictional identities only in its temporary repository.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-check-mailmap.sh:
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author'
export GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_AUTHOR_DATE='2026-10-29T00:00:00+00:00'
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git init -q --object-format=sha1 -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config commit.gpgsign false
git config core.hooksPath /dev/null
printf 'ready\n' > status.txt
git add status.txt
git commit -qm 'Record status'
original_commit="$(git rev-parse HEAD)"
printf 'Canonical Author <canonical@example.invalid> <author@example.invalid>\n' > .mailmap
printf 'Lookup results:\n'
printf '%s\n' 'Example Author <author@example.invalid>' 'Other Person <other@example.invalid>' |
git check-mailmap --stdin
printf 'Stored identity: '
git log -1 --format='%an <%ae>'
printf 'Mapped identity: '
git log -1 --format='%aN <%aE>'
test "$(git rev-parse HEAD)" = "$original_commit"
printf 'Commit identity unchanged: yes\n'Run it:
bash demonstrate-check-mailmap.shObserved output:
Lookup results:
Canonical Author <canonical@example.invalid>
Other Person <other@example.invalid>
Stored identity: Example Author <author@example.invalid>
Mapped identity: Canonical Author <canonical@example.invalid>
Commit identity unchanged: yesRead the result
The matching contact becomes the canonical name and address; the other contact passes through unchanged. Lowercase %an and %ae show the stored author fields, while uppercase %aN and %aE honor the mailmap. The final assertion verifies that HEAD has not changed. The newly created .mailmap is deliberately left uncommitted inside this disposable fixture.
Apply it carefully
A mailmap changes presentation in commands that support it; it does not authenticate a person or alter the original commit bytes. Confirm real identity associations before adding them. In a real project, review and commit the mapping file separately so other contributors receive it. --stdin accepts one contact per line, making it useful for checking a list before changing shared reporting.
The official Git reference documents these options. The script creates and removes only its own temporary fixture; it does not contact a remote or change your existing repository.
Clean up
Remove the saved script, return to the starting directory, and remove the empty practice directory:
rm -- demonstrate-check-mailmap.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect its remaining files rather than deleting unknown content.
Acknowledgements
This post was created with assistance from AI.