July 19, 2026

Trunk-based development when the team is just you

Listen to the summary
0:00 / 0:00
Trunk-based development for a solo developer, cover graphic for erkshitiz.com.np

For the first few months of working alone, I kept doing the thing every team job had trained into me: open a feature branch, work on it for a while, open a pull request, merge when it’s done. Nobody was reviewing those pull requests. Nobody else was pushing to the repository at all. I did it anyway, because it felt like the responsible way to write software, and it took an embarrassingly long time to notice it was actively costing me time rather than saving it.

The branch that outlived its own feature

The clearest example was a branch for adding CSV export to an internal tool. Smallish feature, maybe a day of real work. I opened the branch, did about half of it, got pulled onto something more urgent, and came back to it five days later. In those five days I’d merged two unrelated changes to main: a dependency bump and a fix to how a config value got parsed. Neither one touched the export code directly. Both of them touched files near it.

Merging the export branch back into main took longer than finishing the feature had. Not because of a real logical conflict, nobody else’s intent was competing with mine, just git seeing overlapping diffs in nearby lines and refusing to guess which version I wanted. I sat there resolving a conflict against my own five-day-old work, on a change nobody but me had ever seen, that existed purely because I’d chosen to keep it separate from main for those five days instead of one.

git checkout feature/csv-export
git merge main
# CONFLICT (content): Merge conflict in internal/export/handler.go
# CONFLICT (content): Merge conflict in internal/config/config.go

That’s not a scary conflict. It’s a fifteen-minute annoyance. But it was a fifteen-minute annoyance I had manufactured entirely by myself, for no benefit I could point to afterward.

What branches are actually for

Branch isolation exists to solve one problem: keeping your in-progress work from colliding with someone else’s in-progress work before either of you is ready to reconcile. That’s a real problem on a team. Two people editing the same file over the same few days need a mechanism that lets each of them work without stepping on the other, and a review step before the merge that makes sure the reconciliation actually makes sense to a second set of eyes.

None of that applies when there’s no second person. There’s no other work in flight to protect against, because I’m the only one producing work. There’s no reviewer whose context I need to preserve by keeping a diff small and isolated, because I’m also the reviewer, and I already have the entire context in my head from having written the thing an hour ago. The branch wasn’t protecting anything. It was just deferred integration, adding a delay between writing code and finding out whether it fits with everything else, for a codebase where I’m the only source of “everything else.”

What changed

I moved to committing straight to main in small, working increments, and reaching for a feature flag when something needs to ship gradually or land before it’s fully finished. If the CSV export had been three commits straight to main behind an export_csv flag instead of one branch held open for five days, each commit would have been tested against whatever else landed that week immediately, not five days later in a batch. Smaller conflicts, if any, resolved the same day they’re created, when the context is still fresh instead of half-forgotten.

This isn’t a claim that branches are bad. On a team, the review gate and the isolation are worth the coordination cost, because the alternative is two people’s half-finished work colliding with no chance for a second opinion first. The mistake was importing a team’s safety mechanism into a context that has none of the risk it was built for. A long-lived branch with a team of one isn’t cautious. It’s just latency, and I was the only one paying for it.