Git Succinctly Branches

Grenar multiplicerar den grundläggande funktionaliteten som erbjuds genom att tillåta användare att förkla sin historia. Att skapa en ny filial är relaterad till att begära en ny utvecklingsmiljö, komplett med en isolerad arbetsmapp, staging-område och projekthistoria.


Grundläggande förgrenad utveckling

Detta ger dig samma sinnesro som att göra en "säker" kopia av ditt projekt, men du har nu den extra kapaciteten att arbeta på flera versioner samtidigt. Grenar möjliggör a icke-linjärt arbetsflöde-förmågan att utveckla orelaterade funktioner parallellt. Som vi kommer att upptäcka senare är ett icke-linjärt arbetsflöde en viktig föregångare till Gits samarbetsmodell som distribueras.

Till skillnad från SVN eller CVS är Gits filialimplementation otroligt effektiv. SVN möjliggör filialer genom att kopiera hela projektet till en ny mapp, precis som du skulle göra utan någon revisionskontrollprogramvara. Detta gör fusioner klumpiga, felaktiga och långsamma. Däremot är Git-grenar helt enkelt en pekare till ett engagemang. Eftersom de arbetar på commit-nivå istället för direkt på filnivån, gör Git-filialer det mycket lättare att sammanfoga divergerande historier. Detta har en dramatisk inverkan på att förgrena arbetsflöden.


Manipulera grenar

Git skiljer grenfunktionalitet till några olika kommandon. De git grenen Kommando används för att lista, skapa eller ta bort grenar.

Listning Branches

Först och främst måste du kunna se dina befintliga filialer:

 git grenen

Detta kommer att mata ut alla dina nuvarande grenar, tillsammans med en asterisk bredvid den som för närvarande är "utcheckad" (mer om det senare):

 * Master-funktionen Quick-Bug-Fix

De bemästra filial är Gits standardgren, som skapas med det första engagemanget i något förråd. Många utvecklare använder denna filial som projektets "viktigaste" historia - en permanent filial som innehåller alla större förändringar det går igenom.

Skapa grenar

Du kan skapa en ny fil genom att skicka filnamnet till samma git grenen kommando:

 git grenen 

Detta skapar en pekare till nuvarande HUVUD, men gör det inte byta till den nya filialen (du behöver git checkout för det). Omedelbart efter att ha begärt en ny filial kommer ditt förråd att se ut som följande.


Skapa en ny filial

Din nuvarande filial (bemästra) och den nya filialen (något-funktion) båda hänvisar till samma förpliktelse, men alla nya förbinder dig att spela in kommer att vara exklusiva för den nuvarande filialen. Återigen kan du arbeta med orelaterade funktioner parallellt, samtidigt som du behåller förnuftiga historier. Till exempel, om din nuvarande filial var något-funktion, Din historia skulle se ut som följer efter att ha begått en stillbild.


Begå sig på något-funktion gren

Den nya HUVUD (betecknas med det markerade commitet) existerar endast i något-funktion gren. Det kommer inte dyka upp i loggutmatningen av bemästra, Inte heller kommer dess ändringar att visas i arbetskatalogen efter att du har checkat ut bemästra.

Du kan faktiskt se den nya filialen i den interna databasen genom att öppna filen .git / refs / huvuden /. Filen innehåller ID för det refererade commitet, och det är den enda definitionen av en Git-filial. Detta är anledningen till att filialerna är så lätta och lätta att hantera.

Radera grenar

Slutligen kan du radera filialer via -d flagga:

 gitgren -d 

Men Gits engagemang för att aldrig förlora ditt arbete hindrar det från att ta bort grenar med otänkta förpliktelser. För att tvinga bort raderingen, använd -D flagga istället:

 git grenen -D 

Unmerged ändringar kommer att gå vilse, så var väldigt försiktig med det här kommandot.


Checka ut grenar

Det är självklart att skapa grenar är värdelösa utan att kunna växla mellan dem. Git kallar detta "checkar ut" en filial:

 git checkout 

När du har kontrollerat den angivna filialen uppdateras din arbetsmapp för att matcha den angivna branschens åtagande. Dessutom har HUVUD är uppdaterad för att peka på den nya filialen, och alla nya förbindelser kommer att lagras på den nya filialen. Du kan tänka dig att kolla in en fil som växlar till en ny projektmapp, förutom att det blir mycket lättare att dra ändringar tillbaka till projektet.


Kolla in olika grenar

Med detta i åtanke är det vanligtvis en bra idé att ha en rena arbetskatalog innan du checkar ut en filial. En ren katalog finns när det inte finns några obestämda ändringar. Om detta inte är fallet, git checkout har potential att skriva över dina ändringar.

Som med att göra en "säker" revision kan du experimentera med en ny filial utan rädsla för att förstöra befintlig funktionalitet. Men du har nu en dedikerad historia att arbeta med, så att du kan spela in ett experiments framsteg med exakt samma git lägg till och git commit kommandon från tidigare i boken.


Utveckla flera funktioner parallellt

Denna funktionalitet blir ännu kraftigare när vi lär oss hur man sammanfogar divergerande historier tillbaka till "huvud" -grenen (t.ex.., bemästra). Vi kommer till det på ett ögonblick, men först finns det ett viktigt användningsfall av git checkout det måste övervägas ...

Friliggande huvudenheter

Git låter dig också använda git checkout med taggar och begå ID, men så gör du dig i en fristående HEAD-tillstånd. Det betyder att du inte är på en gren längre - du tittar direkt på ett engagemang.


Kolla in en gammal begåvning

Du kan titta och lägga till nya förpliktelser som vanligt, men eftersom det inte finns någon gren som pekar på tilläggen, kommer du att förlora allt ditt arbete så fort du växlar tillbaka till en riktig gren. Lyckligtvis skapar en ny filial i en fristående HUVUD staten är lätt nog:

 git checkout -b 

Detta är en genväg för git grenen följd av git checkout . Därefter får du en glänsande ny grenreferens till den tidigare fristående HUVUD. Detta är ett mycket användbart förfarande för att förkroppsliga experiment utanför gamla revisioner.


Sammanslagning av filialer

Sammanslagning är processen att dra förbindelser från en gren till en annan. Det finns många sätt att kombinera grenar, men målet är alltid att dela information mellan grenar. Detta gör att en av de viktigaste funktionerna i Git sammanfogas. De två vanligaste sammanslagningsmetoderna är:

  • "Fast-forward" -fusion
  • "3-vägs" -fusion

De använder båda samma kommando, git-sammanslagning, men metoden bestäms automatiskt baserat på strukturen i din historia. I varje fall, filialen du vill slå in i måste checkas ut, och målbranschen kommer att förbli oförändrad. De följande två avsnitten presenterar två möjliga sammanfogningsscenarier för följande kommandon:

 git checkout master git sammanfoga en del funktion

Återigen sammanfogar detta något-funktion gren in i bemästra gren, lämnar den tidigare orörd. Du skulle normalt köra dessa kommandon när du har slutfört en funktion och vill integrera den i det stabila projektet.

Snabba fusioner

Det första scenariot ser ut så här:


Innan snabbspolningen fortsätter

Vi skapade en filial för att utveckla en ny funktion, lagt till två förbindelser, och nu är den redo att integreras i huvudkodbasen. I stället för att skriva om de två begås saknas från bemästra, Git kan "snabba fram" på bemästra grenens pekare för att matcha platsen för något-funktion.


Efter snabbspolningen

Efter sammanslagningen bemästra filialen innehåller all önskad historia, och funktionsgrenen kan raderas (om du inte vill fortsätta att utveckla den). Detta är den enklaste typen av sammanslagning.

Självfallet kunde vi ha gjort de två förbundna direkt på bemästra gren; dock med hjälp av en dedikerad funktionen gren gav oss en säker miljö för att experimentera med ny kod. Om det inte visade sig rätt, kunde vi helt enkelt radera filialen (i motsats till att återställa / återställa). Eller om vi lagt till en massa mellanliggande förpliktelser som innehåller trasig kod, kunde vi städa upp det innan vi slog in det bemästra (se Återställning nedan). Eftersom projekt blir mer komplicerade och förvärvar fler medarbetare, gör denna typ av förgrenad utveckling Git ett fantastiskt organisationsverktyg.

3-vägs sammanslagningar

Men inte alla situationer är enkla nog för ett snabbt framåtriktat engagemang. Kom ihåg att den största fördelen med grenar är möjligheten att utforska många oberoende utvecklingslinjer samtidigt. Som ett resultat kommer du ofta att stöta på ett scenario som ser ut som följande:


Innan 3-vägsfusionen

Det började som en snabbspolning, men vi lade till ett engagemang för bemästra gren medan vi fortfarande utvecklade något-funktion. Till exempel kunde vi ha slutat arbeta med funktionen för att fixa en tids känslig bugg. Naturligtvis bör bugfixen läggas till huvudförvaret så snart som möjligt, så vi hamnar i det ovanstående scenariot.

Sammanslagning av funktionsgrenen i bemästra i detta sammanhang resulterar i en "3-vägs" -fusion. Detta uppnås med exakt samma kommandon som snabbspolningslängden från föregående avsnitt.


Efter 3-vägsfusionen

Git kan inte spola framåt bemästra pekaren till något-funktion utan backtracking. Istället genererar det en ny fusion commit som representerar den kombinerade ögonblicksbilden för båda grenarna. Observera att detta nya engagemang har två förälder åtar sig, vilket ger den tillgång till båda historierna (ja, springande git logg efter det att 3-vägs sammanslagning visar sig från båda grenarna).

Namnet på denna sammanslagningsalgoritm härstammar från den interna metoden som används för att skapa sammanslagningsbegränsningen. Git tittar på tre förbinder sig att generera det slutliga tillståndet för sammanslagningen.

Sammanslagningskonflikter

Om du försöker kombinera två grenar som gör olika ändringar i samma del av koden, vet Git inte vilken version som ska användas. Detta kallas a slå samman konflikten. Självklart kan detta aldrig hända under en snabbsammanställning. När Git möter en sammanslagningskonflikt ser du följande meddelande:

 Automatisk sammanslagning index.html CONFLICT (innehåll): Sammanfoga konflikt i  Automatisk sammanfogning misslyckades; fixa konflikter och sedan begå resultatet.

I stället för att automatiskt lägga till sammanslagningsbegäran, slutar Git och frågar dig vad du ska göra. Löpning git status i den här situationen kommer att returnera något som följande:

 # På grenmästare # Unmerged-banor: # # båda ändrade: 

Varje fil med konflikt lagras under avsnittet "Unmerged paths". Git annoterar dessa filer för att visa innehållet från båda versionerna:

 <<<<<<< HEAD This content is from the current branch. ======= This is a conflicting change from another branch. >>>>>>> lite-funktion

Delen före ======= är från bemästra gren och resten är från den gren du försöker integrera.

För att lösa konflikten, ta bort <<<<<<, =======, och >>>>>>> notation, och ändra koden till vad du vill behålla. Sedan berätta för Git du är klar att lösa konflikten med git lägg till kommando:

 git lägg till 

Det är rätt; allt du behöver göra är att arrangera den konfliktade filen för att markera den som lös. Slutligen slutför du 3-vägs-fusionen genom att generera sammanslagningsfördraget:

 git commit

Logmeddelandet är utsäde med ett sammanfogningsmeddelande tillsammans med en "konflikt" -lista som kan vara särskilt användbar när man försöker lista ut var något gick fel i ett projekt.

Och det är allt som finns att slå samman i Git. Nu när vi har en förståelse för mekanikerna bakom Git-grenarna, kan vi ta en djupgående titt på hur veteran Git-användare utnyttjar grenar i deras dagliga arbetsflöde.


Förgrena arbetsflöden

Arbetsflödena som presenteras i detta avsnitt är kännetecknet för Git-baserad revisionskontroll. Den lättvikta, lättmonterade naturen av Gits filialimplementering gör dem till ett av de mest produktiva verktygen i din arsenal för mjukvaruutveckling..

Alla grenar i arbetsflödet roterar runt git grenen, git checkout, och git-sammanslagning kommandon som presenteras tidigare i detta kapitel.

Typer av grenar

Det är ofta användbart att tilldela särskild mening till olika grenar för att organisera ett projekt. Detta avsnitt introducerar de vanligaste typerna av grenar, men kom ihåg att dessa skillnader är rent ytliga - till Git, en gren är en gren.

Alla grenar kan kategoriseras som antingen permanent grenar eller ämnesgrenar. Den förra innehåller huvudprojektets historia (t.ex.., bemästra), medan de senare är tillfälliga grenar som används för att genomföra en specifik ämne, sedan kasseras (t.ex.., något-funktion).

Permanenta grenar

Permanenta grenar är livsnerven i något förråd. De innehåller alla viktiga waypoint för ett mjukvaruprojekt. De flesta utvecklare använder bemästra uteslutande för stabil kod. I dessa arbetsflöden, du aldrig begå sig direkt bemästra-Det är bara en integrationsgren för färdiga funktioner som byggdes i dedikerade ämnesgrenar.

Dessutom lägger många användare till ett andra abstraktionslager i en annan integrationsgren (konventionellt kallad utveckla, även om namnet är tillräckligt). Detta frigör bemästra gren för verkligen stabil kod (t ex offentliga åtaganden) och användningar utveckla som en intern integrationsgren för att förbereda sig för en offentlig release. Till exempel visar följande diagram flera funktioner som är integrerade i utveckla, då en enda, slutlig sammanfoga i bemästra, vilket symboliserar en offentlig utgåva.


Använda bemästra filial uteslutande för offentliggöranden

Ämnesgrenar

Ämnesföreningar faller i allmänhet i två kategorier: funktionen grenar och snabbkorrigeringsgrenar. Funktionsgrenar är tillfälliga grenar som inkapslar en ny funktion eller refaktor, skyddar huvudprojektet från otestad kod. De stämmer typiskt från en annan gren eller en integrationsgren, men inte den "super stabila" grenen.


Utveckla en funktion i en isolerad gren

Hotfix-grenar är av samma karaktär, men de härrör från public release-filialen (t.ex.., bemästra). I stället för att utveckla nya funktioner, är de för att snabbt klistra in huvudlinjen av utveckling. Vanligtvis betyder det buggfixar och andra viktiga uppdateringar som inte kan vänta till nästa stora utgåva.


patchning bemästra med en snabbkorrigeringsgren

Återigen är de meningar som tilldelas var och en av dessa grenar rent konventionella-Git ser ingen skillnad mellan bemästra, utveckla, funktioner och snabbkorrigeringar. Med det i åtanke, var inte rädd för att anpassa dem till dina egna ändamål. Gitans skönhet är dess flexibilitet. När du förstår mekaniken bakom Git-grenar är det enkelt att designa nya arbetsflöden som passar ditt projekt och personlighet.


omräkningar görs långt

Återhämtning är processen att flytta en filial till en ny bas. Gits återskapande förmåga gör filialer ännu mer flexibla genom att tillåta användare att manuellt organisera sina filialer. Som att slå samman, git rebase kräver att filialen checkas ut och tar den nya basen som ett argument:

 git checkout-funktionen git rebase master

Detta rör sig hela något-funktion gren på toppen av bemästra:


omräkningar görs långt något-funktionbemästra gren

Efter rebasen är funktionsgrenen en linjär förlängning av bemästra, vilket är ett mycket renare sätt att integrera förändringar från en gren till en annan. Jämför denna linjära historia med en sammanslagning av bemästra in i något-funktion, vilket resulterar i exakt samma kodbas i den sista snapshoten:


integrera bemästra in i något-funktion med en 3-vägs sammanslagning

Eftersom historien har avvikit, måste Git använda ett extra sammanslagningsfördrag för att kombinera grenarna. Att göra detta många gånger under utveckling av en långsiktig funktion kan resultera i en mycket rörig historia.

Dessa extra sammanslagningar är överflödiga - de existerar bara för att dra ändringar från bemästra in i något-funktion. Vanligtvis vill du att din sammanslagning förbinder sig betyda något som att slutföra en ny funktion. Det är därför många utvecklare väljer att dra i förändringar med git rebase, eftersom det resulterar i en helt linjär historia i funktionsgrenen.

Interaktiv återställning

Interaktiv återställning går ett steg längre och tillåter dig att Byta förbinder dig när du flyttar dem till den nya basen. Du kan ange en interaktiv rabatt med -jag flagga:

 git rebase -i mästare

Detta fyller i en textredigerare med en sammanfattning av varje commit i funktionen, tillsammans med ett kommando som bestämmer på vilket sätt Det ska överföras till den nya basen. Om du till exempel har två förpliktelser i en filial, kan du ange en interaktiv rabatt som följande:

 välj 58dec2a Första begå för ny funktion squash 6ac8a9f Andra begå för ny funktion

Standarden plocka Kommando flyttar den första förbindelsen till den nya basen som den normala git rebase, men då squash kommando berättar Git att kombinera det andra engagemanget med den föregående, så du slutar med ett engagemang som innehåller alla dina ändringar:


Interaktivt återställa något-funktion gren

Git tillhandahåller flera interaktiva återkommande kommandon, vilka var och en sammanfattas i kommentarfältet i konfigurationslistan. Poängen är att interaktiv rebating låter dig fullständigt skriva om en filials historia till dina exakta specifikationer. Det betyder att du kan lägga till så många mellanliggande förpliktelser till en gren som du behöver, och sedan gå tillbaka och fixa dem till meningsfull progression efter det faktum.

Andra utvecklare tror att du är en lysande programmerare, och visste exakt hur man genomför hela funktionen i ett fall. Denna typ av organisation är väldigt viktigt för att stora projekt ska ha en navigerbar historia.

Omskrivningshistorik

Återhämtning är ett kraftfullt verktyg, men du måste vara godtagbar vid din omskrivning av historia. Båda typerna av återhämtning faktiskt inte flytta befintliga förbindelser-de skapa helt nya (betecknas med en asterisk i diagrammet ovan). Om du inspekterar begår som har blivit föremål för en rabatt märker du att de har olika ID, även om de representerar samma innehåll. Detta innebär att man återkommer förstör befintliga förbinder sig att "flytta" dem.

Som du kan tänka dig har detta dramatiska konsekvenser för samarbetande arbetsflöden. Att förstöra ett offentligt engagemang (t.ex. något på bemästra gren) är som att riva ut grunden för allians arbete. Git har ingen aning om hur man kombinerar allas förändringar, och du kommer att ha en massa ursäkta att göra. Vi tar en djupare titt på detta scenario när vi lär oss hur vi kommunicerar med fjärrförvar.

För nu, bara följa den gyllene regeln att återuppta: återkalla aldrig en gren som har drivits till ett offentligt förråd.

Denna lektion representerar ett kapitel från Git Succinctly, en gratis eBook från laget på Syncfusion.