-
1. Kom igång
- 1.1 Om versionshantering
- 1.2 En kort historik om Git
- 1.3 Vad är Git?
- 1.4 Kommandoraden
- 1.5 Installera Git
- 1.6 Första gången med Git
- 1.7 Få hjälp
- 1.8 Sammanfattning
-
2. Grunderna i Git
- 2.1 Att få tag i ett Git‑kodförråd
- 2.2 Spara ändringar i kodförrådet
- 2.3 Visa incheckningshistoriken
- 2.4 Ångra saker
- 2.5 Arbeta med fjärrkodförråd
- 2.6 Att tagga
- 2.7 Git-alias
- 2.8 Sammanfattning
-
3. Git-grenar
- 3.1 Grenar i korthet
- 3.2 Grundläggande gren- och sammanfogningsarbete
- 3.3 Grenhantering
- 3.4 Arbetsflöden med grenar
- 3.5 Fjärrgrenar
- 3.6 Ombasering
- 3.7 Sammanfattning
-
4. Git på servern
- 4.1 Protokollen
- 4.2 Konfigurera Git på en server
- 4.3 Generera din publika SSH-nyckel
- 4.4 Konfigurera servern
- 4.5 Git-demon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Tredjepartsalternativ
- 4.10 Sammanfattning
-
5. Distribuerat Git
-
6. GitHub
-
7. Git-verktyg
- 7.1 Revisionsurval
- 7.2 Interaktiv köläggning
- 7.3 Lägga undan och städa
- 7.4 Signera ditt arbete
- 7.5 Sökning
- 7.6 Skriva om historik
- 7.7 Nollställning förklarad
- 7.8 Avancerad sammanslagning
- 7.9 Rerere
- 7.10 Felsöka med Git
- 7.11 Undermoduler
- 7.12 Bunta
- 7.13 Ersätt
- 7.14 Lagring av inloggningsuppgifter
- 7.15 Sammanfattning
-
8. Anpassa Git
- 8.1 Git‑konfiguration
- 8.2 Git‑attribut
- 8.3 Git‑krokar
- 8.4 Ett exempel på Git‑upprätthållen policy
- 8.5 Sammanfattning
-
9. Git och andra system
- 9.1 Git som klient
- 9.2 Migrera till Git
- 9.3 Sammanfattning
-
10. Git bakom kulisserna
- 10.1 Lågnivådel och användardel
- 10.2 Git-objekt
- 10.3 Git-referenser
- 10.4 Packfiler
- 10.5 Refspecen
- 10.6 Överföringsprotokoll
- 10.7 Underhåll och dataåterställning
- 10.8 Miljövariabler
- 10.9 Sammanfattning
-
A1. Bilaga A: Git i andra miljöer
- A1.1 Grafiska gränssnitt
- A1.2 Git i Visual Studio
- A1.3 Git i Visual Studio Code
- A1.4 Git i IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git i Sublime Text
- A1.6 Git i Bash
- A1.7 Git i Zsh
- A1.8 Git i PowerShell
- A1.9 Sammanfattning
-
A2. Bilaga B: Bädda in Git i dina applikationer
- A2.1 Git på kommandoraden
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Bilaga C: Git-kommandon
- A3.1 Uppstart och konfiguration
- A3.2 Skaffa och skapa projekt
- A3.3 Grundläggande ögonblicksbilder
- A3.4 Grening och sammanslagning
- A3.5 Dela och uppdatera projekt
- A3.6 Inspektion och jämförelse
- A3.7 Felsökning
- A3.8 Patchning
- A3.9 E‑post
- A3.10 Externa system
- A3.11 Administration
- A3.12 Lågnivåkommandon
3.1 Git-grenar - Grenar i korthet
Nästan alla versionshanteringssystem har någon form av stöd för grenar. Att arbeta med grenar innebär att du lämnar huvudlinjen för utveckling och fortsätter att arbeta utan att störa den. I många VCS-verktyg är detta en ganska dyr process som ofta kräver att du skapar en ny kopia av källkodskatalogen, vilket kan ta lång tid för stora projekt.
En del kallar Gits grenmodell för dess "unika signum", och den gör verkligen att Git sticker ut i VCS-världen. Vad är det som är så speciellt? Gits sätt att hantera grenar på är extremt lättviktigt, vilket gör att grenåtgärder går nästan omedelbart, och att byta fram och tillbaka mellan grenar ofta går snabbt. Till skillnad från många andra VCS:er uppmuntrar Git arbetsflöden där man ofta skapar grenar och slår ihop dem, till och med flera gånger om dagen. Att förstå och behärska den här funktionen ger dig ett kraftfullt och unikt verktyg och kan helt förändra hur du utvecklar.
Grenar i korthet
För att verkligen förstå hur Git hanterar grenar behöver vi ta ett steg tillbaka och titta på hur Git lagrar data.
Som du kanske minns från Vad är Git? lagrar Git inte data som en serie ändringar eller ändringsmängder, utan som en serie ögonblicksbilder.
När du gör en incheckning sparar Git ett incheckningsobjekt som innehåller en pekare till ögonblicksbilden av innehållet du köade. Objektet innehåller också författarens namn och e-postadress, meddelandet du skrev och pekare till de incheckningar som kom direkt före (dess föräldrar): inga föräldrar för den första incheckningen, en förälder för en vanlig incheckning och flera föräldrar för en incheckning som är resultatet av en sammanslagning av två eller fler grenar.
För att visualisera detta kan vi anta att du har en katalog med tre filer, att du köar dem och gör en incheckning. När du köar filerna beräknas en kontrollsumma för varje fil (SHA-1-hashen som nämndes i Vad är Git?), Git lagrar filversionen i kodförrådet (Git kallar dem blobbar) och lägger kontrollsumman i köytan:
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
När du skapar incheckningen med git commit beräknar Git en kontrollsumma för varje underkatalog (i det här fallet bara projektets rotkatalog) och lagrar dem som ett trädobjekt i kodförrådet.
Git skapar sedan ett incheckningsobjekt med metadata och en pekare till projektets rotträd så att ögonblicksbilden kan återskapas vid behov.
Ditt Git-kodförråd innehåller nu fem objekt: tre blobbar (var och en representerar innehållet i en av de tre filerna), ett träd som listar katalogens innehåll och pekar ut vilka filnamn som motsvarar vilka blobbar, och en incheckning med pekare till rotträdet och dess metadata.
Om du gör ändringar och checkar in igen sparar nästa incheckning en pekare till den som kom direkt före.
En gren i Git är helt enkelt en lätt flyttbar pekare till en av dessa incheckningar.
Standardgrenens namn i Git är master.
När du börjar göra incheckningar får du en master-gren som pekar på den senaste incheckningen.
Varje gång du checkar in flyttas master-pekaren framåt automatiskt.
|
Notera
|
“master”-grenen i Git är inte något särskilt.
Den är precis som vilken annan gren som helst.
Det enda skälet till att nästan alla kodförråd har den är att |
Skapa en ny gren
Vad händer när du skapar en ny gren?
Du skapar helt enkelt en ny pekare som du kan flytta runt.
Säg att du vill skapa en gren som heter testing.
Det gör du med git branch:
$ git branch testing
Det här skapar en ny pekare till samma incheckning som du står på just nu.
Hur vet Git vilken gren du står på?
Den håller en särskild pekare som heter HEAD.
Observera att detta skiljer sig från HEAD i andra VCS:er som Subversion eller CVS.
I Git är det en pekare till den lokala gren du för närvarande står på.
I det här fallet är du fortfarande på master.
git branch skapade bara en ny gren – den bytte inte till den.
Du kan lätt se detta genom att köra git log med flaggan --decorate, som visar var grenpekare ligger.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
Du ser att master och testing pekar på samma incheckning f30ab.
Byta gren
För att byta till en befintlig gren kör du git checkout.
Låt oss byta till den nya grenen testing:
$ git checkout testing
Det flyttar HEAD så att den pekar på testing.
Vad betyder det? Låt oss göra en incheckning:
$ vim test.rb
$ git commit -a -m 'Make a change'
Det intressanta är att din testing-gren har flyttat fram, medan master fortfarande pekar på incheckningen du stod på när du bytte gren.
Låt oss byta tillbaka till master:
$ git checkout master
|
Notera
|
git log visar inte alltid alla grenarOm du kör Grenen finns kvar; Git visar bara den historik den tror att du är intresserad av.
Som standard visar För att visa historiken för den gren du vill se behöver du ange den explicit: |
Kommandot gjorde två saker.
Det flyttade HEAD-pekaren tillbaka till master och återställde filerna i arbetskatalogen till ögonblicksbilden som master pekar på.
Det betyder också att ändringar du gör från och med nu kommer att divergera från en äldre version av projektet.
I praktiken spolar det tillbaka arbetet du gjorde i testing så att du kan gå i en annan riktning.
|
Notera
|
Byta gren ändrar filer i arbetskatalogen
Det är viktigt att veta att när du byter gren i Git ändras filerna i arbetskatalogen. Om du byter till en äldre gren återställs arbetskatalogen till hur den såg ut när du senast checkade in på den grenen. Om Git inte kan göra detta utan konflikter får du inte byta gren. |
Låt oss göra några ändringar och checka in igen:
$ vim test.rb
$ git commit -a -m 'Make other changes'
Nu har projektets historik divergerat (se Divergerad historik).
Du skapade och bytte till en gren, gjorde arbete där, och bytte sedan tillbaka till huvudgrenen och gjorde annat arbete.
Båda ändringarna är isolerade i separata grenar: du kan byta fram och tillbaka mellan dem och sammanfoga dem när du är redo.
Och allt detta gjorde du med branch, checkout och commit.
Du kan också se detta med git log.
Om du kör git log --oneline --decorate --graph --all skrivs hela historiken ut, samt var grenpekare finns och hur historiken har divergerat.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Make other changes
| * 87ab2 (testing) Make a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commit of my project
Eftersom en gren i Git i grunden är en fil som innehåller den 40 tecken långa SHA-1-kontrollsumman för incheckningen den pekar på, är grenar billiga att skapa och ta bort. Att skapa en ny gren är i praktiken lika enkelt som att skriva 41 byte till en fil (40 tecken plus radbrytning).
Detta står i skarp kontrast till äldre VCS-verktyg där grenar innebär att hela projektets filer kopieras till en ny katalog. Det kan ta sekunder eller minuter beroende på projektets storlek, medan Git alltid är omedelbart. Eftersom vi lagrar föräldrarna till varje incheckning hittar Git automatiskt en lämplig bas för sammanslagningar, vilket gör dem enkla att genomföra. Detta uppmuntrar utvecklare att skapa och använda grenar ofta.
Låt oss se varför.
|
Notera
|
Skapa och byta gren samtidigt
Det är vanligt att vilja skapa en ny gren och byta till den direkt.
Det kan göras i ett steg med |