¿Cómo revierto mis cambios a un submódulo git?

271

Tengo un submódulo git (RestKit) que he agregado a mi repositorio.

Cambié accidentalmente algunos archivos allí y me gustaría volver a la versión de origen. Para hacer eso, traté de correr

Mac:app-ios user$ git submodule update RestKit

Pero como puede ver aquí, esto no funcionó ya que todavía es "contenido modificado":

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

Incluso

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

no revierte archivos modificados localmente.
¿Cómo restablezco el contenido de ese submódulo?

Eric
fuente
Si git reset --hardno funciona, primero intente especificar la rama remota con git reset --hard origin/<branch_name>.
Jerry K.

Respuestas:

209

Vaya al directorio del submódulo, luego realice un git reset --hardrestablecimiento de todos los archivos modificados a su último estado confirmado. Tenga en cuenta que esto descartará todos los cambios no comprometidos.

Jamie Penney
fuente
66
La actualización del submódulo git (incluso sin el --init) funcionó para que abandonara los "cambios" del submódulo cuando en realidad no había cambiado nada. Si va al directorio de submódulos y el estado de git aparece vacío, intente esto en lugar del restablecimiento.
ADN ecléctico
16
git submodule update --inittrabajó para mi; sin --initeso no funcionó en absoluto.
Según Lundberg el
¡¡Magnífico!! Hice cambios en el submódulo en un repositorio mío donde lo importé. Y esto lo volvió a lo que se suponía que debía ser.
Noitidart
2
restablecer --hard no funcionó para mí, mi submódulo aún no se pudo deinitar debido a cambios locales.
malhal
33
Además de @markshiz, git submodule update -f --initpara mi caso.
otiai10
280

Si desea hacer esto para todos los submódulos, sin tener que cambiar los directorios, puede realizar

git submodule foreach git reset --hard

También puede usar el indicador recursivo para aplicar a todos los submódulos:

git submodule foreach --recursive git reset --hard

el Cuervo
fuente
77
esto funciona mucho mejor para la automatización que tratar de crear un CD en cada directorio de submódulos.
Travis Castillo
44
Tenga en cuenta que es posible que también deseegit submodule foreach --recursive git clean -x -f -d
yoyo
1
en mi máquina (Windows usando Git 2.22.0) Necesito comillas simples alrededor del segundo comando git cuando uso el indicador --recursive o no funcionará: git submodule foreach --recursive 'git clean -x -f -d'
aatwo
196

Un método más seguro que todas las respuestas anteriores:

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

El primer comando "desvincula" por completo todos los submódulos, el segundo realiza un nuevo pago de ellos.
Lleva más tiempo que los otros métodos, pero funcionará independientemente del estado de sus submódulos.

qwertzguy
fuente
1
Lamentablemente, esto no funcionó en mi caso (con archivos locales modificados en un submódulo git), el comando "actualizar --init" arrojaerror: Your local changes to the following files would be overwritten by checkout
rogerdpack
Para actualizar un submódulo específico haga: $ git submodule deinit -f - <submodule_path> y luego $ git submodule update --init - <submodule_path>
Priyank
Probé todos los métodos anteriores hasta llegar a este. Para mí, este es el único que tiene mi git buscar "limpio" (sin el *en mi PS1que git status -unoera incapaz de explicar).
Guy Rapaport
60

Bueno para mi tener

git reset --hard

simplemente restablezca el submódulo al estado donde se desprotegió, no es necesario para el estado / compromiso referenciado del repositorio principal. Todavía tendré "contenidos modificados" como dijo OP. Entonces, para que el submódulo vuelva a la confirmación correcta, ejecuto:

git submodule update --init

Luego, cuando lo hago git status, está limpio en el submódulo.

suma de comprobación
fuente
lamentablemente submodule update --initno parece revertir las modificaciones locales en mi caso de todos modos: |
rogerdpack
48

hacer 4 pasos secuenciales:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f
jiahut
fuente
2
El único que me ayudó también.
Victor Sergienko
pregunta, si el submódulo es nuevo, no habrá un archivo .git dentro de ese directorio, ¿correcto? ¿El comando git burbujeará al repositorio principal?
santiago arizti
1
@jiahut ¿Incluso después de hacer esto, todavía tengo "(nuevas confirmaciones") al lado de mi submódulo cuando hago 'git status' desde el padre?
David Doria
1
@DavidDoria git submodule updatefue lo que me solucionó el problema (new commits).
ubershmekel
31

Esto funcionó para mí, incluso recursivamente en submódulos (quizás es por eso que su -f no funcionó, porque cambió un submódulo dentro del submódulo):

git submodule update -f --recursive
Sergiu Todirascu
fuente
12

Primero intente esto, como otros han dicho:

git submodule update --init

Si eso no funciona, cambie al directorio del submódulo y use el siguiente comando para ver si hay algún cambio en el submódulo:

git status

Si hay cambios en su submódulo, elimínelos. Verifique que no pueda ver ningún cambio cuando ejecute "git status".

Luego, regrese al repositorio principal y ejecute "git submodule update --init" nuevamente.

Jean Libera
fuente
9

Desde Git 2.14 (Q3 2017), no tiene que entrar en cada submódulo para hacer un git reset(como en git submodule foreach git reset --hard)

Esto se debe a que git reset en sí mismo ahora sabe cómo ir recursivamente a submódulos.

Ver commit 35b96d1 (21 de abril de 2017) y commit f2d4899 , commit 823bab0 , commit cd279e2 (18 de abril de 2017) por Stefan Beller ( stefanbeller) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 5f074ca , 29 de mayo de 2017)

incorporado / reinicio: agregue --recurse-submodules switch

git-reset es otro manipulador de árbol en funcionamiento, que debería enseñarse sobre submódulos.

Cuando un usuario usa git-reset y solicita que se repita en submódulos, esto restablecerá los submódulos al nombre del objeto tal como está registrado en el superproyecto, separando los HEADs.

Advertencia : la diferencia entre:

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

es que el primero también restablecerá el árbol de trabajo del repositorio principal principal, ya que el segundo solo restablecerá el árbol de trabajo de submódulos.
Así que úsalo con precaución.

VonC
fuente
7

Para git <= 2.13, estos dos comandos combinados deberían restablecer sus repositorios con submódulos recursivos:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init
cmcginty
fuente
3

Esto funciona con nuestras bibliotecas que ejecutan GIT v1.7.1, donde tenemos un repositorio de paquetes DEV y un repositorio de paquetes LIVE. Los repositorios en sí mismos no son más que un shell para empaquetar los activos de un proyecto. Todos los submódulos.

LIVE nunca se actualiza intencionalmente, sin embargo, pueden ocurrir archivos de caché o accidentes, dejando el repositorio sucio. Los submódulos nuevos agregados al DEV también deben inicializarse dentro de LIVE.

Repositorio de paquetes en DEV

Aquí queremos obtener todos los cambios ascendentes que aún no conocemos, luego actualizaremos nuestro repositorio de paquetes.

# 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   

Repositorio de paquetes en LIVE

Aquí queremos extraer los cambios comprometidos con el repositorio DEV, pero no los cambios ascendentes desconocidos.

# Pull changes
git pull

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

# Initialize / Update 
git submodule update --init --recursive
David H.
fuente
2

Si desea descartar todos los cambios en todo el repositorio junto con los submódulos, puede usar

git restore . --recurse-submodules

Esto deshacerá todos los cambios realizados en el repositorio y en los submódulos.

Nitin Garg
fuente
0

mi manera de restablecer todos los submódulos (SIN separar y mantener su rama "maestra"):

submódulo git foreach 'git checkout master && git reset --hard $ sha1'

alex_1948511
fuente