2012-03-27 9 views
12

A veces encuentro que tengo un archivo que con el tiempo ha crecido para contener más clases/funciones/elementos que me gustan. ¡Es hora de refactorizar! Generalmente encuentro en este caso que mi único archivo se convierte en varios: en sí mismo más varios otros archivos, cada uno con distintos segmentos del archivo.¿Está bien "abusar" de la funcionalidad de cambio de nombre de Mercurial para seguir el movimiento de los bloques de código?

Desafortunadamente, la simple creación de estos archivos nuevos "rompe" la historia un poco, es difícil decir que esas funciones originalmente provenían de otro archivo. Es aún peor si se hicieron otros cambios en el código durante la refactorización.

Uno de mis compañeros de trabajo descubrió que podía "abusar" la funcionalidad de cambio de nombre al hacer algo como esto:

hg rename --after original_file new_file_1 
hg rename --after original_file new_file_2 
hg rename --after original_file new_file_3 
hg add original_file 

El resultado es que cada uno de los nuevos archivos se ve como un cambio de nombre con el resto del archivo eliminado, y el archivo original parece que perdió los bloques eliminados. Hasta ahora, esto parece ideal. Sin embargo, me preocupa que estos múltiples cambios de nombre vayan a causar confusas fusiones más adelante.

¿Hay algún problema con este enfoque de "cambiar el nombre de varias veces"?

Respuesta

9

Debe asegurarse de que know what hg copy really means antes de hacer esto.

En resumen, la copia de un archivo de original_file a new_file_1 añade un enlace que Mercurial usará en el futuro se funde si y sólo si que no puede encontrar new_file_1 en el ancestro común. Normalmente, este solo será el caso en la primera fusión después de hacer la copia.

Un gráfico puede ilustrar esto mejor:

old --- edit old --- edit in old copied to new --- edit old --- merge 
    \    /       /
    copy old new --/------- edit new ------------/ 

Empezamos con un conjunto de cambios en la que tiene el archivo old. A continuación, edite old en una rama y copie old en new en otra. En la primera fusión, la edición a old se copia en new. En la segunda fusión no existe un tratamiento especial para new ya que new se encuentra en el antecesor común (el conjunto de cambios copy old new).

Lo que esto significa para su caso es que hay una gran diferencia en las fusiones futuras dependiendo de cuándo las personas vean el copy old new. Si puede hacer que todos usen

old --- copy old new 

como punto de partida, entonces todo está bien. Pero si alguien tiene ramas fuera del conjunto de cambios old y realmente editó old en esa rama, entonces obtendrán conflictos de combinación cuando intenten fusionarse con el conjunto de cambios copy old new.

Más precisamente, obtienen conflictos de combinación si han editado alguna parte del archivo old que no se ha copiado en el archivo new.Los conflictos de combinación lo alertan sobre el hecho de que hubo un cambio en old que debe copiarse en new. Sin embargo, cuando realmente lo hizo

hg copy old new1 
hg copy old new2 
hg copy old new3 

entonces obtendrá conflictos de fusión irrelevantes en dos de los tres archivos nuevos.

Si acaba de borrar el archivo old y ha añadido tres nuevos archivos, a continuación, a pesar de ello obtener un conflicto de combinación aquí: se le pedirá

remove changed old which local deleted 
use (c)hanged version or leave (d)eleted? 

Si se prefiere ver que pronto o ver el El inicio de la herramienta de fusión depende de usted, pero ahora usted sabe las consecuencias de hg copy (o hg rename --after, es realmente lo mismo).

+0

¡Impresionante! ¡Gracias por la respuesta detallada! –

8

más fácil es utilizar hg copy para ello:

hg copy original_file new_file_1 
hg copy original_file new_file_2 
hg copy original_file new_file_3 

Ahora los 3 tienen la historia inicial. Pero, sí, de cualquier manera esto está perfectamente bien y se hace comúnmente.

Cuestiones relacionadas