¿Cuándo usar el subárbol git?


81

¿Qué problema git subtreeresuelve? ¿Cuándo y por qué debería usar esa función?

Leí que se usa para la separación de repositorios . Pero, ¿por qué no crearía simplemente dos repositorios independientes en lugar de unir dos no relacionados en uno?

Este tutorial de GitHub explica cómo realizar fusiones de subárboles de Git .

cómo usarlo, pero no cuándo (casos de uso) y por qué , y cómo se relaciona git submodule. Usaría submódulos cuando tengo una dependencia en otro proyecto o biblioteca.


1
"separación de repositorios"! = "repositorios no relacionados" piensa en dependencias en tu repositorio y no quieres usar submódulos (por alguna razón, tal vez no te guste que no sean transparentes y que las rutas en las confirmaciones en el submódulo no coincide con su ruta en el repositorio principal de git).
cyphar

1
@cyphar: ¿Estás diciendo que ambos submoduley subtreeestán más o menos logrando el mismo objetivo que es incorporar proyectos relacionados y que la única diferencia es que submodulepodría ser un poco menos transparente y actualizar los submódulos es una operación de dos pasos y que el inconveniente subtreees que ¿Los mensajes de confirmación estarán todos mezclados entre los dos proyectos?
Lernkurve

1
Bueno, no es realmente un inconveniente en ciertos casos. Por ejemplo, si necesita dividir un repositorio que tiene subtrees y se introdujo un error en una dependencia, encontrará la confirmación exacta en elsubtree que introdujo el error. Con los submódulos, solo encontrará que la confirmación que revirtió la submodulecausa del error y usted es una especie de SOL si desea encontrar rápidamente qué confirmación en una submodulecausa un error en su proyecto principal.
cyphar

1
Aquí hay un artículo que compara el subárbol git y el submódulo git con ejemplos prácticos nering.dev/2016/git-submodules-vs-subtrees
8ctopus

Respuestas:


58

Debe tener cuidado de anotar explícitamente de qué está hablando cuando usa el término 'subárbol' en el contexto de, gitya que en realidad hay dos temas separados pero relacionados aquí:

Estrategia de fusión de git-subtree y git subtree .

El TL; DR

Ambos conceptos relacionados con los subárboles le permiten gestionar de forma eficaz varios repositorios en uno. A diferencia de git-submodule, donde solo los metadatos se almacenan en el repositorio raíz, en forma de .gitmodules , y debe administrar los repositorios externos por separado.

Más detalles

La estrategia de fusión de subárboles de git es básicamente el método más manual que utiliza los comandos a los que hizo referencia.

git-subtree es un script de shell contenedor para facilitar una sintaxis más natural. En realidad, esto sigue siendo parte de contribgit y no está completamente integrado en las páginas de manual habituales. En cambio, la documentación se almacena junto con el script.

Aquí está la información de uso:

NAME
----
git-subtree - Merge subtrees together and split repository into subtrees


SYNOPSIS
--------
[verse]
'git subtree' add   -P <prefix> <commit>
'git subtree' add   -P <prefix> <repository> <ref>
'git subtree' pull  -P <prefix> <repository> <ref>
'git subtree' push  -P <prefix> <repository> <ref>
'git subtree' merge -P <prefix> <commit>
'git subtree' split -P <prefix> [OPTIONS] [<commit>]

Me he encontrado con una buena cantidad de recursos sobre el tema de los subárboles, ya que estaba planeando escribir una publicación de blog propia. Actualizaré esta publicación si lo hago, pero por ahora aquí hay información relevante para la pregunta en cuestión:

Mucho de lo que está buscando se puede encontrar en este blog de Atlassian de Nicola Paolucci, la sección correspondiente a continuación:

¿Por qué utilizar subárbol en lugar de submódulo?

Hay varias razones por las que puede que le resulte subtreemejor utilizar:

  • La gestión de un flujo de trabajo sencillo es sencilla.
  • gitSe admiten versiones anteriores de (incluso antes v1.5.2).
  • El código del subproyecto está disponible justo después clonede que se realiza el superproyecto.
  • subtreeno requiere que los usuarios de su repositorio aprendan nada nuevo, pueden ignorar el hecho de que está utilizando subtreepara administrar dependencias.
  • subtreeno agrega nuevos archivos de metadatos como lo submoduleshace (es decir .gitmodule).
  • El contenido del módulo se puede modificar sin tener una copia de repositorio separada de la dependencia en otro lugar.

En mi opinión, los inconvenientes son aceptables:

  • Debe aprender sobre una nueva estrategia de fusión (es decir subtree).
  • Contribuir con el código upstreampara los subproyectos es un poco más complicado.
  • La responsabilidad de no mezclar código de superproyecto y subproyecto en las confirmaciones recae en usted.

También estaría de acuerdo con gran parte de esto. Recomendaría consultar el artículo ya que trata sobre algunos usos comunes.

Es posible que haya notado que también ha escrito un seguimiento aquí donde menciona un detalle importante que se deja fuera de este enfoque ...

git-subtree ¡actualmente no incluye el control remoto!

Esta miopía probablemente se deba al hecho de que las personas a menudo agregan un control remoto manualmente cuando se trata de subárboles, pero esto tampoco se almacena en git. El autor detalla un parche que ha escrito para agregar estos metadatos al compromiso que git-subtreeya genera. Hasta que esto se convierta en la línea principal oficial de git, puede hacer algo similar modificando el mensaje de confirmación o almacenándolo en otra confirmación.

También encuentro esta publicación de blog muy informativa. El autor agrega un tercer método de subárbol que llama git-streea la mezcla. Vale la pena leer el artículo ya que hace un buen trabajo comparando los tres enfoques. Da su opinión personal de lo que le gusta y lo que no le gusta y explica por qué creó el tercer enfoque.

Extras

Pensamientos finales

Este tema muestra tanto el poder gitcomo la segmentación que puede ocurrir cuando una característica simplemente no da en el blanco.

Personalmente, he creado un disgusto por lo git-submoduleque me resulta más confuso de entender para los contribuyentes. También prefiero mantener TODAS mis dependencias administradas dentro de mis proyectos para facilitar un entorno fácilmente reproducible sin tratar de administrar múltiples repositorios. git-submodule, sin embargo, es mucho más conocido en la actualidad, por lo que obviamente es bueno estar al tanto y dependiendo de su audiencia, eso puede influir en su decisión.


12

En primer lugar: creo que su pregunta tiende a obtener respuestas fuertemente obstinadas y puede considerarse fuera de tema aquí. Sin embargo, no me gusta esa política de SO y empujaría el límite de estar en el tema un poco hacia afuera, así que me gusta responder y espero que otros también lo hagan.

En el tutorial de GitHub que señaló, hay un enlace a Cómo usar la estrategia de fusión de subárboles que brinda un punto de vista sobre las ventajas / desventajas:

Comparación de la fusión de subárboles con submódulos

El beneficio de usar la combinación de subárboles es que requiere menos carga administrativa de los usuarios de su repositorio. Se trabaja con más edad (antes de Git) v1.5.2 clientes y tiene el código justo después de clon.

Sin embargo, si utiliza submódulos , puede optar por no transferir los objetos del submódulo . Esto puede ser un problema con la combinación de subárboles.

Además, en caso de que realice cambios en el otro proyecto, es más fácil enviar cambios si solo usa submódulos.

Aquí está mi punto de vista basado en lo anterior:

A menudo trabajo con personas (= confirmadores) que no son usuarios habituales de git, algunos todavía (y siempre) tendrán problemas con el control de versiones. Educarlos sobre cómo usar la estrategia de fusión de submódulos es básicamente imposible. Implica los conceptos de controles remotos adicionales, sobre la fusión, las ramificaciones y luego mezclar todo en un solo flujo de trabajo. Tirar de aguas arriba y empujar aguas arriba es un proceso de dos etapas. Dado que las ramas son difíciles de entender para ellos, todo esto es inútil.

Con los submódulos todavía es demasiado complicado para ellos ( suspiro ) pero es más fácil de entender: es solo un repositorio dentro de un repositorio (están familiarizados con la jerarquía) y puedes empujar y tirar como de costumbre.

Proporcionar scripts de contenedor simples es más fácil en mi humilde opinión para el flujo de trabajo del submódulo.

Para grandes super-repositorios con muchos sub-repositorios, el punto de elegir no clonar datos de algunos sub-repositorios es una ventaja importante de los submódulos. Podemos limitar esto en función de los requisitos de trabajo y el uso de espacio en disco.

El control de acceso puede ser diferente. Todavía no he tenido este problema, pero si diferentes repositorios requieren diferentes controles de acceso, prohibiendo efectivamente a algunos usuarios de algunos sub-repositorios, me pregunto si eso es más fácil de lograr con el enfoque de submódulo.

Personalmente, estoy indeciso sobre qué usar. Entonces comparto tu confusión: o]


3
Esta respuesta es la más fuertemente obstinada que he visto, a pesar de la contradicción, ya que es la única respuesta y la profecía autocumplida. El suspiro exasperado, la actitud agorera sobre la capacidad de aprender de los demás, esta es una respuesta muy arrogante. Su opinión sobre la política probablemente pertenece a Meta, donde podría ser útil. Sin embargo, la respuesta en sí misma, fuera de la pelusa egoísta, es bastante buena.
vgoff

1
@vgoff: Tu crítica es correcta. Perdón por ser aparentemente arrogante, son solo> 15 años de experiencia laboral con personas que han sido capacitadas durante ese tiempo por diferentes personas en diferentes sistemas de control de versiones y aún copian archivos de texto a multitud de archivos .backup.<timestamp>. Creo que dejé claro al principio que va a tener opiniones. Otros, con suerte, pueden proporcionar una visión más objetiva, y me sorprende que nadie lo haya hecho todavía.
cfi

Todavía no lo entiendo. ¿Está diciendo que submodulees la forma antigua obsoleta de incorporar bibliotecas usadas y subtreees la nueva forma brillante?
Lernkurve

No. Los documentos al menos no mencionan que ninguno de los dos está en desuso. Y para mí, los documentos tienen la última palabra (a excepción de los errores). Son solo dos flujos de trabajo diferentes para lograr algo similar. Ambos tienen ventajas y desventajas. Para mí, el hecho de que ninguno de los gurús git todavía haya respondido es una confirmación de que para el experto las diferencias son insignificantes. Lo más probable es que use la estrategia de fusión de subárboles porque es la que se implementó anteriormente y la gente está familiarizada con read-tree(y ramificación / fusión / control remoto de todos modos). submodulesfue agregado el
cfi

5

Un caso de uso real que tenemos donde git subtree fue una salvación:

El producto principal de nuestra empresa es altamente modular y desarrollado en varios proyectos en repositorios separados. Todos los módulos tienen su hoja de ruta separada. Todo el producto se compone de todos los módulos de versiones de hormigón.

En paralelo, la versión concreta de todo el producto se personaliza para cada uno de nuestros clientes: ramas separadas para cada módulo. La personalización debe realizarse a veces en varios proyectos a la vez ( cross-module customization).

Para tener un ciclo de vida del producto separado (mantenimiento, ramas de funciones) para el producto personalizado, presentamos el subárbol git. Tenemos un repositorio de git-subtree para todos los módulos personalizados. Nuestra personalización es 'git subtree push' de todos los días a todos los repositorios originales a las ramas de personalización.

Así evitamos administrar muchos repositorios y muchas braches. ¡git-subtree aumentó nuestra productividad varias veces!

ACTUALIZAR

Más detalles sobre la solución que se publicó en los comentarios:

Creamos un repositorio completamente nuevo. Luego agregamos cada proyecto que tenía una rama de cliente a ese nuevo repositorio como subárbol. Teníamos un trabajo de jenkins que hacía retroceder los cambios maestros de los repositorios originales a la rama del cliente con regularidad. Trabajamos solo con el "repositorio del cliente" usando el flujo típico de git con ramas de características y mantenimiento.

Nuestro repositorio de 'cliente' también tenía scripts de construcción que también adaptamos para este cliente en particular.

Sin embargo, existe un peligro de solución presentada.

A medida que nos alejábamos más y más del desarrollo principal del producto, la posible actualización para ese cliente en particular era cada vez más difícil. En nuestro caso, estuvo bien, ya que el estado del proyecto antes del subárbol ya estaba lejos de la ruta principal, por lo que el subárbol introduce al menos un orden y la posibilidad de introducir un flujo de git predeterminado.


Marek, me enfrento a lo que suena como la misma situación y soy relativamente nuevo en el git y forcejeo con las posibilidades. Me gustaría saber más sobre su configuración.
goug

Creé un repositorio completamente nuevo. Luego agregué cada proyecto que tenía una rama de cliente a ese repositorio como subárbol. Teníamos un trabajo de jenkins que hacía retroceder los cambios en los repositorios originales a la rama del cliente. En nuestro repositorio de cliente estábamos trabajando normalmente en el maestro con funciones, ramas de mantenimiento.
Marek Jagielski

El problema era que nos alejábamos cada vez más del desarrollo principal del producto. Entonces, la posible actualización para ese cliente en particular era cada vez más difícil. En nuestro caso estuvo bien, ya que el estado del proyecto antes del subárbol ya estaba lejos de la ruta principal, por lo que el subárbol introduce al menos un orden y la posibilidad de introducir el flujo de git predeterminado.
Marek Jagielski

Una cosa más que nuestro repositorio 'cliente' también tenía la construcción de scripts que también estábamos adaptando para este cliente en particular.
Marek Jagielski

1
Me gustaría recomendarle que incorpore su información adicional de los comentarios en su respuesta; definitivamente hacen que esta sea una mejor respuesta.
James Skemp

5

Básicamente, Git-subtree son las alternativas para el enfoque de Git-submodule: hay muchos inconvenientes o, más bien, diría, debe tener mucho cuidado al usar git-submodules. por ejemplo, cuando tiene "un" repositorio y dentro de "uno", ha agregado otro repositorio llamado "dos" usando submódulos. Cosas que debes cuidar:

  • Cuando cambia algo en "dos", necesita confirmar y presionar dentro de "dos", si está en el directorio de nivel superior (es decir, en "uno") sus cambios no se resaltarán.

  • Cuando un usuario desconocido intenta clonar su "un" repositorio, después de clonar "uno", ese usuario necesita actualizar los submódulos para obtener los "dos" repositorios

Estos son algunos de los puntos y para una mejor comprensión te recomiendo que veas este video: https://www.youtube.com/watch?v=UQvXst5I41I

  • Para superar estos problemas, se inventa el enfoque de subárbol. Para obtener los conceptos básicos sobre git-subtree, eche un vistazo a esto: https://www.youtube.com/watch?v=t3Qhon7burE

  • Encuentro que el enfoque de subárbol es más confiable y práctico en comparación con los submódulos :) (Soy muy principiante para decir estas cosas)

¡Salud!


2

Para agregar a las respuestas anteriores, un inconveniente adicional de usar subárbol es el tamaño del repositorio en comparación con los submódulos.

No tengo ninguna métrica del mundo real, pero dado que cada vez que se realiza una inserción en un módulo, en todos los lugares donde se usa ese módulo se obtiene una copia del mismo cambio en el módulo principal (cuando se actualiza posteriormente en esos repositorios).

Entonces, si una base de código está muy modularizada, eso se sumará bastante rápido.

Sin embargo, dado que los precios del almacenamiento siempre están bajando, eso puede no ser un factor significativo.


El almacenamiento no es el problema. ¡La entropía es el problema ! Por ejemplo, tiene 1000 herramientas de 10 KB a 100 KB, cada una de las cuales comparte una base de código común de, por ejemplo, 35 GB (porque contiene una gran cantidad de módulos de diferentes fuentes). Con los submódulos transfieres alrededor de 36 GB para todos, ¡pero probablemente más de 1 TB con el subárbol git! También tenga en cuenta que el submódulo tiene una ventaja claramente injusta si se trata de una git gcdeduplicación de ZFS (paquetes de objetos). Por lo tanto, las bases de código más pequeñas de AFAICS (en cuanto al tamaño del repositorio, no al repositorio) deberían ir con submódulos, los más grandes con monorepo. Todavía no encontré ningún uso para el subárbol.
Tino

@tino Git deducirá subárboles con código común muy bien. Solo hice algunos experimentos para confirmar. Para el código extraído, necesitaría ejecutar algo como ZFS. Pero los submódulos no son diferentes.
Matthias
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.