2011-10-24 13 views
78

Ho un sottomodulo git nel mio repository git principale. A quanto ho capito, il repository principale memorizza un valore SHA (da qualche parte ...), indicando il commit specifico del sottomodulo che è "collegato a".Come ripristinare un puntatore del sottomodulo Git al commit memorizzato nel repository contenente?

Sono entrato nel mio sottomodulo e ho digitato git checkout some_other_branch. Non ho idea di quale impegno provenga.

Vorrei ripristinare quel puntatore in modo che il repository principale e il sottomodulo siano di nuovo sincronizzati.

Il mio primo (probabilmente ingenuo) istinto diceva git reset --hard - che sembra funzionare per tutto il resto. Con mia sorpresa, non ha funzionato per questo scenario.

Quindi ho capito che posso digitare git diff, annotare l'ID SHA che il puntatore del sottomodulo usava avere, quindi andare al sottomodulo e git checkout [SHA ID] ... ma sicuramente ci deve essere un modo più semplice?

Come sto ancora imparando sui sottomoduli git, non esitate a correggere la mia terminologia se ci sono parole per concetti che non conosco.

risposta

112

si desidera aggiornare il vostro modulo di modo che sia in sintonia con ciò che il repository genitore ritiene che dovrebbe essere. Questo è ciò che il comando di aggiornamento è destinato:

Dalla pagina di manuale modulo:

 
Update the registered submodules, i.e. clone missing submodules and 
checkout the commit specified in the index of the containing 
repository. This will make the submodules HEAD be detached unless 
--rebase or --merge is specified or the key submodule.$name.update 
is set to rebase or merge. 

Esegui questo e tutto deve essere ben:

git submodule update 
+2

In qualche modo, per me avevo bisogno per aggiungere '--init'. Senza di esso, i sottomoduli rimarrebbero in uno stato con '(nuovi commit)'. Anche se i miei sottomoduli erano già inizializzati. – Ambidex

+0

@Ambidex Sì l'opzione '--init' è fondamentale in tutto questo. Mi è stato chiesto il nome utente e la password poiché i miei sottomoduli sono stati clonati su https. Sono andato in entrambe le cartelle e ho impostato i telecomandi per usare il protocollo 'ssh' per il checkout. –

14

Per modificare il commit a cui punta un sottomodulo, è necessario eseguire il checkout di tale versione nel sottomodulo, quindi tornare al repository contenente, aggiungere e confermare tale modifica.

Oppure, se si desidera che il sottomodulo sia nella versione a cui punta il repository superiore, fare git submodule update --recursive. Aggiungi --init se hai appena clonato.

Inoltre, git submodule senza un comando di sottomodulo mostrerà il commit a cui si sta puntando. Ci sarà un - o un + davanti al commit se non è sincronizzato.

Se si guarda un albero con un sottomodulo al suo interno, è possibile vedere che il sottomodulo è contrassegnato come commit in contrapposizione al resto che sono blob o alberi.

per vedere ciò che un particolare commit punti WRT per sottomoduli è possibile:

git ls-tree <some sha1, or branch, etc> Submodule/path 

è quindi possibile vedere il commit o qualsiasi altra cosa, se ti passando che nel registro, ecc (l'opzione git-dir al git livello di comando consente di saltare dover cd verso il modulo):

git --git-dir=Submodule/path log -1 $(<the above statement>) 
4

Usa git ls-tree HEAD nella cartella "SuperProject" per vedere in che cosa era originariamente impegnato il tuo sottomodulo? Quindi passare alla directory del sottomodulo e utilizzare git log --oneline --decorate per vedere in quale ramo è attivo il commit originale. Infine, git checkout original-commit-branch.

Utilizzando alcune directory di prova ho creato, ecco cosa i comandi potrebbero assomigliare:

$ git --version 
git version 1.7.4.1 
$ git status 
# On branch master 
# 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: sm2 (new commits) 
# 
no changes added to commit (use "git add" and/or "git commit -a") 
$ git ls-tree HEAD 
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d .gitmodules 
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 main 
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed sm1 
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337 sm2 
$ cd sm2 
$ git log --oneline --decorate 
5b8d48f (HEAD, foo1) foo1.1 
f68bed6 (origin/master, origin/HEAD, master) Initial commit. 
$ git checkout master 
Switched to branch 'master' 
$ cd .. 
$ git status 
# On branch master 
nothing to commit (working directory clean) 

Il "SuperProject" mostra il modulo SM2 a commettere f68bed6 ma SM2 ha la sua testa 5b8d48f. Il commit del sottomodulo f68bed6 ha tre rami su di esso che possono essere utilizzati per il checkout nella directory del sottomodulo.

+0

GRAZIE DAN, PERFECTO! – Alec

2

Un altro caso in cui mi sono imbattuto è se nel sottomodulo è stato modificato un passaggio che si desidera eliminare. git submodule update non rimuoverà quella modifica, né git resetterà --hard sulla directory genitore. Devi andare nella directory del sottomodulo e fare un reset git --hard. Quindi, se voglio scartare completamente cambiamenti unstaged sia il mio genitore e modulo, faccio la seguente:

In Parent:

git reset --hard 

git submodule update 

In sottomodulo:

git reset --hard 
Problemi correlati