Detener a los desarrolladores que se comprometen con la rama incorrecta en DVCS


12

El problema

Estoy en un proyecto de software que tiene unos 10 desarrolladores, compartimos el código fuente a través de Mercurial. Tenemos una rama de desarrollo y producción por lanzamiento. Repetidamente durante el curso del proyecto, hemos tenido código fuente de una rama, es decir, v1, entrando en parches y ramas de mantenimiento para versiones anteriores de software, es decir, v2.

Esto da como resultado que se dedique el tiempo de retroceso al commit incorrecto o que el código incorrecto (posiblemente no QAd) llegue y se implemente en la rama incorrecta si no notamos que el código ha entrado en la rama incorrecta.

Nuestro diseño / método de sucursal y combinación

               v1-test   v1-patch1   v1-patch2
               ^---------^-----------^                v1-prod
              /         / \           \
-----------------------/   \           \              v1-dev
              \             \           \
               --------------------------\            v2-dev
                             \       \    \ 
                              ^-------^-------------  v2-prod
                              v2-test v2-patch1      

Por lo tanto, trabajaremos en una rama de desarrollo de lanzamiento, hasta que se considere lista , bifurque para una sola rama de prueba / UAT / Producción, donde se realizan todos los lanzamientos y mantenimiento. Las etiquetas se utilizan para crear versiones de esta rama. Mientras se prueba v1, se creará una rama para v2 y los desarrolladores comenzarán a trabajar en nuevas características.

Lo que suele suceder es que un desarrollador compromete el trabajo debido a v2-dev branch en v1-dev o v1-prod, o peor aún, fusionan v2-dev en v1-prod (o errores similares).

Le decimos a la mayoría de los desarrolladores que no accedan a las ramas -prod , sin embargo, el código todavía se cuela. Un grupo de desarrolladores más senior 'cuida' la rama -prod.

Cabe señalar que, si bien v2 acaba de comenzar el desarrollo, es posible que todavía haya algunos parches bastante fuertes en v1 para solucionar problemas. Es decir, v1 puede no solo estar recibiendo un parche pequeño e impar.

Lo que hemos intentado hasta ahora

  • Tener una rama de producto separada, con porteros. Una rama -prod debería generar advertencias a través de su nombre y la mayoría de los desarrolladores no necesitan estar en esa rama. Esto realmente no ha reducido el problema.
  • Creó la conciencia de este problema entre los desarrolladores, para tratar de hacerlos más vigilantes. Nuevamente, esto no ha sido muy exitoso.

Posibles razones que veo para los desarrolladores que se comprometen con la rama incorrecta

  • Un diseño de sucursal demasiado complejo
  • Tener desarrollo activo en múltiples ramas en paralelo. (El proyecto exhibe síntomas de uso del modelo de avalancha ).
  • Los desarrolladores no entienden el DVCS lo suficientemente bien

Preguntas que he leído que fueron algo relevantes

He leído esta pregunta sobre no comprometerse con la rama equivocada y creo que las respuestas con respecto a las señales visuales pueden ser útiles. Sin embargo, no estoy completamente convencido de que los problemas que estamos experimentando no sean síntomas de un problema más fundamental.

Con las pistas visuales, podemos incorporarlas fácilmente en la línea de comando, sin embargo, aproximadamente la mitad del equipo usa eclipse, lo que no estoy seguro de cómo incorporar señales visuales.

Pregunta

¿Qué métodos, en forma de software, gestión de proyectos o gobernanza, podemos usar para reducir (idealmente) los compromisos con la sucursal equivocada que toma nuestro tiempo o ensucia nuestro código implementado?

Se agradecería un comentario específico sobre las razones que creo que pueden estar contribuyendo como se describe anteriormente, pero esto no debería limitar su respuesta.


16
Estás tratando de encontrar una solución técnica a un problema social. Si cree que el problema es que no entienden el DVCS, dedique tiempo a capacitar a su personal; a la larga, dará sus frutos si tiene que perder constantemente el tiempo arreglando fusiones / compromisos incorrectos. Si cree que el problema es que son descuidados y no les importa su trabajo, este es un problema de gestión.
Sean McSomething

Es en parte un problema de gestión, pero también es un problema de herramienta para permitir que los desarrolladores tomen decisiones sensatas.
Michael Shaw

Respuestas:


22

El problema es que está cambiando el significado de una rama a la mitad del proceso.

Inicialmente, la v1 devrama es para el desarrollo. Todas las nuevas características van allí. En algún momento en el futuro, se convierte en una rama de mantenimiento para la v1 releaserama. Este es el quid del problema.

No es que los desarrolladores sean descuidados, es que los permisos y roles de la sucursal son descuidados y están sujetos a cambios.

Lo que debe hacer es establecer el rol de cada rama y mantener ese rol. Si el rol cambia, bifurca.

Por ejemplo:

 developer
  commits    |   |  |   |    |     |   |     |
             v   v  v   v    v     v   v     v
 dev  +--+---------------------+------------------->
         |           ^    ^    |           ^    ^
         |           |    |    |           |    |
 v1      +----+------+----+    |           |    |
           prod  patches       |           |    |
                               |           |    |
                               |           |    |
 v2                            +-----+-----+----+
                                  prod  patches

En este modelo, los desarrolladores siempre se comprometen con el desarrollo. Si está creando un parche, verifique el parche en la rama de esa versión (o mejor aún, bifurque la rama de la versión para un parche y luego vuelva a fusionarlo en la rama de la versión).

Un artículo que debe leer (y probablemente es un eufemismo para "debería") es Estrategias de ramificación de SCM avanzadas de Stephen Vance.

En este artículo, primero defino la ramificación en un sentido general. Luego discuto varias estrategias para ramificar, comenzando con lo obvio y pasando a varias que son más apropiadas para esfuerzos de desarrollo más grandes. En el camino, discuto los pros y los contras de cada estrategia, utilizándolos para motivar los cambios que componen las estrategias más complejas ...

En este artículo, identifica cinco roles que pueden tener las ramas. A veces, una rama puede cumplir dos roles y los roles no necesariamente necesitan una nueva rama siempre que las políticas de rol no cambien a mitad de rama (ocasionalmente verá la mención de "rama en política incompatible").

Estos roles son:

  1. Línea principal. Aquí es de donde están hechas las ramas. La ramificación siempre desde la línea principal hace que las fusiones sean más fáciles, ya que las dos ramas tendrán un antepasado común que no está rama por rama sobre ramas.
  2. Desarrollo. Aquí es donde los desarrolladores registran el código. Uno puede tener múltiples ramas de desarrollo para aislar los cambios de alto riesgo de los que son rutinarios y mundanos.
  3. Mantenimiento. Corrección de errores en un entorno de producción existente.
  4. Acumulación. Al fusionar dos sucursales, es posible que uno no quiera arriesgarse a desestabilizar la línea principal. Entonces ramifique la línea principal, combine las ramas en el acumulador y vuelva a la línea principal una vez que se resuelvan las cosas.
  5. Embalaje. Empaquetar un lanzamiento ocurre en las ramas del empaque. Esto a menudo se convierte en el lanzamiento y sirve para aislar el esfuerzo de lanzamiento del desarrollo. Vea ¿Cómo lidiar con confirmaciones no deseadas que rompen las versiones de lanzamiento de larga duración? para ver un ejemplo de dónde el embalaje entra en conflicto con el desarrollo.

En su ejemplo, tiene una línea principal en cascada (esto es un problema, hace que las fusiones sean más difíciles, ¿qué sucede si desea fusionar una solución para v1 en v2 y v3?), Una rama de desarrollo que se convierte en una rama de mantenimiento ( cambio de política, esto es un problema).

Ok, dices, eso es genial, pero esto fue escrito por fuerza, que es un VCS centralizado: estoy usando DVCS.

Veamos el modelo de flujo de Git y ver cómo se aplica.

La rama maestra (azul) es la rama de lanzamiento, para el etiquetado. No es la línea principal. La línea principal es en realidad la rama de desarrollo (amarillo). Las ramas de liberación (verde) son el rol del empaque. El desarrollo de bajo riesgo ocurre en la línea principal, el desarrollo de alto riesgo ocurre en las ramas de características (rosa). En este modelo, la acumulación se realiza en la rama de desarrollo. El mantenimiento se considera 'hotfix' que es rojo.

Si bien las políticas de roles no coinciden exactamente (cada producto tiene su propio ciclo de vida ligeramente diferente), sí coinciden.

Hacer esto debería simplificar su política de ramificación y facilitar a todos los involucrados.


+1 Gran respuesta técnica, podría funcionar si no la documenta, probablemente no. No es probable que el problema se resuelva por completo a menos que la estrategia de ramificación se documente con procedimientos claros.
mattnz

1
@mattnz Hay patrones de ramificación más avanzados (ghads, voy a usar la palabra). Sin embargo, el 'todos se comprometen a desarrollar siempre' y 'cuando esté listo, bifurcar una versión de desarrollo' debería llevarlo al 90% del camino hacia la solución. Entonces, los únicos casos extraños son 'trabajar en un parche' y luego es un "Sé que estoy haciendo esto en una versión anterior, cambia a esa rama".

1
He aceptado esta respuesta, ya que formará la base de los cambios que haremos en nuestro SCM. Los enlaces a Advanced SCM Branching Stratagies y el modelo git-flow han sido particularmente apreciados. También intentaremos invertir en capacitación para mejorar la comprensión de nuestros desarrolladores de lo que hacen con HG.
imp25

@ imp25 puede encontrar hg-flow útil para el lado hg en lugar de git.

@ imp25 (y algunas preguntas y respuestas sobre StackOverflow hgflow - stackoverflow.com/questions/14011921/... stackoverflow.com/questions/13021807/... )

3

Si bien ha intentado usar una rama de producto separada con controladores de acceso, parece que el único repositorio se usa para hacer las compilaciones de producción. Si las compilaciones de producción solo se hicieran desde un repositorio de producción, que solo el escribiente puede escribir, entonces los desarrolladores no podrían presionarlo. Esto pone una carga en el guardián, que solo presionará al repositorio de producción después de la revisión. Por supuesto, las personas aún podrían retirarse del repositorio de producción cuando sea necesario.

A medida que las personas adquieren experiencia, se les debe rotar a través del rol de guardián de puerta, para obtener la comprensión más profunda o la atención que parecen carecer.

Y como regla general, aplique la Navaja de Occam: toda la estructura del repositorio debe ser lo más simple posible para hacer su trabajo.

Ver también el comentario de Sean.


2

Es posible que los desarrolladores simplemente no obtengan DVCS lo suficientemente bien, pero creo que es mucho más probable que simplemente haya pasado demasiado, y los desarrolladores no pueden realizar un seguimiento de lo que están haciendo de momento en momento. Olvidan en qué rama se supone que están trabajando, y sus cambios terminan en el lugar equivocado.

Sugeriría que tiene un problema con el hecho de que todos trabajan regularmente en todas estas ramas.

La sugerencia de @ andy256 de un repositorio separado para productos ciertamente ayudaría, pero es posible que deba considerar dividir el trabajo de manera diferente o tal vez organizar las cosas para que ningún desarrollador trabaje en más de una rama en una semana determinada.


1

Parece que has identificado uno de mis principales osos de error. La mayoría de las herramientas de control de código fuente son exactamente eso, las herramientas de control de código fuente. Permiten que un grupo de desarrolladores trabajen en el mismo directorio de origen, haciendo cambios y manejando conflictos. Ha habido algunos bordes ásperos en el camino, pero cvs, subversion, git, mercural, etc., todos cumplen con esto.

Luego tiene el siguiente paso, cuando necesita estabilizar el código para su lanzamiento, e introduce la ramificación. Aquí es donde las herramientas comienzan a fallar a los desarrolladores. Las herramientas son capaces de hacer la ramificación e incluso de identificar los conjuntos de cambios que se han acumulado en las sucursales después de que se han ramificado, pero ese no es el problema que ahora enfrenta.

Las herramientas son realmente deficientes para seleccionar qué cambios deben copiarse en otras ramas y cuándo debe ocurrir. Git-flow intenta resolver esto creando una estrategia de ramificación que significa que cuando se fusionan las ramas, se fusionan TODOS sus cambios, y luego requiere que el programador tome decisiones sensatas sobre cuándo y qué ramas se fusionan.

En un único repositorio donde todos los desarrolladores están trabajando en un proyecto que tiene un solo hilo de lanzamiento, git flow resuelve el problema, pero la vida no es tan simple para muchas empresas.

El entorno complejo es donde tiene múltiples equipos responsables de diferentes aspectos de la solución total, realizando lanzamientos internos a otros equipos. git-flow simplemente no es capaz de resolver este tipo de problema.

La única forma en que he visto este trabajo es si cada equipo es responsable de definir sus lanzamientos y controlar cuándo cambian sus dependencias. Solo porque el equipo A ha lanzado la versión 1.3, el equipo B solo comienza a usar la versión 1.3 del equipo A cuando el equipo B lo elige.

En efecto, un equipo de desarrolladores define los grupos de cambios que necesitan ser movidos, y los desarrolladores que reciben los cambios definen cuándo reciben el grupo de cambios.

La única herramienta de control de fuente que he visto que realmente ofrece esto es precisa, e incluso entonces, la mayoría de sus desarrolladores se quejarán porque la GUI es demasiado confusa para ellos y no se comporta como una subversión ...

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.