Posterior a de una larga compilación de información dimos con la solución este atolladero que pueden tener muchos usuarios. Te brindamos la respuesta y esperamos resultarte de mucha apoyo.
Solución:
Esta página de GitPro resume muy bien la consecuencia de una actualización de submódulo de git
Cuando corres
git submodule update
, comprueba la versión específica del proyecto, pero no dentro de una rama. Esto se 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 desea trabajar en un entorno de cabeza independiente, porque es fácil perder cambios..
Si realiza una actualización inicial de submódulo, confirme en ese directorio de submódulo sin crear una rama para trabajar, y luego ejecute git submodule update nuevamente desde el superproyecto sin comprometerse mientras tanto, Git sobrescribirá sus cambios sin avisarle. Técnicamente, no perderá el trabajo, pero no tendrá una rama apuntando hacia é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 --remote
vs git 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 un reparado commit, que es todo 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 tiene un puntero al que volver.
Cambiar ramas con submódulos en ellas también puede ser complicado. Si crea una nueva rama, agrega un submódulo allí y luego vuelve a cambiar a una rama sin ese submódulo, todavía tiene el directorio del submódulo como un directorio sin seguimiento:
Entonces, para responder a sus preguntas:
¿Puedo crear ramas / modificaciones y usar push / pull como lo haría en repositorios regulares, o hay cosas sobre las que tener cuidado?
Puede crear una rama y enviar modificaciones.
ADVERTENCIA (de Git Submodule Tutorial): Siempre publique (envíe) el cambio de submódulo antes de publicar (empuje) el cambio en el superproyecto que hace referencia a él. Si olvida publicar el cambio de submódulo, otros no podrán clonar el repositorio.
¿Cómo avanzaría el compromiso al que se hace referencia al 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 usando dos partes móviles:
- los
.gitmodules
archivo 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 en su proyecto.
Desde la página del submódulo de git
no puede modificar el contenido del submódulo desde dentro del proyecto principal
100% correcto: no puede modificar un submódulo, solo consulte una de sus confirmaciones.
Esta es la razón por la que, cuando modifica un submódulo desde dentro del proyecto principal, usted:
- Necesito comprometerme y empujar dentro de el submódulo (al módulo ascendente), y
- luego suba en su proyecto principal y vuelva a comprometerse (para que ese proyecto principal se refiera a la nueva confirmación de submódulo que acaba de crear y enviar)
Un submódulo le permite tener un enfoque basado en componentes desarrollo, donde el proyecto principal solo se refiere a confirmaciones específicas de otros componentes (aquí “otros repositorios de Git declarados como submódulos”).
Un submódulo es un marcador (compromiso) para otro repositorio de Git que no está vinculado por el ciclo de desarrollo del proyecto principal: este (el “otro” repositorio de Git) puede evolucionar de forma independiente.
Depende del proyecto principal elegir de ese otro repositorio cualquier confirmación que necesite.
Sin embargo, si lo desea, por conveniencia, modifique uno de esos submódulos directamente desde su proyecto principal, Git le permite hacerlo, siempre que primero publicar esas modificaciones de submódulo en su repositorio de Git original, y luego comprometer su proyecto principal refiriéndose a un nuevo versión de dicho submódulo.
Pero la idea principal sigue siendo: hacer referencia a componentes específicos que:
- tienen 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 (esto es lo que Configuración La gestión se trata de englobar el mero sistema de control de versiones)
Si un componente realmente pudiera desarrollarse al mismo tiempo como 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 una fusión de subárbol (también presentado en la pregunta Transferencia de código heredado base de cvs al repositorio distribuido), vinculando el historial de los dos repositorios de Git.
¿Eso ayuda a comprender el true naturaleza de los submódulos de Git?
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 quitar el -q opción de seguir todo el proceso.
Para abordar el --rebase
vs. --merge
opción:
Digamos que tienes el super repositorio 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 cualquier confirmación que hagas en este punto. Entonces, ha comenzado a trabajar en una nueva rama en el submódulo B
cd B
git checkout -b bestIdeaForBEver
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 se merece. Usted, por costumbre, fusiona los cambios más recientes y actualiza sus submódulos.
git merge develop
git submodule update
¡Oh no! Estás de nuevo en un estado sin cabeza de nuevo, probablemente porque B ahora apunta al SHA asociado con la nueva sugerencia 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 que la mejor idea para B se ha vuelto a basar en la nueva confirmación y, lo que es más importante, todavía está en su rama de desarrollo para B, ¡no en un estado sin cabeza!
(Los --merge
fusionará los cambios de beforeUpdateSHA a afterUpdateSHA en su rama de trabajo, en lugar de volver a agrupar sus cambios en afterUpdateSHA).
Te mostramos las reseñas y valoraciones de los lectores
Si te apasiona la programación, eres capaz de dejar una división acerca de qué te ha parecido esta noticia.