Skip to main content

What does the 'high merge complexity' warning mean?

Sometimes Gearset will show a warning about a high merge complexity. This article explains why this matters and what to do about it.

Steve Ballantine avatar
Written by Steve Ballantine
Updated over 3 weeks ago

What is merge complexity?

Typically, git will perform a 3-way merge when merging changes. For pipelines, this usually means comparing:

  • Most recent commit on the promotion branch

  • Most recent commit on the environment branch

  • The last ancestor commit that is shared to those two commits

In the example below, develop is being merged into main and the shared ancestor would be commit #1, with hash 752d352. This is referred to as the 'base' commit of the merge.

In reality, commit histories are usually more complex than this and there are several scenarios that can cause git to identify multiple base commits rather than just one.

Multiple merge base example

This section describes a scenario that causes multiple merge bases. Feel free to skip this explanation if you don't need the detail though.

In this scenario we have 2 long-lived environment branches, main and develop and 3 feature branches. We ignore aspects of the pipelines branching model that would make this even more complex within Gearset (I.e. promotion branches and back propagation PRs)

  • feature1 and feature2 are created from main

  • a single change is committed to each of the feature branches.

  • feature1 is merged into develop and then main

  • feature2 is merged into develop

  • feature3 is now created from main

  • a change is committed to feature3

  • feature2 is merged into feature3 to leave us on commit #7 - 56eab2de

  • If we try to merge feature3 in to develop then the shared ancestor is 16e7560 on main. However, there are two different paths to get to our current commit at 56eab2de. These two paths mean that we have 2 merge bases that now need to be reconciled. The corresponding commits for these paths are:

    • a84b77d from main

    • c5eb2ee from feature2

If you want to investigate this for yourself then you can view the list of merge bases between the two branches by running

git merge-base --all feature3 develop

Why does this matter?

When there are multiple merge bases, our Semantic merge algorithm will need to run for each combination of possible bases in turn. Essentially multiplying the time taken to merge by the number of merge bases.
Semantic merge is highly optimised. However, in situations involving hundreds of merge bases it can easily become a significant portion of the time spent validating or deploying changes.

With Gearset's semantic merge algorithm, merges with 1 merge base take under 6 seconds on average. In comparison, merges with 50 or more merge bases take around 26 minutes on average!

In pipelines, we use the semantic merge algorithm as part of every validation run, as well as for many deployment runs. Every time a PR is created, or a source branch in a PR is updated, a validation is triggered. Every time an environment is updated it can trigger validations in the PRs that are open against that environment.

If all of these actions are taking 26+ minutes then it can quickly become very difficult to push changes through the pipeline with the velocity required by stakeholders.

It's worth noting that Azure DevOps will show a similar message 'Warning: Multiple merge bases detected' in this situation for similar reasons.

How do I fix it?

This problem can have two slightly different high-level causes:

The branch for the static environment is out of sync with the main branch

In this case, all PRs targeting the environment will show this warning.

This can be resolved by creating a sync PR using the sync icon. (see this article for more details on sync PRs)

This will merge your main branch into the environment branch. Any new feature branches created after this should now use this as the base commit when merging.

However, existing feature branches will still show the warning as they were branched from main before the sync commit was created and therefore cannot use it as a common ancestor.

The feature branch commit history is introducing additional merge bases

In this case, only some PRs will show this warning and the warning will probably persist as the feature is promoted to subsequent environments.

This will usually be caused by adding complexity to the commit history of the feature (or promotion) branch. E.g.

  1. Creating a feature branch from a branch other than the branch at the end of your pipeline (e.g. Main/Master).

  2. Merging another branch directly into the feature or promotion branch.

In general, it is best to avoid getting in to this state by ensuring your team know not to perform the actions listed above.

One way to resolve this scenario after it's happened is to create a new feature branch from your main branch and then squash merge the problematic feature branch into it.

⚠️ Bear in mind that this will squash all the changes in the old branch into a single commit, so you lose some of the detail in the commit history.

Note that as a rule, squash merging is not compatible with Pipelines. In this case though, it can be used as a workaround:

  1. We have a pipeline with 3 long-lived static environment branches staging, uat and main. We have a feature branch, my-feature, which is showing the 'high merge base count' warning message.

  2. Create a new branch from main, we'll call this branch my-feature-squashed for this example.

  3. Use your VCS (GitHub, ADO, etc) to create a pull request merging my-feature into my-feature-squash

  4. Once any conflicts are resolved and any other issues addressed, merge the PR in the VCS using a squash merge. Note that this setting could be disabled so you may first need to update repository settings to temporarily allow it.

  5. You can now create a new feature against your dev sandbox within Gearset and choose my-feature-squashed as the feature branch.

  6. The change can now be promoted through your pipeline within Gearset as normal.

Did this answer your question?