Close

Submódulos de Git

Los submódulos de Git permiten mantener un repositorio de Git como subdirectorio de otro repositorio de Git. Son una referencia a otro repositorio en una instantánea concreta en el tiempo. Con submódulos de Git, un repositorio de Git puede incorporar y rastrear el historial de versiones de código externo.


¿Qué es un submódulo de Git?


A menudo, un repositorio de código depende de código externo, que se puede incorporar de varias maneras diferentes. Por ejemplo, se puede copiar y pegar directamente en el repositorio principal. Este método tiene el inconveniente de que se pierden los cambios en sentido ascendente hechos en el repositorio externo. Otro método para incorporar código externo es mediante el uso de un sistema de gestión de paquetes de un lenguaje como Ruby Gems o NPM. Este método tiene el inconveniente de que requiere la instalación y gestión de versiones en todos los lugares donde se implementa el código de origen. Estos dos métodos de incorporación sugeridos no permiten hacer un seguimiento de las ediciones y los cambios en el repositorio externo.

Un submódulo de Git es un registro dentro de un repositorio host de Git que apunta a una confirmación específica en otro repositorio externo. Los submódulos son muy estáticos y solo rastrean confirmaciones específicas. Además, no rastrean las referencias o ramas de Git y no se actualizan automáticamente cuando se actualiza el repositorio host. Al añadir un submódulo a un repositorio, se creará un nuevo archivo .gitmodules. El archivo .gitmodules contiene metadatos sobre la asignación entre la URL del proyecto del submódulo y el directorio local. Si el repositorio host tiene varios submódulos, el archivo .gitmodules tendrá una entrada para cada submódulo.

¿Cuándo se usan los submódulos de Git?


Si necesitas mantener una gestión estricta de las versiones de tus dependencias externas, puede tener sentido usar submódulos de Git. Estos son algunos de los mejores casos prácticos para los submódulos de Git:

  • Cuando un subproyecto o componente externo 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.
  • 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.
bases de datos
Material relacionado

Cómo mover un repositorio de Git completo

Logotipo de Bitbucket
VER LA SOLUCIÓN

Aprende a usar Git con Bitbucket Cloud

Comandos comunes para submódulos de Git


Añadir un submódulo de Git

El comando git submodule add se usa para añadir un nuevo submódulo a un repositorio existente. El siguiente es un ejemplo que crea un repositorio vacío y explora los submódulos de Git.

$ mkdir git-submodule-demo
$ cd git-submodule-demo/
$ git init
Initialized empty Git repository in /Users/atlassian/git-submodule-demo/.git/

Esta secuencia de comandos creará un nuevo directorio git-submodule-demo, ingresará a ese directorio y lo inicializará como un repositorio nuevo. A continuación, añadiremos un submódulo a este nuevo repositorio.

$ git submodule add https://bitbucket.org/jaredw/awesomelibrary
Cloning into '/Users/atlassian/git-submodule-demo/awesomelibrary'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.

El comando git submodule add toma un parámetro de URL que apunta a un repositorio de Git. Aquí hemos agregado la biblioteca awesomelibrary como submódulo. Git clonará inmediatamente el submódulo. Ahora podemos revisar el estado actual del repositorio mediante git status...

$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

new file:   .gitmodules
new file:   awesomelibrary

Ahora hay dos archivos nuevos en el repositorio .gitmodules y en el directorio awesomelibrary. Al mirar el contenido de .gitmodules, se muestra la nueva asignación de submódulos:

[submodule "awesomelibrary"]
path = awesomelibrary
url = https://bitbucket.org/jaredw/awesomelibrary
$ git add .gitmodules awesomelibrary/
$ git commit -m "added submodule"
[main (root-commit) d5002d0] added submodule
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 awesomelibrary

Clonación de submódulos de Git

git clone /url/to/repo/with/submodules
git submodule init
git submodule update

Submódulo Init de Git

El comportamiento predeterminado de git submodule init es copiar la asignación del archivo .gitmodules en el archivo local ./.git/config. Esto puede parecer redundante y llevar a cuestionar la utilidad de git submodule init. git submodule init tiene un comportamiento extendido en el que acepta una lista de nombres de módulos explícitos. Esto habilita un flujo de trabajo que activa únicamente submódulos concretos que se necesitan para trabajar en el repositorio. Puede ser práctico si hay muchos submódulos en un repositorio, pero no es necesario recuperarlos todos para el trabajo que se está realizando.

Flujos de trabajo de submódulos

Una vez que los submódulos se inicializan y actualizan correctamente dentro de un repositorio principal, se pueden utilizar exactamente como repositorios independientes. Esto significa que los submódulos tienen sus propias ramas e historial. Al realizar cambios en un submódulo, es importante publicar los cambios del submódulo y, a continuación, actualizar la referencia de los repositorios principales en el submódulo. Sigamos con el ejemplo de awesomelibrary y hagamos algunos cambios:

$ cd awesomelibrary/
$ git checkout -b new_awesome
Switched to a new branch 'new_awesome'
$ echo "new awesome file" > new_awesome.txt
$ git status
On branch new_awesome
Untracked files:
  (use "git add <file>..." to include in what will be committed)

new_awesome.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add new_awesome.txt
$ git commit -m "added new awesome textfile"
[new_awesome 0567ce8] added new awesome textfile
 1 file changed, 1 insertion(+)
 create mode 100644 new_awesome.txt
$ git branch
  main
* new_awesome

Aquí hemos cambiado el directorio al submódulo awesomelibrary. Hemos creado un nuevo archivo de texto new_awesome.txt con algo de contenido y hemos añadido y confirmado este nuevo archivo en el submódulo. Ahora vamos a cambiar los directorios al repositorio principal y revisaremos el estado actual del repositorio principal.

$ cd ..
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   awesomelibrary (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

Al ejecutar git status vemos que el repositorio principal conoce las nuevas confirmaciones que se han hecho en el submódulo awesomelibrary. No entra en detalles sobre las actualizaciones específicas porque de eso se encargan los repositorios de submódulos. El repositorio principal solo se preocupa por fijar el submódulo a una confirmación. Ahora podemos volver a actualizar el repositorio principal haciendo git add y git commit en el submódulo. Esto pondrá todo en buen estado con el contenido local. Si trabajas en equipo, es fundamental que envíes con git push las actualizaciones del submódulo y del repositorio principal.

Cuando se trabaja con submódulos, una causa habitual de errores es olvidar enviar actualizaciones para los usuarios remotos. Volviendo al trabajo que acabamos de hacer con awesomelibrary, solamente hemos enviado las actualizaciones al repositorio principal. Si otro desarrollador fuera a incorporar el último repositorio principal, apuntaría a una confirmación de awesomelibrary que no se pudo incorporar porque nosotros no enviamos el submódulo. Esto rompería el repositorio local de los desarrolladores remotos. Para evitar este problema, recuerda confirmar y enviar siempre el submódulo y el repositorio principal.

Conclusión


Los submódulos de Git son una herramienta eficaz para utilizar Git como herramienta de gestión de dependencias externa. Antes de usarlos, sopesa sus pros y sus contras, ya que son una función avanzada y los miembros del equipo pueden tener una curva de aprendizaje a la hora de adoptarlos.


Compartir este artículo

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.

Gente que colabora utilizando un muro lleno de herramientas

Blog de Bitbucket

Ilustración de Devops

Ruta de aprendizaje de DevOps

Demostraciones de funciones con expertos de Atlassian del Centro de demostraciones

Cómo funciona Bitbucket Cloud con Atlassian Open DevOps

Suscríbete para recibir el boletín de DevOps

Thank you for signing up