In poche parole, un repository remoto è uno che non è il tuo. Potrebbe essere su un server centrale, sul personal computer di un altro sviluppatore o persino sul tuo file system. Finché puoi accedervi da un qualche tipo di protocollo di rete, Git rende incredibilmente facile condividere i contributi con altri repository.
Il ruolo principale degli archivi remoti è quello di rappresentare altri sviluppatori all'interno del proprio repository. Le filiali, d'altra parte, dovrebbero occuparsi solo dello sviluppo del progetto. Vale a dire, non provare a dare a ogni sviluppatore la propria filiale su cui lavorare: dai a ciascuno un repository completo e riserva le filiali per lo sviluppo di funzionalità.
Questo capitolo inizia trattando la meccanica dei telecomandi e quindi presenta i due flussi di lavoro più comuni della collaborazione basata su Git: il flusso di lavoro centralizzato e il flusso di lavoro dell'integratore.
Simile a ramo di git
, il git remote
il comando viene utilizzato per gestire le connessioni ad altri repository. I telecomandi non sono altro che segnalibri per altri repository: invece di digitare il percorso completo, ti consentono di fare riferimento a un nome intuitivo. Impareremo come utilizzare questi segnalibri all'interno di Git Below.
È possibile visualizzare i telecomandi esistenti chiamando il git remote
comando senza argomenti:
git remote
Se non ci sono telecomandi, questo comando non produrrà alcuna informazione. Se hai usato git clone
per ottenere il tuo repository, vedrai un origine
a distanza. Git aggiunge automaticamente questa connessione, partendo dal presupposto che probabilmente vorrai interagire con esso lungo la strada.
Puoi richiedere un po 'più di informazioni sui telecomandi con -v
bandiera:
git remote -v
Questo visualizza il percorso completo del repository. La specifica dei percorsi remoti è discussa nella prossima sezione.
Il git remote add
comando crea una nuova connessione a un repository remoto.
git remote add
Dopo aver eseguito questo comando, puoi raggiungere il repository Git su
utilizzando
. Ancora una volta, questo è semplicemente un segnalibro conveniente per un nome lungo percorso - lo fa non creare un collegamento diretto nel repository di qualcun altro.
Git accetta molti protocolli di rete per specificare la posizione di un repository remoto, inclusi file://
, ssh: //
, http: //
, e la sua usanza idiota://
protocollo. Per esempio:
git remote aggiungi utente ssh: //[email protected]/some-user/some-repo.git
Dopo aver eseguito questo comando, è possibile accedere al repository all'indirizzo github.com/some-user/some-repo.git
usando solo alcuni utenti
. Dal momento che abbiamo usato ssh: //
come protocollo, probabilmente ti verrà richiesta una password SSH prima che ti sia permesso di fare qualsiasi cosa con l'account. Ciò rende SSH una buona scelta per garantire l'accesso in scrittura agli sviluppatori, mentre i percorsi HTTP sono generalmente utilizzati per fornire accesso in sola lettura. Come scopriremo presto, questo è stato progettato come una funzionalità di sicurezza per ambienti distribuiti.
Infine, puoi eliminare una connessione remota con il seguente comando:
git remote rm
I commit possono essere l'unità atomica del controllo di versione basato su Git, ma rami sono il mezzo in cui comunicano i repository remoti. Rami remoti agire proprio come i rami locali che abbiamo coperto finora, tranne che rappresentano un ramo nel repository di qualcun altro.
Una volta scaricato un ramo remoto, puoi ispezionarlo, unirlo ed estenderlo come qualsiasi altro ramo. Ciò consente una curva di apprendimento molto breve se si capisce come utilizzare i rami localmente.
Viene chiamato l'atto di scaricare i rami da un altro repository attraente. Per recuperare un ramo remoto, puoi specificare il repository e il ramo che stai cercando:
git fetch
Oppure, se vuoi scaricare ogni filiale in
, semplicemente ometti il nome del ramo. Dopo aver recuperato, puoi vedere i rami scaricati passando il -r
opzione a ramo di git
:
git branch -r
Questo ti dà una lista di filiali che assomiglia a qualcosa:
origine / origine principale / origine di alcune caratteristiche / un'altra funzione
I rami remoti hanno sempre come prefisso il nome remoto (origine/
) per distinguerli dai rami locali.
Ricorda, Git utilizza archivi remoti come segnalibri-connessioni non in tempo reale con altri repository. I rami remoti sono copie delle filiali locali di un altro repository. Al di fuori del recupero effettivo, i repository sono ambienti di sviluppo completamente isolati. Ciò significa anche che Git non preleverà mai automaticamente i rami per accedere alle informazioni aggiornate: è necessario farlo manualmente.
Ma questa è una buona cosa, poiché significa che non devi preoccuparti costantemente di ciò che gli altri stanno contribuendo mentre fai il tuo lavoro. Questo è possibile solo a causa del flusso di lavoro non lineare abilitato dai rami di Git.
A tutti gli effetti, i rami remoti si comportano come rami di sola lettura. Puoi controllare in sicurezza la loro storia e visualizzare i loro commit tramite git checkout
, ma non puoi continuare a svilupparli prima di integrarli nel tuo repository locale. Questo ha senso quando si considera il fatto che i rami remoti sono copie dei commit di altri utenti.
Il ...
la sintassi è molto utile per filtrare la cronologia del registro. Ad esempio, il seguente comando visualizza tutti i nuovi aggiornamenti da origin / master
che non sono nel tuo locale maestro
ramo. In genere è consigliabile eseguirlo prima di unire le modifiche in modo da sapere esattamente cosa si sta integrando:
git log master ... origine / master
Se questo produce un commit, significa che sei dietro al progetto ufficiale e probabilmente dovresti aggiornare il tuo repository. Questo è descritto nella prossima sezione.
È possibile effettuare il checkout di filiali remote, ma ti metterà in una posizione distaccata CAPO
stato. Questo è sicuro per la visualizzazione delle modifiche di altri utenti prima di integrarli, ma qualsiasi modifica aggiunta verrà persa a meno che non si crei un nuovo suggerimento di ramo locale per farvi riferimento.
Naturalmente, il punto di partenza è integrare i rami remoti risultanti nel progetto locale. Supponiamo che tu contribuisca a un progetto open source e che tu stia lavorando a una funzione chiamata un po 'di funzionalità
. Come il progetto "ufficiale" (tipicamente indicato da origine
) avanza, potresti voler incorporare i nuovi commit nel tuo repository. Ciò assicurerebbe che la tua funzionalità funzioni ancora con sviluppi all'avanguardia.
Fortunatamente, puoi usare lo stesso identico git si fondono
comando per incorporare le modifiche da origin / master
nel tuo branch funzionalità:
git checkout some-feature git fetch origine git unione origine / master
Dal momento che la tua cronologia è divergente, ciò si traduce in un'unione a 3 vie, dopo di che la tua un po 'di funzionalità
filiale ha accesso alla versione più aggiornata del progetto ufficiale.
maestro
in un ramo di funzionalità Tuttavia, frequentemente si fondono con origin / master
solo per inserire aggiornamenti alla fine risulta una storia piena di commit di fusione senza significato. A seconda di quanto strettamente la tua funzione deve tracciare il resto della base di codice, il rebasing potrebbe essere un modo migliore per integrare le modifiche:
git checkout some-feature git fetch origine git rebase origine / master
Come con il rebasing locale, ciò crea una storia perfettamente lineare priva di commit di unione superflui:
maestro
La ridefinizione / fusione dei rami remoti ha gli stessi identici compromessi discussi nel capitolo sulle filiali locali.
Dato che la sequenza di recupero / unione è una tale circostanza comune nello sviluppo distribuito, Git fornisce a Tirare
comando come una comoda scorciatoia:
git pull origin / master
Questo recupera il ramo principale dell'origine e quindi lo unisce al ramo corrente in un unico passaggio. Puoi anche passare il --rebase
opzione da usare git rebase
invece di git si fondono
.
Per completare il git fetch
comando, Git fornisce anche a Spingere
comando. La spinta è quasi l'opposto del recupero, in quel branco di importazioni impetuoso, mentre spinge i rami delle esportazioni in un altro repository.
spingere
Il comando precedente invia il locale
al repository remoto specificato. Tranne, invece di a a distanza ramo, spingere
crea a Locale ramo. Ad esempio, in esecuzione git push mary my-feature
nel tuo repository locale apparirà come nella prospettiva di Mary (il tuo repository non sarà influenzato dalla spinta).
Notare che my-funzione
è un Locale ramo nel deposito di Maria, mentre sarebbe a a distanza ramo se l'avesse recuperata da sola.
Questo fa spingere un'operazione pericolosa. Immagina di star sviluppando nel tuo repository locale, quando, all'improvviso, un nuovo ramo locale si presenta dal nulla. Ma i repository dovrebbero servire come ambienti di sviluppo completamente isolati, quindi perché dovrebbe spingere
esiste anche? Come scopriremo a breve, la spinta è uno strumento necessario per mantenere i repository Git pubblici.
Ora che abbiamo un'idea di base su come Git interagisce con altri repository, possiamo discutere i flussi di lavoro reali supportati da questi comandi. I due modelli di collaborazione più comuni sono: il flusso di lavoro centralizzato e il flusso di lavoro dell'integratore. Gli utenti SVN e CVS dovrebbero essere abbastanza a proprio agio con il sapore di Git dello sviluppo centralizzato, ma l'utilizzo di Git significa che sarete anche in grado di sfruttare le sue capacità di fusione altamente efficienti. Il flusso di lavoro dell'integratore è un tipico modello di collaborazione distribuita e non è possibile in sistemi puramente centralizzati.
Mentre leggi questi flussi di lavoro, tieni presente che Git considera tutti i repository come uguali. Non esiste un repository "master" secondo Git come esiste con SVN o CVS. La base di codice "ufficiale" è semplicemente una convenzione di progetto, l'unico motivo per cui è il repository ufficiale è perché è lì che si trovano tutti origine
punti remoti.
Ogni modello di collaborazione coinvolge almeno uno pubblico repository che funge da punto di ingresso per più sviluppatori. I repository pubblici hanno il vincolo esclusivo dell'essere spoglio-non devono avere una directory di lavoro. Ciò impedisce agli sviluppatori di sovrascrivere accidentalmente il lavoro degli altri spingere
. È possibile creare un repository nudo passando il --spoglio
opzione a git init
:
git init --bare
I repository pubblici dovrebbero funzionare come impianti di stoccaggio-non ambienti di sviluppo. Ciò viene comunicato aggiungendo a .idiota
estensione al percorso del file del repository, poiché il database del repository interno risiede nella root del progetto anziché in .idiota
sottodirectory. Quindi, un esempio completo potrebbe essere simile a:
git init --bare some-repo.git
A parte la mancanza di una directory di lavoro, non c'è nulla di speciale in un repository spoglio. È possibile aggiungere connessioni remote, premere su di esso e tirare da esso nel solito modo.
Il flusso di lavoro centralizzato è più adatto ai piccoli team in cui ogni sviluppatore ha accesso in scrittura al repository. Consente la collaborazione utilizzando un singolo repository centrale, proprio come il flusso di lavoro SVN o CVS. In questo modello, tutti le modifiche devono essere condivise tramite il repository centrale, che di solito è memorizzato su un server per consentire la collaborazione basata su Internet.
Gli sviluppatori lavorano individualmente nel proprio repository locale, che è completamente isolato da tutti gli altri. Una volta che hanno completato una funzione e sono pronti a condividere il loro codice, lo ripuliscono, lo integrano nel loro locale maestro
, e inviarlo al repository centrale (ad es., origine
). Ciò significa anche che ogni sviluppatore ha bisogno dell'accesso SSH al repository centrale.
Quindi, tutti gli altri possono recuperare i nuovi commit e incorporarli nei loro progetti locali. Di nuovo, questo può essere fatto con una fusione o un rebase, a seconda delle convenzioni della tua squadra.
Questo è il processo principale alla base dei flussi di lavoro centralizzati, ma ha un impatto quando più utenti tentano di aggiornare contemporaneamente il repository centrale. Immagina uno scenario in cui due sviluppatori hanno terminato una funzione, unendola nel loro locale maestro
, e ho provato a pubblicarlo allo stesso tempo (o vicino ad esso).
Chi arriva al server per primo può spingere i propri commit normalmente, ma poi il secondo sviluppatore rimane bloccato con una cronologia divergente, e Git non può eseguire una fusione veloce. Ad esempio, se uno sviluppatore di nome John dovesse spingere le sue modifiche subito prima di Mary, vedremmo un conflitto nel repository di Mary:
L'unico modo per fare il origine
Il maestro (aggiornato da John) corrisponde a quello di Mary maestro
è a sovrascrivere Impegno di John. Ovviamente, questo sarebbe molto brutto, quindi Git interrompe la spinta e genera un messaggio di errore:
! [respinto] master -> master (non-fast-forward) errore: impossibile inviare alcuni ref a 'some-repo.git'
Per rimediare a questa situazione, Mary deve sincronizzarsi con il repository centrale. Quindi, sarà in grado di spingere i suoi cambiamenti nel solito modo.
git fetch origine master git rebase origine / master git push origine master
Oltre a ciò, il flusso di lavoro centralizzato è relativamente semplice. Ogni sviluppatore rimane nel proprio repository locale, spostando / spingendo periodicamente verso il repository centrale per mantenere tutto aggiornato. È un flusso di lavoro conveniente da configurare, poiché è richiesto un solo server e sfrutta la funzionalità SSH esistente.
Il flusso di lavoro dell'integratore è un modello di sviluppo distribuito in cui tutti gli utenti mantengono il proprio pubblico repository, oltre a quello privato. Esiste come soluzione ai problemi di sicurezza e scalabilità inerenti al flusso di lavoro centralizzato.
Lo svantaggio principale del flusso di lavoro centralizzato è quello ogni gli sviluppatori hanno bisogno di accedere a tutto il progetto. Questo va bene se stai lavorando con un piccolo team di sviluppatori fidati, ma immagina uno scenario in cui stai lavorando a un progetto software open source e un estraneo trova un bug, lo risolve e vuole incorporare l'aggiornamento nel progetto principale. Probabilmente non vuoi dare a lui o lei l'accesso al repository centrale, dal momento che lui o lei potrebbe iniziare a spingere tutti i tipi di commit casuali, e si perderebbe effettivamente il controllo del progetto.
Ma quello che puoi fare è dire al contributore di spingere le modifiche a suo proprio repository pubblico. Quindi, puoi inserire la sua correzione di bug nel tuo repository privato per assicurarti che non contenga alcun codice non dichiarato. Se approvi i suoi contributi, tutto ciò che devi fare è unirli in una filiale locale e portarli nel repository principale come al solito. Sei diventato un integratore, oltre a uno sviluppatore ordinario:
In questo flusso di lavoro, a ogni sviluppatore è richiesto solo l'accesso push suo proprio repository pubblico. Il contributore utilizza SSH per inviare al proprio repository pubblico, ma l'integratore può recuperare le modifiche tramite HTTP (un protocollo di sola lettura). Questo rende un ambiente più sicuro per tutti, anche quando aggiungi più collaboratori:
Nota che il team deve ancora concordare su un singolo repository "ufficiale" da cui estrarre, altrimenti i cambiamenti verrebbero applicati fuori ordine e tutti finirebbero fuori sincrono molto rapidamente. Nel diagramma sopra, "Your Public Repo" è il progetto ufficiale.
Come integratore, devi tenere traccia di più telecomandi di quanto faresti nel flusso di lavoro centralizzato, ma questo ti dà la libertà e la sicurezza di incorporare le modifiche da qualsiasi sviluppatore senza minacciare la stabilità del progetto.
Inoltre, il flusso di lavoro dell'integratore non ha un singolo punto di accesso per fungere da punto di strozzatura per la collaborazione. Nei flussi di lavoro centralizzati, tutti devono essere completamente aggiornati prima di pubblicare le modifiche, ma non è il caso dei flussi di lavoro distribuiti. Di nuovo, questo è un risultato diretto dello stile di sviluppo non lineare abilitato dall'implementazione di ramo di Git.
Questi sono enormi vantaggi per i grandi progetti open-source. Organizzare centinaia di sviluppatori per lavorare su un singolo progetto non sarebbe possibile senza la sicurezza e la scalabilità della collaborazione distribuita.
Supportare questi modelli di collaborazione centralizzati e distribuiti era tutto ciò che Git avrebbe dovuto fare. La directory di lavoro, lo stage, i commit, i branch e i remoti sono stati progettati appositamente per abilitare questi flussi di lavoro e praticamente tutto ciò che in Git ruota intorno a questi componenti.
Fedele alla filosofia UNIX, Git è stato progettato come una suite di strumenti interoperabili, non un singolo programma monolitico. Continuando ad esplorare le numerose funzionalità di Git, scoprirai che è molto semplice adattare i singoli comandi a flussi di lavoro completamente nuovi.
Ora ti lascio che applichi questi concetti ai progetti del mondo reale, ma quando inizi a incorporare Git nel tuo flusso di lavoro quotidiano, ricorda che non è un punto d'argento per la gestione dei progetti. È semplicemente uno strumento per tracciare i tuoi file e nessuna quantità di conoscenza Git intimo può compensare una serie di convenzioni casuali all'interno di un team di sviluppo.
Questa lezione rappresenta un capitolo da Git in modo succinto, un eBook gratuito dal team di Syncfusion.