aggiornamento del sottomodulo git

Non sono chiaro su quali siano i seguenti mezzi (da git submodule update docs):

… farà distaccare i sottomoduli HEAD, a meno che non sia specificato --rebase o --merge

In che modo --rebase / --merge cambia le cose?

Il mio caso d’uso principale è di avere un gruppo di repository centrali, che inserirò tramite i submoduli in altri repository. Mi piacerebbe essere in grado di migliorare questi repository centrali, direttamente nella loro posizione originale, o all’interno dei loro repository di incorporamento (quelli che li usano tramite il submodule).

  • Da questi sottomoduli, posso creare rami / modifiche e utilizzare push / pull proprio come farei nei normali repository, o ci sono delle cose per cui essere cauti?
  • Come potrei far avanzare il commit di riferimento del sottomodulo da say (taggato) da 1.0 a 1.1 (anche se il capo del repository originale è già 2.0), o scegliere quale commit del ramo viene usato del tutto?

Questa pagina GitPro riassume bene le conseguenze di un aggiornamento del sottomodulo git

Quando esegui l’ git submodule update , controlla la versione specifica del progetto, ma non all’interno di un ramo. Questo è chiamato avere una testa staccata – significa che il file HEAD punta direttamente a un commit, non a un riferimento simbolico.
Il problema è che generalmente non si vuole lavorare in un ambiente indipendente, perché è facile perdere le modifiche .
Se esegui un aggiornamento iniziale del sottomodulo, esegui il commit in quella directory del sottomodulo senza creare un ramo su cui lavorare, quindi esegui di nuovo l’aggiornamento del sottomodulo git dal superprogetto senza impegnarti nel frattempo, Git sovrascriverà le tue modifiche senza dirlo. Tecnicamente non perderai il lavoro, ma non avresti un ramo che lo punta, quindi sarà un po ‘difficile da recuperare.


Nota marzo 2013:

Come menzionato in ” git submodule tracking latest “, un sottomodulo ora (git1.8.2) può tracciare un ramo.

 # add submodule to track master branch git submodule add -b master [URL to Git repo]; # update your submodule git submodule update --remote # or (with rebase) git submodule update --rebase --remote 

Vedi ” git submodule update --remote vs git pull “.

La risposta di MindTooth illustra un aggiornamento manuale (senza configurazione locale):

 git submodule -q foreach git pull -q origin master 

In entrambi i casi, ciò cambierà i riferimenti dei sottomoduli (il gitlink , una voce speciale nell’indice repo parent ) e sarà necessario aggiungere, commettere e spingere detti riferimenti dal repository principale.
La prossima volta che clonerai quel repository padre, popolerà i sottomoduli per riflettere i nuovi riferimenti SHA1.

Il resto di questa risposta descrive in dettaglio la caratteristica del sottomodulo classico (riferimento a un commit fisso , che è il punto dietro la nozione di un sottomodulo).


Per evitare questo problema, crea un ramo quando lavori in una directory di sottomodulo con git checkout -b work o qualcosa di equivalente. Quando esegui l’aggiornamento del sottomodulo una seconda volta, ripristinerà comunque il tuo lavoro, ma almeno avrai un puntatore a cui tornare.

Anche il cambio di filiali con i sottomoduli può essere complicato. Se crei un nuovo ramo, aggiungi un sottomodulo e poi torni a un ramo senza quel sottomodulo, hai ancora la directory del sottomodulo come una directory non tracciata:


Quindi, per rispondere alle tue domande:

posso creare rami / modifiche e usare push / pull proprio come farei nei normali repository, o ci sono cose per cui essere cauti?

È ansible creare un ramo e apportare modifiche.

ATTENZIONE (da Git Submodule Tutorial ): Pubblicare sempre (premere) la modifica del sottomodulo prima di pubblicare (premere) la modifica al superprogetto che la fa riferimento. Se si dimentica di pubblicare la modifica del sottomodulo, gli altri non saranno in grado di clonare il repository.

come potrei far avanzare il commit di riferimento del sottomodulo da say (taggato) da 1.0 a 1.1 (anche se il capo del repository originale è già 2.0)

La pagina ” Understanding Submodules ” può aiutare

I sottomoduli Git sono implementati usando due parti mobili:

  • il file .gitmodules e
  • un tipo speciale di object ad albero.

Questi insieme triangolano una revisione specifica di un repository specifico che viene verificato in una posizione specifica nel progetto.


Dalla pagina del sottomodulo git

non è ansible modificare il contenuto del sottomodulo all’interno del progetto principale

100% corretto: non è ansible modificare un sottomodulo, fare riferimento solo a uno dei suoi commit.

Questo è il motivo per cui, quando modifichi un sottomodulo all’interno del progetto principale, tu:

  • necessità di commit e push all’interno del sottomodulo (al modulo upstream), e
  • quindi vai nel tuo progetto principale e re-commit (in modo che il progetto principale faccia riferimento al nuovo sottomodulo che ti impegni appena creato e premuto)

Un sottomodulo consente di avere uno sviluppo di un approccio basato sui componenti , in cui il progetto principale si riferisce solo a commit specifici di altri componenti (qui “altri repository Git dichiarati come sottomoduli”).

Un sottomodulo è un marcatore (commit) in un altro repository Git che non è vincolato dal ciclo di sviluppo del progetto principale: esso (l’altro repository Git) può evolvere indipendentemente.
Spetta al progetto principale scegliere da quell’altro repository qualunque sia il commit di cui ha bisogno.

Tuttavia, se vuoi, per comodità , modificare uno di questi sottomoduli direttamente dal tuo progetto principale, Git ti permette di farlo, a patto che tu prima pubblichi le modifiche del sottomodulo al suo repository Git originale, e poi impegni il tuo progetto principale riferendosi a una nuova versione di detto sottomodulo.

Ma l’idea principale rimane: fare riferimento a componenti specifici che:

  • hanno il loro ciclo di vita
  • hanno il loro set di tag
  • hanno il loro sviluppo

L’elenco di commit specifici a cui fai riferimento nel tuo progetto principale definisce la tua configurazione (questo è l’aspetto di Configuration Management, englobing mere Version Control System )

Se un componente può davvero essere sviluppato contemporaneamente al progetto principale (perché qualsiasi modifica sul progetto principale implicherebbe la modifica della sottodirectory, e viceversa), allora sarebbe un “sottomodulo” non più, ma un unione secondaria (presentata anche nella domanda Trasferimento del codice legacy di base da cvs a repository distribuito ), che collega la cronologia dei due repo Git insieme.

Questo aiuta a capire la vera natura dei Sottomoduli Git?

Per aggiornare ciascun sottomodulo, è ansible richiamare il seguente comando. (Alla radice del repository.)

 git submodule -q foreach git pull -q origin master 

È ansible rimuovere l’opzione -q per seguire l’intero processo.

Per indirizzare l’opzione –rebase vs –merge:

Diciamo che hai un super-repo A e un sottomodulo B e vuoi lavorare nel sottomodulo B. Hai fatto i compiti e sai che dopo aver chiamato

git submodule update

sei in uno stato senza testa, quindi qualsiasi impegno che fai a questo punto è difficile da raggiungere. Quindi, hai iniziato a lavorare su un nuovo ramo nel sottomodulo B

 cd B git checkout -b bestIdeaForBEver  

Nel frattempo, qualcun altro nel progetto A ha deciso che l’ultima e più grande versione di B è davvero ciò che A merita. Per abitudine, unisci le ultime modifiche e aggiorna i tuoi sottomoduli.

  git merge develop git submodule update 

Oh no! Sei di nuovo in uno stato senza testa, probabilmente perché B sta ora indicando lo SHA associato al nuovo suggerimento di B, o qualche altro commit. Se solo avessi:

 git merge develop git submodule update --rebase Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437. Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437' 

Ora che l’idea migliore per B è stata ridefinita sul nuovo commit e, ancora più importante, sei ancora nel tuo ramo di sviluppo per B, non in uno stato senza testa!

(il –merge unirà le modifiche da beforeUpdateSHA a afterUpdateSHA nel tuo ramo di lavoro, invece di ribasare le tue modifiche su afterUpdateSHA.)

Git 1.8.2 presenta una nuova opzione --remote che abiliterà esattamente questo comportamento. In esecuzione

 git submodule update --rebase --remote 

recupererà le ultime modifiche da upstream in ogni sottomodulo, rebase in loro e verificherà l’ultima revisione del sottomodulo. Come dicono i documenti :

–a distanza

Questa opzione è valida solo per il comando di aggiornamento. Invece di usare SHA-1 registrato del superprogetto per aggiornare il sottomodulo, utilizzare lo stato del ramo di tracciamento remoto del sottomodulo.

Questo è equivalente all’esecuzione di git pull in ogni sottomodulo, che è generalmente esattamente quello che vuoi.

(Copiato da questa risposta )