Close

git subtree: la alternativa al submódulo de Git

Primer plano de Nicola Paolucci
Nicola Paolucci

Experto en desarrollo


Internet está lleno de artículos sobre por qué no debes usar submódulos de Git. Aunque los submódulos vienen muy bien en algunos casos, tienen varios inconvenientes.

Por supuesto, hay alternativas. Existen (al menos) dos herramientas con las que rastrear el historial de dependencias de software de tu proyecto y, al mismo tiempo, poder seguir usando Git:

  • Subárbol de Git
  • Repositorio de Google

En esta entrada, voy a analizar git subtree y mostraré por qué es una mejora (aunque no sea perfecta) respecto al submódulo de Git.

¿Qué es git subtree y cuáles son sus ventajas?


Con git subtree puedes anidar un repositorio dentro de otro en forma de subdirectorio. Es una de las formas en que los proyectos de Git pueden gestionar las dependencias de los proyectos.

Diagrama de git subtree antes/después

Ventajas de git subtree:

  • Gestionar un flujo de trabajo sencillo es fácil.
  • Se admiten versiones anteriores de Git (incluso anteriores a la v1.5.2).
  • El código del subproyecto está disponible nada más clonar el superproyecto.
  • Para usar git subtree, los usuarios de tu repositorio no tienen que aprender nada nuevo. Ni siquiera necesitan saber que estás usando git subtree para gestionar las dependencias.
  • git subtree no añade nuevos archivos de metadatos como lo hace el submódulo de Git (.gitmodule).
  • El contenido del módulo se puede modificar sin tener una copia de repositorio independiente de la dependencia en otro lugar.

Inconvenientes (en nuestra opinión, bastante aceptables):

  • Debes aprender una nueva estrategia de fusión (git subtree).
  • Aportar código para subproyectos de nivel superior es algo más complicado.
  • Tienes la responsabilidad de no mezclar código de superproyecto y subproyecto en las confirmaciones.
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

Cómo usar git subtree


git subtree está disponible en la versión estándar de Git desde mayo de 2012 (v1.7.11 y posteriores). En la versión instalada por Homebrew en OS X, subtree está integrado correctamente, pero puede que en otras plataformas tengas que seguir las instrucciones de instalación.

Aquí puedes ver un ejemplo canónico de rastrear un plugin de Vim con git subtree.

La vía rápida sin seguimiento remoto

Si solo quieres cortar y pegar un par de líneas, lee este párrafo. En primer lugar, añade subtree en una carpeta prefix determinada:

git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

Lo habitual es no almacenar todo el historial del subproyecto en tu repositorio principal, pero si quieres conservarlo omite la marca --squash.

El comando anterior da este resultado:

git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'

Como puedes ver, esto registra una merge commit combinando con squash todo el historial del repositorio vim-surround en uno solo:

1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]

Si después de un tiempo quieres actualizar el código del plugin desde el repositorio de nivel superior, puedes hacer un git subtree pull:

git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

Es algo rápido e indoloro, pero los comandos son un poco largos y difíciles de recordar. Para acortar los comandos, podemos añadir el subproyecto como remoto.

Añadir el subproyecto como remoto

Si agregamos el subtree como remoto, podemos acortar las referencias:

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Ahora podemos añadir el subtree (como antes), pero con una referencia más corta al remoto:

git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

El comando para actualizar el subproyecto en una fecha posterior pasa a ser:

git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

Aportar código a nivel superior

Ahora podemos confirmar las correcciones que queremos en el subproyecto de nuestro directorio de trabajo local. Cuando llegue el momento de aportar código al proyecto de nivel superior, habrá que bifurcar el proyecto y añadirlo como otro remoto:

git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git

Ahora podemos usar el comando subtree push de la siguiente manera:

git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main

Con esto, estamos listos y podemos abrir una solicitud de incorporación de cambios para el mantenedor del paquete.

¿Se puede hacer sin el comando git subtree?

¡Sí! Sí se puede. git subtree es diferente de la estrategia de fusión de subárboles. Puedes seguir usando la estrategia de fusión, aunque, por alguna razón, git subtree no esté disponible. Sigue estos pasos.

Añade la dependencia como git remote:

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Antes de leer el contenido de la dependencia en el repositorio, es importante registrar una fusión para poder rastrear todo el historial del árbol del plugin hasta el momento:

git merge -s ours --no-commit tpope-vim-surround/main

Esta es la salida:

Automatic merge went well; stopped before committing as requested

Después, leemos el contenido del último objeto árbol en el repositorio de plugin en nuestro directorio de trabajo listo para la confirmación:

git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main

Ahora podemos confirmar (y será una confirmación de fusión que preservará el historial del árbol que leemos):

git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround

Si queremos actualizar el proyecto, ahora podemos hacer una incorporación con la estrategia de fusión de git subtree:

git pull -s subtree tpope-vim-surround main

El comando git subtree es una gran alternativa


Después de llevar un tiempo usando submódulos de Git, verás que git subtree resuelve muchos de los problemas con los submódulos. Como de costumbre, con todo lo relacionado con Git, hay una curva de aprendizaje para sacar todo el partido de la función.

Para seguir aprendiendo sobre Git, sígueme en Twitter (@durdn). Recuerda también echar un vistazo a Bitbucket de Atlassian si buscas una buena herramienta para gestionar tus repositorios de Git.

Actualización: Después de publicar este artículo, escribí otro artículo sobre la eficacia de git subtree.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


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.

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