tag - SVN y código compartido entre varios proyectos.
tag svn (6)
Tengo varios proyectos en SVN. Cada uno de estos proyectos se asienta en su propio tronco y se ramifica para lanzamientos.
Y hay un código compartido que se utiliza en cada proyecto. La pregunta es cuál es la mejor manera de manejar el código.
Permítanme dar un par de escenarios y los temas relacionados con ellos.
a) Coloque el código compartido en un tronco separado (o repositorio) y use svn: external.
En el caso de que ramifiquemos algunos de los proyectos, habrá dos problemas:
- Cualquier modificación del código compartido que se realice en el troncal se propagará a la rama, porque svn: external recogerá los cambios
- En el caso de que en algún momento necesitemos volver atrás y compilar exactamente el código que se creó para su lanzamiento, será difícil para nosotros obtener el código exacto, porque snv: external volverá a recoger la última copia del código compartido, en lugar de Código en el momento en que se realizó el proyecto.
Según tengo entendido hay un trabajo alrededor. Tan pronto como nos bifurcemos, podemos modificar svn: external para recoger la revisión exacta del código compartido. Sin embargo, hay de nuevo dos trampas:
- Necesitas recordar hacer esto cada vez que bifurcas. (Odio esas cosas, que es fácil de olvidar).
- No puede modificar el código compartido, si necesita hacer un hotfix para el proyecto liberado / ramificado.
b) Otra solución es derivar el código compartido cuando el proyecto se ramifica y cambiar de forma externa para apuntar a copia copiada del código compartido.
- Una vez más, uno de los problemas es el paso manual, que es fácil de olvidar.
- Otro problema es fusionar problemas. SVN omitirá los aspectos externos cuando intente fusionar los cambios en el proyecto con el troncal. Entonces, nuevamente, el desarrollador debe recordar fusionar el código compartido manualmente.
¿Me estoy perdiendo algo? ¿Hay alguna manera razonable de manejar esto?
La respuesta que falta en tu lista es:
c) Siempre apunte los aspectos externos a una versión específica del código compartido.
Esto funciona notablemente bien:
- Siempre puede desplegar una versión específica de su proyecto y garantizar la compilación.
- La bifurcación y el etiquetado es una operación solo en la ruta del proyecto.
- Se pueden hacer actualizaciones al código compartido para 1 proyecto, pero el segundo proyecto no las recogerá hasta que esté listo para hacerlo.
- Cuando el segundo proyecto recoge los cambios, obtiene un evento grabado en su baúl que dice que se detectó y por qué.
- Tienes la oportunidad de lanzar una versión específica de la biblioteca con características específicas para un proyecto. Esto puede sacarte de los agujeros si un proyecto no está listo para un cambio de API pero necesita ciertas correcciones de errores, etc.
Si es necesario, las bibliotecas se pueden extraer en una copia de trabajo por separado y modificarlas junto con su proyecto principal. Si el proyecto se cambia temporalmente para recoger el código de la copia de trabajo en el disco, puede seguir trabajando en bibliotecas y proyectos en paralelo, si es necesario.
Mi recomendación para manejar el código compartido (particularmente con Java y .NET o una biblioteca C / C ++) es usar dos conjuntos de repositorios: uno para el código fuente y otro para las versiones publicadas. Cuando realiza cambios en el proyecto ''común'', confirma los cambios de origen en el árbol de origen, luego lo crea y luego publica los archivos binarios confirmándolos como una nueva revisión en el árbol de la versión. Los proyectos que usan el proyecto ''común'' luego usan la propiedad svn: externals para traer los binarios liberados. No hay tentación de modificar las imágenes locales del código compartido. Si alguien quiere modificar el código ''común'', entonces lo hacen a través de las prácticas de desarrollo normales para ese proyecto.
Para más detalles, vea esta answer a una pregunta similar.
Tienes dos respuestas correctas, con dos conjuntos de inconvenientes.
Esto es lo que recomendaría
Coloque su código compartido en otro repositorio, etiquete el código con la versión de lanzamiento Cree un svn externals en su directorio troncal que apunte a su etiqueta.
Cuando cambie su biblioteca, vuelva a etiquetarla y actualice su aplicación de troncal. Cuando tome una rama, su rama seguirá apuntando a la versión etiquetada correcta de su biblioteca.
Alternativamente, intente construir una versión separada de su biblioteca y haga referencia a la biblioteca como jar o lib / so.
Usamos una estructura de repositorio único como esta:
/trunk/project1
/trunk/classlibrary (shared code)
/trunk/project2
En C # (que puede no ser su idioma de elección), project1 y project2 incluyen una referencia a classlibrary. Cuando construimos (aquí hay una gran ventaja del modelo compilado .NET), se encuentran incoherencias entre el proyecto que se está construyendo y la biblioteca de clases. Estas inconsistencias se resuelven antes de cometer cambios. Usando una herramienta de construcción basada en servidor (usamos CruiseControl.NET) podemos construir todos los proyectos a la vez, lo que nos informará de cualquier problema.
A menos que su proyecto1 y su proyecto2 necesiten hacer referencia a una versión específica de la biblioteca de clases (lo que evitamos, al tratar de hacer que el proyecto1 y el proyecto2 usen siempre la última versión de la biblioteca de clases), esto funciona increíblemente sin problemas.
Tiendo a evitar hacer repositorios separados para aplicaciones relacionadas. Dado que la biblioteca de clases en el ejemplo anterior une todas estas cosas, hay poca ventaja o lógica para mantenerlas en versiones separadas, ya que la razón real por la que se separan en el nivel del proyecto es que es un código compartido. Las aplicaciones de producción que comparten código lo hacen por una razón: deberían usar la misma versión del código compartido, lo que implica que deberían ser parte de la misma rama de control de origen.
Utilizamos un sistema similar al de CWT: el código compartido tiende a ser proyectos separados por derecho propio y, como tal, existe por separado en el repositorio (o en un repositorio separado). Dentro del proyecto que utiliza los proyectos externos (el proyecto ascendente ), incluimos los binarios compilados / empaquetados para el proyecto compartido / descendente.
De esta manera, el proyecto anterior no se verá afectado por cambios inesperados en los proyectos posteriores.
Hemos escrito algunos scripts para actualizar automáticamente los principales proyectos ascendentes con versiones más recientes de estos binarios cuando sea necesario (de lo contrario, es un proceso manual para copiar el paquete en los proyectos apropiados, pero eso no es un gran problema de todos modos).
El inconveniente que hemos visto hasta ahora en este método de Madnes ^ W es que los proyectos posteriores que están en desarrollo muy activo (por ejemplo, en las primeras etapas de una nueva biblioteca) requieren lo que puede parecer un número excesivo de actualizaciones al proyecto anterior. La prueba del proyecto en sentido ascendente puede requerir la actualización de la biblioteca compartida, la compilación, la copia de ese binario en sentido ascendente y la compilación / implementación / cualquiera que sea el proyecto en sentido ascendente. Sin embargo, una vez que el frenesí inicial de desarrollo en una biblioteca se ralentiza y la libra se vuelve algo estable, este "problema" se evapora.
Al igual que con CWT, el proyecto anterior no puede modificar el código compartido de ninguna manera significativa. Los cambios en sentido descendente se deben realizar dentro de ese proyecto de manera explícita y se deben propagar en sentido ascendente cuando sea necesario.
Personalmente, mantengo un repositorio separado y luego uso el atributo [ http://svnbook.red-bean.com/en/1.0/ch07s03.html svn: externals].
Los externos de SVN le permiten vincularse a otros repositorios (incluso los que no ejecuta, por ejemplo, el repositorio de subversión de smarty) cuando ejecuta una actualización svn, tanto su proyecto como el repositorio externo se actualizarán.
con externos SVN también puede enlazar a revisiones específicas utilizando algo como http://path-to-project.com/svn/thing -r1234
para versiones y otras cosas que necesita para mantener la estática
La práctica recomendada IMHO es siempre especificar una revisión y luego actualizar el número de revisión a medida que realiza cambios en la biblioteca compartida para que pueda realizar un seguimiento de POR QUÉ actualizó estos datos. También mantiene todo sano al etiquetar o ramificar el proyecto principal.