Tutorial - risolvere i conflitti tra modifiche
Abbiamo così imparato come effettuare un semplice merge in TutorialEffettuareMerge.
Mercurial gestisce anche casi più complessi. Non è strano che due persone modifichino esattamente le stesse linee di un file; in questo caso bisogna sapere cosa fare. Questi casi sono chiamati conflitti; il primo passo per risolverli è immaginarsi come accadano.
Creiamo una situazione artificiale di conflitto. Come fatto in precedenza, iniziamo clonanod my-hello:
$ cd .. $ hg clone my-hello my-hello-not-cvs
Ora aggiungiamo una nuova linea di output a hello.c:
$ cd my-hello-not-cvs $ vi hello.c
Cambiamo così il main:
int main(int argc, char **argv)
{
printf("hello, world!\n");
printf("sure am glad I'm not using CVS!\n");
return 0;
}
Inseguito commentiamo la modifica:
$ hg commit -m "Give thanks for dodging bullet"
Facciamo riferimento a TutorialPrimaModifica e creiamo un changeset in my-hello-new-output al quale è aggiunta già una seconda linea di output Che succede quando proviamo a eseguire l pull?
$ hg pull ../my-hello-new-output pulling from ../my-hello-new-output searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge)
Eseguiamo l'update.
$ hg update abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
cfr. anche Branch
Come in TutorialEffettuareMerge, dobbiamo lanciare hg merge. Come prima, il programma di merge si eseguirà automaticamente.
$ hg merge
- Se siamo stati attenti, o fortunati, ed è installato un programma di merge, potremo vedere cosa è in conflitto tra le due modifiche e decidere come risolvere il problema.
Qui sotto ecco l'esempio del messaggio che mostra il conflitto in vim sotto Linux.
/* * hello.c * * Placed in the public domain by Bryan O'Sullivan * * This program is not covered by patents in the United States or other * countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("hello, world!\n"); <<<<<<< /home/motoko/project/my-hello-not-cvs/hello.c.orig.197516148 printf("sure am glad I'm not using CVS!\n"); ||||||| /tmp/hello.c~base.aYR8Pf ======= printf("sure am glad I'm using Mercurial!\n"); >>>>>>> /tmp/hello.c~other.F7OpXy return 0; }
Mercurial usa un merg a 3 vie per ogni file. Questo vuol dire che ci sono tre file di input per ogni processo di unificazione( merge ). Si tratta di:
- File locali(dal repository corrente)
- Altri file(dal repository che deve essere unito)
- File di base(ultima versione del file prima che si separassero le ramificazioni)
Per più informazioni riguardo alle 3 vie controllare ThreeWayMerge su Revctrl wiki.
Tuttavia, se non dovessimo avere un programma a interfaccia grafica di merge installato, saremo portati ad un editor di testo, che visiterà il file che dobbiamo unire. Facendo tutto ciò a mano c'è il rischio di fare errori e l'operazione comunque resta noiosa. E' meglio uscire dall'editor e usare il comando hg rollback per annullare l'effetto del pull, installare poi un programma di merge e provare di nuovo.
(NB: prima della versione 0.9 di Mercurial, si sarebbe dovuto usare il comandohg update -m al posto di hg merge o hg undo invece di hg rollback)