2008-10-14 19 views
21

Nuestra política al entregar una nueva versión es crear una rama en nuestro VCS y manejarla a nuestro equipo de control de calidad. Cuando este último da luz verde, etiquetamos y lanzamos nuestro producto. La rama se mantiene para recibir (solo) correcciones de errores para que podamos crear versiones técnicas. Esas correcciones de errores se fusionaron posteriormente en el tronco.¿Cómo maneja la tensión entre la refactorización y la necesidad de fusionarse?

Durante este tiempo, el tronco ve el trabajo de desarrollo principal y está potencialmente sujeto a cambios de refactorización.

El problema es que hay una tensión entre la necesidad de tener un tronco estable (para que la combinación de correcciones de errores tenga éxito - por lo general no puede si el código ha sido extraído a otro método o movido a otra clase) y la necesidad de refactorizarlo al introducir nuevas funciones.

La política en nuestro lugar es no hacer ninguna refactorización antes de que pase suficiente tiempo y la rama sea lo suficientemente estable. Cuando este es el caso, uno puede comenzar a hacer cambios de refactorización en el tronco, y las correcciones de errores se deben confirmar manualmente tanto en el tronco como en la rama.

Pero esto significa que los desarrolladores deben esperar bastante tiempo antes de comprometerse en el tronco cualquier cambio de refactorización, ya que esto podría romper la fusión posterior de la rama al tronco. Y tener que portar manualmente errores de la rama al tronco es doloroso. Me parece que esto dificulta el desarrollo ...

¿Cómo manejas esta tensión?

Gracias.

Respuesta

14

Esto es un problema real. Empeora si tiene varias versiones que necesita admitir y ha ramificado para cada una. Incluso peor si tiene una rama R R genuina R & también.

Mi preferencia era permitir que la troncal principal proceda a su velocidad normal y no esperar porque en un entorno donde los tiempos de liberación eran importantes comercialmente, nunca podría argumentar que deberíamos permitir que el código se estabilice ("qué , ¿quieres decir que lo liberó en un estado inestable? ").

La clave era asegurarse de que las pruebas unitarias que se crearon para las correcciones de errores se transfirieron cuando el error se migró a la rama principal. Si los cambios de su nuevo código son simplemente re-factoring, entonces las pruebas antiguas deberían funcionar igual de bien. Si los cambios son tales que ya no son válidos, entonces no se puede simplemente arreglar el puerto en ningún caso, y deberá pedirle a alguien que reflexione sobre la solución en el nuevo flujo de código.

Después de unos años gestionando este tipo de problema, llegué a la conclusión de que probablemente necesite 4 secuencias de código como mínimo para proporcionar soporte y cobertura adecuados, y una colección de procesos bastante rigurosos para administrar el código entre ellos. Es un poco como el problema de poder dibujar cualquier mapa en 4 colores.

Nunca encontré literatura realmente buena sobre este tema. Inevitablemente estará vinculado a su estrategia de lanzamiento y a los SLA que firma con sus clientes.

Adición: También debo mencionar que era necesario escribir la fusión de sucursales como hitos específicos en el cronograma de publicación de la rama principal. No subestime la cantidad de trabajo que podría implicar unir sus sucursales si tiene una colección de desarrolladores trabajadores que realizan las funciones de implementación de su trabajo.

0

Donde trabajo, nos mantenemos con la refactorización en la rama principal.Si las fusiones se vuelven complicadas, solo tienen que tratarse de manera ad-hoc, todas son factibles, pero ocasionalmente toman un poco de tiempo.

0

Tal vez nuestro problema proviene del hecho de que tenemos ramas que deben tener una vida bastante larga (hasta 18 meses), y hay muchas soluciones que hay que hacer contra ellas.

Asegurarse de que sólo se ramifican a partir de código extremadamente estable, probablemente ayudará, pero no será tan fácil ... :(

+0

Eh, esto no es ni siquiera una respuesta, por no hablar de la respuesta ... – Benjol

1

creo que la tensión puede ser manejado mediante la adición de ingredientes siguientes a su proceso de desarrollo:

  1. integración continua
  2. pruebas funcionales automatizadas (supongo que ya cuentan con pruebas unitarias)
  3. entrega automatizada

Con la integración continua, cada compromiso implica una compilación donde se ejecutan todas las pruebas de la unidad y se alarma si algo sale mal. Empieza a trabajar más con head y es menos propenso a la bifurcación de la base de código.

Con pruebas funcionales automatizadas, puede probar su aplicación con tan solo hacer clic en el botón. Generalmente, dado que estas pruebas toman más tiempo, se realizan todas las noches. Con esto, el rol clásico del control de versiones comienza a perder importancia. Usted no toma la decisión sobre cuándo lanzar según la versión y su vencimiento, sino que es más una decisión comercial. Si ha implementado las pruebas unitarias y funcionales y su equipo está presentando el código probado, la cabeza siempre debe estar en un estado que pueda liberarse. Los errores son continuamente descubiertos y corregidos y lanzados entregados, pero este no es más un proceso cíclico, sino continuo.

Probablemente tenga dos tipos de detractores, ya que esto implica cambiar algunas prácticas arraigadas desde hace mucho tiempo. En primer lugar, el cambio de paradigma de la entrega continua parece contraintuitivo para los gerentes. "¿No nos arriesgamos a enviar un error importante?" Si echas un vistazo a las distribuciones de Linux o Windows, esto es exactamente lo que están haciendo: empujar lanzamientos hacia los clientes. Y dado que cuenta con un conjunto de pruebas automatizadas, los peligros disminuyen aún más.

A continuación, equipo o departamento de QA. (¡Algunos argumentarían que el problema es su existencia en sí misma!) En general, serán reacios a automatizar las pruebas. Significa aprender una herramienta nueva y, a veces, complicada. Aquí, lo mejor es predicar haciéndolo. Nuestro equipo de desarrollo comenzó a trabajar en integraciones continuas y, al mismo tiempo, redactó el conjunto de pruebas funcionales con Selenium. Cuando el equipo de QA vio la herramienta en acción, fue difícil oponerse a su implementación.

Finalmente, el paso es que el proceso que describí no es tan simple como agregar 3 ingredientes a su proceso de desarrollo. Implica un cambio profundo en la forma en que desarrolla el software.

+0

Estoy de acuerdo con sus tres elementos, pero no creo que ayudan por mi preocupación ... Me preocupa la dificultad de fusionar los cambios en una línea de desarrollo que sufre grandes cambios de refactorización: estos cambios conducen a muchos conflictos ... :( –

+0

La idea detrás de la integración continua es realizar refactorizaciones en pequeños pasos y para integrarse continuamente. De esta forma, se mitigan algunos de los problemas. Dependiendo del diseño de su código, aún podría terminar con cambios de frenado de gran alcance. Refactor para reducir primero las dependencias. – Dan

5

Donde trabajo, creamos ramas de trabajo temporales, breves (menos de un día - algunas semanas) por cada cambio no trivial (función agregar o corrección de errores). El tronco es estable e (idealmente) potencialmente liberable todo el tiempo; solo hecho elementos se fusionaron en él. Todo lo que se compromete desde el tronco se fusiona en las ramas de trabajo todos los días; esto se puede automatizar en gran medida (usamos Hudson, Ant y Subversion). (Este último punto porque generalmente es mejor resolver cualquier conflicto más pronto que tarde, por supuesto).)

El modelo actual que utilizamos fue influenciado en gran medida por un excelente artículo (which I've plugged before) por Henrik Kniberg: Version Control for Multiple Agile Teams.

(En nuestro caso, tenemos dos equipos de scrum trabajando en una base de código, pero hemos llegado a pensar que este modelo puede ser beneficioso incluso con un equipo.)

Hay algo de sobrecarga sobre la ramificación adicional y fusionarse, pero no demasiado, en realidad, una vez que te acostumbras y mejoras con las herramientas (por ejemplo, svn merge --reintegrate es útil). Y no, no creo una rama temporal siempre, p. para refactorizaciones más pequeñas y de bajo riesgo (sin relación con los elementos principales que actualmente están en funcionamiento) que pueden completarse fácilmente con una confirmación en el enlace troncal.

También mantenemos una rama de versión anterior en la que se reparan errores críticos de vez en cuando. Es cierto que puede haber trabajo de fusión manual (a veces tedioso) si alguna parte particular del código ha evolucionado significativamente en el tronco en comparación con la rama. (Es de esperar que se convierta en un problema menor a medida que avanzamos hacia la liberación continua de incrementos desde el tronco (internamente) y dejando que el marketing & decida cuándo quieren hacer una versión externa.)

No estoy seguro de que esto responda su pregunta directamente, o si puede aplicar esto en su entorno (con el equipo de control de calidad separado y todo), pero al menos puedo decir que la tensión que describe no existe para nosotros y somos libres de refactorizar cada vez que lo hagamos. ¡Buena suerte!

1

Tal Git (u otro DVCS) son mejores en el manejo une a códigos actualizadas gracias al hecho de que (realmente) gestionar los cambios en lugar de comparar los archivos ... Como Joel says:

Con la versión distribuida control, las fusiones son fáciles y funcionan bien. Así que puede tener una sucursal estable y una sucursal de desarrollo, o crear sucursales de larga duración para su equipo de control de calidad, donde prueban cosas antes de la implementación, o puede crear sucursales efímeras para probar nuevas ideas y ver cómo funcionan.

no se ha probado todavía, aunque ...

+0

Los cambios de refactorización a menudo son t El tipo de cambios que no pueden fusionarse automáticamente, incluso con DVCS. (Por ejemplo, si una persona cambia la firma de un método en una rama, y ​​otra mueve el método en una segunda rama, y ​​otra persona arregla algo en un nivel diferente para eliminar por completo la necesidad del método). Usar DVCS disminuirá. los problemas, pero no eliminarlos por completo. – Ken

Cuestiones relacionadas