Skip to main content
Dat 2. semester
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Git-exercises-1

Git – fra ændringer til historik

Formål

I denne øvelse skal du arbejde med Git både fra Git Bash og fra IntelliJ.

Du har tidligere arbejdet med Git og GitHub gennem grafiske værktøjer. Denne gang skal du undersøge, hvad der faktisk sker i Git, når du ændrer, gemmer og deler kode.

Målet er ikke at lære en række Git-kommandoer udenad. Du skal i stedet bruge Git til at løse forskellige problemer, der opstår undervejs.

Efter øvelsen skal du kunne forklare sammenhængen mellem:

Working Directory → Staging Area → Local Repository → Remote Repository


Del 1 – Et projekt uden versionsstyring

Du har startet et nyt Java-projekt i IntelliJ.

Projektet indeholder:

src/
  Main.java
  Customer.java
README.md

Du opdager, at projektet endnu ikke bruger Git.

Opgave

Find ud af, hvordan du kan gøre projektmappen til et lokalt Git-repository.

Brug Git Bash.

Undersøg derefter repositoryets tilstand.

Overvej

  • Hvordan kan Git se, at mappen nu er et repository?
  • Er dine Java-filer allerede gemt i Git-historikken?
  • Hvad betyder det, når en fil er untracked?
Se svar

Kør:

git init
git status

git init opretter et lokalt Git-repository i projektmappen. Git gemmer repositoryets interne informationer i en skjult mappe med navnet .git.

Filerne er endnu ikke gemt i Git-historikken. De vises derfor typisk som untracked, fordi Git kan se dem, men endnu ikke sporer dem.

Der findes endnu ingen commits, og staging area er tom.

---

Del 2 – Hvad har jeg egentlig ændret?

Du arbejder videre på programmet.

Foretag ændringer i både:

Main.java
Customer.java

Du bliver afbrudt og vender tilbage til projektet senere.

Du kan ikke længere huske præcis, hvad du har ændret.

Opgave

Brug Git Bash til at undersøge:

  1. hvilke filer der er ændret
  2. præcis hvilke linjer der er ændret

Overvej

Der findes forskellige Git-kommandoer til at besvare:

Hvilke filer er ændret?

og:

Hvad er ændret inde i filerne?

Find en løsning på begge problemer.

Se svar

Kør:

git status

for at se, hvilke filer der er ændret.

Kør derefter:

git diff

for at se de konkrete linjer, der er ændret i arbejdsområdet.

Begge filer bør vises som ændrede. Der er endnu ikke oprettet nye commits, og ændringerne er endnu ikke staged.

---

Del 3 – Jeg vil ikke gemme det hele sammen

Du er tilfreds med ændringen i Customer.java.

Ændringen i Main.java er derimod stadig halvfærdig.

Du vil derfor lave et snapshot af kun den færdige ændring.

Opgave

Find ud af, hvordan du kan gøre Customer.java klar til næste commit uden samtidig at tage ændringen i Main.java med.

Undersøg repositoryets status bagefter.

Spørgsmål

Kan du ud fra Git’s status se forskel på:

  • ændringen, der skal med i næste commit
  • ændringen, der endnu ikke skal med?

Lav derefter et commit med den færdige ændring.

Undersøg status igen.

Overvej

Hvor befinder ændringen i Main.java sig nu?

Hvor befinder ændringen i Customer.java sig?

Se svar

Kør:

git add Customer.java
git status

Customer.java vises nu som staged, mens Main.java stadig kun er ændret i arbejdsområdet.

Opret derefter et commit:

git commit -m "Opdater Customer"

Kontrollér status igen:

git status

Commit-historikken indeholder nu ændringen fra Customer.java. Ændringen i Main.java er stadig kun i arbejdsområdet og er ikke committed.

---

Del 4 – Ups, den skulle ikke med

Foretag igen ændringer i mindst to filer.

Gør begge filer klar til næste commit.

Du opdager nu:

Den ene fil er ikke færdig og skal alligevel ikke med i næste commit.

Du vil beholde ændringerne i filen, men fjerne filen fra det kommende commit.

Opgave

Find ud af, hvordan du kan fjerne filen fra staging area uden at miste dine ændringer.

Kontrollér resultatet med Git.

Vigtigt spørgsmål

Hvad er forskellen på:

at fjerne en ændring fra staging area

og

at slette selve ændringen?

Se svar

Hvis du eksempelvis vil fjerne Main.java fra staging area, men beholde ændringerne, kan du køre:

git restore --staged Main.java
git status

Main.java vises stadig som ændret i arbejdsområdet, men er ikke længere staged.

Den anden fil forbliver staged.

git restore --staged fjerner kun ændringen fra staging area. Kommandoen sletter ikke ændringen fra filen.

---

Del 5 – Den ændring var en dårlig idé

Foretag en mindre ændring i en fil, som allerede er kendt af Git.

Gem filen.

Du fortryder ændringen og vil have filen tilbage præcis som ved seneste commit.

Opgave

Find en Git-løsning, som kan genskabe filen.

Kontrollér før og efter, hvad Git registrerer.

Overvej

Hvorfor skal man være mere forsigtig med denne handling end med blot at fjerne en fil fra staging area?

Se svar

Kontrollér først status:

git status

Gendan derefter filen:

git restore Customer.java

Kontrollér status igen:

git status

Filen bør ikke længere være markeret som ændret.

git restore Customer.java sletter de lokale ændringer i filen og gendanner den version, der svarer til den seneste commit. Derfor skal man være forsigtig med kommandoen.

Commit-historikken ændres ikke.

---

Del 6 – Hvad skete der egentlig?

Efterhånden har projektet fået flere commits.

En medstuderende spørger:

Hvilke ændringer har vi egentlig gemt indtil nu?

Opgave

Find projektets commit-historik fra Git Bash.

Find derefter en måde at vise historikken i en mere kompakt form.

Find følgende oplysninger:

  • commit-id
  • commit-besked
  • forfatter
  • rækkefølgen af commits

Find derefter den samme historik i IntelliJ.

Overvej

Er det to forskellige historikker, du ser?

Eller viser Git Bash og IntelliJ de samme informationer på forskellige måder?

Se svar

Vis den fulde historik med:

git log

Vis en kompakt version med:

git log --oneline

git log viser blandt andet commit-id, commit-besked, forfatter og tidspunkt. Commits vises normalt med det nyeste commit først.

IntelliJ viser den samme lokale Git-historik i Git-vinduet, typisk under fanen Log. Forskellen er kun, hvordan informationerne præsenteres.

---

Del 7 – Et commit var for tidligt

Lav en mindre ændring og commit den.

Umiddelbart bagefter opdager du:

Jeg var faktisk ikke færdig. Jeg vil gerne fjerne det seneste commit fra historikken, men beholde ændringerne, så jeg kan arbejde videre på dem.

Opgave

Undersøg, hvordan git reset kan bruges til dette.

Kontrollér både før og efter med:

  • repositoryets status
  • commit-historikken

Overvej

Hvad skete der med:

  1. committet?
  2. ændringerne i filerne?

Undgå git reset --hard i denne øvelse.

Se svar

Kontrollér først historikken og status:

git log --oneline
git status

Fjern derefter det seneste commit, men behold ændringerne staged:

git reset --soft HEAD~1

Kontrollér resultatet:

git log --oneline
git status

Det seneste commit er nu fjernet fra den lokale historik, men ændringerne fra committet findes stadig i staging area.

Hvis du i stedet vil beholde ændringerne i arbejdsområdet uden at have dem staged, kan du bruge:

git reset HEAD~1

Undgå:

git reset --hard HEAD~1

fordi denne variant kan slette ændringerne.

---

Del 8 – Jeg har brug for et rent arbejdsområde

Du er midt i en ændring, som ikke er færdig.

Du ønsker ikke at committe den.

Men du har midlertidigt brug for at få projektet tilbage til en ren tilstand.

Opgave

Find ud af, hvordan Git kan lægge dine ufærdige ændringer midlertidigt til side.

Kontrollér derefter repositoryets status.

Undersøg, hvor Git har gemt ændringerne.

Få til sidst ændringerne tilbage og kontrollér, at de igen findes i dine filer.

Overvej

Hvad er forskellen på et commit og et stash?

Hvornår ville du bruge det ene frem for det andet?

Se svar

Gem ændringerne midlertidigt med:

git stash

Kontrollér status:

git status

Arbejdsområdet bør nu være rent.

Se dine stashes med:

git stash list

Hent den seneste stash tilbage med:

git stash pop

Ændringerne findes nu igen i arbejdsområdet.

Et commit gemmer en permanent del af projektets historik. Et stash gemmer ændringer midlertidigt uden at oprette et almindeligt commit i projektets historik.

---

Del 9 – Fra lokalt repository til GitHub

Indtil nu har Git-historikken kun eksisteret på din computer.

Opret nu et tomt repository på GitHub til projektet.

Du skal forbinde dit lokale repository med dette remote repository.

Opgave

Find ud af:

  1. hvordan du forbinder dit lokale repository med GitHub
  2. hvordan du kan kontrollere, hvilket remote repository dit lokale repository peger på
  3. hvordan du sender dine commits til GitHub

Kontrollér resultatet på GitHub.

Overvej

Er Git og GitHub det samme?

Hvilke commits eksisterede, før du oprettede GitHub-repositoryet?

Hvor befandt de sig?

Se svar

Tilføj GitHub-repositoryet som remote:

git remote add origin https://github.com/BRUGERNAVN/REPOSITORY.git

Kontrollér forbindelsen:

git remote -v

Send commits til GitHub:

git push -u origin main

Hvis din lokale branch hedder master, skal du i stedet bruge:

git push -u origin master

Git og GitHub er ikke det samme. Git er versionsstyringssystemet, mens GitHub er en online platform, hvor Git-repositories kan gemmes og deles.

De commits, du lavede før oprettelsen af GitHub-repositoryet, fandtes kun i dit lokale repository på computeren.

---

Del 10 – En ændring kommer den anden vej

Foretag nu en lille ændring direkte på GitHub, fx i README.md, og commit ændringen på GitHub.

Gå tilbage til IntelliJ.

Din lokale fil indeholder endnu ikke ændringen.

Problem

GitHub og dit lokale repository indeholder nu ikke helt det samme.

Opgave

Find ud af, hvordan du får ændringen fra GitHub ned på din computer.

Kontrollér bagefter:

  • filens indhold
  • Git-status
  • commit-historikken

Find derefter det nye commit i IntelliJ.

Se svar

Hent ændringen fra GitHub med:

git pull

git pull henter ændringerne fra remote-repositoryet og integrerer dem i dit lokale repository.

Kontrollér derefter:

git status
git log --oneline

README.md skal nu indeholde ændringen fra GitHub, og det nye commit skal kunne ses i den lokale historik.

I IntelliJ kan du se det nye commit i Git-vinduets Log-fane.

Hvis både den lokale og den remote version har ændret de samme linjer, kan der opstå en merge-konflikt. I så fald skal konflikten løses manuelt, før pull-handlingen kan afsluttes.

---

Del 11 – Git Bash og IntelliJ arbejder sammen

Nu skal du bevidst skifte mellem de to værktøjer.

  1. Foretag en ændring i IntelliJ.
  2. Undersøg ændringen fra Git Bash.
  3. Stage filen fra Git Bash.
  4. Kontrollér i IntelliJ, at filen er staged.
  5. Commit ændringen fra IntelliJ.
  6. Undersøg commit-historikken fra Git Bash.
  7. Push ændringen fra IntelliJ.
  8. Kontrollér resultatet på GitHub.

Spørgsmål

Forklar med dine egne ord:

Hvorfor kan Git Bash se et commit, som blev lavet fra IntelliJ?

Se svar

Git Bash og IntelliJ bruger det samme lokale Git-repository i projektmappen.

Når IntelliJ laver et commit, skriver IntelliJ ændringen til repositoryets .git-mappe. Git Bash læser derefter den samme information fra den samme .git-mappe.

Derfor kan Git Bash se commits, som er oprettet fra IntelliJ, og omvendt.

---

Afsluttende udfordring – Hvor er mine ændringer?

Du skal nu vise, at du forstår Git’s model og ikke blot de enkelte kommandoer.

Forestil dig følgende fire situationer.

Situation A

Du har ændret Customer.java, men endnu ikke gjort andet.

Situation B

Du har ændret Customer.java og gjort ændringen klar til næste commit.

Situation C

Du har committed ændringen, men endnu ikke sendt den til GitHub.

Situation D

Du har committed og sendt ændringen til GitHub.

Placér ændringen i den rigtige del af modellen:

Working Directory


Staging Area


Local Repository


Remote Repository

Forklar for hver situation:

  • Hvor findes ændringen?
  • Hvordan kan du undersøge det?
  • Hvad skal der ske for at flytte ændringen til næste trin?
Se svar

Situation A – Working Directory

Ændringen findes kun i arbejdsområdet.

Undersøg det med:

git status
git diff

For at flytte ændringen til staging area skal du køre:

git add Customer.java

Situation B – Staging Area

Ændringen er gjort klar til næste commit.

Undersøg det med:

git status
git diff --staged

For at flytte ændringen til det lokale repository skal du oprette et commit:

git commit -m "Opdater Customer"

Situation C – Local Repository

Ændringen findes i et lokalt commit, men endnu ikke på GitHub.

Undersøg det med:

git log --oneline
git status

For at flytte ændringen til remote-repositoryet skal du pushe:

git push

Situation D – Remote Repository

Ændringen findes både i det lokale repository og på GitHub.

Undersøg det med:

git status
git log --oneline

Du kan også kontrollere resultatet direkte på GitHub.

Når det lokale repository og remote-repositoryet er synkroniserede, bør arbejdsområdet være rent, og der bør ikke være commits, som mangler at blive pushed.

---

Git-værktøjskasse

Når du går i stå, kan du undersøge, om en af følgende kommandoer kan hjælpe dig:

git init
git status
git diff
git diff --staged
git add
git restore
git restore --staged
git commit
git log
git log --oneline
git reset
git stash
git stash list
git stash pop
git remote -v
git remote add
git push
git pull

Du skal ikke nødvendigvis bruge dem i denne rækkefølge.

Start med problemet – vælg derefter Git-kommandoen.

Husk især

Når du er i tvivl om, hvad der foregår i dit repository, er et godt første spørgsmål:

Hvad siger git status?