¿Cómo cambiar el repositorio remoto para un submódulo git?

724

He creado un repositorio git con un submódulo en él. Puedo decirle al submódulo mismo que cambie su ruta de repositorio remoto, pero no estoy seguro de cómo decirle al repositorio principal cómo cambiar la ruta de repositorio remoto para el submódulo.

No me sorprendería si no tuviera suerte y tuviera que hacer las cosas manualmente, ya que incluso eliminar submódulos no es fácil.

Andrew Grimm
fuente
8
Nota: Git 2.25 (Q1 2020) viene con un nuevo comando ":git submodule set-url [--] <path> <newurl>
VonC

Respuestas:

1010

Debería poder editar el .gitmodulesarchivo para actualizar la URL y luego ejecutarlo git submodule syncpara reflejar ese cambio en el superproyecto y su copia de trabajo.

Jim Puls
fuente
22
Esto no parece actualizar .git / config, al menos en 1.7.1 o 1.7.3.
davidtbernal
66
¿Esto también actualiza la configuración de URL del submódulo para los commits anteriores? Por ejemplo, si compro una confirmación anterior, ¿apuntará a nuevas URL de submódulo?
maxmelbin
63
Se usa git submodule foreach -q git config remote.origin.urlpara ver las URL de submódulo "reales"
Joel Purra
10
No se actualizó .git/configpara mí usando git 2.1.0. Tuve que actualizar ambos .gitmodulesy .git/configmanualmente antes de ejecutar a git submodule sync --recursivepara que se actualizara mi submódulo remoto.
desseim
77
Parece que le falta el paso clave git submodule update --init --recursive --remoteque realmente cambia el repositorio al nuevo control remoto
Jason Axelson,
155

Estos comandos harán el trabajo en el símbolo del sistema sin alterar ningún archivo en el repositorio local

git config --file=.gitmodules submodule.Submod.url https://github.com/username/ABC.git
git config --file=.gitmodules submodule.Submod.branch Development
git submodule sync
git submodule update --init --recursive --remote

Mire el blog para ver capturas de pantalla: Cambio de URL / Rama de submódulos GIT a otra URL / rama del mismo repositorio

Pavan Sokke Nagaraj
fuente
8
Esto funcionó pero tuve que recordar empujar los cambios al control remoto. git add .gitmodules git commit -m "modified submodule URL" git push origin master
skulz00
55
Bueno, eso me creó un desastre terrible. Los comandos se dejaron en silencio, pero el repositorio de submódulos real todavía cree que su control remoto es el antiguo (la URL anterior). ¿Quizás estos comandos deberían ir acompañados de otros comandos dentro del repositorio del submódulo?
Motti Shneor
55
El último comando es un poco extremo ... Si tiene submódulos con submódulos dentro, esto también actualizará remotamente los submódulos, lo que es poco probable que necesite.
Baptiste Wicht
77
¡Tenga en cuenta que necesita reemplazar Submod con el nombre de su submódulo!
Shital Shah
133

En términos simples, solo necesita editar el archivo .gitmodules, luego volver a sincronizar y actualizar:

Edite el archivo, ya sea a través de un comando git o directamente:

git config --file=.gitmodules -e

o solo:

vim .gitmodules

luego sincronizar y actualizar:

git submodule sync
git submodule update --init --recursive --remote
Matthew Wilcoxson
fuente
66
git submodule update --initfuncionó para mí, --remoteparece vincularlo a la CABEZA del repositorio remoto.
Chaim Eliyah
96

Con Git 2.25 (Q1 2020), puede modificarlo .
Consulte "La URL del submódulo Git ha cambiado " y el nuevo comando

git submodule set-url [--] <path> <newurl>

Respuesta original (mayo de 2009, hace diez años)

En realidad, se envió un parche en abril de 2009 para aclarar el gitmodulerol.

Entonces ahora el documentación de gitmodule aún no incluye:

El .gitmodulesarchivo, ubicado en el directorio de nivel superior de un árbol de trabajo de git, es un archivo de texto con una sintaxis que coincide con los requisitos -of linkgit: git-config 1 .
[NUEVO]:
como Git administra este archivo, rastrea los registros + de los submódulos de un proyecto.
La información almacenada en este archivo se utiliza como una pista para preparar la versión autorizada del registro almacenado en el archivo de configuración del proyecto.
Los cambios de registro específicos del usuario (por ejemplo, para tener en cuenta las diferencias en las URL de submódulo debido a situaciones de red) deben realizarse en el archivo de configuración, mientras que los cambios de registro que se propagarán (por ejemplo, + debido a una reubicación de la fuente del submódulo) deben realizarse en este archivo .

Eso prácticamente confirma la respuesta de Jim .


Si sigue este tutorial de submódulo git , verá que necesita un "git submodule init " para agregar las URL del repositorio de submódulos a .git / config.

" git submodule sync" se agregó en agosto de 2008 precisamente para facilitar esa tarea cuando la URL cambia (especialmente si el número de submódulos es importante).
El script asociado con ese comando es lo suficientemente sencillo:

module_list "$@" |
while read mode sha1 stage path
do
    name=$(module_name "$path")
    url=$(git config -f .gitmodules --get submodule."$name".url)
    if test -e "$path"/.git
    then
    (
        unset GIT_DIR
        cd "$path"
        remote=$(get_default_remote)
        say "Synchronizing submodule url for '$name'"
        git config remote."$remote".url "$url"
    )
    fi
done

El objetivo sigue siendo: git config remote."$remote".url "$url"

VonC
fuente
Quería cambiar la URL del submódulo solo en esta máquina. Desde el proyecto principal pude modificar el registro .git/confighaciendo: git config submodule."$submodule_name".url "$new_url" que también se describe aquí .
joeytwiddle
¿Qué hacen los guiones dobles opcionales git submodule set-url [--] <path> <newurl>?
Jeverling
1
@jeverling Ayudan a separar las opciones de los parámetros: consulte stackoverflow.com/a/1192194/6309
VonC
1
Tenga en cuenta que para los usuarios de Ubuntu con una versión anterior git puede usar este PPA para actualizar: launchpad.net/~git-core/+archive/ubuntu/ppa
starbeamrainbowlabs
69

Lo que funcionó para mí (en Windows, usando git versión 1.8.3.msysgit.0):

  • Actualice .gitmodules con la ruta al nuevo repositorio
  • Elimine la línea correspondiente del archivo ".git / config"
  • Elimine el directorio correspondiente en el directorio ".git / modules / external"
  • Elimine el directorio de submódulos desprotegido en sí (no estoy seguro si esto es necesario)
  • Correr git submodule initygit submodule update
  • Asegúrese de que el submódulo extraído esté en la confirmación correcta, y confirme eso, ya que es probable que el hash sea diferente

Después de hacer todo eso, todo está en el estado que esperaría. Sin embargo, imagino que otros usuarios del repositorio tendrán un dolor similar cuando vengan a actualizar, ¡sería prudente explicar estos pasos en su mensaje de confirmación!

Ben Hymers
fuente
2
Muchas gracias por esto. Este es el único que funcionó para mí después de que ya había ejecutado un git submodule update. Seguir las otras respuestas no cambiaría lo que había en el ./git/modules/externaldirectorio, por lo que intentar actualizarlo provocaría que todavía extraiga la URL incorrecta.
NtscCobalt
Esto parece ser un poco peligroso, y no estoy seguro de que conserve la historia del submódulo anterior. Si, por ejemplo, desea verificar una confirmación o rama antigua de su repositorio principal (la que contiene el submódulo), no estoy seguro de que sepa extraer el submódulo VIEJO adjunto y relacionado con esa confirmación anterior del principal .
Motti Shneor
No, es casi seguro que no lo sabrá, tendrá que hacer todos los pasos después del primero nuevamente. Esto es justo lo que encontré que funcionó para destruir el estado actual del submódulo. No sé si el estado de cosas ha cambiado desde que escribí esto, cuenta :)
Ben Hymers
@MottiShneor que parece peligroso de hecho si necesita mantener el historial de submódulos anterior, aunque no estoy seguro de eso. En mi caso, es la única solución que funcionó, lo que quería era básicamente reemplazar el submódulo original con mi propio tenedor
arainone
1
Seguí estos pasos y descubrí que "Eliminar el directorio de submódulos desprotegido en sí mismo (no estoy seguro de si es necesario)" es necesario; de lo contrario, encontrarás "fatal: No es un repositorio de git: ..." al ejecutar la actualización de submódulos de git
PiersyP
10

Simplemente edite su archivo .git / config . Por ejemplo; Si tiene un submódulo "común" , puede hacerlo en el supermódulo:

git config submodule.common.url /data/my_local_common
FelipeC
fuente
Esta es solo la mejor manera si está tratando de cambiar la URL para un uso único, no de forma permanente en el superproyecto. Por ejemplo, desea clonar submódulos de copias locales en el disco.
Andy
4

git config --file=.gitmodules -e abre el editor predeterminado en el que puede actualizar la ruta

LuGo
fuente