“black weaving machine” by Fancycrave on Unsplash

Normally¹ when you merge 2 branches, your version control system can resolve the differences and merge them automatically. However, when the branches have competing commits your version control system needs your intervention to decide which changes to incorporate in the final merge. Say hello to merge conflicts.

In this post, I talk about a set of recommendations that have served me well minimising the number of merge conflicts or at least the difficulty and time spent resolving them.

That doesn’t sound too bad

A few reasons why merge conflicts shouldn’t be taken lightly are:

They cost money . Time that a developer spends resolving avoidable merge conflicts is time wasted. Since time is money, merge conflicts cost money.

. Time that a developer spends resolving avoidable merge conflicts is time wasted. Since time is money, merge conflicts cost money. They create frustration. When a merge conflict happens, in the worst case scenario, all these activities may have happened already:

1. Developer(s) has created a new feature.

2. Other developers code reviewed that feature.

3. Developer(s) addressed CR comments.

4. Developer(s) tested the feature.

5. QA tested the feature. When a merge conflict happens, the process from above needs to be re-done after the conflicts are resolved. Best case scenario it restarts from 4, worst case scenario starts from 1 if the conflicts include conflicting business logic.

They increase the chances of a regression . This is particularly important because merge conflicts tend to happen at the end of a development cycle (Sprint if you use Scrum) with less time to react to problems.

. This is particularly important because merge conflicts tend to happen at the end of a development cycle (Sprint if you use Scrum) with less time to react to problems. Merge conflicts are more likely to happen and to be more impactful in distributed teams.

What aspects contribute to having merge conflicts?

Based on my personal experience, these are some non-technical aspects that increase the likelihood of running into merge conflicts:

a. Working on big features.

b. Large development teams.

c. Distributed development teams.

d. Ineffective communication across the development team. This is more likely to happen if the other aspects exist.

On a personal note, I must admit that I started writing this post after a release working in a environment with a-c present and where we also ran into d a few times:

a. We worked on a major feature.

b. We were 2 teams of 5 and 4 developers each (you may argue that’s not a big team) working together.

c. We were distributed across 3 different timezones: CST, EST and CEST.

Research

I approached this problem using 2 lines of research:

See if there is a particular branching strategy that could alleviate this problem. For this part, I checked engineering blogs from big tech corporations like Facebook and Microsoft as well as remote-only companies like Trello, Basecamp and Toptal.

I found 2 very interesting posts from Microsoft that I recommend reading: i) Defining your Branching and Merging Strategy and ii) Branching and Merging Primer. Hudl has a strong remote culture. Working in a distributed team is something most of my colleagues have experience with. So, I reached out to other developers at Hudl who work in a distributed remote environment like mine to learn from their experience. As with point 1. no silver bullet option was found. However, those conversations contributed to create the recommendations listed in this post.

Research Outcome

There’s no silver bullet when it comes to eliminating merge conflicts, as you’re probably already aware of. The most impactful practices I’ve found to prevent them are:

Raise awareness of potential areas of conflict ASAP. Create and work on small tasks so chances for impactful merge conflicts are lower. Sync up your feature branch frequently.

A more comprehensive list of recommendations can be found in the next section. As said before, there’s no silver bullet. You’re probably aware of most if not all items in that list. But I still think it is useful to have them captured in a single place to make it easier to reference and remember them.

Recommendations to minimise the occurrence and impact of Merge Conflicts

Note: Some of the items in this list assumes using Gitflow as branching strategy.

Think ahead: Identify as early as possible potential areas of conflict. If you use Scrum, use your planning, refining and stand ups to identify these overlapping areas. If you use any other methodology, whenever you’re planning or thinking what’s coming next for you and your colleagues.

Identify as early as possible potential areas of conflict. If you use Scrum, use your planning, refining and stand ups to identify these overlapping areas. If you use any other methodology, whenever you’re planning or thinking what’s coming next for you and your colleagues. If problematic merge conflicts are foreseen, evaluate if a different story/task splitting approach avoids them. You may find S.P.I.D.R. helpful in that situation.

avoids them. You may find S.P.I.D.R. helpful in that situation. The smaller the tasks & features , the smaller the chances of merge conflicts.

, the smaller the chances of merge conflicts. Merge your feature branches as soon as possible. If they’re done, don’t let them hanging in there.

If your team thinks about an enhancement that can be added, merge your current branch if it already adds value and create a new one for that enhancement.

If they’re done, don’t let them hanging in there. If your team thinks about an enhancement that can be added, merge your current branch if it already adds value and create a new one for that enhancement. Sync up feature branches with master frequently .

. Do not branch too deeply. You will be increasing the time to execute each merge and resolve potential conflicts. Meaning, avoid a situation like this:

Do not branch too deeply

Structure your branch tree so you minimise the chances for overlapping sibling branches . You should aim to merge along the hierarchy; i.e, merge children into parent instead of 2 sibling branches.

. You should aim to merge along the hierarchy; i.e, merge children into parent instead of 2 sibling branches. Be aware that the more work is planned to be parallelised, more chances to have merge conflicts.

If merge conflicts are unavoidable, plan some time ahead to make sure you address them and their potential side-effects properly.

This has worked well for us in all circumstances of team size and distribution. What has worked well for you? Please, leave a comment and as always, feedback more than welcome! Twitter is always an option too ;) @JuanjoRamos82

This article was originally posted on In the Hudl.