Enkelt uttryckt är ett fjärrförråd ett som inte är ditt eget. Det kan vara på en central server, en annan utvecklars personliga dator, eller till och med ditt filsystem. Så länge du kan komma åt det från ett slags nätverksprotokoll, gör Git det otroligt enkelt att dela med dig av andra arkiv.
Den primära roll som fjärrförråd är att representera andra utvecklare i ditt eget förråd. Grenar å andra sidan bör bara ta itu med projektutveckling. Det vill säga, försök inte ge varje utvecklare sin egen filial för att arbeta, ge var och en ett komplett förråd och reservera filialer för att utveckla funktioner.
Det här kapitlet börjar genom att täcka fjärrkontrollens mekanik och presenterar sedan de två vanligaste arbetsflödena i Git-baserat samarbete: det centrala arbetsflödet och integratorns arbetsflöde.
Liknande git grenen
, de git fjärrkontroll
Kommando används för att hantera anslutningar till andra repositorier. Fjärrkontrollen är ingenting annat än bokmärken till andra repositorier - istället för att skriva hela sökvägen, får de dig att referera till det med ett användarvänligt namn. Vi lär oss hur vi kan använda dessa bokmärken inom Git Below.
Du kan se dina befintliga fjärrkontroller genom att ringa git fjärrkontroll
kommando utan argument:
git fjärrkontroll
Om du inte har några fjärrkontroller, kommer det här kommandot inte att ge någon information. Om du använde git klon
för att få ditt förråd ser du en ursprung
avlägsen. Git lägger automatiskt till den här anslutningen, under antagandet att du förmodligen vill interagera med den på vägen.
Du kan begära lite mer information om dina fjärrkontroller med -v
flagga:
git remote -v
Detta visar hela sökvägen till förvaret. Specificera fjärrvägar diskuteras i nästa avsnitt.
De git remote add
kommandot skapar en ny anslutning till ett fjärrförråd.
git remote add
När du har kört det här kommandot kan du nå Git-förvaret på
använder sig av
. Återigen är det här bara ett bekvämt bokmärke för ett långt sökväg - det gör det inte skapa en direktlänk till någon annans repository.
Git accepterar många nätverksprotokoll för att specificera platsen för ett fjärrförvar, inklusive fil://
, ssh: //
, http: //
, och dess anpassade git: //
protokoll. Till exempel:
git remote lägg till en användare ssh: //[email protected]/some-user/some-repo.git
När du har kört det här kommandot kan du komma åt förvaret på github.com/some-user/some-repo.git
använder endast något-användare
. Sedan vi använde ssh: //
Som protokoll kommer du förmodligen att bli uppmanad till ett SSH-lösenord innan du får göra något med kontot. Detta gör SSH till ett bra val för att ge skrivåtkomst till utvecklare, medan HTTP-banor vanligtvis används för att tillhandahålla skrivskyddad åtkomst. Som vi snart kommer att upptäcka är detta utformat som en säkerhetsfunktion för distribuerade miljöer.
Slutligen kan du ta bort en fjärranslutning med följande kommando:
git remote rm
Förpliktelser kan vara atomenheten i Git-baserad versionskontroll, men grenar är mediet där fjärrförvaringar kommunicerar. Fjärrgrenar agera precis som de lokala grenarna vi hittills har täckt, förutom att de representerar en filial i någon annans förråd.
När du har laddat ner en avdelnings filial kan du inspektera, slå samman och utöka den som någon annan filial. Detta ger en mycket kort inlärningskurva om du förstår hur man använder grenar lokalt.
Uppgiften att ladda ner filialer från ett annat förråd heter hämta. För att hämta en fjärranslutning kan du ange förvaret och filialen du letar efter:
git hämta
Eller om du vill ladda ner varje gren i
, helt enkelt släppa filnamnet. Efter hämtning kan du se de nedladdade filialerna genom att passera -r
alternativ till git grenen
:
git grenen -r
Detta ger dig en fillista som ser ut som:
Ursprung / Mästare Ursprung / En del-funktion Ursprung / En annan funktion
Fjärrgrenar är alltid prefixade med fjärrnavnet (ursprung/
) för att skilja dem från lokala grenar.
Kom ihåg att Git använder externa repositories som bokmärken-inte realtidsanslutningar med andra repositorier. Fjärrgrenar är kopior av de lokala grenarna i ett annat förråd. Utanför den faktiska hämtningen är repositorier helt isolerade utvecklingsmiljöer. Det betyder också att Git aldrig automatiskt hämtar filialer för att få tillgång till uppdaterad information. Du måste göra det manuellt.
Men det här är en bra sak, eftersom det betyder att du inte behöver ständigt oroa sig för vad alla andra bidrar med när du gör ditt jobb. Detta är endast möjligt tack vare det icke-linjära arbetsflödet aktiverat av Git-grenar.
För alla ändamål uppför sig avlägsen filialer som skrivskyddade filialer. Du kan säkert inspektera sin historia och visa sina förpliktelser via git checkout
, men du kan inte fortsätta utveckla dem innan du integrerar dem i ditt lokala arkiv. Det här är meningsfullt när man beaktar det faktum att avlägsna grenar är kopior av andra användares förpliktelser.
De ...
Syntaxen är mycket användbar för att filtrera logghistorik. Följande kommando visar till exempel nya uppdateringar från ursprung / master
som inte finns i din lokala bemästra
gren. Det är generellt en bra idé att köra detta innan du slår samman förändringar så att du vet exakt vad du integrerar:
git log master ... ursprung / master
Om det här kommit ut, betyder det att du står bakom det officiella projektet och du borde noga uppdatera ditt förråd. Detta beskrivs i nästa avsnitt.
Det är möjligt att kassa avlägsna grenar, men det kommer att sätta dig i en fristående HUVUD
stat. Det här är säkert för att visa andra användares ändringar innan de integreras, men eventuella ändringar du lägger till kommer att gå vilse om du inte skapar ett nytt lokaltips för att referera till dem.
Självklart är hela hämtpunkten att integrera de avlägsna grenarna i ditt lokala projekt. Låt oss säga att du är en bidragsyter till ett open source-projekt, och du har arbetat med en funktion som heter något-funktion
. Som det "officiella" projektet (vanligtvis pekade på av ursprung
) går framåt, kanske du vill integrera sina nya förbindelser i ditt förråd. Detta skulle säkerställa att din funktion fortfarande fungerar med den blödande utvecklingen.
Lyckligtvis kan du använda exakt samma git-sammanslagning
kommandot att införliva ändringar från ursprung / master
in i din funktionsgren:
git checkout någon funktion git hämta ursprung git sammanfoga ursprung / mästare
Eftersom din historia har divergerat resulterar det i en 3-vägsfusion, varefter din något-funktion
filialen har tillgång till den mest aktuella versionen av det officiella projektet.
bemästra
in i en funktionsgren Sammanfogar emellertid ofta med ursprung / master
bara för att dra in uppdateringar resulterar så småningom i en historia fylld med meningslösa sammanslagningar. Beroende på hur nära din funktion behöver spåra resten av kodbasen, kan återhämtning vara ett bättre sätt att integrera ändringar:
git checkout någon funktion git hämta ursprung git rebase ursprung / mästare
Liksom med lokal återställning skapar detta en perfekt linjär historia fri från överflödiga sammanslagningar:
bemästra
Återuppbyggande / sammanslagning av avdelningar har exakt samma avvägningar som diskuteras i kapitlet om lokala filialer.
Eftersom hämtnings- / fusionssekvensen är en sådan vanlig förekomst i distribuerad utveckling, ger Git en dra
kommandot som en bekväm genväg:
git pull origin / master
Detta hämtar ursprungets huvudgren, och slår sedan samman den i nuvarande gren i ett steg. Du kan också vidarebefordra --basåren
alternativ att använda git rebase
istället för git-sammanslagning
.
För att komplettera git hämta
kommando, ger Git också en tryck
kommando. Pushing är nästan Det motsatta av att hämta, i att hämta importgrenar, samtidigt som man trycker exportgrenar till ett annat förråd.
git push
Ovanstående kommando skickar den lokala
till det angivna fjärrförvaret. Utom i stället för a avlägsen gren, git push
skapar en lokal gren. Till exempel körs git push mary my-funktionen
i ditt lokala förråd ser ut som följande från Marias perspektiv (ditt förråd kommer inte att påverkas av pushen).
Lägg märke till att my-funktion
är en lokal gren i Marias förråd, medan det skulle vara en avlägsen gren hade hon hämtat det själv.
Detta gör att en farlig operation drivs. Tänk dig att du utvecklar dig i ditt eget lokala förråd, när det plötsligt uppstår en ny lokal filial upp ur ingenstans. Men repositories ska fungera som helt isolerade utvecklingsmiljöer, så varför borde det git push
ens existera? Som vi kommer att upptäcka inom kort är pushing ett nödvändigt verktyg för att behålla offentliga Git-repositorier.
Nu när vi har en grundläggande uppfattning om hur Git interagerar med andra repositorier, kan vi diskutera verkliga arbetsflöden som stöds av dessa kommandon. De två vanligaste samarbetsmodellerna är: det centrala arbetsflödet och integrationsarbetet. SVN- och CVS-användare borde vara ganska bekväma med Gits smak av centraliserad utveckling, men med hjälp av Git betyder du att du också kan utnyttja dess höga effektivitetsfusioner. Integrator-arbetsflödet är en typisk distribuerad samarbetsmodell och är inte möjlig i rent centraliserade system.
När du läser igenom dessa arbetsflöden, kom ihåg att Git behandlar alla repositories som jämlikar. Det finns inget "mästare" förråd enligt Git som det finns med SVN eller CVS. Den "officiella" kodbasen är bara en projektkonvention - den enda anledningen till att det är det officiella förvaret är att det är där allas ursprung
fjärrpunkter.
Varje samarbetsmodell innebär minst en offentlig repository som fungerar som en punkt-of-entry för flera utvecklare. Offentliga repositorier har den unika begränsningen av att vara bar-De får inte ha en arbetsregister. Detta förhindrar att utvecklare från misstag överskriver varandras arbete med git push
. Du kan skapa ett blott repository genom att passera --bar
alternativ till git init
:
git init --bare
Offentliga förråd bör endast fungera som lagerlokaler-inte utvecklingsmiljöer. Detta förmedlas genom att lägga till en .git
förlängning till arkivets filväg, eftersom den interna arkivdatabasen ligger i projektrot i stället för .git
underkatalog. Så, ett komplett exempel kan se ut:
git init --bare some-repo.git
Bortsett från brist på en arbetsförteckning finns det inget särskilt om ett blottförråd. Du kan lägga till fjärranslutningar, trycka på den och dra från den på vanligt sätt.
Det centraliserade arbetsflödet passar bäst för små grupper där varje utvecklare har skrivåtkomst till förvaret. Det möjliggör samarbete genom att använda ett enda centralförråd, ungefär som SVN eller CVS-arbetsflödet. I den här modellen, Allt Ändringar måste delas via centraldatabasen, som vanligtvis lagras på en server för att möjliggöra internetbaserat samarbete.
Utvecklare arbetar individuellt i sitt eget lokala förråd, vilket är helt isolerat från alla andra. När de har slutfört en funktion och är redo att dela sin kod, rensar de upp den, integrerar den i deras lokala bemästra
, och tryck det till centralförvaret (t.ex.., ursprung
). Detta innebär också att varje utvecklare behöver SSH-åtkomst till centralförvaret.
Då kan alla andra hämta de nya förbindelserna och införliva dem i sina lokala projekt. Återigen kan detta göras med antingen en sammanslagning eller en rebase, beroende på ditt lags konventioner.
Det här är kärnprocessen bakom centraliserade arbetsflöden, men det stöter på stötar när flera användare försöker samtidigt uppdatera det centrala förvaret. Föreställ dig ett scenario där två utvecklare färdigställde en funktion, slog den samman i deras lokala bemästra
, och försökte publicera det samtidigt (eller nära det).
Den som kommer till servern först kan driva sina förpliktelser som vanligt, men då kommer den andra utvecklaren fast med en divergerande historia, och Git kan inte utföra en snabbspolning. Om en utvecklare med namnet John skulle till exempel trycka sina ändringar strax före Mary så skulle vi se en konflikt i Marys repository:
Det enda sättet att göra ursprung
s mästare (uppdaterad av john) matcha marias bemästra
är att skriva över Johns begåvning. Självklart skulle detta vara väldigt dåligt, så Git avbryter pushen och matar ut ett felmeddelande:
! [rejected] master -> master (icke-snabbspolning) -fel: misslyckades med att trycka några refs till 'some-repo.git'
För att avhjälpa denna situation behöver Mary synkronisera med centralförvaret. Då kommer hon att kunna driva sina förändringar på vanligt sätt.
git hämta ursprung master git rebase ursprung / master git push origin master
Annat än det är det centraliserade arbetsflödet relativt enkelt. Varje utvecklare stannar i sitt eget lokala förråd, som regelbundet drar / skjuter till centralförvaret för att hålla allt uppdaterat. Det är ett bekvämt arbetsflöde att konfigurera, eftersom endast en server krävs och det utnyttjar befintlig SSH-funktionalitet.
Integrator-arbetsflödet är en distribuerad utvecklingsmodell där alla användare behåller sina egna offentlig förvar, förutom deras privata. Det finns som en lösning på säkerhetsproblemen och skalbarhetsproblemen i det centrala arbetsflödet.
Den största nackdelen med det centraliserade arbetsflödet är det varje utvecklaren behöver trycka åtkomst till hela projektet. Det här är bra om du arbetar med ett litet team av betrodda utvecklare, men föreställ dig ett scenario där du arbetar med ett program med öppen källkod och en främling hittade en bugg, fixar den och vill integrera uppdateringen i huvudprojekt. Du vill förmodligen inte ge honom eller henne en push tillträde till centralförvaret, eftersom han eller hon kan börja driva alla typer av slumpmässiga förpliktelser, och du skulle effektivt förlora kontrollen över projektet.
Men vad du kan göra är att berätta bidragsgivaren att driva ändringarna till hans eller hennes egen offentligt förråd. Därefter kan du dra sin buggfix i ditt privata arkiv för att se till att det inte innehåller någon svart kod. Om du godkänner hans bidrag, allt du behöver göra är att slå dem samman i en lokal gren och trycka det till huvudförvaret som vanligt. Du har blivit en integrator, förutom en vanlig utvecklare:
I det här arbetsflödet behöver varje utvecklare bara driva åtkomst till hans eller hennes egen offentligt förråd. Bidragsgivaren använder SSH för att trycka till sitt offentliga förvar, men integratorn kan hämta ändringarna via HTTP (ett skrivskyddat protokoll). Detta ger en säkrare miljö för alla, även när du lägger till fler medarbetare:
Observera att laget fortfarande måste vara överens om att ett enda "officiellt" förvar för att dra från - annars skulle ändringar göras utan ordning och alla skulle sluta synkronisera mycket snabbt. I det ovanstående diagrammet är "Your Public Repo" det officiella projektet.
Som en integratör måste du hålla reda på fler fjärrkontroller än vad du skulle göra i det centrala arbetsflödet, men det ger dig frihet och säkerhet för att införliva förändringar från någon utvecklare utan att hota projektets stabilitet.
Dessutom har integrator-arbetsflödet ingen enkel åtkomstpunkt för att fungera som en chokeringspunkt för samarbete. I centrala arbetsflöden måste alla vara helt uppdaterade innan de publicerar ändringar, men det är inte fallet i distribuerade arbetsflöden. Återigen är detta ett direkt resultat av den olinjära utvecklingsstilen som aktiveras av Gits filialimplementation.
Det här är stora fördelar för stora open source-projekt. Att organisera hundratals utvecklare för att arbeta på ett enda projekt skulle inte vara möjligt utan säkerhet och skalbarhet hos distribuerat samarbete.
Att stödja dessa centraliserade och distribuerade samarbetsmodeller var allt Git någonsin menat att göra. Arbetskatalogen, scenen, förbindelserna, filialerna och fjärrkontrollerna var alla specifikt utformade för att möjliggöra dessa arbetsflöden och nästan allt i Git kretsar kring dessa komponenter.
Trogen på UNIX-filosofin var Git utformad som en serie interoperabla verktyg, inte ett enda monolitiskt program. När du fortsätter att utforska Gits många möjligheter, finner du att det är väldigt enkelt att anpassa individuella kommandon till helt nya arbetsflöden.
Jag lämnar nu det till dig att tillämpa dessa begrepp på verkliga projekt, men när du börjar integrera Git i ditt dagliga arbetsflöde, kom ihåg att det inte är en silverkula för projektledning. Det är bara ett verktyg för att spåra dina filer, och ingen mängd intim Git-kunskap kan kompensera för en slumpmässig uppsättning konventioner inom ett utvecklingslag.
Denna lektion representerar ett kapitel från Git Succinctly, en gratis eBook från laget på Syncfusion.