Actualización del submódulo de Git

Resuelto deepblue asked hace 14 años • 4 respuestas

No tengo claro qué significa lo siguiente (de la documentación de actualización del submódulo de Git ):

...hará que los submódulos HEAD se separe, a menos que se especifique --rebaseo ...--merge

¿Cómo --rebasecambia --mergelas cosas?

Mi principal caso de uso es tener un montón de repositorios centrales, que integraré mediante submódulos en otros repositorios. Me gustaría poder mejorar estos repositorios centrales, ya sea directamente en su ubicación original o desde sus repositorios integrados (los que los usan a través de un submódulo).

  • Desde estos submódulos, ¿puedo crear ramas/modificaciones y usar push/pull como lo haría en los repositorios normales, o hay cosas con las que tener cuidado?
  • ¿Cómo podría avanzar el compromiso al que se hace referencia en el submódulo de, por ejemplo, (etiquetado) 1.0 a 1.1 (aunque el encabezado del repositorio original ya está en 2.0), o elegir qué compromiso de rama se utiliza?
deepblue avatar Dec 30 '09 16:12 deepblue
Aceptado

Esta página de GitPro resume muy bien las consecuencias de una actualización del submódulo de git

Cuando ejecuta git submodule update, verifica la versión específica del proyecto, pero no dentro de una rama. A esto se le llama tener un encabezado separado; significa que el archivo HEAD apunta directamente a una confirmación, no a una referencia simbólica.
El problema es que, por lo general, no conviene trabajar en un entorno de cabeza separada, porque es fácil perder los cambios .
Si realiza una actualización inicial del submódulo, confirma en ese directorio de submódulo sin crear una rama para trabajar y luego ejecuta git submodule update nuevamente desde el superproyecto sin confirmar mientras tanto, Git sobrescribirá sus cambios sin avisarle. Técnicamente no perderás el trabajo, pero no tendrás una rama apuntando a él, por lo que será algo difícil de recuperar.


Nota de marzo de 2013:

Como se menciona en " Git Submodule Tracking Latest ", un submódulo ahora (git1.8.2) puede rastrear una rama.

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 
# or (with rebase)
git submodule update --rebase --remote

Ver " git submodule update --remotevsgit pull ".

La respuesta de MindTooth ilustra una actualización manual (sin configuración local):

git submodule -q foreach git pull -q origin master

En ambos casos, eso cambiará las referencias de los submódulos (el gitlink , una entrada especial en el índice del repositorio principal ), y deberá agregar, confirmar y enviar dichas referencias desde el repositorio principal.
La próxima vez que clone ese repositorio principal, completará los submódulos para reflejar esas nuevas referencias SHA1.

El resto de esta respuesta detalla la característica clásica del submódulo (referencia a una confirmación fija , que es el punto detrás de la noción de submódulo).


Para evitar este problema, cree una rama cuando trabaje en un directorio de submódulo con git checkout -b work o algo equivalente. Cuando realice la actualización del submódulo por segunda vez, aún revertirá su trabajo, pero al menos tendrá un puntero al que volver.

Cambiar ramas con submódulos también puede ser complicado. Si crea una nueva rama, agrega un submódulo allí y luego vuelve a una rama sin ese submódulo, aún tendrá el directorio del submódulo como un directorio sin seguimiento:


Entonces, para responder a tus preguntas:

¿Puedo crear ramas/modificaciones y usar push/pull como lo haría en repositorios normales, o hay cosas con las que tener cuidado?

Puede crear una rama y enviar modificaciones.

ADVERTENCIA (del Tutorial del submódulo de Git ): siempre publique (envíe) el cambio del submódulo antes de publicar (envíe) el cambio en el superproyecto que hace referencia a él. Si olvida publicar el cambio del submódulo, otros no podrán clonar el repositorio.

¿Cómo podría avanzar el compromiso al que se hace referencia en el submódulo de, por ejemplo, (etiquetado) 1.0 a 1.1 (aunque el encabezado del repositorio original ya está en 2.0)?

La página " Comprensión de los submódulos " puede ayudar

Los submódulos de Git se implementan mediante dos partes móviles:

  • el .gitmodulesarchivo y
  • un tipo especial de objeto de árbol.

Estos juntos triangulan una revisión específica de un repositorio específico que se extrae en una ubicación específica de su proyecto.


Desde la página del submódulo de git

no se puede modificar el contenido del submódulo desde el proyecto principal

100% correcto: no puedes modificar un submódulo, solo hacer referencia a una de sus confirmaciones.

Es por eso que, cuando modifica un submódulo desde el proyecto principal, usted:

  • necesita confirmar y empujar dentro del submódulo (al módulo ascendente), y
  • luego suba a su proyecto principal y vuelva a confirmar (para que ese proyecto principal se refiera al nuevo submódulo confirmado que acaba de crear y enviar)

Un submódulo le permite tener un enfoque de desarrollo basado en componentes , donde el proyecto principal solo hace referencia a confirmaciones específicas de otros componentes (aquí "otros repositorios Git declarados como submódulos").

Un submódulo es un marcador (compromiso) con otro repositorio de Git que no está vinculado al ciclo de desarrollo del proyecto principal: (el "otro" repositorio de Git) puede evolucionar de forma independiente.
Depende del proyecto principal elegir de ese otro repositorio cualquier compromiso que necesite.

Sin embargo, si desea, por conveniencia , modificar uno de esos submódulos directamente desde su proyecto principal, Git le permite hacerlo, siempre que primero publique esas modificaciones del submódulo en su repositorio de Git original y luego confirme su proyecto principal haciendo referencia a una nueva versión de dicho submódulo.

Pero la idea principal sigue siendo: hacer referencia a componentes específicos que:

  • tener su propio ciclo de vida
  • tener su propio conjunto de etiquetas
  • tener su propio desarrollo

La lista de confirmaciones específicas a las que se refiere en su proyecto principal define su configuración (de esto se trata la Gestión de la Configuración , que abarca el mero Sistema de Control de Versiones )

Si un componente realmente pudiera desarrollarse al mismo tiempo que su proyecto principal (porque cualquier modificación en el proyecto principal implicaría modificar el subdirectorio, y viceversa), entonces ya no sería un "submódulo", sino un fusión de subárbol (también presentada en la pregunta Transferencia de código base heredado de cvs a repositorio distribuido ), vinculando el historial de los dos repositorios de Git.

¿Eso ayuda a comprender la verdadera naturaleza de los submódulos de Git?

VonC avatar Dec 30 '2009 09:12 VonC

Para actualizar cada submódulo, puede invocar el siguiente comando (en la raíz del repositorio):

git submodule -q foreach git pull -q origin master

Puede eliminar la opción -q para seguir todo el proceso.

MindTooth avatar Feb 01 '2012 20:02 MindTooth

Para abordar la opción --rebasevs .:--merge

Digamos que tienes el superrepositorio A y el submódulo B y quieres trabajar un poco en el submódulo B. Has hecho tu tarea y lo sabes después de llamar

git submodule update

estás en un estado sin HEAD, por lo que es difícil volver a realizar cualquier confirmación que realices en este punto. Entonces, has comenzado a trabajar en una nueva rama en el submódulo B.

cd B
git checkout -b bestIdeaForBEver
<do work>

Mientras tanto, alguien más en el proyecto A ha decidido que la última y mejor versión de B es realmente lo que A merece. Usted, por costumbre, fusiona los cambios más recientes y actualiza sus submódulos.

<in A>
git merge develop
git submodule update

¡Oh, no! Estás nuevamente en un estado sin cabeza, probablemente porque B ahora apunta al SHA asociado con el nuevo consejo de B, o alguna otra confirmación. Si tan solo tuvieras:

git merge develop
git submodule update --rebase

Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'

Ahora, la mejor idea jamás creada para B se ha adaptado al nuevo compromiso y, lo que es más importante, todavía estás en tu rama de desarrollo para B, ¡no en un estado sin cabeza!

( --mergeFusionará los cambios de beforeUpdateSHA a afterUpdateSHA en su rama de trabajo, en lugar de rebasar sus cambios en afterUpdateSHA).

robinspb avatar Jan 25 '2014 00:01 robinspb