The “best“ practice
I used to believe that having feature branches is a best practice. But it turned out to be a poor practice, with a significant impact on lead time - the time needed to deliver value to the customer.
In most of the teams I worked with, there were two common branching strategies:
Feature branching
Git Flow
By now, these strategies have become the most popular ways to work in a team. They promise to help collaboration among team members. Pull Request (PR) reviews became the standard way to improve software quality. There are more and more tools built to work efficiently with Git and branches.
The only problem is that this part of our ecosystem is built on a bad practice. If we build our development flow on weak sand, we can expect nothing but bad outcomes.
Why feature branches are bad?
The negative effect of feature branches is clear: ask any developer about their biggest frustrations. They will surely mention the long PR review processes. Developers usually need to wait several days for their PR to be reviewed. They get comments, resume working and address the issues. After completing the changes, they request another review, and the cycle continues. Meanwhile, no value is delivered to the customer.
Unless there are some untrusted authors working together, I see no value in feature branches. They just slow down the entire development process. They lead to productivity-killer context switches, create bottlenecks, and result in longer lead time. The PR reviews also contribute to poor code quality as they tend to be superficial. They’re focused on things scratching only the surface of the app, instead of the deep details.
Every branch is a different version of our application. The more we have, the more versions we need to maintain. They come with a high mental load and possible merge conflicts. They’re the source of many problems. Problems that could be easily prevented. But how can we prevent them?
The best branching strategy
The best Git branching strategy is the no-branch strategy. No more long PR reviews, no more merge conflicts, and no multiple versions of our app. Only a single source of truth.
To throw away branches, we need to utilize Trunk-Based Development (TBD). The rule is simple: everyone is working on the master branch. It’s a practice of working on the main branch and pushing to the remote directly.
The well-known book Accelerate also found that working directly on the master, instead of having long-lived branches, leads to higher delivery performance. That same conclusion has been repeated every year in the DORA DevOps reports.
It’s also important to note that TBD is the prerequisite of Continuous Integration (CI). CI isn’t a tool such as GitHub Actions or Jenkins. Instead, it’s a decades-old practice of Extreme Programming. It involves integrating our work into the master multiple times per day. When integrating our work, we need to ensure that the code on the master remains functional. We can confirm this with our automated tests.
Who will review our code?
Instead of PR reviews, there is a more efficient way to do it: real-time reviewing through pair and mob programming. It will result in better knowledge-sharing, faster feedback, and deeper reviews. And the cherry on top is that it improves team morale.
Conclusion
In most cases, you don’t need feature branches. Just use Trunk-Based Development and work on the master. This is the first step to applying CI. To enable CI you need a trustworthy test suite you can always rely on. To have a quality test suite, Test-Driven Development is your best friend. And instead of the inefficient PR reviews, do the code review in real-time with Pair and Mob programming.
Software development can be much simpler and faster if we don’t complicate our life with feature branches.
More collaboration is often the answer to many software problems teams are encountering.
Conclusion, year 2024 and there are tons of teams and devs who still don't know what continuous integration is or what rebase is all about.