We built a little script to count our own commits per day, because we wanted an honest number for “how much did we actually ship.” The first day we ran it, the tool told us we made 134 commits across 13 repositories. That felt great for about ten seconds, until we looked at the per-repo breakdown and realized the number was almost entirely a lie. Not a rounding error. The real figure was under 25 unique commits, and the gap was hiding in two places we had stopped thinking of as duplication at all.

Here is the breakdown the script spat out:

legacy-site-repo 13
renamed-site-repo 13
local clone 10
local clone 2 10
local clone 3 10
local clone 4 10
local clone 5 10
local clone 6 10
local clone 8 10
local clone 9 10
local clone 10 10
local clone 7 9
site-archive 9

Two things jump out if you stare at it. The two 13s are suspiciously equal. And there is a column of nines and tens that is obviously one number wearing ten hats.

The mirror: two names, one history

legacy-site-repo and renamed-site-repo were the same project. One was the original repository name and the other the migration target; during the transition both directories and remotes existed on disk. We had stopped seeing them as the same thing because they live in different folders with different names, and it is easy to treat a folder name as an identity.

Git does not. When we pulled the commit list out of each, the SHAs were byte-identical. They were the exact same hashes, not similar commits made around the same time: a7e6cb5, 6f89781, 01368a5, 26b6797, and the rest, present in both repos. A commit ID identifies the same commit object and history position in both views. If two repositories show the same SHA, that is one commit that two directories can both see, and it is one piece of work.

So those 13 commits in renamed-site-repo are the same 13 commits in legacy-site-repo. Our script counted every one of them twice. Thirteen real commits became 26 in the total.

The clones: one fix, seen ten times

The site block is the same disease with a bigger blast radius. We run a SaaS platform under IIS, and our local dev setup is ten clones of the same repo, local clone through local clone 10, each bound to its own local site so we can have several branches live in browsers at once without a build dance. They are ten working copies of one project, and they fetch from the same origin.

So when the day’s ten commits land, every clone that has fetched develop sees those same ten SHAs. The script dutifully reported “10 commits in local clone, 10 in local clone 2, 10 in local clone 3,” all the way down. That is ten commits observed ten times, which is not 100 commits. (local clone 7 and site-archive showed nine because they had fetched slightly stale, which is its own tell: when “identical” repos disagree by one, the difference is fetch timing, not work.)

Add it up. Thirteen mirrored commits, ten unique site commits multiplied across eleven clone directories, and the inflated 134 collapses to roughly 23 unique commits once you dedupe. The metric we built to keep ourselves honest was off by nearly 6x in the flattering direction.

Why a directory is the wrong unit

The bug is conceptual. We were counting commits per repository directory, and we were implicitly assuming one directory equals one stream of work. In a normal layout that assumption holds well enough to be invisible. In any workflow with mirrors, clones, or worktrees it is just wrong, and it is wrong in the direction you least want a self-measurement to be wrong: it tells you you did more than you did.

The clone-heavy setup makes it acute, but you do not need ten clones to get bitten. Any of these will do it:

  • A repo mid-rename or mid-migration with both old and new directories on disk.
  • A mirror clone you keep for backup or for a second remote.
  • Git worktrees, where one repository legitimately checks out across several directories.
  • A fork you cloned next to the upstream you also cloned.
  • A monorepo you also vendored into another project as a subtree, which shares commit history.

Every one of these puts the same SHAs in more than one place, and any tool that sums “commits per directory” will multiply your output by however many copies you happen to have lying around.

The fix is one line of intent

The fix is embarrassingly small once you name the unit correctly. The unit of work is the commit, identified by its SHA, not the directory it happens to be visible from. So you gather every commit SHA from every repo, throw them in a set, and count the set.

Terminal window
# Naive: counts each clone's view separately, multiplies by copy count
for d in */; do
git -C "$d" log --since=midnight --oneline | wc -l
done | paste -sd+ | bc
# Honest: union of unique SHAs across every repo, counted once
for d in */; do
git -C "$d" log --since=midnight --author="you" --format='%H'
done | sort -u | wc -l

The difference between those two snippets is sort -u, and that one detail is the entire post. The first answer flatters you in proportion to how many copies of your repos you keep. The second answer is the same no matter how many clones, mirrors, or worktrees are on disk, because a set does not care how many times you hand it the same element.

If you want the number to mean something, dedupe before you aggregate, and key the dedupe on the SHA. The same logic extends to anything you derive from git: lines changed, files touched, “active days,” tickets referenced in commit messages. Sum them per directory and your mirrors and clones inflate every figure. Union them by commit hash and you get the real number.

The wider point: self-instrumentation lies in the flattering direction

What stuck with us afterward was the direction of the error, more than the off-by-6x. We built this to keep ourselves honest, and the default implementation lied in exactly the way that would have felt good to believe. A metric that overcounts output is a metric nobody is motivated to audit, which is precisely why it survives.

The general rule we took from it: when you instrument yourself, assume the first version is optimistic and go looking for the double-count before you trust the trend line. The check is cheap. Pick one suspiciously round or suspiciously high day and verify it by hand against the underlying objects. If the per-directory numbers come in pairs of equal values, or in a long flat run of the same count, you are looking at copies, not work.

Commit hashes are content addresses. Treat them as the identity of the work, not the folders they live in, and your numbers stop lying to you.

Takeaway

If a report counts engineering output per repository folder, ask whether it dedupes on the commit ID first. In our case a per-directory count reported 134 commits against roughly 23 unique commits, because mirrors and local clones showed the same commits repeatedly. A metric that overcounts output is one nobody is motivated to audit, so verify one high day by hand before trusting the trend.