Pregunta

Me gustaría cambiar el nombre del directorio de un submódulo Git en mi superproject Git.

Supongamos que tengo la siguiente entrada en mi .gitmodules expediente:

[submodule ".emacs.d/vimpulse"]  
path = .emacs.d/vimpulse  
url = git://gitorious.org/vimpulse/vimpulse.git

¿Qué tengo que escribir para mover el .emacs.d/vimpulse directorio a .emacs.d/vendor/vimpulse sin eliminarlo primero (explicado aquí y aquí) y luego vuelva a acumularlo.

¿Git realmente necesita toda la ruta en la etiqueta de submódulo?

[submodule ".emacs.d/vimpulse"]

¿O también es posible almacenar solo el nombre del subproyecto?

[submodule "vimpulse"]
¿Fue útil?

Solución

Nota: Como se menciona en los comentarios, esta respuesta se refiere a los pasos necesarios con versiones anteriores de GIT. Git ahora tiene soporte nativo para mudanzas de submódulos:

Desde Git 1.8.5, git mv old/submod new/submod Funciona como se esperaba y te hace todas las tuberías. Es posible que desee usar Git 1.9.3 o más nuevo, porque incluye correcciones para el movimiento de submódulos.


Es similar a cómo elimina un submódulo (ver ¿Cómo elimino un submódulo?):

  1. Editar .gitmodules y cambie la ruta del submódulo de manera apropiada y póngalo en el índice con git add .gitmodules.
  2. Si es necesario, cree el directorio principal de la nueva ubicación del submódulo (mkdir -p new/parent).
  3. Mueva todo el contenido de lo anterior al nuevo directorio (mv -vi old/parent/submodule new/parent/submodule).
  4. Asegúrese de que Git rastree este directorio (git add new/parent).
  5. Retire el directorio anterior con git rm --cached old/parent/submodule.
  6. Mover el directorio .git/modules/old/parent/submodule con todo su contenido a .git/modules/new/parent/submodule.
  7. Editar el .git/modules/new/parent/config archivo, asegúrese de que el elemento de trabajo de trabajo apunte a las nuevas ubicaciones, por lo que en este ejemplo debería ser worktree = ../../../../../new/parent/module. Por lo general, debería haber dos más .. luego directorios en la ruta directa en ese lugar.
  8. Editar el archivo new/parent/module/.git, asegúrese de que la ruta en él apunte a la nueva ubicación correcta dentro del proyecto principal .git carpeta, entonces en este ejemplo gitdir: ../../../.git/modules/new/parent/submodule.

    git status La salida se ve así para mí después:

    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   .gitmodules
    #       renamed:    old/parent/submodule -> new/parent/submodule
    #
    
  9. Finalmente, comete los cambios.

Otros consejos

La respuesta más moderna, tomada del comentario de Valloric anterior:

  1. Actualizar a Git 1.9.3 (o 2.18 Si el submódulo contiene submódulos anidados)
  2. git mv old/submod new/submod
  3. Luego, el directorio .gitmodules y el directorio de submódulo ya están organizados para un comet. (Puede verificar esto con git status.)
  4. Cometer los cambios con git commit¡Y estás listo para ir!

¡Hecho!

En mi caso, quería mover un submódulo de un directorio a un subdirectorio, por ejemplo, "AfNetworking" -> "Ext/Afnetworking". Estos son los pasos que seguí:

  1. Editar .gitModules cambiando el nombre y la ruta del submódulo para ser "ext/afnetworking"
  2. Mueva el directorio GIT de Submodule desde ".Git/Modules/Afnetworking" To ".git/módulos/ext/afnetworking"
  3. Mueva la biblioteca de "Afnetworking" a "Ext/Afnetworking"
  4. Editar ".git/módulos/ext/afnetworking/config" y corregir el [core] worktree línea. El mío cambió de ../../../AFNetworking a ../../../../ext/AFNetworking
  5. Editar "ext/afnetworking/.git" y arreglar gitdir. El mío cambió de ../.git/modules/AFNetworking a ../../git/modules/ext/AFNetworking
  6. git add .gitmodules
  7. git rm --cached AFNetworking
  8. git submodule add -f <url> ext/AFNetworking

Finalmente, vi en el estado de Git:

matt$ git status
# On branch ios-master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   .gitmodules
#   renamed:    AFNetworking -> ext/AFNetworking

Et voila. El ejemplo anterior no cambia la profundidad del directorio, lo que hace una gran diferencia en la complejidad de la tarea, y no cambia el nombre del submódulo (que puede no ser realmente necesario, pero hice que fuera coherente con lo que sucedería si agregara un nuevo módulo en esa ruta).

Actualización: 2014-11-26] como Yar resume bien a continuación, Antes de hacer algo, asegúrese de conocer la URL del submódulo. Si se desconoce, abra .git/.gitmodules y examina la clavesubmodule.<name>.url.

Lo que funcionó para mí era Retire el antiguo submódulo usando git submodule deinit <submodule> seguido por git rm <submodule-folder>. Luego agregue el submódulo nuevamente con el nuevo nombre de carpeta y confirmación. Verificar el estado de Git antes de comprometerse muestra el antiguo submódulo renombrado al nuevo nombre y .GitModule modificado.

$ git submodule deinit foo
$ git rm foo
$ git submodule add https://bar.com/foo.git new-foo
$ git status
renamed:    foo -> new-foo
modified:   .gitmodules
$ git commit -am "rename foo submodule to new-foo"

El truco parece ser comprender que el .git El directorio de los submódulos ahora se mantiene en el repositorio maestro, debajo .git/modules, y cada submódulo tiene un .git Archivar eso lo señala. Este es el procedimiento que necesita ahora:

  • Mueva el submódulo a su nuevo hogar.
  • Editar el .git Archivo en el directorio de trabajo del submódulo y modifique la ruta que contiene para que apunte al directorio correcto en el repositorio maestro .git/modules directorio.
  • Ingrese el repositorio maestro .git/modules directorio y busque el directorio correspondiente a su submódulo.
  • Editar el config archivo, actualización del worktree ruta para que apunte a la nueva ubicación del directorio de trabajo del submódulo.
  • Editar el .gitmodules Archivo en la raíz del repositorio maestro, actualizando la ruta al directorio de trabajo del submódulo.
  • git add -u
  • git add <parent-of-new-submodule-directory> (Es importante que agregue el padre, y no el directorio de submódulo en sí).

Algunas notas:

  • los [submodule "submodule-name"] colocar .gitmodules y .git/config deben coincidir entre sí, pero no corresponden a nada más.
  • El directorio de trabajo de submódulo y .git El directorio debe señalarse correctamente entre sí.
  • los .gitmodules y .git/config Los archivos deben estar sincronizados.

Puede agregar un nuevo submódulo y eliminar el submódulo anterior usando comandos estándar. (debería evitar cualquier error accidental dentro de .git)

Ejemplo de configuración:

mkdir foo; cd foo; git init; 
echo "readme" > README.md; git add README.md; git commit -m "First"
## add submodule
git submodule add git://github.com/jquery/jquery.git
git commit -m "Added jquery"
## </setup example>

Examle Move 'jQuery' a 'Vendor/jQuery/jQuery':

oldPath="jquery"
newPath="vendor/jquery/jquery"
orginUrl=`git config --local --get submodule.${oldPath}.url`

## add new submodule
mkdir -p `dirname "${newPath}"`
git submodule add -- "${orginUrl}" "${newPath}"

## remove old submodule
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}"              ## remove old src
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (housekeeping)

## commit
git add .gitmodules
git commit -m "Renamed ${oldPath} to ${newPath}"

Método de bonificación para submódulos grandes:

Si el submódulo es grande y prefiere no esperar el clon, puede crear el nuevo submódulo usando el antiguo como origen, y luego cambiar el origen.

Ejemplo (use la misma configuración de ejemplo)

oldPath="jquery"
newPath="vendor/jquery/jquery"
baseDir=`pwd`
orginUrl=`git config --local --get submodule.${oldPath}.url`

# add new submodule using old submodule as origin
mkdir -p `dirname "${newPath}"`
git submodule add -- "file://${baseDir}/${oldPath}" "${newPath}"

## change origin back to original
git config -f .gitmodules submodule."${newPath}".url "${orginUrl}"
git submodule sync -- "${newPath}"

## remove old submodule
...

La cadena en comillas después de [Submódulo" no importa. Puede cambiarlo a "Foobar" si lo desea. Se usa para encontrar la entrada coincidente en ".Git/config".

Por lo tanto, si realiza el cambio antes de ejecutar "git submodule init", funcionará bien. Si realiza el cambio (o recoge el cambio a través de una fusión), deberá editar manualmente .git/config o ejecutar "git submodule init" nuevamente. Si hace este último, se quedará con una entrada inofensiva "varada" con el nombre anterior en .git/config.

La solución dada no funcionó para mí, sin embargo, una versión similar ...

Esto es con un repositorio clonado, por lo tanto, los repos de submódulo git están contenidos en los repositorios superiores .git dir. Todos los cationes son del repositorio superior:

  1. Editar .gitmodules y cambiar la configuración "ruta =" para el submódulo en cuestión. (No es necesario cambiar la etiqueta, ni agregar este archivo al índice).

  2. Editar .git/módulos/name/config y cambiar la configuración "worktree =" para el submódulo en cuestión

  3. correr:

    mv submodule newpath/submodule
    git add -u
    git add newpath/submodule
    

Me pregunto si marca la diferencia si los repositorios son atómicos o submódulos relativos, en mi caso era relativo (Submódulo/.git es una referencia de regreso a TopProject/.Git/Modules/Submodule)

Solo usa el script de shell git-submodule-move.

Ayer pasé por esta prueba y esta respuesta funcionó perfectamente. Aquí están mis pasos, para mayor claridad:

  1. Asegúrese de que el submódulo se registre y lo empuje a su servidor. También necesitas saber en qué rama se encuentra.
  2. ¡Necesita la URL de su submódulo! Usar more .gitmodules Porque una vez que eliminas el submódulo no va a estar cerca
  3. Ahora puedes usar deinit, rm y entonces submodule add

EJEMPLO

Comandos

    git submodule deinit Classes/lib/mustIReally
    git rm foo
    git submodule add http://developer.audiob.us/download/SDK.git lib/AudioBus

    # do your normal commit and push
    git commit -a 

NOTA: Git MV no hace esto. En absoluto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top