Description
How do you avoid merge conflicts in your Salesforce deployments?
In this session recording from the Gearset DevOps Summit, Andy Barrick (DevOps Architect at Gearset) talks about merge conflicts which are a fact of life for teams using version control and how you can go about minimizing them.
In this talk find out:
- What’s a merge conflict?
- Common causes for merge conflicts
- Ways to minimize the likelihood and complexity of merge conflicts
Learn more:
Transcript
So, we're gonna have a look today at merge conflicts. You mentioned in the last session, you may, maybe, encountered them described in other the sessions so far today. We're gonna have a look, obviously, what they are, but we're gonna look as well at ways to avoid them how into the first place, shifting left, the mantra of DevOps, and ways that you can, we will maybe see them as more of a, a team exercise how you can avoid them in the first place. They're not necessarily just the the developer concern.
So who am I and why am I here?
Well, I've just said why I'm here to present that I have worked on the Salesforce platform for about ten years. I was in, ISVs mainly beforehand, a lead developer or a technical architect in professional services, packaging financial force, CTinia, cloud sense, service max, and then I worked a lot on projects where, you know, we got tried to get stuff into production and, you know, the the deployment side of it all didn't work quite so well. And of course, we end up on the hook for, you know, the production aug not being quite right. And so I wanted to do something at that. And so I joined gear set to do that. But merge conflicts, you know, the developer side of things very much, a daily, a daily activity for me.
So as mentioned, we're gonna have a look at, emerge conflicts, a fact of life, for for teams using version control.
That is very true, but they don't necessarily have to be. There are ways at which can design your processes the way that you're gonna work to hopefully avoid these happening in the first place as much as possible. It's never gonna be completely.
It's never gonna be completely clear of conflicts, and that's potentially we'll dig into the causes of why that will be, and look at look the strategies of avoidance.
So, to start with then, just to make sure that everyone's on the same page, you might, you know, you might be looking to a diversion control system, and therefore not have experienced this, potentially already worked with one and do get them regularly. You may be at any level of maturity, but so just to make sure that everyone at the same level of thinking. If you have ever used the Salesforce UI, you've opened up a rec to edit it. Left it around for a while. Click save and got the message that actually you can't save because someone else has got and made changes.
You've got a data sort of conflict there. A merge conflict is very similar to that sort of situation.
If you could imagine that in that thinking about the UI there, if I opened up a record and edited field a, let's say, on the record.
And the at some other user, somewhere else around the world, edited the same record, field b.
Now if if both people saved at the same time, if you could imagine that Salesforce might say, okay, well, I know you haven't changed field b, so I'll take your version of field a, and I'll take the other person of field b. They haven't changed a, and I'll manage to sort of combine them together into a amalgamated state where I can accept both changes. That's effectively git is doing. It's very smart at being able to detect what different bits have changed.
But if both users try to change field a at the time, it's not gonna be able to do that, and neither can get. Ultimately, it's two different branches have changed the same bit the same lines of a file, but in different ways.
And ultimately, you don't want for all, we talk about automation and such dev ops. You definitely don't want to automate merger conflict resolution. You don't want some automated process deciding for you what some potentially critical bit of your business logic has gonna look like get saying, Hey, I need some help here. You know, I need some human interaction to tell me exactly what this final state should be.
Our dev ops as a as a concept is always very much around trade offs.
We we heard it in the last session as well. You can't necessarily improve one thing without affecting another.
In a world where there was no version control, it's saying, you're just deploying org to org. You don't you don't get merge conflicts see, because you can only change one thing at a time.
The existence of the ability to have future branches, which effectively mean you can have your application in multiple different states at the same time.
Is the root cause of of how you can get merge conflicts, obviously. You know, if if there if there wasn't the ability to have parallel states. There wouldn't be a need to merge them back together again. But the benefit of being able to do that for developments of different features in parallel is obviously considered a far greater benefit than the cost of having to resolve merge conflicts.
So we've generally accepted that that's a reasonable trade off to make. But we can hopefully reduce even further the number of instances in which we get merge conflicts.
So, for Salesforce teams, there's two, as we can see here, two typical all main root causes of merge conflicts.
Long lift feature branches as we just defined.
The two branches, different changes to the same bits of file.
The longer a branch lives on for, it makes sense that the of some other branch changing the same bit of the file in potentially a different way are going to increase.
And also Salesforce's representation and better data.
XML, quite obviously, the vast majority of it is in XML.
Git, for all I spoke about how it's very good at being able to detect where changes have happened in files.
When it comes to repeating blocks of metadata, it rather falls lower.
If you think about, consider like a book where you've got every paragraph that begins with the same thirty left words and ends with the same thirty words. And you've got to work out if someone's put a new paragraph in or changed an old paragraph, you're gonna have to dig into bits in the middle that are different each time to work out what each one actually is.
And ultimately, that's what gets gets tripped up by with XML, but it sees the same bits. It can't work out which one's which. It would need to dig into the XML schema and understand which are the identifying properties, master label, API name, those those critical ones to know which each block actually refers to.
And the metadata API can return data, especially around profiles in nondeterministic ways.
So you can find that the retrieval of the same item can actually be come back in a different order, and that obviously can get up as well due to the XML parsing issues.
So with that context set, we'll have a look at these five packages about how we can reduce the instances of merge conflicts occurring.
We'll dig into each one in detail I won't read through them specifically here. So the first one is avoiding having teammates working on the same part of an org.
Like we said at the start, you know, two people working on the same thing in different ways is going to result in an increased risk of conflicts.
The example I like to think about here is where you've got be, I had some couriers and a dispatcher.
And at the start of the day, the dispatcher gets the, you the job orders, the tasks to do, prints them out five minutes before they start.
Your looks at the first one, courier one at the first of the Right? You're going up to floor twenty of that building.
Second job, you're going up to floor twenty one of the same building.
That's clearly inefficient, right? That's obviously wouldn't you would expect that not to happen in real life. If you use things like field service, you know, the whole dispatching logic. There's lots of lots of solutions for problems like that.
But you would expect that dispatcher to have done some sort of curation of the tap, the job list, come up with the idea of sending the first curry with both parcels, basically to the same building, to be the correct solution.
And that translates to your feature backlog.
If you've got two developers who are about to work on the same same bit of metadata in two different features.
As we've discussed, this is where your conflicts are going to arise.
So looking at the backlog and either working out whether these can potentially be combined, or separated, staggered. The second can't start until the first is finished potentially.
Will help you avoid the conflict happening in the first place.
It's a wide it widens this out a bit because the question then that would follow on, I guess, would be, well, how do we know what we're gonna be working on?
And having a solid application architecture that's well known, that's easy to pick up, and tenure, of course, can help with developers becoming familiar with the projects that they're working on.
But a team working on the backlog together to join stories to split them apart to understand exactly what the solution would be.
What changes are going to be needed to be made to achieve the outcome.
In that sense, you can pre prevent the conflicts occurring in the first because you're preempting it by knowing exactly what's going to be worked on in parallel.
Joining stories is obviously one of the solutions.
The staggering was the other. You might then think about, well, we join stories up together, what if the business only want one of the two to go? You know?
This comes back to understanding the the actual requirements. If you're working on something and the business don't want it to get and move on into the production org, you've then spent a lot of time working on something that's ultimately not adding value.
So shifting left, identifying the value, identifying the solutions, and keeping those that work on the same bit of the separate avoids the conflict from ever occurring.
Emerging is critically important. What we what we mean about early here is within the life cycle of the story itself.
The one thing that's bound to cause trouble, as we mentioned at the start, long live feeds branches. The sooner you're going to merge these branches, the much less chance there is for anything to conflict with it. You can see here in the diagram, if it's clear enough, the strategy where we're merging early, we can potentially conflict we've got three potential conflicts merging late, there's six.
So simply by merging early, every branch has started at the same point essentially, but because of how they've been merged in, we've cut in half the number of potential conflicts that there might be.
Branches can can certainly stay around longer where you've got where they descend into Decates about acceptance criteria, we're back to those again, or long running code reviews. If there's no clarity, If there's no definition of done for a particular feature, this can lead to branches being left open for longer as people try and work out exactly whether it's completed or not. So again, shifting it left being absolutely clear on on what you're gonna work on how gonna provide it and how you're gonna test it to know that it's good enough to then be merged.
The third option, the third strategy is to merge often, which on the face, it might seem like the same thing as the last.
It's it's a different lens the same problem. That's for sure. You know, if the longer a branch exists, the more changes it couldn't accumulate, and the more the more chance there is of those changes complete me something else.
If you've got completed and validated work, stuck on feature branches, it isn't being merged. It's not unlike having them having stuck in a warehouse that you could sell I mean, it's just stuck in the warehouse. It's not providing any value to your end users. It's getting in the way of other in the warehouse. When you actually need to get to it, it's problematic. Right? It's hidden.
It's hidden on the stuff. And it's just cool you cost to maintain.
And ultimately, when it does come to merge, you've then got a raft of conflicts potentially, that someone needs to wind back three months to pick out a hopefully rather extreme figure. But going back to someone saying, you worked on this three months ago. I'm trying to merge it. It's now conflicted.
Help me solve it. They're unlikely to be able to provide you with any, rapidity, the, the state of their mind when they were making those changes.
And the chances of course, in that scenario that what it's conflicting with is work done by somebody else who's maybe not even on the project or with the company anymore, and how do you get it how do you get their thoughts? It's very difficult.
So merging often, is a significant strategy for avoiding merge conflicts.
Abandon work as well. That's another another potential issue.
Work that gets into something like your UAT environment and hangs around for ages, waiting for someone to test it, waiting to be approved. Again, that whole sort of debate about, is it finished? Is it ready? Is it is it acceptable?
You want to avoid those sorts of scenarios.
So this this one strikes at the heart of, of good setups.
Having when we say teammates here, that would be, effectively, the developers, right, encourage the team, the team, the people are creating the changes to take ownership of their merges.
This isn't overriding the idea of peer review or anything like that, that should, still have critical parts of the process.
But DevOps came about because of the silo between development and operations, of course development do the work specifically each feature, and then throw it over the wall is the old phrase to operations who've got to create some sort of release out of it. It's the equivalent of flat pack furniture, if you will. You know, you get all these components. You've got to put them together.
If they've not been created in a way that's been proven that they fit together, you as the constructor are gonna have a heck of a job trying to create whatever it's meant to at the end of it.
So by having the developers take on the responsibility of merges, if conflicts exist, then they're gonna be much better placed to be able to solve this. They're gonna be closer to the work. If you're merging earlier, merging often. They're getting them they're encountering these issues to solve while it's all fresh in their mind.
And you don't have that problem of a manager having to sort out hundreds of potential pull request merges that are all potentially conflicting against each other.
It's not also to eliminate the concept of a release manager, as we mentioned. It's you know, there's lots of use cases where that that's still a very relevant role. You know, I've worked on plenty of projects where I didn't get a license for the production environment, because it cost a bit. I didn't need access. It was a customer's data who I I shouldn't see in any of.
So there were internal release teams, you know, that's not we're not saying that the developers should go all the way to production.
But creating, as far as that first integration point, where they can prove this is becoming a a solid unit of release to take forward down the pipeline, then definitely the best place to start that process. And it as we said, it's a true spirit of DevOps. Calabrio across roles, not becoming one set of people doing everything, but having an overlap between responsibilities to make that handover between the stages much much more agreeable, more seamless.
Good practice of decomposition for Apex classes.
So we've spoken about, we've spoken about the team We've spoken about product owners, curating the backlog, architecture.
Is the is the focus here. Having a a defined and clear architecture One thing that surprised me when I moved into the Salesforce world for sure was the, the difference in adoption of things like the object oriented standards, the the gang of four, the pat those those pans, use of interfaces, and all this sort of stuff.
The single responsibility principle, if you've ever looked at an org and found a a trigger handler class for an account or contact, that's three and a thousand lines long, you'll probably realize that that isn't often it's not quite as common in Salesforce as maybe it is in other in other environments.
Thinking back to how we defined the merge conflict, two different branches, the same bit of metadata in different ways.
A class like that that's three thousand lines long is a prime candidate for a in merge conflicts.
Salesforce when they brought our SFDX attacks, like the object file, the huge monolithic object file that that were just, you know, again, thousands of lines long and split it apart so that each field became its own file. That's essentially what the respond. This is what we're looking at for Apex classes here.
Smaller classes, more classes, smaller classes classes that that do one thing, that you haven't got these huge trigger handler classes that do absolutely everything related to it, you know, inserting other objects, deleting things that aren't even related to the object that their trigger handler for.
If you've got patterns or, matches, you know, that there's some sort of alphabetical order or all private methods go together or something. It's very easy for two purpose working on a busy class like that to try and put something new in at the same point on different branches.
And again, that's exactly how a conflict come about.
It's not just Apex crosses though. Of course now, flows. You can create sub flows.
You can you can also create some pretty hefty old main flows that that could become like the the monolithic Apex classes, so you can split flows apart as well.
I'm not sure quite how, things like profiles and permission sets really escape the SFDX, model. They're still these huge monolithic XML files, which are obviously the, you know, tick any number of boxes for being susceptible to merge conflicts, but there's we'll have a look at some I some alternative approaches that can help with those sorts of files. But we seen across these five examples how various roles, not just developers. We might frame merge conflicts as they're a developer thing. Right? There are things that developers get that developers have to solve, and they do. You know, developers end up with the consequences of it, or maybe release managers as we discussed, although that's not ideal.
But the avoidance of them in the first can be more of a team exercise.
You can anticipate scenarios in which they're going to emerge, and you can work as a team to address that.
So one other I'll just do quick time check. So that started as a very odd number. How are we doing? About ten minutes. Good.
Alright. So the strategies that we've looked at so far have covered one of the two common use cases. We said there were two main causes. These were long running feature branches, and Salesforce's representation of XML. What we've looked at so far largely fits in that first well, exclusively fits in that first bucket. Smaller stories, more agility, more collaboration, lots of dev ops things.
Now pipeline, Gearsat pipelines will will cover both.
Pipelines is our functionality to give you this high level overview of everything that's going through your workflow, you can you can see you've you've probably seen this in other sessions today as well, so you may be familiar if you're not, a gear set customer representation of features going into orgs, where you can see the components that are in there. You can see if there's any conflicts, you can resolve com within gear set, but it gives you this high level overview of your whole workflow pipeline.
What it also has though is a proprietary semantic merge algorithm.
And this if you think back to when we were describing, the XML and the the the concept the the paragraphs in a book all starting and ending with the same thing and how you'd have to dig into the middle bit to know which one any particular paragraph was.
This is what gearset does with the Salesforce XML. It knows what Salesforce XML means. It knows what the relevant, you know, the significant properties are in any given file. So if you give it a profile that's all come back jumbled up on a feature branch, when the developers pulled it from the org, when compared to what's in the, environment branch, then gear set can reorder because it knows what blocks make sense, and it can find, actually, when your version control system has thrown up its hands and said, this looks horrific conflicted.
If you've ever seen, a conflicted profile XML file with fifteen hundred reds and greens all over the place.
You can see that in gear set and say, actually, there's no change or there's one new field. That's the net change here. So get get as it understands that, and makes those sorts of merge conflicts disappear. This isn't about avoidance.
This is about actually realizing that there is no merge conflict in the first place.
We've got a merge conflict UI. You can resolve the conflicts directly in gear set, you used to just be able to choose a theirs or hours scenario, but you can even now take certain chunks from one side or the other if the if the resolution needs to be a, combination of the two.
We that like we said at the start, though, there's no automation of it. We will show genuine merge conflicts.
It's just semantic ones that Gearset will solve. If two people have changed a label to two different things, That's a real merge conflict, and gearset will show you that.
How you actually get to a scenario where people have changed the label in two different ways is another matter be that's some something for the other five steps that we looked at before.
So We've spoken a number of times about culture and teams working together in collaboration.
And ultimately, that is the bedrock of DevOps. And so it's just focused on a specific something like complex might seem to developers.
Actually, teams working and embracing DevOps as a way of working, it a fundamental part of improving your process such that you not just avoid merge conflicts, right? But increase that performance as we were just seeing in the last session there, getting those metrics, whatever they are, whatever's important to you, climbing in the direction that you want them to go.
By combining those five strategies, use of gear sets pipelines as well for the bits that the strategies can't handle, then that'll get you definitely climbing your dev ops maturity and getting those numbers going in the the right direction. So we'd recommend anyone here isn't a customer of gear set.
To take out the fully featured thirty day trial, you can you can use pipelines, you can use every every bit of the gear set platform, and benefit from all our instant tune and support, and all the good stuff that I'm sure you've learned about gear set across the course of today. So far, So, well, I should mention as well actually that straight after this, or after straight after this is coffee.
After coffee, there's a, a meet the product owner's session in the library room, which is upstairs on the right, where they'll be represented the pipelines feature, as well as other other areas of the gear set platform, he'll be delighted to take your questions and, your comments about about anything gear set. But with that in mind, If anyone's got any product specific questions, that forum upstairs would be a perfect place for those. But if there's any more conceptual about what we've just heard, then I'd be delighted to take any questions now.
Nothing.
Nothing. Nothing. Nothing. Nothing. Nothing. Nothing. Nothing. Nothing. Nothing. Nothing. Nothing. Cool. Well merge conflicts. Don't don't don't get him anymore now.
No. No excuses. You've got merge conflicts. Gone. All gone. Well, lovely. Very much, everybody. Andy.
Thank you.