Supongamos que está desarrollando un producto de software que tiene lanzamientos periódicos. ¿Cuáles son las mejores prácticas con respecto a la ramificación y fusión? Cortar las ramas de lanzamiento periódico al público (o quien sea su cliente) y luego continuar el desarrollo en el tronco, o considerar el tronco como la versión estable, etiquetarlo como un lanzamiento periódicamente y realizar su trabajo experimental en las ramas. ¿Qué piensan las personas si el baúl se considera "oro" o se considera una "caja de arena"?
version-control
Sam McAfee
fuente
fuente
Respuestas:
He probado ambos métodos con una gran aplicación comercial.
La respuesta a qué método es mejor depende en gran medida de su situación exacta, pero escribiré lo que mi experiencia general ha demostrado hasta ahora.
El mejor método en general (en mi experiencia): el tronco siempre debe ser estable.
Aquí hay algunas pautas y beneficios de este método:
Si intenta hacer lo contrario y hacer todo su desarrollo en el tronco, tendrá los siguientes problemas:
Simplemente no tendrá la flexibilidad que necesita si intenta mantener una rama estable y el tronco como el entorno limitado de desarrollo. La razón es que no puede elegir y elegir del tronco lo que desea poner en esa versión estable. Ya estaría todo mezclado en el maletero.
El único caso en particular que yo diría que haga todo el desarrollo en el tronco, es cuando está comenzando un nuevo proyecto. Puede haber otros casos también dependiendo de su situación.
Por cierto, los sistemas de control de versiones distribuidas proporcionan mucha más flexibilidad y recomiendo cambiar a hg o git.
fuente
He trabajado con ambas técnicas y diría que el mejor camino es desarrollar en el tronco y ramificar puntos estables como lanzamientos.
Esas personas de arriba que se oponen diciendo que tendrás:
Probablemente no haya utilizado técnicas de integración continua.
Es cierto que si no realiza varias compilaciones de prueba durante el día, por ejemplo, una vez cada hora más o menos, se dejará abierto a estos problemas que rápidamente estrangularán el ritmo de desarrollo.
Al hacer varias compilaciones de prueba durante el día, las actualizaciones de la base del código principal se pliegan rápidamente para que otros puedan usarlo y también le avisa durante el día si alguien ha roto la compilación para que puedan arreglarlo antes de irse a casa.
Como se señaló, solo descubrir una compilación rota cuando falla la compilación nocturna para ejecutar las pruebas de regresión es una locura y ralentizará las cosas rápidamente.
Lea el artículo de Martin Fowler sobre Integración continua . Desarrollamos nuestro propio sistema para un proyecto importante (3,000kSLOC) en aproximadamente 2,000 líneas de Posix sh.
fuente
Tiendo a adoptar el enfoque de "rama de lanzamiento". El tronco es volátil. Una vez que se acerca el tiempo de lanzamiento, haría una rama de lanzamiento, que trataría con más cautela. Cuando eso finalmente esté hecho, etiquetaría / etiquetaría el estado del repositorio para conocer la versión lanzada "oficial".
Entiendo que hay otras formas de hacerlo, así es como lo hice en el pasado.
fuente
Ambos.
El tronco se usa para la mayoría del desarrollo. Pero se espera que se realicen los mejores esfuerzos para garantizar que cualquier registro en el tronco no lo rompa. (parcialmente verificado por un sistema automatizado de compilación y prueba)
Las versiones se mantienen en su propio directorio, y solo se realizan correcciones de errores en ellas (y luego se fusionan en el tronco).
Cualquier característica nueva que va a dejar la troncal en un estado inestable o inoperante se realiza en su propia rama separada y luego se fusiona con la troncal al finalizar.
fuente
Me gusta y uso el enfoque descrito por Henrik Kniberg en Control de versiones para equipos ágiles múltiples . Henrik hizo un gran trabajo al explicar cómo manejar el control de versiones en un entorno ágil con múltiples equipos (también funciona para un solo equipo en entornos tradicionales) y no tiene sentido parafrasearlo, así que simplemente publicaré la "hoja de trucos" (que se explica por sí mismo) a continuación:
Me gusta porque:
Y en caso de que no fuera lo suficientemente explícito: el desarrollo se realiza en "ramas de trabajo", el enlace troncal se usa para el código HECHO (liberable). Verifique el Control de versiones para múltiples equipos ágiles para todos los detalles.
fuente
Una buena referencia sobre un proceso de desarrollo que mantiene estable el tronco y hace todo el trabajo en las sucursales es el Sistema de desarrollo de máxima calidad de Divmod . Un resumen rápido:
Utilizan SVN para esto, pero esto podría hacerse fácilmente con cualquiera de los sistemas de control de versiones distribuidos.
fuente
Creo que su segundo enfoque (por ejemplo, etiquetar lanzamientos y hacer cosas experimentales en ramas, considerando el tronco estable) es el mejor enfoque.
Debe quedar claro que las ramas heredan todos los errores de un sistema en el momento en que se ramifica: si se aplican arreglos a un tronco, tendrá que ir uno por uno a todas las ramas si mantiene las ramas como una especie de liberar el terminador del ciclo. Si ya ha tenido 20 versiones y descubrió un error que se remonta a la primera, tendrá que volver a aplicar su solución 20 veces.
Se supone que las ramas son las cajas de arena reales, aunque el tronco también tendrá que desempeñar este papel: las etiquetas indicarán si el código es "dorado" en ese momento, adecuado para su lanzamiento.
fuente
Nos desarrollamos en el tronco a menos que los cambios sean demasiado importantes, desestabilizadores o nos acerquemos a un lanzamiento importante de uno de nuestros productos, en cuyo caso creamos una rama temporal. También creamos una rama permanente para cada lanzamiento de producto individual. El documento de Microsoft sobre la orientación de ramificación me pareció bastante útil. El tutorial de Eric Sink sobre la ramificación también es interesante, y señala que lo que funciona para Microsoft puede ser demasiado pesado para algunos de nosotros. Fue en nuestro caso, en realidad utilizamos el enfoque que Eric dice que su equipo hace.
fuente
Depende de tus situaciones. Usamos Perforce y generalmente tenemos varias líneas de desarrollo. El tronco se considera "oro" y todo el desarrollo ocurre en las ramas que se fusionan con la línea principal cuando son lo suficientemente estables como para integrarse. Esto permite el rechazo de características que no hacen el corte y puede proporcionar una capacidad incremental sólida con el tiempo que los proyectos / características independientes pueden recoger.
Hay un costo de integración para fusionarse y ponerse al día con las nuevas características incluidas en el tronco, pero de todos modos sufrirá este dolor. Hacer que todos se desarrollen juntos en el tronco puede conducir a una situación en el salvaje oeste, mientras que la ramificación le permite escalar y elegir los puntos en los que desea tomar las amargas píldoras de integración. Actualmente estamos ampliados a más de cien desarrolladores en una docena de proyectos, cada uno con múltiples lanzamientos que usan los mismos componentes principales, y funciona bastante bien.
La belleza de esto es que puede hacer esto de forma recursiva: una rama de gran característica puede ser su propio tronco con otras ramas que se desprenden si es así. Además, las versiones finales obtienen una nueva sucursal que le brinda un lugar para realizar un mantenimiento estable.
fuente
Intentar gestionar el mantenimiento del código de producción actual en línea con el nuevo desarrollo es, en el mejor de los casos, problemático. Para mitigar esos problemas, el código debe ramificarse en una línea de mantenimiento una vez que se hayan completado los esfuerzos de prueba y el código esté listo para la entrega. Además, la línea principal debe ramificarse para ayudar en la estabilización de la versión, para contener los esfuerzos de desarrollo experimental o para albergar cualquier esfuerzo de desarrollo cuyo ciclo de vida se extienda a través de varias versiones.
Se debe crear una rama que no sea de mantenimiento solo cuando existe la probabilidad (o certeza) de colisiones entre el código que serían difíciles de manejar de otra manera. Si la sucursal no resuelve un problema logístico, creará uno.
El desarrollo de liberación normal ocurre en la línea principal. Los desarrolladores entran y salen de la línea principal para el trabajo de lanzamiento normal. El trabajo de desarrollo para los parches para el código de producción actual debe estar en la rama de esa versión y luego fusionarse con la línea principal una vez que el parche haya pasado la prueba y se haya implementado. El trabajo en las sucursales que no son de mantenimiento debe coordinarse caso por caso.
fuente
Depende del tamaño de su esfuerzo de desarrollo. Varios equipos que trabajan en paralelo no podrán trabajar de manera efectiva, todos en el mismo código (troncal). Si solo tiene un pequeño grupo de personas trabajando y su principal preocupación es cortar una rama para que pueda continuar trabajando mientras regresa a la rama para hacer correcciones de errores en el código de producción actual que funcionaría. Este es un uso trivial de ramificación y no demasiado pesado.
Si tiene mucho desarrollo paralelo, querrá tener sucursales para cada uno de los esfuerzos, pero eso también requerirá más disciplina: asegurarse de que sus sucursales se prueben y estén listas para fusionarse. La programación se fusiona para que dos grupos no intenten fusionarse al mismo tiempo, etc.
Algunas ramas están en desarrollo durante tanto tiempo que tiene que permitir fusiones del tronco a la rama para reducir la cantidad de sorpresas cuando finalmente se fusiona de nuevo con el tronco.
Tendrá que experimentar si tiene un gran grupo de desarrolladores y tener una idea de lo que funciona en su situación. Aquí hay una página de Microsoft que puede ser algo útil: http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx
fuente
Estamos utilizando el tronco para el desarrollo principal y la rama para trabajos de mantenimiento de versiones. Funciona bien Pero entonces las ramas solo deben usarse para corregir errores, sin cambios importantes, especialmente en el lado de la base de datos, tenemos la regla de que solo puede ocurrir un cambio de esquema en el tronco principal y nunca en la rama.
fuente
Si vas a trabajar a través de un ciclo de lanzamiento, gran característica, te dejarán en una sucursal. De lo contrario, trabajamos en troncales y bifurcaciones para cada versión de producción en el momento de la construcción.
Las compilaciones de producción anteriores se trasladan en ese momento a old_production_ y la versión actual de productos siempre es solo producción. Todo lo que nuestro servidor de compilación sabe sobre producción es cómo implementar la rama de producción, y comenzamos esa compilación con un disparador de fuerza.
fuente
Seguimos el enfoque de tronco = desarrollo actual, enfoque de rama = lanzamiento (s). En el momento del lanzamiento al cliente, ramificamos el tronco y simplemente lo mantenemos rodando hacia adelante. Deberá tomar una decisión sobre cuántos lanzamientos está preparado para admitir. Cuanto más soporte, más se fusionará con las correcciones de errores. Intentamos mantener a nuestros clientes en no más de 2 lanzamientos detrás del baúl. (Por ejemplo, Dev = 1.3, versiones compatibles 1.2 y 1.1).
fuente
El tronco es generalmente la línea principal de desarrollo.
Las versiones se ramifican y, a menudo, el trabajo experimental o principal se realiza en las ramas y luego se fusiona con el tronco cuando está listo para integrarse con la línea principal de desarrollo.
fuente
El tronco generalmente debe ser su principal fuente de desarrollo. De lo contrario, pasará mucho tiempo fusionándose en nuevas funciones. Lo he visto de otra manera y generalmente genera muchos dolores de cabeza de integración de último momento.
Rotulamos nuestros lanzamientos para que podamos responder rápidamente a emergencias de producción sin distribuir el desarrollo activo.
fuente
Para mí, depende del software que esté usando.
Bajo CVS, simplemente trabajaría en "troncal" y nunca etiquetaría / ramificaría, porque fue realmente doloroso hacer lo contrario.
En SVN, haría mis cosas "de última generación" en el tronco, pero cuando llegara el momento de hacer un empuje del servidor, me etiquetarían adecuadamente.
Recientemente me cambié a git. Ahora encuentro que nunca trabajo en el maletero. En su lugar, uso una rama de sandbox con nombre "new-featurename" y luego me fusiono en una rama fija de "producción actual". Ahora que lo pienso, realmente debería estar haciendo ramas "release-VERSIONNUMBER" antes de volver a fusionarme en "producción actual" para poder volver a las versiones estables más antiguas ...
fuente
Realmente depende de qué tan bien su organización / equipo maneje las versiones y qué SCM use.
fuente
Aquí está el diseño SVN que prefiero:
Todo el trabajo se realiza desde el desarrollo / troncal, excepto las características principales que requieren su propia rama. Después de probar el trabajo contra el desarrollo / troncal, fusionamos los problemas probados en beta / troncal. Si es necesario, el código se prueba con el servidor beta. Cuando estamos listos para implementar algunos cambios, simplemente fusionamos las revisiones apropiadas en la versión / troncal y la implementamos.
Las etiquetas se pueden hacer en la rama beta o en la rama de lanzamiento para que podamos realizar un seguimiento de la versión específica tanto para la versión beta como para la versión.
Este diseño permite mucha flexibilidad. También nos facilita dejar las revisiones en beta / trunk mientras fusionamos otros para liberar / trunk si algunas revisiones no pasaron las pruebas en beta.
fuente
El método que utilizamos es el enfoque de Perforce, que se discute extensamente en el gran libro de Laura Wingerd:
http://oreilly.com/catalog/9780596101855/index.html
Si bien el libro está centrado en el rendimiento (Wingerd es un gerente de producto de Perforce), los conceptos se pueden aplicar a cualquiera o todos los VCS.
El enfoque de rendimiento (y plataforma) nos ha servido muy bien. Se usa en muchas empresas (google, Intuit y, según he oído, el propio Microsoft Windows).
Vale la pena leer el libro.
fuente
Lea esto: http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf
fuente
No hay una respuesta única para la pregunta de la convención de subversión en mi humilde opinión.
Realmente depende de la dinámica del proyecto y la compañía que lo utiliza. En un entorno de ritmo muy rápido, cuando una versión puede ocurrir tan a menudo como cada pocos días, si intenta etiquetar y ramificar religiosamente, terminará con un repositorio inmanejable. En dicho entorno, el enfoque de sucursal cuando sea necesario crearía un entorno mucho más sostenible.
Además, en mi experiencia, es extremadamente fácil, desde un punto de vista administrativo puro, cambiar entre metodologías svn cuando lo desee.
Los dos enfoques que he sabido que funcionan mejor son la rama cuando es necesario y la rama de cada tarea. Estos son, por supuesto, una especie de opuesto exacto entre sí. Como dije, se trata de la dinámica del proyecto.
fuente
@Brian R. Bondy: Tenga en cuenta que esto no es una solución una vez que su equipo alcanza una cierta cantidad de personas / tareas manejadas en paralelo en el proyecto.
Una vez que un departamento de control de calidad está involucrado en qa, los esfuerzos necesarios para proporcionar una instalación por rama en progreso son simplemente demasiado altos. Piense en SOA / Clientes / Servidores / Servicios web / Bases de datos que deben proporcionarse por sucursal .
Esta solución también carece de la etapa de integración.
fuente