Merge — is een bewerking in Git die wijzigingen uit de ene branch in de andere samenvoegt, waarbij een merge commit wordt aangemaakt. Git ondersteunt verschillende strategieën: fast-forward (lineaire geschiedenis), three-way merge (met aanmaak van een merge commit) en squash merge (samendrukken van alle commits in één). Volgens gegevens van git-scm.com, 2025, blijft merge het meest gebruikte mechanisme voor code-integratie in teamontwikkeling met Git.
Belangrijkste
Merge (samenvoegen) — is een fundamentele bewerking in Git die wijzigingen van de ene branch (source) naar de andere (target) samenvoegt. Als resultaat van het samenvoegen ontvangt de doelbranch alle commits uit de bronbranch die er nog niet in aanwezig waren. Afhankelijk van de situatie kan Git merge op drie verschillende manieren uitvoeren.
De belangrijkste waarde van merge is het behoud van de geschiedenis: de merge commit legt het feit van het samenvoegen van branches vast, bewaart informatie over wanneer en welke branches zijn samengevoegd. Dit vergemakkelijkt de audit van wijzigingen, het vinden van regressies en het begrijpen van de ontwikkelingschronologie. In grote projecten is de merge commit de standaardmanier van code-integratie.
Volgens GitLab Flow worden merge commits gebruikt in 73% van de teams die met Git werken. Alternatieve benaderingen (rebase, squash) hebben de voorkeur van teams die gericht zijn op lineaire geschiedenis. De keuze van strategie hangt af van de teamgrootte, de frequentie van releases en de in het project aangenomen afspraken.
Merge is nodig wanneer een ontwikkelaar klaar is met het werken aan een functie en deze wil integreren in develop of main. Een typisch scenario: een ontwikkelaar heeft een feature branch gemaakt van develop, er een paar dagen aan gewerkt, en in die tijd zijn er nieuwe commits van andere deelnemers in develop verschenen. Vóór het samenvoegen moeten de wijzigingen worden gecombineerd — en daarvoor wordt merge gebruikt.
Zonder merge is het onmogelijk om gezamenlijk aan dezelfde code in Git te werken. Elke keer dat twee ontwikkelaars tegelijkertijd wijzigingen aanbrengen in dezelfde codebase, divergeren hun branches. Merge — is de enige manier om deze wijzigingen terug samen te brengen zonder gegevensverlies.
Git ondersteunt drie typen merge, elk bedoeld voor zijn eigen scenario. De keuze van het type samenvoegen beïnvloedt de commitgeschiedenis, het gemak van terugdraaien en de leesbaarheid van de log.
Fast-forward treedt op wanneer de doelbranch geen nieuwe commits heeft gehad sinds het aanmaken van de bronbranch. In dit geval verplaatst Git eenvoudigweg de aanwijzer van de doelbranch naar voren, naar de laatste commit van de bronbranch. De geschiedenis blijft lineair, zonder merge commit.
# Fast-forward merge: develop is niet veranderd sinds het aanmaken van feature
git checkout develop
git merge feature/new-login
# Resultaat: de aanwijzer van develop is verplaatst naar het einde van feature
# Er is geen merge commit aangemaakt
Fast-forward is handig voor kortlevende branches, waar de ontwikkelaar alleen heeft gewerkt. Maar deze benadering heeft een nadeel: de informatie dat de branch bestond, gaat verloren — alle commits zien eruit alsof ze direct in develop zijn gemaakt.
Three-way merge wordt uitgevoerd wanneer beide branches na het divergentiepunt nieuwe commits hebben. Git maakt een aparte merge commit met twee ouders, die het feit van het samenvoegen van branches vastlegt. Deze benadering wordt aanbevolen voor feature branches in teamontwikkeling.
# Geforceerde three-way merge met de vlag --no-ff
git checkout develop
git merge --no-ff feature/new-login
# Merge commit aangemaakt met standaardbericht
# Kan eigen bericht instellen via -m
git merge --no-ff feature/new-login -m "Merge feature/new-login into develop"
De vlag --no-ff garandeert het aanmaken van een merge commit, zelfs als fast-forward mogelijk is. Dit is de beste praktijk voor het behoud van informatie over vertakkingen in het project.
Squash merge perst alle commits van de bronbranch in één samen en past deze toe op de doelbranch. De functiegeschiedenis gaat verloren — er komt één commit met alle wijzigingen in de branch. Dit is handig wanneer gedetailleerde commits in de feature branch geen waarde toevoegen aan de algemene geschiedenis.
# Squash merge: alle commits van feature samengeperst in één
git checkout develop
git merge --squash feature/experimental
git commit -m "feat: experimental login flow (squashed)"
Squash is geschikt voor kladjes, experimentele branches en situaties waarin het belangrijk is om de geschiedenis schoon te houden. Nadeel — de verbinding met de originele commits gaat verloren, wat het terugdraaien van individuele wijzigingen bemoeilijkt.
Ours en Theirs — twee speciale merge-strategieën in Git. Ours negeert volledig de wijzigingen uit de bronbranch en behoudt alleen wat in de doelbranch staat. Theirs daarentegen accepteert bij elk conflict de versie van de bronbranch. Deze strategieën zijn nuttig bij het samenvoegen van grote hoeveelheden code, wanneer van tevoren bekend is welke versie moet winnen.
Het mechanisme van merge in Git is gebaseerd op het vergelijken van drie punten: de gemeenschappelijke voorouder (merge base), de toestand van de bronbranch en de toestand van de doelbranch. Git vindt de merge base — de laatste commit die gemeenschappelijk is voor beide branches — en berekent welke wijzigingen er in elke branch na divergentie hebben plaatsgevonden.
Git gebruikt het drievoudige algoritme voor samenvoegen, dat niet alleen de twee vergeleken versies van het bestand in overweging neemt, maar ook hun gemeenschappelijke voorouder. Dankzij dit kan Git automatisch situaties oplossen waarin wijzigingen in de ene branch de gewijzigde delen van de andere niet beïnvloeden — zelfs als beide bestanden zijn gewijzigd.
Laten we het volgende scenario bekijken: twee ontwikkelaars werken aan verschillende bestanden in dezelfde feature branch. De eerste heeft LoginActivity.kt gewijzigd, de tweede — ProfileFragment.kt. Wanneer ze hun wijzigingen samenvoegen, ziet Git dat de wijzigingen verschillende bestanden betreffen en voert merge automatisch uit, zonder menselijke tussenkomst.
Als beide ontwikkelaars LoginActivity.kt hebben gewijzigd, maar in verschillende methoden — zal Git het ook automatisch afhandelen door de wijzigingen regel voor regel te combineren. Een conflict ontstaat alleen als beide dezelfde regels hebben gewijzigd of als de ene code heeft verwijderd die de andere heeft gewijzigd.
Een merge conflict ontstaat wanneer Git de wijzigingen niet automatisch kan combineren, omdat beide branches dezelfde regels op verschillende manieren hebben gewijzigd. In dit geval markeert Git de conflictgebieden in de bestanden en wacht op handmatige oplossing door de ontwikkelaar.
Conflictgebieden worden gemarkeerd met speciale markers: <<<<<<< HEAD toont code uit de doelbranch, ======= — de scheiding, >>>>>>> source-branch — code uit de bronbranch. De ontwikkelaar moet handmatig kiezen welke variant te behouden of ze te combineren.
# 1. Start merge en zie het conflict
git merge feature/new-login
# Uitvoer: CONFLICT (content): Merge conflict in LoginActivity.kt
# 2. Bekijk de lijst van bestanden met conflicten
git status
# both modified: src/ui/login/LoginActivity.kt
# 3. Los het conflict op: bewerk het bestand, verwijder markers
# 4. Voeg het opgeloste bestand toe en voltooi merge
git add src/ui/login/LoginActivity.kt
git merge --continue
# of: git commit (zonder --continue)
Voor het oplossen van conflicten zijn er hulpmiddelen: git mergetool opent een visuele merger (Meld, Beyond Compare, VS Code). Veel ontwikkelaars geven er de voorkeur aan conflicten in de IDE op te lossen — IntelliJ IDEA en Android Studio bieden een ingebouwd hulpmiddel met driepaneelsvergelijking, dat dit proces aanzienlijk vereenvoudigt.
Tips voor het oplossen van conflicten: begrijp altijd wat elke kant van het conflict doet, verwijder andermans code niet zonder de logica ervan te begrijpen, en als het conflict te complex is — betrek de auteur van beide branches bij de gezamenlijke oplossing.
De keuze tussen Merge en Rebase — een van de meest voorkomende architecturale beslissingen in Git. Beide benaderingen combineren wijzigingen, maar doen dit op verschillende manieren: merge behoudt de vertakkingsgeschiedenis, rebase herschrijft de geschiedenis en maakt deze lineair.
Veel teams gebruiken een hybride benadering: rebase om de feature branch bij te werken naar de huidige staat van develop (git rebase develop), vervolgens merge met de vlag --no-ff om het samenvoegen vast te leggen. Dit geeft een schone geschiedenis binnen de functie en informatieve samenvoegpunten op het niveau van develop.
Veelgestelde vragen
Zonder --no-ff voert Git fast-forward merge uit, indien mogelijk — eenvoudigweg de branchaanwijzer verplaatsen. Met --no-ff maakt Git altijd een merge commit aan, waarbij informatie over vertakkingen behouden blijft. Aanbevolen voor feature branches in teamontwikkeling.
Gebruik git mergetool of het ingebouwde hulpmiddel van de IDE. Als het conflict tientallen bestanden betreft — zijn de branches mogelijk te ver uit elkaar gegroeid. In dat geval is het verstandig om met het team een samenvoegplan te bespreken, mogelijk het in meerdere fasen op te delen.
Ja: git merge --abort annuleert merge als deze nog niet is voltooid (conflict). Als merge al is voltooid — gebruik dan git reset --hard HEAD~1 of git revert -m 1 <merge-commit> voor een veilige terugdraaiing.
Aanbevolen voor teamwerk. De merge commit legt het feit van samenvoegen vast, bevat verwijzingen naar beide branches en vergemakkelijkt het begrijpen van de geschiedenis. Voor persoonlijke of experimentele branches is squash merge of fast-forward acceptabel.
Git kan binaire bestanden niet automatisch samenvoegen — het kiest één van de versies in zijn geheel. Voor binaire bestanden (afbeeldingen, .aab, .apk) wordt aanbevolen parallelle wijzigingen te minimaliseren en Git LFS te gebruiken voor grote bestanden.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook