Chapter 1. Introduction: What Is Trunk-Based Development?

Software development often goes wrong. And it can be bad. Sometimes really bad. But there are things you can do that not only make it less bad but actually make it go well. And trunk-based development is one of those things. Trunk-based development brings you better code faster and makes your developers happier. Better. Faster. Happier.

Trunk-based development (TBD) is a technique that many professionals advocate enthusiastically,1 and it’s one that I’ll argue is essential for continuous integration. But despite continuous integration being a widely known term, surprisingly few software developers have any experience with TBD. It’s also quite controversial: people can react strongly against the changes required to fully adopt TBD.

So who or what is TBD for? It’s unlikely to be appropriate for contexts such as open source projects, where often the contributors do not know one another and their collaboration occurs sporadically and over long time periods. But as long as contributors to a codebase are able to collaborate closely, TBD is very effective. It’s not a technique that can be adopted lightly: you’ll also need to learn and adopt several associated practices to reap the benefits of TBD, and if you’re not used to them, that part of it will be nontrivial. You can’t just flick a switch and turn TBD on. But the skills needed for TBD are all incredibly valuable; thus they should be viewed as benefits of, as well as prerequisites for, TBD.

So what is trunk-based development? It’s possible to guess, if you know that trunk in this context means the main branch of your code. The idea is that you develop all your code in that one branch. No other branches—just the one. What’s more, you and your colleagues should aim to merge small changes from your machine to that same branch several times a day, such that the code builds continuously, with all tests passing. And as a result, you and your colleagues will always have the latest version of all the code.2

I have a lot more to tell you about trunk-based development, but I’ll start by painting a picture of what happens when software development goes wrong. Then I’ll encourage you to imagine: what if things could be better? What if you could have nirvana? What even is nirvana? I’ll give you my definition, which is “better, faster, happier.” But how can we get there? That’s where TBD comes in.

When Software Development Goes Wrong

Software projects can go wrong in lots of different ways. As developers, our lives can be made miserable by:

Merge hell

You try to merge code from two or more sources, but the result is so tangled that you struggle to see a way forward. Nothing builds. You can’t tell which code came from where, or how to combine two or more differing intentions in a way that makes sense. In an effort to make sense of one part, you might unintentionally remove code from another part. Maybe tests fail or code won’t build in ways that are hard to understand or rectify. Perhaps you have to abandon the merge altogether, or re-create key parts of the code by hand. (More about this in Chapter 2.)

Moving slowly

You thought you’d be finished with this feature by now, but you keep encountering new problems. Every time you estimate a new end time, you fail to achieve it. Your colleagues, your managers, other departments, your users...all are getting restless and putting more and more pressure on you to move faster and get the project done. The increasing stress only adds to the pain. You don’t move faster. You feel miserable.

Technical debt

You know your code has problems, but you don’t have time to fix them. People complain about quality and about the speed of delivery. You and your colleagues start to blame each other for the code’s imperfections. Poor code accumulates on top of poor code as you bodge and fix your way through, and the longer this goes on, the worse it gets.

What If Things Could Be Better, Faster, Happier?

What if every merge was small and trivial? What if you knew your colleagues’ code almost as well as you knew your own? What if you could deliver working code several times a day? What if your code was healthy and of high quality? What if it was easy to understand, well factored, modular, loosely coupled, and highly cohesive?

How could that be? Well…why do you write code? Most individuals, teams, and companies would cite two reasons:

  • “Creating software is intrinsically satisfying.”

  • “We want to create a quality product.”

Many details are hidden within these deceptively simple statements. What you and I find satisfying about software development might differ. Your definition of quality might be different from mine. But regardless of the details, these two statements can lead you to two goals:

  • To enjoy your job

  • To deliver a quality product

I’m defining quality here as “resulting in value,” again recognizing that value will be defined and measured differently in different circumstances, and that the recipients of value will vary, within companies as well as between companies.

Many people—myself included—believe that the most effective way to create quality software is via continuous delivery, in which the value of the software is increased continuously in small increments. Since this report is concerned specifically with the coding part of the software development equation, I’ll be focusing on getting the value of the code to increase quickly, via small increments. This brings me to the following desired outcomes:

  • Happy software developers

  • Quality code whose value increases quickly—that is, better code faster

My argument is that TBD provides both, which is why these two outcomes are at the core of my belief that TBD is the best way to develop software.

Code is valuable if it maximizes your ability to deliver a valuable product. I want to be able to continuously maintain and increase the value of that product, so I want to be able to continuously maintain and increase the ability of the code to support that goal. If quality means “resulting in value,” then code is of high quality when it can be changed and enhanced quickly and easily, thus releasing value on a continuous basis.

TBD and its associated practices give you code that can be changed, enhanced, and therefore integrated quickly and easily, which means:

  • The whole team benefits from code enhancements as soon as they are made.

  • You don’t have to guess what other code your code needs to integrate with—you can see it.

  • You get fast feedback about your code. That means you can quickly discover and fix any issues caused by integrating your code with your colleagues’ code, and you can quickly discover whether your code improvements are having the desired effect.

  • Responsibility for the code’s quality does not rest on any one person’s shoulders.

Let’s look more closely at that last statement. It’s tempting to get hung up on the code itself and forget that software development is a collaborative activity. We have to work together to get the job done. People matter, and collaboration is a core part of what makes trunk-based development work.

You could argue either that better code faster leads to happier developers, or that happier developers lead to better code faster. The two outcomes are not independent. Which one you care about more will depend on your point of view, but either way, I want to give you the option of hugging some geek joy close to your chest.

Chapter 2 will list the benefits of trunk-based development in much greater detail, but each benefit will bring us back to happier developers and to better, faster code.3

Isn’t Trunk-Based Development Just Continuous Integration?

Continuous integration (CI) is a term that was originally coined by Kent Beck in the late 1990s as one of the 12 core practices of Extreme Programming. In Chapter 16 of Extreme Programming Explained (Addison-Wesley), Beck writes: “No code sits unintegrated for more than a couple of hours. At the end of every development episode, the code is integrated with the latest release.” In other words, you are integrating your code with all of your colleagues’ code...continuously.

Continuous integration means integrating any new code with the rest of your codebase. The ideal is that every developer has all their colleagues’ latest code on their machine. Any divergence is both small and short-lived, and after integration, the code still compiles and the tests pass.

When advocates of CI say continuous, we mean “all the time.” Constantly. Repeatedly. And going by Beck’s definition, if you’re not doing trunk-based development, then you’re not really doing continuous integration.

People have been practicing CI—and therefore TBD—ever since Beck coined the term. But these days many use the term CI to describe a branch-based approach to development, straying from Beck’s original definition.4

This semantic diffusion has meant that a lot of proprietary pipeline-coordination tools have the name “continuous integration” attached to them, even though they’re not used in a way that fits Beck’s definition.5 CI cannot happen without TBD. But it is technically possible to practice TBD without practicing CI, because you could keep all your changes on your local machine and rarely merge with the remote main branch. So I’ll use the term continuous trunk-based development (CTBD) in places where there might be any doubt about what I mean.

Continuous Integration Enables Continuous Delivery

Have you ever waited weeks for a feature to be finished and deployed, only to discover that it doesn’t meet users’ needs, or that your new feature is already out of date or hard to integrate?

Continuous delivery (CD) describes the practice of deploying your code with everything it needs to be live and fully functional to the customer…continuously. The faster your users can see what you’ve built, the faster they can let you know whether you’re fulfilling their needs and desires. If not, or if their needs and desires have changed, it’s better that you discover that quickly, before you’ve invested lots of time and effort into building the wrong thing in the wrong way.

The scope of this report is restricted to TBD and CI, which are concerned purely with code. I’ve had to be disciplined to avoid straying any further into discussions of CD. But my contention is that CD is impossible without CI. CD aims to take every product change through to production continuously and seamlessly (as long as the change passes various tests). If you don’t integrate every code change with all other changes (continuous integration), then CD simply can’t happen. So CI is a precursor to CD, and CD is highly desirable. But this report is focused on the CI piece of the software development puzzle.

OK, Tell Me More!

As you’ve no doubt gathered, this report makes the case for using trunk-based development. My aims are to persuade you that TBD is worth considering if you’re not doing it already, and then to help you get started on using this powerful technique. Chapter 2 looks at how and why TBD can make your code better, your integration faster, and you happier. Chapter 3 looks at how it’s done and takes you through some important skills and practices. Chapter 4 is all about why people matter (they do, they really do).

But if you normally develop in feature branches, you might wonder:

  • How can I get my code reviewed without branches and pull requests?

  • What if I need branches and pull requests for regulatory compliance?

  • What if I want to create short-lived branches?

  • Won’t frequent integrations and merges just slow me down?

  • What if I’m working on a proof of concept or a knotty bug?

  • What if I’m working on an open source project?

  • What if I’m working on untested or tightly coupled legacy code?

  • What if my colleagues don’t want to practice TBD?

If this is you and you’re dying to get answers to these questions, feel free to skip ahead to the relevant sections in Chapter 5.

1 See, e.g., articles by Trisha Gee, Eli Mydlarz, and Dave Farley.

2 These days it feels like we can mostly take source control for granted, but there are still tiny pockets of people who don’t use a version control system such as Git or Team Foundation Version Control. This report is all about the “trunk,” or main branch, which implies one of these systems. You need a single source code repository.

3 When I say faster, I do not mean that everyone is driving themselves into an early grave by working at breakneck speed. Thinking takes time, and our brains need room to breathe. I mean that the gaps between stages are as small as possible so that you can get feedback quickly.

4 If you’re not sure whether this describes you, try Jez Humble’s tongue-in-cheek continuous integration certification test.

5 I use the term trunk-based development because it is clear and descriptive. It tells you what it is: the practice of using only one branch and committing all code to that branch. But it is worth noting that Martin Fowler prefers to use the term continuous integration out of respect for Beck and in an attempt to resist semantic diffusion.

Get What Is Trunk-Based Development? now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.