Close

Confronto dei flussi di lavoro Git: cosa dovresti sapere

Git è il sistema di controllo delle versioni più comunemente usato oggi. Un flusso di lavoro Git è una ricetta o una raccomandazione su come usare Git per svolgere un lavoro in modo coerente e produttivo. I flussi di lavoro Git incoraggiano gli sviluppatori e i team DevOps a sfruttare Git in modo efficace e coerente. Git offre molta flessibilità nel modo in cui gli utenti gestiscono le modifiche. Data l'attenzione di Git alla flessibilità, non esiste un processo standardizzato su come interagire con Git. Quando si lavora con un team su un progetto gestito da Git, è importante assicurarsi che il team sia d'accordo su come verrà applicato il flusso di modifiche. Per garantire che il team sia coordinato, è necessario sviluppare o selezionare un flusso di lavoro Git concordato. Esistono diversi flussi di lavoro Git pubblicizzati che potrebbero essere adatti al tuo team. Qui, discuteremo alcune di queste opzioni del flusso di lavoro Git.

La gamma di possibili flussi di lavoro può rendere difficile sapere da dove cominciare quando si implementa Git sul posto di lavoro. Questa pagina fornisce un punto di partenza esaminando i flussi di lavoro Git più comuni per i team di software.

Nel corso della lettura, ricorda che questi flussi di lavoro sono progettati per essere linee guida piuttosto che regole ferree. Vogliamo mostrarti cosa è possibile, in modo che tu possa mescolare e abbinare aspetti di diversi flussi di lavoro per soddisfare le tue esigenze individuali.


Che cos'è un flusso di lavoro Git di successo?


Quando valuti un flusso di lavoro per il tuo team, è molto importante che tu consideri la cultura del tuo team. Vuoi che il flusso di lavoro migliori l'efficacia del tuo team e che non sia un peso che limita la produttività. Alcuni aspetti da considerare quando si valuta un flusso di lavoro Git sono:

  • Questo flusso di lavoro è scalabile in base alle dimensioni del team?
  • È facile annullare gli errori con questo flusso di lavoro?
  • Questo flusso di lavoro impone nuovi sovraccarichi cognitivi non necessari al team?

Flusso di lavoro centralizzato


Repository centrali e locali

Il flusso di lavoro centralizzato è un ottimo flusso di lavoro Git per i team che stanno eseguendo il passaggio da SVN. Come Subversion, il flusso di lavoro centralizzato utilizza un repository centrale che funge da punto di accesso unico per tutte le modifiche al progetto. Invece di trunk, il branch di sviluppo predefinito si chiama main e tutte le modifiche vengono salvate in questo branch. Questo flusso di lavoro non richiede altri branch oltre a quello principale.

Il passaggio a un sistema di controllo delle versioni distribuito può sembrare un compito arduo, ma non è necessario modificare il flusso di lavoro esistente per sfruttare Git. Il tuo team può sviluppare progetti esattamente nello stesso modo in cui lo fa con Subversion.

Tuttavia, usare Git per potenziare il tuo flusso di lavoro di sviluppo presenta alcuni vantaggi rispetto a SVN. Innanzitutto, fornisce a ogni sviluppatore la propria copia locale dell'intero progetto. Questo ambiente isolato consente a ogni sviluppatore di lavorare indipendentemente rispetto a tutte le altre modifiche a un progetto: può aggiungere commit al proprio repository locale e dimenticare completamente gli sviluppi upstream finché non gli torneranno utili.

In secondo luogo, dà accesso al robusto modello di ramificazione e fusione di Git. A differenza di SVN, i Branch di Git sono progettati per essere un meccanismo sicuro per l'integrazione del codice e la condivisione delle modifiche tra i repository. Il flusso di lavoro centralizzato è simile ad altri flussi di lavoro nell'utilizzo di un repository ospitato in remoto sul lato server da cui gli sviluppatori eseguono push e pull. Rispetto ad altri flussi di lavoro, il flusso di lavoro centralizzato non ha modelli di richieste pull o forking definiti. Un flusso di lavoro centralizzato è generalmente più adatto per i team che eseguono la migrazione da SVN a Git e per team di piccole dimensioni.

Finestra della console
materiale correlato

Registro Git avanzato

Logo di Bitbucket
Scopri la soluzione

Impara a utilizzare Git con Bitbucket Cloud

Come funziona


Gli sviluppatori iniziano clonando il repository centrale. Nelle loro copie locali del progetto, modificano i file e apportano le modifiche come farebbero con SVN; tuttavia, questi nuovi commit sono archiviati localmente: sono completamente isolati dal repository centrale. Ciò consente agli sviluppatori di posticipare la sincronizzazione upstream fino a quando non si trovano in un punto di interruzione comodo.

Per pubblicare le modifiche al progetto ufficiale, gli sviluppatori eseguono il "push" del loro branch principale al repository centrale. È l'equivalente di svn commit, tranne per il fatto che aggiunge tutti i commit locali che non sono già nel branch principale centrale.

Inizializza il repository centrale

Inizializza il repository centrale delle cure

Innanzitutto, qualcuno deve creare il repository centrale su un server. Se si tratta di un nuovo progetto, puoi inizializzare un repository vuoto. Altrimenti, dovrai importare un repository Git o SVN esistente.

I repository centrali devono sempre essere archivi semplici (non dovrebbero avere una directory di lavoro), che possono essere creati come segue:

ssh user@host git init --bare /path/to/repo.git

Assicurati di utilizzare un nome utente SSH valido per l'utente, il dominio o l'indirizzo IP del tuo server per l'host e la posizione in cui desideri archiviare il tuo repository per /path/to/repo.git. Nota che l'estensione .git è convenzionalmente aggiunta al nome del repository per indicare che si tratta di un repository.

Archivi centrali ospitati

I repository centrali vengono spesso creati tramite servizi di hosting Git di terze parti come Bitbucket Cloud. Il processo di inizializzazione di un semplice repository discusso sopra è gestito per te dal servizio di hosting. Il servizio di hosting fornirà quindi un indirizzo a cui il repository centrale potrà accedere dal tuo repository locale.

Clona il repository centrale

Successivamente, ogni sviluppatore crea una copia locale dell'intero progetto. Ciò si ottiene tramite il comando git clone:

git clone ssh://user@host/path/to/repo.git

Quando cloni un repository, Git aggiunge automaticamente una scorciatoia chiamata origin che rimanda al repository "principale", supponendo che tu voglia interagire con esso più avanti.

Apporta modifiche ed esegui il commit

Una volta che il repository è clonato localmente, uno sviluppatore può apportare modifiche utilizzando il processo di commit standard di Git: modifica, stage e commit. Se non conosci l'area staging, è un modo per preparare un commit senza dover includere ogni modifica nella directory di lavoro. Questo ti consente di creare commit altamente mirati, anche se hai apportato molte modifiche locali.

git status # View the state of the repo
git add <some-file> # Stage a file
git commit # Commit a file</some-file>

Ricorda che poiché questi comandi creano commit locali, John può ripetere questo processo tutte le volte che vuole senza preoccuparsi di ciò che sta succedendo nel repository centrale. Questo può essere molto utile per funzionalità di grandi dimensioni che devono essere suddivise in blocchi più semplici e piccoli.

Inviare nuovi commit al repository centrale

Una volta che il repository locale ha apportato nuove modifiche. Queste modifiche dovranno essere pubblicate per condividerle con altri sviluppatori del progetto.

git push origin main

Questo comando trasferirà le nuove modifiche confermate al repository centrale. Quando si inviano modifiche al repository centrale, è possibile che siano stati precedentemente inviati aggiornamenti di un altro sviluppatore che contengono codice in conflitto con gli aggiornamenti push previsti. Git emetterà un messaggio che indica questo conflitto. In questa situazione, dovrà prima essere eseguito git pull. Questo scenario di conflitto verrà approfondito nella sezione seguente.

Gestire i conflitti

Il repository centrale rappresenta il progetto ufficiale, quindi la sua cronologia dei commit dovrebbe essere considerata sacra e immutabile. Se i commit locali di uno sviluppatore divergono dal repository centrale, Git si rifiuterà di eseguire il push delle modifiche perché ciò sovrascriverebbe i commit ufficiali.

Gestire i conflitti

Prima che lo sviluppatore possa pubblicare la propria funzionalità, deve recuperare i commit centrali aggiornati e aggiungere nuovamente le modifiche. È come dare il comando di aggiungere le modifiche al lavoro già effettuato da John. Il risultato è una storia perfettamente lineare, proprio come nei flussi di lavoro SVN tradizionali.

Se le modifiche locali sono direttamente in conflitto con i commit upstream, Git sospenderà il processo di riassegnazione e ti darà la possibilità di risolvere manualmente i conflitti. La cosa bella di Git è che usa gli stessi comandi git status e git add sia per generare commit che per risolvere i conflitti di fusione. Questo facilita ai nuovi sviluppatori la gestione delle proprie fusioni. Inoltre, se si mettono nei guai, con Git è molto facile annullare l'intero rebase e riprovare (o andare a cercare aiuto).

Esempio


Facciamo un esempio generale di come un piccolo team tipico collaborerebbe utilizzando questo flusso di lavoro. Vedremo come due sviluppatori, John e Mary, possono lavorare su funzionalità separate e condividere i loro contributi tramite un repository centralizzato.

John lavora sulla sua funzionalità

Processo relativo alla funzionalità Modifica Stage Commit

Nel suo repository locale, John può sviluppare funzionalità utilizzando il processo di commit standard di Git: modifica, stage e commit.

Ricorda che poiché questi comandi creano commit locali, John può ripetere questo processo tutte le volte che vuole senza preoccuparsi di ciò che sta succedendo nel repository centrale.

Mary lavora sulla sua funzionalità

Funzionalità Modifica Stage Commit

Nel frattempo, Mary sta lavorando alla sua funzionalità nel suo repository locale utilizzando lo stesso processo di modifica/stage/commit. Come John, a lei non importa cosa sta succedendo nell'archivio centrale e non le interessa davvero cosa sta facendo John nel suo repository locale, poiché tutti i repository locali sono privati.

John pubblica la sua funzionalità

Funzionalità di pubblicazione

Una volta che John avrà terminato la sua funzionalità, dovrebbe pubblicare i suoi commit locali nel repository centrale in modo che altri membri del team possano accedervi. Può farlo con il comando git push, in questo modo:

git push origin main

Ricorda che l'origine è la connessione remota al repository centrale creato da Git quando John lo ha clonato. L'argomento principale dice a Git di provare a far assomigliare il branch principale dell'origine al suo branch principale locale. Poiché il repository centrale non è stato aggiornato da quando John lo ha clonato, ciò non causerà alcun conflitto e il push funzionerà come previsto.

Mary cerca di pubblicare la sua funzionalità

Errore del comando Push

Vediamo cosa succede se Mary cerca di eseguire il push della sua funzionalità dopo che John ha pubblicato con successo le sue modifiche nel repository centrale. Può usare esattamente lo stesso comando push:

git push origin main

Ma, poiché la sua cronologia locale si è discostata dal repository centrale, Git rifiuterà la richiesta con un messaggio di errore piuttosto dettagliato:

error: failed to push some refs to '/path/to/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Questo impedisce a Mary di sovrascrivere i commit ufficiali. Deve inserire gli aggiornamenti di John nel suo repository, integrarli con le sue modifiche locali e poi riprovare.

Mary esegue la riassegnazione sui commit di John

Riassegnazione pull Git

Mary può usare git pull per incorporare le modifiche upstream nel suo repository. Questo comando è un po' come svn update: estrae l'intera cronologia dei commit upstream nel repository locale di Mary e cerca di integrarla con i suoi commit locali:

git pull --rebase origin main

L'opzione —rebase dice a Git di spostare tutti i commit di Mary nella punta del branch principale dopo averlo sincronizzato con le modifiche dal repository centrale, come mostrato di seguito:

Riassegnazione a main

Il pull funzionerebbe comunque se dimenticassi questa opzione, ma finiresti con un «merge commit» superfluo ogni volta che qualcuno ha bisogno di sincronizzarsi con il repository centrale. Per questo flusso di lavoro, è sempre meglio eseguire la riassegnazione invece di generare un merge commit.

Mary risolve un conflitto di fusione

Riassegnazione a commit

La riassegnazione funziona trasferendo ogni commit locale al branch principale aggiornato uno alla volta. Ciò significa che rilevi i conflitti di fusione in base a ogni singolo commit piuttosto che risolverli tutti in un unico merge commit di massa. Ciò mantiene i tuoi commit il più mirati possibile e rende pulita la cronologia del progetto. A sua volta, questo rende molto più facile capire dove sono stati introdotti i bug e, se necessario, annullare le modifiche con un impatto minimo sul progetto.

Se Mary e John stanno lavorando su funzionalità non correlate, è improbabile che il processo di riassegnazione generi conflitti. Ma se questo accade, Git metterà in pausa la riassegnazione in corrispondenza del commit corrente e genererà il seguente messaggio, insieme ad alcune istruzioni pertinenti:

CONFLICT (content): Merge conflict in <some-file>
Flusso di lavoro Git per la risoluzione dei conflitti durante un'operazione di merge.

Il bello di Git è che chiunque può risolvere autonomamente i propri conflitti di fusione. Nel nostro esempio, Mary eseguirebbe semplicemente un git status per vedere dov'è il problema. I file in conflitto verranno visualizzati nella sezione Percorsi non uniti:

# Unmerged paths:
# (use "git reset HEAD <some-file>..." to unstage)
# (use "git add/rm <some-file>..." as appropriate to mark resolution)
#
# both modified: <some-file>

Quindi, Mary modificherà i file a suo piacimento. Una volta soddisfatta del risultato, potrà eseguire lo staging dei file nel solito modo e lasciare che git rebase si occupi del resto:

git add <some-file>
git rebase --continue

E questo è tutto. Git passerà al commit successivo e ripeterà il processo per tutti gli altri commit che generano conflitti.

Se arrivi a questo punto e te ne rendi conto e non hai idea di cosa stia succedendo, niente panico. Basta eseguire il seguente comando e tornerai subito al punto di partenza:

git rebase --abort

Mary pubblica con successo la sua funzionalità

Sincronizzazione repository centrale

Dopo aver terminato la sincronizzazione con il repository centrale, Mary sarà in grado di pubblicare le sue modifiche con successo:

git push origin main

Come continuare

Come puoi vedere, è possibile replicare un ambiente di sviluppo Subversion tradizionale usando solo una manciata di comandi Git. Questo è ottimo per la transizione dei team da SVN, ma non sfrutta la natura distribuita di Git.

Il flusso di lavoro centralizzato è ottimo per i piccoli team. Il processo di risoluzione dei conflitti descritto sopra può costituire un collo di bottiglia man mano che il tuo team cresce in termini di dimensioni. Se il tuo team è a suo agio con il flusso di lavoro centralizzato ma vuole semplificarne gli sforzi di collaborazione, vale sicuramente la pena esplorare i vantaggi del flusso di lavoro Feature Branch. Dedicando un branch isolato a ciascuna funzionalità, è possibile avviare discussioni approfondite sulle nuove aggiunte prima di integrarle nel progetto ufficiale.

Altri flussi di lavoro comuni


Il flusso di lavoro centralizzato è essenzialmente un elemento costitutivo per altri flussi di lavoro Git. I flussi di lavoro Git più diffusi avranno una sorta di repository centralizzato da cui i singoli sviluppatori eseguiranno operazioni di push e pull. Di seguito parleremo brevemente di alcuni altri flussi di lavoro Git popolari. Questi flussi di lavoro estesi offrono modelli più specializzati per quanto riguarda la gestione dei branch per lo sviluppo di funzionalità, gli hot fix e l'eventualpost del blog rilascio.

Creazione di branch di funzioni


Feature Branching è un'estensione logica del flusso di lavoro centralizzato. L'idea principale alla base del flusso di lavoro Feature Branch è che l'intero sviluppo delle funzionalità avviene in un branch dedicato anziché nel branch principale. Questo incapsulamento rende facile per più sviluppatori lavorare su una particolare funzionalità senza toccare la base di codice principale. Significa anche che il branch principale non conterrà mai codice errato, il che è un enorme vantaggio per gli ambienti di continuous integration.

Flusso di lavoro di Gitflow


Il Gitflow Workflow è stato pubblicato per la prima volta in un apprezzato post sul blog del 2010 di Vincent Driessen di nvie. Il flusso di lavoro di Gitflow definisce un rigoroso modello di creazione di branch progettato in base al rilascio del progetto. Questo flusso di lavoro non aggiunge nuovi concetti o comandi oltre a quanto richiesto per il flusso di lavoro del branch di funzioni. Assegna invece ruoli molto specifici ai diversi branch e definisce modi e tempi della loro interazione.

Flusso di lavoro di fork


Il flusso di lavoro Forking è fondamentalmente diverso dagli altri flussi di lavoro discussi in questo tutorial. Invece di utilizzare un singolo repository lato server come codebase "centrale", tramite il fork ogni sviluppatore avrà a disposizione un repository lato server. Di conseguenza, ogni collaboratore non avrà uno, ma due repository Git: uno privato locale e uno pubblico lato server.

Linee guida


Non esiste un flusso di lavoro Git valido per tutti. Come affermato in precedenza, è importante sviluppare un flusso di lavoro Git che aumenti la produttività del tuo team. Oltre alla cultura di squadra, un flusso di lavoro dovrebbe integrare anche la cultura aziendale. Le funzionalità di Git come branch e tag dovrebbero integrare il programma di rilascio della tua attività. Se il tuo team utilizza un software di gestione dei progetti per il monitoraggio delle attività, potresti voler utilizzare branch corrispondenti alle attività in corso. Inoltre, alcune linee guida da considerare quando si prende una decisione su un flusso di lavoro sono:

Branch di breve durata

Più a lungo un branch esiste separato dal branch di produzione, maggiore è il rischio di conflitti di fusione e problemi di implementazione. I branch di breve durata promuovono fusioni e implementazioni più pulite.

Ridurre al minimo e semplificare i ripristini

È importante disporre di un flusso di lavoro che aiuti a prevenire in modo proattivo le fusioni che dovranno essere ripristinate. Un flusso di lavoro che testa un branch prima di consentirne l'unione nel branch principale è un esempio. Tuttavia, gli incidenti accadono. Detto questo, è utile avere un flusso di lavoro che consenta facili ripristini senza interrompere il flusso per gli altri membri del team.

Rispettare un calendario dei rilasci

Un flusso di lavoro dovrebbe integrare il ciclo di rilascio dello sviluppo del software della tua azienda. Se prevedi di rilasciarlo più volte al giorno, vorrai mantenere stabile il tuo branch principale. Se il tuo programma di rilascio è meno frequente, potresti prendere in considerazione l'utilizzo dei tag Git per taggare un branch a una versione.

Riepilogo


In questo documento abbiamo discusso dei flussi di lavoro Git. Abbiamo esaminato in modo approfondito un flusso di lavoro centralizzato con esempi pratici. Ampliando l'analisi del flusso di lavoro centralizzato, abbiamo discusso di flussi di lavoro specializzati aggiuntivi. Alcuni punti chiave di questo documento sono:

  • Non esiste un flusso di lavoro Git valido per tutti
  • Un flusso di lavoro dovrebbe essere semplice e migliorare la produttività del tuo team
  • I tuoi requisiti aziendali dovrebbero aiutarti a modellare il tuo flusso di lavoro G

Per saperne di più sul prossimo flusso di lavoro Git, dai un'occhiata alla nostra analisi completa del flusso di lavoro Feature Branch.


Condividi l'articolo

Letture consigliate

Aggiungi ai preferiti queste risorse per ricevere informazioni sui tipi di team DevOps e aggiornamenti continui su DevOps in Atlassian.

Le persone collaborano utilizzando una parete piena di strumenti

Blog di Bitbucket

Illustrazione su Devops

Percorso di apprendimento DevOps

Funzione Demo Den per demo con esperti Atlassian

Come Bitbucket Cloud funziona con Atlassian Open DevOps

Iscriviti alla nostra newsletter DevOps

Thank you for signing up