Agregar un nuevo Subproyecto

Submódulo

git submodule add https://github.com/githubtraining/submodulo-ejemplo

git commit -m "agregando un nuevo submodulo"

El comando submodule add agrega un nuevo archivo llamado .gitmodules junto con un subdirectorio que contiene los archivos de submodulo-ejemplo. Ambos se agregan a tu index (staging area) y solo necesitas agregarlos a tu commit. El historial del submódulo permanecerá independiente del proyecto principal.

Subárbol

git subtree add --prefix=submodulo-ejemplo https://github.com/githubtraining/submodulo-ejemplo main --squash

El comando subtree add agrega un subdirectorio que contiene los archivos de submodulo-ejemplo. La práctica más común es utilizar la opción --squash para combinar el historial del subproyecto en un único commit, que luego se inserta en el árbol existente del proyecto principal. Se puede omitir la opción --squash para mantener todo el historial de la rama seleccionada del subproyecto.

Ver las diferencias de un Subproyecto

Submódulo

Para ver las diferencias (diff) de un submódulo:

# mostrar cambios al commit del submódulo
git diff submodulo-ejemplo
# mostrar una línea de los registros de los nuevos commits en el submódulo
git diff --submodule submodulo-ejemplo
# mostrar cambios de los archivos en el submódulo
git diff --submodule=diff

Subárbol

No se requiere ningún comando especial

Clonar un repositorio con Subproyecto

Submódulo

Para clonar un repositorio junto con su submódulo:

git clone --recurse-submodules URL

Si no se utiliza --recurse-submodules se puede clonar e inicializar todos los submódulos:

git submodule update --init --recursive

Utilizar --recursive solo es necesario si algún submódulo tiene submódulos.

Subárbol

No se requiere ningún comando especial

Descargar actualizaciones de Superproyectos

Submódulo

De forma predeterminada, el repositorio del submódulo se recupera, pero no se actualiza cuando ejecuta git pull en el superproyecto. Se necesita usar git submodule update, o agregar --recurse-submodules a pull:

git pull
git submodule update --init --recursive
# o, en un comando (Git >= 2.14)
git pull --recurse-submodules

--init es necesario si el superproyecto agregó nuevos submódulos, y --recursive es necesario si algún submódulo tiene submódulos.

Si alguna vez el superproyecto cambia la URL del submódulo, se requiere un comando por separado:

# copia la nueva URL a to configuración local
git submodule sync --recursive
# actualiza el submodulo desde la nueva URL
git submodule update --init --recursive

--recursive solo es necesario si algún submódulo tiene submódulos.

Subárbol

No se requiere ningún comando especial

Cambiar de rama

Submódulo

De forma predeterminada, el árbol de trabajo del submódulo no se actualiza para que coincida con el commit registrado en el superproyecto al cambiar de rama. Necesita usar git submodule update, o agregar--recurse-submodules a checkout:

git checkout <branch>
git submodule update --recursive
# o, en un comando (Git >= 2.13)
git checkout --recurse-submodules <branch>

Subárbol

No se requiere ningún comando especial

Descargar actualizaciones de Subproyectos

Submódulo

# Actualiza el repositorio de submódulos
git submodule update --remote
# Registra los cambios en el superproyecto
git commit -am "Update submodule"

Si tiene más de un submódulo, puede agregar la ruta al submódulo al final del comando git submodule update --remote para especificar qué subproyecto actualizar.

Por defecto, git submodule update --remote actualizará el submódulo al último commit en la ramamain del submódulo remoto.

Se puede cambiar la rama predeterminada para futuras llamadas con:

# Git >= 2.22
git submodule set-branch other-branch
# o
git config -f .gitmodules submodule.example-submodule.branch otra-rama

Subárbol

git subtree pull --prefix=submodulo-ejemplo https://github.com/githubtraining/submodulo-ejemplo main --squash

Se puede acortar el comando agregando la URL del subárbol como remoto:

git remote add sub-remote https://github.com/githubtraining/submodulo-ejemplo.git

Se pueden utilizar los commandos add/pull de otras referencias reemplazando main con la referencia deseada (e.g. stable, v1.0).

Realizar cambios en un Subproyecto

En la mayoría de los casos, se considera una buena práctica realizar cambios en una copia (clon) separada del repositorio de subproyectos e incorporarlos al proyecto principal. Cuando esto no sea práctico, siga estas instrucciones:

Submódulo

Acceda al directorio del submódulo y cree una rama:

cd example-submodule
git checkout -b nombre-rama main

Los cambios requieren dos commits, una en el repositorio del subproyecto y otra en el repositorio principal. ¡No olvides agregar tanto el submódulo como el superproyecto!

Subárbol

No se requiere ningún comando especial, los cambios se agregaran en la rama del proyecto principal.

Es posible crear commits mezclando cambios en el subproyecto y el proyecto principal, pero esto generalmente no se recomienda.

Subir cambios al repositorio del Subproyecto

Submódulo

Mientras está en el directorio del submódulo:

git push

O mientras está en el directorio principal:

git push --recurse-submodules=on-demand

Subárbol

git subtree push --prefix=submodulo-ejemplo https://github.com/githubtraining/submodulo-ejemplo main

Configuraciones útiles para submódulos

Siempre muestre el registro del submódulo cuando vea diferencias:

git config --global diff.submodule log

Muestre un breve resumen de los cambios del submódulo en su mensaje git status:

git config --global status.submoduleSummary true

Haga que push sea predeterminado en --recurse-submodules = on-demand:

git config --global push.recurseSubmodules on-demand

Haga que todos los comandos (excepto clone) estén predeterminados en --recurse-submodules si admiten la bandera (esto funciona para git pull desde Git 2.15):

git config --global submodule.recurse true