aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

Git Rebase vs Merge: wanneer gebruik je wat

De keuze tussen git rebase en git merge wordt in de meeste teams veel vaker bediscussieerd dan begrepen. Beide combineren het werk van twee branches; het verschil zit in hoe de geschiedenis er daarna uitziet en in hoe je conflicten afhandelt. Dit artikel laat zien wat elk commando werkelijk doet, wanneer je voor welke kiest, en de klassieke ongelukken waar teams tegenaan lopen, allemaal met concrete voorbeelden.

Beide doen hetzelfde werk, maar schrijven de geschiedenis anders

Stel dat je feature hebt afgetakt van main, en terwijl je werkte, is main verder gegaan. Nu wil je de nieuwe commits van main in je branch. Daar zijn twee manieren voor.

Merge neemt de uiteinden van beide branches en maakt een nieuwe merge commit. Je eigen commits blijven ongemoeid; de twee geschiedenissen worden simpelweg op één punt aan elkaar geknoopt:

git checkout feature
git merge main

Rebase zet je commits tijdelijk opzij, verplaatst het startpunt van je branch naar de laatste main, en past je commits opnieuw toe bovenop die nieuwe basis, één voor één:

git checkout feature
git rebase main

Het resultaat: na een merge vertakt en herenigt de geschiedenis zich, terwijl ze na een rebase een rechte lijn lijkt, alsof je vanaf het begin op de huidige main had gewerkt.

Rebase kopieert commits, het verplaatst ze niet

Dit is het cruciale punt om te begrijpen: rebase verplaatst je commits niet, het kopieert ze. Elke opnieuw toegepaste commit krijgt een nieuwe hash, want al is de inhoud identiek, hij hangt nu aan een andere parent. De oude commits blijven nog even in je reflog staan, maar je branch wijst nu naar de nieuwe kopieën.

Het praktische gevolg is groot: rebase herschrijft de geschiedenis. Op een lokale branch die je met niemand hebt gedeeld, is dat volkomen veilig. Maar doe je het op een gedeelde branch die anderen al gepulld hebben, dan komt ieders geschiedenis niet meer overeen met de jouwe. Dat brengt ons bij de allerbelangrijkste regel.

De gouden regel: rebase nooit gedeelde geschiedenis

Onthoud je maar één regel, dan voorkom je de meeste problemen:

  • Rebase gerust branches die alleen van jou zijn, nog niet gepusht, of waar niemand werk op heeft gebaseerd.
  • Rebase nooit branches die iedereen deelt, zoals main of develop.

Heb je een feature-branch gerebased die je al had gepusht, dan moet je force-pushen om de remote bij te werken. Geef hier in plaats van een kale --force altijd de voorkeur aan de veiligere variant:

git push --force-with-lease

--force-with-lease weigert de push als de remote branch afwijkt van wat je het laatst zag (dus als iemand er ondertussen op heeft gepusht), zodat je het werk van een teamgenoot niet stilletjes overschrijft. Een gewone --force biedt die bescherming niet.

Conflicten: in één keer of stap voor stap

De conflictafhandeling verschilt aanzienlijk tussen beide. Bij merge komen alle wijzigingen op één punt samen; je lost de conflicten één keer op, draait git add, en voltooit de merge.

Bij rebase kunnen conflicten, doordat je commits op volgorde opnieuw worden toegepast, bij elke commit apart opduiken. Als meerdere van je commits dezelfde regel raken, moet je een vergelijkbaar conflict misschien meerdere keren oplossen. De flow gaat zo:

# los de conflicterende bestanden op, dan:
git add <bestand>
git rebase --continue

# om die commit over te slaan:
git rebase --skip

# om alles te annuleren en terug te gaan:
git rebase --abort

Loopt het uit de hand, dan brengt git rebase --abort je precies terug naar de toestand van vóór de rebase; als je vastloopt kun je dus rustig annuleren en opnieuw proberen in plaats van te panikeren.

De geschiedenis opschonen met interactieve rebase

Het krachtigste gebruik van rebase is niet branches combineren, maar je eigen commitgeschiedenis bewerken. Met git rebase -i (interactief) kun je commits samenvoegen, herordenen of hun berichten corrigeren voordat je pusht:

git rebase -i HEAD~4

In de editor die opent, kies je per commit een commando: pick (zo laten), squash (samenvoegen met de vorige), reword (bericht aanpassen), drop (verwijderen). Zo vouw je een rommel van "fix", "weer een fix", "typo" commits samen tot één betekenisvolle commit en maak je de pull request de moeite van het reviewen waard. Doe ook dit alleen op commits die je nog niet hebt gedeeld.

Een praktische teamstrategie

Voor de meeste teams werkt een hybride aanpak goed:

  • Om je feature-branch actueel te houden, rebase je main in je branch (git rebase main), zodat de geschiedenis vlak blijft en er geen nutteloze merge commits opstapelen.
  • Bij het binnenhalen van de feature-branch in main gebruik je merge, vaak met --no-ff, zodat "deze feature kwam hier binnen" duidelijk vastligt in één merge commit.
  • Voor je de pull request opent, ruim je je commits op met git rebase -i.

Veel teams integreren PR's ook via "squash and merge": de hele feature landt als één commit op main. Dat houdt de main-geschiedenis uiterst leesbaar, met elke regel voor één feature. Welke strategie je ook kiest, het draait erom als team consistent te zijn; een team waarin de helft rebaset en de helft merget, krijgt de slechtste geschiedenis van allemaal.

Veelgestelde vragen

Is rebase gevaarlijker dan merge?

Het is niet gevaarlijk, het heeft alleen regels omdat het de geschiedenis herschrijft. Op lokale, niet-gedeelde branches is rebase volkomen veilig en houdt het de geschiedenis schoon. Het enige echte gevaar is een gedeelde branch die anderen gebruiken rebasen en force-pushen; zolang je die regel niet breekt, kun je het vrij gebruiken.

Hoe annuleer ik een rebase als er een conflict optreedt?

Het commando git rebase --abort brengt je precies terug naar de toestand van voordat je de rebase begon. Je verliest geen enkele commit, en uitstappen om met een merge verder te gaan is een prima keuze als je in de war raakt.

Wat als ik per ongeluk mijn geschiedenis kapotmaak?

git reflog is je vangnet. Git bewaart een tijdje elke oude positie waar je branch naar heeft gewezen; zoek de juiste hash in de reflog en keer terug naar dat moment met git reset --hard <hash>. Daarom is "de geschiedenis herschrijven" veel minder definitief dan het klinkt.

Wil je de Git-workflow van je team vereenvoudigen? Laten we samen verstandige branchingstrategieën, CI/CD-integratie en een schone commitgeschiedenis opzetten. Neem contact op en we ontwerpen een workflow die bij je project past.

Devamı için