DEV Community

Amir Zilber
Amir Zilber

Posted on

I built a tool that reads your git history and tells you a story

Every codebase has a story buried in its git history.

Who really owns what. Which areas are dying quietly. Whether the team is building new things or just putting out fires. Which files will become a black box if one person leaves tomorrow.

The problem: nobody reads git log. It's thousands of dry lines that nobody has time for.

So I built git-story. One command. Ten seconds. A complete narrative.

What it looks like
┌────────────────────────── git-story ──────────────────────────┐
│ flask · 3,812 commits · 662 files · 856 authors · 16y 1m │
└───────────────────────────────────────────────────────────────┘
!! STORY
-> . is the heart of this repo (1,249 commits, 204 authors)
-> examples/minitwit/static/style.css hasn't been touched
in 16.2 years — possible dead code
-> .github/workflows/pre-commit.yaml and zizmor.yaml change
together 100% of the time — they might want to be one module
-> This repo is 16 years old — it has a story worth reading
The part I find most interesting: MOOD
It classifies every commit message into one of four categories:

BUILDING — add, implement, feature, create
FIXING — fix, bug, patch, revert
CLEANUP — refactor, remove, rename, simplify
MAINTENANCE — update, bump, upgrade, docs
Then it charts how that's changed over time:

~~ MOOD — what kind of work dominates over time

  • + + + x x x x x x o o +=BUILD x=FIXIN ~=CLEAN o=MAINT This project is currently in maintenance mode. It shifted from building to maintenance over time. Flask's story: heavy feature building from 2009–2016, then a gradual shift into maintenance and stewardship. Exactly what you'd expect from a mature, stable framework — but now you can see it.

DRIFT: where is the energy going?
Compares the last 6 months vs. the prior 6 months for every directory:

// DRIFT — last 6mo vs prior 6mo
.github/workflows ^ +150% gaining — something is being hardened
src/flask ~ +12% stable
docs/tutorial vv -60% fading
src/flask/json DEAD went completely silent — possibly retired
src/flask/json going DEAD makes sense — JSON handling moved to Python's stdlib. The tool found it from commit patterns alone, without reading a line of code.

SILOS: the real bus-factor risk
This is the one that surprises people most.

Not "one person wrote 50% of commits" — that's too abstract. Instead: which specific files has only one human ever touched?

!! SILOS — files only one person has ever touched
302 of 662 files (46%) are single-owner. High risk.
David Lord (124 files)
uv.lock — 19 commits, last touched 20 days ago
.github/workflows/pre-commit.yaml — 16 commits
requirements/build.txt — 16 commits
... and 119 more
Armin Ronacher (82 files)
docs/_themes/flasky/static/flasky.css_t — untouched since 2010
docs/patterns.rst — untouched since 2010
... and 77 more
46% of Flask's files are known only to one person. If David Lord left tomorrow, the entire CI infrastructure would become a black box. That's a real organizational risk, visible in 10 seconds.

How to run it
pip install rich
curl -O https://raw.githubusercontent.com/amirzilber/git-story/main/git_story.py
python git_story.py path/to/your/repo
No other dependencies. Works on any git repository in any language.

Adjust drift window

python git_story.py . --window 3 # quarter vs quarter
python git_story.py . --window 12 # year vs year

Show more results

python git_story.py . --top 20
What's next
I want to add:

HTML export for shareable reports
A web version — paste a GitHub URL, get the story
Weekly digest: automatic diff of this week vs last week
The GitHub repo is at github.com/amirzilber/git-story. Would love to hear what "story signals" other people wish they had when joining a new codebase.

What's the first thing you try to figure out when you join a new project?

Top comments (0)