You can configure Bitbucket Data Center and Server
to cascade changes to newer release branches, and reduce the need for manual maintenance of branches. Follow the best practices described on this page to establish a branching strategy conducive for cascading merges. You can configure cascading merge for:
- a single repository
- an entire project
Conditions for cascading a merge
To cascade a merge, Bitbucket must be able to determine the ordering of branches, and rely on semantic versioning of branch names. For example, Bitbucket will order these branch names like this: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. Learn more about the branch ordering algorithm, including some examples of branch ordering, later on this page.
Bitbucket expects that the 'development' branch, typically the default branch, is always ahead of any 'release' branches. The final merge in the cascade of merge operations will be to the 'development' branch.
The following conditions must also be met:
- A branching model must be configured.
- The 'release' branch type must be enabled or a 'production' branch must be set.
- The merge must be made using a pull request to a 'release' or 'production' branch type.
- There must be newer branches than the target branch of the pull request.
What happens if a cascading merge fails?
When a cascading merge fails, Bitbucket creates a new pull request for the failed merge, and the cascade of merge operation stops. You should resolve the conflict locally before approving the new merge, which may start a new series of cascading merges. Note that a pull request that gets automatically opened when a merge fails won't trigger the continuation of the initial merge chain if resolved locally (which is the approach that we recommend).
Some reasons when a cascading merge could fail include:
- a conflict detected that prevents the merge.
an open pull request already exists with the same source and target that the cascading merge would close.
For example, if you have multiple release branches, R1, R2, R3, and R4, they can all automatically merge into one another with automatic merging enabled. I.e., If you merge a pull request to R2, it will automatically merge R3 and R4 until you get to the development branch.
With automatic merging on, let's then say that there is a merge failure with R4. If you merge to R1, then Bitbucket merges to R2 and R3, but cannot merge to R4 because of the conflict. Bitbucket then opens a pull request from R3 to R4. The pull request is assigned to you because you attempted to perform the merge. Conflicts will need to be resolved and there are chances you may not even see that there was a pull request created.
You can choose from these two options on how pull requests from the upstream merge conflict should behave:
- Allowed to merge but only to the pull request opened for the merge conflict. This means that the next time a merge is attempted, there will be a warning stating that there is an open pull request downstream.
- Blocked from merging until the pull request that was opened for the merge conflict is resolved. This means that any merging is blocked because of the open pull request downstream.
Enable cascading merge
By default, branch settings (including cascading merge settings) from the project level are inherited by the repositories. Repository admins can either inherit the project-level branch settings or override the settings at the repository level.
Configure cascading merge for all repositories in a project
To enable cascading merge for all repositories in a project (requires project admin permission):
- Go to Project settings > Branches.
- In the Cascading merge section, select On, and then select Save.
Configure cascading merge for a single repository
If the project admin hasn't restricted repository-level changes, you can customize settings for individual repositories. Learn more about how project admins can restrict changes to repository settings
To enable cascading merge for an individual repository (requires repository admin permission):
- Go to Repository settings > Branches.
- In the Cascading merge section, select On and then select Save.
Branch ordering algorithm
To cascade changes to newer release branches, Bitbucket must be able to determine the ordering of branches. Ordering is based on semantic versioning in the naming pattern for branches.
Bitbucket uses the following ordering algorithm to determine the branches in the merge chain:
- Branches are selected and ordered on the basis of the name of the branch that started the cascade (i.e. the target of the pull request for the merge).
- Branch names are split into tokens using any of these characters: underscore '_', hyphen '-', plus '+', or period '.'.
- Only branches matching the name of the pull request target are added into the merge path. Matching means that every token before the first numeric token must be equal to the corresponding tokens of the target branch's name.
- Branches are ordered by number, if a given token is numeric. When comparing a numeric token with an ASCII token, the numeric is ranked higher (that is, it is considered as being a newer version).
- If both tokens are non-numeric, a simple ASCII comparison is used.
- In the unlikely case of the above algorithm resulting in equality of 2 branch names, a simple string comparison is performed on the whole branch name.
- There is a limit of 30 merges.
Branch ordering examples
The table below provides examples of branch naming patterns that Bitbucket is able, and not able, to order correctly:
Bitbucket tokenizes on the '.' and the '-' of '1.1-rc1' and is able to order these branch names correctly.
Bitbucket tokenizes on the '.' and the '_' and orders the numeric parts of these branch names correctly.
Bitbucket tokenizes on the '.' and the '_' but cannot recognize that 'bitbucket_1.1' should follow '1.0'.