Pregunta

En mi empresa estamos usando un repositorio SVN para mantener nuestro código C ++. El código base se compone de una parte común (infraestructura y aplicaciones) y proyectos de clientes (desarrollados como complementos).

El diseño del repositorio tiene este aspecto:

  • 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 para un proyecto cliente incluye los datos del proyecto y cada proyecto que usa (por ejemplo, Infraestructura).

El diseño real de cada directorio es -

  • infraestructura
    • ramas
    • etiquetas
    • tronco
  • proyecto-para-cliente-2
    • ramas
    • etiquetas
    • tronco

Y lo mismo ocurre con el resto de los proyectos.

Tenemos varios problemas con el diseño anterior:

  1. Es difícil comenzar un nuevo entorno de desarrollo para un proyecto de cliente, ya que uno tiene que revisar todos los proyectos involucrados (por ejemplo: Infraestructura, App1, App2, proyecto-para-cliente-1).
  2. Es difícil etiquetar un lanzamiento en los proyectos de un cliente, por la misma razón que la anterior.
  3. En caso de que un proyecto de cliente necesite cambiar algún código común (por ejemplo, infraestructura), a veces usamos una rama. Es difícil hacer un seguimiento de las sucursales que se utilizan en los proyectos.

¿Hay alguna forma en SVN para resolver alguno de los anteriores? Pensé en usar svn: externals en los proyectos del cliente, pero después de leer esta publicación entiendo que podría no ser la elección correcta.

¿Fue útil?

Solución

Puedes manejar esto con svn: externals. Esta es la url a un lugar en un repositorio svn Esto le permite extraer partes de un repositorio diferente (o el mismo). Una forma de usar esto es en proyecto-para-cliente2, agrega un enlace svn: externals a la rama de infraestructura que necesita, la rama de aplicación1 que necesita, etc. Entonces, cuando selecciona proyecto-para-cliente2, obtiene Todas las piezas correctas.

Los enlaces svn: externals se versionan junto con todo lo demás, por lo que a medida que project-for-client1 se etiqueten, se ramifiquen y se actualicen, las ramas externas correctas siempre se activarán.

Otros consejos

Una sugerencia es cambiar el diseño del directorio desde

  • infraestructura
    • ramas
    • etiquetas
    • tronco
  • proyecto-para-cliente-1
    • ramas
    • etiquetas
    • tronco
  • proyecto-para-cliente-2
    • ramas
    • etiquetas
    • tronco

a

  • ramas
    • feature-1
      • Infraestructura
      • proyecto-para-cliente-1
      • proyecto-para-cliente-2
  • etiquetas
  • baúl
    • Infraestructura
    • proyecto-para-cliente-1
    • proyecto-para-cliente-2

También hay algunos problemas con este diseño. Las sucursales se vuelven masivas, pero al menos es más fácil etiquetar lugares específicos en su código.

Para trabajar con el código, uno simplemente verificará el tronco y trabajará con eso. Entonces no necesitas los scripts que revisan los diferentes proyectos. Solo se refieren a Infraestructura con " ../ Infraestructura " ;. Otro problema con este diseño es que necesita retirar varias copias si desea trabajar en proyectos de forma completamente independiente. De lo contrario, un cambio en Infraestructura para un proyecto puede hacer que otro proyecto no se compile hasta que también se actualice.

Esto podría hacer que los lanzamientos sean un poco más engorrosos también, y separar el código para diferentes proyectos.

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

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

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

Cada secuencia de comandos se ve así:

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

Donde los comandos pueden ser un checkout, actualización o etiqueta. Es un poco más complicado que eso, pero significa que todo es coherente, el control, la actualización y el etiquetado se convierten en un solo comando.

Y, por supuesto, intentamos dividirnos lo menos posible, que es la sugerencia más importante que puedo hacer. Si necesitamos dividir algo, intentaremos trabajar fuera del tronco o la versión previamente etiquetada de tantas dependencias como sea posible.

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

En este momento está realizando varias comprobaciones para crear una copia de trabajo. Si utilizara elementos externos, haría exactamente esto, pero de forma automática y coherente cada vez.

Si dirige sus externos a etiquetas (y / o revisiones específicas) dentro de los proyectos de destino, solo necesita etiquetar el proyecto actual por lanzamiento (ya que esa etiqueta indicaría exactamente a qué externo estaba apuntando). También tendría un registro dentro de su proyecto de exactamente cuando cambió sus referencias 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 lo externo, pero aún no lo he encontrado (incluso conceptualmente). Ciertamente, la estructura que está usando puede generar una gran cantidad de información y control en su proceso de desarrollo, y los externos pueden agregar más. Sin embargo, los problemas que tenía no eran problemas fundamentales de corrupción: una solución limpia resolvería todo y son bastante raras (¿realmente no puedes crear una nueva sucursal de una biblioteca en tu repositorio?).

Puntos a considerar: uso de elementos externos recursivos. No me vendieron ni el sí ni el no de esto y tiendo a ir con un enfoque pragmático.

Considere usar el pistón como lo sugiere el artículo, no lo he visto en acción, por lo que realmente no puedo hacer comentarios, puede hacer el mismo trabajo que los externos de una mejor manera.

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

Solo cuando existe una relación entre proyectos individuales, como software, esquemas de hardware, documentación, etc. Usamos un solo repositorio, por lo que el número de revisión sirve para que todo el paquete alcance un estado conocido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top