Como git submodule add -b
funciona
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 status
en el submódulo muestra "Actualmente no en ninguna rama").
No puedo encontrar ninguna información sobre .gitmodules
o .git/config
sobre 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 pull
cambios que comprometen sus puntos de directorio de submódulos.git submodule update
en realidad se fusiona en el nuevo código.fuente
cd my_submodule; git checkout [ref in submodule's repository
rendimientosfatal: reference is not a tree: ...
. Es como sigit
solo operara en el repositorio principal.git checkout v1.0
una 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
.gitmodules
tiene 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 status
desde 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
-b
hace es agregar una línea en su.gitmodules
archivo. 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
-b
opción te compra es la posibilidad de agregar una--remote
bandera 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 -b
No es una forma mágica de mantener todo actualizado con una rama. Simplemente agrega información sobre una rama en el.gitmodules
archivo 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
.gitmodules
y después de hacerlo$ git submodule update --init --remote TestModule
recibí un error que decíafatal: Needed a single revision
yUnable to find current origin/TestTag revision in submodule path 'TestModule'
. Al hacerlo con una rama real, funciona. ¿Hay alguna forma de especificar una etiqueta.gitmodules
sin tener que especificar la confirmación exacta?.gitmodules
y corrígit submodule update
y 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 -v
dentro 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
--remote
opció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 --remote
y 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 .$toplevel
se introdujo en git1.7.2 en mayo de 2010: commit f030c96 .dtmland
agrega 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
foreach
secuencia de comandos no dependerá del código rígido<path>
, si lo sustituye<path>
con$toplevel/
.foreach
secuencia 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 --merge
ogit 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
.gitmodules
archivo?git submodule add -b tags/<sometag> <url>
que puede ver como la líneabranch = tags/<sometag>
en.gitmodules
Un 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 status
del 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.git
y presionar esa función ...? = DPara cambiar la rama de un submódulo (suponiendo que ya tenga el submódulo como parte del repositorio):
cd
a la raíz de su repositorio que contiene los submódulos.gitmodules
para 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
--remote
opción en lagit submodule update
línea de comando, Git revisará en modo HEAD separado (si--checkout
se 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--depth
parámetro y no le indica a Git sobre qué rama desea clonar , ¡ y en realidad no puede en lagit submodule update
línea de comando! -, se comportará implícitamente como se explica en lagit-clone(1)
documentación paragit clone --single-branch
cuando--branch
falta 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 update
comando, 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