Close

Sottomoduli Git

I sottomoduli Git consentono di mantenere un repository git come sottodirectory di un altro repository git e sono semplicemente un riferimento a un altro repository in un particolare momento nel tempo. I sottomoduli Git fanno in modo che un repository Git possa incorporare e tenere traccia della cronologia delle versioni del codice esterno.


Cos'è un sottomodulo git?


Spesso un repository di codice dipende da codice esterno. Questo codice esterno può essere incorporato in alcuni modi diversi. Può essere ad esempio copiato e incollato direttamente nel repository principale. Lo svantaggio di questo metodo è che si perde qualsiasi modifica upstream apportata al repository esterno. Un altro metodo per incorporare il codice esterno consiste nell'uso di un sistema di gestione dei pacchetti per i linguaggi di programmazione, come Ruby Gems o NPM. Lo svantaggio di questo metodo è che richiede l'installazione e la gestione delle versioni in tutte le posizioni in cui viene distribuito il codice di origine. Entrambi questi metodi di incorporazione suggeriti non consentono di tenere traccia delle modifiche e dei cambiamenti che riguardano il repository esterno.

Un sottomodulo git è un record all'interno di un repository git host che punta a un commit specifico in un altro repository esterno. I sottomoduli sono molto statici e tengono traccia solo di commit specifici. Non tengono traccia dei riferimenti o dei branch git e non vengono aggiornati automaticamente quando viene aggiornato il repository host. Quando si aggiunge un sottomodulo a un repository, viene creato un nuovo file .gitmodules. Tale file contiene metadati sulla mappatura tra l'URL del progetto del sottomodulo e la directory locale. Se il repository host contiene più sottomoduli, nel file .gitmodules vi sarà una voce relativa a ogni sottomodulo.

Quando occorre usare un sottomodulo git?


Se devi mantenere una rigorosa gestione delle versioni sulle dipendenze esterne, può avere senso usare i sottomoduli git. Di seguito sono riportati alcuni dei migliori casi d'uso relativi ai sottomoduli git.

  • Quando un componente esterno 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.
  • 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.
Database
materiale correlato

Come spostare un repository Git completo

Logo di Bitbucket
Scopri la soluzione

Impara a utilizzare Git con Bitbucket Cloud

Comandi comuni relativi ai sottomoduli git


Aggiungere il sottomodulo git

Il comando git submodule add viene utilizzato per aggiungere un nuovo modulo secondario a un repository esistente. Di seguito è riportato un esempio in cui viene creato un repository vuoto e vengono esplorati i moduli secondari git.

$ mkdir git-submodule-demo
$ cd git-submodule-demo/
$ git init
Initialized empty Git repository in /Users/atlassian/git-submodule-demo/.git/

Questa sequenza di comandi crea una nuova directory, git-submodule-demo, entra in tale directory e la inizializza come nuovo repository. Quindi, aggiungiamo un sottomodulo a questo nuovo repository.

$ git submodule add https://bitbucket.org/jaredw/awesomelibrary
Cloning into '/Users/atlassian/git-submodule-demo/awesomelibrary'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.

Il comando git submodule add prende un parametro URL che punta a un repository git. Qui abbiamo aggiunto awesomelibrary come sottomodulo. Git clonerà immediatamente il sottomodulo. Ora possiamo esaminare lo stato attuale del repository utilizzando git status...

$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

new file:   .gitmodules
new file:   awesomelibrary

Adesso, ci sono due nuovi file nel repository .gitmodules e nella directory awesomelibrary. Se analizziamo i contenuti di .gitmodules, vedremo la nuova mappatura del sottomodulo

[submodule "awesomelibrary"]
path = awesomelibrary
url = https://bitbucket.org/jaredw/awesomelibrary
$ git add .gitmodules awesomelibrary/
$ git commit -m "added submodule"
[main (root-commit) d5002d0] added submodule
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 awesomelibrary

Clonazione dei sottomoduli git

git clone /url/to/repo/with/submodules
git submodule init
git submodule update

Git submodule init

Come comportamento predefinito, git submodule init copia la mappatura dal file .gitmodules al file locale ./.git/config. Questo comportamento può sembrare ridondante e può far sorgere dei dubbi sull'utilità di git submodule init. git submodule init prevede un comportamento esteso in cui accetta una lista di nomi di modulo espliciti. Ciò rende disponibile un flusso di lavoro che attiva soltanto i sottomoduli specifici necessari per lavorare sul repository. Tale flusso di lavoro può essere utile se in un repository sono presenti molti sottomoduli, ma non occorre recuperarli tutti per il lavoro che si sta svolgendo.

Flussi di lavoro dei sottomoduli

Una volta che i sottomoduli sono stati inizializzati e aggiornati correttamente in un repository principale, possono essere utilizzati esattamente come i repository autonomi. Ciò significa che i sottomoduli hanno i propri branch e la propria cronologia. È importante pubblicare le modifiche apportate a un sottomodulo e quindi aggiornare il riferimento dei repository principali al sottomodulo. Continuiamo con l'esempio di awesomelibrary e apportiamo alcune modifiche:

$ cd awesomelibrary/
$ git checkout -b new_awesome
Switched to a new branch 'new_awesome'
$ echo "new awesome file" > new_awesome.txt
$ git status
On branch new_awesome
Untracked files:
  (use "git add <file>..." to include in what will be committed)

new_awesome.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add new_awesome.txt
$ git commit -m "added new awesome textfile"
[new_awesome 0567ce8] added new awesome textfile
 1 file changed, 1 insertion(+)
 create mode 100644 new_awesome.txt
$ git branch
  main
* new_awesome

Qui abbiamo modificato la directory nel sottomodulo awesomelibrary. Abbiamo creato un nuovo file di testo, new_awesome.txt, con alcuni contenuti e abbiamo aggiunto e sottoposto a commit questo nuovo file nel sottomodulo. Ora modifichiamo nuovamente le directory nel repository principale e rivediamo lo stato attuale di tale repository.

$ cd ..
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   awesomelibrary (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

L'esecuzione di git status mostra che il repository principale è a conoscenza dei nuovi commit nel sottomodulo awesomelibrary. Non entra nei dettagli sugli aggiornamenti specifici, perché questa è responsabilità dei repository del sottomodulo. Il repository principale si occupa solo di associare il sottomodulo a un commit. Ora possiamo aggiornare nuovamente il repository principale eseguendo i comandi git add e git commit sul sottomodulo. Questi comandi riporteranno tutti gli elementi in uno stato corretto rispetto ai contenuti locali. Se lavori in un ambiente di team, è fondamentale eseguire il comando git push sugli aggiornamenti del sottomodulo e del repository principale.

Quando si lavora con i sottomoduli, una comune fonte di confusione ed errore è dimenticare di eseguire il push degli aggiornamenti per gli utenti remoti. Se rivediamo il lavoro svolto in awesomelibrary, vedremo che abbiamo eseguito il push soltanto degli aggiornamenti al repository principale. Se un altro sviluppatore esegue un pull del repository principale più recente, che punta a un commit di awesomelibrary, non potrà portare a termine l'operazione di pull perché abbiamo dimenticato di eseguire il push del sottomodulo. In questo caso, il repository locale degli sviluppatori remoti risulta danneggiato. Per evitare questo scenario di errore, assicurati di eseguire sempre il commit e il push del repository principale e del sottomodulo.

Conclusione


I sottomoduli Git sono un modo efficace per sfruttare git come strumento esterno di gestione delle dipendenze. Valuta i pro e i contro dei sottomoduli git prima di utilizzarli, poiché sono funzionalità avanzate e possono avere una curva di apprendimento per l'adozione da parte dei membri del team.


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