One of the issues that commonly crops up when working in a large deployment team is how to selectively merge metadata or work around merge conflicts.
In this article we'll discuss:
- Why merge conflicts arise
- How Gearset helps you avoid them
- How to manually resolve them
- Why it's not possible to fully automate merge conflict resolution
What is a merge conflict?
Merge conflicts are situations where there are two competing changes to a single part of metadata which cannot be automatically resolved by your version control system.
The conflicts must be resolved manually before the pull request (or merge request) can be completed.
Why do merge conflicts arise?
Merge conflicts typically arise when teams of developers and admins work on a common set of metadata components, such as Apex classes or custom objects.
The merge conflict is flagged when one developer attempts to merge their branch into another - usually when a feature branch is merged into master ahead of a release to integration testing or production.
Let's take an example to see how this arises in practice.
- Jason and Matt are developers working on two separate user stories. Each of them are working in their own feature branches in GitHub as part of their team's Agile development flow, meaning they can make changes in isolation of each other.
- Jason edits an Apex class,
CustomSiteRegisterController.cls, to set the severity of a dialogue box from an ERROR to a WARNING, and leaves a comment.
- Jason completes his work, opens a pull request, and merges his work into the master branch in the repository.
- While this has been going on, Matt, in his own feature branch, decides to remove these same lines of the
CustomSiteRegisterController.clsclass, as a user has reported that they are causing unexpected issues in integration testing.
- When Matt now comes to open a pull request to merge his changes into master, he runs into a merge conflict.
- When he looks into the detail, he can see that there are now two changes being made to the same lines of that Apex class. His own change, and Jason's change. The version control system does not know which version the team want to use.
- Matt and Jason must now decide which set of changes they wish to keep in this Apex class.
How Gearset helps you avoid merge conflicts
Merge conflicts can take time to resolve. As such, it's worth taking steps to avoid them where possible. Gearset can help teams avoid merge conflicts in three ways:
- Gearset's comparisons between different environments make it easy for developers to compare their own feature branch with that of a team member. This will highlight potential merge conflicts before they arise, allowing the team to communicate on how to resolve them early.
- For many metadata types, Gearset sidesteps the whole merging issue by having a deep understanding of your metadata. This understanding means that Gearset can deconstruct Salesforce objects into their constituent components, and stitch them back together effortlessly so you don’t need to merge anything. For example, custom objects are broken down into their constituent fields. By minimising the size of each component, the chance of two developers making conflicting changes is drastically reduced.
- Gearset's change monitoring jobs can flag changes to developers as soon as they get released into an integration environment. This is facilitated by using continuous integration to rapidly deploy changes as soon as they are merged into the master release branch in your repository.
Let's take another example to demonstrate how this decomposition works in Gearset.
Jason has made two changes to the Opportunity object in his development environment - adding a new field, and modifying an existing one. He only wants to move the new field into production. Unbeknownst to Jason, Matt has made another change to the same object directly in production - he has also modified the existing field.
Moving just this single change with Change Sets or with the Force.com Migration Tool would be tricky, and very error prone.
With Gearset it is nice and easy as each of the changes are treated as separate components that Jason can deploy in isolation.
Here we can see the field in the Opportunity that he's modified to add some help text.
And here we can see the new field that he's added to the Opportunity object.
It is then very easy for Jason to select just the changes that he's ready to promote to his production environment. As he's not moving the field that both he and Matt have modified, he won't run into a conflict and can deploy his new field with confidence.
Resolving merge conflicts
When you do run into a merge conflict, there are two main options.
To perform a manual merge, you really need to get the Apex or VisualForce from both orgs, and then reconcile the differences using something like KDiff or Eclipse. Once you have your merged file, you can then use Gearset to deploy the files from your local machine into your target org.
Version control assisted merge
As demonstrated in the example above, if you're using version control to manage revisions to your code, another option is to kick off the merge / pull request process to resolve conflicts. Once the code has been merged and committed to a release branch, you can then deploy it out to your Salesforce orgs using Gearset.
Why automatic merge conflict resolution isn't always possible
In an ideal world, every merge conflict would be automatically resolved so teams don't have to spend time manually fixing them.
Version control systems such as GitHub have been designed from the ground to facilitate this process, and have powerful algorithms for automatically handling merge conflicts. However, in some cases, this automatic resolution is just not possible.
Code has too much meaning to just automatically merge the files if there is a conflict. Successfully integrating two sets of changes relies on knowledge that only the developer has. It can be a slow process, but it's too risky to do ‘best-effort’ and end up with an Apex class that doesn’t compile!
It's worth reiterating that no tool can handle this situation - despite the claims of some other release management tools for Salesforce! This problem exists across every development platform and language, and none have managed to find a way to automatically resolve these conflicts.
Want to know more?
There are a few good guides to handling merge conflicts:
- GitHub documentation: https://help.github.com/articles/about-merge-conflicts/ and https://help.github.com/articles/resolving-a-merge-conflict-on-github/
- Git Tower guide to conflicts: https://www.git-tower.com/learn/git/ebook/en/command-line/advanced-topics/merge-conflicts