Git-exercises-1
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
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.
Find ud af, hvordan du kan gøre projektmappen til et lokalt Git-repository.
Brug Git Bash.
Undersøg derefter repositoryets tilstand.
- 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.
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.
Brug Git Bash til at undersøge:
- hvilke filer der er ændret
- præcis hvilke linjer der er ændret
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.
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.
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.
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.
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.
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.
Find ud af, hvordan du kan fjerne filen fra staging area uden at miste dine ændringer.
Kontrollér resultatet med Git.
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.
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.
Find en Git-løsning, som kan genskabe filen.
Kontrollér før og efter, hvad Git registrerer.
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.
Efterhånden har projektet fået flere commits.
En medstuderende spørger:
Hvilke ændringer har vi egentlig gemt indtil nu?
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.
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.
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.
Undersøg, hvordan git reset kan bruges til dette.
Kontrollér både før og efter med:
- repositoryets status
- commit-historikken
Hvad skete der med:
- committet?
- æ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.
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.
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.
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.
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.
Find ud af:
- hvordan du forbinder dit lokale repository med GitHub
- hvordan du kan kontrollere, hvilket remote repository dit lokale repository peger på
- hvordan du sender dine commits til GitHub
Kontrollér resultatet på GitHub.
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.
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.
GitHub og dit lokale repository indeholder nu ikke helt det samme.
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.
Nu skal du bevidst skifte mellem de to værktøjer.
- Foretag en ændring i IntelliJ.
- Undersøg ændringen fra Git Bash.
- Stage filen fra Git Bash.
- Kontrollér i IntelliJ, at filen er staged.
- Commit ændringen fra IntelliJ.
- Undersøg commit-historikken fra Git Bash.
- Push ændringen fra IntelliJ.
- Kontrollér resultatet på GitHub.
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.
Du skal nu vise, at du forstår Git’s model og ikke blot de enkelte kommandoer.
Forestil dig følgende fire situationer.
Du har ændret Customer.java, men endnu ikke gjort andet.
Du har ændret Customer.java og gjort ændringen klar til næste commit.
Du har committed ændringen, men endnu ikke sendt den til GitHub.
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.
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.
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?