Git-tutorial: samenwerken met branches, merge en rebase
geverifieerd op 7 september 2026 · 10 min
Maak een branch met git switch -c nom, werk eraan en merge hem daarna met git merge vanaf de doelbranch. Bij een conflict zet Git markeringen in het bestand: schrijf de juiste inhoud, verwijder de markeringen en doe dan git add en git commit. git merge --abort maakt op elk moment alles ongedaan.
Een branch is een parallelle ontwikkellijn. Daarmee werk je aan een feature zonder de stabiele versie aan te raken, terwijl je collega aan zijn kant hetzelfde doet. Dit hoofdstuk behandelt de volledige cyclus: een branch aanmaken, hem mergen, een conflict met de hand oplossen en kiezen tussen merge en rebase.
git switch in plaats van git checkout
Historisch deed git checkout alles: van branch wisselen, er een aanmaken, een bestand terugzetten, naar een specifieke commit springen. Die opeenstapeling van rollen is de eerste bron van verwarring bij beginners, en een bron van ongelukken bij de rest.
Git 2.23, uitgebracht in augustus 2019, splitste het commando in tweeën: git switch om tussen branches te wisselen, git restore om wijzigingen ongedaan te maken. Bij hun release stonden ze als experimenteel te boek, in de officiële documentatie is dat niet langer zo. Dit hoofdstuk gebruikt ze, en geeft telkens het equivalent in checkout, dat je nog lang in tutorials en op Stack Overflow zult tegenkomen.
| Bedoeling | Modern commando | Oude vorm |
|---|---|---|
| Van branch wisselen | git switch nom | git checkout nom |
| Een branch aanmaken en erheen gaan | git switch -c nom | git checkout -b nom |
| Terug naar de vorige branch | git switch - | git checkout - |
| De wijziging van een bestand ongedaan maken | git restore fichier | git checkout -- fichier |
| Een bestand uit de index halen | git restore --staged fichier | git reset HEAD fichier |
Een branch aanmaken en eraan werken
git switch -c feature/panierSwitched to a new branch 'feature/panier'De branch vertrekt vanaf de commit waarop je stond. Je kunt nu gewoon wijzigen, toevoegen en committen: niets daarvan verschijnt op main zolang je het niet hebt gemerged.
Voor branchnamen legt Git geen enkele regel op, maar de prefixen feature/, fix/ en hotfix/ zijn een wijdverbreide conventie, en de interfaces van de hosters groeperen ze visueel.
Om te zien waar je staat:
git branch # de lokale branches
git branch -vv # met de laatste commit en de gevolgde remote branch
git branch -a # lokale en remote
git switch - # terug naar de vorige branchOm de branch te publiceren en zichtbaar te maken voor het team:
git push -u origin feature/panierDe branch van een collega ophalen
Andersom brengt git fetch je beeld van de server bij zonder iets in je branches te wijzigen:
git fetch origin feature/collegue # een specifieke branch
git fetch --all # alle remote repositories
git branch -r # wat je van de server weet origin/HEAD -> origin/main
origin/feature/collegue
origin/mainDaarna hoef je er alleen nog naartoe te schakelen. Git maakt de lokale branch automatisch aan en koppelt hem aan die van de server:
git switch feature/colleguebranch 'feature/collegue' set up to track 'origin/feature/collegue'.
Switched to a new branch 'feature/collegue'Als Git weigert van branch te wisselen
Dit is een van de eerste fouten die je tegenkomt:
error: Your local changes to the following files would be overwritten by checkout:
index.html
Please commit your changes or stash them before you switch branches.
AbortingGit beschermt je werk: het bestand dat je hebt gewijzigd heeft op de andere branch niet dezelfde inhoud, en wisselen zou het overschrijven. Drie oplossingen, in volgorde van voorkeur.
Committen, als het werk samenhangend is. Dat is bijna altijd het juiste antwoord, een onvolmaakte commit op een werkbranch kost niets en corrigeer je later met de commando’s om terug te komen op je stappen uit het vorige hoofdstuk.
Opzijzetten, als het werk half af is:
git stash # zet de wijzigingen opzij
git switch main # …je doet wat je te doen had…
git switch -
git stash pop # haalt de wijzigingen terugSaved working directory and index state WIP on main: 6d495d9 Page d accueilWeggooien, met git restore ., als de wijzigingen niets waard waren. Zonder weg terug.
Een branch mergen
Is de feature klaar, ga dan naar de doelbranch en merge:
git switch main
git merge feature/panierHebben de twee branches verschillende bestanden gewijzigd, dan merget Git helemaal zelf en hoeft het je niets te vragen. Interessant wordt het in het andere geval.
Een conflict oplossen
Dit is de situatie die voor dit hoofdstuk is nagebouwd. Op feature/panier is de tweede regel van index.html vervangen door een bericht dat de winkelwagen leeg is. Op main is de eerste regel aangepast om de merknaam toe te voegen. Beide branches hebben hetzelfde bestand aangeraakt.
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.Er is niets stuk. Git heeft gemerged wat het kon en laat de rest aan jou. Vraag eerst waar je staat:
git statusOn branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")Wil je alleen de lijst met te behandelen bestanden:
git diff --name-only --diff-filter=UOpen het bestand. Git heeft er markeringen in gezet:
<<<<<<< HEAD
<h1>Boutique Gekkode</h1>
<p>Bienvenue sur la boutique.</p>
=======
<h1>Boutique</h1>
<p>Votre panier est vide.</p>
>>>>>>> feature/panierHet lezen gaat mechanisch. Tussen <<<<<<< HEAD en ======= staat de versie van de branch waarop je staat, hier main. Tussen ======= en >>>>>>> staat de versie van de branch die je merget.
Aan jou om het juiste resultaat te schrijven. Dat is niet per se de ene of de andere: hier zijn beide wijzigingen goed en moeten ze naast elkaar bestaan.
<h1>Boutique Gekkode</h1>
<p>Votre panier est vide.</p>Verwijder de drie markeringen, die mogen niet in het bestand blijven staan. Meld daarna aan Git dat het geregeld is en rond de merge af:
git add index.html
git commit -m "Fusionne feature/panier dans main"* 0899b0c Fusionne feature/panier dans main
|
| * aacf4c0 Panier : message quand le panier est vide
* | 11ff16b Ajoute le nom de la marque au titre
|/
* 6d495d9 Page d accueilDe merge-commit heeft twee ouders, en de graaf maakt dat zichtbaar.
Alles annuleren en opnieuw beginnen
Gaat het conflict je boven de pet, dan zit je nergens aan vast:
git merge --abortDe repository keert precies terug naar de toestand van voor het merge-commando. Er gaat niets verloren, je kunt later opnieuw beginnen of erover overleggen met de auteur van de andere branch.
merge of rebase
Beide brengen het werk van de ene branch in de andere onder, maar niet op dezelfde manier.
git merge maakt een merge-commit die de twee geschiedenissen verbindt. De geschiedenis houdt exact bij wat er is gebeurd, inclusief het feit dat er twee branches naast elkaar hebben bestaan. De graaf is getrouw, maar hij vertakt.
git rebase speelt je commits opnieuw af boven op de doelbranch, alsof je vanaf de laatste versie ervan had gewerkt. De geschiedenis blijft een rechte lijn, makkelijker te lezen, maar ze wordt herschreven: je commits krijgen een andere hash.
git switch feature/panier
git rebase mainEen rebase kan dezelfde conflicten tegenkomen als een merge, commit voor commit. Het oplossen gaat identiek, alleen het commando om verder te gaan verschilt:
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
error: could not apply 4937109... Promo
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Could not apply 4937109... Promogit add index.html
git rebase --continue
# of, om alles te annuleren
git rebase --abortDe gouden regel past in één zin: rebase nooit een branch die anderen al hebben opgehaald. Een gedeelde geschiedenis herschrijven dwingt je collega’s om die van hen met de hand te repareren. Op je eigen werkbranch, voordat je hem aanbiedt, is een rebase daarentegen volkomen legitiem en levert hij een veel leesbaardere geschiedenis op.
Het alledaagse geval: iemand was je voor met pushen
Je wilt pushen, en Git weigert:
To /root/o.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to '/root/o.git'
hint: Updates were rejected because the remote contains work that you do notDe server heeft commits die jij niet hebt. Die moet je eerst binnenhalen. En op een verse repository stelt Git je dan een vraag in plaats van te handelen:
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:Sinds versie 2.27 weigert Git in jouw plaats te kiezen. Beantwoord de vraag voor eens en altijd, zoals voorgesteld in het installatiehoofdstuk:
git config --global pull.rebase trueHet verloop wordt dan dit:
git pull --rebase
git pushFrom /root/o
622a60b..38b7dc5 main -> origin/main
Rebasing (1/1)Successfully rebased and updated refs/heads/main.
* 5b45117 Ajoute app.js
* 38b7dc5 Ajoute la doc
* 622a60b DepartJe commit is boven op die van je collega geplaatst en de geschiedenis is lineair gebleven, zonder overbodige merge-commit. Dit is de instelling die je een beginnend team moet aanraden.
Tot slot een waarschuwing: probeer een geweigerde push nooit vlot te trekken met git push --force. Dat commando overschrijft het werk dat op de server staat. Moet je echt forceren, na een rebase van je eigen branch, gebruik dan git push --force-with-lease, dat weigert commits te overschrijven die jij niet had gezien.
Opruimen
Een samengevoegde branch heeft geen reden meer om te bestaan. Is hij met -u gepubliceerd, push dan eerst zijn laatste commits: Git weigert een lokale branch te verwijderen die voorloopt op zijn remote branch, ook al is hij in main samengevoegd.
git push origin feature/panier
git branch -d feature/panierDeleted branch feature/panier (was bc2203a).Zonder die voorafgaande push is de melding duidelijk:
warning: not deleting branch 'feature/panier' that is not yet merged to
'refs/remotes/origin/feature/panier', even though it is merged to HEAD
error: the branch 'feature/panier' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/panier'
hint: Disable this message with "git config set advice.forceDeleteBranch false"Is de branch niet gemerged, dan houdt Git je tegen, wat een nuttig vangnet is:
error: the branch 'feature/promo' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/promo'
hint: Disable this message with "git config set advice.forceDeleteBranch false"Om de branch ook op de server te verwijderen en de lokale referenties op te ruimen die overbodig zijn geworden:
git push origin --delete feature/panier
git fetch --prunegit fetch haalt de toestand van de server op zonder iets in je branches te mergen, anders dan git pull. De optie --prune verwijdert meteen de remote branches die niet meer bestaan, die je collega’s hebben gemerged en gewist.
Je kunt nu samenwerken. Het laatste hoofdstuk gaat over organisatie: welk branchmodel je kiest, afhankelijk van je team.
Veelgemaakte fouten
git stash, voordat je van branch wisselt.git pull zelf te kiezen tussen merge en rebase. Regel dat met git config --global pull.rebase true.git pull --rebase. Gebruik nooit git push --force om eroverheen te walsen: dat overschrijft het werk van anderen.<<<<<<<, ======= en >>>>>>> moeten uit het bestand verdwijnen voor de git add.