two tortoise subversion repositorio estructura create crear branches svn mercurial branch subrepos externals

tortoise - Adaptación de svn: uso externo para pasar a Mercurial



svn merge branch to trunk (1)

Tenemos en un entorno corporativo una estructura de repositorio svn que se ve así:

root libs shared_lib1 shared_lib2 private_lib public_code private_code

donde public_code es un repositorio externo que es de código abierto y donde personas ajenas a la empresa tienen acceso de lectura-escritura. shared_lib1 y shared_lib2 también son repositorios externos compartidos con un grupo diferente de programadores de otra compañía. Soy el mantenedor y puedo hacer básicamente lo que sea técnicamente mejor, los usuarios externos tendrán que adaptarse.

Ahora me pregunto cuál es la mejor manera de pasar de esta estructura a un repositorio mercurial.

1) Podría simular de cerca la configuración anterior usando subrepositorios mercuriales. O
2) Podría hacer un gran repositorio para nosotros y tres nuevos repositorios más pequeños y separados para los socios externos (básicamente, bifurcar proyectos) e intercambiar conjuntos de cambios entre el grande y los diferentes.

Con la configuración 1) en svn, la bifurcación es una pesadilla porque, por política, siempre debo ramificar public_code, shared_lib1 y shared_lib2 cuando ramifico la raíz. Para esto tengo que llamar a la rama svn cuatro veces y modificar las propiedades svn: externals a mano tres veces. ¿Puedo ramificar fácilmente el repositorio principal en mercurial y obtener automáticamente nuevas sucursales para todos los sub-repositorios?

Cuando configuro 2), el sistema de archivos será diferente entre repositorios. Por ejemplo, tendré public_code / Makefile en el repositorio "root" pero el archivo será solo "Makefile" en el repositorio "public_code". ¿Mercurial podrá sincronizar los cambios entre los repos? ¿Cómo podría ser el flujo de trabajo?


Con la configuración 1) en SVN, la bifurcación es una pesadilla porque, por política, siempre debo ramificar public_code , shared_lib1 y shared_lib2 cuando shared_lib2 root . Para esto tengo que llamar a la svn branch cuatro veces y modificar svn:externals propiedades svn:externals mano tres veces. ¿Puedo ramificar fácilmente el repositorio principal en Mercurial y obtener automáticamente nuevas sucursales para todos los sub-repositorios?

No, los subrepositorios no funcionan así. Las ramas con nombre en el repositorio de nivel superior no se propagarán a los subrepositorios automáticamente. Si shared_lib1 una rama 1.x en su código, entonces no está claro que shared_lib1 también debe tener la rama 1.x De hecho, probablemente no debería ramificarse al mismo tiempo las ramas de código de nivel superior, especialmente si la biblioteca está siendo utilizada por varios proyectos de nivel superior diferentes.

Cuando configuro 2), el sistema de archivos será diferente entre repositorios. Por ejemplo, tendré public_code/Makefile en la root repositorio pero el archivo será solo Makefile en el repo public_code . ¿Mercurial podrá sincronizar los cambios entre los repos? ¿Cómo podría ser el flujo de trabajo?

No, no puedes empujar y tirar entre los repositorios si los creas así. Solo puede hacer push / pull entre repositorios cuando se originan en el mismo repositorio "madre". Aquí parece que creará tres repositorios no relacionados.

En una situación como esta, debe evaluar cuidadosamente por qué tiene svn:externals en Subversion y cómo se correlacionan con los subrepositorios de Mercurial . No son un reemplazo 1-1 para svn:externals . También debería buscar soporte de herramienta para subrepos, tanto en Mercurial como en su hosting de Mercurial, su sistema de compilación continua, etc. Escribí parte del código de retapo de Mercurial y, a partir de Mercurial 2.0, todavía hay algunos bordes afilados aquí y allá.

En pocas palabras, lo que los subrepositorios te dan es un acoplamiento muy estrecho entre los subsistemas. Normalmente, esto es algo que hay que evitar :-) Hacemos todo lo posible para que nuestros sistemas de software se acoplen holgadamente ya que eso nos da flexibilidad.

El caso de uso principal para los subrepositorios es un "repositorio de compilación" donde rastrea las versiones precisas de los componentes que utilizó en una compilación determinada. No puede pedirle a Mercurial que rastree la punta de una rama determinada en un subrepo, siempre rastreará un conjunto de cambios dado en un repositorio dado. Esto es lo que hace posible volver a crear un proceso de pago determinado más adelante: el archivo .hgsubstate rastrea los conjuntos de cambios precisos que se extrajeron en cada subrepo.

Por lo tanto, si su repositorio root no se usa para el desarrollo, sino solo para la creación de versiones, los subrepositorios pueden funcionar de maravilla para usted. El flujo de trabajo será algo así como

$ cd root $ cd libs/shared_lib1 $ hg pull $ hg update 2.0 $ cd ../.. $ make test && hg commit -m "Updated to sharedlib1 2.0" $ hg tag 2.3

A continuación, libera la versión 2.3 de su software y Mercurial sabe que depende de la versión 2.0 de shared_lib1 . Harás esto de vez en cuando cuando las personas responsables de los subcomponentes te digan que tienen un nuevo lanzamiento listo para ti. ¡Su servidor CI por supuesto puede hacerlo todas las noches para ver si los componentes funcionan juntos!

Los supositorios funcionan menos bien si los desarrolladores están trabajando directamente en la root y si hacen cambios en los subcomponentes como parte de su trabajo en la root . Eso es una indicación de un acoplamiento demasiado apretado entre los componentes: si el código principal depende de un conjunto de cambios exacto de un subcomponente, entonces el subcomponente debería estar directamente en el código principal. Además, hg commit en el repositorio de nivel superior se repetirá y usará el mismo mensaje de confirmación en los subrepos cuando ui.commitsubrepos=True . (El valor predeterminado fue cambiado a False en Mercurial 2.0.) Esto a menudo no se desea y cuando tiene sentido, entonces el subrepo se acopla muy estrechamente y debe ser parte del repositorio de nivel superior.

Entonces, para resumir: use subrepos si root es un "repositorio de compilación". De lo contrario, debe alinear los componentes en el repositorio de nivel superior, o debe acoplar las piezas juntas de forma más flexible mediante el uso de algo como Maven o similar para administrar las dependencias. Estas herramientas normalmente le permitirán decir "por favor, la última versión de root y todas sus dependencias" y luego podrá hacer una versión formal cuando esté satisfecho con las pruebas. Estas compilaciones de "instantáneas" no se pueden reproducir con precisión, pero tampoco es necesario, solo las versiones finales necesitan un seguimiento de dependencias estricto y preciso.