Close

Sottomoduli: concetto fondamentale, flussi di lavoro e suggerimenti

Primo piano di Nicola Paolucci
Nicola Paolucci

Developer Advocate


Includere i sottomoduli come parte del processo di sviluppo di Git consente di includere altri progetti nella base di codice, mantenendo la loro cronologia separata, ma sincronizzata con la tua. È un modo pratico per risolvere i problemi relativi alla libreria e alla dipendenza dei fornitori. Come al solito con tutto ciò che riguarda git, l'approccio è dogmatico e richiede un po' di studio prima di poter essere usato con competenza. In giro ci sono già informazioni valide e dettagliate sui sottomoduli, quindi non mi ripeterò a tal proposito. Quello che farò qui è condividere alcuni aspetti interessanti che ti aiuteranno a sfruttare al meglio questa funzione.

Database
materiale correlato

Come spostare un repository Git completo

Logo di Bitbucket
Scopri la soluzione

Impara a utilizzare Git con Bitbucket Cloud

Concetto fondamentale


Vorrei iniziare spiegando brevemente un concetto fondamentale sui sottomoduli che ne semplificherà l'utilizzo.

I sottomoduli sono monitorati dal commit esatto specificato nel progetto principale, non da un branch, da un riferimento o da qualsiasi altro riferimento simbolico.

Non vengono mai aggiornati automaticamente quando viene aggiornato il repository specificato dal sottomodulo, ma solo quando viene aggiornato il progetto principale stesso. Come espresso molto chiaramente nel capitolo Pro Git menzionato in precedenza:

Quando apporti modifiche ed esegui il commit in una sottodirectory [del sottomodulo] specifica, il superprogetto nota che l'HEAD è cambiato e registra il commit esatto su cui stai lavorando; in questo modo, quando altri clonano questo progetto, possono ricreare esattamente l'ambiente.

O in altre parole:

[...] i sottomoduli git [...] sono statici. Estremamente statici. I commit specifici vengono monitorati tramite i sottomoduli git e non con branch, riferimenti o singoli commit. Se aggiungi i commit a un sottomodulo, il progetto principale non lo saprà. Ai sottomoduli git non interessa se ci sono tanti fork di un modulo. È presente un repository remoto che punta a un unico commit. Finché non aggiorni il progetto principale, non cambia nulla.

Possibili flussi di lavoro


Tenendo a mente questo concetto fondamentale e riflettendoci sopra, puoi comprendere che i sottomoduli (submodule) supportano bene alcuni flussi di lavoro e altri in modo meno ottimale. Esistono almeno tre scenari in cui i sottomoduli rappresentano una scelta corretta:

  • Quando un componente o un sottoprogetto cambia troppo velocemente o le modifiche imminenti interromperanno l'API, puoi bloccare il codice su un commit specifico per ragioni di sicurezza.

  • Quando c'è un componente che non viene aggiornato molto spesso e che desideri monitorare come dipendenza del fornitore. Io procedo così per i plugin vim, ad esempio.

  • Quando deleghi una porzione del progetto a una terza parte e desideri integrare il suo lavoro in un momento o in un rilascio specifico. Ripeto: questo procedimento funziona quando gli aggiornamenti non sono troppo frequenti.

Ringrazio finch per le ottime spiegazioni degli scenari.

Suggerimenti utili


L'infrastruttura dei sottomoduli è molto solida e consente un'utile separazione e integrazione delle basi di codice. Esistono tuttavia operazioni semplici le cui procedure non sono intuitive o che non sono efficacemente supportate dall'interfaccia utente da riga di comando.

Se nel tuo progetto usi i sottomoduli git, avrai già incontrato queste operazioni oppure lo farai a breve. Quando ciò accadrà, dovrai andare a cercare la soluzione. Più e più volte. Ti faccio risparmiare tempo: aggiungi questa pagina a Instapaper, Evernote o ai più tradizionali segnalibri (:D:D) per essere a posto per un po'.

Quindi, ecco alcune procedure che ti torneranno utili:

Come sostituire un sottomodulo git con il proprio fork


Questo è un flusso di lavoro molto comune: inizi a utilizzare il progetto di qualcun altro come sottomodulo, ma dopo un po' vuoi personalizzarlo e modificarlo in autonomia, quindi vuoi eseguire un fork del progetto e sostituire il sottomodulo con il tuo fork. Come si fa?

I sottomoduli sono archiviati in .gitmodules:

$ cat .gitmodules [submodule "ext/google-maps"] path = ext/google-maps url = git://git.naquadah.org/google-maps.git

Puoi semplicemente modificare l'URL con un editor di testo e quindi eseguire quanto segue:

$ git submodule sync

In questo modo aggiorni .git/config, che contiene una copia di questa lista di sottomoduli (potresti anche modificare semplicemente la sezione [submodule] pertinente di .git/config manualmente).

Riferimenti su Stack Overflow

Come faccio a rimuovere un sottomodulo?


È un'esigenza abbastanza comune, ma prevede una procedura leggermente complicata. Per rimuovere un sottomodulo devi:

1. Eliminare la riga pertinente dal file .gitmodules.

2. Eliminare la sezione pertinente da .git/config.

3. Eseguire git rm --cached path_to_submodule (senza slash finale).

4. Eseguire il commit ed eliminare i file dei moduli secondari ora non monitorati.

Riferimenti su Stack Overflow

Come faccio a reintegrare un sottomodulo nel progetto?


Oppure, in altre parole: come faccio ad annullare la struttura del sottomodulo da un sottomodulo git? Se tutto ciò che vuoi è inserire il codice del sottomodulo nel repository principale, devi rimuovere il sottomodulo e aggiungere nuovamente i file nel repository principale:

1. Elimina il riferimento al modulo secondario dall'indice, ma conserva i file:

git rm --cached submodule_path (no trailing slash)

2. Elimina il file .gitmodules, o, se hai più di un modulo secondario, modifica questo file rimuovendo il modulo secondario dalla lista:

git rm .gitmodules

3. Rimuovi la cartella dei metadati .git (assicurati di averne creato un backup):

rm -rf submodule_path/.git

4. Aggiungi il modulo secondario submodule all'indice del repository principale:

git add submodule_path git commit -m "remove submodule"

NOTA: la procedura descritta sopra è distruttiva per la cronologia del sottomodulo. Nei casi in cui desideri conservare una cronologia coerente dei sottomoduli, devi eseguire un "merge" più complesso. Per maggiori dettagli consulta questo riferimento molto completo su Stack Overflow.

Come ignorare le modifiche nei sottomoduli


A volte i moduli secondari (submodules) potrebbero diventare dirty da soli. Ad esempio, se usi git submodules git per tenere traccia dei plugin vim, questi potrebbero generare o modificare file locali come gli helptags. Purtroppo, git status inizierà a infastidirti relativamente a queste modifiche, anche se non ti interessano affatto e non hai intenzione di sottoporle a commit.

La soluzione è molto semplice. Apri il file .gitmodules alla radice del repository e, per ogni sottomodulo che vuoi ignorare, aggiungi ignore = dirty come in questo esempio:

[submodule ".vim/bundle/msanders-snipmate"] path = .vim/bundle/msanders-snipmate url = git://github.com/msanders/snipmate.vim.git ignore = dirty

Pericolo! Insidie dell'interazione con i repository remoti


Come ci ricorda il tutorial sui sottomoduli Git disponibile su kernel.org, ci sono alcune cose importanti da ricordare quando si interagisce con i repository remoti.

La prima è pubblicare sempre la modifica al sottomodulo prima di pubblicare la modifica al superprogetto che vi fa riferimento. Si tratta di un passaggio fondamentale in quanto potrebbe impedire ad altri di clonare il repository.

La seconda è ricordarsi sempre di eseguire il commit di tutte le modifiche prima di eseguire il comando git submodule update, poiché le eventuali modifiche verranno sovrascritte!

Conclusioni


Grazie a queste note, dovresti essere in grado di affrontare molti comuni flussi di lavoro ricorrenti che emergono quando si utilizzano i sottomoduli. In un prossimo post scriverò sulle alternative a git submodule.

Seguimi alla pagina @durdn e segui anche il fantastico team di @Bitbucket per altre informazioni su DVCS.

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
Argomento successivo

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