Git CLI en Theoretische Fundamenten
NOTES
- Alles is LOKAAL
- .git, niet echt leeg
- Lifecycle, terugkomen op diagram na elke stap
- add (staging area = beetje zoals winkelkar voor je naar de kassa gaat), commit, staging area terug leeg, rm, log
- Undo
- Diffs
- Oefening
- Config
Er zijn oefeningen. Je hoeft dus niet mee te doen als ik iets toon.
Versiebeheer en Git zijn cruciaal als professioneel maar ook hobby dev. Maar ook: centraal en onmisbaar bij gebruik van AI.
GitOps: https://chrisshort.net/gitops-an-implementation-of-devops/
We hebben GitHub (de web-interface) en GitHub Desktop gebruikt om een Git repo aan te maken, wijzigingen op te slaan (commit), de repo lokaal te krijgen (clone) en lokale aanpassingen naar GitHub door te sturen (push).
In dit hoofdstuk zetten we eerst een stapje terug door met de Git CLI (Command Line Interface) te leren werken. We doen dit initieel volledig lokaal. We leren de basisconcepten van Git zelf en commando's die je dagelijks gebruikt.
Fundamenten
Met een CLI leren werken terwijl er grafische Git-clients zoals GitHub Desktop bestaan, lijkt misschien overbodig of zinloos...
De CLI is echter een uitstekende manier om een fundamentele kennis van Git op te bouwen. Met een goed inzicht in die fundamenten zullen meer geavanceerde concepten die later aan bod komen veel gemakkelijker te begrijpen zijn.
De CLI:
- Is altijd en overal bruikbaar
- Werkt precies hetzelfde op elk platform
- Helpt je de fundamenten te begrijpen
- Wordt veel gebruikt door AI Agents
Git CLI Installeren¶
Download en installeer de laatste versie vanaf https://git-scm.com/downloads/win.
Als je Windows Subsystem for Linux (WSL) gebruikt, volg dan de Linux instructies. Je kan ook beide versies installeren.
Git installeren op macOS is het makkelijkst via Homebrew, een pakketbeheersysteem waarmee je eenvoudig heel wat extra software kan installeren.
Op de Homebrew homepage vind je een link naar "Homebrew's laatste GitHub release". Daar kan je onderaan de pagina Homebrew downloaden (bvb. Homebrew-4.6.11.pkg).
Eens Homebrew geïnstalleerd is kan je Git als volgt installeren vanuit een Terminal sessie:
Meer info: https://git-scm.com/downloads/mac
Testen¶
Vanuit een terminal (Cmd of Powershell voor Windows):
Dit werkt ook in een terminal die je rechtstreeks in VS Code opent (View → Terminal of CTRL+`/CMD+`).
Documentatie¶
De Git documentatie is erg goed en een handige bron om bij de hand te hebben.
- On-line: https://git-scm.com/docs
- Met het
gitcommando:git help.
Het uitstekende boek Pro Git is gratis beschikbaar, zowel online als in PDF of ePub formaat.
Basis Configuratie¶
We komen later terug op configuratiemogelijkheden van Git. Om verder te werken is het belangrijk eerst een aantal basisinstellingen aan te passen. Gebruik in onderstaande commando's je eigen naam en email adres.
git config --global user.name "John Doe"
git config --global user.email "john.doe@gmail.com"
git config --global init.defaultBranch main
Wat een defaultBranch precies is en waarom we dit aanpassen komt ook later nog aan bod.
Git Repository¶
NOTES
Duidelijk en uitgebreid uitleggen wat er precies gebeurd.
- We gaan een LOKAAL Git systeem opzetten om de versies te beheren van een fictief project
- Git bewaart alle informatie over de versies in een soort database
- Met
git initmaken we zo een nieuwe (lege) database voor ons project - directory = folder = repo = programmeer-project
- staging = winkelkar
Repository
Een Git repository, of kortweg repo, is een opslagplaats die de complete geschiedenis en huidige staat van een codebase (project) bewaart, inclusief bestanden, wijzigingen en versies.
Één directory (folder of map) = één git repo
Je kan van elke directory een Git repo maken. Die directory hoeft niet leeg te zijn.
In VS Code maken we een nieuwe directory om in te werken. In het startscherm kies je Open..., ofwel File → Open in het menu (= CTRL+O / CMD+O). Maak een nieuwe directory met een naam naar keuze (bvb. hello) en open deze.
In VS Code voeg je dan volgende bestanden toe:
Repository Aanmaken - init¶
Om de Git CLI te gebruiken hebben we een terminal nodig. Dit kan via een aparte applicatie (Terminal applicatie in Linux/macOS; WSL, Cmd of Powershell in Windows). Maar je kan ook rechtstreeks in VS Code een terminal openen via View → Terminal (of CTRL+` / CMD+`).
Om een Git repo te maken (initialiseren) gebruik je het commando git init (in de directory):
Initialized empty Git repository in /Users/syntra/dev/hello/.git/
Het commando git status geeft informatie over de repo en zullen we nog veel gebruiken:
No commits yet
Untracked files: # (1)
(use "git add <file>..." to include in what will be committed)
README.md
hello.py
nothing added to commit but untracked files present (use "git add" to track)
In de output zie je dat we op de branch (tak, zoals de tak van een boom) genaamd main zitten. Een branch kan je zien als één bepaalde lijst met versies (commits) van de code. Om te beginnen zal dit altijd main zijn. Wat een branch precies is, en hoe je er mee werkt, komt later nog uitgebreid aan bod.
Extra: De .git directory
In de output van git init zie je dat een .git directory is gemaakt.
Alle git informatie zal worden bijgehouden in deze directory (en enkel deze directory). Dit betekent dat:
- Je zelf zeker geen wijzigingen in deze directory mag maken!
- Na het verwijderen van deze directory zijn alle sporen van git weg.
Lifecycle van een Bestand¶
NOTES
Superbelangrijk en gaan we nog veel op terugkomen!
Terugkomen op diagram bij elk commando in de volgende secties.
In Git bevindt elk bestand zich altijd in één bepaalde state (staat, of status). Via de verschillende commando's kan die state veranderen.
Elk bestand begint in de untracked state. Dit zien we duidelijk in de output van het git status commando. Dit betekent dat het bestand nog onbekend is voor Git.
Eenmaal een bestand gekend is zal het altijd in één van de drie mogelijke states verkeren: modified, staged of committed
git add¶
Om een nieuw bestand toe te voegen aan de Git repo gebruik je eerst het commando git add. De state van het bestand verandert dan naar staged. Het bestand zit dan in de zogenoemde staging area. In de staging area verzamel je een groep bestanden en wijzigingen die als één transactie toegevoegd zullen worden in het versie-systeem. Het is dus een soort wachtplaats.
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
In GitHub Desktop deden we dit door bestanden aan of af te vinken.
git commit¶
Nadat de gewenste bestanden en wijzigingen zijn klaargezet in de staging area kunnen ze als één geheel worden toegevoegd aan de Git-history met het commando git commit. Met het argument -m/--message geef je een beschrijving van de wijzigingen.
1 file changed, 1 insertion(+)
create mode 100644 hello.py
git statusOn branch main
nothing to commit, working tree clean
git status vertelt ons hier dat de working tree clean is. De working tree (of working directory) is de verzameling bestanden die overeenkomt met de huidige branch (of commit). M.a.w. de bestanden die je op dat moment in de directory van je repo kan zien en gebruiken. De working tree is "clean" wanneer er geen veranderingen zijn t.o.v. de gecommitte versie.
'The Staging Area', Julia Evans
Julia Evans maakt al meer dan 10 jaar bijzonder leerzame blog-posts en samenvattingen in strip-formaat over allerlei technologische onderwerpen. Ook Git komt vaak aan bod, zoals hier:
Oefening¶
Maak een kleine aanpassing in hello.py. Gebruik git status om te bevestigen dat de state van hello.py nu modified is.
Stage deze aanpassing alsook het README.md bestand. Commit dan de aanpassingen. Controleer het resultaat met git status
Oplossing
Maak een aanpassing in hello.py met je editor. Bvb.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
no changes added to commit (use "git add" and/or "git commit -a")
git add hello.py README.mdgit commit -m "Improve hello.py and add README"[main 245bfa1] Improve hello.py and add README
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 README.md
git statusOn branch main
nothing to commit, working tree clean
git rm¶
Het kan gebeuren dat een bestand per ongeluk in de Git-history is beland. Of gewoon niet meer nodig is. Om een bestand uit Git te verwijderen gebruik je het git rm commando.
Let op!
Met git rm wordt het bestand uit Git en je computer verwijderd. Om enkel uit Git te verwijderen gebruik je het --cached argument. Het bestand blijft dan gewoon bestaan en is terug in de untracked state.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: README.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
Net als bij git add wordt het te verwijderen bestand eerst toegevoegd aan de staging area. Om de verwijdering (samen met eventuele andere aanpassingen) effectief door te voeren gebruiken we opnieuw git commit
1 file changed, 1 deletion(-)
delete mode 100644 README.md
Commit Geschiedenis (History)¶
Elke commit bevat de volgende informatie:
- ID
- Auteur (wie)
- Datum (wanneer)
- Beschrijving (waarom)
- Diff (wat)
git log¶
Met het git log commando kan je de commit geschiedenis bekijken, vanaf de laatste commit. Met het commando git help log zie je dat er erg veel opties en mogelijkheden zijn. We bekijken hier de meest gebruikte.
Author: Fabrice Devaux <fabrice.devaux@gmail.com>
Date: Sun Aug 24 14:56:26 2025 +0200
Improve hello.py and add README
commit f39a6cce08ebbb1a63616030322e46b4ff4d653c
Author: Fabrice Devaux <fabrice.devaux@gmail.com>
Date: Sun Aug 24 14:31:08 2025 +0200
Add initial hello.py version
(HEAD is een reference en main is een branch - hier komen we later op terug)
'The current branch: HEAD', Julia Evans
--oneline optie¶
Met git log --oneline krijg je, zoals te verwachten, een enkele lijn per commit.
f39a6cc Add initial hello.py version
Je ziet dat de commit ID ingekort is tot de eerste 7 karakters. Dit is hier genoeg om een unieke commit aan te duiden.
--stat optie¶
Met git log --stat krijg je voor elke commit de "statistieken" van de wijzigingen: welke bestanden, hoeveel lijnen en het soort wijziging.
Je kan de opties vaak ook combineren. Zo zal git log --oneline --stat de commit informatie op 1 lijn plaatsen, gevolgd door de statistieken.
README.md | 1 +
hello.py | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
f39a6cc Add initial hello.py version
hello.py | 1 +
1 file changed, 1 insertion(+)
filename argument¶
Door na het git log commando een bestandsnaam te plaatsen krijgen we enkel de commits te zien die betrekking hebben op dat bestand.
Veranderingen ongedaan maken¶
git restore¶
Met git restore kan je veranderingen die nog niet gestaged zijn ongedaan maken. In het lifecycle diagram: van modified naar committed.
Merk op dat de output van git status je het juiste commando al aangeeft.
Na een ongewenste verandering in hello.py:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.py
no changes added to commit (use "git add" and/or "git commit -a")
git restore hello.pygit statusOn branch main
nothing to commit, working tree clean
Let op!
git restore is permanent. De veranderingen zijn nooit toegevoegd in de Git geschiedenis dus kunnen ook niet terug opgehaald worden.
Als het bestand geopend is in een editor zoals VS Code kan je mogelijks wel nog de veranderingen terug krijgen.
Unstage (git restore --staged)¶
Met git restore --staged kan je veranderingen die wel al gestaged zijn ongedaan maken. In het lifecycle diagram: van staged naar modified.
Opnieuw krijg je van git status het geschikte commando.
Na een ongewenste verandering in hello.py:
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.py
git restore --staged hello.pygit statusOn branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.py
no changes added to commit (use "git add" and/or "git commit -a")
git restore hello.py
NOTES
Later bekijken we hoe je ook reeds gecommitte veranderingen ongedaan kan maken.
Veranderingen Bekijken¶
Git houdt alle versies en details superefficient bij. Het is dan ook belangrijk om snel en gemakkelijk specifieke versies en verschillen te kunnen ophalen.
Een diff is een weergave van de verschillen tussen twee versies van een of meerdere bestand(en), waarbij zichtbaar wordt welke regels zijn toegevoegd, gewijzigd of verwijderd. Een diff is niet specifiek aan Git -- zo zal het Linux commando diff a.txt b.txt de verschillen weergeven tussen de bestanden a.txt en b.txt.
Nieuwe wijzigingen¶
Wijzigingen die nog niet gestaged zijn bekijk je met het git diff commando.
Na het toevoegen van een regel in README.md:
index 3836229..9ebb1b9 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
# My first Git repo
+This is a new line
Let op!
git diff toont alleen wijzigingen in bestanden die al getrackt worden (gekend zijn) door Git. Een nieuw bestand zal je dus niet te zien krijgen!
Om de wijzigingen die wel al gestaged zijn te zien gebruik je het git diff --staged commando.
index 3836229..9ebb1b9 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
# My first Git repo
+This is a new line
Bestaande Commits en Diffs¶
Om de inhoud van een bestaande commit te bekijken is er het commando git show.
Author: Fabrice Devaux <fabrice.devaux@gmail.com>
Date: Sun Aug 24 14:56:26 2025 +0200
Improve hello.py and add README
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3836229
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# My first Git repo
diff --git a/hello.py b/hello.py
index 078d6bf..e0f8470 100644
--- a/hello.py
+++ b/hello.py
@@ -1 +1,2 @@
-print("Hello Git")
+message = "Hello from my first Git repo"
+print(message)
Met git log -p (-p voor patch) krijgen we dezelfde informatie voor een lijst commits.
Author: Fabrice Devaux <fabrice.devaux@gmail.com>
Date: Sun Aug 24 14:56:26 2025 +0200
Improve hello.py and add README
diff --git a/README.md b/README.md
...
commit f39a6cce08ebbb1a63616030322e46b4ff4d653c
Author: Fabrice Devaux <fabrice.devaux@gmail.com>
Date: Sun Aug 24 14:31:08 2025 +0200
Add initial hello.py version
diff --git a/hello.py b/hello.py
new file mode 100644
...
Met git diff kunnen we ook een diff krijgen met alle wijzigingen tussen twee specifieke commits.
git diff f39a6cc..3ecf8d5 geeft alle verschillende tussen de commits f39a6cc en 3ecf8d5.
Git Blame¶
git blame (letterlijk beschuldigen) is een superhandig commando waarmee je lijn per lijn precies kan zien wie als laatste die lijn heeft aangepast, wat de commit ID is, en wanneer dit gebeurd is.
455cc537 (Fabrice Devaux 2025-09-07 09:30:14 +0200 2)
3ecf8d52 (Fabrice Devaux 2025-08-24 14:56:26 +0200 3) message = "Hello from my first Git repo"
3ecf8d52 (Fabrice Devaux 2025-08-24 14:56:26 +0200 4) print(message)
Ons klein test-projectje bevat natuurlijk niet veel veranderingen. Wil je een idee krijgen van de kracht van dit commando, bekijk dan eens een grotere codebase zoals FastAPI: https://github.com/fastapi/fastapi/blame/master/fastapi/openapi/models.py.
Oefeningen¶
- Voeg een nieuw bestand
test.pytoe (commit) - Pas iets aan in
README.mdentest.py - Stage de aanpassingen in
README.md - Bekijk de commit geschiedenis en status van de repo
- Bekijk de uitstaande aanpassingen
- Maak alle uitstaande aanpassingen ongedaan. Gebruik enkel git commando's.
- Verwijder het
test.pybestand en commit deze verandering
Extra: Aanpassingen in een staged bestand
Wat gebeurt er als een bestand dat al gestaged is (maar nog niet gecommit) wordt gewijzigd?
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.py
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.py
Het hello.py bestand is nu gestaged en niet gestaged tegelijk! Wanneer een bestand wordt gestaged houdt Git de exacte versie van het bestand bij op dat moment. M.a.w. de oorspronkelijke inhoud van het bestand is nog steeds gestaged, maar de latere aanpassing niet. We zouden nu enkel de oorspronkelijke versie kunnen committen, of de nieuwe aanpassingen ook stagen (opnieuw met git add hello.py).
Configuratie¶
git config¶
Git heeft een heleboel configuratieparameters. De meesten zul je echter nooit moeten aanpassen.
De configuratie wordt bewaard in gewone tekst-bestanden en kan op 3 locaties voorkomen. Elke locatie overschrijft de waarden van de vorige.
Die bestanden pas je in principe niet met de hand aan. Met het git config commando kunnen we configuratie bekijken en aanpassen.
| Bestand | Toepassing | Git commando |
|---|---|---|
/etc/gitconfig( C:\ProgramData\Git\config op Windows) |
Iedere gebruiker | git config --system |
~/.gitconfig of ~/.config/git/config( C:\Users\$USER\.gitconfig op Windows) |
Huidige gebruiker | git config --global |
<repo-directory>/.git/config |
Lokale repo | git config |
Met git help -c krijg je een lijst van alle mogelijke parameters. Om te beginnen zijn er maar een paar die we willen aanpassen.
Identiteit¶
De user.name en user.email parameters worden gebruikt in commits. Hier willen we onze eigen identiteit instellen - zeker in repos waar we onze code willen delen, of waar we zullen samenwerken met andere ontwikkelaars.
Omdat dit in principe hetzelfde zal zijn voor elke repo gebruiken we --global. Met git config get kunnen we de waarde van een parameter controleren.
Editor¶
Soms heeft een Git commando tekst input nodig van de gebruiker. Bijvoorbeeld bij het git commit commando wanneer geen commit message is meegegeven met de -m parameter. Git zal dan je tekst editor openen zodat je daar een commit message kan samenstellen.
Op Linux, macOS en WSL zal dit standaard de waarde van de $EDITOR variabele zijn (meestal vim of emacs). Als je met vim kan werken is dat een goede optie. Met de core.editor configuratie parameter kunnen we Git een andere editor laten gebruiken.
Bijvoorbeeld om VS Code te gebruiken op Linux, macOS of Windows:
Configuratie overzicht¶
Met git config --list --show-origin krijg je een overzicht van alle aangepaste configuratie en waar die configuratie ingesteld is.
file:/Users/dfabrice/.gitconfig user.email=fabrice.devaux@gmail.com
file:/Users/dfabrice/.gitconfig user.name=Fabrice Devaux
Bestanden negeren (.gitignore)¶
Er zullen altijd een aantal bestanden of directories zijn die je nooit wilt committen. Je kan Git configureren om deze altijd te negeren m.b.v. het .gitignore bestand. Hierin plaats je telkens op een aparte lijn de naam of een expressie van wat genegeerd moet worden.
Het .gitignore bestand zelf voeg je wel toe in Git.
1 file changed, 3 insertions(+)
create mode 100644 .gitignore
touch test.tempgit statusOn branch main
nothing to commit, working tree clean
Samenvatting¶
Samenvatting
- De Git CLI is altijd en overal bruikbaar en werkt hetzelfde op elk platform. Ze bouwt fundamenteel inzicht op in Git en wordt veel gebruikt door AI Agents.
- De basisconfiguratie doe je met
git config --global: user.name, user.email en init.defaultBranch. - Eén directory = één repo: met
git initmaak je van elke directory een repo. Alle Git-informatie leeft in de verborgen.gitdirectory. - Elk bestand zit in één state: untracked, modified, staged of committed (het lifecycle diagram!). Met
git addzet je bestanden klaar in de staging area, een wachtplaats; metgit commitgaan ze als één geheel de geschiedenis in.git rmverwijdert een bestand uit Git - met--cachedblijft het bestand bestaan. git statustoont de state van de repo en geeft ook telkens het juiste commando aan.- Elke commit bevat ID, auteur, datum, beschrijving en diff. Met
git logbekijk je de geschiedenis - met--oneline,--statof een bestandsnaam als argument. - Wijzigingen ongedaan maken kan met
git restore(modified → committed - permanent!) engit restore --staged(staged → modified). git difftoont niet-gestagde wijzigingen (enkel van bestanden die Git al kent!),git diff --stagedde gestagde.git showengit log -ptonen de diffs van commits,git diff <a>..<b>vergelijkt twee commits.git blametoont per lijn wie, wanneer en in welke commit iets veranderde.- De configuratie wordt bewaard in 3 locaties (
--system,--globalen lokaal); elke locatie overschrijft de vorige. Metcore.editorkies je de editor die Git opent.git config --list --show-origingeeft een overzicht van de aangepaste configuratie. - Het bestand
.gitignorezorgt dat bestanden die je nooit wil committen ook nooit gecommit worden. Het.gitignorebestand zelf voeg je wel toe aan Git.
Wat moet je kunnen?
- Je kent het lifecycle diagram grondig!
- Je kan de output van een
git statuscommando interpreteren - Je kan met
git addengit commitwerken om nieuwe aanpassingen te committen - Je begrijpt de output van het
git logcommando - Je weet het je met
git shoween bepaalde commit kan inspecteren en begrijpt de output - Je weet wat het
.gitignorebestand doet



