Conflicto que marca confusión al tirar de un file borrado con los darcs

Mi confusión surge de la siguiente statement tomada de aquí :

Cuando se ejecutan parches que entran en conflicto entre sí (p. Ej., Cambian la misma parte del file), Darcs detecta el conflicto y lo marca en el contenido del repository. Luego deja que el usuario resuelva el problema.

Esto parecía inconsistente con lo que estaba viendo, así que creé el siguiente flujo de trabajo usando darcs 2.5.2:

  1. Crear repo foo;
  2. Cree un file no vacío en foo y grábelo;
  3. Clonar foo a bar;
  4. Eliminar el file en foo y grabarlo;
  5. Agregue otra línea al file en la barra y grábela;
  6. Tirar de foo en la barra, get notificación de conflicto;

Después de seguir estos pasos, ejecuté darcs whatsnew en la barra, y me mostraron dos 'primitivos de parche':

  1. Un hunk eliminando todo el "file no vacío en foo", pero sin mencionar la línea agregada y grabada en la barra;
  2. A rmfile eliminando el file.

Mi pregunta es: ¿por qué no se menciona la línea agregada y grabada en la barra?

Si ejecuto darcs revert en la barra, todo tiene sentido: veo el "file no vacío" afectado por ninguno de los parches en conflicto, según esta statement tomada desde aquí :

El command darcs revert eliminará la marca del conflicto y hará una copy de security para indicar el estado anterior a los parches conflictivos.

Pero luego, si ejecuto darcs mark-conflicts , vuelvo al mismo estado que después del pull, con los dos 'primitivos del parche' mencionados anteriormente, y sin mencionar la línea agregada y grabada en la barra.


Para reference / reproducción aquí está mi flujo de trabajo completo desde la línea de command:

 $ mkdir foo $ cd foo/ foo$ darcs initialize foo$ touch shopping foo$ vi shopping <-- add a couple of lines foo$ darcs add shopping foo$ darcs record addfile ./shopping Shall I record this change? (1/2) [ynW...], or ? for more options: y hunk ./shopping 1 +cake +pie Shall I record this change? (2/2) [ynW...], or ? for more options: y What is the patch name? Added shopping Do you want to add a long comment? [yn]n Finished recording patch 'Added shopping' foo$ cd .. $ darcs get foo/ bar $ cd bar/ bar$ vi shopping <-- add another line bar$ darcs record hunk ./shopping 2 +beer Shall I record this change? (1/1) [ynW...], or ? for more options: y What is the patch name? Added beer Do you want to add a long comment? [yn]n Finished recording patch 'Added beer' bar$ cd ../foo foo$ rm shopping foo$ darcs record hunk ./shopping 1 -cake -pie Shall I record this change? (1/2) [ynW...], or ? for more options: y rmfile ./shopping Shall I record this change? (2/2) [ynW...], or ? for more options: y What is the patch name? Removed shopping Do you want to add a long comment? [yn]n Finished recording patch 'Removed shopping' foo$ cd ../bar bar$ darcs pull Pulling from "../foo"... Mon Nov 14 19:26:44 GMT 2011 dukedave@gmail.com * Removed shopping Shall I pull this patch? (1/1) [ynW...], or ? for more options: y Backing up ./shopping(-darcs-backup0) We have conflicts in the following files: ./shopping Finished pulling and applying. bar$ darcs whatsnew hunk ./shopping 1 -cake -pie rmfile ./shopping 

Si ejecuta darcs changes -v dentro de la barra, verá el historial de los cambios, incluido el conflicto que se presentó como resultado de la extracción de parches conflictivos.

He resumido tu ejemplo en algo siempre más corto:

 DARCS=/usr/bin/darcs $DARCS init --repo foo cd foo echo 'a' > myfile $DARCS add myfile && $DARCS record -am 'Add myfile' $DARCS get . ../bar rm myfile $DARCS record -am 'Remove myfile' cd ../bar echo 'b' >> myfile $DARCS record -am 'Change myfile' $DARCS pull -a ../foo $DARCS changes -v 

Ahora, después de eso, veo esta salida de los darcs changes -v

 Tue Nov 15 19:44:38 GMT 2011 Owen Stephens <darcs@owenstephens.co.uk> * Remove myfile conflictor [ hunk ./myfile 2 +b ] |: hunk ./myfile 1 -a conflictor {{ |: hunk ./myfile 2 +b |: hunk ./myfile 1 -a }} [] |hunk ./myfile 1 |-a |: rmfile ./myfile Tue Nov 15 19:44:38 GMT 2011 Owen Stephens <darcs@owenstephens.co.uk> * Change myfile hunk ./myfile 2 +b Tue Nov 15 19:44:38 GMT 2011 Owen Stephens <darcs@owenstephens.co.uk> * Add myfile addfile ./myfile hunk ./myfile 1 +a 

Entonces, expliquemos el loco resultado de "Eliminar mi file". "Eliminar mi file" existe como sigue en foo:

 Tue Nov 15 19:44:38 GMT 2011 Owen Stephens <darcs@owenstephens.co.uk> * Remove myfile hunk ./myfile 1 -a rmfile ./myfile 

Entonces, un hunk en la línea 1 y eliminación del file.

Tirando de "eliminar mifile" en la barra, modificamos el contenido del parche introduciendo primitivas especiales "conflictivas" que representan las primitivas dentro de "Quitar mifile" que entran en conflicto con otras primitivas en la barra. Nb no hay pérdida de información aquí; siempre podemos volver a las primitivas originales anulando los cambios conflictivos, en este caso, anulando "change myfile".

Los conflictos son confusos, pero AFAICT esencialmente separa los cambios que entran en conflicto con un parche actual, x en 2 sets: "ix", que es el set de parches que incluye: i) parches que entran en conflicto con x y algún otro parche en el informe ii) parches que entran en conflicto con un parche que entra en conflicto con x "xx", que es la secuencia de parches que solo entran en conflicto con el parche x. Creo que la razón por la que esto se hace es que los Conflictores tienen el efecto de "deshacer" primitivas que causan conflictos, pero solo aquellas que no han sido destruidas por otro Conflictor.

El resultado que vemos es algo así como:

 "conflictor" ix "[" xx "]" x 

Estoy abusando de la notación, pero espero que puedas descifrar algo de eso (mira src / Darcs / Patch / V2 / (Real.hs | Non.hs) en el repository de darcs.net para la historia completa)

En este caso, "Eliminar mifile" tiene 2 parches primitivos y (en este caso) 2 conflictos conflictivos cuando se los tira a la barra.

La primera primitiva (eliminar la línea 1 de myfile) solo entra en conflicto con la primitiva dentro de "Change myfile" (agrega "b" a la línea 2 de mifile) y ese es el primer conflicto:

 conflictor [ <--- The start of xx (no ix here) hunk ./myfile 2 +b ] <--- The end of xx |: hunk ./myfile 1 <--- x -a 

NB ("|:" es un marcador que delimita el context de un primitve "No" de la primitiva misma; no intentaré explicarlo más, solo leo debajo: para ver el primitivo en cuestión)

La segunda primitiva (eliminar mifile) es solo un poco más complicada: (rmfile mifile) entra en conflicto con (agrega 'b' a la línea 2 de mifile) que, como sabemos, entra en conflicto (elimina la línea 1 de mifile), así que ambos entran " ix ", sin parches en" xx ". Eliminaré los delimitadores innecesarios "|:" y espaciaré las cosas:

 conflictor {{ hunk ./myfile 2 +b hunk ./myfile 1 -a }} [] <--- no xx |hunk ./myfile 1 <--- start of x |-a |: rmfile ./myfile <--- end of x 

El file mfile final (rmfile) tiene un context para identificar la primitiva exacta a la que nos referimos (no estoy seguro de por qué / cómo se requiere esto, pero ahí estamos), que está marcado por los | ' delimitado por "|:".

Finalmente, intentar explicar la salida de darcs whatsnew in foo; cuando hay varios parches en conflicto, creo que el efecto real del conflicto es "deshacer" cualquier parche en conflicto, sin dar el efecto de ninguno; da el comienzo de algunas explicaciones: http://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory_and_conflicts .

Creo que lo que está viendo es el resultado de la conmutación forzada de "Change myfile" y "Remove myfile", llámalos A y B respectivamente. Luego, para fusionar los dos, Darcs crea A^-1 y conmuta A^-1 y B para dar B' y (A^-1)' donde B' tiene el efecto de A^-1 (ya que estamos forzando el conmutación al trabajo), lo que significa que el efecto de B' (es decir, la combinación "eliminar mifile") es simplemente deshacer la adición de la línea realizada por "Cambiar mi file".

No he tenido time de ver cómo darcs mark-conflicts , por lo que aún no puedo explicar los cambios de trabajo que está viendo con los darcs changes de barras en la barra.