Close

Git e dipendenze del progetto

Primo piano di Nicola Paolucci
Nicola Paolucci

Developer Advocate

Rifletti sulle domande seguenti. Come gestisci le dipendenze del progetto con git? Il nostro progetto è composto da più repository interdipendenti. Attualmente li gestiamo con svn:externals. Qual è il modo migliore per gestirli con git? Come si divide un repository molto grande in componenti più piccoli usando git? Questi sono alcuni esempi delle domande più frequenti che abbiamo ricevuto durante la tappa europea del nostro ultimo tour Getting Git Right.

Questo argomento sembra essere una nota dolente per molti team software che adottano git, quindi in questo articolo cercherò di far luce sulla questione.

Ovviamente le dipendenze del progetto e l'infrastruttura di compilazione sono due aree interconnesse, e anche all'interno di Atlassian si è scatenata una discussione sul "futuro delle compilazioni".

Avere repository separati invece di averne uno solo può complicare alcune cose. Ma è un passaggio relativamente naturale, a volte obbligatorio, dell'evoluzione di un progetto software per almeno due motivi principali: aumento dei tempi di compilazione e dipendenze condivise tra i progetti.

Rifletti sulle domande seguenti. Come gestisci le dipendenze del progetto con git? Il nostro progetto è composto da più repository interdipendenti. Attualmente li gestiamo con svn:externals. Qual è il modo migliore per gestirli con git? Come si divide un repository molto grande in componenti più piccoli usando git? Questi sono alcuni esempi delle domande più frequenti che abbiamo ricevuto durante la tappa europea del nostro ultimo tour Getting Git Right.

Questo argomento sembra essere una nota dolente per molti team software che adottano git, quindi in questo articolo cercherò di far luce sulla questione.

Ovviamente le dipendenze del progetto e l'infrastruttura di compilazione sono due aree interconnesse, e anche all'interno di Atlassian si è scatenata una discussione sul "futuro delle compilazioni".

Avere repository separati invece di averne uno solo può complicare alcune cose. Ma è un passaggio relativamente naturale, a volte obbligatorio, dell'evoluzione di un progetto software per almeno due motivi principali: aumento dei tempi di compilazione e dipendenze condivise tra i progetti.


Rapida panoramica delle linee guida e delle soluzioni subottimali


Quindi torniamo alla domanda: come si monitorano e gestiscono le dipendenze del progetto con git?

Se possibile, non si fa!

Scherzi a parte, rispondo a questa domanda dapprima a grandi linee per poi approfondire l'argomento. Innanzitutto, prendiamo atto del fatto che non esiste una soluzione ottimale, in git o in altre soluzioni, che risolva in modo indolore tutti i problemi legati alle dipendenze dei progetti.

Una volta che un progetto supera una certa dimensione, ha senso suddividerlo in componenti logici, ma non aspettare di avere più di 100 milioni di righe di codice in un unico repository per farlo. Le seguenti sono solo delle linee guida che ti aiuteranno ad elaborare il tuo personale approccio.

Logo Git
materiale correlato

Installa Git

Logo di Bitbucket
Scopri la soluzione

Impara a utilizzare Git con Bitbucket Cloud

Prima scelta: uso di uno strumento di compilazione/per le dipendenze appropriato al posto di git


Gli strumenti di gestione delle dipendenze sono il metodo che attualmente consiglio per gestire le difficoltà e i tempi di compilazione in costante aumento dei progetti di grandi dimensioni.

Mantieni i moduli separati in repository individuali e gestisci la loro interdipendenza con uno strumento creato appositamente. C'è uno strumento per (quasi) tutti gli stack tecnologici esistenti. Ecco alcuni esempi:

  • Maven (o Gradle) se usi Java
  • Npm per le app Node
  • Bower, Component.io ecc. se usi Javascript (aggiornato!)
  • Pip e requirements.txt se usi Python
  • RubyGems, Bundler se usi Ruby
  • NuGet per .NET
  • Ivy (o delle azioni CMake personalizzate) per C++ (aggiornato!)
  • CocoaPods per le app Cocoa iOS
  • Composier o Phing per PHP (aggiunto!)
  • In Go l'infrastruttura di compilazione/delle dipendenze è in qualche modo integrata nel linguaggio (anche se si sta lavorando a una soluzione più completa, vedi godep). Per il nostro server Git, Bitbucket Server, utilizziamo sia Maven che Bower. In fase di compilazione, lo strumento selezionato esegue un pull delle versioni corrette delle dipendenze per consentire la compilazione del progetto principale. Alcuni di questi strumenti presentano dei limiti e formulano ipotesi non ottimali, ma sono tuttavia comprovati e validi.

Le difficoltà di suddivisione del progetto

In parole semplici, all'inizio di un progetto tutto è racchiuso in un'unica build. Ma, man mano che il progetto cresce, la build potrebbe diventare troppo lenta e a quel punto diventa necessaria la memorizzazione nella cache. È qui che entra in gioco la gestione delle dipendenze. Questo, a proposito, implica che i sottomoduli (vedi sotto) si prestano molto bene ai linguaggi dinamici, ad esempio. Fondamentalmente, penso che la maggior parte di noi prima o poi debba occuparsi dei tempi di compilazione, motivo per cui è importante usare uno strumento di gestione delle dipendenze.

La suddivisione dei componenti in repository separati comporta delle serie difficoltà. In ordine sparso:

  • Per apportare modifiche a un componente è necessario un rilascio
  • L'operazione richiede tempo e può non andare a buon fine per molte ragioni banali
  • Sembra un'operazione inutile da eseguire per le piccole modifiche
  • Richiede la configurazione manuale di nuove build per ogni componente
  • Ostacola la rilevabilità dei repository
  • Richiede il refactoring quando non tutta l'origine è disponibile in un unico repository
  • In alcune configurazioni (come la nostra) l'aggiornamento delle API richiede un rilascio milestone del prodotto, quindi del plugin e poi ancora del prodotto. Forse ho saltato alcune cose, ma credo di aver reso il concetto. La soluzione perfetta al problema è tutt'altro che questa.

Seconda scelta: uso dei sottomoduli git


Se non puoi o non vuoi usare uno strumento per le dipendenze, git offre una funzione per la gestione dei sottomoduli (submodules). I sottomoduli possono essere pratici, soprattutto per i linguaggi dinamici. Tuttavia, non è detto che saranno necessariamente in grado di farti evitare i tempi di compilazione lenti. Ho già scritto alcune linee guida e suggerimenti a riguardo e ho anche esplorato delle alternative. Anche su Internet in generale si possono trovare molti argomenti contro il loro utilizzo.

Corrispondenza diretta tra svn:external e git

MA! Se cerchi una corrispondenza diretta tra svn:externals e git, è consigliabile usare i sottomoduli (submodules assicurandoti che i submodules tengano traccia solo dei branch di rilascio e non dei commit casuali.

Terza scelta: uso di altri strumenti di compilazione e per le dipendenze tra stack


Non sempre ti ritroverai a lavorare a un progetto completamente uniforme e che può essere compilato e assemblato con un solo strumento. Ad esempio, alcuni progetti mobili dovranno gestire le dipendenze Java e C++ o utilizzare strumenti proprietari per generare risorse. Per queste situazioni più complesse, puoi potenziare Git aggiungendo un ulteriore livello. Un ottimo esempio in questo caso è il repository di Android.

Altri strumenti di compilazione degni di nota:

Conclusioni e letture aggiuntive


Charles O'Farrell ha suggerito ulteriori letture con spunti di riflessione molto interessanti sull'argomento dell'infrastruttura di compilazione (e Maven):

Vorrei concludere con questa eccellente citazione tratta dall'ultimo articolo riportato sopra. Anche se riguarda Maven, potrebbe applicarsi ugualmente ad altri strumenti di compilazione e per le dipendenze:

"La cache non fa altro che velocizzare le cose. Si potrebbe rimuovere completamente la cache e il sistema circostante funzionerebbe allo stesso modo, solo più lentamente. Inoltre, la cache non ha effetti collaterali. Indipendentemente da come si è utilizzata la cache in passato, una determinata query nella cache restituirà lo stesso valore per la stessa query in futuro.

L'esperienza offerta da Maven è molto diversa da quella descritta! I repository Maven vengono usati come cache, ma senza le proprietà della cache. Quando si effettua una query in un repository Maven, le operazioni svolte in precedenza hanno grande importanza. Viene restituito l'elemento inserito più di recente e la query può persino non andare a buon fine se fa riferimento a un elemento non ancora inserito nel repository".

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


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