Git 🌙
Chapters â–Ÿ 2nd Edition

5.3 Distribuerade Git - UnderhÄlla ett projekt

UnderhÄlla ett projekt

Förutom att veta hur du bidrar effektivt till ett projekt, behöver du troligen kunskap om hur man underhÄller ett. Det kan innebÀra att acceptera och tillÀmpa patcher som genererats via format-patch och skickats till dig via mejl, eller att integrera Àndringar i fjÀrrgrenar. Oavsett om du underhÄller ett eget arkiv eller vill hjÀlpa till med att godkÀnna patcher, behöver du veta hur man accepterar bidrag pÄ ett strukturerat sÀtt, dels för att underlÀtta för bidragslÀmnare och dels för att underhÄllet ska bli hÄllbart för dig över tid.

Arbeta i Àmnesgrenar

NĂ€r det gĂ€ller att integrera nytt arbete Ă€r det generellt en bra idĂ© att prova hur den fungerar i en Ă€mnesgren — det vill sĂ€ga en tillfĂ€llig gren som Ă€r specifikt skapad för att prova det nya arbetet. Det gör det enkelt att justera patcherna individuellt och kunna lĂ€mna dem som inte fungerar tills bidragslĂ€mnaren har tid att Ă„terkomma med förbĂ€ttringar. Om du skapar ett grennamn baserat pĂ„ temat för den patch du testar, till exempel ruby_client eller liknande, kommer du enkelt pĂ„mind om syftet med grenen om du mĂ„ste lĂ€mna den och komma tillbaka senare. UnderhĂ„llarna av Git anger en namnrymd för dessa grenar ocksÄ — till exempel sc/ruby_client, dĂ€r prefixet sc Ă€r förkortningen för personen som bidrog med arbetet. Som du sĂ€kert kommer ihĂ„g kan du skapa grenen frĂ„n din master-gren pĂ„ följande sĂ€tt:

$ git branch sc/ruby_client master

Vill du byta till den direkt anvÀnder du istÀllet checkout -b:

$ git checkout -b sc/ruby_client master

Nu Àr du redo att lÀgga till det bidragande arbetet nÀr du har bestÀmt dig för om du vill applicera förslaget i nÄgon av dina lÄnglivade grenar eller inte

Arbeta via mejl

Om du tar emot patcher som ska integreras i ditt projekt via mejl, behöver du först du applicera patchen i din Àmnesgren för att kunna granska den. Det finns tvÄ sÀtt att applicera en mejlad patch: med git apply eller med git am.

Applicera en mejlad patch med apply

Om du har fÄtt patchen av nÄgon som genererade den med git diff eller nÄgon variant av Unix diff-kommandot (rekommenderas inte; se mer i nÀsta avsnitt), kan du applicera den med git apply. Om vi utgÄr frÄn att du sparade patchen pÄ /tmp/patch-ruby-client.patch, ser det ut sÄ hÀr:

$ git apply /tmp/patch-ruby-client.patch

Kommandot Ă€ndrar filerna i ditt lokala arkiv. Det Ă€r nĂ€stan identiskt som att köra patch -p1 för att applicera patchen, men det accepterar inte lika luddiga matchningar som patch. Det hanterar ocksĂ„ filer som lĂ€ggs till, tas bort och döps om om de beskrivs i git diff-formatet, vilket patch inte gör. Slutligen Ă€r git apply en “applicera allt eller avbryt allt”-modell, dĂ€r allt eller inget appliceras. patch kan Ă„ andra sidan applicera delar av patchfiler, men det kan lĂ€mna ditt lokala arkiv i ett lite mĂ€rkligt tillstĂ„nd. Övergripande sett Ă€r git apply ett mer konservativt kommando Ă€n patch. Det kommer inte att göra en inceckning Ă„t dig — nĂ€r du har kört kommandot behöver du köa och checka in Ă€ndringarna manuellt.

git apply kan ocksĂ„ anvĂ€ndas för att se om en patch kan lĂ€ggas till utan konflikter innan du försöker applicera den — kör git apply --check följt av patchen-filen:

$ git apply --check 0001-seeing-if-this-helps-the-gem.patch
error: patch misslyckades: ticgit.gemspec:1
error: ticgit.gemspec: patchen kan inte tillÀmpas

Om det inte finns nÄgon utdata kan patchen integreras utan problem. Detta kommando avslutar med ett nollskilt tal om kontrollen misslyckas, sÄ det kan anvÀndas i skript med om du vill.

Applicera en mejlad patch med am

Om bidragslÀmnaren Àr en van Git-anvÀndare som anvÀnde kommandot format-patch för att generera sin patch, blir ditt jobb genast enklare. Patchen innehÄller dÄ Àven författarinformation och ett incheckningsmeddelande. Om du har möjlighet, uppmuntra dina bidragslÀmnare att anvÀnda format-patch istÀllet för diff för att generera patchar till ditt projekt. git apply borde bara anvÀndas för patchar till legacy projekt.

För att applicera en patch som genererats av format-patch anvÀnder du git am (kommandot heter am eftersom det anvÀnds för att "applicera en serie patchar frÄn en mejlbox"). Tekniskt sett Àr git am byggt för att lÀsa en mbox-fil, som Àr ett enkelt, textbaserat format för att lagra ett eller flera e-postmeddelanden i en textfil. Det ser ut sÄ hÀr:

FrÄn 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
FrÄn: Jessica Smith <jessica@example.com>
Datum: Sun, 6 Apr 2008 10:17:23 -0700
Ämne: [PATCH 1/2] add limit to log function

Limit log functionality to the first 20

Det hÀr Àr början pÄ utdata frÄn git format-patch-kommandot som du sÄg i föregÄende avsnitt; det Àr ocksÄ ett giltigt mbox-e-postformat. Om nÄgon har mejlat patchen till dig pÄ rÀtt sÀtt med git send-email och du laddar ner den i mbox-format, kan du peka git am till mbox-filen för att den ska börja applicera alla patchar den ser. Om du anvÀnder en mejlklient som kan spara flera mejl i mbox-format, kan hela patchserier sparas i en fil och sen kan du köra git am för att applicera dem en i sÀnder.

Om nÄgon dÀremot laddade upp en patchfil som genererats via git format-patch till ett Àrendehanteringssystem eller liknande, kan du spara filen lokalt och sedan köra git am för att applicera den:

$ git am 0001-limit-log-function.patch
Applicerar: add limit to log function

Den applicerades utan konflikt och skapade automatiskt en ny incheckning Ă„t dig. Informationen om författaren tas frĂ„n mejlets FrĂ„n- och Datum-rubriker, meddelandet i incheckningen tas frĂ„n Ämne och brödtexten (innan patchen) i mejlet. Om den hĂ€r patchen applicerades frĂ„n mbox-exemplet ovan, skulle den genererade incheckningen se ut ungefĂ€r sĂ„ hĂ€r:

$ git log --pretty=fuller -1
commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
Författare:     Jessica Smith <jessica@example.com>
Författardatum: Sun Apr 6 10:17:23 2008 -0700
Incheckning:     Scott Chacon <schacon@gmail.com>
Inchdeckningsdatum: Thu Apr 9 09:19:06 2009 -0700

   add limit to log function

   Limit log functionality to the first 20

Incheckningsinformationen anger vem som applicerade patchen och vid vilken tidpunkt. Författarinformation anger vem som skapade den och nÀr.

Det Àr inte omöjligt att patchen inte kan appliceras pÄ grund av konflikter. Kanske har din huvudgren divergerat för lÄngt frÄn den gren patchen byggdes frÄn, eller sÄ förgrenades den frÄn en patch som du inte har applicerat Àn. git am-processen kommer dÄ att misslyckas och du blir tillfrÄgad om hur du vill lösa konflikten:

$ git am 0001-seeing-if-this-helps-the-gem.patch
TillÀmpar: seeing if this helps the gem
error: patch misslyckades: ticgit.gemspec:1
error: ticgit.gemspec: patchen kan inte tillÀmpas
Patchen misslyckades pÄ 0001.
NÀr du har löst problemet, kör "git am --resolved".
Om du hellre vill hoppa över patchen, kör "git am --skip" istÀllet.
För att ÄtergÄ till ursprunglig gren och sluta patcha, kör "git am --abort".

Det hĂ€r kommandot anger i vilka berörda filer det finns konflikter, precis som vid en sammanslagning eller ombasering. Du löser det hĂ€r problemet pĂ„ ungefĂ€r samma sĂ€tt — redigerar filen för att lösa konflikten, köar den nya filen och kör sedan git am --resolved för att fortsĂ€tta till nĂ€sta patch:

$ (fix the file)
$ git add ticgit.gemspec
$ git am --resolved
TillÀmpar: seeing if this helps the gem

Om du vill att Git ska försöka göra en lite mer intelligent operation för att lösa konflikten kan du lÀgga till en -3-flagga. Git försöker dÄ att göra en trefÀltsfusion. Det Àr inte förvalt eftersom det inte fungerar om den incheckning som patchen förgrenades ifrÄn inte finns i ditt arkiv. Om patchen dÀremot förgrenades frÄn en offentlig incheckning Àr -3-flaggan generellt mycket smartare för att applicera en patch med konflikter:

$ git am -3 0001-seeing-if-this-helps-the-gem.patch
TillÀmpar: seeing if this helps the gem
error: patch misslyckades: ticgit.gemspec:1
error: ticgit.gemspec: patchen kan inte tillÀmpas
AnvÀnder indexinfo för att Äterskapa ett bastrÀd...
Faller tillbaka pÄ att patcha grundversionen och trevÀgssammanslagning...
Inga Àndringar -- Patchen har redan tillÀmpats.

Utan -3-flaggan skulle patchen i det hÀr fallet ha betraktats som konfliktfylld. Med -3-flaggan appliceras den utan problem.

Om du applicerar ett helt gÀng patcher frÄn en mbox kan du ocksÄ köra am-kommandot i interaktivt lÀge, vilket stannar processen vid varje patch för att frÄga om du vill applicera den:

$ git am -3 -i mbox
Incheckningskroppen Àr:
--------------------------
seeing if this helps the gem
--------------------------
TillÀmpa? [Y]=ja/[N]=nej/[E]=redigera/[V]=visa patch/[A]=godta alla:

Det hÀr Àr anvÀndbart om du har mÄnga patcher för att kunna se dem först om du inte skulle komma ihÄg vad nÄgon handlar om, eller hoppa över nÄgon som du redan har lagt till.

NÀr alla patcher har lagts till och checkats in i din gren behöver du bestÀmma om och hur du ska integrera dem i en lÄnglivad gren.

Checka ut fjÀrrgrenar

Om ditt bidrag kom frÄn en Git-anvÀndare som har checkat ut sin egen gren, skickat ett antal Àndringar till den och sedan skickat URL:en till sitt repo och namnet pÄ den grenen som Àndringarna finns i till dig, kan du lÀgga till den som en fjÀrrgren och göra sammanslagning lokalt.

Om Jessika till exempel skickar ett mejl och skriver att hon har en bra ny funktion i ruby-client-grenen i sitt arkiv, kan du testa den genom att lÀgga till den som fjÀrrgren och checka ut den lokalt:

$ git remote add jessica git://github.com/jessica/myproject.git
$ git fetch jessica
$ git checkout -b rubyclient jessica/ruby-client

Om hon mejlar dig igen med en annan gren som har en annan bra funktion kan du direkt köra fetch och checkout eftersom du redan har stÀllt in fjÀrrgrenen.

Det hĂ€r Ă€r mest anvĂ€ndbart om du arbetar regelbundet med en person. Om nĂ„gon bara bidrar med en patch lite dĂ„ och dĂ„ Ă€r det mindre tidskrĂ€vande att acceptera den via e-post Ă€n att krĂ€va att alla kör sina egna servrar och stĂ€ndigt lĂ€gga till och ta bort fjĂ€rrgrenar för att fĂ„ nĂ„gra patcher. Du kommer sannolikt inte heller att vilja ha hundratals fjĂ€rrgrenar, dĂ€r de flesta Ă€r frĂ„n nĂ„gon som bara bidrar med en patch eller tvĂ„. Hur som helst, skript och hostade tjĂ€nster kan göra det enklare — det beror till stor del pĂ„ hur du och dina bidragslĂ€mnare utvecklar.

Den andra fördelen med den hĂ€r metoden Ă€r att du behĂ„ller historiken för incheckningarna. Även om du kanske har sammanslagningskonflikter, sĂ„ vet du var i historiken deras arbete Ă€r baserat; en korrekt trefĂ€ltsfusion Ă€r standard istĂ€llet för att behöva ange en -3 och hoppas att patchen genererades frĂ„n en offentlig incheckning som du har tillgĂ„ng till.

Om du inte samarbetar kontinuerligt med en person men ÀndÄ vill dra in kod frÄn dem pÄ det hÀr sÀttet kan du ange URL:en till fjÀrrarkivet nÀr du kör git pull. Det gör en enstaka hÀmtning frÄn ett fjÀrrarkiv utan att spara URL:en som en fjÀrreferens:

$ git pull https://github.com/onetimeguy/project
FrÄn https://github.com/onetimeguy/project
 * branch            HEAD       -> FETCH_HEAD
Sammanslagning genomförd med strategi 'recursive'.

Avgöra vad som ska integreras

Nu har du en Àmnesgren som innehÄller ett bidrag. Du behöver nu bestÀmma vad du vill göra med den. I det hÀr avsnittet gÄr vi igenom nÄgra kommandon som du kan anvÀnda för att granska exakt vad som kommer att tillÀmpas om du sammanfogar den hÀr grenen med din huvudgren.

Det Àr ofta anvÀndbart att fÄ en överblick över alla de incheckningar i den hÀr grenen som inte finns i din huvudgren. Du kan utesluta incheckningar i huvudgrenen genom att lÀgga till --not-flaggan före grennamnet. Det gör samma sak som kommandot master..contrib som vi anvÀnde tidigare. Om din bidragslÀmnare skickar tvÄ patchar, du skapar en gren som heter contrib och applicerar dessa patchar dÀr kan du köra detta:

$ git log contrib --not master
commit 5b6235bd297351589efc4d73316f0a68d484f118
Författare: Scott Chacon <schacon@gmail.com>
Datum:   Fri Oct 24 09:53:59 2008 -0700

    seeing if this helps the gem

commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
Författare: Scott Chacon <schacon@gmail.com>
Datum:   Mon Oct 22 19:38:36 2008 -0700

    updated the gemspec to hopefully work better

För att se vad varje incheckning gör, kom ihÄg att du kan ange -p-flaggan till git log. DÄ lÀggs diffen till som tillÀmpandet av en patch ger.

För att se en fullstÀndig diff över vad som skulle hÀnda om du sammanfogade hela Àmnesgrenen med en annan gren, kan du behöva anvÀnda ett lite mÀrkligt trick för att fÄ korrekta resultat. Du kanske tror att du kan köra detta:

$ git diff master

Det hÀr kommandot ger dig mycket riktigt en diff, men om din master-gren har flyttats framÄt sedan du förgrenade Àmnesgrenen frÄn den Àr de nÄgot vilseledande. Detta beror pÄ att Git direkt jÀmför ögonblicksbilder av den sista incheckningen pÄ den Àmnesgren du Àr pÄ och ögonblicksbilden av den senaste incheckningen pÄ master-grenen. Om du, till exempel, har lagt till en rad i en fil pÄ master-grenen, kommer en direkt jÀmförelse av grenarnas ögonblicksbilder fÄ det att se ut som att Àmnesgrenen kommer att ta bort den raden.

Om master-grenen inte har rört sig Àr det inte ett problem, men har historiken divergerat kommer diffen att se ut som att du lÀgger till allt nytt i din Àmnesgren och tar bort allt unikt för master-grenen.

Vad du verkligen vill se Ă€r Ă€ndringarna som lagts till i funktionsgrenen — resultatet av de Ă€ndringar som bblir om du slĂ„r ihop den hĂ€r grenen med master. Det gör du genom att be Git jĂ€mföra den sista incheckningen pĂ„ din temagren med den första gemensamma föregĂ„ngaren den har med master-grenen.

Tekniskt sett kan du göra det genom att explicit rÀkna ut den gemensamma föregÄngaren och sedan köra diff pÄ den:

$ git merge-base contrib master
36c7dba2c95e6bbb78dfa822519ecfec6e1ca649
$ git diff 36c7db

Eller, mer koncist:

$ git diff $(git merge-base contrib master)

Hur som helst sÄ Àr ingen av dessa sÀrskilt bekvÀma, sÄ Git ger en annan förkortning för att göra samma sak: trepunktssyntaxen. I kontexten git diff-kommandot kan du sÀtta tre punkter efter en annan gren för att göra en diff mellan den sista incheckningen pÄ den gren du Àr pÄ och dess gemensamma föregÄngare med en annan gren:

$ git diff master...contrib

Det hÀr kommandot visar dig exakt vad som har lagts till i den hÀr grenen sedan den delade föregÄngaren med master-grenen. Det Àr en mycket anvÀndbar syntax att lÀgga pÄ minnet.

Integrera kod frÄn bidragslÀmnare

NÀr allt arbete i din funktionsgren Àr redo att slÄs ihop i din huvudgren Àr frÄgan hur du ska göra det. Vidare, vilken övergripande arbetsflöde vill du anvÀnda för att underhÄlla ditt projekt? Du har ett antal metoder att vÀlja mellan, och vi kommer att gÄ igenom nÄgra av dem

Arbetsflöden med sammanslagning

Ett grundlÀggande arbetsflöde Àr att helt enkelt slÄ ihop allt arbete direkt i din master-gren. I det hÀr scenariot har du en master-gren som innehÄller stabil kod. NÀr du har arbete i en funktionsgren som du tror att du har slutfört, eller arbete som nÄgon annan har bidragit med och du har verifierat, slÄr du ihop det i din master-gren, tar bort den just sammanfogade temagrenen och upprepar.

Om vi har ett arkiv med arbete i tvÄ grenar som heter ruby_client och php_client som ser ut som Historik med flera funktionsgrenar, och vi slÄr ihop ruby_client följt av php_client, kommer din historik att se ut som Efter en sammanslagning med en funktionsgren..

Historik med flera funktionsgrenar.
Figur 73. Historik med flera funktionsgrenar
Efter en sammanslagning med en funktionsgren.
Figur 74. Efter en sammanslagning med en funktionsgren.

Det hÀr Àr förmodligen det enklaste arbetsflödet, men det kan bli problematiskt om du arbetar med större eller mer stabila projekt dÀr du vill vara riktigt försiktig med vad du introducerar.

Om du har ett viktigare projekt kanske du vill anvÀnda en tvÄfas-sammanslagningcykel. I det scenariot har du tvÄ lÄnglivade grenar, master och develop, dÀr du bestÀmmer att master uppdateras endast nÀr en mycket stabil version skapas och all ny kod integreras i develop-grenen. Du skickar regelbundet bÄda dessa grenar till det publika arkivet. Varje gÄng du har en ny funktionsgren att slÄ ihop (Före en sammanslagning av en funktionsgren.), slÄr du ihop den i develop (Efter en sammanslagning av en funktionsgren.); sedan, nÀr du taggar en version, snabbspolar du master till dÀr develop-grenen Àr stabil (Efter en ny version.).

Före en sammanslagning av en funktionsgren.
Figur 75. Före en sammanslagning av en funktionsgren.
Efter en sammanslagning av en funktionsgren.
Figur 76. Efter en sammanslagning av en funktionsgren.
Efter en ny version.
Figur 77. Efter en ny version.

PÄ det hÀr sÀttet, nÀr folk klonar ditt projekts arkiv, kan de antingen kolla ut master för att bygga den senaste stabila versionen och enkelt hÄlla sig uppdaterade pÄ den, eller kolla ut develop, som Àr den mer skÀrpta innehÄllet. Du kan ocksÄ utöka det hÀr konceptet genom att ha en integrate-gren dÀr allt arbete sammanfogas. NÀr kodbasen pÄ den grenen Àr stabil och passerar tester, slÄr du ihop den i en develop-gren; och nÀr den har visat sig vara stabil under en tid, snabbspolar du din master-gren.

Arbetsflöde med stora sammanslagningar

Git-projektet har fyra lÄnglivade grenar: master, next och pu (proposed updates) för nytt arbete, och maint för underhÄllsbackportar. NÀr nytt arbete introduceras av bidragslÀmnare samlas det i temagrenar i förvaltarens arkiv pÄ ett sÀtt som liknar det som har beskrivits (se Hantera en komplex serie med parallella Àmnesgrenar.). Vid det hÀr laget utvÀrderas temana för att avgöra om de Àr sÀkra och redo för anvÀndning eller om de behöver mer arbete. Om de Àr sÀkra slÄs de ihop i next, och den grenen pushas upp sÄ att alla kan prova temana integrerade tillsammans.

Hantera en komplex serie med parallella Àmnesgrenar.
Figur 78. Hantera en komplex serie med parallella Àmnesgrenar.

Om det behövs mer arbete pÄ en temagren slÄs den ihop med pu istÀllet. NÀr det har bestÀmts att de Àr helt stabila slÄs de ihop med master-grenen. next- och pu-grenarna byggs sedan om frÄn master. Det hÀr innebÀr att master nÀstan alltid rör sig framÄt, next ombaseras ibland, och pu ombaseras Ànnu oftare:

SlÄ ihop Àmnesgrenar med lÄnglivade integrationsgrenar.
Figur 79. SlÄ ihop Àmnesgrenar med lÄnglivade integrationsgrenar.

NĂ€r en Ă€mnesgren Ă€ntligen har slagits ihop med master-grenen tas den bort frĂ„n arkivet. Git-projektet hr ocksĂ„ en maint-gren som Ă€r en gren som Ă€r förgrenad frĂ„n den senaste versionen för att tillhandahĂ„lla bakĂ„tkompatibla patchar om en underhĂ„llsversion krĂ€vs. SĂ„, nĂ€r du klonar Git-arkivet har du fyra grenar som du kan kolla ut för att utvĂ€rdera projektet i olika utvecklingsstadier, beroende pĂ„ hur nyskapande du vill vara eller hur du vill bidra; och förvaltaren har ett strukturerat arbetsflöde för att hjĂ€lpas Ă„t att granska nya bidrag. Git-projektet har ett specialiserat arbetsflöde. För att förstĂ„ det bĂ€ttre kan du lĂ€sa mer pĂ„ Git Maintainer’s guide.

Arbetsflöden med ombasering och plocka russin ur kakan

NÀr du har arbete i en temagren och har bestÀmt att du vill integrera det, kan du göra det pÄ tvÄ sÀtt: genom att ombasera eller plocka russin ur kakan. Vissa förvaltare föredrar att ombasera eller plocka russin ur kakan för att hÄlla en mestadels linjÀr historik. NÀr du har arbete i en temagren och har bestÀmt att du vill integrera det, flyttar du till den grenen och kör ombasera-kommandot för att bygga om Àndringarna pÄ din nuvarande master-gren (eller develop, och sÄ vidare). Om det gÄr bra kan du snabbspola din master-gren. I slutÀnden fÄr du en linjÀr projektshistorik.

Ett annat sÀtt att flytta in arbete frÄn en gren till en annan Àr att plocka russin ur kakan. Att plocka russin ur kakan i Git Àr som en ombasering men för en enskild incheckning. Det tar en patch frÄn en incheckning och försöker applicera den pÄ den gren du Àr pÄ. Detta Àr anvÀndbart om du har ett antal incheckningar pÄ en temagren och du baran vill integrera en av dem, eller om du föredrar att plocka in incheckningarna en och en istÀllet för att göra en ombasering. Om du till exempel har ett projekt som ser ut sÄ hÀr:

Exempel historik före russin plockats ur kakan.
Figur 80. Exempel historik före russin plockats ur kakan.

Om du vill dra in incheckningen e43a6 i din master-gren kan du köra

$ git cherry-pick e43a6
Avslutade en cherry-pick.
[master]: created a0a41a9: "More friendly message when locking the index fails."
 3 filer Àndrade, 17 tillagda(+), 3 borttagna(-)

Det hÀr drar in Àndringarna i incheckning e43a6 in i din master-gren., men du fÄr ett nytt SHA-1-vÀrde för incheckningen eftersom datumet som den tillÀmpades Àr annorlunda. Din historik ser nu ut sÄ hÀr:

Historik efter russinplockning av en inceckning pÄ en funktionsgren.
Figur 81. Historik efter russinplockning av en inceckning pÄ en funktionsgren.

Nu kan du radera din funktionsgren och slÀppa incheckningarna som du inte vill fÄ in.

Rerere

Om du gör massor av sammanslagningar och ombaseringar, eller om du underhĂ„ller en lĂ„nglivad funktionsgren, har Git en funktion som heter “rerere” som kan vara anvĂ€ndbar.

Rerere stĂ„r för “reuse recorded resolution” — det Ă€r ett sĂ€tt att förkorta manuell konflikthantering. NĂ€r rerere Ă€r aktiverat kommer Git att behĂ„lla en uppsĂ€ttning före- och efterbilder frĂ„n lyckade sammanslagningar, och om det mĂ€rker att det finns en konflikt som ser precis ut som en du redan har löst, kommer Git bara att anvĂ€nda lösningen frĂ„n förra gĂ„ngen, utan att störa dig med den. Rerere stands for “reuse recorded resolution” — it’s a way of shortcutting manual conflict resolution. When rerere is enabled, Git will keep a set of pre- and post-images from successful merges, and if it notices that there’s a conflict that looks exactly like one you’ve already fixed, it’ll just use the fix from last time, without bothering you with it.

Funktionen har tvÄ delar: en konfigurationsinstÀllning och ett kommando. KonfigurationsinstÀllningen Àr rerere.enabled, och det Àr tillrÀckligt anvÀndbart för att lÀgga i din globala konfiguration:

$ git config --global rerere.enabled true

NÀr du Àn gör en sammanslagning som löser konflikter, kommer lösningen nu att sparas i cachen om den skulle behövas i framtiden.

Om du behöver kan du interagera med rerere-cachen med hjÀlp av kommandot git rerere. NÀr det anvÀnds ensamt, kollar Git sin databas med lösningar och försöker hitta en matchning med eventuella aktuella konflikter och lösa dem (Àven om det görs automatiskt om rerere.enabled Àr instÀllt pÄ true). Det finns ocksÄ underkommandon för att se vad som kommer att sparas, för att radera specifika lösningar frÄn cachen och för att rensa hela cachen. Vi kommer att gÄ in pÄ rerere mer i detalj i Rerere.

Versionsmarkeringar

NÀr du har bestÀmt dig för att slÀppa en ny version av ditt projekt, vill du förmodligen tilldela en tagg sÄ att du kan Äterskapa den versionen nÀr som helst framöver. Du kan skapa en ny tagg som diskuterats i Grunder i Git. Om du bestÀmmer dig för att signera taggen som underhÄllare ser taggningen ut sÄ hÀr:

$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Scott Chacon <schacon@gmail.com>"
1024-bit DSA key, ID F721C45A, created 2009-02-09

Om du signerar dina taggar kan du fÄ problem med att distribuera den offentliga PGP-nyckeln som anvÀnds för att signera dina taggar. Förvaltaren för Git-projektet har löst detta problem genom att inkludera sin offentliga nyckel som en blob i arkivet och sedan lÀgga till en tagg som pekar direkt pÄ det innehÄllet. För att göra detta kan du ta reda pÄ vilken nyckel du vill anvÀnda genom att köra gpg --list-keys:

$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09]
uid                  Scott Chacon <schacon@gmail.com>
sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09]

Du kan dÄ importera nyckeln direkt i Git-databasen genom att exportera den och skicka den genom git hash-object, som skriver en ny blob med de innehÄllen i Git och ger dig tillbaka SHA-1 för blobben:

$ gpg -a --export F721C45A | git hash-object -w --stdin
659ef797d181633c87ec71ac3f9ba29fe5775b92

Nu nÀr du har innehÄllet i din nyckel i Git kan du skapa en tagg som pekar direkt pÄ den genom att ange det nya SHA-1-vÀrdet frÄn hash-object:

$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92

Med kommandot git push --tags kan du nu dela taggen maintainer-pgp-pub med alla. Om nÄgon vill verifiera en tagg kan de direkt importera din PGP-nyckel genom att dra ut blobben direkt ur databasen och importera den i GPG:

$ git show maintainer-pgp-pub | gpg --import

De kan ocksÄ anvÀnda den nyckeln för att verifiera alla dina signerade taggar. Om du dessutom inkluderar instruktioner i taggmeddelandet kan körning av git show <tagg> lÄta dig ge slutanvÀndaren mer specifika instruktioner om taggverifiering.

Generera versionsnummer

I Git finns det inget inbyggt sÀtt att generera löpande versionsnummer som v123 eller liknande för varje incheckning. Om du vill ha ett versionnummber som Àr logiskt för mÀnniskor för varje incheckning, kan du köra git describe pÄ incheckningen. Till svar genererar Git en strÀng som bestÄr av namnet pÄ den senaste taggen tidigare Àn den incheckningen, följt av antalet incheckningar sedan den taggen, följt av en del av SHA-1-vÀrdet för den incheckningen (föregÄnget av bokstaven g som betyder Git):

$ git describe master
v1.6.2-rc1-20-g8c5b85c

PÄ det hÀr sÀttet kan du fÄ en strÀng som Àr meningsfull för mÀnniskor att anvÀnda som versionsnummer. Om du bygger Git frÄn kÀllkoden som Àr klonad frÄn Git-arkivet ger git --version dig nÄgot som ser ut sÄ hÀr. Om du beskriver en incheckning som du direkt har taggat ger den dig helt enkelt taggnamnet.

git describe-kommandot krÀver annoterade taggar som standard (taggar som skapats med flaggorna -a eller -s); om du vill dra nytta av lÀttviktiga (icke-annoterade) taggar ocksÄ, lÀgg till --tags-flaggan till kommandot. Du kan ocksÄ anvÀnda den hÀr strÀngen som mÄl för ett git checkout- eller git show-kommando, Àven om det förlitar sig pÄ det förkortade SHA-1-vÀrdet i slutet, sÄ det kanske inte Àr giltigt för evigt. Till exempel hoppade Linux-kÀrnan nyligen frÄn 8 till 10 tecken för att sÀkerstÀlla SHA-1-objektens unicitet, sÄ Àldre git describe-utdata namn ogiltigförklarades.

Förbereda ett slÀpp

Nu vill du slÀppa en ny version. En av de saker du vill göra Àr att skapa ett arkiv av den senaste ögonblicksbilden av din kod för de arma sjÀlar som inte anvÀnder Git. Kommandot för att göra detta Àr git archive:

$ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
$ ls *.tar.gz
v1.6.2-rc1-20-g8c5b85c.tar.gz

Om nÄgon öppnar det arkivet fÄr de den senaste ögonblicksbilden av ditt projekt i en projektkatalog. Du kan ocksÄ skapa ett zip-arkiv ungefÀr pÄ samma sÀtt men genom att ange --format=zip-flaggan till git archive:

$ git archive master --prefix='project/' --format=zip > `git describe master`.zip

Nu har du en snyggt arkiv och en zipkatalog av ditt projekts slÀpp som du kan ladda upp till din webbplats eller mejla till folk.

Shortlog

Det Àr dags att mejla till din mejllista med personer som vill veta vad som hÀnder i ditt projekt. Ett trevligt sÀtt att snabbt fÄ en slags Àndringslogg över vad som har lagts till i ditt projekt sedan ditt senaste slÀpp eller mejl Àr att anvÀnda kommandot git shortlog. Det sammanfattar alla incheckningar i det intervall du ger det; till exempel ger följande en sammanfattning av alla incheckningar sedan ditt senaste slÀpp, om ditt senaste slÀpp hette v1.0.1:

$ git shortlog --no-merges master --not v1.0.1
Chris Wanstrath (6):
      Add support for annotated tags to Grit::Tag
      Add packed-refs annotated tag support.
      Add Grit::Commit#to_patch
      Update version and History.txt
      Remove stray `puts`
      Make ls_tree ignore nils

Tom Preston-Werner (4):
      fix dates in history
      dynamic version method
      Version bump to 1.0.2
      Regenerated gemspec for version 1.0.2

Du fÄr en enhetlig sammanfattning av samtliga incheckningar sedan v1.0.1, grupperade efter författare, som du kan skicka till din mejllista.

scroll-to-top