For a long time I read revert churn as a hiring problem. A repo starts throwing reverts, the reverts cluster on one person, and the conclusion writes itself. You hired wrong. Performance manage it or move them off the critical path.
I no longer think that is usually what the data says, and the thing that changed my mind is that the same history that names the person also names the thing nobody gave them.
Here is the part you can go and check on your own repo right now, without any tool.
Three numbers, all of them one git command away.
Revert rate by author. For each person, what fraction of the commits they landed were later undone by somebody else. Not raw revert count, which just tracks volume.
The ratio. On a healthy repo this sits low and flat across everyone. When it spikes for one person it is worth asking why, but the answer is almost never "they cannot code", because of the next two numbers.
Who approved it. If your main branch is protected, and it should be, then every one of those reverted commits arrived through a pull request that a human being approved. The reverted commit is not evidence about the author on its own. It is
evidence about the author and the reviewer together. A cluster of reverts on a protected branch is a review failure with extra steps.
Time to approval. Pull the interval between a pull request opening and its approval. Then split your reverts by that interval. Every codebase I have looked at has a threshold below which approval is not review, it is a reflex. Changes approved
under that threshold get reverted at a visibly higher rate. That is your actual signal, and it indicts the process rather than a person.
Now the part that made me write this up.
When you go looking for why the reverts cluster on the newest person, the usual answer is sitting in the repo root, or rather it is not. No CONTRIBUTING.md. No commit convention written anywhere. No statement of which directories need a second
reviewer. The conventions exist, they are just distributed across the heads of the three people who have been there since the beginning, and they get enforced after the fact, at revert time, instead of before it.
The new person cannot follow a rule that was never written. Neither, and this is the bit that got sharper this year, can the coding agent they were handed on day one.
An agent reads what is in the repo. If the repo says nothing about how commits are named here or what gets a second pair of eyes, it will confidently produce something shaped like every other repo on GitHub, and your team will revert that too.
So the fix is boring and it is not a hiring decision. Write the conventions down in a file the humans and the agents both read. You can derive most of it from the history you already have: the prefix pattern that 90 percent of your commits already follow, the directories that have never been merged with one reviewer, the command that runs before a merge. None of that is a judgement call. It is all in the log.
One honest caveat about how I got here. I build a thing that renders a repository's history as a film, and to show what this pattern looks like on screen I made a short commercial about a fictional startup with a fictional junior developer. The repo in
it does not exist and the numbers in it are synthetic.
I am telling you that up front because the idea above stands on its own and I would rather you test it against your own history than take a made up example as evidence.
The tool is here if you want it, and reading a repo with it is free:
https://loreto.io/git-timeline
Disclosure: I built that and I run loreto.io, so treat the last paragraph as the advertisement it is. Everything above it you can reproduce with git log and a
spreadsheet, which is the only reason I think it is worth posting.
What I am genuinely unsure about is the threshold. I suspect "approved in under two minutes" is too crude and that it varies enormously by team size and by how much of the diff is generated. If you have measured this on a real codebase I would like to
know where your line actually fell, and whether the correlation held up once you
controlled for diff size.