Je bent vast wel bekend met het fenomeen dat als je in een groep of team
samenwerkt aan een document er vele verschillende versies ontstaan:
belangrijk_rapport.docx
belangrijk_rapport1.docx
belangrijk_rapport1-wijzigingen-Piet.docx
belangrijk_rapport2.docx
belangrijk_rapport1-wijzigingen-Piet-2.docx
belangrijk_rapport2-wijzigingen-Ahmed.docx
belangrijk_rapport-definitief.docx
belangrijk_rapport-definitief2.docx
Dan is het maar hopen dat iedereen altijd in de laatste versie werkt en
dat duidelijk is wát de laatste versie is. Het wordt al snel een
rommeltje. Nog lastiger wordt het als er in een latere versie een
wijziging is aangebracht die teruggedraaid moet worden. Maar in welke
versie staat het goede stuk?
Tegenwoordig kan samenwerken aan een document gelukkig een stuk
eenvoudiger, bijvoorbeeld met Google Drive of Microsoft Office365,
waarbij er één document is die online staat waar iedereen in werkt. Maar
dat zorgt voor een ander probleem: wat als je een wijziging wilt
terugdraaien die al vele aanpassingen terug is gemaakt? In plaats van
tientallen documenten, is er nu nog maar één document met een beperkte
geschiedenis.
In softwareontwikkeling werk je vaak ook met meerdere personen aan
dezelfde broncode. En de broncode is zelden één bestand, maar vele
honderden. Je zou misschien verwachten dat daar dezelfde problemen
spelen. Ofwel er zijn vele verschillende versies per bestand, ofwel er
is maar één versie per bestand zonder goede mogelijkheid om terug te
gaan naar vorige versies.
Gelukkig is dit niet het geval. In de softwareontwikkeling is het
namelijk heel gebruikelijk om met goed versiebeheer te werken. In de nieuwe reeks Werken met Git leer je werken met Git, één van de meest gebruikte systemen om
versiebeheer in je softwareprojecten toe te passen.
In dit eerste artikel leer je wat versiebeheer inhoudt, en zet je de eerste stappen in het werken met Git.
Een spoor met zijsporen
Versiebeheer is het proces van het bijhouden van wijzigingen in
bestanden door de tijd heen. Een versiebeheersysteem (VCS, van
Version Control System) is een softwaretool die dit proces mogelijk
maakt. Een VCS houdt een overzicht bij van alle wijzigingen die in de
bestanden zijn aangebracht, samen met metadata zoals wie de
wijziging heeft gemaakt en wanneer.
Met een VCS kun je:
Eerdere versies van bestanden ophalen
Verschillen tussen versies bekijken
Wijzigingen van meerdere personen samenvoegen
Experimenteren met wijzigingen zonder de hoofdversie te beïnvloeden
Moderne VCSen lossen beide eerder geschetste problemen op. Er is per
bestand maar één naam (dus niet main.py en main1.py, et
cetera.). Tegelijkertijd is er wel goed versiebeheer voor dat bestand.
Wijzigingen zijn eenvoudig terug te draaien en wijzigingen van meerder
personen zijn eenvoudig samen te voegen. Dit wordt mogelijk gemaakt door
het concept van aftakkingen, meestal branches genaamd.
Stel je een spoor voor die de hoofdlijn van de ontwikkeling omvat
(meestal master of main genoemd). Vanaf deze hoofdlijn kun je
zijsporen maken, zogenaamde branches. Elke branch is een
afzonderlijke lijn van ontwikkeling, bijvoorbeeld nieuwe functionaliteit
die je wilt toevoegen, of een experiment als je nog niet precies weet
hoe je iets wilt aanpakken. Is het werk op het zijspoor klaar, dan kan
het zijspoor weer teruggevoerd worden naar het hoofdspoor.
Stel dat je een nieuwe functie wilt toevoegen aan je programma. Je maakt
een nieuwe branch aan vanaf de hoofdlijn en brengt daar je wijzigingen
in aan. Ondertussen kunnen collega's doorgaan met het aanbrengen van
wijzigingen in de hoofdlijn of in hun eigen branch. Wanneer je
tevreden bent met je wijzigingen, kun je jouw branch samenvoegen
(mergen) met de hoofdlijn. Het versiebeheersysteem zal de
wijzigingen van jouw branch combineren met de wijzigingen die
ondertussen in de hoofdlijn zijn aangebracht door je collega's.
Als er conflicten optreden, bijvoorbeeld wanneer iemand anders hetzelfde
deel van een bestand heeft gewijzigd, zal het VCS je vragen om deze
handmatig op te lossen voordat de merge kan worden voltooid.
Blijkt nu dat jouw wijziging een bug bevat waardoor het programma
vastloopt, dan kun je heel eenvoudig terug naar moment in de tijd waar
alles nog wel naar behoren werkte. Ondertussen kun je dan in een
branch weer werken aan een verbeterde versie van jouw functionaliteit.
Eenvoudig (samen)werken
Goed versiebeheer maakt eenvoudig samenwerken mogelijk. Jij en je
collega's kunnen tegelijkertijd aan dezelfde code werken, zonder dat je
elkaar in de weg zit. Iedereen kan in zijn eigen branch werken en
wijzigingen samenvoegen wanneer ze klaar zijn. Ook kun je zien wie welke
wijzigingen wanneer heeft aangebracht, handig als je iets probeert te
begrijpen.
Maar ook in een project waar je alleen aan werkt, is versiebeheer erg
handig. Branches stellen je in staat om te experimenteren met nieuwe
ideeën of functies zonder de stabiliteit van de hoofdversie in gevaar te
brengen. Als je experiment mislukt, kun je de branch gewoon weggooien
zonder de hoofdlijn te beïnvloeden. En als je een fout maakt, kun je
eenvoudig terugkeren naar een eerdere versie van je code. Dit kan veel
tijd en moeite besparen in vergelijking met het handmatig ongedaan maken
van wijzigingen.
Om te oefenen met een VCS leer je werken met Git. Git is momenteel het
meestgebruikte VCS, zelfs in die mate dat het de de facto standaard
is, alhoewel er nog wel enkele andere oplossingen zijn. Omdat de kans zo
groot is dat je Git gaat tegenkomen, is het waardevol hiermee te leren
werken.
Git is een open source VCS, gratis verkrijgbaar en in 2005 grotendeels
door Linus Torvalds ontwikkeld. Linus is de oorspronkelijke ontwikkelaar
van het besturingssysteem Linux, ook open source. Omdat er
tegenwoordig duizenden mensen wereldwijd aan Linux werken en deze
ontwikkelaars in 2005 problemen kregen met het vorige VCS besloten ze
zelf een VCS te ontwikkelen. Daar is Git uit voortgekomen.
Git installeren
Om Git te gebruiken, moet het wel aanwezig zijn op je computer. Ga naar
de website van Git om het te installeren. Werk je met Linux of MacOS,
dan is de kans groot dat het al aanwezig is op je systeem. Installeer je
Git op Windows, doorloop dan het hele installatieproces met alle
standaard instellingen.
Ga naar https://git-scm.com/ om Git te downloaden voor jouw systeem.
Ga naar de documentatie
voor verdere instructies over het installeren op jouw systeem.
Een project maken
Om te oefenen met Git, heb je eerst een project met bestanden nodig.
Maak daarom ergens op je computer een map aan, genaamd mijn_project.
Maak hierin ook één bestand: README.md. Laat het bestand leeg.
In veel softwareprojecten zul je een README-bestand tegenkomen. Dit is
een tekstbestand met informatie over het project. Tegenwoordig is dit
vaak een Markdown-bestand (vandaar de extensie .md), maar dit kan ook
iets anders zijn. Het is in elk geval belangrijk dat het een (platte)
tekstbestand is, dus niet een Word-bestand, bijvoorbeeld.
Vanaf nu ga je in de terminal werken. De voorbeelden zijn in Linux, maar
de commando's zijn op elk systeem hetzelfde. In Windows kun je het best
met Git Bash werken. Dit is een terminal die automatisch mee is
geïnstalleerd toen je Git installeerde. Werk je in Linux of MacOS, dan
kun je de ingebouwde terminal gebruiken. Om Git Bash in Windows te
openen, ga je in de bestandenbrowser van Windows naar je net aangemaakte
project. Klik dan met je rechtermuisknop in de map, selecteer eventueel
meer opties kiezen en vervolgens Open Git Bash hier.
Je ziet dan een nieuwe terminal verschijnen.
Je bent nu klaar om met Git te gaan werken in je project.
Een repository maken
Eerder leerde je al over de algemene werking van versiebeheer. De hele
geschiedenis van een project, inclusief alle wijzigingen en metadata
over de wijzigingen zijn beschikbaar. Al deze informatie moet wel ergens
opgeslagen worden. Ook moet duidelijk zijn wat wel en niet tot het
versiebeheer hoort. In Git noem je deze opslagplaats een repository. Een repository moet je eerst aanmaken. Dit doe je in
je terminal met git init. Doe dit vanuit de hoofdmap van je project.
Met git init wordt er een map aan je project toegevoegd, genaamd
.git. Waarschijnlijk zie je deze map niet in je map terug, omdat het
een verborgen map is (doordat het met een punt begint). Dit is echter
afhankelijk van je instellingen, dus het kan zijn dat je de map wel
ziet. In deze map zal Git alles bijhouden. Je hoeft zelf nooit iets te
doen met die map, alles zal verlopen via het git commando. Verwijder
je deze map, dan verlies je het versiebeheer in dit project.
Wijzig nooit zelf iets aan de .git-map. Alle wijzigingen die je wilt doen, doe je via de git-commando's die je gaat leren.
Wijzigingen bijhouden
Je hebt nu een repository aangemaakt, maar zoals je zag toen je het
commando uitvoerde, is het een lege repository. Typ ook maar eens
git status in.
Het resultaat van git status laat zien dat je momenteel in de
branchmain werkt, dat er nog geen commits zijn (waarover later
meer) en dat er één bestand is dat nog niet door Git wordt bijgehouden
(untracked).
In de voorbeelden zie je dat de branchmain heet. Afhankelijk van
je instellingen kan dit ook master zijn. Dit was eerder
gebruikelijk, maar tegenwoordig zie je steeds vaker de naam main
omdat master een negatieve bijklank heeft.
Om goed te begrijpen wat er gaande is, is het belangrijk om te weten dat
een bestand zich in één van vier stadia kan bevinden:
Untracked (niet gevolgd)
Staged (klaar voor de volgende commit)
Unmodified (ongewijzigd sinds de vorige commit)
Modified (gewijzigd sinds de vorige commit of stage)
Untracked
Zodra je een bestand toevoegt aan je project of - zoals in dit geval -
een nieuwe repository begint, zijn je bestanden in het stadium
untracked. Dit betekent dat Git de status van de bestanden niet
bijhoudt. Ze zijn niet opgenomen in de repository. In dit geval wil je
het bestand juist wel bijhouden, dus voeg je het toe aan het volgende
stadium: staged. Dit doe je met het commando git add
<bestandsnaam>.
Voer je nu nogmaals git status uit, dan zie je dat er één nieuw
bestand is: README.md. Dit bestand staat nu onder het kopje
Changes to be committed. Dat wil zeggen dat het klaar staat om toe
te voegen aan de volgende commit. Een commit is als een foto van een
bepaald moment in je project. Bekijk nogmaals de volgende afbeelding:
Elk bolletje in de afbeelding is een commit, ofwel een vastgelegde
moment in de tijd. Momenteel heb je nog geen commit gedaan en werk je
dus vóór het eerste bolletje. Met git add README.md heb je Git
verteld dat je README.md wilt toevoegen aan de volgende commit,
het bevindt zich nu in de fase staged. Het staat klaar om aan de
commit toegevoegd te worden, maar is nog niet toegevoegd.
Voordat je verdergaat: voeg eerst een willekeurige tekst toe aan
README.md, sla het bestand op en voer dan nogmaals git status
uit.
Je ziet dat README.md nu tweemaal in het overzicht staat. Een keer
als new file onder Changes to be committed en een keer als
modified (gewijzigd) onder het kopje Changes not staged for
commit. Dat lijkt vreemd, je hebt één bestand met twee statussen!
Door eerder het commando git add README.md te gebruiken, heb je
ervoor gezorgd dat README.md klaar staat voor de commit, zoals
het op dat moment is. Zou je nu een foto maken (een
commit maken), dan zou je dus een lege README.md aan de commit
toevoegen. De wijzigingen die je hebt aangebracht, worden niet aan de
commit toegevoegd. Wil je dit wel, dan dien je dus eerst weer git
add README.md uit te voeren, waarmee de wijzigingen van de status
modified naar staged worden gebracht.
Voer je nu git commit -m 'Voeg README toe' uit, dan committeer
je alle wijzigingen die met je git add hebt toegevoegd. Er wordt een
foto gemaakt van de status van het project op dat moment, het eerste
groene bolletje in de eerdere afbeelding. Met git commit -m
<bericht> voeg je alles wat zich in de fase staged bevindt toe aan
de commit. Omdat elke commit een bericht moet hebben, voeg je dat
toe met -m (van message).
Voer je dan weer git status uit, dan zie je README.md nergens
meer terug. Dit betekent dat het in het stadium Unmodified
(ongewijzigd) is. Sinds de vorige commit is dit bestand niet
gewijzigd.
In plaats van het toevoegen aan *staging* van elk bestand apart met
git add , kun je ook alle bestanden in de map die
wijzigingen hebben of zijn toegevoegd in één keer toevoegen met git
add . (let op de punt).
Tot slot
In dit artikel heb je geleerd wat versiebeheer is in een softwareproject en heb je de eerste stappen gezet in het werken met Git. Je weet hoe je één of meer bestanden aan een commit kunt toevoegen, zodat je een 'foto' hebt van de bestanden zoals ze op een bepaald moment zijn. In een volgend artikel ga je dieper in op werken met branches. Hoe maak je een branch, hoe werk je erin en hoe voeg je een branch weer samen met de hoofdtak?
Over de auteur
Erwin Matijsen
Erwin is de oprichter van python-cursus.nl. In allerlei rollen heeft hij Python ingezet, van het eenvoudiger maken van zijn werk tot het opleveren van complete (web)applicaties. Met vrouw en kinderen woont hij in Havelte (Drenthe), midden in de prachtige natuur. Daar wandelt hij graag, zeker ook omdat de beste ingevingen tijdens een wandeling - weg van de computer - lijken te komen.
Vragen, opmerkingen?
Heb je vragen, opmerkingen, suggesties of tips naar aanleiding van deze blog?
Neem dan contact met ons op, of laat het weten via
Mastodon of
LinkedIN.