Pre-commit hook that checks and maintains .mailmap completeness
Project description
mailmap-checker
A pre-commit hook that detects unmapped Git identities by comparing your .mailmap against the full commit history. It groups authors and committers by email address and email local-part so duplicates are caught even across domain changes.
Follows the gitmailmap specification: all four mapping formats are supported, and both names and emails are matched case-insensitively.
How it works
The checker scans git log for all unique author and committer identities and groups them using two rules:
Rule 1 — Same email (case-insensitive)
Identities that share the exact same email address are the same person.
Alice Johnson <alice@acme.com>
alice.j <alice@acme.com> ← same email, grouped together
Rule 2 — Same email local-part (different domain)
Identities whose email local-part (the part before @) matches are likely the same person who changed companies or used a different address. Local-parts shorter than 8 characters are automatically skipped to reduce false positives.
Alice Johnson <alice.johnson@acme.com>
Alice Johnson <alice.johnson@oldcorp.com> ← same local-part, grouped
Alice J <alice.johnson@personal.net> ← same local-part, grouped
Once groups are built, the checker looks for identities that are not mapped in .mailmap. If a group has more than one identity and any of them is missing from the file, the hook fails and reports the gap.
Example
Given these three identities in git history and an empty .mailmap:
Alice Johnson <alice.johnson@acme.com>
Alice Johnson <alice.johnson@oldcorp.com>
Alice J <alice.johnson@personal.net>
mailmap-checker check detects the gap:
Found 2 unmapped identities in 1 group:
Canonical: Alice J <alice.johnson@personal.net>
- Alice Johnson <alice.johnson@acme.com>
- Alice Johnson <alice.johnson@oldcorp.com>
mailmap-checker fix --dry-run suggests entries to add:
Suggested .mailmap entries:
Alice J <alice.johnson@personal.net> Alice Johnson <alice.johnson@acme.com>
Alice J <alice.johnson@personal.net> Alice Johnson <alice.johnson@oldcorp.com>
Note: When no
.mailmapexists, the tool picks the alphabetically first identity as the canonical. In this case it choseAlice J <alice.johnson@personal.net>, but the actual preferred identity is likelyAlice Johnson <alice.johnson@acme.com>. After runningfix, open.mailmapand swap the canonical if needed:Alice Johnson <alice.johnson@acme.com> Alice Johnson <alice.johnson@oldcorp.com> Alice Johnson <alice.johnson@acme.com> Alice J <alice.johnson@personal.net>
Disabling local-part matching
If Rule 2 produces false positives on very large repositories, disable it with --no-local-part-matching.
Installation
Pre-commit hook (recommended)
# .pre-commit-config.yaml
repos:
- repo: https://github.com/cansarigol/mailmap-checker
rev: "" # run: pre-commit autoupdate
hooks:
- id: mailmap-check
Then run pre-commit autoupdate to pin the latest release.
Available hooks
| Hook ID | Description |
|---|---|
mailmap-check |
Fail if any identity is missing from .mailmap |
mailmap-fix |
Automatically add missing entries to .mailmap |
mailmap-fix-dry-run |
Preview suggested entries without modifying the file |
Standalone
pip install mailmap-checker
Usage
check
Scan all Git authors and committers and exit non-zero if any identity is missing from .mailmap.
mailmap-checker check
init
Create a .mailmap file (if it does not exist) and run a full check.
mailmap-checker init
fix
Preview or apply suggested .mailmap entries.
# Preview
mailmap-checker fix --dry-run
# Apply
mailmap-checker fix
Common options
| Flag | Description |
|---|---|
--mailmap <path> |
Custom .mailmap file path (default: git config mailmap.file, then .mailmap) |
--git-dir <path> |
Path to git repository (default: current directory) |
--no-local-part-matching |
Disable grouping by email local-part across domains |
Contributing
git clone https://github.com/cansarigol/mailmap-checker.git
cd mailmap-checker
uv sync
uv run poe setup # installs pre-commit and commit-msg hooks
uv run poe check # lint + security + tests
Commits must follow Conventional Commits with a required scope (e.g. feat(cli): add --verbose flag).
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mailmap_checker-0.2.1.tar.gz.
File metadata
- Download URL: mailmap_checker-0.2.1.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ed70cffaa514db3960f6802b218affc5c101ef796eb5a2990882681d3621845
|
|
| MD5 |
f51e144c53236afe2c7d94b34e27dc54
|
|
| BLAKE2b-256 |
da87015c9a5418a0a142042c5040f0e5f2aaba77fb4276933c5d50572c489b07
|
File details
Details for the file mailmap_checker-0.2.1-py3-none-any.whl.
File metadata
- Download URL: mailmap_checker-0.2.1-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
abc72cd6bf70474fd281a64512a17dec90ffd8f60048efc0bd59db84fd7c9015
|
|
| MD5 |
8376ed210f3328547634d0f2c0aac882
|
|
| BLAKE2b-256 |
aa324a7d1f3ada6f8852733d986926fb1f009f225800e0f48c6c8e8a2d886e2a
|