The big file was dead
The dread of an unfamiliar codebase is real and it points you at the wrong file almost every time.
I spent my first full day on an inherited store reading one file.
It was the biggest thing in the project and the developer handing it over had brought it up twice, both times with a small laugh, so of course that’s where I went. I read it the way you read something you’re scared of, which is quickly, then slowly, then a third time. I came out of the third pass no further along than the first.
The next morning I ran the log over it, mostly to find out who to blame. Last change 2018, one line, inside a merge. Before that, a real edit in 2017.
It still ran on every page load. I checked. But nothing anybody had wanted from that site in two years had needed a single line of it to move. I’d spent a day getting fluent in a room nobody goes into.
The last time I took over one of these, the terrifying file really was the business. A 200-line function every page called, and the ugliest stretch of it was a pricing rule with a comment above it telling me not to touch it, which I’d have cheerfully simplified in week one. So the instinct I brought with me was that big and ugly means important. That’s about half right, and the half it gets wrong costs you a week.
Follow the money
I should have asked the log where the work goes first, and I do that before opening anything now.
# which files this project actually works on
git log --since="2 years ago" --name-only --format=format: \
| sed '/^$/d' | sort | uniq -c | sort -rn | head
That’s every file named in every commit for two years, counted, biggest first. The sed is there because --format=format: leaves a blank line per commit, and without it those blanks sort straight to the top and sit there looking like the most edited file in the project.
71 skin/frontend/store/default/css/styles.css
58 app/design/frontend/store/default/template/checkout/cart.phtml
44 app/code/local/Store/Shipping/Model/Carrier/Table.php
37 app/design/frontend/store/default/template/catalog/product/view.phtml
29 app/code/local/Store/Checkout/Block/Onepage/Shipping.php
26 skin/frontend/store/default/js/cart.js
The stylesheet on top is true of every project I’ve ever run this on and is not information. The rest of it is. This store is a cart and a shipping calculator with a catalog attached. I got that out of one shell pipeline instead of out of three meetings.
The file I’d read isn’t in that list. It isn’t further down it either. Nothing touched it inside the window. So it doesn’t appear at all, which is an answer delivered as an absence.
A directory tree tells you how somebody once meant to organize this. The log tells you where everyone has actually been. Those are two different documents, and only one of them gets updated by accident every time anybody does anything.
It’s worth reading a hot file’s history and not only its contents, too. A few of those cart commits are reverts of each other, the same free shipping rule going in and coming back out over about a year, and that argument is nowhere in the code, because code only ever shows you who won. The ugly parts of a codebase are usually ugly because somebody lost an argument in them, and the log is the only place the argument survives.
It always feels like this
Without a procedure my first day looks like the one I just described, and it looked like that for most of my first few years.
I open the project. There’s a small unpleasant jolt of not understanding it. So I open a file, because opening a file feels like doing something. It doesn’t help, because a file on its own means nothing. So I open another one. By lunch there are 14 tabs, I’ve read pieces of all of them, and the not-understanding has compounded into something with a pulse.
That isn’t a research method. It’s a nervous habit with a text editor attached.
It took me a shameful number of years to accept that feeling lost in an unfamiliar codebase is a constant and not a signal. It’s there in hour one whether the code is beautiful or appalling, whether the project is documented or a swamp, whether you’re any good at this or you aren’t. It’s what an unfamiliar codebase feels like from the inside, and it tells you nothing about the codebase and nothing about you.
I read it as a verdict for years, which made me want it over with, which made me rush, which is the precise thing that makes it take longer.
A procedure fixes that, and not because the steps are optimal. It fixes it because on step three of six you know you’re on step three of six, so “I don’t understand this yet” becomes a schedule instead of an accusation.
Stupid question, but
Keep a file open while you read, and write down what confused you. Not notes on what the code does. Notes on what confused you.
Every “why is this here.” Every “where does this come from.” Every “I assumed X and it turned out to be Y.” They’re the most valuable thing you’ll produce that month and they last about three weeks.
- Two shipping carriers under Store/Shipping. Only one is registered in
config.xml. Is the other dead, or is something calling it directly?
- `is_wholesale` on customer_entity, set on a couple hundred rows.
Nothing I can find reads it.
- Free shipping threshold appears in three places and they disagree.
Which one does the site use?
- Why does the cart template get edited every other week?
By week three you’ll have absorbed all of them, and absorbing them feels like getting good at the project. It is instead the loss of the only outsider’s view this codebase will get until the next person arrives, who’ll be exactly as quiet about it for exactly the same reason.
At the end of the first month about half of mine have answers, and the answers go in the README, which is the onboarding document the project never had, written by the only person qualified to write it, who is the newest one on it. Knowing the project is exactly what disqualifies you from that job, so it has to happen while you’re still ignorant enough to have the questions.
Almost any order will do
The order I wrote up a few years ago is still the one I use. The site before the code, the log before the files, the manifest, the entry points, the templates, then the logic, and always with a question in hand instead of a hope of understanding.
I’d change the emphasis. I presented it as though the order were the insight, and having done this a dozen or so more times since, I don’t think it is. Almost any consistent order would do the same work. The point is having one at all, because the alternative isn’t a different order, it’s the instinct, and the instinct walks you into the biggest file in the project and keeps you there until it gets dark.
Diving in isn’t faster. It only feels like progress, at the exact hour when progress is what you want most and is worth the least. The big file will still be there in week three if it ever turns out you needed it, and for what it’s worth, I never did open it again.