¿Cómo revertir un puntero de submódulo Git al commit almacenado en el repositorio que lo contiene?

128

Tengo un submódulo git en mi repositorio principal de git. Según tengo entendido, el repositorio principal almacena un valor SHA (en algún lugar ...), apuntando a la confirmación específica del submódulo al que está "vinculado".

Entré en mi submódulo y escribí git checkout some_other_branch. No tengo idea de qué compromiso vengo.

Me gustaría revertir ese puntero para que el repositorio principal y el submódulo estén sincronizados nuevamente.

Mi primer instinto (probablemente ingenuo) fue decir git reset --hard: eso parece funcionar para todo lo demás. Para mi sorpresa, no funcionó para este escenario.

Entonces descubrí que puedo escribir git diff, anotar la ID de SHA que solía tener el puntero del submódulo, y luego dirigirme al submódulo y git checkout [SHA ID]... ¿pero seguramente debe haber una manera más fácil?

Como todavía estoy aprendiendo sobre los submódulos git, siéntase libre de corregir mi terminología si hay palabras para conceptos que no conozco.

Smashery
fuente

Respuestas:

167

Desea actualizar su submódulo para que esté sincronizado con lo que el repositorio principal cree que debería ser. Para esto está el comando de actualización:

Desde la página de manual del submódulo:

Actualice los submódulos registrados, es decir, clone los submódulos faltantes y
desproteger la confirmación especificada en el índice del contenedor
repositorio. Esto hará que los submódulos HEAD se separen a menos que
--rebase o --merge se especifica o el submódulo clave. $ name.update
está configurado para rebase o fusión.

Ejecute esto y todo debería estar bien:

git submodule update
Brian Riehman
fuente
44
De alguna manera, para mí necesitaba agregar --init. Sin él, los submódulos permanecerían en un estado con (new commits). Aunque mis submódulos ya estaban inicializados.
Ambidex
@Ambidex sí, la --initopción es crucial en todo esto. Se me solicitó el nombre de usuario y la contraseña ya que mis submódulos se clonaron a través de https. Fui a ambas carpetas y configuré los controles remotos para usar el sshprotocolo de pago.
A-Dubb
1
no funciona si submódulo commit hash se modificó y unstaged
tribbloid
puede agregar --recursivo para que no necesite ir a todos los submódulos
Gaspa79
21

Para cambiar la confirmación a la que apunta un submódulo, debe verificar esa versión en el submódulo, luego volver al repositorio que contiene, agregar y confirmar ese cambio.

O, si desea que el submódulo esté en la versión a la que apunta el repositorio superior, hágalo git submodule update --recursive. Agregue --initsi acaba de clonar.

Además, git submodulesin un comando de submódulo le mostrará la confirmación a la que está apuntando. Habrá un - o un + delante del commit si no está sincronizado.

Si observa un árbol con un submódulo, puede ver que el submódulo está marcado commitcomo opuesto al resto que son manchas o árboles.

para ver qué puntos de confirmación en particular se escriben en submódulos, puede:

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

luego puede ver el commit o cualquier otra cosa si lo desea pasando eso al registro, etc. (la git-diropción en el nivel de comando git le permite omitir tener que bajar el CD al submódulo):

git --git-dir=Submodule/path log -1 $(<the above statement>)
Adam Dymitruk
fuente
El siguiente comando me ayudó (quería ignorar cualquier cambio en el submódulo y también en mi módulo): git submodule update --init --recursive
Rajesh Goel
6

Otro caso que acabo de encontrar es si hay un cambio sin etapas en el submódulo que desea descartar. git submodule update no eliminará ese cambio, ni git reset --hard en el directorio padre. Debe ir al directorio de submódulos y hacer un restablecimiento de git --hard. Entonces, si deseo descartar por completo los cambios no escalonados tanto en mi padre como en mi submódulo, hago lo siguiente:

En padre:

git reset --hard

git submodule update

En submódulo:

git reset --hard
Benjamin Noffsinger
fuente
5

Úselo git ls-tree HEADen la carpeta "superproyecto" para ver en qué estado se encontraba originalmente su submódulo. Luego cambie al directorio de submódulos y use git log --oneline --decoratepara ver en qué rama se encuentra el commit original. Finalmente,git checkout original-commit-branch .

Utilizando algunos directorios de prueba que configuré, así es como se verían los comandos:

$ 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)

El "superproyecto" muestra el submódulo sm2 en commit f68bed6pero sm2 tiene su HEAD en 5b8d48f. La confirmación de submódulo f68bed6tiene tres ramas que pueden usarse para pagar en el directorio de submódulos.

Dan Cruz
fuente
GRACIAS DAN, PERFECTO!
Alec
1

Quería ignorar cualquier cambio en el submódulo y en mi módulo también

El siguiente comando me ayudó:

git submodule update --init --recursive
Rajesh Goel
fuente