Git non inizializzerà / sincronizzerà / aggiornerà nuovi sottomoduli


113

Ecco parte del contenuto del mio .gitmodulesfile:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

Tuttavia, .git/configcontiene solo il primo:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

Il secondo sottomodulo ( external/pyfacebook) è stato aggiunto da un altro sviluppatore in un ramo delle funzionalità. Ho ereditato lo sviluppo ora e ho verificato il ramo delle funzionalità. Tuttavia, Git non estrarrà il sottomodulo per me. Ho provato:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • Rimozione di tutte le definizioni del sottomodulo da .git/confige in esecuzione git submodule init. Copia solo sul sottomodulo esistente in precedenza e ignora quello nuovo.
  • Inserimento di nuove definizioni di sottomodulo .git/configmanualmente e in esecuzione git submodule update. Solo i sottomoduli esistenti in precedenza si preoccupano di aggiornare.

in varie combinazioni, ma git semplicemente non si aggiornerà in .git/configbase ai nuovi contenuti di .gitmodules, né creerà la external/pyfacebookcartella e tirerà i contenuti del sottomodulo.

Cosa mi sto perdendo? L'intervento manuale (aggiunta di una voce di sottomodulo a mano .git/config) è veramente necessario, e perché?

Modifica: l' intervento manuale non funziona. L'aggiunta manuale della nuova voce del sottomodulo a .git/confignon fa nulla. Il nuovo sottomodulo viene ignorato.


1
in esecuzione 1.7.7.1 e con lo stesso problema: "git submodule sync" non aggiorna .git / config dopo una modifica a .gitmodules.
James Pritts

Risposte:


92

Ho avuto lo stesso problema: si è scoperto che il file .gitmodules era stato sottoposto a commit, ma il commit del sottomodulo effettivo (ovvero il record dell'ID commit del sottomodulo) non lo era.

L'aggiunta manuale sembrava fare il trucco, ad esempio:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(Anche senza rimuovere nulla da .git / config o .gitmodules.)

Quindi eseguire il commit per registrare correttamente l'ID.

Aggiunta di ulteriori commenti a questa risposta funzionante: se l'aggiornamento del sottomodulo git init o l'aggiornamento del sottomodulo git non funziona, come descritto sopra, l'aggiunta dell'URL del sottomodulo git dovrebbe fare il trucco. Si può fare un controllo incrociato di questo

 git config --list

e si dovrebbe ottenere una voce del sottomodulo che si desidera inserire nel risultato del comando git config --list. Se c'è una voce del tuo sottomodulo nel risultato della configurazione, allora il solito aggiornamento del sottomodulo git --init dovrebbe estrarre il tuo sottomodulo. Per testare questo passaggio, è possibile rinominare manualmente il sottomodulo e quindi aggiornare il sottomodulo.

 mv yourmodulename yourmodulename-temp
 git submodule update --init

Per scoprire se hai modifiche locali nel sottomodulo, puoi vederlo tramite git status -u (se vuoi vedere i cambiamenti nel sottomodulo) o git status --ignore-submodules (se non vuoi vedere i cambiamenti in il sottomodulo).


A cosa serve external/pyfacebook?
IgorGanapolsky

2
@IgorGanapolsky Questo è il percorso di destinazione del tuo sottomodulo.
yuhua

Questo mi ha aiutato, grazie mille! Potrei semplicemente aggiungere che se il percorso di destinazione esiste già (cosa che ha fatto per me come risultato del tentativo di altri comandi) si ottiene il seguente messaggio che si aggiunge alla confusione:'your/local/path' already exists and is not a valid git repo
Michael Ambrus,

1
una riga per leggere le voci in "git config --list":git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
Puggan Se

64

git versione 2.7.4. Questo comando aggiorna il codice locale git submodule update --init --force --remote


20
Non fare niente per me.
Carlo Wood

1
per quanto riguarda git-submodule [documentazione) ( git-scm.com/docs/git-submodule#git-submodule---remote ) il comando di cui sopra dovrebbe aggiornare il ramo locale dei sottomoduli.
palik

1
@palik sei rock!
Denis Trofimov

1
Puoi aggiornare il singolo modulo con git submodule update --init --force --remote <module-name>.
Adam Faryna,

15

Ha avuto lo stesso problema, quando git ignorato inite updatecomandi e non fa nulla.

COME RISOLVERE

  1. La cartella del sottomodulo dovrebbe essere salvata nel repository git
  2. Non dovrebbe essere in .gitignore

Se tali requisiti sono soddisfatti, funzionerà. Altrimenti, tutti i comandi verranno eseguiti senza alcun messaggio e risultato.

Se hai fatto tutto questo e ancora non funziona:

  1. Aggiungi il sottomodulo manualmente, ad es git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. eseguire il commit e il push di tutti i file .gitmodulese della cartella del modulo (nota, il contenuto della cartella non verrà eseguito il commit)
  5. rilascia il tuo repository git locale
  6. clonarne uno nuovo
  7. assicurati che .git/confignon abbia ancora sottomoduli
  8. Ora, git submodule init- e vedrai un messaggio che il modulo ha registrato
  9. git submodule update - recupererà il modulo
  10. Ora guarda .git/confige troverai il sottomodulo registrato

1
Credo che il percorso per i sottomoduli POSSA essere in .gitignore. Almeno l'ho fatto funzionare seguendo la risposta di @DaveJamesMiller. Nient'altro ha funzionato per me.
gebbissimo

7

Sembra esserci molta confusione qui (anche) nelle risposte.

git submodule initè non destinato a generare magicamente roba in .git / config (da .gitmodules). Ha lo scopo di impostare qualcosa in una sottodirectory completamente vuota dopo la clonazione del progetto genitore o il pull di un commit che aggiunge un sottomodulo precedentemente non esistente.

In altre parole, segui una git clonedi un progetto che ha sottomoduli (che saprai dal fatto che il clone ha estratto un file .gitmodules) da un git submodule update --init --recursive.

Tu non seguite git submodule add ...con un git submodule init(o git submodule update --init), che non dovrebbe funzionare. In effetti, l'aggiunta aggiornerà già il .git / config appropriato se le cose funzionano.

MODIFICARE

Se un sottomodulo git precedentemente inesistente è stato aggiunto da qualcun altro, e fai un git pulldi quel commit, la directory di quel sottomodulo sarà completamente vuota (quando esegui git submodule statusl'hash del nuovo sottomodulo dovrebbe essere visibile ma avrà un -davanti it.) In questo caso è necessario far seguire al proprio git pullanche un git submodule update --init(più --recursivequando si tratta di un sottomodulo all'interno di un sottomodulo) per poter estrarre il nuovo sottomodulo precedentemente inesistente; proprio come dopo un primo clone di un progetto con sottomoduli (dove ovviamente non avevi neanche quei sottomoduli prima).


1
Questo è interessante, perché git help submoduledice questo su init: "init: inizializza i sottomoduli registrati nell'indice (che sono stati aggiunti e salvati altrove) copiando i nomi dei sottomoduli e gli URL da .gitmodules a .git / config." Quindi sembra che dovrebbe fare esattamente quello che dici che non fa ...? Tempo per un aggiornamento sulla documentazione di git?
Brad

@ Brad Non credo di averlo detto, ma ho aggiunto un chiarimento per quel caso specifico. Grazie.
Carlo Wood

@CarloWood hai idea del perché gli autori di sottomoduli git abbiano deciso che --initdovrebbe essere necessario per ottenere nuovi sottomoduli (invece di afferrarli automaticamente update)? Sembra che l'aggiornamento del tuo repository dovrebbe prendere tutto il necessario a meno che non distrugga i dati. Con --initesso ti costringe a sapere che potrebbero essere stati creati nuovi sottomoduli, o semplicemente emettere sempre un --initogni volta, nel qual caso, ancora, sembrerebbe che dovrebbe essere abilitato di default.
Catskul

@Catskul Ovviamente non ho idea del motivo per cui gli autori dei sottomoduli git abbiano deciso qualcosa, ma la mia ipotesi è che "update" sia riservato all'aggiornamento di qualcosa che già esiste, e "init" sia usato per creare qualcosa (localmente) di nuovo. Sotto il cofano i due sono probabilmente abbastanza diversi da giustificare un comando diverso.
Carlo Wood

6

Ho avuto lo stesso problema ma nessuna delle soluzioni sopra ha aiutato. Le voci in .gitmodules e in .git / config erano corrette ma il comando non git submodules update --init --recursivestava facendo nulla. Ho anche rimosso la directory del sottomodulo e ho eseguito git submodules update --init --recursivee ho recuperato la directory del sottomodulo, ma con esattamente lo stesso commit di prima.

Ho trovato la risposta in questa pagina . Il comando è:git submodule update --remote


2
Questa è stata anche la soluzione corretta per me. Stavo correndo git submodule updateinvece di git submodule update --remote.
Andrew Medlin

5

Un po 'per magia, ma oggi sono corso git submodule initseguito da git submodule syncseguito da git submodule updatee ha iniziato a tirare i miei sottomoduli ... Magia? Forse! Questa è davvero una delle esperienze più fastidiose con Git ...

Grattalo. In realtà l'ho fatto funzionare facendo git submodule update --init --recursive. Spero che questo ti aiuti.

PS: assicurati di essere nella directory root di git, non in quella del sottomodulo.


7
No, questo non fa assolutamente nulla per me.
IgorGanapolsky

@IgorGanapolsky Ho modificato la risposta sopra con ciò che ha funzionato per me. Fammi sapere se funziona!
Levi Figueira

Ho provato i tuoi nuovi comandi, ma neanche loro hanno fatto nulla.
IgorGanapolsky

5

Pensare che la configurazione manuale .gitmodulessia sufficiente è SBAGLIATO

Il mio locale al git version 2.22.0momento della stesura di questo articolo.

Così sono arrivato a questo thread chiedendomi perché non git submodule initfunzionava; Ho impostato il .gitmodulesfile e ho proceduto a fare git submodule init...

IMPORTANTE

  1. git submodule add company/project.git includes/projectè richiesto (quando si aggiunge il modulo per la prima volta), questo:

    • aggiungi config a .git/config
    • aggiorna il .gitmodulesfile
    • traccia la posizione del sottomodulo ( includes/projectin questo esempio).
  2. si deve quindi git commitdopo aver aggiunto il modulo, questo commetterà .gitmodulese la posizione modulo cingolato.

Quando il progetto viene nuovamente clonato, avrà la .gitmodulesdirectory e i sottomoduli vuoti (ad esempio includes/projectin questo esempio). A questo punto .git/confignon ha ancora la configurazione del sottomodulo, finché non git submodule initviene eseguito, e ricorda che funziona solo perché gli .gitmodulesAND includes/projectsono tracciati nel repository git principale.

Anche per riferimento vedere:



3

Ho avuto lo stesso problema.

.gitmodulesaveva il sottomodulo, ma dopo un git submodule initcomando non era presente .git/config.

Si scopre che lo sviluppatore che ha aggiunto il sottomodulo ha anche aggiunto la directory del sottomodulo al .gitignorefile. Non funziona.


2

Come te, ho scoperto che la sincronizzazione del sottomodulo git non fa quello che ti aspetti che faccia. Solo dopo aver git submodule addripetuto un esplicito cambia l'URL di un sottomodulo.

Quindi, ho inserito questo script in ~/bin/git-submodule-sync.rb:

https://gist.github.com/frimik/5125436

E utilizzo la stessa logica anche su alcuni script di distribuzione git post-ricezione.

Tutto quello che devo fare ora è modificare .gitmodules, quindi eseguire questo script e finalmente funziona come pensavo git submodule syncdovesse.


Questo sembra accadere solo su alcuni repository ... forse a causa di qualche bug in Git. Non mi è capitato su repository di nuova creazione per molto tempo, ma molto tempo fa, quando accadeva sempre su alcuni
repository

2

Oggi ho avuto lo stesso problema e ho capito che perché ho digitato git submodule initallora avevo quelle righe nel mio .git/config:

[submodule]
   active = .

L'ho rimosso e ho digitato:

git submodule update --init --remote

E tutto è tornato alla normalità, il mio sottomodulo aggiornato nella sua sottodirectory come al solito.


2

Il problema per me è che lo sviluppatore precedente del repository aveva eseguito il commit della submodules/thingcartella come una cartella normale, il che significa che quando ho provato a eseguire git submodule add ..., non funzionava con:, 'submodules/thing' already exists in the indexma anche il tentativo di aggiornare il sottomodulo falliva perché ha visto che il percorso non funzionava contenere un sottomodulo.

Per risolvere il problema, ho dovuto eliminare la submodules/thingcartella, eseguire il commit dell'eliminazione, quindi eseguire il git submodule addcomando per aggiungerla di nuovo correttamente:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing

1

Quando l'ho visto oggi, uno sviluppatore aveva spostato parte dell'albero in una nuova sottodirectory e sembra che il suo client git non abbia registrato le regole del sottoprogetto aggiornate nell'albero, invece sono state solo bombardate, lasciando che si .gitmodulesriferiscano entrambi a non aggiornati posizioni ea sottoprogetti che non esistevano più nell'albero corrente.

Aggiungere nuovamente i sottomoduli e confrontare i commit shas del sottomodulo con quelli trovati in git show $breaking_commit_sha(ricerca di righe corrispondenti a regexp ^-Subproject) per regolare le cose fisse necessarie.


1

L'eliminazione della directory del sottomodulo e del suo contenuto (cartella "external / pyfacebook"), se esistente, git submodule add ...potrebbe risolvere i problemi.


1
Questo era il problema per me. Qualcuno aveva salvato la cartella "submodule" come una normale cartella, il che significa che quando ho provato a eseguire "git submodule add ...", non sarebbe riuscito con: "'vendor / mobx-state-tree' esiste già nell'indice" , ma anche il tentativo di aggiornare il sottomodulo falliva perché ha visto che il percorso non conteneva un sottomodulo). Per risolvere il problema, ho dovuto eliminare la cartella, eseguire il commit dell'eliminazione, quindi eseguire il comando git add per aggiungerla di nuovo correttamente.
Venryx

1

Ho avuto un problema simile con un sottomodulo. Semplicemente non voleva essere clonato / estratto / aggiornato / qualunque cosa.

Quando git submodule add git@my-repo.git destinationho provato ad aggiungere nuovamente il sottomodulo usando ho ottenuto il seguente output:

A git directory for 'destination' is found locally with remote(s):
  origin        git@my-repo.git
If you want to reuse this local git directory instead of cloning again from
  git@my-repo.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

Quindi, ho provato a applicare il comando add :
git submodule add --force git@my-repo.git destination

Nel mio caso ha funzionato.


0

Per la cronaca:
ho creato lo stesso numero aggiungendo un repository vuoto come sottomodulo. In questo caso, non era disponibile un hash di riferimento per il sottomodulo, il che ha portato all'errore descritto dal poster originale.

L'aggiunta forzata del repository dopo aver eseguito il commit ha risolto il problema (come nel post di Arvids)
git submodule add --force git@my-repo.git destination


0
  • Rimuovi il sottomodulo dal tuo .git/config
  • Esegui git submodule initcomando
  • Vai alla directory del tuo sottomodulo ed esegui git pull origin master

Ora dovrebbe funzionare


0

Condivido solo ciò che ha funzionato per me:

git clone --recurse-submodules <repository path>

Questo clona il repository remoto che include già i sottomoduli. Ciò significa che non sarà necessario eseguire l'aggiornamento del sottomodulo git o l'inizializzazione dopo la clonazione.


0

Sotto il comando di sincronizzazione è stato risolto il problema:

git submodule sync
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.