Git
Chapters ▾ 2nd Edition

3.5 Git förgreningar - Fjärrgrenar

Fjärrgrenar

Fjärreferenser är referenser (pekare) i dina fjärrförvar, inklusive grenar, taggar och så vidare. Du kan få en fullständig lista av fjärreferenser genom kommandot git ls-remote [fjärrnamn], eller git remote show [fjärrnamn] för fjärrgrenar såväl som ytterligare information. Dock är ett vanligare sätt är att dra nytta av fjärrspårade grenar.

Fjärrspårade grenar är referenser till tillståndet hos fjärrgrenar. De är lokala referenser som du inte kan flytta, utan Git flyttar dem åt dig när du kommunicerar med fjärrförvaret över nätverket, för att på ett korrekt sätt representera dess tillstånd. Du kan tänka på dem som bokmärke, för att påm,inna dig om var grenarna hos ditt fjärrförvar var senast du anslöt till det.

Namnen hos fjärrspårade grenar har formen <fjärrnamn>/<gren>. Till exempel om du vill se var master-grenen på ditt origin-fjärrförvar såg ut senast du kommunicerade med fjärrförvaret, så skulle du kontrollera grenen origin/master. Om du arbetade med en kollega och vederbörande publicerade en iss53-gren, så kanske du har en egen iss53-gren, men grenen på servern skulle representeras av den fjärrspårade grenen origin/iss53.

Detta kan låta lite förvirrande, så låt oss ta ett exempel. Anta att du har en Gitserver på ditt nätverk som nås via git.ourcompany.com. Om du klonar från detta, kommer Gits clone-kommando automatiskt benämna det origin och hämta hem all data, skapa en pekare till var dess master-gren är och benämner den origin/master lokalt hos dig. Git ger dig också en egen lokal master-gren som pekar på samma ställe som fjärrförvarets master-gren så att du kan börja jobba.

Notera
“origin” är inte speciell

Precis som att namnet “master” inte betyder något särskilt i Git, betyder inte heller “origin” något särskilt. Medan “master” är standardnamnet för den första grenen när du kör git init, varför namnet är så välanvent, är “origin” standardnamnet för ett fjärrförvar när du kör git clone. Om du kör git clone -o booyah istället kommer du ha booyah/master som din standardfjärrgren.

Server and local repositories after cloning.
Figur 30. Server och lokala förvar efter kloning

Om du jobbar lite på din lokala master-gren och någon annan under tiden skickar ändringar till git.ourcompany.com och uppdaterar dess master-gren kommer era historiker att utvecklas olika. Och så länge du inte kommunicerar med din server kommer din origin/master pekare inte att flyttas.

Local and remote work can diverge.
Figur 31. Lokalt arbete och fjärrarbete kan divergera

För att synkronisera ditt arbete med ett fjärrförvar kör du kommandot git fetch <fjärrnamn> (i vårt fall git fetch origin). Kommandont kontrollerar vilken server som “origin” är (i detta fallet är det git.ourcompany.com), hämptar data från den som du inte redan har och uppdaterar din lokala databas, samt flyttar din origin/master-pekare till sin nya uppdaterade position.

`git fetch` updates your remote references.
Figur 32. git fetch uppdaterar dina fjärrspårade grenar

För att demonstrera att ha flera fjärrservrar och vad fjärrgrenar för dessa fjärrprojekten ser ut som, antag att du har ytterligare en intern Gitserver som bara används för utveckling av ett av era sprintteam. Denna server finns på ``git.team1.ourcompany.com`. Du kan lägga till en ny fjärreferens till projektet du nu jobbar på genom att köra kommandopt git remote add som vi behandlade i Grunder i Git. Benämn denna server teamone som kommer vara ditt smeknamn för sökvägen.

Adding another server as a remote.
Figur 33. Lägga till ytterligare en server som ett fjärrförvar

Nu kan du köra git fetch teamone för att hämta all från fjärrservern teamone som du ännu inte har. Eftersom den servern har ett delmängd av datan din origin-server har just nu hämtar Git ingen data men sätter en fjärrspårad gren som den kallar teamone/master som pekar på den version som teamone har som sin master-gren.

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

Publicera

När du vill dela grenar med världen, behöver du publicera dem på ett fjärrförvar dit du har skrivrättigheter. Dina lokala grenar synkroniseras inte automatiskt för fjärrservrarna som du skriver till — du måste explicit publicera grenarna som du vill dela. På så vis kan du använda privata grenar för arbete du inte vill dela och bara publicera de ämnesgrenar du vill samarbeta på.

Om du har en gren sopm heter serverfix som du vill arbeta på tillsammans med andra kan du publicera den på samma sätt som du publicerade din första gren. Kör git push <fjärrnamn> <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

Detta är lite av en genväg. Git expanderar automatiskt grennamnet serverfix till refs/heades/serferfix:refs/heads/serverfix, som betyder “Ta min lokala gren serverfix och publicera den genom att uppdatera fjärrförvarets serverfix-gren.” Vi kommer gå igenom refs/heads/-delen i detalj i Git Internals, men i allmänhet kan du strunta i det. Du kan också köra git push origin serverfix:serverfix, som gör samma sak — den säger “Ta min serverfix-gren och gör den till fjärrförvarets serverfix-gren.” Du kan använda detta formatet för att publicera en lokal gren till en fjärrgren som heter något annat. Om du inte vill att den skall kallas serverfix på servern, kan du istället köra git push origin serverfix:grymgren för att publicera din lokala gren serverfix under namnet grymgren på servern.

Notera
Skriv inte ditt lösenord varje gång

Om du använder en HTTPS-sökväg att publicera via, kommer Git fråga efter ditt användarnamn och lösenord för autentisering. Som standard kommer den begära informationen via terminalen så att servern kan avgöra om du får publicera.

Om du inte vill skriva in det varenda gång du publicerar kan du sätta upp en “legitimationsgömma” (eng. “credential cache”). Det enklaste är att datorn håller informationen i minnet några minuter, vilket lätt kan konfigureras genom att köra git config --global credential.helper cache.

För mer information om de olika möjligheterna att temporärt spara legitimationsinformation, se Credential Storage.

Nästa gång någon av dina kollegor hämtar från servern, kommer de få en referens till var serverns version av serverfix är under 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 hämtar information som för det med sig nya fjärrspårade grenar så får du inte automatiskt en lokal editerbar kopia av dem. Med andra ord kommer du inte i detta fallet ha en ny serverfix-gren — du har bara en origin/serverfix-pekare som du inte kan modifiera.

För att slå samman detta arbete in i din nuvarande arbetsgren kan du köra git merge origin/serverfix. Om du vill ha din egen serverfix-gren som du kan jobba med, kan du basera den på din fjärrspårade gren:

$ 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 som du kan jobba på som pekar dit origin/serverfix pekar.

Följa grenar

Att checka ut en lokal gren från ett fjärrspårad gren skapar automatiskt det som kallas för en “följande gren” (och den gren den följer kallas för en “uppströmsgren”). Följande grenar är lokala grenar som har en direkt koppling till en fjärrgren. Om du är på en följande gren och skriver git pull, vet Git automatiskt vilken server den skall hämta data från och vilken gren den skall slå ihop ändringarna i.

När du klonar ett förvar skapas generellt en master-gren som följer origin/master. Du kan dock konfigurera andra följande grenar om du önskar — en som följer grenar i andra fjärrförvar, eller om du inte vill följa master-grenen. Det enkla fallet är exemplet du just såg, att köra git checkout -b <gren> <fjärrnamn>/<gren>. Detta är så vanligt förekommande att Git tillhandahåller kortkommandot --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 till och med så vanligt att det faktiskt finns en genväg till kortkommandot. Om grenen du försöker checka ut (a) inte existerar och (b) exakt matchar namnet på en gren endast i ett fjärrförvar, kommer Git att skapa en följande 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 sätta upp en lokal gren med ett annat namn än fjärrgrenen kan du enkelt använda den första versionen 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 uppdatera från origin/serverfix.

Om du redan har en lokal gren och vill konfigurera mot en fjärrgren du just hämtat hem eller vill byta ut den uppströmsgren du följer, kan du använda flaggan -u eller --set-upstream-to till kommandot git branch för att explicit ställa in denna när som helst.

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

När du har en följande gren inställd kan du referera dess upströmsgren genom kortkommandona @{upstream} eller @{u}. Så om du är på grenen master och den följer origin/master kan du göra något i stil med git merge @{u} istället för git merge origin/master om du vill.

Om du vill se vilka följande grenar du har inställda, kan du använda flaggan -vv till kommandot git branch. Detta kommer lista dina lokala grenar med mer information, inklusive vad varje gren följer och om din lokala gren ligger före, efter, eller bådadera.

$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  testing   5ea463a trying something new

Här kan du se att vår iss53-gren följer origin/iss53 och ligger “före” med två, vilket betyder att vi har två versioner lokalt som inte är publicerade på servern. Vi kan också se att vår master-gren följer origin/master och är uppdaterad. Vi kan även se att vår gren serverfix följer grenen server-fix-good på vår teamone-server och ligger före med tree och efter med en, vilket betyder att det finns en version på servern som vi inte har inkorporerat i vår lokala gren, och tre versioner lokalt som vi inte har publicerat. Slutligen kan vi se att vår gren testing inte följer någon fjärrgren.

Det är viktigt att notera att dessa siffror återspeglar hur det såg ut senast du hämnade information från varje server. Kommandot kontaktar inte servrarna, utan säger dig vad den kommer ihåg från senast du kontaktade dem. Om du vill vara fullständigt säker kring siffrorna, måste du kontakta alla fjärrförvar innan du kör detta. Du kan göra det såhär:

$ git fetch --all; git branch -vv

Uppdatera

Medan kommandot git fetch hämtar alla ändringar från servern som du ännu inte har, kommer det inte att modifiera din arbetskatalog alls. Den kommer bara hämta data och låter dig slå samman ändringarna själv. Dock finns kommandot git pull som i praktiken är git fetch direkt följt av git merge, i de flesta fall. Om du har en följande gren konfigurerad så som demonstrerades i föregående avsnitt, antingen genom att uttryckligen sätta den eller att den skapades åt dig av kommandona clone eller checkout, kommer git pull kontrollera vilket fjärrförvar och gren din aktuella gren följer, hämta från förvaret och sedan försöka slå samman de inkommande ändringarna med din lokala gren.

Ofta är det bättre att helt enkelt använda kommandona fetch och merge explicit eftersom magin hos git pull ofta kan vara förvirrande.

Ta bort Fjärrgrenar

Anta att du är klar med en fjärrgren — antag att du och dina kollegor är klara med en funktion och har slagit samman ändringarna in i ditt fjärrförvars master-gren (eller vilken gren din stabila kodbas finns i). Du kan ta bort en fjärrgren genom flaggan --delete till git push. Om du vill ta bort din serverfix-gren från servern kör du följande:

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

Vad detta gör i praktiken är att den tar pekaren från servern. Gitservern kommer generellt att behålla all data ett tag innan det körs en skräpsamlingsomgång, så om den togs bort oavsiktigen, är den ofta lätt att återskapa.

scroll-to-top