
Andrew Hanna

Andrew Hanna

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.
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.
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.
.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.
Drie gaten zijn goed om te kennen voordat je erop leunt:
.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.
*.flow-meta.xml buiten je patronen en los die op in Flow Builder.
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.
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.
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.
Vrijblijvend.