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.
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.
Git skiljer grenfunktionalitet till några olika kommandon. De git grenen
Kommando används för att lista, skapa eller ta bort grenar.
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.
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.
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.
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.
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.
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.
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.
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 ...
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.
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 ä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:
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.
Det första scenariot ser ut så här:
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 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.
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:
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.
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.
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 iAutomatisk 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.
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.
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 ä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.
bemästra
filial uteslutande för offentliggöranden Ä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.
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.
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.
Å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
:
något-funktion
på bemä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:
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 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:
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.
Å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.