Enkelt sagt er et eksternt lager et som ikke er ditt eget. Det kan være på en sentral server, en annen utviklers personlige datamaskin eller filsystemet ditt. Så lenge du kan få tilgang til den fra en slags nettverksprotokoll, gjør Git det utrolig enkelt å dele bidrag med andre lagre.
Den primære rollen som eksterne repositorier er å representere andre utviklere i ditt eget lager. Grener, derimot, skal bare håndtere prosjektutvikling. Det vil si, ikke forsøk å gi hver utvikler sin egen grense for å arbeide, gi hver et komplett lager og reservere grener for å utvikle funksjoner.
Dette kapittelet begynner med å dekke fjernkontrollens mekanikk, og presenterer deretter de to vanligste arbeidsflytene i Git-basert samarbeid: den sentrale arbeidsflyten og integrator-arbeidsflyten.
Lik git grenen
, de git fjernkontroll
Kommandoen brukes til å administrere tilkoblinger til andre repositorier. Fjernkontroller er ikke noe annet enn bokmerker til andre repositorier - i stedet for å skrive hele banen, lar de deg referere den til et brukervennlig navn. Vi lærer hvordan vi kan bruke disse bokmerkene i Git Below.
Du kan se dine eksisterende fjernkontroller ved å ringe git fjernkontroll
kommandoen uten argumenter:
git fjernkontroll
Hvis du ikke har fjernbetjeninger, vil denne kommandoen ikke sende ut noen informasjon. Hvis du brukte git klon
For å få ditt lager, ser du en opprinnelse
fjernkontroll. Git legger automatisk til denne tilkoblingen, under antagelsen om at du sannsynligvis vil samhandle med den nedover veien.
Du kan be om litt mer informasjon om fjernkontrollene dine med -v
flagg:
git fjernkontroll -v
Dette viser hele banen til depotet. Angi fjernbaner blir diskutert i neste avsnitt.
De git fjernkontroll legg til
kommandoen skaper en ny tilkobling til et eksternt lager.
git fjernkontroll legg til
Etter å ha kjørt denne kommandoen, kan du nå Git-depotet på
ved hjelp av
. Igjen, dette er bare et praktisk bokmerke for et langt baneavn, det gjør det ikke opprett en direkte kobling til andres repository.
Git godtar mange nettverksprotokoller for å spesifisere plasseringen til et eksternt lager, inkludert fil://
, ssh: //
, http: //
, og det er egendefinert git: //
protokoll. For eksempel:
git fjernkontroll legg til noen bruker ssh: //[email protected]/some-user/some-repo.git
Etter å ha kjørt denne kommandoen, kan du få tilgang til depotet på github.com/some-user/some-repo.git
bruker bare noen bruker
. Siden vi brukte ssh: //
Som protokollen blir du sannsynligvis bedt om et SSH-passord før du får lov til å gjøre noe med kontoen. Dette gjør SSH et godt valg for å gi skriveadgang til utviklere, mens HTTP-baner vanligvis brukes til å gi skrivebeskyttet tilgang. Som vi snart oppdager, er dette utformet som en sikkerhetsfunksjon for distribuerte miljøer.
Til slutt kan du slette en ekstern tilkobling med følgende kommando:
git remote rm
Forpliktelser kan være atomgruppen av Git-basert versjonskontroll, men grener er mediet der eksterne repositorier kommuniserer. Fjerngrener handle akkurat som de lokale filialene vi har dekket så langt, bortsett fra at de representerer en filial i andres repository.
Når du har lastet ned en ekstern avdeling, kan du inspisere, slå sammen og utvide den som enhver annen gren. Dette gir en veldig kort læringskurve hvis du forstår hvordan du bruker grener lokalt.
Handlingen om å laste ned grener fra et annet depot er kalt henter. For å hente en ekstern avdeling, kan du spesifisere depotet og grenen du leter etter:
git hente
Eller, hvis du vil laste ned hver gren i
, bare utelate grenavnet. Etter henting kan du se de nedlastede filialene ved å passere -r
alternativ til git grenen
:
git grenen -r
Dette gir deg en filoversikt som ser ut som:
opprinnelse / master opprinnelse / noen-funksjon opprinnelse / en annen-funksjon
Fjerngrener er alltid prefiks med fjernnavnet (opprinnelse/
) for å skille dem fra lokale grener.
Husk, Git bruker eksterne repositorier som bokmerker-ikke sanntidsforbindelser med andre repositorier. Fjerngrener er kopier av de lokale grenene til et annet lager. Utenfor selve hentingen er repositorier helt isolerte utviklingsmiljøer. Dette betyr også at Git aldri automatisk henter grener for å få tilgang til oppdatert informasjon - du må gjøre dette manuelt.
Men dette er en god ting, siden det betyr at du ikke trenger å hele tiden bekymre deg for hva alle andre bidrar til mens du gjør arbeidet ditt. Dette er bare mulig på grunn av den ikke-lineære arbeidsflyten aktivert av Git-grener.
For all hensikt oppfører fjernforgreninger seg som skrivebeskyttede grener. Du kan trygt inspisere deres historie og se deres forpliktelser via git kassen
, men du kan ikke fortsette å utvikle dem før du integrerer dem i ditt lokale lager. Dette gir mening når du vurderer det faktum at fjerngrener er kopier av andre brukeres forpliktelser.
De ...
syntaks er veldig nyttig for filtrering av logghistorikk. Følgende kommando viser for eksempel nye oppdateringer fra opprinnelse / herre
som ikke er i din lokale herre
gren. Det er vanligvis en god ide å kjøre dette før du slår sammen endringer, slik at du vet nøyaktig hva du integrerer:
git log master ... origin / master
Hvis dette utgir noen forpliktelser, betyr det at du står bak det offisielle prosjektet og du bør sannsynligvis oppdatere lageret ditt. Dette er beskrevet i neste avsnitt.
Det er mulig å sjekke fjerngrener, men det vil sette deg i en frittliggende HODE
stat. Dette er trygt for å vise andre brukeres endringer før de integreres, men eventuelle endringer du legger til, vil gå tapt, med mindre du oppretter en ny lokal grenavtale for å referere dem.
Selvfølgelig er hele poenget med å integrere de resulterende avdelingene i ditt lokale prosjekt. La oss si at du er en bidragsyter til et åpen kildekode-prosjekt, og du har jobbet med en funksjon som heter noen-feature
. Som det "offisielle" prosjektet (typisk påpekt av opprinnelse
) beveger seg fremover, kan det være lurt å innlemme sin nye forpliktelse til ditt arkiv. Dette vil sikre at funksjonen din fortsatt fungerer med blødende utviklingen.
Heldigvis kan du bruke nøyaktig samme git fusjon
kommandoen for å inkludere endringer fra opprinnelse / herre
inn i filialen din:
git checkout noen-funksjon git hente opprinnelse git fusjon opprinnelse / master
Siden historien din har avviklet, resulterer dette i en 3-veisfusjon, hvoretter din noen-feature
gren har tilgang til den mest oppdaterte versjonen av det offisielle prosjektet.
herre
inn i en avdeling Men ofte fusjonere med opprinnelse / herre
bare for å trekke inn oppdateringer resulterer til slutt i en historie full av meningsløse sammenføyningsposter. Avhengig av hvor tett funksjonen din trenger for å spore resten av koden, kan det være bedre å integrere endringer på nytt.
git checkout noen-funksjon git hente opprinnelse git rebase opprinnelse / master
Som med lokal gjenoppretting, skaper dette en perfekt lineær historie uten overflødig sammenslåing:
herre
Tilbakestilling / sammenslåing av eksterne grener har nøyaktig samme avvik som beskrevet i kapitlet om lokale grener.
Siden henting / fusjonssekvensen er en så vanlig forekomst i distribuert utvikling, gir Git en dra
kommandoen som en praktisk snarvei:
git pull origin / master
Dette henter opprinnelsens hovedgren, og smelter den sammen i den nåværende grenen i ett trinn. Du kan også passere --rebase
alternativ å bruke git rebase
i stedet for git fusjon
.
For å utfylle git hente
kommando, gir Git også en trykk
kommando. Pushing er nesten Det motsatte av å hente, ved å hente importgrener, mens du presser eksportgrener til et annet lager.
git push
Kommandoen ovenfor sender den lokale
til det angitte fjernlageret. Unntatt, i stedet for a fjern gren, git push
skaper en lokal gren. For eksempel, kjører git push mary min-funksjonen
i ditt lokale lager vil se ut som følgende fra Marias perspektiv (ditt depot vil ikke påvirkes av pushen).
Legg merke til det min-feature
er en lokal gren i Marias repository, mens det ville være en fjern gren hadde hun hentet det selv.
Dette gjør at det skjer en farlig operasjon. Tenk deg at du utvikler deg i ditt eget lokale depot, når plutselig en ny lokal avdeling viser deg ut av ingenting. Men, repositories skal fungere som helt isolerte utviklingsmiljøer, så hvorfor skal det git push
selv eksisterer? Som vi vil oppdage kort, er pushing et nødvendig verktøy for å opprettholde offentlige Git-repositorier.
Nå som vi har en grunnleggende ide om hvordan Git samhandler med andre repositorier, kan vi diskutere virkelige arbeidsflyter som støttes av disse kommandoene. De to vanligste samarbeidsmodellene er: Den sentrale arbeidsflyten og integrator-arbeidsflyten. SVN- og CVS-brukere bør være ganske komfortable med Gits smak av sentralisert utvikling, men ved hjelp av Git betyr det at du også kan utnytte sin høye effektivitetskombinasjonsmuligheter. Integrator-arbeidsflyten er en typisk distribuert samarbeidsmodell og er ikke mulig i rent sentraliserte systemer.
Når du leser gjennom disse arbeidsflytene, vær oppmerksom på at Git behandler alle repositorier som likeverdige. Det er ikke noe "master" repository i henhold til Git som det er med SVN eller CVS. Den "offisielle" kodebasen er bare en prosjektkonvensjon - den eneste grunnen til at det er det offisielle depotet, er fordi det er hvor alles opprinnelse
fjernpunkter.
Hver samarbeidsmodell involverer minst en offentlig lagringsplass som fungerer som en poeng for innlegg for flere utviklere. Offentlige repositorier har den unike begrensningen av å være naken-de må ikke ha en arbeidskatalog. Dette forhindrer at utviklere ved et uhell overskriver hverandres arbeid med git push
. Du kan opprette et blott arkiv ved å passere --naken
alternativ til git init
:
git init --bare
Offentlige lagre bør bare fungere som lagringsanlegg-ikke utviklingsmiljøer. Dette blir formidlet ved å legge til en .git
utvidelse til depotets filbane, siden den interne databasen ligger i prosjektroten i stedet for .git
katalogen. Så et komplett eksempel kan se ut som:
git init --bare some-repo.git
Bortsett fra mangel på en arbeidskatalog, er det ikke noe spesielt med et blott repository. Du kan legge til eksterne tilkoblinger, trykke på den og trekke fra den på vanlig måte.
Den sentraliserte arbeidsflyten passer best til små lag der hver utvikler har skriveadgang til depotet. Det tillater samarbeid ved å bruke et enkelt sentralt arkiv, mye som SVN- eller CVS-arbeidsflyten. I denne modellen, alle Endringer må deles gjennom sentralarkivet, som vanligvis lagres på en server for å aktivere Internett-basert samarbeid.
Utviklere arbeider individuelt i sitt eget lokale depot, som er helt isolert fra alle andre. Når de har fullført en funksjon og er klare til å dele koden, rydder de opp, integrerer den i deres lokale herre
, og skyv den til sentralarkivet (f.eks., opprinnelse
). Dette betyr også at hver utvikler trenger SSH-tilgang til sentralarkivet.
Deretter kan alle andre hente de nye forpliktelsene og inkorporere dem i sine lokale prosjekter. Igjen kan dette gjøres med enten en fusjon eller en rebase, avhengig av lagets konvensjoner.
Dette er kjerneprosessen bak sentraliserte arbeidsflyter, men det treffer en støt når flere brukere prøver å samtidig oppdatere sentralarkivet. Tenk deg et scenario der to utviklere ferdig en funksjon, fusjonerte den inn i deres lokale herre
, og prøvde å publisere det samtidig (eller i nærheten av det).
Den som kommer til serveren først, kan presse sine forpliktelser som normalt, men så kommer den andre utvikleren fast med en divergerende historie, og Git kan ikke utføre en fortrykningssammenheng. For eksempel, hvis en utvikler ved navn John skulle presse sine endringer rett før Mary, ville vi se en konflikt i Marys repository:
Den eneste måten å gjøre opprinnelse
s mester (oppdatert av john) match marias herre
er til skrive Johannes forpliktelse. Selvfølgelig vil dette være veldig dårlig, så Git avbryter push og utdataene en feilmelding:
! [rejected] master -> master (ikke-fast-forward) feil: klarte ikke å trykke noen refs til 'some-repo.git'
For å rette opp denne situasjonen, må Mary synkronisere med sentralarkivet. Da vil hun kunne presse sine endringer på vanlig måte.
git hente opprinnelse master git rebase opprinnelse / master git push opphav mester
Annet enn det, er den sentrale arbeidsflyten relativt enkel. Hver utvikler forblir i sitt eget lokale lager, med jevne mellomrom trekker / skyver til sentralarkivet for å holde alt oppdatert. Det er en praktisk arbeidsflyt å konfigurere, da bare én server er nødvendig, og den utnytter eksisterende SSH-funksjonalitet.
Integrator-arbeidsflyten er en distribuert utviklingsmodell der alle brukerne opprettholder sin egen offentlig depot, i tillegg til deres private. Den finnes som en løsning på sikkerhets- og skalerbarhetsproblemer som er knyttet til den sentrale arbeidsflyten.
Den største ulempen ved den sentraliserte arbeidsflyten er det hver Utviklerens behov gir tilgang til hele prosjektet. Dette er greit hvis du jobber med et lite team av pålitelige utviklere, men forestill deg et scenario der du jobber med et open source-programvareprosjekt, og en fremmed fant en feil, fikset det og ønsker å innlemme oppdateringen i hovedprosjekt. Du vil sannsynligvis ikke gi ham eller henne presset tilgang til sentralarkivet, siden han eller hun kunne begynne å presse alle slags tilfeldige forpliktelser, og du ville effektivt miste kontroll over prosjektet.
Men hva du kan gjøre, er å fortelle bidragsyteren å skifte endringene til hans eller hennes egen offentlig lager. Deretter kan du trekke sin feilretting inn i ditt private arkiv for å sikre at den ikke inneholder noen svart kode. Hvis du godtar hans bidrag, er alt du trenger å gjøre, flette dem inn i en lokal gren og skyve den til hovedregisteret som vanlig. Du har blitt en integrator, i tillegg til en vanlig utvikler:
I denne arbeidsflyten trenger hver utvikler bare å få tilgang til hans eller hennes egen offentlig lager. Bidragsyteren bruker SSH til å presse til hans eller hennes offentlige arkiv, men integratoren kan hente endringene over HTTP (en skrivebeskyttet protokoll). Dette gir et sikrere miljø for alle, selv når du legger til flere samarbeidspartnere:
Vær oppmerksom på at teamet fortsatt må være enig om et enkelt "offisielt" lager for å trekke fra - ellers ville endringer bli brukt utenfor rekkefølge, og alle ville raskt synkronisere seg. I diagrammet ovenfor er "Ditt offentlige repo" det offisielle prosjektet.
Som integrator må du holde øye med flere fjernkontroller enn du ville i den sentrale arbeidsflyten, men dette gir deg frihet og sikkerhet for å inkludere endringer fra enhver utvikler uten å true prosjektets stabilitet.
I tillegg har integrator-arbeidsflyten ingen enkel tilgangspunkt for å tjene som et chokeringspunkt for samarbeid. I sentraliserte arbeidsflyter må alle være helt oppdaterte før de publiserer endringer, men det er ikke tilfelle i distribuerte arbeidsflyter. Igjen, dette er et direkte resultat av den ikke-lineære utviklingsstilen aktivert av Gits grensesnittimplementering.
Dette er store fordeler for store open source-prosjekter. Å organisere hundrevis av utviklere for å jobbe med et enkelt prosjekt ville ikke være mulig uten sikkerhet og skalerbarhet av distribuert samarbeid.
Å støtte disse sentrale og distribuerte samarbeidsmodellene var alt Git var ment å gjøre. Arbeidsoversikten, scenen, begavene, filialene og fjernkontrollene var alle spesielt designet for å aktivere disse arbeidsflytene, og nesten alt i Git dreier seg om disse komponentene.
Sann på UNIX-filosofien, var Git utformet som en serie interoperable verktøy, ikke et enkelt monolitisk program. Når du fortsetter å utforske Gits mange muligheter, vil du oppdage at det er veldig enkelt å tilpasse individuelle kommandoer til helt nye arbeidsflyter.
Jeg lar deg nå bruke disse konseptene til virkelige prosjekter, men når du begynner å innlemme Git i din daglige arbeidsflyt, husk at det ikke er en sølvkule for prosjektledelse. Det er bare et verktøy for å spore filene, og ingen mengde intim Git kunnskap kan gjøre opp for et tilfeldig sett av konvensjoner i et utviklingslag.
Denne leksjonen representerer et kapittel fra Git Succinctly, en gratis eBok fra teamet på Syncfusion.