Introducir una política de ramificación de control de versiones a un equipo pequeño


17

Soy un contratista que recientemente comenzó con una empresa.

El equipo es de 3 desarrolladores que consta de 2 desarrolladores de nivel junior a medio, con otro en el mismo nivel que comenzará pronto, y yo (6 años xp). Tanto para los desarrolladores existentes es su primer trabajo fuera de la universidad / colegio, y nunca antes han tenido un desarrollador senior que supervise su trabajo.

No existe una política explícita de control de versiones. Los desarrolladores realizan todo el desarrollo en el tronco y luego lo implementan en producción directamente desde sus máquinas de desarrollo. El equipo existente no está familiarizado con la ramificación.

Estoy cambiando todo esto e introduciendo CI, servidores de prueba / preparación / producción de TDD, etc., junto con una política de control de versiones para complementar esto.

El sistema de control de fuente es TFS, que nunca he usado antes. Está configurado como un repositorio gigante.

He escrito algunos consejos para ellos, pero ¿hay algo más que deba agregar / modificar, teniendo en cuenta la experiencia del equipo?

Política de control de versiones

El desarrollo se realiza en el tronco.

Si se estima que un cambio demorará más de una semana, entonces debe hacerse en una rama, con fusiones regulares desde el tronco hacia la rama para evitar que los dos se desincronicen.

Liberar ramas creadas para el código de producción. Esa rama solo debe contener código estable. Podemos tener una rama de lanzamiento que se actualiza desde el tronco una vez por sprint, o podemos hacer una rama de lanzamiento separada para cada semana.

Si es necesario realizar una corrección de errores urgente que afecte al código de producción, se realiza en la rama de lanzamiento y se fusiona nuevamente en el tronco.

Si adoptamos la estrategia de una rama de lanzamiento, el tronco se fusiona con la rama de lanzamiento una vez por sprint hacia el final del sprint.

Si adoptamos la rama separada por estrategia de lanzamiento, el tronco NUNCA se fusiona con la rama de lanzamiento

En algunos escenarios, puede ser necesario corregir el error dos veces en diferentes ramas, si las ramas han divergido demasiado. Si estamos haciendo carreras cortas, esto no debería suceder con demasiada frecuencia.


Planeo tener tres servidores. Entorno de prueba que siempre ejecuta el último código en el repositorio. Un entorno de ensayo que ejecuta el último candidato de lanzamiento para ensayo / prueba del código de candidato de lanzamiento y propósitos de UAT, y el entorno de producción.

La razón por la que planeo hacer esto es que hasta ahora el cliente solo ha hecho software interno. El proyecto más nuevo es para un cliente de medios de alto perfil, y creo que el equipo necesita adoptar un modelo de desarrollo más profesional que el que hacen en este momento.

Por ejemplo, en este momento, un usuario puede telefonear al equipo con un informe de error. Los desarrolladores localizan y corrigen el error, hacen una prueba rápida de globo ocular en sus propias máquinas y luego lo implementan directamente en producción. Sin pruebas automatizadas ni nada.


En retrospectiva, creo que la rama de características está demasiado lejos y la eliminaré.

Así que esencialmente se reduce a a) no ramificación en absoluto) b) una rama de liberación y el tronco, y c) una rama de liberación por liberación y el tronco.

Me inclinaba hacia lo último. Mi pensamiento inicial sería que tendría un candidato de lanzamiento y un lanzamiento para estar en vivo en servidores separados (UAT / Producción) al mismo tiempo, pero efectivamente el enlace troncal es el candidato de lanzamiento en cualquier momento, por lo que una rama por la liberación se inclina hacia la locura. Lo único que pensaría sería que si no quisiéramos que nuestras partes interesadas vieran el código de desarrollo, entonces podríamos necesitar una rama candidata de lanzamiento por separado, pero YAGNI y todo eso .....


3
¿consideró agregar una explicación de por qué eligió de esta manera? digamos, de manera similar a cómo se hace aquí . Además, ¿marcó la "Guía de ramificación del servidor de Microsoft Team Foundation" (por ejemplo, aquí )?
mosquito

3
Pruebe este
gbjbaanb

1
Tenga en cuenta que estoy usando TFS, no un DVCS como GIT. Eso parece un poco específico.
MrBliz

2
El final de ese enlace dice: "Todos trabajan desde el tronco. Se bifurcan cuando se libera el código. Se bifurca cuando se necesita una corrección de errores para el código ya lanzado. Se bifurca para los prototipos". Sugeriría que, para un comienzo simple, simplemente etiquete las versiones cuando esté razonablemente seguro de que están hechas. A menos que tenga múltiples desarrolladores trabajando en múltiples funciones, no es necesario tener más de 1 sucursal. Todos agregan funciones, todos corrigen el candidato de lanzamiento, todos están de acuerdo cuando está listo para etiquetar. Eso significa que solo tiene que entregar ramas para corregir errores más adelante.
TafT

1
Me incomoda poner esto como respuesta, porque está demasiado basado en la opinión, pero he tenido un gran éxito al convencer a la gente de que use una etiqueta de "último bien conocido" (LKG), que es una etiqueta en movimiento en el tronco que identifica al último "bendecido". "versión (CCB, pruebas, etc.). A los desarrolladores se les dice que los lanzamientos se realizarán desde esta etiqueta LKG, no desde la cabecera del tronco, y más allá de eso, son libres de usar cualquier enfoque que tenga sentido para ellos en ese momento. He encontrado que este patrón genera espontáneamente ramas de características cuando es el momento adecuado, sin ningún esfuerzo inicial o trabajo adicional en las partes de los desarrolladores.
Cort Ammon - Restablece a Monica el

Respuestas:


16

Para un equipo de 3-4 desarrolladores, estás proponiendo WAY demasiadas ramas.

Cada rama que cree es una sobrecarga adicional que conlleva un costo (tiempo dedicado a la fusión, realizar un seguimiento de qué está dónde, etc.). Debe asegurarse de que el beneficio que obtiene de tener una sucursal supera el costo.

Tenga en cuenta que el único beneficio real para una sucursal es el aislamiento del código. Eso significa que necesita una razón concreta para querer tener el código aislado.

Tener una rama de lanzamiento separada para cada sprint es una locura. ¿Por qué necesita el código de un sprint aislado del código para el siguiente? ¿Por qué no tener una sola rama de lanzamiento estable que se lleva adelante con cada sprint?

Si se estima que un cambio demorará más de una semana, entonces debe hacerse en una rama, con fusiones regulares desde el tronco hacia la rama para evitar que los dos se desincronicen.

Casi cualquier nueva característica no trivial llevará al menos una semana en tiempo real después de que tenga en cuenta el desarrollo, las pruebas del desarrollador, las interrupciones diarias y otras actividades, etc.

Además, ¿qué es una "fusión regular"? ¿Diario? ¿Semanal? Cada fusión que realice requiere tiempo: debe asegurarse de que la rama de fusión de destino se compila y ejecuta después de sus cambios. En un equipo pequeño, la fusión frecuente es una gran carga.

Tenemos un equipo de 4 desarrolladores trabajando en una base de código de más de 1 millón de líneas y así es como operamos:

  • Rama principal donde se realiza todo el desarrollo
  • Una rama por lanzamiento principal (hecho aproximadamente una vez al año)

La regla principal es: no verifique el código que no se construye.

Eso es. Simple, fácil de entender, obtiene el aislamiento que necesitamos (en cualquier momento podemos crear una versión de lanzamiento para cualquier versión).

Las ventajas de tener todo el trabajo de desarrollo realizado en una rama:

  1. Los desarrolladores siempre están sincronizados entre sí. No hay fusiones dolorosas porque dos desarrolladores estuvieron en sus propias sucursales durante semanas creando cambios incompatibles.
  2. Las construcciones rotas se encuentran el mismo día. Tenemos una compilación nocturna que ejecuta el último código en main. Si alguien registra el código que no se construye por algún motivo, lo sabremos de inmediato.
  3. Con todos trabajando siempre en el mismo código, aumenta las posibilidades de que se encuentre un error más temprano que tarde.
  4. No combine gastos generales que no sean correcciones específicas para liberar ramas. En un equipo pequeño, este es el grande.

10
"Tenga en cuenta que el único beneficio real para una sucursal es el aislamiento del código. Eso significa que necesita una razón concreta para querer tener el código aislado". - ¿Qué tal una revisión de código? Creo que esa es una buena razón, incluso con solo dos desarrolladores.
BlueRaja - Danny Pflughoeft

2
La revisión de código y la ramificación no están realmente relacionadas. ¿Estás diciendo que no quieres que el código se registre en una rama en particular antes de que se revise?
17 de 26

55
@ 17 de 26, sí. La revisión de código generalmente se usa como requisito previo para estar en la línea principal. Por lo tanto, debe mostrar el código de alguna manera antes de eso: en su monitor, en un correo electrónico o, en muchas configuraciones, en una sucursal. Esto funciona mejor con una herramienta de gestión de repositorios como GitHub o gerrit.
Paul Draper

3
TFS admite revisiones de código a través de conjuntos de estanterías, que son áreas de retención temporales en el control de origen. El código puede vivir allí hasta que se revise y luego se registre.
17 de 26

2
Supongo que el punto es que las ramas no son realmente el mecanismo adecuado para hacer revisiones de código.
17 de 26

31

Has escrito algunos consejos para ellos, pero no has explicado por qué tu enfoque es mejor que el que ya usan . Esto puede ser problemático. Si tiene un espíritu "Lo haremos a mi manera, porque tengo seis años de experiencia profesional y usted no" (y leyendo su pregunta, se ve exactamente de esta manera), esté listo para ser odiado por los miembros de su equipo que intentarán hacer lo que no puedan para aplicar sus conceptos.

¿Tienen un problema que necesita ser resuelto? Es crucial responder a esta pregunta primero, porque realmente tienen un problema y recibirán con agrado sus sugerencias, o funcionan perfectamente bien como lo hacen actualmente, y simplemente los está presionando en su forma de trabajar , solo porque prefiere trabaja de esta manera.

Eventualmente, obligarlos a usar ramas puede tener un impacto extremadamente negativo . Trabajar con un tronco es fácil, especialmente en un entorno ágil. Un desarrollador confirma los cambios en la troncal, eventualmente manejando pequeños conflictos, y esos cambios son utilizados inmediatamente por la plataforma de Integración Continua. Con ramas:

  • Un desarrollador tiene que pensar dónde debe ubicarse el cambio,

  • Alguien tiene que administrar ramas y fusiones de ramas al tronco,

  • Las fusiones entre sucursales se realizan con menos frecuencia que los commits, lo que significa que alguien tiene que lidiar con conflictos que son más grandes y más difíciles de manejar que un conflicto entre dos commits,

  • Cada commit no necesariamente encuentra su camino hacia la Integración Continua, lo que retrasa la información que obtienen los desarrolladores sobre los efectos que puede tener un commit (especialmente regresiones).

El hecho de que:

El equipo existente no está familiarizado con la ramificación.

empeora aún más las cosas. Trabajé en un equipo de programadores sin experiencia, donde un gerente sin experiencia decidió jugar con sucursales. Esto resultó en mucho ( mucho ) tiempo perdido y es exactamente lo que desea evitar para un proyecto que tiene plazos.


3
Bueno, en este modelo, ¿cómo va a detener la entrada de código inestable a la producción sin ramificación?
MrBliz

2
@MrBliz: a través de interruptores. Puede activar una función para desarrolladores, pero desactivarla para usuarios finales si no está lista para RTM.
Arseni Mourzenko

3
Teniendo en cuenta la experiencia de los desarrolladores con los que estoy trabajando y la falta actual de pruebas automatizadas, no creo que sea una buena idea para nuestra situación.
MrBliz

44
@MrBliz usted detiene el código inestable que pasa a producción al aislarlo en las ramas de lanzamiento (ese es exactamente su propósito) y al probarlo . Las ramas de características no ayudan en eso; de hecho, esto conlleva un mayor riesgo de introducir inestabilidad por fusiones grandes, no integradas y difíciles de controlar
mosquito

1
@MrBliz, sí, me di cuenta de eso (y creo que lo entendiste bien, si no explicaste el razonamiento para apoyar eso). Es solo que ni su comentario ni esta respuesta mencionan explícitamente si se trata de lanzamientos o ramas de características (¿o ambas?), Así que comenté para enfatizar la diferencia . FWIW ser vago acerca de esto es probablemente lo único que no me gusta de esta respuesta
mosto

3

Como dice Mainma, ten cuidado con la ramificación. Menciona ramificaciones cada pocas semanas, ¿es realmente necesario tener muchas sucursales?

Alternativamente, también podría tener un modelo 'pull' en lugar de un modelo push. Si estaba utilizando Git o Mercurial, podría hacer que un servidor de integración validara sus cambios antes de pasar al servidor central. En TFS, puede hacer algo similar utilizando registros cerrados . De esta manera, puede tener validación y evitar la complejidad de las ramas.


Efectivamente, solo habría tres ramas activas (liberación, candidato de liberación y troncal) al mismo tiempo, y la mayoría de las veces solo la rama de liberación y la troncal.
MrBliz

Las ramas antiguas se eliminarán en TFS o se ocultarán con mayor precisión.
MrBliz
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.