generando diferencias entre dos twigs, después de una revisión parcial

Digamos que tengo esta situación en git:

B---D---F---H---J---K--->topic / / / A---C---E---G---I--->master 

Después de llegar tan lejos como para confirmar F, presento la twig de tema para su revisión. El revisor hace algunas sugerencias, y el mundo avanza, por lo que se realiza otra fusión. Como se responde aquí, ¿se diferencia Git en la twig de tema, excluyendo las confusiones de fusión que ocurrieron mientras tanto? la forma de generar la diferencia de A a F simplemente git diff master..topic . Ahora, sin embargo, las revisiones B y D ya se han revisado, y me gustaría excluirlas de una nueva diferencia para su revisión. git diff E..topic incluye G e I sin embargo.

¿Cómo obtengo una diferencia de H, J y K, excluyendo las cosas atrapadas a través de G e I?

Excepto en algunos casos especiales que implican diffs de fusión (cuando se puede usar --combined ), las diferencias de confirmación siempre son par-wise. Esto cambia la forma en que se interpreta x..y . En lugar de este significado, "todas las revoluciones alcanzables desde y que no son alcanzables desde x ", significa "comparar la revolución con la revolución".

(Vale la pena señalar aquí que la respuesta en la pregunta vinculada pasa por alto el hecho de que x..y se interpreta de manera diferente en git diff que en otros commands de git).

Cuando solicitas E..topic , git resuelve el topic en un compromiso específico, en este caso K y luego compara el tree en E con el tree en K Es por eso que ve cambios de G e I , porque esos cambios se introdujeron a través de J través de la fusión.

Podría comparar F y K , pero esto todavía mostrará los cambios en G e I , porque de nuevo, esos cambios están realmente en J

De hecho, hay solo una forma de ignorar lo que sucedió en J , manteniendo F y H intactos así, y eso es build un tree que lo omita o lo revierte. Por ejemplo, comenzando en H , podría agregar un parche basado en la diferencia entre J y K :

  K' <-- HEAD[detached] / B---D---F---H---J---K <-- topic / / / A---C---E---G---I <-- master 

(para hacer esto, git checkout topic~2 para desprenderse en commit H , luego git cherry-pick topic para agregar, a su HEAD ahora separado, los cambios hechos para pasar de J a K ).

Ahora puedes comparar el tree en commit E con el tree en HEAD (en commit K' ):

 git diff E HEAD # or git diff E..HEAD or git diff E.. 

Pero eso no es, en general, lo que la gente quiere revisar. De hecho, dado que seguramente abandonará rev K' completo (generando solo para fines de revisión), ¡revisarán una versión del código que nunca se usa!

Esta es la razón por la que la respuesta aceptada a la pregunta vinculada es simplemente git diff master..topic que significa exactamente lo mismo que el git diff master topic , y en este caso compara el tree para I con el tree para K Está proponiendo enviar, en topic sucursal, un tree que se parece a K Ese es el código que estará en el topic . Tiene alguna diferencia con el código que está en rev I en el master . La diferencia que tiene para I es la sum de los cambios en F , H , K y cualquier trabajo de corrección que se hizo para hacer que J encaja. Tiene los cambios hechos en G (y por supuesto los en I mismo) pero esos no son cambios a I , esos son meramente cambios incorporados en I

Una forma más completa de revisar el código es presentar cuatro diffs para su revisión:

  1. E contra F
  2. F vs H
  3. H vs J (quizás una diferencia combinada, H -y- I frente a J )
  4. J vs K

El primer diff le dice a sus revisores que, si lo aceptan, será posible verificar un tree que se ve como F (que es cierto, simplemente git checkout F ). La segunda diferencia le dice a sus revisores que, al tener F en sus repositorys, será posible verificar H (si aceptan eso), etc. Obviamente cuatro revisiones son más difíciles que una, razón por la cual la gente acepta accesos directos como comparar I vs K

La sugerencia de torek (hacer múltiples revisiones) es una posibilidad, pero tiene el desafortunado efecto secundario de significar que el código que se dice necesita mejorar después de F y se lo fija en H debe ser revisado dos veces: una vez en su estado bajo par, y una vez cuando ha sido terminado. Lo bueno de git diff master..topic fue que aplastó estos, y solo dio la diferencia final entre las twigs.

Lo que hice para resolver el problema fue crear una twig desde F , fusionar el master hasta allí y luego hacer una diferencia entre mi nueva twig temporal y la twig de topic . De esta forma, se pasaron por alto todos los cambios en el master , y solo se utilizan los cambios en la twig del topic desde el punto de revisión anterior.