Large teams working on shared repositories are familiar with the challenges of branching and merging code, maintaining it, and rolling out releases. Without a solid version source control branching strategy, merge conflicts can compromise workflows and delay releases. In this article, we’ll explore the top two branching models in software development: Trunk-Based Development (TBD) and Gitflow

We’ll break down:

  • The key characteristics of each source control branching strategy;
  • How the Gitflow branching model compares to trunk-based development;
  • Best practices for agile development workflow;
  • Merge conflict resolution strategies for Gitflow;
  • Which teams benefit the most from each approach.

What is Branching in Version Control?

Branching is a powerful tool that gives development teams a dedicated space to work on their code changes before merging them into a main branch. It enables features to be developed on separate branches, bug fixes to be addressed independently, and other tasks to be handled without disrupting the main branch. But how you address branching and merging can make a world of difference in DevOps.

After all, merge conflicts are a common source of frustration for your developers. In fact, they can significantly impact your team’s productivity and time to market. Luckily, a well-implemented branching strategy can reduce merge conflicts, making this a crucial process to ensure successful and timely releases.

Gitflow vs Trunk-Based Development

Before the days of version control software, developers would often create two versions of their software as a way of tracking changes and reverse to an earlier version if necessary. These would lead to long, parallel branches, which were often hard to merge with one another. But that was the state of the art when Gitflow was introduced in 2010. 

With Gitflow, teams keep at least two long branches: the ‘main’, which is the master; and the ‘develop’ branch, which is used as a working environment. Although it’s a complex structure, Gitflow still holds value for its rigorous management of development stages and clear workflows. However, it has steadily been losing popularity (spoiler alert) in favor of trunk-based development. 

In contrast to Gitflow, trunk-based development has a simpler architecture. It requires everyone to work on the same “trunk” (or “main” in Git). There are only a few short-lived support branches, and they should be merged with the main often. Teams looking for a more agile development workflow benefit from this approach – in fact, it’s a requirement for CI/CD – because the ‘main’ is always deployable.  

Here’s a quick comparison between Gitflow and trunk-based development: 

Trunk-Based DevelopmentGitflow
short-lived branches which result in small commitslong branches or multiple primary branches, with large commits
eases the friction of code integrations and merge conflictslarger and infrequent merges may introduce conflicting updates that are hard to identify and resolve 
everyone needs to pay attention to CI/CD or they could block the delivery chainit’s incompatible with continuous delivery 
the code must be automatically reviewed to avoid issuesonly certain individuals can approve changes to the main code
it’s better for continuous development 
  works well in fast-paced environments and agile workflows
it’s appropriate for cyclical releases and software with multiple versions
well-suited for large teams with a clear hierarchy 

Now, we’ll look closer into the pros and cons of Git Flow vs Trunk-Based Development so that you decide which is the best branching strategy for your team. 

What is Trunk-Based Development?

Trunk-based development is a highly efficient source control branching strategy. The trunk, also known as the main or the mainline, is the single source of truth. All team members work on this single shared branch. TBD then encourages developers to integrate small, frequent changes into the ‘trunk’, ‘main’ or ‘master’ branch, ensuring a streamlined and efficient development process.

There could be short-lived branches, but the emphasis is on frequent (often daily) commits. The idea is to maintain shippable code at all times. This source control branching strategy is obviously tailor made for continuous development, but it has other advantages. Branching and merging regularly avoids merge conflicts, and any issues can be addressed right away.

How does trunk-based development reduce merge conflicts?

Trunk-based development relies on devs to push small, frequent commits. This process ensures that code is committed regularly – even multiple times throughout the day – which significantly reduces the likelihood of merge conflicts. Plus, by keeping these conflicts limited to very small chunks of code, they also become easier to review and fix.

For instance, imagine that Alice and Bob are working on related features. They continuously merge their small, isolated changes into the trunk. This frequent integration helps detect and resolve conflicts early, and prevents large, complex issues that arise from long-lived branches. 

However, there’s a big drawback. In TBD, a single broken commit – thanks to untested or buggy code – can block the pipeline, and other developers can’t merge their changes until the issue is fixed. Therefore, Alice and Bob must follow some version control best practices, like automated tests, to ensure the trunk’s stability.

Trunk-based development best practices

Small batches and frequent commits

Trunk-based development works better when developers work on small batches. Usually, they will merge at least once a day, if not more. This makes branching and merging easier and faster, not to mention that it avoids conflicts. Any issues should be fixed right away. Once the code is merged, delete the short-lived branches. 

Pre-commit hooks

In large teams, not all developers will have the same coding style. Pre-commit hooks can enforce code linting, formatting and running unit tests to ensure syntax, style consistency and auto-format code according to predefined rules. This will prevent merge conflicts over trivial differences, like whitespace or indentation. 

Consistent commit messages

Leaving consistent commit messages helps other developers understand what was added at each point. This not only helps the code review process, but also makes it easy to track changes in the mainline. By the way, don’t forget that at Assembla you can link tickets to commits.

Code review

Automated code review is the backbone of TBD. With changes being committed frequently, a robust review process is essential. At Assembla, you can integrate merge requests with your CI/CD tools (including our built-in Jenkins integration) to see where the changes pass or fail. You can read more about Assembla merge requests here.

Automated merge conflict detection via CI/CD

CI/CD pipelines can be set up to automatically detect merge conflicts before changes are merged into the trunk. Some modern CI/CD systems even simulate merges in advance, flagging conflicts in advance. This allows developers to resolve issues proactively and prevent broken code from entering the main branch. 

Automatic process 

TBD is compatible with automation. As code is committed, an automatic build process gets triggered, which then kicks off an automated test to check for quality. This process ensures that any failures are addressed immediately and automatically. It’s possible to merge to the trunk, build, push to beta, test, push to staging, test again, and push to production with little or even no human intervention. (Of course, teams should have rollback strategies in place in case the automated test fails in production.)

Feature flags 

In TBD, uncoordinated feature releases can cause merge conflicts. One way to avoid them is using  feature flags (or toggles) to prevent half-implemented features from being accidentally enabled by other devs. When you use a feature flag, you can merge new code directly into the main branch without immediately exposing these changes to all users, which keeps the trunk “clean”. This approach allows for testing new features in production environments under real conditions. Once tested, the feature can be turned off without deploying new code. 

Releasable state & monitoring 

In Trunk-Based Development, the mainline failures are immediately attended to, and the mainline must be always in a ‘releasable state’. This means it has gone through a series of reviews, validation, and testing, and is ready for deployment. Continuous monitoring is also crucial, where the feedback is continuous, which helps with the overall code quality.

Trunk-Based Development has proven successful for many teams and organizations across different industries, stages of development and priorities. Below are some of the key reasons why certain teams have found success with TBD.

  • Agile development teams: agile is a natural companion for Trunk-Based Development. It can speed up feedback loops, decrease integration issues, and streamline bug detection and fixing. These benefits translate into enhanced collaboration, accelerated delivery, and improved customer satisfaction, making it an ideal choice for Agile teams. 
  • Microservices architecture-based teams: microservices architecture is a business approach in which a single application is composed of many smaller, independent services, each responsible for a specific function. This makes these teams highly dependent on good communication and integration processes. A robust CI/CD driven by TBD is necessary for microservices teams to succeed as it reduces the complexity of integration and rollbacks.
  • Organizations driving quality first: organizations that prioritize high-quality software above all tend to implement extensive automation early in the development process. TBD aligns perfectly with these goals by promoting frequent, small commits. Coupled with continuous integration and testing, each small code change can be automatically tested and validated for the highest quality.

  • Startups: for startups, the ability to pivot, release rapidly, and adapt swiftly to changes is crucial. Complex branching methodologies can slow down these efforts, potentially leading to failure. TBD, on the other hand, is an ideal match for startups. It accelerates the release cycle, improves time to market, and fosters a culture of embracing changes, all of which are vital for startup success.Who should adopt trunk-based development and why?

What is Gitflow? 

Gitflow is a Git branching strategy. It was initially created to improve software release management. Therefore, it’s not a tool, an app or a software, but merely a model to organize Git branches and ship releases more efficiently. It was first published by Vicent Driessen at Nvie all the way back in 2010. 

What’s the Gitflow branching model?

While trunk-based development encourages short-term branching, Gitflow is the opposite. In a simple Gitflow vs Trunk, the clearest difference is that it revolves around multiple and typically long-lived branches. The Gitflow branching model sets up a clear workflow for teams planning regular releases, which was common when it was designed. 

The main issue is that large and infrequent merges can introduce bugs that are harder to identify and resolve due to their sheer size. However, one could also argue that constant merge conflicts and bugs are a symptom of a poorly organized structure.  So let’s take a closer look at the Gitflow branching structure. 

What’s the Gitflow structure?

Gitflow uses two main branches:

  •  The ‘main’ branch serves as a master for production releases. This branch can be tagged at various points to identify different versions or releases. Obviously, other branches are only merged into the main branch after they have been vetted and tested.
  • Meanwhile, the ‘development’ branch is an environment for day to day development work and features that are still being tested. When you’re adding new features, you branch off from this ‘development’ branch into a short-lived ‘feature’ branch. Once the feature is reviewed, it will be merged with the development branch.

There are two other types of supporting branches:

  •  A ‘release’ branch is used for finishing touches or to fix minor bugs before releasing new code. It’s usually branched out of the development branch. When it’s good, it’s merged into the master ‘main’ branch. 
  • Then there are ‘hotfix branches’, for urgent fixes. This should be based on the main branch, and once ready should be merged with both the main and the development branches to ensure the fix persists in future releases.

What are the advantages of the Gitflow branching model?

Clear workflow

The Gitflow branching model defines a clear and predictable workflow for managing features, releases, and fixes. By clearly separating development efforts (on ‘develop’ and ‘feature’ branches), release preparations (on ‘release’ branches), and emergency corrections (the ‘hotfix’ branches), Gitflow helps manage complexity and maintain stability in production.

Parallel development

Gitflow empowers developers by providing robust support for managing various versions of production releases with parallel development. Each branch is focused on a different goal, reducing dependencies and making it a breeze to track and manage different versions of your software. 

Release management 

One of the strengths of Gitflow is its strong emphasis on software release management. The use of dedicated ‘release’ branches allows for pre-release adjustments like bug fixes, documentation generation, and other release-specific tasks without disrupting ongoing development on the ‘develop’ branch.

Standardization and discipline 

Gitflow may be the best branching strategy for large teams. Even though the structure may be complex at onboarding, it enforces a disciplined approach to source code management. Team members know where to branch off, when to merge, and exactly in which branch they should be working on. This is particularly useful in team environments and larger projects. 

Merge conflict resolution strategies

One of the main disadvantages people find on Gitflow is that two developers may be working on different features for a long time. When they need to merge into the same branch, it can create conflicts. Therefore, let’s look at some version control best practices when you’re using Gitflow:

Rebase before merging

Before pushing any major updates, rebase it with the latest develop branch. This minimizes conflicts because it gives you an opportunity to incorporate the latest changes from other developers before your changes are merged. 

Use pull requests before merging

Developers shouldn’t push directly to the main or development branches. Instead, if the feature branch they’re working on seems ready, they should submit a merge request. The request will then be reviewed by another developer before they are merged into the main. Hopefully, this will help to catch potential conflicts early.  

Cherry-pick specific commits

If you only need certain commits from a branch, use git cherry-pick instead of merging the entire branch. This command lets you quickly integrate specific fixes or updates without merging an entire branch, which is more cumbersome and may even introduce unnecessary changes. 

Quality Assurance (QA) 

Before merging code into develop, see it passes automated tests (unit, integration, e2e) to catch any issues early on. For release branches, use a staging environment for QA/UAT, regression testing, and performance benchmarks to ensure everything works as expected before deployment. 

Use tags 

Always tag releases in the main branch. This provides a clear record of deployed releases and helps track software versions. 

Who should adopt Gitflow development, and why?

There’s a reason why Gitflow is a classic. Despite the popularity of trunk-based development, Gitflow is still one of the best strategies for large teams. Here are some contexts where you should think about using Gitflow for collaborative software development. 

  • Software with predictable release cycles: Gitflow is meant to be used for teams with a predictable, long term release cycle (i.e., versioned software), and not for companies that need to update their code very often (continuous delivery for web apps, for example). 
  • Teams who need to support multiple versions of the same software: if your team supports multiple versions of the software – i.e., if you need to actively maintain an old version – then release branches can help. Gitflow is a good choice for teams that handle multiple releases in parallel, because the branching model can easily accommodate that scenario. 
  • Git branching for regulated industries: Gitflow is well suited for teams that need to meet strict release and compliance requirements. Industries like healthcare, energy, financial services often prioritize regulatory requirements over speed of release. Gitflow provides an organized process, stronger tracking for each version, and greater accountability about who merged what, which is essential for compliance.
  • Large, distributed teams: while trunk-based development works well for smaller,  synchronized teams, Gitflow is better at establishing rules and workflows for larger, distributed teams. The branching structure establishes a clear set of rules, makes it easier to manage the delivery dates for new features, track progress and schedule new releases. 

What are the alternatives to Gitflow?

Apart from Gitflow, there’s Trunk-Based Development, as we’ve seen. There are also other Git workflows, including GitHub flow and GitLab Flow.

With GitHub flow, the main branch has the production-ready code and should be deployable. Side branches, including feature branches, are used for new features and bug fixes, and they are merged with the main as soon as the work is finished and reviewed. Because of this simple structure, GitHub flow is a good alternative for smaller teams and products that don’t support multiple versions. 

The GitLab Flow is a more structured approach. As with the previous option, the main branch contains code ready to be deployed. There are small branches for bug fixes, which are merged into the main branch. However, the main is not the source of truth when it comes to releases. Rather, it introduces environment branches and releases branches. The latter are used for versioned releases. 

Gitflow vs Trunk Based Development for software release management

Gitflow and Trunk-Based Development (TBD) both offer unique advantages tailored to different development needs and team structures. To sum up what we’ve seen so far:

Gitflow is perfect for teams that need structured, sequential releases. It is particularly effective for larger teams and projects that require thorough staging and testing before deployment. The model’s use of multiple branch types allows for detailed management of features and fixes, ensuring that each release is stable and vetted. That is why Gitflow is ideal for complex projects with stability requirements or those that must comply with strict regulatory standards.

On the other hand, Trunk-Based Development is best suited for teams prioritizing rapid iteration and continuous integration. TBD encourages all developers to work collaboratively on a single branch (the trunk), minimizing the complexity and overhead of managing multiple branches. This approach supports a faster cycle of feedback and deployment, making it ideal for agile teams that aim for frequent and incremental updates. 

TBD is particularly effective in reducing merge conflicts and aligning closely with DevOps practices, promoting a more streamlined and dynamic development process. Even Gitflow’s architect, Vincent Driessen, seems to agree that times have changed in a note of reflection he added in 2020: 

 “(…) the most popular type of software that is being developed with Git is shifting more towards web apps – at least in my bubble. Web apps are typically continuously delivered, not rolled back, and you don’t have to support multiple versions of the software running in the wild. 

This is not the class of software that I had in mind when I wrote the blog post 10 years ago. If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow) instead of trying to shoehorn git-flow into your team. 

If, however, you are building software that is explicitly versioned, or if you need to support multiple versions of your software in the world, then git-flow may still be as good of a fit to your team as it has been to people in the last 10 years.” 

TL; DR. What’s the best branching strategy: Gitflow or trunk-based development?

Gitflow is ideal for structured, versioned software releases, while Trunk-Based Development works best for CI/CD and fast-paced agile workflows. That said, each method has its strengths and downsides. The choice between them should be based on the specific needs and goals of your project and team.