Submódulos: conceptos básicos, flujos de trabajo y consejos
Nicola Paolucci
Experto en desarrollo
Incluir submódulos como parte del desarrollo de Git te permite incluir otros proyectos en el código base, a la vez que mantienes su historial separado pero sincronizado con el tuyo. Se trata de una forma práctica de resolver los problemas de dependencia y de la biblioteca de proveedores. Como es habitual en todo lo relacionado con Git
, el enfoque es obstinado y requiere un poco de estudio antes de que pueda usarse con soltura. Ya hay información buena y detallada sobre los submódulos
, así que no voy a repetir lo mismo. Lo que voy a hacer aquí es compartir algunas cosas interesantes que te ayudarán a aprovechar al máximo esta función.
Índice
Material relacionado
Cómo mover un repositorio de Git completo
VER LA SOLUCIÓN
Aprende a usar Git con Bitbucket Cloud
Concepto básico
En primer lugar, explicaré brevemente un concepto básico sobre los submódulos que facilitará el trabajo con ellos.
El seguimiento de los submódulos se realiza mediante la confirmación exacta especificada en el proyecto principal, no mediante una rama, una referencia u otra referencia simbólica.
Nunca se actualizan automáticamente cuando se actualiza el repositorio especificado por el submódulo, solo cuando se actualiza el proyecto principal en sí. Como se expresa muy claramente en el capítulo de Pro Git mencionado anteriormente:
Cuando haces cambios y confirmas en ese subdirectorio [de submódulo], el superproyecto detecta que HEAD ha cambiado y registra la confirmación exacta con la que estás trabajando actualmente; de esa manera, cuando otros clonan este proyecto, pueden recrear el entorno con exactitud.
En otras palabras:
[...] los submódulos de Git [...] son estáticos. Muy estáticos. Estás haciendo un seguimiento de confirmaciones específicas con submódulos de Git; es decir, de una sola confirmación, no de ramas ni referencias. Si añades confirmaciones a un submódulo, el proyecto principal no lo detectará. A los submódulos de Git no les importa que tengas unas cuantas bifurcaciones de un módulo. Tienes un repositorio remoto y apuntas a una sola confirmación. No cambiará nada hasta que no actualices el proyecto principal.
Posibles flujos de trabajo
Si recuerdas este concepto básico y reflexionas sobre él, entenderás que submodule
admite bien algunos flujos de trabajo y no tan bien otros. Hay al menos tres situaciones en las que los submódulos son una buena elección:
-
Cuando un componente o subproyecto cambia demasiado rápido o hay cambios próximos que rompan la API, puedes bloquear el código a una confirmación específica por tu propia seguridad.
-
Cuando tienes un componente que no se actualiza con mucha frecuencia y quieres hacer un seguimiento de él como dependencia del proveedor. Hago esto para mis plugins de Vim, por ejemplo.
-
Cuando delegas una parte del proyecto a un tercero y quieres integrar su trabajo en un momento o publicación concretos. Al igual que antes, es práctico hacerlo así si las actualizaciones no son demasiado frecuentes.
Gracias a finch por estas situaciones tan bien explicadas.
Consejos útiles
La infraestructura de submódulos es potente y permite una separación e integración de bases de código que resulta muy útil. Sin embargo, hay operaciones simples que no tienen un procedimiento simplificado ni un soporte sólido en la interfaz de usuario de la línea de comandos.
Si usas submódulos de Git en tu proyecto, te habrás topado con ellos o lo harás más adelante. Cuando eso ocurra, tendrás que buscar la solución. Una y otra vez. Permíteme ahorrarte tiempo de investigación: guarda esta página en Instapaper, Evernote o añadiéndola a marcadores (como en los viejos tiempos :D:D) y lo tendrás todo listo.
Vale, pongámonos con ello:
Cómo sustituir un submódulo de Git por tu propia bifurcación
Es un flujo de trabajo muy habitual. Empiezas a usar el proyecto de otra persona como submódulo, pero después de un tiempo necesitas personalizarlo y modificarlo por tu cuenta, así que conviene que bifurques el proyecto y reemplaces el submódulo por tu propia bifurcación. Veamos cómo se hace:
Los submódulos se almacenan en .gitmodules
:
$ cat .gitmodules [submodule "ext/google-maps"] path = ext/google-maps url = git://git.naquadah.org/google-maps.git
Puedes editar la URL con un editor de texto y luego ejecutar lo siguiente:
$ git submodule sync
Este comando actualiza .git/config
, que contiene una copia de esta lista de submódulos (también puedes editar la sección [submodule]
correspondiente de .git/config
manualmente).
Cómo eliminar un submódulo
Es una necesidad bastante común, pero tiene un procedimiento un poco complicado. Para eliminar un submódulo, tienes que hacer lo siguiente:
1. Elimina la línea correspondiente del archivo .gitmodules
.
2. Elimina la sección correspondiente de .git/config
.
3. Ejecuta git rm --cached path_to_submodule
(sin barra diagonal al final).
4. Confirma y elimina los archivos del submódulo del que se ha dejado de hacer un seguimiento.
Cómo volver a integrar un submódulo en un proyecto
O en otras palabras: ¿cómo se anula un submódulo de Git? Si lo único que quieres es añadir el código de tu submódulo en el repositorio principal, solo tienes que eliminar el submódulo y volver a añadir los archivos al repositorio principal:
1. Elimina la referencia al submódulo del índice, pero conserva los archivos:
git rm --cached submodule_path (no trailing slash)
2. Elimina el archivo .gitmodules o, si tienes más de un submódulo, edita este archivo eliminando el submódulo de la lista:
git rm .gitmodules
3. Elimina la carpeta de metadatos .git (antes de hacerlo, asegúrate de que tienes una copia de seguridad de esta carpeta):
rm -rf submodule_path/.git
4. Añade el submodule
al índice del repositorio principal:
git add submodule_path git commit -m "remove submodule"
NOTA: El procedimiento descrito anteriormente es destructivo para el historial del submódulo. Si quieres conservar un historial coherente de tus submódulos, debes llevar a cabo una fusión específica. Si quieres obtener más información, consulta esta completísima referencia de Stack Overflow.
Cómo ignorar los cambios en los submódulos
A veces, los submódulos (submodules
) pueden “ensuciarse” (volverse dirty
) por sí solos. Por ejemplo, si usas submodules
de Git para hacer un seguimiento de tus plugins de Vim, pueden generar o modificar archivos locales como helptags
. Lamentablemente, git status empezará a molestarte por esos cambios, aunque no tengas ningún interés en ellos ni intención de confirmarlos.
La solución es muy sencilla. Abre el archivo .gitmodules
en la raíz de tu repositorio y, para cada submódulo que quieras ignorar, añade ignore = dirty
, como en este ejemplo:
[submodule ".vim/bundle/msanders-snipmate"] path = .vim/bundle/msanders-snipmate url = git://github.com/msanders/snipmate.vim.git ignore = dirty
¡Peligro! Riesgos al interactuar con repositorios remotos
Como nos recuerda el tutorial de submódulos de Git de kernel.org, hay algunas cosas importantes que debes tener en cuenta al interactuar con tus repositorios remotos.
La primera es publicar siempre el cambio del submódulo antes de publicar dicho cambio en el superproyecto que hace referencia a él. Esto es fundamental, ya que puede impedir que otros clonen el repositorio.
La segunda es recordar siempre que hay que confirmar todos los cambios antes de ejecutar git submodule update
, ya que los cambios que haya se sobrescribirán.
Conclusiones
Con estas notas, deberías poder abordar muchos flujos de trabajo habituales que suelen surgir al usar submódulos. En una próxima entrada hablaré sobre alternativas a git submodule
.
Sígueme (@durdn) y sigue al increíble equipo de @Bitbucket para saberlo todo sobre DVCS.
Compartir este artículo
Tema siguiente
Lecturas recomendadas
Consulta estos recursos para conocer los tipos de equipos de DevOps o para estar al tanto de las novedades sobre DevOps en Atlassian.