Samenvoegen of mergen — is de bewerking van het samenvoegen van twee branches in Git, waarbij wijzigingen van de ene branch naar de andere worden overgebracht. In moderne softwareontwikkeling is merge de standaard manier om een feature-branch in de hoofdbranch van het project te integreren. Volgens GitHub Octoverse 2024 worden er dagelijks meer dan 15 miljoen merges uitgevoerd. Merge — het belangrijkste mechanisme van samenwerking, waarmee het werk van meerdere ontwikkelaars in één product kan worden verenigd.
Belangrijkste punten
Merge in Git — is de bewerking van het samenvoegen van twee of meer ontwikkelingsgeschiedenissen in één. Wanneer een ontwikkelaar een branch merged, vindt Git automatisch de gemeenschappelijke voorouder (base commit) en maakt een nieuwe merge-commit die de wijzigingen van beide branches bevat. Three-way merge — het standaardalgoritme dat drie toestanden vergelijkt: de gemeenschappelijke voorouder, de eerste branch en de tweede branch.
Het merge-proces begint met het commando git merge. Git bepaalt het punt waar de branches uiteenliepen en past de wijzigingen van de bronbranch sequentieel toe op de doelbranch. Als de wijzigingen niet conflicteren, voert Git fast-forward uit of maakt een merge-commit, afhankelijk van de instellingen. Fast-forward — het scenario waarbij de doelbranch eenvoudigweg wordt verplaatst naar de commits van de bronbranch.
# Schakel naar doelbranch en voeg samen
git checkout main
git merge feature/payment-module
# Voeg samen met expliciete no-fast-forward
git merge --no-ff feature/payment-module
# Breek samenvoeging af als conflicten te complex zijn
git merge --abort
De vlag --no-ff (no fast-forward) forceert het maken van een merge-commit, zelfs wanneer fast-forward mogelijk is. Dit bewaart de informatie dat de wijzigingen in een aparte branch zijn gemaakt. Veel teams geven de voorkeur aan deze aanpak om de vertakking van de geschiedenis expliciet te behouden.
In Git bestaan drie hoofdstrategieën voor het samenvoegen van branches, elk geschikt voor een specifiek scenario. De keuze van de strategie hangt af van de teamcultuur en de vereisten voor de zuiverheid van de projectgeschiedenis.
| Strategie | Resultaat | Wanneer toepassen |
|---|---|---|
| Standard merge | merge-commit + volledige geschiedenis | teams die volledige geschiedenis waarderen |
| Squash merge | één commit, geschiedenis samengeperst | feature-branches met veel kleine commits |
| Rebase merge | lineaire geschiedenis, zonder merge-commit | persoonlijke feature-branches, vóór het maken van een PR |
Standard merge maakt een merge-commit met twee ouders. De volledige geschiedenis blijft behouden, maar de vertakkingsgraaf wordt complexer. Squash merge combineert alle commits van de feature-branch in één en past deze toe op de doelbranch — de geschiedenis wordt lineair en schoon, maar informatie over tussenliggende stappen gaat verloren.
Rebase, hoewel geen volwaardige merge, bereikt hetzelfde resultaat — wijzigingen van de ene branch worden overgebracht naar de andere. Het verschil is dat de geschiedenis wordt herschreven: commits van de feature-branch worden opnieuw gemaakt bovenop de laatste commit van de doelbranch. Dit geeft een perfect lineaire geschiedenis, maar vereist force push bij het verzenden.
Een conflict bij mergen ontstaat wanneer in twee branches dezelfde regels van een bestand zijn gewijzigd. Git kan niet automatisch bepalen welke versie behouden moet worden en vereist tussenkomst van de ontwikkelaar. Conflicten worden in bestanden weergegeven als speciale markers: <<<<<<<, =======, >>>>>>>.
Het conflictoplossingsproces omvat verschillende stappen. Eerst opent de ontwikkelaar het conflicterende bestand en kiest handmatig de gewenste wijzigingen. Het is belangrijk om niet simpelweg een van de versies te kiezen, maar de logica van beide wijzigingen te begrijpen en een correcte beslissing te nemen. Na het bewerken van het bestand worden de conflictmarkers verwijderd en worden de wijzigingen via git add aan de staging area toegevoegd.
# Bekijk lijst van conflicterende bestanden
git status
# Start mergetool (bijv. VS Code, IntelliJ)
git mergetool
# Na het oplossen van alle conflicten
git add .
git merge --continue
# Of breek de samenvoeging volledig af
git merge --abort
Het gebruik van visuele merge-tools versnelt het oplossen van conflicten aanzienlijk. VS Code, IntelliJ IDEA en GitKraken bieden interfaces met drie panelen: huidige branch, inkomende branch en resultaat. De tool git mergetool opent automatisch de geconfigureerde editor voor elk conflicterend bestand.
De beste manier om complexe conflicten te voorkomen is regelmatige synchronisatie van de feature-branch met de hoofdbranch. Als de ontwikkelaar dagelijks main in zijn eigen branch merged, zullen conflicten klein en gemakkelijk oplosbaar zijn. Ophoping van wijzigingen gedurende een week garandeert complexe conflicten met een hoog risico op fouten.
Rebase en merge — twee manieren om wijzigingen te combineren, en de keuze ertussen veroorzaakt vaak discussies in teams. Rebase verplaatst commits van de ene branch naar de andere en herschrijft de geschiedenis. Merge maakt een nieuwe merge-commit en behoudt de vertakkingsgeschiedenis. Elke benadering heeft zijn voor- en nadelen.
Rebase is geschikt wanneer een ontwikkelaar in zijn lokale feature-branch werkt en een schone lineaire geschiedenis wil krijgen voordat hij een Pull Request maakt. Na rebase worden alle commits sequentieel gerangschikt, zonder overbodige merge-commits. Rebase vereist echter force push en is niet toepasbaar op branches waar meerdere mensen tegelijkertijd aan werken.
De gouden regel van Git: gebruik geen rebase op commits die al naar de gedeelde repository zijn gepusht. Dit garandeert dat de geschiedenis in de gedeelde branch onveranderd blijft en andere ontwikkelaars geen dubbele of verloren commits tegenkomen. Voor integratie van de feature-branch in de hoofdbranch gebruik je merge via Pull Request.
Het juiste merge-proces — de basis van stabiele ontwikkeling. In modern teamwerk wordt merge niet via de console uitgevoerd, maar via Pull Request op GitHub of Merge Request in GitLab. Een PR doorloopt code-review, automatische CI-controles en wordt pas daarna in de hoofdbranch gemerged.
Eerste praktijk — merge alleen na het doorstaan van alle controles. De CI-pipeline moet het project bouwen, tests uitvoeren en de codekwaliteit controleren. Als zelfs maar één controle niet is geslaagd, wordt de merge geblokkeerd. Moderne platforms (GitHub, GitLab) hebben ingebouwde bescherming: branch protection rules blokkeren automatisch merge bij CI-falen.
Tweede praktijk — merge nooit kapotte code. Voor het mergen moet de ontwikkelaar ervoor zorgen dat zijn wijzigingen de build niet breken en bestaande functionaliteit niet regresseren. Hiervoor bestaan geautomatiseerde tests en code-review.
Derde praktijk — ruim feature-branches op na het mergen. Een branch die al is gemerged, moet worden verwijderd. Dit voorkomt verwarring en rommel in de repository. GitHub biedt automatisch aan om de branch te verwijderen na het mergen van een PR, en de repository-instellingen kunnen worden geconfigureerd voor automatische verwijdering.
Veelgestelde vragen
Merge — het samenvoegen van twee Git-branches in één. Wijzigingen van de ene branch worden overgebracht naar de andere via een three-way merge. Het resultaat wordt vastgelegd in een nieuwe merge-commit met twee ouder-commits. Merge commit bewaart informatie over welke branches zijn samengevoegd.
Merge maakt een nieuwe merge-commit en behoudt de vertakkingsgeschiedenis. Rebase herschrijft de geschiedenis door commits over een andere branch te verplaatsen zonder een merge-commit te maken. Rebase geeft een lineaire geschiedenis, maar vereist force push. Merge is veiliger voor gedeelde branches, rebase is beter voor persoonlijke.
Open het conflicterende bestand, vind de markers <<<<<<<, ======= en >>>>>>>, kies de gewenste wijzigingen en verwijder de markers. Voeg het bestand toe via git add en voltooi de merge met git merge --continue. Gebruik git mergetool voor visuele oplossing in VS Code of IntelliJ IDEA.
Pull Request (of Merge Request) is verplicht bij het mergen van een feature-branch in de hoofdbranch van het project. Een PR doorloopt code-review van collega's en automatische CI-controles. Dit is de standaard van moderne ontwikkeling. Direct pushen naar de main-branch is in de meeste projecten verboden.
Squash merge combineert alle commits van de feature-branch in één vóór het mergen. Dit geeft een schone geschiedenis van de hoofdbranch zonder tussenliggende werk-commits. Gebruik squash merge wanneer de feature-branch veel service-commits (wip, fixes) bevat en het niet nodig is om alle tussenliggende stappen in de geschiedenis te bewaren.
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