Start free
Andrew Hanna

Andrew Hanna

Een Salesforce-bewuste git merge driver opzetten

Een Salesforce-bewuste git merge driver opzetten

Kort: Een merge driver is een programma dat git aanroept in plaats van zijn eigen regelgebaseerde merge, voor de bestandspatronen die jij aanwijst. Wijs er een aan voor je Salesforce-metadata in .gitattributes, registreer hem in de git-config van elke clone, en onafhankelijke XML-nodewijzigingen mergen vanzelf in plaats van als conflictmarkeringen binnen te komen. Het is een instelling per clone, dus je hebt een bootstrapstap nodig, en hij draait nooit op de merge-knop van je host.

Dit is de opzetgids, niet de oplosgids. Heb je nu al conflictmarkeringen open staan, lees dan eerst Salesforce-metadataconflicten oplossen zonder iemands werk kwijt te raken, en kom daarna hier terug om de volgende lichting te voorkomen.

Wat doet een merge driver precies?

Bij een three-way merge heeft git drie versies van een bestand nodig: de gemeenschappelijke voorouder, jouw kant en de binnenkomende kant. Standaard verzoent git die regel voor regel. Een merge driver vervangt die stap door een commando naar keuze, en git geeft de drie versies mee als tijdelijke bestanden.

Het contract is klein. Git vult de placeholders in op je commandoregel:

  • %O de gemeenschappelijke voorouder
  • %A jouw versie, en het bestand waarin de driver het resultaat schrijft
  • %B de binnenkomende versie
  • %P het echte pad van het bestand dat gemerged wordt
  • %L de grootte van de conflictmarkering

Exit 0 en git legt de inhoud van %A vast als een schone merge. Exit niet-nul en git behandelt het als een conflict en laat %A voor een mens liggen. Dat is de hele interface, en daarom kan een Salesforce-bewuste driver zo simpel zijn als een script dat beide kanten als XML parseert, de childnodes onder elke parent samenvoegt, en alleen afhaakt als hetzelfde sleutelelement aan beide kanten andere waarden draagt.

Hoe stel je er een in in git?

Twee bestanden, en maar een ervan zit in versiebeheer.

Registreer de driver eerst in de git-config. Die staat in .git/config en is lokaal aan de clone:

git config merge.sfxml.name "Salesforce metadata XML merge"
git config merge.sfxml.driver "sf-xml-merge %O %A %B %P"

Vertel git daarna welke bestanden hij beheert, in .gitattributes in de root van de repo. Dit bestand wordt wel gecommit, dus elke collega krijgt het:

force-app/**/*.profile-meta.xml      merge=sfxml
force-app/**/*.permissionset-meta.xml merge=sfxml
force-app/**/*.layout-meta.xml       merge=sfxml
force-app/**/*.translation-meta.xml  merge=sfxml

Begin smal. Voeg de twee of drie metadatatypen toe die de meeste conflicten opleveren, draai er een sprint mee, en verbreed de patronen daarna. Een driver die stilletjes een type verkeerd behandelt dat je nooit getest hebt, is erger dan het conflict dat hij verving.

Waarom heeft elke clone opzet nodig, en hoe automatiseer je dat?

.gitattributes zit in versiebeheer, merge.sfxml.driver niet, en git weigert een commando te draaien dat het alleen uit een gekloond bestand kent. Die scheiding is bewust beveiligingsontwerp: een repository die je kloont kan jouw machine geen willekeurige commando's laten uitvoeren.

Het praktische gevolg is dat een collega die de opzet overslaat geen foutmelding krijgt. Git valt stil terug op de ingebouwde tekstmerge en die persoon ziet conflictmarkeringen, terwijl de rest schone merges ziet. Los het op met een bootstrapstap die niemand hoeft te onthouden: commit een scripts/setup-merge-driver.sh die de twee git config-commando's draait, roep die aan vanuit de post-install hook van je package manager, en laat hem luid falen als de driver ontbreekt.

Welke merges ziet de driver nooit?

Drie gaten zijn goed om te kennen voordat je erop leunt:

  • Merges aan serverkant. De merge-knop op GitHub, GitLab of Bitbucket draait op hun infrastructuur, zonder toegang tot jouw .git/config. Een pull request die op je laptop schoon zou mergen, kan daar alsnog conflicten melden. De oplossing is de gebruikelijke: merge de doelbranch lokaal in je feature branch, waar de driver wel draait, en push de resolutie.
  • Eenzijdige wijzigingen. Git roept een driver alleen aan als beide kanten het bestand hebben aangeraakt. Veranderde maar een kant iets, dan neemt git die kant en start je driver nooit.
  • Gegenereerde XML. Een driver kan nodes samenvoegen, maar kan niet weten dat twee Flow-versies onverenigbare logica beschrijven. Houd *.flow-meta.xml buiten je patronen en los die op in Flow Builder.

Is er een variant zonder installatie?

Ja, voor de puur additieve gevallen. Git heeft een ingebouwde union-driver die alle regels van beide kanten behoudt, en die vraagt helemaal geen configregel:

force-app/**/labels/*.labels-meta.xml merge=union

Hij is bot. Union merge plakt aan elkaar in plaats van te ontdubbelen, dus een node die beide branches toevoegden landt twee keer en het bestand kan ongeldig terugkomen. Gebruik hem alleen op platte, puur additieve lijsten zoals custom labels, en houd een deployvalidatie in CI om te vangen wat er misgaat. Zie het als tussenoplossing terwijl je een echte driver beoordeelt, niet als eindstation.

Driver, platform of oplossen op de pull request?

Een merge driver is de goedkoopste laag en de smalste: hij haalt valse conflicten weg op gitniveau, op ontwikkelaarsmachines, en doet niets aan validatie of deployment. DevOps-platformen bouwen semantische merge in de pipeline met een visueel three-way paneel, wat het gat aan serverkant dicht maar de resolutie aan hun tooling bindt.

Serpent kiest de derde route en lost op de pull request zelf op. Serpent AI leest het conflict, stelt een resolutie voor en wacht op jouw review voordat het wordt toegepast, zodat de fix landt waar de merge echt plaatsvindt in plaats van op de laptop die toevallig goed is ingesteld. Bekijk Serpent AI, of blader door meer evergreen Salesforce DevOps-playbooks in de Serpent-gidsen.

Veelgestelde vragen

Moet ik de merge driver zelf schrijven?

Niet per se. Er bestaan open source Salesforce XML merge drivers, en elke XML-bewuste mergetool kun je in een shellscript van twee regels wikkelen dat het %O %A %B-contract volgt. Zelf bouwen is een redelijke middag werk als je metadata een ongebruikelijke vorm heeft.

Verandert een merge driver bestanden die al gecommit zijn?

Nee. Hij draait alleen tijdens een merge, op het mergeresultaat. De historie blijft onaangeroerd, dus je kunt er een toevoegen en weer weghalen zonder iets te herschrijven.

Wat gebeurt er als de driver crasht?

Git behandelt een niet-nul exit als een onopgelost conflict en laat de markeringen staan, dus een kapotte driver valt terug op het gedrag dat je al had. Laat die van jou niet-nul afsluiten bij alles wat hij niet begrijpt, in plaats van te gokken.

Vervangt dit het normaliseren van metadata bij retrieve?

Nee, en de twee stapelen goed. Normaliseren van elementvolgorde verkleint de diffs voordat git ze ziet, en de driver pakt op wat daarna overblijft. Doe beide als het kan.

Gerelateerde artikelen

Benieuwd naar sneller releasen voordat je instapt? Laten we praten

Vrijblijvend.