Sessie 12: Git Branches: Parallelle universums voor je code
Vorige sessie leerde je commits maken: foto’s van je code op één tijdlijn. Alles netjes achter elkaar.
Maar wat als je een nieuw idee wil uitproberen? Een lasergun toevoegen aan je game, bijvoorbeeld. Je weet niet of het gaat werken. Je wil je werkende code niet kapot maken.
Daar zijn branches voor.
Een branch is een kopie van je code waar je vrij kunt experimenteren. Je hoofdcode (de master-branch) blijft veilig. Als je experiment werkt, plak je het terug in master. Werkt het niet? Je gooit de branch weg. Je master-branch heeft er nooit iets van gemerkt.
Noot: Op GitHub en in veel nieuwe projecten heet de hoofdbranch
mainin plaats vanmaster. Dat is exact hetzelfde, alleen de naam is anders. In deze cursus gebruiken wemaster, maar als je onlinemaintegenkomt, weet je dat het hetzelfde betekent.
Wat je vandaag leert
- Wat een branch is en hoe Git branches intern opslaat
- Branches aanmaken, wisselen en samenvoegen
- Wat een merge conflict is en hoe je het oplost
- Wanneer je wél en níet een branch moet gebruiken
Stap 0: Herhaling: waar sta je nu?
Open je terminal in het project van vorige sessie. Check waar je bent:
git status
git log --onelineJe hebt een paar commits op master. Dit is je stabiele basis: hier ga je straks vanaf splitsen.
Stap 1: Je eerste branch
Je gaat een nieuwe feature toevoegen: een highscore.txt-bestand dat de hoogste score bijhoudt. Maar eerst maak je een branch:
git branch highscore-featureGit heeft nu een nieuwe branch aangemaakt. Maar je staat nog steeds op master. Check welke branches er zijn:
git branchJe ziet:
highscore-feature
* masterHet sterretje bij master betekent: “hier sta je nu.” Wissel naar je nieuwe branch:
git switch highscore-feature(Oudere Git-versies gebruiken git checkout highscore-feature. Beide werken.)
Nog een keer git branch: het sterretje staat nu bij highscore-feature. Alles wat je nu commit, gebeurt op deze branch. master blijft onaangeroerd.
Tip: Je kunt een branch aanmaken en er meteen naartoe switchen in één commando:
git switch -c mijn-nieuwe-branch-c staat voor “create”. Dit is sneller en je vergeet nooit te switchen.
Stap 2: Werk doen op een branch
Maak een nieuw bestand aan:
echo "HIGHSCORE: 0" > highscore.txtCommit je werk:
git add highscore.txt
git commit -m "Add highscore.txt met beginwaarde 0"Voeg nog een bestand toe dat de highscore leest:
echo 'def lees_highscore():' > highscore_manager.py
echo ' with open("highscore.txt") as f:' >> highscore_manager.py
echo ' return int(f.read().split(": ")[1])' >> highscore_manager.pyCommit opnieuw:
git add highscore_manager.py
git commit -m "Add highscore_manager: functie om highscore te lezen"Kijk nu naar je log:
git log --onelineJe ziet al je commits van master, plus de twee nieuwe. Git onthoudt de hele keten.
Stap 3: Twee werelden tegelijk
Switch terug naar master:
git switch masterKijk wat er hier is:
lshighscore.txt en highscore_manager.py zijn… weg. Ze bestaan alleen op de highscore-feature-branch. Op master is alles nog precies zoals je het achterliet.
Dit is de magie van branches: twee (of meer) versies van je project, tegelijk op je computer, zonder dat ze elkaar in de weg zitten.
Switch nog eens heen en weer om het te voelen:
git switch highscore-feature # bestanden zijn terug
git switch master # bestanden zijn weer wegStap 4: Samenvoegen met git merge
Je highscore-feature werkt. Tijd om hem terug in master te zetten. Dit heet mergen.
Zorg dat je op master staat:
git switch masterVoeg de branch samen:
git merge highscore-featureGit toont iets als Updating a1b2c3d..e4f5g6h en Fast-forward. Je highscore-feature-commits zijn nu onderdeel van master. Controleer:
ls
git log --onelinehighscore.txt en highscore_manager.py staan nu op master. Alle commits van de feature-branch zijn opgenomen in de geschiedenis.
Stap 5: Wat zijn merge conflicts?
Stel: je hebt op master iets veranderd in highscore.txt, bijvoorbeeld “HIGHSCORE: 100” in plaats van “HIGHSCORE: 0”. En tegelijkertijd heb je op een andere branch highscore.txt ook veranderd, naar “HIGHSCORE: 500”.
Als je nu probeert te mergen, weet Git niet welke versie de juiste is. Dat is een merge conflict. Git vraagt jóu om te beslissen.
Laten we het expres uitlokken.
Op master:
echo "HIGHSCORE: 100" > highscore.txt
git add highscore.txt
git commit -m "Update highscore naar 100 op master"Maak een nieuwe branch en verander daar hetzelfde bestand:
git switch -c andere-highscore
echo "HIGHSCORE: 500" > highscore.txt
git add highscore.txt
git commit -m "Update highscore naar 500"Switch terug naar master en probeer te mergen:
git switch master
git merge andere-highscoreGit zegt: CONFLICT (content): Merge conflict in highscore.txt. Open highscore.txt in je editor. Je ziet:
<<<<<<< HEAD
HIGHSCORE: 100
=======
HIGHSCORE: 500
>>>>>>> andere-highscoreDit zijn de twee versies. HEAD is jouw master-versie. Daaronder staat de versie van andere-highscore. Jij kiest welke je houdt, of je combineert ze.
Verwijder de markers en kies één versie:
HIGHSCORE: 500Sla het bestand op. Vertel Git dat het conflict is opgelost:
git add highscore.txt
git commit -m "Merge: highscore van andere-highscore gekozen"Conflict opgelost. Git kan weer verder.
Stap 6: Branches opruimen
Je feature is gemerged. De branch heb je niet meer nodig:
git branch -d highscore-feature
git branch -d andere-highscore-d staat voor “delete”. Git weigert een branch te verwijderen die nog niet gemerged is: dat is een veiligheidsklep. Als je écht weg wil gooien zonder mergen, gebruik je -D (hoofdletter). Maar wees daar voorzichtig mee.
Wanneer wél een branch, wanneer niet?
| Wél een branch | Géén branch |
|---|---|
| Nieuwe feature die tijd kost | Typo in een comment fixen |
| Experiment waarvan je niet weet of het werkt | Kleine bugfix van één regel |
| Iets dat je werkende code kan breken | Je werkt alleen en je wijziging is duidelijk |
| Je werkt samen met anderen | (bij solo-werk is master vaak genoeg) |
Vuistregel: Als je twijfelt, maak een branch. Een branch kost niks. Code kwijtraken wel.
Tips om vlot te werken met branches
- Houd branches kort. Een branch van 3 uur is prima. Een branch van 3 weken wordt een merge-nachtmerrie: hoe langer je wacht met mergen, hoe meer er intussen op
masterverandert, en hoe groter de kans op conflicts. - Eén ding per branch. “Highscore toevoegen” is een goede branch. “Highscore, menu, en nieuwe levels toevoegen” is te veel: split het op.
- Merge vaak. Werk je feature af, merge hem meteen terug naar
master. Kleine, frequente merges zijn makkelijker dan één groot monster-merge. - Geef branches duidelijke namen.
highscore-featureis goed.test123ofbranch2zijn slecht. Over een week weet je niet meer wat er intest123zat. - Check waar je bent voor je begint.
git branchofgit statusvertelt je op welke branch je staat. Maak hier een gewoonte van, zodat je voorkomt dat je per ongeluk opmastercode schrijft die eigenlijk op een feature-branch hoort.
Showcase
Laat aan een coach en een buddy zien:
git branchmet minstens twee branches (waarondermaster).- Op elke branch een ander bestand of andere code.
- Switch heen en weer: de bestanden verschijnen en verdwijnen.
- Een succesvolle merge van een feature-branch in
master.
Tot de volgende keer!
“Tot nu toe leeft al je code alleen op jouw laptop. Volgende keer zetten we hem online. Je maakt een GitHub-account, pusht je repository naar het internet, en je game is overal ter wereld te bekijken. En: je kunt samenwerken met anderen. GitHub: je code de wereld in.”
Neem mee naar huis
- Makkelijk: Maak een branch voor een kleine feature in een bestaand project. Commit je werk en merge hem terug.
- Middel: Creëer expres een merge conflict (twee branches die hetzelfde bestand wijzigen) en los het op.
- Lastig: Werk met drie branches tegelijk op hetzelfde project. Merge ze één voor één terug in
master. Check na elke merge of alles nog werkt. - Erg lastig: Maak een branch, commit drie wijzigingen, switch terug naar
master, maak daar óók een wijziging in hetzelfde bestand, en merge de branch. Los het conflict zorgvuldig op en check metgit log --graphhoe de geschiedenis eruitziet.