hgbook

annotate it/ch10-hook.xml @ 761:a2086a5e6ab8

Literal transation of Ch.10.
author Giulio@puck
date Tue Jul 21 18:19:26 2009 +0200 (2009-07-21)
parents
children 6cb8638afe1a
rev   line source
Giulio@761 1 <chapter id="chap:hook">
Giulio@761 2 <?dbhtml filename="usare-gli-hook-per-gestire-gli-eventi-nei-repository.html"?>
Giulio@761 3 <title>Usare gli hook per gestire gli eventi nei repository</title>
Giulio@761 4
Giulio@761 5 <para id="x_1e6">Mercurial offre un potente meccanismo per consentirvi di effettuare azioni automatiche in risposta agli eventi che accadono in un repository. In alcuni casi, potete persino controllare la risposta di Mercurial a questi eventi.</para>
Giulio@761 6
Giulio@761 7 <para id="x_1e7">Il nome che Mercurial usa per indicare una di queste azioni è <emphasis>hook</emphasis>. Gli hook vengono chiamati <quote>trigger</quote> in alcuni sistemi di controllo di revisione, ma i due nomi si riferiscono alla stessa idea.</para>
Giulio@761 8
Giulio@761 9 <sect1>
Giulio@761 10 <title>Un'introduzione agli hook in Mercurial</title>
Giulio@761 11
Giulio@761 12 <para id="x_1e8">Qui di seguito troverete una breve lista degli hook supportati da Mercurial. Rivisiteremo ognuno di questi hook in maggior dettaglio più avanti, nella <xref linkend="sec:hook:ref"/>.</para>
Giulio@761 13
Giulio@761 14 <para id="x_1f6">Ognuno degli hook la cui descrizione comincia con la parola <quote>Controlling</quote> ha l'abilità di determinare se un'attività può procedere. Se l'hook ha successo, l'attività può procedere; se fallisce, l'attività non viene permessa oppure viene annullata, a seconda dell'hook.</para>
Giulio@761 15
Giulio@761 16 <itemizedlist>
Giulio@761 17 <listitem><para id="x_1e9"><literal role="hook">changegroup</literal>: viene eseguito dopo che un gruppo di changeset proveniente da qualche altra parte è stato propagato nel repository.</para>
Giulio@761 18 </listitem>
Giulio@761 19 <listitem><para id="x_1ea"><literal role="hook">commit</literal>: viene eseguito dopo che un nuovo changeset è stato creato nel repository locale.</para>
Giulio@761 20 </listitem>
Giulio@761 21 <listitem><para id="x_1eb"><literal role="hook">incoming</literal>: viene eseguito una volta per ogni nuovo changeset proveniente da qualche altra parte che è stato propagato nel repository. Notate la differenza con <literal role="hook">changegroup</literal>, che viene eseguito una volta per ogni <emphasis>gruppo</emphasis> di changeset propagato nel repository.</para>
Giulio@761 22 </listitem>
Giulio@761 23 <listitem><para id="x_1ec"><literal role="hook">outgoing</literal>: viene eseguito dopo che un gruppo di changeset è stato trasmesso da questo repository.</para>
Giulio@761 24 </listitem>
Giulio@761 25 <listitem><para id="x_1ed"><literal role="hook">prechangegroup</literal>: viene eseguito prima di cominciare a propagare un gruppo di changeset nel repository.</para>
Giulio@761 26 </listitem>
Giulio@761 27 <listitem><para id="x_1ee"><literal role="hook">precommit</literal>:
Giulio@761 28 Controlling. This is run before starting a commit.</para>
Giulio@761 29 </listitem>
Giulio@761 30 <listitem><para id="x_1ef"><literal role="hook">preoutgoing</literal>: Controlling. Viene eseguito prima di cominciare a trasmettere un gruppo di changeset da questo repository.</para>
Giulio@761 31 </listitem>
Giulio@761 32 <listitem><para id="x_1f0"><literal role="hook">pretag</literal>: Controlling. Viene eseguito prima di creare un'etichetta.</para>
Giulio@761 33 </listitem>
Giulio@761 34 <listitem><para id="x_1f1"><literal role="hook">pretxnchangegroup</literal>: Controlling. Viene eseguito dopo che un gruppo di changeset proveniente da un altro repository è stato propagato nel repository locale, ma prima che la transazione che renderebbe permanenti i cambiamenti nel repository sia completata.</para>
Giulio@761 35 </listitem>
Giulio@761 36 <listitem><para id="x_1f2"><literal role="hook">pretxncommit</literal>: Controlling. Viene eseguito dopo che un nuovo changeset è stato creato nel repository locale, ma prima che la transazione che lo renderebbe permanente sia completata.</para>
Giulio@761 37 </listitem>
Giulio@761 38 <listitem><para id="x_1f3"><literal role="hook">preupdate</literal>: Controlling. Viene eseguito prima di cominciare un aggiornamento o un'unione della directory di lavoro.</para>
Giulio@761 39 </listitem>
Giulio@761 40 <listitem><para id="x_1f4"><literal role="hook">tag</literal>: viene eseguito dopo che un'etichetta è stata creata.</para>
Giulio@761 41 </listitem>
Giulio@761 42 <listitem><para id="x_1f5"><literal role="hook">update</literal>: viene eseguito dopo che un'operazione di aggiornamento o di unione della directory di lavoro è stata completata.</para>
Giulio@761 43 </listitem></itemizedlist>
Giulio@761 44
Giulio@761 45 </sect1>
Giulio@761 46 <sect1>
Giulio@761 47 <title>Hook e sicurezza</title>
Giulio@761 48
Giulio@761 49 <sect2>
Giulio@761 50 <title>Gli hook vengono eseguiti con i vostri privilegi</title>
Giulio@761 51
Giulio@761 52 <para id="x_1f7">Quando eseguite un comando Mercurial in un repository e quel comando causa l'esecuzione di un hook, quell'hook esegue sul <emphasis>vostro</emphasis> sistema, sotto il <emphasis>vostro</emphasis> account utente, con il <emphasis>vostro</emphasis> livello di privilegio. Dato che gli hook sono frammenti di codice eseguibile, dovreste trattarli con un adeguato livello di sospetto. Non installate un hook a meno che non confidiate di sapere chi lo ha creato e che cosa fa.</para>
Giulio@761 53
Giulio@761 54 <para id="x_1f8">In alcuni casi, potreste essere esposti a hook che non avete installato voi. Se lavorate con Mercurial su un sistema che non vi è familiare, Mercurial eseguirà gli hook definiti nel file <filename role="special">~/.hgrc</filename> globale per quel sistema.</para>
Giulio@761 55
Giulio@761 56 <para id="x_1f9">Se state lavorando con un repository posseduto da un altro utente, Mercurial può eseguire gli hook definiti nel repository di quell'utente, ma li eseguirà ancora con la <quote>vostra identità</quote>. Per esempio, se estraete i cambiamenti da quel repository tramite <command role="hg-cmd">hg pull</command>, e il suo file <filename role="special">.hg/hgrc</filename> definisce un hoook <literal role="hook">outgoing</literal> locale, quell'hook verrà eseguito sotto il vostro account utente anche se non possedete quel repository.</para>
Giulio@761 57
Giulio@761 58 <note>
Giulio@761 59 <para id="x_1fa">Questo si applica se state estraendo cambiamenti da un repository su un file system locale o di rete. Se state eseguendo l'estrazione via HTTP o SSH, qualsiasi hook <literal role="hook">outgoing</literal> eseguirà sotto qualunque account sta eseguendo il processo server, sul server.</para>
Giulio@761 60 </note>
Giulio@761 61
Giulio@761 62 <para id="x_1fb">Per vedere quali hook sono definiti in un repository, usate il comando <command role="hg-cmd">hg showconfig hooks</command>. Se state lavorando in un repository, ma state comunicando con un repository che non possedete (e.g. usando <command role="hg-cmd">hg pull</command> o <command role="hg-cmd">hg incoming</command>), ricordate che sono gli hook dell'altro repository che dovreste controllare, non i vostri.</para>
Giulio@761 63 </sect2>
Giulio@761 64
Giulio@761 65 <sect2>
Giulio@761 66 <title>Gli hooks non si propagano</title>
Giulio@761 67
Giulio@761 68 <para id="x_1fc">In Mercurial, gli hook non sono soggetti a controllo di revisione e non si propagano quando clonate un repository o ne estraete i cambiamenti. La ragione è semplice: un hook è un frammento di codice eseguibile completamente arbitrario. Esegue sotto la vostra identità utente, con il vostro livello di privilegio, sulla vostra macchina.</para>
Giulio@761 69
Giulio@761 70 <para id="x_1fd">Sarebbe estremamente avventato per qualsiasi sistema distribuito di controllo di revisione implementare hook soggetti al controllo di revisione, dato che questo offrirebbe un modo facilmente sfruttabile di sovvertire gli account degli utenti del sistema di controllo di revisione.</para>
Giulio@761 71
Giulio@761 72 <para id="x_1fe">Dato che Mercurial non propaga gli hook, se state collaborando con altre persone su un progetto comune, non dovreste presumere che gli altri stiano usando gli stessi hook Mercurial che state usando voi, o che i loro siano correttamente configurati. Dovreste documentare gli hook che vi aspettate che le persone usino.</para>
Giulio@761 73
Giulio@761 74 <para id="x_1ff">In una intranet aziendale, questo è in qualche modo più facile da controllare, dato che per esempio potete fornire una installazione <quote>standard</quote> di Mercurial su un file system NFS e usare un file <filename role="special">~/.hgrc</filename> #site-wide# per definire hook che tutti gli utenti vedranno. Tuttavia, come vedremo nella prossima sezione, anche questo approccio ha dei limiti.</para>
Giulio@761 75 </sect2>
Giulio@761 76
Giulio@761 77 <sect2>
Giulio@761 78 <title>Gli hook possono essere sostituiti</title>
Giulio@761 79
Giulio@761 80 <para id="x_200">Mercurial vi consente di sostituire una definizione di hook ridefinendo quell'hook. Potete disabilitarlo impostando il suo valore alla stringa vuota, o cambiare il suo comportamento come desiderate.</para>
Giulio@761 81
Giulio@761 82 <para id="x_201">Se fate ricorso a un file <filename role="special">~/.hgrc</filename> di sistema o #site-wide# che definisce alcuni hook, dovreste quindi capire che i vostri utenti sono in grado di disabilitare o sostituire quegli hook.</para>
Giulio@761 83 </sect2>
Giulio@761 84
Giulio@761 85 <sect2>
Giulio@761 86 <title>Assicurarvi che gli hook critici vengano eseguiti</title>
Giulio@761 87
Giulio@761 88 <para id="x_202">Talvolta potreste voler imporre una politica che non volete che gli altri siano in grado di aggirare. Per esempio, potreste avere un requisito che ogni changeset deve passare una rigorosa serie di test. Definire questo requisito attraverso un hook in un file <filename role="special">~/.hgrc</filename> #site-wide# non funzionerà per i computer portatili degli utenti remoti, e naturalmente gli utenti locali potranno sovvertirla a piacimento sostituendo quell'hook.</para>
Giulio@761 89
Giulio@761 90 <para id="x_203">Invece, potete impostare le vostre politiche per l'uso di Mercurial in modo da aspettarsi che le persone propaghino i cambiamenti attraverso un server <quote>canonico</quote> ben noto che avete messo in sicurezza e configurato adeguatamente.</para>
Giulio@761 91
Giulio@761 92 <para id="x_204">Un modo di fare questo è attraverso una combinazione di ingegneria sociale e tecnologia. Impostate un account con accesso ristretto; gli utenti possono trasmettere i cambiamenti attraverso la rete ai repository gestiti da questo account, ma non possono usare l'account per entrare sul server ed eseguire i normali comandi di shell. In questo scenario, un utente può effettuare il commit di un changeset che contiene tutta la vecchia spazzatura che vuole.</para>
Giulio@761 93
Giulio@761 94 <para id="x_205">Quando qualcuno trasmette un changeset al server da cui tutti estraggono i cambiamenti, il server verificherà il changeset prima di accettarlo come permanente, e lo rifiuterà se non riesce a passare i test. Se le persone si limitano a estrarre i cambiamenti da questo server di filtraggio, questo servirà ad assicurare che tutti i cambiamenti estratti dalle persone siano stati auotamticamente controllati.</para>
Giulio@761 95
Giulio@761 96 </sect2>
Giulio@761 97 </sect1>
Giulio@761 98
Giulio@761 99 <sect1 id="sec:hook:simple">
Giulio@761 100 <title>Una breve guida all'uso degli hook</title>
Giulio@761 101
Giulio@761 102 <para id="x_212">Scrivere un hook Mercurial è facile. Cominciamo con un hook che viene eseguito quando l'invocazione di <command role="hg-cmd">hg commit</command> termina e che stampa semplicemente l'hash del changeset appena creato. L'hook è chiamato <literal role="hook">commit</literal>.
Giulio@761 103 </para>
Giulio@761 104
Giulio@761 105 <para id="x_213">Tutti gli hook seguono lo schema presentato in questo esempio.</para>
Giulio@761 106
Giulio@761 107 &interaction.hook.simple.init;
Giulio@761 108
Giulio@761 109 <para id="x_214">Aggiungete una voce alla sezione <literal role="rc-hooks">hooks</literal> del vostro file <filename role="special">~/.hgrc</filename>. Sulla sinistra si trova il nome dell'evento su cui attivarsi, sulla destra si trova l'azione da intraprendere. Come potete vedere, potete eseguire comandi di shell arbitrari in un hook. Mercurial passa informazioni aggiuntive all'hook usando le variabili d'ambiente (cercate <envar>HG_NODE</envar> nell'esempio).</para>
Giulio@761 110
Giulio@761 111 <sect2>
Giulio@761 112 <title>Effettuare molteplici azioni per evento</title>
Giulio@761 113
Giulio@761 114 <para id="x_215">Piuttosto spesso, vorrete definire più di un hook per un particolare tipo di evento, come mostrato qui sotto.</para>
Giulio@761 115
Giulio@761 116 &interaction.hook.simple.ext;
Giulio@761 117
Giulio@761 118 <para id="x_216">Mercurial vi permette di fare questo aggiungendo una <emphasis>estensione</emphasis> alla fine del nome di un hook. Il nome di un hook si estende dando il nome dell'hook, seguito da un punto (il carattere <quote><literal>.</literal></quote>), seguito da altro testo di vostra scelta. Per esempio, Mercurial eseguirà sia <literal>commit.foo</literal> che <literal>commit.bar</literal> all'occorrenza dell'evento <literal>commit</literal>.</para>
Giulio@761 119
Giulio@761 120 <para id="x_217">Per dare un ordine di esecuzione ben definito quando ci sono molteplici hook definiti per un evento, Mercurial ordina gli hook secondo l'estensione ed esegue i comandi di hook in questo ordine. Nell'esempio precedente, eseguirà <literal>commit.bar</literal> prima di <literal>commit.foo</literal>, e <literal>commit</literal> prima di entrambi.</para>
Giulio@761 121
Giulio@761 122 <para id="x_218">&Egrave; una buona idea usare un'estensione in qualche modo descrittiva quando definite un nuovo hook. Questo vi aiuterà a ricordare lo scopo di quell'hook. Se l'hook fallisce, otterrete un messaggio di errore che contiene il nome dell'hook e l'estensione, quindi l'impiego di una estensione descrittiva potrebbe darvi un suggerimento immediato sul motivo per cui l'hook è fallito (si veda la <xref linkend="sec:hook:perm"/> per un esempio).</para>
Giulio@761 123
Giulio@761 124 </sect2>
Giulio@761 125 <sect2 id="sec:hook:perm">
Giulio@761 126 <title>Controllare se un'attività può procedere</title>
Giulio@761 127
Giulio@761 128 <para id="x_219">Nei nostri primi esempi, abbiamo usato l'hook <literal role="hook">commit</literal>, che viene eseguito dopo che un commit è stato completato. Questo è uno tra i vari hook Mercurial che vengono eseguiti dopo che un'attività si conclude. Questi hook non hanno alcun modo di influenzare l'attività stessa.</para>
Giulio@761 129
Giulio@761 130 <para id="x_21a">Mercurial definisce un certo numero di eventi che accadono prima che un'attività cominci, o dopo che è cominciata ma prima che termini. Gli hook che vengono attivati da questi eventi hanno l'abilità aggiuntiva di scegliere se l'attività può continuare o se verrà abortita.</para>
Giulio@761 131
Giulio@761 132 <para id="x_21b">L'hook <literal role="hook">pretxncommit</literal> viene eseguito dopo che un commit è stato completamente eseguito ma non è ancora concluso. In altre parole, i metadati che rappresentano il changeset sono stati scritti su disco, ma la transazione non ha ancora avuto il permesso di completarsi. L'hook <literal role="hook">pretxncommit</literal> ha l'abilità di decidere se la transazione può completarsi oppure se deve essere abortita.</para>
Giulio@761 133
Giulio@761 134 <para id="x_21c">Se l'hook <literal role="hook">pretxncommit</literal> termina con un codice di stato uguale a zero, la transazione può completare, il commit si conclude e l'hook <literal role="hook">commit</literal> viene eseguito. Se l'hook <literal role="hook">pretxncommit</literal> termina con un codice di stato diverso da zero, la transazione viene abortita, i metadati che rappresentano il changeset vengono cancellati e l'hook <literal role="hook">commit</literal> non viene eseguito.</para>
Giulio@761 135
Giulio@761 136 &interaction.hook.simple.pretxncommit;
Giulio@761 137
Giulio@761 138 <para id="x_21d">L'hook in questo esempio controlla che il messaggio di commit contenga un identificatore di bug. Se lo contiene, il commit può completare, altrimenti il commit viene abortito.</para>
Giulio@761 139
Giulio@761 140 </sect2>
Giulio@761 141 </sect1>
Giulio@761 142 <sect1>
Giulio@761 143 <title>Implementare i vostri hook</title>
Giulio@761 144
Giulio@761 145 <para id="x_21e">Quando state scrivendo un hook, potreste trovare utile eseguire Mercurial con l'opzione <option role="hg-opt-global">-v</option> oppure con l'elemento di configurazione <envar role="rc-item-ui">verbose</envar> impostato a <quote>true</quote>. Quando fate così, Mercurial stamperà un messaggio prima di invocare ogni hook.</para>
Giulio@761 146
Giulio@761 147 <sect2 id="sec:hook:lang">
Giulio@761 148 <title>Scegliere come il vostro hook dovrebbe eseguire</title>
Giulio@761 149
Giulio@761 150 <para id="x_21f">Potete implementare un hook come un programma normale&emdhas;tipicamente uno script di shell&emdash;o come una funzione Python che viene eseguita nell'ambito del processo Mercurial.</para>
Giulio@761 151
Giulio@761 152 <para id="x_220">Implementare un hook come programma esterno ha il vantaggio di non richiedere alcuna conoscenza del funzionamento interno di Mercurial. Potete invocare i normali comandi Mercurial per ottenere qualsiasi informazione aggiuntiva di cui abbiate bisogno. Il #trade-off# è che gli hook esterni sono più lenti rispetto agli hook #in-process#.</para>
Giulio@761 153
Giulio@761 154 <para id="x_221">Un hook Python #in-process# ha accesso completo alla API di Mercurial e non <quote>#shell out#</quote> a un altro processo, quindi è inerentemente più veloce rispetto a un hook esterno. In più, ottenere la maggior parte delle informazioni richieste da un hook è più facile usando la API di Mercurial che eseguendo i comandi Mercurial.</para>
Giulio@761 155
Giulio@761 156 <para id="x_222">Se siete a vostro agio con Python, o richiedete prestazioni elevate, implementarei vostri hook in Python potrebbe essere una buona scelta. Tuttavia, quando avete un hook semplice da scrivere e le prestazioni non vi interessano (probabilmente per la maggior parte degli hook), uno script di shell è perfettamente adeguato.</para>
Giulio@761 157
Giulio@761 158 </sect2>
Giulio@761 159 <sect2 id="sec:hook:param">
Giulio@761 160 <title>I parametri di hook</title>
Giulio@761 161
Giulio@761 162 <para id="x_223">Mercurial invoca ogni hook con un insieme di parametri ben definito. In Python, un parametro viene passato come un argomento con nome alla vostra funzione di hook. Per un programma esterno, un parametro viene passato come una variabile d'ambiente.</para>
Giulio@761 163
Giulio@761 164 <para id="x_224">Sia che il vostro hook sia implementato in Python che come uno script di shell, i nomi e i valori dei parametri specifici per quell'hook saranno gli stessi. Un parametro booleano sarà rappresentato come un valore booleano in Python, ma come il numero 1 (per <quote>vero</quote>) o 0 (per <quote>falso</quote>) come una variabile d'ambiente per un hook esterno. Se il nome di un parametro di hook è <literal>foo</literal>, anche l'argomento con nome per un hook Python sarà chiamato <literal>foo</literal>, mentre la variabile d'ambiente per un hook esterno sarà chiamata <literal>HG_FOO</literal>.</para>
Giulio@761 165 </sect2>
Giulio@761 166
Giulio@761 167 <sect2>
Giulio@761 168 <title>I valori di ritorno degli hook e il controllo delle attività</title>
Giulio@761 169
Giulio@761 170 <para id="x_225">Un hook che viene eseguito con successo deve terminare con uno stato uguale a zero se è esterno, o restituire il valore booleano <quote>falso</quote> se è #in-process#. Il fallimento viene indicato con uno stato di terminazione diverso da zero per un hook esterno, o dal valore booleano <quote>vero</quote> per un hook #in-process#. Se un hook #in-process# solleva un'eccezione, l'hook viene considerato come fallito.</para>
Giulio@761 171
Giulio@761 172 <para id="x_226">Per un hook che controlla se un'attività può procedere, zero o falso significano <quote>concesso</quote>, mentre un numero diverso da zero, vero, o un'eccezione significano <quote>negato</quote>.</para>
Giulio@761 173 </sect2>
Giulio@761 174
Giulio@761 175 <sect2>
Giulio@761 176 <title>Scrivere un hook esterno</title>
Giulio@761 177
Giulio@761 178 <para id="x_227">Quando definite un hook esterno nel vostro file <filename role="special">~/.hgrc</filename> e l'hook viene eseguito, il suo valore viene passato alla vostra shell, che lo interpreta. Questo significa che potete usare i normali costrutti di shell nel corpo dell'hook.</para>
Giulio@761 179
Giulio@761 180 <para id="x_228">Un hook eseguibile viene sempre eseguito con la sua directory corrente impostata alla directory radice del repository.</para>
Giulio@761 181
Giulio@761 182 <para id="x_229">Ogni parametro di hook viene passato come una variabile di ambiente con il nome in maiuscolo preceduto dalla stringa <quote><literal>HG_</literal></quote>.
Giulio@761 183 </para>
Giulio@761 184
Giulio@761 185 <para id="x_22a">Con l'eccezione dei parametri di hook, Mercurial non imposta o modifica alcuna variabile d'ambiente quando esegue un hook. Questo è utile da ricordare se state scrivendo un hook #site-wide# che potrebbe venire eseguito da un certo numero di utenti differenti con differenti variabili d'ambiente impostate. In situazioni multi-utente, non dovreste fare affidamento sul fatto che le variabili di ambiente siano impostate con i valori che avete nel vostro ambiente quando state collaudando l'hook.</para>
Giulio@761 186 </sect2>
Giulio@761 187
Giulio@761 188 <sect2>
Giulio@761 189 <title>Dire a Mercurial di usare un hook #in-process#</title>
Giulio@761 190
Giulio@761 191 <para id="x_22b">La sintassi del file <filename role="special">~/.hgrc</filename> per definire un hook #in-process# è leggermente differente da quella per un hook eseguibile. Il valore dell'hook deve cominciare con il testo <quote><literal>python:</literal></quote> e proseguire con il nome completamente qualificato dell'oggetto invocabile da usare come il valore dell'hook.</para>
Giulio@761 192 </para>
Giulio@761 193
Giulio@761 194 <para id="x_22c">Il modulo in cui si trova l'hook viene automaticamente importato quando l'hook viene eseguito. Fino a quando il nome del modulo e il valore di <envar>PYTHONPATH</envar> sono corretti, dovrebbe <quote>funzionare e basta</quote>.
Giulio@761 195 </para>
Giulio@761 196
Giulio@761 197 <para id="x_22d">Il seguente frammento di un file <filename role="special">~/.hgrc</filename> di esempio illustra la sintassi e il significato delle nozioni appena descritte.</para>
Giulio@761 198 <programlisting>[hooks]
Giulio@761 199 commit.example = python:mymodule.submodule.myhook</programlisting>
Giulio@761 200 <para id="x_22e">Quando Mercurial esegue l'hook <literal>commit.example</literal>, importa <literal>mymodule.submodule</literal>, cerca l'oggetto invocabile chiamato <literal>myhook</literal> e lo invoca.</para>
Giulio@761 201 </sect2>
Giulio@761 202
Giulio@761 203 <sect2>
Giulio@761 204 <title>Implementare un hook #in-process#</title>
Giulio@761 205
Giulio@761 206 <para id="x_22f">Il più semplice hook #in-process# non fa nulla, ma illustra la forma base della API degli hook:</para>
Giulio@761 207 <programlisting>def myhook(ui, repo, **kwargs):
Giulio@761 208 pass</programlisting>
Giulio@761 209 <para id="x_230">Il primo argomento di un hook Python è sempre un oggetto <literal role="py-mod-mercurial.ui">ui</literal>. Il secondo è un oggetto repository, al momento sempre un'istanza di <literal role="py-mod-mercurial.localrepo">localrepository</literal>. Gli altri argomenti con nome seguono questi due argomenti. Quali vengono passati dipende dall'hook che viene invocato, ma un hook può ignorare gli argomenti di cui non ha bisogno depositandoli in un dizionario di argomenti con nome, come succede con <literal>**kwargs</literal> qui sopra.</para>
Giulio@761 210
Giulio@761 211 </sect2>
Giulio@761 212 </sect1>
Giulio@761 213 <sect1>
Giulio@761 214 <title>Alcuni hook di esempio</title>
Giulio@761 215
Giulio@761 216 <sect2>
Giulio@761 217 <title>Scrivere messaggi di commit significativi</title>
Giulio@761 218
Giulio@761 219 <para id="x_231">&Egrave; difficile immaginare un messaggio di commit utile che sia anche molto breve. Il semplice hook <literal role="hook">pretxncommit</literal> dell'esempio seguente vi impedirà di esguire il commit di un changeset con un messaggio più piccolo di dieci byte.</para>
Giulio@761 220
Giulio@761 221 &interaction.hook.msglen.go;
Giulio@761 222 </sect2>
Giulio@761 223
Giulio@761 224 <sect2>
Giulio@761 225 <title>Controllare lo spazio bianco in coda</title>
Giulio@761 226
Giulio@761 227 <para id="x_232">Un uso interessante per un hook relativo ai commit è quello di aiutarvi a scrivere codice più pulito. Un semplice esempio di <quote>codice più pulito</quote> è l'affermazione che un cambiamento non dovrebbe aggiungere alcuna nuova riga di testo che contiene <quote>spazio bianco in coda</quote>. Lo spazio bianco in coda è composto da una serie di spazi e caratteri di tabulazione alla fine di una riga di testo. Nella maggior parte dei casi, lo spazio bianco in coda è rumore invisibile e superfluo, ma è occasionalmente problematico, e in genere le persone preferiscono sbarazzarsene.</para>
Giulio@761 228
Giulio@761 229 <para id="x_233">Potete usare l'hook <literal role="hook">precommit</literal> o l'hook <literal role="hook">pretxncommit</literal> per scoprire se avete un problema di spazio bianco in coda. Se usate <literal role="hook">precommit</literal>, l'hook non saprà quali file state inserendo, quindi dovrà controllare ogni file modificato nel repository alla ricerca di spazio bianco in coda. Se volete inserire un cambiamento al solo file <filename>foo</filename>, ma il flie <filename>bar</filename> contiene spazio bianco in coda, effettuare un controllo tramite l'hook <literal role="hook">precommit</literal> vi impedirà di eseguire il commit di <filename>foo</filename> a causa dei problemi con <filename>bar</filename>. Questo non sembra il comportamento corretto.</para>
Giulio@761 230
Giulio@761 231 <para id="x_234">Se doveste scegliere l'hook <literal role="hook">pretxncommit</literal>, il controllo non accadrà fino al momento appena precedente il completamento della transizione di commit. Questo vi consentirà di controllare il problema solo sui file esatti che verranno inseriti. Tuttavia, se avete inserito il messaggio di commit interattivamente e l'hook fallisce, la transazione verrà abortita e dovrete riscrivere il messaggio di commit dopo aver corretto lo spazio bianco in coda e invocato ancora <command role="hg-cmd">hg commit</command>.</para>
Giulio@761 232
Giulio@761 233 &interaction.ch09-hook.ws.simple;
Giulio@761 234
Giulio@761 235 <para id="x_235">In questo esempio, introduciamo un semplice hook <literal role="hook">pretxncommit</literal> che controlla lo spazio bianco in coda. Questo hook è breve, ma non molto utile. Termina con uno stato di errore se un cambiamento aggiunge una riga con spazio bianco in coda a un file qualsiasi, ma non stampa alcuna informazione che potrebbe aiutarci a individuare il file o la riga che contiene il problema. L'hook ha anche la piacevole proprietà di non fare attenzione alle righe non modificate, in quanto solo le righe che introducono nuovo spazio bianco in coda causano problemi.</para>
Giulio@761 236
Giulio@761 237 &ch09-check_whitespace.py.lst;
Giulio@761 238
Giulio@761 239 <para id="x_236">Questa versione è molto più complessa, ma anche molto più utile. Analizza un diff in formato unified per vedere se una qualsiasi riga aggiunge spazio bainco in coda e stampa ilnome del file e il numero della riga di ogni occorrenza di questo tipo. Anche meglio, se il cambiamento aggiunge spazio bianco in coda, questo hook salva il messaggio di commit e stampa il nome del file salvato prima di uscire e dire a Mercurial di abortire la transazione, in modo che possiate usare l'opzione <option role="hg-opt-commit">-l filename</option> del comando <command role="hg-cmd">hg commit</command> per riutilizzare il messaggio di commit salvato una volta che avete corretto il problema.</para>
Giulio@761 240
Giulio@761 241 &interaction.ch09-hook.ws.better;
Giulio@761 242
Giulio@761 243 <para id="x_237">Come digressione finale, notate in questo esempio l'uso della funzionalità di modifica sul posto di <command>sed</command> per eliminare lo spazio bianco in coda da un file. Questo impiego è sufficientemente conciso e utile che lo riprodurrò qui di seguito (usando <command>perl</command> per essere sicuro).</para>
Giulio@761 244 <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting>
Giulio@761 245
Giulio@761 246 </sect2>
Giulio@761 247 </sect1>
Giulio@761 248 <sect1>
Giulio@761 249 <title>Hook inclusi</title>
Giulio@761 250
Giulio@761 251 <para id="x_238">Mercurial viene distribuito con diversi hook inclusi che potete trovare nella directory <filename class="directory">hgext</filename> dell'albero dei sorgenti di Mercurial. Se state usando un pacchetto eseguibile di Mercurial, gli hook si trovano nella directory <filename class="directory">hgext</filename> posizionata dovunque il vostro pacchetto abbia installato Mercurial.</para>
Giulio@761 252
Giulio@761 253 <sect2>
Giulio@761 254 <title><literal role="hg-ext">acl</literal>&emdash;controllo di accesso per parti di un repository</title>
Giulio@761 255
Giulio@761 256 <para id="x_239">L'estensione <literal role="hg-ext">acl</literal> vi permette di controllare a quali utenti remoti è permesso di trasmettere changeset verso un server attraverso la rete. Potete proteggere qualsiasi porzione di un repository (compreso l'intero repository), in modo che uno specifico utente remoto possa trasmettere cambiamenti che non influenzano le parti protette.</para>
Giulio@761 257
Giulio@761 258 <para id="x_23a">Questa estensione implementa il controllo di accesso sulla base dell'identità dell'utente che effettua la trasmissione, <emphasis>non</emphasis> di chi ha eseguito il commit dei changeset che vengono trasferiti. Ha senso usare questo hook solo se avete un ambiente server chiuso che autentica gli utenti remoti e volete essere sicuri che solo specifici utenti possano trasmettere cambiamenti a quel server.</para>
Giulio@761 259
Giulio@761 260 <sect3>
Giulio@761 261 <title>Configurare l'hook <literal role="hook">acl</literal></title>
Giulio@761 262
Giulio@761 263 <para id="x_23b">Per gestire i cambiamenti in entrata, l'hook <literal role="hg-ext">acl</literal> deve essere usato come un hook <literal role="hook">pretxnchangegroup</literal>. Questo vi permette di vedere quali file vengono modificati da ogni changeset in entrata e di abortire un gruppo di changeset se modificano file <quote>proibiti</quote>. Ecco un esempio di come attivare l'hook:</para>
Giulio@761 264 <programlisting>[hooks]
Giulio@761 265 pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
Giulio@761 266
Giulio@761 267 <para id="x_23c">L'estensione <literal role="hg-ext">acl</literal> si configura usando tre sezioni.</para>
Giulio@761 268
Giulio@761 269 <para id="x_23d">La sezione <literal role="rc-acl">acl</literal> contiene solo la voce <envar role="rc-item-acl">sources</envar>, che elenca le fonti di cambiamenti in entrata a cui l'hook deve fare attenzione. Di solito, non avrete bisogno di configurare questa sezione.</para>
Giulio@761 270 <itemizedlist>
Giulio@761 271 <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>: controlla i changeset in entrata che arrivano da un repository remoto via HTTP o SSH. Questo è il valore predefinito di <envar role="rc-item-acl">sources</envar> e di solito è l'unica impostazione di cui avrete bisogno per questo elemento di configurazione.</para>
Giulio@761 272 </listitem>
Giulio@761 273 <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>: controlla i changeset in entrata che arrivano attraverso un'estrazione da un repository locale.</para>
Giulio@761 274 </listitem>
Giulio@761 275 <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>: controlla i cambiamenti in entrata che arrivano attraverso una trasmissione da un repository locale.</para>
Giulio@761 276 </listitem>
Giulio@761 277 <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>: controlla i changeset in entrata che arrivano da un altro repository attraverso un #bundle#.</para>
Giulio@761 278 </listitem></itemizedlist>
Giulio@761 279
Giulio@761 280 <para id="x_242">La sezione <literal role="rc-acl.allow">acl.allow</literal> controlla gli utenti a cui è permesso aggiungere changeset al repository. Se questa sezione non è presente, il permesso viene concesso a tutti gli utenti a cui non viene esplicitamente negato. Se questa sezione è presente, il permesso viene negato a tutti gli utenti a cui non viene esplicitamente concesso (quindi una sezione vuota significa che il permesso è negato a tutti gli utenti).</para>
Giulio@761 281
Giulio@761 282 <para id="x_243">La sezione <literal role="rc-acl.deny">acl.deny</literal> determina a queli utenti viene impedito di aggiungere changeset al repository. Se questa sezione non è presente o è vuota, tutti gli utenti hanno il permesso di aggiungere.</para>
Giulio@761 283
Giulio@761 284 <para id="x_244">Le sintassi per le sezioni <literal role="rc-acl.allow">acl.allow</literal> e <literal role="rc-acl.deny">acl.deny</literal> sono identiche. Sulla sinistra di ogni voce si trova un pattern di tipo glob che corrisponde a file e directory relativi alla radice del repository, sulla destra si trova un nome utente.</para>
Giulio@761 285
Giulio@761 286 <para id="x_245">Nell'esempio seguente, l'utente <literal>docwriter</literal> può trasmettere cambiamenti solo al sottoalbero <filename class="directory">docs</filename> del repository, mentre l'utente <literal>intern</literal> può trasmettere cambiamenti a qualsiasi file o directory tranne <filename class="directory">source/sensitive</filename>.
Giulio@761 287 </para>
Giulio@761 288 <programlisting>[acl.allow]
Giulio@761 289 docs/** = docwriter
Giulio@761 290 [acl.deny]
Giulio@761 291 source/sensitive/** = intern</programlisting>
Giulio@761 292
Giulio@761 293 </sect3>
Giulio@761 294 <sect3>
Giulio@761 295 <title>Collaudo e risoluzione dei problemi</title>
Giulio@761 296
Giulio@761 297 <para id="x_246">Se volete collaudare l'hook <literal role="hg-ext">acl</literal>, eseguitelo con le informazioni di debug di Mercurial abilitate. Dato che probabilmente lo eseguirete su un server dove non è conveniente (o talvolta possibile) passare l'opzione <option role="hg-opt-global">--debug</option>, non dimenticatevi che potete abilitare le informazioni di debug nel vostro file <filename role="special">~/.hgrc</filename>:
Giulio@761 298 </para>
Giulio@761 299 <programlisting>[ui]
Giulio@761 300 debug = true</programlisting>
Giulio@761 301 <para id="x_247">Con questo abilitato, l'hook <literal role="hg-ext">acl</literal> stamperà abbastanza informazioni da permettervi di capire perché sta consentendo o vietando le trasmissioni da specifici utenti.</para>
Giulio@761 302
Giulio@761 303 </sect3>
Giulio@761 304 </sect2>
Giulio@761 305
Giulio@761 306 <sect2>
Giulio@761 307 <title><literal
Giulio@761 308 role="hg-ext">bugzilla</literal>&emdash;integrazione con Bugzilla</title>
Giulio@761 309
Giulio@761 310 <para id="x_248">L'estensione <literal role="hg-ext">bugzilla</literal> aggiunge un commento a un bug su Bugzilla ogni volta che trova un riferimento all'identificatore di quel bug in un messaggio di commit. Potete installare questo hook su un server condiviso, in modo che l'hook venga eseguito ogni volta che un utente remoto trasmette i cambiamenti a quel server.</para>
Giulio@761 311
Giulio@761 312 <para id="x_249">L'hook aggiunge al bug un commento che somiglia a questo (potete configurare i contenuti del commento, come vedrete fra un attimo):</para>
Giulio@761 313 <programlisting>Changeset aad8b264143a, made by Joe User
Giulio@761 314 &lt;joe.user@domain.com&gt; in the frobnitz repository, refers
Giulio@761 315 to this bug. For complete details, see
Giulio@761 316 http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
Giulio@761 317 Changeset description: Fix bug 10483 by guarding against some
Giulio@761 318 NULL pointers</programlisting>
Giulio@761 319 <para id="x_24a">Il valore di questo hook è che automatizza il processo di aggiornare un bug ogni volta che un changeset vi fa riferimento. Se configurate l'hook in maniera adeguata, faciliterà la navigazione diretta da un bug su Bugzilla a un changeset che si riferisce a quel bug.</para>
Giulio@761 320
Giulio@761 321 <para id="x_24b">Potete usare il codice di questo hook come un punto di partenza per ricette di integrazione con Bugzilla più esotiche. Ecco alcune possibilità.</para>
Giulio@761 322 <itemizedlist>
Giulio@761 323 <listitem><para id="x_24c">Richiedere che ogni changeset trasmesso al server abbia un identificatore di bug valido nel suo messaggio di commit. In questo caso, vorrete configurare l'hook come un hook <literal role="hook">pretxncommit</literal>. Questo permetterebbe all'hook di rifiutare cambiamenti che non contengono identificatori di bug.</para>
Giulio@761 324 </listitem>
Giulio@761 325 <listitem><para id="x_24d">Permettere ai changeset in entrata di modificare automaticamente lo <emphasis>stato</emphasis> di un bug, come pure di aggiungere semplicemente un commento. Per esempio, l'hook potrebbe riconoscere la stringa <quote>fixed bug 31337</quote> come indicatore che dovrebbe aggiornare lo stato del bug 31337 a <quote>richiede un collaudo</quote>.</para>
Giulio@761 326 </listitem></itemizedlist>
Giulio@761 327
Giulio@761 328 <sect3 id="sec:hook:bugzilla:config">
Giulio@761 329 <title>Configurare l'hook <literal role="hook">bugzilla</literal></title>
Giulio@761 330
Giulio@761 331 <para id="x_24e">Dovreste configurare questo hook nel file <filename role="special">~/.hgrc</filename> del vostro server come un hook <literal role="hook">incoming</literal>, per esempio come segue:</para>
Giulio@761 332 <programlisting>[hooks]
Giulio@761 333 incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
Giulio@761 334
Giulio@761 335 <para id="x_24f">A causa della natura specializzata di questo hook e dato che Bugzilla non è stato implementato con questo tipo di integrazioni in mente, configurare questo hook è un processo in qualche modo complicato.</para>
Giulio@761 336
Giulio@761 337 <para id="x_250">Prima di cominciare, dovete installare i #binding# Python per MySQL sulla macchina (o le macchine) dove intendete eseguire l'hook. Se non sono disponibili sotto forma di pacchetto eseguibile per il vostro sistema, potete scaricarli da <citation>web:mysql-python</citation>.
Giulio@761 338 </para>
Giulio@761 339
Giulio@761 340 <para id="x_251">Le informazioni di configurazione per questo hook si trovano nella sezione <literal role="rc-bugzilla">bugzilla</literal> del vostro file <filename role="special">~/.hgrc</filename>.
Giulio@761 341 </para>
Giulio@761 342 <itemizedlist>
Giulio@761 343 <listitem><para id="x_252"><envar role="rc-item-bugzilla">version</envar>: la versione di Bugzilla installata sul server. Lo schema di database che Bugzilla usa cambia occasionalmente, quindi questo hook deve sapere esattamenre quale schema usare.</para>
Giulio@761 344 </listitem>
Giulio@761 345 <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>: il nome della macchina del server MySQL che memorizza i vostri dati di Bugzilla. Il database deve essere configurato per consentire le connessioni da qualunque macchina stia eseguendo l'hook <literal role="hook">bugzilla</literal>.
Giulio@761 346 </para>
Giulio@761 347 </listitem>
Giulio@761 348 <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>: il nome utente con il quale connettersi al server MySQL. Il database deve essere configurato per consentire a questo utente di connettersi da qualunque macchina stia eseguendo l'hook <literal role="hook">bugzilla</literal>. Questo utente deve essere in grado di modificare le tabelle di Bugzilla. Il valore predefinito di questo elemento è <literal>bugs</literal>, che è il nome standard dell'utente Bugzilla in un database MySQL.</para>
Giulio@761 349 </listitem>
Giulio@761 350 <listitem><para id="x_255"><envar role="rc-item-bugzilla">password</envar>: la password MySQL per l'utente che avete configurato alla voce precedente. Il testo della password viene memorizzato in chiaro, quindi dovreste assicurarvi che utenti non autorizzati non possano leggere il file <filename role="special">~/.hgrc</filename> dove avete inserito questa informazione.</para>
Giulio@761 351 </listitem>
Giulio@761 352 <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>: il nome del database Bugzilla sul server MySQL. Il valore predefinito di questo elemento è <literal>bugs</literal>, che è il nome standard del database MySQL dove Bugzilla memorizza i propri dati.</para>
Giulio@761 353 </listitem>
Giulio@761 354 <listitem><para id="x_257"><envar role="rc-item-bugzilla">notify</envar>: se volete che Bugzilla invii una email di notifica agli interessati dopo che questo hook ha aggiunto un commento a un bug, avrete bisogno che questo hook esegua un comando ogni volta che aggiorna il database. Il comando da eseguire dipende da dove avete installato Bugzilla, ma tipicamente somiglierà al seguente, se avete installato Bugzilla in <filename class="directory">/var/www/html/bugzilla</filename>:</para>
Giulio@761 355 <programlisting>cd /var/www/html/bugzilla &amp;&amp;
Giulio@761 356 ./processmail %s nobody@nowhere.com</programlisting>
Giulio@761 357 </listitem>
Giulio@761 358 <listitem><para id="x_258">Il programma <literal>processmail</literal> di Bugzilla si aspetta che gli vengano passati un identificatore di bug (l'hook sostituisce <quote><literal>%s</literal></quote> con l'identificatore di bug) e un indirizzo email. Si aspetta anche di essere in grado di scrivere su alcuni file nella directory in cui viene eseguito. Se Bugzilla e questo hook non sono installati sulla stessa macchina, dovrete trovare un modo per eseguire <literal>processmail</literal> sul server dove Bugzilla è installato.</para>
Giulio@761 359 </listitem></itemizedlist>
Giulio@761 360
Giulio@761 361 </sect3>
Giulio@761 362 <sect3>
Giulio@761 363 <title>Correlare i nomi utente Mercurial ai nomi utente Bugzilla</title>
Giulio@761 364
Giulio@761 365 <para id="x_259">Di default, l'hook <literal role="hg-ext">bugzilla</literal> prova a utilizzare l'indirizzo email di chi ha eseguito il commit del changeset come il nome utente Bugzilla con cui aggiornare un bug. Se questa impostazione non vi soddisfa, potete correlare gli indirizzi email degli utenti Mercurial ai nomi utente Bugzilla tramite una sezione <literal role="rc-usermap">usermap</literal>.</para>
Giulio@761 366
Giulio@761 367 <para id="x_25a">Ogni elemento nella sezione <literal role="rc-usermap">usermap</literal> contiene un indirizzo emial sulla sinistra e un nome utente Bugzilla sulla destra.</para>
Giulio@761 368 <programlisting>[usermap]
Giulio@761 369 jane.user@example.com = jane</programlisting>
Giulio@761 370 <para id="x_25b">Potete tenere i dati della sezione <literal role="rc-usermap">usermap</literal> in un normale file <filename role="special">~/.hgrc</filename>, oppure dire all'hook <literal role="hg-ext">bugzilla</literal> di leggere le informazioni da un file <filename>usermap</filename> esterno. In quest'ultimo caso, potete memorizzare i dati del file <filename>usermap</filename> da soli in (per esempio) un repository modificabile dall'utente. Questo rende possibile permettere ai vostri utenti di mantenere le proprie voci della sezione <envar role="rc-item-bugzilla">usermap</envar>. Il file <filename role="special">~/.hgrc</filename> principale potrebbe somigliare a questo:</para>
Giulio@761 371 <programlisting># il normale file hgrc fa riferimento a un file di correlazioni esterno
Giulio@761 372 [bugzilla]
Giulio@761 373 usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
Giulio@761 374 <para id="x_25c">Mentre il file <filename>usermap</filename> a cui fa riferimento potrebbe somigliare a questo:</para>
Giulio@761 375 <programlisting># bugzilla-usermap.conf - all'interno di un repository Mercurial
Giulio@761 376 [usermap] stephanie@example.com = steph</programlisting>
Giulio@761 377
Giulio@761 378 </sect3>
Giulio@761 379 <sect3>
Giulio@761 380 <title>Configurare il testo che viene aggiunto a un bug</title>
Giulio@761 381
Giulio@761 382 <para id="x_25d">Potete configurare il testo che questo hook aggiunge come commento specificandolo sotto forma di un template Mercurial. Diverse voci del file <filename role="special">~/.hgrc</filename> (sempre nella sezione <literal role="rc-bugzilla">bugzilla</literal>) controllano questo comportamento.</para>
Giulio@761 383 <itemizedlist>
Giulio@761 384 <listitem><para id="x_25e"><literal>strip</literal>: il numero di parti iniziali da eliminare dal percorso di un repository per costruire un percorso parziale da usare in un URL. Per esempio, se i repository sul vostro server si trovano nella directory <filename class="directory">/home/hg/repos</filename>, e voi avete un repository il cui percorso è <filename class="directory">/home/hg/repos/app/tests</filename>, allora impostando <literal>strip</literal> a <literal>4</literal> otterrete il percorso parziale <filename class="directory">app/tests</filename>. L'hook renderà disponibile questo percorso parziale con il nome <literal>webroot</literal> durante l'espansione di un template.</para>
Giulio@761 385 </listitem>
Giulio@761 386 <listitem><para id="x_25f"><literal>template</literal>: il testo del template da usare. In aggiunta alle solite variabili relative ai changeset, questo template può usare <literal>hgweb</literal> (il valore dell'elemento di configurazione <literal>hgweb</literal> menzionato in precedenza) e <literal>webroot</literal> (il percorso costruito usando l'elemeno <literal>strip</literal> appena descritto).</para>
Giulio@761 387 </listitem></itemizedlist>
Giulio@761 388
Giulio@761 389 <para id="x_260">In più, potete aggiungere un elemento <envar role="rc-item-web">baseurl</envar> alla sezione <literal role="rc-web">web</literal> del vostro file <filename role="special">~/.hgrc</filename>. L'hook <literal role="hg-ext">bugzilla</literal> lo renderà disponibile durante l'espansione di un template, come la stringa di base da usare nel costruire un URL che consentirà agli utenti di navigare da un commento Bugzilla verso un changeset correlato. Ecco un esempio di come usare questo elemento:</para>
Giulio@761 390 <programlisting>[web]
Giulio@761 391 baseurl = http://hg.domain.com/</programlisting>
Giulio@761 392
Giulio@761 393 <para id="x_261">Ecco un esempio dell'insieme di informazioni di configurazione da usare per l'hook <literal role="hg-ext">bugzilla</literal>.</para>
Giulio@761 394
Giulio@761 395 &ch10-bugzilla-config.lst;
Giulio@761 396
Giulio@761 397 </sect3>
Giulio@761 398 <sect3>
Giulio@761 399 <title>Collaudo e risoluzione dei problemi</title>
Giulio@761 400
Giulio@761 401 <para id="x_262">I problemi più comuni con la configurazione dell'hook <literal role="hg-ext">bugzilla</literal> sono relativi all'esecuzione dello script <filename>processmail</filename> di Bugzilla e alla correlazione tra nomi utente Mercurial e nomi utente Bugzilla.</para>
Giulio@761 402
Giulio@761 403 <para id="x_263">Se ricordate quanto detto nella <xref linkend="sec:hook:bugzilla:config"/>, l'utente che esegue il processo Mercurial sul server è anche quello che eseguirà lo script <filename>processmail</filename>. Questo script talvolta chiederà a Bugzilla di scrivere sui file nella sua directory di configurazione, e di solito i file di configurazione di Bugzilla sono proprietà dell'utente che esegue il processo del vostro server web.</para>
Giulio@761 404
Giulio@761 405 <para id="x_264">Potete far eseguire <filename>processmail</filename> con un'identità utente appropriata tramite il comando <command>sudo</command>. Ecco una voce di esempio da un file <filename>sudoers</filename>.</para>
Giulio@761 406 <programlisting>hg_user = (httpd_user)
Giulio@761 407 NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
Giulio@761 408 <para id="x_265">Questo consente all'utente <literal>hg_user</literal> di eseguire il programma <filename>processmail-wrapper</filename> sotto l'identità dell'utente <literal>httpd_user</literal>.</para>
Giulio@761 409
Giulio@761 410 <para id="x_266">Questa indirezione attraverso uno script che funge da involucro è necessaria, perché <filename>processmail</filename> si aspetta di venire eseguito con la propria directory corrente impostata al percorso di installazione di Bugzilla, ma non è possibile specificare questo vincolo in un file <filename>sudoers</filename>. Il contenuto dello script involucro è semplice:</para>
Giulio@761 411 <programlisting>#!/bin/sh
Giulio@761 412 cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
Giulio@761 413 <para id="x_267">Non sembra che l'indirizzo email passato a <filename>processmail</filename> abbia importanza.</para>
Giulio@761 414
Giulio@761 415 <para id="x_268">Se la vostra <literal role="rc-usermap">usermap</literal> non è impostata correttamente, gli utenti vedranno un messaggio di errore stampato dall'hook <literal role="hg-ext">bugzilla</literal> quando trasmetotno i cambiamenti al server. Il messaggio di errore somiglierà al seguente:</para>
Giulio@761 416 <programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting>
Giulio@761 417 <para id="x_269">Questo significa che l'indirizzo email dell'utente Mercurial, <literal>john.q.public@example.com</literal>, non è un nome utente Bugizlla valido, né possiede una voce nella vostra <literal role="rc-usermap">usermap</literal> che lo metta in relazione con un nome utente Bugzilla valido.</para>
Giulio@761 418
Giulio@761 419 </sect3>
Giulio@761 420 </sect2>
Giulio@761 421
Giulio@761 422 <sect2>
Giulio@761 423 <title><literal role="hg-ext">notify</literal>&emdash;inviare notifiche via email</title>
Giulio@761 424
Giulio@761 425 <para id="x_26a">Sebbene il server web predefinito di Mercurial fornisca i feed RSS dei cambiamenti per ogni repository, molte persone preferiscono ricevere notifiche dei cambiamenti via email. L'hook <literal role="hg-ext">notify</literal> vi permette di inviare notifiche a un insieme di indirizzi email ogni volta che arrivano changeset a cui quelle persone sono interessate.</para>
Giulio@761 426
Giulio@761 427 <para id="x_26b">Come l'hook <literal role="hg-ext">bugzilla</literal>, anche l'hook <literal role="hg-ext">notify</literal> è guidato da un template, in modo che possiate personalizzare i contenuti dei messaggi di notifica inviati.</para>
Giulio@761 428
Giulio@761 429 <para id="x_26c">Di default, l'hook <literal role="hg-ext">notify</literal> include un diff di ogni changeset che spedisce; potete limitare le dimensioni del diff, oppure disattivare interamente questa funzionalità. &Egrave; utile per consentire agli interessati di revisionare i cambiamenti immediatamente, piuttosto che obbligarli a cliccare per seguire un URL.</para>
Giulio@761 430
Giulio@761 431 <sect3>
Giulio@761 432 <title>Configurare l'hook <literal role="hg-ext">notify</literal></title>
Giulio@761 433
Giulio@761 434 <para id="x_26d">Potete impostare l'hook <literal role="hg-ext">notify</literal> per spedire un messaggio email per changeset in entrata, o uno per gruppo di changeset in entrata (tutti quelli che sono arrivati in una singola estrazione o trasmissione).</para>
Giulio@761 435 <programlisting>[hooks]
Giulio@761 436 # spedisci una email per gruppo di cambiamenti
Giulio@761 437 changegroup.notify = python:hgext.notify.hook
Giulio@761 438 # spedisci una email per cambiamento
Giulio@761 439 incoming.notify = python:hgext.notify.hook</programlisting>
Giulio@761 440
Giulio@761 441 <para id="x_26e">Le informazioni di configurazione per questo hook si trovano nella sezione <literal role="rc-notify">notify</literal> del file <filename role="special">~/.hgrc</filename>.</para>
Giulio@761 442 <itemizedlist>
Giulio@761 443 <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>: di default, questo hook non spedisce alcuna email, ma stampa il messaggio che <emphasis>avrebbe</emphasis> inviato. Impostate questo elemento a <literal>false</literal> per consentire alle email di venire spedite. La ragione per cui la spedizione delle email è disabilitata di default è che ci vogliono diverse prove per configurare questa estensione esattamente come vorreste, e non starebbe bene #spam# gli interessati con un certo numero di notifiche <quote>guaste</quote> mentre correggete la vostra configurazione.</para>
Giulio@761 444 </listitem>
Giulio@761 445 <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>: il percorso di un file di configurazione che contiene le informazioni di sottoscrizione. Questo viene tenuto separato dal file <filename role="special">~/.hgrc</filename> principale in modo che possiate mantenerlo in un proprio repository. Le persone possono poi clonare quel repository, aggiornare le proprie sottoscrizioni e trasmettere i cambiamenti al vostro server.</para>
Giulio@761 446 </listitem>
Giulio@761 447 <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>: il numero di parti iniziali da eliminare dal percorso di un repository quando state decidendo se è possibile sottoscriversi alle notifiche di un repository. Per esempio, se i repository sul vostro server si trovano in <filename class="directory">/home/hg/repos</filename>, e <literal role="hg-ext">notify</literal> sta considerando un repository chiamato <filename class="directory">/home/hg/repos/shared/test</filename>, impostare <envar role="rc-item-notify">strip</envar> a <literal>4</literal> farà in modo che <literal role="hg-ext">notify</literal> restringa il percorso da considerare a <filename class="directory">shared/test</filename> e cerchi le sottoscrizioni corrispondenti a esso.</para>
Giulio@761 448 </listitem>
Giulio@761 449 <listitem><para id="x_272"><envar role="rc-item-notify">template</envar>: il testo del template da usare quando i messaggi vengono iniviati. Questo specifica i contenuti sia delle intestazioni che del corpo del messaggio.</para>
Giulio@761 450 </listitem>
Giulio@761 451 <listitem><para id="x_273"><envar role="rc-item-notify">maxdiff</envar>: il massimo numero di righe di dati di diff da aggiungere alla fine di un messaggio. Se un diff è più lungo di questo limite, viene troncato. Di default, questo è impostato a 300. Impostate questo a <literal>0</literal> per omettere i diff dalle email di notifica.</para>
Giulio@761 452 </listitem>
Giulio@761 453 <listitem><para id="x_274"><envar role="rc-item-notify">sources</envar>: una lista di fonti di changeset da considerare. Questo vi permette di limitare <literal role="hg-ext">notify</literal> in modo che spedisca email riguardanti solo particolari utenti remoti che hanno trasmesso modifiche a questo repository attraverso un particolare sevrer, per esempio. Leggete la <xref linkend="sec:hook:sources"/> per sapere quali fonti potete specificare qui.</para>
Giulio@761 454 </listitem></itemizedlist>
Giulio@761 455
Giulio@761 456 <para id="x_275">Se impostate l'elemento <envar role="rc-item-web">baseurl</envar> nella sezione <literal role="rc-web">web</literal>, potete usarlo in un template, dove sarà disponibile con il nome <literal>webroot</literal>.</para>
Giulio@761 457
Giulio@761 458 <para id="x_276">Ecco un esempio dell'insieme di informazioni di configurazione da usare per l'hook <literal role="hg-ext">notify</literal>.</para>
Giulio@761 459
Giulio@761 460 &ch10-notify-config.lst;
Giulio@761 461
Giulio@761 462 <para id="x_277">Questo produrrà un messaggio che somiglierà al seguente:</para>
Giulio@761 463
Giulio@761 464 &ch10-notify-config-mail.lst;
Giulio@761 465
Giulio@761 466 </sect3>
Giulio@761 467 <sect3>
Giulio@761 468 <title>Collaudo e risoluzione dei problemi</title>
Giulio@761 469
Giulio@761 470 <para id="x_278">Non dimenticate che il comportamento predefinito dell'estensione <literal role="hg-ext">notify</literal> è quello di <emphasis>non spedire alcuna mail</emphasis> fino a quando non lo avete esplicitamente configurato per farlo, impostando <envar role="rc-item-notify">test</envar> a <literal>false</literal>. Fino a quel momento, si limiterà a stampare il messaggio che <emphasis>avrebbe</emphasis> inviato.</para>
Giulio@761 471
Giulio@761 472 </sect3>
Giulio@761 473 </sect2>
Giulio@761 474 </sect1>
Giulio@761 475 <sect1 id="sec:hook:ref">
Giulio@761 476 <title>Informazioni per gli implementatori di hook</title>
Giulio@761 477
Giulio@761 478 <sect2>
Giulio@761 479 <title>Esecuzione degli hook #in-process#</title>
Giulio@761 480
Giulio@761 481 <para id="x_279">Un hook #in-process# viene invocato con argomenti della forma seguente:</para>
Giulio@761 482 <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting>
Giulio@761 483 <para id="x_27a">Il parametro <literal>ui</literal> è un oggetto di tipo <literal role="py-mod-mercurial.ui">ui</literal>. Il parametro <literal>repo</literal> è un oggetto di tipo <literal role="py-mod-mercurial.localrepo">localrepository</literal>. I nomi e i valori dei parametri <literal>**kwargs</literal> dipendono dall'hook coinvolto, ma hanno le seguenti caratteristiche comuni:</para>
Giulio@761 484 <itemizedlist>
Giulio@761 485 <listitem><para id="x_27b">Se un parametro si chiama <literal>node</literal> o <literal>parentN</literal>, conterrà un identificatore esadecimale di changeset. La stringa vuota viene usata per rappresentare l'identificatore di changeset <quote>nullo</quote> invece di una stringa di zero.</para>
Giulio@761 486 </listitem>
Giulio@761 487 <listitem><para id="x_27c">Se un parametro si chiama <literal>url</literal>, conterrà l'URL di un repository remoto, nel caso possa essere determinato.</para>
Giulio@761 488 </listitem>
Giulio@761 489 <listitem><para id="x_27d">I parametri con valore booleano vengono rappresentati come oggetti Python di tipo <literal>bool</literal>.</para>
Giulio@761 490 </listitem></itemizedlist>
Giulio@761 491
Giulio@761 492 <para id="x_27e">Un hook #in-process# viene invocato senza cambiare la directory di lavoro del processo (a differenza degli hook esterni, che vengono eseguiti nella radice del repository) L'hook non deve mai cambiare questa directory, altrimenti causerà il fallimento di tutte le proprie invocazioni alla API di Mercurial.</para>
Giulio@761 493
Giulio@761 494 <para id="x_27f">Se un hook restituisce il valore booleano <quote>falso</quote>, si considera terminato con successo. Se restituisce il valore booleano <quote>vero</quote> oppure solleva un'eccezione, si considera fallito. Un modo utile di pensare a questa convenzione di esecuzione è <quote>dimmi se hai fallito</quote>.</para>
Giulio@761 495
Giulio@761 496 <para id="x_280">Notate che gli identificatori di changeset sono passati agli hook Python sotto forma di stringhe esadecimali, non degli hash binari che la API Mercurial usa normalmente. Per convertire un hash da esadecimale a binario, usate la funzione <literal>bin</literal>.
Giulio@761 497 </para>
Giulio@761 498 </sect2>
Giulio@761 499
Giulio@761 500 <sect2>
Giulio@761 501 <title>Esecuzione degli hook esterni</title>
Giulio@761 502
Giulio@761 503 <para id="x_281">Un hook esterno viene passato alla shell dell'utente che sta eseguendo Mercurial. Le funzionalità di quella shell, come la sostituzione delle variabili e la redirezione dei comandi, sono disponibili. L'hook viene eseguito nella directory radice del repository (a differenza degli hook #in-process#, che vengono eseguiti nella stessa directory in cui è stato eseguito Mercurial).</para>
Giulio@761 504
Giulio@761 505 <para id="x_282">I parametri di hook sono passati all'hook sotto forma di variabili d'ambiente. Il nome di ogni variabile d'ambiente viene convertito in maiuscolo e preceduto dalla stringa <quote><literal>HG_</literal></quote>. Per esempio, se ilnome di un parametro è <quote><literal>node</literal></quote>, il nome della variabile d'ambiente che rappresenta quel parametro sarà <quote><literal>HG_NODE</literal></quote>.</para>
Giulio@761 506
Giulio@761 507 <para id="x_283">Un parametro booleano è rappresentato come la stringa <quote><literal>1</literal></quote> se è <quote>vero</quote>, o <quote><literal>0</literal></quote> se è <quote>falso</quote>. Se una variabile d'ambiente è chiamata <envar>HG_NODE</envar>, <envar>HG_PARENT1</envar>, o <envar>HG_PARENT2</envar>, conterrà un identificatore di changeset rappresentato come stringa esadecimale. La stringa vuota viene usate per rappresentare l'identificatore di changeset <quote>nullo</quote> invece di una stringa di zeri. Se una variabile d'ambiente è chiamata <envar>HG_URL</envar>, conterrà l'URL di un repository remoto, nel caso possa essere determinato.</para>
Giulio@761 508
Giulio@761 509 <para id="x_284">Se un hook termina con uno stato uguale a zero, si considera terminato con successo. Se terina con uno stato diverso da zero, si condiera fallito.</para>
Giulio@761 510 </sect2>
Giulio@761 511
Giulio@761 512 <sect2>
Giulio@761 513 <title>Scoprire da dove vengono i changeset</title>
Giulio@761 514
Giulio@761 515 <para id="x_285">Un hook che coinvolge il trasferimento di changeset tra un repository locale e un altro potrebbe essere in grado di trovare informazioni sul <quote>lato opposto</quote>. Mercurial sa <emphasis>come</emphasis> i cambiamenti vengono trasferiti e in molti casi da o a <emphasis>dove</emphasis> vengono trasferiti.</para>
Giulio@761 516
Giulio@761 517 <sect3 id="sec:hook:sources">
Giulio@761 518 <title>Le fonti dei changeset</title>
Giulio@761 519
Giulio@761 520 <para id="x_286">Mercurial dirà a un hook quali mezzi vengono o sono stati usati per trasferire i changeset tra repository. Questa informazione viene fornita da Mercurial in un parametro Python chiamato <literal>source</literal> o in una variabile d'ambiente chiamata <envar>HG_SOURCE</envar>.</para>
Giulio@761 521
Giulio@761 522 <itemizedlist>
Giulio@761 523 <listitem><para id="x_287"><literal>serve</literal>: i changeset sono trasferiti da o a un repository remoto via HTTP o SSH.</para>
Giulio@761 524 </listitem>
Giulio@761 525 <listitem><para id="x_288"><literal>pull</literal>: i changeset sono trasferiti attraverso un'estrazione da un repository a un altro.</para>
Giulio@761 526 </listitem>
Giulio@761 527 <listitem><para id="x_289"><literal>push</literal>: i changeset sono trasferiti attraverso una trasmissione da un repository a un altro.</para>
Giulio@761 528 </listitem>
Giulio@761 529 <listitem><para id="x_28a"><literal>bundle</literal>: i changeset sono trasferiti da o verso un #bundle#.</para>
Giulio@761 530 </listitem></itemizedlist>
Giulio@761 531 </sect3>
Giulio@761 532
Giulio@761 533 <sect3 id="sec:hook:url">
Giulio@761 534 <title>La destinazione dei cambiamenti&emdash;gli URL dei repository remoti</title>
Giulio@761 535
Giulio@761 536 <para id="x_28b">Quando è possibile, Mercurial dirà a un hook l'ubicazione del <quote>lato opposto</quote> di un'attività che trasferisce i dati dei changeset tra repository. Questa informazione viene fornita da Mercurial in un parametro Python chiamato <literal>url</literal> o in una variabile d'ambiente chiamata <envar>HG_URL</envar>.</para>
Giulio@761 537
Giulio@761 538 <para id="x_28c">Questa informazione non è sempre nota. Se un hook viene invocato in un repository condiviso via HTTP o SSH, Mercurial non è in grado di dire dove si trova il repository, ma potrebbe sapere da dove si sta connettendo il client. In questi casi, l'URL prenderà una delle seguenti forme:</para>
Giulio@761 539 <itemizedlist>
Giulio@761 540 <listitem><para id="x_28d"><literal>remote:ssh:1.2.3.4</literal>&emdash;client SSH remoto, all'indirizzo IP <literal>1.2.3.4</literal>.</para>
Giulio@761 541 </listitem>
Giulio@761 542 <listitem><para id="x_28e"><literal>remote:http:1.2.3.4</literal>&emdash;client HTTP remoto, all'indirizzo IP <literal>1.2.3.4</literal>. Se il client sta usando SSL, questo URL sarà nella forma <literal>remote:https:1.2.3.4</literal>.</para>
Giulio@761 543 </listitem>
Giulio@761 544 <listitem><para id="x_28f">Empty&emdash;Mercurial non è riuscito a scoprire nessuna informazione sul client remoto.</para>
Giulio@761 545 </listitem></itemizedlist>
Giulio@761 546 </sect3>
Giulio@761 547 </sect2>
Giulio@761 548 </sect1>
Giulio@761 549 <sect1>
Giulio@761 550 <title>Guida di riferimento agli hook</title>
Giulio@761 551
Giulio@761 552 <sect2 id="sec:hook:changegroup">
Giulio@761 553 <title><literal role="hook">changegroup</literal>&emdash;dopo l'aggiunta di changeset remoti</title>
Giulio@761 554
Giulio@761 555 <para id="x_290">Questo hook viene eseguito dopo che un gruppo di changeset preesistenti è stato aggiunto al repository, per esempio tramite <command role="hg-cmd">hg pull</command> o <command role="hg-cmd">hg unbundle</command>. Questo hook viene eseguito una volta per ogni operazione che aggiunge uno o più changeset, a differenza dell'hook <literal role="hook">incoming</literal>, che viene eseguito una volta per changeset a prescindere dal fatto che il changeset sia arrivato in un gruppo.</para>
Giulio@761 556
Giulio@761 557 <para id="x_291">Alcuni possibili usi di questo hook includono far partire un assemblaggio o un collaudo automatico dei changeset aggiunti, l'aggiornamento di un database di bug, o la notifica che un repository contiene nuovi cambiamenti.</para>
Giulio@761 558
Giulio@761 559 <para id="x_292">I parametri di questo hook sono i seguenti.</para>
Giulio@761 560 <itemizedlist>
Giulio@761 561 <listitem><para id="x_293"><literal>node</literal>: un identificatore di changeset. L'identificatore del primo changeset nel gruppo che è stato aggiunto. Tutti i changeset tra questo e <literal role="tag">tip</literal> compresi sono stati aggiunti da una singola invocazione di <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg push</command>, o <command role="hg-cmd">hg unbundle</command>.</para>
Giulio@761 562 </listitem>
Giulio@761 563 <listitem><para id="x_294"><literal>source</literal>: una stringa. La fonte di questi cambiamenti. Si veda la <xref linkend="sec:hook:sources"/> per i dettagli.</para>
Giulio@761 564 </listitem>
Giulio@761 565 <listitem><para id="x_295"><literal>url</literal>: un URL. L'ubicazione del repository remoto, nel caso sia nota. Si veda la <xref linkend="sec:hook:url"/> per maggiori informazioni.</para>
Giulio@761 566 </listitem></itemizedlist>
Giulio@761 567
Giulio@761 568 <para id="x_296">Si vedano anche gli hook: <literal role="hook">incoming</literal> (<xref linkend="sec:hook:incoming"/>), <literal role="hook">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>), <literal role="hook">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>)</para>
Giulio@761 569 </sect2>
Giulio@761 570
Giulio@761 571 <sect2 id="sec:hook:commit">
Giulio@761 572 <title><literal role="hook">commit</literal>&emdash;dopo la creazione di un nuovo changeset</title>
Giulio@761 573
Giulio@761 574 <para id="x_297">Questo hook viene eseguito dopo che un nuovo changeset è stato creato.</para>
Giulio@761 575
Giulio@761 576 <para id="x_298">I parametri di questo hook sono i seguenti.</para>
Giulio@761 577 <itemizedlist>
Giulio@761 578 <listitem><para id="x_299"><literal>node</literal>: un identificatore di changeset. L'identificatore del changeset appena inserito.</para>
Giulio@761 579 </listitem>
Giulio@761 580 <listitem><para id="x_29a"><literal>parent1</literal>: un identificatore di changeset. L'identificatore di changeset del primo genitore del changeset appena inserito.</para>
Giulio@761 581 </listitem>
Giulio@761 582 <listitem><para id="x_29b"><literal>parent2</literal>: un identificatore di changeset. L'identificatore di changeset del secondo genitore del changeset appena inserito.</para>
Giulio@761 583 </listitem></itemizedlist>
Giulio@761 584
Giulio@761 585 <para id="x_29c">Si vedano anche gli hook: <literal role="hook">precommit</literal> (<xref linkend="sec:hook:precommit"/>), <literal role="hook">pretxncommit</literal> (<xref linkend="sec:hook:pretxncommit"/>)</para>
Giulio@761 586 </sect2>
Giulio@761 587
Giulio@761 588 <sect2 id="sec:hook:incoming">
Giulio@761 589 <title><literal role="hook">incoming</literal>&emdash;dopo l'aggiunta di un changeset remoto</title>
Giulio@761 590
Giulio@761 591 <para id="x_29d">Questo hook viene eseguito dopo che un changeset preesistente è stato aggiunto al repository, per esempio attraverso l'invocazione di <command role="hg-cmd">hg push</command>. Se un gruppo di changeset è stato aggiunto in una singola operazione, questo hook viene eseguito una volta per ogni changeset aggiunto.</para>
Giulio@761 592
Giulio@761 593 <para id="x_29e">Potete usare questo hook per gli stessi scopi dell'hook <literal role="hook">changegroup</literal> hook (<xref linkend="sec:hook:changegroup"/>); talvolta è semplicemente più conveniente eseguire un hook per ogni gruppo di changeset, mentre altre volte è più comodo eseguirlo per ogni changeset.</para>
Giulio@761 594
Giulio@761 595 <para id="x_29f">I parametri di questo hook sono i seguenti.</para>
Giulio@761 596 <itemizedlist>
Giulio@761 597 <listitem><para id="x_2a0"><literal>node</literal>: un identificatore di changeset. L'identificatore del changeset appena aggiunto.</para>
Giulio@761 598 </listitem>
Giulio@761 599 <listitem><para id="x_2a1"><literal>source</literal>: una stringa. La fonte di questi cambiamenti. Si veda la <xref linkend="sec:hook:sources"/> per i dettagli.</para>
Giulio@761 600 </listitem>
Giulio@761 601 <listitem><para id="x_2a2"><literal>url</literal>: un URL. L'ubicazione del repository remoto, nel caso sia nota. Si veda la <xref linkend="sec:hook:url"/> per maggiori informazioni.</para>
Giulio@761 602 </listitem></itemizedlist>
Giulio@761 603
Giulio@761 604 <para id="x_2a3">Si vedano anche gli hook: <literal role="hook">changegroup</literal> (<xref linkend="sec:hook:changegroup"/>), <literal role="hook">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>), <literal role="hook">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>)</para>
Giulio@761 605 </sect2>
Giulio@761 606
Giulio@761 607 <sect2 id="sec:hook:outgoing">
Giulio@761 608 <title><literal role="hook">outgoing</literal>&emdash;dopo la propagazione dei changeset</title>
Giulio@761 609
Giulio@761 610 <para id="x_2a4">Questo hook viene eseguito dopo che un gruppo di changeset è stato propagato al di fuori di questo repository, per esempio attraverso l'invocazione dei comandi <command role="hg-cmd">hg push</command> o <command role="hg-cmd">hg bundle</command>.</para>
Giulio@761 611
Giulio@761 612 <para id="x_2a5">Questo hook può essere impiegato per notificare gli amministratori che alcuni cambiamenti sono stati estratti.</para>
Giulio@761 613
Giulio@761 614 <para id="x_2a6">I parametri di questo hook sono i seguenti.</para>
Giulio@761 615 <itemizedlist>
Giulio@761 616 <listitem><para id="x_2a7"><literal>node</literal>: un identificatore di changeset. L'identificatore del primo changeset del gruppo che è stato mandato.</para>
Giulio@761 617 </listitem>
Giulio@761 618 <listitem><para id="x_2a8"><literal>source</literal>: una stringa. La fonte dell'operazione (si veda la <xref linkend="sec:hook:sources"/>). Se un client remoto ha estratto i cambiamenti da questo repository, il valore di <literal>source</literal> sarà <literal>serve</literal>. Se il client che ha ottenuto i cambiamenti di questo repository era locale, il valore di <literal>source</literal> sarà <literal>bundle</literal>, <literal>pull</literal>, o <literal>push</literal>, a seconda dell'operazione effettuata dal client.</para>
Giulio@761 619 </listitem>
Giulio@761 620 <listitem><para id="x_2a9"><literal>url</literal>: un URL. L'ubicazione del repository remoto, nel caso sia nota. Si veda la <xref linkend="sec:hook:url"/> per maggiori informazioni.</para>
Giulio@761 621 </listitem></itemizedlist>
Giulio@761 622
Giulio@761 623 <para id="x_2aa">Si vedano anche gli hook: <literal role="hook">preoutgoing</literal> (<xref linkend="sec:hook:preoutgoing"/>)</para>
Giulio@761 624 </sect2>
Giulio@761 625
Giulio@761 626 <sect2 id="sec:hook:prechangegroup">
Giulio@761 627 <title><literal role="hook">prechangegroup</literal>&emdash;prima di cominciare ad aggiungere changeset remoti</title>
Giulio@761 628
Giulio@761 629 <para id="x_2ab">Questo hook di controllo viene eseguito prima che Mercurial cominci ad aggiungere un gruppo di changeset proveniente da un altro repository.</para>
Giulio@761 630
Giulio@761 631 <para id="x_2ac">Questo hook non possiede alcuna informazione sui changeset che verranno aggiunti, perché viene eseguito prima che la trasmissione di quei changeset possa cominciare. Se questo hook fallisce, i changeset non verranno trasmessi.</para>
Giulio@761 632
Giulio@761 633 <para id="x_2ad">Questo hook si può utilizzare per evitare che i cambiamenti vengano aggiunti a un repository. Per esempio, potreste usarlo per <quote>congelare</quote> temporaneamente o permanentemente un ramo ospitato su un server in modo che gli utenti non possano trasmettervi alcuna modifica, consentendo comunque a un amministratore locale di modificare il repository.</para>
Giulio@761 634
Giulio@761 635 <para id="x_2ae">I parametri di questo hook sono i seguenti.</para>
Giulio@761 636 <itemizedlist>
Giulio@761 637 <listitem><para id="x_2af"><literal>source</literal>: una stringa. La fonte di questi cambiamenti. Si veda la <xref linkend="sec:hook:sources"/> per i dettagli.</para>
Giulio@761 638 </listitem>
Giulio@761 639 <listitem><para id="x_2b0"><literal>url</literal>: un URL. L'ubicazione del repository remoto, nel caso sia nota. Si veda la <xref linkend="sec:hook:url"/> per maggiori informazioni.</para>
Giulio@761 640 </listitem></itemizedlist>
Giulio@761 641
Giulio@761 642 <para id="x_2b1">Si vedano anche gli hook: <literal role="hook">changegroup</literal> (<xref linkend="sec:hook:changegroup"/>), <literal role="hook">incoming</literal> (<xref linkend="sec:hook:incoming"/>), <literal role="hook">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>)</para>
Giulio@761 643 </sect2>
Giulio@761 644
Giulio@761 645 <sect2 id="sec:hook:precommit">
Giulio@761 646 <title><literal role="hook">precommit</literal>&emdash;prima di cominciare l'inserimento di un changeset</title>
Giulio@761 647
Giulio@761 648 <para id="x_2b2">Questo hook viene eseguito prima che Mercurial cominci l'inserimento di un nuovo changeset. Viene eseguito prima che Mercurial conosca i metadati dell'inserimento, come i file da inserire, il messaggio e la data di commit.</para>
Giulio@761 649
Giulio@761 650 <para id="x_2b3">Questo hook può essere usato per disabilitare la possibilità di inserire nuovi changeset, pur permettendo la trasmissione di changeset in entrata. Un'altra possibilità è quella di eseguire l'assemblaggio o il collaudo e permettere all'inserimento di cominciare solo se l'assemblaggio o il collaudo hanno successo.</para>
Giulio@761 651
Giulio@761 652 <para id="x_2b4">I parametri di questo hook sono i seguenti.</para>
Giulio@761 653 <itemizedlist>
Giulio@761 654 <listitem><para id="x_2b5"><literal>parent1</literal>: un identificatore di changeset. L'identificatore di changeset del primo genitore della directory di lavoro.</para>
Giulio@761 655 </listitem>
Giulio@761 656 <listitem><para id="x_2b6"><literal>parent2</literal>: un identificatore di changeset. L'identificatore di changeset del secondo genitore della directory di lavoro.</para>
Giulio@761 657 </listitem></itemizedlist>
Giulio@761 658 <para id="x_2b7">Se l'inserimento procede, i genitori della directory di lavoro diventeranno i genitori del nuovo changeset.</para>
Giulio@761 659
Giulio@761 660 <para id="x_2b8">Si vedano anche gli hook: <literal role="hook">commit</literal> (<xref linkend="sec:hook:commit"/>), <literal role="hook">pretxncommit</literal> (<xref linkend="sec:hook:pretxncommit"/>)</para>
Giulio@761 661 </sect2>
Giulio@761 662
Giulio@761 663 <sect2 id="sec:hook:preoutgoing">
Giulio@761 664 <title><literal role="hook">preoutgoing</literal>&emdash;prima di cominciare la propagazione dei changeset</title>
Giulio@761 665
Giulio@761 666 <para id="x_2b9">Questo hook viene invocato prima che Mercurial conosca le identità dei changeset da trasmettere.</para>
Giulio@761 667
Giulio@761 668 <para id="x_2ba">Questo hook può essere usato per evitare che i changeset vengano trasmessi a un altro repository.</para>
Giulio@761 669
Giulio@761 670 <para id="x_2bb">I parametri di questo hook sono i seguenti.</para>
Giulio@761 671 <itemizedlist>
Giulio@761 672 <listitem><para id="x_2bc"><literal>source</literal>: una stringa. La fonte dell'operazione che sta tentando di ottenere i cambiamenti da questo repository (si veda la <xref linkend="sec:hook:sources"/>). Leggete la documentazione del parametro <literal>source</literal> per l'hook <literal role="hook">outgoing</literal> nella <xref linkend="sec:hook:outgoing"/> per i possibili valori di questo parametro.</para>
Giulio@761 673 </listitem>
Giulio@761 674 <listitem><para id="x_2bd"><literal>url</literal>: un URL. L'ubicazione del repository remoto, nel caso sia nota. Si veda la <xref linkend="sec:hook:url"/> per maggiori informazioni.</para>
Giulio@761 675 </listitem></itemizedlist>
Giulio@761 676
Giulio@761 677 <para id="x_2be">Si vedano anche gli hook: <literal role="hook">outgoing</literal> (<xref linkend="sec:hook:outgoing"/>)</para>
Giulio@761 678 </sect2>
Giulio@761 679
Giulio@761 680 <sect2 id="sec:hook:pretag">
Giulio@761 681 <title><literal role="hook">pretag</literal>&emdash;prima di etichettare un changeset</title>
Giulio@761 682
Giulio@761 683 <para id="x_2bf">Questo hook di controllo viene eseguito prima della creazione di un etichetta. Se l'hook ha successo, la creazione dell'etichetta procede. Se l'hook fallisce, l'etichetta non viene creata.</para>
Giulio@761 684
Giulio@761 685 <para id="x_2c0">I parametri di questo hook sono i seguenti.</para>
Giulio@761 686 <itemizedlist>
Giulio@761 687 <listitem><para id="x_2c1"><literal>local</literal>: un booleano. Indica se l'etichetta è locale a questa istanza del repository (i.e. memorizzata nel file <filename role="special">.hg/localtags</filename>) o se è gestita da Mercurial (memorizzata nel file <filename role="special">.hgtags</filename>).</para>
Giulio@761 688 </listitem>
Giulio@761 689 <listitem><para id="x_2c2"><literal>node</literal>: un identificatore di changeset. L'identificatore del changeset da etichettare.</para>
Giulio@761 690 </listitem>
Giulio@761 691 <listitem><para id="x_2c3"><literal>tag</literal>: una stringa. Il nome dell'etichetta da creare.</para>
Giulio@761 692 </listitem></itemizedlist>
Giulio@761 693
Giulio@761 694 <para id="x_2c4">Se l'etichetta da creare è soggetta a controllo di revisione, anche gli hook <literal role="hook">precommit</literal> e <literal role="hook">pretxncommit</literal> (<xref linkend="sec:hook:commit"/> e <xref linkend="sec:hook:pretxncommit"/>) verranno eseguiti.</para>
Giulio@761 695
Giulio@761 696 <para id="x_2c5">Si vedano anche gli hook: <literal role="hook">tag</literal> (<xref linkend="sec:hook:tag"/>)</para>
Giulio@761 697 </sect2>
Giulio@761 698
Giulio@761 699 <sect2 id="sec:hook:pretxnchangegroup">
Giulio@761 700 <title><literal
Giulio@761 701 role="hook">pretxnchangegroup</literal>&emdash;prima di completare l'aggiunta di changeset remoti</title>
Giulio@761 702
Giulio@761 703 <para id="x_2c6">Questo hook di controllo viene eseguito prima di completare la transazione che gestisce l'aggiunta di un gruppo di nuovi changeset provenienti dall'esterno del repository. Se l'hook ha successo, la transazione viene completata e tutti i changeset diventano permanenti all'interno di questo repository. Se l'hook fallisce, la transazione viene abortita e i dati relativi ai changeset vengono cancellati.</para>
Giulio@761 704
Giulio@761 705 <para id="x_2c7">Questo hook può accedere ai metadati associati con i changeset quasi aggiunti, ma dovrebbe evitare di modificarli in maniera permanente. L'hook deve anche evitare di modificare la directory di lavoro.</para>
Giulio@761 706
Giulio@761 707 <para id="x_2c8">Mentre questo hook è in esecuzione, se altri processi Mercurial accedono a questo repository, saranno in grado di vedere i changeset quasi aggiunti come se fossero permanenti. Questo potrebbe provocare delle condizioni di corsa critica se non eseguite i passi necessari per evitarle.</para>
Giulio@761 708
Giulio@761 709 <para id="x_2c9">Quesro hook può essere usato per esaminare automaticamente un gruppo di changeset. Se l'hook fallisce, tutti i changeset vengono <quote>respinti</quote> quando la transazione viene abortita.</para>
Giulio@761 710
Giulio@761 711 <para id="x_2ca">I parametri di questo hook sono i seguenti.</para>
Giulio@761 712 <itemizedlist>
Giulio@761 713 <listitem><para id="x_2cb"><literal>node</literal>: un identificatore di changeset. L'identificatore del primo changeset nel gruppo che è stato aggiunto. Tutti i changeset tra questo e <literal role="tag">tip</literal> compresi sono stati aggiunti da una singola invocazione di <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg push</command>, o <command role="hg-cmd">hg unbundle</command>.</para>
Giulio@761 714 </listitem>
Giulio@761 715 <listitem><para id="x_2cc"><literal>source</literal>: una stringa. La fonte di questi cambiamenti. Si veda la <xref linkend="sec:hook:sources"/> per i dettagli.</para>
Giulio@761 716 </listitem>
Giulio@761 717 <listitem><para id="x_2cd"><literal>url</literal>: un URL. L'ubicazione del repository remoto, nel caso sia nota. Si veda la <xref linkend="sec:hook:url"/> per magggiori informazioni.</para>
Giulio@761 718 </listitem></itemizedlist>
Giulio@761 719
Giulio@761 720 <para id="x_2ce">Si vedano anche gli hook: <literal role="hook">changegroup</literal> (<xref linkend="sec:hook:changegroup"/>), <literal role="hook">incoming</literal> (<xref linkend="sec:hook:incoming"/>), <literal role="hook">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>)</para>
Giulio@761 721 </sect2>
Giulio@761 722
Giulio@761 723 <sect2 id="sec:hook:pretxncommit">
Giulio@761 724 <title><literal role="hook">pretxncommit</literal>&emdash;prima di completare l'inserimento di un nuovo changeset</title>
Giulio@761 725
Giulio@761 726 <para id="x_2cf">Questo hook di controllo viene eseguito prima di completare la transazione che gestisce un nuovo inserimento. Se l'hook ha successo, la transazione viene completata e il changeset diventa permanente all'interno di questo repository. Se l'hook fallisce, la transazione viene abortita e i dati dell'inserimento vengono cancellati.</para>
Giulio@761 727
Giulio@761 728 <para id="x_2d0">Questo hook può accedere ai metadati associati con il changeset quasi inserito, ma dovrebbe evitare di modificarli in maniera permanente. L'hook deve anche evitare di modificare la directory di lavoro.</para>
Giulio@761 729
Giulio@761 730 <para id="x_2d1">Mentre questo hook è in esecuzione, se altri processi Mercurial accedono a questo repository, saranno in grado di vedere i changeset quasi aggiunti come se fossero permanenti. Questo potrebbe provocare delle condizioni di corsa critica se non eseguite i passi necessari per evitarle.</para>
Giulio@761 731
Giulio@761 732 <para id="x_2d2">I parametri di questo hook sono i seguenti.</para>
Giulio@761 733
Giulio@761 734 <itemizedlist>
Giulio@761 735 <listitem><para id="x_299"><literal>node</literal>: un identificatore di changeset. L'identificatore del changeset appena inserito.</para>
Giulio@761 736 </listitem>
Giulio@761 737 <listitem><para id="x_29a"><literal>parent1</literal>: un identificatore di changeset. L'identificatore di changeset del primo genitore del changeset appena inserito.</para>
Giulio@761 738 </listitem>
Giulio@761 739 <listitem><para id="x_29b"><literal>parent2</literal>: un identificatore di changeset. L'identificatore di changeset del secondo genitore del changeset appena inserito.</para>
Giulio@761 740 </listitem></itemizedlist>
Giulio@761 741
Giulio@761 742 <para id="x_2d6">Si vedano anche gli hook: <literal role="hook">precommit</literal> (<xref linkend="sec:hook:precommit"/>)</para>
Giulio@761 743 </sect2>
Giulio@761 744
Giulio@761 745 <sect2 id="sec:hook:preupdate">
Giulio@761 746 <title><literal role="hook">preupdate</literal>&emdash;prima di eseguire un aggiornamento o un'unione nella directory di lavoro</title>
Giulio@761 747
Giulio@761 748 <para id="x_2d7">Questo hook viene eseguito prima di cominciare un aggiornamento o un'unione nella directory di lavoro. Viene eseguito solo se i normali controlli effettuati da Mercurial prima di un aggiornamento determinano che l'aggiornamento o l'unione possono procedere. Se l'hook ha successo, l'aggiornamento o l'unione possono procedere; se fallisce, l'aggiornameno o l'unione non vengono cominciati.</para>
Giulio@761 749
Giulio@761 750 <para id="x_2d8">I parametri di questo hook sono i seguenti.</para>
Giulio@761 751 <itemizedlist>
Giulio@761 752 <listitem><para id="x_2d9"><literal>parent1</literal>: un identificatore di changeset. L'identificatore del genitore a cui la directory di lavoro sta per essere aggiornata. Se si sta per effettuare un'unione, questo genitore non verrà modificato.</para>
Giulio@761 753 </listitem>
Giulio@761 754 <listitem><para id="x_2da"><literal>parent2</literal>: un identificatore di changeset. Il suo valore viene impostato solo se si sta eseguendo un'unione. Contiene l'identificatore della revisione con cui la directory di lavoro viene unita.</para>
Giulio@761 755 </listitem></itemizedlist>
Giulio@761 756
Giulio@761 757 <para id="x_2db">Si vedano anche gli hook: <literal role="hook">update</literal> (<xref linkend="sec:hook:update"/>)</para>
Giulio@761 758 </sect2>
Giulio@761 759
Giulio@761 760 <sect2 id="sec:hook:tag">
Giulio@761 761 <title><literal role="hook">tag</literal>&emdash;dopo aver etichettato un changeset</title>
Giulio@761 762
Giulio@761 763 <para id="x_2dc">Questo hook viene eseguito dopo la creazione di un'etichetta.</para>
Giulio@761 764
Giulio@761 765 <para id="x_2dd">I parametri di questo hook sono i seguenti.</para>
Giulio@761 766 <itemizedlist>
Giulio@761 767 <listitem><para id="x_2c1"><literal>local</literal>: un booleano. Indica se l'etichetta è locale a questa istanza del repository (i.e. memorizzata nel file <filename role="special">.hg/localtags</filename>) o se è gestita da Mercurial (memorizzata nel file <filename role="special">.hgtags</filename>).</para>
Giulio@761 768 </listitem>
Giulio@761 769 <listitem><para id="x_2c2"><literal>node</literal>: un identificatore di changeset. L'identificatore del changeset che è stato etichettato.</para>
Giulio@761 770 </listitem>
Giulio@761 771 <listitem><para id="x_2c3"><literal>tag</literal>: una stringa. Il nome dell'etichetta creata.</para>
Giulio@761 772 </listitem></itemizedlist>
Giulio@761 773
Giulio@761 774 <para id="x_2e1">Se l'etichetta creata è soggetta a controllo di revisione, l'hook <literal role="hook">commit</literal> (<xref linkend="sec:hook:commit"/>) verrà eseguito prima di questo hook.</para>
Giulio@761 775
Giulio@761 776 <para id="x_2e2">Si vedano anche gli hook: <literal role="hook">pretag</literal> (<xref linkend="sec:hook:pretag"/>)</para>
Giulio@761 777 </sect2>
Giulio@761 778
Giulio@761 779 <sect2 id="sec:hook:update">
Giulio@761 780 <title><literal role="hook">update</literal>&emdash;dopo aver eseguito un aggiornamento o un'unione nella directory di lavoro</title>
Giulio@761 781
Giulio@761 782 <para id="x_2e3">Questo hook viene eseguito dopo il completamento di un aggiornamento o di un'unione nella directory di lavoro. Dato che un'unione può fallire (se il comando esterno <command>hgmerge</command> non è in grado di risolvere i conflitti in un file), questo hook comunica se l'aggiornamento o l'unione sono stati completati in maniera pulita.</para>
Giulio@761 783
Giulio@761 784 <itemizedlist>
Giulio@761 785 <listitem><para id="x_2e4"><literal>error</literal>: un booleano. Indica se l'aggiornamento o l'unione sono stati completati con successo.</para>
Giulio@761 786 </listitem>
Giulio@761 787 <listitem><para id="x_2e5"><literal>parent1</literal>: un identificatore di changeset. L'identificatore del genitore a cui la directory di lavoro è stata aggiornata. Se è stata effettuata un'unione, questo genitore non viene modificato.</para>
Giulio@761 788 </listitem>
Giulio@761 789 <listitem><para id="x_2e6"><literal>parent2</literal>: un identificatore di changeset. Il suo valore viene impostato solo se è stata eseguita un'unione. Contiene l'identificatore della revisione con cui la directory di lavoro è stata unita.</para>
Giulio@761 790 </listitem></itemizedlist>
Giulio@761 791
Giulio@761 792 <para id="x_2e7">Si vedano anche gli hook: <literal role="hook">preupdate</literal> (<xref linkend="sec:hook:preupdate"/>)</para>
Giulio@761 793
Giulio@761 794 </sect2>
Giulio@761 795 </sect1>
Giulio@761 796 </chapter>