Come ripristinare un puntatore Gm Submodule al commit memorizzato nel repository contenente?


128

Ho un sottomodulo git nel mio repository git principale. Da quanto ho capito, il repository principale memorizza un valore SHA (da qualche parte ...), indicando il commit specifico del sottomodulo a cui è "collegato".

Entrai nel mio sottomodulo e digitai git checkout some_other_branch. Non ho idea da quale impegno venissi.

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

Il mio primo (probabilmente ingenuo) istinto è stato quello di dire git reset --hardche sembra funzionare per tutto il resto. Con mia sorpresa, non ha funzionato per questo scenario.

Quindi ho capito che posso scrivere git diff, annotare l'ID SHA che aveva il puntatore del sottomodulo, quindi dirigersi nel sottomodulo e git checkout [SHA ID]... ma sicuramente ci deve essere un modo più semplice?

Dato che sto ancora imparando a conoscere i sottomoduli di Git, sentiti libero di correggere la mia terminologia se ci sono parole per concetti che non conosco.

Risposte:


167

Si desidera aggiornare il sottomodulo in modo che sia sincronizzato con quello che il repository padre ritiene debba essere. Ecco a cosa serve il comando di aggiornamento:

Dalla manpage del sottomodulo:

Aggiornare i sottomoduli registrati, ovvero clonare i sottomoduli mancanti e
verifica il commit specificato nell'indice del contenimento
repository. Ciò farà staccare i sottomoduli HEAD a meno che
--rebase o --merge è specificato o il sottomodulo della chiave. $ name.update
è impostato su rebase o merge.

Esegui questo e tutto dovrebbe andare bene:

git submodule update

4
In qualche modo, per me avevo bisogno di aggiungere --init. Senza di essa, i sottomoduli rimarrebbero in uno stato con (new commits). Anche se i miei sottomoduli erano già stati inizializzati.
Ambidex,

@Ambidex sì, l' --initopzione è cruciale in tutto questo. Mi è stato richiesto 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 utilizzare il sshprotocollo per il checkout.
A-Dubb

1
non funziona se l'hash di commit del sottomodulo viene modificato e non
messo in

può aggiungere --recursive in modo da non dover andare a tutti i sottomoduli
Gaspa79

21

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

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

Inoltre, git submodulesenza un comando sottomodulo ti mostrerà il commit a cui stai puntando. Ci sarà un - o un + davanti al commit se non è sincronizzato.

Se guardi un albero con un sottomodulo, puoi vedere che il sottomodulo è contrassegnato commitcome opposto al resto che sono macchie o alberi.

per vedere quali punti di commit specifici vengono scritti nei sottomoduli puoi:

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

puoi quindi vedere il commit o qualsiasi altra cosa, se lo desideri, passandolo nel log, ecc. (l' git-diropzione a livello di comando git ti consente di saltare il cd fino al sottomodulo):

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

Il comando di seguito mi ha aiutato (volevo ignorare qualsiasi cambiamento nel sottomodulo e anche nel mio modulo): git submodule update --init --recursive
Rajesh Goel

6

Un altro caso in cui mi sono appena imbattuto è se c'è una modifica non messa in scena nel sottomodulo che vuoi scartare. L'aggiornamento del sottomodulo di git non rimuoverà tale modifica, né ripristinerà git --hard nella directory principale. Devi andare nella directory del sottomodulo e fare un reset git --hard. Quindi, se voglio eliminare completamente le modifiche non messe in scena sia nel mio genitore sia nel mio sottomodulo, faccio quanto segue:

Nel genitore:

git reset --hard

git submodule update

Nel sottomodulo:

git reset --hard

5

Utilizzare git ls-tree HEADnella cartella "superproject" per vedere a quale commit era originariamente il sottomodulo. Quindi passare alla directory del sottomodulo e utilizzare git log --oneline --decorateper vedere su quale ramo si trova il commit originale. Infine, git checkout original-commit-branch.

Usando alcune directory di test che ho impostato, ecco come potrebbero apparire i comandi:

$ 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 sottomodulo sm2 in commit f68bed6ma sm2 ha HEAD a 5b8d48f. Il commit del sottomodulo f68bed6ha tre rami su di esso che possono essere usati per il checkout nella directory del sottomodulo.


GRAZIE DAN, PERFETTO!
Alec,


1

Volevo ignorare qualsiasi cambiamento nel sottomodulo e anche nel mio modulo

Il seguente comando mi ha aiutato:

git submodule update --init --recursive
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.