ventajas proceso modelo metodos ingenieria formales etapas desventajas desarrollo concurrente componentes basado mercurial workflow dvcs mercurial-queue

proceso - ¿Cómo gestionar el desarrollo concurrente con mercurial?



modelo de metodos formales (3)

Entonces, la pregunta es, en el momento en que se le indica que deje de trabajar en la característica A y que comience con la característica B, ¿qué opciones alternativas existen para: ¿Cómo administrar el desarrollo concurrente con mercurial?

Veamos el problema con la concurrencia eliminada, de la misma manera que escribe código en subprocesos: defina un flujo de trabajo simple para resolver cualquier problema que se le presente y aplíquelo a cada problema. Mercurial se unirá al trabajo, una vez hecho. Por lo tanto, el programador A trabajará en la característica A. El programador B trabajará en la característica B. Ambos son los únicos. (Si tan solo tuviéramos cerebros multi-core :)

Siempre usaría sucursales con nombre, porque eso le permite a Mercurial hacer su trabajo: mantener el historial de su proyecto y recordar por qué realizó los cambios en qué orden en su código fuente.

Estoy de acuerdo con el sentimiento de Brandon, pero me pregunto si se le pasó por alto esa característica ¿A no se ha probado? En el peor de los casos, el código compila y pasa las pruebas unitarias, pero algunos métodos implementan los requisitos anteriores, y algunos métodos implementan los nuevos. Una diferencia con respecto al registro anterior es la herramienta que usaría para ayudarme a volver a la pista con la función A.

¿Está su código para la característica A en un punto en el que normalmente lo registraría? Cambiar de la función A a trabajar en la función B no es una razón para enviar código a la cabecera o a una rama. Solo ingrese el código que compila y pasa sus pruebas. Mi razón es que si el programador C necesita comenzar con la función C, una nueva comprobación de esta rama ya no es el mejor lugar para comenzar. Mantener saludables a sus sucursales, significa que puede responder rápidamente, con correcciones de errores más confiables.

El objetivo es tener su código (probado y verificado) en ejecución, por lo que desea que todo su código termine fusionado en la cabeza (de sus ramas de desarrollo y heredadas). Mi punto parece ser, he visto que las ramas se utilizan de manera ineficiente: el código se vuelve obsoleto y luego no se usa, la combinación se vuelve más difícil que el problema original.

Sólo tu opción 1 tiene sentido para mí. En general:

  1. Debes pensar que tu código funciona, antes de que alguien más lo vea.
  2. Favorece la cabeza sobre una rama.
  3. Sucursal y registro si alguien más está detectando el problema.
  4. Bifurque si su sistema automatizado o probadores solo necesitan su código.
  5. Rama si eres parte de un equipo, trabajando en un problema. Considérelo la cabeza, ver 1-4.

Con la excepción de los archivos de configuración, los procesos de compilación deben ser una comprobación y un solo comando de compilación. No debería ser más difícil cambiar entre clones, que si un nuevo programador se uniera al proyecto. (Admito que mi proyecto necesita algo de trabajo aquí).

Esta es una pregunta de mejores prácticas, y espero que la respuesta sea "depende". Solo espero aprender más escenarios del mundo real y flujos de trabajo.

En primer lugar, estoy hablando de diferentes cambios para el mismo proyecto, así que no hay subrepo por favor.

Digamos que tienes tu base de código en un repositorio de hg. Empieza a trabajar en una nueva y complicada función A, luego su probador confiable informa de un error B (tiene probadores, ¿verdad?).

Es trivial si (la solución para) B depende de A. Usted simplemente ci A y luego ci B.

Mi pregunta es qué hacer cuando son independientes (o al menos parece ahora).

Puedo pensar en las siguientes maneras:

  1. Utilice un clon separado para B.
  2. Use ramas anónimas o con nombre, o marcadores, en el mismo repositorio.
  3. Use MQ (con el parche B en la parte superior de A).
  4. Usar MQ ramificado (explicaré más adelante).
  5. Usar múltiples MQ (desde 1.6)

1 y 2 están cubiertos por un excelente blog de @Steve Losh vinculado a una pregunta ligeramente relacionada .

La única gran ventaja de 1 sobre las otras opciones es que no requiere ninguna reconstrucción cuando se pasa de trabajar en una cosa a otra, porque los archivos están separados físicamente e independientemente. Entonces, realmente es la única opción si, por ejemplo, A y / o B tocan un archivo de encabezado que define un booleano tri-estatal y está incluido en miles de archivos C (no me digas que no has visto un código tan antiguo base).

3 es probablemente el más fácil (en términos de configuración y gastos generales), y puede cambiar el orden de A y B si B es una solución pequeña y / o urgente. Sin embargo, puede ser difícil si A y B tocan el mismo archivo (s). Es fácil arreglar los trozos de parches que no se aplicaron si los cambios A y B son ortogonales en el mismo archivo (s), pero conceptualmente todavía es un poco arriesgado.

4 puede marearte pero es la forma más potente, flexible y escalable. Por defecto, hg qinit con -c ya que quiero marcar los parches de trabajo en curso y presionarlos / jalarlos, pero se necesita un salto conceptual para darse cuenta de que también se puede bifurcar en el repositorio de MQ. Aquí están los pasos (mq = hg --mq):

  1. hg qnew bugA ; hacer cambios para A; hg qref
  2. mq branch branchA; hg qci
  3. hg qpop; mq up -rtip^
  4. hg qnew bugB ; hacer cambios para B; hg qref
  5. mq branch branchB; hg qci
  6. Para volver a trabajar en A: hg qpop; mq up branchA; hg qpush hg qpop; mq up branchA; hg qpush

Parece una locura tomar tantos pasos, y siempre que necesite cambiar de trabajo, debe hg qci; hg qpop; mq up <branch>; hg qpush hg qci; hg qpop; mq up <branch>; hg qpush hg qci; hg qpop; mq up <branch>; hg qpush . Pero considere esto: tiene varias sucursales de lanzamiento con nombre en el mismo repositorio, y necesita trabajar en varios proyectos y correcciones de errores al mismo tiempo para todos (es mejor que obtenga un bono garantizado para este tipo de trabajo). Te perderías muy pronto con los otros enfoques.

Ahora mis compañeros hg amantes, ¿hay otras / mejores alternativas?

(ACTUALIZACIÓN) qqueue casi hace que # 4 sea obsoleto. Vea la descripción elegante de Steve Losh here .


Parece que no hay más o mejores opciones que las que enumeré en la pregunta. Así que aquí están de nuevo.

  1. Utilice un clon por proyecto.
    • Pros: separación total, por lo tanto no hay reconstrucción al cambiar de proyecto.
    • Contras: la cadena de herramientas necesita cambiar entre dos clones.
  2. Use ramas anónimas o con nombre, o marcadores, en el mismo repositorio.
    • Ventajas: práctica estándar de hg (o cualquier DVCS); limpio y claro.
    • Contras: debe confirmar antes de cambiar y reconstruir después.
  3. Utilice MQ con un parche (o varios parches consecutivos) por proyecto.
    • Pros: simple y fácil.
    • Contras: debe qrefresh antes de cambiar y reconstruir después; Difícil y arriesgado si los proyectos no son ortogonales.
  4. Use una rama MQ (o qqueue en 1.6+) por proyecto.
    • Pros: ultra flexible y escalable (para la cantidad de proyectos concurrentes)
    • Contras: debe qrefresh y qcommit antes de cambiar y reconstruir después; se siente complicado

Como siempre, no hay una bala de plata, así que elige la que más te convenga para el trabajo.

(ACTUALIZACIÓN) Para cualquiera que esté enamorado de MQ, usar MQ encima de las sucursales regulares (# 2 + # 3) es probablemente la práctica más común y preferible.

Si tiene dos proyectos simultáneos con línea de base en dos sucursales (por ejemplo, la próxima versión y la versión actual), es trivial saltar entre ellas de esta manera:

hg qnew; {coding}; hg qrefresh; {repeat} hg qfinish -a hg update -r <branch/bookmark/rev> hg qimport -r <rev>; {repeat}

Para el último paso, qimport debe agregar una opción -a para importar una línea de conjuntos de cambios a la vez. Espero que Meister Geisler se dé cuenta de esto :)


Siempre usaría sucursales con nombre, porque eso le permite a Mercurial hacer su trabajo: mantener el historial de su proyecto y recordar por qué realizó los cambios en qué orden en su código fuente. El hecho de tener un clon o dos en su disco es generalmente fácil, dado mi estilo de trabajo, al menos:

  1. ¿Su proyecto carece de un proceso de compilación, de modo que pueda probar y ejecutar las cosas directamente desde el código fuente? Entonces me sentiré tentado a tener un solo clon, y hg up lado a otro cuando necesito trabajar en otra rama.

  2. Pero si tienes un buildout, virtualenv u otra estructura que se construye, y que puede divergir entre las dos ramas, entonces hacer un hg up luego esperar a que el proceso de compilación vuelva a ejecutarse puede ser un gran dolor, especialmente si la configuración de una base de datos de muestra están involucrados. En ese caso, definitivamente usaría dos clones, uno sentado en la punta del tronco y otro sentado en la punta de la rama de emergencia.