Hoppa till innehåll

Hämta ändringar: git fetch och git pull

  • Att hämta nya commits med git fetch, och se vad som är nytt innan du för in det.
  • Att hämta och föra in på en gång med git pull.
  • Vad du gör när git push nekas, och när git pull frågar hur grenarna ska föras ihop.

Så fort du arbetar från två datorer, eller med någon annan, kommer det commits till fjärr-repositoryt som du inte har. GitGitEtt program som sparar versioner av filerna i ett projekt, så att man kan se vad som ändrats, gå tillbaka till tidigare versioner och arbeta flera samtidigt.Läs mer om Git hämtar dem aldrig av sig själv. Du måste hämta dem innan du kan bygga vidare på dem, och innan du får skicka dina egna.

  • git fetch hämtar nya commits från origin och flyttar fram origin/main. Din egen main och dina filer ändras inte. Det är alltid ofarligt.
  • git pull gör en git fetch och sedan en mergeMergeAtt föra ihop ändringarna från två branches till en. Git gör det automatiskt när det går och ber om hjälp när samma rader ändrats på olika sätt.Läs mer om merge av origin/main in i din main. Det är precis samma merge som i modul 4: en fast-forward när bara servern har nya commits, och en merge-commit när ni båda har det.

Servern tar bara emot en git push som är en fast-forward för grenen där. Har någon annan hunnit skicka commits som du inte har nekas din push. Då hämtar du först med git pull, och skickar sedan.

I exemplet delar resplan och resplan-laptop samma fjärr-repository, som i lektion 2. På laptopen läggs dag 4 till och skickas:

Terminal (resplan-laptop)
$ git commit -m "Lägg till dag 4: Sundsvall"
[main 223a0d9] Lägg till dag 4: Sundsvall
1 file changed, 1 insertion(+)
$ git push
To /tmp/kim/server/resplan.git
7620fac..223a0d9 main -> main

I resplan vet Git ännu ingenting om det. git status jämför bara med hur origin/main såg ut senast:

Terminal (resplan)
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

Hämta, och fråga igen:

Terminal (resplan)
$ git fetch
From ../server/resplan
7620fac..223a0d9 main -> origin/main
$ git status
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean

Nu vet Git att origin/main ligger en commit före. Du kan se vad som är nytt innan du för in det:

Terminal (resplan)
$ git diff main origin/main
diff --git a/resplan.txt b/resplan.txt
index d9d77fc..7893b8b 100644
--- a/resplan.txt
+++ b/resplan.txt
@@ -3,3 +3,4 @@ Resplan sommaren
Dag 1: Stockholm
Dag 2: Uppsala
Dag 3: Gävle
+Dag 4: Sundsvall

git pull för in ändringarna. Här blir det en fast-forward:

Terminal (resplan)
$ git pull
Updating 7620fac..223a0d9
Fast-forward
resplan.txt | 1 +
1 file changed, 1 insertion(+)

Nu har båda gjort en ny commit samtidigt. Laptopen hann skicka dag 5 först. När resplan försöker skicka en ny rubrik nekas den:

Terminal (resplan)
$ git push
To ../server/resplan.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to '../server/resplan.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Inget har gått förlorat. Git skyddar bara laptopens commit från att skrivas över. Lösningen är git pull och sedan git push.

Första gången grenarna har gått isär frågar git pull hur de ska föras ihop:

Terminal (resplan)
$ git pull
From ../server/resplan
223a0d9..c290728 main -> origin/main
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Kursen använder merge, som du kan från modul 4. Ställ in det en gång för alla dina repositories och hämta igen:

Terminal (resplan)
$ git config --global pull.rebase false
$ git pull
Auto-merging resplan.txt
Merge made by the 'ort' strategy.
resplan.txt | 1 +
1 file changed, 1 insertion(+)

git pull öppnar texteditorn för merge-commitens meddelande, precis som git merge. Med git pull --no-edit används det ifyllda meddelandet direkt. Nu går det att skicka:

Terminal (resplan)
$ git log --oneline --graph
* fdccd6c (HEAD -> main) Merge branch 'main' of ../server/resplan
|\
| * c290728 (origin/main) Lägg till dag 5: Umeå
* | 1578de3 Lägg till årtal i rubriken
|/
* 223a0d9 Lägg till dag 4: Sundsvall
* 7620fac Lägg till dag 3: Gävle
* 226c08c Första versionen av resplanen
$ git push
To ../server/resplan.git
c290728..fdccd6c main -> main

Du spelar två personer, eller samma person vid två datorer. Mapparna resplan-git och resplan-andra-datorn från förra lektionen är kopplade till samma repository på GitHub.

1. Vad är skillnaden mellan git fetch och git pull?
Visa rätt svar
  • git fetch hämtar bara. git pull hämtar och gör en merge in i din gren.
2. git status säger "Your branch is behind 'origin/main' by 1 commit". Vad betyder det?
Visa rätt svar
  • Servern har en commit som du inte har fört in än: Kör git pull för att föra in den.
3. Din git push nekas med "Updates were rejected because the remote contains work that you do not have locally". Vad gör du?
Visa rätt svar
  • git pull, och sedan git push: Hämta och för in de nya commitsen först.

  • git fetch hämtar nya commits och flyttar fram origin/main. Dina filer ändras inte.
  • git status och git diff main origin/main visar vad som är nytt efter en git fetch.
  • git pull är git fetch plus en merge. Det kan bli en fast-forward, en merge-commit eller en konflikt.
  • En git push nekas när servern har commits som du inte har. Kör git pull, och sedan git push.
  • Ställ in git config --global pull.rebase false en gång, så vet git pull att den ska göra en merge.