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

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

root libs shanetworking_lib1 shanetworking_lib2 private_lib public_code private_code 

donde public_code es un repository externo que es de código abierto y donde personas ajenas a la empresa tienen acceso de lectura-escritura. shanetworking_lib1 y shanetworking_lib2 también son repositorys externos compartidos con un grupo diferente de progtwigdores 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 repository mercurial.

1) Podría simular de cerca la configuration anterior usando subrepositorys mercuriales. O
2) Podría hacer un gran repository para nosotros y tres nuevos repositorys más pequeños y separados para los socios externos (básicamente, bifurcar proyectos) e intercambiar sets de cambios entre el grande y los diferentes.

Con la configuration 1) en svn, la bifurcación es una pesadilla porque, por política, siempre debo ramificar public_code, shanetworking_lib1 y shanetworking_lib2 cuando ramifico la raíz. Para esto tengo que llamar a la twig svn cuatro veces y modificar las properties svn: externals a mano tres veces. ¿Puedo ramificar fácilmente el repository principal en mercurial y get automáticamente nuevas sucursales para todos los sub-repositorys?

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

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

No, los subrepositorys no funcionan así. Las twigs con nombre en el repository de nivel superior no se propagarán a los subrepositorys automáticamente. Si shanetworking_lib1 una twig 1.x en su código, entonces no está claro que shanetworking_lib1 también debe tener la twig 1.x De hecho, probablemente no debería ramificarse al mismo time las twigs 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 files será diferente entre repositorys. Por ejemplo, tendré public_code/Makefile en la root repository pero el file 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 repositorys si los creas así. Solo puede hacer push / pull entre repositorys cuando se originan en el mismo repository "madre". Aquí parece que creará tres repositorys 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 subrepositorys de Mercurial . No son un reemploop 1-1 para svn:externals . También debería search soporte de herramienta para subrepos, tanto en Mercurial como en su hosting de Mercurial, su sistema de compilation 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 subrepositorys 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 subrepositorys es un "repository de compilation" donde rastrea las versiones precisas de los componentes que utilizó en una compilation determinada. No puede pedirle a Mercurial que rastree la punta de una twig determinada en un subrepo, siempre rastreará un set de cambios dado en un repository dado. Esto es lo que hace posible volver a crear un process de pago determinado más adelante: el file .hgsubstate rastrea los sets de cambios precisos que se extrajeron en cada subrepo.

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

 $ cd root $ cd libs/shanetworking_lib1 $ hg pull $ hg update 2.0 $ cd ../.. $ make test && hg commit -m "Updated to shanetworkinglib1 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 shanetworking_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 server CI por supuesto puede hacerlo todas las noches para ver si los componentes funcionan juntos!

Los supositorios funcionan less 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 set de cambios exacto de un subcomponente, entonces el subcomponente debería estar directamente en el código principal. Además, hg commit en el repository de nivel superior se repetirá y usará el mismo post de confirmación en los subrepos cuando ui.commitsubrepos=True . (El valor pnetworkingeterminado 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 repository de nivel superior.

Entonces, para resumir: use subrepos si root es un "repository de compilation". De lo contrario, debe alinear los componentes en el repository 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 dependencies. Estas herramientas normalmente le permitirán decir "por favor, la última versión de root y todas sus dependencies" y luego podrá hacer una versión formal cuando esté satisfecho con las testings. Estas comstackciones de "instantáneas" no se pueden reproducir con precisión, pero tampoco es necesario, solo las versiones finales necesitan un seguimiento de dependencies estricto y preciso.