Estrategia para la revisión de código antes de combinar para dominar desde ramas de características

22

Mi equipo y yo usamos ramas de características (con git). Me pregunto cuál es la mejor estrategia para la revisión de código antes de fusionar para dominar.

  1. Comprobé una nueva rama de master, llamémosla fb_ # 1
  2. Me comprometo un par de veces y quiero volver a fusionarlo con Master
  3. Antes de fusionarme, se supone que alguien debe hacer una revisión del código

Ahora hay 2 posibilidades:

Primero

  1. Combino maestro para FB_ # 1 ( no FB_ # 1 al maestro) para que sea lo más al día posible
  2. Un compañero de equipo revisa los cambios entre la cabeza maestra y la cabeza fb_ # 1
  3. Si fb_ # 1 está bien, fusionamos fb_ # 1 para dominar
  4. Pros: no hay código obsoleto en revisión
  5. Contras: si alguien más combina algo entre "1". y 2." sus cambios aparecen en la revisión, aunque pertenecen a otra revisión.

2do

  1. Un compañero de equipo revisa los cambios entre el punto de pago (git merge-base master fb_ # 1) y fb_ # 1 head
  2. Pros: vemos exactamente lo que cambió durante el trabajo en la rama de características
  3. Contras: algún código obsoleto puede aparecer en la revisión.

¿De qué manera crees que es mejor y por qué ? Tal vez hay otro enfoque más adecuado?

Andrzej Gis
fuente

Respuestas:

9

Hay una variación de su primera opción:

  1. fusionar maestro a fb_ # 1 (no fb_ # 1 a maestro) para que esté lo más actualizado posible
  2. Un compañero de equipo revisa los cambios entre el maestro en el punto en que se fusionó y el jefe de fb_ # 1
  3. Si fb_ # 1 está bien, fusionamos fb_ # 1 para dominar
  4. comprobación rápida de que la fusión está bien

p.ej.

... ma -- ... -- mm -- ... -- mf  <- master
      \            \         /
       f1 ... fn -- fm -----      <-- fb_#1

dónde:

  • ma es el antepasado de master y fb_ # 1.
  • fn es el último cambio en tu sucursal
  • mm es el commit que era master / HEAD en el momento en que se fusionó con su rama (dando fm ).

Entonces, compara mm y fm en su revisión inicial, y luego verifica rápidamente después de fusionar mf para asegurarse de que nada haya cambiado significativamente en el maestro durante los pasos 1-3. Esto parece tener todas las ventajas y desventajas de la revisión inicial.

Esto supone que la revisión es rápida en comparación con la frecuencia normal de los cambios enviados al maestro, por lo que fm -> mf a menudo sería un avance rápido.

Si ese no es el caso, por cualquier razón, los inconvenientes simplemente pasarán de la revisión inicial a la revisión posterior a la fusión, y puede ser más simple simplemente fusionarse directamente en el maestro y hacer una sola revisión allí.

Inútil
fuente
¿Cómo obtengo "el punto que fusionaste"? ¿"Git merge-base master head" estará bien, o mostrará el punto de ramificación inicial?
Andrzej Gis
A menos que actualice deliberadamente master después de la fusión, será master.
Inútil
Sí, pero ¿cómo obtener ese punto si alguien más lo actualiza?
Andrzej Gis
Cuando estés en la rama fb, úsalo git show HEAD. Como ese será el comando de fusión fm , enumerará a ambos padres. Entonces, tienes el hash de mm . Alternativamente, puede ver trivialmente al padre en gitkcualquier otro navegador git
inútil el
13

3ro

  • Usted rebase la rama sobre la que amo tanto lo componen al día y mantener los cambios separan.

    Esto crea una nueva historia de la rama. Serán nuevas revisiones con nuevas ID que tendrán el mismo contenido, pero se derivarán del último maestro y no se vincularán a las revisiones anteriores. Las revisiones anteriores todavía están disponibles en "reflog" si necesita consultarlas, por ejemplo, porque encuentra que cometió un error en la resolución de conflictos. Además de eso no valen nada. Git elimina por defecto el reflog después de 3 meses y descarta las revisiones anteriores.

  • Utiliza rebase interactivo ( git rebase -iy git commit --amend) para reordenar, editar y limpiar los cambios para que cada uno realice un cambio lógicamente cerrado.

    Esto nuevamente crea un nuevo historial, esta vez con el beneficio adicional de que puede reestructurar los cambios para que tengan más sentido durante la revisión.

  • Pros:

    • no hay código obsoleto en revisión
    • vemos exactamente lo que se cambió durante el trabajo en la rama de características
  • Contras:
    • un poco mas de trabajo
    • debe tener cuidado de no volver a crear nada que ya esté fusionado o que haya compartido, y el destinatario no espera que se rebobine.

Por lo general, el trabajo adicional significa que primero debe revisar el código usted mismo y eso también detectará muchos problemas.

Esto es lo que hacen Linux y Git. Y no es inusual ver series de 20 a 25 parches enviados para su revisión y reescritos varias veces en esos proyectos.

En realidad, Linux lo hizo desde el principio del proyecto cuando su control de versión elegido era tarballs y parches. Cuando muchos años después, Linus se propuso crear git, fue la razón principal para implementar el rebasecomando y su variante interactiva. También debido a esto, git tiene una noción separada de autor y confirmador . El autor es quien creó la revisión por primera vez y el confirmador es quien la tocó por última vez. Dado que tanto en Linux como en Git, los parches todavía se envían por correo electrónico, los dos casi nunca son la misma persona.

Jan Hudec
fuente
1
+1 también el OP no preguntó sobre los siguientes pasos, pero para obtener su función en master, podría usar una merge --no-ffque muestre claramente esa rama en master en lugar de que la función desaparezca en el resto de los commits
hasta el
@stijn: --no-fftiene sus altibajos . Personalmente me parece más ruido que cualquier otra cosa. YMMV.
Jan Hudec
sí, es una cuestión de preferencia. Si el master normalmente es limpio y directo, no me importa que las características grandes tengan una "burbuja" separada. Si maestro es un desastre ya, sin ff lo agrava
stijn
Ojalá pudiera aceptar el modo de una respuesta. Una solución híbrida sería ideal. Usar rebase y luego comparar con el punto de ramificación parece ser la mejor manera de hacerlo.
Andrzej Gis
Segunda estafa: no creo que pueda hacer esto si ya ha compartido su sucursal con alguien. Cuando reescribes el historial habrá inconsistencias.
sixtyfootersdude
4

En realidad, existe una tercera posibilidad, y muy probablemente muchas otras, ya que GIT es más una implementación de un marco SCM que una implementación de una metodología SCM. Esta tercera posibilidad se basa en rebase.

El rebasesubcomando GIT toma una serie de commit (generalmente desde su punto de ramificación hasta la punta de su rama temática topic) y los reproduce en otro lugar (típicamente en la punta de su rama de integración, por ejemplo master). El rebasesubcomando produce nuevas confirmaciones, lo que brinda la oportunidad de reorganizar las confirmaciones de una forma que es más fácil de revisar. Esto produce una nueva serie de commit, similar a lo que topicsolía ser pero que aparece arraigado en la parte superior de la rama de integración. topicGIT todavía llama a esta nueva rama , por lo que se descarta la referencia anterior. Etiqueto informalmente topic-0el estado original de su sucursal topic-1y así sucesivamente sus diversas refactorizaciones.

Aquí está mi sugerencia para su topicsucursal:

  1. (Paso opcional) Reorganiza interactivamente la rama de su tema topicen su punto de ramificación (vea la --fixupopción para commity las opciones -iy --autosquashen rebase), lo que le brinda la oportunidad de reescribir sus confirmaciones de una manera que sea más fácil de revisar. Esto da como resultado una rama topic-1.

  2. Reorganiza su rama de tema en la parte superior de su rama de integración, es similar a hacer una fusión, pero "no contamina" el historial con una fusión que no es más que un artefacto de ingeniería de software. Esto da como resultado una rama topic-2.

  3. Enviar topic-2a un compañero de equipo que lo revisa en contra de la punta de master.

  4. Si topic-2está bien, combínalo con master.

NOTA: Las ramas, donde rama se refiere al árbol de confirmación, serán todas llamadas por GIT, por lo tanto, al final del proceso, solo la rama topic-2tiene un nombre en GIT.

Pros:

  • No hay código obsoleto en revisión.
  • No hay revisiones espurias de "fusiones extranjeras" (el fenómeno que describió en 1er).
  • Oportunidad de reescribir los compromisos de una manera limpia.

Contras:

  • En lugar de una rama topic-0, hay tres artefactos ramas topic-0, topic-1y topic-2que se crean en el árbol de confirmación. (Aunque en cualquier momento, solo uno de ellos tiene un nombre en GIT).

En su primer escenario «si alguien fusionó algo entre" 1 ". y "2." »se refiere al tiempo que transcurre entre la creación del punto de ramificación y el momento en que decide fusionarse. En este escenario «si alguien fusionó algo entre" 1 ". y "2." »se refiere al tiempo que transcurre entre el rebase y la fusión, que generalmente es muy corto. Por lo tanto, en el escenario que proporciono, puede "bloquear" la masterrama durante el tiempo de la fusión sin perturbar significativamente su flujo de trabajo, mientras que no es práctico en el primer escenario.

Si está realizando revisiones sistemáticas de código, probablemente sea una buena idea reorganizar las confirmaciones de manera adecuada (paso opcional).

La gestión de los artefactos de rama intermedios solo presenta una dificultad si los comparte entre repositorios.

Michael Le Barbier Grünewald
fuente
No debería haber topic-0, topic-1y topic-2ramas. En el segundo en que se completa el rebase, la versión anterior es irrelevante. Así que todo lo que habría es topic@{1}, topic@{2}, topic@{yesterday}, topic@{3.days.ago}etc, para guardar su trasero en caso de que encuentre usted estropeó la resolución de conflictos en el rebase.
Jan Hudec
Las tres ramas existen, pero no tienen nombre (sin referencia). Quizás debería enfatizar esto.
Michael Le Barbier Grünewald
Las revisiones existen y son apuntadas por las entradas de reflog. Pero como ramas solo hay una topic,. Porque rama en git es solo el nombre.
Jan Hudec
¿Cómo me salva de "fusiones extranjeras"? ¿Qué sucede si alguien se fusiona con el maestro después de enviar el tema 2 a un compañero de equipo y que el compañero de equipo lo revisa contra la punta del maestro?
Andrzej Gis
@JanHudec En cualquier momento, sólo hay una rama llamada topicen GIT, siempre es una de las ramas (una rama de árbol como en cometer, no como en la referencia GIT) etiqueté topic-0, topic-1, topic-2.
Michael Le Barbier Grünewald