mercurial - Hg dependencias sub-repositorio
dependencies subrepos (2)
Dice que desea rastrear en qué versión dependen cada uno, pero también estaría contento con una sola copia de A compartida entre B, C y D. Estas se excluyen mutuamente: con una sola copia de A, cualquier cambio a A provocar un cambio en el .hgsub de cada uno de B, C y D, por lo que no hay independencia en el control de versiones (ya que todo B, C y D se confirmarán después de un cambio a A).
Tener copias separadas también será incómodo. Si realiza un cambio que afecta tanto la copia de B de A como la copia de C, entonces intente empujar toda la estructura, los cambios a (digamos) B tendrán éxito pero los cambios a C fallarán porque requieren la fusión con los cambios que acaba de empujar B, para evitar crear nuevas cabezas. Y eso será un dolor.
La forma en que lo haría (y tal vez hay mejores formas) sería crear un repositorio D con subreposiciones de A, B y C. Cada uno de B y C tendría algún archivo de ubicación A sin seguimiento (que se te pedirá que ingrese a través de un enlace posterior a la clonación), indicando a su sistema de compilación dónde buscar su repositorio A. Esto tiene la ventaja de funcionar, pero se pierde la comodidad de un sistema que rastrea las versiones concurrentes de {B, C} y A. Una vez más, puede hacerlo manualmente con un archivo de versión A en cada uno de B o C actualizado por un gancho , lea de un gancho, y puede hacer que funcione, pero no creo que sea posible usar la implementación subrepos en hg. Mis sugerencias realmente se reducen a la implementación de un sistema de subrepo simplificado propio.
Ha habido un par de preguntas sobre las dependencias de sub-repo Hg en el pasado ( here y here ) pero las respuestas aceptadas no parecen abordar el problema para mí.
Un proyecto mío tiene 4 dependencias: A, B, C, D. D depende de A, B y C; y B y C dependen de A:
Quiero usar los sub-repositorios de Hg para almacenarlos para poder hacer un seguimiento de la versión de cada uno de ellos. Esto se debe a que, mientras estoy usando A, B, C y D en este proyecto, otros proyectos requerirán solo A y B. Por lo tanto, B y C deben rastrear qué versión de A necesitan independientemente de D. Al mismo tiempo, en mi aplicación, las versiones de B y C referenciadas por una versión dada de D siempre deben usar la misma versión de A que la referenciada por versión dada de D (de lo contrario, solo se caerá en el tiempo de ejecución). Lo que realmente quiero es permitirles que se hagan referencia entre sí como hermanos en el mismo directorio, es decir, los D de .hgsub se parecerían a los siguientes, y los B y C se parecerían a la primera línea.
../A = https:(central kiln repo)/A
../B = https:(central kiln repo)/B
../C = https:(central kiln repo)/C
Sin embargo, esto no parece funcionar: puedo ver por qué (sería fácil darle a la gente la suficiente cuerda para colgarse), pero es una pena, ya que creo que es la mejor solución para mis dependencias. He leído algunas soluciones sugeridas que describiré rápidamente y por qué no funcionan para mí:
Incluya copias como subdirectorios anidados , refiérase a estos como sub-repositorios Hg. Esto produce la siguiente estructura de directorios (he eliminado las copias primarias de A, B, C, B / A, C / A porque puedo aceptar hacer referencia a las copias dentro de / D en su lugar):
- proyecto / (todos los archivos principales del proyecto)
- proyecto / D
- proyecto / D / A
- proyecto / D / B
- proyecto / D / B / A
- proyecto / D / C
- proyecto / D / C / A
Problemas con este enfoque:
- Ahora tengo 3 copias de A en el disco, todas las cuales podrían tener modificaciones independientes que deben sincronizarse y fusionarse antes de pasar a un repositorio central.
- Tengo que usar otros mecanismos para garantizar que B, C y D hagan referencia a la misma versión de A (por ejemplo, D podría usar v1 mientras que D / B podría usar v2)
Una variación: use lo anterior pero especifique el RHS de .hgsub para apuntar a una copia en la copia principal (es decir, B y C deberían tener el .hgsub a continuación):
A = ../A
Problemas con este enfoque:
- Todavía tengo tres copias en disco
- La primera vez que clone B o C, intentará extraer de forma recursiva la versión referenciada de A de ".. / A", que puede no existir, probablemente causando un error. Si no existe, no da ninguna pista sobre dónde se debe encontrar el repositorio.
- Cuando hago un impulso recursivo de cambios, los cambios en D / B / A no entran en el repositorio central compartido; simplemente son empujados a D / A en su lugar. Por lo tanto, si presiono dos veces seguidas, puedo garantizar que todos los cambios se habrán propagado correctamente, pero esto es todo un problema.
- De manera similar, si hago un tirón recursivo (manual), tengo que ordenar correctamente para obtener los últimos cambios (es decir, tirar D / A antes de tirar D / B / A)
Use enlaces simbólicos para señalar la carpeta / D / B / A a D / A etc.
Problemas con este enfoque:
- los enlaces simbólicos no se pueden codificar en el repositorio de Hg, por lo que cada vez que un miembro del equipo clona el repositorio, tienen que crear manualmente / con un script volver a crear los enlaces simbólicos. Esto puede ser aceptable pero preferiría una mejor solución. También (preferencia personal) encuentro que los enlaces simbólicos son muy poco intuitivos.
¿Son estas las mejores soluciones disponibles? ¿Hay una buena razón por la que mi .hgsub inicial (ver arriba) es un sueño imposible, o hay una manera en que puedo solicitar / implementar este cambio?
ACTUALIZADO para explicar mejor el uso más amplio de A, B, C, D
En lugar de intentar administrar sus dependencias a través de Mercurial (o con cualquier SCM), intente utilizar una herramienta de administración de dependencias, como Apache Ivy .
Usando un enfoque basado en Ivy, no tiene sub-repos, solo tendría los proyectos A, B, C y D. A produce un artefacto (por ejemplo, .jar, .so o .dll, etc.), que es publicado en un repositorio de artefactos (básicamente un lugar donde guardas tus artefactos de compilación) con una versión. Los proyectos B y C pueden depender de una versión específica de A (controlada a través de un archivo ivy.xml en cada proyecto) que Ivy recuperará del repositorio de artefactos. Los proyectos B y C también producen artefactos que se publican en su repositorio. El proyecto D depende de B y C e Ivy puede recibir instrucciones para recuperar las dependencias de forma transitoria, lo que significa que obtendrá los artefactos para B, C y A (porque dependen de A).
Se puede usar un enfoque similar con Apache Maven y Gradle (el último utiliza a Ivy)
Las principales ventajas son que:
- deja muy claro qué versiones de cada componente está utilizando un proyecto (a veces las personas se olvidan de verificar
.hgsub
, por lo que no saben que están trabajando con subrepos), - hace que sea imposible cambiar un proyecto dependiente (ya que está trabajando con artefactos, no con código)
- y le evita tener que reconstruir proyectos dependientes y no estar seguro de qué versión está utilizando.
- le evita tener múltiples copias redundantes de proyectos que son utilizados por otros proyectos.
EDITAR: ¿Respuesta similar con un giro ligeramente diferente en Mejores prácticas para sub-módulos de características de proyecto con Mercurial y Eclipse?