DEV Community

Cover image for Git Submodules: Repositorios dentro de otros Repositorios
Juan Carlos Garcia Esquivel
Juan Carlos Garcia Esquivel

Posted on

Git Submodules: Repositorios dentro de otros Repositorios

"Mantén tu código modular, pero tus dependencias bajo control. Git Submodules permite que un repositorio contenga a otros como directorios, manteniendo historias independientes."


¿Qué es un Git Submodule?

Un Git Submodule es esencialmente un puntero a un commit específico en otro repositorio. A diferencia de un simple "copy-paste", un submódulo permite que un repositorio (el Parent) mantenga una referencia exacta a una versión de otro repositorio (el Submodule).

¿Por qué no solo copiar el código?

  1. Historia Limpia: Los commits del submódulo no ensucian el historial del proyecto principal.
  2. Independencia: Puedes trabajar en la librería/componente de forma aislada.
  3. Versatilidad: Múltiples proyectos pueden apuntar a diferentes versiones (commits) de la misma librería.

Cómo se usa: Ejemplo con Obsidian

Para que los comandos tengan sentido, imaginemos que estás en tu repositorio de obsidian de notas (tu Vault) y quieres integrar un plugin que tú mismo estás desarrollando.

1. Integrar tu plugin por primera vez

En lugar de copiar los archivos manualmente ya que estás desarrollando el plugin y aún no está en la lista oficial, le dices a Git que este repositorio externo debe vivir dentro de tu vault (tu repositorio principal de notas).


# Añade tu plugin directamente en la carpeta donde Obsidian lo reconoce
git submodule add https://github.com/user/custom-plugin.git .obsidian/plugins/custom-plugin

Enter fullscreen mode Exit fullscreen mode

El comando anterior crea un vínculo permanente. Obsidian verá la carpeta y cargará el plugin, pero Git sabrá que ese contenido no pertenece al historial de tus notas, sino a un proyecto externo.

2. El "Superpoder": Modificar el plugin en tiempo real

Imagina que estás usando tu plugin en tu Vault y te das cuenta de un error: un parámetro de configuración no tiene límites y está causando problemas. Como es un submódulo, no tienes que cambiar de proyecto.

# 1. Entras a la carpeta del plugin (un repo de Git independiente)
cd .obsidian/plugins/obsidian-custom-plugin

# 2. Corriges el código agregando el límite al parámetro, haces commit y push al repo del PLUGIN
git add .
git commit -m "fix: add validation limits to config parameter"
git push origin main

# 3. Vuelves a la raíz de tus NOTAS (tu repositorio principal)
cd ../../../

# 4. Actualizas el puntero de tu Vault para que "recuerde" que ahora debe usar esta versión corregida
git add .obsidian/plugins/custom-plugin
git commit -m "chore: update plugin to version with config limits"
Enter fullscreen mode Exit fullscreen mode

¿Por qué así? Este es el "superpoder": puedes desarrollar el plugin mientras lo usas. El último commit en el Vault asegura que, si alguien más descarga tus notas, obtendrá la versión con el nuevo botón que acabas de crear.

El Misterio del "Segundo Commit": ¿Por qué doble trabajo?

Es la duda más común: "Si ya hice commit en el plugin, ¿por qué debo hacer otro en el Vault?". La respuesta corta es por Estabilidad y Determinismo.

La Analogía del Catálogo

Imagina que tu Vault es una Biblioteca y tu plugin es un Libro.

  1. Commit en el Plugin: El autor escribe una nueva edición del libro. El libro ahora es diferente, pero sigue estando en su propia caja.
  2. Commit en el Vault: Tú, como bibliotecario, tienes que actualizar la ficha del catálogo. Si no actualizas la ficha, el catálogo seguirá diciendo a los lectores que busquen la "Edición 1", aunque la "Edición 2" ya exista en la estantería.

Lo que Git ve realmente (El Puntero)

Para Git, el submódulo no es una carpeta; es un archivo especial que contiene un solo dato: un Hash (ID de commit).

Estado Referencia en el Vault Versión real en la carpeta ¿Hay cambios pendientes?
Inicial Hash: abc123 Hash: abc123 No (Limpio)
Tras corregir bug Hash: abc123 Hash: def456 (Desincronizado)
Tras commit en Vault Hash: def456 Hash: def456 No (Sincronizado)

¿Por qué es bueno esto?

Si dentro de 2 años quieres volver a ver tus notas de hoy, Git usará el "papelito" que guardaste hoy (def456). Aunque en el futuro el plugin haya cambiado mil veces más, tu Vault de hoy siempre cargará la versión que tú confirmaste que funcionaba. Evita que actualizaciones futuras rompan tus proyectos viejos.


3. Sincronizar el Vault en otra máquina

Si clonas tu Vault en una laptop nueva, la carpeta del plugin aparecerá vacía. Git no descarga submódulos por seguridad (para evitar descargas pesadas sin aviso).

# Inicializa la configuración local y descarga el contenido del plugin
git submodule update --init --recursive
Enter fullscreen mode Exit fullscreen mode

¿Por qué así? init registra el submódulo en tu configuración local y update descarga los archivos reales. Gracias al paso anterior, esta nueva máquina bajará automáticamente la versión corregida con los límites de configuración.


Casos de Uso Comunes

  • Librerías Compartidas: Tienes una librería de UI o de utilidades que usas en 5 aplicaciones diferentes.
  • Arquitectura de Microservicios: Mantener contratos de API o configuraciones compartidas.
  • Plugins/Temas (El caso Obsidian):
    Si desarrollas plugins o temas para Obsidian, este es el flujo de trabajo definitivo. Normalmente, tu plugin vive en su propio repositorio. Para probarlo, podrías copiar los archivos manualmente a tu carpeta .obsidian/plugins/, pero esto es tedioso y propenso a errores.

    La solución Pro: Agrega el repo de tu plugin como un submódulo directamente en .obsidian/plugins/mi-plugin.

    Método Instalación Normal Submódulo en el Vault
    Workflow Copiar/Pegar archivos cada vez. El código vive dentro de tu entorno real.
    Commits Debes ir a otra carpeta para pushear. Puedes hacer commits desde tu vault.
    Tracking El vault ignora el código del plugin. El vault sabe qué versión exacta del plugin usas.

    Ejemplo Real: Estás tomando notas y notas un bug en tu plugin. Al ser un submódulo, simplemente abres el código ahí mismo, lo corriges, haces commit en la carpeta del plugin y sigues con tus notas. El repositorio de tus notas (tu vault) solo verá que el "puntero" del plugin cambió, manteniendo ambos proyectos limpios pero perfectamente integrados.


Cómo quitar un submódulo (The Clean Way)

Quitar un submódulo es un proceso de varios pasos porque Git es muy cuidadoso con la integridad de los datos.

  1. Des-registrar el submódulo:
   git submodule deinit -f path/to/submodule
Enter fullscreen mode Exit fullscreen mode
  1. Eliminar de la caché de Git:
   git rm -f path/to/submodule
Enter fullscreen mode Exit fullscreen mode
  1. Eliminar la carpeta física (si aún existe):
   rm -rf .git/modules/path/to/submodule
Enter fullscreen mode Exit fullscreen mode
  1. Limpiar el archivo .gitmodules: Asegúrate de que no queden rastros de la configuración en ese archivo.
  2. Commit de los cambios:
   git add .
   git commit -m "Remove submodule [NAME]"
Enter fullscreen mode Exit fullscreen mode

Pro Tips

  • Detached HEAD: Por defecto, los submódulos se descargan en estado "detached HEAD" (apuntando a un commit, no a una rama). Si vas a editar código dentro del submódulo, asegúrate de hacer git checkout main primero.
  • Git status: El repositorio principal solo verá un "cambio" si el hash del commit al que apunta el submódulo cambia.

Reflexión Final

Los Git Submodules son una herramienta de doble filo. Por un lado, te permiten mantener una arquitectura modular y limpia, vinculando componentes externos sin "ensuciar" el historial de tu proyecto principal. Por otro, introducen una capa de complejidad que puede confundir a los equipos si no se maneja con disciplina (especialmente con el estado de Detached HEAD).

La regla de oro: úsalos para dependencias estables que necesites versionar con precisión. Si estás editando el submódulo tanto como el repositorio principal, quizás sea momento de reconsiderar si deben estar separados.

Top comments (0)