fix: merge contributions by commit email - #18
Conversation
Author names were only merged through a hardcoded list of aliases, so the
same person showed up as several rows whenever they had committed under
different spellings of their name ("Brayo" and "brayo", "2e3s" and
"Demmie", "wojnilowicz" and "Łukasz Wojniłowicz", ...).
Commits sharing an author email are now merged into a single author,
transitively and across all repos at once, so a person also gets a single
row in the "total" table. The name with the most commits wins, with ties
broken by name to keep the output deterministic. Emails that identify a
git default rather than a person are ignored, and the manual alias list is
kept for the aliases that don't share an email (dependabot, mojibake, ...).
Also fixes two related bugs: the blame lines of a merged-away alias were
dropped instead of being attributed to the author it merged into, and two
names that only differed by unicode normalization overwrote each other
instead of being merged.
Fixes ActivityWatch#9
Greptile SummaryThis PR merges contributor identities that share commit emails across repositories, chooses a deterministic canonical display name, preserves manual aliases, and remaps blame from merged aliases.
Confidence Score: 4/5The PR should not merge until email filtering prevents malformed and shared default addresses from collapsing unrelated contributor rows. Accepted email values become transitive identity keys, but the current check admits any non-blocklisted string containing Files Needing Attention: src/contributor_stats/main.py Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Git histories across repositories] --> B[Extract mailmap-resolved names and emails]
B --> C[Normalize and filter emails]
C --> D[Group names transitively by shared email]
D --> E[Choose canonical name by commit count]
E --> F[Merge per-repository statistics]
E --> G[Remap alias blame lines]
F --> H[Repository tables]
G --> H
H --> I[Merged total table]
Reviews (1): Last reviewed commit: "fix: merge contributions by commit email" | Re-trigger Greptile |
| email = email.strip().lower() | ||
| if "@" not in email or email in GENERIC_EMAILS: | ||
| return "" |
There was a problem hiding this comment.
normalize_email accepts every non-blocklisted string containing @, including malformed values such as a@@b and shared defaults such as root@build-host. These accepted values are used directly for transitive author grouping. If unrelated contributors share one of these values, their commits and blame are incorrectly combined into one row. Validate the address structure and reject generic local or shared patterns instead of relying on four exact strings.
Fixes #9
Author names were only merged through the hardcoded
author_mergeslist, so the same person showed up as several rows whenever they had committed under different spellings of their name.What changed
a↔b,b↔c⇒ one author) and is computed across all repos at once, so a person also gets a single row in the mergedtotaltable instead of a different winner per repo.noreply@github.com,you@example.com, ...) and malformed ones are ignored, so they can't merge two people together.author_mergeslist is kept, for the aliases that don't share a commit email (dependabot-preview[bot], theErik Bjäreholtmojibake, ...).Two related bugs fixed along the way:
authorInfosinstead of being merged, losing one of them.Effect on the tables
Running against the currently cloned repos, this merges (among others):
brayoBrayo2e3sDemmiewojnilowiczŁukasz WojniłowiczErik Bjareholt,Erik BjäreholtErik BjäreholtnikanarNikanaBill-linuxBill Ang LikewdeKewdeZach SZach StroutAyushAyush SinghyuhyuhldrNicolae/nicolaeNicolae StronceaMåns MagnussonNothing else in the generated tables changes, apart from the blame percentages that shift because alias blame lines are no longer dropped.
Testing
make typecheckpasses.tests/test_main.pycovers the email normalization, the (transitive) grouping, the canonical-name choice and its determinism, and the merging inget_authorInfos— including that the manual alias list and the unicode normalization still apply. It needs no network or GitHub token.aw-client,aw-qtandawatcherand diffed the produced tables against the ones frommasterto confirm the only changes are the intended merges.