Meny for Per-Arne's Git Good!
Fag og prosjekt Per-Arne's Git Good!

Tre områder: arbeidsmappen, staging-området og HEAD

Modul 1: Grunnmuren · 11 min

Den interaktive leksjonen trenger JavaScript. Teksten under er hele leksjonen.

Etter leksjonen kan du

  • forklare hvor en filversjon ligger, i arbeidsmappen, i staging-området eller i HEAD, og forutsi hvilken versjon som havner i neste commit forstå
  • lese git status --short og si hva de to kolonnene betyr forstå
  • velge mellom git diff og git diff --staged for å se det du faktisk lurer på anvende

Forstå: Tre steder en fil kan ligge

En fil kan finnes i tre versjoner samtidig. Arbeidsmappen er filene du ser og redigerer. Staging-området, også kalt index, er utkastet til neste commit. HEAD peker på siste commit på branchen din, og snapshotet der er den tredje versjonen. Akkurat nå er alle tre like.

Når du redigerer filen, endres bare arbeidsmappen. Staging-området og HEAD har fortsatt den gamle versjonen. Git sier at filen er endret, men ikke staget.

git add kopierer filen slik den er akkurat nå, inn i staging-området. Det er en kopi av innholdet, ikke et merke på filen.

Redigerer du igjen etter git add, får du tre ulike versjoner. Den nye linjen finnes bare i arbeidsmappen. Staging-området husker fortsatt kopien du tok.

En diff sammenligner alltid to versjoner. git diff sammenligner staging-området med arbeidsmappen, altså det du ikke har staget ennå. git diff --staged sammenligner HEAD med staging-området, altså det du har staget.

Se demo: Commiten tar det som er staget

Vi starter med et repository med én commit. Først legger vi til en linje i README. Se at bare kortet i arbeidsmappen endrer seg.

$ echo "Install: npm install" >> README.md

git diff viser forskjellen mellom staging-området og arbeidsmappen. Plusstegnet markerer den nye linjen. Den er ennå ikke staget.

$ git diff

Nå kopierer vi denne versjonen inn i staging-området. Kortet i midten får den nye versjonen.

$ git add README.md

Så redigerer vi videre, slik man ofte gjør. Vi legger til en linje til, etter git add. Nå har filen tre ulike versjoner.

$ echo "Run: npm start" >> README.md

Den korte statusen viser to bokstaver. Første kolonne sammenligner HEAD med staging-området. Andre kolonne sammenligner staging-området med arbeidsmappen. MM betyr altså én endring som er staget, og en nyere som ikke er det.

$ git status --short

git diff --staged viser det som er staget: bare install-linjen.

$ git diff --staged

Nå committer vi. Hva tror du havner i snapshotet?

$ git commit -m "Add install instructions"

Status igjen. Første kolonne er tom: staging-området og HEAD er like. Andre kolonne sier M: npm start-linjen venter fortsatt i arbeidsmappen.

$ git status --short

Oppgaver

  1. Legg til linjen Install: npm install nederst i README.md.
  2. Vis endringene som ikke er staget ennå.
  3. Stage README.md.
  4. Vis statusen i kortformat.
  5. Commit det som er staget, og bare det.

Øv: Overfør: velg hva som blir med

Et nytt prosjekt der flere filer allerede er endret, og én er delvis staget. Start med å undersøke tilstanden.

Oppgaver

  1. todo.txt har en staget versjon og en enda nyere redigering. Lag en commit som inneholder den nyeste versjonen av todo.txt, og ingen andre filer.
  2. Både app.js og notes.txt er endret. Commit bare endringen i app.js. notes.txt skal fortsatt være endret, men ikke committet.

Sjekk deg selv: Hent det fram igjen

Du har staget README.md, og så redigert den igjen. Du vil se bare den nyeste redigeringen. Hvilken kommando bruker du?

  • git diff
  • git diff --staged
  • git diff HEAD

git status --short viser MM app.js. Hva betyr det?

  • Filen er endret i to commits
  • Filen har en endring som er staget, og en nyere som ikke er det
  • Filen har en konflikt

Repetisjon fra forrige leksjon: repositoryet sporer app.js, notes.txt og todo.txt. Du endrer og stager app.js. notes.txt har også en endring du ikke har staget. Du committer. Hvilke filer finnes i snapshotet til den nye commiten?

  • Bare app.js, fordi det var den eneste filen som ble endret
  • Alle tre: den nye versjonen av app.js, og de to andre slik de var i forrige commit
  • Alle tre, slik de ser ut i arbeidsmappen akkurat nå

Vanlige misforståelser

  • «Commiten tar filen slik den ser ut i editoren.» Den tar versjonen som ligger i staging-området.
  • «git add merker filen, så senere endringer blir med automatisk.» git add kopierer innholdet slik det er akkurat da.
  • «git diff viser alt som skal committes.» Vanlig git diff viser bare det som ennå ikke er staget.

Les mer

De tre områdene, presist

  • Arbeidsmappen (working tree) er vanlige filer på disk. Editoren din ser bare denne.
  • Staging-området (index) er filen .git/index. Den er en fullstendig liste over alle sporede filer og innholdet deres, ikke bare en liste over endringer. Rett etter en commit er staging-området lik HEAD. Når folk sier at «ingenting er staget», betyr det at staging-området og HEAD er like.
  • HEAD peker på branchen du står på, og branchen peker på den siste commiten. Snapshotet i den commiten er sammenligningspunktet for «hva er endret siden sist».
  • En fil er sporet når den finnes i staging-området. En ny fil er usporet til første git add.

git commit lager snapshotet fra staging-området. Arbeidsmappen leses ikke. Derfor må en redigering etter git add stages på nytt for å bli med.

Hvilke to versjoner sammenlignes?

En diff har alltid to endepunkter. Velg kommando etter hvilket spørsmål du stiller:

Kommando Sammenligner Svarer på
git diff staging-området → arbeidsmappe Hva har jeg endret, men ikke staget?
git diff --staged HEAD → staging-området Hva blir med i neste commit?
git diff HEAD HEAD → arbeidsmappe Alt som er endret siden siste commit

--cached betyr det samme som --staged. Usporede filer vises aldri i git diff, så en ny fil du har glemt å stage, finner du bare i git status.

Her har README.md fått én linje som er staget, og én nyere som ikke er det:

$ git diff
diff --git a/README.md b/README.md
index 33684f8..f7ea923 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
 Welcome
 Install: npm install
+Run: npm start
$ git diff --staged
diff --git a/README.md b/README.md
index ba4c514..33684f8 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 Welcome
+Install: npm install
  • index 33684f8..f7ea923 er ID-ene til de to filversjonene som sammenlignes. Legg merke til at 33684f8 er «etter» i den ene diffen og «før» i den andre. Det er den stagede versjonen.
  • @@ -1,2 +1,3 @@ er overskriften til en hunk, en sammenhengende blokk med endringer: fra linje 1 i den gamle versjonen, 2 linjer, til linje 1 i den nye, 3 linjer.
  • Linjer med + er lagt til, linjer med - er fjernet, og linjer med mellomrom er kontekst.
  • Nyttige valg: --stat gir en oversikt per fil, --name-only gir bare filnavn, og -- fil begrenser diffen til én fil.

Les git status --short

$ git status --short
MM README.md
AM app.js
D  gone.txt
R  old.txt -> renamed.txt
?? new.txt

Første kolonne (X) sammenligner HEAD med staging-området. Andre kolonne (Y) sammenligner staging-området med arbeidsmappen. Et mellomrom betyr «ingen forskjell».

Kode Betyr
M Endret og staget
M Endret, ikke staget
MM En staget endring og en nyere som ikke er staget
A Ny fil, staget
AM Ny fil staget, så endret igjen
D Sletting staget, for eksempel med git rm
D Slettet fra disk, men slettingen er ikke staget
R Omdøping staget, for eksempel med git mv
?? Usporet

Den lange git status sier det samme med ord, og foreslår kommandoer. Der ser du git restore --staged <file>, som angrer det du har staget ved å legge HEAD-versjonen tilbake i staging-området, og git restore <file>, som forkaster endringen i arbeidsmappen. Den siste kan ikke angres, fordi endringen aldri var lagret i Git. Leksjonen om å angre går gjennom begge.

Måter å stage på

  • git add notes.txt stager akkurat de filene du nevner. Det er mest presist.
  • git add . stager alt under mappen du står i: endrede, nye og slettede filer, men ikke filer som er ignorert.
  • git add -A gjør det samme for hele repositoryet.
  • git add -u stager endringer og slettinger i filer Git allerede sporer, men ingen nye filer.
  • git add -p lar deg velge bit for bit. Det lærer du i leksjonen om gode commits.
  • git rm notes.txt sletter en fil og stager slettingen. git mv old.txt new.txt omdøper og stager.

Vanen som sparer deg for flest feil: kjør git diff --staged rett før git commit.

Vanlige overraskelser

  • «Endringen ble ikke med i commiten.» Du kjørte git add før den siste redigeringen. git status --short viser M på filen. Stage den på nytt og commit.
  • «Diffen er tom, men status viser endringer.» git diff viser ingenting når alt er staget. Bruk git diff --staged.
  • «Den nye filen vises ikke i diffen.» Den er usporet. Den står under ?? i status.
  • Skrivefeil i filnavnet:
$ git add REDME.md
fatal: pathspec 'REDME.md' did not match any files

Ingenting ble staget. Sjekk navnet med git status, og prøv igjen.

Les videre