Manejando las relaciones entre múltiples proyectos de subversión

En mi compañía estamos usando un repository SVN para contener nuestro código C ++. La base de código se compone de una parte común (infraestructura y aplicaciones) y proyectos de cliente (desarrollados como complementos).

El layout del repository se ve así:

  • Infraestructura
  • App1
  • App2
  • App3
  • proyecto-para-cliente-1
    • App1-plugin
    • App2-plugin
    • Configuración
  • proyecto-para-cliente-2
    • App1-plugin
    • App2-plugin
    • Configuración

Una versión típica de un proyecto de cliente incluye los datos del proyecto y cada proyecto que utiliza (por ejemplo, Infraestructura).

El layout real de cada directory es –

  • Infraestructura
    • twigs
    • tags
    • el maletero
  • proyecto-para-cliente-2
    • twigs
    • tags
    • el maletero

Y lo mismo aplica para el rest de los proyectos.

Tenemos varios problemas con el layout anterior:

  1. Es difícil comenzar un nuevo entorno de desarrollo para un proyecto de cliente, ya que uno tiene que verificar todos los proyectos involucrados (por ejemplo: Infraestructura, App1, App2, project-for-client-1).
  2. Es difícil labelr un lanzamiento en un proyecto de cliente, por la misma razón que la anterior.
  3. En caso de que un proyecto del cliente necesite cambiar algún código común (por ejemplo, Infraestructura), a veces usamos una twig. Es difícil hacer un seguimiento de qué twigs se utilizan en los proyectos.

¿Hay alguna manera en SVN para resolver cualquiera de los anteriores? Pensé en usar svn: external en los proyectos del cliente, pero después de leer esta publicación comprendo que podría no ser la opción correcta.

Podrías manejar esto con svn: externals. Esta es la url de un punto en un svn repo. Esto le permite extraer partes de un repository diferente (o el mismo). Una forma de utilizar esto es en project-for-client2, agrega un enlace svn: external a la twig de la infraestructura que necesita, la twig de la aplicación1 que necesita, etc. Por lo tanto, cuando revisa project-for-client2, obtiene todas las piezas correctas.

Los enlaces svn: externals están versionados junto con todo lo demás, de modo que cuando project-for-client1 se etiquete, se bifurque y se actualice, las twigs externas correctas siempre se extraerán.

Una sugerencia es cambiar el layout del directory de

  • Infraestructura
    • twigs
    • tags
    • el maletero
  • proyecto-para-cliente-1
    • twigs
    • tags
    • el maletero
  • proyecto-para-cliente-2
    • twigs
    • tags
    • el maletero

a

  • twigs
    • feature-1
      • Infraestructura
      • proyecto-para-cliente-1
      • proyecto-para-cliente-2
  • tags
  • el maletero
    • Infraestructura
    • proyecto-para-cliente-1
    • proyecto-para-cliente-2

También hay algunos problemas con este layout. Las twigs se vuelven masivas, pero al less es más fácil labelr lugares específicos en tu código.

Para trabajar con el código, uno simplemente echa un vistazo a la cajuela y trabaja con eso. Entonces no necesitas los scripts que verifican todos los proyectos diferentes. Simplemente se refieren a Infraestructura con "../Infraestructura". Otro problema con este layout es que tiene que pagar varias copys si desea trabajar en proyectos de forma completamente independiente. De lo contrario, un cambio en la infraestructura de un proyecto podría causar que otro proyecto no se compile hasta que se actualice también.

Esto también puede hacer que las versiones sean un poco más engorrosas y separando el código para diferentes proyectos.

Sí, apesta. Hacemos lo mismo, pero realmente no puedo pensar en un mejor layout.

Entonces, lo que tenemos es un set de scripts que pueden automatizar todo lo relacionado con la subversión. El proyecto de cada cliente contendrá un file llamado project.list , que contiene todos los proyectos / routes de subversión necesarios para build ese cliente. Por ejemplo:

 Infrastructure/trunk LibraryA/trunk LibraryB/branches/foo CustomerC/trunk 

Cada guión se ve así:

 for PROJ in $(cat project.list); do # execute commands here done 

Donde los commands pueden ser un pago, actualización o label. Es un poco más complicado que eso, pero significa que todo es coherente, el control, la actualización y el labeldo se convierte en un solo command.

Y, por supuesto, tratamos de ramificar lo less posible, que es la sugerencia más importante que puedo hacer. Si necesitamos ramificar algo, trataremos de trabajar fuera del tronco o la versión labelda previamente de tantas dependencies como sea posible.

Primero, no estoy de acuerdo con que los externos sean malos. Aunque no son perfectos.

Por el momento, está realizando varias comprobaciones para crear una copy de trabajo. Si usó Externals, haría exactamente esto, pero de forma automática y consistente cada vez.

Si dirige sus externos a las tags (y / o revisiones específicas) dentro de los proyectos objective, solo necesita labelr el proyecto actual por versión (ya que esa label indicaría exactamente a qué externo estaba apuntando). También tendría un logging dentro de su proyecto de exactamente cuándo modificó sus references externas para usar una nueva versión de una biblioteca en particular.

Los externos no son una panacea, y como muestra la publicación, puede haber problemas. Estoy seguro de que hay algo mejor que los externos, pero aún no lo he encontrado (incluso conceptualmente). Ciertamente, la estructura que está utilizando puede generar una gran cantidad de información y control en su process de desarrollo, el uso de elementos externos puede agregar a eso. Sin embargo, los problemas que tenía no eran problemas fundamentales de corrupción: un process limpio resolvería todo y son bastante raros (¿realmente no puede crear una nueva twig de una biblioteca en su repository?).

Puntos a considerar: usar elementos externos recursivos. No me venden con el sí o el no de esto y tienden a adoptar un enfoque pragmático.

Considere usar pistón como lo sugiere el artículo, no lo he visto en acción, así que no puedo comentar realmente, puede hacer el mismo trabajo de manera externa.

Desde mi experiencia, creo que es más útil tener un repository para cada proyecto individual. De lo contrario, tienes los problemas que dices y, además, los numbers de revisión cambian si cambian otros proyectos, lo que podría ser confuso.

Solo cuando existe una relación entre proyectos individuales, como software, esquemas de hardware, documentation, etc. Usamos un único repository, por lo que el número de revisión sirve para que todo el package llegue a un estado conocido.