¿Cuándo debo dejar de comprometerme para dominar nuevos proyectos?
26
Cada vez que comienza un nuevo proyecto, por lo general tiene sentido comenzar por comprometerse directamente a dominar hasta que tenga algo "estable", y luego comience a trabajar en ramas.
Al menos, así es como lo hago normalmente. ¿Hay alguna manera de iniciar ramas inmediatamente desde la segunda confirmación? ¿Tiene sentido hacerlo de esta manera? Obviamente, "Initial Commit" siempre estará en master, pero después de eso, ¿cuándo sabré que es el momento adecuado para comenzar a crear sucursales para nuevas características?
La clave es la cuestión de cuál es la política de Master. Con git, por lo general, la política de sucursal en Master es la versión estable compilable . A veces, Master es la 'línea principal' donde las ramas se hacen y se fusionan antes de fusionarse con una rama Release. Estos son dos enfoques diferentes de rol / política.
A menudo es una fuente de errores que las personas cambien el rol o la política de una sucursal a mitad del proyecto. Es más fácil para un desarrollador en solitario comunicar estos cambios a los contribuyentes, pero tratando de lograr que una docena de programadores reconozcan "Master ahora está en 1.0, ramifique las características en lugar de que todos lo presionen"
Toqué el enfoque de política anterior. La política para Master es que es la versión estable compilable . El registro de pequeños cambios incrementales en este medio que no tenga algo edificable estable en todo momento. No registrar pequeños cambios va en contra de "muchos registros pequeños (pero completos)" que tienden a ser la mejor política (y se fomenta con una fácil ramificación).
Desde una perspectiva basada en roles, usted comenzó con master como roles principales, de lanzamiento, mantenimiento y desarrollo, y luego, en algún momento, el rol de desarrollo y mantenimiento se traslada a las sucursales. Esto nuevamente significa un cambio en lo que está permitido en master y puede confundir a los contribuyentes en cuanto a dónde pertenecen las cosas. También puede (ligeramente) confundir el historial de la rama, alentando grandes compromisos que significan fusiones más grandes y difíciles de entender.
Clave los roles y políticas en las ramas simples y consistentes desde el principio.
Estoy de acuerdo principalmente con esto, pero no diría simplemente edificable , diría liberable (estable). El maestro no debe contener código que simplemente compila, debe contener código que en realidad ha sido probado exhaustivamente. Debería poder retirarse del master en cualquier momento, confiando en el conocimiento de que no habrá defectos graves.
Aaronaught
Estoy totalmente de acuerdo con Aaronaught, ya que en mi humilde opinión es perfectamente posible (y la mejor práctica) trabajar de una manera en la que el paso de un estado edificable al siguiente siempre es solo un pequeño cambio incremental, nunca uno grande.
Doc Brown
1
@MichaelT He visto ramas 'dev' muchas veces, pero nunca las escuché explicadas en el contexto de un "maestro temprano" antes. Creo que usaré esto, gracias.
Droogans
13
Existen principalmente dos situaciones en las que normalmente desea comenzar a trabajar con sucursales:
cuando usted o su equipo tienen que iniciar una nueva característica que tiene la más mínima posibilidad de no agregarse a la próxima versión (que puede ser la primera versión), luego comience el desarrollo en una rama de características separada
cuando tiene que proporcionar correcciones para errores graves en la última versión, y desea crear una nueva versión de corrección de errores que contenga solo esas correcciones, pero no características desarrolladas recientemente (y probablemente inestables)
Para este tipo de decisiones, creo que es útil pensar siempre en términos de "nuevas características" o "correcciones de errores", desde el punto en que tiene una primera versión compilable / ejecutable de su programa.
Michael Feathers enumera cuatro razones para cambiar en su famoso libro, pero yo pondría "optimizar recursos" en "nueva rama de características" (para una característica no funcional) y "mejorar el diseño" la mayoría de las veces también en "nueva rama de características" , ya que en mi humilde opinión, uno nunca debe mejorar el diseño cuando no está destinado a facilitar la implementación de una característica específica .
Si sigues git-flow , y, francamente, creo que estás loco si usas Git y no usas ese modelo de ramificación, entonces nunca deberías comprometerte masterhasta que estés realmente listo para un lanzamiento público.
Su primer compromiso masterdebe ser un repositorio vacío. Su próximo compromiso masterdebe ser un compromiso de fusión de la developrama o una rama de lanzamiento temporal, y debe ser estable, probado y listo para su implementación (si es una aplicación) o distribución pública (si es una biblioteca).
No son otros modelos de ramificación de Git, pero la mayoría de ellos han se derivan de modelos SCM centralizado de edad avanzada y pueden conducir a serios problemas en un entorno DVCS. No tiene que usar realmente la extensión git-flow, y no necesariamente necesita todas esas ramas de lanzamiento / revisión / función, pero lo básico es developy master, y entra un código inestable develop.
Ni siquiera necesitas ese primer compromiso master. Recuerde que masterno es nada especial para git, no necesita estar allí. Solo puede tener una rama de desarrollo hasta que desee hacer un lanzamiento.
Miles Rout
2
@MilesRout: Si bien eso es cierto en principio, no puede fusionarse a menos que la rama ya exista, y el proceso dicta que cada compromiso con el maestro debe ser una fusión sin avance rápido. A menos que me falte algo, la única alternativa a una confirmación vacía inicial sería bifurcar al maestro fuera de una bifurcación de desarrollo o liberación arbitraria , lo que significaría que compartirían la misma confirmación, que es algo que se supone para evitar.
Aaronaught
1
Ah, ese es realmente un buen punto. +1 para publicar y comentar.
Miles Rout
1
Neal Ford, de Thoughtworks, aboga por el uso de funciones que se alternan con la ramificación para evitar el problema de "fusionar el infierno". Considere el caso en el que dos programadores se fusionan diariamente de la rama principal y uno de ellos realiza cambios considerables durante algunas semanas y luego se compromete. El otro programador podría terminar en un infierno de fusión. Para evitar este problema, Ford recomienda "adelantar el dolor" (un atributo ágil bien conocido) al tener solo una rama y comprometerse diariamente. La función adicional se agrega a través de conmutadores de función que deshabilitan la función hasta que se haya probado completamente.
Esta metodología parece funcionar mejor en un entorno que implementa la entrega continua ya que los problemas con una confirmación se detectarán de inmediato.
Han pasado dos años desde la última respuesta a esta pregunta y creo que ahora la historia cambia. Para mí, la respuesta es "Siempre que use el control del código fuente para rastrear versiones".
Para elaborar, en estos días el seguimiento de versiones de proyectos con control de código fuente no siempre funciona. (por ejemplo, usando npm para gestionar la dependencia y especificar versiones semánticas con '^') En ese caso, los artefactos del proyecto cambian cada vez que se produce una compilación, sin corresponder necesariamente a los cambios del código fuente cada vez. Para manejar este tipo de nuevos desafíos, algunos equipos eligen haber construido 'artefactos' guardados en el sistema de control de artefactos (por ejemplo, JFrog Artifactory) para realizar un seguimiento de las versiones del proyecto.
Obviamente, cuando ya tiene el control de versión de artefactos en su lugar, no extraerá el 'código de producción' de una rama GIT y lo compilará / implementará en producción, en su lugar, consultará al sistema de control de artefactos para obtener versiones directamente ejecutables para la implementación. En tales casos, el concepto de 'rama de liberación' pierde repentinamente su significado. Y cada vez que su equipo decida no asociar git branch con la versión de lanzamiento, comprometerse / presionar directamente para dominar se convierte en una buena opción una vez más: viene como rama predeterminada cada vez que se clona el repositorio, por lo tanto, dada la semántica ampliamente aceptada y bien comunicada cambios Aún así, como sugiere la respuesta aceptada, probablemente deberías ir a asignar un rol a las ramas, incluido el maestro, y usar esas ramas solo para esos roles en particular.
Por último, voy un paso más allá y sugiero usar master como rama de desarrollo en proyectos con solo un puñado de committers principales. Cuál es el caso de mi equipo y probablemente lo mismo para la mayoría de las tiendas de microservicios. Comprometerse con master elimina la comunicación del proceso de cambios y potencialmente evita 'fusionar el infierno' cuando se trabaja en funciones en múltiples sprints. Además, el código en la rama maestra ni siquiera tiene que 'funcionar', el proceso automatizado de compilación / prueba le dirá qué salió mal y de todos modos es bastante fácil verificar el historial de git y contactar al autor que rompió la compilación / prueba :-)
Voy a tomar una posición radical: ramificarme en cada idea. Primero en git las sucursales son baratas, el costo principal de una sucursal es recordar para qué sirve. También estoy de acuerdo en que el primer compromiso para dominar es un candidato de liberación. Recomiendo comenzar con una rama de prueba de concepto. Cuando haya probado su concepto, puede fusionarlo con su rama de desarrollo vacía o reescribir según lo bueno que sea su primer intento. desde este punto, se ramifica desde el desarrollo para cada error, característica, abstracción, etc.
Existen principalmente dos situaciones en las que normalmente desea comenzar a trabajar con sucursales:
cuando usted o su equipo tienen que iniciar una nueva característica que tiene la más mínima posibilidad de no agregarse a la próxima versión (que puede ser la primera versión), luego comience el desarrollo en una rama de características separada
cuando tiene que proporcionar correcciones para errores graves en la última versión, y desea crear una nueva versión de corrección de errores que contenga solo esas correcciones, pero no características desarrolladas recientemente (y probablemente inestables)
Para este tipo de decisiones, creo que es útil pensar siempre en términos de "nuevas características" o "correcciones de errores", desde el punto en que tiene una primera versión compilable / ejecutable de su programa.
Michael Feathers enumera cuatro razones para cambiar en su famoso libro, pero yo pondría "optimizar recursos" en "nueva rama de características" (para una característica no funcional) y "mejorar el diseño" la mayoría de las veces también en "nueva rama de características" , ya que en mi humilde opinión, uno nunca debe mejorar el diseño cuando no está destinado a facilitar la implementación de una característica específica .
fuente
Si sigues git-flow , y, francamente, creo que estás loco si usas Git y no usas ese modelo de ramificación, entonces nunca deberías comprometerte
master
hasta que estés realmente listo para un lanzamiento público.Su primer compromiso
master
debe ser un repositorio vacío. Su próximo compromisomaster
debe ser un compromiso de fusión de ladevelop
rama o una rama de lanzamiento temporal, y debe ser estable, probado y listo para su implementación (si es una aplicación) o distribución pública (si es una biblioteca).No son otros modelos de ramificación de Git, pero la mayoría de ellos han se derivan de modelos SCM centralizado de edad avanzada y pueden conducir a serios problemas en un entorno DVCS. No tiene que usar realmente la extensión git-flow, y no necesariamente necesita todas esas ramas de lanzamiento / revisión / función, pero lo básico es
develop
ymaster
, y entra un código inestabledevelop
.fuente
master
. Recuerde quemaster
no es nada especial para git, no necesita estar allí. Solo puede tener una rama de desarrollo hasta que desee hacer un lanzamiento.Neal Ford, de Thoughtworks, aboga por el uso de funciones que se alternan con la ramificación para evitar el problema de "fusionar el infierno". Considere el caso en el que dos programadores se fusionan diariamente de la rama principal y uno de ellos realiza cambios considerables durante algunas semanas y luego se compromete. El otro programador podría terminar en un infierno de fusión. Para evitar este problema, Ford recomienda "adelantar el dolor" (un atributo ágil bien conocido) al tener solo una rama y comprometerse diariamente. La función adicional se agrega a través de conmutadores de función que deshabilitan la función hasta que se haya probado completamente.
Esta metodología parece funcionar mejor en un entorno que implementa la entrega continua ya que los problemas con una confirmación se detectarán de inmediato.
fuente
Han pasado dos años desde la última respuesta a esta pregunta y creo que ahora la historia cambia. Para mí, la respuesta es "Siempre que use el control del código fuente para rastrear versiones".
Para elaborar, en estos días el seguimiento de versiones de proyectos con control de código fuente no siempre funciona. (por ejemplo, usando npm para gestionar la dependencia y especificar versiones semánticas con '^') En ese caso, los artefactos del proyecto cambian cada vez que se produce una compilación, sin corresponder necesariamente a los cambios del código fuente cada vez. Para manejar este tipo de nuevos desafíos, algunos equipos eligen haber construido 'artefactos' guardados en el sistema de control de artefactos (por ejemplo, JFrog Artifactory) para realizar un seguimiento de las versiones del proyecto.
Obviamente, cuando ya tiene el control de versión de artefactos en su lugar, no extraerá el 'código de producción' de una rama GIT y lo compilará / implementará en producción, en su lugar, consultará al sistema de control de artefactos para obtener versiones directamente ejecutables para la implementación. En tales casos, el concepto de 'rama de liberación' pierde repentinamente su significado. Y cada vez que su equipo decida no asociar git branch con la versión de lanzamiento, comprometerse / presionar directamente para dominar se convierte en una buena opción una vez más: viene como rama predeterminada cada vez que se clona el repositorio, por lo tanto, dada la semántica ampliamente aceptada y bien comunicada cambios Aún así, como sugiere la respuesta aceptada, probablemente deberías ir a asignar un rol a las ramas, incluido el maestro, y usar esas ramas solo para esos roles en particular.
Por último, voy un paso más allá y sugiero usar master como rama de desarrollo en proyectos con solo un puñado de committers principales. Cuál es el caso de mi equipo y probablemente lo mismo para la mayoría de las tiendas de microservicios. Comprometerse con master elimina la comunicación del proceso de cambios y potencialmente evita 'fusionar el infierno' cuando se trabaja en funciones en múltiples sprints. Además, el código en la rama maestra ni siquiera tiene que 'funcionar', el proceso automatizado de compilación / prueba le dirá qué salió mal y de todos modos es bastante fácil verificar el historial de git y contactar al autor que rompió la compilación / prueba :-)
fuente
Voy a tomar una posición radical: ramificarme en cada idea. Primero en git las sucursales son baratas, el costo principal de una sucursal es recordar para qué sirve. También estoy de acuerdo en que el primer compromiso para dominar es un candidato de liberación. Recomiendo comenzar con una rama de prueba de concepto. Cuando haya probado su concepto, puede fusionarlo con su rama de desarrollo vacía o reescribir según lo bueno que sea su primer intento. desde este punto, se ramifica desde el desarrollo para cada error, característica, abstracción, etc.
fuente