¿Hay alguna manera de hacer que git pull actualice automáticamente los submódulos?

203

¿Hay alguna manera de tener automáticamente git submodule update(o preferiblemente git submodule update --initllamado cada vez que git pullse hace?

Buscando una configuración de git, o un alias de git para ayudar con esto.

philfreo
fuente
44
Relacionado: stackoverflow.com/questions/1899792/…
philfreo
1
¿Por qué es preferible un alias de git a un alias de shell?
wnoise
20
los alias de git son agradables porque encapsula el comando en el espacio de nombres "git". También puede preguntar por qué todos los comandos git comienzan con "git" en lugar de tener sus propios nombres.
Lily Ballard
55
Para cualquiera que encuentre esto, las respuestas altamente votadas están actualmente desactualizadas. La respuesta de Kane es precisa: stackoverflow.com/a/49427199/3499424
John Neuhaus el

Respuestas:

176

A partir de Git 2.14 , puede usarlo git pull --recurse-submodules(y asignarle el alias que desee).

A partir de Git 2.15 , puede establecer submodule.recurseen verdadero para habilitar el comportamiento deseado.

Puede hacer esto globalmente ejecutando:

git config --global submodule.recurse true
Kane
fuente
3
Confirmado con 2.16, establecer esto en verdadero hará git pullque también obtenga un submódulo y se ejecute submodule update. Esto realmente necesita ser la respuesta aceptada ahora
John Neuhaus
1
Para establecer esto globalmente:git config --global submodule.recurse true
wintersolutions
14
Me frustraron los submódulos, luego hice esto. Ahora funcionan como yo esperaría. ¿Hay alguna razón por la que no estoy pensando que este no es el comportamiento predeterminado?
Ben
9
Deberían permitir eso git clonetambién. Y actívelo por defecto. De lo contrario, siempre habrá una gran resistencia al uso de submódulos, ya que los módulos de las personas siempre se desincronizan :-(
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@CiroSantilli新疆改造中心法轮功六四事件Santilli git comandos (como commit, fetch, pull, etc.) están diseñados para ser aplicado solamente al repositorio actual. un submódulo es otro repositorio y no debería verse afectado por comandos ejecutados en el repositorio principal de forma predeterminada. Este es un tipo de decisión de diseño del desarrollador de git.
anion
113

git config --global alias.pullall '!git pull && git submodule update --init --recursive'

Si desea que los argumentos se pasen a git pull, use esto en su lugar:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'
Lily Ballard
fuente
44
recuerde usar "git config --global" si desea este alias en todos los repositorios de git que usa
yoyo
43

Comenzando con Git 1.7.5, debería actualizar los submódulos automáticamente de forma predeterminada, como lo desea.

[EDIT: por comentarios: el nuevo comportamiento 1.7.5 es automáticamente ir a buscar las últimas confirmaciones de submódulos, pero no a actualizar ellos (en el git submodule updatesentido). Por lo tanto, la información en esta respuesta es relevante como fondo, pero no es una respuesta completa en sí misma. Todavía necesita un alias para extraer y actualizar submódulos en un comando.]

El comportamiento predeterminado, "a pedido", es actualizar los submódulos cada vez que obtiene una confirmación que actualiza la confirmación del submódulo, y esta confirmación aún no se encuentra en su clon local.
También puede actualizarlo en cada búsqueda o nunca (supongo que antes del comportamiento 1.7.5).
La opción de configuración para cambiar este comportamiento es fetch.recurseSubmodules.

Esta opción se puede establecer en un valor booleano o en on-demand.
Establecerlo en un valor booleano cambia el comportamiento de fetchy pullrecurrir incondicionalmente a submódulos cuando se establece en verdadero o no recurrir en absoluto cuando se establece en falso.

Cuando se establece en on-demand(el valor predeterminado), fetchy pull solo se repetirá en un submódulo poblado cuando su superproyecto recupere una confirmación que actualice la referencia del submódulo .

Ver:

para más información.

git fetch --recurse-submodules[=yes|on-demand|no]
Christopher Rogers
fuente
27
Cuidado: como explican las respuestas a continuación, esto solo recupera los cambios automáticamente, aún tiene que hacer una actualización de submódulo, por lo que la respuesta del alias es correcta.
Artem
44
@Artem es correcto. Esta respuesta, aunque útil, no aborda toda la pregunta. Esta configuración simplemente realiza a git fetch, no a git submodule update.
Andrew Ferrier
2
Esta respuesta es altamente engañosa. Incluso cuando se usa con git pull, en lugar de git fetch, esta opción solo hace que la búsqueda sea recursiva. No cambiará el commit que está desprotegido en los submódulos. Así que git submodule updatesigue siendo necesario, según lo observado por @Artem.
Mark Amery
31

¡Me sorprende que nadie haya mencionado usar git hooks para hacer esto!

Simplemente agregue los archivos con nombre post-checkouty post-mergea su .git/hooksdirectorio de los repositorios relevantes, y ponga lo siguiente en cada uno de ellos:

#!/bin/sh
git submodule update --init --recursive

Como solicitó específicamente un alias, suponiendo que desea tenerlo para muchos repositorios, puede crear un alias que los agregue a un repositorio .git/hookspara usted.

taleinat
fuente
2
¿Hay alguna manera de hacer de este un escenario global? ¿O uno que obtienes automáticamente cuando revisas el repositorio?
Raoul Steffen
3
La última versión de git, 2.9, ha agregado una configuración con el nombre core.hooksPathde un directorio de ganchos , consulte los documentos para git-configobtener más detalles.
taleinat
1
En cuanto a algo recibido automáticamente al pagar, busqué pero no pude encontrar nada por el estilo. Una fuente mencionó que esto no se admite a propósito para problemas de seguridad, ya que podría utilizarse fácilmente para ejecutar código arbitrario en máquinas cliente.
taleinat
1
Veo cómo puede ser un problema de seguridad. Después de todo, quiero usarlo para ejecutar el código que programo en las computadoras de mis compañeros de trabajo sin tener que instruirlos.
Raoul Steffen
1
Esta solución fue mi primer pensamiento, pero luego me di cuenta de que no cubriría a las personas que usan git pull --rebase:(
Vaz
8

Un alias, como lo sugiere Kevin Ballard, es una solución perfectamente buena. Solo para lanzar otra opción, también podría usar un gancho posterior a la fusión que simplemente se ejecuta git submodule update [--init].

Cascabel
fuente
7

Puede crear un alias para el comando git que maneja automáticamente la actualización de submódulos. Agregue lo siguiente a su .bashrc

# make git submodules usable
#   This overwrites the 'git' command with modifications where necessary, and
#   calls the original otherwise
git() {
    if [[ $@ == clone* ]]; then
        gitargs=$(echo "$@" | cut -c6-)
        command git clone --recursive $gitargs
    elif [[ $@ == pull* ]]; then
        command git "$@" && git submodule update --init --recursive
    elif [[ $@ == checkout* ]]; then
        command git "$@" && git submodule update --init --recursive
    else
        command git "$@"
    fi
}
Branden Ghena
fuente
1
En lugar de un alias para git, puede agregar alias a git a través del comando alias o creando comandos en su ruta que comiencen con git- (git-bettermodule)
idbrii el
7

Como otros han mencionado, puede configurarlo fácilmente con:

git config --global submodule.recurse true

Sin embargo, si eres como yo y tienes una .gitconfigconfiguración más compleja (mi ~/.gitconfigarchivo principal se usa includepara cargar en otros .gitconfigarchivos), y nunca puedes recordar cómo convertir entre el gitformato de configuración de la línea de comandos y el .gitconfigformato, así es como agregarlo a cualquiera de sus .gitconfigarchivos:

[submodule]
  recurse = true
Jacob Evelyn
fuente
0

La única forma en que pude actualizar los submódulos y submódulos anidados:

git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;

Estaba luchando para crear el alias a través de la terminal debido a los corchetes, así que tuve que agregar esto manualmente a .gitconfig para global:

[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"

¿Alguna sugerencia sobre cómo ejecutar los comandos o el alias automáticamente?

Sauli Kiviranta
fuente