¿Cómo muevo un submódulo GIT existente dentro de un repositorio Git?
-
25-09-2019 - |
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"]
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?):
- Editar
.gitmodules
y cambie la ruta del submódulo de manera apropiada y póngalo en el índice congit add .gitmodules
. - Si es necesario, cree el directorio principal de la nueva ubicación del submódulo (
mkdir -p new/parent
). - Mueva todo el contenido de lo anterior al nuevo directorio (
mv -vi old/parent/submodule new/parent/submodule
). - Asegúrese de que Git rastree este directorio (
git add new/parent
). - Retire el directorio anterior con
git rm --cached old/parent/submodule
. - Mover el directorio
.git/modules/old/parent/submodule
con todo su contenido a.git/modules/new/parent/submodule
. - 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 serworktree = ../../../../../new/parent/module
. Por lo general, debería haber dos más..
luego directorios en la ruta directa en ese lugar. 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 ejemplogitdir: ../../../.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 #
Finalmente, comete los cambios.
Otros consejos
La respuesta más moderna, tomada del comentario de Valloric anterior:
- Actualizar a Git 1.9.3 (o 2.18 Si el submódulo contiene submódulos anidados)
git mv old/submod new/submod
- Luego, el directorio .gitmodules y el directorio de submódulo ya están organizados para un comet. (Puede verificar esto con
git status
.) - 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í:
- Editar .gitModules cambiando el nombre y la ruta del submódulo para ser "ext/afnetworking"
- Mueva el directorio GIT de Submodule desde ".Git/Modules/Afnetworking" To ".git/módulos/ext/afnetworking"
- Mueva la biblioteca de "Afnetworking" a "Ext/Afnetworking"
- Editar ".git/módulos/ext/afnetworking/config" y corregir el
[core] worktree
línea. El mío cambió de../../../AFNetworking
a../../../../ext/AFNetworking
- Editar "ext/afnetworking/.git" y arreglar
gitdir
. El mío cambió de../.git/modules/AFNetworking
a../../git/modules/ext/AFNetworking
git add .gitmodules
git rm --cached AFNetworking
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 delworktree
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:
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).
Editar .git/módulos/name/config y cambiar la configuración "worktree =" para el submódulo en cuestión
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:
- Asegúrese de que el submódulo se registre y lo empuje a su servidor. También necesitas saber en qué rama se encuentra.
- ¡Necesita la URL de su submódulo! Usar
more .gitmodules
Porque una vez que eliminas el submódulo no va a estar cerca - Ahora puedes usar
deinit
,rm
y entoncessubmodule add
EJEMPLO
- Git Submodule está en: clases/lib/Mustireally
- Mudarse a: lib/audiobus
- URL: http://developer.audiob.us/download/sdk.git
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.