Now you and Sally are working on parallel branches of the project: you're working on a private branch, and Sally is working on the trunk, or main line of development.
Adesso voi e Sally state lavorando sui rami paralleli del progetto: voi lavorate su un ramo privato e Sally lavora su tronco (trunk), o linea principale dello sviluppo.
For projects that have a large number of contributors, it's common for most people to have working copies of the trunk. Whenever someone needs to make a long-running change that is likely to disrupt the trunk, a standard procedure is to create a private branch and commit changes there until all the work is complete.
Per progetti che hanno grande numero di contribuenti, è comune per molta gente di avere copie di lavoro del tronco. Ogni volta che qualcuno ha bisogno di fare durature modifiche, che potrebbero disturbare il tronco, procedura standard è di creare un ramo privato e pubblicare le modifiche là finché tutto il lavoro no è completo.
So, the good news is that you and Sally aren't interfering with each other. The bad news is that it's very easy to drift too far apart. Remember that one of the problems with the “crawl in a hole” strategy is that by the time you're finished with your branch, it may be near-impossible to merge your changes back into the trunk without a huge number of conflicts.
Allora, la notizia buona è che voi e Sally non vi disturbate a vicenda. La cativa è che è molto facile slittare tropo lontano. Ricordate che uno dei problemi della strategia «nascondersi in una buca» è che quando avrete finito con il vostro ramo, potrebbe essere quasi impossibile fondere vostre modifiche nel tronco principale senza largo numero di conflitti.
Instead, you and Sally might continue to share changes as you work. It's up to you to decide which changes are worth sharing; Subversion gives you the ability to selectively “copy” changes between branches. And when you're completely finished with your branch, your entire set of branch changes can be copied back into the trunk.
Invece, voi e Sally potette continuare di scambiarsi modifiche mentre lavorate. Spetta a voi decidere qualle modifiche vale la pena condividere; Subversion vi dà l'abilità di «copiare» modifiche tra i rami selettivamente. E quando avrete completamente finito con il vostro ramo, vostro completto insieme di modifiche del ramo può essere copiato dietro nel tronco.
In the previous section, we mentioned that both you and
Sally made changes to integer.c
on
different branches. If you look at Sally's log message for
revision 344, you can see that she fixed some spelling errors.
No doubt, your copy of the same file still has the same spelling
errors. It's likely that your future changes to this file will
be affecting the same areas that have the spelling errors, so
you're in for some potential conflicts when you merge your
branch someday. It's better, then, to receive Sally's change
now, before you start working too heavily
in the same places.
Nella precedente sezione, abbiamo menzionato che
entrambi, voi e Sally avete fatto modifiche su
integer.c
nei rami diversi.
Se date un sguardo al messaggio di log di Sally (versione
344), potete vedere che ella ha corretto qualche errore di battitura.
Senza dubbio, vostra copia dello stesso file ancora ha gli stessi
errori. È probabile che le vostre future modifiche al file toccheranno
gli stessi posti che hanno errori di battitura, così sorgeranno alcuni
potenziali conflitti, quando un giorno andrete a fondere il vostro ramo.
Meglio incorporare le modifiche di Sally adesso,
prima che cominciate lavoro troppo pesante
sugli stessi posti.
It's time to use the svn merge command. This command, it turns out, is a very close cousin to the svn diff command (which you read about in Chapter 3). Both commands are able to compare any two objects in the repository and describe the differences. For example, you can ask svn diff to show you the exact change made by Sally in revision 344:
È ora di usare comando svn merge. Questo comando, come si vedrà, è cugino molto stretto del comando svn diff (di quale avete letto nel Capitolo 3). Entrambi comandi sono capaci di comparare qualsiasi due oggetti in deposito(repository) e descrivere le differenze. Per esempio, potete chiedere a svn diff di mostrare esatta modifica fatta da Sally nella versione 344:
$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk
Index: integer.c
===================================================================
--- integer.c (revision 343)
+++ integer.c (revision 344)
@@ -147,7 +147,7 @@
case 6: sprintf(info->operating_system, "HPFS (OS/2 or NT)"); break;
case 7: sprintf(info->operating_system, "Macintosh"); break;
case 8: sprintf(info->operating_system, "Z-System"); break;
- case 9: sprintf(info->operating_system, "CPM"); break;
+ case 9: sprintf(info->operating_system, "CP/M"); break;
case 10: sprintf(info->operating_system, "TOPS-20"); break;
case 11: sprintf(info->operating_system, "NTFS (Windows NT)"); break;
case 12: sprintf(info->operating_system, "QDOS"); break;
@@ -164,7 +164,7 @@
low = (unsigned short) read_byte(gzfile); /* read LSB */
high = (unsigned short) read_byte(gzfile); /* read MSB */
high = high << 8; /* interpret MSB correctly */
- total = low + high; /* add them togethe for correct total */
+ total = low + high; /* add them together for correct total */
info->extra_header = (unsigned char *) my_malloc(total);
fread(info->extra_header, total, 1, gzfile);
@@ -241,7 +241,7 @@
Store the offset with ftell() ! */
if ((info->data_offset = ftell(gzfile))== -1) {
- printf("error: ftell() retturned -1.\n");
+ printf("error: ftell() returned -1.\n");
exit(1);
}
@@ -249,7 +249,7 @@
printf("I believe start of compressed data is %u\n", info->data_offset);
#endif
- /* Set postion eight bytes from the end of the file. */
+ /* Set position eight bytes from the end of the file. */
if (fseek(gzfile, -8, SEEK_END)) {
printf("error: fseek() returned non-zero\n");
$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk Index: integer.c =================================================================== --- integer.c (revision 343) +++ integer.c (revision 344) @@ -147,7 +147,7 @@ case 6: sprintf(info->operating_system, "HPFS (OS/2 or NT)"); break; case 7: sprintf(info->operating_system, "Macintosh"); break; case 8: sprintf(info->operating_system, "Z-System"); break; - case 9: sprintf(info->operating_system, "CPM"); break; + case 9: sprintf(info->operating_system, "CP/M"); break; case 10: sprintf(info->operating_system, "TOPS-20"); break; case 11: sprintf(info->operating_system, "NTFS (Windows NT)"); break; case 12: sprintf(info->operating_system, "QDOS"); break; @@ -164,7 +164,7 @@ low = (unsigned short) read_byte(gzfile); /* read LSB */ high = (unsigned short) read_byte(gzfile); /* read MSB */ high = high << 8; /* interpreta MSB correttamente */ - total = low + high; /* sommali inseme per un totale corretto */ + total = low + high; /* sommali insieme per un totale corretto */ info->extra_header = (unsigned char *) my_malloc(total); fread(info->extra_header, total, 1, gzfile); @@ -241,7 +241,7 @@ Memorizza offset con ftell() ! */ if ((info->data_offset = ftell(gzfile))== -1) { - printf("errore: ftell() ha resttituito -1.\n"); + printf("errore: ftell() ha restituito -1.\n"); exit(1); } @@ -249,7 +249,7 @@ printf("Credo che inizio dei dati compressi è %u\n", info->data_offset); #endif - /* Imposta poszione otto byte dalla fine del file. */ + /* Imposta posizione otto byte dalla fine del file. */ if (fseek(gzfile, -8, SEEK_END)) { printf("errore: fseek() ha restituito non-zero\n");
The svn merge command is almost exactly the same. Instead of printing the differences to your terminal, however, it applies them directly to your working copy as local modifications:
Il comando svn merge è quasi esattamente uguale. Invece di mostrare le differenze sullo schermo, tuttavia, le applica direttamente nella vostra copia di lavoro come modifiche locali:
$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status M integer.c
The output of svn merge shows that your
copy of integer.c
was patched. It now
contains Sally's change—the change has been
“copied” from the trunk to your working copy of
your private branch, and now exists as a local modification.
At this point, it's up to you to review the local modification
and make sure it works correctly.
L'output di svn merge mostra che vostra
copia di integer.c
era stata modificata. Adesso
contiene le modifiche di Sally—le modifiche erano state
«copiate» dal tronco nella copia di lavoro
del vostro ramo privato e adesso esistono come modifiche locali.
A questo punto, tocca a voi rivedere le modifiche locali ed assicurare
che funzionano correttamente.
In another scenario, it's possible that things may not have
gone so well, and that integer.c
may have
entered a conflicted state. You might need to resolve the
conflict using standard procedures (see Chapter 3), or if you
decide that the merge was a bad idea altogether, simply give up
and svn revert the local change.
In un altro scenario, è possibile che le cose possono non andare
così bene e perciò integer.c
può entrare
nello stato di conflitto. Potette avere bisogno di risolvere
il conflitto usando procedure standard (vedi Capitolo 3), oppure
se decidete che fusione era del tutto una cativa idea,
semplicemente passare sopra e scartare con svn revert
le modifiche locali.
But assuming that you've reviewed the merged change, you can svn commit the change as usual. At that point, the change has been merged into your repository branch. In version control terminology, this act of copying changes between branches is commonly called porting changes.
Ma assumendo che avete ispezionato le modifiche incorporate, potete pubblicarle con svn commit come al solito. A questo punto, la modifica sarà fusa dentro il vostro ramo del deposito(repository). Nella terminologia di controlo delle versioni, questo atto di copiatura delle modifiche tra i rami è comunemnte chaimato porting dele modifiche.
When you commit the local modification, make sure your log message mentions that you're porting a specific change from one branch to another. For example:
Facendo commit delle modifiche locali, assicuratevi che vostro messaggio menziona che state portando una modifica specifica da un ramo ad altro. Per esempio:
$ svn commit -m "integer.c: ported r344 (spelling fixes) from trunk."
Sending integer.c
Transmitting file data .
Committed revision 360.
$ svn commit -m "integer.c: portata r344 (fix di ortografia) dal tronco." Sending integer.c Transmitting file data . Committed revision 360.
As you'll see in the next sections, this is a very important “best practice” to follow.
Come vedrete nella prossima sezione, questa è molto importante «regola d'arte» da seguire.
A word of warning: while svn diff and svn merge are very similar in concept, they do have different syntax in many cases. Be sure to read about them in Chapter 9 for details, or ask svn help. For example, svn merge requires a working-copy path as a target, i.e. a place where it should apply the tree-changes. If the target isn't specified, it assumes you are trying to perform one of the following common operations:
Una parola di avvertimento: anche se svn diff e svn merge sono nel concetto molto simili, hanno in molti casi la sintassi diversa. Assicuratevi di leggere dettagli nel Capitolo 9 o chiedete lumi a svn help. Per esempio, svn merge richiede percorso di copia di lavoro come destinazione, i.e. un posto dove può applicare le modifiche della struttura. Se la destinazione non è specificata, assume che state provando di fare una delle seguenti comuni operazioni:
You want to merge directory changes into your current working directory.
Volete fondere modifiche delle cartelle nella vostra cartella di lavoro.
You want to merge the changes in a specific file into a file by the same name which exists in your current working directory.
Volete fondere le modifiche d'un file specifico dentro un file con lo stesso nome che esiste nella vostra cartella di lavoro.
If you are merging a directory and haven't specified a target path, svn merge assumes the first case above and tries to apply the changes into your current directory. If you are merging a file, and that file (or a file by the same name) exists in your current working directory, svn merge assumes the second case and tries to apply the changes to a local file with the same name.
Se state fondendo una cartella e non avete specificato percorso di destinazione, svn merge assume il primo caso sopra e prova applicare le modifiche dentro vostra cartella attuale. Se state fondendo un file e questo file (o un file con lo stesso nome) esiste dentro vostra cartella attuale, svn merge assume il secondo caso e prova applicare le modifiche dentro file locale con lo stesso nome.
If you want changes applied somewhere else, you'll need to say so. For example, if you're sitting in the parent directory of your working copy, you'll have to specify the target directory to receive the changes:
Se volete applicare le modifiche in un altro posto, dovete dirlo. Per esempio, se siete nella cartella parente della vostra copia di lavoro, dovete specificare cartella destinazione per ricevere le modifiche:
$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk my-calc-branch U my-calc-branch/integer.c
You've now seen an example of the svn merge command, and you're about to see several more. If you're feeling confused about exactly how merging works, you're not alone. Many users (especially those new to version control) are initially perplexed about the proper syntax of the command, and about how and when the feature should be used. But fear not, this command is actually much simpler than you think! There's a very easy technique for understanding exactly how svn merge behaves.
Abbiamo visto un esempio di comando svn merge, e stiamo per vedere di più. Se vi sentite confusi riguardo come funziona esattamente la fusione, non siete soli. Molti utenti (specialmente quelli nuovi a cotrollo delle versioni) rimangono inizialmente perplessi riguardo la giusta sintassi del comando e come e quando usare questa caratteristica. Non avere paura, questo comando è in verità molto più semplice che si pensa. C'è una tecnica molto semplice per capire esattamente come svn merge agisce.
The main source of confusion is the name of the command. The term “merge” somehow denotes that branches are combined together, or that there's some sort of mysterious blending of data going on. That's not the case. A better name for the command might have been svn diff-and-apply, because that's all that happens: two repository trees are compared, and the differences are applied to a working copy.
La fonte primaria della confusione è il nome del comando. Il termine «merge»(fondere) qualche volta denota che i rami sono combinati tra loro, oppure che ci sta qualche sorta di misterioso mescolamento dei dati. Non è il caso. Più appropriato nome per questo comando forse sarebbe svn diff-and-apply(trova-differenze-e-applicale), perché questo è tutto che accade: due strutture del deposito(repository) sono comparate e le differenze sono applicate alla copia di lavoro.
The command takes three arguments:
Il comando prende tre argomenti:
An initial repository tree (often called the left side of the comparison),
Una struttura del deposito(repository) iniziale (spesso chiamata il lato sinistro della comparazione),
A final repository tree (often called the right side of the comparison),
Una struttura del deposito(repository) finale (spesso chiamata il lato destro della comparazione),
A working copy to accept the differences as local changes (often called the target of the merge).
Una copia di lavoro per ricevere le differenze come modifiche locali (spesso chiamata la destinazione della fusione).
Once these three arguments are specified, the two trees are compared, and the resulting differences are applied to the target working copy as local modifications. When the command is done, the results are no different than if you had hand-edited the files, or run various svn add or svn delete commands yourself. If you like the results, you can commit them. If you don't like the results, you can simply svn revert all of the changes.
Una volta specificati questi tre argomenti, le due strutture sono comparate e le differenze risultanti sono applicate alla copia di lavoro destinataria come modifiche locali. Quando il comando finisce il suo lavoro, il risultato non è diverso da come aveste editato i file manualmente o aveste da soli avviato svariati comandi svn add o svn delete. Se il risultato vi piace, potete fare commit. Se non vi piace, con semplice comando svn revert scartate tutte le modifiche.
The syntax of svn merge allows you to specify the three necessary arguments rather flexibly. Here are some examples:
La sintassi di comando svn merge vi permete di specificare i tre argomenti necessari in modo molto flessibile Qui ci sono alcuni esempi:
$ svn merge http://svn.example.com/repos/branch1@150 \ http://svn.example.com/repos/branch2@212 \ my-working-copy $ svn merge -r 100:200 http://svn.example.com/repos/trunk my-working-copy $ svn merge -r 100:200 http://svn.example.com/repos/trunk
The first syntax lays out all three arguments explicitly, naming each tree in the form URL@REV and naming the working copy target. The second syntax can be used as a shorthand for situations when you're comparing two different revisions of the same URL. The last syntax shows how the working-copy argument is optional; if omitted, it defaults to the current directory.
La prima sintassi elenca tutti e tre argomenti esplicitamente, nominando ogni struttura in forma URL@REV e nominando la copia di lavoro ricevente. La seconda sintassi può essere usata, quando state comparando due versioni diverse dello stesso URL. L'ultima sintassi mostra che argomento 'copia di lavoro' è facoltativo; se omesso, il suo valore predefinito è la cartella attuale.
Merging changes sounds simple enough, but in practice it can become a headache. The problem is that if you repeatedly merge changes from one branch to another, you might accidentally merge the same change twice. When this happens, sometimes things will work fine. When patching a file, Subversion typically notices if the file already has the change, and does nothing. But if the already-existing change has been modified in any way, you'll get a conflict.
Fondere modifiche suona abbastanza semplice, ma in prattica può diventare mal di testa. Il problema è che se ripetutamente fondete modifiche da un ramo ad altro, potete accidentalmente fondere la stessa modifica due volte. Se succede questo, a volte tutto va bene. Quando Subversion applica le modifiche su un file, tipicamente si accorge che il file queste modifiche ha già e non fa niente. Ma se la già esistente modifica era ulteriormente modificata, otente un conflitto.
Ideally, your version control system should prevent the double-application of changes to a branch. It should automatically remember which changes a branch has already received, and be able to list them for you. It should use this information to help automate merges as much as possible.
Idealmente, vostro sistema di controlo delle versioni dovrebbe prevenire la doppia applicazione delle modifiche su un ramo. Dovrebbe automaticamente ricordare quale modifiche il ramo ha già ricevuto ed essere capace di elencarle per voi. Dovrebbe usare queste informazioni per automatizzare le fusioni quanto più possibile.
Unfortunately, Subversion is not such a system. Like CVS, Subversion does not yet record any information about merge operations. When you commit local modifications, the repository has no idea whether those changes came from running svn merge, or from just hand-editing the files.
Sfortunatamente, un sistema così non è Subversion. Come il CVS, Subversion non memorizza ancora nessuna informazione riguardo operazioni di fusioni. Quando fatte commit delle modifiche locali, il deposito(repository) non ha idea se queste modifiche arrivano da svn merge eseguito o da editazione a mano dei file.
What does this mean to you, the user? It means that until the day Subversion grows this feature, you'll have to track merge information yourself. The best place to do this is in the commit log-message. As demonstrated in the earlier example, it's recommended that your log-message mention a specific revision number (or range of revisions) that are being merged into your branch. Later on, you can run svn log to review which changes your branch already contains. This will allow you to carefully construct a subsequent svn merge command that won't be redundant with previously ported changes.
Che cosa significa questo per voi, utente? Significa che fino al giorno in cui Subversion avrà questa capacità, dovete tracciare informazioni riguardo le fusioni da soli. Il posto migliore dove farlo è messaggio di commit. Come era dimostrato nel esempio precedente, è raccomandato che vostro messaggio menziona specifico numero della revisione (o rango delle revisioni) che state fondendo nel vostro ramo. In futuro potete avviare comando svn log per vedere quale modifiche contiene già il vostro ramo. Questo vi permete di costruire con cura prossimi comandi svn merge che non saranno redundanti con le modifiche già riportate in precedenza.
In the next section, we'll show some examples of this technique in action.
Nella prossima sezione mostreremo in azione alcuni esempi di questa tecnica.
Because merging only results in local modifications, it's not usually a high-risk operation. If you get the merge wrong the first time, simply svn revert the changes and try again.
Perché risultato delle fusioni sono soltanto le modifiche locali, questa non è normalmente una operazione ad alto rischio. Se vi capita di fondere male prima volta, semplicemente buttate via le modifiche (svn revert) e provate di nuovo.
It's possible, however, that your working copy might already have local modifications. The changes applied by a merge will be mixed with your pre-existing ones, and running svn revert is no longer an option. The two sets of changes may be impossible to separate.
È possibile, comunque, che vostra copia di lavoro contiene anche le modifiche locali. Le modifiche applicate da merge saranno mischiate tra le vostre e avviare comando svn revert non è più una scelta pratticabile. Potrebbe essere impossibile separare i due insiemi delle modifiche.
In cases like this, people take comfort in being able to
predict or examine merges before they happen. One simple
way to do that is to run svn diff with
the same arguments you plan to pass to svn
merge, as we already showed in our first example
of merging. Another method of previewing is to pass the
--dry-run
option to the merge
command:
In casi come questo, le persone si confortano con la possibilità
di prevedere o esaminare fusione prima che accade. Un semplice
modo per farlo è avviare svn diff
con gli stessi argomenti che avete in mente di passare a
svn merge, come abbiamo già mostrato nel nostro
primo esempio. Altro metodo di anteprima è aggiungere la opzione
--dry-run
(a secco) al comando merge:
$ svn merge \-\-dry-run -r 343:344 http://svn.example.com/repos/calc/trunk
U integer.c
$ svn status
# nothing printed, working copy is still unchanged.
$ svn merge --dry-run -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status # non stampa niente, copia di lavoro è ancora intatta.
The --dry-run
option doesn't actually
apply any local changes to the working copy. It only shows
status codes that would be printed in a
real merge. It's useful for getting a “high
level” preview of the potential merge, for those
times when running svn diff gives too
much detail.
La opzione --dry-run
in verità non applica
nessuna modifica locale alla copia di lavoro. Mostra solo output
che sarebbe mostrato con la fusione vera.
Questo è utile per avere una previsione ad «alto
livello» della potenziale fusione, per quelle volte dove
comando svn diff dà troppi dettagli.
Just like the svn update command, svn merge applies changes to your working copy. And therefore it's also capable of creating conflicts. The conflicts produced by svn merge, however, are sometimes different, and this section explains those differences.
Così come comando svn update, anche svn merge applica modifiche alla vostra copia di lavoro. E perciò è capace generare conflitti. I conflitti prodotti da svn merge, tuttavia, sono a volte diversi e questa sezione spiega queste differenze.
To begin with, assume that your working copy has no local edits. When you svn update to a particular revision, the changes sent by the server will always apply “cleanly” to your working copy. The server produces the delta by comparing two trees: a virtual snapshot of your working copy, and the revision tree you're interested in. Because the left-hand side of the comparison is exactly equal to what you already have, the delta is guaranteed to correctly convert your working copy into the right-hand tree.
Per cominciare, si assume che vostra copia di lavoro non ha editazioni locali. Quando la aggiornate (svn update) ad una particolare versione, le modifiche mandate dal server si applicano sempre alla vostra copia di lavoro in modo «pulito». Il server produce un ??delta? comparando due strutture: un'instantanea virtuale della vostra copia di lavoro e struttura della revisione a quale siete interessati. Perché lato sinistra della comparazione è uguale a quel che già avete il delta garantisce di correttamente convertire vostra copia di lavoro nella struttura di lato destra.
But svn merge has no such guarantees and can be much more chaotic: the user can ask the server to compare any two trees at all, even ones that are unrelated to the working copy! This means there's large potential for human error. Users will sometimes compare the wrong two trees, creating a delta that doesn't apply cleanly. svn merge will do its best to apply as much of the delta as possible, but some parts may be impossible. Just like the Unix patch command sometimes complains about “failed hunks”, svn merge will complain about “skipped targets”:
Ma svn merge non ha tali garanzie e può essere più caotico: utente può chidere al server di comparare qualsiasi due strutture, anche tali che non hanno nessun legame con la copia di lavoro. Questo significa che qui c'è largo potenziale per errori umani. Utenti possono a volte comparare due strutture sbagliate, creando delta che non si applica pulitamente. svn merge farà il meglio per applicare più possibile il delta, ma su alcune parti questo potrà essere impossibile. Nello stesso modo come comando Unix patch a volte si lamenta di ??«failed hunks»?, svn merge può accusare «skipped targets» (destinazioni saltate):
$ svn merge -r 1288:1351 http://svn.example.com/repos/branch U foo.c U bar.c Skipped missing target: 'baz.c' U glub.c C glorb.h $
In the previous example it might be the case that
baz.c
exists in both snapshots of the
branch being compared, and the resulting delta wants to
change the file's contents, but the file doesn't exist in
the working copy. Whatever the case, the
“skipped” message means that the user is most
likely comparing the wrong two trees; they're the classic
sign of driver error. When this happens, it's easy to
recursively revert all the changes created by the merge
(svn revert --recursive), delete any
unversioned files or directories left behind after the
revert, and re-run svn merge with
different arguments.
Nel esempio precedente può essere caso che
baz.c
esiste in entrambe instantanee del
ramo comparato e delta risultante vuole cambiare il contenuto del
file, ma il file non esiste nella copia di lavoro.
Qualunque sia causa, il messaggio
«skipped»(saltato) significa che
con alta probabilità utente sta comparando le strutture sbagliate;
questo è un segno classico del 'errore del conducente'.
Quando accade ciò, è semplice invertire ricorsivamente tutte le
modifiche create dalla fusione (svn revert --recursive),
cancellare ogni file o cartella rimasta senza controllo delle versioni
dopo revert e rifare svn merge con argomenti
diversi.
Also notice that the previous example shows a conflict
happening on glorb.h
. We already
stated that the working copy has no local edits: how can a
conflict possibly happen? Again, because the user can use
svn merge to define and apply any old
delta to the working copy, that delta may contain textual
changes that don't cleanly apply to a working file, even if
the file has no local modifications.
Notare ancora che precedente esempio mostra un conflitto
accaduto su glorb.h
. Abbiamo già stabilito
che copia di lavoro non ha editazioni locali: come può allora
accadere un conflitto? Di nuovo, perché l'utente può usare
svn merge per definire ed applicare qualsiasi
delta vecchio a copia di lavoro, tale delta può contenere modifiche
testuali che non si applicano in modo pulito al file di lavoro,
anche se il file non ha le modifiche locali.
Another small difference between svn
update and svn merge are the
names of the full-text files created when a conflict
happens. In sezione chiamata «Risolvere i conflitti(Mettere insieme i cambiamenti operati da
altri)», we saw
that an update produces files named
filename.mine
,
filename.rOLDREV
, and
filename.rNEWREV
. When svn
merge produces a conflict, though, it creates
three files named filename.working
,
filename.left
, and
filename.right
. In this case, the
terms “left” and “right” are
describing which side of the double-tree comparison the file
came from. In any case, these differing names will help you
distinguish between conflicts that happened as a result of an
update versus ones that happened as a result of a
merge.
Altra piccola differenza tra svn update e
svn merge sono i nomi
dei file testuali creati quando accade un conflitto.
Nella sezione chiamata «Risolvere i conflitti(Mettere insieme i cambiamenti operati da
altri)», abbiamo visto che
un aggiornamento (update) produce file nominati
filename.mine
,
filename.rOLDREV
e
filename.rNEWREV
. Quando comando svn
merge produce un conflitto, ??though?, crea
tre file nominati filename.working
,
filename.left
e
filename.right
. Qui i
termini «left» e «right» descrivono
da quale lato della comparazione delle strutture proviene il file.
In qualsiasi caso, questi nomi diversi vi aiuteranno
distinguere tra conflitti che accadono come risultato d'un
aggiornamento (update) e tali che accadono come risultato d'una
fusione (merge).
When conversing with a Subversion developer, you might very likely hear reference to the term ancestry. This word is used to describe the relationship between two objects in a repository: if they're related to each other, then one object is said to be an ancestor of the other.
Parlando con sviluppatori di Subversion, uno può molto probabilmente sentire riferimento al termine ascendenza(ancestry). Questa parola è usata per descrivere la relazione tra due oggetti nel deposito(repository): se sono in relazione si dice che uno è antenato dell'altro.
For example, suppose you commit revision 100, which
includes a change to a file foo.c
.
Then foo.c@99
is an
“ancestor” of foo.c@100
.
On the other hand, suppose you commit the deletion of
foo.c
in revision 101, and then add a
new file by the same name in revision 102. In this case,
foo.c@99
and
foo.c@102
may appear to be related
(they have the same path), but in fact are completely
different objects in the repository. They share no history
or “ancestry”.
Per esempio, supponiamo che voi depositate la versione 100,
che include una modifica a file foo.c
.
Dopo questo il file foo.c@99
è un
«antenato» di foo.c@100
.
Caso oposto, supponiamo che depositate la cancellazione del
foo.c
nella versione 101 e dopo aggiugete
nuovo file con lo stesso nome nella versione 102. In questo caso,
foo.c@99
e
foo.c@102
possono apparire in relazione
(hanno lo stesso percorso e nome), ma in verità sono oggetti
del deposito(repository) completamente diversi. Non condividono nessuna storia
o «ascendenza».
The reason for bringing this up is to point out an
important difference between svn diff and
svn merge. The former command ignores
ancestry, while the latter command is quite sensitive to it.
For example, if you asked svn diff to
compare revisions 99 and 102 of foo.c
,
you would see line-based diffs; the diff
command is blindly comparing two paths. But if you asked
svn merge to compare the same two objects,
it would notice that they're unrelated and first attempt to
delete the old file, then add the new file; the output would
indicate a deletion followed by an add:
La ragione per spiegare questo è di puntare il dito
sulla differenza importante tra svn diff e
svn merge. Il primo comando ignora
ascendenza, invece il secondo è assai sensibile ad essa.
Per esempio, chiedendo a svn diff di
comparare revisioni 99 e 102 di foo.c
,
potete vedere differenze basate sulle linee; il comando
diff
ciecamente compara i due file.
Ma se chiedete a svn merge di comparare
gli stessi oggetti, lui si accorge che non sono in relazione
e prima provede a cancellare quello vecchio e poi aggiunge
nuovo; output indicherà una cancellazione seguita da una aggiunta:
D foo.c A foo.c
Most merges involve comparing trees that are ancestrally
related to one another, and therefore svn
merge defaults to this behavior. Occasionally,
however, you may want the merge
command to
compare two unrelated trees. For example, you may have
imported two source-code trees representing different vendor
releases of a software project (see sezione chiamata «Vendor branches»).
If you asked svn merge to compare the two
trees, you'd see the entire first tree being deleted,
followed by an add of the entire second tree!
Molte fusioni coinvolgono comparazioni delle strutture che sono
genealogicamente relazionate tra loro, e perciò svn
merge ha come predefinito questo comportamento. Occasionalmente,
tuttavia, si può volere che comando merge
compara
due strutture che non sono in relazione. Per esempio, si può importare
due strutture del codice sorgente che rappresentano due rilasci pubblici
d'un progetto software (vedi la sezione chiamata «Vendor branches»).
Chiedendo a svn merge di comparare queste due strutture,
si vede prima la cancellazione completta della prima struttura,
seguita da aggiunta di tutta la seconda struttura!
In these situations, you'll want svn
merge to do a path-based comparison only, ignoring
any relations between files and directories. Add the
--ignore-ancestry
option to your merge
command, and it will behave just like svn
diff. (And conversely, the
--notice-ancestry
option will cause
svn diff to behave like the
merge
command.)
In tali situazioni, si chiede a svn
merge di fare comparazione basata solo sui nomi, ignorando
qualsiasi relazione tra i file e cartelle. Si aggiunge opzione
--ignore-ancestry
al vostro comando di fusione,
e quello si comporterà esattamente come svn
diff. (E al contrario, la opzione
--notice-ancestry
causerà che
svn diff aggirà come comando
merge
.)