M365Con 2027 – gratis online conferentie · 11–22 Jan 2027 · 120 sessions→ m365con.net

Blog · Mirko Peters

Verder dan de basis: Git-branches, merges en merge-conflicten ontrafeld

By ·

Welkom terug bij de shownotes en het bijbehorende blog van de aflevering van deze week! Als je de podcast volgt, weet je dat we de essentiële tools induiken die onze engineering- en cloudbeheerworkflows soepel laten lopen. Vandaag gaan we verder dan de introductiecommando's zoals git add en git commit. We pakken de kernmechanismen aan die junior developers én ervaren systeembeheerders de stuipen o

Automatically translated with AI from the original post. Read the English original

▶ BLOGBeyond the Basics:Demystifying Git…M365.FM
Titelbild: Beyond the Basics: Demystifying Git Branches, Merges, and Merge Conflicts

Welkom terug bij de shownotes en het bijbehorende blog van de aflevering van deze week! Als je de podcast volgt, weet je dat we de essentiële tools induiken die onze engineering- en cloudbeheerworkflows soepel laten lopen. Vandaag gaan we verder dan de introductiecommando's zoals git add en git commit. We pakken de kernmechanismen aan die junior developers én ervaren systeembeheerders de stuipen op het lijf jagen: Git-branches, merges en die gevreesde merge-conflicten.

Versiebeheer is het onzichtbare vangnet van moderne softwareontwikkeling en cloudinfrastructuurbeheer. Of je nu infrastructuur als code provisioneert met Terraform, Kubernetes-manifesten uitrolt of microservices schrijft, je moet begrijpen hoe je de geschiedenis van je code beheert. Zodra meerdere mensen dezelfde repository aanpassen, kan het zonder een degelijke branchingstrategie snel chaotisch worden. In deze diepduik behandelen we precies hoe Git branching afhandelt, hoe merges onder de motorkap werken en hoe je conflicten met vertrouwen oplost in plaats van in paniek.

De mechanismen van Git-branches begrijpen

Om Git-branches echt onder de knie te krijgen, moeten we eerst een veelvoorkomend misverstand uit de weg ruimen. Veel mensen zien een branch als een aparte map of een fysieke kopie van een codebase. Als je uit oudere versiebeheersystemen zoals SVN komt, is dat denkmodel moeilijk kwijt te raken. In Git is een branch echter niets van dat alles. Een Git-branch is simpelweg een lichtgewicht, verplaatsbare pointer naar een specifieke commit.

Zie de commitgeschiedenis van Git als een gerichte acyclische graaf, of eenvoudiger: een keten van snapshots. Elke commit bevat een cryptografische hash van de inhoud, metadata en een verwijzing naar de bovenliggende commit. Wanneer je een branch aanmaakt, kopieert Git je bestanden niet. Het maakt alleen een nieuw tekstbestand aan met een 40 tekens lange SHA-1-hash: de commithash waar de branch op dat moment naar wijst. Daardoor is het aanmaken van branches en het wisselen ertussen razendsnel, ongeacht de omvang van je project.

De HEAD-pointer en het wisselen van branches

Hoe weet Git op welke branch je op dit moment werkt? Dat gebeurt met een speciale pointer die HEAD heet. Meestal wijst HEAD naar je huidige lokale branch. Wanneer je een commando uitvoert zoals git checkout feature-branch of git switch feature-branch, past Git de HEAD-pointer aan zodat die naar de nieuwe branch wijst, en werkt het het zichtbare bestandssysteem bij naar de snapshot van de commit waar die branch naar wijst.

HEAD begrijpen is cruciaal voor cloudbeheerders en developers, omdat het je helpt de gevreesde status 'detached HEAD' te vermijden. Een detached HEAD betekent simpelweg dat je HEAD-pointer rechtstreeks naar een commithash wijst in plaats van naar een branchnaam. Als je in die status commits maakt en daarna wegschakelt, kunnen die commits verweesd raken en lastig terug te vinden zijn. Werk dus altijd op een branch!

Isolatie creëren voor veilig experimenteren

De belangrijkste kracht van branching is isolatie. In een productieomgeving wil je nooit experimentele code schrijven of een risicovolle infrastructuurwijziging testen op de hoofdbranch van productie (vaak main of master genoemd). Door een feature- of fixbranch aan te maken, creëer je een afgeschermde tijdlijn. Je kunt zoveel rommelige commits maken als je wilt, dingen kapotmaken, repareren en lokaal de geschiedenis herschrijven, zonder ooit je teamgenoten of de live omgeving te raken.

De kunst en wetenschap van het mergen van code

Zodra je feature af, getest en klaar is om te integreren, moet je die wijzigingen terugbrengen naar de hoofdcodebase. Hier komt merging om de hoek kijken. Net als bij branching heeft merging specifieke mechanismen die belangrijk zijn om te begrijpen als je een schone, leesbare projectgeschiedenis wilt behouden.

Git biedt een paar verschillende strategieën voor merges, maar de twee meest voorkomende zijn Fast-forward-merges en Three-way-merges. Het verschil tussen deze twee zal voor altijd veranderen hoe je je commitgraaf bekijkt.

Fast-forward-merges

Stel je voor dat je een nieuwe branch maakt vanaf main, drie commits maakt, en in die tijd heeft niemand anders de main-branch aangeraakt. De pointer van de main-branch is niet verschoven. Wanneer je overschakelt naar main en git merge feature-branch uitvoert, ziet Git dat de huidige branch een exacte voorouder is van de feature-branch.

In plaats van een nieuwe mergecommit te maken, verplaatst Git de pointer van de main-branch gewoon vooruit naar dezelfde commit als de feature-branch. Dit heet een fast-forward merge. Het resultaat is een lineaire, overzichtelijke geschiedenis, maar het verbergt wel dat de wijzigingen op een aparte branch zijn ontwikkeld.

Three-way merges en mergecommits

Wat gebeurt er als je main-branch *wel* nieuwe commits heeft ontvangen terwijl jij aan je feature-branch werkte? Een fast-forward merge is dan niet meer mogelijk. Je branch en de main-branch zijn uit elkaar gegroeid.

Om ze samen te voegen voert Git een three-way merge uit. Het kijkt naar drie afzonderlijke snapshots:

Git vergelijkt deze drie snapshots om een nieuwe commit samen te stellen, slim een mergecommit genoemd. Deze mergecommit heeft twee bovenliggende commits: een van je feature-branch en een van de doelbranch. Sommige ontwikkelaars geven de voorkeur aan een strikt lineaire geschiedenis (vaak bereikt via rebase), maar mergecommits zijn juist geweldig voor cloud- en infrastructuurrepositories, omdat ze een duidelijk, onweerlegbaar auditspoor geven van het moment waarop een feature-branch in productie is opgenomen.

Mergeconflicten ontrafeld: waarom ze ontstaan en hoe je ze oplost

Ah, het mergeconflict. Alleen het woord al is genoeg om koude zweetdruppels op je voorhoofd te krijgen. Je typt git merge, en in plaats van een soepele integratie zie je die angstaanjagende melding: CONFLICT (content): Merge conflict in main.tf. Automatic merge failed; fix conflicts and then commit the result.

Laten we ontrafelen waarom dit gebeurt. Een mergeconflict is geen bug in Git. Het is eigenlijk Git dat de handen in de lucht steekt en zegt: "Hé, mens, ik ben maar een domme computerprogramma. Twee verschillende personen hebben precies dezelfde regel code op twee verschillende manieren gewijzigd, en ik heb geen wiskundige manier om te weten welke wijziging je wilt behouden. Jij beslist."

Anatomie van een mergeconflict

Wanneer er een conflict optreedt, past Git de getroffen bestanden in je werkmap aan om beide versies te tonen. Als je dat bestand opent in je code-editor of via de opdrachtregel, zie je conflictmarkeringen die er zo uitzien:

<<<<<<< HEAD
resource "aws_instance" "web_server" {
instance_type = "t3.medium"
}
======
resource "aws_instance" "web_server" {
instance_type = "t3.large"
}
>>>>>>>> feature-branch

Laten we deze markeringen even doorlopen, zodat je er nooit verloren naar kijkt:

Stap-voor-stap oplossingsproces

Een conflict oplossen is een methodisch proces. Raak niet in paniek en volg deze stappen:

  1. Open het bestand in je editor: Moderne IDE's zoals Visual Studio Code hebben fantastische ingebouwde UI-tools voor het oplossen van conflicten, met side-by-side vergelijkingen en knoppen zoals "Accept Current Change", "Accept Incoming Change" en "Accept Both Changes".
  2. Bewerk de code: Bepaal hoe de uiteindelijke code eruit moet zien. Verwijder de conflictmarkeringen (<<<<<<<, =======, >>>>>>>). In ons infrastructuurvoorbeeld zou je kunnen besluiten dat je toch een t3.large-instance nodig hebt, dus verwijder je de markeringen en behoud je de binnenkomende wijziging.
  3. Markeer het opgeloste bestand als gereed: Zodra je alle conflicterende bestanden hebt opgelost, moet je Git laten weten dat het werk klaar is. Voer git add uit voor elk opgelost bestand.
  4. Rond de merge af: Voer git commit uit om de mergecommit af te ronden. Zat je midden in een complexe rebase of cherry-pick, volg dan de instructies op het scherm om door te gaan.

Best practices voor soepele samenwerking in productieomgevingen

Nu je de werking van branches, merges en conflicten begrijpt, hoe pas je dit toe in een professionele teamomgeving? Of je nu cloudinfrastructuur beheert of consumentenapplicaties bouwt, door strikte teamworkflows te volgen voorkom je catastrofale productie-storingen.

Hanteer een beproefde branchingstrategie

Laat niet iedereen naar main pushen wanneer het hem uitkomt. Implementeer een branchingstrategie zoals GitFlow, GitHub Flow of Trunk-Based Development. Voor de meeste cloudbeheerteams en teams die snel ontwikkelen is GitHub Flow buitengewoon effectief. Die werkt met één main-branch en kortlevende feature-branches die via Pull Requests (PR's) of Merge Requests (MR's) worden samengevoegd.

Pull regelmatig en rebase verstandig

Een van de belangrijkste oorzaken van grote, pijnlijke mergeconflicten is te lang in isolatie werken. Als je drie weken aan een feature-branch werkt zonder updates uit main te halen, loopt je branch flink uit de pas met de rest van het team. Maak er een gewoonte van om regelmatig updates uit main naar je feature-branch te pullen. Zo blijven eventuele conflicten klein, overzichtelijk en eenvoudig op te lossen.

Gebruik Pull Request-reviews en CI/CD-pipelines

Voeg nooit code direct samen zonder peer review. Pull requests vormen een cruciale menselijke poortwachter. Koppel bovendien je versiebeheersysteem aan een Continuous Integration (CI)-pipeline. Zodra een pull request wordt geopend, moeten geautomatiseerde tests, linters en infrastructuur-beveiligingsscans (zoals Terraform plan-controles) automatisch draaien. Als de geautomatiseerde tests falen, blijft de knop om samen te voegen vergrendeld. Zo komt kapotte code nooit in je productieomgeving terecht.

Conclusie: Git beheersen voor onbevreesde deployments

Versiebeheer is veel meer dan een back-uptool; het is de ruggengraat van samenwerkende engineering en cloudbeheer. Door te begrijpen dat branches simpelweg wijzers zijn, door in te zien hoe three-way merges de geschiedenis opbouwen en door mergeconflicten rustig en methodisch aan te pakken, verander je Git van een intimiderend obstakel in een krachtige bondgenoot.

Neem wat je vandaag hebt geleerd, open een sandbox-repository en oefen gericht met het maken en oplossen van conflicten. Hoe vertrouwder je raakt met de mechanismen onder de motorkap, hoe onbevreesder je deployments worden. Bedankt dat je meeleest met de blogpost van deze week. Abonneer je zeker op de podcast, laat een review achter en deel deze aflevering met een teamgenoot die een opfris­cursus over Git-branches kan gebruiken. Tot de volgende keer: houd je commits schoon en je pipelines groen!

Infrastructure as code Terraform

Related articles

RSS