¿Continúa el desarrollo en una twig o en el tronco?

Supongamos que está desarrollando un producto de software que tiene lanzamientos periódicos. ¿Cuáles son las mejores prácticas con respecto a la bifurcación y la fusión? Cortar twigs de publicación periódicas para el público (o cualquiera que sea su cliente) y luego continuar el desarrollo en el tronco, o considerar el tronco como la versión estable, labelrlo como un lanzamiento periódicamente y hacer su trabajo experimental en sucursales. ¿Qué piensan los demás que el baúl se considera "oro" o se considera "caja de arena"?

He intentado ambos methods 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 debe ser siempre estable.

Aquí hay algunas pautas y beneficios de este método:

  • Codifique cada tarea (o set relacionado de tareas) en su propia twig, luego tendrá la flexibilidad de cuándo le gustaría fusionar estas tareas y realizar una publicación.
  • QA debe hacerse en cada twig antes de fusionarse con el tronco.
  • Al hacer un control de calidad en cada twig individual, sabrá exactamente qué causó la falla más fácil.
  • Esta solución se adapta a cualquier número de desarrolladores.
  • Este método funciona ya que la bifurcación es una operación casi instantánea en SVN.
  • Etiquete cada versión que realice.
  • Puede desarrollar funciones que no planea lanzar por un time y decidir exactamente cuándo fusionarlas.
  • Por todo el trabajo que haga, puede tener el beneficio de comprometer su código. Si solo trabaja fuera del tronco, probablemente mantendrá su código sin comprometer mucho, y por lo tanto sin protección y sin historial automático.

Si intenta hacer lo contrario y hacer todo su desarrollo en el tronco, tendrá los siguientes problemas:

  • Problemas constantes de compilation para comstackciones diarias
  • Pérdida de productividad cuando un desarrollador comete un problema para todas las demás personas del proyecto
  • Ciclos de lanzamiento más largos, porque necesita finalmente get una versión estable
  • Lanzamientos less estables

Simplemente no tendrá la flexibilidad que necesita si intenta mantener estable una sucursal y la troncal como la caja de arena de desarrollo. La razón es que no puedes elegir y elegir en el maletero lo que quieres poner en esa versión estable. Ya estaría todo mezclado en el maletero.

El único caso en particular que diría para hacer todo el desarrollo en el maletero, es cuando comienzas un nuevo proyecto. Puede haber otros casos también según su situación.


Por cierto, los sistemas de control de versiones distribuidas proporcionan mucha más flexibilidad y recomiendo cambiar a hg o git.

He trabajado con ambas técnicas y diría que desarrollar en el tronco y derivar puntos estables a medida que se libera es la mejor manera de hacerlo.

Las personas de arriba que objetan diciendo que tendrás:

  • Problemas constantes de compilation para comstackciones diarias
  • Pérdida de productividad cuando un desarrollador comete un problema para todas las demás personas del proyecto

probablemente no haya usado técnicas de continuous integration.

Es cierto que si no realiza varias comstackciones de testing durante el día, digamos una vez cada hora más o less, se dejará expuesto a estos problemas, lo que estrangulará rápidamente el ritmo del desarrollo.

Al realizar varias comstackciones de testing durante el día, se repliegan rápidamente las actualizaciones de la base del código principal para que otras puedan usarlo y también se le avise durante el día si alguien ha roto la compilation para poder repararlo antes de volver a casa.

Como se señaló, solo descubrir una estructura rota cuando falla el desarrollo nocturno de las testings de regresión es una locura y ralentizará las cosas rápidamente.

Lea el artículo de Martin Fowler sobre Integración Continua . Lanzamos nuestro propio sistema para un gran proyecto (3.000kSLOC) en aproximadamente 2.000 líneas de Posix sh.

Tiendo a tomar el enfoque de "liberación de la twig". El maletero es volátil. Una vez que se acerca el time de lanzamiento, crearía una twig de lanzamiento, que trataría con más cautela. Cuando finalmente haya terminado, labelré / labelré el estado del repository para conocer la versión publicada "oficial".

Entiendo que hay otras maneras de hacerlo, así es como lo hice en el pasado.

Ambos.

El tronco se usa para la mayoría del desarrollo. Pero se espera que se hagan los mejores esfuerzos para garantizar que cualquier logging en el maletero no lo rompa. (parcialmente verificado por un sistema automatizado de compilation y testing)

Las versiones se mantienen en su propio directory, con solo correcciones de errores que se realizan en ellas (y luego se fusionan en el tronco).

Cualquier nueva característica que va a dejar el tronco en un estado inestable o que no funciona se realiza en su propia twig separada y luego se fusionó en el tronco al finalizar.

Me gusta y uso el enfoque descrito por Henrik Kniberg en el Control de versiones para múltiples equipos ágiles . 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 equipos individuales en entornos tradicionales) y no tiene sentido parafrasearlo, así que solo publicaré la "hoja de trucos" (que es auto explicativo) a continuación:

texto alternativotexto alternativo

Me gusta porque:

  • Es simple: puedes getlo de la image.
  • Funciona (y escala) bien sin demasiados problemas de fusión y conflicto.
  • Puede lanzar el "software de trabajo" en cualquier momento (en el espíritu de ágil).

Y por si acaso no fue lo suficientemente explícito: el desarrollo se realiza en "twigs de trabajo", el tronco se utiliza para el código DONE (liberable). Verifique el control de versiones para múltiples equipos ágiles para get todos los detalles.

Una buena reference en un process de desarrollo que mantiene estable el tronco y todo funciona en sucursales es el Sistema de desarrollo de calidad definitivo de Divmod. Un resumen rápido:

  • Todo el trabajo realizado debe tener un ticket asociado
  • Se crea una nueva sucursal para cada boleto donde se realiza el trabajo para ese boleto
  • Los cambios de esa twig no se fusionan de nuevo en el troncal principal sin ser revisados ​​por otro miembro del proyecto

Usan SVN para esto, pero esto podría hacerse fácilmente con cualquiera de los sistemas de control de versiones distribuidas.

Creo que su segundo enfoque (por ejemplo, labelr lanzamientos y hacer cosas experimentales en las sucursales, considerando el tronco estable) es el mejor enfoque.

Debería quedar claro que las sucursales henetworkingan todos los errores de un sistema en el momento en que está ramificado: si se aplican correcciones a un tronco, tendrá que ir uno por uno a todas las twigs si mantiene twigs como una especie de soltar el terminador del ciclo. Si ya tuvo 20 lanzamientos y descubrió un error que data desde el primero, tendrá que volver a aplicar su solución 20 veces.

Se supone que las twigs son las cajas de arena reales, aunque el tronco también tendrá que desempeñar esta function: las tags indicarán si el código es "oro" en ese momento, adecuado para su lanzamiento.

Desarrollamos en el tronco a less que los cambios sean demasiado importantes, desestabilizadores, o nos estamos acercando a una versión principal de uno de nuestros productos, en cuyo caso creamos una twig temporal. También creamos una sucursal permanente para cada lanzamiento de producto individual. Encontré el documento de Microsoft en Branching Guidance bastante útil. El tutorial sobre ramificación de Eric Sink también es interesante, y señala que lo que funciona para Microsoft puede ser demasiado pesado para el rest de nosotros. Fue en nuestro caso, realmente utilizamos el enfoque que Eric dice que hace su equipo.

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 twigs que se fusionan a la línea principal cuando son lo suficientemente estables para integrarse. Esto permite el rechazo de las características que no hacen el corte y puede proporcionar una capacidad incremental sólida a lo largo del time que los proyectos / características independientes pueden recoger.

Hay un costo de integración para la fusión y la recuperación de las nuevas funciones incorporadas en el enlace troncal, pero de todos modos vas a sufrir este dolor. Hacer que todos se desarrollen en el tronco juntos puede conducir a una situación salvaje, mientras que la ramificación le permite escalar y elegir los puntos en los que le gustaría tomar las píldoras de integración amarga. Actualmente tenemos una escala de más de cien desarrolladores en una docena de proyectos, cada uno con múltiples lanzamientos que usan los mismos componentes centrales, y funciona bastante bien.

La belleza de esto es que puedes hacer esto de manera recursiva: una gran twig característica puede ser su propio tronco con otras twigs que se desprenden si lo hace. Además, los lanzamientos finales obtienen una nueva sucursal que le brinda un lugar para realizar un mantenimiento estable.

Estamos utilizando el tronco para el desarrollo principal y la twig para el trabajo de mantenimiento de lanzamientos. Funciona bien Pero las twigs solo deberían usarse para corregir errores, sin cambios importantes, especialmente en el lado de la database, tenemos una regla de que solo un cambio de esquema puede ocurrir en el tronco principal y nunca en la twig.

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 los esfuerzos de testing se hayan completado 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 múltiples lanzamientos.

Una sucursal sin mantenimiento debe crearse solo cuando existe la probabilidad (o certeza) de colisiones entre el código que sería difícil de manejar de otra manera. Si la sucursal no resuelve un problema logístico, creará uno.

El desarrollo de lanzamiento normal ocurre en la línea principal. Los desarrolladores ingresan y salen de la línea principal para el trabajo de lanzamiento normal. El trabajo de desarrollo para parches hasta el código de producción actual debe estar en la twig para esa versión y luego fusionarse con la línea principal una vez que el parche haya pasado la testing y se implemente. El trabajo en sucursales sin mantenimiento debe coordinarse caso por caso.

Depende del tamaño de tu esfuerzo de desarrollo. Múltiples equipos trabajando 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 twig para que pueda continuar trabajando mientras regresa a la sucursal para corregir errores en el código de producción actual que funcionaría. Este es un uso trivial de ramificación y no demasiado engorroso.

Si tienes muchos desarrollos paralelos, querrás tener sucursales para cada uno de los esfuerzos, pero eso también requerirá más disciplina: Asegúrate de que tus twigs estén probadas y lists para fusionarse nuevamente. La progtwigción se combina para que dos grupos no intenten fusionarse al mismo time, etc.

Algunas twigs se encuentran en desarrollo durante tanto time que debes permitir las fusiones desde el tronco hasta la twig para networkingucir el número de sorpresas cuando finalmente se fusiona con el tronco.

Tendrás que experimentar si tienes un gran grupo de desarrolladores y tener una idea de lo que funciona en tu situación. Aquí hay una página de Microsoft que puede ser de alguna utilidad: http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx

Seguimos el tronco = flujo de desarrollo actual, twig = lanzamiento (s). En el lanzamiento al cliente ramificamos el tronco y simplemente mantenemos el tronco rodando hacia adelante. Tendrá que tomar una decisión sobre cuántos lanzamientos está preparado para admitir. Mientras más apoyes, más fusión estarás haciendo en la corrección de errores. Tratamos de mantener a nuestros clientes en no más de 2 lanzamientos detrás del maletero. (Por ejemplo, Dev = 1.3, versiones compatibles 1.2 y 1.1).

El tronco es generalmente la línea de desarrollo principal.

Las versiones se ramifican y muchas veces se realiza un trabajo experimental o mayor en las twigs y luego se fusiona con el tronco cuando está listo para integrarse con la línea de desarrollo principal.

El maletero generalmente debería ser su principal fuente de desarrollo. De lo contrario, pasará mucho time fusionándose en nuevas funciones. Lo he visto de otra manera y generalmente lleva a muchos dolores de cabeza de integración de última hora.

Etiquetamos nuestros lanzamientos para que podamos responder rápidamente a emergencias de producción sin distribuir el desarrollo activo.

Si vas a trabajar en un ciclo de lanzamiento, gran característica, te quedarás abandonado en una sucursal. De lo contrario, trabajamos en troncales y ramificamos para cada lanzamiento de producción en el momento en que construimos.

Las comstackciones de producción anteriores se mueven en ese momento a old_production_ y el lanzamiento de producto actual siempre es solo producción. Todo nuestro server de compilation sabe acerca de la producción es cómo implementar la twig de producción, y pateamos esa construcción con un gatillo de fuerza.

Para mí, depende del software que estoy usando.

En CVS, simplemente trabajaba en "trunk" y nunca labelba / branch, porque era realmente doloroso hacer lo contrario.

En SVN, iba a hacer mis cosas "de punta sangrienta" en el maletero, pero cuando llegó el momento de hacer un push de server, me labelron de manera apropiada.

Recientemente cambié a git. Ahora descubro que nunca trabajo en el maletero. En su lugar, utilizo una twig de sandbox llamada "new-featurename" y luego me fundo en una twig fija de "producción actual". Ahora que lo pienso, realmente debería estar haciendo las twigs "release-VERSIONNUMBER" antes de volver a fusionarme con "current-production" para poder volver a las versiones estables anteriores …

Realmente depende de qué tan bien su organización / equipo maneje las versiones y qué SCM utiliza.

  • Si lo que viene a continuación (en la próxima versión) se puede planificar fácilmente, es mejor desarrollarlo en el maletero. La administración de sucursales requiere más time y resources. Pero si el próximo no se puede planificar fácilmente (sucede todo el time en organizaciones más grandes), probablemente terminarás cometiendo cereza (cientos / miles) en lugar de twigs (varias o decenas).
  • Con Git o Mercurial, administrar twigs es mucho más fácil que cvs y subversión. Me gustaría ir a la logica de metodologías de tronco / twig de tema estable. Esto es lo que usa el equipo de git.git. lea: http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
  • Con Subversion, primero apliqué la metodología de desarrollo en el tronco. Hubo bastante trabajo cuando se trataba de la date de lanzamiento porque cada vez que tenía que elegir compromisos (mi empresa no es buena para planificar). Ahora soy una especie de experto en Subversion y conozco bastante bien la administración de las sucursales en Subversion, por lo que me estoy moviendo hacia el logot de metodologías de trunk / topic estable. Funciona mucho mejor que antes. Ahora estoy probando la forma en que funciona el equipo git.git, aunque probablemente seguiremos con Subversion.

Aquí está el layout SVN que prefiero:

  • raíz
    • desarrollo
      • twigs
        • feature1
        • feature2
      • el maletero
    • beta
      • tags
      • el maletero
    • lanzamiento
      • tags
      • el maletero

Todo el trabajo se realiza desde desarrollo / troncal, a exception de las características principales que requieren su propia twig. Después de que el trabajo se testing contra desarrollo / troncal, fusionamos problemas probados en beta / trunk. Si es necesario, el código se testing contra el server beta. Cuando estamos listos para lanzar algunos cambios, simplemente fusionamos las revisiones apropiadas en release / trunk y deploy.

Las tags se pueden crear en la twig beta o en la twig de publicación para que podamos realizar un seguimiento de la versión específica tanto para la versión beta como para la versión.

Este layout permite mucha flexibilidad. También nos facilita dejar las revisiones en beta / trunk mientras fusionamos otras para lanzar / trunk si algunas revisiones no pasan las testings en beta.

@Brian R. Bondy: Tenga en count que esta 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 installation por twig en progreso son simplemente demasiado altos. Piense en SOA / Clientes / Servidores / WebServicios / Bases de datos que deben proporcionarse por twig .

Esta solución también carece de la etapa de integración.

El método que usamos es el enfoque Perforce, que se discute extensamente en el gran libro de Laura Wingerd:

http://oreilly.com/catalog/9780596101855/index.html

Si bien el libro es forzosamente céntrico (Wingerd es un administrador de producto Perforce), los conceptos se pueden aplicar a cualquiera o todos los VCS.

El enfoque forzado (y la plataforma) nos ha servido muy bien. Se usa en muchas empresas (google, Intuit y, según he escuchado, Microsoft Windows).

Vale la pena leer el libro.

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 de la compañía que lo usa. En un entorno muy acelerado, cuando un lanzamiento puede ocurrir tan a menudo como cada pocos días, si intenta labelr y ramificar religiosamente, terminará con un repository inmanejable. En ese entorno, el enfoque de ramificación 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 bifurcación cuando se necesita y la bifurcación de cada tarea. Estos son, por supuesto, una especie de opuesto exacto el uno del otro. Como dije, todo se trata de la dinámica del proyecto.