Why I like trunk-based development

For the majority of my software development career, I’ve worked with version control in a very similar way.

There are one or two long-lived branches, usually a combination of develop, master or main, that contain the production version of the code. When starting work on a new feature or bug fix, a new branch is created where the changes are made in isolation, and is submitted for review once complete. This is typically referred to as “Git Flow” or “GitHub Flow”.

Whilst those changes are awaiting review, a new task is started and the process is repeated.

Trunk-based development

Something that I’ve been practicing and advocating for lately is trunk-based development, where there’s only one branch that everyone works on, and commits and pushes to instead of creating separate per-task branches.

Even on a client project where I was the only Developer, I was used to creating per-task branches and I can recall when trying to demo two features to a client and the application broke when switching between branches.

The vast majority of the time, whether working individually or on a team, I’ve found that the per-task branches weren’t needed and working on a single branch was easier and simpler.

There are still occassions when a temporary branch is needed, but in general, all changes are made to the single branch.

Trunk-based development ties in nicely with the continuous integration approach, where everyone commits and pushes their work at least once a day - ideally, multiple times a day. This eliminates long-running feature or bug fix branches that get out of sync with the main branch as well as conflicting with each other.

It seemed scary to begin with, having been used to per-task branches and asynchronous peer reviews via pull or merge requests, but trunk-based development has made things simpler and encourages other best practices such as pair and mob programming. having a good CI pipeline to identify regressions, using feature flags to separate code deployments from feature releases, and frequent code integration and deployment via continuous commits and pushes.