2012-03-27 5 views
12

A volte trovo di avere un file che nel tempo è cresciuto fino a contenere più classi/funzioni/elementi di cui mi piace. È tempo di refactoring! Di solito in questo caso trovo che il mio unico file diventi più: stesso più molti altri file, ciascuno contenente segmenti distinti del file.Va bene "abusare" della funzionalità di rinomina di Mercurial per tracciare il movimento dei blocchi di codice?

Sfortunatamente, la creazione di questi nuovi file "interrompe" la cronologia un po '- è difficile dire che queste funzioni originariamente provenivano da un altro file. È anche peggio se ci sono state altre modifiche apportate al codice durante il refactoring.

Uno dei miei colleghi ha scoperto che poteva "abusare" della funzionalità rinomina facendo qualcosa di simile:

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 

Il risultato è che ciascuno dei nuovi file si presenta come una ridenominazione con il resto del file rimosso e il file originale sembra aver perso i blocchi rimossi. Finora, questo sembra l'ideale. Tuttavia, sono preoccupato che questi rinvii multipli causeranno confuse fusioni lungo la linea.

C'è qualcosa di sbagliato in questo approccio "rinominare più volte"?

risposta

9

Prima di procedere, assicurati di averlo know what hg copy really means.

In breve, la copia di un file da original_file a new_file_1 aggiunge un collegamento che Mercurial userà in futuro si fonde se e solo se non riesce a trovare new_file_1 nella antenato comune. In genere ciò si verifica solo nella prima unione dopo aver eseguito la copia.

Un grafico potrebbe illustrare meglio questo:

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

Si comincia con un changeset in cui si dispone del file old. Quindi modificare old su un ramo e copiare old in new in un altro. Nella prima unione la modifica a old viene copiata in new. Nella seconda unione non è previsto alcun trattamento speciale per new poiché new si trova nell'antenato comune (il changeset copy old new).

Ciò significa che c'è una grande differenza nelle fusioni future a seconda di quando le persone vedono lo copy old new. Se puoi far usare a tutti il ​​numero

come punto di partenza, quindi le cose vanno bene. Ma se qualcuno si dirama dal changeset old e ha effettivamente modificato old in quel ramo, allora otterranno conflitti di unione quando tentano di unirsi con il changeset copy old new.

Più precisamente, ottengono conflitti di unione se hanno modificato qualsiasi parte del file old che non è stata copiata nel file new.I conflitti di unione segnalano il fatto che è stato apportato un cambiamento in old che deve essere copiato in new. Tuttavia, quando lo hai fatto davvero

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

allora avrai conflitti di fusione irrilevanti in due dei tre nuovi file.

Se si era appena eliminato il file old e ha aggiunto tre nuovi file, allora si dovrebbe comunque ottenere un conflitto di unione qui: ti verrà chiesto

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

Se si preferisce vedere che pronta o vedere la Unisci strumento di avvio dipende da te - ma ora conosci le conseguenze di hg copy (o hg rename --after, è davvero la stessa cosa).

+0

Fantastico! Grazie per la risposta dettagliata! –

8

Più facile è quello di utilizzare hg copy per questo:

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

Ora tutti e 3 hanno la storia originale. Ma, sì, in entrambi i casi questo è perfettamente a posto e comunemente fatto.

Problemi correlati