hgbook

changeset 814:99c201b30491

Minor changes and translation of code snippets for Ch.13.
author Giulio@puck
date Sat Aug 15 18:03:50 2009 +0200 (2009-08-15)
parents 15eeeef467d2
children 1df12479f7e5
files it/ch13-mq-collab.xml it/examples/auto-snippets.xml it/examples/mq.guards.init.it it/examples/mq.guards.qguard.it it/examples/mq.guards.qguard.neg.it it/examples/mq.guards.qguard.pos.it it/examples/mq.guards.qselect.cat.it it/examples/mq.guards.qselect.error.it it/examples/mq.guards.qselect.foo.it it/examples/mq.guards.qselect.foobar.it it/examples/mq.guards.qselect.qpush.it it/examples/mq.guards.qselect.quux.it it/examples/mq.guards.series.it
line diff
     1.1 --- a/it/ch13-mq-collab.xml	Sat Aug 15 17:22:37 2009 +0200
     1.2 +++ b/it/ch13-mq-collab.xml	Sat Aug 15 18:03:50 2009 +0200
     1.3 @@ -4,7 +4,7 @@
     1.4  
     1.5    <para id="x_15d">Sebbene sia facile imparare gli usi più semplici di Mercurial Queues, sono un pizzico di disciplina e alcune delle funzioni meno usate di MQ  che rendono possibile lavorare in ambienti di sviluppo complicati.</para>
     1.6  
     1.7 -  <para id="x_15e">In questo capitolo, userò come esempio una tecnica che ho impiegato per gestire lo sviluppo di un driver del kernel di Linux per un dispositivo Infiniband. Il driver in questione è grande (almeno per le dimensioni dei driver), poiché contiene 25.000 righe di codice distribuite su 35 file sorgente. Viene mantenuto da un piccolo gruppo di sviluppatori.</para>
     1.8 +  <para id="x_15e">In questo capitolo, userò come esempio una tecnica che ho impiegato per gestire lo sviluppo di un driver del kernel di Linux per un dispositivo Infiniband. Il driver in questione è grande (almeno per le dimensioni dei driver), poiché contiene 25.000 righe di codice distribuite su 35 file sorgente, e viene mantenuto da un piccolo gruppo di sviluppatori.</para>
     1.9  
    1.10    <para id="x_15f">Sebbene la maggior parte del materiale in questo capitolo sia specifica per Linux, gli stessi principi si applicano per qualsiasi base di codice di cui non siate i proprietari principali e su cui dobbiate fare parecchio lavoro.</para>
    1.11  
    1.12 @@ -17,7 +17,7 @@
    1.13      <itemizedlist>
    1.14        <listitem><para id="x_162">Un obiettivo è l'albero di sviluppo principale del kernel di Linux. In questo caso, le attività di manutenzione del codice sono parzialmente condivise con altri sviluppatori della comunità del kernel, che effettuano modifiche <quote>estemporanee</quote> al driver man mano che sviluppano e rifiniscono i sottosistemi del kernel.</para>
    1.15        </listitem>
    1.16 -      <listitem><para id="x_163">Manteniamo anche un certo numero di <quote>backport</quote> (letteralmente, conversioni all'indietro) verso vecchie versioni del kernel di Linux, per supportare le necessità di clienti che stanno utilizzando distribuzioni di Linux più vecchie che non incorporano i nostri driver. (Effetuare il <emphasis>backport</emphasis> del codice significa modificarlo per farlo funzionare in una versione del suo ambiente di destinazione più vecchia di quella per la quale era stato sviluppato.)</para>
    1.17 +      <listitem><para id="x_163">Manteniamo anche un certo numero di <quote>backport</quote> (letteralmente, conversioni all'indietro) verso vecchie versioni del kernel di Linux, per soddisfare le necessità di clienti che stanno utilizzando distribuzioni di Linux più vecchie che non incorporano i nostri driver. (Effetuare il <emphasis>backport</emphasis> del codice significa modificarlo per farlo funzionare in una versione del suo ambiente di destinazione più vecchia di quella per la quale era stato sviluppato.)</para>
    1.18        </listitem>
    1.19        <listitem><para id="x_164">Infine, rilasciamo il software seguendo una tabella di marcia che non è necessariamente allineata con quella usata da chi sviluppa il kernel e da chi distribuisce il sistema operativo, in modo da poter consegnare nuove funzionalità ai clienti senza obbligarli ad aggiornare il loro kernel o la loro intera distribuzione.</para>
    1.20        </listitem>
    1.21 @@ -32,7 +32,7 @@
    1.22  
    1.23        <para id="x_167">Il secondo è quello di mantenere un singolo albero di sorgenti pieno di istruzioni condizionali che attivano o disattivano parti di codice a seconda dell'ambiente designato. Dato che queste istruzioni <quote>ifdef</quote> non sono permesse nell'albero del kernel di Linux, è necessario seguire una procedura manuale o automatica per eliminarle e produrre un albero pulito. Una base di codice mantenuta in questo modo diventa rapidamente un caos di blocchi condizionali che sono difficili da capire e mantenere.</para>
    1.24  
    1.25 -      <para id="x_168">Nessuno di questi approcci è particolarmente adatto a situazioni in cui non <quote>possedete</quote> la copia ufficiale di un albero di sorgenti. Nel caso di un driver Linux che viene distribuito insieme al kernel standard, l'albero di Linus contiene la copia del codice che verrà considerata ufficiale dal resto del mondo. La versione a monte del <quote>mio</quote> driver può essere modificata da persone che non conosco, senza che io nemmeno lo scopra fino a quando i cambiamenti non appaiono nell'albero di Linus.</para>
    1.26 +      <para id="x_168">Nessuno di questi approcci è particolarmente adatto a situazioni in cui non <quote>possedete</quote> la copia ufficiale di un albero di sorgenti. Nel caso di un driver Linux che viene distribuito insieme al kernel standard, l'albero di Linus contiene la copia del codice che verrà universalmente considerata ufficiale. La versione a monte del <quote>mio</quote> driver può essere modificata da persone che non conosco, senza che io nemmeno lo scopra fino a quando i cambiamenti non appaiono nell'albero di Linus.</para>
    1.27  
    1.28        <para id="x_169">Questi approcci hanno la debolezza aggiuntiva di rendere difficile generare patch ben formate da presentare a monte.</para>
    1.29  
    1.30 @@ -49,7 +49,7 @@
    1.31  
    1.32      <para id="x_16c">Questo ci fornisce un piccolo repository contenente due patch che non hanno alcuna dipendenza reciproca, perché coinvolgono file differenti.</para>
    1.33  
    1.34 -    <para id="x_16d">L'idea alla base dell'applicazione condizionale è la possibilità di <quote>etichettare</quote> una patch con una <emphasis>guardia</emphasis>, che è semplicemente una stringa di testo di vostra scelta, per poi dire a MQ di selezionare le guardie specifiche da usare al momento di applicare le patch. MQ applicherà, o salterà, una patch con guardia, a seconda delle guardie che avete selezionato.</para>
    1.35 +    <para id="x_16d">L'idea alla base dell'applicazione condizionale è la possibilità di <quote>etichettare</quote> una patch con una <emphasis>guardia</emphasis>, che è semplicemente una stringa di testo di vostra scelta, per poi dire a MQ di selezionare le guardie specifiche da usare al momento di applicare le patch. MQ applicherà, o salterà, una patch con guardia a seconda delle guardie che avete selezionato.</para>
    1.36  
    1.37      <para id="x_16e">Una patch può avere un numero arbitrario di guardie, ognuna delle quali è <emphasis>positiva</emphasis> (<quote>applica questa patch se questa guardia è selezionata</quote>) o <emphasis>negativa</emphasis> (<quote>salta questa patch se questa guardia è selezionata</quote>). Una patch senza alcuna guardia viene sempre applicata.</para>
    1.38  
    1.39 @@ -57,7 +57,7 @@
    1.40    <sect1>
    1.41      <title>Controllare le guardie su una patch</title>
    1.42  
    1.43 -    <para id="x_16f">Il comando <command role="hg-ext-mq">qguard</command> vi permette di determinare quali guardie dovrebbero applicarsi a una patch, o di visualizzare le guardie già in effetto. Senza alcun argomento, il comando mostra le guardie della patch attualmente in cima alla pila.</para>
    1.44 +    <para id="x_16f">Il comando <command role="hg-ext-mq">qguard</command> vi permette di determinare quali guardie dovrebbero applicarsi a una patch, o di visualizzare le guardie già attive. Senza alcun argomento, il comando mostra le guardie della patch attualmente in cima alla pila.</para>
    1.45  
    1.46      &interaction.mq.guards.qguard;
    1.47  
    1.48 @@ -87,7 +87,7 @@
    1.49  
    1.50      <para id="x_174">Il comando <command role="hg-ext-mq">qselect</command> determina quali guardie sono attive in un dato momento. Il suo effetto è quello di determinare quali patch verranno applicate da MQ la prossima volta che invocherete <command role="hg-ext-mq">qpush</command>. Non ha alcun altro effetto, in particolare non agisce in alcun modo sulle patch che sono già applicate.</para>
    1.51  
    1.52 -    <para id="x_175">Invocato senza argomenti, il comando <command role="hg-ext-mq">qselect</command> elenca le guardie attualmente in effetto, una per ogni riga. Gli argomenti vengono trattati come i nomi delle guardie da applicare.</para>
    1.53 +    <para id="x_175">Invocato senza argomenti, il comando <command role="hg-ext-mq">qselect</command> elenca le guardie attualmente attive, una per ogni riga. Gli argomenti vengono trattati come i nomi delle guardie da applicare.</para>
    1.54  
    1.55      &interaction.mq.guards.qselect.foo;
    1.56  
    1.57 @@ -119,11 +119,11 @@
    1.58      <itemizedlist>
    1.59        <listitem><para id="x_17c">Una patch che non ha guardie viene sempre applicata.</para>
    1.60        </listitem>
    1.61 -      <listitem><para id="x_17d">Se la patch ha una qualsiasi guardia negativa che corrisponde a una qualsiasi guardia correntemente selezionata, la patch viene saltata.</para>
    1.62 -      </listitem>
    1.63 -      <listitem><para id="x_17e">Se la patch ha una qualsiasi guardia positiva che corrisponde a una qualsiasi guardia correntemente selezionata, la patch viene applicata.</para>
    1.64 -      </listitem>
    1.65 -      <listitem><para id="x_17f">Se la patch ha guardie positive o negative, ma nessuna corrisponde a qualsiasi guardia correntemente selezionata, la patch viene saltata.</para>
    1.66 +      <listitem><para id="x_17d">Se la patch ha una guardia negativa che corrisponde a una guardia attualmente selezionata, la patch viene saltata.</para>
    1.67 +      </listitem>
    1.68 +      <listitem><para id="x_17e">Se la patch ha una guardia positiva che corrisponde a una guardia attualmente selezionata, la patch viene applicata.</para>
    1.69 +      </listitem>
    1.70 +      <listitem><para id="x_17f">Se la patch ha guardie positive o negative, ma nessuna corrisponde a una guardia attualmente selezionata, la patch viene saltata.</para>
    1.71        </listitem>
    1.72      </itemizedlist>
    1.73  
    1.74 @@ -131,7 +131,7 @@
    1.75    <sect1>
    1.76      <title>Ridimensionare l'ambiente di lavoro</title>
    1.77  
    1.78 -    <para id="x_180">Lavorando sul driver di dispositivo menzionato in precedenza, non applico le patch a un normale albero del kernel di Linux, ma uso un repository che contiene solo una fotografia dei file sorgente rilevanti per lo sviluppo del dispositivo Infiniband. &Egrave; più facile lavorare con questo repository, perché le sue dimensioni sono l'1% delle dimensioni di un repository del kernel.</para>
    1.79 +    <para id="x_180">Lavorando sul driver di dispositivo menzionato in precedenza, non applico le patch a un normale albero del kernel di Linux, ma uso un repository che contiene solo una fotografia dei file sorgente rilevanti per lo sviluppo del dispositivo Infiniband. Lavorare con questo repository è più facile, perché le sue dimensioni sono l'1% delle dimensioni di un repository del kernel.</para>
    1.80  
    1.81      <para id="x_181">Poi scelgo una versione <quote>di base</quote> sulla quale le patch vengono applicate. Questa è una fotografia dell'albero del kernel di Linux scattata su una revisione di mia scelta. Quando scatto la fotografia, registro l'identificatore di changeset proveniente dal repository del kernel nel messaggio di commit. Dato che la fotografia mantiene la <quote>forma</quote> e il contenuto delle parti rilevanti dell'albero del kernel, posso applicare le mie patch sul mio repository ridotto o su un normale albero del kernel.</para>
    1.82  
    1.83 @@ -145,25 +145,25 @@
    1.84  
    1.85      <para id="x_184">La sequenza dei gruppi di patch che mantengo è la seguente. L'ordine di questi gruppi è importante per i motivi che verranno descritti dopo aver introdotto i gruppi.</para>
    1.86      <itemizedlist>
    1.87 -      <listitem><para id="x_185">Il gruppo delle patch <quote>accettate</quote>. Sono le patch che il gruppo di sviluppo ha proposto al mantenitore del sottosistema Infiniband e che sono state accettate, ma che non sono presenti nella fotografia su cui si basa il repository ridotto. Queste sono patch <quote>a sola lettura</quote>, presenti unicamente allo scopo di trasformare l'albero in uno stato simile a quello in cui si trova nel repository del mantenitore a monte.</para>
    1.88 -      </listitem>
    1.89 -      <listitem><para id="x_186">Il gruppo delle patch da <quote>rielaborare</quote>. Sono le patch che ho proposto ma per le quali il mantenitore a monte ha richiesto alcune modifiche prima di poterle accettare.</para>
    1.90 -      </listitem>
    1.91 -      <listitem><para id="x_187">Il gruppo delle patch <quote>in sospeso</quote>. Sono le patch che non ho ancora proposto al mantenitore a monte, ma su cui dobbiamo finire di lavorare. Queste patch saranno <quote>a sola lettura</quote> per un po'. Se il mantenitore a monte le accetta al momento di proporle, le sposterò alla fine del gruppo <quote>accettate</quote>. Se ne richiede la modifica, le sposterò all'inizio del gruppo da <quote>rielaborare</quote>.</para>
    1.92 +      <listitem><para id="x_185">Il gruppo delle patch <quote>accettate</quote>. Sono le patch che il gruppo di sviluppo ha proposto al manutentore del sottosistema Infiniband e che sono state accettate, ma che non sono presenti nella fotografia su cui si basa il repository ridotto. Queste sono patch <quote>a sola lettura</quote>, presenti unicamente allo scopo di trasformare l'albero in uno stato simile a quello in cui si trova nel repository del manutentore a monte.</para>
    1.93 +      </listitem>
    1.94 +      <listitem><para id="x_186">Il gruppo delle patch da <quote>rielaborare</quote>. Sono le patch che ho proposto ma per le quali il manutentore a monte ha richiesto alcune modifiche prima di poterle accettare.</para>
    1.95 +      </listitem>
    1.96 +      <listitem><para id="x_187">Il gruppo delle patch <quote>in sospeso</quote>. Sono le patch che non ho ancora proposto al manutentore a monte, ma su cui dobbiamo finire di lavorare. Queste patch saranno <quote>a sola lettura</quote> per un po'. Se il manutentore a monte le accetta al momento di proporle, le sposterò alla fine del gruppo <quote>accettate</quote>. Se ne richiede la modifica, le sposterò all'inizio del gruppo da <quote>rielaborare</quote>.</para>
    1.97        </listitem>
    1.98        <listitem><para id="x_188">Il gruppo delle patch <quote>in corso</quote>. Sono le patch che vengono attivamente sviluppate e che non dovrebbero essere ancora presentate a nessuno.</para>
    1.99        </listitem>
   1.100        <listitem><para id="x_189">Il gruppo delle patch di <quote>backport</quote>. Sono le patch che riadattano l'albero dei sorgenti a una vecchia versione dell'albero del kernel.</para>
   1.101        </listitem>
   1.102 -      <listitem><para id="x_18a">Il gruppo delle patch da <quote>non rilasciare</quote>. Sono le patch che per qualche ragione non dovrebbero mai essere presentate a monte. Per esempio, una patch di questo tipo potrebbe modificare le stringhe di identificazione incluse nei driver per rendere più facile distinguere, nel testo del campo, tra una versione del driver presa dall'albero e una versione consegnata a un rivenditore di distribuzioni.</para>
   1.103 -      </listitem>
   1.104 -    </itemizedlist>
   1.105 -
   1.106 -    <para id="x_18b">Tornando alle ragioni per cui i gruppi di patch sono ordinati in questo modo, ci piacerebbe che le patch più in basso nella pila siano il più possibile stabili, in modo da non aver bisogno di rielaborare le patch più in alto a causa di modifiche a loro contesto. Mettere le patch che non verranno mai cambiate all'inizio del file <filename role="special">series</filename> serve proprio a questo scopo.</para>
   1.107 +      <listitem><para id="x_18a">Il gruppo delle patch da <quote>non rilasciare</quote>. Sono le patch che per qualche ragione non dovrebbero mai essere presentate a monte. Per esempio, una patch di questo tipo potrebbe modificare le stringhe di identificazione incluse nei driver per rendere più facile distinguere, nel testo del campo, una versione del driver presa dall'albero da una versione consegnata a un rivenditore di distribuzioni.</para>
   1.108 +      </listitem>
   1.109 +    </itemizedlist>
   1.110 +
   1.111 +    <para id="x_18b">Tornando alle ragioni per cui i gruppi di patch sono ordinati in questo modo, ci piacerebbe che le patch più in basso nella pila siano il più possibile stabili, in modo da non aver bisogno di rielaborare le patch più in alto a causa di modifiche al loro contesto. Mettere le patch che non verranno mai cambiate all'inizio del file <filename role="special">series</filename> serve proprio a questo scopo.</para>
   1.112  
   1.113      <para id="x_18c">Ci piacerebbe anche applicare le patch che sappiamo di aver bisogno di modificare su un albero di sorgenti che somiglia il più possibile all'albero a monte. Questo è il motivo per cui teniamo le patch accettate in giro per un po'.</para>
   1.114  
   1.115 -    <para id="x_18d">Le patch di <quote>backport</quote> e da <quote>non rilasciare</quote> si trovano alla fine del file <filename role="special">series</filename>. Le patch di backport devono essere applicate su tutte le altre patch, e le patch da <quote>non rilasciare</quote> potrebbero anche rimanere in un posto sicuro.</para>
   1.116 +    <para id="x_18d">Le patch di <quote>backport</quote> e da <quote>non rilasciare</quote> si trovano alla fine del file <filename role="special">series</filename>. Le patch di <quote>backport</quote> devono essere applicate su tutte le altre patch, e anche le patch da <quote>non rilasciare</quote> dovrebbero essere messe in un posto sicuro.</para>
   1.117  
   1.118    </sect1>
   1.119    <sect1>
   1.120 @@ -172,13 +172,13 @@
   1.121      <para id="x_18e">Nel mio lavoro, uso un certo numero di guardie per controllare quali patch devono essere applicate.</para>
   1.122  
   1.123      <itemizedlist>
   1.124 -      <listitem><para id="x_18f">Le patch <quote>accettate</quote> sono sorvegliate da <literal>accepted</literal>. Questa guardia è abilitata per la maggior parte del tempo. Quando sto applicando le patch su un albero dove le patch sono già presenti, posso disabilitare questa patch così le patch che la seguono verranno applicate in maniera pulita.</para>
   1.125 +      <listitem><para id="x_18f">Le patch <quote>accettate</quote> sono sorvegliate da <literal>accettate</literal>. Questa guardia è abilitata per la maggior parte del tempo. Quando sto applicando le patch su un albero dove le patch sono già presenti, posso disabilitare questa guardia così le patch che la seguono verranno applicate in maniera pulita.</para>
   1.126        </listitem>
   1.127        <listitem><para id="x_190">Le patch che sono <quote>terminate</quote>, ma non sono ancora state proposte, non hanno guardie. Se sto applicando la pila delle patch a una copia dell'albero a monte, non ho bisogno di abilitare alcuna guardia per ottenere un albero di sorgenti ragionevolmente sicuro.</para>
   1.128        </listitem>
   1.129 -      <listitem><para id="x_191">Le patch che hanno bisogno di essere rielaborate prima di venire nuovamente presentate sono sorvegliate da <literal>rework</literal>.</para>
   1.130 -      </listitem>
   1.131 -      <listitem><para id="x_192">Per quelle patch che sono ancora in lavorazione, uso <literal>devel</literal>.</para>
   1.132 +      <listitem><para id="x_191">Le patch che hanno bisogno di essere rielaborate prima di venire nuovamente presentate sono sorvegliate da <literal>rielaborare</literal>.</para>
   1.133 +      </listitem>
   1.134 +      <listitem><para id="x_192">Per quelle patch che sono ancora in lavorazione, uso <literal>sviluppo</literal>.</para>
   1.135        </listitem>
   1.136        <listitem><para id="x_193">Una patch di backport potrebbe avere diverse guardie, una per ogni versione del kernel a cui si applica. Per esempio, una patch che effettua il backport di una parte del codice alla versione 2.6.9 del kernel avrà una guardia <literal>2.6.9</literal>.</para>
   1.137        </listitem>
   1.138 @@ -190,9 +190,9 @@
   1.139  
   1.140        <para id="x_195">Usando MQ, scrivere una patch di backport è un processo semplice. Tutto quello che una patch di questo tipo deve fare è modificare una parte di codice che usa una funzione del kernel non presente in una vecchia versione del kernel, in modo che il driver continui a funzionare correttamente con la vecchia versione.</para>
   1.141  
   1.142 -      <para id="x_196">Un obiettivo utile da raggiungere nella scrittura di una buona patch di backport è far sembrare che il codice sia stato scritto per la vecchia versione del kernel che state considerando. Meno intrusiva è la patch, più facile sarà da capire e mantenere. Se state scrivendo una collezione di patch di backport per evitare l'effetto <quote>caos</quote> causato da molte istruzioni <literal>#ifdef</literal> (contenenti blocchi di codice che vengono usati solo in maniera condizionata) nel vostro codice, evitate di introdurre nelle patch <literal>#ifdef</literal> dipendenti dalle versioni del kernel. Piuttosto, scrivete diverse patch, ognuna delle quali provoca cambiamenti incondizionati, e controllate la loro applicazione usando le guardie.</para>
   1.143 -
   1.144 -      <para id="x_197">Ci sono due ragioni per separare le patch di backport in un gruppo distinto dalle patch <quote>normali</quote> i cui effetti vengono modificati da quelle. Il primo è che mescolarle insieme rende più difficile usare uno strumento come l'estensione <literal role="hg-ext">patchbomb</literal> per automatizzare il processo di spedizione delle patch a un mantenitore a monte. Il secondo è che le patch di backport potrebbero perturbare il contesto in cui una successiva patch normale viene applicata, rendendo impossibile applicare la patch normale in maniera pulita <emphasis>senza</emphasis> che la patch di backport precedente sia già stata applicata.</para>
   1.145 +      <para id="x_196">Un obiettivo utile da raggiungere nella scrittura di una buona patch di backport è far sembrare che il codice sia stato scritto per la vecchia versione del kernel che state considerando. Meno intrusiva è la patch, più facile sarà da capire e mantenere. Se state scrivendo una collezione di patch di backport per evitare l'effetto <quote>caos</quote> causato da molte istruzioni <literal>#ifdef</literal> (contenenti blocchi di codice che vengono usati solo in maniera condizionata) nel vostro codice, evitate di introdurre <literal>#ifdef</literal> dipendenti dalle versioni del kernel nelle patch. Piuttosto, scrivete diverse patch, ognuna delle quali provoca cambiamenti incondizionati, e controllate la loro applicazione usando le guardie.</para>
   1.146 +
   1.147 +      <para id="x_197">Ci sono due ragioni per separare le patch di backport in un gruppo distinto dalle patch <quote>normali</quote> i cui effetti vengono modificati da quelle. Il primo è che mescolarle insieme rende più difficile usare uno strumento come l'estensione <literal role="hg-ext">patchbomb</literal> per automatizzare il processo di spedizione delle patch a un manutentore a monte. Il secondo è che le patch di backport potrebbero perturbare il contesto in cui una successiva patch normale viene applicata, rendendo impossibile applicare la patch normale in maniera pulita <emphasis>senza</emphasis> che la patch di backport precedente sia già stata applicata.</para>
   1.148  
   1.149      </sect2>
   1.150    </sect1>
   1.151 @@ -225,7 +225,7 @@
   1.152        <programlisting>[extdiff]
   1.153  cmd.interdiff = hg-interdiff</programlisting>
   1.154        <para id="x_1a0">Questa riga ordina a <literal role="hg-ext">hgext</literal> di rendere disponibile il comando <literal>interdiff</literal>, in modo che possiate ridurre l'invocazione precedente di <command role="hg-ext-extdiff">extdiff</command> a qualcosa di un po' più maneggevole.</para>
   1.155 -      <programlisting>hg interdiff -r A:B my-change.patch</programlisting>
   1.156 +      <programlisting>hg interdiff -r A:B mio-cambiamento.patch</programlisting>
   1.157  
   1.158        <note>
   1.159  	<para id="x_1a1">Il comando <command>interdiff</command> funziona bene solo se i file sottostanti dai quali vengono generate le versioni di una patch rimangono gli stessi. Se create una patch, modificate i file sottostanti e poi rigenerate la patch, <command>interdiff</command> potrebbe non produrre alcun risultato utile.</para>
     2.1 --- a/it/examples/auto-snippets.xml	Sat Aug 15 17:22:37 2009 +0200
     2.2 +++ b/it/examples/auto-snippets.xml	Sat Aug 15 18:03:50 2009 +0200
     2.3 @@ -156,17 +156,17 @@
     2.4  <!ENTITY interaction.hook.simple.pretxncommit SYSTEM "hook.simple.pretxncommit.it">
     2.5  <!ENTITY interaction.issue29.go SYSTEM "issue29.go.it">
     2.6  <!ENTITY interaction.mq.dodiff.diff SYSTEM "mq.dodiff.diff.it">
     2.7 -<!ENTITY interaction.mq.guards.init SYSTEM "results/mq.guards.init.lxo">
     2.8 -<!ENTITY interaction.mq.guards.qguard SYSTEM "results/mq.guards.qguard.lxo">
     2.9 -<!ENTITY interaction.mq.guards.qguard.neg SYSTEM "results/mq.guards.qguard.neg.lxo">
    2.10 -<!ENTITY interaction.mq.guards.qguard.pos SYSTEM "results/mq.guards.qguard.pos.lxo">
    2.11 -<!ENTITY interaction.mq.guards.qselect.cat SYSTEM "results/mq.guards.qselect.cat.lxo">
    2.12 -<!ENTITY interaction.mq.guards.qselect.error SYSTEM "results/mq.guards.qselect.error.lxo">
    2.13 -<!ENTITY interaction.mq.guards.qselect.foo SYSTEM "results/mq.guards.qselect.foo.lxo">
    2.14 -<!ENTITY interaction.mq.guards.qselect.foobar SYSTEM "results/mq.guards.qselect.foobar.lxo">
    2.15 -<!ENTITY interaction.mq.guards.qselect.qpush SYSTEM "results/mq.guards.qselect.qpush.lxo">
    2.16 -<!ENTITY interaction.mq.guards.qselect.quux SYSTEM "results/mq.guards.qselect.quux.lxo">
    2.17 -<!ENTITY interaction.mq.guards.series SYSTEM "results/mq.guards.series.lxo">
    2.18 +<!ENTITY interaction.mq.guards.init SYSTEM "mq.guards.init.it">
    2.19 +<!ENTITY interaction.mq.guards.qguard SYSTEM "mq.guards.qguard.it">
    2.20 +<!ENTITY interaction.mq.guards.qguard.neg SYSTEM "mq.guards.qguard.neg.it">
    2.21 +<!ENTITY interaction.mq.guards.qguard.pos SYSTEM "mq.guards.qguard.pos.it">
    2.22 +<!ENTITY interaction.mq.guards.qselect.cat SYSTEM "mq.guards.qselect.cat.it">
    2.23 +<!ENTITY interaction.mq.guards.qselect.error SYSTEM "mq.guards.qselect.error.it">
    2.24 +<!ENTITY interaction.mq.guards.qselect.foo SYSTEM "mq.guards.qselect.foo.it">
    2.25 +<!ENTITY interaction.mq.guards.qselect.foobar SYSTEM "mq.guards.qselect.foobar.it">
    2.26 +<!ENTITY interaction.mq.guards.qselect.qpush SYSTEM "mq.guards.qselect.qpush.it">
    2.27 +<!ENTITY interaction.mq.guards.qselect.quux SYSTEM "mq.guards.qselect.quux.it">
    2.28 +<!ENTITY interaction.mq.guards.series SYSTEM "mq.guards.series.it">
    2.29  <!ENTITY interaction.mq.id.lxoput SYSTEM "results/mq.id.lxoput.lxo">
    2.30  <!ENTITY interaction.mq.id.output SYSTEM "mq.id.output.it">
    2.31  <!ENTITY interaction.mq.qinit-help.help SYSTEM "mq.qinit-help.help.it">
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/it/examples/mq.guards.init.it	Sat Aug 15 18:03:50 2009 +0200
     3.3 @@ -0,0 +1,12 @@
     3.4 +<!-- BEGIN mq.guards.init -->
     3.5 +<screen><prompt>$</prompt> <userinput>hg qinit</userinput>
     3.6 +<prompt>$</prompt> <userinput>hg qnew ciao.patch</userinput>
     3.7 +<prompt>$</prompt> <userinput>echo ciao &gt; ciao</userinput>
     3.8 +<prompt>$</prompt> <userinput>hg add ciao</userinput>
     3.9 +<prompt>$</prompt> <userinput>hg qrefresh</userinput>
    3.10 +<prompt>$</prompt> <userinput>hg qnew arrivederci.patch</userinput>
    3.11 +<prompt>$</prompt> <userinput>echo arrivederci &gt; arrivederci</userinput>
    3.12 +<prompt>$</prompt> <userinput>hg add arrivederci</userinput>
    3.13 +<prompt>$</prompt> <userinput>hg qrefresh</userinput>
    3.14 +</screen>
    3.15 +<!-- END mq.guards.init -->
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/it/examples/mq.guards.qguard.it	Sat Aug 15 18:03:50 2009 +0200
     4.3 @@ -0,0 +1,5 @@
     4.4 +<!-- BEGIN mq.guards.qguard -->
     4.5 +<screen><prompt>$</prompt> <userinput>hg qguard</userinput>
     4.6 +arrivederci.patch: senza guardie
     4.7 +</screen>
     4.8 +<!-- END mq.guards.qguard -->
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/it/examples/mq.guards.qguard.neg.it	Sat Aug 15 18:03:50 2009 +0200
     5.3 @@ -0,0 +1,6 @@
     5.4 +<!-- BEGIN mq.guards.qguard.neg -->
     5.5 +<screen><prompt>$</prompt> <userinput>hg qguard -- ciao.patch -quux</userinput>
     5.6 +<prompt>$</prompt> <userinput>hg qguard ciao.patch</userinput>
     5.7 +ciao.patch: -quux
     5.8 +</screen>
     5.9 +<!-- END mq.guards.qguard.neg -->
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/it/examples/mq.guards.qguard.pos.it	Sat Aug 15 18:03:50 2009 +0200
     6.3 @@ -0,0 +1,6 @@
     6.4 +<!-- BEGIN mq.guards.qguard.pos -->
     6.5 +<screen><prompt>$</prompt> <userinput>hg qguard +foo</userinput>
     6.6 +<prompt>$</prompt> <userinput>hg qguard</userinput>
     6.7 +arrivederci.patch: +foo
     6.8 +</screen>
     6.9 +<!-- END mq.guards.qguard.pos -->
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/it/examples/mq.guards.qselect.cat.it	Sat Aug 15 18:03:50 2009 +0200
     7.3 @@ -0,0 +1,5 @@
     7.4 +<!-- BEGIN mq.guards.qselect.cat -->
     7.5 +<screen><prompt>$</prompt> <userinput>cat .hg/patches/guards</userinput>
     7.6 +foo
     7.7 +</screen>
     7.8 +<!-- END mq.guards.qselect.cat -->
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/it/examples/mq.guards.qselect.error.it	Sat Aug 15 18:03:50 2009 +0200
     8.3 @@ -0,0 +1,5 @@
     8.4 +<!-- BEGIN mq.guards.qselect.error -->
     8.5 +<screen><prompt>$</prompt> <userinput>hg qselect +foo</userinput>
     8.6 +fallimento: la guardia '+foo' comincia con un carattere non valido: '+'
     8.7 +</screen>
     8.8 +<!-- END mq.guards.qselect.error -->
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/it/examples/mq.guards.qselect.foo.it	Sat Aug 15 18:03:50 2009 +0200
     9.3 @@ -0,0 +1,11 @@
     9.4 +<!-- BEGIN mq.guards.qselect.foo -->
     9.5 +<screen><prompt>$</prompt> <userinput>hg qpop -a</userinput>
     9.6 +la coda delle patch è vuota
     9.7 +<prompt>$</prompt> <userinput>hg qselect</userinput>
     9.8 +nessuna guardia attiva
     9.9 +<prompt>$</prompt> <userinput>hg qselect foo</userinput>
    9.10 +il numero di patch non applicate senza guardia è cambiato da 1 a 2
    9.11 +<prompt>$</prompt> <userinput>hg qselect</userinput>
    9.12 +foo
    9.13 +</screen>
    9.14 +<!-- END mq.guards.qselect.foo -->
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/it/examples/mq.guards.qselect.foobar.it	Sat Aug 15 18:03:50 2009 +0200
    10.3 @@ -0,0 +1,11 @@
    10.4 +<!-- BEGIN mq.guards.qselect.foobar -->
    10.5 +<screen><prompt>$</prompt> <userinput>hg qselect foo bar</userinput>
    10.6 +il numero di patch non applicate senza guardia è cambiato da 0 a 2
    10.7 +<prompt>$</prompt> <userinput>hg qpop -a</userinput>
    10.8 +nessuna patch applicata
    10.9 +<prompt>$</prompt> <userinput>hg qpush -a</userinput>
   10.10 +applico ciao.patch
   10.11 +applico arrivederci.patch
   10.12 +ora a: arrivederci.patch
   10.13 +</screen>
   10.14 +<!-- END mq.guards.qselect.foobar -->
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/it/examples/mq.guards.qselect.qpush.it	Sat Aug 15 18:03:50 2009 +0200
    11.3 @@ -0,0 +1,7 @@
    11.4 +<!-- BEGIN mq.guards.qselect.qpush -->
    11.5 +<screen><prompt>$</prompt> <userinput>hg qpush -a</userinput>
    11.6 +applico ciao.patch
    11.7 +applico arrivederci.patch
    11.8 +ora a: arrivederci.patch
    11.9 +</screen>
   11.10 +<!-- END mq.guards.qselect.qpush -->
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/it/examples/mq.guards.qselect.quux.it	Sat Aug 15 18:03:50 2009 +0200
    12.3 @@ -0,0 +1,9 @@
    12.4 +<!-- BEGIN mq.guards.qselect.quux -->
    12.5 +<screen><prompt>$</prompt> <userinput>hg qselect quux</userinput>
    12.6 +il numero di patch applicate con guardia è cambiato da 0 a 2
    12.7 +<prompt>$</prompt> <userinput>hg qpop -a</userinput>
    12.8 +la coda delle patch è vuota
    12.9 +<prompt>$</prompt> <userinput>hg qpush -a</userinput>
   12.10 +la serie di patch è già stata completamente applicata
   12.11 +</screen>
   12.12 +<!-- END mq.guards.qselect.quux -->
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/it/examples/mq.guards.series.it	Sat Aug 15 18:03:50 2009 +0200
    13.3 @@ -0,0 +1,6 @@
    13.4 +<!-- BEGIN mq.guards.series -->
    13.5 +<screen><prompt>$</prompt> <userinput>cat .hg/patches/series</userinput>
    13.6 +ciao.patch #-quux
    13.7 +arrivederci.patch #+foo
    13.8 +</screen>
    13.9 +<!-- END mq.guards.series -->