Como git submodule add -bfunciona
Después de agregar un submódulo con una rama específica, un nuevo repositorio clonado (después git submodule update --init) estará en una confirmación específica, no la rama en sí ( git statusen el submódulo muestra "Actualmente no en ninguna rama").
No puedo encontrar ninguna información sobre .gitmoduleso .git/configsobre la rama del submódulo o cualquier confirmación específica, entonces, ¿cómo lo resuelve Git?
Además, ¿es posible especificar una etiqueta en lugar de una rama?
Estoy usando la versión 1.6.5.2.
git
git-submodules
Ivan
fuente
fuente

Respuestas:
Nota: Git 1.8.2 agregó la posibilidad de rastrear ramas. Vea algunas de las respuestas a continuación.
Es un poco confuso acostumbrarse a esto, pero los submódulos no están en una rama. Son, como usted dice, solo un puntero a una confirmación particular del repositorio del submódulo.
Esto significa que, cuando alguien más revisa su repositorio o extrae su código y actualiza git submodule, el submódulo se desprotege para ese commit en particular.
Esto es excelente para un submódulo que no cambia a menudo, porque entonces todos en el proyecto pueden tener el submódulo en el mismo commit.
Si desea mover el submódulo a una etiqueta en particular:
Luego, otro desarrollador que quiere cambiar el submodule_directory a esa etiqueta, hace esto
git pullcambios que comprometen sus puntos de directorio de submódulos.git submodule updateen realidad se fusiona en el nuevo código.fuente
cd my_submodule; git checkout [ref in submodule's repositoryrendimientosfatal: reference is not a tree: .... Es como sigitsolo operara en el repositorio principal.git checkout v1.0una rama o una etiqueta?Me gustaría agregar una respuesta aquí que en realidad es solo un conglomerado de otras respuestas, pero creo que puede ser más completa.
Sabes que tienes un submódulo Git cuando tienes estas dos cosas.
Tu
.gitmodulestiene una entrada como esta:Tiene un objeto de submódulo (denominado SubmoduleTestRepo en este ejemplo) en su repositorio de Git. GitHub los muestra como objetos "submódulos". O hacerlo
git submodule statusdesde una línea de comando. Los objetos de submódulo Git son tipos especiales de objetos Git y contienen la información SHA para una confirmación específica.Cada vez que haga un
git submodule update, rellenará su submódulo con contenido del commit. Sabe dónde encontrar el commit debido a la información en el.gitmodules.Ahora, todo lo que
-bhace es agregar una línea en su.gitmodulesarchivo. Entonces, siguiendo el mismo ejemplo, se vería así:El objeto submódulo todavía apunta a una confirmación específica. Lo único que la
-bopción te compra es la posibilidad de agregar una--remotebandera a tu actualización según la respuesta de Vogella:En lugar de completar el contenido del submódulo en el commit señalado por el submódulo, reemplaza ese commit con el último commit en la rama maestra, LUEGO llena el submódulo con ese commit. Esto se puede hacer en dos pasos por respuesta djacobs7. Como ahora ha actualizado la confirmación a la que apunta el objeto de submódulo, debe confirmar el objeto de submódulo modificado en su repositorio de Git.
git submodule add -bNo es una forma mágica de mantener todo actualizado con una rama. Simplemente agrega información sobre una rama en el.gitmodulesarchivo y le da la opción de actualizar el objeto de submódulo a la última confirmación de una rama específica antes de completarla.fuente
.gitmodulesy después de hacerlo$ git submodule update --init --remote TestModulerecibí un error que decíafatal: Needed a single revisionyUnable to find current origin/TestTag revision in submodule path 'TestModule'. Al hacerlo con una rama real, funciona. ¿Hay alguna forma de especificar una etiqueta.gitmodulessin tener que especificar la confirmación exacta?.gitmodulesy corrígit submodule updatey no pasó nada?(Git 2.22, Q2 2019, ha introducido
git submodule set-branch --branch aBranch -- <submodule_path>)Tenga en cuenta que si tiene un submódulo existente que aún no está rastreando una rama , entonces ( si tiene git 1.8.2+ ):
Asegúrese de que el repositorio principal sepa que su submódulo ahora rastrea una rama:
Asegúrese de que su submódulo sea realmente el último de esa rama:
(con 'origen' es el nombre de la distancia aguas arriba de recompra del submódulo se ha clonado a partir de.
Un
git remote -vdentro de esa sub-módulo mostrará la misma. Por lo general, es 'origen')No olvide registrar el nuevo estado de su submódulo en su repositorio principal:
La actualización posterior para ese submódulo tendrá que usar la
--remoteopción:Tenga en cuenta que con Git 2.10+ (Q3 2016), puede usar '
.' como nombre de sucursal:Pero, como se ha comentado por LubosD
Eso significa Git 2.23 (agosto de 2019) o más.
Ver " Confundido por
git checkout"Si desea actualizar todos sus submódulos siguiendo una rama:
Tenga en cuenta que el resultado, para cada submódulo actualizado, casi siempre será un HEAD separado , como lo nota Dan Cameron en su respuesta .
( Clintm señala en los comentarios que, si ejecuta
git submodule update --remotey el sha1 resultante es el mismo que la rama en la que se encuentra actualmente el submódulo, no hará nada y dejará el submódulo todavía "en esa rama" y no en el estado de la cabeza separada. )Para asegurarse de que la rama esté realmente desprotegida (y eso no modificará el SHA1 de la entrada especial que representa el submódulo para el repositorio principal), sugiere:
Cada submódulo seguirá haciendo referencia al mismo SHA1, pero si realiza nuevas confirmaciones, podrá empujarlas porque serán referenciadas por la rama a la que desea que el submódulo rastree.
Después de ese empuje dentro de un submódulo, no olvide volver al repositorio principal, agregar, confirmar y empujar el nuevo SHA1 para esos submódulos modificados.
Tenga en cuenta el uso de
$toplevel, recomendado en los comentarios de Alexander Pogrebnyak .$toplevelse introdujo en git1.7.2 en mayo de 2010: commit f030c96 .dtmlandagrega en los comentarios :El mismo comando pero más fácil de leer:
umläute refina el comando de dtmland con una versión simplificada en los comentarios :
líneas múltiples:
Antes de Git 2.26 (Q1 2020), una búsqueda a la que se le pide que busque actualizaciones de forma recurrente en submódulos inevitablemente produce resmas de salida, y se hace difícil detectar mensajes de error.
Se le ha enseñado al comando a enumerar submódulos que tenían errores al final de la operación .
Ver commit 0222540 (16 de enero de 2020) por Emily Shaffer (
nasamuffin) .(Fusionada por Junio C Hamano -
gitster- en commit b5c71cc , 05 de febrero de 2020)fuente
foreachsecuencia de comandos no dependerá del código rígido<path>, si lo sustituye<path>con$toplevel/.foreachsecuencia de comandos no podrá extraer submódulos que no siguen una rama. Sin embargo, este comando te da ambos:git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch'git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'git submodule update --remote --mergeogit submodule update --remote --rebase. Estos comandos hacen el seguimiento de la rama remota.Git 1.8.2 agregó la posibilidad de rastrear ramas.
Ver también submódulos Git
fuente
.gitmodulesarchivo?git submodule add -b tags/<sometag> <url>que puede ver como la líneabranch = tags/<sometag>en.gitmodulesUn ejemplo de cómo uso los submódulos de Git.
Y eso se parece un poco a esto:
¿Tal vez ayuda (aunque uso una etiqueta y no una rama)?
fuente
git reset --hard V3.1.2? Acabo de recibir un "nada que confirmar" con unogit statusdel directorio principal.En mi experiencia, el cambio de sucursales en el superproyecto o los pagos futuros seguirá causando HEADs separados de submódulos, independientemente de si el submódulo se ha agregado y rastreado correctamente (es decir, @ djacobs7 y @Johnny Z respuestas).
Y en lugar de verificar manualmente la rama correcta manualmente o mediante un script, se puede usar git submodule foreach .
Esto verificará el archivo de configuración del submódulo para la propiedad de la rama y revisará la rama establecida.
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'fuente
Los submódulos de Git son un poco extraños, siempre están en modo de "cabeza separada", no se actualizan a la última confirmación en una rama como es de esperar.
Sin embargo, esto tiene sentido cuando lo piensas. Digamos que creo un repositorio foo con la barra de submódulos . Empujo mis cambios y le digo que compruebe commit a7402be desde el repositorio foo .
Luego imagina que alguien comete un cambio en la barra del repositorio antes de que puedas hacer tu clon.
Cuando eche un vistazo, confirme a7402be desde el repositorio foo , espera obtener el mismo código que introduje. Es por eso que los submódulos no se actualizan hasta que les dices explícitamente y luego realizas una nueva confirmación.
Personalmente, creo que los submódulos son la parte más confusa de Git. Hay muchos lugares que pueden explicar los submódulos mejor que yo. Recomiendo Pro Git de Scott Chacon.
fuente
git clone git://github.com/git/git.gity presionar esa función ...? = DPara cambiar la rama de un submódulo (suponiendo que ya tenga el submódulo como parte del repositorio):
cda la raíz de su repositorio que contiene los submódulos.gitmodulespara editarpath = ...yurl = ...eso dicebranch = your-branch, para cada submódulo; guardar el archivo.gitmodules.$ git submodule update --remote... esto debería extraer los últimos commits en la rama especificada, para cada submódulo así modificado.
fuente
Tengo esto en mi archivo .gitconfig. Todavía es un borrador, pero resultó útil a partir de ahora. Me ayuda a volver a conectar siempre los submódulos a su rama.
fuente
Usamos Quack para extraer un módulo específico de otro repositorio de Git. Necesitamos extraer el código sin toda la base de código del repositorio proporcionado; necesitamos un módulo / archivo muy específico de ese enorme repositorio y debemos actualizarlo cada vez que ejecutamos la actualización.
Entonces lo logramos de esta manera:
Crear configuración
Con la configuración anterior, crea un directorio desde el repositorio GitHub proporcionado como se especifica en la configuración del primer módulo, y el otro es extraer y crear un archivo desde el repositorio dado.
Otros desarrolladores solo necesitan ejecutar
Y extrae el código de las configuraciones anteriores.
fuente
El único efecto de elegir una rama para un submódulo es que, cada vez que pasa la
--remoteopción en lagit submodule updatelínea de comando, Git revisará en modo HEAD separado (si--checkoutse selecciona el comportamiento predeterminado ) la última confirmación de esa rama remota seleccionada .Debe tener especial cuidado al usar esta función de seguimiento de rama remota para submódulos Git si trabaja con clones poco profundos de submódulos. La rama que elija para este propósito en la configuración de submódulos NO ES la que se clonará durante
git submodule update --remote. Si pasa también el--depthparámetro y no le indica a Git sobre qué rama desea clonar , ¡ y en realidad no puede en lagit submodule updatelínea de comando! -, se comportará implícitamente como se explica en lagit-clone(1)documentación paragit clone --single-branchcuando--branchfalta el parámetro explícito y, por lo tanto , clonará solo la rama primaria .Sin sorpresa, después de la etapa de clonación realizada por el
git submodule updatecomando, finalmente intentará verificar la última confirmación para la rama remota que configuró previamente para el submódulo y, si esta no es la principal, no es parte de su clon superficial local, y por lo tanto fallará confuente
git submodule add -b desarrollo --name nombre-rama - https: //branch.git
fuente