# Tracing Who Actually Wrote a Library From Its Commit History

*You will take any public repo and name the engineer who owns its core subsystems, separating real authorship from bot noise and formatting churn, with commit data to back it.*

- Canonical URL: https://www.refolk.ai/guides/who-wrote-the-library-commit-forensics
- Pillar: Engineering and open source
- Format: Teardown
- Published: 2026-08-02
- Last reviewed: 2026-08-02
- Reading time: 17 min
- Keywords: who wrote most of a github repo, identify code owner from commit history, find the real author of an open source project, git blame find contributor to hire, find github contributor email

## Key takeaways

- Commit count is a weak proxy for authorship: a maintainer who merges everything and a formatting bot both top `git shortlog`, so ranking by it names the wrong person.
- In Refolk's index, 964 US software and senior-software engineers list Rust as a skill, but adding an 'open source maintainer' headline keyword dropped that count to 0 - nobody self-labels as a maintainer, which is why you must attribute code instead of searching titles.
- Roughly 81.5% of GitHub contributions in 2025 happened in private repositories, so a public repo is a floor on an engineer's real output, never a ceiling.
- Squash merges break attribution: before December 2019 the PR opener became the sole author, and a regression around 2020-03-04 shifted authorship to the merging bot, so you must read `Co-authored-by:` trailers to recover the writer.
- Blame modifiers `-w`, `-M`, `-C`, and `--ignore-revs-file` strip whitespace churn, moved lines, copied lines, and bulk formatter commits so a reformat does not steal authorship.

You found a repository your team admires or a competitor depends on, and you want to recruit the one or two engineers who actually wrote its core. This guide is for engineering managers, technical founders, developer-relations leads, and technical sourcers who need to turn a repo into a named, verified hire target. It carries one worked example all the way from clone to a named engineer with a current employer, showing the real commands, the intermediate counts, and the wrong turns.

Most GitHub-sourcing advice stops at "look at the contribution graph and pinned repos" and treats a repo as a flat list of usernames. That misses the forensic work: separating the person who wrote the core logic from the maintainer who merged it, the bot that formatted it, and the drive-by fixer who patched a typo. This is that work.

## Why a repo's top committer is usually the wrong person to recruit

The person at the top of `git shortlog` is frequently not the person who wrote the code you admire. Commit count rewards whoever merges, formats, and bumps versions, not whoever designed the subsystem.

Here is the trap in plain terms. Commit count is not a good measure of contribution, and it only works when a team has an agreed commit style everyone follows - which almost no open source project has. A maintainer who squashes and merges every pull request accumulates hundreds of commits without writing a line of the logic. A formatting bot that runs on every push can out-commit every human. Rank by that number and you will draft an outreach message to the wrong engineer.

The deeper reason you cannot shortcut this with a search is that the people you want do not label themselves. In Refolk's index of professional profiles, 964 US engineers with a Software or Senior Software Engineer title list Rust as a skill. Add "open source maintainer" as a headline keyword to the same query and the count drops to zero. Nobody writes "maintainer" in their headline. The evidence of who built the thing lives in the commit history, not in a self-reported profile field.

**0 - US Rust engineers in Refolk's index who self-label as "open source maintainer"**

The same query without that keyword returns 964, which is why authorship must be traced from commits, not titles.

So the job splits into two halves. First, forensic attribution: name the engineer who wrote the core, with commit data to back it. Second, sourcing: map that identity to a live person you can reach. This guide does both, in order.

## The one repository we will trace, and the shape of the method

I will carry a single hypothetical target through every step: a widely-used vector-database library with a busy history, a formatting bot, squash merges, and a vendored dependency checked into the tree. Those four things are exactly the noise sources you must strip, so it is a fair stand-in for whatever repo you are looking at.

The overall shape is a funnel. You start with everyone who ever touched the repo and narrow, at each stage, to the person who owns the code that matters.

#### From every contributor to one hire target

| Stage | Figure | Note |
| --- | --- | --- |
| All author identities (git shortlog) | 340 | raw rows, before dedup |
| Distinct humans (after .mailmap) | 190 | identity fragments merged |
| Touched a core file | 24 | excludes docs, tests, vendored |
| Own surviving core lines (post-noise-strip) | 3 | real logic authorship |
| Named target with current employer | 1 | verified, reachable |

*Each stage removes a category of noise until one named owner of the core remains.*

The counts above are illustrative of the shape, not measured facts about a specific repo. What matters is the narrowing: 340 identity rows collapse to 190 humans, only 24 of whom touched the core, and only three of those own meaningful surviving logic once formatting and refactor noise is stripped.

> **Note:** Ordering is a genuine fork
>
> Some practitioners run a tree-level tool like git-who first for triage, then blame the core files. Others blame the core files directly and never run repo-wide stats. Both are defensible; this guide blames the core because it produces fewer false positives on large repos.

## Step one through four: from clone to noise-free blame

The first half of the procedure gets you from a fresh clone to a blame output that reflects who wrote logic, not who reformatted it. These four steps do the unglamorous cleanup that everything downstream depends on.

Start by cloning and running a first-pass ranking:

```
git clone <repo>
git shortlog -sne --all
```

`git shortlog -sne` gives per-author commit counts with emails: `-s` summarises, `-n` sorts by count, `-e` shows the email. Read this as triage only. In our vector-database example, the top row was a `github-actions[bot]` with hundreds of commits, and the second was the project's lead maintainer. Neither wrote the core distance-metric code we cared about. That is the wrong turn the published guides walk you straight into.

Next, deduplicate. The same human often appears as several rows because they changed their commit name or email over the years. Add a `.mailmap` file to the repo root: if a `.mailmap` file exists it is used to map author email addresses to a real author name, one mapping per line. A line like `Real Name <canonical@example.com> <old@example.com>` folds two rows into one. After this, one human occupies one row, and your counts stop lying by fragmentation.

Then isolate the core. Pick the directory or files holding the library's actual logic and ignore tests, docs, config, and anything vendored. In the example, the core lived under `src/index/` and `src/distance/`; a checked-in `vendor/` dependency and a generated `proto/` directory were pulled in by an early contributor who wrote none of it. Attributing those would have credited a drive-by import as core authorship.

Now strip formatting and refactor noise, the step that fixes the most common false positive. A single Prettier, Black, or clang-format commit rewrites every line in a file, and blame then attributes the whole file to whoever ran the formatter. You see one person was last to modify a file and quickly realize it was a singular formatting commit. The fix has two parts.

**Noise-free blame on a core file**

```
# 1. Put full 40-char hashes of bulk reformat/refactor commits here:
#    .git-blame-ignore-revs (repo root)
#    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2   # ran clang-format across tree
#    (comments allowed; each hash must be the full 40 characters)

# 2. Blame the core file, ignoring churn:
git blame -w -M -C --ignore-revs-file .git-blame-ignore-revs src/distance/cosine.rs
```

*Replace src/distance/cosine.rs with your core file. Collect formatter hashes into .git-blame-ignore-revs first.*

`--ignore-revs-file` support arrived in Git 2.23. When a revision is ignored, the lines it changed are reassigned to the previous commit that modified them, so the formatter no longer holds authorship. GitHub also picks the file up automatically for its own blame view if it is named `.git-blame-ignore-revs`. Each of the other modifiers corrects a distinct distortion.

| Modifier | Corrects for |
|---|---|
| `-w` | whitespace-only reformat churn |
| `-M` | lines moved within a file |
| `-C` | lines copied from another file |
| `--ignore-revs-file` | bulk formatter/refactor commits |

Run blame without these flags and then with them on the same file. In the example, the unadorned blame credited the lead maintainer with 60% of `cosine.rs` because they had run a tree-wide `clang-format`. With the formatter commit ignored and `-M -C` set, that dropped to under 10%, and a different engineer surfaced as the real author of the metric logic. That reversal is the whole point of the exercise.

## The full procedure, start to finish

Below is the complete sequence, each step with a done-state so you know when to move on. Steps one through four are the cleanup above; five through eight resolve ownership and turn it into a reachable person.

#### Trace a library's core author from clone to verified target

1. **Clone and orient** - Clone the target and run `git shortlog -sne --all` for a first-pass ranking of commit counts and emails. Treat the count as triage only, not truth.
2. **Deduplicate identities** - Add a `.mailmap` mapping author emails to one canonical name so one human is one row. Done when duplicates from name or email changes are folded.
3. **Isolate the core subsystem** - Choose the directories holding the library's logic and exclude tests, docs, config, and vendored code. Done when you attribute only code that matters.
4. **Strip formatting and refactor noise** - List bulk reformat commit hashes in `.git-blame-ignore-revs` and re-run blame with `-w -M -C --ignore-revs-file`. Done when blame reflects logic, not churn.
5. **Rank surviving-line ownership** - Run `git blame --line-porcelain | sort | uniq -c` per core file, or git-ownership for surviving-lines-over-time. Done when you have a per-subsystem owner.
6. **Resolve squash and merge distortions** - For top files, inspect `Co-authored-by:` trailers and author-versus-committer fields. Done when the writer is named, distinct from the merger or bot.
7. **Recover the outreach email** - Append `.patch` to a commit URL or run `git log --format=email` to read the From header. Done when you have a verified email or a documented noreply block.
8. **Cross-check against the live profile** - Map the GitHub identity to a current employer and role. Done when you have a named target with a current company.

For step five, the surviving-line count is the number that matters. Run this per core file:

```
git blame --line-porcelain -w -M -C --ignore-revs-file .git-blame-ignore-revs src/distance/cosine.rs \
  | sed -n 's/^author //p' | sort | uniq -c | sort -rn
```

This counts the lines currently attributed to each author after all your corrections. Do it across the handful of core files and you get a per-subsystem owner rather than a repo-wide committer. Tree-level tools help here too: git-who answers who contributed most significantly to specific parts of a codebase over time, and handles the large-refactoring case that plain blame mishandles. git-ownership walks the full history and renders surviving lines per author over time to a single HTML file, which is useful when you want to see whether an author's ownership is rising or being replaced.

> **Rule:** Surviving lines, not total lines, name the owner
>
> Attribute by lines that survive in the current tree after ignoring formatter and refactor commits. A person who wrote 2,000 lines that were later rewritten owns none of the code you are looking at today.

## Resolving squash merges, the trap that hides the real author

Squash merges are the single biggest reason the wrong name surfaces, because Git records author and committer separately and squashing collapses them. The author is the person who initially wrote the change; the committer is updated when the commit is applied later as a patch by someone else during integration.

Squash-and-merge combines a pull request's commits into one commit. The attribution behaviour has changed twice, and both changes are traps you must know about.

| Period | Who the squash commit credits as author |
|---|---|
| Before December 2019 | The person who opened the PR, as sole author |
| After December 2019 | Every commit author credited as `Co-authored-by:` |
| After ~2020-03-04 (regression) | The merging bot appears as author |

Before December 2019, whoever opened the pull request became the sole author of the squash commit, even if a colleague wrote every line. After December 2019, GitHub credits every commit author in the PR as a co-author. Then a regression dated around 2020-03-04 made merge commits show the bot name as author. So the headline author of a squashed commit is unreliable across all three eras.

The recovery is always the same. Open the blamed commit and read two things: the `Co-authored-by:` trailers in the commit message, which list the real writers, and the AuthorDate versus CommitDate fields, where a gap signals the change was written earlier and integrated later by someone else. In the example, the blame for the core index file pointed at a squash commit whose headline author was the maintainer; the `Co-authored-by:` trailer named the engineer who actually wrote it, and their AuthorDate was three weeks before the CommitDate. That trailer was the hire target.

> The headline author of a squashed commit is a receipt for the merge, not a claim on the code.

This is also where a search tool earns its place. Once forensics have named the engineer, you still have to find every other person who fits the same profile so you are not recruiting a sample of one. Describing the shape in plain English is faster than reconstructing it from filters.

I ran this search: `Engineers in the US who list Rust and have contributed to open source systems projects, not at Google or Meta.` - [see the full result list](https://www.refolk.ai/s/pv601v7xc7).

*Returns named US systems engineers with public open source history, excluding the two employers you already know hire heavily in this pool.*

For context on where those engineers sit today: in Refolk's index, the top employers of US Rust engineers in the sample are Oxide Computer Company with three, Google with two, and Meta with two. That tells you which companies you are competing with before you write a word.

## How this goes wrong: the false positives that name the wrong engineer

Every step above exists to defeat a specific way attribution lies. Here are the eight failure modes, what each one produces, and the check that catches it. This is the part of the method worth memorising, because a confident wrong answer here wastes an outreach and burns credibility with the candidate.

- **Ranking by commit count.** A bot or a merge-heavy maintainer tops `shortlog` while writing none of the logic. Check: exclude merge commits and inspect the actual diffs, not the count.
- **Blaming a reformat commit.** One person appears to own a file because a single Prettier or clang-format commit rewrote every line. Check: build `.git-blame-ignore-revs` and re-run blame.
- **Squash-merge masking.** The PR opener or the merging bot shows as sole author. Check: read `Co-authored-by:` trailers and compare AuthorDate to CommitDate.
- **Identity fragmentation.** One person appears as several rows after changing their commit name or email. Check: apply a `.mailmap`.
- **Noreply email dead end.** The `.patch` view returns a `users.noreply.github.com` address that routes nowhere. Check: pivot to the GitHub username and profile instead of the email.
- **Fork confusion.** A fork carries the upstream's full history, so its "top authors" are the original project's, not the forker's. Check: confirm the repo is not a fork and diff against upstream.
- **Vendored or generated code.** Attribution credits a checked-in dependency or build artifact. Check: exclude those paths, for example with `--exclude-regex '^vendor/'`.
- **Private-work blind spot.** A thin public trail understates a strong engineer. Check: treat public output as a floor and corroborate with talks, releases, and profile history.

> **Watch out:** Fork confusion will name a stranger
>
> A fork inherits every commit from upstream, so its author ranking is the upstream project's ranking. If you blame a fork thinking it is the source, you will "discover" and try to recruit engineers who never touched the fork. Confirm the repo is the canonical source before you trust a single number.

The last failure mode deserves the most humility, because it is structural rather than a mistake you can command your way out of. The public commit graph shows only a fraction of any engineer's work.

## The attribution ceiling: what commit history cannot tell you

Public commit forensics can only ever see a minority of an engineer's real output, so treat everything you find as a floor on their ability, never a ceiling. The share of GitHub work that happens in private has been growing and is now the large majority.

| Octoverse year | Public contribution share | Private contribution share |
|---|---|---|
| 2022 | ~20% | ~80% |
| 2024 | ~18% | 82%+ |
| 2025 | ~18.5% | 81.5% |

In 2025, 81.5% of contributions happened in private repositories, even though public and open-source projects still made up 63% of all repositories on the platform. The prior year was similar: more than 82% of contributions were private, across more than 181 million private repositories carrying 4.3 billion contributions in 2024. The public shares for 2024 and 2025 above are derived as 100% minus the published private share.

The practical consequence is simple. If your target has a thin public trail, that is not evidence they are weak. Roughly four-fifths of what they do is invisible to you. Corroborate with conference talks, release notes where they are credited, and their profile history before you decide either way. Conversely, a rich public trail is strong positive evidence precisely because it is voluntary and rare.

#### What each layer of evidence proves about an engineer

1. **Self-reported profile** - Weakest. Titles and skills, easy to inflate, and rarely mention "maintainer" at all.
2. **Public commit forensics** - Verifiable but partial. Names who wrote the core, covers roughly one-fifth of real output.
3. **Talks, releases, credited work** - Corroborates the private four-fifths and shows judgement beyond code.
4. **Current role and employer** - Tells you reachability and who you are competing with.

*Public commits are the narrowest and most verifiable layer; the layers above fill the private-work blind spot.*

## Recovering the email and closing the loop

Once forensics have named the writer, get a reachable address and confirm the person is live. The reliable route is the patch view: find any commit by the person on GitHub and append `.patch` to the URL. It renders the commit as a Git patch email, and the From header carries the committer's name and address. From a clone, `git log --format=email` or `git shortlog -sne` exposes the same author emails.

This fails cleanly when the account has email privacy enabled. In that case the address is a `users.noreply.github.com` no-reply that cannot be changed and routes nowhere, which by design prevents tools from harvesting authors. When you hit that wall, do not guess an address; pivot to the GitHub username and the public profile, and reach the person through their site, a talk bio, or a professional profile instead.

Then close the loop by mapping the GitHub identity to a current employer and role. A verified author with a stale employer is not yet a target. This last cross-check is where forensics ends and sourcing begins, and where describing the whole cohort in plain English beats reconstructing it from filters. [Refolk](/) takes a description like "senior engineers who wrote the parser or compiler internals of a popular open source project" and returns named people with current employers, which turns your single forensic result into a shortlist you can actually run a search against.

#### Before you write the outreach message

- [ ] Ranking is by surviving core lines, not by commit count.
- [ ] A `.mailmap` has folded the target's duplicate identities into one row.
- [ ] Bulk formatter and refactor commits are listed in `.git-blame-ignore-revs` and blame was re-run with `-w -M -C`.
- [ ] The blamed commit's `Co-authored-by:` trailers and AuthorDate-vs-CommitDate confirm the target wrote the code, not merged it.
- [ ] The repo is confirmed not to be a fork of the real source.
- [ ] Vendored and generated paths were excluded from attribution.
- [ ] You have a verified authoring email, or you have documented a noreply block and a profile-based route instead.
- [ ] The GitHub identity is mapped to a current employer and role.

## Keeping this repeatable

Turn the one-off teardown into a reusable check so the next repo takes minutes, not an afternoon. Save your `.git-blame-ignore-revs` conventions and the surviving-line one-liner as a shell function you can point at any core file. Keep a short note per repo recording which directories are core, whether it is a fork, and which formatter it uses, because those three facts drive every correction above and rarely change.

Re-run the attribution when the repo has a major release or a visible refactor, since ownership of surviving lines shifts as code is rewritten. The mechanism to re-check is the same each time: blame the core files with noise stripped, read the `Co-authored-by:` trailers on the top commits, and confirm the named engineer's current employer before you reach out. The numbers will move; the method does not.

## Frequently asked questions

### How do I find who wrote most of a GitHub repo, not just who committed most?

Do not rank by commit count. Run `git blame --line-porcelain file | sed -n 's/^author //p' | sort | uniq -c | sort -rn` on the core files, with `-w -M -C` and a `.git-blame-ignore-revs` file to strip formatting and moves. That counts surviving lines of real logic per author, which is a far better proxy for who wrote the subsystem than `git shortlog`, where a merging maintainer or a bot rises to the top.

### How do I get a GitHub contributor's email for outreach?

Find any commit by the person on GitHub and append `.patch` to the URL; the From header of the resulting patch email carries the author name and address. From a local clone, `git log --format=email` or `git shortlog -sne` exposes the same. This fails when the account has email privacy enabled, in which case you get a `users.noreply.github.com` address that routes nowhere, and you should pivot to the username and public profile.

### Why does git blame show one person owning a file they did not write?

Usually a bulk reformat. A single Prettier, Black, or clang-format commit rewrites every line, so blame attributes the whole file to whoever ran the formatter. List that commit's full 40-character hash in `.git-blame-ignore-revs` and re-run blame with `--ignore-revs-file`; the ignored lines get reassigned to the previous commit that touched them. Large refactors and file moves cause the same illusion, which `-M` and `-C` correct.

### How do squash merges break authorship attribution?

Before December 2019, whoever opened the pull request became the sole author of the squash commit. GitHub now credits every commit author as a `Co-authored-by:` trailer, but a regression around 2020-03-04 caused merge commits to show the bot name as author. So the squash commit's headline author is unreliable; read the `Co-authored-by:` trailers and compare AuthorDate to CommitDate to recover who actually wrote the change.

### Is a thin public GitHub trail proof someone is a weak engineer?

No. Roughly 81.5% of GitHub contributions in 2025 happened in private repositories, so most of any engineer's real output is invisible to public forensics. Treat a public repo as a floor on their work, not a ceiling. Corroborate a thin trail with conference talks, release notes, and their profile history before you conclude anything about their strength.

---

*From the Refolk guide library. I revise these guides rather than replacing them, so the current version is always at https://www.refolk.ai/guides/who-wrote-the-library-commit-forensics*
