Every code base is founded on branching and version control system. With scale a lot of problems arise that are proved to be labor-intensive, costly, and inefficient.
Let’s take a look at improving a process of code merging.
The strategies
It is crucial for a team to work towards an agreement upon strategy and workflow, when it comes to git repositories. It’s more important to select one and to be consistent about your selection, than overthinking which strategy to choose.
First, let’s compare two most common strategies.
Gitflow - a history lesson
Gitflow, is a strict development model where only certain individuals can approve changes to the main code. This helps to maintain code quality and minimize the number of bugs. Gitflow has more, longer-lived branches and larger commits than trunk-based development.
- requires a staging develop branch, which is merged to main, on release date
- long-lived branches, big feature branches
- large commits
- challenging for introducing CI/CD, because of changes nature
- difficult to review, although it relies on supervisors and code acceptors
- useful for projects that have a scheduled release cycle
- complicated branch structure
- main branch can become stale, when releases are separated in time
- merge conflicts may be difficult to resolve
Trunk-based - current go-to strategy
Trunk-based development is a required practice of CI/CD.
Trunk-based development is a version control management practice where developers merge small, frequent updates to a core “trunk” or main branch. Since it streamlines merging and integration phases, it helps achieve CI/CD and increases software delivery and organizational performance.
- small branches, small changes
- easy code review
- feature flags (turn on/off new features, as development process is rapid)
- allow CI/CD given automated tests and code coverage reports are utilized
- requires gradual automation tests (unit, e2e, integration) with coverage
- code review after automation passes
- delete merged branches
When selecting a strategy you should always consider structure of an organization (size and number of developer teams) and release/delivery process.
In some cases continuous delivery is not possible e.g. when dealing with a service of strategic meaning, specific hardware architecture, or other factors, such as a client who wants to control deployment process.
Working towards an agreement
At my current company, our team gradually worked towards a strategy, which is sort of hybrid of both above-mentioned ones. It is a result of working within live code bases of relatively new and legacy code bases.
Helpful tips
We decided to squash all our commits and rebase feature branches against the origin.
This solution resolves merge conflict problems, as the first developer to merge has priority and then the next one has to resolve conflicts locally.
History of changes is clean and straight as an arrow (and so is the tree structure).