¿Ramificarse o no ramificarse?


84

Hasta hace poco, mi flujo de trabajo de desarrollo era el siguiente:

  1. Obtenga la función del propietario del producto
  2. Hacer una rama (si la característica es más de 1 día)
  3. Implementarlo en una sucursal
  4. Combinar cambios de la rama principal a mi rama (para reducir conflictos durante la fusión hacia atrás)
  5. Fusionar mi rama de nuevo a la rama principal

A veces hubo problemas con la fusión, pero en general me gustó.

Pero recientemente veo más y más seguidores de la idea de no hacer sucursales, ya que hace que sea más difícil practicar la integración continua, la entrega continua, etc. Y suena especialmente gracioso para las personas con antecedentes de VCS distribuidos que hablaban tanto sobre implementaciones de gran fusión de Git, Mercurial, etc.

Entonces, la pregunta es si deberíamos usar ramas hoy en día


2
Estoy seguro de que esta es la plataforma adecuada para esto, pero sí, me ramificaría. Pero tal vez debería pensar en fusionar ciertos conjuntos de características de nuevo al maestro antes de que estén 100% terminados (para dar vistas previas: P)
ZeissS

1
Parece que necesitan mejores estrategias para fusionarse.
b01

1
Siempre he visto todos los commits como una fusión, incluso si es de local a remoto. La fusión de ramas es la misma, solo conjuntos de cambios más grandes, por lo que no entiendo cuál es el argumento de ninguna manera. ¿Alguien ha hecho un perfil real sobre el rendimiento de cualquiera de estas técnicas, o es solo una optimización pre-madura?
tylermac

Yo diría que las sucursales facilitarían el CI ...
tdammers

77
No publique en forma cruzada la misma publicación literalmente en varios sitios de Stack Exchange.
Adam Lear

Respuestas:


64

A menos que todos estén trabajando en el mismo árbol de trabajo, está utilizando ramas, ya sea que las llame así o no. Cada vez que un desarrollador se registra en su árbol de trabajo, crea una rama de desarrollo local separada, y cada vez que se registra se fusiona. Para la mayoría de los equipos, la pregunta no es si usa ramas, las preguntas son ¿cuántas y con qué propósito ?

La única forma de lograr una integración verdaderamente "continua" es que todos trabajen desde el mismo árbol de trabajo. De esa manera, sabrá de inmediato si sus cambios afectan negativamente a los de otra persona. Obviamente, eso es insostenible. Necesita un cierto grado de aislamiento en una rama para lograr algo, incluso si esa "rama" es solo su directorio de trabajo local. Lo que se necesita es un equilibrio adecuado de integración y aislamiento.

En mi experiencia, el uso de más ramas mejora el grado de integración, porque la integración se realiza precisamente con las personas que debe hacerse, y todos los demás pueden aislar más fácilmente los problemas no relacionados según sea necesario.

Por ejemplo, pasé el último día rastreando tres errores relacionados con la integración recientemente introducidos en nuestra compilación que bloqueaban mi trabajo "real". Después de hacer mi debida diligencia al informar estos errores a las personas que necesitan corregirlos, ¿se supone que debo esperar hasta que terminen para continuar con mi trabajo? Por supuesto no. Creé una sucursal local temporal que revierte esos cambios para poder tener una línea de base estable con la que trabajar mientras sigo recibiendo los últimos cambios desde arriba.

Sin la capacidad de hacer una nueva rama para ese propósito, me vería reducido a una de tres opciones: revertir los cambios en el repositorio central, mantener manualmente los parches que los revierten en mi árbol de trabajo e intentar no registrarlos accidentalmente , o volver a una versión anterior a la introducción de esos errores. Es probable que la primera opción rompa alguna otra dependencia. La segunda opción es mucho trabajo, por lo que la mayoría de las personas elige la tercera opción, que esencialmente evita que realice más trabajo de integración hasta que se solucionen los errores encontrados anteriormente.

Mi ejemplo utilizó una sucursal local privada, pero el mismo principio se aplica a las sucursales compartidas. Si comparto mi sucursal, tal vez otras 5 personas puedan continuar con sus tareas principales en lugar de realizar un trabajo de integración redundante, por lo tanto, en conjunto, se realiza un trabajo de integración más útil. El problema con la ramificación y la integración continua no es cuántas ramas tiene, sino con qué frecuencia las combina.


1
Si revierte las confirmaciones no deseadas en su nueva rama, ¿no las revierte en la rama maestra cuando se fusiona? Personalmente, me bifurcaría desde un punto anterior a los cambios no deseados, y elegiría los cambios de los que dependo en la nueva bifurcación.
Anthony

@anthony Lo más probable es que limpie su historial (elimine las reversiones) antes de fusionar. Alguien en contra de la reescritura del historial probablemente sea mejor siguiendo su método.
idbrii

Si eliminas la ramificación y la reescritura del historial, ¿por qué usar Git?
everton

80

la pregunta es ¿deberíamos usar ramas hoy en día?

Bueno, hace aproximadamente medio año me asignaron realizar un estudio para responder a esa pregunta. Aquí está el resumen, basado en referencias estudiadas (enumeradas a continuación)

  • no existe una "mejor" estrategia de ramificación comúnmente acordada aplicable a ningún proyecto
    • la mayoría de los recursos parecen estar de acuerdo en que elegir una estrategia productiva depende de los detalles específicos del proyecto
    • nota al margen. Según lo anterior, parece que cualquier cambio en la estrategia de ramificación del proyecto debe probarse, medirse y compararse con otras opciones probadas
  • La opinión popular es que fusionarse con Subversion requiere muchos esfuerzos. Todos los que compararon SVN y Git notan que la fusión es mucho más fácil con Git
  • Un factor importante parece ser si las emisiones de producción se originan en el tronco o las ramas. Los equipos que realizan lanzamientos de productos desde la troncal (que no parecen ser una forma muy popular) tienen esencialmente prohibido utilizar una estrategia de troncal inestable . Los equipos que realizan lanzamientos de productos de sucursales tienen más opciones de ramificación para elegir.
  • Las estrategias populares parecen ser troncales estables, troncales inestables y ramas de desarrollo (integración)

referencias

  • http://msdn.microsoft.com/en-us/library/aa730834%28v=vs.80%29.aspx

    ... Decidir sobre la mejor estrategia de ramificación es un acto de equilibrio. Debe compensar las ganancias de productividad con un mayor riesgo Una forma de validar una estrategia elegida es considerar un escenario de cambio. Por ejemplo, si decide alinear ramas con la arquitectura del sistema (por ejemplo, una rama representa un componente del sistema) y espera cambios arquitectónicos significativos, es posible que tenga que reestructurar sus ramas y procesos y políticas asociados con cada cambio. Elegir una estrategia de ramificación inadecuada puede causar gastos generales de proceso y una larga integración y ciclos de lanzamiento que resultan frustrantes para todo el equipo ...

  • http://www.cmcrossroads.com/bradapp/acme/branching/

    ... La integración incremental y frecuente es una de las señales del éxito, y su ausencia es a menudo una característica del fracaso. Los métodos actuales de gestión de proyectos tienden a evitar modelos de cascada estrictos y adoptan los modelos en espiral de desarrollo iterativo / incremental y entrega evolutiva. Las estrategias de integración incremental, como Merge Early y Frecuentemente y sus variantes, son una forma de gestión de riesgos que intenta eliminar el riesgo más temprano en el ciclo de vida cuando hay más tiempo para responder. [Booch], [McCarthy] y [McConnell] ven la regularidad del ritmo entre integraciones como un indicador principal de la salud del proyecto (como un "pulso" o un "latido").  
     
    La integración temprana y frecuente no solo aumenta el riesgo antes y en "fragmentos" más pequeños, sino que también comunica los cambios entre los compañeros de equipo ...

  • http://www.codinghorror.com/blog/2007/10/software-branching-and-parallel-universes.html

    ... En la mayoría de los sistemas de control de código fuente, puede crear cientos de sucursales sin ningún problema de rendimiento; es la sobrecarga mental de realizar un seguimiento de todas esas ramas de las que realmente debe preocuparse ... La ramificación es una bestia compleja. Hay docenas de maneras de ramificarse, y nadie puede decirle realmente si lo está haciendo bien o mal ...

  • http://www.lostechies.com/blogs/derickbailey/archive/2010/02/24/branching-strategies-when-to-branch-and-merge.aspx

    ... Hay muchos aspectos de un sistema a tener en cuenta al bifurcar su código ... Al final, el objetivo es proporcionar un entorno limitado para el contexto en el que se está escribiendo el código. Comprender las opciones disponibles, cuando cada opción se adapta mejor a la situación actual y el costo de estas opciones lo ayudará a decidir cómo y cuándo ramificar ...

  • http://www.snuffybear.com/ucm_branch.htm
    Nota dadas otras referencias enumeradas aquí, la afirmación del autor de que "Este artículo describe tres modelos de ramificación clave utilizados en proyectos de Ingeniería de Software" no parece justificado. La terminología utilizada no parece generalizada ( EFIX , Modelo-1,2,3, etc.).

  • http://svn.haxx.se/users/archive-2007-10/att-0101/SCMBranchingModels-talkback.pdf La
    referencia presenta un ejemplo interesante de dificultades para comunicar estrategias de ramificación.

  • http://simpleprogrammer.com/2010/06/04/simple-branching-strategy-part-1-back-to-basics/
    ... Mantenlo simple. Trabajar directamente desde el tronco es, con mucho, el mejor enfoque en mi opinión.  
     
    Casi suena a herejía cuando lo escribo en mi pantalla, pero si me aguantas un momento, no solo te mostraré por qué creo que esto es esencial para un proceso ágil, sino que te mostraré cómo para que funcione ...  
     
    ... Si tuviera que basar mi razonamiento en un argumento sólido, sería el valor de la integración continua. Escribí en un blog sobre el valor de CI y las mejores prácticas en el pasado. Soy un gran defensor de CI ...  
     
    ... Usted realmente tiene que hacerse una pregunta aquí: "¿Es toda la sobrecarga que está incurriendo de hacer su ramificación complicada y la fusión de la estrategia que resulta en un valor real que no existe más de una estrategia más simple?" ...  
     
    .. Una estrategia que he usado efectivamente en el pasado y que he desarrollado con el tiempo. Lo resumiré brevemente aquí.

  • http://www.codelathe.com/blog/index.php/2009/07/02/a-svn-branching-strategy-that-works/
    ... Finalmente, recuerde que no existe una estrategia ideal de ramificación y fusión. Depende bastante de su entorno de desarrollo único ...

  • http://blog.perforce.com/blog/?cat=62
    ... El peor de los casos es que introduce un problema de "fusión semántica", donde el resultado de una fusión automática es incorrecto, pero se compila bien y se escabulle pruebas, posiblemente incluso sobreviviendo el tiempo suficiente para ser un error visible para el cliente. Eek!  
     
    Agregando insulto a la lesión, ya que pueden escapar de la detección por más tiempo, los problemas de fusión semántica son más difíciles de solucionar más adelante, ya que el cambio ya no está fresco en la mente del desarrollador que originó el cambio. (Por lo general, es mejor combinar los cambios poco después de que se hayan realizado, idealmente por el desarrollador que originó el cambio si es práctico) ...

  • https://stackoverflow.com/questions/34975/branching-strategies Los
    miembros de la comunidad comparten diferentes experiencias en varios proyectos utilizando diversas estrategias de ramificación. No hay consenso acordado sobre "mejor" o "peor".

  • http://www.stickyminds.com/s.asp?F=S16454_COL_2
    Esencialmente un breve resumen de las cosas presentadas en http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf

    • http://www.stickyminds.com/s.asp?F=S16511_COL_2
      ... Hay tres enfoques comunes para decidir cuándo y cómo ramificarse:
      • Cree la rama de lanzamiento cuando esté "completada", y planee solucionar problemas de última hora en esta línea de código. En este caso, la rama de lanzamiento es realmente una "línea de código de preparación de lanzamiento", como se describe en los Patrones de administración de configuración de software , ya que espera que aún haya trabajo por hacer.
      • Cambie su estilo de trabajo para evitar el trabajo final de integración, trabajando fuera de la línea de desarrollo activa.
      • Se ramifica para el nuevo trabajo creando una rama de tareas y fusionando ese trabajo en la línea de desarrollo activa después de que se complete el lanzamiento.
        ... Una razón para ramificar es aislar el código al final de una versión para que pueda estabilizarse. El aislamiento a través de la ramificación a menudo oculta un problema de calidad que terminará manifestándose en el costo adicional de mantener flujos paralelos antes de que se lance un producto. Ramificar es fácil. Más bien, es la fusión y la sobrecarga cognitiva de entender cómo fluyen los cambios entre las ramas lo que es difícil, por lo que es importante elegir un proceso que minimice el costo de ramificación y fusión ...
  • http://nvie.com/posts/a-successful-git-branching-model/ Estrategia orientada a Git.
    ... Consideramos que origin / master es la rama principal donde el código fuente de HEAD siempre refleja un estado listo para producción .  
     
    Consideramos que origen / desarrollo es la rama principal donde el código fuente de HEAD siempre refleja un estado con los últimos cambios de desarrollo entregados para la próxima versión. Algunos lo llamarían la "rama de integración". Aquí es donde se construyen todas las compilaciones nocturnas automáticas ...

  • http://svnbook.red-bean.com/en/1.5/svn.branchmerge.html
    ... las políticas del proyecto varían ampliamente en cuanto a cuándo es apropiado crear una rama de características. Algunos proyectos nunca usan ramas de características en absoluto: los commits a / trunk son gratuitos para todos. La ventaja de este sistema es que es simple: nadie necesita aprender sobre ramificaciones o fusiones. La desventaja es que el código troncal a menudo es inestable o inutilizable. Otros proyectos utilizan las ramas a un extremo: no se producen cambios siempre comprometida con el tronco directamente. Incluso los cambios más triviales se crean en una rama de corta duración, se revisan cuidadosamente y se fusionan con el tronco. Luego se elimina la rama. Este sistema garantiza un tronco excepcionalmente estable y utilizable en todo momento, pero a costa de un tremendoproceso de gastos generales.  
     
    La mayoría de los proyectos adoptan un enfoque intermedio. Comúnmente insisten en que / trunk compile y pase las pruebas de regresión en todo momento. Se requiere una rama de características solo cuando un cambio requiere una gran cantidad de confirmaciones desestabilizadoras. Una buena regla general es hacer esta pregunta: si el desarrollador trabajó durante días de forma aislada y luego cometió el gran cambio de una vez (para que / trunk nunca se desestabilizara), ¿sería un cambio demasiado grande para revisar? Si la respuesta a esa pregunta es "sí", el cambio debe desarrollarse en una rama de características. A medida que el desarrollador confirma cambios incrementales en la sucursal, los pares pueden revisarlos fácilmente.  
     
    Finalmente, está la cuestión de cómo mantener mejor una rama de características en "sincronización" con el tronco a medida que avanza el trabajo. Como mencionamos anteriormente, existe un gran riesgo de trabajar en una sucursal durante semanas o meses; Los cambios en el tronco pueden continuar llegando hasta el punto en que las dos líneas de desarrollo difieren tanto que puede convertirse en una pesadilla tratar de fusionar la rama con el tronco.  
     
    Es mejor evitar esta situación fusionando regularmente los cambios del tronco a la rama. Haga una política: una vez por semana, combine los cambios de troncal de la rama de la última semana ...

  • http://thedesignspace.net/MT2archives/000680.html
    ... Esta sección del tutorial de Eclipse CVS se basa en el artículo de Paul Glezen en el sitio web de Eclipse: Ramificación con Eclipse y CVS , y se utiliza con su permiso bajo los términos de La licencia EPL. Los cambios que estoy haciendo en su versión son principalmente para expandirlo con más imágenes y explicaciones paso a paso, e integrarlo con mis propios tutoriales para principiantes en un intento de hacerlo más accesible para principiantes y diseñadores. Los desarrolladores experimentados probablemente preferirán trabajar desde la versión de Paul ...

  • http://learnsoftwareprocesses.com/2007/12/29/common-branching-strategies/
    ... Estos son algunos de los modelos de ramificación comunes:  

    1. Modelo de ramificación por lanzamiento: una de las estrategias de ramificación más comunes es alinear sucursales con lanzamientos de productos. Una sucursal posee todos los activos de desarrollo de software para una única versión. Ocasionalmente, las actualizaciones deben fusionarse de una versión a otra, pero generalmente nunca se combinan. Las ramas se suspenderán cuando se retire un lanzamiento.  
    2. Sucursal por promoción: otro enfoque muy común es alinear sucursales con niveles de promoción de activos de software. Una versión de desarrollo específica se ramifica en una rama de prueba, en la que se realizan todas las pruebas de integración y sistema. Cuando completa las pruebas, los activos de desarrollo de software se ramifican en la rama de Producción y finalmente se implementan.  
    3. Rama por tarea: para evitar la superposición de tareas (o actividades) y una pérdida de productividad, puede aislarlas en una rama separada. Tenga en cuenta que estas son ramas a corto plazo que deben fusionarse tan pronto como se complete la tarea, de lo contrario el esfuerzo de fusión requerido puede exceder los beneficios de productividad de crearlos en primer lugar.  
    4. Rama por componente: puede alinear cada rama con la arquitectura del sistema. En esta estrategia, ramifica componentes individuales (o subsistemas). Luego, cada equipo que desarrolla un componente decide cuándo fusionar su código nuevamente en la línea de desarrollo que sirve como la rama de integración. Esta estrategia puede funcionar bien si la arquitectura del sistema está en su lugar y los componentes individuales tienen interfaces bien definidas. El hecho de que desarrolle componentes en sucursales permite un control más preciso sobre los activos de desarrollo de software.  
    5. Rama por tecnología: otra estrategia de ramificación alineada con la arquitectura del sistema. En este caso, las ramas están alineadas con las plataformas tecnológicas. El código común se gestiona en una rama separada. Debido a la naturaleza única de los activos de desarrollo de software administrados en las sucursales, probablemente nunca se fusionen ...
  • http://msdn.microsoft.com/en-us/library/bb668955.aspx
    ... Consulte las pautas de ramificación y fusión en "Pautas de control de origen" en esta guía para obtener un resumen de las pautas de ramificación y fusión. ... Cuando ramifique, considere lo siguiente:

    • No ramifique a menos que su equipo de desarrollo necesite trabajar en el mismo conjunto de archivos al mismo tiempo. Si no está seguro de esto, puede etiquetar una compilación y crear una rama a partir de esa compilación en un momento posterior. La fusión de sucursales puede llevar mucho tiempo y ser compleja, especialmente si hay cambios significativos entre ellas.
    • Estructura los árboles de tus ramas de modo que solo necesites fusionarte a lo largo de la jerarquía (arriba y abajo del árbol de ramas) en lugar de a través de la jerarquía. La ramificación a través de la jerarquía requiere que use una fusión sin base, lo que requiere una resolución de conflictos más manual.
    • La jerarquía de la rama se basa en la rama principal y la rama secundaria, que pueden ser diferentes a la estructura física del código fuente en el disco. Al planificar sus fusiones, tenga en cuenta la estructura de ramificación lógica en lugar de la estructura física en el disco.
    • No se ramifique demasiado profundamente. Debido a que lleva tiempo ejecutar cada fusión y resolver conflictos, una estructura de ramificación profunda puede significar que los cambios en una rama secundaria pueden tardar mucho tiempo en propagarse a la rama principal. Esto puede afectar negativamente los cronogramas del proyecto y aumentar el tiempo para corregir errores.
    • Se ramifica a un alto nivel e incluye archivos de configuración y fuente.
    • Evolucione su estructura de ramificación con el tiempo.
    • La fusión requiere que uno o más desarrolladores ejecuten la fusión y resuelvan conflictos. La fuente fusionada debe probarse a fondo porque no es raro tomar malas decisiones de fusión que pueden desestabilizar la construcción.
    • Combinar en la jerarquía de sucursales es especialmente difícil y requiere que manejes manualmente muchos conflictos que de otro modo podrían manejarse automáticamente.  
      La decisión de crear una sucursal puede reducirse a si el costo de fusionar conflictos en tiempo real es mayor que el costo indirecto de fusionar conflictos entre sucursales ...
  • http://kashfarooq.wordpress.com/2009/11/23/bazaar-branching-strategy-with-a-subversion-trunk/

    • http://kashfarooq.wordpress.com/2010/12/16/bazaar-branching-strategy-with-a-subversion-trunk-revised/
    • http://kashfarooq.wordpress.com/2009/11/02/using-bazaar-feature-branches-with-a-subversion-trunk/
    • http://kashfarooq.wordpress.com/2009/09/08/bazaar-or-git-moving-away-from-subversion/
      ... ¿Alguna de estas quejas de Subversion le suena familiar?
      • Se le indica aleatoriamente que "necesita ejecutar la actualización". Luego haces una actualización, que lleva años completar. Y luego, finalmente, ves que no hubo cambios que debían descargarse.
      • Se le indica aleatoriamente que "necesita ejecutar la limpieza".
      • Tienes grandes problemas de fusión. Por ejemplo, utiliza ReSharper para cambiar el nombre de una clase y, mientras tanto, otra persona ha actualizado esa clase. Luego verá el temido error de conflicto del árbol (estremecimiento). O peor aún, cambia el nombre de un espacio de nombres y una carpeta completos (doble estremecimiento). Ahora realmente estás en un mundo de dolor.
      • Sus fusiones tienden a ser cada vez más manuales. Con frecuencia tiene que usar WinMerge porque Subversion no tiene ni idea.
      • A menudo está esperando que Tortoise se actualice / verifique modificaciones / cualquier cosa.  
         
        Tengo un repositorio de subversión en mi memoria USB. ¡Tengo conflictos de árbol y problemas de fusión con eso, y soy el único usuario!  
         
        El principal problema es la fusión ...  
         
    • "subversión apesta" suena familiar. ¿Es hora de escuchar a Joel y Linus ?
  • http://social.msdn.microsoft.com/Forums/en/tfsversioncontrol/thread/f127676c-8f05-410c-9a30-0eb43a26a9fa una
    discusión sobre las mejores prácticas para liberar la estrategia de rama de aislamiento en el caso de sistemas en evolución.

  • http://branchingguidance.codeplex.com/
    "Microsoft Team Foundation Server Branching Guidance": documento enorme y detallado con recomendaciones adaptadas a diferentes proyectos: versión HTML aquí . Demuestra que Microsoft no cree en estrategias de ramificación wrt de enfoque único para todos.

  • https://stackoverflow.com/questions/597707/best-branching-strategy-when-doing-continuous-integration
    ¿Cuál es la mejor estrategia de ramificación para usar cuando quieres hacer una integración continua? ... La respuesta depende del tamaño de su equipo y la calidad de su control de origen y la capacidad de combinar correctamente conjuntos de cambios complejos ...

  • http://codicesoftware.blogspot.com/2010/03/branching-strategies.html
    ... CVS y SVN estaban desalentando toda la estrategia de bifurcación / fusión ya que eran totalmente incapaces de hacerlo ... ... Regla simple: cree una rama de tarea para cada nueva característica o corrección de errores que implemente ... Puede sonar exagerado para los usuarios de SVN / CVS, pero sabe que cualquier SCM moderno le permitirá crear ramas en un segundo, por lo que no hay una sobrecarga real.  
     
    Nota importante: si lo miras detenidamente, verás que estoy hablando de usar ramas de tareas como listas de cambios para hombres ricos ...

  • http://publib.boulder.ibm.com/infocenter/cchelp/v7r0m1/index.jsp?topic=/com.ibm.rational.clearcase.cc_proj.doc/c_bntr_plnbrstrat.htm
    ... La política de ramificación está influenciada por el desarrollo objetivos del proyecto y proporciona un mecanismo para controlar la evolución de la base del código. Existen tantas variaciones de la política de ramificación como las organizaciones que usan el control de versiones de Rational ClearCase. Pero también hay similitudes que reflejan la adhesión común a las mejores prácticas ...

  • http://blogs.open.collab.net/svn/2007/11/branching-strat.html
    ... El modelo de Subversion (o modelo de código abierto general con mayor precisión) es lo que se muestra en el modelo de tronco inestable. .

  • http://en.wikipedia.org/wiki/Trunk_%28software%29
    En el campo del desarrollo de software, troncal se refiere a la rama (versión) sin nombre de un árbol de archivos bajo control de revisión . El tronco generalmente está destinado a ser la base de un proyecto en el que progresa el desarrollo. Si los desarrolladores están trabajando exclusivamente en el tronco, siempre contiene la última versión de vanguardia del proyecto, pero por lo tanto también puede ser la versión más inestable. Otro enfoque es dividir una rama del tronco, implementar cambios en esa rama y fusionar los cambios nuevamente en el tronco cuando la rama ha demostrado ser estable y funciona. Dependiendo del modo de desarrollo y commitLa política de la troncal puede contener la versión más estable o menos estable o algo intermedio.  
     
    A menudo, el trabajo principal del desarrollador se lleva a cabo en el tronco y las versiones estables se ramifican, y las correcciones de errores ocasionales se fusionan de las ramas al tronco. Cuando el desarrollo de versiones futuras se realiza en ramas que no son troncales, generalmente se realiza para proyectos que no cambian con frecuencia, o donde se espera que el cambio tarde mucho tiempo en desarrollarse hasta que esté listo para incorporarse en el tronco. .

  • http://www.mcqueeney.com/roller/page/tom/20060919
    ... Estas son notas de un seminario web sobre las mejores prácticas de Subversion , realizado el 30 de agosto de 2006 por CollabNet. ... Dos estrategias organizacionales: troncal inestable versus troncal estable ... ... PREFIERE una troncal inestable cuando sea posible ...

  • https://stackoverflow.com/questions/153812/subversion-is-trunk-really-the-best-place-for-the-main-development
    En SVN, trunk es el lugar recomendado para el desarrollo principal y utilizo esta convención para todos mis proyectos Sin embargo, esto significa que el tronco a veces es inestable, o incluso está roto ... ... ¿no sería mejor hacer el "desarrollo salvaje" en alguna rama como / branch / dev y solo fusionarse con el tronco cuando la construcción es razonable ¿sólido?

    • ... El tronco es donde se supone que sucederá el desarrollo continuo. Realmente no debería tener un problema con el código "roto", si todos están probando sus cambios antes de confirmarlos. Una buena regla general es hacer una actualización (obtener todo el código más reciente de los repositorios) después de haber codificado los cambios. Luego construya y haga algunas pruebas unitarias. Si todo funciona y funciona, debería ser bueno revisarlo ...
    • ... No, el baúl no es el mejor lugar. En nuestra organización siempre seguimos este enfoque: Trunk contiene código de lanzamiento, por lo que siempre se compila. Con cada nuevo lanzamiento / hito, abrimos una nueva sucursal. Cada vez que un desarrollador posee un artículo, crea una nueva rama para esta rama de lanzamiento y la fusiona en una rama de lanzamiento solo después de probarlo. La rama de liberación se fusiona con el tronco después de las pruebas del sistema ...
  • http://blog.yclian.com/2009/03/working-on-branches-and-stable-trunk.html
    ... Solía ​​trabajar en el tronco porque para todos los proyectos en los que trabajé, o bien estaba el único desarrollador o el equipo se aseguraron de que todos los registros de código hayan pasado las pruebas locales. De lo contrario, creamos (todavía) ramas para la corrección de errores, código grande para nuevas funciones, etc.  
     
    Hace aproximadamente 2 meses, tuve una breve sesión de git con Kamal y él compartió conmigo la idea de la historia / rama . Y a medida que mi equipo comenzó a crecer con más desarrolladores, siento la necesidad de alentar más ramificaciones y ahora esto se ha convertido en una regla. Para un proyecto con pruebas automatizadas definidas con la configuración de CI, se garantiza un tronco estable y esta práctica puede encajar muy bien en él.  
     
    No usamos git sino Subversion porque así es como comenzamos y todavía nos sentimos cómodos con él ahora (la mayoría de las veces) ...

  • http://www.ericsink.com/scm/scm_branches.html
    Esto es parte de un libro en línea llamado Source Control HOWTO , una guía de mejores prácticas sobre control de fuentes, control de versiones y gestión de la configuración ...  
     
    ... Ramificación preferida de Eric Practique ... Mantenga un tronco "básicamente inestable". Realice su desarrollo activo en el tronco, cuya estabilidad aumenta a medida que se acerca a la liberación. Después de enviar, cree una rama de mantenimiento y manténgala siempre muy estable ...  
     
    ... En el próximo capítulo profundizaré en el tema de la fusión de ramas ...

  • http://marc.info/?l=forrest-dev&m=112504297928196&w=2
    Correo inicial del hilo sobre estrategias de ramificación para el proyecto Apache Forrest

    • tenga en cuenta que actualmente el proyecto parece usar un modelo de tronco inestable con ramas de lanzamiento:
    • "El trabajo de desarrollo se realiza en el tronco de SVN ... Hay" ramas de liberación "de SVN, por ejemplo, forrest_07_branch". ( directrices del proyecto )
    • "Construyendo los paquetes candidatos de lanzamiento ... 17. Cree una rama de mantenimiento en SVN ..." ( Cómo liberar )
  • Documentos de ramificación de O'Reilly CVS:
    http://commons.oreilly.com/wiki/index.php/Essential_CVS/Using_CVS/Tagging_and_Branching#Basically_stable

    • ... La filosofía de ramificación básicamente estable establece que la troncal debe contener datos del proyecto que siempre estén cerca de estar listos para su lanzamiento ... ... Más variaciones indulgentes de esta filosofía permiten que cualquier cosa que pase la prueba de la unidad del desarrollador se fusione en el el maletero. Un enfoque tan relajado requiere que un candidato de lanzamiento sea ramificado y sometido a un análisis de control de calidad completo antes de la publicación ...
    • ... La filosofía básicamente inestable establece que el enlace troncal debería contener el código más reciente, independientemente de su estabilidad, y que los candidatos de lanzamiento deberían ser ramificados para el control de calidad.
       
       
      ... Más variaciones indulgentes también permiten la ramificación para código experimental, refactorización y otros códigos de casos especiales. La fusión de una rama nuevamente en el tronco es realizada por los gerentes de la rama. ...
      • Tenga en cuenta que el recurso anterior no apareció en ninguna de las búsquedas que realicé (¿las pautas relacionadas con CVS ya no son populares?)
  • Mejores prácticas en SCM (artículo de rendimiento) en
    http://www.perforce.com/perforce/papers/bestpractices.html
    ... seis áreas generales de implementación de SCM, y algunas mejores prácticas de grano grueso dentro de cada una de esas áreas. Los siguientes capítulos explican cada elemento ...
    Espacios de trabajo, líneas de código, ramificación, propagación de cambios, compilaciones, procesos ...


37
¡Creo que es la respuesta más larga que he visto en cualquier pregunta de intercambio de pila!
John Fisher

2
@JohnFisher bien según JIRA , en ese entonces pasé 6 horas compilando y resumiendo estas referencias :)
mosquito

2
Le falta algún tipo de resumen, que debería indicar si usar o no nuevas ramas para nuevas características. Su respuesta es solo una suma de enlaces a varios artículos: algunos dicen una cosa, mientras que otros dicen todo lo contrario. Tu respuesta es bastante larga, así que puede que me haya perdido.
B 8овић

3
El resumen de @BЈовић se proporciona al comienzo de la respuesta: 'no existe una "mejor" estrategia de ramificación comúnmente acordada aplicable a ningún proyecto. * La mayoría de los recursos parecen coincidir en que la elección de la estrategia productiva depende de las especificaciones particulares del proyecto
mosquito

2
Lectura complementaria: Desarrollo basado en troncales de Google vs Facebook "Ellos [Google y Facebook] no tienen problemas de fusión, porque por regla general los desarrolladores no se están fusionando hacia / desde las sucursales. Al menos hasta el servidor del repositorio central no lo están. En las estaciones de trabajo , los desarrolladores pueden estar fusionándose hacia / desde sucursales locales , y volver a emitir cuando empujan algo que está "hecho" de regreso al repositorio central ... "
mosquito

7

Si tiene varios equipos trabajando en diferentes funciones al mismo tiempo, no hay forma de que pueda omitir la ramificación. Debe compartir el código (parcialmente implementado) con los miembros del equipo, evitando que otros equipos obtengan sus funciones no terminadas.

Las ramas son la forma más fácil de lograrlo.

Aunque es bueno acortar el ciclo de vida de las ramas y evitar trabajar en el mismo módulo en dos ramas al mismo tiempo, entonces no tendrá problemas de conflicto / fusión.


5

Pero recientemente veo más y más seguidores de la idea de no hacer sucursales, ya que hace que sea más difícil practicar la integración continua, la entrega continua, etc.

Bueno, ¿te resulta más difícil practicar la integración continua, la entrega continua, etc. , concretamente?

Si no, no veo ninguna razón para cambiar su forma de trabajar.

Por supuesto, es una buena práctica seguir lo que está sucediendo y cómo evolucionan las mejores prácticas actuales. Pero no creo que debamos abandonar nuestros procesos / herramientas / otras cosas solo porque X (y / o Y y / o Z) dijeron que ya no son una moda :-)


¡Claro que lo hace! Es la cuestión de las prioridades: ramificación (aislamiento de características) vs. fácil integración, entrega, etc.
SiberianGuy

1
es solo una cuestión de herramienta CI que está utilizando. ¿Qué le impide hacer compilaciones y "entregar continuamente" desde una sucursal?
Shaddix

@ Shaddix, por lo general, es difícil entregar desde la sucursal. Por ejemplo, ¿cómo entregaría desde la rama de funciones?
SiberianGuy

1
¿Cuál es el problema si tiene todo el código fuente ramificado (como en DVCS)?
Shaddix

1
@Shaddix, cuanto más código haya ramificado, más conflictos tendrá durante la fusión
SiberianGuy

4

Qué conjunto de respuestas tan interesante. En más de 20 años, nunca he trabajado en una empresa que haya hecho más que un uso trivial de la ramificación (generalmente solo para lanzamientos de sucursales).

La mayoría de los lugares en los que he trabajado dependen de registros bastante rápidos y detección / resolución rápida de colisiones: la metodología ágil enseña que puede resolver los problemas más rápidamente si los nota mientras ambas partes están pensando activamente en ese código.

Por otro lado, no he usado mucho git y tal vez sea la inclusión de la etiqueta git lo que influyó en estas respuestas: entiendo que la rama / fusión se da con git porque es muy fácil.


2
+1, estos git'er dunns se están volviendo cada vez más fanáticos sobre la discutible superioridad de git sobre otras configuraciones de control de versiones / CI.
maple_shaft

3

Sí, debe usar ramas para aislar cualquier esfuerzo de desarrollo (al menos medio). Consulte "¿ Cuándo debe ramificarse? ".

El problema es más el uso de fusiones de avance rápido (que incluyen un historial de sucursal dentro de otro), siempre que elimine primero todas las "confirmaciones de puntos de control intermedios" (que pueden ser un problema en caso de reversión o git bisect).
Ver " La comprensión de flujo de trabajo Git ", con el fin de distinguir las ramas privadas (no destinado a ser empujado a) de las ramas públicas, que serán completados por fusiones ff (fusiones avance rápido) siempre que haga la limpieza necesaria dentro de la rama está fusionando .
Consulte también " ¿Por qué git usa la combinación de avance rápido de forma predeterminada? ".


2

Absolutamente deberías usar ramas. Hay una serie de puntos fuertes en eso.

  • Puede verificar su trabajo a medida que avanza si le preocupa perder el trabajo debido a una falla de HD, pérdida de computadora portátil, etc. y no romperá el CI principal.
  • Todavía puede hacer CI, solo configure su propio CI local para vigilar su sucursal.
  • Si la función se pone en espera de repente (eso nunca sucede), simplemente puede estacionarla.

Demasiado duro nunca es una excusa. Siempre toma más esfuerzo hacerlo bien.


2
Quiero desestimar esto no porque esté en contra de la ramificación, sino porque usted sugiere que deberían usarse TODO EL TIEMPO.
maple_shaft

¿Dónde dijo eso, lo editó o algo así?
b01

configure su propio CI local para vigilar su sucursal en busca de sucursales de corta duración (2-5 días) que podrían ser una sobrecarga. He estado allí hecho eso
mosquito

1
Estaba respondiendo a la pregunta de usar ramas en general o básicamente nunca usar ramas. Como con cualquier regla o política, el buen juicio debe entrar en juego. No colaboro en muchos de mis proyectos, pero sigo haciendo un uso liberal de las ramas principalmente para la tercera viñeta que mencioné. Además, en cuanto a la primera viñeta, ¿cuántas veces recibió una solicitud urgente para obtener alguna función / arreglo en vivo, pero luego ingresa y tiene aproximadamente 3 características a medio terminar en master.
Bill Leeper

Eso no está haciendo CI. I en CI defiende la integración, integrando el trabajo de todos los desarrolladores, es decir, la fusión. No hay nada de malo en ejecutar pruebas localmente para cada confirmación, pero eso es lo mismo.
bdsl

2

Si dos equipos trabajan en su propia sucursal, no verán los cambios del otro equipo, incluso si ambos integran la mastersucursal. Eso significaría que sus ramas de desarrollo se separarán y si uno de los equipos se fusiona con él master, el otro equipo tiene que modificar muchos cambios.

Por lo tanto, incluso si tiene sucursales para características, le recomiendo que haga 'backports' de todas las refactorizaciones a la rama maestra y mantenga la rama solo para nuevas características.

  • Refactorizaciones de backport

Creo que a veces podría ser más fácil usar los cambios de funciones para deshabilitar funciones nuevas y no probadas que aún no deberían entrar en producción. De esa manera, todos los demás equipos verán los cambios y no tendrá que ocurrir una fusión de Big Bang.

  • Usar interruptores de funciones

2

Acabamos de pasar por esto (nuevamente). Primero tuvimos todo el debate GIT / SVN, lo que nos llevó a estrategias de ramificación en general.

Todas las empresas más grandes utilizan una estrategia basada en troncales, donde todos trabajan en la misma sucursal, y las construcciones y la integración continua suceden desde esa sucursal. La prevención de conflictos se realiza mediante la modularización de código, el cambio de funciones y las herramientas inteligentes. Esto suena difícil ... porque lo es. Pero si está teniendo este debate es porque ha sido víctima de las fantasías de las personas sobre la ramificación. Algunos afirman que usan la herramienta de inserción SCM aquí con un mecanismo de ramificación de promoción totalmente compatible con sarbanes-oxley, y todo es brillante. Están mintiendo, engañándose a sí mismos o no están trabajando en la misma escala de sistema que usted.

Ramificar y fusionar es difícil. Especialmente si tiene un negocio que regularmente cambia de opinión y exige retrocesos, etc.

Esta oración puede salvarle la vida: ¡ Lo que está en el SCM no es lo mismo que lo que está en sus artefactos construidos!

Si tiene problemas con la ramificación es porque está haciendo un mal uso de su SCM. Todos lo hemos estado haciendo por años. Tiene un sistema en el lugar donde se utiliza el SCM para determinar qué se incluye en su compilación final.

Ese no es el trabajo de la SCM. El SCM es un servidor de archivos glorificado. El trabajo de determinar qué archivos de su SCM van a su compilación pertenece a sus herramientas de compilación.

Se está trabajando en el Módulo A y entra en su versión semanal. El módulo B es el módulo A, pero con el proyecto X, y se está trabajando en la misma rama, pero no se está incorporando en su versión. En algún momento en el futuro, desea lanzar el proyecto X. Entonces le dice a su herramienta de compilación que deje de instalar el módulo A y comience a instalar el módulo B.

Habrá mucho llanto y retorcimientos de manos sobre esto. Qué iffery y aullidos generales. Tal es el nivel de emoción que rodea a algo tan simple como un repositorio de archivos, no importa cuán inteligente sea.

Pero ahí está tu respuesta.


1

El principal problema con la ramificación es la dificultad de volver a fusionarse en la rama principal cuando se completa el desarrollo. La fusión puede ser un proceso manual y propenso a errores, por lo tanto, debe evitarse la mayor parte del tiempo.

Algunas excepciones notables en las que prefiero la ramificación son para la refactorización masiva, características gigantes que tardan más que un sprint en desarrollarse, o características disruptivas que interrumpirían el desarrollo de otras características durante la mayoría de ese sprint.


44
Parece que necesita una mejor práctica para desarrollar nuevas funciones. Personalmente, me gusta construir mis proyectos para que sea fácil aislar características, generalmente en un archivo / clase / o lo que sea. De esa manera, agregar o eliminar código no causa interrupciones importantes en la entrega o problemas al fusionar un nuevo código o al extraer un código antiguo. Esto funciona bien cuando se desarrolla con múltiples desarrolladores también. Pero puedo entender si está trabajando en un proyecto que puede no haber sido iniciado por usted, o no tiene una opinión real sobre cómo continúa el proyecto.
b01

1
@ b01, eso es bastante acertado. Nadie puede encontrar el diseño perfecto cuando los requisitos van y vienen y cambian más rápido que un niño con TDAH en crack. Otras veces terminas tratando de refactorizar el código heredado para mejorar el diseño y esta situación surge de vez en cuando. No es el peor problema que puede tener un equipo, y es mucho mejor que algunos lugares en los que trabajé, donde incluso sugiriendo refactorizar en una reunión te hará morir a golpes con un bate de béisbol como una escena de The Untouchables.
maple_shaft

Totalmente en desacuerdo. Si se divide por ramas de calidad y se fusiona con frecuencia (diariamente es bueno), entonces evita casi todas las fusiones "manuales y propensas a errores".
Paul Nathan

@Paul, confía en mí que no funciona para todos los proyectos o tecnologías. Piense en un archivo de configuración XML común como en Struts, donde todos están metiendo sus manos todos los días. Pero no, tu camino funciona todo el tiempo y merecía totalmente el voto negativo. Gracias.
maple_shaft

1
@maple_shaft meta-sugerencia, si considera las etiquetas (git) y publica algo que el usuario típico de esas etiquetas consideraría negativo, espere votos negativos de sobrevuelo. Los sobrevuelos son casi siempre una reacción injustificada a ser lastimados por algún comentario que tomas personalmente. Considéralo bueno porque aumenta tu reputación a través del techo.
Bill K

1

Recomiendo este tipo de esquema de sucursal:

lanzamiento - prueba - desarrollo

Luego, desde el desarrollo, ramificado por desarrollador y / o por característica.

Cada uno de los desarrolladores tiene una rama con la que jugar, y se fusiona desde, y luego, con la rama de desarrollo de manera rutinaria, idealmente todos los días (siempre que se compile).

Este tipo de esquema funciona muy bien con muchos desarrolladores y múltiples proyectos en la misma base de código.


0

Nosotros hacemos uso de ramas, pero no a nivel granular de la función. Usamos ramas para cada sprint. En esencia, ramificar no es algo malo en la OMI, ya que simula el concepto de SOC en la función, o capa de sprint. Puede reconocer y administrar fácilmente qué rama pertenece a qué característica o sprint.

En mi humilde opinión, a continuación, responder es, . Aún deberíamos usar ramificaciones.


0

El proceso en mi organización hace un uso extensivo de sucursales y (un proceso que se parece un poco) a la integración continua.

En una vista de alto nivel, los desarrolladores no se preocupan demasiado por fusionarse con la línea principal, solo se comprometen con la rama. un proceso (semi) automatizado verifica qué características están programadas para entrar en la línea principal, fusiona esas ramas y construye el producto. El proceso funciona porque en realidad integramos este proceso de fusión desde el rastreador de problemas, para que la herramienta de compilación sepa qué ramas fusionar.


Parece que este proceso se interrumpirá si un desarrollador ha refactorizado algún código preexistente en una rama, y ​​un desarrollador en una rama separada ha escrito algo que se basa en la versión anterior del código.
bdsl

@bdsl: ese es un problema que puede surgir en cualquier estrategia de ramificación (incluida la no ramificación), siempre que tenga varios desarrolladores en la misma base de código. en esa organización (desde entonces me mudé), éramos un equipo lo suficientemente pequeño como para que todos tuviéramos una idea bastante buena de lo que estábamos haciendo los demás, por lo que nos advertíamos mutuamente cuando era probable que algunos de nuestros cambios fueran en conflicto. En cualquier caso, la integración continua ayudó muchísimo a detectar este tipo de problemas en cuestión de minutos u horas después de la introducción del conflicto.
SingleNegationElimination

Sí, pero parece mucho menos probable si la refactorización se fusiona con la línea principal el mismo día en que se realizó, en lugar de esperar hasta que una nueva característica esté lista.
bdsl

@bdsl eso no siempre es una opción; Es posible que necesite una "rama buena y que funcione" en todo momento, por ejemplo, para enviar correcciones de errores de emergencia. Sin embargo, la técnica alternativa, fusionar la línea principal en la función de forma regular, suele ser A-OK, y mi recomendación fuerte no importa cuál sea su estrategia de ramificación.
SingleNegationElimination
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.