Pregunta

Esta mañana, leí dos opiniones sobre refactorización.

  • Opinión 1 (página no presente)
  • Opinión 2 (página no presente)

Recomiendan el código de bifurcación (y luego la fusión) para:

  1. Mantenga limpio el baúl.
  2. Permitir que un desarrollador se aleje de los cambios riesgosos.

En mi experiencia (particularmente con StarTeam de Borland), la fusión es una operación no trival. Y por esa razón, me bifurco solo cuando debo (es decir, cuando quiero congelar un candidato de liberación).

En teoría, la ramificación tiene sentido, pero los mecanismos de fusión hacen que sea una operación muy arriesgada.

Mis preguntas:

  
      
  • ¿Te sientes cómodo fusionando código?
  •   
  • ¿Ramifica el código por razones distintas a la congelación de un lanzamiento?   candidato?
  •   
¿Fue útil?

Solución

Algunos principios rectores sueltos:

  • Sucede tarde y solo cuando necesitas
  • Combinar temprano y con frecuencia
  • Haga que la persona adecuada realice la fusión, ya sea que la persona que realizó los cambios o la persona que escribió la versión original sean las mejores

La ramificación es solo otra herramienta, necesita aprender a usarla de manera efectiva si desea obtener el máximo beneficio.

Su actitud hacia las sucursales probablemente debería diferir entre los proyectos de código abierto distribuidos (como los de Git) y los proyectos de desarrollo de su compañía (posiblemente ejecutándose en SVN). Para los proyectos distribuidos, querrá alentar la ramificación para maximizar la innovación y la experimentación, para la última variedad querrá un control más estricto y dictar políticas de registro para cada línea de código que dicta cuándo se debe o no la bifurcación, principalmente para "proteger" y "proteger" ; el código.

Aquí hay una guía de ramificación:
http://www.vance.com/steve/perforce/Branching_Strategies.html

Aquí hay una guía más corta con algunas prácticas recomendadas de alto nivel:
https: //www.perforce. com / sites / default / files / pdf / high-level-perforce-best-practice.pdf

Otros consejos

La ramificación puede ser dolorosa, pero no debería ser.

Eso es lo que los proyectos similares a git (mercurial, bazar) nos dicen sobre CVS y SVN. En git y mercurial, la ramificación es fácil. En SVN es fácil, pero con grandes proyectos puede ser un poco difícil de administrar (debido al tiempo empleado en el proceso de bifurcación / fusión que puede ser muy largo, en comparación con otros como git y mercurial) y difícil si no hay -los conflictos obvios). Eso no ayuda a los usuarios que no están acostumbrados a bifurcar a menudo a tener confianza en la bifurcación. Muchos usuarios que no conocen los poderosos usos de las ramificaciones, simplemente lo mantienen alejado para no agregar nuevos problemas a sus proyectos, dejando que el miedo a lo desconocido los aleje de la eficiencia.

La ramificación debería ser una herramienta fácil y poderosa que tendríamos que usar por cualquier motivo lo suficientemente bueno como para ramificar.

Algunas buenas razones para las sucursales:

  • trabajar en una función específica en paralelo con otras personas (o mientras trabaja en otras funciones alternativamente si está solo en el proyecto);
  • tener varias versiones de marca de la aplicación;
  • tener versiones paralelas de la misma aplicación, como técnicas concurrentes desarrolladas al mismo tiempo por parte del equipo para ver qué funciona mejor;
  • tener recursos de la aplicación que se está cambiando en un artista / diseñador (por ejemplo en juegos) rama específica donde la aplicación es estable " mientras que otras ramas y troncales se usan para la adición y depuración de funciones;
  • [agregar aquí usos útiles]

La ramificación es trivial. La fusión no es. Por esa razón, rara vez ramificamos algo.

Usando SVN, encontré que la ramificación es relativamente indolora. Especialmente si periódicamente fusionas el tronco en tu rama para evitar que se desincronice demasiado.

Usamos svn. Solo nos lleva unos 5 minutos llegar al código de sucursal. Es trivial en comparación con la cantidad de dolor que nos ahorra al arruinar el maletero.

Trabajar en una base de código de millones de líneas de código con cientos de desarrolladores que se ramifican es algo cotidiano. La vida útil de la sucursal varía según la cantidad de trabajo que se realice.

Para una pequeña corrección:

  • el diseñador hace un sidebranch fuera de la corriente principal
  • hace cambios
  • pruebas
  • comentarios
  • fusiona los cambios acumulados de la transmisión principal al sidebranch
  • itera a través de uno o más de los pasos anteriores
  • se fusiona de nuevo a la corriente principal

Para una función de equipo de varias personas:

  • el equipo hace que una característica salga de la corriente principal
  • el miembro del equipo individual opera en la característica de lado como en " pequeña solución " Enfoque y se fusiona para presentar a sidebranch.
  • sidebranch prime periódicamente combina los cambios acumulados de la transmisión principal a la característica de sidebranch. Es mucho más fácil lidiar con pequeñas combinaciones incrementales de la corriente principal a la característica de la banca lateral.
  • cuando la característica funciona, haga una fusión final de la transmisión principal a la característica de la barra lateral
  • fusionar la característica de la barra lateral a la transmisión principal

Para una versión de software del cliente:

  • hacer una rama de lanzamiento
  • entregar arreglos según sea necesario para liberar la rama
  • las correcciones se propagan a / desde la transmisión principal según sea necesario

Las secuencias de lanzamiento del cliente pueden ser muy caras de soportar. Requiere recursos de prueba - personas y equipo. Después de un año o dos, el conocimiento del desarrollador sobre secuencias específicas comienza a ser obsoleto a medida que la corriente principal avanza.

¿Te imaginas cuánto debe costarle a Microsoft admitir XP, Vista y Windows 7 simultáneamente? Piense en los bancos de pruebas, la administración, la documentación, el servicio al cliente y, finalmente, los equipos de desarrolladores.

Regla de oro: Nunca rompe la corriente principal, ya que puedes detener a un gran número de desarrolladores. $$$

El problema de la bifurcación es el motivo por el que utilizo un sistema de control de versiones distribuidas (Git en mi caso, pero también hay Mercurial y Bazaar) donde crear una bifurcación es trivial.

Uso ramas de corta duración todo el tiempo para el desarrollo. Esto me permite meterme en mi propio repositorio, cometer errores y tomar malas decisiones, y luego rebase los cambios en la rama principal para que solo queden en el historial los cambios limpios.

Uso tag s para marcar el código congelado, y en estos sistemas es fácil retroceder y ramificarse para corregir errores sin tener una carga de sucursales de larga duración en el código base.

Utilizo Subversion y considero que la ramificación es muy simple y fácil. Así que para responder a la pregunta 1 ... Sí.

El motivo de la bifurcación puede variar enormemente. Me ramifico si siento que debería. Bastante difícil de poner reglas y razones para todas las posibilidades.

Sin embargo, en la medida en que " Permitir que un desarrollador se aleje de los cambios riesgosos " comentario. Estoy totalmente de acuerdo con eso. Creo una rama cuando quiero jugar realmente con el código y desearía ser el único desarrollador que trabaja en él. Cuando se ramifica, puedes hacer eso ...

He estado en un proyecto usando svn y TFS y la bifurcación por sí misma es una cosa realmente simple.

Utilizamos ramificaciones para el lanzamiento de candidaturas, así como para funciones experimentales y de larga duración y para aislarnos de las interferencias de otros equipos.

El único momento doloroso en la ramificación es la fusión, porque una rama antigua o muy desarrollada puede diferir mucho del tronco y puede requerir un esfuerzo significativo para fusionarse.

Habiendo dicho lo anterior, diría que la ramificación es una práctica poderosa y útil que debe tenerse en cuenta al desarrollar.

Si la fusión es demasiado dolorosa, considere migrar a un mejor VCS. Será un dolor más grande, pero solo una vez.

Usamos svn y hemos adoptado una regla para dividir los cambios de ruptura. Los cambios menores se hacen directamente en el tronco.

También filtramos lanzamientos.

La ramificación y la fusión nos han funcionado bien. Por supuesto, hay ocasiones en las que tenemos que sentarnos y pensar cómo encajan las cosas, pero por lo general, svn hace un gran trabajo al fusionar todo.

Utilizo svn, se tarda menos de un minuto en derivar el código. Solía ??usar Clearcase, tardaba menos de un minuto en codificar una sucursal. También he usado otros SCM más pequeños y no soportaban las ramas o eran demasiado dolorosos de usar. Starteam suena como el último.

Entonces, si no puede migrar a uno más útil (en realidad, solo he escuchado cosas malas sobre Starteam), es posible que tenga que probar un enfoque diferente: bifurcación manual. Esto implica revisar su código, copiarlo en un directorio diferente y luego agregarlo como un nuevo directorio. Cuando necesite fusionar, compruebe ambos directorios y use WinMerge para realizar la combinación, registrando los resultados en el directorio original. Incómodo y potencialmente difícil si continúas usando la rama, pero funciona.

el truco con Branching es no tratarlo como un producto completamente nuevo. Es una rama: un dispositivo de vida relativamente corta que se utiliza para realizar cambios por separado y de manera segura en la caja principal del producto. Cualquiera que piense que fusionar es difícil es refactorizar tanto los archivos de código (es decir, cambiar el nombre, copiar, crear nuevos, eliminar antiguos) que la rama se convierte en algo completamente diferente, o mantener la rama tanto tiempo que los cambios acumulados pueden soportar poco parecido al original. Puede mantener una sucursal durante mucho tiempo, solo tiene que fusionar sus cambios regularmente. Haga esto y la ramificación / fusión se vuelve muy fácil.

Sólo lo he hecho un par de veces, por lo que no estoy exactamente cómodo con él.

Lo he hecho para realizar experimentos de diseño que abarcarían algunos registros, por lo que la ramificación es una forma fácil de construir un jardín para jugar. Además, me permitió jugar mientras otras personas trabajaban en la rama principal , así que no perdimos mucho tiempo.

También lo he hecho al realizar cambios de amplio rango que harían que el tronco no sea compilable. Quedó claro en mi proyecto que tendría que eliminar la seguridad de tipo de tiempo de compilación para una gran parte de la base de código (ir de genéricos a system.object). Sabía que esto llevaría un tiempo y requeriría cambios en todo el código base que interfiriera con el trabajo de otras personas. También rompería la construcción hasta que estuviera completo. Así que ramifiqué y eliminé los genéricos, trabajando hasta compilar esa rama. Luego lo fusioné de nuevo en el maletero.

Esto resultó bastante bien. Evitó muchos pasos, lo cual fue genial. Esperemos que nada como esto vuelva a surgir. Es algo raro que un diseño cambie y requiera este tipo de ediciones de amplio rango que no den como resultado que se elimine mucho código ...

Las ramas deben gestionarse correctamente para que la fusión sea indolora. En mi experiencia (con Perforce), la integración regular a la sucursal desde la línea principal significó que la integración nuevamente en la línea principal fue muy fácil.

Solo hubo raras ocasiones en las que falló la fusión. La integración constante de la línea principal a la sucursal puede haber involucrado fusiones, pero solo fueron de pequeñas ediciones que las herramientas automáticas podrían manejar sin intervención humana. Esto significaba que el usuario no había " ver " esto está sucediendo.

Por lo tanto, cualquier fusión requerida en la integración final a menudo también podría manejarse automáticamente.

Las herramientas de combinación de 3 vías de Perforces fueron de gran ayuda cuando realmente se necesitaban.

  

¿Se siente cómodo con el código de bifurcación?

Realmente depende de la herramienta que esté usando. Con Starteam, la ramificación es de hecho no trivial (TBH, Starteam apesta en la ramificación). Con Git, la ramificación es una actividad regular y es muy fácil.

  

¿Ramifica el código por razones distintas a la congelación de un candidato de lanzamiento?

Bueno, esto realmente depende de tu patrón de control de versión, pero la respuesta corta es sí. En realidad, sugiero leer los siguientes artículos:

Me gusta mucho el patrón descrito en el primer artículo y se puede aplicar con cualquier Sistema de control de versiones (no distribuido), incluido Starteam.

Podría considerar el segundo enfoque (en realidad, una combinación de ambas estrategias) con (y solo con) un Sistema de control de versiones distribuido (DVCS) como Git, Mercurial ...

Utilizamos StarTeam y solo nos ramificamos cuando tenemos una situación que lo requiere (es decir, una revisión de la producción durante el ciclo de lanzamiento o algún proyecto de largo alcance que abarque varias ventanas de lanzamiento). Utilizamos etiquetas de vista para identificar lanzamientos y eso hace que sea sencillo crear sucursales más tarde según sea necesario. Todas las compilaciones se basan en estas etiquetas de vista y no compilamos código no etiquetado.

Los desarrolladores deben seguir un " código - prueba - confirmar " modelo y si necesitan una vista para algún propósito de prueba o " riesgoso " El desarrollo lo crean y lo gestionan. Administro el repositorio y creo sucursales solo cuando las necesitamos. Esos tiempos son (pero no se limitan a):

  • Hotfix de producción
  • Proyectos con ciclos de desarrollo largos o superpuestos
  • Reescritura extensa o desarrollo experimental

La herramienta de combinación en StarTeam no es la mejor, pero todavía tengo que encontrar un problema causado por ella. Quienquiera que haga la fusión solo necesita estar MUY seguro de que sabe lo que está haciendo.

Creando una " Referencia de solo lectura " Ver en Star Team y establecerlo en una configuración flotante permitirá que los cambios en el troncal se muestren automáticamente en la rama. Establecer elementos para ramificar en el cambio. Esto es bueno para los esfuerzos de desarrollo concurrente.

Creando una " Referencia de solo lectura " ver con una configuración etiquetada es lo que usaría para las correcciones de las versiones de producción existentes (suponiendo que las haya etiquetado).

La ramificación es trivial, como la mayoría ha respondido, pero la fusión, como usted dice, no lo es.

Las claves reales son desacoplamiento y pruebas unitarias. Intente desacoplar antes de su rama, y ??vigile la red principal para asegurarse de que se mantengan el desacoplamiento y la interfaz. De esa manera, cuando llega el momento de fusionarse, es como reemplazar una pieza de lego: retire la pieza antigua y la nueva pieza encaja perfectamente en su lugar. Las pruebas unitarias están ahí para garantizar que no se rompa nada.

La ramificación y la fusión deben ser bastante sencillas.

  • Me siento muy cómodo bifurcándome / fusionándome.
  • La bifurcación se realiza por diferentes motivos, según el modelo de su proceso de desarrollo /

Hay algunos modelos de ramas diferentes:

Aquí hay uno

  Trunk          
  .      
  .      
  .      
  ..         
  . ....     
  .   ...
  .      ..Release1
  .      
  .      
  ...        
  .  .... 
  .    ...Release2
  .      
  .      
  ..         
  . ...  
  .  .. 
  .    ...Release3
  .      
  .      

Aquí hay algo curioso. Supongamos que Release1 necesitaba algunas correcciones de errores. Ahora necesitas la versión Release1 para desarrollar 1.1. Eso está bien, porque ahora puede bifurcar R1, hacer su trabajo y luego fusionarse nuevamente con R1 para formar R1.1. ¿Observe cómo esto mantiene las diferencias entre los lanzamientos?

Otro modelo de bifurcación es tener todo el desarrollo realizado en el Troncal, y cada versión se etiqueta, pero no se realiza ningún desarrollo adicional en esa versión en particular. Suceden ramas para el desarrollo.

  Trunk                                           
  .                                                         
  .                                                         
  .                                                         
  .Release1           
  .                       
  .                       
  .                   
  .                   
  .Release2           
  .                   
  .......                 
  .      ......       
  .           ...DevVer1
  .          .    
  .          .            
  .        ...DevVer2
  .      ....         
  .  ....             
  ...                     
  .Release3           
      .

Puede que haya uno o dos modelos de otras ramas principales, no puedo recordarlos de la cabeza.

La conclusión es que su VCS debe ser compatible con la creación de sucursales y combinaciones flexibles. Los sistemas VCS por archivo presentan una gran IMO (RCS, Clearcase, CVS). SVN se dice que es una molestia aquí también, no estoy seguro de por qué.

Mercurial hace un gran trabajo aquí, al igual que (creo) git.

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