Alla fine, qualsiasi progetto software interessante dipenderà da un altro progetto, libreria o framework. Git fornisce sottomoduli per aiutare con questo. I sottomoduli consentono di includere o incorporare uno o più repository come sottocartella all’interno di un altro repository.
Per molti progetti, i sottomoduli non sono la risposta migliore (più su questo sotto), e anche al loro meglio, lavorare con i sottomoduli può essere complicato, ma iniziamo guardando un esempio diretto.,
Aggiunta di un sottomodulo
Supponiamo che tu stia lavorando a un progetto chiamato Slingshot. Hai il codice per y-shaped stick
e unrubber-band
.
foto flickr condivisa da young@art sotto una licenza Creative Commons ( BY)
Allo stesso tempo, in un altro repository, hai un altro progetto chiamato Rock—è solo una libreria generica rock
, ma pensi che sarebbe perfetto per Slingshot.
È possibile aggiungere rock
come sottomodulo di slingshot
., Nel repository slingshot
:
A questo punto, avrai una cartella rock
all’interno di slingshot
, ma se dovessi sbirciare all’interno di quella cartella, a seconda della versione Git, potresti vedere nothing niente.,
le versioni più Recenti di Git viene fatto automaticamente, ma le versioni precedenti si richiede di comunicare esplicitamente Git per scaricare il contenuto di rock
:
Se tutto sembra buono, è possibile impegnarsi in questo cambiamento e avrete un rock
cartella slingshot
repository con tutti i contenuti del rock
repository.,
Su GitHub, il rock
icona della cartella avrà un po ‘ di indicazione che si tratta di un submodule:
E clic su rock
cartella di rock
repository.
Questo è tutto! Hai incorporato il repositoryrock
all’interno del repositoryslingshot
. Puoi interagire con tutto il contenuto darock
come se fosse una cartella all’interno dislingshot
(perché lo è).,
Sulla riga di comando, Git comandi emessi da slingshot
(o una qualsiasi delle altre cartelle, rubber-band
e y-shaped-stick
) opererà nel principale “repository” slingshot
ma i comandi problema del rock
cartella funzionerà solo sui rock
repository:
Entrare in un progetto che utilizza il sotto-moduli
Ora, dicono che sei un nuovo collaboratore adesione Progetto Fionda., Inizieresti eseguendo git clone
per scaricare il contenuto del repositoryslingshot
. A questo punto, se dovessi sbirciare all’interno della cartella rock
, vedresti nothing niente.
Ancora una volta, Git si aspetta che gli chiediamo esplicitamente di scaricare il contenuto del sottomodulo., È possibile utilizzare git submodule update --init --recursive
anche qui, ma se siete clonazione slingshot
per la prima volta, è possibile utilizzare una versione modificata clone
comando per accertarsi di scaricare di tutto, comprese le eventuali sotto-moduli:
il passaggio a sotto-moduli
Si può essere un po ‘ difficile prendere uno già esistente sottocartella e di trasformarlo in una dipendenza esterna. Diamo un’occhiata a un esempio.
Stai per iniziare un nuovo progetto—un magic roll-back can–che ha anche bisogno di unrubber-band
., Prendiamo il rubber-band
è stato creato perslingshot
, dividerlo in un repository stand-alone e quindi incorporarlo in entrambi i progetti tramite sottomoduli.
Puoi prendere tutto dalla cartellarubber-band
del progetto Slingshot ed estrarlo in un nuovo repository e persino mantenere la cronologia di commit.
Iniziamo estraendo il contenuto della cartellarubber-band
daslingshot
., Puoi usaregit filter-branch
per farlo, lasciandoti solo i commit relativi arubber-band
. Il comandogit filter-branch
riscriverà la cronologia del nostro repository, facendo sembrare che la cartellarubber-band
fosse stata il proprio repository per tutto il tempo. Per ulteriori informazioni su git filter-branch
, vedere questo articolo.
Il primo passo è fare una copia di slingshot
su cui lavorare—l’obiettivo finale è che rubber-band
rimanga come proprio repository, quindi lascia slingshot
così com’è., È possibile utilizzarecp
con-r
per copiare ricorsivamente l’intera cartellaslingshot
in una nuova cartellarubber-band
.,
sembra rubber-band
è solo un altro slingshot
, ma ora, dal rubber-band
repository, eseguire git filter-branch
:
A questo punto, avrete una cartella rubber-band
, che è un repository che sorta di analogo Progetto di Fionda, ma ha solo il file e si impegnano storia rubber-band
cartella.,
Poiché hai copiato questo daslingshot
, il nuovo repository avrà ancora tutti i rami di tracciamento remoto che hai configurato quando eraslingshot
. Non vuoi spingere rubber-band
suslingshot
. Vuoi spingere questo in un nuovo repository.
Crea un nuovo repository per rubber-band
su GitHub, quindi aggiorna il telecomando per rubber-band
., Supponendo che si stesse chiamando il telecomandoorigin
, è possibile:
Quindi è possibile pubblicare il nuovo “generic rubber-band module” congit push
.,
Ora che hai separato rubber-band
nel proprio repository, è necessario eliminare il vecchio rubber-band
cartella slingshot
repository:
aggiornamento slingshot
usare rubber-band
come submodule:
Come abbiamo visto prima, quando eravamo aggiunta di rock
ora abbiamo un repository-in-un-repository., Tre repository, infatti: il repository” parent “slingshot
, più i due repository” sub”,rock
erubber-band
.
Inoltre, se ci immergiamo di nuovo nella cronologia di slingshot
, vedremo i commit che abbiamo originariamente fatto in rubber-band
quando era una cartella—l’eliminazione della cartella non ha cancellato alcuna cronologia., Questo a volte può essere un po ‘ confuso—dal momento che il repository rubber-band
“child” ha una versione copiata e modificata di quei vecchi slingshot
commit, a volte può sembrare che tu stia avendo déja vu.
Sfortunatamente, qualsiasi collaboratore che estrae slingshot
a questo punto avrà una cartella vuotarubber-band
., Potresti voler ricordare ai tuoi collaboratori di eseguire questo comando per assicurarti che abbiano tutto il contenuto del sottomodulo:
Vorrai anche aggiungere il sottomodulorubber-band
amagic roll-back can
. Fortunatamente, tutto ciò che devi fare è seguire la stessa procedura che hai usato in precedenza quando hai aggiuntorock
aslingshot
, in “Aggiunta di un sottomodulo.”
Consigli sull’uso di sottomoduli (o meno)
- Prima di aggiungere un repository come sottomodulo, controlla prima se hai un’alternativa migliore disponibile., I sottomoduli Git funzionano abbastanza bene per casi semplici, ma in questi giorni ci sono spesso strumenti migliori disponibili per la gestione delle dipendenze rispetto a quelli che i sottomoduli Git possono offrire. I linguaggi moderni come Go hanno sistemi di gestione delle dipendenze amichevoli e consapevoli di Git integrati fin dall’inizio. Altri, come rubygems di Ruby, Nodo.js ‘ npm, o CocoaPods Cocoa e Carthage, sono stati aggiunti dalla comunità di programmazione. Anche gli sviluppatori front-end hanno strumenti come Bower per gestire librerie e framework per JavaScript e CSS lato client.
- Ricorda che Git non scarica il contenuto del sottomodulo per impostazione predefinita., Se stai aggiungendo un sottomodulo a un progetto esistente, assicurati che chiunque lavori al progetto sappia che deve eseguire comandi come
git submodule update
egit clone --recursive
per assicurarti che ottengano tutto—questo include qualsiasi servizio di distribuzione o test automatico che potrebbe essere coinvolto nel progetto! Ti consigliamo di utilizzare qualcosa come i nostri “Script per regolarli tutti” per assicurarti che tutti i collaboratori e i servizi abbiano accesso allo stesso contenuto del repository ovunque. - Sottomoduli richiedono di bilanciare con attenzione la coerenza e la convenienza., La configurazione utilizzata qui preferisce fortemente la coerenza, a costo di un po ‘ di convenienza. In genere è meglio avere i sottomoduli di un progetto bloccati su uno specifico SHA, in modo che tutti i collaboratori ricevano lo stesso contenuto. Ma questa configurazione rende anche difficile per gli sviluppatori nel repository “genitore” contribuire alle modifiche al repository del sottomodulo.
- Ricorda che i collaboratori non vedranno automaticamente gli aggiornamenti ai sottomoduli: se aggiorni un sottomodulo, potresti dover ricordare ai tuoi colleghi di eseguire
git submodule update
o probabilmente vedranno un comportamento strano., - Gestire repository dinamici, in rapida evoluzione o fortemente co-dipendenti con sottomoduli può rapidamente diventare frustrante. Questo post è stato incentrato su relazioni di repository genitore-figlio semplici e relativamente statiche. Un futuro post di follow-up illustrerà alcune strategie per aiutare a gestire i flussi di lavoro dei sottomoduli più complessi.