Come faccio a ripristinare le mie modifiche a un sottomodulo git?


283

Ho un sottomodulo git (RestKit) che ho aggiunto al mio repository.

Ho cambiato accidentalmente alcuni file e vorrei tornare alla versione originale. Per farlo, ho provato a correre

Mac:app-ios user$ git submodule update RestKit

Ma come puoi vedere qui, questo non ha funzionato in quanto è ancora "contenuto modificato":

Mac:app-ios user$ git status
...
#   modified:   RestKit (modified content)

Anche

Mac:app-ios user$ git submodule update -f RestKit 

non ripristina i file modificati localmente.
Come si ripristina il contenuto di quel sottomodulo?


Se git reset --hardnon funziona, prova prima a specificare il ramo remoto con git reset --hard origin/<branch_name>.
Jerry K.

Risposte:


217

Spostati nella directory del sottomodulo, quindi esegui a git reset --hardper ripristinare tutti i file modificati all'ultimo stato di commit. Tieni presente che questa operazione eliminerà tutte le modifiche non confermate.


7
L'aggiornamento del sottomodulo git (anche senza --init) ha funzionato per me per abbandonare le "modifiche" del sottomodulo quando in realtà non avevo cambiato nulla. Se vai nella directory del sottomodulo e git status risulta vuoto, prova questo invece del ripristino.
DNA eclettico

22
git submodule update --initha funzionato per me; senza --initnon funzionava affatto.
Per Lundberg,

Stupendo !! Ho apportato modifiche al sottomodulo in un mio repo in cui l'ho importato. E questo lo ha riportato a quello che doveva essere.
Noitidart

2
reset --hard non ha funzionato per me, il mio sottomodulo non poteva ancora essere deinit a causa di modifiche locali.
malhal

38
oltre a @markshiz, git submodule update -f --initper il mio caso.
otiai10

290

Se vuoi farlo per tutti i sottomoduli, senza dover cambiare directory, puoi eseguire

git submodule foreach git reset --hard

Puoi anche usare il flag ricorsivo da applicare a tutti i sottomoduli:

git submodule foreach --recursive git reset --hard


8
questo funziona molto meglio per l'automazione che provare a eseguire il cd in ogni directory del sottomodulo.
Travis Castillo

5
Nota che potresti anche volerlogit submodule foreach --recursive git clean -x -f -d
yoyo

1
sulla mia macchina (Windows che utilizza Git 2.22.0) Ho bisogno di virgolette singole attorno al secondo comando git quando uso il flag --recursive o non funzionerà: git submodule foreach --recursive 'git clean -x -f -d'
aatwo

215

Un metodo più sicuro rispetto a tutte le risposte precedenti:

git submodule deinit -f .
git submodule update --init

Il primo comando "svincola" completamente tutti i sottomoduli, il secondo ne esegue quindi un nuovo checkout.
Ci vuole più tempo rispetto agli altri metodi, ma funzionerà qualunque sia lo stato dei tuoi sottomoduli.


1
Purtroppo questo non ha funzionato nel mio caso (con file locali modificati in un sottomodulo git), il comando "update --init" sputaerror: Your local changes to the following files would be overwritten by checkout
rogerdpack

1
Per aggiornare un sottomodulo specifico fai: $ git submodule deinit -f - <submodule_path> e poi $ git submodule update --init - <submodule_path>
Priyank

1
Ho provato tutti i metodi sopra fino a quando non sono arrivato a questo. Per me, questo è l'unico che ha reso il mio git "pulito" (senza il *mio PS1che git status -unonon è stato in grado di spiegare).
Guy Rapaport

62

Bene per me, avendo

git reset --hard

basta reimpostare il sottomodulo allo stato in cui è stato estratto, non necessario per il commit / stato di riferimento del repository principale. Avrò ancora "contenuti modificati" come ha detto OP. Quindi, per riportare il sottomodulo al commit corretto, eseguo:

git submodule update --init

Quindi quando lo faccio git status, è pulito sul sottomodulo.


purtroppo submodule update --initnon sembra comunque annullare le modifiche locali nel mio caso: |
rogerdpack

48

fai 4 passaggi sequenziali:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f

2
L'unico che ha aiutato anche me.
Victor Sergienko

domanda, se il sottomodulo è nuovo, non ci sarà un file .git all'interno di quella directory, corretto? il comando git verrà visualizzato nel repository principale?
santiago arizti

1
@jiahut Anche dopo aver fatto questo, ho ancora "(nuovi commit") accanto al mio sottomodulo quando eseguo 'git status' dal genitore?
David Doria

1
@DavidDoria git submodule updateera ciò che ha risolto il problema (new commits)per me.
ubershmekel

31

Questo ha funzionato per me, anche ricorsivamente nei sottomoduli (forse è per questo che il tuo -f non ha funzionato, perché hai cambiato un sottomodulo all'interno del sottomodulo):

git submodule update -f --recursive

14

Per prima cosa prova questo, come altri hanno detto:

git submodule update --init

Se ciò non funziona, passare alla directory del sottomodulo e utilizzare il seguente comando per vedere se ci sono modifiche al sottomodulo:

git status

Se ci sono modifiche al tuo sottomodulo, sbarazzartene. Verifica di non poter vedere alcuna modifica quando esegui "git status".

Successivamente, torna al repository principale ed esegui di nuovo "git submodule update --init".


9

Da Git 2.14 (Q3 2017), non è necessario entrare in ogni sottomodulo per eseguire un git reset(come in git submodule foreach git reset --hard)

Questo perché git reset stesso ora sa come entrare ricorsivamente nei sottomoduli.

Vedere commit 35b96d1 (21 aprile 2017) e commit f2d4899 , commit 823bab0 , commit cd279e2 (18 aprile 2017) di Stefan Beller ( stefanbeller) .
(Fuso da Junio ​​C Hamano - gitster- in commit 5f074ca , 29 maggio 2017)

builtin / reset: aggiungi l'opzione --recurse-submodules

git-reset è ancora un altro manipolatore di alberi funzionante, che dovrebbe essere istruito sui sottomoduli.

Quando un utente usa git-reset e richiede di ricorrere ai sottomoduli, questo reimposterà i sottomoduli al nome dell'oggetto registrato nel superprogetto, staccando gli HEAD.

Avvertimento : la differenza tra:

  • git reset --hard --recurse-submodule e
  • git submodule foreach git reset --hard

è che il primo ripristinerà anche l'albero di lavoro del repository principale principale, poiché il secondo ripristinerà solo l'albero di lavoro dei sottomoduli.
Quindi usa con cautela.


7

Per git <= 2.13 questi due comandi combinati dovrebbero resettare i tuoi repository con sottomoduli ricorsivi:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init

3

Funziona con le nostre librerie che eseguono GIT v1.7.1, dove abbiamo un repository di pacchetti DEV e un repository di pacchetti LIVE. I repository stessi non sono altro che una shell per impacchettare le risorse per un progetto. tutti i sottomoduli.

Il LIVE non viene mai aggiornato intenzionalmente, tuttavia possono verificarsi file cache o incidenti, lasciando il repository sporco. Anche i nuovi sottomoduli aggiunti al DEV devono essere inizializzati all'interno di LIVE.

Repository dei pacchetti in DEV

Qui vogliamo estrarre tutte le modifiche a monte di cui non siamo ancora a conoscenza, quindi aggiorneremo il nostro repository di pacchetti.

# Recursively reset to the last HEAD
git submodule foreach --recursive git reset --hard

# Recursively cleanup all files and directories
git submodule foreach --recursive git clean -fd

# Recursively pull the upstream master
git submodule foreach --recursive git pull origin master

# Add / Commit / Push all updates to the package repo
git add .
git commit -m "Updates submodules"
git push   

Repository dei pacchetti in LIVE

Qui vogliamo estrarre le modifiche che sono impegnate nel repository DEV, ma non le modifiche a monte sconosciute.

# Pull changes
git pull

# Pull status (this is required for the submodule update to work)
git status

# Initialize / Update 
git submodule update --init --recursive

1

il mio modo per resettare tutti i sottomoduli (SENZA scollegare e mantenere il loro ramo "master"):

sottomodulo git foreach "git checkout master && git reset --hard $ sha1"


Cos'è $ sha1?
Nujufas

1

Se vuoi eliminare tutte le modifiche nell'intero repository insieme ai sottomoduli, puoi usare

git restore . --recurse-submodules

Questo annullerà tutte le modifiche apportate nel repository e nei moduli secondari.


0

Se ci sono modifiche nei tuoi sottomoduli, usa

git submodule foreach --recursive git reset --hard

Se le tue modifiche sono modifiche al sottomodulo remoto, usa

git submodule update --init

Se queste modifiche sono state salvate, utilizzare

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