-
1. Kom igÄng
- 1.1 Om versionshantering
- 1.2 En kort historik av Git
- 1.3 Vad Àr Git?
- 1.4 Kommandoraden
- 1.5 Installera Git
- 1.6 AnvÀnda Git för första gÄngen
- 1.7 FÄ hjÀlp
- 1.8 Sammanfattning
-
2. Grunder i Git
- 2.1 Skaffa ett Git-förvar
- 2.2 Spara Àndringar till förvaret
- 2.3 Visa historiken
- 2.4 Ă ngra saker
- 2.5 Jobba med fjÀrrförvar
- 2.6 Taggning
- 2.7 Git alias
- 2.8 Sammanfattning
-
3. Git förgreningar
-
4. Git pÄ servern
- 4.1 Protokollen
- 4.2 Skaffa Git pÄ en server
- 4.3 Generera din publika SSH-nyckel
- 4.4 Konvigurera servern
- 4.5 Git Daemonen
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Alternativ tillhandahÄllna av tredje part
- 4.10 Sammanfattning
-
5. Distribuerade Git
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Summary
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Git Internals
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Summary
-
A1. Bilaga A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in PowerShell
- A1.7 Summary
-
A2. Bilaga B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Bilaga C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
5.2 Distribuerade Git - Medverka i ett projekt
Medverka i ett projekt
Det svĂ„ra med att beskriva hur du gör för att bidra till ett projekt Ă€r att medverkan kan ske pĂ„ mĂ€ngder av olika sĂ€tt. Tack vare Gits flexibelt skiljer sig anvĂ€ndningen Ă„t, vilket gör det nĂ€st intill omöjligt att sĂ€ga hur du borde göraâââvarje projekt arbetar pĂ„ sitt sĂ€tt. Faktorer som pĂ„verkar hur ett projekt Ă€r organiserat Ă€r antalet aktivt involverade, överenskomna arbetsprocesser och fördelningen av behörigheter för att checka in kod Det finns dock nĂ„gra generella riktlinjer som kan hjĂ€lpa dig att komma igĂ„ng.
För det förstaâââhur mĂ„nga involverade bidrar aktivt med kĂ€llkod och hur ofta? I mindre pojekt Ă€r det vanligt att ett par, tre utvecklare gör nĂ„gra fĂ„ incheckningar om dagen, kanske Ă€nnu fĂ€rre om projektet Ă€r vilande. I större projekt, eller företag för den delen, kan hundratals utvecklare arbeta aktivt med kodbasen och bidra med tusentals incheckningar varje dag.
Det Ă€r viktigt att kĂ€nna till ungefĂ€r hur mĂ„nga som arbetar aktivt i kodbasen. Ju fler utvecklare, ju mer problem kan du stöta pĂ„ för att fĂ„ din kod att lĂ€ggas till och integreras sömlöst. Under tiden du arbetar med dina Ă€ndringar, eller vĂ€ntar pĂ„ att fĂ„ dem godkĂ€nda, kan ny kod göra dem ofunktionellaâââeller rentav inaktuella. Hur kan du dĂ„ göra för att din egen kodbas ska hĂ„llas uppdaterad och dina incheckningar aktuella?
För det andra, hur ser projektets beslutade arbetsprocess ut? Ăr det en centraliserad process, sĂ„ att varje utvecklare har samma skrivrĂ€ttigheter till koden pĂ„ huvudgrenen? Har projektet en förvaltare eller integrationsansvarig som granskar alla patcher? Ska samtliga patcher granskas och godkĂ€nnas av en annan utvecklare? Kommer du att vara involverad i den processen? Eller finns det ett kvalitetsledningssystem med testare pĂ„ plats som du behöver skicka dina Ă€ndringar till först?
Till sist spelar behörigheter för incheckningar in. Din medverkan kommer att skilja sig mycket Ät beroende pÄ om du har skrivrÀttigheter till kodbasen eller inte. Om du inte har det, hur ser processen ut för att granska och godkÀnna bidrag? Finns det ens en sÄdan process? Hur mÄnga Àndringar ska skickas med i taget? Hur ofta?
Alla dessa frÄgor pÄverkar hur du bÀst bidrar till ett projekt, liksom vilka arbetssÀtt du sjÀlv föredrar eller har tillgÄng till. Vi kommer att gÄ igenom tillvÀgagÄngssÀtten ur olika aspekter i en serie anvÀndarfall, frÄn enkla till mer komplexa. Du borde kÀnna igen det specifika arbetssÀtt du förvÀntas anvÀnda i dessa exempel.
Riktlinjer för incheckningar
Innan vi gÄr in pÄ anvÀndarfallen kommer en kort kommentar om incheckningsmeddelanden.
Att ha bra riktlinjer för incheckningar, och att hÄlla sig till dem, gör det betydligt enklare att anvÀnda Git tillsammans med andra.
I Git-projektet finns ett dokument med flera bra tips pÄ saker att tÀnka pÄ för att göra incheckningar till en patch.
Du hittar det i filen Documentation/SubmittingPatches
i Gits kÀllkod.
Först av allt, sÄ bör dina bidrag inte ha nÄgra felaktiga mellanslag.
Git har ett lĂ€tt sĂ€tt att kontrollera detâââinnan du gör en incheckning, kör kommandot git diff --check
.
Det ger dig en lista över möjliga mellanslag som kan vara felaktiga.
git diff --check
.Kör kommandot innan en incheckning för att snabbt kontrollera om du Àr pÄ vÀg att checka in mellanslag som kan irritera andra utvecklare.
För det andra, försök att göra varje incheckning till logiskt separat enhet.
Om du kan, försök att hÄlla dina Àndringar lÀttsmÀlta - koda inte en hel helg pÄ fem olika uppgifter, för att sen skicka dem som en enda gigantisk incheckning pÄ mÄndan.
Ăven om du inte har checkat in pĂ„ en hel helg, anvĂ€nd köomrĂ„det för att dela upp ditt arbete i minst fem incheckningar pĂ„ mĂ„ndagen, med ett tydligt meddelande per incheckning.
Om nÄgra av Àndringarna Àr i samma fil, försök att anvÀnda git add --patch
för att delvis köa filer (lÀs mer i Interactive Staging).
Projektets ögonblicksbild lÀngst ut pÄ grenen kommer att se likadan ut oavsett om du gör en incheckning eller fem, sÄ lÀnge som alla Àndringar lÀggs till förr eller senare.
Försök dÀrför att göra det sÄ enkelt som möjligt för dina kollegor nÀr de ska granska dina Àndringar.
Med det tillvĂ€gagĂ„ngssĂ€ttet blir det ocksĂ„ enklare att dra ut eller Ă„terstĂ€lla nĂ„gon av Ă€ndringarna i efterhand, om det skulle behövas. I avsnittet Rewriting History finns en mĂ€ngd anvĂ€ndbara tips för att skriva om Git-historiken och interaktivt köa filerâââanvĂ€nd dessa verktyg för att fĂ„ en logisk och förstĂ„elig historik innan du skickar arbetet vidare till nĂ„gon annan.
Slutligen behövs en struktur för incheckningsmeddelandet. Med vanan att alltid skriva bra meddelanden blir anvĂ€ndningen av - och samarbetet i - Git betydligt enklare. Tumregeln Ă€r att dina meddelanden ska börja med en mening pĂ„ max 50 tecken som sammanfattar Ă€ndringen, följt av en blank rad och en mer detaljerad beskrivning. Git-projektet gör gĂ€llande att beskrivningen bör inkludera anledningen till Ă€ndringen och en jĂ€mförelse med tidigare beteendeâââdet Ă€r en bra riktlinje att följa. Det Ă€r ocksĂ„ bra att skriva i imperativ form. Med andra ord, ge order. IstĂ€llet för âJag lade till test förâ eller âLĂ€gger till test för,â skriv âLĂ€gg till test förâ HĂ€r Ă€r en mall ursprungligen skriven av Tim Pope:
Kort (50 tecken max), befallande sammanfattning
Mer detaljerad text, om nödvÀndigt. HÄll den till cirka 72 tecken eller
sÄ. Första raden kan ofta jÀmföras med Àmnet pÄ ett mejl och resten av
innehÄllet med brödtexten. Den tomma raden mellan titel och brödtext
Àr absolut nödvÀndig (om du inte utelÀmnar innehÄllet helt); verktyg som
ombasera kan bli förvirrade om de skrivs ihop.
Ytterligare paragrafer skrivs efter en tom rad.
- Punktlistor Àr ocksÄ ok
- Efter en tom rad och ett inledande mellanslag anvÀnds ofta
bindestreck eller asterisk som punkt, men det finns olika
konventioner.
Om alla dina incheckningsmeddelande följer den hÀr mallen kommer det att bli lÀttare, bÄde för dig och dem du samarbetar med.
Git-projektet har vĂ€lformatterade incheckningsmeddelandenâââkör git log --no-merges
dÀr för att fÄ inspiration till hur en vÀl formatterad incheckningshistorik kan se ut.
Notera
|
Gör som vi sÀger och inte som vi gör
För att vara helt Àrliga, mÄnga av exemplen i den hÀr boken har inte sÄ vÀrst vÀlformatterade incheckningsmeddelanden; vi anvÀnder ofta Som sagt, gör som vi sÀger, inte som vi gör. |
Privat, litet team
Det enklaste arbetssĂ€ttet du sannolikt kommer stöta pĂ„ Ă€r ett privat projekt med en eller tvĂ„ involverade utvecklare. I den hĂ€r kontexten betyder âprivatâ sluten kĂ€llkodâââden Ă€r inte tillgĂ€nglig för nĂ„gon utomstĂ„ende. Du och de andra utvecklarna har skrivbehörigheter till arkivet.
I den hÀr uppsÀttningen liknar arbetssÀttet det som du kanske stöter pÄ nÀr du anvÀnder Subversion eller nÄgot annat centraliserat versionshanteringssystem.
Du behÄller fördelarna med saker som att kunna checka in offline, en betydligt enklare förgrening och sammanslagning, men arbetsprocesserna Àr mycket lika; den största skillnaden Àr att sammanslagningar sker i klienten istÀllet för frÄn servern vid incheckning.
LÄt oss ta ett exempel pÄ hur det kan gÄ till nÀr tvÄ utvecklare börjar samarbeta i ett gemensamt arkiv.
Den första utvecklaren, John, klonar arkivet och gör en Àndring som checkas in lokalt.
(Informationsmeddelandena har ersatts med ...
för att korta ner exemplen.)
# Johns dator
$ git clone john@githost:simplegit.git
Klonar till 'simplegit'...
...
$ cd simplegit/
$ vim lib/simplegit.rb
$ git commit -am 'remove invalid default value'
[master 738ee87] remove invalid default value
1 fil Àndrad, 1 tillagd(+), 1 borttagen(-)
Jessika, den andra utvecklaren, gör samma sakâââklonar arkivet och checkar in en Ă€ndring:
# Jessikas dator
$ git clone jessika@githost:simplegit.git
Klonar till 'simplegit'...
...
$ cd simplegit/
$ vim TODO
$ git commit -am 'add reset task'
[master fbff5bc] add reset task
1 fil Àndrad, 1 tillagd(+), 0 borttagen(-)
Sen skickar Jessika sina Àndringar till servern, vilket funkar bra:
# Jessikas dator
$ git push origin master
...
Till jessika@githost:simplegit.git
1edee6b..fbff5bc master -> master
Den sista raden i outputen Àr ett anvÀndbart meddelande frÄn sÀndningen.
Formateringen Àr <gammalref>..<nyref> frÄnref -> tillref
, dÀr gammalref
betyder tidigare referens, nyref
Àr den nya referensen, frÄnref
Àr namnet pÄ den lokala referens som Àndringen kommer frÄn och tillref
Àr fjÀrreferensen som har blivit uppdaterad.
Du kommer att se liknande output i exemplen nedanför, en grundförstÄelse kommer göra det lÀttare att förstÄ innebörden av arkivens varierade stadier.
Mer detaljer finns i git-push dokumentation.
För att fortsĂ€tta med det hĂ€r exemepletâââkort efterĂ„t gör John nĂ„gra Ă€ndringar, checkar in dem lokalt och försöker skicka dem till samma server som Jessika:
# Johns dator
$ git push origin master
Till john@githost:simplegit.git
! [refuserad] master -> master (ej snabbspolad)
error: misslyckades sÀnda vissa referenser till 'john@githost:simplegit.git'
I det hÀr fallet kan John inte skicka sina incheckningar pÄ grund av Jessikas tidigare incheckning av sina Àndringar. Det hÀr Àr sÀrskilt viktigt att förstÄ om du tidigare har anvÀnt Subversion, för du kommer att mÀrka att de tvÄ utvecklarna inte Àndrade i samma fil. Subversion gör en sammanslagning automatiskt pÄ servern om olika filer har Àndrats, men med Git behöver du sjÀlv först sammanfoga incheckningarna lokalt. Med andra ord, John mÄste först hÀmta Jessikas Àndringar i fjÀrrarkivet och sammanfoga dem i sitt lokala arkiv innan han kommer att fÄ tillÄtelse att skicka Àndringarna.
Som ett första steg hÀmtar John Jessikas Àndringar(Jessikas Àndringar hÀmtas bara, de slÄs inte ihop med hans filer):
$ git fetch origin
...
FrÄn john@githost:simplegit
+ 049d078...fbff5bc master -> origin/master
Johns arkiv ser nu ut ungefÀr sÄ hÀr:
Nu kan John slÄ ihop de Àndringar han hÀmtade av Jessika med filerna pÄ sin dator:
$ git merge origin/master
Sammanslagning gjord med metoden 'recursive'.
TODO | 1 +
1 fil Àndrad, 1 tillÀgg(+), 0 borttagna(-)
Om den lokala sammanslagningen gÄr smidigt kommer Johns uppdaterade historik se ut ungefÀr sÄ hÀr:
origin/master
.Nu kanske John vill testa den nya koden för att vara helt sÀker pÄ att ingen av Jessikas Àndringar pÄverkat hans, och om allt gÄr bra kan han slutligen skicka sina sammanslagna Àndringar till servern:
$ git push origin master
...
Till john@githost:simplegit.git
fbff5bc..72bbc59 master -> master
Till sist ser Johns incheckningshistorik ut sÄ hÀr:
origin
.Under tiden har Jessika skapat en ny gren med namnet issue54
, och gjort tre incheckningar till den nya grenen.
Hon har inte hÀmtat Johns Àndringar Àn, sÄ hennes incheckningshistorik ser ut sÄ hÀr:
Plötsligt fÄr Jessika veta att John har skickat nya Àndringar till servern och vill kika pÄ dem, sÄ hon hÀmtar alla Àndringar frÄn servern med kommandot:
# Jessikas dator
$ git fetch origin
...
FrÄn jessika@githost:simplegit
fbff5bc..72bbc59 master -> origin/master
Nu hÀmtas Johns incheckade Àndringar ner. Jessikas historik kommer att se ut sÄ hÀr:
Jessika tycker att Àndringarna pÄ hennes nya gren Àr klara, men hon vill veta vilka delar av Johns arbete som hon mÄste slÄ ihop med sitt arbete sÄ att hon kan skicka dem.
Hon kör git log
för att fÄ reda pÄ det:
$ git log --no-merges issue54..origin/master
commit 738ee872852dfaa9d6634e0dea7a324040193016
Författare: John Smith <jsmith@example.com>
Datum: Fri May 29 16:01:27 2009 -0700
ta bort ogiltigt standardvÀrde
Syntaxen issue54..origin/master
anvÀnds för att filtrera loggar.
Git ombeds att bara visa de incheckningar i den senare referensen (origin/master
i det hÀr fallet) som inte finns pÄ den första referensen (hÀr issue54
).
Vi kommer att gÄ igenom syntaxen i detalj i avsnitt Commit Ranges.
FrÄn ovanstÄende output kan vi utlÀsa att det bara Àr en enda av Johns incheckningar som Jessika inte har slagit ihop med sitt arbete lokalt.
Om hon slÄr ihop sina Àndringar med Àndringarna pÄ origin/master
Àr det bara den incheckningen som kommer att pÄverka hennes lokala arkiv.
Nu kan Jessika slÄ ihop sin lokala funktionsgren med sin huvudgren, slÄ samman Johns Àndringar (origin/master
) med sin master
gren och sen skicka sitt arbete till servern igen. .
NÀr alla Àndringar pÄ grenen issue54
har checkats in, börjar Jessika med att byta tillbaka till sin huvudgren:
$ git checkout master
Byter till gren 'master'
Din gren ligger efter 'origin/master' med 2 incheckningar, kan snabbspolas.
Jessika kan slÄ ihop antingen origin/master
eller issue54
förstâââde Ă€r bĂ„da uppströms, sĂ„ ordningen spelar ingen roll.
Den slutliga ögonblicksbilden blir identisk oavsett vilken ordning hon vÀljer, det Àr bara historiken som kommer att skilja sig Ät.
Hon bestÀmmer sig för att slÄ ihop grenen issue54
först:
$ git merge issue54
Uppdaterar fbff5bc..4af4298
Snabbspolar
README | 1 +
lib/simplegit.rb | 6 +++++-
2 filer Àndrade, 6 tillÀgg(+), 1 borttagen(-)
Inget ovÀntat hÀnder, som du kan se var det en sammanslagning som kunde snabbspolas framÄt.
Jessika kan nu avsluta sammanslagningarna lokalt genom att slÄ ihop de Àndringar hon hÀmtade tidigare frÄn John och som Àr vÀntar kvar pÄ origin/master
:
$ git merge origin/master
SlÄr ihop lib/simplegit.rb automatiskt
Sammanslagning gjorde med metoden 'recursive'.
lib/simplegit.rb | 2 +-
1 fil Àndrad, 1 tillÀgg(+), 1 borttagning(-)
Allt slogs ihop smidigt, Jessikas historik ser nu ut sÄ hÀr:
FjÀrreferensen origin/master
kan nÄs frÄn Jessikas huvudgren, sÄ hon borde kunna skicka sina Àndringar utan problem (förutsatt att John inte har skickat fler Àndringar under tiden):
$ git push origin master
...
Till jessika@githost:simplegit.git
72bbc59..8059c15 master -> master
BÄda utvecklarna har nu checkat in sina versioner av filerna nÄgra gÄnger och fÄtt in varandras Àndringar i sina lokala kodbaser.
Det hÀr Àr en av de enklaste arbetsprocesserna.
Du arbetar ett tag (vanligtvis i en funktionsgren), och slÄr ihop arbetet i huvudgrenen nÀr det Àr klart.
NÀr du vill dela ditt arbete, hÀmtar du och slÄr ihop din huvudgren med origin/master
och skickar tillbaka din huvudgren till servern.
Den generella arbetsprocessen ser ut ungefÀr sÄ hÀr:
Privat större team
NÀsta exempel Àr medverkan i ett större, privat team. HÀr tittar vi nÀrmre pÄ hur arbetsprocessen kan se ut nÀr mindre team samarbetar pÄ features, som dÀrefter slÄs ihop av andra team.
SĂ€g att John och Jessika arbetar tillsammans pĂ„ en funktion (vi kallar den âfeatureAâ). Samtidigt samarbetar Jessika och en tredje utecklare, Josie, pĂ„ en annan, (âfeatureBâ). I det hĂ€r fallet anvĂ€nder sig företaget av en slags integrationsstyrt arbetsprocess, dĂ€r arbetet av ett enskilt team slĂ„s samman med huvudgrenen av specifika ingengörer. Arkivets huvudgren kan endast uppdateras av dessa. Allt arbete sker pĂ„ förgreningar som sedan slĂ„s ihop av andra i ett senare skede.
Vi följer med Jessika medan hon arbetar pÄ sina features parallellt, med tvÄ olika utvecklare, i en sÄdan hÀr miljö.
Vi utgÄr ifrÄn att hon redan har klonat arkivet, nÀr hon bestÀmmer sig för att börja med featureA
.
Hon skapar en ny gren för funktionen och jobbar lite pÄ den:
# Jessikas dator
$ git checkout -b featureA
Bytte till en ny gren 'featureA'
$ vim lib/simplegit.rb
$ git commit -am 'add limit to log function'
[featureA 3300904] add limit to log function
1 fil Àndrades, 1 tillÀgg(+), 1 borttagning(-)
I det hÀr lÀget behöver hon dela sitt jobb med John, sÄ hon skickar sin featureA
-gren med incheckningarna till servern.
Jessika har inte behörighet att slÄ ihop sina Àndringar med huvuudgrenen, sÄ hon behöver skicka dem till en annan gren för att kunna samarbeta med John:
$ git push -u origin featureA
...
Till jessica@githost:simplegit.git
* [new branch] featureA -> featureA
Jessika mejlar John för att berÀtta att hon har skickat Àndringar till en gren med namnet featureA
och att han kan kolla pÄ dem nu.
Medan hon vÀntar pÄ feedback frÄn John bestÀmmer hon sig för att börja jobba pÄ featureB
tillsammans med Josie.
Hon börjar med att skapa en ny gren frÄn serverns huvudgren:
# Jessikas dator
$ git fetch origin
$ git checkout -b featureB origin/master
Bytte till en ny gren 'featureB'
Nu gör Jessika ett par inckeckningar pÄ `featureB`grenen:
`[source,console]
$ vim lib/simplegit.rb $ git commit -am 'made the ls-tree function recursive' [featureB e5b0fdc] made the ls-tree function recursive 1 fil Àndrad, 1 tillÀgg(+), 1 borttagen(-) $ vim lib/simplegit.rb $ git commit -am 'add ls-files' [featureB 8512791] add ls-files 1 fil Àndrad, 5 tillÀgg(+), 0 borttagna(-)
Jessikas arkiv ser nu ut sÄ hÀr:
Hon Àr redo att skicka sina Àndringar nÀr hon fÄr ett mejl frÄn Josie som skriver att en gren hon har börjat pÄ för featureB
redan har skickats till servern som grenen featureBee
.
Jessika behöver slÄ ihop de Àndringarna med sina innan hon kan skicka sitt arbete till den gren Josie skickat till servern.
Jessika hÀmtar först Josies Àndringar med git fetch
:
$ git fetch origin
...
FrÄn jessika@githost:simplegit
* [new branch] featureBee -> origin/featureBee
Om vi antar att Jessika fortfarande Àr utcheckad pÄ grenen featureB
, sÄ kan hon nu slÄ Josies arbete med den grenen med kommandot git merge
:
$ git merge origin/featureBee
SlÄr ihop lib/simplegit.rb automatiskt.
Sammanslagning gjord med metoden 'recursive'.
lib/simplegit.rb | 6 ++++++
1 fil Àndrad, 6 tillÀgg(+), 0 borttagna(-)
Sammanslagning gjord med metoden 'recursive'.
lib/simplegit.rb | 4 ++++
1 fil Àndrad, 4 tillÀgg(+), 0 borttagna(-)
I det hÀr lÀget vill Jessika skicka allt som finns pÄ featureB
tillbaka till servern, men utan att skicka upp sin egna gren.
Eftersom Josie redan har pÄbörjat en uppströms featureBee
-gren sÄ vill Jessika skicka till den grenen.
Det gör hon med:
$ git push -u origin featureB:featureBee
...
Till jessick@githost:simplegit.git
fba9af8..cd685d1 featureB -> featureBee
Detta kallas för en referensspecifikation.
Se The Refspec för mer information om Gits referensspecifikationer och hur du kan anvÀnda dem.
LÀgg ocksÄ mÀrke till -u
-flaggan; det Àr en kortversion av kommandot --set-upstream
, som sparar en referens till den fjÀrrgren som din lokala gren spÄrar.
Plötsligt fÄr Jessika ett mail frÄn John, som berÀttar att han har skickat nÄgra Àndringar till featureA
-grenen och ber henne kolla pÄ dem.
Ă
terigen kör Jessika ett enkelt git fetch
för att hÀmta allt nytt innehÄll frÄn servern, inklusive Johns senaste arbete:
$ git fetch origin
...
FrÄn jessika@githost:simplegit
3300904..aad881d featureA -> origin/featureA
Jessika kan nu lÀsa loggarna med Johns senaste Àndringar genom att jÀmföra innehÄllet som hÀmtades för featureA
med den lokala kopian av samma gren:
$ git log featureA..origin/featureA
commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
Författare: John Smith <jsmith@example.com>
Datum: Fri May 29 19:57:33 2009 -0700
changed log output to 30 from 25
Om Jessika gillar det hon ser kan hon fusionera Johns nya arbete till sin lokala featureA
gren med:
$ git checkout featureA
Bytte till gren 'featureA'
$ git merge origin/featureA
Uppdaterar 3300904..aad881d
Snabbspolar
lib/simplegit.rb | 10 +++++++++-
1 fil Àndrad, 9 tillÀgg(+), 1 borttagen(-)
Till sist kanske Jessika vill göra nÄgra mindre Àndringar i det sammanslagna innehÄllet.
Hon har full frihet att göra sina Àndringar, checka in dem till sin lokala gren featureA
och skicka tillbaka slutresultatet till servern.
$ git commit -am 'small tweak'
[featureA 774b3ed] small tweak
1 fil Àndrad, 1 tillÀgg(+), 1 borttagen(-)
$ git push
...
Till jessika@githost:simplegit.git
3300904..774b3ed featureA -> featureA
Jessikas incheckningshistorik kommer nu att se ut ungefÀr sÄ hÀr:
Vid nÄgon tidpunkt kommer Jessika, John och Josie att behöva informera dem som ansvarar för huvudgrenen att featureA
och featureB
Àr redo att slÄs ihop med den.
NÀr sammanslagningen med huvudgrenen dÄ Àr klar, kommer en hÀmtning av den att fÄ med den nya versionsincheckningen.
Historiken kommer dÄ att se ut sÄ hÀr:
MÄnga byter till Git pÄ grund av möjligheten för flera team att arbeta parallellt och kombinera sina förgreningar sent i processen. Möjligheten att mindre grupperingar inom ett team kan samarbeta via fjÀrrgrenar utan att nödvÀndigtvis behöva involvera hela teamet Àr utan tvekan en av Gits stora fördelar. Arbetsprocessen som precis har beskrivts ser ut ungefÀr sÄhÀr:
Ăppet, litet projekt
Att bidra till öppna projekt Àr ofta lite annorlunda Àn privata. Eftersom du vanligtvis inte har behörighet att göra Àndringar direkt i projektet behöver förvaltarna fÄ ditt arbete pÄ nÄgot annat sÀtt. I det första exemplet ska vi titta pÄ hur man förgrenar ett arkiv pÄ de hostingsajter för Git som tillÄter det. MÄnga hostingsajter har stöd för förgreningar, (sÄsom GitHub, BitBucket, repo.or.cz med flera) och mÄnga projektansvariga förvÀntar sig att andra medverkar pÄ det sÀttet. Det andra exemplet beskriver arbetsprocessen i de projekt som istÀllet föredrar att acceptera patchade bidrag via mejl.
Det första du behöver göra Àr troligen att klona grundarkivet och skapa en funktionsgren för patcherna du planerar att bidra med Flödet ser helt enkelt ut sÄ hÀr:
$ git clone <url>
$ cd project
$ git checkout -b featureA
... arbeta ...
$ git commit
... arbeta ...
$ git commit
Notera
|
Du kanske kommer att vilja anvÀnda |
NÀr arbetet Àr klart och du Àr redo att dela det med förvaltarnas, gÄ till ursprungsarkivets projektsida och klicka pÄ knappen ``Fork`` för att skapa en kopia av projektet som du har full behörighet till.
DÀrefter lÀgger du till det nya repots URL som ett nytt fjÀrrarkiv för ditt lokala arkiv; i det hÀr exemplet kan vi kalla det för mingaffel
:
$ git remote add mingaffel <url>
Sedan behöver du skicka ditt arbete till det hÀr arkivet. Det Àr enklare att skicka den finessgren du arbetar pÄ till ditt kopierade arkiv Àn att fusionera det arbetet i din huvudgren och fusionera den. Om ditt arbete inte bli godkÀnt, eller om din incheckning inte blir cherry-pickad, sÄ slipper du spola tillbaka din huvudgren (lÀs mer om Gits cherry-pick i Arbetsflöden med ombasering och plocka russin ur kakan). Om de ansvariga Ä andra sidan slÄr ihop, ombaserar eller cherry-pickar din funktion, sÄ kommer du att fÄ tillbaka den genom att dra ner Àndringar frÄn deras repo ÀndÄ. Hur du Àn gör kan du skicka ditt arbete med:
$ git push -u mingaffel featureA
NÀr ditt arbete har skickats till din förgrening av arkivet behöver du meddela förvaltarna av originalprojektet att du har arbete som du skulle vilja att de slÄr samman.
Detta kallas ofta för en pull request och du behöver vanligtvis göra en sĂ„dan begĂ€ran antingen via websidaâââGitHub har sin egen ``Pull Request``-mekanism som vi kommer att gĂ„ igenom i GitHubâââeller sĂ„ kan du köra kommandot git request-pull
och mejla den efterföljande utdatan till de ansvariga.
Kommandot git request-pull
tar basgrenenen, det vill sÀga den gren du vill att din funktionsgren dras in i, och Git-arkivets URL som du vill att de accepterar kod ifrÄn, och sammanfattar alla Àndringar du begÀr ska tas in.
Om Jessika till exempel vill skicka en pull request till John, och hon har gjort tvÄ incheckningar pÄ funktionsgrenen som hon just har skickat, sÄ kan hon anvÀnda det sÄ hÀr:
$ git request-pull origin/master mingaffel
Följande Àndringar sen incheckning 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
Jessika Smith (1):
added a new function
Àr tillgÀngliga i git-arkivet pÄ:
git://githost/simplegit.git featureA
Jessika Smith (2):
add limit to log function
change log output to 30 from 25
lib/simplegit.rb | 10 +++++++++-
1 fil Àndrad, 9 tillÀgg(+), 1 borttagning(-)
Den hĂ€r utdatan kan skickas till de ansvarigaâââden beskriver frĂ„n vilken gren arbetet förgrenades, ger en sammanfattning av incheckningarna och varifrĂ„n den nya funktionen kan hĂ€mtas.
I ett projekt dÀr du inte Àr ansvarig Àr det oftast enklast att ha en huvudgren, t.ex master
, som alltid följer origin/master
och sen arbeta i funktionsgrenar som du enkelt kan radera om de inte godkÀnns.
Att isolera funktioner tll funktionsgrenar gör det ocksÄ lÀttare för dig att flytta ditt arbete om Ànden pÄ huvudarkivet har rört sig under tiden du arbetat sÄ att din version inte lÀngre kan sammanfogas pÄ ett smidigt sÀtt.
Om du till exempel vill skicka in en andra funktionsgren till projektet, fortsĂ€tt inte att arbeta pĂ„ den funktionsgren du nyss skickade uppâââbörja istĂ€llet om frĂ„n arkivets huvudgren:
$ git checkout -b featureB origin/master
... arbeta ...
$ git commit
$ git push mingaffel featureB
$ git request-pull origin/master myfork
... e-postbrevet genererar förfrÄgan att hÀmta till ansvarig ...
$ git fetch origin
Now, each of your topics is contained within a siloâââsimilar to a patch queueâââthat you can rewrite, rebase, and modify without the topics interfering or interdepending on each other, like so: Nu Ă€r bĂ„da dina funktioner i varsitt siloâââsom en kö för patcharâââsom du kan skriva om, ombasera och Ă€ndra utan att funktionerna pĂ„verkar eller blir beroende av varandra:
featureB
.Om vi sÀger att projektets ansvariga har dragit in ett gÀng andra patches innan de testar din första gren, sÄ kan den inte sammanfogas automatiskt.
I det hÀr fallet kan du försöka att ombasera den grenen sÄ att den hamnar lÀngst ut pÄ toppen av origin/master
, lösa eventuella konflikter och skicka in din version igen:
$ git checkout featureA
$ git rebase origin/master
$ git push -f mingaffel featureA
Det hÀr skriver om historiken enligt bilden nedan Versionshistorik efter avslutat arbete med featureA
..
featureA
.Eftersom du flyttade grenen behöver du ange -f
till ditt kommando för att kunna ersÀtta serverns featureA
-gren med en annan incheckning Àn den ursprungliga.
Ett alternativ vore att skicka det hÀr nya arbetet till en annnan gren pÄ servern (som kanske kan heta featureAv2
),
Vi tittar nÀrmre pÄ ytterligare ett alternativ: ansvariga har tittat Àndringarna i din andra gren och gillar dem mestadels, men de skulle vilja att du gjorde en justering.
Du anvÀnder möjligheten att flytta förgreningen frÄn featureA
till huvudgrenen.
Du kan göra det hÀr genom att skapa en ny gren frÄn origin/master
, sammanfoga featureB
dÀr, lösa eventuella konflikter, göra Àndringen och skicka det som en ny gren:
$ git checkout -b featureBv2 origin/master
$ git merge --squash featureB
... justera ...
$ git commit
$ git push mingaffel featureBv2
Flaggan --squash
komprimerar alla incheckningar pÄ grenen som ska slÄs ihop till en enda versionsÀndring, vilket ger samma status i arkivet som vid en sammanslagning.
Det innnebÀr att dina framtida incheckningar bara kommer att ha en förÀlder och ger dig möjlighet att dra in alla Àndringar frÄn en annan gren och göra fler Àndringar innan den nya incheckningen kommer pÄ prÀnt.
Ibland kan det vara anvÀndarbart att anvÀnda flaggan --no-commit
för att fördröja en ny incheckning vid en sammanslagning istÀllet för som i den ordinarie sammanslagningsprocessen.
I det hÀr lÀget kan du meddela ansvarig att du har gjort de begÀrda Àndringarna och att de kan hitta dessa i din featureBv2
.
featureBv2
.Ăppet, större projekt via mejl
MĂ„nga projekt har sina rutiner för att acceptera patcharâââdu behöver kolla upp de specifika reglerna för varje projekt, eftersom de kommer att skilja sig Ă„t. Eftersom det finns flera Ă€ldre, större projekt som endast accepterar patchar via en mejllista för utvecklare, sĂ„ kommer vi att gĂ„ igenom ett exempel pĂ„ hur det gĂ„r till.
Arbetsprocessen liknar den i föregĂ„ende exempletâââdu skapar finessgrenar som du arbetar pĂ„. Den stora skillnaden Ă€r att du inte kan skicka dina inceckningar till fjĂ€rrarkivet. IstĂ€llet behöver du mejla varje commit till en mejllista för utvecklare.
$ git checkout -b topicA
... arbeta ...
$ git commit
... arbeta ...
$ git commit
Nu har du tvÄ incheckningar som du vill skicka till mejllistan.
För att generera mbox-formatterade filer som du kan mejla till listan, anvÀnder du git format-patch
âââdet gör om varje incheckning till ett mejl med den första raden i incheckningsmeddelandet som Ă€mne och resten av meddelandet plus patchen som innehĂ„ll.
Det fina med det hÀr Àr att nÀr en patch frÄn ett mejl genererat med format-patch
appliceras, sÄ bevaras incheckningsinformationen korrekt.
$ git format-patch -M origin/master
0001-add-limit-to-log-function.patch
0002-changed-log-output-to-30-from-25.patch
format-patch
-kommandot skriver ut namnen pÄ de patchfiler som skapas.
Flaggan -M
talar om för Git att leta efter omdöpta filer.
Filerna kommer att se ut sÄ hÀr:
$ cat 0001-add-limit-to-log-function.patch
Av 330090432754092d704da8e76ca5c05c198e71a8 MĂ„n Sep 17 00:00:00 2001
FrÄn: Jessica Smith <jessica@example.com>
Datum: Sön, 6 apr 2008 10:17:23 -0700
Ămne: [PATCH 1/2] add limit to log function
Limit log functionality to the first 20
---
lib/simplegit.rb | 2 +-
1 fil Àndrad, 1 tillagd(+), 1 borttagen(-)
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 76f47bc..f9815f1 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -14,7 +14,7 @@ class SimpleGit
end
def log(treeish = 'master')
- command("git log #{treeish}")
+ command("git log -n 20 #{treeish}")
end
def ls_tree(treeish = 'master')
--
2.1.0
Du kan ocksÄ redigera patchfilerna för att lÀgga till mer information till mejllistan som du inte vill ska visas i incheckningsmeddelandet.
Om du lÀgger till text mellan raden ---
och början av patchen (inleds med raden diff --git
), sÄ kan utvecklarna lÀsa meddelandet, men det ignoreras i patchningsprocessen.
Det Àr en bra plats att lÀgga till information om varför du gjorde Àndringarna, eller om du har nÄgra speciella instruktioner för att testa dem.
För att skicka patchfilen till mejllistan kan du antingen klistra in innehÄllet i ditt mejlprogram eller skicka det via kommandoraden.
Att klistra in texten orsakar ofta formatteringsproblem, speciellt med âsmartareâ klienter som inte bevarar radbrytningar och mellanslag korrekt.
Som tur Àr har Git ett verktyg som hjÀlper dig att skicka korrekt formatterade patchar via IMAP, vilket gör det enklare.
Vi kommer att visa hur du skickar en patch via Gmail, som rÄkar vara den e-postklient vi kÀnner till bÀst.
Du kan lÀsa detaljerade instruktioner för en mÀngd e-postklienter i slutet av filen Documentation/SubmittingPatches
i Gits kÀllkod.
Först behöver du sÀtta upp IMAP-sektionen i din ~/.gitconfig
-fil.
Du kan sÀtta varje vÀrde separat med en serie git config
-kommandon, eller lÀgga till dem manuellt.
I slutÀnden ska din konfigurationsfil se ut nÄgot sÄ hÀr:
[imap]
folder = "[Gmail]/Drafts"
host = imaps://imap.gmail.com
user = user@gmail.com
pass = YX]8g76G_2^sFbd
port = 993
sslverify = false
Om din IMAP-server inte anvÀnder SSL sÄ Àr de tvÄ sista raderna nog inte nödvÀndiga, och vÀrdet för host
kommer dÄ att vara imap://
istÀllet för imaps://
.
NÀr det Àr instÀllt kan du anvÀnda git imap-send
för att placera patchserien i mappen Drafts pÄ den angivna IMAP-servern:
$ cat *.patch |git imap-send
Analyserar imap.gmail.com... ok
Ansluter till [74.125.142.109]:993... ok
Loggar in...
skickar 2 meddelanden
100% (2/2) klart
Nu borde du kunna gÄ till din Drafts-mapp, Àndra To-fÀltet till mejllistan du ska skicka patchen till, eventuellt lÀgga till cc:a till den person som Àr ansvarig, och skicka ivÀg det.
Du kan ocksÄ skicka patcharna via en SMTP-server.
Precis som tidigare kan du sÀtta varje vÀrde separat med en serie git config
-kommandon, eller lÀgga till dem manuellt i ~/.gitconfig
-filen:
[sendemail]
smtpencryption = tls
smtpserver = smtp.gmail.com
smtpuser = user@gmail.com
smtpserverport = 587
NÀr det Àr instÀllt kan du anvÀnda git send-email
för att skicka patcharna:
$ git send-email *.patch
0001-added-limit-to-log-function.patch
0002-changed-log-output-to-30-from-25.patch
FrÄn vem ska breven skickas? [Jessica Smith <jessica@example.com>]
E-postbreven kommer att skickas frÄn: Jessica Smith <jessica@example.com>
Till vem ska breven sÀndas (om nÄgon)? jessica@example.com
Message-ID att anvÀnda som In-Reply-To för det första brevet? y
Git kommer att stÀlla en rad frÄgor om hur du vill att e-posten ska se ut för varje skickad patch. De kommer att se ut ungefÀr sÄ hÀr:
(mbox) LÀgger till cc: Jessica Smith <jessica@example.com> frÄn
\line 'From: Jessica Smith <jessica@example.com>'
OK. Loggen sÀger:
Sendmail: /usr/sbin/sendmail -i jessica@example.com
FrÄn: Jessica Smith <jessica@example.com>
Till: jessica@example.com
Ămne: [PATCH 1/2] added limit to log function
Datum: Sat, 30 May 2009 13:29:15 -0700
Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com>
X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty
In-Reply-To: <y>
References: <y>
Result: OK
Sammanfattning
I den hÀr delen har vi gÄtt igenom en mÀngd olika arbetsflöden för olika slags Git-projekt som du troligen kommer att stöta pÄ, samt introducerat ett par nya verktyg för att hjÀlpa dig att hantera processerna. I nÀsta del kommer du att fÄ lÀra dig hur du hanterar den andra sidan av myntet: att underhÄlla ett Git-projekt. Du fÄr lÀra dig att vara en vÀlvillig diktator eller integrationsansvarig.