hgbook

annotate it/ch12-mq.xml @ 768:87d7000115f8

Literal translation of Ch.12.
author Giulio@puck
date Wed Jul 29 19:44:57 2009 +0200 (2009-07-29)
parents
children bdea936798c4
rev   line source
Giulio@768 1 <chapter id="chap:mq">
Giulio@768 2 <?dbhtml filename="gestire-il-cambiamento-con-mercurial-queues.html"?>
Giulio@768 3 <title>Gestire il cambiamento con Mercurial Queues</title>
Giulio@768 4
Giulio@768 5 <sect1 id="sec:mq:patch-mgmt">
Giulio@768 6 <title>Il problema della gestione delle patch</title>
Giulio@768 7
Giulio@768 8 <para id="x_3ac">Ecco uno scenario comune: avete bisogno di installare un pacchetto software dai sorgenti, ma trovate un bug che dovete correggere nei sorgenti prima di poter cominciare a usare il pacchetto. Fate le vostre modifiche, vi dimenticate del pacchetto per un po' e alcuni mesi dopo avete bisogno di aggiornare il pacchetto a una nuova versione. Se la versione più nuova del pacchetto ha ancora il bug, dovete estrarre la vostra correzione dal vecchio albero dei sorgenti e applicarla alla nuova versione. Questa è un'attività seccante ed è facile commettere errori.</para>
Giulio@768 9
Giulio@768 10 <para id="x_3ad">Questo è un semplice caso del problema di <quote>gestione delle patch</quote>. Avete un albero di sorgenti <quote>a monte</quote> che non potete cambiare; avete bisogno di fare alcune modifiche locali all'albero a monte; e vi piacerebbe essere in grado di mantenere separate quelle modifiche, in modo da poterle applicare a nuove versioni della sorgente a monte.</para>
Giulio@768 11
Giulio@768 12 <para id="x_3ae">Il problema di gestione delle patch si presenta in molte situazioni. Probabilmente la più visibile è quella in cui un utente di un progetto software open source contribuisce la correzione di un bug o una nuova funzione ai manutentori del progetto sotto forma di patch.</para>
Giulio@768 13
Giulio@768 14 <para id="x_3af">I distributori di sistemi operativi che includono software open source hanno spesso bisogno di effettuare modifiche ai pacchetti che distribuiscono in modo da assemblarli correttamente nei propri ambienti.</para>
Giulio@768 15
Giulio@768 16 <para id="x_3b0">Quando avete alcune modifiche da mantenere, è facile gestire una singola patch usando i programmi standard <command>diff</command> e <command>patch</command> (si veda la <xref linkend="sec:mq:patch"/> per una discussione di questi strumenti). Una volta che il numero di modifiche cresce, comincia ad avere senso l'idea di mantenere le patch come <quote>frammenti di lavoro</quote> distinti, in modo che per esempio una singola patch conterrà solo una correzione di bug (la patch potrebbe modificare diversi file, ma sta facendo <quote>solo una cosa</quote>) e potreste avere un certo numero di queste patch per bug differenti che dovete correggere e modifiche locali di cui avete bisogno. In questa situazione, se sottoponete una patch per la correzione di un bug ai manutentori del pacchetto a monte e questi includono la vostra correzione in una release successiva, potete semplicemente scartare quella singola patch quando state aggiornando a una nuova release.</para>
Giulio@768 17
Giulio@768 18 <para id="x_3b1">Mantenere una singola patch per un albero a monte è un compito un po' fastidioso e soggetto a errori, ma non è difficile. Tuttavia, la complessità del problema cresce rapidamente man mano che il numero di patch che dovete mantenere aumenta. Con più di un piccolo numero di patch in mano, cpaire quali dovete applicare e mantenerle passa da confuso a opprimente.</para>
Giulio@768 19
Giulio@768 20 <para id="x_3b2">Fortunatamente, Mercurial include una potente estensione, chiamata Mercurial Queues (letteralmente, Code di Mercurial) o semplicemente <quote>MQ</quote>, che semplifica grandemente il problema di gestione delle patch.</para>
Giulio@768 21
Giulio@768 22 </sect1>
Giulio@768 23 <sect1 id="sec:mq:history">
Giulio@768 24 <title>La preistoria di Mercurial Queues</title>
Giulio@768 25
Giulio@768 26 <para id="x_3b3">Verso la fine degli anni '90, diversi sviluppatori del kernel di Linux cominciarono a mantenere alcune <quote>serie di patch</quote> che modificavano il comportamento del kernel di Linux. Alcune di queste serie si concentravano sulla stabilità, alcune sulla copertura di funzionalità e altre erano più sperimentali.</para>
Giulio@768 27
Giulio@768 28 <para id="x_3b4">La dimensinoe di queste serie di patch crebbe rapidamente. Nel 2002, Andrew Morton pubblicò alcuni script di shell che aveva usato per automatizzare la gestione delle proprie code di patch. Andrew era riuscito a usare questi script per gestire centinaia (talvolta migliaia) di patch per il kernel di Linux.</para>
Giulio@768 29
Giulio@768 30 <sect2 id="sec:mq:quilt">
Giulio@768 31 <title>Una coperta a scacchi</title>
Giulio@768 32
Giulio@768 33 <para id="x_3b5">All'inizio del 2003, Andreas Gruenbacher and Martin Quinson presero in prestito l'approccio degli script di Andrew e pubblicarono uno strumento chiamato <quote>patchwork quilt</quote> (letteralmente, coperta a scacchi) <citation>web:quilt</citation>, o semplicemente <quote>quilt</quote> (si veda <citation>gruenbacher:2005</citation> per un articolo che lo descrive). Dato che quilt sostanzialmente automatizzava la gestione delle patch, guadagnò rapidamente un grande seguito tra gli sviluppatori di software open source.</para>
Giulio@768 34
Giulio@768 35 <para id="x_3b6">Quilt gestisce una <emphasis>pila di patch</emphasis> per un albero di directory. Per cominciare, dovete dire a quilt di gestire un albero di directory e quali file volete che gestisca; esso memorizza i nomi e il contenuto di quei file. Per correggere un bug, create una nuova patch (usando un singolo comando), modificate i file che dovete correggere, poi <quote>aggiornate</quote> la patch.</para>
Giulio@768 36
Giulio@768 37 <para id="x_3b7">L'operazione di aggiornamento induce quilt a esaminare l'albero di directory; aggiorna la patch con tutte le modifiche che avete fatto. Potete creare un'altra patch in aggiunta alla prima, che terrà traccia dei cambiamenti richiesti per modificare l'albero da <quote>albero con una patch applicata</quote> ad <quote>albero con due patch applicate</quote>.</para>
Giulio@768 38
Giulio@768 39 <para id="x_3b8">Potete <emphasis>cambiare</emphasis> quali patch sono applicate all'albero. Se <quote>estraete</quote> una patch, i cambiamenti effettuati da quella patch spariranno dall'albero di directory. Quilt si ricorda quali patch avete estratto, comunque, così potete <quote>inserire</quote> nuovamente una patch estratta e l'albero di directory verrà ripristinato per contenere le modifiche in quella patch. La cosa più importante è che potete eseguire il comando di <quote>aggiornamento</quote> in ogni momento, e la patch applicata più recentemente verrà aggiornata. Questo significa che, in ogni momento, potete cambiare sia quali patch sono applicate sia quali modifiche vengono effettuate da quelle patch.</para>
Giulio@768 40
Giulio@768 41 <para id="x_3b9">Quilt non sa nulla di strumenti di controllo di revisione, così funziona altrettanto bene con un archivio estratto che con una copia di lavoro di Subversion.</para>
Giulio@768 42 </sect2>
Giulio@768 43
Giulio@768 44 <sect2 id="sec:mq:quilt-mq">
Giulio@768 45 <title>Da patchwork quilt a Mercurial Queues</title>
Giulio@768 46
Giulio@768 47 <para id="x_3ba">A metà del 2005, Chris Mason prese le funzionalità di quilt e implementò un'estensione che chiamò Mercurial Queues, che aggiungeva a Mercurial un comportamento simile a quello di quilt.</para>
Giulio@768 48
Giulio@768 49 <para id="x_3bb">La differenza chiave tra quilt e MQ è che quilt non sa nulla di sistemi di controllo di revisione, mentre MQ è <emphasis>integrata</emphasis> in Mercurial. Ogni patch che inserite è rappresentata sotto forma di changeset Mercurial. Estraete una patch, e il changeset sparisce.</para>
Giulio@768 50
Giulio@768 51 <para id="x_3bc">Dato che quilt non si preoccupa degli strumenti di controllo di revisione, rimane un software tremendamente utile da conoscere per impiegarlo nelle situazioni in cui non potete usare Mercurial e MQ.</para>
Giulio@768 52
Giulio@768 53 </sect2>
Giulio@768 54 </sect1>
Giulio@768 55 <sect1>
Giulio@768 56 <title>L'enorme vantaggio di MQ</title>
Giulio@768 57
Giulio@768 58 <para id="x_3bd">Non posso esagerare il valore che MQ offre attraverso l'unificazione di patch e controllo di revisione.</para>
Giulio@768 59
Giulio@768 60 <para id="x_3be">Una delle ragioni principali per cui le patch hanno continuato a venire usate nel mondo del software libero e open source&emdash;nonostante la disponibilità di strumenti di controllo di revisione sempre più capaci attraverso gli anni&emdash; è l'<emphasis>agilità</emphasis> che offrono.</para>
Giulio@768 61
Giulio@768 62 <para id="x_3bf">I tradizionali strumenti di controllo di revisione effettuano una registrazione permanente di ogni cosa che fate. Mentre questo ha un grande valore, è anche piuttosto soffocante. Se volete effettuare un esperimento allucinato, dovete stare molto attenti a come procedete, o rischiate di lasciare tracce inutili&emdash;o peggio, ingannevoli e destabilizzanti&emdash; dei vostri #missteps# e dei vostri errori nella registrazione permanente delle revisioni.</para>
Giulio@768 63
Giulio@768 64 <para id="x_3c0">Al contrario, il matrimonio tra controllo di revisione distribuito e patch realizzato da MQ rende molto più facile isolare il vostro lavoro. Le vostre patch si basano sulla normale cronologia delle revisioni e potete farle sparire e comparire a piacere. Se non vi piace una patch, potete scartarla. Se una patch non è esattamente come volete che sia, vi basta correggerla&emdash;tutte le volte che ne avete bisogno, fino a quando non l'avete affinata nella forma che desiderate.</para>
Giulio@768 65
Giulio@768 66 <para id="x_3c1">Per esempio, l'integrazione delle patch con il controllo di revisione rende la comprensione delle patch&emdash;e delle interazioni con il codice su cui si basano&emdash;e la correzione dei loro effetti <emphasis>enormemente</emphasis> più facile. Dato che ogni patch applicata ha un changeset associato, potete invocare <command role="hg-cmd">hg log</command> con un nome di file per vedere quali changeset e quali patch hanno avuto effetto sul file. Potete usare il comando <command role="hg-cmd">hg bisect</command> per condurre una ricerca binaria attraverso tutti i changeset e le patch applicate per vedere dove un bug è stato introdotto o corretto. Potete usare il comando <command role="hg-cmd">hg annotate</command> per vedere quali changeset o patch hanno modificato una particolare riga di un file sorgente. E così via.</para>
Giulio@768 67 </sect1>
Giulio@768 68
Giulio@768 69 <sect1 id="sec:mq:patch">
Giulio@768 70 <title>Capire le patch</title>
Giulio@768 71
Giulio@768 72 <para id="x_3c2">Dato che MQ non nasconde la sua natura orientata alle patch, è utile capire cosa sono le patch e conoscere un po' gli strumenti che lavorano con esse.</para>
Giulio@768 73
Giulio@768 74 <para id="x_3c3">Il tradizionale comando Unix <command>diff</command> confronta due file e stampa una lista di differenze tra loro. Il comando <command>patch</command> interpreta queste differenze come <emphasis>modifiche</emphasis> da effettuare a un file. Date un'occhiata qui di seguito per vedere un semplice esempio di questi comandi in azione.</para>
Giulio@768 75
Giulio@768 76 &interaction.mq.dodiff.diff;
Giulio@768 77
Giulio@768 78 <para id="x_3c4">Il tipo di file generato da <command>diff</command> (e che <command>patch</command> prende in ingresso) viene chiamato una <quote>patch</quote> o un <quote>diff</quote>; non c'è alcuna differenza tra una patch e un diff. (Noi useremo il termine <quote>patch</quote>, dato che è quello più comunemente usato.)</para>
Giulio@768 79
Giulio@768 80 <para id="x_3c5">Un file di patch può cominciare con testo arbitrario; il comando <command>patch</command> ignora questo testo, ma MQ lo usa come messaggio di commit quando crea i changeset. Per trovare l'inizio del contenuto della patch, <command>patch</command> cerca la prima riga che comincia con la stringa <quote><literal>diff -</literal></quote>.</para>
Giulio@768 81
Giulio@768 82 <para id="x_3c6">MQ lavora con i diff in formato <emphasis>unified</emphasis> (<command>patch</command> può accettare molti altri formati di diff, ma MQ no). Un diff in formato unified contiene due tipi di intestazione. L'<emphasis>intestazione di file</emphasis> descrive il file che viene modificato e contiene il nome del file da modificare. Quando <command>patch</command> vede una nuova intestazione di file, cerca il file con quel nome per cominciare a modificarlo.</para>
Giulio@768 83
Giulio@768 84 <para id="x_3c7">L'intestazione di file è seguita da una serie di <emphasis>blocchi</emphasis>. Ogni blocco comincia con un'intestazione che identifica l'intervallo di numeri di riga nel file che il blocco dovrebbe modificare. Dopo l'intestazione, un blocco comincia e finisce con alcune (di solito tre) righe di testo dal file originale che vengono chiamate il <emphasis>contesto</emphasis> del blocco. Se c'è solo una quantità ridotta di contesto tra blocchi successivi, <command>diff</command> non stampa una nuova intestazione, ma si limita a unire i blocchi insieme, con alcune righe di contesto tra le modifiche.</para>
Giulio@768 85
Giulio@768 86 <para id="x_3c8">Ogni riga di contesto comincia con un carattere di spazio. Nell'ambito di un blocco, una riga che comincia con <quote><literal>-</literal></quote> significa <quote>rimuovi questa riga,</quote> mentre una riga che comincia con <quote><literal>+</literal></quote> significa <quote>inserisci questa riga.</quote> Per esempio, una riga modificata viene rappresentata da una cancellazione e un inserimento.</para>
Giulio@768 87
Giulio@768 88 <para id="x_3c9">Ritorneremo ad alcuni degli aspetti più sottili delle patch più tardi (nella <xref linkend="sec:mq:adv-patch"/>), ma ora dovreste avere abbastanza informazioni per usare MQ.</para>
Giulio@768 89 </sect1>
Giulio@768 90
Giulio@768 91 <sect1 id="sec:mq:start">
Giulio@768 92 <title>Cominciare a usare Mercurial Queues</title>
Giulio@768 93
Giulio@768 94 <para id="x_3ca">Dato che MQ è implementata come un'estensione, dovete esplicitamente abilitarla prima di poterla suare. (Non avete bisogno di scaricare nulla, perché MQ è inclusa con la distribuzione standard di Mercurial.) Per abilitare MQ, modificate il vostro file <filename role="home">~/.hgrc</filename> aggiungendo le seguenti righe.</para>
Giulio@768 95
Giulio@768 96 <programlisting>[extensions]
Giulio@768 97 hgext.mq =</programlisting>
Giulio@768 98
Giulio@768 99 <para id="x_3cb">Una volta che avete abilitato l'estensione, vi verranno messi a disposizione alcuni nuovi comandi. Per verificare che l'estensione funzioni, potete usare <command role="hg-cmd">hg help</command> per vedere se il comando <command role="hg-ext-mq">qinit</command> viene elencato come disponibile.</para>
Giulio@768 100
Giulio@768 101 &interaction.mq.qinit-help.help;
Giulio@768 102
Giulio@768 103 <para id="x_3cc">Potete usare MQ con <emphasis>qualsiasi</emphasis> repository Mercurial, e i suoi comandi operano solo all'interno di quel repository. Per cominciare, preparate semplicemente il repository usando il comando <command role="hg-ext-mq">qinit</command> command.</para>
Giulio@768 104
Giulio@768 105 &interaction.mq.tutorial.qinit;
Giulio@768 106
Giulio@768 107 <para id="x_3cd">Questo comando crea una directory vuota chiamata <filename role="special" class="directory">.hg/patches</filename>, dove MQ terrà i propri metadati. Come accade con molti comandi Mercurial, il comando <command role="hg-ext-mq">qinit</command> non stamperà nulla nel caso termini con successo.</para>
Giulio@768 108
Giulio@768 109 <sect2>
Giulio@768 110 <title>Creare una nuova patch</title>
Giulio@768 111
Giulio@768 112 <para id="x_3ce">Per cominciare a lavorare su una nuova patch, usate il comando <command role="hg-ext-mq">qnew</command>. Questo comando prende un argomento, il nome della patch da creare.</para>
Giulio@768 113
Giulio@768 114 <para id="x_3cf">MQ userà questo nome come il nome di un file che memorizzerà nella directory <filename role="special" class="directory">.hg/patches</filename>, come potete vedere qui sotto.</para>
Giulio@768 115
Giulio@768 116 &interaction.mq.tutorial.qnew;
Giulio@768 117
Giulio@768 118 <para id="x_3d0">La directory <filename role="special" class="directory">.hg/patches</filename> contiene anche altri due nuovi file, <filename role="special">series</filename> e <filename role="special">status</filename>. Il file <filename role="special">series</filename> elenca tutte le patch che MQ conosce per questo repository, con una patch per riga. Mercurial usa il file <filename role="special">status</filename> per tenere traccia internamente di tutte le patch che MQ ha <emphasis>applicato</emphasis> a questo repository.</para>
Giulio@768 119
Giulio@768 120 <note>
Giulio@768 121 <para id="x_3d1">Talvolta, potreste voler modificare il file <filename role="special">series</filename> a mano, per esempio per cambiare la sequenza in cui sono applicate alcune patch. Tuttavia, modificare manualmente il file <filename role="special">status</filename> è quasi sempre una cattiva idea, dato che è facile rovinare l'idea di MQ di quello che sta succedendo.</para>
Giulio@768 122 </note>
Giulio@768 123
Giulio@768 124 <para id="x_3d2">Una volta che avete creato la vostra nuova patch, potete modificare i file nella directory di lavoro come fareste di solito. Tutti i normali comandi Mercurial, come <command role="hg-cmd">hg diff</command> e <command role="hg-cmd">hg annotate</command>, funzionano allo stesso modo in cui funzionavano prima.</para>
Giulio@768 125 </sect2>
Giulio@768 126
Giulio@768 127 <sect2>
Giulio@768 128 <title>Aggiornare una patch</title>
Giulio@768 129
Giulio@768 130 <para id="x_3d3">Quando raggiungete un punto in cui volete salvare il vostro lavoro, usate il comando <command role="hg-ext-mq">qrefresh</command> per aggiornare la patch su cui state lavorando.</para>
Giulio@768 131
Giulio@768 132 &interaction.mq.tutorial.qrefresh;
Giulio@768 133
Giulio@768 134 <para id="x_3d4">Questo comando include nella vostra patch i cambiamenti che avete fatto nella directory di lavoro e aggiorna il changeset corrispondente alla patch in modo che contenga quei cambiamenti.</para>
Giulio@768 135
Giulio@768 136 <para id="x_3d5">Potete eseguire <command role="hg-ext-mq">qrefresh</command> tutte le volte che volete, quindi è un buon modo per <quote>controllare</quote> il vostro lavoro. Aggiornate la vostra patch al momento opportuno, tentate un esperimento e se l'esperimento non funziona usate <command role="hg-cmd">hg revert</command> per ripristinare le vostre modifiche all'ultimo aggiornamento che avete compiuto.</para>
Giulio@768 137
Giulio@768 138 &interaction.mq.tutorial.qrefresh2;
Giulio@768 139 </sect2>
Giulio@768 140
Giulio@768 141 <sect2>
Giulio@768 142 <title>Impilare e registrare le patch</title>
Giulio@768 143
Giulio@768 144 <para id="x_3d6">Una volta che avete finito di lavorare su una patch, o avete bisogno di lavorare su un'altra patch, potete usare di nuovo il comando <command role="hg-ext-mq">qnew</command> per creare una nuova patch. Mercurial applicherà questa patch a partire dalla vostra patch esistente.</para>
Giulio@768 145
Giulio@768 146 &interaction.mq.tutorial.qnew2;
Giulio@768 147
Giulio@768 148 <para id="x_3d7">Notate che la patch contiene le modifiche nella nostra patch precedente come parte del proprio contesto (potete vederlo più chiaramente nell'output di <command role="hg-cmd">hg annotate</command>).</para>
Giulio@768 149
Giulio@768 150 <para id="x_3d8">Finora, con l'eccezione di <command role="hg-ext-mq">qnew</command> e <command role="hg-ext-mq">qrefresh</command>, siamo stati attenti a usare solo gli ordinari comandi Mercurial. Tuttavia, MQ fornisce molti comandi che sono più facili da usare quando state pensando in termini di patch, come illustrato di seguito.</para>
Giulio@768 151
Giulio@768 152 &interaction.mq.tutorial.qseries;
Giulio@768 153
Giulio@768 154 <itemizedlist>
Giulio@768 155 <listitem><para id="x_3d9">Il comando <command role="hg-ext-mq">qseries</command> elenca tutte le patch per questo repository note a MQ, dalla più vecchia alla più recente (più recentemente <emphasis>creata</emphasis>).</para>
Giulio@768 156 </listitem>
Giulio@768 157 <listitem><para id="x_3da">Il comando <command role="hg-ext-mq">qapplied</command> elenca tutte le patch che MQ ha <emphasis>applicato</emphasis> a questo repository, ancora dalla più vecchia alla più recente (più recentemente applicata).</para>
Giulio@768 158 </listitem></itemizedlist>
Giulio@768 159 </sect2>
Giulio@768 160
Giulio@768 161 <sect2>
Giulio@768 162 <title>Manipolare la pila delle patch</title>
Giulio@768 163
Giulio@768 164 <para id="x_3db">La discussione precedente implica che ci deve essere una differenza tra patch <quote>note</quote> e patch <quote>applicate</quote>, e in effetti c'è. MQ può gestire una patch senza che sia applicata al repository.</para>
Giulio@768 165
Giulio@768 166 <para id="x_3dc">Una patch <emphasis>applicata</emphasis> ha un corrispondente changeset nel repository e gli effetti della patch e del changeset sono visibili nella directory di lavoro. Potete annullare l'applicazione di una patch usando il comando <command role="hg-ext-mq">qpop</command>. La patch estratta è ancora <emphasis>nota</emphasis>, o gestita, da MQ, ma non ha più un corrispondente changeset nel repository, e la directory di lavoro non contiene più le modifiche apportate dalla patch. La <xref linkend="fig:mq:stack"/> illustra la differenza tra patch applicate e registrate.</para>
Giulio@768 167
Giulio@768 168 <figure id="fig:mq:stack">
Giulio@768 169 <title>Patch applicate e non applicate nella pila delle patch di MQ</title>
Giulio@768 170 <mediaobject>
Giulio@768 171 <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
Giulio@768 172 <textobject><phrase>XXX add text</phrase></textobject>
Giulio@768 173 </mediaobject>
Giulio@768 174 </figure>
Giulio@768 175
Giulio@768 176 <para id="x_3de">Potete riapplicare una patch non applicata o estratta usando il comando <command role="hg-ext-mq">qpush</command>. Questo crea un nuovo changeset da far corrispondere alla patch, e le modifiche della patch diventano ancora una volta presenti nella directory di lavoro. Di seguito, vengono mostrati esempi di <command role="hg-ext-mq">qpop</command> e <command role="hg-ext-mq">qpush</command> in azione.</para>
Giulio@768 177
Giulio@768 178 &interaction.mq.tutorial.qpop;
Giulio@768 179
Giulio@768 180 <para id="x_3df">Notate che una volta che abbiamo estratto una patch o due patch, l'output di <command role="hg-ext-mq">qseries</command> rimane lo stesso, mentre quello di <command role="hg-ext-mq">qapplied</command> è cambiato.</para>
Giulio@768 181
Giulio@768 182 </sect2>
Giulio@768 183
Giulio@768 184 <sect2>
Giulio@768 185 <title>Inserire ed estrarre molte patch</title>
Giulio@768 186
Giulio@768 187 <para id="x_3e0">Mentre ognuno dei comandi <command role="hg-ext-mq">qpush</command> e <command role="hg-ext-mq">qpop</command> opera in maniera predefinita su una singola patch alla volta, potete inserire ed estrarre molte patch in un unico passaggio. L'opzione <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option> di <command role="hg-ext-mq">qpush</command> lo induce a inserire tutte le patch non applicate, mentre l'opzione <option role="hg-ext-mq-cmd-qpop-opt">-a</option> di <command role="hg-ext-mq">qpop</command> lo induce a estrarre tutte le patch applicate. (Per ulteriori modi di inserire ed estrarre molte patch, si veda la <xref linkend="sec:mq:perf"/> più avanti.)</para>
Giulio@768 188
Giulio@768 189 &interaction.mq.tutorial.qpush-a;
Giulio@768 190 </sect2>
Giulio@768 191
Giulio@768 192 <sect2>
Giulio@768 193 <title>I controlli di sicurezza, e come #overriding them#</title>
Giulio@768 194
Giulio@768 195 <para id="x_3e1">Diversi comandi MQ controllano la directory di lavoro prima di fare qualunque cosa e falliscono se trovano una qualsiasi modifica. Si comportano in questo modo per assicurarsi che non perdiate alcun cambiamento che avete fatto ma che non avete ancora incorporato in una patch. L'esempio seguente illustra questo caso: il comando <command role="hg-ext-mq">qnew</command> eviterà di creare una nuova patch se ci sono cambiamenti in sospeso, causati in questo caso dall'invocazione di <command role="hg-cmd">hg add</command> su <filename>file3</filename>.</para>
Giulio@768 196
Giulio@768 197 &interaction.mq.tutorial.add;
Giulio@768 198
Giulio@768 199 <para id="x_3e2">Tutti i comandi che controllano la directory di lavoro accettano un'opzione <quote>so cosa sto facendo</quote> che si chiama sempre <option>-f</option>. L'esatto significato di <option>-f</option> dipende dal comando. Per esempio, <command role="hg-cmd">hg qnew <option role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command> incorporerà i cambiamenti in sospeso nella nuova patch creata, ma <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command> annullerà le modifiche a qualsiasi file affetto dalla patch che sta estraendo. Assicuratevi di leggere la documentazione per l'opzione <option>-f</option> di un comando prima di usarla!</para>
Giulio@768 200 </sect2>
Giulio@768 201
Giulio@768 202 <sect2>
Giulio@768 203 <title>Lavorare su diverse patch alla volta</title>
Giulio@768 204
Giulio@768 205 <para id="x_3e3">Il comando <command role="hg-ext-mq">qrefresh</command> aggiorna sempre la patch applicata <emphasis>in cima alla pila</emphasis>. Questo significa che potete sospendere il lavoro su una patch (aggiornandola), estrarre o inserire per posizionare una patch differente in cima alla pila e lavorare su <emphasis>quella</emphasis> patch per un po'.</para>
Giulio@768 206
Giulio@768 207 <para id="x_3e4">Ecco un esempio che illustra come potete sfruttare questa possibilità. Diciamo che state sviluppando una nuova funzione sotto forma di due patch. La prima è una modifica al nucleo del vostro software e la seconda&emdash;basata sulla prima&emdash;modifica l'interfaccia utente per usare il codice che avete appena aggiunto al nucleo. Se notate un bug nel nucleo mentre state lavorando sulla patch per l'interfaccia utente, è facile correggere il nucleo. Vi basta usare <command role="hg-ext-mq">qrefresh</command> per salvare le modifiche in corso alla vostra patch di interfaccia ed estrarre tramite <command role="hg-ext-mq">qpop</command> la patch del nucleo. Correggete il bug nel nucleo, aggiornate la patch del nucleo con <command role="hg-ext-mq">qrefresh</command> e inserite la patch di interfaccia tramite <command role="hg-ext-mq">qpush</command> per continuare a lavorare dal punto dove avevate lasciato.</para>
Giulio@768 208 </sect2>
Giulio@768 209 </sect1>
Giulio@768 210
Giulio@768 211 <sect1 id="sec:mq:adv-patch">
Giulio@768 212 <title>Ulteriori informazioni sulle patch</title>
Giulio@768 213
Giulio@768 214 <para id="x_3e5">MQ usa il comando GNU <command>patch</command> per applicare le patch, quindi è utile conoscere qualche altro aspetto dettagliato sul funzionamento di <command>patch</command> e sulle patch stesse.</para>
Giulio@768 215
Giulio@768 216 <sect2>
Giulio@768 217 <title>#The strip count#</title>
Giulio@768 218
Giulio@768 219 <para id="x_3e6">Se guardate alle intestazioni di file in una patch, noterete che i percorsi dei nomi di solito hanno un componente aggiuntivo iniziale che non è presente nel percorso reale. Questo è un rimasuglio del modo in cui le persone erano solite generare le patch (viene ancora fatto in questo modo, ma è piuttosto raro con i moderni strumenti di controllo di revisione).</para>
Giulio@768 220
Giulio@768 221 <para id="x_3e7">Alice estrarrebbe un archivio, modificherebbe i file e poi deciderebbe di voler creare una patch. Quindi rinominerebbe della directory di lavoro, estrarrebbe l'archivio nuovamente (da qui nasce il bisogno di modificare il nome) e userebbe le opzioni <option role="cmd-opt-diff">-r</option> e <option role="cmd-opt-diff">-N</option> del comando <command>diff</command> per generare ricorsivamente una patch tra la directory non modificata e quella modificata. Il risultato sarebbe che il nome della directory non modificata si troverebbe all'inizio del percorso sulla parte destra in ogni intestazione di file e il nome della directory modificata si troverebbe all'inizio del percorso sulla parte destra.</para>
Giulio@768 222
Giulio@768 223 <para id="x_3e8">Dato che chi riceve la patch dalle Alice della rete probabilmente non avrebbe le due copie, modificata e non, della directory, con esattamente gli stessi nomi, il comando <command>patch</command> ha un'opzione <option role="cmd-opt-patch">-p</option> che indica il numero di elementi iniziali da eliminare dal percorso al momento di applicare una patch. Questo numero viene chiamato <emphasis>#strip count#</emphasis>.</para>
Giulio@768 224
Giulio@768 225 <para id="x_3e9">Un'opzione <quote><literal>-p1</literal></quote> significa <quote>usa uno #strip count# di uno</quote>. Se <command>patch</command> vede un nome di file <filename>foo/bar/baz</filename> in un'intestazione di file, eliminerà <filename>foo</filename> e proverà ad applicare la patch al file <filename>bar/baz</filename>. (Strettamente parlando, lo #strip count# si riferisce al numero di <emphasis>separatori di percorso</emphasis> (e dei relativi elementi) da eliminare. Uno #strip count# pari a uno trasformerà <filename>foo/bar</filename> in <filename>bar</filename>, ma <filename>/foo/bar</filename> (notate lo slash iniziale) in <filename>foo/bar</filename>.)</para>
Giulio@768 226
Giulio@768 227 <para id="x_3ea">Lo #strip count# <quote>standard</quote> per le patch è pari a uno, in quanto quasi tutte le patch contengono un elemento iniziale da eliminare nel percorso. Il comando <command role="hg-cmd">hg diff</command> di Mercurial genera nomi di percorso in questa forma, e sia il comando <command role="hg-cmd">hg import</command> che MQ si aspettano patch con uno #strip count# pari a uno.</para>
Giulio@768 228
Giulio@768 229 <para id="x_3eb">Se qualcuno vi invia una patch che volete aggiungere alla vostra coda delle patch e la patch ha bisogno di uno #strip count# diverso da uno, non potete usare semplicemente <command
Giulio@768 230 role="hg-ext-mq">qimport</command> con la patch, perché <command role="hg-ext-mq">qimport</command> non è ancora dotato di un'opzione <literal>-p</literal> (si veda il <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">problema 311</ulink>). L'alternativa migliore che avete è quella di creare una vostra patch con <command role="hg-ext-mq">qnew</command> e poi usare <command>patch -pN</command> per applicare la patch che avete ricevuto, seguito da <command role="hg-cmd">hg addremove</command> per registrare qualsiasi file aggiunto o rimosso dalla patch, seguito da <command role="hg-ext-mq">hg qrefresh</command>. Questa complessità potrebbe diventare inutile; si veda il <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">problema 311</ulink> per i dettagli.
Giulio@768 231 </para>
Giulio@768 232 </sect2>
Giulio@768 233
Giulio@768 234 <sect2>
Giulio@768 235 <title>Strategie per applicare una patch</title>
Giulio@768 236
Giulio@768 237 <para id="x_3ec">Quando <command>patch</command> applica un blocco, prova a impiegare una serie di strategie successive sempre meno accurate per fare in modo di applicare il blocco. Questa tecnica di #falling-back# spesso rende possibile prendere una patch che è stata generata da una vecchia versione di un file e applicarla alla nuova versione di quel file.</para>
Giulio@768 238
Giulio@768 239 <para id="x_3ed">Come prima cosa, <command>patch</command> cerca una corrispondenza esatta, dove i numeri di riga, il contesto e il testo da modificare devono applicarsi in maniera esatta. Se non può fare una corrispondenza esatta, cerca una corrispondenza esatta per il contesto, senza onorare le informazioni sulla numerazione delle righe. Se questa strategia ha successo, stampa una riga di output dicendo che il blocco è stato applicato, ma a una certa <emphasis>distanza</emphasis> dal numero di riga originale.</para>
Giulio@768 240
Giulio@768 241 <para id="x_3ee">Se la corrispondenza con il solo contesto fallisce, <command>patch</command> rimuove la prima e l'ultima riga del contesto e tenta una corrispondenza con la sola versione <emphasis>ridotta</emphasis> del contesto. Se il blocco con il contesto ridotto ha successo, stampa un messaggio dicendo di aver applicato il blocco con un <emphasis>fattore di incertezza</emphasis> (il numero dopo il fattore di incertezza indica quante righe del contesto sono state escluse da <command>patch</command> prima che la patch si potesse applicare).</para>
Giulio@768 242
Giulio@768 243 <para id="x_3ef">Quando nessuna di queste tecniche funziona, <command>patch</command> stampa un messaggio dicendo che il blocco in questione è stato rifiutato. Salva i blocchi rifiutati (anche chiamati semplicemente <quote>rifiuti</quote>) in un file con lo stesso nome e un'estensione <filename role="special">.rej</filename> aggiuntiva. Salva anche le copie non modificate del file con un'estensione <filename role="special">.orig</filename>; la copia del file senza alcuna estensione conterrà le modifiche fatte dal blocco che sono state <emphasis>effettivamente</emphasis> applicate. Se avete una patch che modifica il file <filename>foo</filename> con sei blocchi, e uno di essi non si riesce ad applicare, avrete: una copia <filename>foo.orig</filename> non modificata del file originale, un file <filename>foo.rej</filename> contenente un blocco e il file <filename>foo</filename> contenente le modifiche effettuate dai cinque blocchi applicati con successo.</para>
Giulio@768 244 </sect2>
Giulio@768 245
Giulio@768 246 <sect2>
Giulio@768 247 <title>Alcune stranezze nella rappresentazione delle patch</title>
Giulio@768 248
Giulio@768 249 <para id="x_3f0">Ci sono alcune cose utili da sapere sul modo in cui <command>patch</command> lavora con i file.</para>
Giulio@768 250 <itemizedlist>
Giulio@768 251 <listitem><para id="x_3f1">Questo dovrebbe già essere ovvio, ma <command>patch</command> non è in grado di gestire i file binari.</para>
Giulio@768 252 </listitem>
Giulio@768 253 <listitem><para id="x_3f2">Non si cura neanche del bit di esecuzione, bensì crea nuovi file come leggibili, ma non eseguibili.</para>
Giulio@768 254 </listitem>
Giulio@768 255 <listitem><para id="x_3f3"><command>patch</command> tratta la rimozione di un file come un diff tra il file da rimuovere e un file vuoto. Quindi la vostra idea di <quote>cancellare un file</quote> viene rappresentata in una patch come <quote>ogni riga di questo file è stata cancellata</quote>.</para>
Giulio@768 256 </listitem>
Giulio@768 257 <listitem><para id="x_3f4">Tratta l'aggiunta di un file come un diff tra un file vuoto e il file da aggiungere. Quindi la vostra idea di <quote>aggiungere un file</quote> viene rappresentata in una patch come <quote>ogni riga di questo file è stata aggiunta</quote>.</para>
Giulio@768 258 </listitem>
Giulio@768 259 <listitem><para id="x_3f5">Tratta un file rinominato come la rimozione del file con il vecchio nome e l'aggiunta del file con il nuovo nome. Questo significa che i file rinominati hanno una grande impronta sulle patch. (Notate anche che Mercurial attualmente non cerca di inferire se i file in una patch sono stati rinominati o copiati.)</para>
Giulio@768 260 </listitem>
Giulio@768 261 <listitem><para id="x_3f6"><command>patch</command> non è in grado di rappresentare i file vuoti, quindi non potete usare una patch per rappresentare la nozione di <quote>aggiungere questo vile vuoto all'albero</quote>.</para>
Giulio@768 262 </listitem>
Giulio@768 263 </itemizedlist>
Giulio@768 264 </sect2>
Giulio@768 265
Giulio@768 266 <sect2>
Giulio@768 267 <title>Fate attenzione all'incertezza</title>
Giulio@768 268
Giulio@768 269 <para id="x_3f7">Sebbene l'applicazione di un blocco a una certa distanza, o con un certo fattore di incertezza, avrà spesso un successo completo, queste tecniche inesatte lasciano naturalmente aperta la possibilità di rovinare il file modificato. Il caso più comune è tipicamente quello in cui la patch viene applicata due volte, o a una posizione sbagliata nel file. Se <command>patch</command> o <command role="hg-ext-mq">qpush</command> dovessero mai mezionare la distanza o il fattore di incertezza, dovreste assicurarvi che i file sono stati modificati in maniera corretta.</para>
Giulio@768 270
Giulio@768 271 <para id="x_3f8">Spesso è una buona idea aggiornare una patch che è stata applicata con una distanza o un fattore di incertezza; l'aggiornamento della patch genera nuove informazioni di contesto che permetteranno di applicarla in maniera pulita. Dico <quote>spesso,</quote> non <quote>sempre,</quote> perché qualche volta l'aggiornamento di una patch ne renderà impossibile l'applicazione su una revisione differente dei file coinvolti. In alcuni casi, come quando state mantenendo una patch che deve essere applicabile a versioni multiple di un albero di sorgenti, è considerato accettabile avere una patch che si applica con qualche incertezza, purché abbiate verificato i risultati del processo di applicazione in casi come questi.</para>
Giulio@768 272 </sect2>
Giulio@768 273
Giulio@768 274 <sect2>
Giulio@768 275 <title>Gestire il rifiuto</title>
Giulio@768 276
Giulio@768 277 <para id="x_3f9">Se <command role="hg-ext-mq">qpush</command> non riesce ad applicare una patch, stamperà un messaggio di errore e terminerà. Se ha lasciato alcuni file <filename role="special">.rej</filename>, normalmente è meglio correggere i blocchi rifiutati prima di inserire altre patch in cima alla pila o fare qualsiasi ulteriore modifica.</para>
Giulio@768 278
Giulio@768 279 <para id="x_3fa">Se la vostra patch <emphasis>era solita</emphasis> applicarsi in maniera pulita, e non lo fa più perché avete modificato il codice sottostante su cui le vostre patch si basavano, Mercurial Queues può aiutarvi; leggete la <xref linkend="sec:mq:merge"/> per i dettagli.</para>
Giulio@768 280
Giulio@768 281 <para id="x_3fb">Sfortunatamente, non c'è alcuna grande tecnica per gestire i blocchi rifiutati. Molto spesso, avrete bisogno di esaminare il file <filename role="special">.rej</filename> e di modificare il file di destinazione, applicando a mano i blocchi rifiutati.</para>
Giulio@768 282
Giulio@768 283 <para id="x_3fd">Un programmatore del kernel di Linux, Chris Mason (l'autore di Mercurial Queues), ha realizzato uno strumento chiamato <command>mpatch</command> (<ulink url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>), che adotta un approccio semplice per automatizzare l'applicazione dei blocchi rifiutati da <command>patch</command>. Il comando <command>mpatch</command> può aiutarvi nel caso il blocco sia stato rifiutato per quattro tipiche ragioni:</para>
Giulio@768 284
Giulio@768 285 <itemizedlist>
Giulio@768 286 <listitem><para id="x_3fe">il contesto nel mezzo di un blocco è cambiato;</para>
Giulio@768 287 </listitem>
Giulio@768 288 <listitem><para id="x_3ff">all'inizio o alla fine del blocco manca una certa quantità di contesto;</para>
Giulio@768 289 </listitem>
Giulio@768 290 <listitem><para id="x_400">un blocco più ampio potrebbe applicarsi meglio&emdash;interamente o in parte&emdash;se fosse suddiviso in blocchi più piccoli;</para>
Giulio@768 291 </listitem>
Giulio@768 292 <listitem><para id="x_401">un blocco rimuove righe con un contesto leggermente differente rispetto a quello attualmente presente nel file.</para>
Giulio@768 293 </listitem>
Giulio@768 294 </itemizedlist>
Giulio@768 295
Giulio@768 296 <para id="x_402">Se usate il comando <command>mpatch</command>, dovreste controllare doppiamente con attenzione i risultati quando avete finito. In effetti, <command>mpatch</command> impone questo metodo di doppio controllo sul risultato dello strumento, depositandovi automaticamente in un programma di gestione delle unioni quando ha concluso il proprio lavoro, in modo che possiate verificare i risultati e risolvere qualsiasi conflitto rimanente.</para>
Giulio@768 297 </sect2>
Giulio@768 298 </sect1>
Giulio@768 299
Giulio@768 300 <sect1>
Giulio@768 301 <title>Ulteriori informazioni sulla gestione delle patch</title>
Giulio@768 302
Giulio@768 303 <para id="x_6db">Man mano che acquisite familiarità con MQ, comincerete a voler eseguire altri tipi di operazioni di gestione delle patch.</para>
Giulio@768 304
Giulio@768 305 <sect2>
Giulio@768 306 <title>Cancellare le patch non volute</title>
Giulio@768 307
Giulio@768 308 <para id="x_6dc">Se volete sbarazzarvi di una patch, usate il comando <command role="hg-ext-mq">hg qdelete</command> per cancellare il file contenente la patch e rimuovere la sua voce dalla serie di patch. Se provate a cancellare una patch che è ancora applicata, <command role="hg-ext-mq">hg qdelete</command> si rifiuterà di operare.</para>
Giulio@768 309
Giulio@768 310 &interaction.ch11-qdelete.go;
Giulio@768 311 </sect2>
Giulio@768 312
Giulio@768 313 <sect2>
Giulio@768 314 <title>Convertire verso e da revisioni permanenti</title>
Giulio@768 315
Giulio@768 316 <para id="x_6dd">Una volta che avete finito di lavorare con una patch e volete trasformarla in un changeset permanente, usate il comando <command role="hg-ext-mq">hg qfinish</command>. Passate una revisione al comando per identificare la patch che volete trasformare in un normale changeset, questa patch deve essere già stata applicate.</para>
Giulio@768 317
Giulio@768 318 &interaction.ch11-qdelete.convert;
Giulio@768 319
Giulio@768 320 <para id="x_6e0">Il comando <command role="hg-ext-mq">hg qfinish</command> accetta una opzione <option>--all</option> o <option>-a</option> per trasformare tutte le patch applicate in normali changeset.</para>
Giulio@768 321
Giulio@768 322 <para id="x_6de">&Egrave; anche possibile trasformare un changeset esistente in una patch, passando l'opzione <option>-r</option> al comando <command role="hg-ext-mq">hg qimport</command>.</para>
Giulio@768 323
Giulio@768 324 &interaction.ch11-qdelete.import;
Giulio@768 325
Giulio@768 326 <para id="x_6df">Notate che ha senso convertire un changeset in una patch solo se non avete propagato quel changeset in altri repository. L'identificatore del changeset importato cambierà ogni volta che aggiornate la patch, cosa che indurrà Mercurial a trattarlo come se non fosse correlato al changeset originale che avete trasmesso da qualche altra parte.</para>
Giulio@768 327 </sect2>
Giulio@768 328 </sect1>
Giulio@768 329
Giulio@768 330 <sect1 id="sec:mq:perf">
Giulio@768 331 <title>Ottenere le prestazioni migliori da MQ</title>
Giulio@768 332
Giulio@768 333 <para id="x_403">MQ è molto efficiente nel gestire un grande numero di patch. Ho effettuato alcuni esperimenti sulle prestazioni a metà del 2006 per una presentazione che ho tenuto alla conferenza EuroPython 2006 (su macchine più moderne, dovreste aspettarvi risultati migliori di quelli che vedrete nel seguito). Come #data set# ho usato la serie di patch 2.6.17-mm1 per il kernel di Linux, contenente 1.738 patch. Ho applicato queste patch a un repository del kernel di Linux contenente tutte le 27.472 revisioni intercorse tra Linux 2.6.12-rc2 e Linux 2.6.17.</para>
Giulio@768 334
Giulio@768 335 <para id="x_404">Sul mio vecchio e lento portatile, sono riuscito a eseguire <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> per tutte le 1.738 patch in 3.5 minuti e a eseguire <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> per tutte le patch in 30 secondi. (Su portatili più recenti, il tempo per estrarre tutte le patch è sceso a due minuti.) Ho potuto aggiornare una delle patch più grandi (che ha effettuato 22.779 righe di cambiamenti a 287 file) eseguendo <command role="hg-ext-mq">qrefresh</command> in 6.6 secondi.</para>
Giulio@768 336
Giulio@768 337 <para id="x_405">Chiaramente, MQ è particolarmente adatto per lavorare su alberi di grandi dimensioni, ma ci sono alcuni trucchi che potete usare per ottenere pefrormance ancora migliori.</para>
Giulio@768 338
Giulio@768 339 <para id="x_406">Prima di tutto, provate a <quote>raggruppare</quote> insieme le operazioni. Ogni volta che eseguite <command role="hg-ext-mq">qpush</command> o <command role="hg-ext-mq">qpop</command>, questi comandi esaminano la directory di lavoro una volta per assicurarsi che non avete effettuato alcuna modifica dimenticandovi poi di invocare <command role="hg-ext-mq">qrefresh</command>. Su alberi di piccole dimensioni, il tempo impiegato da questa disamina è insignificante. Tuttavia, su un albero di medie dimensioni (contenente decine di migliaia di file), questa operazione può impiegare anche più di un secondo.</para>
Giulio@768 340
Giulio@768 341 <para id="x_407">I comandi <command role="hg-ext-mq">qpush</command> e <command role="hg-ext-mq">qpop</command> vi permettono di estrarre e inserire più patch alla volta. Potete identificare la <quote>patch di destinazione</quote> a cui volete giungere. Quando usate <command role="hg-ext-mq">qpush</command> specificando una destinazione, il comando inserirà patch fino a quando quella patch non si troverà in cima alla pila delle patch applicate. Quando usate <command role="hg-ext-mq">qpop</command> con una destinazione, MQ estrarrà patch fino a quando la patch di destinazione non si troverà in cima.</para>
Giulio@768 342
Giulio@768 343 <para id="x_408">Potete identificare una patch di destinazione usando il nome della patch oppure un numero. Se usate un identificatore numerico, il conteggio delle patch parte da zero; questo significa che la prima patch corrisponde a zero, la seconda a uno, e così via.</para>
Giulio@768 344 </sect1>
Giulio@768 345
Giulio@768 346 <sect1 id="sec:mq:merge">
Giulio@768 347 <title>Aggiornare le vostre patch quando il codice sottostante cambia</title>
Giulio@768 348
Giulio@768 349 <para id="x_409">Capita spesso di avere una pila di patch su un repository sottostante che non modificate direttamente. Se state lavorando sui cambiamenti a codice di terze parti, o su una funzione che impiegate più tempo a sviluppare rispetto alla velocità di cambiamento del codice al di sotto, avrete spesso bisogno di sincronizzarvi con il codice sottostante e di correggere ogni blocco delle vostre patch che non è più applicabile. Questa operazione si chiama <emphasis>rifondare</emphasis> la vostra serie di patch.</para>
Giulio@768 350
Giulio@768 351 <para id="x_40a">Il modo più semplice per fare questo è di usare <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> per estrarre le vostre patch, poi invocare <command role="hg-cmd">hg pull</command> per propagare i cambiamenti nel repository sottostante e infine eseguire <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> per inserire nuovamente le vostre patch. MQ interromperà l'inserimento ogni volta che incontra una patch che non riesce ad applicare a causa di qualche conflitto, dandovi la possibilità di risolvere i conflitti, aggiornare la patch affetta tramite <command role="hg-ext-mq">qrefresh</command> e continuare a inserire fino a quando non avete corretto l'intera pila.</para>
Giulio@768 352
Giulio@768 353 <para id="x_40b">Questo approccio è semplice e funziona bene se non vi aspettate modifiche al codice sottostante che influenzino quanto bene si applicano le vostre patch. Se la vostra pila di patch tocca codice che viene modificato in maniera frequente o invasiva nel repository sottostante, tuttavia, corregere a mano i blocchi rifiutati diventa velocemente una seccatura.</para>
Giulio@768 354
Giulio@768 355 <para id="x_40c">&Egrave; possibile automatizzare parzialmente il processo di rifondazione. Se le vostre patch si applicano in maniera pulita su una qualche revisione del repository sottostante, MQ può usare questa informazione per aiutarvi a risolvere i conflitti tra le vostre patch e revisioni differenti.</para>
Giulio@768 356
Giulio@768 357 <para id="x_40d">Il processo è leggermente complicato.</para>
Giulio@768 358 <orderedlist>
Giulio@768 359 <listitem><para id="x_40e">Per cominciare, invocate <command role="hg-cmd">hg qpush -a</command> per inserire tutte le vostre patch sulla revisione su cui sapete che si applicano in maniera pulita.</para>
Giulio@768 360 </listitem>
Giulio@768 361 <listitem><para id="x_40f">Salvate una copia di backup della vostra directory delle patch usando <command role="hg-cmd">hg qsave <option role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>. Questo stampa il nome della directory in cui sono state salvate le patch. Salverà le patch in una directory chiamata <filename role="special" class="directory">.hg/patches.N</filename>, dove <literal>N</literal> è un piccolo intero. Inserirà anche un <quote>changeset di salvataggio</quote> in cima alle vostre patch applicate, per registrare internamente gli stati dei file <filename role="special">series</filename> e <filename role="special">status</filename>.</para>
Giulio@768 362 </listitem>
Giulio@768 363 <listitem><para id="x_410">Usate <command role="hg-cmd">hg pull</command> per propagare i nuovi cambiamenti nel repository sottostante. (Non invocate <command role="hg-cmd">hg pull -u</command>; vedete più avanti perché.)</para>
Giulio@768 364 </listitem>
Giulio@768 365 <listitem><para id="x_411">Aggiornate la directory di lavoro alla nuova revisione di punta, usando <command role="hg-cmd">hg update <option role="hg-opt-update">-C</option></command> per #override# le patch che avete inserito.</para>
Giulio@768 366 </listitem>
Giulio@768 367 <listitem><para id="x_412">Unite tutte le patch usando <command>hg qpush -m -a</command>. L'opzione <option role="hg-ext-mq-cmd-qpush-opt">-m</option> di <command role="hg-ext-mq">qpush</command> dice a MQ di effettuare un'unione a tre vie se la patch non si riesce ad applicare.</para>
Giulio@768 368 </listitem></orderedlist>
Giulio@768 369
Giulio@768 370 <para id="x_413">Durante l'esecuzione di <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>, ogni patch nel file <filename role="special">series</filename> viene applicata normalmente. Se una patch viene applicata con un fattore di incertezza o viene rifiutata, MQ guarda alla coda che avete salvato tramite <command role="hg-ext-mq">qsave</command> ed effettua un'unione a tre vie con il corrispondente changeset. Questa unione usa il normale meccanismo di unione di Mercurial, quindi potrebbe aprire uno strumento grafico per le unioni in modo da aiutarvi a risolvere i problemi.</para>
Giulio@768 371
Giulio@768 372 <para id="x_414">Quando avete finito di risolvere gli effetti di una patch, MQ aggiornerà la vostra patch sulla base dei risultati dell'unione.</para>
Giulio@768 373
Giulio@768 374 <para id="x_415">Alla fine di questo processo, il vostro repository avrà una testa aggiuntiva proveniente dalla vecchia coda delle patch, e una copia della vecchia coda delle patch si troverà in <filename role="special" class="directory">.hg/patches.N</filename>. Potete rimuovere la testa aggiuntiva usando <command role="hg-cmd">hg qpop -a -n patches.N</command> o <command role="hg-cmd">hg strip</command>. Potete cancellare <filename role="special" class="directory">.hg/patches.N</filename> una volta che siete sicuri che non ne avete più bisogno come backup.</para>
Giulio@768 375 </sect1>
Giulio@768 376
Giulio@768 377 <sect1>
Giulio@768 378 <title>Identificare le patch</title>
Giulio@768 379
Giulio@768 380 <para id="x_416">I comandi MQ che lavorano con le patch vi permettono di fare riferimento a una patch usando il suo nome o un numero. Il riferimento per nome funziona in modo abbastanza ovvio: passate il nome <filename>foo.patch</filename> a <command role="hg-ext-mq">qpush</command>, per esempio, e il comando inserirà patch fino a quando <filename>foo.patch</filename> non verrà applicata.</para>
Giulio@768 381
Giulio@768 382 <para id="x_417">Potete abbreviare il riferimento a una patch usando sia un nome che una differenza numerica: <literal>foo.patch-2</literal> significa <quote>due patch prima di <literal>foo.patch</literal></quote>, mentre <literal>bar.patch+4</literal> significa <quote>quattro patch dopo <literal>bar.patch</literal></quote>.</para>
Giulio@768 383
Giulio@768 384 <para id="x_418">Il riferimento per indice non è molto differente. La prima patch visualizzata da <command role="hg-ext-mq">qseries</command> è la patch numero zero (sì, è uno di quei sistemi di conteggio che partono da zero), la seconda è la patch numero uno, e così via.</para>
Giulio@768 385
Giulio@768 386 <para id="x_419">MQ rende anche più facile lavorare con le patch quando state usando i normali comandi Mercurial. Tutti i comandi che accettano un identificatore di changeset accettano anche il nome di una patch applicata. MQ accresce le etichette normalmente presenti nel repository con un'etichetta eponima per ogni patch applicata. In più, le etichette speciali <literal role="tag">qbase</literal> e <literal role="tag">qtip</literal> identificano le patch applicate rispettivamente in fondo e in cima alla pila.</para>
Giulio@768 387
Giulio@768 388 <para id="x_41a">Queste aggiunte alla funzione di #tagging# di Mercurial rendono ancora più facile utilizzare le patch.</para>
Giulio@768 389 <itemizedlist>
Giulio@768 390 <listitem><para id="x_41b">Volete bombardare di patch una mailing list con l'ultima serie dei vostri cambiamenti?</para>
Giulio@768 391 <programlisting>hg email qbase:qtip</programlisting>
Giulio@768 392 <para id="x_41c">(Non sapete cosa sia un <quote>bombardamento di patch</quote>? Leggete la <xref linkend="sec:hgext:patchbomb"/>.)</para>
Giulio@768 393 </listitem>
Giulio@768 394 <listitem><para id="x_41d">Avete bisogno di vedere tutte le patch che da <literal>foo.patch</literal> in poi hanno toccato i file contenuti in una sottodirectory del vostro albero?</para>
Giulio@768 395 <programlisting>hg log -r foo.patch:qtip subdir</programlisting>
Giulio@768 396 </listitem>
Giulio@768 397 </itemizedlist>
Giulio@768 398
Giulio@768 399 <para id="x_41e">Dato che MQ rende disponibili i nomi delle patch al resto di Mercurial tramite il meccanismo interno delle etichette, non avete bisogno di digitare l'intero nome di una patch quando volete identificarla per nome.</para>
Giulio@768 400
Giulio@768 401 <para id="x_41f">Un'altra piacevole conseguenza del rappresentare i nomi di patch come etichette è che il comando <command role="hg-cmd">hg log</command> mostrerà il nome di una patch come un'etichetta, semplicemente come parte del proprio output normale. Questo rende facile distinguere visivamente le patch applicate dalle <quote>normali</quote> revisioni sottostanti. L'esempio seguente mostra alcuni comandi Mercurial in azione con le patch applicate.</para>
Giulio@768 402
Giulio@768 403 &interaction.mq.id.output;
Giulio@768 404 </sect1>
Giulio@768 405
Giulio@768 406 <sect1>
Giulio@768 407 <title>Informazioni utili</title>
Giulio@768 408
Giulio@768 409 <para id="x_420">Ci sono alcuni aspetti dell'uso di MQ che non trovano posto in sezioni dedicate, ma che è bene conoscere. Li presento qui, in un unico posto.</para>
Giulio@768 410
Giulio@768 411 <itemizedlist>
Giulio@768 412 <listitem><para id="x_421">Normalmente, quando estraete una patch tramite <command role="hg-ext-mq">qpop</command> e poi la reinserite tramite <command role="hg-ext-mq">qpush</command>, il changeset che rappresenta la patch dopo l'estrazione/inserimento avrà una <emphasis>diversa identità</emphasis> rispetto al changeset che rappresentava l'hash in precedenza. Leggete <!--<xref linkend="sec:mqref:cmd:qpush"/>-->FIXME per sapere perché succede questo.</para>
Giulio@768 413 </listitem>
Giulio@768 414 <listitem><para id="x_422">Non è una buona idea usare <command role="hg-cmd">hg merge</command> per unire i cambiamenti da un altro ramo con un changeset di patch, almeno se volete mantenere la <quote>natura di patch</quote> di quel changeset e dei changeset che si trovano sotto a quello nella pila delle patch. Se provate a farlo, sembrerà avere successo, ma l'effetto sarà quello di confondere MQ.</para>
Giulio@768 415 </listitem>
Giulio@768 416 </itemizedlist>
Giulio@768 417 </sect1>
Giulio@768 418
Giulio@768 419 <sect1 id="sec:mq:repo">
Giulio@768 420 <title>Gestire le patch in un repository</title>
Giulio@768 421
Giulio@768 422 <para id="x_423">Dato che la directory <filename role="special" class="directory">.hg/patches</filename> di MQ risiede fuori dalla directory di lavoro di un repository Mercurial, il repository Mercurial <quote>sottostante</quote> non sa nulla della gestione o della presenza delle patch.</para>
Giulio@768 423
Giulio@768 424 <para id="x_424">Questo presenta l'interessante possibilità di gestire i contenuti della directory delle patch come un repository Mercurial indipendente. Questo può essere un modo utile per lavorare. Per esempio, potete lavorare su una patch per un po', aggiornala tramite <command role="hg-ext-mq">qrefresh</command> it, poi usare <command role="hg-cmd">hg commit</command> per registrare lo stato corrente della patch. Questo vi permette di <quote>ritornare</quote> a quella versione della patch più tardi.</para>
Giulio@768 425
Giulio@768 426 <para id="x_425">Potete quindi condividere differenti versioni della stessa pila di patch tra molteplici repository sottostanti. Uso questo quando sto sviluppando una funzione del kernel di Linux. Ho una copia intatta dei miei sorgenti del kernel per ogni diversa architettura di CPU e un repository clonato sotto ognuno di questi che contiene le patch su cui sto lavorando. Quando voglio collaudare un cambiamento su un'architettura differente, trasmetto le mie patch correnti al repository associato con il kernel di quell'architettura, estraggo e inserisco tutte le mie patch, e assemblo e collaudo quel kernel.</para>
Giulio@768 427
Giulio@768 428 <para id="x_426">Gestire le patch in un repository rende possibile a più sviluppatori di lavorare sulla stessa serie di patch senza scontrarsi tra loro, il tutto basandosi su sorgenti sottostanti che potrebbero o non potrebbero controllare.</para>
Giulio@768 429
Giulio@768 430 <sect2>
Giulio@768 431 <title>Il supporto di MQ per i repository di patch</title>
Giulio@768 432
Giulio@768 433 <para id="x_427">MQ vi aiuta a lavorare con la directory <filename role="special" class="directory">.hg/patches</filename> come un repository; quando preparate un repository per lavorare con le patch usando <command role="hg-ext-mq">qinit</command>, potete passare l'opzione <option role="hg-ext-mq-cmd-qinit-opt">hg -c</option> per creare la directory <filename role="special" class="directory">.hg/patches</filename> sotto forma di un repository Mercurial.</para>
Giulio@768 434
Giulio@768 435 <note>
Giulio@768 436 <para id="x_428">Se dimenticate di usare l'opzione <option role="hg-ext-mq-cmd-qinit-opt">hg -c</option>, potete semplicemente posizionarvi nella directory <filename role="special" class="directory">.hg/patches</filename> in qualsiasi momento e invocare <command role="hg-cmd">hg init</command>. Non dimenticate, però, di aggiungere una voce per il file <filename role="special">status</filename> al file <filename role="special">.hgignore</filename> (<command role="hg-cmd">hg qinit <option role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command> fa questo automaticamente per voi); non volete <emphasis>davvero</emphasis> gestire il file <filename role="special">status</filename>.</para>
Giulio@768 437 </note>
Giulio@768 438
Giulio@768 439 <para id="x_42a">Per convenienza, se MQ nota che la directory <filename class="directory">.hg/patches</filename> è un repository, userà automaticamente <command role="hg-cmd">hg add</command> per aggiungere ogni patch che create e importate.</para>
Giulio@768 440
Giulio@768 441 <para id="x_42b">MQ fornisce il comando abbreviato <command role="hg-ext-mq">qcommit</command> che esegue <command role="hg-cmd">hg commit</command> nella directory <filename role="special" class="directory">.hg/patches</filename>, per salvare noiose digitazioni.</para>
Giulio@768 442
Giulio@768 443 <para id="x_42c">Infine, come convenienza per gestire la directory delle patch, potete definire l'alias <command>mq</command> sui sistemi Unix. Per esempio, sui sistemi Linux che usano la shell <command>bash</command>, potete includere il seguente frammento nel vostro file <filename role="home">~/.bashrc</filename>.</para>
Giulio@768 444
Giulio@768 445 <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
Giulio@768 446
Giulio@768 447 <para id="x_42d">Potete poi invocare comandi della forma <command>mq pull</command> dal repository principale.</para>
Giulio@768 448 </sect2>
Giulio@768 449
Giulio@768 450 <sect2>
Giulio@768 451 <title>Alcune cose a cui fare attenzione</title>
Giulio@768 452
Giulio@768 453 <para id="x_42e">Il supporto di MQ per lavorare con un repository pieno di patch è limitato in alcuni aspetti di dettaglio.</para>
Giulio@768 454
Giulio@768 455 <para id="x_42f">MQ non può automaticamente scoprire i cambiamenti che avete fatto alla directory delle patch. Se usate <command role="hg-cmd">hg pull</command>, fate delle modifiche a mano, o invocate <command role="hg-cmd">hg update</command> per aggiornare i cambiamenti alle patch o al file <filename role="special">series</filename>, dovrete usare <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> e poi <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> nel repository sottostante per fare in modo che quei cambiamenti si mostrino anche là. Se dimenticate di fare questo, potete confondere l'idea che MQ si è fatto su quali patch sono state applicate.</para>
Giulio@768 456
Giulio@768 457 </sect2>
Giulio@768 458 </sect1>
Giulio@768 459 <sect1 id="sec:mq:tools">
Giulio@768 460 <title>Strumenti di terze parti che lavorano con le patch</title>
Giulio@768 461
Giulio@768 462 <para id="x_430">Una volta che avete lavorato che le patch per un po', vi troverete affamati di strumenti che vi aiutino a capire e manipolare le patch che state maneggiando.</para>
Giulio@768 463
Giulio@768 464 <para id="x_431">Il comando <command>diffstat</command> <citation>web:diffstat</citation> genera un istogramma delle modifiche effettuate a ogni file in una patch. Fornisce un buon modo di <quote>#get a sense of#</quote> una patch&emdash;quali file coinvolge e quante modifiche introduce a ogni file e nell'insieme. (Trovo che è una buona idea usare l'opzione <option role="cmd-opt-diffstat">-p</option> di <command>diffstat</command> #as a matter of course#, in quanto altrimenti proverà a fare cose furbe con i prefissi dei nomi di file che almeno io trovo inevitabilmente confuse.)</para>
Giulio@768 465
Giulio@768 466 &interaction.mq.tools.tools;
Giulio@768 467
Giulio@768 468 <para id="x_432">Il pacchetto <literal role="package">patchutils</literal> <citation>web:patchutils</citation> è inestimabile. Fornisce un insieme di piccole utilità che seguono la <quote>filosofia Unix:</quote> ognuna fa una singola cosa utile con una patch. Il comando di <literal role="package">patchutils</literal> che uso di più è <command>filterdiff</command>, che estrae sottinsiemi di un file di patch. Per esempio, data una patch che modifica centinaia di file attraverso dozzine di directory, una singola invocazione di <command>filterdiff</command> può generare una patch più piccola che tocca solo i file il cui nome corrisponde a un particolare pattern di tipo glob. Leggete la <!--<xref linkend="mq-collab:tips:interdiff"/>-->FIXME per un altro esempio.</para>
Giulio@768 469
Giulio@768 470 </sect1>
Giulio@768 471 <sect1>
Giulio@768 472 <title>Strategie valide per lavorare con le patch</title>
Giulio@768 473
Giulio@768 474 <para id="x_433">Sia che voi stiate lavorando su una serie di patch da sottoporre a un progetto software libero o open source, o su una serie che intendete trattare come una sequenza di normali changeset una volta che avete finito, potete usare alcune semplici tecniche per mantenere bene organizzato il vostro lavoro.</para>
Giulio@768 475
Giulio@768 476 <para id="x_434">Date nomi descrittivi alle vostre patch. Un buon nome per una patch potrebbe essere <filename>rework-device-alloc.patch</filename>, perché vi suggerirà immediatamente qual è lo scopo della patch. I nomi lunghi non dovrebbero essere un problema; non digiterete i nomi spesso, ma <emphasis>invocherete</emphasis> comandi come <command role="hg-ext-mq">qapplied</command> e <command role="hg-ext-mq">qtop</command> più e più volte. Una buona denominazione diventa particolarmente importante quando avete un certo numero di patch con cui lavorare, o se vi state destreggiando tra un certo numero di attività differenti e le vostre patch ottengono solo una frazione della vostra attenzione.</para>
Giulio@768 477
Giulio@768 478 <para id="x_435">Fate attenzione alle patch su cui state lavorando. Usate frequentemente il comando <command role="hg-ext-mq">qtop</command> e date un'occhiata al testo delle vostre patch&emdash;per esempio, usando <command role="hg-cmd">hg tip <option role="hg-opt-tip">-p</option></command>)&emdash;per assicurarvi di sapere dove vi trovate. Mi è capitato spesso di modificare e aggiornare una patch diversa da quella che intendevo, ed è spesso complicato trasferire le modifiche nella patch giusta dopo averle effettuate in quella sbagliata.</para>
Giulio@768 479
Giulio@768 480 <para id="x_436">Per questo motivo, vale davvero la pena di investire un po' di tempo per imparare a usare alcuni degli strumenti di terze parti che ho descritto nella <xref linkend="sec:mq:tools"/>, in particolare <command>diffstat</command> e <command>filterdiff</command>. Il primo vi darà velocemente un'idea di quali modifiche effettuerà la vostra patch, mentre il secondo vi renderà più facile #splice out# blocchi particolari di una patch e inserirli in un'altra.</para>
Giulio@768 481
Giulio@768 482 </sect1>
Giulio@768 483 <sect1>
Giulio@768 484 <title>MQ #cookbook#</title>
Giulio@768 485
Giulio@768 486 <sect2>
Giulio@768 487 <title>Gestire patch <quote>elementari</quote></title>
Giulio@768 488
Giulio@768 489 <para id="x_437">Dato che il costo di aggiungere file in un nuovo repository Mercurial è così basso, ha molto senso gestire le patch in questo modo anche se volete semplicemente fare alcune modifiche a un archivo di sorgenti che avete scaricato.</para>
Giulio@768 490
Giulio@768 491 <para id="x_438">Cominciate con lo scaricare ed estrarre l'archivio dei sorgenti, trasformandoli in un repository Mercurial.</para>
Giulio@768 492
Giulio@768 493 &interaction.mq.tarball.download;
Giulio@768 494
Giulio@768 495 <para id="x_439">Continuate creando una pila di patch e facendo le vostre modifiche.</para>
Giulio@768 496
Giulio@768 497 &interaction.mq.tarball.qinit;
Giulio@768 498
Giulio@768 499 <para id="x_43a">Diciamo che trascorrono alcune settimane o mesi e gli autori di quel pacchetto rilascia una nuova versione. Prima di tutto, propagate i loro cambiamenti nel repository.</para>
Giulio@768 500
Giulio@768 501 &interaction.mq.tarball.newsource;
Giulio@768 502
Giulio@768 503 <para id="x_43b">La serie di comandi iniziata con <command role="hg-cmd">hg locate</command> che avete appena invocato cancella tutti i file dalla directory di lavoro, in modo che l'opzione <option role="hg-opt-commit">--addremove</option> di <command role="hg-cmd">hg commit</command> possa effettivamente dirvi quali file sono stati davvero rimossi nella nuova versione dei sorgenti.</para>
Giulio@768 504
Giulio@768 505 <para id="x_43c">Infine, potete applicare le vostre patch al nuovo albero.</para>
Giulio@768 506
Giulio@768 507 &interaction.mq.tarball.repush;
Giulio@768 508 </sect2>
Giulio@768 509
Giulio@768 510 <sect2 id="sec:mq:combine">
Giulio@768 511 <title>Combinare intere patch</title>
Giulio@768 512
Giulio@768 513 <para id="x_43d">MQ vi fornisce il comando <command role="hg-ext-mq">qfold</command> per consentirvi di combinare intere patch. Questo comando <quote>include</quote> le patch che nominate, nell'ordine in cui le nominate, nella patch applicata in cima alla pila, e concatena le loro descrizioni alla fine della descrizione di questa patch. Le patch che includete non devono essere applicate prima di includerle.</para>
Giulio@768 514
Giulio@768 515 <para id="x_43e">L'ordine in cui includete le patch è importante. Se la vostra patch applicata in cima alla pila è <literal>foo</literal> e voi utilizzate <command role="hg-ext-mq">qfold</command> per includere <literal>bar</literal> e <literal>quux</literal> in essa, otterrete una patch che opererà come se aveste applicato prima <literal>foo</literal>, poi <literal>bar</literal>, seguito da <literal>quux</literal>.</para>
Giulio@768 516 </sect2>
Giulio@768 517
Giulio@768 518 <sect2>
Giulio@768 519 <title>Unire parte di una patch con un'altra</title>
Giulio@768 520
Giulio@768 521 <para id="x_43f">Unire <emphasis>parte</emphasis> di una patch con un'altra patch è più difficile che combinare intere patch.</para>
Giulio@768 522
Giulio@768 523 <para id="x_440">Se volete spostare cambiamenti a interi file, potete usare le opzioni <option role="cmd-opt-filterdiff">-i</option> e <option role="cmd-opt-filterdiff">-x</option> di <command>filterdiff</command> per scegliere le modifiche da ritagliare da una patch, aggiungendo il risultato del comando in coda alla patch con cui volete effettuare l'unione. Di solito non avrete bisogno di modificare la patch da cui prelevate le modifiche da unire. Piuttosto, MQ riporterà alcune parti rifiutate quando eseguite <command role="hg-ext-mq">qpush</command> su di essa (a causa dei blocchi che avete spostato nell'altra patch) e voi potrete semplicemente aggiornare la patch tramite <command role="hg-ext-mq">qrefresh</command> per scartare i blocchi duplicati.</para>
Giulio@768 524
Giulio@768 525 <para id="x_441">Se avete una patch con più blocchi che modificano un file, e volete spostare solo alcuni di questi blocchi, il lavoro diventa più complicato, ma potete comunque automatizzarlo parzialmente. Usate <command>lsdiff -nvv</command> per stampare alcuni metadati sulla patch.</para>
Giulio@768 526
Giulio@768 527 &interaction.mq.tools.lsdiff;
Giulio@768 528
Giulio@768 529 <para id="x_442">Questo comando stampa tre tipi diversi di numeri:</para>
Giulio@768 530 <itemizedlist>
Giulio@768 531 <listitem><para id="x_443">(nella prima colonna) un <emphasis>numero di file</emphasis> per identificare ogni file modificato dalla patch;</para>
Giulio@768 532 </listitem>
Giulio@768 533 <listitem><para id="x_444">(sulla riga seguente, indentato) il numero di riga del file modificato dove comincia il blocco; e</para>
Giulio@768 534 </listitem>
Giulio@768 535 <listitem><para id="x_445">(sulla stessa riga) un <emphasis>numero di blocco</emphasis> per identificare quel blocco.</para>
Giulio@768 536 </listitem>
Giulio@768 537 </itemizedlist>
Giulio@768 538
Giulio@768 539 <para id="x_446">Dovrete ispezionare visivamente e leggere la patch per identificare i numeri di file e di blocco che volete, ma poi potrete passarli alle opzioni <option role="cmd-opt-filterdiff">--files</option> e <option role="cmd-opt-filterdiff">--hunks</option> di <command>filterdiff</command> per selezionare esattamente quel file e quel blocco che volete estrarre.</para>
Giulio@768 540
Giulio@768 541 <para id="x_447">Una volta che avete questo blocco, potete aggiungerlo in coda alla vostra patch di destinazione e continuare con il resto della <xref linkend="sec:mq:combine"/>.</para>
Giulio@768 542
Giulio@768 543 </sect2>
Giulio@768 544 </sect1>
Giulio@768 545 <sect1>
Giulio@768 546 <title>Differenze tra quilt e MQ</title>
Giulio@768 547
Giulio@768 548 <para id="x_448">Se avete già familiarità con quilt, MQ fornisce un insieme di comandi simile. Ci sono alcune differenze nel modo in cui questi comandi lavorano.</para>
Giulio@768 549
Giulio@768 550 <para id="x_449">Avrete già notato che la maggior parte dei comandi di quilt hanno una controparte MQ che comincia semplicemente con una <quote><literal>q</literal></quote>. Le eccezioni sono i comandi <literal>add</literal> e <literal>remove</literal> di quilt, le cui controparti sono i normali comandi Mercurial <command role="hg-cmd">hg add</command> e <command role="hg-cmd">hg remove</command>. Non c'è alcun comando MQ equivalente al comando quilt <literal>edit</literal>.</para>
Giulio@768 551
Giulio@768 552 </sect1>
Giulio@768 553 </chapter>