Push to master, do it often

🗓️
•
🔄
•
⏳ 7 min

If we think of software development as a means to satisfying the needs of a user(s), we’ll notice some “gaps” in the way those needs are conveyed:

In an ideal world, the user would peek over our shoulders while we code, understand what we are writing, and let us know if we are on the right track.

Since this is a bit unrealistic, we would want to ensure our efforts make sense by giving the user the latest version of our software, as soon and frequently as possible. This would inform us of our mistakes quickly and establish a short feedback loop between development and production.

TBD is one of the approaches we might use to achieve this goal.

What even is TBD?

Trunk Based Development is a practice in which branches are generally avoided and all (most) of the development is done in one main “Trunk” branch, also used for deploys, QA and the likes. You don’t need to strictly avoid all branches, but no long-lived branches should exist.

It follows that, for this to be viable, you would want your commits to be small and really frequent, and your code to be thoroughly tested and always releasable.

Simply put, you should aspire to constantly commit excellent, tested code straight to production.

What’s wrong with branches?

Nothing inherently wrong, but we often forget the trade-offs of using them.

Merge Hell

In big projects with multiple dev teams working on shared code, Merge Hell is a very real issue.

Nobody wants to spend half a work-day resolving merge conflicts, much less pay for someone’s salary to do so.

The feeling you get after resolving merge conflicts for 2 hours, only to find out more conflicting code was pushed in the meantime is… not nice. It’s just not a productive use of time.

Information hiding

If you are working on a branch created more than a day ago, you only know how your code behaves with yesterday’s project. Today’s project might not behave the same, and you might need to re-think what you are doing.

Wouldn’t you want to know if that’s the case as soon as possible?

Moreover, while your work is not in the main branch, you are hiding information from the rest of the team. Nobody knows what your code looks like, how it behaves or how to work with it. Why hide that information?

Value adding speed

Instead of asking what’s wrong with branches, one might ask: Why do we need them (especially long-lived ones) anyway?

We are clearly able to push directly to master when a hotfix is needed. Even if the repo settings prevent this, given an important enough issue, we create a branch on the fly that lives for less than an hour and goes straight to production, no fluff involved.

This is done as a way to very quickly update the software currently in production, in order to add value by squashing a bug or fixing a glaring issue. Wouldn’t we want the same speed when releasing new features or updating our UI?

Why do we reserve this luxury only for emergency situations?

Elephants in the room

CI/CD

One might argue that these pitfalls are avoided by practicing CI, no need to do TBD. The thing is, you are probably not really doing CI if you aren’t also doing TBD.

CI is an ambiguous concept, as it relies on what one considers “continuous”. Teams coming from a monthly release cycle might consider weekly integrations to be “continuous”, while one might argue that daily integrations are the bare minimum for CI.

CI/CD is also quite often mistaken with “having a pipeline”, which is indeed part of the deal, but not the whole thing.

If we want to deliver software continuously (CD), we need to integrate our work continuously (CI). This indeed requires a well-thought-out pipeline to production, but it also requires thorough testing and practicing TBD.

The fundamental assumption of CI is that there’s only one interesting version, the current one. -src-

If the only interesting version is the current one, why waste effort, time and resources in other versions? When practicing TBD, CI will naturally follow (one would otherwise have to be very “brave”).

PRs

Does this mean we need to ditch PRs completely? As mentioned before, branches are not the devil, PRs have their place.

TBD is a way of approaching development, not a strict dogma. We’ll see that these principles can be followed even in a PR centric workflow. So long as they are used in a specific and well reasoned way.

Still, you might want to reconsider why exactly we use and (in theory) “need” PRs, since they have some clear downsides:

Gatekeeping

More often than not, PRs are used as a form of gatekeeping. Surprisingly, this can make sense in some scenario.

Other than these situations, one struggles to find a reason for one team member to veto the work of another.

Trust

Some might feel uncomfortable with the idea of “just letting anyone push to master”. Besides from that not being the point and for the sake of argument: why?

What would you expect to happen? Would you expect your teammates to knowingly introduce bugs? Are you worried that they aren’t “good enough”? “Professional enough”?

As mentioned before, it’s reasonable to worry about these things in some scenarios (mainly OSS projects), but other than that, these concerns are either unreasonable or need to be tackled well before thinking about introducing TBD in your team’s workflow.

A team can’t work efficiently and effectively if their members don’t fully trust each other. If that isn’t the case, you are probably better off leaving TBD for further down the line, as there are likely more pressing issues to take care of.


Other posts you might like