Chapters ▾ 2nd Edition

3.5 Git-grenar - Fjärrgrenar

Fjärrgrenar

Fjärrreferenser är referenser (pekare) i dina fjärrkodförråd, inklusive grenar, taggar och annat. Du kan få en fullständig lista över fjärrreferenser med git ls-remote <fjärr> eller git remote show <fjärr> för fjärrgrenar och mer information. Men det vanligaste är att använda fjärrspårade grenar.

Fjärrspårade grenar är referenser till tillståndet hos fjärrgrenar. Det är lokala referenser som du inte kan flytta själv; Git flyttar dem åt dig när du kommunicerar över nätet så att de representerar fjärrkodförrådets läge korrekt. Se dem som bokmärken som påminner dig om var grenarna låg sist du anslöt.

Fjärrspårade grenar har namnet <fjärr>/<gren>. Om du till exempel vill se hur master i fjärrkodförrådet origin såg ut senaste gången du kommunicerade med det, tittar du på origin/master. Om du arbetar med en kollega som skickat upp en gren iss53 kan du ha en egen lokal iss53, men grenen på servern representeras av fjärrspårade origin/iss53.

Det här kan vara aningen förvirrande, så låt oss visa ett exempel. Anta att du har en Git‑server i ditt nätverk på git.ourcompany.com. När du klonar från den namnger Git automatiskt fjärrkodförrådet origin, hämtar all data, skapar en pekare till var dess master-gren ligger och kallar den origin/master lokalt. Git ger dig också en lokal master-gren som pekar på samma ställe som fjärrkodförrådets master, så att du kan arbeta vidare.

Notera
“origin” är inte speciell

Precis som att namnet “master” inte betyder något särskilt i Git, gäller detsamma för “origin”. master är standardnamnet på startgrenen när du kör git init, vilket är varför det är så vanligt, och origin är standardnamnet på fjärrkodförrådet när du kör git clone. Om du kör git clone -o booyah får du i stället booyah/master som standardfjärrgren.

Server och lokala kodförråd efter kloning
Figur 30. Server och lokala kodförråd efter kloning

Om du gör arbete på din lokala master och någon annan under tiden skickar upp ändringar till git.ourcompany.com och uppdaterar dess master, kommer historikerna att gå åt olika håll. Så länge du inte kontaktar origin flyttas inte din origin/master-pekare.

Lokalt och fjärrarbete kan divergera
Figur 31. Lokalt och fjärrarbete kan divergera

För att synkronisera med ett fjärrkodförråd kör du git fetch <fjärr> (i vårt fall git fetch origin). Kommandot slår upp vilken server origin är (här git.ourcompany.com), uppdaterar data du inte har och uppdaterar din lokala databas, samt flyttar origin/master till sitt nya, uppdaterade läge.

`git fetch` uppdaterar fjärrspårade grenar
Figur 32. git fetch uppdaterar fjärrspårade grenar

För att visa hur flera fjärrservrar ser ut kan vi anta att du har en annan intern Git‑server som bara används av ett sprintlag. Servern finns på git.team1.ourcompany.com. Du kan lägga till den som fjärrreferens i projektet du jobbar på genom git remote add, som vi tog upp i Grunderna i Git. Ge fjärrkodförrådet namnet teamone som kortnamn för URL:en.

Lägga till ytterligare en server som fjärrkodförråd
Figur 33. Lägga till ytterligare en server som fjärrkodförråd

Nu kan du köra git fetch teamone för att uppdatera allt som teamone har som du saknar. Eftersom den servern bara har en delmängd av datan som origin har, uppdaterar Git ingen data men sätter en fjärrspårad gren teamone/master som pekar på den incheckning som teamone har som sin master.

Fjärrspårad gren för `teamone/master`
Figur 34. Fjärrspårad gren för teamone/master

Skicka

När du vill dela en gren med omvärlden behöver du skicka den till ett fjärrkodförråd där du har skrivrättigheter. Dina lokala grenar synkroniseras inte automatiskt – du måste skicka de grenar du vill dela. Då kan du ha privata grenar för arbete du inte vill dela och skicka bara de ämnesgrenar du vill samarbeta kring.

Om du har en gren som heter serverfix och vill arbeta med andra kan du skicka den på samma sätt som din första gren. Kör git push <fjärr> <gren>:

$ git push origin serverfix
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
Total 24 (delta 2), reused 0 (delta 0)
To https://github.com/schacon/simplegit
 * [new branch]      serverfix -> serverfix

Det här är en genväg. Git expanderar automatiskt grennamnet serverfix till refs/heads/serverfix:refs/heads/serverfix, vilket betyder: "Ta min lokala gren serverfix och uppdatera fjärrkodförrådets serverfix-gren". Vi går igenom refs/heads/ i detalj i Git bakom kulisserna, men du kan i regel utelämna det. Du kan också göra git push origin serverfix:serverfix, vilket är samma sak. Detta format låter dig skicka en lokal gren till en fjärrgren med ett annat namn. Om du inte vill kalla den serverfix i fjärrkodförrådet kan du köra git push origin serverfix:awesomebranch för att skicka din lokala serverfix som awesomebranch i fjärrkodförrådet.

Notera
Skriv inte lösenordet varje gång

Om du använder HTTPS-URL när du skickar upp kommer Git‑servern fråga efter användarnamn och lösenord för autentisering. Som standard frågar den via terminalen så att servern kan avgöra om du får skicka.

Om du inte vill skriva in det varje gång kan du sätta upp en "inloggningsmellanlagring". Det enklaste är att låta datorn hålla det i minnet några minuter, vilket du kan ställa in med git config --global credential.helper cache.

Mer information om olika mellanlagringsalternativ finns i Lagring av inloggningsuppgifter.

Nästa gång en kollega uppdaterar från servern får de en referens till var serverns serverfix ligger, som fjärrgrenen origin/serverfix:

$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit
 * [new branch]      serverfix    -> origin/serverfix

Det är viktigt att notera att när du uppdaterar nya fjärrspårade grenar får du inte automatiskt en lokal, redigerbar kopia av dem. I det här fallet har du alltså ingen ny lokal serverfix-gren – bara en origin/serverfix-pekare som du inte kan ändra.

För att sammanfoga arbetet med din nuvarande gren kan du köra git merge origin/serverfix. Om du vill ha en egen serverfix-gren att jobba i kan du basera den på fjärrspårade grenen:

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

Detta ger dig en lokal gren att arbeta på som börjar där origin/serverfix ligger.

Spårande grenar

Att växla till en lokal gren från en fjärrspårad gren skapar automatiskt en "spårande gren" (och grenen den följer kallas "uppströmsgren"). Spårande grenar är lokala grenar med en direkt koppling till en fjärrgren. Om du står på en spårande gren och skriver git pull vet Git automatiskt vilken server den ska hämta från och vilken gren som ska sammanfogas in.

När du klonar ett kodförråd skapas normalt en master-gren som spårar origin/master. Du kan dock skapa andra spårande grenar om du vill – till exempel för grenar i andra fjärrkodförråd eller för att inte spåra master. Det enkla fallet är det du såg nyss, git checkout -b <gren> <fjärr>/<gren>. Det är så vanligt att Git har en kortform: --track.

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

Det är så vanligt att det till och med finns en genväg till genvägen. Om grenen du försöker växla till (a) inte finns lokalt och (b) exakt matchar en gren i ett enda fjärrkodförråd, skapar Git en spårande gren åt dig:

$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

För att skapa en lokal gren med ett annat namn än fjärrgrenen kan du använda första varianten med ett annat lokalt grennamn:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

Nu kommer din lokala gren sf automatiskt att dra från origin/serverfix.

Om du redan har en lokal gren och vill koppla den till en fjärrgren du just uppdaterat, eller byta vilken uppströmsgren den spårar, kan du använda -u eller --set-upstream-to med git branch för att sätta detta när som helst.

$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Notera
Uppströmskortform

När du har en spårande gren kan du referera uppströmsgrenen med @{upstream} eller @{u}. Om du står på master och den spårar origin/master kan du skriva git merge @{u} i stället för git merge origin/master om du vill.

Om du vill se vilka spårande grenar du har kan du använda git branch -vv. Det listar dina lokala grenar med mer information, inklusive vad varje gren spårar och om den ligger före, efter eller bådadera.

$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] Add forgotten brackets
  master    1ae2a45 [origin/master] Deploy index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] This should do it
  testing   5ea463a Try something new

Här ser vi att iss53 spårar origin/iss53 och ligger "före" med två, vilket betyder att vi har två lokala incheckningar som inte är skickade. Vi ser också att master spårar origin/master och är uppdaterad. serverfix spårar server-fix-goodteamone och ligger före med tre och efter med en, vilket betyder att det finns en incheckning på servern som vi inte har sammanfogat ännu och tre lokala incheckningar som inte är skickade. Slutligen ser vi att testing inte spårar någon fjärrgren.

Det är viktigt att notera att dessa siffror bara gäller sedan senaste gången du uppdaterade från varje server. Kommandot kontaktar inte servrarna utan visar vad som finns i din lokala mellanlagring. Vill du ha helt uppdaterade siffror behöver du uppdatera från alla fjärrkodförråd precis innan du kör det, till exempel så här:

$ git fetch --all; git branch -vv

Dra

Kommandot git fetch uppdaterar ditt lokala kodförråd med alla ändringar från servern som du inte redan har. Det uppdaterar bara datan och låter dig sammanfoga den själv. git pull är i de flesta fall git fetch följt direkt av git merge. Om du har en spårande gren inställd, antingen genom att du satte den explicit eller för att clone eller checkout skapade den, kommer git pull att slå upp vilken server och gren din nuvarande gren spårar, uppdatera från servern och försöka sammanfoga fjärrgrenen.

Ta bort fjärrgrenar

Anta att du är klar med en fjärrgren – du och dina kollegor är färdiga med en funktion och har sammanfogat den in i fjärrkodförrådets master (eller den gren där er stabila kodlinje finns). Du kan ta bort en fjärrgren med --delete till git push. Om du vill ta bort serverfix från servern kör du:

$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 - [deleted]         serverfix

Det enda detta gör är i praktiken att ta bort pekaren på servern. Git‑servern behåller oftast data en tid tills skräpsamling körs, så om det togs bort av misstag går det ofta att återställa.