¿Qué hace hg copy?

Hace poco hicimos una hg copy de un directory en nuestro repository. Pensamos que hace algo así como cp -a y hg add y tal vez marcar de alguna manera que este file ha sido copydo de otro file dentro del repository (para que hg annotate muestre el committer original). Pero ahora parece que hg copy hace más o cosas diferentes que eso. Realmente no pude encontrar mucho sobre cómo funciona exactamente la copy. Asi que:

  • ¿Qué hace exactamente hg copy y qué tratamiento especial causa esto en el futuro?
  • Si resulta ser "lo incorrecto ™" en nuestro caso, ¿cómo desmarca el file como una copy de otro file?

(Esta pregunta se hizo en la list de correo de Mercurial, es posible que desee seguir el hilo original también).

  • ¿Qué hace exactamente hg copy y qué tratamiento especial causa esto en el futuro?

Agrega nuevos files y los marca como copys de los files antiguos. Debido a que son copys, un cambio realizado en el file original se fusionará en copy. El time fluye de izquierda a derecha:

 (init) --- (edit a.txt) ---- (a.txt edit is copied to b.txt) \ / (hg copy a.txt b.txt) 
  • Si resulta que 'hacemos lo incorrecto ™' en nuestro caso, ¿cómo desmarca el file como una copy de otro file?

Este mecanismo solo se activa cuando se fusiona. Si b.txt no está presente en la revisión ancestral común (init en el gráfico anterior), entonces Mercurial hará una búsqueda hacia atrás para ver si b.txt se copy desde otro lugar.

Continuemos el gráfico anterior en forma abreviada:

 (i) -- (edit a) -- (a edit copied to b) -- (edit a) -- (merge) \ / / (copy ab) --/------- (edit b) ------------------/ 

La pregunta es cómo se realiza la fusión final. El punto ancestro común ahora es el nodo copy ab y aquí están presentes tanto a como b . ¡Esto significa que no habrá ninguna búsqueda de copys! Por lo tanto, la segunda edición no se combinará en b .

Para verificarlo, lo probé:

 $ hg init $ echo a > a $ hg add a $ hg commit -m init $ hg copy ab $ hg commit -m "copy ab" 

Esta fue la copy, b ahora contiene a única.

 $ hg update 0 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ echo aa >> a $ hg commit -m "edit a" created a new head $ hg merge merging a and b to b 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg commit -m "a edit copied to b" 

Esta fue la primera combinación y la edición de a se ha copydo en b :

 $ cat b a aa 

Ahora hacemos cambios en paralelo:

 $ echo aaa >> a $ hg commit -m "edit a again" $ hg update 3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo bbb >> b $ hg commit -m "edit b" created new head $ hg merge 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) 

No hay más copys hechas:

 $ cat a a aa aaa $ cat b a aa bbb 

En cuanto a deshabilitar esto … no se puede deshabilitar explícitamente la detección de copy. Pero como espero haber ilustrado anteriormente, no te "molestará" de nuevo después de la primera fusión.

Si la primera combinación es un problema, puede usar hg resolve --tool internal:local para restablecer los files a su estado anterior a la fusión. Entonces con

 $ hg resolve --tool internal:local b 

podríamos haber traído b a solo contener una línea con a .