hgbook

changeset 1002:55d1bf9b47a4

French translation : merge with Romain Perlisse's repository
author Frédéric Bouquet <youshe.jaalon@gmail.com>
date Mon Sep 14 01:31:50 2009 +0200 (2009-09-14)
parents 669ae1a09e46 0fba9db5e75c
children f4f740bb58be
files
line diff
     1.1 --- a/.hgignore	Mon Sep 14 01:18:56 2009 +0200
     1.2 +++ b/.hgignore	Mon Sep 14 01:31:50 2009 +0200
     1.3 @@ -25,6 +25,8 @@
     1.4  en/examples/results
     1.5  en/html
     1.6  en/svn
     1.7 +fr/examples/results
     1.8 +fr/html
     1.9  it/examples/results
    1.10  it/html
    1.11  stylesheets/system-xsl
     2.1 --- a/.hgtags	Mon Sep 14 01:18:56 2009 +0200
     2.2 +++ b/.hgtags	Mon Sep 14 01:31:50 2009 +0200
     2.3 @@ -1,2 +1,3 @@
     2.4  18131160f7ee3b81bf39ce2c58f762b8d671cef3 submitted
     2.5  94d2205f02e7c47931db382a3a80553ef01b3913 1st-edition-it
     2.6 +a6b81cd31cfd5da20e0dc629ee65cc4f3b08eb58 french-xdoc-build-fixed
     3.1 --- a/fr/ch02-tour-basic.xml	Mon Sep 14 01:18:56 2009 +0200
     3.2 +++ b/fr/ch02-tour-basic.xml	Mon Sep 14 01:31:50 2009 +0200
     3.3 @@ -51,13 +51,14 @@
     3.4  
     3.5        <itemizedlist>
     3.6          <listitem><para id="x_4">Ubuntu et Debian:</para>
     3.7 -          <programlisting>apt-get install mercurial</listitem>
     3.8 +          <programlisting>apt-get install mercurial</programlisting></listitem>
     3.9          <listitem><para id="x_5">Fedora:</para>
    3.10 -          <programlisting>yum install mercurial</programlisting>
    3.11 +          <programlisting>yum install mercurial</programlisting></listitem>
    3.12          <listitem><para id="x_6">Gentoo:</para>
    3.13             <programlisting>emerge mercurial</programlisting></listitem>
    3.14          <listitem><para id="x_715">OpenSUSE:</para>
    3.15 -          <programlisting>zypper install mercurial</programlisting>
    3.16 +          <programlisting>zypper install
    3.17 +          mercurial</programlisting></listitem>
    3.18        </itemizedlist>
    3.19  
    3.20      </sect2>
    3.21 @@ -84,7 +85,7 @@
    3.22      <sect2>
    3.23        <title>L'aide intégrée</title>
    3.24  
    3.25 -      <para id="x_e">Mercurial fournit un système d'aide intégré, ce qui est
    3.26 +      <para id="x_f">Mercurial fournit un système d'aide intégré, ce qui est
    3.27          inestimable quand vous vous retrouvez coincé à essayer de vous
    3.28          rappeler comment lancer une commande. Si vous êtes bloqué, exécutez
    3.29          simplement <command role="hg-cmd">hg help</command>; elle affichera
    3.30 @@ -99,7 +100,7 @@
    3.31          help <option role="hg-opt-global">-v</option></command>.  L'option 
    3.32          <option role="hg-opt-global">-v</option> est l'abréviation de 
    3.33          <option role="hg-opt-global">--verbose</option>, et indique à Mercurial 
    3.34 -        d'afficher plus d'informations que d'habitude.</para>
    3.35 +        d'ficher plus d'informations que d'habitude.</para>
    3.36  
    3.37       </sect2>
    3.38    </sect1>
    3.39 @@ -192,7 +193,7 @@
    3.40  
    3.41      &interaction.tour.log;
    3.42  
    3.43 -    <para "x_1c">Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque
    3.44 +    <para id="x_1c">Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque
    3.45        révision enregistrée pour ce projet. Dans la terminologie de Mercurial, nous
    3.46        appelons chacun de ces évènements enregistrés un <emphasis>changeset</emphasis>, parce
    3.47        qu'il contient un ensemble de modifications sur plusieurs fichiers.</para>
    3.48 @@ -469,7 +470,7 @@
    3.49          status</command> n'affichera aucune information sur les fichiers que
    3.50        vous n'avez pas modifiés.</para>
    3.51   
    3.52 -    <para id="x_3d">Le <quote><literal>M</literal></quote> indique que
    3.53 +    <para id="x_3e">Le <quote><literal>M</literal></quote> indique que
    3.54        Mercurial a remarqué que nous avons modifié le fichier
    3.55        <filename>hello.c</filename>. Nous n'avons pas besoin
    3.56        <emphasis>d'informer</emphasis> Mercurial que nous allons modifier un
    3.57 @@ -740,7 +741,7 @@
    3.58    <sect1>
    3.59      <title>Partager ses modifications</title>
    3.60  
    3.61 -    <para id="x_58">Nous avons mentionné plus haut que les dépôts 
    3.62 +    <para id="x_58">Nous avons mentionné plus haut que les dépôts 
    3.63        de Mercurial sont autosuffisants. Ce qui signifie que la nouvelle
    3.64        révision que vous venez de créer existe seulement dans votre 
    3.65        répertoire <filename class="directory">my-hello</filename>. Étudions 
    3.66 @@ -749,7 +750,7 @@
    3.67      <sect2 id="sec:tour:pull">
    3.68        <title>Récupérer les modifications d'autres dépôts</title>
    3.69  
    3.70 -      <para id="x_5a">Pour commencer, construisons un clone de notre dépôt 
    3.71 +      <para id="x_59">Pour commencer, construisons un clone de notre dépôt 
    3.72          <filename class="directory">hello</filename> qui ne contiendra pas 
    3.73          le changement que nous venons d'effectuer. Nous l'appellerons notre 
    3.74          dépôt temporaire <filename
     4.1 --- a/fr/ch03-tour-merge.xml	Mon Sep 14 01:18:56 2009 +0200
     4.2 +++ b/fr/ch03-tour-merge.xml	Mon Sep 14 01:31:50 2009 +0200
     4.3 @@ -11,368 +11,437 @@
     4.4  
     4.5    <sect1>
     4.6      <title>Fusionner différents travaux</title>
     4.7 -      <para od="x_339">La fusion  est un aspect fondamental lorsqu'on
     4.8 +      <para id="x_339">La fusion  est un aspect fondamental lorsqu'on
     4.9        travaille iavec un gestionnaire de source distribué.</para>
    4.10  
    4.11        <itemizedlist>
    4.12 -        <listitem><para>Alice et Bob ont chacun une copie personnelle du dépôt d'un
    4.13 -  projet sur lequel ils collaborent. Alice corrige un \textit{bug}
    4.14 -  dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
    4.15 -  sien. Ils veulent un dépôt partagé avec à la fois le correctif du
    4.16 -  \textit{bug} et la nouvelle fonctionnalité.</para>
    4.17 -</listitem>
    4.18 -<listitem><para>Je travaille régulièrement sur plusieurs tâches différentes sur
    4.19 -  un seul projet en même temps, chacun isolé dans son propre dépôt.
    4.20 -  Travailler ainsi signifie que je dois régulièrement fusionner une
    4.21 -  partie de mon code avec celui des autres.</para>
    4.22 -</listitem></itemizedlist>
    4.23 -
    4.24 -<para>Parce que la fusion est une opération si commune à réaliser,
    4.25 -Mercurial la rend facile. Étudions ensemble le déroulement des opérations.
    4.26 -Nous commencerons encore par faire un clone d'un autre dépôt (vous voyez
    4.27 -que l'on fait ça tout le temps ?) puis nous ferons quelques modifications
    4.28 -dessus.
    4.29 -<!-- &interaction.tour.merge.clone; -->
    4.30 -Nous devrions avoir maintenant deux copies de <filename>hello.c</filename> avec
    4.31 -des contenus différents. Les historiques de ces deux dépôts ont aussi
    4.32 -divergés, comme illustré dans la figure <xref linkend="fig:tour-merge:sep-repos"/>.</para>
    4.33 -
    4.34 -<para><!-- &interaction.tour.merge.cat; --></para>
    4.35 -
    4.36 -<informalfigure>
    4.37 -
    4.38 -<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-sep-repos"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
    4.39 -  <caption><para>Historiques récent divergents des dépôts \dirname{my-hello</para></caption>
    4.40 -  et <filename class="directory">my-new-hello</filename>}
    4.41 -  \label{fig:tour-merge:sep-repos}</para>
    4.42 -</informalfigure>
    4.43 -
    4.44 -<para>Nous savons déjà que récupérer les modifications depuis notre dépôt
    4.45 -<filename class="directory">my-hello</filename> n'aura aucun effet sur l'espace de travail.
    4.46 -</para>
    4.47 -
    4.48 -<para><!-- &interaction.tour.merge.pull; -->
    4.49 -</para>
    4.50 -
    4.51 -<para>Néanmoins, la commande <command role="hg-cmd">hg pull</command> nous indique quelque chose au
    4.52 -sujet des <quote>heads</quote>.
    4.53 -</para>
    4.54 -
    4.55 -<sect2>
    4.56 -<title>\textit{Head changesets}</title>
    4.57 -
    4.58 -<para>Une \textit{head}\footnote{NdT: Je garde \textit{head} que j'accorde
    4.59 -au féminin comme la coutume orale l'a imposé.} est un \textit{changeset}
    4.60 -sans descendants, ou enfants, comme on les désigne parfois. La révision
    4.61 -\textit{tip} est une \textit{head}, car la dernière révision dans un dépôt
    4.62 -n'a aucun enfant, mais il est important de noter qu'un dépôt peut contenir
    4.63 -plus d'une \textit{head}.
    4.64 -</para>
    4.65 -
    4.66 -<informalfigure>
    4.67 -
    4.68 -<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-pull"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
    4.69 -  \caption{Contenu d'un dépôt après avoir transféré le contenu du dépôt
    4.70 -    <filename class="directory">my-hello</filename> dans le dépôt <filename class="directory">my-new-hello</filename>}
    4.71 -  \label{fig:tour-merge:pull}
    4.72 -</para>
    4.73 -</informalfigure>
    4.74 -
    4.75 -<para>Dans la figure <xref linkend="fig:tour-merge:pull"/>, vous pouvez constater l'effet
    4.76 -d'un \textit{pull} depuis le dépôt <filename class="directory">my-hello</filename> dans le dépôt
    4.77 -<filename class="directory">my-new-hello</filename>. L'historique qui était déjà présent dans le dépôt
    4.78 -<filename class="directory">my-new-hello</filename> reste intact, mais une nouvelle révision a été
    4.79 -ajoutée. En vous reportant à la figure <xref linkend="fig:tour-merge:sep-repos"/>,
    4.80 -vous pouvez voir que le \textit{<emphasis>changeset ID</emphasis>} reste le même dans
    4.81 -le nouveau dépôt, mais que le <emphasis>numéro de révision</emphasis> reste le même.
    4.82 -(Ceci est un parfait exemple de pourquoi il n'est fiable d'utiliser les
    4.83 -numéros de révision lorsque l'on discute d'un \textit{changeset}.) Vous
    4.84 -pouvez voir les \texit{heads} présentes dans le dépôt en utilisant la
    4.85 -commande <command role="hg-cmd">hg heads</command>.
    4.86 -<!-- &interaction.tour.merge.heads; -->
    4.87 -</para>
    4.88 -
    4.89 -</sect2>
    4.90 -<sect2>
    4.91 -<title>Effectuer la fusion</title>
    4.92 -
    4.93 -<para>Que se passe-t-il quand vous essayez d'utiliser la commande <command role="hg-cmd">hg update</command>
    4.94 -pour mettre à jour votre espace de travail au nouveau \textit{tip}.
    4.95 -<!-- &interaction.tour.merge.update; -->
    4.96 -Mercurial nous prévient que la commande <command role="hg-cmd">hg update</command> n'effectuera pas
    4.97 -la fusion, il ne veut pas mettre à jour l'espace de travail quand il
    4.98 -estime que nous pourrions avoir besoin d'une fusion, à moins de lui
    4.99 -forcer la main. À la place, il faut utiliser la commande <command role="hg-cmd">hg merge</command>
   4.100 -pour fusionner les deux \textit{heads}.
   4.101 -<!-- &interaction.tour.merge.merge; -->
   4.102 -</para>
   4.103 -
   4.104 -<informalfigure>
   4.105 -
   4.106 -<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-merge"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   4.107 -  \caption{Espace de travail et dépôt lors d'une fusion, et dans le
   4.108 -    \textit{commit} qui suit.}
   4.109 -  \label{fig:tour-merge:merge}
   4.110 -</para>
   4.111 -</informalfigure>
   4.112 -
   4.113 -<para>Ceci met à jour l'espace de travail de manière à ce qu'il contienne
   4.114 -les modifications des <emphasis>deux</emphasis> \textit{heads}, ce qui apparaît dans
   4.115 -les sorties de la commande <command role="hg-cmd">hg parents</command> et le contenu de
   4.116 -<filename>hello.c</filename>.
   4.117 -<!-- &interaction.tour.merge.parents; -->
   4.118 -</para>
   4.119 -
   4.120 -</sect2>
   4.121 -<sect2>
   4.122 -<title>Effectuer le \textit{commit} du résultat de la fusion</title>
   4.123 -
   4.124 -<para>Dès l'instant où vous avez effectué une fusion, <command role="hg-cmd">hg parents</command> vous
   4.125 -affichera deux parents, avant que vous n'exécutiez la commande
   4.126 -<command role="hg-cmd">hg commit</command> sur le résultat de la fusion.
   4.127 -<!-- &interaction.tour.merge.commit; -->
   4.128 -Nous avons maintenant un nouveau \textit{tip}, remarquer qu'il contient
   4.129 -<emphasis>à la fois</emphasis> nos anciennes \textit{heads} et leurs parents. Ce sont
   4.130 -les mêmes révisions que nous avions affichées avec la commande
   4.131 -<command role="hg-cmd">hg parents</command>.
   4.132 -</para>
   4.133 -
   4.134 -<para><!-- &interaction.tour.merge.tip; -->
   4.135 -Dans la figure <xref linkend="fig:tour-merge:merge"/>, vous pouvez voir une représentation
   4.136 -de ce qui se passe dans l'espace de travail pendant la fusion, et comment ceci
   4.137 -affecte le dépôt lors du \textit{commit}. Pendant la fusion, l'espace de travail,
   4.138 -qui a deux \texit{changesets} comme parents, voit ces derniers devenir le parent
   4.139 -%%% TODO: le parent ou "les parents" : plus logique mais si il reste seulement
   4.140 -%%% un changeset, alors c'est effectivement un parent (le changeset est hermaphrodite)
   4.141 -d'un nouveau \textit{changeset}.
   4.142 -</para>
   4.143 -
   4.144 -</sect2>
   4.145 -</sect1>
   4.146 -<sect1>
   4.147 -<title>Fusionner les modifications en conflit</title>
   4.148 -
   4.149 -<para>La plupart des fusions sont assez simple à réaliser, mais parfois
   4.150 -vous vous retrouverez à fusionner des fichiers où la modification touche
   4.151 -la même portion de code, au sein d'un même fichier. À moins que ces
   4.152 -modification ne soient identiques, ceci aboutira à un <emphasis>conflit</emphasis>,
   4.153 -et vous devrez décider comment réconcilier les différentes modifications
   4.154 -dans un tout cohérent.
   4.155 -</para>
   4.156 -
   4.157 -<informalfigure>
   4.158 -
   4.159 -<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-conflict"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   4.160 -  <caption><para>Modifications conflictuelles dans un document</para></caption>
   4.161 -  \label{fig:tour-merge:conflict}
   4.162 -</para>
   4.163 -</informalfigure>
   4.164 -
   4.165 -<para>La figure <xref linkend="fig:tour-merge:conflict"/> illustre un cas de modifications
   4.166 -conflictuelles dans un document. Nous avons commencé avec une version simple
   4.167 -de ce fichier, puis nous avons ajouté des modifications, pendant que
   4.168 -quelqu'un d'autre modifiait le même texte. Notre tâche dans la résolution
   4.169 -du conflit est de décider à quoi le fichier devrait ressembler.
   4.170 -</para>
   4.171 -
   4.172 -<para>Mercurial n'a pas de mécanisme interne pour gérer les conflits.
   4.173 -À la place, il exécute un programme externe appelé <command>hgmerge</command>.
   4.174 -Il s'agit d'un script shell qui est embarqué par Mercurial, vous
   4.175 -pouvez le modifier si vous le voulez. Ce qu'il fait par défaut est
   4.176 -d'essayer de trouver un des différents outils de fusion qui seront
   4.177 -probablement installés sur le système. Il commence par les outils
   4.178 -totalement automatiques, et si ils échouent (parce que la résolution
   4.179 -du conflit nécessite une intervention humaine) ou si ils sont absents,
   4.180 -le script tente d'exécuter certains outils graphiques de fusion.
   4.181 -</para>
   4.182 -
   4.183 -<para>Il est aussi possible de demander à Mercurial d'exécuter un autre
   4.184 -programme ou un autre script au lieu de la commande <command>hgmerge</command>,
   4.185 -en définissant la variable d'environnement <envar>HGMERGE</envar> avec le nom
   4.186 -du programme de votre choix.
   4.187 -</para>
   4.188 -
   4.189 -<sect2>
   4.190 -<title>Utiliser un outil graphique de fusion</title>
   4.191 -
   4.192 -<para>Mon outil de fusion préféré est <command>kdiff3</command>, que j'utilise ici
   4.193 -pour illustrer les fonctionnalités classiques des outils graphiques
   4.194 -de fusion. Vous pouvez voir une capture d'écran de l'utilisation de
   4.195 -<command>kdiff3</command> dans la figure <xref linkend="fig:tour-merge:kdiff3"/>. Cet outil
   4.196 -effectue une <emphasis>fusion \textit{three-way</emphasis>}, car il y a trois différentes
   4.197 -versions du fichier qui nous intéresse. Le fichier découpe la partie
   4.198 -supérieure de la fenêtre en trois panneaux:
   4.199 -</para>
   4.200 -
   4.201 -<itemizedlist>
   4.202 -<listitem><para>A gauche on la version de <emphasis>base</emphasis> du fichier, soit la plus
   4.203 -  récente version des deux versions qu'on souhaite fusionner.
   4.204 -</para>
   4.205 -</listitem>
   4.206 -<listitem><para>Au centre, il y a <quote>notre</quote> version du fichier, avec le contenu
   4.207 -  que nous avons modifié.
   4.208 -</para>
   4.209 -</listitem>
   4.210 -<listitem><para>Sur la droite, on trouve <quote>leur</quote> version du fichier, celui qui
   4.211 -  contient le \textit{changeset} que nous souhaitons intégré.
   4.212 -</para>
   4.213 -</listitem></itemizedlist>
   4.214 -
   4.215 -<para>Dans le panneau en dessous, on trouve le <emphasis>résultat</emphasis> actuel de notre
   4.216 -fusion. Notre tâche consiste donc à remplacement tous les textes en rouges,
   4.217 -qui indiquent des conflits non résolus, avec une fusion manuelle et pertinente
   4.218 -de <quote>notre</quote> version et de la <quote>leur</quote>.
   4.219 -</para>
   4.220 -
   4.221 -<para>Tous les quatre panneaux sont <emphasis>accrochés ensemble</emphasis>, si nous déroulons
   4.222 -les ascenseurs verticalement ou horizontalement dans chacun d'entre eux, les
   4.223 -autres sont mis à jour avec la section correspondante dans leurs fichiers
   4.224 -respectifs.
   4.225 -</para>
   4.226 -
   4.227 -<informalfigure>
   4.228 -
   4.229 -<para>  <mediaobject><imageobject><imagedata fileref="kdiff3"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   4.230 -  <caption><para>Utilisation de \command{kdiff3</para></caption> pour fusionner différentes versions
   4.231 -  d'un fichier.}
   4.232 -  \label{fig:tour-merge:kdiff3}
   4.233 -</para>
   4.234 -</informalfigure>
   4.235 -
   4.236 -<para>Pour chaque portion de fichier posant problème, nous pouvons choisir
   4.237 -de résoudre le conflit en utilisant une combinaison
   4.238 -de texte depuis la version de base, la notre, ou la leur. Nous pouvons
   4.239 -aussi éditer manuellement les fichiers à tout moment, si c'est
   4.240 -nécessaire.
   4.241 -</para>
   4.242 -
   4.243 -<para>Il y a <emphasis>beaucoup</emphasis> d'outils de fusion disponibles, bien trop pour
   4.244 -en parler de tous ici. Leurs disponibilités varient selon les plate formes
   4.245 -ainsi que leurs avantages et inconvénients. La plupart sont optimisé pour
   4.246 -la fusion de fichier contenant un texte plat, certains sont spécialisé
   4.247 -dans un format de fichier précis (généralement XML).
   4.248 -</para>
   4.249 -
   4.250 -</sect2>
   4.251 -<sect2>
   4.252 -<title>Un exemple concret</title>
   4.253 -
   4.254 -<para>Dans cet exemple, nous allons reproduire la modification de l'historique
   4.255 -du fichier de la figure <xref linkend="fig:tour-merge:conflict"/> ci dessus. Commençons
   4.256 -par créer un dépôt avec une version de base de notre document.
   4.257 -</para>
   4.258 -
   4.259 -<para><!-- &interaction.tour-merge-conflict.wife; -->
   4.260 -Créons un clone de ce dépôt et faisons une modification dans le fichier.
   4.261 -<!-- &interaction.tour-merge-conflict.cousin; -->
   4.262 -Et un autre clone, pour simuler que quelqu'un d'autre effectue une
   4.263 -modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
   4.264 -de devoir effectuer des \textit{merge} avec vos propres travaux quand
   4.265 -vous isolez les tâches dans des dépôts distincts. En effet, vous
   4.266 -aurez alors à trouver et résoudre certains conflits).
   4.267 -<!-- &interaction.tour-merge-conflict.son; -->
   4.268 -Maintenant que ces deux versions différentes du même fichier sont
   4.269 -créées, nous allons configurer l'environnement de manière appropriée pour
   4.270 -exécuter notre \textit{merge}.
   4.271 -<!-- &interaction.tour-merge-conflict.pull; -->
   4.272 -</para>
   4.273 -
   4.274 -<para>Dans cette exemple, je n'utiliserais pas la commande Mercurial
   4.275 -habituelle <command>hgmerge</command> pour effectuer le \textit{merge},
   4.276 -car il me faudrait abandonner ce joli petit exemple automatisé
   4.277 -pour utiliser un outil graphique. À la place, je vais définir
   4.278 -la variable d'environnement <envar>HGMERGE</envar> pour indiquer à
   4.279 -Mercurial d'utiliser la commande non-interactive <command>merge</command>.
   4.280 -Cette dernière est embarquée par de nombreux systèmes <quote>à la Unix</quote>.
   4.281 -Si vous exécutez cet exemple depuis votre ordinateur, ne vous
   4.282 -occupez pas de définir <envar>HGMERGE</envar>.
   4.283 -<!-- &interaction.tour-merge-conflict.merge; -->
   4.284 -Parce que <command>merge</command> ne peut pas résoudre les modifications
   4.285 -conflictuelles, il laisse des <emphasis>marqueurs de différences</emphasis>
   4.286 -\footnote{NdT: Oui, je traduis \textit{merge markers} par un sens
   4.287 -inverse en Français, mais je pense vraiment que c'est plus clair
   4.288 -comme ça...} à l'intérieur du fichier qui a des conflits, indiquant
   4.289 -clairement quelles lignes sont en conflits, et si elles viennent de
   4.290 -notre fichier ou du fichier externe.
   4.291 -</para>
   4.292 -
   4.293 -<para>Mercurial peut distinguer, à la manière dont la commande <command>merge</command>
   4.294 -se termine, qu'elle n'a pas été capable d'effectuer le \textit{merge},
   4.295 -alors il nous indique que nous devons effectuer de nouveau cette
   4.296 -opération. Ceci peut être très utile si, par exemple, nous exécutons un
   4.297 -outil graphique de fusion et que nous le quittons sans nous rendre compte
   4.298 -qu'il reste des conflits ou simplement par erreur.
   4.299 -</para>
   4.300 -
   4.301 -<para>Si le \textit{merge} automatique ou manuel échoue, il n'y a rien pour
   4.302 -nous empêcher de <quote>corriger le tir</quote> en modifiant nous même les fichiers,
   4.303 -et enfin effectuer le \textit{commit} du fichier:
   4.304 -<!-- &interaction.tour-merge-conflict.commit; -->
   4.305 -</para>
   4.306 -
   4.307 -</sect2>
   4.308 -</sect1>
   4.309 -<sect1>
   4.310 -<title>Simplification de la séquence pull-merge-commit</title>
   4.311 -<para>\label{sec:tour-merge:fetch}
   4.312 -</para>
   4.313 -
   4.314 -<para>La procédure pour effectuer la fusion indiquée ci-dessus est simple,
   4.315 -mais requiert le lancement de trois commandes à la suite.
   4.316 -</para>
   4.317 -<programlisting>
   4.318 -<para>  hg pull
   4.319 -  hg merge
   4.320 -  hg commit -m 'Merged remote changes'
   4.321 -</para>
   4.322 -</programlisting>
   4.323 -
   4.324 -<para>Lors du \textit{commit} final, vous devez également saisir un message,
   4.325 -qui aura vraisemblablement assez peu d'intérêt.
   4.326 -</para>
   4.327 -
   4.328 -<para>Il serait assez sympathique de pouvoir réduire le nombre d'opérations
   4.329 -nécessaire, si possible. De fait Mercurial est fourni avec une
   4.330 -extension appelé <literal role="hg-ext">fetch</literal> qui fait justement cela.
   4.331 -</para>
   4.332 -
   4.333 -<para>Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
   4.334 -d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
   4.335 -léger et facile à utiliser. Certains extensions ajoutent de nouvelles
   4.336 -commandes que vous pouvez utiliser en ligne de commande, alors que
   4.337 -d'autres travaillent <quote>en coulisse,</quote> par exemple en ajoutant des
   4.338 -possibilités au serveur.
   4.339 -</para>
   4.340 -
   4.341 -<para>L'extension <literal role="hg-ext">fetch</literal> ajoute une nouvelle commande nommée, sans
   4.342 -surprise, <command role="hg-cmd">hg fetch</command>. Cette extension résulte en une combinaison
   4.343 -de <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg update</command> and <command role="hg-cmd">hg merge</command>. Elle commence par
   4.344 -récupérer les modifications d'un autre dépôt dans le dépôt courant.
   4.345 -Si elle trouve que les modifications ajoutent une nouvelle \textit{head},
   4.346 -elle effectue un \textit{merge}, et ensuite \texit{commit} le résultat
   4.347 -du \textit{merge} avec un message généré automatiquement. Si aucune
   4.348 -\textit{head} n'ont été ajouté, elle met à jour le répertoire de travail
   4.349 -au niveau du nouveau \textit{changeset} \textit{tip}.
   4.350 -</para>
   4.351 -
   4.352 -
   4.353 -<para>Activer l'extension <literal role="hg-ext">fetch</literal> est facile. Modifiez votre <filename role="special">.hgrc</filename>,
   4.354 -et soit allez à la section <literal role="rc-extensions">extensions</literal> soit créer une
   4.355 -section <literal role="rc-extensions">extensions</literal>. Ensuite ajoutez une ligne qui consiste
   4.356 -simplement en <quote>\Verb+fetch =</quote>.
   4.357 -</para>
   4.358 -
   4.359 -<programlisting>
   4.360 -<para>  [extensions]
   4.361 -  fetch =
   4.362 -</para>
   4.363 -</programlisting>
   4.364 -<para>(Normalement, sur la partie droite de <quote><literal>=</literal></quote> devrait apparaître
   4.365 -le chemin de l'extension, mais étant donné que l'extension <literal role="hg-ext">fetch</literal>
   4.366 -fait partie de la distribution standard, Mercurial sait où la trouver.)
   4.367 -</para>
   4.368 -
   4.369 -</sect1>
   4.370 +        <listitem>
   4.371 +          <para id="x_33a">Alice et Bob ont chacun une copie personnelle du dépôt d'un
   4.372 +            projet sur lequel ils collaborent. Alice corrige un bug
   4.373 +            dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
   4.374 +            sien. Ils veulent un dépôt partagé avec à la fois le correctif du
   4.375 +            bug et la nouvelle fonctionnalité.</para>
   4.376 +       </listitem>
   4.377 +       <listitem>
   4.378 +         <para id="x_33b">Je travaille régulièrement sur plusieurs tâches différentes sur
   4.379 +           un seul projet en même temps, chacun isolé dans son propre dépôt.
   4.380 +           Travailler ainsi signifie que je dois régulièrement fusionner une
   4.381 +           partie de mon code avec celui des autres.</para>
   4.382 +       </listitem>
   4.383 +     </itemizedlist>
   4.384 +
   4.385 +     <para id="x_33c">Parce que la fusion est une opération si commune à réaliser,
   4.386 +       Mercurial la rend facile. Étudions ensemble le déroulement des
   4.387 +       opérations. Nous commencerons encore par faire un clone d'un autre
   4.388 +       dépôt (vous voyez que l'on fait ça tout le temps ?) puis nous ferons 
   4.389 +       quelques modifications dessus.</para>
   4.390 +       
   4.391 +       &interaction.tour.merge.clone;
   4.392 +       
   4.393 +     <para id="x_33d">Nous devrions avoir maintenant deux copies de
   4.394 +       <filename>hello.c</filename> avec des contenus différents. Les
   4.395 +       historiques de ces deux dépôts ont aussi divergés, comme illustré dans
   4.396 +       la figure <xref linkend="fig:tour-merge:sep-repos"/>.</para>
   4.397 +
   4.398 +      &interaction.tour.merge.cat1;
   4.399 +     
   4.400 +     <para id="x_722">Et ici est notre légèrement différente version du
   4.401 +       dépôt.</para>
   4.402 +     
   4.403 +      &interaction.tour.merge.cat2;
   4.404 +     
   4.405 +     <figure id="fig:tour-merge:sep-repos">
   4.406 +       <title>Historique divergent des dépôts <filename
   4.407 +         class="directory">my-hello</filename> et <filename
   4.408 +         class="directory">my-new-hello</filename>.</title>
   4.409 +       <mediaobject>
   4.410 +         <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
   4.411 +         <textobject><phrase>XXX ajoute un test</phrase></textobject>
   4.412 +       </mediaobject>
   4.413 +     </figure>
   4.414 +
   4.415 +     <para id="x_33f">Nous savons déjà que récupérer les modifications depuis
   4.416 +       notre dépôt <filename class="directory">my-hello</filename> n'aura
   4.417 +       aucun effet sur l'espace de travail.</para>
   4.418 +
   4.419 +      &interaction.tour.merge.pull;
   4.420 +
   4.421 +     <para id="x_340">Néanmoins, la commande <command role="hg-cmd">hg
   4.422 +       pull</command> nous indique quelque chose au sujet des 
   4.423 +       <quote>heads</quote>.</para>
   4.424 +
   4.425 +     <sect2>
   4.426 +       <title>Les révisions 'heads'</title>
   4.427 +
   4.428 +       <para id="x_341">Rappellez vous que Mercurial enregistre quelle révision
   4.429 +         est le parent de chaque révision. Si une révision a un parent, nous
   4.430 +         l'appelons un enfant(child) ou un descendant de ce parent. Une
   4.431 +         "head" est une révision qui n'a donc pas d'enfant. La révision tip
   4.432 +         est donc une "head", car c'est la révision la plus récente du dépôt
   4.433 +         qui n'a pas d'enfant. Il y a des moments où un dépôt peut contenir
   4.434 +         plusieurs "head".</para>
   4.435 +
   4.436 +       <figure id="fig:tour-merge:pull">
   4.437 +         <title>Contenu du dépôt après une récupération ("pull") depuis le
   4.438 +           dépôt <filename
   4.439 +           class="directory">my-hello</filename> vers le dépôt <filename
   4.440 +           class="directory">my-new-hello</filename></title>
   4.441 +         <mediaobject>
   4.442 +           <imageobject>
   4.443 +             <imagedata fileref="tour-merge-pull"/>
   4.444 +           </imageobject>
   4.445 +           <textobject><phrase>XXX ajoute un texte</phrase></textobject>
   4.446 +         </mediaobject>
   4.447 +       </figure>
   4.448 +
   4.449 +       <para id="x_343">Dans la figure <xref linkend="fig:tour-merge:pull"/>,
   4.450 +         vous pouvez constater l'effet d'un \textit{pull} depuis le dépôt
   4.451 +         <filename class="directory">my-hello</filename> dans le dépôt
   4.452 +         <filename class="directory">my-new-hello</filename>. L'historique qui
   4.453 +         était déjà présent dans le dépôt <filename
   4.454 +         class="directory">my-new-hello</filename> reste intact, mais une
   4.455 +         nouvelle révision a été ajoutée. En vous reportant à la figure <xref
   4.456 +         linkend="fig:tour-merge:sep-repos"/>, vous pouvez voir que le
   4.457 +         <emphasis>ID de révision (changeset ID)</emphasis> reste le même dans
   4.458 +         le nouveau dépôt, mais que le <emphasis>numéro de
   4.459 +         révision</emphasis> reste le même. (Ceci est un parfait exemple de
   4.460 +         pourquoi il n'est fiable d'utiliser les numéros de révision lorsque
   4.461 +         l'on discute d'un \textit{changeset}.) Vous pouvez voir les "heads"
   4.462 +         présentes dans le dépôt en utilisant la commande <command
   4.463 +         role="hg-cmd">hg heads</command>.</para>
   4.464 +
   4.465 +        &interaction.tour.merge.heads;
   4.466 +      </sect2>
   4.467 +
   4.468 +      <sect2>
   4.469 +        <title>Effectuer la fusion</title>
   4.470 +
   4.471 +        <para id="x_344">Que se passe-t-il quand vous essayez d'utiliser la
   4.472 +          commande <command role="hg-cmd">hg update</command> pour mettre à
   4.473 +          jour votre espace de travail au nouveau "tip"</para>
   4.474 +         
   4.475 +         &interaction.tour.merge.update;
   4.476 +
   4.477 +         
   4.478 +        <para id="x_345">Mercurial nous prévient que la commande <command
   4.479 +          role="hg-cmd">hg update</command> n'effectuera pas
   4.480 +          la fusion, il ne veut pas mettre à jour l'espace de travail quand il
   4.481 +          estime que nous pourrions avoir besoin d'une fusion, à moins de lui
   4.482 +          forcer la main. À la place, il faut utiliser la commande <command
   4.483 +          role="hg-cmd">hg merge</command> pour fusionner les deux
   4.484 +          "heads".</para>
   4.485 +
   4.486 +       <para id="x_723">Pour commencer une fusion (merge) entre deux "heads",
   4.487 +       nous utilisons la commande <command role="hg-cmd">hg merge</command>.</para>
   4.488 +
   4.489 +        &interaction.tour.merge.merge; 
   4.490 +      
   4.491 +       <para id="x_347">Nous résolvons les conflits dans le fichier
   4.492 +         <filename>hello.c</filename>. Ceci met à jour le répertoire de travail
   4.493 +         de sorte qu'il ne contienne les modifications ne provenance des
   4.494 +         <emphasis>deux</emphasis> "heads", ce qui est indiqué par la
   4.495 +         la sortie de la commande <command role="hg-cmd">hg
   4.496 +         parents</command> et le contenu du fichier
   4.497 +         <filename>hello.c</filename>.</para>
   4.498 +
   4.499 +        &interaction.tour.merge.parents;
   4.500 +     </sect2>
   4.501 +
   4.502 +     <sect2>
   4.503 +       <title>Effectuer l'ajout (commit) du résultat de la fusion</title>
   4.504 +
   4.505 +       <para id="x_348">Dès l'instant où vous avez effectué une fusion
   4.506 +         (merge), <command role="hg-cmd">hg parents</command> vous
   4.507 +         affichera deux parents, avant que vous n'exécutiez la commande
   4.508 +         <command role="hg-cmd">hg commit</command> sur le résultat de la
   4.509 +         fusion.</para>
   4.510 +
   4.511 +        &interaction.tour.merge.commit;
   4.512 +
   4.513 +      <para id="x_349">Nous avons maintenant un nouveau tip, remarquer qu'il
   4.514 +        contient <emphasis>à la fois</emphasis> nos anciennes "heads" et leurs
   4.515 +        parents. Ce sont les mêmes révisions que nous avions affichées avec
   4.516 +        la commande <command role="hg-cmd">hg parents</command>.</para>
   4.517 +
   4.518 +       &interaction.tour.merge.tip;
   4.519 +
   4.520 +      <para id="x_34a">Dans la figure <xref linkend="fig:tour-merge:merge"/>,
   4.521 +        vous pouvez voir une représentation de ce qui se passe dans l'espace
   4.522 +        de travail pendant la fusion, et comment ceci affecte le dépôt lors
   4.523 +        du "commit". Pendant la fusion, l'espace de travail, qui a deux
   4.524 +        révisions (changesets) comme parents, voit ces derniers devenir le parent
   4.525 +        d'une nouvelle révision (changeset).</para>
   4.526 +
   4.527 +      <figure id="fig:tour-merge:merge">
   4.528 +        <title>Working directory and repository during merge, and
   4.529 +          following commit</title>
   4.530 +        <mediaobject>
   4.531 +          <imageobject>
   4.532 +            <imagedata fileref="figs/tour-merge-merge.png"/>
   4.533 +          </imageobject>
   4.534 +          <textobject><phrase>XXX ajoute texte</phrase></textobject>
   4.535 +        </mediaobject>
   4.536 +      </figure>
   4.537 +
   4.538 +    </sect2>
   4.539 +  </sect1>
   4.540 +
   4.541 +  <sect1>
   4.542 +    <title>Fusionner les modifications en conflit</title>
   4.543 +
   4.544 +    <para id="x_34b">La plupart des fusions sont assez simple à réaliser, mais 
   4.545 +      parfois vous vous retrouverez à fusionner des fichiers où la modification 
   4.546 +      touche la même portion de code, au sein d'un même fichier. À moins 
   4.547 +      que ces modification ne soient identiques, ceci aboutira à un 
   4.548 +      <emphasis>conflit</emphasis>, et vous devrez décider comment réconcilier 
   4.549 +      les différentes modifications dans un tout cohérent.</para>
   4.550 +
   4.551 +    <figure id="fig:tour-merge:conflict">
   4.552 +      <title>Modifications en conflits dans un document</title>
   4.553 +      <mediaobject>
   4.554 +        <imageobject><imagedata fileref="tour-merge-conflict"/></imageobject>
   4.555 +        <textobject><phrase>XXX ajoute texte</phrase></textobject>
   4.556 +      </mediaobject>
   4.557 +    </figure>
   4.558 +
   4.559 +    <para id="x_34d">La figure <xref linkend="fig:tour-merge:conflict"/>
   4.560 +      illustre un cas de modifications conflictuelles dans un document. Nous
   4.561 +      avons commencé avec une version simple de ce fichier, puis nous avons
   4.562 +      ajouté des modifications, pendant que quelqu'un d'autre modifiait le même
   4.563 +      texte. Notre tâche dans la résolution du conflit est de décider à quoi le
   4.564 +      fichier devrait ressembler.</para>
   4.565 +
   4.566 +    <para id="x_34e">Mercurial n'a pas de mécanisme interne pour gérer 
   4.567 +      les conflits. À la place, il exécute un programme externe appelé 
   4.568 +      <command>hgmerge</command>. Il s'agit d'un script shell qui est 
   4.569 +      embarqué par Mercurial, vous pouvez le modifier si vous le voulez. 
   4.570 +      Ce qu'il fait par défaut est d'essayer de trouver un des différents 
   4.571 +      outils de fusion qui seront probablement installés sur le système. 
   4.572 +      Il commence par les outils totalement automatiques, et si ils 
   4.573 +      échouent (parce que la résolution du conflit nécessite une
   4.574 +      intervention humaine) ou si ils sont absents, le script tente
   4.575 +      d'exécuter certains outils graphiques de fusion.</para>
   4.576 +
   4.577 +    <para id="x_34f">Il est aussi possible de demander à Mercurial d'exécuter
   4.578 +      un autre programme ou un autre script en définissant la variable
   4.579 +      d'environnement <envar>HGMERGE</envar> avec le nom
   4.580 +      du programme de votre choix.</para>
   4.581 +
   4.582 +    <sect2>
   4.583 +      <title>Utiliser un outil graphique de fusion</title>
   4.584 +
   4.585 +      <para id="x_350">Mon outil de fusion préféré est
   4.586 +      <command>kdiff3</command>, que j'utilise ici pour illustrer les
   4.587 +        fonctionnalités classiques des outils graphiques de fusion. Vous pouvez
   4.588 +        voir une capture d'écran de l'utilisation de <command>kdiff3</command>
   4.589 +        dans la figure <xref linkend="fig:tour-merge:kdiff3"/>. Cet outil
   4.590 +        effectue une <emphasis>fusion \textit{three-way</emphasis>}, car il y a
   4.591 +        trois différentes versions du fichier qui nous intéresse. Le fichier
   4.592 +        découpe la partie supérieure de la fenêtre en trois panneaux:</para>
   4.593 +      <itemizedlist>
   4.594 +        <listitem><para id="x_351">A gauche on la version de
   4.595 +          <emphasis>base</emphasis> du fichier, soit la plus récente version
   4.596 +          des deux versions qu'on souhaite fusionner.</para></listitem>
   4.597 +        <listitem><para id="x_352">Au centre, il y a <quote>notre</quote>
   4.598 +          version du fichier, avec le contenu que nous avons modifié.</para></listitem>
   4.599 +        <listitem><para id="x_353">Sur la droite, on trouve
   4.600 +        <quote>leur</quote> version du fichier, celui qui contient la
   4.601 +        révision que nous souhaitons intégré.</para>
   4.602 +        </listitem></itemizedlist>
   4.603 +      <para id="x_354">Dans le panneau en dessous, on trouve le
   4.604 +        <emphasis>résultat</emphasis> actuel de notre fusion. Notre tâche
   4.605 +        consiste donc à remplacement tous les textes en rouges,
   4.606 +        qui indiquent des conflits non résolus, avec une fusion manuelle et 
   4.607 +        pertinente de <quote>notre</quote> version et de la <quote>leur</quote>.
   4.608 +      </para>
   4.609 +
   4.610 +      <para id="x_355">Tous les quatre panneaux sont <emphasis>accrochés ensemble</emphasis>, 
   4.611 +        si nous déroulons les ascenseurs verticalement ou horizontalement dans chacun 
   4.612 +        d'entre eux, les autres sont mis à jour avec la section correspondante dans leurs 
   4.613 +        fichiers respectifs.</para>
   4.614 +
   4.615 +      <figure id="fig:tour-merge:kdiff3">
   4.616 +        <title>Utiliser <command>kdiff3</command> pour fusionner les
   4.617 +          différentes version d'un fichier.</title>
   4.618 +        <mediaobject>
   4.619 +          <imageobject>
   4.620 +            <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
   4.621 +            <textobject>
   4.622 +              <phrase>XXX ajoute texte</phrase>
   4.623 +            </textobject>
   4.624 +          </mediaobject>
   4.625 +       </figure>
   4.626 +
   4.627 +       <para id="x_357">Pour chaque portion de fichier posant problème, nous
   4.628 +         pouvons choisir de résoudre le conflit en utilisant une combinaison de
   4.629 +         texte depuis la version de base, la notre, ou la leur. Nous pouvons
   4.630 +         aussi éditer manuellement les fichiers à tout moment, si c'est nécessaire.</para>
   4.631 +
   4.632 +       <para id="x_358">Il y a <emphasis>beaucoup</emphasis> d'outils de
   4.633 +         fusion disponibles, bien trop pour en parler de tous ici. Leurs
   4.634 +         disponibilités varient selon les plate formes  ainsi que leurs
   4.635 +         avantages et inconvénients. La plupart sont optimisé pour
   4.636 +         la fusion de fichier contenant un texte plat, certains sont spécialisé
   4.637 +         dans un format de fichier précis (généralement XML).</para>
   4.638 +    </sect2>
   4.639 +
   4.640 +    <sect2>
   4.641 +      <title>Un exemple concret</title>
   4.642 +
   4.643 +      <para id="x_359">Dans cet exemple, nous allons reproduire la
   4.644 +        modification de l'historique du fichier de la figure <xref
   4.645 +        linkend="fig:tour-merge:conflict"/> ci dessus. Commençons par créer
   4.646 +        un dépôt avec une version de base de notre document.</para>
   4.647 +
   4.648 +      &interaction.tour-merge-conflict.wife; 
   4.649 +
   4.650 +      <para id="x_35a">Créons un clone de ce dépôt et faisons une
   4.651 +        modification dans le fichier.</para>
   4.652 +
   4.653 +      &interaction.tour-merge-conflict.cousin;
   4.654 +      
   4.655 +      <para id="x_35b">Et un autre clone, pour simuler que quelqu'un d'autre effectue une
   4.656 +        modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
   4.657 +        de devoir effectuer des fusions (merges) avec vos propres travaux quand
   4.658 +        vous isolez les tâches dans des dépôts distincts. En effet, vous
   4.659 +        aurez alors à trouver et résoudre certains conflits).</para>
   4.660 +
   4.661 +      &interaction.tour-merge-conflict.son;
   4.662 +
   4.663 +      <para id="x_35c">Maintenant que ces deux versions différentes du même fichier sont
   4.664 +        créées, nous allons configurer l'environnement de manière appropriée pour
   4.665 +        exécuter notre fusion (merge).</para>
   4.666 +
   4.667 +      &interaction.tour-merge-conflict.pull;
   4.668 +
   4.669 +      <para id="x_35d">Dans cette exemple, je n'utiliserais pas la commande Mercurial
   4.670 +        habituelle <command>hgmerge</command> pour effectuer le
   4.671 +        fusion (merge), car il me faudrait abandonner ce joli petit exemple automatisé
   4.672 +        pour utiliser un outil graphique. À la place, je vais définir la
   4.673 +        variable d'environnement <envar>HGMERGE</envar> pour indiquer à
   4.674 +        Mercurial d'utiliser la commande non-interactive <command>merge</command>.
   4.675 +        Cette dernière est embarquée par de nombreux systèmes <quote>à la Unix</quote>.
   4.676 +        Si vous exécutez cet exemple depuis votre ordinateur, ne vous
   4.677 +        occupez pas de définir <envar>HGMERGE</envar>.</para>
   4.678 +
   4.679 +     &interaction.tour-merge-conflict.merge; 
   4.680 +
   4.681 +
   4.682 +     <para id="x_35f">Parce que <command>merge</command> ne peut pas résoudre
   4.683 +       les modifications conflictuelles, il laisse des <emphasis>marqueurs de
   4.684 +       différences</emphasis> à l'intérieur du fichier qui a des conflits,
   4.685 +       indiquant clairement quelles lignes sont en conflits, et si elles
   4.686 +       viennent de notre fichier ou du fichier externe.
   4.687 +     </para>
   4.688 +
   4.689 +     <para id="x_360">Mercurial peut distinguer, à la manière dont la
   4.690 +       commande <command>merge</command> se termine, qu'elle n'a pas été
   4.691 +       capable d'effectuer la fusion (merge), alors il nous indique que nous
   4.692 +       devons effectuer de nouveau cette opération. Ceci peut être très utile
   4.693 +       si, par exemple, nous exécutons un outil graphique de fusion et que
   4.694 +       nous le quittons sans nous rendre compte qu'il reste des conflits ou 
   4.695 +       simplement par erreur.</para>
   4.696 +
   4.697 +     <para id="x_361">Si la fusion (merge) automatique ou manuelle échoue, 
   4.698 +       il n'y a rien pour nous empêcher de <quote>corriger le tir</quote> en
   4.699 +       modifiant nous même les fichiers, et enfin effectuer le "commit" du 
   4.700 +       fichier:</para>
   4.701 +
   4.702 +     &interaction.tour-merge-conflict.commit;
   4.703 +
   4.704 +     <note>
   4.705 +       <title>Où est la <command>hg resolve</command> ?</title>
   4.706 +       
   4.707 +       <para id="x_724">La commande <command>hg resolve</command> a été
   4.708 +         introduit dans la version 1.1 de Mercurial, qui a été publié en
   4.709 +         décembre 2008. Si vous utilisez une version plus anciennne de
   4.710 +         Mercurial (exécutez la command <command>hg version</command> pour en
   4.711 +         avoir le coeur net), cette commande ne sera pas disponible. Si votre
   4.712 +         version de Mercurial est plus ancienne que la 1.1, vous devriez très
   4.713 +         fortement considérer une mise à jour à une version plus récente avant
   4.714 +         d'essayer de régler des fusions complexes.</para>
   4.715 +       </note>
   4.716 +     </sect2>
   4.717 +   </sect1>
   4.718 +
   4.719 +   <sect1 id="sec:tour-merge:fetch">
   4.720 +     <title>Simplification de la séquence pull-merge-commit</title>
   4.721 +
   4.722 +     <para id="x_362">La procédure pour effectuer la fusion indiquée
   4.723 +       ci-dessus est simple, mais requiert le lancement de trois commandes à la
   4.724 +       suite.</para>
   4.725 +
   4.726 +     <programlisting>hg pull -u
   4.727 +hg merge
   4.728 +hg commit -m 'Merged remote changes'</programlisting>
   4.729 +
   4.730 +     <para id="x_363">Lors du "commit" final, vous devez également saisir un
   4.731 +       message, qui aura vraisemblablement assez peu d'intérêt.</para>
   4.732 +
   4.733 +     <para id="x_364">Il serait assez sympathique de pouvoir réduire le
   4.734 +       nombre d'opérations nécessaire, si possible. De fait Mercurial est
   4.735 +       fourni avec une extension appelé <literal role="hg-ext">fetch</literal>
   4.736 +       qui fait justement cela.</para>
   4.737 +
   4.738 +     <para id="x_365">Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
   4.739 +       d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
   4.740 +       léger et facile à utiliser. Certains extensions ajoutent de nouvelles
   4.741 +       commandes que vous pouvez utiliser en ligne de commande, alors que
   4.742 +       d'autres travaillent <quote>en coulisse,</quote> par exemple en ajoutant des
   4.743 +       possibilités au serveur.</para>
   4.744 +
   4.745 +     <para id="x_366">L'extension <literal role="hg-ext">fetch</literal>
   4.746 +       ajoute une nouvelle commande nommée, sans surprise, <command
   4.747 +       role="hg-cmd">hg fetch</command>. Cette extension résulte en une
   4.748 +       combinaison de <command role="hg-cmd">hg pull</command>, <command
   4.749 +       role="hg-cmd">hg update</command> and <command role="hg-cmd">hg
   4.750 +       merge</command>. Elle commence par récupérer les modifications d'un
   4.751 +       autre dépôt dans le dépôt courant. Si elle trouve que les
   4.752 +       modifications ajoutent une nouvelle "head", elle effectue un "merge",
   4.753 +       et ensuite "commit" le résultat du "merge" avec un message généré
   4.754 +       automatiquement. Si aucune "head" n'ont été ajouté, elle met à jour le
   4.755 +       répertoire de travail au niveau de la nouvelle révision tip.</para>
   4.756 +     
   4.757 +     <para id="x_367">Activer l'extension <literal
   4.758 +       role="hg-ext">fetch</literal> est facile. Modifiez votre <filename
   4.759 +       role="special">.hgrc</filename>, et soit allez à la section <literal
   4.760 +       role="rc-extensions">extensions</literal> soit créer une section
   4.761 +       <literal role="rc-extensions">extensions</literal>. Ensuite ajoutez
   4.762 +       une ligne qui consiste simplement en <quote>\Verb+fetch =</quote>.</para>
   4.763 +
   4.764 +     <programlisting>[extensions]
   4.765 +fetch =</programlisting>
   4.766 +
   4.767 +    <para id="x_368">(Normalement, sur la partie droite de
   4.768 +      <quote><literal>=</literal></quote> devrait apparaître le chemin de
   4.769 +      l'extension, mais étant donné que l'extension <literal
   4.770 +      role="hg-ext">fetch</literal> fait partie de la distribution standard,
   4.771 +      Mercurial sait où la trouver.) </para>
   4.772 +
   4.773 +  </sect1>
   4.774 +  
   4.775 +  <sect1>
   4.776 +    <title>Renommer, copier, et fusionner (merge)</title>
   4.777 +
   4.778 +    <para id="x_729">En cours de la vie d'un projet, nous allons souvent 
   4.779 +      vouloir changer la disposition de ses fichiers et de ses répertoires. 
   4.780 +      Ceci peut être aussi simple que de changer le nom d'un seul fichier, 
   4.781 +      et aussi compliqué que de restructurer une hiérarchie entiere de fichier
   4.782 +      au sein du projet.</para>
   4.783 +
   4.784 +    <para id="x_72a">Mercurial permet de faire ce genre de modification de
   4.785 +      manière fluide, à condition de l'informer de ce que nous faisons. Si 
   4.786 +      vous voulez renommenr un ficher, vous devriez utiliser les commande
   4.787 +      <command>hg rename</command><footnote>
   4.788 +        <para id="x_72b">Si vous un utilisateur de Unix, vous serez content
   4.789 +          de savoir que la commande  <command>hg rename</command> command 
   4.790 +          peut être abrégée en <command>hg mv</command>.</para>
   4.791 +      </footnote> pour changer son nom, ainsi Mercurial peut ensuite prendre
   4.792 +      la bonne décision, plus tard, en cas de fusionv (merge).</para>
   4.793 +
   4.794 +    <para id="x_72c">Nous étudierojns en détail l'utilisation de ces commandes, 
   4.795 +      en détail, dans le chapitre <xref linkend="chap:daily.copy"/>.</para>
   4.796 +  </sect1>
   4.797  </chapter>
   4.798  
   4.799  <!--
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/fr/complete.xml	Mon Sep 14 01:31:50 2009 +0200
     5.3 @@ -0,0 +1,16711 @@
     5.4 +<?xml version="1.0"?>
     5.5 +
     5.6 +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
     5.7 + "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
     5.8 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     5.9 +<book id="hg">
    5.10 +  <title>Mercurial: The Definitive Guide</title>
    5.11 +  
    5.12 +  <!-- hg parents &#x2d;&#x2d;template '{node|short} ({date|shortdate})' 
    5.13 +  <subtitle>Compiled from 8a1d3f1aff17 (2009-03-10)</subtitle>
    5.14 +  -->
    5.15 +  <subtitle>Compiled from $rev_id$</subtitle>
    5.16 +  <bookinfo>
    5.17 +    <edition>1</edition>
    5.18 +    <isbn>9780596800673</isbn>
    5.19 +    <authorgroup>
    5.20 +      <author>
    5.21 +        <firstname>Bryan</firstname>
    5.22 +        <surname>O'Sullivan</surname>
    5.23 +      </author>
    5.24 +    </authorgroup>
    5.25 +
    5.26 +    <editor>
    5.27 +      <firstname>Mike</firstname>
    5.28 +      <surname>Loukides</surname>
    5.29 +    </editor>
    5.30 +
    5.31 +    <copyright>
    5.32 +      <year>2006</year>
    5.33 +      <year>2007</year>
    5.34 +      <year>2008</year>
    5.35 +      <year>2009</year>
    5.36 +      <holder>Bryan O'Sullivan</holder>
    5.37 +    </copyright>
    5.38 +  </bookinfo>
    5.39 +
    5.40 +  <!-- BEGIN ch00 -->
    5.41 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    5.42 +
    5.43 +<preface id="chap:preface">
    5.44 +  <?dbhtml filename="preface.html"?>
    5.45 +  <title>Preface</title>
    5.46 +
    5.47 +  <sect1>
    5.48 +    <title>Un conte technique</title>
    5.49 +
    5.50 +    <para id="x_72e">Il y a quelques années, quand j'ai voulu expliqué
    5.51 +    pourquoi je pensais que le gestion de révision distribuée est importante,
    5.52 +    le domaine était encore si nouveau qu'il n'y avait presque aucune 
    5.53 +    littérature publiée pour servir de référence aux personnes intéressées.</para>
    5.54 +
    5.55 +    <para id="x_72f">Bien qu'à cette époque je passais beaucoup de temps
    5.56 +    à travailler sur les entrailles de Mercurial, je me suis mis à la 
    5.57 +    rédaction de ce livre parce qu'il me semblait la manière la plus efficace
    5.58 +    d'aider notre logiciel à atteindre un vaste auditoire, toujours avec 
    5.59 +    l'idée que la gestion de révision devrait être distribuée par nature. J'ai 
    5.60 +    publié ce libre en ligne sous une licence libre pour la même raison : pour 
    5.61 +    diffuser la parole auprès du monde.</para>
    5.62 +
    5.63 +    <para id="x_730">Il y a un rythme familier à un bon livre sur un logiciel 
    5.64 +    qui ressemble de près au fait de conter une histoire : Pourquoi ceci est ? 
    5.65 +    Pourquoi ceci est important ? Comment peut il m'aider ? Comment m'en 
    5.66 +    servir ? Dans ce livre, j'essaye de répondre à toutes ces questions pour
    5.67 +    la gestion de révision distribuée en général, et pour Mercurial en 
    5.68 +    particulier.</para>
    5.69 +  </sect1>
    5.70 +    
    5.71 +  <sect1>
    5.72 +    <title>Merci de votre soutien à Mercurial</title>
    5.73 +
    5.74 +    <para id="x_731">En achetant une copie de ce livre, vous soutenez le
    5.75 +    développement et la liberté de Mercurial en particulier, et dans 
    5.76 +    l'Open Source, au logiciel libre en général. O'Reilly Media et 
    5.77 +    moi-même donnons les revenus issus des ventes de ce livre à la
    5.78 +    Software Freedom Conservancy (<ulink url="http://www.softwarefreedom.org/">http://www.softwarefreedom.org/</ulink>) 
    5.79 +      qui fournit un support juridique à Mercurial et à de 
    5.80 +      nombreux autres projets Open Source proéminents et de qualité.</para>
    5.81 +  </sect1>
    5.82 +
    5.83 +  <sect1>
    5.84 +    <title>Remerciements</title>
    5.85 +
    5.86 +    <para id="x_732">Ce livre n'aurait pas vu le jour sans les
    5.87 +    efforts de Matt Mackal, l'auteur et le chef du projet Mercurial.
    5.88 +    Il est assisté très efficacement par des centaines de contributeurs
    5.89 +    volontaires à travers le monde.</para>
    5.90 +
    5.91 +    <para id="x_733">Les enfants, Cian et Ruairi, ont toujours été prêt
    5.92 +    à m'aider à me reposer avec de merveilleux et impulsif jeux d'enfants. 
    5.93 +    Je tiens aussi à remercier mon ex-femme, Shannon, pour son soutien.
    5.94 +    </para>
    5.95 +
    5.96 +    <para id="x_734">Mes collègues et amis m'ont aidé et assisté de 
    5.97 +    de nombreuses manières. Cette liste de personne est nécessaire mais très
    5.98 +    incomplète : Stephen Hahn, Karyn Ritter, Bonnie Corwin, James Vasile,
    5.99 +    Matt Norwood, Eben Moglen, Bradley Kuhn, Robert Walsh, Jeremy
   5.100 +    Fitzhardinge, Rachel Chalmers.</para>
   5.101 +
   5.102 +    <para id="x_735">J'ai conçu ce livre de manière ouverte, en publiant
   5.103 +    des brouillons des chapitres du livre sur des site web, au fur et à 
   5.104 +    mesure que je les réalisais. Leurs lecteurs m'ont fait des retours 
   5.105 +    utilisant l'application web que j'avais développée. A la fin de sa
   5.106 +    conception, plus de 100 personnes m'avaient fait des commentaires, 
   5.107 +    un chiffre incroyable quand l'on considère que ce système de 
   5.108 +    commentaire n'a tourné que dans les deux derniers mois de la 
   5.109 +    rédaction du livre.</para>
   5.110 +
   5.111 +    <para id="x_736">J'aimerais particulièrement remercier les 
   5.112 +    personnes suivantes, dont les commentaires représentent plus
   5.113 +    d'un tiers de l'ensemble de ces derniers. Je voudrais les 
   5.114 +    remercier pour leur attention et effort à me faire des retours
   5.115 +    très détaillés.</para>
   5.116 +
   5.117 +    <para id="x_737">Martin Geisler, Damien Cassou, Alexey Bakhirkin, Till Plewe,
   5.118 +      Dan Himes, Paul Sargent, Gokberk Hamurcu, Matthijs van der
   5.119 +      Vleuten, Michael Chermside, John Mulligan, Jordi Fita, Jon
   5.120 +      Parise.</para>
   5.121 +
   5.122 +    <para id="x_738">Je souhaite aussi remercier l'aide des personnes
   5.123 +    qui ont découvert des erreurs et fournit des suggestions avisées
   5.124 +    à travers tout le livre.</para>
   5.125 +
   5.126 +    <para id="x_739">Jeremy W. Sherman, Brian Mearns, Vincent Furia, Iwan
   5.127 +      Luijks, Billy Edwards, Andreas Sliwka, Paweł Sołyga, Eric
   5.128 +      Hanchrow, Steve Nicolai, Michał Masłowski, Kevin Fitch, Johan
   5.129 +      Holmberg, Hal Wine, Volker Simonis, Thomas P Jakobsen, Ted
   5.130 +      Stresen-Reuter, Stephen Rasku, Raphael Das Gupta, Ned
   5.131 +      Batchelder, Lou Keeble, Li Linxiao, Kao Cardoso Félix, Joseph
   5.132 +      Wecker, Jon Prescot, Jon Maken, John Yeary, Jason Harris,
   5.133 +      Geoffrey Zheng, Fredrik Jonson, Ed Davies, David Zumbrunnen,
   5.134 +      David Mercer, David Cabana, Ben Karel, Alan Franzoni, Yousry
   5.135 +      Abdallah, Whitney Young, Vinay Sajip, Tom Towle, Tim Ottinger,
   5.136 +      Thomas Schraitle, Tero Saarni, Ted Mielczarek, Svetoslav
   5.137 +      Agafonkin, Shaun Rowland, Rocco Rutte, Polo-Francois Poli,
   5.138 +      Philip Jenvey, Petr Tesałék, Peter R. Annema, Paul Bonser,
   5.139 +      Olivier Scherler, Olivier Fournier, Nick Parker, Nick Fabry,
   5.140 +      Nicholas Guarracino, Mike Driscoll, Mike Coleman, Mietek Bák,
   5.141 +      Michael Maloney, László Nagy, Kent Johnson, Julio Nobrega, Jord
   5.142 +      Fita, Jonathan March, Jonas Nockert, Jim Tittsler, Jeduan
   5.143 +      Cornejo Legorreta, Jan Larres, James Murphy, Henri Wiechers,
   5.144 +      Hagen Möbius, Gábor Farkas, Fabien Engels, Evert Rol, Evan
   5.145 +      Willms, Eduardo Felipe Castegnaro, Dennis Decker Jensen, Deniz
   5.146 +      Dogan, David Smith, Daed Lee, Christine Slotty, Charles Merriam,
   5.147 +      Guillaume Catto, Brian Dorsey, Bob Nystrom, Benoit Boissinot,
   5.148 +      Avi Rosenschein, Andrew Watts, Andrew Donkin, Alexey Rodriguez,
   5.149 +      Ahmed Chaudhary.</para>
   5.150 +  </sect1>
   5.151 +
   5.152 +  <sect1>
   5.153 +    <title>Conventions utilisées dans ce livre</title>
   5.154 +
   5.155 +    <para id="x_73a">Les conventions typographiques suivantes sont utilisées dans ce livre :</para>
   5.156 +
   5.157 +    <variablelist>
   5.158 +      <varlistentry>
   5.159 +        <term>Italique</term>
   5.160 +
   5.161 +        <listitem>
   5.162 +          <para id="x_73b">Indique les termes nouveaux, les URLs, les
   5.163 +            adresses mail, les noms de fichiers et les extensions de
   5.164 +            fichier.</para>
   5.165 +        </listitem>
   5.166 +      </varlistentry>
   5.167 +
   5.168 +      <varlistentry>
   5.169 +        <term><literal moreinfo="none">Taille constante</literal></term>
   5.170 +
   5.171 +        <listitem>
   5.172 +          <para id="x_73c">Utilisé pour les extraits de code, comme 
   5.173 +          dans les paragraphes pour référer aux éléments du programme,
   5.174 +          tels que les variables ou les noms de fonctions, de bases
   5.175 +          de données, de types de données, de variables d'environnement,
   5.176 +          d'instructions, et de mots clés.</para>
   5.177 +        </listitem>
   5.178 +      </varlistentry>
   5.179 +
   5.180 +      <varlistentry>
   5.181 +        <term><userinput moreinfo="none">Taille constante avec gras</userinput></term>
   5.182 +
   5.183 +        <listitem>
   5.184 +          <para id="x_73d">Afficher les commandes ou autres textes qui
   5.185 +          devraient être saisis par l'utilisateur.</para>
   5.186 +        </listitem>
   5.187 +      </varlistentry>
   5.188 +
   5.189 +      <varlistentry>
   5.190 +        <term><replaceable>Constante avec italique</replaceable></term>
   5.191 +
   5.192 +        <listitem>
   5.193 +          <para id="x_73e">Affiche les textes qui devraient être remplacés 
   5.194 +          par une valeur définie par l'utilisateur ou des valeurs définies
   5.195 +          selon le contexte.</para>
   5.196 +        </listitem>
   5.197 +      </varlistentry>
   5.198 +    </variablelist>
   5.199 +
   5.200 +    <tip>
   5.201 +      <para id="x_73f">Cette icône indique une astuce, une suggestion ou 
   5.202 +      une note d'ordre général.</para>
   5.203 +    </tip>
   5.204 +
   5.205 +    <caution>
   5.206 +      <para id="x_740">Cette icône est un message d'alerte ou de prudence.</para>
   5.207 +    </caution>
   5.208 +  </sect1>
   5.209 +
   5.210 +  <sect1>
   5.211 +    <title>Utiliser les exemples de code</title>
   5.212 +
   5.213 +    <para id="x_741">Ce livre est ici pour vous aider dans votre
   5.214 +    travail. De manière générale, vous pouvez donc utiliser le code
   5.215 +    de ce livre dans vos programmes et votre documentation. Vous
   5.216 +    n'avez pas à nous contacter pour nous demander la permission
   5.217 +    de le faire, à moins que vous ne reproduisiez une partie significative
   5.218 +    du code. Par exemple, écrire un programme qui utilise plusieurs 
   5.219 +    extraits de code du livre ne demande aucune autorisation particulière.
   5.220 +    Vendre ou distribuer un CD-ROM provenant des livres O'Reilly demande
   5.221 +    à l'inverse une autorisation. Répondre à une question en citant ce 
   5.222 +    livre ou ses exemples de code ne demande aucune autorisation préalable.
   5.223 +    Intégrer une grande quantité des codes d'exemples de ce livre dans
   5.224 +    votre propre ouvrage demande une autorisation de notre part.</para>
   5.225 +
   5.226 +    <para id="x_742">Nous apprécions, sans l'exiger, que vous citiez 
   5.227 +    l'ouvrage dans vos écrits l'utilisant, en indiquant le titre, 
   5.228 +    l'auteur, l'éditeur et son ISBN. Par exemple: “<emphasis>Titre du 
   5.229 +    livre</emphasis> par Son Auteur. Copyright 2008 O’Reilly Media, Inc.,
   5.230 +    978-0-596-xxxx-x.”</para>
   5.231 +
   5.232 +    <para id="x_743">Si vous estimez que votre usage des exemples de code
   5.233 +    dépasse le cadre défini ci dessus, n'hésitez pas à nous contacter :
   5.234 +      <email>permissions@oreilly.com</email>.</para>
   5.235 +  </sect1>
   5.236 +
   5.237 +  <sect1>
   5.238 +    <title>Safari® Books Online</title>
   5.239 +
   5.240 +    <note role="safarienabled">
   5.241 +      <para id="x_744">Quand vous voyez l'icône de Safari® Books Online 
   5.242 +      sur la couverture d'un de vos livres techniques préférés, cela signifie
   5.243 +      que le livre est disponible, en ligne, à travers le O’Reilly Network Safari
   5.244 +        Bookshelf.</para>
   5.245 +    </note>
   5.246 +
   5.247 +    <para id="x_745">Safari offre une solution qui est meilleure que
   5.248 +    les e-books. C'est une bibliothèque virtuelle qui vous laisse
   5.249 +    aisément rechercher dans des milliers de livres, mais aussi 
   5.250 +    copier-coller leurs exemples, télécharger des chapitres, et 
   5.251 +    trouver des réponses rapides quand vous avez besoin d'une 
   5.252 +    information précise et à jour. Essayez le gratuitement :
   5.253 +    <ulink role="orm:hideurl:ital" url="http://my.safaribooksonline.com/?portal=oreilly">http://my.safaribooksonline.com</ulink>.</para>
   5.254 +  </sect1>
   5.255 +
   5.256 +  <sect1>
   5.257 +    <title>Comment nous contacter</title>
   5.258 +
   5.259 +    <para id="x_746">Merci d'adresser vos commentaires et vos questions
   5.260 +    sur ce livre à son éditeur:</para>
   5.261 +
   5.262 +    <simplelist type="vert">
   5.263 +      <member>O’Reilly Media, Inc.</member>
   5.264 +
   5.265 +      <member>1005 Gravenstein Highway North</member>
   5.266 +
   5.267 +      <member>Sebastopol, CA 95472</member>
   5.268 +
   5.269 +      <member>800-998-9938 (in the United States or Canada)</member>
   5.270 +
   5.271 +      <member>707-829-0515 (international or local)</member>
   5.272 +
   5.273 +      <member>707 829-0104 (fax)</member>
   5.274 +    </simplelist>
   5.275 +
   5.276 +    <para id="x_747">Nous avons une page web pour cet ouvrage, où nous
   5.277 +    publions des errata, des exemples, et encore d'autres informations
   5.278 +    additionnelles. Vous pouvez accéder à cette page par l'URL suivante:
   5.279 +    </para>
   5.280 +
   5.281 +    <simplelist type="vert">
   5.282 +      <member><ulink url="http://www.oreilly.com/catalog/&lt;catalog           page&gt;"/></member>
   5.283 +    </simplelist>
   5.284 +
   5.285 +    <remark>N'oubliez pas de mettre à jour l'attribut &lt;url&gt; aussi.</remark>
   5.286 +
   5.287 +    <para id="x_748">Pour commenter ou poser des questions techniques 
   5.288 +    sur cet ouvrage, envoyez un email à :</para>
   5.289 +
   5.290 +    <simplelist type="vert">
   5.291 +      <member><email>bookquestions@oreilly.com</email></member>
   5.292 +    </simplelist>
   5.293 +
   5.294 +    <para id="x_749">Pour plus d'informations sur nos livres, nos
   5.295 +    conférences, nos centres d'informations, et le réseau O’Reilly, 
   5.296 +    voyez notre site web :</para>
   5.297 +
   5.298 +    <simplelist type="vert">
   5.299 +      <member><ulink url="http://www.oreilly.com"/></member>
   5.300 +    </simplelist>
   5.301 +  </sect1>
   5.302 +</preface>
   5.303 +
   5.304 +<!--
   5.305 +local variables: 
   5.306 +sgml-parent-document: ("00book.xml" "book" "preface")
   5.307 +end:
   5.308 +-->
   5.309 +
   5.310 +  <!-- BEGIN ch01 -->
   5.311 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
   5.312 +
   5.313 +<chapter id="chap:intro">
   5.314 +  <?dbhtml filename="how-did-we-get-here.html"?>
   5.315 +  <title>Comment en est on arrivé là ?</title>
   5.316 +
   5.317 +<sect1>
   5.318 +<title>À propos de la gestion source</title>
   5.319 +
   5.320 +    <para id="x_6d">La gestion de sources est un processus permettant de gérer différentes
   5.321 +versions de la même information. Dans sa forme la plus simple, c'est
   5.322 +ce que tout le monde fait manuellement : quand vous modifiez
   5.323 +un fichier, vous le sauvegardez sous un nouveau nom contenant un numéro,
   5.324 +à chaque fois plus grand que celui de la version précédente.</para>
   5.325 +
   5.326 +    <para id="x_6e">Ce genre de gestion de version manuelle est cependant facilement sujette
   5.327 +aux erreurs, ainsi, depuis longtemps, des logiciels existent pour
   5.328 +résoudre cette problématique. Les premiers outils de gestion de sources
   5.329 +étaient destinés à aider un seul utilisateur, à automatiser la gestion
   5.330 +des versions d'un seul fichier. Dans les dernières décades, cette cible
   5.331 +s'est largement agrandie, ils gèrent désormais de multiples fichiers, et
   5.332 +aident un grand nombre de personnes à travailler ensemble. Les outils les
   5.333 +plus modernes n'ont aucune difficulté à gérer plusieurs milliers de
   5.334 +personnes travaillant ensemble sur des projets regroupant plusieurs
   5.335 +centaines de milliers de fichiers.</para>
   5.336 +
   5.337 +    <para id="x_6f">L'arrivée de la gestion de révision distribuée est
   5.338 +    relativement récente, et, pour le moment, ce nouveau domaine a grandi
   5.339 +    grâce à la volonté des gens d'explorer ces territoires encore inconnus.
   5.340 +    </para>
   5.341 +
   5.342 +    <para id="x_70">J'écris un livre sur la gestion de révision distribuée
   5.343 +    parce que je pense qu'il s'agit d'un sujet important qui mérite un guide
   5.344 +    du terrain. J'ai choisi d'écrire un livre sur Mercurial car il est
   5.345 +    l'outil le plus facile pour découvrir ce nouveau domaine, tout en étant
   5.346 +    un outil efficace qui répond aux demandes d'environnements réels et
   5.347 +    difficiles, là où d'autres outils de gestions de versions s'effondrent.</para>
   5.348 +
   5.349 +    <sect2>
   5.350 +      <title>Pourquoi utiliser un gestionnaire de source ?</title>
   5.351 +
   5.352 +      <para id="x_71">Il y a de nombreuses raisons pour que vous ou votre équipe souhaitiez
   5.353 +utiliser un outil automatisant la gestion de version pour votre projet.</para>
   5.354 +
   5.355 +      <itemizedlist>
   5.356 +	<listitem><para id="x_72">L'outil se chargera de suivre l'évolution de votre projet, sans
   5.357 +que vous ayez à le faire. Pour chaque modification, vous aurez à votre
   5.358 +disposition un journal indiquant <emphasis>qui</emphasis> a fait quoi, <emphasis>pourquoi</emphasis>
   5.359 +il l'a fait, <emphasis>quand</emphasis> il l'a fait, et
   5.360 +<emphasis>ce</emphasis> qu'il a modifié.</para>
   5.361 +</listitem>
   5.362 +<listitem><para id="x_73">Quand vous travaillez avec d'autres personnes, les logiciels de
   5.363 +gestion de source facilitent le travail collaboratif. Par exemple, quand
   5.364 +plusieurs personnes font, plus ou moins simultanément, des modifications
   5.365 +incompatibles, le logiciel vous aidera à identifier et à résoudre les conflits.</para>
   5.366 +</listitem>
   5.367 +<listitem><para id="x_74">L'outil vous aidera à réparer vos erreurs. Si vous effectuez un changement
   5.368 +qui se révèle être une erreur, vous pourrez revenir à une version
   5.369 +antérieure d'un fichier ou même d'un ensemble de fichiers. En fait, un outil de
   5.370 +gestion de source <emphasis>vraiment</emphasis> efficace vous permettra d'identifier à quel
   5.371 +moment le problème est apparu (voir la section <xref linkend="sec:undo:bisect"/> pour plus
   5.372 +de détails).</para>
   5.373 +</listitem>
   5.374 +<listitem><para id="x_75">L'outil vous permettra aussi de travailler sur plusieurs versions différentes
   5.375 +de votre projet et de gérer l'écart entre chacune.</para>
   5.376 +</listitem></itemizedlist>
   5.377 +<para id="x_76">La plupart de ces raisons ont autant d'importances —du
   5.378 +  moins en théorie— que vous travailliez sur un projet pour vous, ou
   5.379 +  avec une centaine d'autres personnes.
   5.380 +</para>
   5.381 +
   5.382 +<para id="x_77">Une question fondamentale à propos des outils de gestion de
   5.383 +  source, qu'il s'agisse du projet d'une personne ou d'une grande équipe, est
   5.384 +  quels sont ses <emphasis>avantages</emphasis> par rapport à ses
   5.385 +  <emphasis>coûts</emphasis>. Un outil qui est difficile à utiliser ou à
   5.386 +  comprendre exigera un lourd effort d'adaptation.
   5.387 +</para>
   5.388 +
   5.389 +<para id="x_78">)Un projet de cinq milles personnes s'effondrera très
   5.390 +  certainement de lui même sans aucun processus et outil de gestion de
   5.391 +  source. Dans ce cas, le coût d'utilisation d'un logiciel de gestion de
   5.392 +  source est dérisoire puisque <emphasis>sans</emphasis>, l'échec est presque
   5.393 +  garanti.
   5.394 +</para>
   5.395 +
   5.396 +<para id="x_79">D'un autre coté, un <quote>rapide hack</quote> d'une personne
   5.397 +  peut sembler un contexte bien pauvre pour utiliser un outil de gestion de
   5.398 +  source, car, bien évidement le coût d'utilisation dépasse le coût total du
   5.399 +  projet. N'est ce pas ?
   5.400 +</para>
   5.401 +
   5.402 +      <para id="x_7a">Mercurial supporte ces <emphasis>deux</emphasis>
   5.403 +        échelles de travail. Vous pouvez apprendre les bases en quelques
   5.404 +        minutes seulement, et, grâce à sa performance, vous pouvez l'utiliser
   5.405 +        avec facilité sur le plus petit des projets. Cette simplicité
   5.406 +        signifie que vous n'avez pas de concept obscurs ou de séquence de
   5.407 +        commandes défiant l'imagination, sans aucune corrélation avec
   5.408 +        <emphasis>ce que vous êtes entrain de faire</emphasis>. En même
   5.409 +        temps, ces mêmes performances et sa nature
   5.410 +        <quote>peer-to-peer</quote> vous permettent d'adapter, sans
   5.411 +        difficulté, son utilisation à de très grands projets.
   5.412 +</para>
   5.413 +
   5.414 +      <para id="x_7b">Aucun outil de gestion de source ne peut sauver un
   5.415 +        projet mal mené, mais un bon outil peut rendre beaucoup plus fluide
   5.416 +        votre travail.
   5.417 +</para>
   5.418 +
   5.419 +    </sect2>
   5.420 +
   5.421 +    <sect2>
   5.422 +      <title>Les multiples noms de la gestion de source</title>
   5.423 +
   5.424 +      <para id="x_7c">La gestion de source
   5.425 +        <!-- TODO:<footnote><J'ai utilisé systématiquement le terme
   5.426 +            <quote>gestion de source</quote> à travers tout l'ouvrage. Ce
   5.427 +            n'est pas forcement la meilleure traduction, et ceci peut rendre
   5.428 +            la lecture un peu lourde, mais je pense que le document y gagne
   5.429 +            en clarté et en précision. -->
   5.430 +        est un domaine tellement large qu'il n'existe pas qu'un seul nom ou
   5.431 +        acronyme pour le désigner. Voici quelques noms ou acronymes que vous
   5.432 +        rencontrerez le plus souvent.
   5.433 +        <!-- TODO:<footnote> J'ai conservé la liste des noms en anglais pour
   5.434 +          des raisons de commodité (ils sont plus <quote>googelable</quote>).
   5.435 +          En outre, j'ai opté  pour conserver l'ensemble des opérations de
   5.436 +          Mercurial (\textit{commit},\textit{push}, \textit{pull},...) en
   5.437 +          anglais, là aussi pour faciliter la lecture d'autres documents en
   5.438 +          anglais, ainsi que l'utilisation de Mercurial. -->
   5.439 +</para>
   5.440 +
   5.441 +<para>:
   5.442 +</para>
   5.443 +
   5.444 +      <itemizedlist>
   5.445 +	<listitem><para id="x_7d">Revision control (RCS)</para></listitem>
   5.446 +	<listitem><para id="x_7e">Software configuration management (SCM), ou
   5.447 +	    configuration management</para></listitem>
   5.448 +	<listitem><para id="x_7f">Source code management</para></listitem>
   5.449 +	<listitem><para id="x_80">Source code control, ou source control</para></listitem>
   5.450 +	<listitem><para id="x_81">Version control (VCS)</para></listitem></itemizedlist>
   5.451 +
   5.452 + <para id="x_82">Certaines personnes prétendent que ces termes ont en fait
   5.453 +   des sens différents mais en pratique ils se recouvrent tellement qu'il n'y
   5.454 +   a pas réellement de manière pertinente de les distinguer. </para>
   5.455 +
   5.456 +    </sect2>
   5.457 +  </sect1>
   5.458 +
   5.459 +  <sect1>
   5.460 +
   5.461 +<title>A propos des exemples dans ce livre</title>
   5.462 +
   5.463 +    <para id="x_84">Ce livre prend une approche non usuel pour les exemples
   5.464 +      de code. Tous les exemples sont en <quote>live</quote> — Chacun
   5.465 +      est actuellement le résultat d'un script shell qui exécute les
   5.466 +      commandes Mercurial que vous voyez. A chaque fois qu'une image du livre
   5.467 +      est construite à partir des sources, tous les scripts d'exemple sont
   5.468 +      lancés automatiquement, et leurs résultats effectifs sont comparés aux
   5.469 +      résultats attendus.</para>
   5.470 +
   5.471 +    <para id="x_85">L'avantage de dette approche est que les exemples sont
   5.472 +      toujours précis ; ils décrivent <emphasis>exactement</emphasis> la
   5.473 +      conduite de la version de Mercurial qui est mentionnée en entête du
   5.474 +      livre. Si je met à jour la version de Mercurial que je suis en train de
   5.475 +      documenter, et que la sortie de certaines commandes change, la
   5.476 +      construction du livre échoue.</para>
   5.477 +
   5.478 +    <para id="x_86">
   5.479 +      Il existe un petit désavantage à cette approche qui est que les dates et
   5.480 +      heures que vous verrez dans les exemples tendent à être
   5.481 +      <quote>écrasés</quote> ensemble, dans le sens où elles ne sont pas
   5.482 +      celles qu'elles auraient été si un humain avait tapé les commandes. En
   5.483 +      effet, humain ne peut pas taper plus d'une commande toutes les quelques
   5.484 +      secondes, avec le temps qui s'écoule, mes scripts d'exemples exécutent
   5.485 +      plusieurs commandes en une seconde.
   5.486 +    </para>
   5.487 +
   5.488 +    <para id="x_87">Une circonstance de ceci est que plusieurs commits
   5.489 +      consécutifs dans un exemple peuvent apparaître comme ayant eu lieu
   5.490 +      durant la même seconde.
   5.491 +      Vous pouvez observer le phénomène dans l'exemple <literal role="hg-ext" moreinfo="none">bisect</literal> dans <xref linkend="sec:undo:bisect"/>
   5.492 +    </para>
   5.493 +
   5.494 +    <para id="x_88">Donc, lorsque vous lisez ces exemples, ne prêtez pas trop
   5.495 +      d'importance aux dates et heures que vous voyez dans la sortie des
   5.496 +      commandes. Cependant, <emphasis>soyez</emphasis> confiants que le
   5.497 +      comportement que vous voyez est consistent et reproductible 
   5.498 +    </para>
   5.499 +
   5.500 +  </sect1>
   5.501 +
   5.502 +<!-- The next section has disapper from this part of the book. it may be splaced somewhere else... t-->
   5.503 +
   5.504 +  <sect1>
   5.505 +    <title>Tendances de la gestion de source</title>
   5.506 +
   5.507 +    <para id="x_89">Il y a eu une tendance évidente dans le développement et
   5.508 +      l'utilisation d'outils de gestion de source depuis les quatre dernières
   5.509 +      décades, au fur et à mesure que les utilisateurs se sont habitués à
   5.510 +      leur outils et se sont sentis contraints par leurs limitations.
   5.511 +    </para>
   5.512 +
   5.513 +    <para id="x_8a">La première génération commença simplement par gérer un
   5.514 +      fichier unique sur un ordinateur individuel. Cependant, même si ces
   5.515 +      outils présentaient une grande avancée par rapport à la gestion
   5.516 +      manuelle des versions, leur modèle de verrouillage et leur utilisation
   5.517 +      limitée à un seul ordinateur rendaient leur utilisation possible
   5.518 +      uniquement dans une très petite équipe.
   5.519 +    </para>
   5.520 +
   5.521 +    <para id="x_8b">La seconde génération a assoupli ces contraintes en
   5.522 +      adoptant une architecture réseau et centralisée, permettant de gérer
   5.523 +      plusieurs projets entiers en même temps. Alors que les projets
   5.524 +      grandirent en taille, ils rencontrèrent de nouveaux problèmes. Avec les
   5.525 +      clients discutant régulièrement avec le serveurs, la montée en charge
   5.526 +      devint un réel problème sur les gros projets. Une connexion réseau peu
   5.527 +      fiable pouvait complètement empêcher les utilisateurs distants de
   5.528 +      dialoguer avec le serveur. Alors que les projets <emphasis remap="it">Open Source</emphasis> commencèrent à mettre en place des
   5.529 +      accès en lecture seule disponible anonymement, les utilisateurs sans
   5.530 +      les privilèges de <quote>commit</quote> réalisèrent qu'ils ne pouvaient
   5.531 +      pas utiliser les outils pour collaborer naturellement avec le projet,
   5.532 +      comme ils ne pouvaient pas non plus enregistrer leurs modifications.
   5.533 +    </para>
   5.534 +
   5.535 +    <para id="x_8c">La génération actuelle des outils de gestion de source
   5.536 +      est <quote>peer-to-peer</quote> par nature. Tous ces systèmes ont
   5.537 +      abandonné la dépendance à un serveur central, et ont permis à leur
   5.538 +      utilisateur de distribuer les données de leur gestion de source à qui
   5.539 +      en a besoin. La collaboration à travers Internet a transformé la
   5.540 +      contrainte technologique en une simple question de choix et de
   5.541 +      consensus. Les outils modernes peuvent maintenant fonctionner en mode
   5.542 +      déconnecté sans limite et de manière autonome, la connexion au réseau
   5.543 +      n'étant nécessaire que pour synchroniser les modifications avec les
   5.544 +      autres dépôts.
   5.545 +    </para>
   5.546 +  </sect1>
   5.547 +    
   5.548 +  <sect1>
   5.549 +    <title>Quelques avantages des gestionnaires de source distribués</title>
   5.550 +      
   5.551 +    <para id="x_8d">Même si les gestionnaire de source distribués sont depuis
   5.552 +      plusieurs années assez robustes et aussi utilisables que leurs
   5.553 +      prédécesseurs, les utilisateurs d'autres outils n'y ont pas encore été
   5.554 +      sensibilisés. Les gestionnaires de source distribués se distinguent
   5.555 +      particulièrement de leurs équivalents centralisés de nombreuses
   5.556 +      manières.
   5.557 +    </para>
   5.558 +
   5.559 +    <para id="x_8e">Pour un développeur individuel, ils restent beaucoup plus
   5.560 +      rapides que les outils centralisés. Cela pour une raison simple : un
   5.561 +      outil centralisé doit toujours dialoguer à travers le réseau pour la
   5.562 +      plupart des opérations, car presque toutes les métadonnées sont
   5.563 +      stockées sur la seule copie du serveur central. Un outil distribué
   5.564 +      stocke toute ses métadonnées localement. À tâche égale, effectuer un
   5.565 +      échange avec le réseau ajoute un délai aux outils centralisés. Ne
   5.566 +      sous-estimez pas la valeur d'un outil rapide : vous allez passer
   5.567 +      beaucoup de temps à interagir avec un logiciel de gestion de source.
   5.568 +    </para>
   5.569 +
   5.570 +    <para id="x_8f">Les outils distribués sont complètement indépendants des
   5.571 +      aléas de votre serveur, d'autant plus qu'ils répliquent les métadonnées
   5.572 +      à beaucoup d'endroits. Si votre serveur central prend feu, vous avez
   5.573 +      intérêt à ce que les médias de sauvegardes soient fiables, et que votre
   5.574 +      dernier <quote>backup</quote> soit récent et fonctionne sans problème.
   5.575 +      Avec un outil distribué, vous avez autant de <quote>backup</quote> que
   5.576 +      de contributeurs.
   5.577 +    </para>
   5.578 +
   5.579 +    <para id="x_90">En outre, la fiabilité de votre réseau affectera beaucoup
   5.580 +      moins les outils distribués. Vous ne pouvez même pas utiliser un outil
   5.581 +      centralisé sans connexion réseau, à l'exception de quelques commandes,
   5.582 +      très limitées. Avec un outil distribué, si votre connexion réseau tombe
   5.583 +      pendant que vous travaillez, vous pouvez ne même pas vous en rendre
   5.584 +      compte. La seule chose que vous ne serez pas capable de faire sera de
   5.585 +      communiquer avec des dépôts distants, opération somme toute assez rare
   5.586 +      en comparaison aux opérations locales. Si vous avez une équipe de
   5.587 +      collaborateurs très dispersée ceci peut être significatif.
   5.588 +    </para>
   5.589 +
   5.590 +    <sect2>
   5.591 +      <title>Avantages pour les projets Open Source</title>
   5.592 +
   5.593 +      <para id="x_91">Si vous prenez goût à un projet <emphasis remap="it">Open Source</emphasis> et que vous décidez de commencer
   5.594 +        à toucher à son code, et que le projet utilise un gestionnaire de
   5.595 +        source distribué, vous êtes immédiatement un "pair" avec les
   5.596 +        personnes formant le <quote>cœur</quote> du projet. S'ils publient
   5.597 +        leurs dépôts, vous pouvez immédiatement copier leurs historiques de
   5.598 +        projet, faire des modifications, enregistrer votre travail en
   5.599 +        utilisant les mêmes outils qu'eux. Par comparaison avec un outil
   5.600 +        centralisé, vous devez utiliser un logiciel en mode <quote>lecture
   5.601 +          seule</quote> à moins que quelqu'un ne vous donne les privilèges de
   5.602 +        <quote>commit</quote> sur le serveur central. Avant ça, vous ne serez
   5.603 +        pas capable d'enregistrer vos modifications, et vos propres
   5.604 +        modifications risqueront de se corrompre chaque fois que vous
   5.605 +        essayerez de mettre à jour à votre espace de travail avec le serveur
   5.606 +        central.
   5.607 +      </para>
   5.608 +
   5.609 +    <sect3>
   5.610 +      <title>Le non-problème du "fork"</title>
   5.611 +      
   5.612 +      <para id="x_92">Il a été souvent suggéré que les gestionnaires de
   5.613 +        source distribués posent un risque pour les projets <emphasis remap="it">Open Source</emphasis> car ils facilitent grandement la
   5.614 +        création de <quote>fork</quote>.
   5.615 +        <!--footnote{NdT:Création d'une <ulink url="version alternative du
   5.616 +          logiciel">version alternative du
   5.617 +          logiciel</ulink>{http://fr.wikipedia.org/wiki/Fork#Embranchement_d.27un_projet_informatique}
   5.618 +        -->
   5.619 +        Un <quote>fork</quote> apparait quand il y des divergences d'opinion
   5.620 +        ou d'attitude au sein d'un groupe de développeurs qui aboutissent à
   5.621 +        la décision de ne plus travailler ensemble. Chaque parti s'empare
   5.622 +        d'une copie plus ou moins complète du code source du projet et
   5.623 +        continue dans sa propre direction.
   5.624 +      </para>
   5.625 +
   5.626 +
   5.627 +      <para id="x_93">Parfois ces différents partis décident de se
   5.628 +        réconcilier. Avec un serveur central, l'aspect
   5.629 +        <emphasis>technique</emphasis> de cette réconciliation est un
   5.630 +        processus douloureux, et essentiellement manuel. Vous devez décider
   5.631 +        quelle modification est <quote>la gagnante</quote>, et replacer, par
   5.632 +        un moyen ou un autre, les modifications de l'autre équipe dans
   5.633 +        l'arborescence du projet. Ceci implique généralement la perte d'une
   5.634 +        partie de l'historique d'un des partis, ou même des deux.
   5.635 +      </para>
   5.636 +    
   5.637 +      <para id="x_94">Ce que les outils distribués permettent à ce sujet est
   5.638 +        probablement la <emphasis>meilleure</emphasis> façon de développer un
   5.639 +        projet. Chaque modification que vous effectuez est potentiellement un
   5.640 +        <quote>fork</quote>. La grande force de cette approche est que les
   5.641 +        gestionnaires de source distribués doivent être vraiment très
   5.642 +        efficaces pour <emphasis>fusionner (merge)</emphasis>
   5.643 +        <!-- TODO footnote{NdT:j'ai choisi de traduire ici <emphasis
   5.644 +          remap="it">merging</emphasis> par <quote>fusionner</quote> pour des
   5.645 +        raisons de clarté} -->
   5.646 +        des <quote>forks</quote>, car les <quote>forks</quote>, dans ce
   5.647 +        contexte, arrivent tout le temps.
   5.648 +      </para>
   5.649 +      
   5.650 +      <para id="x_95">Si chaque altération que n'importe qui effectue, à tout
   5.651 +        moment, est vue comme un <quote>fork</quote> à fusionner, alors ce
   5.652 +        que le monde de l'<emphasis remap="it">Open Source</emphasis> voit
   5.653 +        comme un <quote>fork</quote> devient <emphasis>uniquement</emphasis>
   5.654 +        une problématique sociale. En fait, les outils de gestions de source
   5.655 +        distribués <emphasis>réduisent</emphasis> les chances de
   5.656 +        <quote>fork</quote> :
   5.657 +      </para>
   5.658 +        
   5.659 +      <itemizedlist>
   5.660 +        <listitem>
   5.661 +        <para>Ils éliminent la distinction sociale qu'imposent les outils
   5.662 +          centralisés entre les membres du projets (ceux qui ont accès au
   5.663 +          <quote>commit</quote>) et ceux de l'extérieur (ce qui ne l'ont
   5.664 +          pas).
   5.665 +        </para>
   5.666 +        <para>Ils rendent plus facile la réconciliation après un
   5.667 +          <quote>fork</quote> social, car tout ce qu'elle implique est une
   5.668 +          simple fusion.
   5.669 +        </para>
   5.670 +        </listitem>
   5.671 +      </itemizedlist>
   5.672 +
   5.673 +      <para id="x_98">Certaines personnes font de la résistance envers les
   5.674 +        gestionnaires de source distribués parce qu'ils veulent garder un
   5.675 +        contrôle ferme sur leur projet, et ils pensent que les outils
   5.676 +        centralisés leur fournissent ce contrôle. Néanmoins, si c'est votre
   5.677 +        cas, sachez que si vous publiez votre dépôt CVS ou Subversion de
   5.678 +        manière publique, il existe une quantité d'outils disponibles pour
   5.679 +        récupérer entièrement votre projet et son historique (quoique
   5.680 +        lentement) et le récréer ailleurs, sans votre contrôle. En fait,
   5.681 +        votre contrôle sur votre projet est illusoire, vous ne faites
   5.682 +        qu'interdire à vos collaborateurs de travailler de manière fluide, en
   5.683 +        disposant d'un miroir ou d'un <quote>fork</quote> de votre
   5.684 +        historique.
   5.685 +      </para>
   5.686 +
   5.687 +    </sect3>
   5.688 +    </sect2>
   5.689 +    <sect2>
   5.690 +      <title>Avantages pour les projets commerciaux</title>
   5.691 +
   5.692 +      <para id="x_99">Beaucoup de projets commerciaux sont réalisés par des
   5.693 +        équipes éparpillées à travers le globe. Les contributeurs qui sont
   5.694 +        loin du serveur central devront subir des commandes lentes et même
   5.695 +        parfois peu fiables. Les solutions propriétaires de gestion de source
   5.696 +        tentent de palier ce problème avec des réplications de sites distants
   5.697 +        qui sont à la fois coûteuses à mettre en place et lourdes à
   5.698 +        administrer. Un système distribué ne souffre pas de ce genre de
   5.699 +        problèmes. En outre, il est très aisé de mettre en place plusieurs
   5.700 +        serveurs de références, disons un par site, de manière à ce qu'il n'y
   5.701 +        ait pas de communication redondante entre les dépôts, sur une
   5.702 +        connexion longue distance souvent onéreuse.
   5.703 +      </para>
   5.704 +
   5.705 +      <para id="x_9a">Les systèmes de gestion de source supportent
   5.706 +        généralement assez mal la monté en charge. Il n'est pas rare pour un
   5.707 +        gestionnaire de source centralisé pourtant onéreux de s'effondrer
   5.708 +        sous la charge combinée d'une douzaine d'utilisateurs concurrents
   5.709 +        seulement. Une fois encore, la réponse à cette problématique est
   5.710 +        généralement encore la mise en place d'un ensemble complexe de
   5.711 +        serveurs synchronisés par un mécanisme de réplication. Dans le cas
   5.712 +        d'un gestionnaire de source distribué, la charge du serveur central
   5.713 +        — si vous avez un— est plusieurs fois inférieure (car
   5.714 +        toutes les données sont déjà répliquées ailleurs), un simple serveur,
   5.715 +        pas très cher, peut gérer les besoins d'une plus grande équipe, et la
   5.716 +        réplication pour balancer la charge devient le travail d'un simple
   5.717 +        script.
   5.718 +      </para>
   5.719 +
   5.720 +      <para id="x_9b">Si vous avez des employés sur le terrain, en train de
   5.721 +        chercher à résoudre un souci sur le site d'un client, ils
   5.722 +        bénéficieront aussi d'un gestionnaire de source distribué. Cet outil
   5.723 +        leur permettra de générer des versions personnalisées, d'essayer
   5.724 +        différentes solutions, en les isolant aisément les unes des autres,
   5.725 +        et de rechercher efficacement à travers l'historique des sources, la
   5.726 +        cause des bugs ou des régressions, tout ceci sans avoir besoin de la
   5.727 +        moindre connexion au réseau de votre compagnie.
   5.728 +      </para>
   5.729 +
   5.730 +    </sect2>
   5.731 +    </sect1>
   5.732 +    <sect1>
   5.733 +      <title>Pourquoi choisir Mercurial?</title>
   5.734 +
   5.735 +      <para id="x_9c">Mercurial a plusieurs caractéristiques qui en font un
   5.736 +        choix particulièrement pertinent pour la gestion de source :
   5.737 +      </para>
   5.738 +    <itemizedlist>
   5.739 +      <listitem><para id="x_9d">Il est simple à apprendre et à utiliser.</para></listitem>
   5.740 +      <listitem><para id="x_9e">Il est léger.</para></listitem>
   5.741 +      <listitem><para id="x_9f">Il s'adapte très bien à la charge.</para></listitem>
   5.742 +      <listitem><para id="x_a0">Il se personnalise facilement.</para></listitem>
   5.743 +    </itemizedlist>
   5.744 +
   5.745 +    <para id="x_a1">Si vous êtes déjà familier d'un outil de gestion de
   5.746 +      source, vous serez capable de l'utiliser en moins de 5 minutes. Sinon,
   5.747 +      ça ne sera pas beaucoup plus long. Les commandes utilisées par
   5.748 +      Mercurial, comme ses fonctionnalités, sont généralement uniformes et
   5.749 +      cohérentes, et vous pouvez ainsi garder en tête simplement quelques
   5.750 +      règles générales, plutôt qu'un lot complexe d'exceptions.
   5.751 +    </para>
   5.752 +
   5.753 +    <para id="x_a2">Sur un petit projet, vous pouvez commencer à travailler
   5.754 +      avec Mercurial en quelques instants. Ajouter des modifications ou des
   5.755 +      branches, transférer ces modifications (localement ou via le réseau),
   5.756 +      et les opérations d'historique ou de statut sont aussi très rapides.
   5.757 +      Mercurial reste hors de votre chemin grâce à sa simplicité
   5.758 +      d'utilisation et sa rapidité d'exécution.
   5.759 +    </para>
   5.760 +
   5.761 +    <para id="x_a3">L'utilité de Mercurial ne se limite pas à de petits
   5.762 +      projets: il est aussi utilisé par des projets ayant des centaines ou
   5.763 +      même des milliers de contributeurs, avec plusieurs dizaines de milliers
   5.764 +      de fichiers, et des centaines de méga octets de code source.
   5.765 +    </para>
   5.766 +
   5.767 +    <para id="x_a4">Si les fonctionnalités au cœur de Mercurial ne sont pas
   5.768 +      suffisantes pour vous, il est très aisé d'en construire d'autres.
   5.769 +      Mercurial est adapté à l'utilisation de scripts, et son implémentation
   5.770 +      interne en Python, propre et claire, rend encore plus facile l'ajout de
   5.771 +      fonctionnalités sous forme d'extensions. Il en existe déjà un certain
   5.772 +      nombre de très populaires et très utiles, dont le périmètre va de la
   5.773 +      recherche de bugs à l'amélioration des performances.
   5.774 +    </para>
   5.775 +
   5.776 +  </sect1>
   5.777 +  <sect1>
   5.778 +    <title>Mercurial comparé aux autres outils</title>
   5.779 +
   5.780 +    <para id="x_a5">Avant que vous n'alliez plus loin, comprenez bien que
   5.781 +      cette section reflète mes propres expériences, et elle est donc (j'ose
   5.782 +      le dire) peu objective. Néanmoins, j'ai utilisé les outils de gestion
   5.783 +      de source listés ci dessous, dans la plupart des cas, pendant plusieurs
   5.784 +      années.
   5.785 +    </para>
   5.786 +
   5.787 +    <sect2>
   5.788 +      <title>Subversion</title>
   5.789 +
   5.790 +      <para id="x_a6">Subversion est un des outils de gestion de source les
   5.791 +        plus populaire, il fût développé pour remplacer CVS. Il a une
   5.792 +        architecture client/server centralisée.
   5.793 +      </para>
   5.794 +
   5.795 +      <para id="x_a7">Subversion et Mercurial ont des noms de commandes très
   5.796 +        similaires pour les mêmes opérations, ainsi si vous êtes familier
   5.797 +        avec l'un, c'est facile d'apprendre l'autre. Ces deux outils sont
   5.798 +        portables sur les systèmes d'exploitation les plus populaires.
   5.799 +      </para>
   5.800 +
   5.801 +      <para id="x_a8">Avant la version 1.5, Subversion n'offrait aucune forme
   5.802 +        de support pour les fusions. Lors de l'écriture de ce livre, ses
   5.803 +        capacités de fusion étaient nouvelles, et réputées pour être <ulink url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">
   5.804 +          complexes et buguées</ulink>.
   5.805 +      </para>
   5.806 +
   5.807 +      <para id="x_a9">Mercurial dispose d'un avantage substantiel en terme de
   5.808 +        performance par rapport à Subversion sur la plupart des opérations
   5.809 +        que j'ai pu tester. J'ai mesuré une différence de performance allant
   5.810 +        de deux à six fois plus rapide avec le système de stockage de fichier
   5.811 +        local de Subversion 1.4.3 (<emphasis>ra_local</emphasis>), qui est la
   5.812 +        méthode d'accès la plus rapide disponible. Dans un déploiement plus
   5.813 +        réaliste, impliquant un stockage réseau, Subversion serait encore
   5.814 +        plus désavantagé. Parce que la plupart des commandes Subversion
   5.815 +        doivent communiquer avec le serveur et que Subversion n'a pas de
   5.816 +        mécanisme de réplication, la capacité du serveur et la bande passante
   5.817 +        sont devenues des goulots d'étranglement pour les projets de taille
   5.818 +        moyenne ou grande.
   5.819 +      </para>
   5.820 +
   5.821 +      <para id="x_aa">En outre, Subversion implique une surcharge
   5.822 +        substantielle dans le stockage local de certaines données, pour
   5.823 +        éviter des transactions avec le serveur, pour certaines opérations
   5.824 +        communes, telles que la recherche des fichiers modifiés
   5.825 +        (<literal moreinfo="none">status</literal>) et l'affichage des modifications par
   5.826 +        rapport à la révision courante (<literal moreinfo="none">diff</literal>). En
   5.827 +        conséquence, un répertoire de travail Subversion a souvent la même
   5.828 +        taille, ou est plus grand, qu'un dépôt Mercurial et son espace de
   5.829 +        travail, et ceci bien que le dépôt Mercurial contienne l'intégralité
   5.830 +        de l'historique.
   5.831 +      </para>
   5.832 +
   5.833 +      <para id="x_ab">Subversion est largement supporté par les outils
   5.834 +        tierces. Mercurial est actuellement encore en retrait de ce point de
   5.835 +        vue. L'écart se réduit néanmoins, en effet, certains des outils
   5.836 +        graphiques sont maintenant supérieurs à leurs équivalents Subversion.
   5.837 +        Comme Mercurial, Subversion dispose d'un excellent manuel
   5.838 +        utilisateur.
   5.839 +      </para>
   5.840 +
   5.841 +      <para id="x_ac">Parce que Subversion ne stocke pas l'historique chez
   5.842 +        ses clients, il est parfaitement adapté à la gestion de projets qui
   5.843 +        doivent suivre un ensemble de larges fichiers binaires et opaques. Si
   5.844 +        vous suivez une cinquantaine de versions d'un fichier incompressible
   5.845 +        de 10MB, l'occupation disque coté client d'un projet sous Subversion
   5.846 +        restera à peu près constante. A l'inverse, l'occupation disque du
   5.847 +        même projet sous n'importe lequel des gestionnaires de source
   5.848 +        distribués grandira rapidement, proportionnellement aux nombres de
   5.849 +        versions, car les différences entre chaque révisions seront très
   5.850 +        grandes.
   5.851 +      </para>
   5.852 +
   5.853 +      <para id="x_ad">En outre, c'est souvent difficile ou, généralement,
   5.854 +        impossible de fusionner des différences dans un fichier binaire. La
   5.855 +        capacité de Subversion de verrouiller des fichiers, pour permettre à
   5.856 +        l'utilisateur d'être le seul à le mettre à jour
   5.857 +        (<quote>commit</quote>) temporairement, est un avantage significatif
   5.858 +        dans un projet doté de beaucoup de fichiers binaires.
   5.859 +      </para>
   5.860 +
   5.861 +      <para id="x_ae">Mercurial peut importer l'historique depuis un dépôt
   5.862 +        Subversion. Il peut aussi exporter l'ensemble des révisions d'un
   5.863 +        projet vers un dépôt Subversion. Ceci rend très facile de
   5.864 +        <quote>prendre la température</quote> et d'utiliser Mercurial et
   5.865 +        Subversion en parallèle, avant de décider de migrer vers Mercurial.
   5.866 +        La conversion de l'historique est incrémentale, donc vous pouvez
   5.867 +        effectuer une conversion initiale, puis de petites additions par la
   5.868 +        suite pour ajouter les nouvelle modifications.
   5.869 +      </para>
   5.870 +
   5.871 +
   5.872 +    </sect2>
   5.873 +    <sect2>
   5.874 +      <title>Git</title>
   5.875 +
   5.876 +      <para id="x_af">Git est un outil de gestion de source distribué qui fût
   5.877 +        développé pour gérer le code source de noyau de Linux. Comme
   5.878 +        Mercurial, sa conception initiale a été inspirée par Monotone.
   5.879 +      </para>
   5.880 +
   5.881 +      <para id="x_b0">Git dispose d'un ensemble conséquent de commandes, avec
   5.882 +        plus de 139 commandes individuelles pour la version 1.5.0. Il a aussi
   5.883 +        la réputation d'être difficile à apprendre. Comparé à Git, le point
   5.884 +        fort de Mercurial est clairement sa simplicité.
   5.885 +      </para>
   5.886 +
   5.887 +      <para id="x_b1">En terme de performance, Git est extrêmement rapide.
   5.888 +        Dans la plupart des cas, il est plus rapide que Mercurial, tout du
   5.889 +        moins sur Linux, alors que Mercurial peut être plus performant sur
   5.890 +        d'autres opérations. Néanmoins, sur Windows, les performances et le
   5.891 +        niveau de support général fourni par Git, au moment de l'écriture de
   5.892 +        cet ouvrage, est bien derrière celui de Mercurial.
   5.893 +      </para>
   5.894 +
   5.895 +      <para id="x_b2">Alors que le dépôt Mercurial ne demande aucune
   5.896 +        maintenance, un dépôt Git exige d'exécuter manuellement et
   5.897 +        régulièrement la commande <quote>repacks</quote> sur ses métadonnées.
   5.898 +        Sans ceci, les performances de git se dégradent et la consommation de
   5.899 +        l'espace disque augmente rapidement. Un serveur qui contient
   5.900 +        plusieurs dépôts Git qui ne sont pas régulièrement et fréquemment
   5.901 +        <quote>repacked</quote> deviendra un vrai problème lors des
   5.902 +        <quote>backups</quote> du disque, et il y eu des cas, où un
   5.903 +        <quote>backup</quote> journalier pouvait durer plus de 24 heures. Un
   5.904 +        dépôt fraichement <quote>repacked</quote> sera légèrement plus petit
   5.905 +        qu'un dépôt Mercurial, mais un dépôt non <quote>repacked</quote> est
   5.906 +        beaucoup plus grand.
   5.907 +      </para>
   5.908 +
   5.909 +      <para id="x_b3">Le cœur de Git est écrit en C. La plupart des commandes
   5.910 +        Git sont implémentées sous forme de scripts Shell ou Perl, et la
   5.911 +        qualité de ces scripts varie grandement. J'ai plusieurs fois constaté
   5.912 +        que certains de ces scripts étaient chargés en mémoire aveuglément et
   5.913 +        que la présence d'erreurs pouvait s'avérer fatal.
   5.914 +      </para>
   5.915 +
   5.916 +      <para id="x_b4">Mercurial peut importer l'historique d'un dépôt Git.</para>
   5.917 +
   5.918 +    </sect2>
   5.919 +    <sect2>
   5.920 +      <title>CVS</title>
   5.921 +
   5.922 +      <para id="x_b5">CVS est probablement l'outil de gestion de source le
   5.923 +        plus utilisé aujourd'hui dans le monde. À cause de son manque de
   5.924 +        clarté interne, il n'est plus maintenu depuis plusieurs années.
   5.925 +      </para>
   5.926 +
   5.927 +      <para id="x_b6">Il a une architecture client/serveur centralisée. Il ne
   5.928 +        regroupe pas les modifications de fichiers dans une opération de
   5.929 +        <quote>commit</quote> atomique, ce qui permet à ses utilisateurs de
   5.930 +        <quote>casser le <emphasis>build</emphasis></quote> assez facilement
   5.931 +        : une personne peut effectuer une opération de <quote>commit</quote>
   5.932 +        sans problème puis être bloquée par besoin de fusion, avec comme
   5.933 +        conséquence néfaste, que les autres utilisateurs ne récupèreront
   5.934 +        qu'une partie de ses modifications. Ce problème affecte aussi la
   5.935 +        manière de travailler avec l'historique du projet. Si vous voulez
   5.936 +        voir toutes les modifications d'une personne du projet, vous devrez
   5.937 +        injecter manuellement les descriptions et les <emphasis remap="it">timestamps</emphasis> des modifications de chacun des
   5.938 +        fichiers impliqués (si vous savez au moins quels sont ces fichiers).
   5.939 +      </para>
   5.940 +
   5.941 +      <para id="x_b7">CVS a une notion étrange des <emphasis remap="it">tags</emphasis> et des branches que je n'essayerai même
   5.942 +        pas de décrire ici. Il ne supporte pas bien les opérations de
   5.943 +        renommage d'un fichier ou d'un répertoire, ce qui facilite la
   5.944 +        corruption de son dépôt. Il n'a presque pas pour ainsi dire de
   5.945 +        contrôle de cohérence interne, il est donc pratiquement impossible de
   5.946 +        dire si un dépôt est corrompu ni à quel point. Je ne recommanderai
   5.947 +        pas CVS pour un projet existant ou nouveau.
   5.948 +      </para>
   5.949 +
   5.950 +      <para id="x_b8">Mercurial peut importer l'historique d'un projet CVS.
   5.951 +        Néanmoins, il y a quelques principes à respecter; ce qui est vrai
   5.952 +        aussi pour les autres outils d'import de projet CVS. À cause de
   5.953 +        l'absence de <quote>commit</quote> atomique et gestion de version de
   5.954 +        l'arborescence, il n'est pas possible de reconstruire de manière
   5.955 +        précise l'ensemble de l'historique. Un travail de
   5.956 +        <quote>devinette</quote> est donc nécessaire, et les fichiers
   5.957 +        renommés ne sont pas détectés. Parce qu'une bonne part de
   5.958 +        l'administration d'un dépôt CVS est effectuée manuellement, et est
   5.959 +        donc, sujette à erreur, il est courant que les imports CVS
   5.960 +        rencontrent de nombreux problèmes avec les dépôt corrompus (des
   5.961 +        <emphasis remap="it">timestamps</emphasis> de révision complètement
   5.962 +        buggés et des fichiers verrouillés depuis des années sont deux des
   5.963 +        problèmes les moins intéressants dont je me souvienne).
   5.964 +      </para>
   5.965 +
   5.966 +      <para id="x_b9">Mercurial peut importer l'historique depuis un dépôt CVS.
   5.967 +      </para>
   5.968 +
   5.969 +
   5.970 +    </sect2>
   5.971 +    <sect2>
   5.972 +      <title>Outils propriétaires</title>
   5.973 +
   5.974 +      <para id="x_ba">Perforce a une architecture client/serveur centralisée,
   5.975 +        sans aucun mécanisme de mise en cache de données coté client.
   5.976 +        Contrairement à la plupart des outils modernes de gestion de source,
   5.977 +        Perforce exige de ses utilisateurs d'exécuter une commande pour
   5.978 +        informer le serveur central de tout fichier qu'ils souhaitent
   5.979 +        modifier.
   5.980 +      </para>
   5.981 +
   5.982 +      <para id="x_bb">Les performances de Perforce sont plutôt bonnes pour
   5.983 +        des petites équipes, mais elles s'effondrent rapidement lorsque le
   5.984 +        nombre d'utilisateurs augmente au delà de la douzaine. Des
   5.985 +        installations de Perforce assez larges nécessitent le déploiement de
   5.986 +        proxies pour supporter la montée en charge associée.
   5.987 +      </para>
   5.988 +
   5.989 +    </sect2>
   5.990 +    <sect2>
   5.991 +      <title>Choisir un outil de gestion de source</title>
   5.992 +
   5.993 +      <para id="x_bc">A l'exception de CVS, tous les outils listés ci-dessus
   5.994 +        ont des forces qui leur sont propres et qui correspondent à certaines
   5.995 +        formes de projet. Il n'y a pas un seul meilleur outil de gestion de
   5.996 +        source qui correspondrait le mieux à toutes les situations.
   5.997 +      </para>
   5.998 +
   5.999 +      <para id="x_bd">En guise exemple, Subversion est un très bon choix
  5.1000 +        lorsqu'on travaille avec beaucoup de fichiers binaires, qui évoluent
  5.1001 +        régulièrement, grâce à sa nature centralisée et sa capacité à
  5.1002 +        verrouiller des fichiers.
  5.1003 +      </para>
  5.1004 +
  5.1005 +      <para id="x_be">Personnellement, je préfère Mercurial pour sa
  5.1006 +        simplicité, ses performances et sa bonne capacité de fusion, et il
  5.1007 +        m'a très bien rendu service de plusieurs années maintenant.
  5.1008 +      </para>
  5.1009 +
  5.1010 +    </sect2>
  5.1011 +  </sect1>
  5.1012 +  <sect1>
  5.1013 +    <title>Migrer depuis un outil à Mercurial</title>
  5.1014 +
  5.1015 +    <para id="x_bf">Mercurial est livré avec une extension nommée <literal role="hg-ext" moreinfo="none">convert</literal>, qui peut, de manière incrémentale
  5.1016 +      importer des révisions depuis différents autres outils de gestion de
  5.1017 +      source. Par <quote>incrémental</quote>, j'entends que vous pouvez
  5.1018 +      convertir l'historique entier du projet en une seule fois, puis
  5.1019 +      relancer l'outil d'import plus tard pour obtenir les modifications
  5.1020 +      effectuées depuis votre import initial.
  5.1021 +    </para>
  5.1022 +
  5.1023 +    <para id="x_c0">Les outils de gestion de source supportés par <literal role="hg-ext" moreinfo="none">convert</literal> sont :
  5.1024 +    </para>
  5.1025 +    <itemizedlist>
  5.1026 +      <listitem><para id="x_c1">Subversion</para></listitem>
  5.1027 +      <listitem><para id="x_c2">CVS</para></listitem>
  5.1028 +      <listitem><para id="x_c3">Git</para></listitem>
  5.1029 +      <listitem><para id="x_c4">Darcs</para></listitem>
  5.1030 +    </itemizedlist>
  5.1031 +
  5.1032 +    <para id="x_c5">En outre, <literal role="hg-ext" moreinfo="none">convert</literal> peut
  5.1033 +      exporter les modifications depuis Mercurial vers Subversion. Ceci rend
  5.1034 +      possible d'essayer Subversion en parallèle avant de choisir une
  5.1035 +      solution définitive, sans aucun risque de perte de données.
  5.1036 +    </para>
  5.1037 +
  5.1038 +    <para id="x_c6">La commande <command role="hg-ext-conver" moreinfo="none">convert</command> est très simple à utiliser.
  5.1039 +      Simplement, indiquez le chemin ou l'URL du dépôt de source, en lui
  5.1040 +      indiquant éventuellement le nom du chemin de destination, et la
  5.1041 +      conversion se met en route. Après cet import initial, il suffit de
  5.1042 +      relancer la commande encore une fois pour importer les modifications
  5.1043 +      effectuées depuis.
  5.1044 +    </para>
  5.1045 +  </sect1>
  5.1046 +
  5.1047 +  <sect1>
  5.1048 +    <title>Une courte histoire de la gestion de source</title>
  5.1049 +
  5.1050 +    <para id="x_c7">Le plus célèbre des anciens outils de gestion de source
  5.1051 +      est <emphasis remap="it">SCCS</emphasis> (Source Code Control System)},
  5.1052 +      que Marc Rochkind conçu dans les laboratoires de recherche de Bell
  5.1053 +      (<emphasis remap="it">Bell Labs</emphasis>), dans le début des années
  5.1054 +      70. <emphasis remap="it">SCCS</emphasis> ne fonctionnait que sur des
  5.1055 +      fichiers individuels, et obligeait chaque personne travaillant sur le
  5.1056 +      projet d'avoir un accès à un répertoire de travail commun, sur le même
  5.1057 +      système. Seulement une seule personne pouvait modifier un fichier au
  5.1058 +      même moment, ce fonctionnement était assuré par l'utilisation de verrou
  5.1059 +      (<quote>lock</quote>). Il était courant que des personnes verrouillent
  5.1060 +      des fichiers, et plus tard, oublient de le déverrouiller ; empêchant
  5.1061 +      n'importe qui d'autre de travailler sur ces fichiers sans l'aide de
  5.1062 +      l'administrateur...
  5.1063 +    </para>
  5.1064 +
  5.1065 +    <para id="x_c8">Walter Tichy a développé une alternative libre à
  5.1066 +      <emphasis remap="it">SCCS</emphasis> au début des années 80, qu'il
  5.1067 +      nomma <emphasis remap="it">RCS (Revision Control System)</emphasis>.
  5.1068 +      Comme <emphasis remap="it">SCCS</emphasis>, <emphasis remap="it">RCS</emphasis> demandait aux développeurs de travailler
  5.1069 +      sur le même répertoire partagé, et de verrouiller les fichiers pour se
  5.1070 +      prémunir de tout conflit issu de modifications concurrentes.
  5.1071 +    </para>
  5.1072 +
  5.1073 +    <para id="x_c9">Un peu plus tard dans les années 1980, Dick Grune utilisa
  5.1074 +      <emphasis remap="it">RCS</emphasis> comme une brique de base pour un
  5.1075 +      ensemble de scripts <emphasis remap="it">shell</emphasis> qu'il
  5.1076 +      intitula cmt, avant de la renommer en <emphasis remap="it">CVS
  5.1077 +        (Concurrent Versions System)</emphasis>.  La grande innovation de CVS
  5.1078 +      était que les développeurs pouvaient travailler simultanément et
  5.1079 +      indépendamment dans leur propre espace de travail. Ces espaces de
  5.1080 +      travail privés assuraient que les développeurs ne se marchent pas
  5.1081 +      mutuellement sur les pieds, comme c'était souvent le cas avec RCS et
  5.1082 +      SCCS. Tous les développeurs disposaient donc de leur copie de tous les
  5.1083 +      fichiers du projet, et ils pouvaient donc librement les modifier. Ils
  5.1084 +      devaient néanmoins effectuer la <quote>fusion</quote> (<emphasis remap="it"><quote>merge</quote></emphasis>) de leurs fichiers, avant
  5.1085 +      d'effectuer le <quote>commit</quote> de leurs modifications sur le dépôt
  5.1086 +      central.
  5.1087 +    </para>
  5.1088 +    
  5.1089 +    <para>Brian Berliner reprit les scripts de Grune's et les réécrit en C,
  5.1090 +      qu'il publia en 1989. Depuis, ce code a été modifié jusqu'à devenir la
  5.1091 +      version moderne de CVS. CVS a acquis ainsi la capacité de fonctionner
  5.1092 +      en réseau, transformant son architecture en client/serveur.
  5.1093 +      L'architecture de CVS est centralisée, seul le serveur a une copie de
  5.1094 +      l'historique du projet. L'espace de travail client ne contient qu'une
  5.1095 +      copie de la dernière version du projet, et quelques métadonnées pour
  5.1096 +      indiquer où le serveur se trouve. CVS a été un grand succès,
  5.1097 +      aujourd'hui il est probablement l'outil de gestion de contrôle le plus
  5.1098 +      utilisé au monde.
  5.1099 +    </para>
  5.1100 +    
  5.1101 +    <para>Au début des années 1990, Sun Microsystems développa un premier
  5.1102 +      outil de gestion de source distribué, nommé TeamWare. Un espace de
  5.1103 +      travail TeamWare contient une copie complète de l'historique du projet.
  5.1104 +      TeamWare n'a pas de notion de dépôt central. (CVS utilisait RCS pour le
  5.1105 +      stockage de l'historique, TeamWare utilisait SCCS).
  5.1106 +    </para>
  5.1107 +    
  5.1108 +    <para>Alors que les années 1990 avançaient, les utilisateurs ont pris
  5.1109 +      conscience d'un certain nombre de problèmes avec CVS. Il enregistrait
  5.1110 +      simultanément des modifications sur différents fichiers
  5.1111 +      individuellement, au lieu de les regrouper dans une seule opération
  5.1112 +      cohérente et atomique. Il ne gère pas bien sa hiérarchie de fichier, il
  5.1113 +      est donc assez aisé de créer le chaos en renommant les fichiers et les
  5.1114 +      répertoires. Pire encore, son code source est difficile à lire et à
  5.1115 +      maintenir, ce qui agrandit largement le <quote>niveau de
  5.1116 +        souffrance</quote> associé à la réparation de ces problèmes
  5.1117 +      d'architecture de manière prohibitive.
  5.1118 +    </para>
  5.1119 +    
  5.1120 +    <para>En 2001, Jim Blandy et Karl Fogel, deux développeurs qui avaient
  5.1121 +      travaillé sur CVS, initièrent un projet pour le remplacer par un outil
  5.1122 +      qui aurait une meilleure architecture et un code plus propre. Le
  5.1123 +      résultat, Subversion, ne quitte pas le modèle centralisé et
  5.1124 +      client/server de CVS, mais ajoute les opérations de
  5.1125 +      <quote>commit</quote> atomique sur de multiples fichiers, une meilleure
  5.1126 +      gestion des espaces de noms, et d'autres fonctionnalités qui en font un
  5.1127 +      meilleur outil que CVS. Depuis sa première publication, il est
  5.1128 +      rapidement devenu très populaire.
  5.1129 +    </para>
  5.1130 +    
  5.1131 +    <para>Plus ou moins simultanément, Graydon Hoare a commencé sur
  5.1132 +      l'ambitieux système de gestion distribué Monotone. Bien que Monotone
  5.1133 +      corrige plusieurs défauts de CVS tout en offrant une architecture
  5.1134 +      <quote>peer-to-peer</quote>, il va aussi plus loin que la plupart des
  5.1135 +      outils de révision de manière assez innovante. Il utilise des
  5.1136 +      <quote>hashs</quote> cryptographiques comme identifiants, et il a une
  5.1137 +      notion complète de <quote>confiance</quote> du code issu des
  5.1138 +      différentes sources.
  5.1139 +    </para>
  5.1140 +    
  5.1141 +    <para>Mercurial est né en 2005. Bien que très influencé par Monotone,
  5.1142 +      Mercurial se concentre sur la facilité d'utilisation, les performances
  5.1143 +      et la capacité à monter en charge pour de très gros projets.
  5.1144 +    </para>
  5.1145 +  
  5.1146 +  </sect1>
  5.1147 +
  5.1148 +</chapter>
  5.1149 +
  5.1150 +<!--
  5.1151 +local variables: 
  5.1152 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.1153 +end:
  5.1154 +-->
  5.1155 +
  5.1156 +  <!-- BEGIN ch02 -->
  5.1157 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.1158 +
  5.1159 +<chapter id="chap:tour-basic">
  5.1160 +  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
  5.1161 +  <title>Une rapide présentation de Mercurial : les bases</title>
  5.1162 +
  5.1163 +  <sect1>
  5.1164 +    <title>Installer Mercurial sur votre système</title>
  5.1165 +
  5.1166 +    <para id="x_1">Des paquetages binaires de Mercurial sont disponibles pour la
  5.1167 +      plupart des systèmes d'exploitation, ce qui rend facile l'utilisation
  5.1168 +      immédiate de Mercurial sur votre ordinateur.</para>
  5.1169 +
  5.1170 +    <sect2>
  5.1171 +      <title>Windows</title>
  5.1172 +
  5.1173 +      <para id="x_c">La meilleur version de Mercurial pour Windows est
  5.1174 +        TortoiseHg, qui peut être téléchargée ici : <ulink url="http://bitbucket.org/tortoisehg/stable/wiki/Home">http://bitbucket.org/tortoisehg/stable/wiki/Home</ulink>.
  5.1175 +        Ce logiciel n'a aucune dépendance exterieure; il fonctionne <quote>et
  5.1176 +          c'est tout</quote>. Il fournit aussi bien les outils en ligne de
  5.1177 +        commmande qu'une interface graphique.</para>
  5.1178 + 
  5.1179 +    </sect2>
  5.1180 +
  5.1181 +    <sect2>
  5.1182 +      <title>Mac OS X</title>
  5.1183 +  
  5.1184 +      <para id="x_a">Lee Cantey publie un installeur de Mercurial pour Mac OS
  5.1185 +        X sur <ulink url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para>
  5.1186 +    </sect2>
  5.1187 +      
  5.1188 +    <sect2>
  5.1189 +      <title>Linux</title>
  5.1190 +
  5.1191 +      <para id="x_2">Parce que chaque distribution de Linux a ses propres
  5.1192 +        outils de gestion de paquets, politiques et rythmes de
  5.1193 +        développements, il est difficile de donner un ensemble
  5.1194 +        d'instructions unique pour installer les binaires de Mercurial. La
  5.1195 +        version de Mercurial avec laquelle vous vous retrouverez dépendra
  5.1196 +        grandement de l'activité de la personne en charge du paquetage pour
  5.1197 +        la distribution.</para>
  5.1198 +
  5.1199 +      <para id="x_3">Pour rester simple, je me concentrerai sur
  5.1200 +        l'installation de Mercurial en ligne de commande, sous les
  5.1201 +        distributions les plus courantes. La plupart des distributions
  5.1202 +        fournissent des gestionnaires graphiques de paquetage qui vous
  5.1203 +        permettront d'installer Mercurial en quelques clicks. Le paquetage
  5.1204 +        devrait se nommer <literal moreinfo="none">mercurial</literal>.</para>
  5.1205 +
  5.1206 +      <itemizedlist>
  5.1207 +        <listitem><para id="x_4">Ubuntu et Debian:</para>
  5.1208 +          <programlisting format="linespecific">apt-get install mercurial</programlisting></listitem>
  5.1209 +        <listitem><para id="x_5">Fedora:</para>
  5.1210 +          <programlisting format="linespecific">yum install mercurial</programlisting></listitem>
  5.1211 +        <listitem><para id="x_6">Gentoo:</para>
  5.1212 +           <programlisting format="linespecific">emerge mercurial</programlisting></listitem>
  5.1213 +        <listitem><para id="x_715">OpenSUSE:</para>
  5.1214 +          <programlisting format="linespecific">zypper install
  5.1215 +          mercurial</programlisting></listitem>
  5.1216 +      </itemizedlist>
  5.1217 +
  5.1218 +    </sect2>
  5.1219 +    <sect2>
  5.1220 +      <title>Solaris</title>
  5.1221 +
  5.1222 +      <para id="x_09">SunFreeWare, à <ulink url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>,
  5.1223 +      fournit des paquets précompilés pour Mercurial.</para>
  5.1224 +    </sect2>
  5.1225 +  </sect1>
  5.1226 +
  5.1227 +  <sect1>
  5.1228 +    <title>Commencer à utiliser Mercurial</title>
  5.1229 +
  5.1230 +    <para id="x_e">Pour commencer, nous utiliserons la commande <command role="hg-cmd" moreinfo="none">hg version</command> pour vérifier si Mercurial est
  5.1231 +      installé proprement. Les informations affichées sur la version ne sont
  5.1232 +      pas réellement importantes en soit, c'est surtout de savoir si elles
  5.1233 +      s'affichent qui nous intéresse.</para>
  5.1234 +
  5.1235 +    <!-- BEGIN tour.version -->
  5.1236 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg version</userinput>
  5.1237 +Mercurial Distributed SCM (version 1.2.1)
  5.1238 +
  5.1239 +Copyright (C) 2005-2009 Matt Mackall &lt;mpm@selenic.com&gt; and others
  5.1240 +This is free software; see the source for copying conditions. There is NO
  5.1241 +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  5.1242 +</screen>
  5.1243 +<!-- END tour.version -->
  5.1244 +
  5.1245 +
  5.1246 +    <sect2>
  5.1247 +      <title>L'aide intégrée</title>
  5.1248 +
  5.1249 +      <para id="x_f">Mercurial fournit un système d'aide intégré, ce qui est
  5.1250 +        inestimable quand vous vous retrouvez coincé à essayer de vous
  5.1251 +        rappeler comment lancer une commande. Si vous êtes bloqué, exécutez
  5.1252 +        simplement <command role="hg-cmd" moreinfo="none">hg help</command>; elle affichera
  5.1253 +        une brève liste des commandes, avec une description pour chacune. Si
  5.1254 +        vous demandez de l'aide sur une commande spécifique (voir
  5.1255 +        ci-dessous), elle affichera des informations plus détaillées.</para>
  5.1256 +
  5.1257 +      <!-- BEGIN tour.help -->
  5.1258 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg help init</userinput>
  5.1259 +hg init [-e CMD] [--remotecmd CMD] [DEST]
  5.1260 +
  5.1261 +create a new repository in the given directory
  5.1262 +
  5.1263 +    Initialize a new repository in the given directory. If the given
  5.1264 +    directory does not exist, it is created.
  5.1265 +
  5.1266 +    If no directory is given, the current directory is used.
  5.1267 +
  5.1268 +    It is possible to specify an ssh:// URL as the destination.
  5.1269 +    See 'hg help urls' for more information.
  5.1270 +
  5.1271 +options:
  5.1272 +
  5.1273 + -e --ssh        specify ssh command to use
  5.1274 +    --remotecmd  specify hg command to run on the remote side
  5.1275 +
  5.1276 +use "hg -v help init" to show global options
  5.1277 +</screen>
  5.1278 +<!-- END tour.help -->
  5.1279 +
  5.1280 +
  5.1281 +      <para id="x_10">Pour un niveau d'informations encore plus détaillé 
  5.1282 +        (ce dont vous aurez rarement besoin), exécuter <command role="hg-cmd" moreinfo="none">hg 
  5.1283 +        help <option role="hg-opt-global">-v</option></command>.  L'option 
  5.1284 +        <option role="hg-opt-global">-v</option> est l'abréviation de 
  5.1285 +        <option role="hg-opt-global">--verbose</option>, et indique à Mercurial 
  5.1286 +        d'ficher plus d'informations que d'habitude.</para>
  5.1287 +
  5.1288 +     </sect2>
  5.1289 +  </sect1>
  5.1290 +  <sect1>
  5.1291 +    <title>Travailler avec un dépôt</title>
  5.1292 +
  5.1293 +    <para id="x_11">Avec Mercurial, tout se déroule au sein du 
  5.1294 +      <emphasis>dépôt</emphasis>. Le dépôt d'un projet contient tous 
  5.1295 +      les fichiers qui <quote>appartiennent</quote> au projet.</para>
  5.1296 +
  5.1297 +    <para id="x_12">Il n'y a rien de particulièrement magique au sujet de 
  5.1298 +      ce dépôt, c'est simplement une arborescence sur votre système de fichiers 
  5.1299 +      que Mercurial traite de manière spéciale. Vous pouvez renommer ou effacer 
  5.1300 +      ce répertoire à n'impporte quel moment, en utilisant la ligne de commande 
  5.1301 +      ou votre explorateur de fichiers.</para>
  5.1302 +
  5.1303 +    <sect2>
  5.1304 +      <title>Faire une copie locale de votre dépôt</title>
  5.1305 +      
  5.1306 +      <para id="x_13"><emphasis>Copier</emphasis> un dépôt est juste un 
  5.1307 +        peu spécial. Bien que vous puissiez utiliser une commande habituelle de 
  5.1308 +        copie pour copier votre dépôt, il vaut mieux utiliser une commande fournie par
  5.1309 +        Mercurial. Cette commande est appelée <command role="hg-cmd" moreinfo="none">hg clone</command>, 
  5.1310 +        car elle crée une copie identique à un dépôt existant.</para>
  5.1311 +
  5.1312 +      <!-- BEGIN tour.clone -->
  5.1313 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone http://hg.serpentine.com/tutorial/hello</userinput>
  5.1314 +destination directory: hello
  5.1315 +requesting all changes
  5.1316 +adding changesets
  5.1317 +adding manifests
  5.1318 +adding file changes
  5.1319 +added 5 changesets with 5 changes to 2 files
  5.1320 +updating working directory
  5.1321 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.1322 +</screen>
  5.1323 +<!-- END tour.clone -->
  5.1324 +
  5.1325 +
  5.1326 +      <para id="x_67c">Un avantage de la commande <command role="hg-cmd" moreinfo="none">hg
  5.1327 +          clone</command> est que, comme nous l'avons vu ci dessus, elle nous
  5.1328 +        permet de faire de cloner les dépôts à travers le réseau. Un autre
  5.1329 +        est qu'elle se rappelle d'où a été cloné un dépôt, ce qui est utile
  5.1330 +        quand on veut mettre à jour le clone.</para>
  5.1331 +
  5.1332 +      <para id="x_14">Si votre opération de clonage réussit, vous devriez maintenant
  5.1333 +        avoir un répertoire local appelé <filename class="directory" moreinfo="none">hello</filename>. 
  5.1334 +        Ce répertoire contiendra quelques fichiers.</para>
  5.1335 +
  5.1336 +      <!-- BEGIN tour.ls -->
  5.1337 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -l</userinput>
  5.1338 +total 4
  5.1339 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:05 hello
  5.1340 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls hello</userinput>
  5.1341 +Makefile  hello.c
  5.1342 +</screen>
  5.1343 +<!-- END tour.ls -->
  5.1344 +
  5.1345 +
  5.1346 +      <para id="x_15">Ces fichiers ont le même contenu et historique dans votre dépôt
  5.1347 +        qu'ils ont dans le dépôt que vous avez cloné.</para>
  5.1348 +
  5.1349 +      <para id="x_16">Chaque dépôt Mercurial est complet, autonome et
  5.1350 +        indépendant. Il contient sa propre copie privée des fichiers du
  5.1351 +        projet et de leur historique. Le clone d'un dépôt se souvient de la
  5.1352 +        localisation du dépôt à partir duquel il a été clôné, mais il ne
  5.1353 +        communique pas avec ce dernier, ou un autre, à moins que vous ne lui
  5.1354 +        demandiez.</para>
  5.1355 +
  5.1356 +      <para id="x_17">Ce que tout ceci signifie pour le moment est que nous
  5.1357 +        sommes libres d'expérimenter avec ce dépôt, confiants dans le fait
  5.1358 +        qu'il s'agit d'un <quote>bac à sable</quote> qui n'affectera personne
  5.1359 +        d'autre.</para>
  5.1360 +
  5.1361 +    </sect2>  
  5.1362 +    <sect2>
  5.1363 +      <title>Quel est le contenu d'un dépôt ?</title>
  5.1364 +
  5.1365 +      <para id="x_18">Prêtons plus attention un instant au contenu d'un dépôt. 
  5.1366 +        Nous voyons qu'il contient un répertoire nommé <filename class="directory" moreinfo="none">.hg
  5.1367 +        </filename>. C'est ici que Mercurial conserve toutes ses
  5.1368 +        métadonnées.</para>
  5.1369 +
  5.1370 +      <!-- BEGIN tour.ls-a -->
  5.1371 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hello</userinput>
  5.1372 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -a</userinput>
  5.1373 +.  ..  .hg  Makefile  hello.c
  5.1374 +</screen>
  5.1375 +<!-- END tour.ls-a -->
  5.1376 + 
  5.1377 +
  5.1378 +      <para id="x_19">Le contenu du répertoire <filename class="directory" moreinfo="none">.hg
  5.1379 +        </filename> et ses sous répertoires sont les seuls propres à Mercurial. 
  5.1380 +        Tous les autres fichiers et répertoires dans le dépôt sont à vous, et 
  5.1381 +        vous pouvez en faire ce que vous voulez.</para>
  5.1382 +
  5.1383 +      <para id="x_1a">Pour introduire un peu de terminologie, le répertoire 
  5.1384 +        <filename class="directory" moreinfo="none">.hg</filename> est un <quote>vrai</quote> 
  5.1385 +        dépôt, et tous les fichiers et les répertoires qui coexistent avec lui, 
  5.1386 +        sont désignés sous le nom <emphasis>espace de travail</emphasis>. Une 
  5.1387 +        manière facile de se rappeler cette distinction est de retenir que le 
  5.1388 +        <emphasis>dépôt</emphasis> contient l'<emphasis>historique</emphasis>
  5.1389 +        de votre projet, alors que l'<emphasis>espace de travail</emphasis> 
  5.1390 +        contient un "<emphasis>snapshot</emphasis>"  de votre projet à un certain 
  5.1391 +        point de son historique.</para>
  5.1392 +
  5.1393 +    </sect2>
  5.1394 +  </sect1>
  5.1395 +  <sect1>
  5.1396 +    <title>Une promenade dans l'historique</title>
  5.1397 +
  5.1398 +    <para id="x_1b">Une des premières choses que vous aurez envie 
  5.1399 +      de faire avec un nouveau dépôt, sera de comprendre son historique. 
  5.1400 +      La commande <command role="hg-cmd" moreinfo="none">hg log</command> vous donne une 
  5.1401 +      vue de l'historique.</para>
  5.1402 +
  5.1403 +    <!-- BEGIN tour.log -->
  5.1404 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log</userinput>
  5.1405 +changeset:   4:2278160e78d4
  5.1406 +tag:         tip
  5.1407 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1408 +date:        Sat Aug 16 22:16:53 2008 +0200
  5.1409 +summary:     Trim comments.
  5.1410 +
  5.1411 +changeset:   3:0272e0d5a517
  5.1412 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1413 +date:        Sat Aug 16 22:08:02 2008 +0200
  5.1414 +summary:     Get make to generate the final binary from a .o file.
  5.1415 +
  5.1416 +changeset:   2:fef857204a0c
  5.1417 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1418 +date:        Sat Aug 16 22:05:04 2008 +0200
  5.1419 +summary:     Introduce a typo into hello.c.
  5.1420 +
  5.1421 +changeset:   1:82e55d328c8c
  5.1422 +user:        mpm@selenic.com
  5.1423 +date:        Fri Aug 26 01:21:28 2005 -0700
  5.1424 +summary:     Create a makefile
  5.1425 +
  5.1426 +changeset:   0:0a04b987be5a
  5.1427 +user:        mpm@selenic.com
  5.1428 +date:        Fri Aug 26 01:20:50 2005 -0700
  5.1429 +summary:     Create a standard "hello, world" program
  5.1430 +
  5.1431 +</screen>
  5.1432 +<!-- END tour.log -->
  5.1433 +
  5.1434 +
  5.1435 +    <para id="x_1c">Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque
  5.1436 +      révision enregistrée pour ce projet. Dans la terminologie de Mercurial, nous
  5.1437 +      appelons chacun de ces évènements enregistrés un <emphasis>changeset</emphasis>, parce
  5.1438 +      qu'il contient un ensemble de modifications sur plusieurs fichiers.</para>
  5.1439 +
  5.1440 +    <para id="x_1d">La commande <command role="hg-cmd" moreinfo="none">hg log</command> affiche 
  5.1441 +    ainsi ces informations :</para>
  5.1442 +
  5.1443 +    <itemizedlist>
  5.1444 +      <listitem><para id="x_1e"><literal moreinfo="none">changeset</literal> : Ce champ contient 
  5.1445 +        un nombre, séparé par deux points (:), d'une chaine hexadécimale. Il 
  5.1446 +        s'agit en fait d'<emphasis>identifiants</emphasis>  d'un changeset. Il y a 
  5.1447 +        deux identifiants car le numéro de la révision est plus court et plus à 
  5.1448 +        facile à saisir qu'une séquence hexadécimale.</para>
  5.1449 +      </listitem>
  5.1450 +      <listitem><para id="x_1f"><literal moreinfo="none">user</literal> : L'identité de la personne 
  5.1451 +        qui a créée ce  %%% laisser le terme anglais car il sera affiché
  5.1452 +        changeset. C'est un champ libre de forme, mais la plupart du
  5.1453 +        temps il contient le nom et l'email de la personne.</para>
  5.1454 +      </listitem>
  5.1455 +      <listitem><para id="x_20"><literal moreinfo="none">date</literal> : La date et l'heure à 
  5.1456 +        laquelle le \textit{changeset} a été créé, ainsi que le fuseau horaire dans 
  5.1457 +        lequelle il a été créé. (La date et l'heure sont locales à ce
  5.1458 +        \textit{fuseau}, elles indiquent donc quelle date et heure il était
  5.1459 +        pour la personne qui a créé ce changeset.</para>
  5.1460 +      </listitem>
  5.1461 +      <listitem><para id="x_21"><literal moreinfo="none">résumé</literal>: La première ligne du 
  5.1462 +        message que le créateur a associé à son changeset pour le décrire.</para>
  5.1463 +      </listitem>
  5.1464 +      <listitem><para id="x_67d">Certains changesets, comme le premier de la
  5.1465 +        liste ci-dessus ont un champ <literal moreinfo="none">tag</literal>. Le tag est une autre
  5.1466 +        façon d'identifier un changeset en lui donnant un nom simple à retenir.
  5.1467 +        (Le tag nommé <literal moreinfo="none">tip</literal> est spécial : il fait toujours
  5.1468 +        référence aux derniers changements dans le dépôt.)</para></listitem>
  5.1469 +    </itemizedlist>
  5.1470 +
  5.1471 +    <para id="x_22">Par défaut, la commande <command role="hg-cmd" moreinfo="none">hg log</command> 
  5.1472 +      n'affiche qu'un résumé, il manque beaucoup de détails.</para>
  5.1473 +
  5.1474 +    <para id="x_23">La figure <xref linkend="fig:tour-basic:history"/> fournit une 
  5.1475 +      représentation graphique de l'historique du dépôt <filename class="directory" moreinfo="none">hello
  5.1476 +      </filename>, pour rendre plus facile de voir dans quelle direction 
  5.1477 +      l'historique se <quote>déroule</quote>. Nous reviendrons régulièrement 
  5.1478 +      sur cette représentation dans ce chapitre et ceux qui suivent.</para>
  5.1479 +
  5.1480 +
  5.1481 +    <figure id="fig:tour-basic:history" float="0">
  5.1482 +      <title>Graphical history of the <filename class="directory" moreinfo="none">hello</filename> repository</title>
  5.1483 +      <mediaobject>
  5.1484 +        <imageobject><imagedata fileref="figs/tour-history.png"/></imageobject>
  5.1485 +        <textobject><phrase>XXX add text</phrase></textobject>
  5.1486 +      </mediaobject>
  5.1487 +    </figure>
  5.1488 +
  5.1489 +
  5.1490 +    <sect2>
  5.1491 +      <title>Changesets, révisions, et collaboration</title>
  5.1492 +      
  5.1493 +      <para id="x_25">Comme l'anglais est réputé pour être un langage maladroit,
  5.1494 +        et que l'informatique est la source de bien des erreurs de terminologie
  5.1495 +        (pourquoi utiliser un seul terme quand quatre feront l'affaire ?), la
  5.1496 +        gestion de version a une variété de mots et de phrases qui veulent dire
  5.1497 +        la même chose. Si vous discutez d'historique de Mercurial avec d'autres
  5.1498 +        personnes, vous constaterez que souvent, le mot <quote>changeset</quote>
  5.1499 +        est contracté simplement en <quote>change</quote> ou (à l'écrit)
  5.1500 +        <quote>cset</quote>, et même parfois un changeset
  5.1501 +        <quote>révision</quote>, abrégé en <quote>rev</quote>.</para>
  5.1502 +
  5.1503 +      <para id="x_26">Bien que le <emphasis>mot</emphasis> que vous utilisez pour 
  5.1504 +        désigner le concept de changeset importe peu, l'<emphasis>identifiant</emphasis> 
  5.1505 +        que vous utilisez pour désigner un <emphasis>changeset</emphasis> spécifique 
  5.1506 +        a une grande importance. Rappelez vous que le champ changeset affiché par la
  5.1507 +        commande <command role="hg-cmd" moreinfo="none">hg log</command> identifie un changeset à
  5.1508 +        la fois avec un numéro de révision et une séquence hexadécimale.</para>
  5.1509 +
  5.1510 +      <itemizedlist>
  5.1511 +        <listitem><para id="x_27">Le numéro de révision est <emphasis>seulement 
  5.1512 +        valable dans ce dépôt</emphasis>,</para></listitem>
  5.1513 +        <listitem><para id="x_28">La séquence hexadécimale est un
  5.1514 +        <emphasis>identifiant permanent, et invariant</emphasis> qui 
  5.1515 +        pourra toujours être associé au changeset exact de <emphasis>chaque</emphasis> 
  5.1516 +        copie de votre dépôt.</para></listitem></itemizedlist>
  5.1517 +
  5.1518 +      <para id="x_29">La distinction est importante. Si vous envoyez un email 
  5.1519 +         à quelqu'un en parlant de la <quote>révision 33</quote>, il est très 
  5.1520 +         probable que sa révision 33 <emphasis>ne sera pas la même</emphasis> 
  5.1521 +         que la votre. La raison de ceci est que le numéro de révision dépend 
  5.1522 +         de l'ordre dans lequel les modifications sont arrivées dans le dépôt, 
  5.1523 +         et il n'y a aucune garantie que les mêmes changements soient arrivés 
  5.1524 +         dans le même ordre dans différents dépôts. Trois modifications
  5.1525 +         <literal moreinfo="none">a,b,c</literal> peuvent aisément apparaitre dans un dépôt 
  5.1526 +         comme <literal moreinfo="none">0,1,2</literal>, et dans un autre comme <literal moreinfo="none">0,2,1
  5.1527 +         </literal>.</para>
  5.1528 +
  5.1529 +      <para id="x_2a">Mercurial utilise les numéros de révision uniquement comme des raccourcis
  5.1530 +        pratiques. Si vous devez discuter d'un \textit{changeset} avec quelqu'un,
  5.1531 +        ou identifer un \textit{changeset} pour une quelconque raison (par exemple,
  5.1532 +        un rapport de \textit{bug}), utilisez la séquence hexadécimale.</para>
  5.1533 +
  5.1534 +    </sect2>
  5.1535 +    <sect2>
  5.1536 +      <title>Afficher une révision spécifique</title>
  5.1537 +
  5.1538 +      <para id="x_2b">Pour réduire la sortie de <command role="hg-cmd" moreinfo="none">hg log
  5.1539 +        </command> à une seule révision, utilisez l'option <option role="hg-opt-log">-r
  5.1540 +        </option> (ou <option role="hg-opt-log">--rev</option>). Vous pouvez utiliser
  5.1541 +        le numéro de révision ou la séquence hexadécimale comme identifiant, et
  5.1542 +        demander autant de révisions que vous le souhaitez.</para>
  5.1543 +
  5.1544 +      <!-- BEGIN tour.log-r -->
  5.1545 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 3</userinput>
  5.1546 +changeset:   3:0272e0d5a517
  5.1547 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1548 +date:        Sat Aug 16 22:08:02 2008 +0200
  5.1549 +summary:     Get make to generate the final binary from a .o file.
  5.1550 +
  5.1551 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 0272e0d5a517</userinput>
  5.1552 +changeset:   3:0272e0d5a517
  5.1553 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1554 +date:        Sat Aug 16 22:08:02 2008 +0200
  5.1555 +summary:     Get make to generate the final binary from a .o file.
  5.1556 +
  5.1557 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 1 -r 4</userinput>
  5.1558 +changeset:   1:82e55d328c8c
  5.1559 +user:        mpm@selenic.com
  5.1560 +date:        Fri Aug 26 01:21:28 2005 -0700
  5.1561 +summary:     Create a makefile
  5.1562 +
  5.1563 +changeset:   4:2278160e78d4
  5.1564 +tag:         tip
  5.1565 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1566 +date:        Sat Aug 16 22:16:53 2008 +0200
  5.1567 +summary:     Trim comments.
  5.1568 +
  5.1569 +</screen>
  5.1570 +<!-- END tour.log-r -->
  5.1571 +
  5.1572 +
  5.1573 +      <para id="x_2c">Si vous voulez voir l'historique de plusieurs révisions
  5.1574 +        sans avoir à les énumérer, vous pouvez utiliser la <emphasis>intervalle
  5.1575 +        de numérotation</emphasis> qui vous permet d'exprimer l'idée <quote>je
  5.1576 +        veux toutes les révisions entre $a$ et $b$, inclus</quote></para>
  5.1577 +
  5.1578 +      <!-- BEGIN tour.log.range -->
  5.1579 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 2:4</userinput>
  5.1580 +changeset:   2:fef857204a0c
  5.1581 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1582 +date:        Sat Aug 16 22:05:04 2008 +0200
  5.1583 +summary:     Introduce a typo into hello.c.
  5.1584 +
  5.1585 +changeset:   3:0272e0d5a517
  5.1586 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1587 +date:        Sat Aug 16 22:08:02 2008 +0200
  5.1588 +summary:     Get make to generate the final binary from a .o file.
  5.1589 +
  5.1590 +changeset:   4:2278160e78d4
  5.1591 +tag:         tip
  5.1592 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1593 +date:        Sat Aug 16 22:16:53 2008 +0200
  5.1594 +summary:     Trim comments.
  5.1595 +
  5.1596 +</screen>
  5.1597 +<!-- END tour.log.range -->
  5.1598 +
  5.1599 +
  5.1600 +      <para id="x_2d">Mercurial respecte aussi l'ordre dans lequel vous spécifiez
  5.1601 +        les révisions, ainsi <command role="hg-cmd" moreinfo="none">hg log -r 2:4</command>
  5.1602 +        affichera <literal moreinfo="none">2,3,4</literal> alors que <command role="hg-cmd" moreinfo="none">hg
  5.1603 +        log -r 4:2</command> affichera <literal moreinfo="none">4,3,2</literal>.</para>
  5.1604 +
  5.1605 +    </sect2>  
  5.1606 +    <sect2>
  5.1607 +      <title>Informations détaillées</title>
  5.1608 +
  5.1609 +      <para id="x_2e">Le résumé affiché par <command role="hg-cmd" moreinfo="none">hg log</command> 
  5.1610 +        est suffisant si vous savez déjà ce que vous cherchez. En 
  5.1611 +        revanche, vous aurez probablement besoin de voir une description 
  5.1612 +        complète du changement, ou une liste des fichiers modifiés si vous 
  5.1613 +        cherchez à déterminer qu'un changeset est bien celui que vous
  5.1614 +        recherchez. L'option \hgopt{-v} de la commande <command role="hg-cmd" moreinfo="none">hg 
  5.1615 +        log</command> (ou <option role="hp-opt-global">--verbose</option>) vous 
  5.1616 +        donne ces informations supplémentaires.</para>
  5.1617 +
  5.1618 +      <!-- BEGIN tour.log-v -->
  5.1619 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -v -r 3</userinput>
  5.1620 +changeset:   3:0272e0d5a517
  5.1621 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1622 +date:        Sat Aug 16 22:08:02 2008 +0200
  5.1623 +files:       Makefile
  5.1624 +description:
  5.1625 +Get make to generate the final binary from a .o file.
  5.1626 +
  5.1627 +
  5.1628 +</screen>
  5.1629 +<!-- END tour.log-v -->
  5.1630 +
  5.1631 +
  5.1632 +      <para id="x_2f">Si vous voulez voir à la fois la description 
  5.1633 +        et le contenu d'une modification, ajouter l'option <option role="hg-opt-log">-p</option> (ou <option role="hg-opt-log">
  5.1634 +        --patch</option>). Ceci affiche le contenu d'une modification 
  5.1635 +        comme un <emphasis>diff unifié</emphasis>
  5.1636 +        <!-- \footnote{NdT: \textit{unified diff}} -->
  5.1637 +        (si vous n'avez jamais vu de diff unifié avant, consultez la 
  5.1638 +        section <xref linkend="sec:mq:patch"/> pour un rapide 
  5.1639 +        survol).</para>
  5.1640 +
  5.1641 +      <!-- BEGIN tour.log-vp -->
  5.1642 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -v -p -r 2</userinput>
  5.1643 +changeset:   2:fef857204a0c
  5.1644 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.1645 +date:        Sat Aug 16 22:05:04 2008 +0200
  5.1646 +files:       hello.c
  5.1647 +description:
  5.1648 +Introduce a typo into hello.c.
  5.1649 +
  5.1650 +
  5.1651 +diff -r 82e55d328c8c -r fef857204a0c hello.c
  5.1652 +--- a/hello.c	Fri Aug 26 01:21:28 2005 -0700
  5.1653 ++++ b/hello.c	Sat Aug 16 22:05:04 2008 +0200
  5.1654 +@@ -11,6 +11,6 @@
  5.1655 + 
  5.1656 + int main(int argc, char **argv)
  5.1657 + {
  5.1658 +-	printf("hello, world!\n");
  5.1659 ++	printf("hello, world!\");
  5.1660 + 	return 0;
  5.1661 + }
  5.1662 +
  5.1663 +</screen>
  5.1664 +<!-- END tour.log-vp -->
  5.1665 +
  5.1666 +
  5.1667 +      <para id="x_67e">L'option <option role="hg-opt-log">-p</option> est
  5.1668 +        incroyablement utile, il est donc important dans s'en rappeller.</para>
  5.1669 +
  5.1670 +    </sect2>
  5.1671 +  </sect1>
  5.1672 +  <sect1>
  5.1673 +    <title>Tout sur les options de commandes</title>
  5.1674 +    
  5.1675 +    <para id="x_30">Avant d'aller plus loin sur le fonctionnement 
  5.1676 +      des commandes de Mercurial, étudions un moment comment elles 
  5.1677 +      fonctionnent de manière générale. Vous trouverez ça probablement 
  5.1678 +      utile pour la suite de notre parcours.</para>
  5.1679 +
  5.1680 +    <para id="x_31">Mercurial utilise une approche directe et cohérente 
  5.1681 +      pour interpréter les options que vous passez aux commandes. Il suit une
  5.1682 +      convention commune à la plupart des systèmes Unix et Linux modernes.</para>
  5.1683 +
  5.1684 +    <itemizedlist>
  5.1685 +      <listitem><para id="x_32">Chaque option a un nom complet. Par exemple, 
  5.1686 +        comme nous l'avons déjà vu, la commande <command role="hg-cmd" moreinfo="none">hg 
  5.1687 +        log</command> accepte l'option <option role="hg-opt-log">--rev
  5.1688 +        </option>.</para>
  5.1689 +      </listitem>
  5.1690 +      <listitem><para id="x_33">La plupart des options disposent de 
  5.1691 +        noms abrégés. Aussi, au lieu d'utiliser <option role="hg-opt-log">--rev
  5.1692 +        </option>, vous pouvez utiliser <option role="hg-opt-log">-r</option>. 
  5.1693 +        (Les options qui  n'ont pas de noms abrégés sont généralement 
  5.1694 +        rarement utilisées).</para>
  5.1695 +      </listitem>
  5.1696 +      <listitem><para id="x_34">Les noms complets commencent par deux 
  5.1697 +        tirets (i.e. <option role="hg-opt-log">--rev</option>),
  5.1698 +        alors que les options courtes commencent avec un seul (i.e. 
  5.1699 +        <option role="hg-opt-log">-r</option>).</para>
  5.1700 +      </listitem>
  5.1701 +     <listitem><para id="x_35">Les noms des options sont cohérents 
  5.1702 +       entre les commandes. Par exemple, chaque commande qui accepte 
  5.1703 +       un changeset ID ou un numéro de révision accepte aussi <option role="hg-opt-log">-r</option> et <option role="hg-opt-log">--rev
  5.1704 +       </option> comme arguments.</para>
  5.1705 +     </listitem>
  5.1706 +   </itemizedlist>
  5.1707 +
  5.1708 +   <para id="x_36">Dans les exemples de ce livre, j'utilise les noms abrégés 
  5.1709 +     plutôt que les noms complets. Ceci est une préférence personnelle, pas 
  5.1710 +     une recommandation.</para>
  5.1711 +
  5.1712 +   <para id="x_37">La plupart des commandes qui affichent une quelconque sortie 
  5.1713 +     à l'écran, afficheront davantage avec l'option <option role="hg-opt-global">
  5.1714 +     -v</option> (ou <option role="hg-opt-global">--verbose</option>), et
  5.1715 +     moins avec l'option <option role="hg-opt-global">-q</option> (ou 
  5.1716 +     <option role="hg-opt-global">--quiet</option>).</para>
  5.1717 +
  5.1718 +    <note>
  5.1719 +      <title>Option naming consistency</title>
  5.1720 +      
  5.1721 +      <para id="x_680">Presque toujours, les commandes de Mercurial utilisent
  5.1722 +      des noms d'options cohérentes pour référer à des concepts identiques.
  5.1723 +      Par exemple, si une commande concerne les changesets, vous les
  5.1724 +      identifierez toujours avec l'option <option role="hg-opt-log">-r</option>.
  5.1725 +      Cette utilisation cohérente des noms d'options permet de mémoriser plus
  5.1726 +      facilement quelles options accepte une commande.</para>
  5.1727 +   </note>
  5.1728 +
  5.1729 +
  5.1730 +  </sect1>
  5.1731 +  <sect1>
  5.1732 +    <title>Faire et vérifier des modifications</title>
  5.1733 +
  5.1734 +    <para id="x_38">Maintenant que nous avons une bonne idée des 
  5.1735 +      commandes pour consulter l'historique de Mercurial, regardons 
  5.1736 +      comment faire des modifications et les examiner.</para>
  5.1737 +     
  5.1738 +    <para id="x_39">La première chose que nous allons faire c'est isoler notre
  5.1739 +      expérience dans un dépôt à part. Nous allons utiliser la commande <command role="hg-cmd" moreinfo="none">hg clone</command>, mais nous n'avons pas besoin de faire
  5.1740 +      une copie de dépôt distant. Comme nous avons déjà une copie locale, nous
  5.1741 +      pouvons juste faire un clone de celle-ci à la place. C'est beaucoup plus
  5.1742 +      rapide que de faire une copie à travers le réseau, et un dépôt cloné
  5.1743 +      localement prend également moins d'espace disque<footnote>
  5.1744 +      <para id="x_681">L'économie d'espace disque apparait clairement quand les
  5.1745 +        dépôts source et destination sont sur le même système de fichier, où, dans
  5.1746 +        ce cas, Mercurial utilisera des liens physiques pour effectuer des partages
  5.1747 +        copie-lors-des-écritures de ses métadonnées internes. Si cette explication
  5.1748 +        ne signifie rien pour vous, ne vous inquietez pas : tout ceci se passe de
  5.1749 +        manière transparente et automatiquement. Vous n'avez pas du tout besoin de
  5.1750 +        comprendre ceci.</para></footnote>.</para>
  5.1751 +  
  5.1752 +    <!-- BEGIN tour.reclone -->
  5.1753 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.1754 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello my-hello</userinput>
  5.1755 +updating working directory
  5.1756 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.1757 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-hello</userinput>
  5.1758 +</screen>
  5.1759 +<!-- END tour.reclone -->
  5.1760 +
  5.1761 +
  5.1762 +    <para id="x_3a">On notera au passage qu'il est souvent considéré comme
  5.1763 +      une bonne pratique de conserver une copie <quote>immaculée</quote>
  5.1764 +      du dépôt distant, à partir de laquelle vous pourrez faire des 
  5.1765 +      copies locales temporaires pour créer des <quote>bacs à sable</quote> 
  5.1766 +      pour chaque tâche sur laquelle vous souhaitez travailler. Ceci 
  5.1767 +      vous permet de travailler sur plusieurs choses en parallèle, 
  5.1768 +      chacune isolée les unes des autres en attendant que ces tâches 
  5.1769 +      soient finies et que vous soyez prêt à les réintégrer. Parce 
  5.1770 +      que les copies locales sont peu coûteuses, il est très rapide 
  5.1771 +      de créer ou détruire des dépôts dès que vous n'en avez plus
  5.1772 +      besoin.</para>
  5.1773 +
  5.1774 +    <para id="x_3b">Dans notre dépôt <filename class="directory" moreinfo="none">my-hello</filename>, nous avons un fichier
  5.1775 +      <filename moreinfo="none">hello.c</filename> qui contient le classique <quote>hello,
  5.1776 +        world</quote>.</para>
  5.1777 +   
  5.1778 +    <!-- BEGIN tour.cat1 -->
  5.1779 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  5.1780 +/*
  5.1781 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  5.1782 + * not covered by patents in the United States or other countries.
  5.1783 + */
  5.1784 +
  5.1785 +#include &lt;stdio.h&gt;
  5.1786 +
  5.1787 +int main(int argc, char **argv)
  5.1788 +{
  5.1789 +	printf("hello, world!\");
  5.1790 +	return 0;
  5.1791 +}
  5.1792 +</screen>
  5.1793 +<!-- END tour.cat1 -->
  5.1794 +
  5.1795 +
  5.1796 +    <para id="x_682">Editons ce fichier pour qu'il affiche une autre ligne
  5.1797 +      sur la sortie standard.</para>
  5.1798 +    
  5.1799 +    <!-- BEGIN tour.cat2 -->
  5.1800 +<screen format="linespecific"># ... edit edit edit ...
  5.1801 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  5.1802 +/*
  5.1803 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  5.1804 + * not covered by patents in the United States or other countries.
  5.1805 + */
  5.1806 +
  5.1807 +#include &lt;stdio.h&gt;
  5.1808 +
  5.1809 +int main(int argc, char **argv)
  5.1810 +{
  5.1811 +	printf("hello, world!\");
  5.1812 +	printf("hello again!\n");
  5.1813 +	return 0;
  5.1814 +}
  5.1815 +</screen>
  5.1816 +<!-- END tour.cat2 -->
  5.1817 +
  5.1818 +
  5.1819 +    <para id="x_3c">La commande Mercurial <command role="hg-cmd" moreinfo="none">hg
  5.1820 +        status</command> nous dira ce que Mercurial sait des fichiers du
  5.1821 +      dépôts.</para>
  5.1822 +
  5.1823 +    <!-- BEGIN tour.status -->
  5.1824 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls</userinput>
  5.1825 +Makefile  hello.c
  5.1826 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.1827 +M hello.c
  5.1828 +</screen>
  5.1829 +<!-- END tour.status -->
  5.1830 +
  5.1831 +
  5.1832 +    <para id="x_3d">La commande <command role="hg-cmd" moreinfo="none">hg status</command>
  5.1833 +      n'affichera pas le contenu des fichiers, mais une ligne commençant par
  5.1834 +      <quote><literal moreinfo="none">M</literal></quote> pour <filename moreinfo="none">hello.c</filename>.
  5.1835 +      A moins que vous lui demandiez, la commande <command role="hg-cmd" moreinfo="none">hg
  5.1836 +        status</command> n'affichera aucune information sur les fichiers que
  5.1837 +      vous n'avez pas modifiés.</para>
  5.1838 + 
  5.1839 +    <para id="x_3e">Le <quote><literal moreinfo="none">M</literal></quote> indique que
  5.1840 +      Mercurial a remarqué que nous avons modifié le fichier
  5.1841 +      <filename moreinfo="none">hello.c</filename>. Nous n'avons pas besoin
  5.1842 +      <emphasis>d'informer</emphasis> Mercurial que nous allons modifier un
  5.1843 +      fichier avant de commencer à le faire, ou que nous avons modifié un
  5.1844 +      fichier après avoir commencé à le faire, il est capable de découvrir ça
  5.1845 +      tout seul. </para>
  5.1846 +
  5.1847 +    <para id="x_3f">C'est déjà pratique de savoir que nous avons modifié le
  5.1848 +      fichier <filename moreinfo="none">hello.c</filename>, mais nous préférerions savoir
  5.1849 +      exactement <emphasis>ce que</emphasis> nous avons changé. Pour ceci, nous
  5.1850 +      utilisons la commande <command role="hg-cmd" moreinfo="none">hg diff</command>.</para>
  5.1851 +
  5.1852 +    <!-- BEGIN tour.diff -->
  5.1853 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
  5.1854 +diff -r 2278160e78d4 hello.c
  5.1855 +--- a/hello.c	Sat Aug 16 22:16:53 2008 +0200
  5.1856 ++++ b/hello.c	Sun Aug 16 14:05:26 2009 +0000
  5.1857 +@@ -8,5 +8,6 @@
  5.1858 + int main(int argc, char **argv)
  5.1859 + {
  5.1860 + 	printf("hello, world!\");
  5.1861 ++	printf("hello again!\n");
  5.1862 + 	return 0;
  5.1863 + }
  5.1864 +</screen>
  5.1865 +<!-- END tour.diff -->
  5.1866 +
  5.1867 +
  5.1868 +    <tip>
  5.1869 +      <title>Comprendre les patches</title>
  5.1870 +   
  5.1871 +      <para id="x_683">Penser à jeter un oeil à <xref linkend="sec:mq:patch"/> si vous n'arrivez pas à lire la sortie
  5.1872 +        ci-dessus.</para>
  5.1873 +    </tip>
  5.1874 +  </sect1>
  5.1875 +  <sect1>
  5.1876 +    <title>Enregister vos modifications dans une nouvelle révision</title>
  5.1877 +   
  5.1878 +    <para id="x_40">Nous pouvons modifier des fichiers, compiler et tester
  5.1879 +      nos modifications, et utiliser les commandes <command role="hg-cmd" moreinfo="none">hg
  5.1880 +        status</command> et <command role="hg-cmd" moreinfo="none">hg diff</command> pour
  5.1881 +      voir les modifications effectuées, jusqu'à ce que nous soyons assez
  5.1882 +      satisfaits pour décider d'enregistrer notre travail dans un
  5.1883 +      \textit{changeset}.</para>
  5.1884 +
  5.1885 +    <para id="x_41">La commande <command role="hg-cmd" moreinfo="none">hg commit</command>
  5.1886 +      vous laisse créer une nouvelle révision, nous désignerons généralement
  5.1887 +      cette opération par <quote>faire un commit</quote> ou
  5.1888 +      <quote>committer</quote>.</para>
  5.1889 +
  5.1890 +    <sect2>
  5.1891 +    <title>Définir le nom d'utilisateur</title>
  5.1892 +
  5.1893 +      <para id="x_42">Quand vous exécutez la commande <command role="hg-cmd" moreinfo="none">hg commit</command> pour la première fois, il n'est
  5.1894 +        pas garanti qu'elle réussisse du premier coup. En effet, Mercurial
  5.1895 +        enregistre votre nom et votre adresse avec chaque modification que
  5.1896 +        vous effectuez, de manière à ce que vous soyez capable (ou d'autres
  5.1897 +        le soient) de savoir qui a fait quelle modification. Mercurial essaye
  5.1898 +        automatiquement de découvrir un nom d'utilisateur qui ait un minimum
  5.1899 +        de sens pour effectuer l'opération de commit avec. Il va essayer
  5.1900 +        chacune des méthodes suivantes, dans l'ordre :</para>
  5.1901 +
  5.1902 +      <orderedlist inheritnum="ignore" continuation="restarts">
  5.1903 +        <listitem><para id="x_43">Si vous spécifiez l'option <option role="hg-opt-commit">-u</option> avec la commande <command role="hg-cmd" moreinfo="none">hg commit</command>, suivi d'un nom
  5.1904 +            d'utilisateur, ceci aura toujours la priorité sur les autres
  5.1905 +            méthodes ci dessous.</para></listitem>
  5.1906 +        <listitem><para id="x_44">Si vous avez défini une variable
  5.1907 +            d'environnement <envar>HGUSER</envar>, c'est cette valeur qui est
  5.1908 +            alors utilisée.</para></listitem>
  5.1909 +        <listitem><para id="x_45">Si vous créez un fichier nommé <filename role="special" moreinfo="none">.hgrc</filename> dans votre répertoire
  5.1910 +            \textit{home}, avec une entrée <envar role="rc-item-ui">username</envar>, c'est la valeur associée
  5.1911 +            qui sera utilisée. Pour voir à quoi ressemble le contenu de ce
  5.1912 +            fichier regardez la section <xref linkend="sec:tour-basic:username"/>
  5.1913 +            ci-dessous.</para></listitem>
  5.1914 +        <listitem><para id="x_46">Si vous avez défini une variable
  5.1915 +            d'environnement <envar>EMAIL</envar> celle ci sera utilisée
  5.1916 +            ensuite.</para></listitem>
  5.1917 +        <listitem><para id="x_47">Enfin, Mercurial interrogera votre système
  5.1918 +            pour trouver votre nom d'utilisateur local ainsi que le nom de la
  5.1919 +            machine hôte, et il fabriquera un nom d'utilisateur à partir de
  5.1920 +            ces données. Comme il arrive souvent que ce genre de noms soit
  5.1921 +            totalement inutile, il vous préviendra en affichant un message
  5.1922 +            d'avertissement.</para></listitem>
  5.1923 +      </orderedlist>
  5.1924 +   
  5.1925 +      <para id="x_48">Si tous ces mécanismes échouent, Mercurial n'exécutera
  5.1926 +        pas la commande, affichant un message d'erreur. Dans ce cas, il ne
  5.1927 +        vous laissera pas effectuer de commit tant que vous n'aurez pas
  5.1928 +        défini un nom d'utilisateur.</para>
  5.1929 +   
  5.1930 +      <para id="x_49">Vous devriez penser à utiliser la variable
  5.1931 +        d'environement <envar>HGUSER</envar> et l'option <option role="hg-opt-commit">-u</option> comme moyen pour
  5.1932 +        <emphasis>changer</emphasis> le nom d'utilisateur par défaut. Pour
  5.1933 +        une utilisation normale, la manière la plus simple et robuste
  5.1934 +        d'opérer est de créer un fichier <filename role="special" moreinfo="none">.hgrc</filename>, voir ci-dessous pour  les détails
  5.1935 +        à ce sujet.</para>
  5.1936 +
  5.1937 +      <sect3 id="sec:tour-basic:username">
  5.1938 +        <title>Créer un fichier de configuration pour Mercurial</title>
  5.1939 +
  5.1940 +        <para id="x_4a">Pour définir un nom d'utilisateur, utilisez votre 
  5.1941 +          éditeur de texte favori pour créer un fichier <filename role="special" moreinfo="none">.hgrc</filename> dans votre répertoire home. 
  5.1942 +          Mercurial va utiliser ce fichier pour retrouver votre 
  5.1943 +          configuration personnelle. Le contenu initial devrait
  5.1944 +          ressembler à ceci :</para>
  5.1945 +   
  5.1946 +        <tip>
  5.1947 +          <title><quote>Home directory</quote> sous Windows</title>
  5.1948 +   
  5.1949 +          <para id="x_716">Quand on parle de répertoire home, sur une version
  5.1950 +            anglaise d'une installation de Windows, il s'agira habituellement
  5.1951 +            d'un répertoire nommée comme votre nom dans <filename moreinfo="none">C:\Documents 
  5.1952 +              and Settings</filename>. Vous pouvez trouver de quelle répertoire
  5.1953 +            il s'agit en lançant une fenêtre d'interpréteur de commande et en
  5.1954 +            exécutant la commande suivante :</para>
  5.1955 +          
  5.1956 +          <screen format="linespecific"><prompt moreinfo="none">C:\</prompt> <userinput moreinfo="none">echo
  5.1957 +              %UserProfile</userinput></screen>
  5.1958 +        </tip>
  5.1959 +   
  5.1960 +        <programlisting format="linespecific"># This is a Mercurial configuration file.
  5.1961 +[ui]
  5.1962 +username = Firstname Lastname &lt;email.address@domain.net&gt;</programlisting>
  5.1963 +
  5.1964 +        <para id="x_4b">La ligne avec <literal moreinfo="none">[ui]</literal> commence une
  5.1965 +          <emphasis>section</emphasis> du fichier de configuration, ainsi la ligne
  5.1966 +          <quote><literal moreinfo="none">username = ...</literal></quote> signifie <quote>
  5.1967 +            définir la valeur de l'élément <literal moreinfo="none">username</literal> dans la
  5.1968 +            section <literal moreinfo="none">ui</literal></quote>. Une section continue jusqu'à ce
  5.1969 +          qu'une nouvelle commence, ou que la fin du fichier soit atteinte.
  5.1970 +          Mercurial ignore les lignes vides et traite tout texte situé à la suite
  5.1971 +          d'un <quote><literal moreinfo="none">#</literal></quote> jusqu'à la fin de la ligne
  5.1972 +          comme un commentaire.</para>
  5.1973 +
  5.1974 +      </sect3>
  5.1975 +      <sect3>
  5.1976 +        <title>Choisir un nom d'utilisateur</title>
  5.1977 + 
  5.1978 +        <para id="x_4c">Vous pouvez utiliser n'importe quelle valeur 
  5.1979 +          pour votre <literal moreinfo="none">username</literal>, car cette information 
  5.1980 +          est destinée à d'autres personnes et non à être interprétée 
  5.1981 +          par Mercurial. La convention que la plupart des personnes
  5.1982 +          suivent est d'utiliser leurs noms suivies de leurs adresses emails,
  5.1983 +          comme montré ci-dessus :</para>
  5.1984 +        <note>
  5.1985 +          <para id="x_4d">Le mécanisme interne du serveur web intégré à Mercurial,
  5.1986 +            masque les adresses emails, pour rendre plus difficile leurs
  5.1987 +            récupérations par les outils utilisés par les spammmers.
  5.1988 +            Ceci réduit la probabilité que de recevoir encore plus de
  5.1989 +            spam si vous vous publiez un dépôt sur internet.</para>
  5.1990 +        </note>
  5.1991 +      </sect3>
  5.1992 +    </sect2>
  5.1993 +    <sect2>
  5.1994 +      <title>Rédiger un message de \textit{commit}</title>
  5.1995 +  
  5.1996 +      <para id="x_4e">Lorsqu'on effectue une opération de commit, Mercurial
  5.1997 +        lance automatiquement un éditeur de texte pour permettre de saisir
  5.1998 +        un message qui décrira les modifications effectuées dans cette
  5.1999 +        révision. Ce message est nommé le <emphasis>message de commit</emphasis>. 
  5.2000 +        Ce sera un enregistrement pour tout lecteur expliquant le pourquoi 
  5.2001 +        et le comment de vos modifications, et il sera affiché par la 
  5.2002 +        commande <command role="hg-cmd" moreinfo="none">hg log</command>.</para>
  5.2003 + 
  5.2004 +      <!-- BEGIN tour.commit -->
  5.2005 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit</userinput>
  5.2006 +</screen>
  5.2007 +<!-- END tour.commit -->
  5.2008 + 
  5.2009 +  
  5.2010 +      <para id="x_4f">L'éditeur que la commande <command role="hg-cmd" moreinfo="none">hg 
  5.2011 +          commit</command> déclenche ne contiendra qu'une ligne vide suivi 
  5.2012 +        d'un certain nombre de lignes commençant par <quote><literal moreinfo="none">HG:
  5.2013 +        </literal></quote>.</para>
  5.2014 +    
  5.2015 +        <programlisting format="linespecific">
  5.2016 +    This is where I type my commit comment.
  5.2017 +    
  5.2018 +    HG: Enter commit message.  Lines beginning with 'HG:' are removed.
  5.2019 +    HG: --
  5.2020 +    HG: user: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2021 +    HG: branch 'default'
  5.2022 +    HG: changed hello.c</programlisting>
  5.2023 +
  5.2024 +
  5.2025 +      <para id="x_50">Mercurial ignore les lignes qui commencent 
  5.2026 +        avec <quote><literal moreinfo="none">HG:</literal></quote>, il ne les 
  5.2027 +        utilise que pour nous indiquer quels fichiers modifiés il se
  5.2028 +        prépare à \textit{commiter}. Modifier ou effacer ces lignes n'a
  5.2029 +        aucune conséquence sur l'opération de commit.
  5.2030 +      </para>
  5.2031 +
  5.2032 +    </sect2>
  5.2033 +    <sect2>
  5.2034 +      <title>Rédiger un message \textit{approprié}</title>
  5.2035 +  
  5.2036 +      <para id="x_51">Comme <command role="hg-cmd" moreinfo="none">hg log</command> n'affiche
  5.2037 +        que la première ligne du message de commit par défaut, il est souvent
  5.2038 +        considéré comme une bonne pratique de rédiger des messages de commit
  5.2039 +        qui tiennent sur une seule ligne. Voilà un exemple concret de message 
  5.2040 +        de commit qui <emphasis>ne suit pas</emphasis> cette directive, et
  5.2041 +        qui a donc un résumé peu lisible.</para>
  5.2042 +
  5.2043 +      <programlisting format="linespecific">
  5.2044 +changeset:   73:584af0e231be
  5.2045 +user:        Censored Person &lt;censored.person@example.org&gt;
  5.2046 +date:        Tue Sep 26 21:37:07 2006 -0700
  5.2047 +summary:     include buildmeister/commondefs.   Add an exports and install
  5.2048 +      </programlisting>
  5.2049 +  
  5.2050 +      <para id="x_52">A ce sujet, il faut noter qu'il n'existe pas de règle 
  5.2051 +        absolue dans ce domaine. Mercurial lui-même n'interprète pas les 
  5.2052 +        contenus des messages de commit, ainsi votre projet est libre de 
  5.2053 +        concevoir différentes politiques de mise en page des messages.</para>
  5.2054 +      
  5.2055 +      <para id="x_53">Ma préférence personnelle va au message court, mais 
  5.2056 +        informatif, qui offre des précisions supplémentaires par rapport à ce 
  5.2057 +        que pourrait m'apprendre une commande <command role="hg-cmd" moreinfo="none">hg log 
  5.2058 +          --patch</command>.</para>
  5.2059 +      
  5.2060 +      <para id="x_55">Si vous exécutez la commande <command role="hg-cmd" moreinfo="none">hg
  5.2061 +          commit</command> sans aucun argument, elle enregistre tous les 
  5.2062 +        changements qui ont été fait, et qui sont indiqué par les commandes
  5.2063 +        <command role="hg-cmd" moreinfo="none">hg status</command> et  <command role="hg-cmd" moreinfo="none">hg diff</command>.</para>
  5.2064 +      
  5.2065 +      <note>
  5.2066 +        <title>Une surprise pour les utilisateurs habitués à Subversion</title>
  5.2067 +   
  5.2068 +        <para id="x_717">Comme n'importe quel autre commande de Mercurial, si
  5.2069 +          vous soumettez pas de manière explicite les noms des fichiers à
  5.2070 +          committer à la commande <command role="hg-cmd" moreinfo="none">hg commit</command>, elle
  5.2071 +          va travailler sur l'ensemble du répertoire de travail. Soyez conscient
  5.2072 +          de ceci si vous venez du monde Subversion ou CVS, car vous pourriez
  5.2073 +          attendre qu'elle opère uniquement le répertoire courant et ses sous
  5.2074 +          répertoires.</para>
  5.2075 +      </note>
  5.2076 +    </sect2>
  5.2077 +    <sect2>
  5.2078 +      <title>Annuler un \textit{commit}</title>
  5.2079 +
  5.2080 +      <para id="x_54">Si, en rédigeant le message, vous décidez que 
  5.2081 +        finalement vous ne voulez pas effectuer ce commit, il suffit 
  5.2082 +        de quitter simplement l'éditeur sans sauver. Ceci n'aura aucune 
  5.2083 +        conséquence sur le dépôt ou les fichiers du répertoire de 
  5.2084 +        travail.</para>
  5.2085 +    </sect2>
  5.2086 +  
  5.2087 +    <sect2>
  5.2088 +      <title>Admirer votre travail</title>
  5.2089 +  
  5.2090 +      <para id="x_56">Une fois que votre \textit{commit} est terminé, vous
  5.2091 +        pouvez utiliser la commande <command role="hg-cmd" moreinfo="none">hg tip</command>
  5.2092 +        pour afficher le \textit{changeset} que vous venez de créer. Cette
  5.2093 +        commande produit  une sortie à l'écran qui est identique à celle du
  5.2094 +        <command role="hg-cmd" moreinfo="none">hg log</command>, mais qui n'affiche que la
  5.2095 +        dernière révision du dépôt.</para>
  5.2096 + 
  5.2097 +      <!-- BEGIN tour.tip -->
  5.2098 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip -vp</userinput>
  5.2099 +changeset:   5:c94f208d1dfb
  5.2100 +tag:         tip
  5.2101 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2102 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2103 +files:       hello.c
  5.2104 +description:
  5.2105 +Added an extra line of output
  5.2106 +
  5.2107 +
  5.2108 +diff -r 2278160e78d4 -r c94f208d1dfb hello.c
  5.2109 +--- a/hello.c	Sat Aug 16 22:16:53 2008 +0200
  5.2110 ++++ b/hello.c	Sun Aug 16 14:05:26 2009 +0000
  5.2111 +@@ -8,5 +8,6 @@
  5.2112 + int main(int argc, char **argv)
  5.2113 + {
  5.2114 + 	printf("hello, world!\");
  5.2115 ++	printf("hello again!\n");
  5.2116 + 	return 0;
  5.2117 + }
  5.2118 +
  5.2119 +</screen>
  5.2120 +<!-- END tour.tip -->
  5.2121 + 
  5.2122 +  
  5.2123 +      <para id="x_57">On fait couramment référence à la dernière révision 
  5.2124 +        du dépôt comme étant la <emphasis>révision tip</emphasis>, ou plus
  5.2125 +        simplement le <emphasis>tip</emphasis>.</para>
  5.2126 +  
  5.2127 +      <para id="x_684">Au passage, la commande <command role="hg-cmd" moreinfo="none">hg
  5.2128 +          tip</command> accepte la plupart des options qu'accepte 
  5.2129 +        <command role="hg-cmd" moreinfo="none">hg log</command>. Ainsi <option role="hg-opt-global">-v</option> ci dessus implique <quote>soit
  5.2130 +          verbeux</quote>, <option role="hg-opt-tip">-p</option>
  5.2131 +        veux dire <quote>affiche le patch</quote>. L'utilisation de l'option
  5.2132 +        <option role="hg-opt-tip">-p</option> pour afficher un patch est un
  5.2133 +        autre exemple de la cohérence des commandes évoquée plus tôt.</para>
  5.2134 +
  5.2135 +    </sect2>
  5.2136 +  </sect1>
  5.2137 +  <sect1>
  5.2138 +    <title>Partager ses modifications</title>
  5.2139 +
  5.2140 +    <para id="x_58">Nous avons mentionné plus haut que les dépôts 
  5.2141 +      de Mercurial sont autosuffisants. Ce qui signifie que la nouvelle
  5.2142 +      révision que vous venez de créer existe seulement dans votre 
  5.2143 +      répertoire <filename class="directory" moreinfo="none">my-hello</filename>. Étudions 
  5.2144 +      comment propager cette modification dans d'autres dépôts.</para>
  5.2145 +
  5.2146 +    <sect2 id="sec:tour:pull">
  5.2147 +      <title>Récupérer les modifications d'autres dépôts</title>
  5.2148 +
  5.2149 +      <para id="x_59">Pour commencer, construisons un clone de notre dépôt 
  5.2150 +        <filename class="directory" moreinfo="none">hello</filename> qui ne contiendra pas 
  5.2151 +        le changement que nous venons d'effectuer. Nous l'appellerons notre 
  5.2152 +        dépôt temporaire <filename class="directory" moreinfo="none">hello-pull</filename>.</para>
  5.2153 + 
  5.2154 +      <!-- BEGIN tour.clone-pull -->
  5.2155 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.2156 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello hello-pull</userinput>
  5.2157 +updating working directory
  5.2158 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.2159 +</screen>
  5.2160 +<!-- END tour.clone-pull -->
  5.2161 +
  5.2162 + 
  5.2163 +      <para id="x_5a">Nous allons utiliser la commande <command role="hg-cmd" moreinfo="none">hg pull</command> pour envoyer les modifications
  5.2164 +        depuis <filename class="directory" moreinfo="none">my-hello</filename> dans <filename class="directory" moreinfo="none">hello-pull</filename>. Néanmoins, récupérer
  5.2165 +        aveuglement des modifications depuis un dépôt a quelque chose d'un
  5.2166 +        peu effrayant. Mercurial propose donc une commande <command role="hg-cmd" moreinfo="none">hg incoming</command> qui permet de savoir quelles
  5.2167 +        modifications la commande <command role="hg-cmd" moreinfo="none">hg pull</command>
  5.2168 +        <emphasis>pourrait</emphasis> entraîner dans notre dépôt, et ceci
  5.2169 +        sans effectuer réellement de modification dessus.</para>
  5.2170 +
  5.2171 +      <!-- BEGIN tour.incoming -->
  5.2172 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hello-pull</userinput>
  5.2173 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg incoming ../my-hello</userinput>
  5.2174 +comparing with ../my-hello
  5.2175 +searching for changes
  5.2176 +changeset:   5:c94f208d1dfb
  5.2177 +tag:         tip
  5.2178 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2179 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2180 +summary:     Added an extra line of output
  5.2181 +
  5.2182 +</screen>
  5.2183 +<!-- END tour.incoming -->
  5.2184 + 
  5.2185 +  
  5.2186 +      <para id="x_5c">Apporter les modifications rapatriées dans un dépôt se
  5.2187 +        résume donc à exécuter la commande <command role="hg-cmd" moreinfo="none">hg
  5.2188 +          pull</command>, et préciser depuis quel dépôt effectuer le <command role="hg-cmd" moreinfo="none">hg pull</command>.</para>
  5.2189 +      
  5.2190 +      <!-- BEGIN tour.pull -->
  5.2191 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.2192 +changeset:   4:2278160e78d4
  5.2193 +tag:         tip
  5.2194 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2195 +date:        Sat Aug 16 22:16:53 2008 +0200
  5.2196 +summary:     Trim comments.
  5.2197 +
  5.2198 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../my-hello</userinput>
  5.2199 +pulling from ../my-hello
  5.2200 +searching for changes
  5.2201 +adding changesets
  5.2202 +adding manifests
  5.2203 +adding file changes
  5.2204 +added 1 changesets with 1 changes to 1 files
  5.2205 +(run 'hg update' to get a working copy)
  5.2206 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.2207 +changeset:   5:c94f208d1dfb
  5.2208 +tag:         tip
  5.2209 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2210 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2211 +summary:     Added an extra line of output
  5.2212 +
  5.2213 +</screen>
  5.2214 +<!-- END tour.pull -->
  5.2215 +
  5.2216 +  
  5.2217 +      <para id="x_5d">Comme vous le voyez avec une sortie avant et après de la
  5.2218 +        commande <command role="hg-cmd" moreinfo="none">hg tip</command>, nous avons réussi à
  5.2219 +        récupérer aisément les modifications dans notre dépôt. Il reste néanmoins
  5.2220 +        quelque chose à faire avant de placer ces modifications dans l'espace de
  5.2221 +        travail.</para>
  5.2222 +   
  5.2223 +      <tip>
  5.2224 +        <title>Récupérer des changements précis</title>
  5.2225 +   
  5.2226 +        <para id="x_5b">Il est possible à cause du délai entre l'exécution de la
  5.2227 +          commande <command role="hg-cmd" moreinfo="none">hg incoming</command> et l'exécution de
  5.2228 +          la commande <command role="hg-cmd" moreinfo="none">hg pull</command>, que vous ne
  5.2229 +          puissiez pas voir toutes les modifications que vous rapporterez d'un
  5.2230 +          autre dépôt. Supposons que vous récupériez les modifications d'un dépôt
  5.2231 +          situé quelque part sur le réseau. Alors que vous regardez le résultat de
  5.2232 +          la commande <command role="hg-cmd" moreinfo="none">hg incoming</command>, et avant que
  5.2233 +          vous ne décidiez de récupérer ces modifications, quelqu'un peut ajouter
  5.2234 +          de nouvelles révisions dans le dépôt distant. Ce qui signifie que vous
  5.2235 +          récupérez plus de révision que ce que vous aviez regardées en utilisant
  5.2236 +          la commande <command role="hg-cmd" moreinfo="none">hg incoming</command>.</para>
  5.2237 +
  5.2238 +        <para id="x_718">Si vous voulez seulement récupérer ce que vous aviez
  5.2239 +          vérifier à l'aide de la commande <command role="hg-cmd" moreinfo="none">hg
  5.2240 +            incoming</command>, ou que pour d'autres raisons vous souhaitiez ne
  5.2241 +          récupérer qu'un sous ensemble des révisions supplémentaires
  5.2242 +          disponibles, indiquant simplement les modifications que vous souhaitez
  5.2243 +          récupérer par leurs ID de révision, soit <command moreinfo="none">hg pull
  5.2244 +            -r7e95bb</command>. </para>
  5.2245 +      </tip>
  5.2246 +  
  5.2247 +    </sect2>
  5.2248 +    <sect2>
  5.2249 +      <title>Mise à jour de l'espace de travail</title>
  5.2250 +  
  5.2251 +      <para id="x_5e">Nous avons jusqu'à maintenant grossièrement défini la
  5.2252 +        relation entre un dépôt et un espace de travail. La commande <command role="hg-cmd" moreinfo="none">hg pull</command> que nous avons exécutée dans la section 
  5.2253 +        <xref linkend="sec:tour:pull"/> a apporté des modifications, que nous
  5.2254 +        avons vérifiées, dans notre dépôt, mais il n'y a aucune trace de ces
  5.2255 +        modifications dans notre espace de travail. En effet, <command role="hg-cmd" moreinfo="none">hg pull</command> ne touche pas (par défaut) à l'espace
  5.2256 +        de travail. C'est la commande <command role="hg-cmd" moreinfo="none">hg update</command>
  5.2257 +        qui s'en charge.</para>
  5.2258 + 
  5.2259 +      <!-- BEGIN tour.update -->
  5.2260 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">grep printf hello.c</userinput>
  5.2261 +	printf("hello, world!\");
  5.2262 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update tip</userinput>
  5.2263 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.2264 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">grep printf hello.c</userinput>
  5.2265 +	printf("hello, world!\");
  5.2266 +	printf("hello again!\n");
  5.2267 +</screen>
  5.2268 +<!-- END tour.update -->
  5.2269 +
  5.2270 +  
  5.2271 +      <para id="x_5f">Il peut sembler un peu étrange que la commande <command role="hg-cmd" moreinfo="none">hg pull</command> ne mette pas à jour l'espace de travail
  5.2272 +        automatiquement. Il y a en fait une très bonne raison à cela : vous
  5.2273 +        pouvez utilisez la commande <command role="hg-cmd" moreinfo="none">hg update</command>
  5.2274 +        pour mettre à jour votre espace de travail à l'état dans lequel il était 
  5.2275 +        à <emphasis>n'importe quelle révision</emphasis> de l'historique du dépôt. 
  5.2276 +        Si vous aviez un espace de travail contenant une ancienne
  5.2277 +        révision—pour chercher l'origine d'un bug, par exemple—et
  5.2278 +        que vous effectuiez un <command role="hg-cmd" moreinfo="none">hg pull</command> qui
  5.2279 +        mettrait à jour automatiquement votre espace de travail, vous ne seriez
  5.2280 +        probablement pas très satisfait.</para>
  5.2281 +  
  5.2282 +      <para id="x_60">Néanmoins, comme les opérations de pull sont très souvent
  5.2283 +        suivies d'un update, Mercurial vous permet de combiner les
  5.2284 +        deux aisément en passant l'option <option role="hg-opt-pull">-u</option> 
  5.2285 +        à la commande <command role="hg-cmd" moreinfo="none">hg pull</command>.</para>
  5.2286 +  
  5.2287 +      <para id="x_61">Si vous étudiez de nouveau la sortie de la commande <command role="hg-cmd" moreinfo="none">hg pull</command> dans la section <xref linkend="sec:tour:pull"/> quand nous l'avons exécutée sans l'option
  5.2288 +        <option role="hg-opt-pull">-u</option>, vous pouvez constater qu'elle a
  5.2289 +        affiché un rappel assez utile : vous devez encore effectuer une
  5.2290 +        opération pour mettre à jour votre espace de travail.</para>
  5.2291 +
  5.2292 +      <para id="x_62">Pour découvrir sur quelle révision de l'espace de 
  5.2293 +        travail on se trouve, utilisez la commande <command role="hg-cmd" moreinfo="none">hg
  5.2294 +          parents</command>.</para>
  5.2295 + 
  5.2296 +      <!-- BEGIN tour.parents -->
  5.2297 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.2298 +changeset:   5:c94f208d1dfb
  5.2299 +tag:         tip
  5.2300 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2301 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2302 +summary:     Added an extra line of output
  5.2303 +
  5.2304 +</screen>
  5.2305 +<!-- END tour.parents -->
  5.2306 +
  5.2307 +   
  5.2308 +      <para id="x_63">Si vous regardez de nouveau le dessin <xref linkend="fig:tour-basic:history"/>, vous verrez les flèches reliant
  5.2309 +        entre elles les révisions. Le nœud d'où la flèche
  5.2310 +        <emphasis>part</emphasis> est dans chaque cas un parent,
  5.2311 +        et le nœud où la flèche <emphasis>arrive</emphasis> est un
  5.2312 +        enfant.</para>
  5.2313 +
  5.2314 +      <para id="x_64">Pour mettre à jour l'espace de travail d'une révision
  5.2315 +        particulière, indiquez un numéro de révision ou un \textit{changeset
  5.2316 +        ID} à la commande <command role="hg-cmd" moreinfo="none">hg update</command>.</para>
  5.2317 +  
  5.2318 +      <!-- BEGIN tour.older -->
  5.2319 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update 2</userinput>
  5.2320 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.2321 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.2322 +changeset:   2:fef857204a0c
  5.2323 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2324 +date:        Sat Aug 16 22:05:04 2008 +0200
  5.2325 +summary:     Introduce a typo into hello.c.
  5.2326 +
  5.2327 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update</userinput>
  5.2328 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.2329 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.2330 +changeset:   5:c94f208d1dfb
  5.2331 +tag:         tip
  5.2332 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2333 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2334 +summary:     Added an extra line of output
  5.2335 +
  5.2336 +</screen>
  5.2337 +<!-- END tour.older -->
  5.2338 +
  5.2339 +   
  5.2340 +      <para id="x_65">Si vous ne précisez pas de manière explicite de numéro 
  5.2341 +        de révision la commande <command role="hg-cmd" moreinfo="none">hg update</command>
  5.2342 +        mettra à jour votre espace de travail avec le contenu de la révison
  5.2343 +        \textit{tip}, comme montré dans l'exemple ci dessus lors du second
  5.2344 +        appel à <command role="hg-cmd" moreinfo="none">hg update</command>.</para>
  5.2345 +    
  5.2346 +    </sect2>
  5.2347 +    <sect2>
  5.2348 +      <title>Transférer les modifications vers un autre dépôt</title>
  5.2349 +  
  5.2350 +      <para id="x_66">Mercurial vous laisse transférer les modifications vers
  5.2351 +        un autre dépôt, depuis votre dépôt actuel. Comme dans l'exemple du
  5.2352 +        <command role="hg-cmd" moreinfo="none">hg pull</command> ci-dessus, nous allons créer
  5.2353 +        un dépôt temporaire vers lequel transférer nos modifications.</para>
  5.2354 +        
  5.2355 +      <!-- BEGIN tour.clone-push -->
  5.2356 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.2357 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello hello-push</userinput>
  5.2358 +updating working directory
  5.2359 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.2360 +</screen>
  5.2361 +<!-- END tour.clone-push -->
  5.2362 +
  5.2363 +  
  5.2364 +      <para id="x_67">La commande <command role="hg-cmd" moreinfo="none">hg outgoing</command>
  5.2365 +        nous indique quels changements nous allons transférer vers l'autre
  5.2366 +        serveur.</para>
  5.2367 + 
  5.2368 +      <!-- BEGIN tour.outgoing -->
  5.2369 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-hello</userinput>
  5.2370 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg outgoing ../hello-push</userinput>
  5.2371 +comparing with ../hello-push
  5.2372 +searching for changes
  5.2373 +changeset:   5:c94f208d1dfb
  5.2374 +tag:         tip
  5.2375 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2376 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2377 +summary:     Added an extra line of output
  5.2378 +
  5.2379 +</screen>
  5.2380 +<!-- END tour.outgoing -->
  5.2381 +
  5.2382 +  
  5.2383 +      <para id="x_68">Et la commande <command role="hg-cmd" moreinfo="none">hg push</command> 
  5.2384 +        effectue réellement le transfert.</para>
  5.2385 + 
  5.2386 +      <!-- BEGIN tour.push -->
  5.2387 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push ../hello-push</userinput>
  5.2388 +pushing to ../hello-push
  5.2389 +searching for changes
  5.2390 +adding changesets
  5.2391 +adding manifests
  5.2392 +adding file changes
  5.2393 +added 1 changesets with 1 changes to 1 files
  5.2394 +</screen>
  5.2395 +<!-- END tour.push -->
  5.2396 +
  5.2397 +  
  5.2398 +      <para id="x_69">Comme avec <command role="hg-cmd" moreinfo="none">hg pull</command>, la
  5.2399 +        commande <command role="hg-cmd" moreinfo="none">hg push</command> ne met pas à jour
  5.2400 +        le répertoire de travail du dépôt dans lequel il transfère les
  5.2401 +        modifications. À l'inverse de <command role="hg-cmd" moreinfo="none">hg
  5.2402 +          pull</command>, <command role="hg-cmd" moreinfo="none">hg push</command> ne fournit
  5.2403 +        pas d'option <literal moreinfo="none">-u</literal> pour forcer la mise à jour de
  5.2404 +        l'espace de travail cible. Cette asymétrie est délibéré : le dépot
  5.2405 +        vers lequel nous transférons peut très bien être un serveur distant
  5.2406 +        et partagé par plusieurs personnes. Si nous devions mettre à jour son
  5.2407 +        répertoire de travail alors que quelqu'un d'autre travaille dessus,
  5.2408 +        nous risquerions de perturber son travail.</para>
  5.2409 +  
  5.2410 +      <para id="x_6a">Qu'est ce qui se passe lorsque vous essayez de récupérer
  5.2411 +        ou de transférer vos modifications et que le dépôt cible a déjà reçu
  5.2412 +        ces modifications ? Rien de bien excitant.</para>
  5.2413 + 
  5.2414 +      <!-- BEGIN tour.push.nothing -->
  5.2415 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push ../hello-push</userinput>
  5.2416 +pushing to ../hello-push
  5.2417 +searching for changes
  5.2418 +no changes found
  5.2419 +</screen>
  5.2420 +<!-- END tour.push.nothing -->
  5.2421 +
  5.2422 +  
  5.2423 +    </sect2>
  5.2424 +  
  5.2425 +    <sect2>
  5.2426 +      <title>Emplacements par défaut</title>
  5.2427 +
  5.2428 +      <para id="x_719">Quand nous faisons un clone d'un dépôt, Mercurial
  5.2429 +        enregistre l'emplacement du dépôt d'origine dans le fichier
  5.2430 +        <filename moreinfo="none">.hg/hgrc</filename> de notre nouveau dépôt. Si nous ne
  5.2431 +        fournissons pas d'emplacement à la commande <command moreinfo="none">hg
  5.2432 +          pull</command> ou à la commande <command moreinfo="none">hg push</command>, ces
  5.2433 +        commandes utiliseront alors cet emplacement comme valeur par défaut.
  5.2434 +        Les commandes <command moreinfo="none">hg incoming</command> et <command moreinfo="none">hg
  5.2435 +          outgoing</command> feront de même.</para>
  5.2436 +  
  5.2437 +      <para id="x_71a">Si vous regardez le fichier
  5.2438 +        <filename moreinfo="none">.hg/hgrc</filename>, vous constaterez que son contenu
  5.2439 +        ressemble à ce qui suit.</para>
  5.2440 +  
  5.2441 +      <programlisting format="linespecific">[paths]
  5.2442 +default = http://www.selenic.com/repo/hg</programlisting>
  5.2443 +      
  5.2444 +      <para id="x_71b">Il est possible—et souvent
  5.2445 +        pratique—d'avoir un emplacement par défaut pour les commandes
  5.2446 +        <command moreinfo="none">hg push</command> et <command moreinfo="none">hg outgoing</command>
  5.2447 +        différent de celui des commandes <command moreinfo="none">hg pull</command> et
  5.2448 +        <command moreinfo="none">hg incoming</command>. C'est faisable en ajoutant une entrée
  5.2449 +        <literal moreinfo="none">default-push</literal> à la section
  5.2450 +        <literal moreinfo="none">[paths]</literal> du <filename moreinfo="none">.hg/hgrc</filename>, comme
  5.2451 +        suit.</para>
  5.2452 +   
  5.2453 +      <programlisting format="linespecific">[paths]
  5.2454 +default = http://www.selenic.com/repo/hg
  5.2455 +default-push = http://hg.example.com/hg</programlisting>
  5.2456 +
  5.2457 +    </sect2>
  5.2458 +    <sect2>
  5.2459 +      <title>Partager ses modifications à travers le réseau</title>
  5.2460 +  
  5.2461 +      <para id="x_6b">Les commandes que nous avons étudiées dans les sections
  5.2462 +        précédentes ne sont pas limitées aux dépôts locaux. Chacune fonctionne 
  5.2463 +        de la même manière à travers une connexion réseau, il suffit de lui 
  5.2464 +        passer une URL à la place d'un chemin de fichier local.</para>
  5.2465 + 
  5.2466 +      <!-- BEGIN tour.outgoing.net -->
  5.2467 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg outgoing http://hg.serpentine.com/tutorial/hello</userinput>
  5.2468 +comparing with http://hg.serpentine.com/tutorial/hello
  5.2469 +searching for changes
  5.2470 +changeset:   5:c94f208d1dfb
  5.2471 +tag:         tip
  5.2472 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2473 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2474 +summary:     Added an extra line of output
  5.2475 +
  5.2476 +</screen>
  5.2477 +<!-- END tour.outgoing.net -->
  5.2478 +
  5.2479 +  
  5.2480 +      <para id="x_6c">Dans cet exemple, nous allons voir quels changements 
  5.2481 +        nous pourrions transférer vers le dépôt distant, mais le dépôt est, 
  5.2482 +        de manière tout à fait compréhensible, pas configuré pour accepter 
  5.2483 +        des modifications d'utilisateurs anonymes.</para>
  5.2484 + 
  5.2485 +      <!-- BEGIN tour.push.net -->
  5.2486 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push http://hg.serpentine.com/tutorial/hello</userinput>
  5.2487 +pushing to http://hg.serpentine.com/tutorial/hello
  5.2488 +searching for changes
  5.2489 +ssl required
  5.2490 +</screen>
  5.2491 +<!-- END tour.push.net -->
  5.2492 + 
  5.2493 +    
  5.2494 +    </sect2>
  5.2495 +
  5.2496 +  </sect1>
  5.2497 +
  5.2498 +  <sect1>
  5.2499 +    <title>Commencer un nouveau projet</title>
  5.2500 +
  5.2501 +    <para id="x_71c">Il est tout aussi aisé de commencer un nouveau projet
  5.2502 +      que de travailler sur un qui existe déjà. La commande <command moreinfo="none">hg
  5.2503 +        init</command> crée un nouveau dépôt Mercurial vide.</para>
  5.2504 +
  5.2505 +    <!-- BEGIN ch01/new.init -->
  5.2506 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init myproject</userinput>
  5.2507 +</screen>
  5.2508 +<!-- END ch01/new.init -->
  5.2509 +
  5.2510 +
  5.2511 +    <para id="x_71d">Ceci crée simplement un répertoire nommé
  5.2512 +      <filename moreinfo="none">myproject</filename> dans le répertoire courant.</para>
  5.2513 +
  5.2514 +    <!-- BEGIN ch01/new.ls -->
  5.2515 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -l</userinput>
  5.2516 +total 12
  5.2517 +-rw-r--r-- 1 rpelisse rpelisse   47 Aug 16 14:04 goodbye.c
  5.2518 +-rw-r--r-- 1 rpelisse rpelisse   45 Aug 16 14:04 hello.c
  5.2519 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:04 myproject
  5.2520 +</screen>
  5.2521 +<!-- END ch01/new.ls -->
  5.2522 +
  5.2523 +
  5.2524 +    <para id="x_71e">Nous pouvons dire que <filename moreinfo="none">myproject</filename> est
  5.2525 +      un dépôt Mercurial car il contient un répertoire
  5.2526 +      <filename moreinfo="none">.hg</filename>.</para>
  5.2527 +
  5.2528 +    <!-- BEGIN ch01/new.ls2 -->
  5.2529 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -al myproject</userinput>
  5.2530 +total 12
  5.2531 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:04 .
  5.2532 +drwx------ 3 rpelisse rpelisse 4096 Aug 16 14:04 ..
  5.2533 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:04 .hg
  5.2534 +</screen>
  5.2535 +<!-- END ch01/new.ls2 -->
  5.2536 +
  5.2537 +
  5.2538 +    <para id="x_71f">Si vous voulons ajouter quelques fichiers préexistants
  5.2539 +      dans ce dépôt, il suffit de les recopier dans le répertoire de travail,
  5.2540 +      et demander à Mercurial de commencer à les suivre en utilisant la
  5.2541 +      commande <command moreinfo="none">hg add</command>.</para>
  5.2542 +
  5.2543 +    <!-- BEGIN ch01/new.add -->
  5.2544 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myproject</userinput>
  5.2545 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cp ../hello.c .</userinput>
  5.2546 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cp ../goodbye.c .</userinput>
  5.2547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add</userinput>
  5.2548 +adding goodbye.c
  5.2549 +adding hello.c
  5.2550 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.2551 +A goodbye.c
  5.2552 +A hello.c
  5.2553 +</screen>
  5.2554 +<!-- END ch01/new.add -->
  5.2555 +
  5.2556 +
  5.2557 +    <para id="x_720">Une fois que nous sommes satisfaits de notre projet,
  5.2558 +      nous pouvons commencer à ajouter nos révisions.</para>
  5.2559 +
  5.2560 +    <!-- BEGIN ch01/new.commit -->
  5.2561 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Initial commit'</userinput>
  5.2562 +</screen>
  5.2563 +<!-- END ch01/new.commit -->
  5.2564 +
  5.2565 +
  5.2566 +    <para id="x_721">Il ne prend que quelques instants pour commencer à
  5.2567 +      utiliser Mercurial sur un nouveau projet, ce qui fait aussi de ses
  5.2568 +      points forts. Travailler avec une gestion de révision devient très
  5.2569 +      facile, nous pouvons même l'utiliser pour les plus petits projets où
  5.2570 +      nous aurions probablement jamais penser utiliser un outils aussi
  5.2571 +      complexe.</para>
  5.2572 +  </sect1>
  5.2573 +</chapter>
  5.2574 +
  5.2575 +<!--
  5.2576 +local variables: 
  5.2577 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.2578 +end:
  5.2579 +-->
  5.2580 +
  5.2581 +  <!-- BEGIN ch03 -->
  5.2582 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.2583 +
  5.2584 +<chapter id="chap:tour-merge">
  5.2585 +  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
  5.2586 +  <title>Un rapide tour de Mercurial: fusionner les travaux</title>
  5.2587 +  
  5.2588 +  <para id="x_338">Nous avons maintenant étudié comment cloner un dépôt, effectuer
  5.2589 +    des changements dedans, et récupérer ou transférer depuis un
  5.2590 +    autre dépôt. La prochaine étape est donc de <emphasis>fusionner</emphasis> les
  5.2591 +    modifications de différents dépôts.</para>
  5.2592 +
  5.2593 +  <sect1>
  5.2594 +    <title>Fusionner différents travaux</title>
  5.2595 +      <para id="x_339">La fusion  est un aspect fondamental lorsqu'on
  5.2596 +      travaille iavec un gestionnaire de source distribué.</para>
  5.2597 +
  5.2598 +      <itemizedlist>
  5.2599 +        <listitem>
  5.2600 +          <para id="x_33a">Alice et Bob ont chacun une copie personnelle du dépôt d'un
  5.2601 +            projet sur lequel ils collaborent. Alice corrige un bug
  5.2602 +            dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
  5.2603 +            sien. Ils veulent un dépôt partagé avec à la fois le correctif du
  5.2604 +            bug et la nouvelle fonctionnalité.</para>
  5.2605 +       </listitem>
  5.2606 +       <listitem>
  5.2607 +         <para id="x_33b">Je travaille régulièrement sur plusieurs tâches différentes sur
  5.2608 +           un seul projet en même temps, chacun isolé dans son propre dépôt.
  5.2609 +           Travailler ainsi signifie que je dois régulièrement fusionner une
  5.2610 +           partie de mon code avec celui des autres.</para>
  5.2611 +       </listitem>
  5.2612 +     </itemizedlist>
  5.2613 +
  5.2614 +     <para id="x_33c">Parce que la fusion est une opération si commune à réaliser,
  5.2615 +       Mercurial la rend facile. Étudions ensemble le déroulement des
  5.2616 +       opérations. Nous commencerons encore par faire un clone d'un autre
  5.2617 +       dépôt (vous voyez que l'on fait ça tout le temps ?) puis nous ferons 
  5.2618 +       quelques modifications dessus.</para>
  5.2619 +       
  5.2620 +       <!-- BEGIN tour.merge.clone -->
  5.2621 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.2622 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello my-new-hello</userinput>
  5.2623 +updating working directory
  5.2624 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.2625 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-new-hello</userinput>
  5.2626 +# Make some simple edits to hello.c.
  5.2627 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">my-text-editor hello.c</userinput>
  5.2628 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'A new hello for a new day.'</userinput>
  5.2629 +</screen>
  5.2630 +<!-- END tour.merge.clone -->
  5.2631 +
  5.2632 +       
  5.2633 +     <para id="x_33d">Nous devrions avoir maintenant deux copies de
  5.2634 +       <filename moreinfo="none">hello.c</filename> avec des contenus différents. Les
  5.2635 +       historiques de ces deux dépôts ont aussi divergés, comme illustré dans
  5.2636 +       la figure <xref linkend="fig:tour-merge:sep-repos"/>.</para>
  5.2637 +
  5.2638 +      <!-- BEGIN tour.merge.cat1 -->
  5.2639 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  5.2640 +/*
  5.2641 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  5.2642 + * not covered by patents in the United States or other countries.
  5.2643 + */
  5.2644 +
  5.2645 +#include &lt;stdio.h&gt;
  5.2646 +
  5.2647 +int main(int argc, char **argv)
  5.2648 +{
  5.2649 +	printf("once more, hello.\n");
  5.2650 +	printf("hello, world!\");
  5.2651 +	printf("hello again!\n");
  5.2652 +	return 0;
  5.2653 +}
  5.2654 +</screen>
  5.2655 +<!-- END tour.merge.cat1 -->
  5.2656 +
  5.2657 +     
  5.2658 +     <para id="x_722">Et ici est notre légèrement différente version du
  5.2659 +       dépôt.</para>
  5.2660 +     
  5.2661 +      <!-- BEGIN tour.merge.cat2 -->
  5.2662 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat ../my-hello/hello.c</userinput>
  5.2663 +/*
  5.2664 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  5.2665 + * not covered by patents in the United States or other countries.
  5.2666 + */
  5.2667 +
  5.2668 +#include &lt;stdio.h&gt;
  5.2669 +
  5.2670 +int main(int argc, char **argv)
  5.2671 +{
  5.2672 +	printf("hello, world!\");
  5.2673 +	printf("hello again!\n");
  5.2674 +	return 0;
  5.2675 +}
  5.2676 +</screen>
  5.2677 +<!-- END tour.merge.cat2 -->
  5.2678 +
  5.2679 +     
  5.2680 +     <figure id="fig:tour-merge:sep-repos" float="0">
  5.2681 +       <title>Historique divergent des dépôts <filename class="directory" moreinfo="none">my-hello</filename> et <filename class="directory" moreinfo="none">my-new-hello</filename>.</title>
  5.2682 +       <mediaobject>
  5.2683 +         <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
  5.2684 +         <textobject><phrase>XXX ajoute un test</phrase></textobject>
  5.2685 +       </mediaobject>
  5.2686 +     </figure>
  5.2687 +
  5.2688 +     <para id="x_33f">Nous savons déjà que récupérer les modifications depuis
  5.2689 +       notre dépôt <filename class="directory" moreinfo="none">my-hello</filename> n'aura
  5.2690 +       aucun effet sur l'espace de travail.</para>
  5.2691 +
  5.2692 +      <!-- BEGIN tour.merge.pull -->
  5.2693 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../my-hello</userinput>
  5.2694 +pulling from ../my-hello
  5.2695 +searching for changes
  5.2696 +adding changesets
  5.2697 +adding manifests
  5.2698 +adding file changes
  5.2699 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.2700 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.2701 +</screen>
  5.2702 +<!-- END tour.merge.pull -->
  5.2703 +
  5.2704 +
  5.2705 +     <para id="x_340">Néanmoins, la commande <command role="hg-cmd" moreinfo="none">hg
  5.2706 +       pull</command> nous indique quelque chose au sujet des 
  5.2707 +       <quote>heads</quote>.</para>
  5.2708 +
  5.2709 +     <sect2>
  5.2710 +       <title>Les révisions 'heads'</title>
  5.2711 +
  5.2712 +       <para id="x_341">Rappellez vous que Mercurial enregistre quelle révision
  5.2713 +         est le parent de chaque révision. Si une révision a un parent, nous
  5.2714 +         l'appelons un enfant(child) ou un descendant de ce parent. Une
  5.2715 +         "head" est une révision qui n'a donc pas d'enfant. La révision tip
  5.2716 +         est donc une "head", car c'est la révision la plus récente du dépôt
  5.2717 +         qui n'a pas d'enfant. Il y a des moments où un dépôt peut contenir
  5.2718 +         plusieurs "head".</para>
  5.2719 +
  5.2720 +       <figure id="fig:tour-merge:pull" float="0">
  5.2721 +         <title>Contenu du dépôt après une récupération ("pull") depuis le
  5.2722 +           dépôt <filename class="directory" moreinfo="none">my-hello</filename> vers le dépôt <filename class="directory" moreinfo="none">my-new-hello</filename></title>
  5.2723 +         <mediaobject>
  5.2724 +           <imageobject>
  5.2725 +             <imagedata fileref="tour-merge-pull"/>
  5.2726 +           </imageobject>
  5.2727 +           <textobject><phrase>XXX ajoute un texte</phrase></textobject>
  5.2728 +         </mediaobject>
  5.2729 +       </figure>
  5.2730 +
  5.2731 +       <para id="x_343">Dans la figure <xref linkend="fig:tour-merge:pull"/>,
  5.2732 +         vous pouvez constater l'effet d'un \textit{pull} depuis le dépôt
  5.2733 +         <filename class="directory" moreinfo="none">my-hello</filename> dans le dépôt
  5.2734 +         <filename class="directory" moreinfo="none">my-new-hello</filename>. L'historique qui
  5.2735 +         était déjà présent dans le dépôt <filename class="directory" moreinfo="none">my-new-hello</filename> reste intact, mais une
  5.2736 +         nouvelle révision a été ajoutée. En vous reportant à la figure <xref linkend="fig:tour-merge:sep-repos"/>, vous pouvez voir que le
  5.2737 +         <emphasis>ID de révision (changeset ID)</emphasis> reste le même dans
  5.2738 +         le nouveau dépôt, mais que le <emphasis>numéro de
  5.2739 +         révision</emphasis> reste le même. (Ceci est un parfait exemple de
  5.2740 +         pourquoi il n'est fiable d'utiliser les numéros de révision lorsque
  5.2741 +         l'on discute d'un \textit{changeset}.) Vous pouvez voir les "heads"
  5.2742 +         présentes dans le dépôt en utilisant la commande <command role="hg-cmd" moreinfo="none">hg heads</command>.</para>
  5.2743 +
  5.2744 +        <!-- BEGIN tour.merge.heads -->
  5.2745 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  5.2746 +changeset:   6:c94f208d1dfb
  5.2747 +tag:         tip
  5.2748 +parent:      4:2278160e78d4
  5.2749 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2750 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2751 +summary:     Added an extra line of output
  5.2752 +
  5.2753 +changeset:   5:5f06f94fbeca
  5.2754 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2755 +date:        Sun Aug 16 14:05:31 2009 +0000
  5.2756 +summary:     A new hello for a new day.
  5.2757 +
  5.2758 +</screen>
  5.2759 +<!-- END tour.merge.heads -->
  5.2760 +
  5.2761 +      </sect2>
  5.2762 +
  5.2763 +      <sect2>
  5.2764 +        <title>Effectuer la fusion</title>
  5.2765 +
  5.2766 +        <para id="x_344">Que se passe-t-il quand vous essayez d'utiliser la
  5.2767 +          commande <command role="hg-cmd" moreinfo="none">hg update</command> pour mettre à
  5.2768 +          jour votre espace de travail au nouveau "tip"</para>
  5.2769 +         
  5.2770 +         <!-- BEGIN tour.merge.update -->
  5.2771 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update</userinput>
  5.2772 +abort: crosses branches (use 'hg merge' or 'hg update -C')
  5.2773 +</screen>
  5.2774 +<!-- END tour.merge.update -->
  5.2775 +
  5.2776 +
  5.2777 +         
  5.2778 +        <para id="x_345">Mercurial nous prévient que la commande <command role="hg-cmd" moreinfo="none">hg update</command> n'effectuera pas
  5.2779 +          la fusion, il ne veut pas mettre à jour l'espace de travail quand il
  5.2780 +          estime que nous pourrions avoir besoin d'une fusion, à moins de lui
  5.2781 +          forcer la main. À la place, il faut utiliser la commande <command role="hg-cmd" moreinfo="none">hg merge</command> pour fusionner les deux
  5.2782 +          "heads".</para>
  5.2783 +
  5.2784 +       <para id="x_723">Pour commencer une fusion (merge) entre deux "heads",
  5.2785 +       nous utilisons la commande <command role="hg-cmd" moreinfo="none">hg merge</command>.</para>
  5.2786 +
  5.2787 +        <!-- BEGIN tour.merge.merge -->
  5.2788 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.2789 +merging hello.c
  5.2790 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  5.2791 +(branch merge, don't forget to commit)
  5.2792 +</screen>
  5.2793 +<!-- END tour.merge.merge -->
  5.2794 + 
  5.2795 +      
  5.2796 +       <para id="x_347">Nous résolvons les conflits dans le fichier
  5.2797 +         <filename moreinfo="none">hello.c</filename>. Ceci met à jour le répertoire de travail
  5.2798 +         de sorte qu'il ne contienne les modifications ne provenance des
  5.2799 +         <emphasis>deux</emphasis> "heads", ce qui est indiqué par la
  5.2800 +         la sortie de la commande <command role="hg-cmd" moreinfo="none">hg
  5.2801 +         parents</command> et le contenu du fichier
  5.2802 +         <filename moreinfo="none">hello.c</filename>.</para>
  5.2803 +
  5.2804 +        <!-- BEGIN tour.merge.parents -->
  5.2805 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.2806 +changeset:   5:5f06f94fbeca
  5.2807 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2808 +date:        Sun Aug 16 14:05:31 2009 +0000
  5.2809 +summary:     A new hello for a new day.
  5.2810 +
  5.2811 +changeset:   6:c94f208d1dfb
  5.2812 +tag:         tip
  5.2813 +parent:      4:2278160e78d4
  5.2814 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2815 +date:        Sun Aug 16 14:05:26 2009 +0000
  5.2816 +summary:     Added an extra line of output
  5.2817 +
  5.2818 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  5.2819 +/*
  5.2820 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  5.2821 + * not covered by patents in the United States or other countries.
  5.2822 + */
  5.2823 +
  5.2824 +#include &lt;stdio.h&gt;
  5.2825 +
  5.2826 +int main(int argc, char **argv)
  5.2827 +{
  5.2828 +	printf("once more, hello.\n");
  5.2829 +	printf("hello, world!\");
  5.2830 +	printf("hello again!\n");
  5.2831 +	return 0;
  5.2832 +}
  5.2833 +</screen>
  5.2834 +<!-- END tour.merge.parents -->
  5.2835 +
  5.2836 +     </sect2>
  5.2837 +
  5.2838 +     <sect2>
  5.2839 +       <title>Effectuer l'ajout (commit) du résultat de la fusion</title>
  5.2840 +
  5.2841 +       <para id="x_348">Dès l'instant où vous avez effectué une fusion
  5.2842 +         (merge), <command role="hg-cmd" moreinfo="none">hg parents</command> vous
  5.2843 +         affichera deux parents, avant que vous n'exécutiez la commande
  5.2844 +         <command role="hg-cmd" moreinfo="none">hg commit</command> sur le résultat de la
  5.2845 +         fusion.</para>
  5.2846 +
  5.2847 +        <!-- BEGIN tour.merge.commit -->
  5.2848 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Merged changes'</userinput>
  5.2849 +</screen>
  5.2850 +<!-- END tour.merge.commit -->
  5.2851 +
  5.2852 +
  5.2853 +      <para id="x_349">Nous avons maintenant un nouveau tip, remarquer qu'il
  5.2854 +        contient <emphasis>à la fois</emphasis> nos anciennes "heads" et leurs
  5.2855 +        parents. Ce sont les mêmes révisions que nous avions affichées avec
  5.2856 +        la commande <command role="hg-cmd" moreinfo="none">hg parents</command>.</para>
  5.2857 +
  5.2858 +       <!-- BEGIN tour.merge.tip -->
  5.2859 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.2860 +changeset:   7:b8e1e756ef55
  5.2861 +tag:         tip
  5.2862 +parent:      5:5f06f94fbeca
  5.2863 +parent:      6:c94f208d1dfb
  5.2864 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.2865 +date:        Sun Aug 16 14:05:33 2009 +0000
  5.2866 +summary:     Merged changes
  5.2867 +
  5.2868 +</screen>
  5.2869 +<!-- END tour.merge.tip -->
  5.2870 +
  5.2871 +
  5.2872 +      <para id="x_34a">Dans la figure <xref linkend="fig:tour-merge:merge"/>,
  5.2873 +        vous pouvez voir une représentation de ce qui se passe dans l'espace
  5.2874 +        de travail pendant la fusion, et comment ceci affecte le dépôt lors
  5.2875 +        du "commit". Pendant la fusion, l'espace de travail, qui a deux
  5.2876 +        révisions (changesets) comme parents, voit ces derniers devenir le parent
  5.2877 +        d'une nouvelle révision (changeset).</para>
  5.2878 +
  5.2879 +      <figure id="fig:tour-merge:merge" float="0">
  5.2880 +        <title>Working directory and repository during merge, and
  5.2881 +          following commit</title>
  5.2882 +        <mediaobject>
  5.2883 +          <imageobject>
  5.2884 +            <imagedata fileref="figs/tour-merge-merge.png"/>
  5.2885 +          </imageobject>
  5.2886 +          <textobject><phrase>XXX ajoute texte</phrase></textobject>
  5.2887 +        </mediaobject>
  5.2888 +      </figure>
  5.2889 +
  5.2890 +    </sect2>
  5.2891 +  </sect1>
  5.2892 +
  5.2893 +  <sect1>
  5.2894 +    <title>Fusionner les modifications en conflit</title>
  5.2895 +
  5.2896 +    <para id="x_34b">La plupart des fusions sont assez simple à réaliser, mais 
  5.2897 +      parfois vous vous retrouverez à fusionner des fichiers où la modification 
  5.2898 +      touche la même portion de code, au sein d'un même fichier. À moins 
  5.2899 +      que ces modification ne soient identiques, ceci aboutira à un 
  5.2900 +      <emphasis>conflit</emphasis>, et vous devrez décider comment réconcilier 
  5.2901 +      les différentes modifications dans un tout cohérent.</para>
  5.2902 +
  5.2903 +    <figure id="fig:tour-merge:conflict" float="0">
  5.2904 +      <title>Modifications en conflits dans un document</title>
  5.2905 +      <mediaobject>
  5.2906 +        <imageobject><imagedata fileref="tour-merge-conflict"/></imageobject>
  5.2907 +        <textobject><phrase>XXX ajoute texte</phrase></textobject>
  5.2908 +      </mediaobject>
  5.2909 +    </figure>
  5.2910 +
  5.2911 +    <para id="x_34d">La figure <xref linkend="fig:tour-merge:conflict"/>
  5.2912 +      illustre un cas de modifications conflictuelles dans un document. Nous
  5.2913 +      avons commencé avec une version simple de ce fichier, puis nous avons
  5.2914 +      ajouté des modifications, pendant que quelqu'un d'autre modifiait le même
  5.2915 +      texte. Notre tâche dans la résolution du conflit est de décider à quoi le
  5.2916 +      fichier devrait ressembler.</para>
  5.2917 +
  5.2918 +    <para id="x_34e">Mercurial n'a pas de mécanisme interne pour gérer 
  5.2919 +      les conflits. À la place, il exécute un programme externe appelé 
  5.2920 +      <command moreinfo="none">hgmerge</command>. Il s'agit d'un script shell qui est 
  5.2921 +      embarqué par Mercurial, vous pouvez le modifier si vous le voulez. 
  5.2922 +      Ce qu'il fait par défaut est d'essayer de trouver un des différents 
  5.2923 +      outils de fusion qui seront probablement installés sur le système. 
  5.2924 +      Il commence par les outils totalement automatiques, et si ils 
  5.2925 +      échouent (parce que la résolution du conflit nécessite une
  5.2926 +      intervention humaine) ou si ils sont absents, le script tente
  5.2927 +      d'exécuter certains outils graphiques de fusion.</para>
  5.2928 +
  5.2929 +    <para id="x_34f">Il est aussi possible de demander à Mercurial d'exécuter
  5.2930 +      un autre programme ou un autre script en définissant la variable
  5.2931 +      d'environnement <envar>HGMERGE</envar> avec le nom
  5.2932 +      du programme de votre choix.</para>
  5.2933 +
  5.2934 +    <sect2>
  5.2935 +      <title>Utiliser un outil graphique de fusion</title>
  5.2936 +
  5.2937 +      <para id="x_350">Mon outil de fusion préféré est
  5.2938 +      <command moreinfo="none">kdiff3</command>, que j'utilise ici pour illustrer les
  5.2939 +        fonctionnalités classiques des outils graphiques de fusion. Vous pouvez
  5.2940 +        voir une capture d'écran de l'utilisation de <command moreinfo="none">kdiff3</command>
  5.2941 +        dans la figure <xref linkend="fig:tour-merge:kdiff3"/>. Cet outil
  5.2942 +        effectue une <emphasis>fusion \textit{three-way</emphasis>}, car il y a
  5.2943 +        trois différentes versions du fichier qui nous intéresse. Le fichier
  5.2944 +        découpe la partie supérieure de la fenêtre en trois panneaux:</para>
  5.2945 +      <itemizedlist>
  5.2946 +        <listitem><para id="x_351">A gauche on la version de
  5.2947 +          <emphasis>base</emphasis> du fichier, soit la plus récente version
  5.2948 +          des deux versions qu'on souhaite fusionner.</para></listitem>
  5.2949 +        <listitem><para id="x_352">Au centre, il y a <quote>notre</quote>
  5.2950 +          version du fichier, avec le contenu que nous avons modifié.</para></listitem>
  5.2951 +        <listitem><para id="x_353">Sur la droite, on trouve
  5.2952 +        <quote>leur</quote> version du fichier, celui qui contient la
  5.2953 +        révision que nous souhaitons intégré.</para>
  5.2954 +        </listitem></itemizedlist>
  5.2955 +      <para id="x_354">Dans le panneau en dessous, on trouve le
  5.2956 +        <emphasis>résultat</emphasis> actuel de notre fusion. Notre tâche
  5.2957 +        consiste donc à remplacement tous les textes en rouges,
  5.2958 +        qui indiquent des conflits non résolus, avec une fusion manuelle et 
  5.2959 +        pertinente de <quote>notre</quote> version et de la <quote>leur</quote>.
  5.2960 +      </para>
  5.2961 +
  5.2962 +      <para id="x_355">Tous les quatre panneaux sont <emphasis>accrochés ensemble</emphasis>, 
  5.2963 +        si nous déroulons les ascenseurs verticalement ou horizontalement dans chacun 
  5.2964 +        d'entre eux, les autres sont mis à jour avec la section correspondante dans leurs 
  5.2965 +        fichiers respectifs.</para>
  5.2966 +
  5.2967 +      <figure id="fig:tour-merge:kdiff3" float="0">
  5.2968 +        <title>Utiliser <command moreinfo="none">kdiff3</command> pour fusionner les
  5.2969 +          différentes version d'un fichier.</title>
  5.2970 +        <mediaobject>
  5.2971 +          <imageobject>
  5.2972 +            <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
  5.2973 +            <textobject>
  5.2974 +              <phrase>XXX ajoute texte</phrase>
  5.2975 +            </textobject>
  5.2976 +          </mediaobject>
  5.2977 +       </figure>
  5.2978 +
  5.2979 +       <para id="x_357">Pour chaque portion de fichier posant problème, nous
  5.2980 +         pouvons choisir de résoudre le conflit en utilisant une combinaison de
  5.2981 +         texte depuis la version de base, la notre, ou la leur. Nous pouvons
  5.2982 +         aussi éditer manuellement les fichiers à tout moment, si c'est nécessaire.</para>
  5.2983 +
  5.2984 +       <para id="x_358">Il y a <emphasis>beaucoup</emphasis> d'outils de
  5.2985 +         fusion disponibles, bien trop pour en parler de tous ici. Leurs
  5.2986 +         disponibilités varient selon les plate formes  ainsi que leurs
  5.2987 +         avantages et inconvénients. La plupart sont optimisé pour
  5.2988 +         la fusion de fichier contenant un texte plat, certains sont spécialisé
  5.2989 +         dans un format de fichier précis (généralement XML).</para>
  5.2990 +    </sect2>
  5.2991 +
  5.2992 +    <sect2>
  5.2993 +      <title>Un exemple concret</title>
  5.2994 +
  5.2995 +      <para id="x_359">Dans cet exemple, nous allons reproduire la
  5.2996 +        modification de l'historique du fichier de la figure <xref linkend="fig:tour-merge:conflict"/> ci dessus. Commençons par créer
  5.2997 +        un dépôt avec une version de base de notre document.</para>
  5.2998 +
  5.2999 +      <!-- BEGIN tour-merge-conflict.wife -->
  5.3000 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  5.3001 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  5.3002 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Mariam Abacha, the wife of former</userinput>
  5.3003 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  5.3004 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  5.3005 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add letter.txt</userinput>
  5.3006 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m '419 scam, first draft'</userinput>
  5.3007 +</screen>
  5.3008 +<!-- END tour-merge-conflict.wife -->
  5.3009 + 
  5.3010 +
  5.3011 +      <para id="x_35a">Créons un clone de ce dépôt et faisons une
  5.3012 +        modification dans le fichier.</para>
  5.3013 +
  5.3014 +      <!-- BEGIN tour-merge-conflict.cousin -->
  5.3015 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.3016 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone scam scam-cousin</userinput>
  5.3017 +updating working directory
  5.3018 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.3019 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd scam-cousin</userinput>
  5.3020 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  5.3021 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  5.3022 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Shehu Musa Abacha, cousin to the former</userinput>
  5.3023 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  5.3024 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  5.3025 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m '419 scam, with cousin'</userinput>
  5.3026 +</screen>
  5.3027 +<!-- END tour-merge-conflict.cousin -->
  5.3028 +
  5.3029 +      
  5.3030 +      <para id="x_35b">Et un autre clone, pour simuler que quelqu'un d'autre effectue une
  5.3031 +        modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
  5.3032 +        de devoir effectuer des fusions (merges) avec vos propres travaux quand
  5.3033 +        vous isolez les tâches dans des dépôts distincts. En effet, vous
  5.3034 +        aurez alors à trouver et résoudre certains conflits).</para>
  5.3035 +
  5.3036 +      <!-- BEGIN tour-merge-conflict.son -->
  5.3037 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.3038 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone scam scam-son</userinput>
  5.3039 +updating working directory
  5.3040 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.3041 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd scam-son</userinput>
  5.3042 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  5.3043 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  5.3044 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Alhaji Abba Abacha, son of the former</userinput>
  5.3045 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  5.3046 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  5.3047 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m '419 scam, with son'</userinput>
  5.3048 +</screen>
  5.3049 +<!-- END tour-merge-conflict.son -->
  5.3050 +
  5.3051 +
  5.3052 +      <para id="x_35c">Maintenant que ces deux versions différentes du même fichier sont
  5.3053 +        créées, nous allons configurer l'environnement de manière appropriée pour
  5.3054 +        exécuter notre fusion (merge).</para>
  5.3055 +
  5.3056 +      <!-- BEGIN tour-merge-conflict.pull -->
  5.3057 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.3058 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone scam-cousin scam-merge</userinput>
  5.3059 +updating working directory
  5.3060 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.3061 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd scam-merge</userinput>
  5.3062 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../scam-son</userinput>
  5.3063 +pulling from ../scam-son
  5.3064 +searching for changes
  5.3065 +adding changesets
  5.3066 +adding manifests
  5.3067 +adding file changes
  5.3068 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.3069 +not updating, since new heads added
  5.3070 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.3071 +</screen>
  5.3072 +<!-- END tour-merge-conflict.pull -->
  5.3073 +
  5.3074 +
  5.3075 +      <para id="x_35d">Dans cette exemple, je n'utiliserais pas la commande Mercurial
  5.3076 +        habituelle <command moreinfo="none">hgmerge</command> pour effectuer le
  5.3077 +        fusion (merge), car il me faudrait abandonner ce joli petit exemple automatisé
  5.3078 +        pour utiliser un outil graphique. À la place, je vais définir la
  5.3079 +        variable d'environnement <envar>HGMERGE</envar> pour indiquer à
  5.3080 +        Mercurial d'utiliser la commande non-interactive <command moreinfo="none">merge</command>.
  5.3081 +        Cette dernière est embarquée par de nombreux systèmes <quote>à la Unix</quote>.
  5.3082 +        Si vous exécutez cet exemple depuis votre ordinateur, ne vous
  5.3083 +        occupez pas de définir <envar>HGMERGE</envar>.</para>
  5.3084 +
  5.3085 +     <!-- BEGIN tour-merge-conflict.merge -->
  5.3086 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">export HGMERGE=merge</userinput>
  5.3087 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.3088 +merging letter.txt
  5.3089 +merge: warning: conflicts during merge
  5.3090 +merging letter.txt failed!
  5.3091 +0 files updated, 0 files merged, 0 files removed, 1 files unresolved
  5.3092 +use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
  5.3093 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat letter.txt</userinput>
  5.3094 +Greetings!
  5.3095 +&lt;&lt;&lt;&lt;&lt;&lt;&lt; /tmp/tour-merge-conflictk3twLJ/scam-merge/letter.txt
  5.3096 +I am Shehu Musa Abacha, cousin to the former
  5.3097 +=======
  5.3098 +I am Alhaji Abba Abacha, son of the former
  5.3099 +&gt;&gt;&gt;&gt;&gt;&gt;&gt; /tmp/letter.txt~other.4O623C
  5.3100 +Nigerian dictator Sani Abacha.
  5.3101 +</screen>
  5.3102 +<!-- END tour-merge-conflict.merge -->
  5.3103 + 
  5.3104 +
  5.3105 +
  5.3106 +     <para id="x_35f">Parce que <command moreinfo="none">merge</command> ne peut pas résoudre
  5.3107 +       les modifications conflictuelles, il laisse des <emphasis>marqueurs de
  5.3108 +       différences</emphasis> à l'intérieur du fichier qui a des conflits,
  5.3109 +       indiquant clairement quelles lignes sont en conflits, et si elles
  5.3110 +       viennent de notre fichier ou du fichier externe.
  5.3111 +     </para>
  5.3112 +
  5.3113 +     <para id="x_360">Mercurial peut distinguer, à la manière dont la
  5.3114 +       commande <command moreinfo="none">merge</command> se termine, qu'elle n'a pas été
  5.3115 +       capable d'effectuer la fusion (merge), alors il nous indique que nous
  5.3116 +       devons effectuer de nouveau cette opération. Ceci peut être très utile
  5.3117 +       si, par exemple, nous exécutons un outil graphique de fusion et que
  5.3118 +       nous le quittons sans nous rendre compte qu'il reste des conflits ou 
  5.3119 +       simplement par erreur.</para>
  5.3120 +
  5.3121 +     <para id="x_361">Si la fusion (merge) automatique ou manuelle échoue, 
  5.3122 +       il n'y a rien pour nous empêcher de <quote>corriger le tir</quote> en
  5.3123 +       modifiant nous même les fichiers, et enfin effectuer le "commit" du 
  5.3124 +       fichier:</para>
  5.3125 +
  5.3126 +     <!-- BEGIN tour-merge-conflict.commit -->
  5.3127 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  5.3128 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  5.3129 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Bryan O'Sullivan, no relation of the former</userinput>
  5.3130 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  5.3131 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  5.3132 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg resolve -m letter.txt</userinput>
  5.3133 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Send me your money'</userinput>
  5.3134 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.3135 +changeset:   3:0954bda76c6b
  5.3136 +tag:         tip
  5.3137 +parent:      1:1ac156b6e708
  5.3138 +parent:      2:7ee20631b33b
  5.3139 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.3140 +date:        Sun Aug 16 14:05:34 2009 +0000
  5.3141 +summary:     Send me your money
  5.3142 +
  5.3143 +</screen>
  5.3144 +<!-- END tour-merge-conflict.commit -->
  5.3145 +
  5.3146 +
  5.3147 +     <note>
  5.3148 +       <title>Où est la <command moreinfo="none">hg resolve</command> ?</title>
  5.3149 +       
  5.3150 +       <para id="x_724">La commande <command moreinfo="none">hg resolve</command> a été
  5.3151 +         introduit dans la version 1.1 de Mercurial, qui a été publié en
  5.3152 +         décembre 2008. Si vous utilisez une version plus anciennne de
  5.3153 +         Mercurial (exécutez la command <command moreinfo="none">hg version</command> pour en
  5.3154 +         avoir le coeur net), cette commande ne sera pas disponible. Si votre
  5.3155 +         version de Mercurial est plus ancienne que la 1.1, vous devriez très
  5.3156 +         fortement considérer une mise à jour à une version plus récente avant
  5.3157 +         d'essayer de régler des fusions complexes.</para>
  5.3158 +       </note>
  5.3159 +     </sect2>
  5.3160 +   </sect1>
  5.3161 +
  5.3162 +   <sect1 id="sec:tour-merge:fetch">
  5.3163 +     <title>Simplification de la séquence pull-merge-commit</title>
  5.3164 +
  5.3165 +     <para id="x_362">La procédure pour effectuer la fusion indiquée
  5.3166 +       ci-dessus est simple, mais requiert le lancement de trois commandes à la
  5.3167 +       suite.</para>
  5.3168 +
  5.3169 +     <programlisting format="linespecific">hg pull -u
  5.3170 +hg merge
  5.3171 +hg commit -m 'Merged remote changes'</programlisting>
  5.3172 +
  5.3173 +     <para id="x_363">Lors du "commit" final, vous devez également saisir un
  5.3174 +       message, qui aura vraisemblablement assez peu d'intérêt.</para>
  5.3175 +
  5.3176 +     <para id="x_364">Il serait assez sympathique de pouvoir réduire le
  5.3177 +       nombre d'opérations nécessaire, si possible. De fait Mercurial est
  5.3178 +       fourni avec une extension appelé <literal role="hg-ext" moreinfo="none">fetch</literal>
  5.3179 +       qui fait justement cela.</para>
  5.3180 +
  5.3181 +     <para id="x_365">Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
  5.3182 +       d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
  5.3183 +       léger et facile à utiliser. Certains extensions ajoutent de nouvelles
  5.3184 +       commandes que vous pouvez utiliser en ligne de commande, alors que
  5.3185 +       d'autres travaillent <quote>en coulisse,</quote> par exemple en ajoutant des
  5.3186 +       possibilités au serveur.</para>
  5.3187 +
  5.3188 +     <para id="x_366">L'extension <literal role="hg-ext" moreinfo="none">fetch</literal>
  5.3189 +       ajoute une nouvelle commande nommée, sans surprise, <command role="hg-cmd" moreinfo="none">hg fetch</command>. Cette extension résulte en une
  5.3190 +       combinaison de <command role="hg-cmd" moreinfo="none">hg pull</command>, <command role="hg-cmd" moreinfo="none">hg update</command> and <command role="hg-cmd" moreinfo="none">hg
  5.3191 +       merge</command>. Elle commence par récupérer les modifications d'un
  5.3192 +       autre dépôt dans le dépôt courant. Si elle trouve que les
  5.3193 +       modifications ajoutent une nouvelle "head", elle effectue un "merge",
  5.3194 +       et ensuite "commit" le résultat du "merge" avec un message généré
  5.3195 +       automatiquement. Si aucune "head" n'ont été ajouté, elle met à jour le
  5.3196 +       répertoire de travail au niveau de la nouvelle révision tip.</para>
  5.3197 +     
  5.3198 +     <para id="x_367">Activer l'extension <literal role="hg-ext" moreinfo="none">fetch</literal> est facile. Modifiez votre <filename role="special" moreinfo="none">.hgrc</filename>, et soit allez à la section <literal role="rc-extensions" moreinfo="none">extensions</literal> soit créer une section
  5.3199 +       <literal role="rc-extensions" moreinfo="none">extensions</literal>. Ensuite ajoutez
  5.3200 +       une ligne qui consiste simplement en <quote>\Verb+fetch =</quote>.</para>
  5.3201 +
  5.3202 +     <programlisting format="linespecific">[extensions]
  5.3203 +fetch =</programlisting>
  5.3204 +
  5.3205 +    <para id="x_368">(Normalement, sur la partie droite de
  5.3206 +      <quote><literal moreinfo="none">=</literal></quote> devrait apparaître le chemin de
  5.3207 +      l'extension, mais étant donné que l'extension <literal role="hg-ext" moreinfo="none">fetch</literal> fait partie de la distribution standard,
  5.3208 +      Mercurial sait où la trouver.) </para>
  5.3209 +
  5.3210 +  </sect1>
  5.3211 +  
  5.3212 +  <sect1>
  5.3213 +    <title>Renommer, copier, et fusionner (merge)</title>
  5.3214 +
  5.3215 +    <para id="x_729">En cours de la vie d'un projet, nous allons souvent 
  5.3216 +      vouloir changer la disposition de ses fichiers et de ses répertoires. 
  5.3217 +      Ceci peut être aussi simple que de changer le nom d'un seul fichier, 
  5.3218 +      et aussi compliqué que de restructurer une hiérarchie entiere de fichier
  5.3219 +      au sein du projet.</para>
  5.3220 +
  5.3221 +    <para id="x_72a">Mercurial permet de faire ce genre de modification de
  5.3222 +      manière fluide, à condition de l'informer de ce que nous faisons. Si 
  5.3223 +      vous voulez renommenr un ficher, vous devriez utiliser les commande
  5.3224 +      <command moreinfo="none">hg rename</command><footnote>
  5.3225 +        <para id="x_72b">Si vous un utilisateur de Unix, vous serez content
  5.3226 +          de savoir que la commande  <command moreinfo="none">hg rename</command> command 
  5.3227 +          peut être abrégée en <command moreinfo="none">hg mv</command>.</para>
  5.3228 +      </footnote> pour changer son nom, ainsi Mercurial peut ensuite prendre
  5.3229 +      la bonne décision, plus tard, en cas de fusionv (merge).</para>
  5.3230 +
  5.3231 +    <para id="x_72c">Nous étudierojns en détail l'utilisation de ces commandes, 
  5.3232 +      en détail, dans le chapitre <xref linkend="chap:daily.copy"/>.</para>
  5.3233 +  </sect1>
  5.3234 +</chapter>
  5.3235 +
  5.3236 +<!--
  5.3237 +local variables: 
  5.3238 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.3239 +end:
  5.3240 +-->
  5.3241 +
  5.3242 +  <!-- BEGIN ch04 -->
  5.3243 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.3244 +
  5.3245 +<chapter id="chap:concepts">
  5.3246 +  <?dbhtml filename="behind-the-scenes.html"?>
  5.3247 +  <title>Derrière le décor</title>
  5.3248 +  
  5.3249 +  <para id="x_2e8">À la différence de beaucoup d'outils de gestion de versions,
  5.3250 +    les concepts sur lesquels se base Mercurial sont assez simples pour
  5.3251 +    qu'il soit facile de comprendre comment le logiciel fonctionne.
  5.3252 +    Bien que leur connaissance ne soit pas nécéssaire, je trouve utile
  5.3253 +    d'avoir un <quote>modèle mental</quote> de ce qui se passe.</para>
  5.3254 +
  5.3255 +  <para id="x_2e9">En effet, cette compréhension m'apporte la confiance que
  5.3256 +    Mercurial a été développé avec soin pour être à la fois
  5.3257 +    <emphasis>sûr</emphasis> et <emphasis>efficace</emphasis>. De surcroît,
  5.3258 +    si il m'est facile de garder en tête ce que le logiciel fait lorsque
  5.3259 +    j'accompli des tâches de révision, j'aurai moins de risques d'être
  5.3260 +    surpris par son comportement.</para>
  5.3261 +
  5.3262 +  <para id="x_2ea">Dans ce chapitre, nous décrirons tout d'abord les concepts
  5.3263 +    essentiels de l'architecture de Mercurial, pour ensuite discuter quelques
  5.3264 +    uns des détails intéressants de son implémentation.</para>
  5.3265 +
  5.3266 +  <sect1>
  5.3267 +    <title>Conservation de l'historique sous Mercurial</title>
  5.3268 +    <sect2>
  5.3269 +      <title>Suivi de l'historique pour un seul fichier</title>
  5.3270 +      
  5.3271 +      <para id="x_2eb">Lorsque Mercurial effectue un suivi des modifications
  5.3272 +        faites à un fichier, il conserve l'historique pour ce fichier dans un
  5.3273 +        <emphasis>filelog</emphasis> sous forme de métadonnées. Chaque entrée
  5.3274 +        dans le filelog contient assez d'informations pour reconstituer une
  5.3275 +        révision du fichier correspondant. Les filelogs sont des fichiers
  5.3276 +        stockés dans le répertoire  <filename role="special" class="directory" moreinfo="none">.hg/store/data</filename>. Un filelog contient
  5.3277 +        des informations de deux types: les données de révision, et un index
  5.3278 +        pour permettre à Mercurial une recherche efficace d'une révision
  5.3279 +        donnée.</para>
  5.3280 +
  5.3281 +      <para id="x_2ec">Lorsqu'un fichier devient trop gros ou a un long
  5.3282 +        historique, son filelog se voit stocker dans un fichier de données
  5.3283 +        (avec un suffixe <quote><literal moreinfo="none">.d</literal></quote>) et un fichier
  5.3284 +        index (avec un suffixe<quote><literal moreinfo="none">.i</literal></quote>)
  5.3285 +        distincts. La relation entre un fichier dans le répertoire de travail
  5.3286 +        et le  filelog couvrant le suivi de son historique dans le dépôt est
  5.3287 +        illustré à la figure <xref linkend="fig:concepts:filelog"/>.</para>
  5.3288 +
  5.3289 +      <figure id="fig:concepts:filelog" float="0">
  5.3290 +        <title>Relations entre les fichiers dans le répertoire de travail et
  5.3291 +        leurs filelogs dans le dépôt</title> 
  5.3292 +        <mediaobject> <imageobject><imagedata fileref="figs/filelog.png"/></imageobject>
  5.3293 +          <textobject><phrase>XXX add text</phrase></textobject>
  5.3294 +        </mediaobject> </figure>
  5.3295 +
  5.3296 +    </sect2>
  5.3297 +    <sect2>
  5.3298 +      <title>Gestion des fichiers suivis</title>
  5.3299 +      
  5.3300 +      <para id="x_2ee">Mercurial a recours à une structure nommée
  5.3301 +        <emphasis>manifest</emphasis> pour rassembler les informations sur
  5.3302 +        les fichiers dont il gère le suivi. Chaque entrée dans ce manifest
  5.3303 +        contient des informations sur les fichiers présents dans une révision
  5.3304 +        donnée. Une entrée store la liste des fichiers faisant partie de la
  5.3305 +        révision, la version de chaque fichier, et quelques autres
  5.3306 +        métadonnées sur ces fichiers.</para>
  5.3307 +
  5.3308 +    </sect2>
  5.3309 +    <sect2>
  5.3310 +      <title>Recording changeset information</title>
  5.3311 +
  5.3312 +      <para id="x_2ef">The <emphasis>changelog</emphasis> contains
  5.3313 +        information about each changeset.  Each revision records who
  5.3314 +        committed a change, the changeset comment, other pieces of
  5.3315 +        changeset-related information, and the revision of the manifest to
  5.3316 +        use.</para>
  5.3317 +
  5.3318 +    </sect2>
  5.3319 +    <sect2>
  5.3320 +      <title>Relationships between revisions</title>
  5.3321 +
  5.3322 +      <para id="x_2f0">Within a changelog, a manifest, or a filelog, each
  5.3323 +	revision stores a pointer to its immediate parent (or to its
  5.3324 +	two parents, if it's a merge revision).  As I mentioned above,
  5.3325 +	there are also relationships between revisions
  5.3326 +	<emphasis>across</emphasis> these structures, and they are
  5.3327 +	hierarchical in nature.</para>
  5.3328 +
  5.3329 +      <para id="x_2f1">For every changeset in a repository, there is exactly one
  5.3330 +	revision stored in the changelog.  Each revision of the
  5.3331 +	changelog contains a pointer to a single revision of the
  5.3332 +	manifest.  A revision of the manifest stores a pointer to a
  5.3333 +	single revision of each filelog tracked when that changeset
  5.3334 +	was created.  These relationships are illustrated in
  5.3335 +	<xref linkend="fig:concepts:metadata"/>.</para>
  5.3336 +
  5.3337 +      <figure id="fig:concepts:metadata" float="0">
  5.3338 +	<title>Metadata relationships</title>
  5.3339 +	<mediaobject>
  5.3340 +	  <imageobject><imagedata fileref="figs/metadata.png"/></imageobject>
  5.3341 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3342 +	</mediaobject>
  5.3343 +      </figure>
  5.3344 +
  5.3345 +      <para id="x_2f3">As the illustration shows, there is
  5.3346 +	<emphasis>not</emphasis> a <quote>one to one</quote>
  5.3347 +	relationship between revisions in the changelog, manifest, or
  5.3348 +	filelog. If a file that
  5.3349 +	Mercurial tracks hasn't changed between two changesets, the
  5.3350 +	entry for that file in the two revisions of the manifest will
  5.3351 +	point to the same revision of its filelog<footnote>
  5.3352 +	  <para id="x_725">It is possible (though unusual) for the manifest to
  5.3353 +	    remain the same between two changesets, in which case the
  5.3354 +	    changelog entries for those changesets will point to the
  5.3355 +	    same revision of the manifest.</para>
  5.3356 +	</footnote>.</para>
  5.3357 +
  5.3358 +    </sect2>
  5.3359 +  </sect1>
  5.3360 +  <sect1>
  5.3361 +    <title>Safe, efficient storage</title>
  5.3362 +
  5.3363 +    <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are
  5.3364 +      provided by a single structure called the
  5.3365 +      <emphasis>revlog</emphasis>.</para>
  5.3366 +
  5.3367 +    <sect2>
  5.3368 +      <title>Efficient storage</title>
  5.3369 +
  5.3370 +      <para id="x_2f5">The revlog provides efficient storage of revisions using a
  5.3371 +	<emphasis>delta</emphasis> mechanism.  Instead of storing a
  5.3372 +	complete copy of a file for each revision, it stores the
  5.3373 +	changes needed to transform an older revision into the new
  5.3374 +	revision.  For many kinds of file data, these deltas are
  5.3375 +	typically a fraction of a percent of the size of a full copy
  5.3376 +	of a file.</para>
  5.3377 +
  5.3378 +      <para id="x_2f6">Some obsolete revision control systems can only work with
  5.3379 +	deltas of text files.  They must either store binary files as
  5.3380 +	complete snapshots or encoded into a text representation, both
  5.3381 +	of which are wasteful approaches.  Mercurial can efficiently
  5.3382 +	handle deltas of files with arbitrary binary contents; it
  5.3383 +	doesn't need to treat text as special.</para>
  5.3384 +
  5.3385 +    </sect2>
  5.3386 +    <sect2 id="sec:concepts:txn">
  5.3387 +      <title>Safe operation</title>
  5.3388 +
  5.3389 +      <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to
  5.3390 +	the end of a revlog file. It never modifies a section of a
  5.3391 +	file after it has written it.  This is both more robust and
  5.3392 +	efficient than schemes that need to modify or rewrite
  5.3393 +	data.</para>
  5.3394 +
  5.3395 +      <para id="x_2f8">In addition, Mercurial treats every write as part of a
  5.3396 +	<emphasis>transaction</emphasis> that can span a number of
  5.3397 +	files.  A transaction is <emphasis>atomic</emphasis>: either
  5.3398 +	the entire transaction succeeds and its effects are all
  5.3399 +	visible to readers in one go, or the whole thing is undone.
  5.3400 +	This guarantee of atomicity means that if you're running two
  5.3401 +	copies of Mercurial, where one is reading data and one is
  5.3402 +	writing it, the reader will never see a partially written
  5.3403 +	result that might confuse it.</para>
  5.3404 +
  5.3405 +      <para id="x_2f9">The fact that Mercurial only appends to files makes it
  5.3406 +	easier to provide this transactional guarantee.  The easier it
  5.3407 +	is to do stuff like this, the more confident you should be
  5.3408 +	that it's done correctly.</para>
  5.3409 +
  5.3410 +    </sect2>
  5.3411 +    <sect2>
  5.3412 +      <title>Fast retrieval</title>
  5.3413 +
  5.3414 +      <para id="x_2fa">Mercurial cleverly avoids a pitfall common to
  5.3415 +	all earlier revision control systems: the problem of
  5.3416 +	<emphasis>inefficient retrieval</emphasis>. Most revision
  5.3417 +	control systems store the contents of a revision as an
  5.3418 +	incremental series of modifications against a
  5.3419 +	<quote>snapshot</quote>.  (Some base the snapshot on the
  5.3420 +	oldest revision, others on the newest.)  To reconstruct a
  5.3421 +	specific revision, you must first read the snapshot, and then
  5.3422 +	every one of the revisions between the snapshot and your
  5.3423 +	target revision.  The more history that a file accumulates,
  5.3424 +	the more revisions you must read, hence the longer it takes to
  5.3425 +	reconstruct a particular revision.</para>
  5.3426 +
  5.3427 +      <figure id="fig:concepts:snapshot" float="0">
  5.3428 +	<title>Snapshot of a revlog, with incremental deltas</title>
  5.3429 +	<mediaobject>
  5.3430 +	  <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject>
  5.3431 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3432 +	</mediaobject>
  5.3433 +      </figure>
  5.3434 +
  5.3435 +      <para id="x_2fc">The innovation that Mercurial applies to this problem is
  5.3436 +	simple but effective.  Once the cumulative amount of delta
  5.3437 +	information stored since the last snapshot exceeds a fixed
  5.3438 +	threshold, it stores a new snapshot (compressed, of course),
  5.3439 +	instead of another delta.  This makes it possible to
  5.3440 +	reconstruct <emphasis>any</emphasis> revision of a file
  5.3441 +	quickly.  This approach works so well that it has since been
  5.3442 +	copied by several other revision control systems.</para>
  5.3443 +
  5.3444 +      <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates
  5.3445 +	the idea.  In an entry in a revlog's index file, Mercurial
  5.3446 +	stores the range of entries from the data file that it must
  5.3447 +	read to reconstruct a particular revision.</para>
  5.3448 +
  5.3449 +      <sect3>
  5.3450 +	<title>Aside: the influence of video compression</title>
  5.3451 +
  5.3452 +	<para id="x_2fe">If you're familiar with video compression or
  5.3453 +	  have ever watched a TV feed through a digital cable or
  5.3454 +	  satellite service, you may know that most video compression
  5.3455 +	  schemes store each frame of video as a delta against its
  5.3456 +	  predecessor frame.</para>
  5.3457 +
  5.3458 +	<para id="x_2ff">Mercurial borrows this idea to make it
  5.3459 +	  possible to reconstruct a revision from a snapshot and a
  5.3460 +	  small number of deltas.</para>
  5.3461 +
  5.3462 +      </sect3>
  5.3463 +    </sect2>
  5.3464 +    <sect2>
  5.3465 +      <title>Identification and strong integrity</title>
  5.3466 +
  5.3467 +      <para id="x_300">Along with delta or snapshot information, a revlog entry
  5.3468 +	contains a cryptographic hash of the data that it represents.
  5.3469 +	This makes it difficult to forge the contents of a revision,
  5.3470 +	and easy to detect accidental corruption.</para>
  5.3471 +
  5.3472 +      <para id="x_301">Hashes provide more than a mere check against corruption;
  5.3473 +	they are used as the identifiers for revisions.  The changeset
  5.3474 +	identification hashes that you see as an end user are from
  5.3475 +	revisions of the changelog.  Although filelogs and the
  5.3476 +	manifest also use hashes, Mercurial only uses these behind the
  5.3477 +	scenes.</para>
  5.3478 +
  5.3479 +      <para id="x_302">Mercurial verifies that hashes are correct when it
  5.3480 +	retrieves file revisions and when it pulls changes from
  5.3481 +	another repository.  If it encounters an integrity problem, it
  5.3482 +	will complain and stop whatever it's doing.</para>
  5.3483 +
  5.3484 +      <para id="x_303">In addition to the effect it has on retrieval efficiency,
  5.3485 +	Mercurial's use of periodic snapshots makes it more robust
  5.3486 +	against partial data corruption.  If a revlog becomes partly
  5.3487 +	corrupted due to a hardware error or system bug, it's often
  5.3488 +	possible to reconstruct some or most revisions from the
  5.3489 +	uncorrupted sections of the revlog, both before and after the
  5.3490 +	corrupted section.  This would not be possible with a
  5.3491 +	delta-only storage model.</para>
  5.3492 +    </sect2>
  5.3493 +  </sect1>
  5.3494 +
  5.3495 +  <sect1>
  5.3496 +    <title>Revision history, branching, and merging</title>
  5.3497 +
  5.3498 +    <para id="x_304">Every entry in a Mercurial revlog knows the identity of its
  5.3499 +      immediate ancestor revision, usually referred to as its
  5.3500 +      <emphasis>parent</emphasis>.  In fact, a revision contains room
  5.3501 +      for not one parent, but two.  Mercurial uses a special hash,
  5.3502 +      called the <quote>null ID</quote>, to represent the idea
  5.3503 +      <quote>there is no parent here</quote>.  This hash is simply a
  5.3504 +      string of zeroes.</para>
  5.3505 +
  5.3506 +    <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see
  5.3507 +      an example of the conceptual structure of a revlog.  Filelogs,
  5.3508 +      manifests, and changelogs all have this same structure; they
  5.3509 +      differ only in the kind of data stored in each delta or
  5.3510 +      snapshot.</para>
  5.3511 +
  5.3512 +    <para id="x_306">The first revision in a revlog (at the bottom of the image)
  5.3513 +      has the null ID in both of its parent slots.  For a
  5.3514 +      <quote>normal</quote> revision, its first parent slot contains
  5.3515 +      the ID of its parent revision, and its second contains the null
  5.3516 +      ID, indicating that the revision has only one real parent.  Any
  5.3517 +      two revisions that have the same parent ID are branches.  A
  5.3518 +      revision that represents a merge between branches has two normal
  5.3519 +      revision IDs in its parent slots.</para>
  5.3520 +
  5.3521 +    <figure id="fig:concepts:revlog" float="0">
  5.3522 +      <title>The conceptual structure of a revlog</title>
  5.3523 +      <mediaobject>
  5.3524 +	<imageobject><imagedata fileref="figs/revlog.png"/></imageobject>
  5.3525 +	<textobject><phrase>XXX add text</phrase></textobject>
  5.3526 +      </mediaobject>
  5.3527 +    </figure>
  5.3528 +
  5.3529 +  </sect1>
  5.3530 +  <sect1>
  5.3531 +    <title>The working directory</title>
  5.3532 +
  5.3533 +    <para id="x_307">In the working directory, Mercurial stores a snapshot of the
  5.3534 +      files from the repository as of a particular changeset.</para>
  5.3535 +
  5.3536 +    <para id="x_308">The working directory <quote>knows</quote> which changeset
  5.3537 +      it contains.  When you update the working directory to contain a
  5.3538 +      particular changeset, Mercurial looks up the appropriate
  5.3539 +      revision of the manifest to find out which files it was tracking
  5.3540 +      at the time that changeset was committed, and which revision of
  5.3541 +      each file was then current.  It then recreates a copy of each of
  5.3542 +      those files, with the same contents it had when the changeset
  5.3543 +      was committed.</para>
  5.3544 +
  5.3545 +    <para id="x_309">The <emphasis>dirstate</emphasis> is a special
  5.3546 +      structure that contains Mercurial's knowledge of the working
  5.3547 +      directory.  It is maintained as a file named
  5.3548 +      <filename moreinfo="none">.hg/dirstate</filename> inside a repository.  The
  5.3549 +      dirstate details which changeset the working directory is
  5.3550 +      updated to, and all of the files that Mercurial is tracking in
  5.3551 +      the working directory. It also lets Mercurial quickly notice
  5.3552 +      changed files, by recording their checkout times and
  5.3553 +      sizes.</para>
  5.3554 +
  5.3555 +    <para id="x_30a">Just as a revision of a revlog has room for two parents, so
  5.3556 +      that it can represent either a normal revision (with one parent)
  5.3557 +      or a merge of two earlier revisions, the dirstate has slots for
  5.3558 +      two parents.  When you use the <command role="hg-cmd" moreinfo="none">hg
  5.3559 +	update</command> command, the changeset that you update to is
  5.3560 +      stored in the <quote>first parent</quote> slot, and the null ID
  5.3561 +      in the second. When you <command role="hg-cmd" moreinfo="none">hg
  5.3562 +	merge</command> with another changeset, the first parent
  5.3563 +      remains unchanged, and the second parent is filled in with the
  5.3564 +      changeset you're merging with.  The <command role="hg-cmd" moreinfo="none">hg
  5.3565 +	parents</command> command tells you what the parents of the
  5.3566 +      dirstate are.</para>
  5.3567 +
  5.3568 +    <sect2>
  5.3569 +      <title>What happens when you commit</title>
  5.3570 +
  5.3571 +      <para id="x_30b">The dirstate stores parent information for more than just
  5.3572 +	book-keeping purposes.  Mercurial uses the parents of the
  5.3573 +	dirstate as <emphasis>the parents of a new
  5.3574 +	  changeset</emphasis> when you perform a commit.</para>
  5.3575 +
  5.3576 +      <figure id="fig:concepts:wdir" float="0">
  5.3577 +	<title>The working directory can have two parents</title>
  5.3578 +	<mediaobject>
  5.3579 +	  <imageobject><imagedata fileref="figs/wdir.png"/></imageobject>
  5.3580 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3581 +	</mediaobject>
  5.3582 +      </figure>
  5.3583 +
  5.3584 +      <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the
  5.3585 +	normal state of the working directory, where it has a single
  5.3586 +	changeset as parent.  That changeset is the
  5.3587 +	<emphasis>tip</emphasis>, the newest changeset in the
  5.3588 +	repository that has no children.</para>
  5.3589 +
  5.3590 +      <figure id="fig:concepts:wdir-after-commit" float="0">
  5.3591 +	<title>The working directory gains new parents after a
  5.3592 +	  commit</title>
  5.3593 +	<mediaobject>
  5.3594 +	  <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject>
  5.3595 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3596 +	</mediaobject>
  5.3597 +      </figure>
  5.3598 +
  5.3599 +      <para id="x_30f">It's useful to think of the working directory as
  5.3600 +	<quote>the changeset I'm about to commit</quote>.  Any files
  5.3601 +	that you tell Mercurial that you've added, removed, renamed,
  5.3602 +	or copied will be reflected in that changeset, as will
  5.3603 +	modifications to any files that Mercurial is already tracking;
  5.3604 +	the new changeset will have the parents of the working
  5.3605 +	directory as its parents.</para>
  5.3606 +
  5.3607 +      <para id="x_310">After a commit, Mercurial will update the
  5.3608 +	parents of the working directory, so that the first parent is
  5.3609 +	the ID of the new changeset, and the second is the null ID.
  5.3610 +	This is shown in <xref linkend="fig:concepts:wdir-after-commit"/>. Mercurial
  5.3611 +	doesn't touch any of the files in the working directory when
  5.3612 +	you commit; it just modifies the dirstate to note its new
  5.3613 +	parents.</para>
  5.3614 +
  5.3615 +    </sect2>
  5.3616 +    <sect2>
  5.3617 +      <title>Creating a new head</title>
  5.3618 +
  5.3619 +      <para id="x_311">It's perfectly normal to update the working directory to a
  5.3620 +	changeset other than the current tip.  For example, you might
  5.3621 +	want to know what your project looked like last Tuesday, or
  5.3622 +	you could be looking through changesets to see which one
  5.3623 +	introduced a bug.  In cases like this, the natural thing to do
  5.3624 +	is update the working directory to the changeset you're
  5.3625 +	interested in, and then examine the files in the working
  5.3626 +	directory directly to see their contents as they were when you
  5.3627 +	committed that changeset.  The effect of this is shown in
  5.3628 +	<xref linkend="fig:concepts:wdir-pre-branch"/>.</para>
  5.3629 +
  5.3630 +      <figure id="fig:concepts:wdir-pre-branch" float="0">
  5.3631 +	<title>The working directory, updated to an older
  5.3632 +	  changeset</title>
  5.3633 +	<mediaobject>
  5.3634 +	  <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject>
  5.3635 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3636 +	</mediaobject>
  5.3637 +      </figure>
  5.3638 +
  5.3639 +      <para id="x_313">Having updated the working directory to an
  5.3640 +	older changeset, what happens if you make some changes, and
  5.3641 +	then commit?  Mercurial behaves in the same way as I outlined
  5.3642 +	above.  The parents of the working directory become the
  5.3643 +	parents of the new changeset.  This new changeset has no
  5.3644 +	children, so it becomes the new tip.  And the repository now
  5.3645 +	contains two changesets that have no children; we call these
  5.3646 +	<emphasis>heads</emphasis>.  You can see the structure that
  5.3647 +	this creates in <xref linkend="fig:concepts:wdir-branch"/>.</para>
  5.3648 +
  5.3649 +      <figure id="fig:concepts:wdir-branch" float="0">
  5.3650 +	<title>After a commit made while synced to an older
  5.3651 +	  changeset</title>
  5.3652 +	<mediaobject>
  5.3653 +	  <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject>
  5.3654 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3655 +	</mediaobject>
  5.3656 +      </figure>
  5.3657 +
  5.3658 +      <note>
  5.3659 +	<para id="x_315">If you're new to Mercurial, you should keep
  5.3660 +	  in mind a common <quote>error</quote>, which is to use the
  5.3661 +	  <command role="hg-cmd" moreinfo="none">hg pull</command> command without any
  5.3662 +	  options.  By default, the <command role="hg-cmd" moreinfo="none">hg
  5.3663 +	    pull</command> command <emphasis>does not</emphasis>
  5.3664 +	  update the working directory, so you'll bring new changesets
  5.3665 +	  into your repository, but the working directory will stay
  5.3666 +	  synced at the same changeset as before the pull.  If you
  5.3667 +	  make some changes and commit afterwards, you'll thus create
  5.3668 +	  a new head, because your working directory isn't synced to
  5.3669 +	  whatever the current tip is.  To combine the operation of a
  5.3670 +	  pull, followed by an update, run <command moreinfo="none">hg pull
  5.3671 +	    -u</command>.</para>
  5.3672 +
  5.3673 +	<para id="x_316">I put the word <quote>error</quote> in quotes
  5.3674 +	  because all that you need to do to rectify the situation
  5.3675 +	  where you created a new head by accident is
  5.3676 +	  <command role="hg-cmd" moreinfo="none">hg merge</command>, then <command role="hg-cmd" moreinfo="none">hg commit</command>.  In other words, this
  5.3677 +	  almost never has negative consequences; it's just something
  5.3678 +	  of a surprise for newcomers.  I'll discuss other ways to
  5.3679 +	  avoid this behavior, and why Mercurial behaves in this
  5.3680 +	  initially surprising way, later on.</para>
  5.3681 +      </note>
  5.3682 +
  5.3683 +    </sect2>
  5.3684 +    <sect2>
  5.3685 +      <title>Merging changes</title>
  5.3686 +
  5.3687 +      <para id="x_317">When you run the <command role="hg-cmd" moreinfo="none">hg
  5.3688 +	  merge</command> command, Mercurial leaves the first parent
  5.3689 +	of the working directory unchanged, and sets the second parent
  5.3690 +	to the changeset you're merging with, as shown in <xref linkend="fig:concepts:wdir-merge"/>.</para>
  5.3691 +
  5.3692 +      <figure id="fig:concepts:wdir-merge" float="0">
  5.3693 +	<title>Merging two heads</title>
  5.3694 +	<mediaobject>
  5.3695 +	  <imageobject>
  5.3696 +	    <imagedata fileref="figs/wdir-merge.png"/>
  5.3697 +	  </imageobject>
  5.3698 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.3699 +	</mediaobject>
  5.3700 +      </figure>
  5.3701 +
  5.3702 +      <para id="x_319">Mercurial also has to modify the working directory, to
  5.3703 +	merge the files managed in the two changesets.  Simplified a
  5.3704 +	little, the merging process goes like this, for every file in
  5.3705 +	the manifests of both changesets.</para>
  5.3706 +      <itemizedlist>
  5.3707 +	<listitem><para id="x_31a">If neither changeset has modified a file, do
  5.3708 +	    nothing with that file.</para>
  5.3709 +	</listitem>
  5.3710 +	<listitem><para id="x_31b">If one changeset has modified a file, and the
  5.3711 +	    other hasn't, create the modified copy of the file in the
  5.3712 +	    working directory.</para>
  5.3713 +	</listitem>
  5.3714 +	<listitem><para id="x_31c">If one changeset has removed a file, and the
  5.3715 +	    other hasn't (or has also deleted it), delete the file
  5.3716 +	    from the working directory.</para>
  5.3717 +	</listitem>
  5.3718 +	<listitem><para id="x_31d">If one changeset has removed a file, but the
  5.3719 +	    other has modified the file, ask the user what to do: keep
  5.3720 +	    the modified file, or remove it?</para>
  5.3721 +	</listitem>
  5.3722 +	<listitem><para id="x_31e">If both changesets have modified a file,
  5.3723 +	    invoke an external merge program to choose the new
  5.3724 +	    contents for the merged file.  This may require input from
  5.3725 +	    the user.</para>
  5.3726 +	</listitem>
  5.3727 +	<listitem><para id="x_31f">If one changeset has modified a file, and the
  5.3728 +	    other has renamed or copied the file, make sure that the
  5.3729 +	    changes follow the new name of the file.</para>
  5.3730 +	</listitem></itemizedlist>
  5.3731 +      <para id="x_320">There are more details—merging has plenty of corner
  5.3732 +	cases—but these are the most common choices that are
  5.3733 +	involved in a merge.  As you can see, most cases are
  5.3734 +	completely automatic, and indeed most merges finish
  5.3735 +	automatically, without requiring your input to resolve any
  5.3736 +	conflicts.</para>
  5.3737 +
  5.3738 +      <para id="x_321">When you're thinking about what happens when you commit
  5.3739 +	after a merge, once again the working directory is <quote>the
  5.3740 +	  changeset I'm about to commit</quote>.  After the <command role="hg-cmd" moreinfo="none">hg merge</command> command completes, the
  5.3741 +	working directory has two parents; these will become the
  5.3742 +	parents of the new changeset.</para>
  5.3743 +
  5.3744 +      <para id="x_322">Mercurial lets you perform multiple merges, but
  5.3745 +	you must commit the results of each individual merge as you
  5.3746 +	go.  This is necessary because Mercurial only tracks two
  5.3747 +	parents for both revisions and the working directory.  While
  5.3748 +	it would be technically feasible to merge multiple changesets
  5.3749 +	at once, Mercurial avoids this for simplicity.  With multi-way
  5.3750 +	merges, the risks of user confusion, nasty conflict
  5.3751 +	resolution, and making a terrible mess of a merge would grow
  5.3752 +	intolerable.</para>
  5.3753 +
  5.3754 +    </sect2>
  5.3755 +
  5.3756 +    <sect2>
  5.3757 +      <title>Merging and renames</title>
  5.3758 +
  5.3759 +      <para id="x_69a">A surprising number of revision control systems pay little
  5.3760 +	or no attention to a file's <emphasis>name</emphasis> over
  5.3761 +	time.  For instance, it used to be common that if a file got
  5.3762 +	renamed on one side of a merge, the changes from the other
  5.3763 +	side would be silently dropped.</para>
  5.3764 +
  5.3765 +      <para id="x_69b">Mercurial records metadata when you tell it to perform a
  5.3766 +	rename or copy. It uses this metadata during a merge to do the
  5.3767 +	right thing in the case of a merge.  For instance, if I rename
  5.3768 +	a file, and you edit it without renaming it, when we merge our
  5.3769 +	work the file will be renamed and have your edits
  5.3770 +	applied.</para>
  5.3771 +    </sect2>
  5.3772 +  </sect1>
  5.3773 +
  5.3774 +  <sect1>
  5.3775 +    <title>Other interesting design features</title>
  5.3776 +
  5.3777 +    <para id="x_323">In the sections above, I've tried to highlight some of the
  5.3778 +      most important aspects of Mercurial's design, to illustrate that
  5.3779 +      it pays careful attention to reliability and performance.
  5.3780 +      However, the attention to detail doesn't stop there.  There are
  5.3781 +      a number of other aspects of Mercurial's construction that I
  5.3782 +      personally find interesting.  I'll detail a few of them here,
  5.3783 +      separate from the <quote>big ticket</quote> items above, so that
  5.3784 +      if you're interested, you can gain a better idea of the amount
  5.3785 +      of thinking that goes into a well-designed system.</para>
  5.3786 +
  5.3787 +    <sect2>
  5.3788 +      <title>Clever compression</title>
  5.3789 +
  5.3790 +      <para id="x_324">When appropriate, Mercurial will store both snapshots and
  5.3791 +	deltas in compressed form.  It does this by always
  5.3792 +	<emphasis>trying to</emphasis> compress a snapshot or delta,
  5.3793 +	but only storing the compressed version if it's smaller than
  5.3794 +	the uncompressed version.</para>
  5.3795 +
  5.3796 +      <para id="x_325">This means that Mercurial does <quote>the right
  5.3797 +	  thing</quote> when storing a file whose native form is
  5.3798 +	compressed, such as a <literal moreinfo="none">zip</literal> archive or a JPEG
  5.3799 +	image.  When these types of files are compressed a second
  5.3800 +	time, the resulting file is usually bigger than the
  5.3801 +	once-compressed form, and so Mercurial will store the plain
  5.3802 +	<literal moreinfo="none">zip</literal> or JPEG.</para>
  5.3803 +
  5.3804 +      <para id="x_326">Deltas between revisions of a compressed file are usually
  5.3805 +	larger than snapshots of the file, and Mercurial again does
  5.3806 +	<quote>the right thing</quote> in these cases.  It finds that
  5.3807 +	such a delta exceeds the threshold at which it should store a
  5.3808 +	complete snapshot of the file, so it stores the snapshot,
  5.3809 +	again saving space compared to a naive delta-only
  5.3810 +	approach.</para>
  5.3811 +
  5.3812 +      <sect3>
  5.3813 +	<title>Network recompression</title>
  5.3814 +
  5.3815 +	<para id="x_327">When storing revisions on disk, Mercurial uses the
  5.3816 +	  <quote>deflate</quote> compression algorithm (the same one
  5.3817 +	  used by the popular <literal moreinfo="none">zip</literal> archive format),
  5.3818 +	  which balances good speed with a respectable compression
  5.3819 +	  ratio.  However, when transmitting revision data over a
  5.3820 +	  network connection, Mercurial uncompresses the compressed
  5.3821 +	  revision data.</para>
  5.3822 +
  5.3823 +	<para id="x_328">If the connection is over HTTP, Mercurial recompresses
  5.3824 +	  the entire stream of data using a compression algorithm that
  5.3825 +	  gives a better compression ratio (the Burrows-Wheeler
  5.3826 +	  algorithm from the widely used <literal moreinfo="none">bzip2</literal>
  5.3827 +	  compression package).  This combination of algorithm and
  5.3828 +	  compression of the entire stream (instead of a revision at a
  5.3829 +	  time) substantially reduces the number of bytes to be
  5.3830 +	  transferred, yielding better network performance over most
  5.3831 +	  kinds of network.</para>
  5.3832 +
  5.3833 +	<para id="x_329">If the connection is over
  5.3834 +	  <command moreinfo="none">ssh</command>, Mercurial
  5.3835 +	  <emphasis>doesn't</emphasis> recompress the stream, because
  5.3836 +	  <command moreinfo="none">ssh</command> can already do this itself.  You can
  5.3837 +	  tell Mercurial to always use <command moreinfo="none">ssh</command>'s
  5.3838 +	  compression feature by editing the
  5.3839 +	  <filename moreinfo="none">.hgrc</filename> file in your home directory as
  5.3840 +	  follows.</para>
  5.3841 +
  5.3842 +	<programlisting format="linespecific">[ui]
  5.3843 +ssh = ssh -C</programlisting>
  5.3844 +
  5.3845 +      </sect3>
  5.3846 +    </sect2>
  5.3847 +    <sect2>
  5.3848 +      <title>Read/write ordering and atomicity</title>
  5.3849 +
  5.3850 +      <para id="x_32a">Appending to files isn't the whole story when
  5.3851 +	it comes to guaranteeing that a reader won't see a partial
  5.3852 +	write.  If you recall <xref linkend="fig:concepts:metadata"/>,
  5.3853 +	revisions in the changelog point to revisions in the manifest,
  5.3854 +	and revisions in the manifest point to revisions in filelogs.
  5.3855 +	This hierarchy is deliberate.</para>
  5.3856 +
  5.3857 +      <para id="x_32b">A writer starts a transaction by writing filelog and
  5.3858 +	manifest data, and doesn't write any changelog data until
  5.3859 +	those are finished.  A reader starts by reading changelog
  5.3860 +	data, then manifest data, followed by filelog data.</para>
  5.3861 +
  5.3862 +      <para id="x_32c">Since the writer has always finished writing filelog and
  5.3863 +	manifest data before it writes to the changelog, a reader will
  5.3864 +	never read a pointer to a partially written manifest revision
  5.3865 +	from the changelog, and it will never read a pointer to a
  5.3866 +	partially written filelog revision from the manifest.</para>
  5.3867 +
  5.3868 +    </sect2>
  5.3869 +    <sect2>
  5.3870 +      <title>Concurrent access</title>
  5.3871 +
  5.3872 +      <para id="x_32d">The read/write ordering and atomicity guarantees mean that
  5.3873 +	Mercurial never needs to <emphasis>lock</emphasis> a
  5.3874 +	repository when it's reading data, even if the repository is
  5.3875 +	being written to while the read is occurring. This has a big
  5.3876 +	effect on scalability; you can have an arbitrary number of
  5.3877 +	Mercurial processes safely reading data from a repository
  5.3878 +	all at once, no matter whether it's being written to or
  5.3879 +	not.</para>
  5.3880 +
  5.3881 +      <para id="x_32e">The lockless nature of reading means that if you're
  5.3882 +	sharing a repository on a multi-user system, you don't need to
  5.3883 +	grant other local users permission to
  5.3884 +	<emphasis>write</emphasis> to your repository in order for
  5.3885 +	them to be able to clone it or pull changes from it; they only
  5.3886 +	need <emphasis>read</emphasis> permission.  (This is
  5.3887 +	<emphasis>not</emphasis> a common feature among revision
  5.3888 +	control systems, so don't take it for granted!  Most require
  5.3889 +	readers to be able to lock a repository to access it safely,
  5.3890 +	and this requires write permission on at least one directory,
  5.3891 +	which of course makes for all kinds of nasty and annoying
  5.3892 +	security and administrative problems.)</para>
  5.3893 +
  5.3894 +      <para id="x_32f">Mercurial uses locks to ensure that only one process can
  5.3895 +	write to a repository at a time (the locking mechanism is safe
  5.3896 +	even over filesystems that are notoriously hostile to locking,
  5.3897 +	such as NFS).  If a repository is locked, a writer will wait
  5.3898 +	for a while to retry if the repository becomes unlocked, but
  5.3899 +	if the repository remains locked for too long, the process
  5.3900 +	attempting to write will time out after a while. This means
  5.3901 +	that your daily automated scripts won't get stuck forever and
  5.3902 +	pile up if a system crashes unnoticed, for example.  (Yes, the
  5.3903 +	timeout is configurable, from zero to infinity.)</para>
  5.3904 +
  5.3905 +      <sect3>
  5.3906 +	<title>Safe dirstate access</title>
  5.3907 +
  5.3908 +	<para id="x_330">As with revision data, Mercurial doesn't take a lock to
  5.3909 +	  read the dirstate file; it does acquire a lock to write it.
  5.3910 +	  To avoid the possibility of reading a partially written copy
  5.3911 +	  of the dirstate file, Mercurial writes to a file with a
  5.3912 +	  unique name in the same directory as the dirstate file, then
  5.3913 +	  renames the temporary file atomically to
  5.3914 +	  <filename moreinfo="none">dirstate</filename>.  The file named
  5.3915 +	  <filename moreinfo="none">dirstate</filename> is thus guaranteed to be
  5.3916 +	  complete, not partially written.</para>
  5.3917 +
  5.3918 +      </sect3>
  5.3919 +    </sect2>
  5.3920 +    <sect2>
  5.3921 +      <title>Avoiding seeks</title>
  5.3922 +
  5.3923 +      <para id="x_331">Critical to Mercurial's performance is the avoidance of
  5.3924 +	seeks of the disk head, since any seek is far more expensive
  5.3925 +	than even a comparatively large read operation.</para>
  5.3926 +
  5.3927 +      <para id="x_332">This is why, for example, the dirstate is stored in a
  5.3928 +	single file.  If there were a dirstate file per directory that
  5.3929 +	Mercurial tracked, the disk would seek once per directory.
  5.3930 +	Instead, Mercurial reads the entire single dirstate file in
  5.3931 +	one step.</para>
  5.3932 +
  5.3933 +      <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme
  5.3934 +	when cloning a repository on local storage.  Instead of
  5.3935 +	copying every revlog file from the old repository into the new
  5.3936 +	repository, it makes a <quote>hard link</quote>, which is a
  5.3937 +	shorthand way to say <quote>these two names point to the same
  5.3938 +	  file</quote>.  When Mercurial is about to write to one of a
  5.3939 +	revlog's files, it checks to see if the number of names
  5.3940 +	pointing at the file is greater than one.  If it is, more than
  5.3941 +	one repository is using the file, so Mercurial makes a new
  5.3942 +	copy of the file that is private to this repository.</para>
  5.3943 +
  5.3944 +      <para id="x_334">A few revision control developers have pointed out that
  5.3945 +	this idea of making a complete private copy of a file is not
  5.3946 +	very efficient in its use of storage.  While this is true,
  5.3947 +	storage is cheap, and this method gives the highest
  5.3948 +	performance while deferring most book-keeping to the operating
  5.3949 +	system.  An alternative scheme would most likely reduce
  5.3950 +	performance and increase the complexity of the software, but
  5.3951 +	speed and simplicity are key to the <quote>feel</quote> of
  5.3952 +	day-to-day use.</para>
  5.3953 +
  5.3954 +    </sect2>
  5.3955 +    <sect2>
  5.3956 +      <title>Other contents of the dirstate</title>
  5.3957 +
  5.3958 +      <para id="x_335">Because Mercurial doesn't force you to tell it when you're
  5.3959 +	modifying a file, it uses the dirstate to store some extra
  5.3960 +	information so it can determine efficiently whether you have
  5.3961 +	modified a file.  For each file in the working directory, it
  5.3962 +	stores the time that it last modified the file itself, and the
  5.3963 +	size of the file at that time.</para>
  5.3964 +
  5.3965 +      <para id="x_336">When you explicitly <command role="hg-cmd" moreinfo="none">hg
  5.3966 +	  add</command>, <command role="hg-cmd" moreinfo="none">hg remove</command>,
  5.3967 +	<command role="hg-cmd" moreinfo="none">hg rename</command> or <command role="hg-cmd" moreinfo="none">hg copy</command> files, Mercurial updates the
  5.3968 +	dirstate so that it knows what to do with those files when you
  5.3969 +	commit.</para>
  5.3970 +
  5.3971 +      <para id="x_337">The dirstate helps Mercurial to efficiently
  5.3972 +	  check the status of files in a repository.</para>
  5.3973 +
  5.3974 +      <itemizedlist>
  5.3975 +	<listitem>
  5.3976 +	  <para id="x_726">When Mercurial checks the state of a file in the
  5.3977 +	    working directory, it first checks a file's modification
  5.3978 +	    time against the time in the dirstate that records when
  5.3979 +	    Mercurial last wrote the file. If the last modified time
  5.3980 +	    is the same as the time when Mercurial wrote the file, the
  5.3981 +	    file must not have been modified, so Mercurial does not
  5.3982 +	    need to check any further.</para>
  5.3983 +	</listitem>
  5.3984 +	<listitem>
  5.3985 +	  <para id="x_727">If the file's size has changed, the file must have
  5.3986 +	    been modified.  If the modification time has changed, but
  5.3987 +	    the size has not, only then does Mercurial need to
  5.3988 +	    actually read the contents of the file to see if it has
  5.3989 +	    changed.</para>
  5.3990 +	</listitem>
  5.3991 +      </itemizedlist>
  5.3992 +
  5.3993 +      <para id="x_728">Storing the modification time and size dramatically
  5.3994 +	reduces the number of read operations that Mercurial needs to
  5.3995 +	perform when we run commands like <command moreinfo="none">hg status</command>.
  5.3996 +	This results in large performance improvements.</para>
  5.3997 +    </sect2>
  5.3998 +  </sect1>
  5.3999 +</chapter>
  5.4000 +
  5.4001 +<!--
  5.4002 +local variables: 
  5.4003 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.4004 +end:
  5.4005 +-->
  5.4006 +
  5.4007 +  <!-- BEGIN ch05 -->
  5.4008 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.4009 +
  5.4010 +<chapter id="chap:daily">
  5.4011 +  <?dbhtml filename="mercurial-in-daily-use.html"?>
  5.4012 +  <title>Mercurial pour une utilisation de tous les jours</title>
  5.4013 +
  5.4014 +  <sect1>
  5.4015 +    <title>Informer Mercurial des fichier à suivre</title>
  5.4016 +
  5.4017 +    <para id="x_1a3">Mercurial ne suit pas les fichiers de votre dépôt tant
  5.4018 +      que vous ne lui avez pas dit de les gérer. La commande <command role="hg-cmd" moreinfo="none">hg status</command> vous dira quels fichiers sont
  5.4019 +      inconnus de Mercurial. Il utilise un
  5.4020 +      <quote><literal moreinfo="none">?</literal></quote> pour montrer ces fichiers.</para>
  5.4021 +
  5.4022 +    <para id="x_1a4">Pour informer Mercurial de suivre un fichier, utilisez
  5.4023 +      la commande <command role="hg-cmd" moreinfo="none">hg add</command>. Une fois que vous
  5.4024 +      avez ajouté un fichier, la ligne correspondante à ce fichier dans la
  5.4025 +      sortie de <command role="hg-cmd" moreinfo="none">hg status</command> change de
  5.4026 +      <quote><literal moreinfo="none">?</literal></quote> à
  5.4027 +      <quote><literal moreinfo="none">A</literal></quote>.</para>
  5.4028 +
  5.4029 +    <!-- BEGIN daily.files.add -->
  5.4030 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init add-example</userinput>
  5.4031 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd add-example</userinput>
  5.4032 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; myfile.txt</userinput>
  5.4033 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4034 +? myfile.txt
  5.4035 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add myfile.txt</userinput>
  5.4036 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4037 +A myfile.txt
  5.4038 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Added one file'</userinput>
  5.4039 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4040 +</screen>
  5.4041 +<!-- END daily.files.add -->
  5.4042 +
  5.4043 +
  5.4044 +    <para id="x_1a5">Après avoir exécuté un <command role="hg-cmd" moreinfo="none">hg
  5.4045 +        commit</command>, les fichiers que vous avez ajoutés avant le commit
  5.4046 +      ne seront plus listés dans la sortie de <command role="hg-cmd" moreinfo="none">hg
  5.4047 +        status</command>. La raison de ceci est que, par défaut, <command role="hg-cmd" moreinfo="none">hg status</command> ne vous montre que les fichiers
  5.4048 +      <quote>intéressants</quote> —ceux que vous avez (par exemple)
  5.4049 +      modifiés, supprimés ou renommés. Si vous aviez un dépôt qui contient un
  5.4050 +      millier de fichiers, vous ne voudriez certainement que rarement entendre
  5.4051 +      parler des fichiers que Mercurial suit, mais qui n'ont pas changés.
  5.4052 +      (Vous pouvez quand même avoir cette information, nous y reviendrons
  5.4053 +      plus tard.)</para>
  5.4054 +
  5.4055 +    <para id="x_1a6">Une fois que vous ajoutez un fichier, Mercurial ne fait
  5.4056 +      rien du tout avec celui-ci immédiatement. Au lieu de ça, il va prendre
  5.4057 +      un "snapshot" de l'état du fichier la prochaine fois que vous
  5.4058 +      exécuterez un commit. Il continuera ensuite à suivre les changements
  5.4059 +      que vous avez fait au fichier chaque fois que vous committerez, et ce,
  5.4060 +      jusqu'à ce que vous supprimiez le fichier.</para>
  5.4061 +
  5.4062 +    <sect2>
  5.4063 +      <title>Nommage des fichiers explicite versus implicite</title>
  5.4064 +
  5.4065 +      <para id="x_1a7">Un comportement utile que Mercurial possède est que si
  5.4066 +        vous passez le nom d'un répertoire à une commande, toute commande
  5.4067 +        Mercurial la traitera comme : <quote>Je veux opérer sur chaque fichier
  5.4068 +          dans ce répertoire et ses sous-répertoires</quote>.</para>
  5.4069 +
  5.4070 +      <!-- BEGIN daily.files.add-dir -->
  5.4071 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b</userinput>
  5.4072 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b/somefile.txt</userinput>
  5.4073 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo c &gt; b/source.cpp</userinput>
  5.4074 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b/d</userinput>
  5.4075 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo d &gt; b/d/test.h</userinput>
  5.4076 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add b</userinput>
  5.4077 +adding b/d/test.h
  5.4078 +adding b/somefile.txt
  5.4079 +adding b/source.cpp
  5.4080 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Added all files in subdirectory'</userinput>
  5.4081 +</screen>
  5.4082 +<!-- END daily.files.add-dir -->
  5.4083 +
  5.4084 +
  5.4085 +      <para id="x_1a8">Remarquez que dans cet exemple, Mercurial affiche le
  5.4086 +        nom des fichiers qu'il a ajouté, alors qu'il ne l'a pas fait lorsque
  5.4087 +        nous avons ajouté le fichier nommé <filename moreinfo="none">myfile.txt</filename>
  5.4088 +        dans l'exemple précédent.</para>
  5.4089 +
  5.4090 +      <para id="x_1a9">Ce qu'il se passe est que dans le premier cas, nous
  5.4091 +        avons nommé explicitement le fichier à ajouter sur la ligne de
  5.4092 +        commande. Ce que Mercurial suppose dans ce cas est que nous savons ce
  5.4093 +        que nous faisons, il n'affiche donc rien en sortie.</para>
  5.4094 +
  5.4095 +      <para id="x_1aa">Cependant, lorsque nous avons
  5.4096 +        <emphasis>implicitement</emphasis> donné les fichiers à l'aide du nom
  5.4097 +        d'un répertoire, Mercurial prend l'initiative d'afficher le nom de
  5.4098 +        chaque fichier avec lequel il fait quelque chose. Ceci clarifie ce
  5.4099 +        qu'il se passe et réduit la probabilité d'une mauvaise surprise
  5.4100 +        restée silencieuse. Ce comportement est commun à la plupart des
  5.4101 +        commandes Mercurial.</para>
  5.4102 +    </sect2>
  5.4103 +    <sect2>
  5.4104 +      <title>Mercurial suit les fichiers, pas les répertoires</title>
  5.4105 +
  5.4106 +      <para id="x_1ab">Mercurial ne suit pas les informations sur les
  5.4107 +        répertoires. En contrepartie, il suit le chemin vers un fichier. Avant
  5.4108 +        de créer un fichier, il crée au préalable les répertoires manquants
  5.4109 +        dans le chemin. Après avoir supprimé un fichier, il supprime chaque
  5.4110 +        répertoire vide qui apparaît dans le chemin du fichier. Ceci apparaît
  5.4111 +        comme une distinction triviale, cependant, cela a une conséquence
  5.4112 +        pratique mineure : il n'est pas possible de représenter un répertoire
  5.4113 +        totalement vide dans Mercurial.</para>
  5.4114 +
  5.4115 +      <para id="x_1ac">Les répertoires vides sont rarement utiles. Il existe
  5.4116 +        cependant des solutions alternatives et non intrusives que vous
  5.4117 +        pouvez utiliser pour obtenir l'effet approprié. Les développeurs de
  5.4118 +        Mercurial ont ainsi pensé que la complexité requise pour gérer les
  5.4119 +        répertoires n'était pas aussi importante que le bénéfice que cette
  5.4120 +        fonctionnalité apporterait.</para>
  5.4121 +
  5.4122 +      <para id="x_1ad">Si vous avez besoin d'un répertoire vide dans votre
  5.4123 +        dépôt, il existe quelques façons d'y arriver. L'une d'elles est de
  5.4124 +        créer un répertoire et ensuite, de faire un <command role="hg-cmd" moreinfo="none">hg
  5.4125 +          add</command> sur un fichier <quote>caché</quote> dans ce
  5.4126 +        répertoire. Sur les systèmes de type Unix, tout fichier dont le nom
  5.4127 +        commence avec un point (<quote><literal moreinfo="none">.</literal></quote>) est
  5.4128 +        considéré comme caché par la plupart des commandes et outils
  5.4129 +        graphiques. Cette approche est illustrée ci-après.</para>
  5.4130 +      
  5.4131 +      <!-- BEGIN daily.files.hidden -->
  5.4132 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init hidden-example</userinput>
  5.4133 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hidden-example</userinput>
  5.4134 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir empty</userinput>
  5.4135 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">touch empty/.hidden</userinput>
  5.4136 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add empty/.hidden</userinput>
  5.4137 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Manage an empty-looking directory'</userinput>
  5.4138 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls empty</userinput>
  5.4139 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.4140 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hidden-example tmp</userinput>
  5.4141 +updating working directory
  5.4142 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4143 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls tmp</userinput>
  5.4144 +empty
  5.4145 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls tmp/empty</userinput>
  5.4146 +</screen>
  5.4147 +<!-- END daily.files.hidden -->
  5.4148 +
  5.4149 +
  5.4150 +      <para id="x_1ae">Une autre façon de s'attaquer au besoin d'un
  5.4151 +        répertoire vide est de simplement d'en créer un dans vos scripts
  5.4152 +        de construction avant qu'ils n'en aient le besoin.</para>
  5.4153 +    </sect2>
  5.4154 +  </sect1>
  5.4155 +
  5.4156 +  <sect1>
  5.4157 +    <title>Comment arrêter de suivre un fichier</title>
  5.4158 +
  5.4159 +    <para id="x_1af">Une fois que vous décidez qu'un fichier n'appartient
  5.4160 +      plus à votre dépôt, utilisez la commande <command role="hg-cmd" moreinfo="none">hg
  5.4161 +        remove</command>. Ceci supprime le fichier et informe Mercurial
  5.4162 +      d'arrêter de le suivre (ce qui prendra effet lors du prochain commit).
  5.4163 +      Un fichier supprimé est représenté dans la sortie de la commande
  5.4164 +      <command role="hg-cmd" moreinfo="none">hg status</command> par un
  5.4165 +      <quote><literal moreinfo="none">R</literal></quote>.</para>
  5.4166 +
  5.4167 +    <!-- BEGIN daily.files.remove -->
  5.4168 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init remove-example</userinput>
  5.4169 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd remove-example</userinput>
  5.4170 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  5.4171 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b</userinput>
  5.4172 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b/b</userinput>
  5.4173 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a b</userinput>
  5.4174 +adding b/b
  5.4175 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Small example for file removal'</userinput>
  5.4176 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove a</userinput>
  5.4177 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4178 +R a
  5.4179 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove b</userinput>
  5.4180 +removing b/b
  5.4181 +</screen>
  5.4182 +<!-- END daily.files.remove -->
  5.4183 +
  5.4184 +
  5.4185 +    <para id="x_1b0">Après avoir fait un <command role="hg-cmd" moreinfo="none">hg
  5.4186 +        remove</command> sur un fichier, Mercurial ne suivra plus aucun
  5.4187 +      changement sur ce fichier, même si vous recréez un fichier avec le même
  5.4188 +      nom dans votre répertoire de travail. Si vous recréez un fichier avec le
  5.4189 +      même nom et que vous désirez que Mercurial suive ce dernier, faite
  5.4190 +      simplement un <command role="hg-cmd" moreinfo="none">hg add</command> sur celui-ci.
  5.4191 +      Mercurial saura alors que le nouveau fichier ne fait pas référence à
  5.4192 +      l'ancien fichier qui portait le même nom.</para>
  5.4193 +
  5.4194 +    <sect2>
  5.4195 +      <title>Supprimer un fichier n'affecte pas son historique</title>
  5.4196 +
  5.4197 +      <para id="x_1b1">Il est important de comprendre que supprimer un fichier
  5.4198 +        n'a que deux effets.</para>
  5.4199 +
  5.4200 +      <itemizedlist>
  5.4201 +        <listitem><para id="x_1b2">Il supprime la version actuelle de ce
  5.4202 +            fichier du répertoire de travail.</para>
  5.4203 +        </listitem>
  5.4204 +        <listitem><para id="x_1b3">Il arrête, à partir du prochain commit, le
  5.4205 +            suivi de Mercurial sur les changements qui ont lieu sur ce
  5.4206 +            fichier.</para>
  5.4207 +        </listitem></itemizedlist>
  5.4208 +        
  5.4209 +      <para id="x_1b4">Supprimer un fichier <emphasis>n'</emphasis>affecte en
  5.4210 +        <emphasis>aucun</emphasis> cas l'<emphasis>historique</emphasis> du
  5.4211 +        fichier.</para>
  5.4212 +
  5.4213 +      <para id="x_1b5">Si vous mettez à jour le répertoire de travail à un
  5.4214 +        changeset qui a été committé alors que le fichier que vous venez de
  5.4215 +        supprimer était encore suivi, ce fichier réapparaîtra dans le
  5.4216 +        répertoire de travail, avec le contenu qu'il avait lorsque vous aviez
  5.4217 +        committé ce changeset. Si vous mettez à jour (update) le répertoire de
  5.4218 +        travail à un changeset ultérieur dans lequel le fichier a été
  5.4219 +        supprimé, Mercurial supprimera une nouvelle fois le fichier du
  5.4220 +        répertoire de travail.</para>
  5.4221 +    </sect2>
  5.4222 +
  5.4223 +    <sect2>
  5.4224 +      <title>Fichiers manquants</title>
  5.4225 +
  5.4226 +      <para id="x_1b6">Mercurial considère qu'un fichier que vous avez
  5.4227 +        supprimé sans utiliser<command role="hg-cmd" moreinfo="none">hg remove</command>
  5.4228 +        comme étant <emphasis>manquant</emphasis>.  Un fichier manquant est
  5.4229 +        représenté avec un <quote><literal moreinfo="none">!</literal></quote> en sortie de
  5.4230 +        <command role="hg-cmd" moreinfo="none">hg status</command>.
  5.4231 +        Les commandes Mercurial ne feront rien avec les fichiers
  5.4232 +        manquants.</para>
  5.4233 +
  5.4234 +      <!-- BEGIN daily.files.missing -->
  5.4235 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init missing-example</userinput>
  5.4236 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd missing-example</userinput>
  5.4237 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  5.4238 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
  5.4239 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'File about to be missing'</userinput>
  5.4240 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">rm a</userinput>
  5.4241 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4242 +! a
  5.4243 +</screen>
  5.4244 +<!-- END daily.files.missing -->
  5.4245 +
  5.4246 +
  5.4247 +      <para id="x_1b7">Si votre dépôt contient un fichier que <command role="hg-cmd" moreinfo="none">hg status</command> reporte comme manquant, et que
  5.4248 +        vous voulez que ce fichier reste supprimé, vous pouvez exécuter
  5.4249 +        <command role="hg-cmd" moreinfo="none">hg remove <option role="hg-opt-remove">--after</option></command> à tout moment
  5.4250 +        pour dire à Mercurial que vous aviez bien voulu supprimer ce
  5.4251 +        fichier.</para>
  5.4252 +
  5.4253 +      <!-- BEGIN daily.files.remove-after -->
  5.4254 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove --after a</userinput>
  5.4255 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4256 +R a
  5.4257 +</screen>
  5.4258 +<!-- END daily.files.remove-after -->
  5.4259 +
  5.4260 +
  5.4261 +      <para id="x_1b8">D'un autre coté, si vous avez supprimé le fichier
  5.4262 +        manquant par accident, donnez à la commande <command role="hg-cmd" moreinfo="none">hg
  5.4263 +          revert</command> le nom du fichier à retrouver. Il réapparaitra dans
  5.4264 +        sa forme non modifiée.</para>
  5.4265 +
  5.4266 +      <!-- BEGIN daily.files.recover-missing -->
  5.4267 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert a</userinput>
  5.4268 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat a</userinput>
  5.4269 +a
  5.4270 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4271 +</screen>
  5.4272 +<!-- END daily.files.recover-missing -->
  5.4273 +
  5.4274 +    
  5.4275 +    </sect2>
  5.4276 +
  5.4277 +    <sect2>
  5.4278 +      <title>Entre nous : Pourquoi dire explicitement à Mercurial de supprimer un
  5.4279 +      fichier ?</title>
  5.4280 +
  5.4281 +      <para id="x_1b9">Vous pourriez vous demander pourquoi il est nécessaire
  5.4282 +        de dire explicitement à Mercurial que vous souhaitez supprimer un
  5.4283 +        fichier. Au début du développement de Mercurial, celui ci vous
  5.4284 +        laissait pourtant supprimer un fichier sans soucis ; Mercurial vous
  5.4285 +        aurait automatiquement informé de l'absence du fichier lorsque vous
  5.4286 +        auriez lancé un <command role="hg-cmd" moreinfo="none">hg commit</command> et arrêté
  5.4287 +        de le suivre. En pratique, ceci a montré qu'il était trop facile de
  5.4288 +        supprimer accidentellement un fichier sans le remarquer.</para>
  5.4289 +    </sect2>
  5.4290 +
  5.4291 +    <sect2>
  5.4292 +      <title>Raccourci utile—ajouter et supprimer des fichiers en une
  5.4293 +      seule étape.</title>
  5.4294 +
  5.4295 +      <para id="x_1ba">Mercurial offre une commande combinée, <command role="hg-cmd" moreinfo="none">hg addremove</command>, qui ajoute les fichiers non
  5.4296 +        suivis et marque les fichiers manquants comme supprimés.</para>
  5.4297 +
  5.4298 +      <!-- BEGIN daily.files.addremove -->
  5.4299 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init addremove-example</userinput>
  5.4300 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd addremove-example</userinput>
  5.4301 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  5.4302 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b</userinput>
  5.4303 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg addremove</userinput>
  5.4304 +adding a
  5.4305 +adding b
  5.4306 +</screen>
  5.4307 +<!-- END daily.files.addremove -->
  5.4308 +
  5.4309 +
  5.4310 +      <para id="x_1bb">La commande <command role="hg-cmd" moreinfo="none">hg commit</command>
  5.4311 +        fournit aussi une option <option role="hg-opt-commit">-A</option> qui
  5.4312 +        exécute le même ajouter-et-supprimer, immédiatement suivi d'un
  5.4313 +        commit.</para>
  5.4314 +
  5.4315 +      <!-- BEGIN daily.files.commit-addremove -->
  5.4316 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo c &gt; c</userinput>
  5.4317 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Commit with addremove'</userinput>
  5.4318 +adding c
  5.4319 +</screen>
  5.4320 +<!-- END daily.files.commit-addremove -->
  5.4321 +
  5.4322 +    
  5.4323 +    </sect2>
  5.4324 +  </sect1>
  5.4325 +
  5.4326 +  <sect1 id="chap:daily.copy">
  5.4327 +    <title>Copier des fichiers</title>
  5.4328 +
  5.4329 +    <para id="x_1bc">Mercurial fournit une commande <command role="hg-cmd" moreinfo="none">hg
  5.4330 +        copy</command> qui vous permet de faire une nouvelle copie d'un
  5.4331 +      fichier. Lorsque vous copiez un fichier en utilisant cette commande,
  5.4332 +      Mercurial crée un enregistrement du fait que ce nouveau fichier est une
  5.4333 +      copie du fichier originel. Il traite ces fichiers copiés spécialement
  5.4334 +      lorsque vous fusionnez (merge) votre travail avec quelqu'un
  5.4335 +      d'autre.</para>
  5.4336 +
  5.4337 +    <sect2>
  5.4338 +      <title>Les résultats d'une copie durant une fusion (merge)</title>
  5.4339 +
  5.4340 +      <para id="x_1bd">Ce qu'il se passe durant une fusion (merge) est que
  5.4341 +        les changements <quote>suivent</quote> une copie. Pour illustrer ce
  5.4342 +        que cela veut dire de la meilleure façon, créons un exemple. Nous
  5.4343 +        allons commencer avec le mini dépôt usuel qui contient un simple
  5.4344 +        fichier.</para>
  5.4345 +
  5.4346 +      <!-- BEGIN daily.copy.init -->
  5.4347 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init my-copy</userinput>
  5.4348 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-copy</userinput>
  5.4349 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo line &gt; file</userinput>
  5.4350 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add file</userinput>
  5.4351 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Added a file'</userinput>
  5.4352 +</screen>
  5.4353 +<!-- END daily.copy.init -->
  5.4354 +
  5.4355 +
  5.4356 +      <para id="x_1be">Nous devons faire du travail en parallèle, ainsi,
  5.4357 +        nous aurons quelque chose à fusionner (merge). Donc clonons notre
  5.4358 +        dépôt.</para>
  5.4359 +
  5.4360 +      <!-- BEGIN daily.copy.clone -->
  5.4361 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.4362 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone my-copy your-copy</userinput>
  5.4363 +updating working directory
  5.4364 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4365 +</screen>
  5.4366 +<!-- END daily.copy.clone -->
  5.4367 +
  5.4368 +
  5.4369 +      <para id="x_1bf">De retour dans notre dépôt initial, utilisons la
  5.4370 +        commande <command role="hg-cmd" moreinfo="none">hg copy</command> pour faire une
  5.4371 +        copie du premier fichier que nous avons créé.</para>
  5.4372 +
  5.4373 +      <!-- BEGIN daily.copy.copy -->
  5.4374 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-copy</userinput>
  5.4375 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy file new-file</userinput>
  5.4376 +</screen>
  5.4377 +<!-- END daily.copy.copy -->
  5.4378 +
  5.4379 +
  5.4380 +      <para id="x_1c0">Si nous regardons ensuite à la sortie de la commande
  5.4381 +        <command role="hg-cmd" moreinfo="none">hg status</command>, les fichiers copiés
  5.4382 +        ont l'air de fichiers normalement ajoutés.</para>
  5.4383 +
  5.4384 +      <!-- BEGIN daily.copy.status -->
  5.4385 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4386 +A new-file
  5.4387 +</screen>
  5.4388 +<!-- END daily.copy.status -->
  5.4389 +
  5.4390 +
  5.4391 +      <para id="x_1c1">Mais si nous passons l'option <option role="hg-opt-status">-C</option> à <command role="hg-cmd" moreinfo="none">hg
  5.4392 +          status</command>, il affiche une autre ligne de sortie : il s'agit
  5.4393 +        du fichier <emphasis>source</emphasis> pour notre copie.</para>
  5.4394 +
  5.4395 +      <!-- BEGIN daily.copy.status-copy -->
  5.4396 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -C</userinput>
  5.4397 +A new-file
  5.4398 +  file
  5.4399 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Copied file'</userinput>
  5.4400 +</screen>
  5.4401 +<!-- END daily.copy.status-copy -->
  5.4402 +
  5.4403 +
  5.4404 +      <para id="x_1c2">Maintenant, de retour dans le dépôt que nous avons
  5.4405 +        cloné, créons un changement en parallèle. Nous allons ajouter une
  5.4406 +        ligne de contenu au fichier original qui a été créé.</para>
  5.4407 +
  5.4408 +      <!-- BEGIN daily.copy.other -->
  5.4409 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../your-copy</userinput>
  5.4410 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'new contents' &gt;&gt; file</userinput>
  5.4411 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Changed file'</userinput>
  5.4412 +</screen>
  5.4413 +<!-- END daily.copy.other -->
  5.4414 +
  5.4415 +
  5.4416 +      <para id="x_1c3">Nous avons alors un fichier <filename moreinfo="none">file</filename>
  5.4417 +        modifié dans ce dépôt. Lorsque nous récupérons (pull) les changements
  5.4418 +        depuis le premier répertoire et fusionnons (merge) les deux "heads",
  5.4419 +        Mercurial propagera les changements que nous avons faits localement
  5.4420 +        au fichier <filename moreinfo="none">file</filename> dans sa copie
  5.4421 +        <filename moreinfo="none">new-file</filename>.</para>
  5.4422 +
  5.4423 +      <!-- BEGIN daily.copy.merge -->
  5.4424 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../my-copy</userinput>
  5.4425 +pulling from ../my-copy
  5.4426 +searching for changes
  5.4427 +adding changesets
  5.4428 +adding manifests
  5.4429 +adding file changes
  5.4430 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.4431 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.4432 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.4433 +merging file and new-file to new-file
  5.4434 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  5.4435 +(branch merge, don't forget to commit)
  5.4436 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat new-file</userinput>
  5.4437 +line
  5.4438 +new contents
  5.4439 +</screen>
  5.4440 +<!-- END daily.copy.merge -->
  5.4441 +
  5.4442 +    
  5.4443 +    </sect2>
  5.4444 +    <sect2 id="sec:daily:why-copy">
  5.4445 +      <title>Pourquoi est-ce que les changements devraient suivre les copies
  5.4446 +        ?</title>
  5.4447 +
  5.4448 +      <para id="x_1c4">Ce comportement—des changements d'un fichiers
  5.4449 +        qui se propagent aux copies de ce fichier—peut sembler
  5.4450 +        ésotérique, mais, dans la plupart des cas, c'est hautement
  5.4451 +        désirable.</para>
  5.4452 +
  5.4453 +      <para id="x_1c5">Pour commencer, souvenez vous que cette propagation
  5.4454 +        a lieue <emphasis>seulement</emphasis> lors des fusions (merge).
  5.4455 +        Donc, si vous faites un	<command role="hg-cmd" moreinfo="none">hg copy</command> sur
  5.4456 +        un fichier, et par la suite modifiez le fichier original durant le
  5.4457 +        cours normal de votre travail, rien n'a lieu.</para>
  5.4458 +
  5.4459 +      <para id="x_1c6">La deuxième chose à savoir c'est que les modifications
  5.4460 +        ne se propageront à travers une copie que si le changeset à partir
  5.4461 +        duquel vous faites une fusion (merge) <emphasis>n'a pas encore
  5.4462 +          vu</emphasis> la copie.</para>
  5.4463 +          
  5.4464 +      <para id="x_1c7">La raison pour laquelle Mercurial fait ainsi est une
  5.4465 +        règle. Imaginons que je corrige un important bug dans un fichier source
  5.4466 +        et que je commit mes changements. Pendant ce temps, vous avez décidé de
  5.4467 +        faire un <command role="hg-cmd" moreinfo="none">hg copy</command> du fichier dans
  5.4468 +        votre dépôt, sans rien savoir au sujet du bug ou à propos de la
  5.4469 +        correction. Vous avez alors commencé à "hacker" sur votre copie du
  5.4470 +        fichier.</para>
  5.4471 +
  5.4472 +      <para id="x_1c8">Si vous aviez récupéré (pull) et fusionné (merge) mes
  5.4473 +        changements, et que Mercurial <emphasis>n'avait pas</emphasis>
  5.4474 +        propagé les changements à travers les copies, votre nouveau fichier
  5.4475 +        source contiendrait maintenant le bug, et à moins que vous ne sachiez
  5.4476 +        qu'il faille propager la correction du bug à la main, le bug aurait
  5.4477 +        <emphasis>subsisté</emphasis> dans votre copie du fichier.</para>
  5.4478 +
  5.4479 +      <para id="x_1c9">En propageant automatiquement les changements qui
  5.4480 +        fixent les bugs à partir du fichier original vers les copies,
  5.4481 +        Mercurial prévient ce type de problèmes. A ma connaissance, Mercurial
  5.4482 +        est le <emphasis>seul</emphasis> système de gestion de révisions qui
  5.4483 +        propage les changements à travers les copies comme ceci.</para>
  5.4484 +
  5.4485 +      <para id="x_1ca">Une fois que votre historique des changements a un
  5.4486 +        enregistrement concernant une copie et qu'une fusion postérieure a
  5.4487 +        eu lieue, il n'y a d'habitude pas d'autre besoin de propager les
  5.4488 +        changements du fichier originel vers le fichier copié. C'est pourquoi
  5.4489 +        Mercurial ne propage les changements à travers les copies qu'à la
  5.4490 +        première fusion, et pas d'avantage.</para>
  5.4491 +    </sect2>
  5.4492 +
  5.4493 +    <sect2>
  5.4494 +      <title>Comment faire des changements qui <emphasis>ne</emphasis>
  5.4495 +      suivent <emphasis>pas</emphasis> une copie</title>
  5.4496 +
  5.4497 +      <para id="x_1cb">Si pour une raison ou une autre, vous décidez que
  5.4498 +        cette fonctionnalité de propager automatiquement les changements à
  5.4499 +        travers les copies n'est pas pour vous, utilisez simplement la
  5.4500 +        commande normale de copie de votre système (sur les systèmes de type
  5.4501 +        Unix, il s'agit de <command moreinfo="none">cp</command>) pour faire une copie d'un
  5.4502 +        fichier. Utilisez ensuite <command role="hg-cmd" moreinfo="none">hg add</command>
  5.4503 +        pour ajouter les nouveaux fichiers à la main. Cependant, avant d'en
  5.4504 +        faire ainsi, relisez <xref linkend="sec:daily:why-copy"/>, et faites
  5.4505 +        un choix en connaissance de cause comme quoi cette fonctionnalité
  5.4506 +        n'est pas appropriée à votre cas spécifique.</para>
  5.4507 +
  5.4508 +    </sect2>
  5.4509 +    <sect2>
  5.4510 +      <title>Comportement de la commande <command role="hg-cmd" moreinfo="none">hg copy</command></title>
  5.4511 +
  5.4512 +      <para id="x_1cc">Lorsque vous utilisez la commande <command role="hg-cmd" moreinfo="none">hg copy</command>, Mercurial crée une copie de chaque
  5.4513 +        fichier source tel qu'il est actuellement dans le répertoire de
  5.4514 +        travail. Cela signifie que si vous effectuez des modifications sur un
  5.4515 +        fichier, puis faites un <command role="hg-cmd" moreinfo="none">hg copy</command> sur
  5.4516 +        celui-ci sans avoir au préalable committé ces changements, la nouvelle
  5.4517 +        copie contiendra aussi les modifications que vous avez fait jusqu'à
  5.4518 +        ce point.	(Je trouve ce comportement quelque peu contre intuitif,
  5.4519 +        c'est pourquoi j'en fais mention ici.)</para>
  5.4520 +      <!-- Vérifier que je n'ai pas fait de contre sens en relisant la
  5.4521 +      version anglaise, ce que je comprend ici me paraît un peu bizarre -->
  5.4522 +
  5.4523 +      <para id="x_1cd">La commande <command role="hg-cmd" moreinfo="none">hg copy</command>
  5.4524 +        agit comme la commande Unix <command moreinfo="none">cp</command> (vous pouvez
  5.4525 +        utilisez l'alias <command role="hg-cmd" moreinfo="none">hg cp</command> si vous
  5.4526 +        préférez).  Nous devons lui donner deux ou plus arguments où le
  5.4527 +        dernier est considéré comme la <emphasis>destination</emphasis>, et
  5.4528 +        les autres comme les <emphasis>sources</emphasis>.</para>
  5.4529 +
  5.4530 +      <para id="x_685">Si vous passez à <command role="hg-cmd" moreinfo="none">hg
  5.4531 +          copy</command> un seul fichier source, et que la destination
  5.4532 +        n'existe pas, ceci créera un nouveau fichier avec ce nom.</para>
  5.4533 +
  5.4534 +      <!-- BEGIN daily.copy.simple -->
  5.4535 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir k</userinput>
  5.4536 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy a k</userinput>
  5.4537 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls k</userinput>
  5.4538 +a
  5.4539 +</screen>
  5.4540 +<!-- END daily.copy.simple -->
  5.4541 +
  5.4542 +
  5.4543 +      <para id="x_1ce">Si la destination est un répertoire, Mercurial copie
  5.4544 +        les sources dans ce répertoire.</para>
  5.4545 +
  5.4546 +      <!-- BEGIN daily.copy.dir-dest -->
  5.4547 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir d</userinput>
  5.4548 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy a b d</userinput>
  5.4549 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls d</userinput>
  5.4550 +a  b
  5.4551 +</screen>
  5.4552 +<!-- END daily.copy.dir-dest -->
  5.4553 +
  5.4554 +
  5.4555 +      <para id="x_1cf">La copie de répertoire est récursive et préserve la
  5.4556 +        structure du répertoire source.</para>
  5.4557 +
  5.4558 +      <!-- BEGIN daily.copy.dir-src -->
  5.4559 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy z e</userinput>
  5.4560 +copying z/a/c to e/a/c
  5.4561 +</screen>
  5.4562 +<!-- END daily.copy.dir-src -->
  5.4563 +
  5.4564 +
  5.4565 +      <para id="x_1d0">Si la source et la destination sont tous deux des
  5.4566 +        répertoires, l'arborescence de la source est recréée dans le
  5.4567 +        répertoire destination.</para>
  5.4568 +    
  5.4569 +      <!-- BEGIN daily.copy.dir-src-dest -->
  5.4570 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy z d</userinput>
  5.4571 +copying z/a/c to d/z/a/c
  5.4572 +</screen>
  5.4573 +<!-- END daily.copy.dir-src-dest -->
  5.4574 +
  5.4575 +
  5.4576 +      <para id="x_1d1">Comme avec la commande <command role="hg-cmd" moreinfo="none">hg
  5.4577 +          remove</command>, si vous copiez un fichier manuellement et voulez
  5.4578 +        que Mercurial sache qu'il s'agit d'une copie, utilisez simplement
  5.4579 +        l'option <option role="hg-opt-copy">--after</option> avec <command role="hg-cmd" moreinfo="none">hg copy</command>.</para>
  5.4580 +
  5.4581 +      <!-- BEGIN daily.copy.after -->
  5.4582 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cp a n</userinput>
  5.4583 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy --after a n</userinput>
  5.4584 +</screen>
  5.4585 +<!-- END daily.copy.after -->
  5.4586 +
  5.4587 +    </sect2>
  5.4588 +  </sect1>
  5.4589 +
  5.4590 +  <sect1>
  5.4591 +    <title>Renommer les fichiers</title>
  5.4592 +
  5.4593 +    <para id="x_1d2">Il est plus commun d'avoir besoin de renommer un
  5.4594 +      fichier que d'en faire une copie. La raison pour laquelle j'ai discuté
  5.4595 +      de la commande <command role="hg-cmd" moreinfo="none">hg copy</command> avant de parler
  5.4596 +      de renommage des fichiers est que Mercurial traite les renommages
  5.4597 +      essentiellement comme une copie. Ainsi, savoir comment Mercurial traite
  5.4598 +      les copies de fichiers vous informe sur ce que vous êtes en droit
  5.4599 +      d'attendre lorsque vous renommez un fichier.</para>
  5.4600 +
  5.4601 +    <para id="x_1d3">Lorsque vous utilisez la commande <command role="hg-cmd" moreinfo="none">hg rename</command>, Mercurial crée une copie de tous
  5.4602 +      les fichiers sources, les supprime et marque ces fichiers comme étant
  5.4603 +      supprimés.</para>
  5.4604 +
  5.4605 +    <!-- BEGIN daily.rename.rename -->
  5.4606 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rename a b</userinput>
  5.4607 +</screen>
  5.4608 +<!-- END daily.rename.rename -->
  5.4609 +
  5.4610 +
  5.4611 +    <para id="x_1d4">La commande <command role="hg-cmd" moreinfo="none">hg status</command>
  5.4612 +      montre les nouveaux fichiers comme ajoutés et les fichiers originaux
  5.4613 +      comme supprimés.</para>
  5.4614 +
  5.4615 +    <!-- BEGIN daily.rename.status -->
  5.4616 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.4617 +A b
  5.4618 +R a
  5.4619 +</screen>
  5.4620 +<!-- END daily.rename.status -->
  5.4621 +
  5.4622 +
  5.4623 +    <para id="x_1d5">A cause du <command role="hg-cmd" moreinfo="none">hg	copy</command>,
  5.4624 +      nous devons utiliser l'option <option role="hg-opt-status">-C</option>
  5.4625 +      pour la commande <command role="hg-cmd" moreinfo="none">hg status</command> afin
  5.4626 +      d'observer que le fichier ajouté est bien suivi par Mercurial comme
  5.4627 +      étant une copie de l'original maintenant supprimé.</para>
  5.4628 +
  5.4629 +    <!-- BEGIN daily.rename.status-copy -->
  5.4630 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -C</userinput>
  5.4631 +A b
  5.4632 +  a
  5.4633 +R a
  5.4634 +</screen>
  5.4635 +<!-- END daily.rename.status-copy -->
  5.4636 +
  5.4637 +
  5.4638 +    <para id="x_1d6">Comme avec <command role="hg-cmd" moreinfo="none">hg remove</command> et
  5.4639 +      <command role="hg-cmd" moreinfo="none">hg copy</command>, vous pouvez informer
  5.4640 +      Mercurial au sujet d'un renommage après coup en utilisant l'option
  5.4641 +      <option role="hg-opt-rename">--after</option>. Dans le plus grand
  5.4642 +      respect, le comportement de la commande <command role="hg-cmd" moreinfo="none">hg
  5.4643 +        rename</command>, et les options qu'il accepte sont similaires à la
  5.4644 +      commande <command role="hg-cmd" moreinfo="none">hg copy</command>.</para>
  5.4645 +
  5.4646 +    <para id="x_686">Si vous êtes familier avec la ligne de commande Unix,
  5.4647 +      vous serez heureux d'apprendre que la commande <command role="hg-cmd" moreinfo="none">hg rename</command> peut être invoquée par <command role="hg-cmd" moreinfo="none">hg mv</command>.</para>
  5.4648 +
  5.4649 +    <sect2>
  5.4650 +      <title>Renommer les fichiers et fusionner (merge) les changements</title>
  5.4651 +
  5.4652 +      <para id="x_1d7">Puise que le "rename" de Mercurial est implanté comme un
  5.4653 +        "copy-and-remove", la même propagation des changements a lieue après
  5.4654 +        un "rename" qu'après un "copy" lorsque vous fusionnez (merge).</para>
  5.4655 +
  5.4656 +      <para id="x_1d8">Si je modifie un fichier et que vous le renommez, si
  5.4657 +        ensuite nous fusionnons nos changements respectifs, mes modifications
  5.4658 +        sur le fichier sous son nom originel seront propagés vers le même
  5.4659 +        fichier sous son nouveau nom. (C'est quelque chose que vous pourriez
  5.4660 +        espérer voir <quote>fonctionner simplement</quote>, mais tous les
  5.4661 +        systèmes de gestion de version ne le font pas.)</para>
  5.4662 +
  5.4663 +      <para id="x_1d9">Tandis qu'avoir des changements qui suivent une copie
  5.4664 +        est une fonctionnalité où vous hocheriez sûrement la tête en disant
  5.4665 +        <quote>oui, cela pourrait être utile</quote>, il est clair que les
  5.4666 +        voir suivre un renommage est définitivement important. Sans cette
  5.4667 +        aptitude, il serait vraiment trop facile d'avoir des changements
  5.4668 +        qui deviennent orphelins lorsque des fichiers sont renommés.</para>
  5.4669 +    </sect2>
  5.4670 +
  5.4671 +    <sect2>
  5.4672 +      <title>Renommages divergeants et fusion (merge)</title>
  5.4673 +
  5.4674 +      <para id="x_1da">Le cas de noms divergeants a lieu lorsque deux
  5.4675 +        développeurs commencent avec un fichier—appelons le
  5.4676 +        <filename moreinfo="none">foo</filename>—dans leurs dépôts respectifs.</para>
  5.4677 +
  5.4678 +      <!-- BEGIN rename.divergent.clone -->
  5.4679 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone orig anne</userinput>
  5.4680 +updating working directory
  5.4681 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4682 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone orig bob</userinput>
  5.4683 +updating working directory
  5.4684 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4685 +</screen>
  5.4686 +<!-- END rename.divergent.clone -->
  5.4687 +
  5.4688 +
  5.4689 +      <para id="x_1db">Anne renomme le fichier en
  5.4690 +        <filename moreinfo="none">bar</filename>.</para>
  5.4691 +
  5.4692 +      <!-- BEGIN rename.divergent.rename.anne -->
  5.4693 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd anne</userinput>
  5.4694 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rename foo bar</userinput>
  5.4695 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m 'Rename foo to bar'</userinput>
  5.4696 +</screen>
  5.4697 +<!-- END rename.divergent.rename.anne -->
  5.4698 +
  5.4699 +
  5.4700 +      <para id="x_1dc">Pendant ce temps, Bob le renomme en
  5.4701 +        <filename moreinfo="none">quux</filename>. (Souvenez vous que <command role="hg-cmd" moreinfo="none">hg mv</command> est un alias pour <command role="hg-cmd" moreinfo="none">hg rename</command>.)</para>
  5.4702 +    
  5.4703 +      <!-- BEGIN rename.divergent.rename.bob -->
  5.4704 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../bob</userinput>
  5.4705 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg mv foo quux</userinput>
  5.4706 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m 'Rename foo to quux'</userinput>
  5.4707 +</screen>
  5.4708 +<!-- END rename.divergent.rename.bob -->
  5.4709 +
  5.4710 +
  5.4711 +      <para id="x_1dd">J'aime à penser qu'il s'agit d'un conflit puisque
  5.4712 +        chaque développeur a exprimé différentes intentions au sujet de ce
  5.4713 +        que le nom de ce fichier aurait du être.</para>
  5.4714 +
  5.4715 +      <para id="x_1de">Que pensez vous qu'il devrait se produire lorsqu'ils
  5.4716 +        fusionnent (merge) leurs travaux ? Le comportement actuel de
  5.4717 +        Mercurial est qu'il préserve toujours les <emphasis>deux</emphasis>
  5.4718 +        noms lorsqu'il fusionne (merge) des changesets qui contiennent des
  5.4719 +        renommages divergeants.</para>
  5.4720 +
  5.4721 +      <!-- BEGIN rename.divergent.merge -->
  5.4722 +<screen format="linespecific"># See http://www.selenic.com/mercurial/bts/issue455
  5.4723 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../orig</userinput>
  5.4724 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../anne</userinput>
  5.4725 +pulling from ../anne
  5.4726 +searching for changes
  5.4727 +adding changesets
  5.4728 +adding manifests
  5.4729 +adding file changes
  5.4730 +added 1 changesets with 1 changes to 1 files
  5.4731 +1 files updated, 0 files merged, 1 files removed, 0 files unresolved
  5.4732 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../bob</userinput>
  5.4733 +pulling from ../bob
  5.4734 +searching for changes
  5.4735 +adding changesets
  5.4736 +adding manifests
  5.4737 +adding file changes
  5.4738 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.4739 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.4740 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.4741 +warning: detected divergent renames of foo to:
  5.4742 + bar
  5.4743 + quux
  5.4744 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4745 +(branch merge, don't forget to commit)
  5.4746 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls</userinput>
  5.4747 +bar  quux
  5.4748 +</screen>
  5.4749 +<!-- END rename.divergent.merge -->
  5.4750 +
  5.4751 +
  5.4752 +      <para id="x_1df">Remarquez que bien que Mercurial vous avertisse au
  5.4753 +        sujet de la divergeance des renommages, il vous laisse faire quelque
  5.4754 +        chose au sujet de la divergeance après la fusion (merge).</para>
  5.4755 +    </sect2>
  5.4756 +
  5.4757 +    <sect2>
  5.4758 +      <title>Renommages et fusion convergeants</title>
  5.4759 +
  5.4760 +      <para id="x_1e0">Un autre type de conflit de renommage intervient
  5.4761 +        lorsque deux personne choisissent de renommer différents fichiers
  5.4762 +        <emphasis>source</emphasis> vers la même
  5.4763 +        <emphasis>destination</emphasis>. Dans ce cas, Mercurial exécute la
  5.4764 +        machinerie normale de fusion (merge) et vous guide vers une
  5.4765 +        solution convenable.</para>
  5.4766 +    </sect2>
  5.4767 +
  5.4768 +    <sect2>
  5.4769 +      <title>Autres cas anguleux relatifs aux noms</title>
  5.4770 +
  5.4771 +      <para id="x_1e1">Mercurial possède un bug de longue date dans lequel il
  5.4772 +        échoue à traiter une fusion (merge) où un coté a un fichier avec un
  5.4773 +        nom donné, alors que l'autre coté possède un répertoire avec le même nom.
  5.4774 +        Ceci est documenté dans l'<ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue29">issue
  5.4775 +          29</ulink>.</para>
  5.4776 +
  5.4777 +      <!-- BEGIN issue29.go -->
  5.4778 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init issue29</userinput>
  5.4779 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd issue29</userinput>
  5.4780 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  5.4781 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -Ama</userinput>
  5.4782 +adding a
  5.4783 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b</userinput>
  5.4784 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -Amb</userinput>
  5.4785 +adding b
  5.4786 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg up 0</userinput>
  5.4787 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  5.4788 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b</userinput>
  5.4789 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b/b</userinput>
  5.4790 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -Amc</userinput>
  5.4791 +adding b/b
  5.4792 +created new head
  5.4793 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.4794 +abort: Is a directory: /tmp/issue29vhrzWD/issue29/b
  5.4795 +</screen>
  5.4796 +<!-- END issue29.go -->
  5.4797 +
  5.4798 +
  5.4799 +    </sect2>
  5.4800 +  </sect1>
  5.4801 +
  5.4802 +  <sect1>
  5.4803 +    <title>Récupération d'erreurs</title>
  5.4804 +
  5.4805 +    <para id="x_1e2">Mercurial possède certaines commandes utiles qui vont
  5.4806 +      vous aider à récupérer de certaines erreurs communes.</para>
  5.4807 +
  5.4808 +    <para id="x_1e3">La commande <command role="hg-cmd" moreinfo="none">hg revert</command>
  5.4809 +      vous permet d'annuler les changements que vous avez faits dans votre
  5.4810 +      répertoire de travail. Par exemple, si vous faites un <command role="hg-cmd" moreinfo="none">hg add</command> sur un fichier par accident, exécutez
  5.4811 +      juste <command role="hg-cmd" moreinfo="none">hg	revert</command> avec le nom du fichier
  5.4812 +      que vous avez ajouté et tandis que le fichier ne sera touché d'une
  5.4813 +      quelconque manière, il ne sera plus suivi comme ajouté par Mercurial.
  5.4814 +      Vous pouvez aussi utiliser la commande <command role="hg-cmd" moreinfo="none">hg
  5.4815 +        revert</command> pour vous débarrasser de modifications erronés
  5.4816 +      apportées à un fichier.</para>
  5.4817 +
  5.4818 +    <para id="x_1e4">Il est utile de se souvenir que la commande <command role="hg-cmd" moreinfo="none">hg revert</command> est utile pour les modifications
  5.4819 +      qui n'ont pas encore été committées. Une fois que vous avez committé un
  5.4820 +      changement, si vous décidez qu'il s'agissait d'une erreur, vous pouvez
  5.4821 +      toujours faire quelque chose à ce sujet, bien que vos options soient
  5.4822 +      un peu plus limitées.</para>
  5.4823 +
  5.4824 +    <para id="x_1e5">Pour plus d'informations au sujet de la commande
  5.4825 +      <command role="hg-cmd" moreinfo="none">hg revert</command>, et des détails sur comment
  5.4826 +      traiter les modifications que vous avez déjà committées, référez vous à
  5.4827 +      <xref linkend="chap:undo"/>.</para>
  5.4828 +  </sect1>
  5.4829 +
  5.4830 +  <sect1>
  5.4831 +    <title>Traiter avec les fusions (merge) malicieuses</title>
  5.4832 +
  5.4833 +    <para id="x_687">Dans des projets compliqués ou conséquents, il n'est pas
  5.4834 +      rare qu'une fusion (merge) de deux changesets finisse par une migraine.
  5.4835 +      Supposez qu'il y ait un gros fichier source qui ait été largement édité de
  5.4836 +      chaque coté de la fusion (merge) : ceci va inévitablement résulter en
  5.4837 +      conflits, dont certains peuvent prendre plusieurs essais pour s'en
  5.4838 +      sortir.</para>
  5.4839 +
  5.4840 +    <para id="x_688">Développons en un cas simple pour voir comment le gérer.
  5.4841 +      Nous allons commencer avec un dépôt contenant un fichier, et le
  5.4842 +      cloner deux fois.</para>
  5.4843 +
  5.4844 +    <!-- BEGIN ch04/resolve.init -->
  5.4845 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init conflict</userinput>
  5.4846 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd conflict</userinput>
  5.4847 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo first &gt; myfile.txt</userinput>
  5.4848 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -A -m first</userinput>
  5.4849 +adding myfile.txt
  5.4850 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.4851 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone conflict left</userinput>
  5.4852 +updating working directory
  5.4853 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4854 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone conflict right</userinput>
  5.4855 +updating working directory
  5.4856 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4857 +</screen>
  5.4858 +<!-- END ch04/resolve.init -->
  5.4859 +
  5.4860 +
  5.4861 +    <para id="x_689">Dans un des clones, nous allons modifier le fichier
  5.4862 +      d'une façon.</para>
  5.4863 +
  5.4864 +    <!-- BEGIN ch04/resolve.left -->
  5.4865 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd left</userinput>
  5.4866 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo left &gt;&gt; myfile.txt</userinput>
  5.4867 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m left</userinput>
  5.4868 +</screen>
  5.4869 +<!-- END ch04/resolve.left -->
  5.4870 +
  5.4871 +
  5.4872 +    <para id="x_68a">Dans un autre, nous allons modifier le fichier
  5.4873 +      différemment.</para>
  5.4874 +
  5.4875 +    <!-- BEGIN ch04/resolve.right -->
  5.4876 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../right</userinput>
  5.4877 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo right &gt;&gt; myfile.txt</userinput>
  5.4878 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m right</userinput>
  5.4879 +</screen>
  5.4880 +<!-- END ch04/resolve.right -->
  5.4881 +
  5.4882 +
  5.4883 +    <para id="x_68b">Ensuite, nous allons récupérer (pull) chaque ensemble de
  5.4884 +      changement dans notre dépôt original.</para>
  5.4885 +
  5.4886 +    <!-- BEGIN ch04/resolve.pull -->
  5.4887 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../conflict</userinput>
  5.4888 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../left</userinput>
  5.4889 +pulling from ../left
  5.4890 +searching for changes
  5.4891 +adding changesets
  5.4892 +adding manifests
  5.4893 +adding file changes
  5.4894 +added 1 changesets with 1 changes to 1 files
  5.4895 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.4896 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../right</userinput>
  5.4897 +pulling from ../right
  5.4898 +searching for changes
  5.4899 +adding changesets
  5.4900 +adding manifests
  5.4901 +adding file changes
  5.4902 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.4903 +not updating, since new heads added
  5.4904 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.4905 +</screen>
  5.4906 +<!-- END ch04/resolve.pull -->
  5.4907 +
  5.4908 +
  5.4909 +    <para id="x_68c">Nous nous attendons à ce que notre dépôt contienne deux
  5.4910 +      "heads".</para>
  5.4911 +
  5.4912 +    <!-- BEGIN ch04/resolve.heads -->
  5.4913 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  5.4914 +changeset:   2:85f1afc84c33
  5.4915 +tag:         tip
  5.4916 +parent:      0:14a820f81f48
  5.4917 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.4918 +date:        Sun Aug 16 14:04:51 2009 +0000
  5.4919 +summary:     right
  5.4920 +
  5.4921 +changeset:   1:085ebbf44348
  5.4922 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.4923 +date:        Sun Aug 16 14:04:51 2009 +0000
  5.4924 +summary:     left
  5.4925 +
  5.4926 +</screen>
  5.4927 +<!-- END ch04/resolve.heads -->
  5.4928 +
  5.4929 +
  5.4930 +    <para id="x_68d">Normalement, si nous lançons <command role="hg-cmd" moreinfo="none">hg
  5.4931 +        merge</command> à ce point, il nous renverra vers une interface
  5.4932 +      utilisateur qui nous permettra de résoudre manuellement les éditions
  5.4933 +      conflictuelles sur le fichier <filename moreinfo="none">myfile.txt</filename>.
  5.4934 +      Cependant, pour simplifier ici les choses dans la présentation, nous
  5.4935 +      aimerions plutôt que la fusion (merge) échoue immédiatement. Voici une
  5.4936 +      façon de le faire.</para>
  5.4937 +
  5.4938 +    <!-- BEGIN ch04/resolve.export -->
  5.4939 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">export HGMERGE=false</userinput>
  5.4940 +</screen>
  5.4941 +<!-- END ch04/resolve.export -->
  5.4942 +
  5.4943 +
  5.4944 +    <para id="x_68e">Nous avons dit au processus de fusion de Mercurial
  5.4945 +      d'exécuter la commande <command moreinfo="none">false</command> (qui échoue
  5.4946 +      immédiatement, à la demande) s'il détecte une fusion (merge) qu'il ne
  5.4947 +      peut pas arranger automatiquement.</para>
  5.4948 +
  5.4949 +    <para id="x_68f">Si nous appelons maintenant <command role="hg-cmd" moreinfo="none">hg
  5.4950 +        merge</command>, il devrait échouer et reporter une erreur.</para>
  5.4951 +
  5.4952 +    <!-- BEGIN ch04/resolve.merge -->
  5.4953 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.4954 +merging myfile.txt
  5.4955 +merging myfile.txt failed!
  5.4956 +0 files updated, 0 files merged, 0 files removed, 1 files unresolved
  5.4957 +use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
  5.4958 +</screen>
  5.4959 +<!-- END ch04/resolve.merge -->
  5.4960 +
  5.4961 +
  5.4962 +    <para id="x_690">Même si nous ne remarquons pas qu'une fusion (merge) a
  5.4963 +      échoué, Mercurial nous empêchera de committer le résultat d'une fusion
  5.4964 +      ratée.</para>
  5.4965 +
  5.4966 +    <!-- BEGIN ch04/resolve.cifail -->
  5.4967 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Attempt to commit a failed merge'</userinput>
  5.4968 +abort: unresolved merge conflicts (see hg resolve)
  5.4969 +</screen>
  5.4970 +<!-- END ch04/resolve.cifail -->
  5.4971 +
  5.4972 +
  5.4973 +    <para id="x_691">Lorsque <command role="hg-cmd" moreinfo="none">hg commit</command>
  5.4974 +      échoue dans ce cas, il suggère que nous utilisons la commande peu
  5.4975 +      connue <command role="hg-cmd" moreinfo="none">hg resolve</command>.  Comme d'habitude,
  5.4976 +      <command role="hg-cmd" moreinfo="none">hg help resolve</command> affichera une aide
  5.4977 +      sommaire.</para>
  5.4978 +
  5.4979 +    <sect2>
  5.4980 +      <title>États de résolution des fichiers</title>
  5.4981 +      <!-- TODO Vérifier traduction : File resolution states -->
  5.4982 +
  5.4983 +      <para id="x_692">Lorsqu'une fusion intervient, la plupart des fichiers
  5.4984 +        vont, la plupart du temps, rester sans modification. Pour chaque
  5.4985 +        fichier sur lequel Mercurial doit faire quelque chose, il suit l'état
  5.4986 +        de celui-ci.</para>
  5.4987 +
  5.4988 +      <itemizedlist>
  5.4989 +        <listitem><para id="x_693">Un fichier
  5.4990 +            <quote><emphasis>resolved</emphasis></quote> a été fusionné
  5.4991 +            (merge) avec succès, que ce soit automatiquement par Mercurial ou
  5.4992 +            manuellement par une intervention humaine.</para></listitem>
  5.4993 +        <listitem><para id="x_694">Un fichier
  5.4994 +            <quote><emphasis>unresolved</emphasis></quote> n'a pas été
  5.4995 +            fusionné (merge) correctement et a besoin de plus
  5.4996 +            d'attention.</para>
  5.4997 +        </listitem>
  5.4998 +      </itemizedlist>
  5.4999 +
  5.5000 +      <para id="x_695">Si Mercurial voit un fichier
  5.5001 +        <emphasis>quelconque</emphasis> dans un état
  5.5002 +        <quote>unresolved</quote> après une fusion (merge), il considère que
  5.5003 +        la fusion (merge) a échoué. Heureusement, nous n'avons pas à
  5.5004 +        recommencer la procédure à partir du début.</para>
  5.5005 +
  5.5006 +      <para id="x_696">L'option <option role="hg-opt-resolve">--list</option>
  5.5007 +        ou <option role="hg-opt-resolve">-l</option> passée à <command role="hg-cmd" moreinfo="none">hg resolve</command> liste l'état de chaque fichier
  5.5008 +        fusionné (merge).</para>
  5.5009 +
  5.5010 +      <!-- BEGIN ch04/resolve.list -->
  5.5011 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg resolve -l</userinput>
  5.5012 +U myfile.txt
  5.5013 +</screen>
  5.5014 +<!-- END ch04/resolve.list -->
  5.5015 +
  5.5016 +
  5.5017 +      <para id="x_697">En sortie de <command role="hg-cmd" moreinfo="none">hg
  5.5018 +          resolve</command>, un fichier "resolved" est marqué avec un
  5.5019 +        <literal moreinfo="none">R</literal>, alors qu'un fichier "unresolved" est marqué
  5.5020 +        d'un <literal moreinfo="none">U</literal>.  S'il existe un fichier listé avec un
  5.5021 +        <literal moreinfo="none">U</literal>, nous savons qu'essayer de committer le résultat
  5.5022 +        de la fusion (merge) échouera.</para>
  5.5023 +    </sect2>
  5.5024 +
  5.5025 +    <sect2>
  5.5026 +      <title>Résoudre une fusion de fichier</title>
  5.5027 +
  5.5028 +      <para id="x_698">Nous avons plusieurs options pour changer l'état d'un
  5.5029 +        fichier de "unresolved" à "resolved". Le plus commun est de relancer
  5.5030 +        <command role="hg-cmd" moreinfo="none">hg resolve</command>. Si nous passons les noms
  5.5031 +        des fichiers individuels ou des répertoires, ceci retentera la fusion
  5.5032 +        de tous les fichiers présents à cet endroit. Nous pouvons aussi
  5.5033 +        passer l'option <option role="hg-opt-resolve">--all</option> ou
  5.5034 +        <option role="hg-opt-resolve">-a</option> qui tentera de fusionner
  5.5035 +        <emphasis>tous</emphasis> les fichiers "unresolved".</para>
  5.5036 +
  5.5037 +      <para id="x_699">Mercurial nous laisse aussi modifier la résolution
  5.5038 +        d'un fichier directement. Nous pouvons marquer un fichier "resolved"
  5.5039 +        en utilisant l'option <option role="hg-opt-resolve">--mark</option>,
  5.5040 +        ou "unresolved" en utilisant l'option <option role="hg-opt-resolve">--unmark</option>. Ceci nous autorise à
  5.5041 +        nettoyer une fusion particulièrement compliquée à la main, et de
  5.5042 +        garder un suivi de nos progrès avec chaque fichier pendant que nous
  5.5043 +        procédons.</para>
  5.5044 +    </sect2>
  5.5045 +  </sect1>
  5.5046 +
  5.5047 +  <sect1>
  5.5048 +    <title>Des "diffs" plus utiles</title>
  5.5049 +
  5.5050 +    <para id="x_6c7">La sortie par défaut de la commande <command role="hg-cmd" moreinfo="none">hg diff</command> est compatible rétrospectivement avec
  5.5051 +      la commande régulière <command moreinfo="none">diff</command>, mais ceci a quelques
  5.5052 +      inconvénients.</para>
  5.5053 +
  5.5054 +    <para id="x_6c8">Considérez le cas où nous utilisons <command role="hg-cmd" moreinfo="none">hg
  5.5055 +        rename</command> pour renommer un fichier.</para>
  5.5056 +
  5.5057 +    <!-- BEGIN ch04/diff.rename.basic -->
  5.5058 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rename a b</userinput>
  5.5059 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
  5.5060 +diff -r f5deb7868663 a
  5.5061 +--- a/a	Sun Aug 16 14:04:49 2009 +0000
  5.5062 ++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
  5.5063 +@@ -1,1 +0,0 @@
  5.5064 +-a
  5.5065 +diff -r f5deb7868663 b
  5.5066 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  5.5067 ++++ b/b	Sun Aug 16 14:04:49 2009 +0000
  5.5068 +@@ -0,0 +1,1 @@
  5.5069 ++a
  5.5070 +</screen>
  5.5071 +<!-- END ch04/diff.rename.basic -->
  5.5072 +
  5.5073 +
  5.5074 +    <para id="x_6c9">La sortie de <command role="hg-cmd" moreinfo="none">hg diff</command>
  5.5075 +      ci-dessus cache le fait que nous avons simplement renommé un fichier.
  5.5076 +      La commande <command role="hg-cmd" moreinfo="none">hg diff</command> accepte l'option
  5.5077 +      <option>--git</option> ou <option>-g</option> pour utiliser un nouveau
  5.5078 +      format de diff qui montre ces informations sous une forme plus
  5.5079 +      expressive.</para>
  5.5080 +
  5.5081 +    <!-- BEGIN ch04/diff.rename.git -->
  5.5082 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff -g</userinput>
  5.5083 +diff --git a/a b/b
  5.5084 +rename from a
  5.5085 +rename to b
  5.5086 +</screen>
  5.5087 +<!-- END ch04/diff.rename.git -->
  5.5088 +
  5.5089 +
  5.5090 +    <para id="x_6ca">Cette option peut aussi aider avec le cas autrement
  5.5091 +      confus : un fichier qui apparaît comme étant modifié en accord avec
  5.5092 +      <command role="hg-cmd" moreinfo="none">hg status</command>, mais où <command role="hg-cmd" moreinfo="none">hg diff</command> n'affiche rien. Cette situation peut
  5.5093 +      survenir si nous changeons les permissions d'exécution du
  5.5094 +      fichier.</para>
  5.5095 +
  5.5096 +    <!-- BEGIN ch04/diff.chmod -->
  5.5097 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">chmod +x a</userinput>
  5.5098 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg st</userinput>
  5.5099 +M a
  5.5100 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
  5.5101 +</screen>
  5.5102 +<!-- END ch04/diff.chmod -->
  5.5103 +
  5.5104 +
  5.5105 +    <para id="x_6cb">La commande normale <command moreinfo="none">diff</command> ne fait pas
  5.5106 +      attention aux permissions des fichiers, ce qui explique pourquoi
  5.5107 +      <command role="hg-cmd" moreinfo="none">hg diff</command> n'affiche rien du tout par
  5.5108 +      défaut. Si nous lui passons l'option <option>-g</option>, ceci nous
  5.5109 +      informe de ce qu'il s'est vraiment passé.</para>
  5.5110 +
  5.5111 +    <!-- BEGIN ch04/diff.chmod.git -->
  5.5112 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff -g</userinput>
  5.5113 +diff --git a/a b/a
  5.5114 +old mode 100644
  5.5115 +new mode 100755
  5.5116 +</screen>
  5.5117 +<!-- END ch04/diff.chmod.git -->
  5.5118 +
  5.5119 +  </sect1>
  5.5120 +
  5.5121 +  <sect1>
  5.5122 +    <title>Quels fichiers suivre et lesquels éviter</title>
  5.5123 +
  5.5124 +    <para id="x_6cc">Les systèmes de gestion de révisions sont en général
  5.5125 +      meilleurs pour gérer les fichiers textes qui sont écrits par les
  5.5126 +      humains, comme le code source, où les fichiers ne changent pas
  5.5127 +      énormément d'une révision à l'autre. Certains systèmes de gestion de
  5.5128 +      révisions centralisés peuvent aussi traiter très convenablement les
  5.5129 +      fichiers binaires, tels que les images bitmap.</para>
  5.5130 +
  5.5131 +    <para id="x_6cd">Par exemple, une équipe de développement de jeux va
  5.5132 +      probablement gérer les deux types : ses codes source et tous ses binaires
  5.5133 +      (ex. données géométriques, textures, schémas de cartes) dans un système
  5.5134 +      de contrôle de révisions.</para>
  5.5135 +    <!-- Vérifier la traduction de map layouts que j'ai traduit par schémas
  5.5136 +    de cartes -->
  5.5137 +
  5.5138 +    <para id="x_6ce">Puisqu'il est d'habitude impossible de fusionner (merge)
  5.5139 +      deux modifications conflictuelles sur un fichier binaire, les systèmes
  5.5140 +      de version centralisés offrent souvent un mécanisme de verrou (lock) qui
  5.5141 +      permet à un utilisateur de dire <quote>Je suis la seule personne qui
  5.5142 +        peut éditer ce fichier</quote>.</para>
  5.5143 +
  5.5144 +    <para id="x_6cf">En comparaison avec un système centralisé, un système
  5.5145 +      décentralisé de gestion de révision change certains facteurs qui
  5.5146 +      guident les décisions sur quels fichiers gérer et comment.</para>
  5.5147 +
  5.5148 +    <para id="x_6d0">Par exemple, un système distribué de gestion de révisions
  5.5149 +      ne peut pas, par sa nature, offrir un système de véroux (lock) sur les
  5.5150 +      fichiers. Il n'y a donc pas de mécanisme inclus pour empêcher deux
  5.5151 +      personnes de faire des modifications conflictuelles sur un fichier
  5.5152 +      binaire. Si vous avez une équipe où plusieurs personnes peuvent souvent
  5.5153 +      éditer un fichier binaire, cela ne serait pas une très bonne idée
  5.5154 +      d'utiliser Mercurial —ou tout autre système distribué de gestion
  5.5155 +      de révisions—pour gérer ces fichiers.</para>
  5.5156 +
  5.5157 +    <para id="x_6d1">Lorsque vous sauvegardez les modifications sur un
  5.5158 +      fichier, Mercurial ne sauvegarde d'habitude que les différences entre
  5.5159 +      la version précédente et la version actuelle d'un fichier. Pour la
  5.5160 +      plupart des fichiers texte, ceci est très efficace. Cependant, certains
  5.5161 +      fichiers (en particulier les fichiers binaires) sont construits d'une
  5.5162 +      façon que même un petit changement sur un contenu logique résulte sur
  5.5163 +      un changement de la plupart des octets du fichier. Par exemple, les
  5.5164 +      fichiers compressés sont particulièrement sujets à ce comportement. Si
  5.5165 +      les différences entre deux versions successives d'un fichier sont
  5.5166 +      toujours très grandes, Mercurial ne sera pas capable de sauvegarder
  5.5167 +      l'historique des révisions sur le fichier très efficacement. Ceci peut
  5.5168 +      affecter aussi bien les besoins pour la sauvegarde locale que le temps
  5.5169 +      nécessaire à cloner le dépôt.</para>
  5.5170 +
  5.5171 +    <para id="x_6d2">Pour avoir une idée de comment ceci pourrait vous
  5.5172 +      affecter en pratique, supposez que nous voulions que Mercurial gère des
  5.5173 +      documents OpenOffice. OpenOffice sauvegarde les documents sur le disque
  5.5174 +      comme des fichiers compressés zip. Même le fait d'éditer ces fichiers
  5.5175 +      d'une seule lettre, changera les bits de la quasi totalité du fichier
  5.5176 +      lorsque vous le sauvegarderez. Maintenant, supposez que ce fichier
  5.5177 +      fasse une taille de 2Mo. Puisque la plupart du fichier change à chaque
  5.5178 +      fois que vous sauvegardez, Mercurial aura à sauvegarder tous les 2Mo du
  5.5179 +      fichier à chaque commit, alors que de votre point de vue, il n'y a
  5.5180 +      que peu de mots qui changent à chaque fois. Un seul fichier
  5.5181 +      souvent édité qui n'est pas bien traité par les hypothèses que Mercurial
  5.5182 +      fait sur les sauvegardes peut facilement avoir un effet colossal sur la
  5.5183 +      taille du dépôt.</para>
  5.5184 +
  5.5185 +    <para id="x_6d3">Même pire, si vous et quelqu'un d'autre éditez le même
  5.5186 +      document OpenOffice sur lequel vous travaillez, il n'y a pas de façon
  5.5187 +      utile pour fusionner votre travail. En fait, il n'y a pas de moyen
  5.5188 +      utile de montrer que les différences sont faites à partir de votre
  5.5189 +      vision des modifications.</para>
  5.5190 +
  5.5191 +    <para id="x_6d4">Il y a ainsi quelques recommandations claires sur les
  5.5192 +      types de fichiers spécifiques avec lesquels faire très
  5.5193 +      attention.</para>
  5.5194 +
  5.5195 +    <itemizedlist>
  5.5196 +      <listitem><para id="x_6d5">Les fichier qui sont très gros et
  5.5197 +          incompressibles, comme les images ISO de CD-ROM, sont, par
  5.5198 +          construction très gros et les cloner à travers un réseau sera très
  5.5199 +          long.</para></listitem>
  5.5200 +     <!-- TODO : Trouver une meilleure traduction pour : ISO CD-ROM images, will by
  5.5201 +     virtue of sheer size make clones over a network very slow. -->
  5.5202 +      <listitem><para id="x_6d6">Les fichiers qui changent beaucoup d'une
  5.5203 +          révision à l'autre peuvent être très chers à sauvegarder si vous
  5.5204 +          les éditez fréquemment, de même que les conflits entre deux éditions
  5.5205 +          concurrentes peuvent être difficiles à résoudre.</para>
  5.5206 +      </listitem>
  5.5207 +    </itemizedlist>
  5.5208 +  </sect1>
  5.5209 +
  5.5210 +  <sect1>
  5.5211 +    <title>Sauvegardes et miroirs</title>
  5.5212 +
  5.5213 +    <para id="x_6d7">Puisque Mercurial maintient une copie complète de
  5.5214 +      l'historique de chaque clone, toute personne qui utilise Mercurial pour
  5.5215 +      collaborer à un projet peut potentiellement agir comme une source de
  5.5216 +      sauvegarde si une catastrophe survenait. Si un dépôt central devient
  5.5217 +      indisponible, vous pouvez construire un remplaçant en clonant une copie
  5.5218 +      du dépôt à partir d'un des contributeurs en récupérant (pull) tous les
  5.5219 +      changements qui n'auraient pas été vus par les autres.</para>
  5.5220 +
  5.5221 +    <para id="x_6d8">Il est simple d'utiliser Mercurial pour construire des
  5.5222 +      serveurs hors site de sauvegarde et des miroirs distants. Initiez une
  5.5223 +      tâche périodique (ex. via la commande <command moreinfo="none">cron</command>) sur un
  5.5224 +      serveur distant pour récupérer (pull) les changements de votre dépôt
  5.5225 +      distant chaque heure. Ceci sera difficile seulement dans le cas
  5.5226 +      improbable où le nombre des dépôts maîtres que vous maintenez change
  5.5227 +      souvent, auquel cas vous aurez besoin de faire un peu de scripting pour
  5.5228 +      rafraichir la liste des dépôt à sauvegarder.</para>
  5.5229 +
  5.5230 +    <para id="x_6d9">Si vous exécutez des sauvegardes traditionnelles de
  5.5231 +      votre dépôt maître sur bande ou disque, et que vous voulez sauvegarder
  5.5232 +      un dépôt nommé <filename moreinfo="none">myrepo</filename>, utilisez la commande
  5.5233 +      <command moreinfo="none">hg clone -U myrepo myrepo.bak</command> pour créer un clone de
  5.5234 +      <filename moreinfo="none">myrepo</filename> avant de commencer vos backups.
  5.5235 +      L'option <option>-U</option> ne crée pas de répertoire de travail après
  5.5236 +      que le clone soit accompli, puisque ceci serait superflu et ferait que
  5.5237 +      la sauvegarde prenne plus de temps.</para>
  5.5238 +
  5.5239 +    <para id="x_6da">Si vous voulez ensuite sauvegarder
  5.5240 +      <filename moreinfo="none">myrepo.bak</filename> au lieu de <filename moreinfo="none">myrepo</filename>,
  5.5241 +      vous aurez la garantie d'avoir une image (snapshot) consistante de
  5.5242 +      votre dépôt sur lequel un développeur insomniaque n'enverra (push) pas de
  5.5243 +      changements en milieu de sauvegarde.</para>
  5.5244 +  </sect1>
  5.5245 +</chapter>
  5.5246 +
  5.5247 +<!--
  5.5248 +local variables: 
  5.5249 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.5250 +end:
  5.5251 +-->
  5.5252 +
  5.5253 +  <!-- BEGIN ch06 -->
  5.5254 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.5255 +
  5.5256 +<chapter id="cha:collab">
  5.5257 +  <?dbhtml filename="collaborating-with-other-people.html"?>
  5.5258 +  <title>Collaborating with other people</title>
  5.5259 +
  5.5260 +  <para id="x_44a">As a completely decentralised tool, Mercurial doesn't impose
  5.5261 +    any policy on how people ought to work with each other.  However,
  5.5262 +    if you're new to distributed revision control, it helps to have
  5.5263 +    some tools and examples in mind when you're thinking about
  5.5264 +    possible workflow models.</para>
  5.5265 +
  5.5266 +  <sect1>
  5.5267 +    <title>Mercurial's web interface</title>
  5.5268 +
  5.5269 +    <para id="x_44b">Mercurial has a powerful web interface that provides several
  5.5270 +      useful capabilities.</para>
  5.5271 +
  5.5272 +    <para id="x_44c">For interactive use, the web interface lets you browse a
  5.5273 +      single repository or a collection of repositories.  You can view
  5.5274 +      the history of a repository, examine each change (comments and
  5.5275 +      diffs), and view the contents of each directory and file.  You
  5.5276 +      can even get a view of history that gives a graphical view of
  5.5277 +      the relationships between individual changes and merges.</para>
  5.5278 +
  5.5279 +    <para id="x_44d">Also for human consumption, the web interface provides
  5.5280 +      Atom and RSS feeds of the changes in a repository.  This lets you
  5.5281 +      <quote>subscribe</quote> to a repository using your favorite
  5.5282 +      feed reader, and be automatically notified of activity in that
  5.5283 +      repository as soon as it happens.  I find this capability much
  5.5284 +      more convenient than the model of subscribing to a mailing list
  5.5285 +      to which notifications are sent, as it requires no additional
  5.5286 +      configuration on the part of whoever is serving the
  5.5287 +      repository.</para>
  5.5288 +
  5.5289 +    <para id="x_44e">The web interface also lets remote users clone a repository,
  5.5290 +      pull changes from it, and (when the server is configured to
  5.5291 +      permit it) push changes back to it.  Mercurial's HTTP tunneling
  5.5292 +      protocol aggressively compresses data, so that it works
  5.5293 +      efficiently even over low-bandwidth network connections.</para>
  5.5294 +
  5.5295 +    <para id="x_44f">The easiest way to get started with the web interface is to
  5.5296 +      use your web browser to visit an existing repository, such as
  5.5297 +      the master Mercurial repository at <ulink url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para>
  5.5298 +
  5.5299 +    <para id="x_450">If you're interested in providing a web interface
  5.5300 +      to your own repositories, there are several good ways to do
  5.5301 +      this.</para>
  5.5302 +
  5.5303 +    <para id="x_69d">The easiest and fastest way to get started in an informal
  5.5304 +      environment is to use the <command role="hg-cmd" moreinfo="none">hg
  5.5305 +	serve</command> command, which is best suited to short-term
  5.5306 +      <quote>lightweight</quote> serving.  See <xref linkend="sec:collab:serve"/> below for details of how to use
  5.5307 +      this command.</para>
  5.5308 +
  5.5309 +    <para id="x_69e">For longer-lived repositories that you'd like to
  5.5310 +      have permanently available, there are several public hosting
  5.5311 +      services available.  Some are free to open source projects,
  5.5312 +      while others offer paid commercial hosting.  An up-to-date list
  5.5313 +      is available at <ulink url="http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting">http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting</ulink>.</para>
  5.5314 +
  5.5315 +    <para id="x_6a0">If you would prefer to host your own repositories, Mercurial
  5.5316 +      has built-in support for several popular hosting technologies,
  5.5317 +      most notably CGI (Common Gateway Interface), and WSGI (Web
  5.5318 +      Services Gateway Interface).  See <xref linkend="sec:collab:cgi"/> for details of CGI and WSGI
  5.5319 +      configuration.</para>
  5.5320 +  </sect1>
  5.5321 +
  5.5322 +  <sect1>
  5.5323 +    <title>Collaboration models</title>
  5.5324 +
  5.5325 +    <para id="x_451">With a suitably flexible tool, making decisions about
  5.5326 +      workflow is much more of a social engineering challenge than a
  5.5327 +      technical one. Mercurial imposes few limitations on how you can
  5.5328 +      structure the flow of work in a project, so it's up to you and
  5.5329 +      your group to set up and live with a model that matches your own
  5.5330 +      particular needs.</para>
  5.5331 +
  5.5332 +    <sect2>
  5.5333 +      <title>Factors to keep in mind</title>
  5.5334 +
  5.5335 +      <para id="x_452">The most important aspect of any model that you must keep
  5.5336 +	in mind is how well it matches the needs and capabilities of
  5.5337 +	the people who will be using it.  This might seem
  5.5338 +	self-evident; even so, you still can't afford to forget it for
  5.5339 +	a moment.</para>
  5.5340 +
  5.5341 +      <para id="x_453">I once put together a workflow model that seemed to make
  5.5342 +	perfect sense to me, but that caused a considerable amount of
  5.5343 +	consternation and strife within my development team.  In spite
  5.5344 +	of my attempts to explain why we needed a complex set of
  5.5345 +	branches, and how changes ought to flow between them, a few
  5.5346 +	team members revolted.  Even though they were smart people,
  5.5347 +	they didn't want to pay attention to the constraints we were
  5.5348 +	operating under, or face the consequences of those constraints
  5.5349 +	in the details of the model that I was advocating.</para>
  5.5350 +
  5.5351 +      <para id="x_454">Don't sweep foreseeable social or technical problems under
  5.5352 +	the rug. Whatever scheme you put into effect, you should plan
  5.5353 +	for mistakes and problem scenarios.  Consider adding automated
  5.5354 +	machinery to prevent, or quickly recover from, trouble that
  5.5355 +	you can anticipate.  As an example, if you intend to have a
  5.5356 +	branch with not-for-release changes in it, you'd do well to
  5.5357 +	think early about the possibility that someone might
  5.5358 +	accidentally merge those changes into a release branch.  You
  5.5359 +	could avoid this particular problem by writing a hook that
  5.5360 +	prevents changes from being merged from an inappropriate
  5.5361 +	branch.</para>
  5.5362 +    </sect2>
  5.5363 +
  5.5364 +    <sect2>
  5.5365 +      <title>Informal anarchy</title>
  5.5366 +
  5.5367 +      <para id="x_455">I wouldn't suggest an <quote>anything goes</quote>
  5.5368 +	approach as something sustainable, but it's a model that's
  5.5369 +	easy to grasp, and it works perfectly well in a few unusual
  5.5370 +	situations.</para>
  5.5371 +
  5.5372 +      <para id="x_456">As one example, many projects have a loose-knit group of
  5.5373 +	collaborators who rarely physically meet each other.  Some
  5.5374 +	groups like to overcome the isolation of working at a distance
  5.5375 +	by organizing occasional <quote>sprints</quote>.  In a sprint,
  5.5376 +	a number of people get together in a single location (a
  5.5377 +	company's conference room, a hotel meeting room, that kind of
  5.5378 +	place) and spend several days more or less locked in there,
  5.5379 +	hacking intensely on a handful of projects.</para>
  5.5380 +
  5.5381 +      <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the
  5.5382 +	<command role="hg-cmd" moreinfo="none">hg serve</command> command, since
  5.5383 +	<command role="hg-cmd" moreinfo="none">hg serve</command> does not require any
  5.5384 +	fancy server infrastructure.  You can get started with
  5.5385 +	<command role="hg-cmd" moreinfo="none">hg serve</command> in moments, by
  5.5386 +	reading <xref linkend="sec:collab:serve"/> below.  Then simply
  5.5387 +	tell the person next to you that you're running a server, send
  5.5388 +	the URL to them in an instant message, and you immediately
  5.5389 +	have a quick-turnaround way to work together.  They can type
  5.5390 +	your URL into their web browser and quickly review your
  5.5391 +	changes; or they can pull a bugfix from you and verify it; or
  5.5392 +	they can clone a branch containing a new feature and try it
  5.5393 +	out.</para>
  5.5394 +
  5.5395 +      <para id="x_458">The charm, and the problem, with doing things
  5.5396 +	in an ad hoc fashion like this is that only people who know
  5.5397 +	about your changes, and where they are, can see them.  Such an
  5.5398 +	informal approach simply doesn't scale beyond a handful
  5.5399 +	people, because each individual needs to know about
  5.5400 +	<emphasis>n</emphasis> different repositories to pull
  5.5401 +	from.</para>
  5.5402 +    </sect2>
  5.5403 +
  5.5404 +    <sect2>
  5.5405 +      <title>A single central repository</title>
  5.5406 +
  5.5407 +      <para id="x_459">For smaller projects migrating from a centralised revision
  5.5408 +	control tool, perhaps the easiest way to get started is to
  5.5409 +	have changes flow through a single shared central repository.
  5.5410 +	This is also the most common <quote>building block</quote> for
  5.5411 +	more ambitious workflow schemes.</para>
  5.5412 +
  5.5413 +      <para id="x_45a">Contributors start by cloning a copy of this repository.
  5.5414 +	They can pull changes from it whenever they need to, and some
  5.5415 +	(perhaps all) developers have permission to push a change back
  5.5416 +	when they're ready for other people to see it.</para>
  5.5417 +
  5.5418 +      <para id="x_45b">Under this model, it can still often make sense for people
  5.5419 +	to pull changes directly from each other, without going
  5.5420 +	through the central repository.  Consider a case in which I
  5.5421 +	have a tentative bug fix, but I am worried that if I were to
  5.5422 +	publish it to the central repository, it might subsequently
  5.5423 +	break everyone else's trees as they pull it.  To reduce the
  5.5424 +	potential for damage, I can ask you to clone my repository
  5.5425 +	into a temporary repository of your own and test it.  This
  5.5426 +	lets us put off publishing the potentially unsafe change until
  5.5427 +	it has had a little testing.</para>
  5.5428 +
  5.5429 +      <para id="x_45c">If a team is hosting its own repository in this
  5.5430 +	kind of scenario, people will usually use the
  5.5431 +	<command moreinfo="none">ssh</command> protocol to securely push changes to
  5.5432 +	the central repository, as documented in <xref linkend="sec:collab:ssh"/>.  It's also usual to publish a
  5.5433 +	read-only copy of the repository over HTTP, as in
  5.5434 +	<xref linkend="sec:collab:cgi"/>. Publishing over HTTP
  5.5435 +	satisfies the needs of people who don't have push access, and
  5.5436 +	those who want to use web browsers to browse the repository's
  5.5437 +	history.</para>
  5.5438 +    </sect2>
  5.5439 +
  5.5440 +    <sect2>
  5.5441 +      <title>A hosted central repository</title>
  5.5442 +
  5.5443 +      <para id="x_6a1">A wonderful thing about public hosting services like
  5.5444 +	<ulink url="http://bitbucket.org/">Bitbucket</ulink> is that
  5.5445 +	not only do they handle the fiddly server configuration
  5.5446 +	details, such as user accounts, authentication, and secure
  5.5447 +	wire protocols, they provide additional infrastructure to make
  5.5448 +	this model work well.</para>
  5.5449 +
  5.5450 +      <para id="x_6a2">For instance, a well-engineered hosting service will let
  5.5451 +	people clone their own copies of a repository with a single
  5.5452 +	click.  This lets people work in separate spaces and share
  5.5453 +	their changes when they're ready.</para>
  5.5454 +
  5.5455 +      <para id="x_6a3">In addition, a good hosting service will let people
  5.5456 +	communicate with each other, for instance to say <quote>there
  5.5457 +	  are changes ready for you to review in this
  5.5458 +	  tree</quote>.</para>
  5.5459 +    </sect2>
  5.5460 +
  5.5461 +    <sect2>
  5.5462 +      <title>Working with multiple branches</title>
  5.5463 +
  5.5464 +      <para id="x_45d">Projects of any significant size naturally tend to make
  5.5465 +	progress on several fronts simultaneously.  In the case of
  5.5466 +	software, it's common for a project to go through periodic
  5.5467 +	official releases.  A release might then go into
  5.5468 +	<quote>maintenance mode</quote> for a while after its first
  5.5469 +	publication; maintenance releases tend to contain only bug
  5.5470 +	fixes, not new features.  In parallel with these maintenance
  5.5471 +	releases, one or more future releases may be under
  5.5472 +	development.  People normally use the word
  5.5473 +	<quote>branch</quote> to refer to one of these many slightly
  5.5474 +	different directions in which development is
  5.5475 +	proceeding.</para>
  5.5476 +
  5.5477 +      <para id="x_45e">Mercurial is particularly well suited to managing a number
  5.5478 +	of simultaneous, but not identical, branches.  Each
  5.5479 +	<quote>development direction</quote> can live in its own
  5.5480 +	central repository, and you can merge changes from one to
  5.5481 +	another as the need arises.  Because repositories are
  5.5482 +	independent of each other, unstable changes in a development
  5.5483 +	branch will never affect a stable branch unless someone
  5.5484 +	explicitly merges those changes into the stable branch.</para>
  5.5485 +
  5.5486 +      <para id="x_45f">Here's an example of how this can work in practice.  Let's
  5.5487 +	say you have one <quote>main branch</quote> on a central
  5.5488 +	server.</para>
  5.5489 +
  5.5490 +      <!-- BEGIN branching.init -->
  5.5491 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init main</userinput>
  5.5492 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd main</userinput>
  5.5493 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This is a boring feature.' &gt; myfile</userinput>
  5.5494 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'We have reached an important milestone!'</userinput>
  5.5495 +adding myfile
  5.5496 +</screen>
  5.5497 +<!-- END branching.init -->
  5.5498 +
  5.5499 +
  5.5500 +      <para id="x_460">People clone it, make changes locally, test them, and push
  5.5501 +	them back.</para>
  5.5502 +
  5.5503 +      <para id="x_461">Once the main branch reaches a release milestone, you can
  5.5504 +	use the <command role="hg-cmd" moreinfo="none">hg tag</command> command to
  5.5505 +	give a permanent name to the milestone revision.</para>
  5.5506 +
  5.5507 +	<!-- BEGIN branching.tag -->
  5.5508 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag v1.0</userinput>
  5.5509 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.5510 +changeset:   1:5e447fdaf941
  5.5511 +tag:         tip
  5.5512 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.5513 +date:        Sun Aug 16 14:04:47 2009 +0000
  5.5514 +summary:     Added tag v1.0 for changeset 6412b791fd06
  5.5515 +
  5.5516 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  5.5517 +tip                                1:5e447fdaf941
  5.5518 +v1.0                               0:6412b791fd06
  5.5519 +</screen>
  5.5520 +<!-- END branching.tag -->
  5.5521 +
  5.5522 +
  5.5523 +      <para id="x_462">Let's say some ongoing
  5.5524 +	development occurs on the main branch.</para>
  5.5525 +
  5.5526 +      <!-- BEGIN branching.main -->
  5.5527 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../main</userinput>
  5.5528 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This is exciting and new!' &gt;&gt; myfile</userinput>
  5.5529 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Add a new feature'</userinput>
  5.5530 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.5531 +This is a boring feature.
  5.5532 +This is exciting and new!
  5.5533 +</screen>
  5.5534 +<!-- END branching.main -->
  5.5535 +
  5.5536 +
  5.5537 +      <para id="x_463">Using the tag that was recorded at the milestone, people
  5.5538 +	who clone that repository at any time in the future can use
  5.5539 +	<command role="hg-cmd" moreinfo="none">hg update</command> to get a copy of
  5.5540 +	the working directory exactly as it was when that tagged
  5.5541 +	revision was committed.</para>
  5.5542 +
  5.5543 +      <!-- BEGIN branching.update -->
  5.5544 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.5545 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -U main main-old</userinput>
  5.5546 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd main-old</userinput>
  5.5547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update v1.0</userinput>
  5.5548 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.5549 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.5550 +This is a boring feature.
  5.5551 +</screen>
  5.5552 +<!-- END branching.update -->
  5.5553 +
  5.5554 +
  5.5555 +      <para id="x_464">In addition, immediately after the main branch is tagged,
  5.5556 +	we can then clone the main branch on the server to a new
  5.5557 +	<quote>stable</quote> branch, also on the server.</para>
  5.5558 +
  5.5559 +      <!-- BEGIN branching.clone -->
  5.5560 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.5561 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -rv1.0 main stable</userinput>
  5.5562 +requesting all changes
  5.5563 +adding changesets
  5.5564 +adding manifests
  5.5565 +adding file changes
  5.5566 +added 1 changesets with 1 changes to 1 files
  5.5567 +updating working directory
  5.5568 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.5569 +</screen>
  5.5570 +<!-- END branching.clone -->
  5.5571 +
  5.5572 +
  5.5573 +      <para id="x_465">If we need to make a change to the stable
  5.5574 +	branch, we can then clone <emphasis>that</emphasis>
  5.5575 +	repository, make our changes, commit, and push our changes
  5.5576 +	back there.</para>
  5.5577 +
  5.5578 +      <!-- BEGIN branching.stable -->
  5.5579 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone stable stable-fix</userinput>
  5.5580 +updating working directory
  5.5581 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.5582 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd stable-fix</userinput>
  5.5583 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This is a fix to a boring feature.' &gt; myfile</userinput>
  5.5584 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Fix a bug'</userinput>
  5.5585 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  5.5586 +pushing to /tmp/branchingPsTziR/stable
  5.5587 +searching for changes
  5.5588 +adding changesets
  5.5589 +adding manifests
  5.5590 +adding file changes
  5.5591 +added 1 changesets with 1 changes to 1 files
  5.5592 +</screen>
  5.5593 +<!-- END branching.stable -->
  5.5594 +
  5.5595 +
  5.5596 +      <para id="x_466">Because Mercurial repositories are independent, and
  5.5597 +	Mercurial doesn't move changes around automatically, the
  5.5598 +	stable and main branches are <emphasis>isolated</emphasis>
  5.5599 +	from each other.  The changes that we made on the main branch
  5.5600 +	don't <quote>leak</quote> to the stable branch, and vice
  5.5601 +	versa.</para>
  5.5602 +
  5.5603 +      <para id="x_467">We'll often want all of our bugfixes on the stable
  5.5604 +	branch to show up on the main branch, too.  Rather than
  5.5605 +	rewrite a bugfix on the main branch, we can simply pull and
  5.5606 +	merge changes from the stable to the main branch, and
  5.5607 +	Mercurial will bring those bugfixes in for us.</para>
  5.5608 +
  5.5609 +      <!-- BEGIN branching.merge -->
  5.5610 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../main</userinput>
  5.5611 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../stable</userinput>
  5.5612 +pulling from ../stable
  5.5613 +searching for changes
  5.5614 +adding changesets
  5.5615 +adding manifests
  5.5616 +adding file changes
  5.5617 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.5618 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.5619 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.5620 +merging myfile
  5.5621 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  5.5622 +(branch merge, don't forget to commit)
  5.5623 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Bring in bugfix from stable branch'</userinput>
  5.5624 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.5625 +This is a fix to a boring feature.
  5.5626 +This is exciting and new!
  5.5627 +</screen>
  5.5628 +<!-- END branching.merge -->
  5.5629 +
  5.5630 +
  5.5631 +      <para id="x_468">The main branch will still contain changes that
  5.5632 +	are not on the stable branch, but it will also contain all of
  5.5633 +	the bugfixes from the stable branch.  The stable branch
  5.5634 +	remains unaffected by these changes, since changes are only
  5.5635 +	flowing from the stable to the main branch, and not the other
  5.5636 +	way.</para>
  5.5637 +    </sect2>
  5.5638 +
  5.5639 +    <sect2>
  5.5640 +      <title>Feature branches</title>
  5.5641 +
  5.5642 +      <para id="x_469">For larger projects, an effective way to manage change is
  5.5643 +	to break up a team into smaller groups.  Each group has a
  5.5644 +	shared branch of its own, cloned from a single
  5.5645 +	<quote>master</quote> branch used by the entire project.
  5.5646 +	People working on an individual branch are typically quite
  5.5647 +	isolated from developments on other branches.</para>
  5.5648 +
  5.5649 +      <figure id="fig:collab:feature-branches" float="0">
  5.5650 +	<title>Feature branches</title>
  5.5651 +	<mediaobject>
  5.5652 +	  <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject>
  5.5653 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.5654 +	</mediaobject>
  5.5655 +      </figure>
  5.5656 +
  5.5657 +      <para id="x_46b">When a particular feature is deemed to be in suitable
  5.5658 +	shape, someone on that feature team pulls and merges from the
  5.5659 +	master branch into the feature branch, then pushes back up to
  5.5660 +	the master branch.</para>
  5.5661 +    </sect2>
  5.5662 +
  5.5663 +    <sect2>
  5.5664 +      <title>The release train</title>
  5.5665 +
  5.5666 +      <para id="x_46c">Some projects are organized on a <quote>train</quote>
  5.5667 +	basis: a release is scheduled to happen every few months, and
  5.5668 +	whatever features are ready when the <quote>train</quote> is
  5.5669 +	ready to leave are allowed in.</para>
  5.5670 +
  5.5671 +      <para id="x_46d">This model resembles working with feature branches.  The
  5.5672 +	difference is that when a feature branch misses a train,
  5.5673 +	someone on the feature team pulls and merges the changes that
  5.5674 +	went out on that train release into the feature branch, and
  5.5675 +	the team continues its work on top of that release so that
  5.5676 +	their feature can make the next release.</para>
  5.5677 +    </sect2>
  5.5678 +
  5.5679 +    <sect2>
  5.5680 +      <title>The Linux kernel model</title>
  5.5681 +
  5.5682 +      <para id="x_46e">The development of the Linux kernel has a shallow
  5.5683 +	hierarchical structure, surrounded by a cloud of apparent
  5.5684 +	chaos.  Because most Linux developers use
  5.5685 +	<command moreinfo="none">git</command>, a distributed revision control tool
  5.5686 +	with capabilities similar to Mercurial, it's useful to
  5.5687 +	describe the way work flows in that environment; if you like
  5.5688 +	the ideas, the approach translates well across tools.</para>
  5.5689 +
  5.5690 +      <para id="x_46f">At the center of the community sits Linus Torvalds, the
  5.5691 +	creator of Linux.  He publishes a single source repository
  5.5692 +	that is considered the <quote>authoritative</quote> current
  5.5693 +	tree by the entire developer community. Anyone can clone
  5.5694 +	Linus's tree, but he is very choosy about whose trees he pulls
  5.5695 +	from.</para>
  5.5696 +
  5.5697 +      <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>.
  5.5698 +	As a general rule, he pulls whatever changes they publish, in
  5.5699 +	most cases without even reviewing those changes.  Some of
  5.5700 +	those lieutenants are generally agreed to be
  5.5701 +	<quote>maintainers</quote>, responsible for specific
  5.5702 +	subsystems within the kernel.  If a random kernel hacker wants
  5.5703 +	to make a change to a subsystem that they want to end up in
  5.5704 +	Linus's tree, they must find out who the subsystem's
  5.5705 +	maintainer is, and ask that maintainer to take their change.
  5.5706 +	If the maintainer reviews their changes and agrees to take
  5.5707 +	them, they'll pass them along to Linus in due course.</para>
  5.5708 +
  5.5709 +      <para id="x_471">Individual lieutenants have their own approaches to
  5.5710 +	reviewing, accepting, and publishing changes; and for deciding
  5.5711 +	when to feed them to Linus.  In addition, there are several
  5.5712 +	well known branches that people use for different purposes.
  5.5713 +	For example, a few people maintain <quote>stable</quote>
  5.5714 +	repositories of older versions of the kernel, to which they
  5.5715 +	apply critical fixes as needed.  Some maintainers publish
  5.5716 +	multiple trees: one for experimental changes; one for changes
  5.5717 +	that they are about to feed upstream; and so on.  Others just
  5.5718 +	publish a single tree.</para>
  5.5719 +
  5.5720 +      <para id="x_472">This model has two notable features.  The first is that
  5.5721 +	it's <quote>pull only</quote>.  You have to ask, convince, or
  5.5722 +	beg another developer to take a change from you, because there
  5.5723 +	are almost no trees to which more than one person can push,
  5.5724 +	and there's no way to push changes into a tree that someone
  5.5725 +	else controls.</para>
  5.5726 +
  5.5727 +      <para id="x_473">The second is that it's based on reputation and acclaim.
  5.5728 +	If you're an unknown, Linus will probably ignore changes from
  5.5729 +	you without even responding.  But a subsystem maintainer will
  5.5730 +	probably review them, and will likely take them if they pass
  5.5731 +	their criteria for suitability. The more <quote>good</quote>
  5.5732 +	changes you contribute to a maintainer, the more likely they
  5.5733 +	are to trust your judgment and accept your changes.  If you're
  5.5734 +	well-known and maintain a long-lived branch for something
  5.5735 +	Linus hasn't yet accepted, people with similar interests may
  5.5736 +	pull your changes regularly to keep up with your work.</para>
  5.5737 +
  5.5738 +      <para id="x_474">Reputation and acclaim don't necessarily cross subsystem
  5.5739 +	or <quote>people</quote> boundaries.  If you're a respected
  5.5740 +	but specialised storage hacker, and you try to fix a
  5.5741 +	networking bug, that change will receive a level of scrutiny
  5.5742 +	from a network maintainer comparable to a change from a
  5.5743 +	complete stranger.</para>
  5.5744 +
  5.5745 +      <para id="x_475">To people who come from more orderly project backgrounds,
  5.5746 +	the comparatively chaotic Linux kernel development process
  5.5747 +	often seems completely insane.  It's subject to the whims of
  5.5748 +	individuals; people make sweeping changes whenever they deem
  5.5749 +	it appropriate; and the pace of development is astounding.
  5.5750 +	And yet Linux is a highly successful, well-regarded piece of
  5.5751 +	software.</para>
  5.5752 +    </sect2>
  5.5753 +
  5.5754 +    <sect2>
  5.5755 +      <title>Pull-only versus shared-push collaboration</title>
  5.5756 +
  5.5757 +      <para id="x_476">A perpetual source of heat in the open source community is
  5.5758 +	whether a development model in which people only ever pull
  5.5759 +	changes from others is <quote>better than</quote> one in which
  5.5760 +	multiple people can push changes to a shared
  5.5761 +	repository.</para>
  5.5762 +
  5.5763 +      <para id="x_477">Typically, the backers of the shared-push model use tools
  5.5764 +	that actively enforce this approach.  If you're using a
  5.5765 +	centralised revision control tool such as Subversion, there's
  5.5766 +	no way to make a choice over which model you'll use: the tool
  5.5767 +	gives you shared-push, and if you want to do anything else,
  5.5768 +	you'll have to roll your own approach on top (such as applying
  5.5769 +	a patch by hand).</para>
  5.5770 +
  5.5771 +      <para id="x_478">A good distributed revision control tool will
  5.5772 +	support both models.  You and your collaborators can then
  5.5773 +	structure how you work together based on your own needs and
  5.5774 +	preferences, not on what contortions your tools force you
  5.5775 +	into.</para>
  5.5776 +    </sect2>
  5.5777 +    <sect2>
  5.5778 +      <title>Where collaboration meets branch management</title>
  5.5779 +
  5.5780 +      <para id="x_479">Once you and your team set up some shared
  5.5781 +	repositories and start propagating changes back and forth
  5.5782 +	between local and shared repos, you begin to face a related,
  5.5783 +	but slightly different challenge: that of managing the
  5.5784 +	multiple directions in which your team may be moving at once.
  5.5785 +	Even though this subject is intimately related to how your
  5.5786 +	team collaborates, it's dense enough to merit treatment of its
  5.5787 +	own, in <xref linkend="chap:branch"/>.</para>
  5.5788 +    </sect2>
  5.5789 +  </sect1>
  5.5790 +
  5.5791 +  <sect1>
  5.5792 +    <title>The technical side of sharing</title>
  5.5793 +
  5.5794 +    <para id="x_47a">The remainder of this chapter is devoted to the question of
  5.5795 +      sharing changes with your collaborators.</para>
  5.5796 +  </sect1>
  5.5797 +
  5.5798 +  <sect1 id="sec:collab:serve">
  5.5799 +    <title>Informal sharing with <command role="hg-cmd" moreinfo="none">hg
  5.5800 +	serve</command></title>
  5.5801 +
  5.5802 +    <para id="x_47b">Mercurial's <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.5803 +      command is wonderfully suited to small, tight-knit, and
  5.5804 +      fast-paced group environments.  It also provides a great way to
  5.5805 +      get a feel for using Mercurial commands over a network.</para>
  5.5806 +
  5.5807 +    <para id="x_47c">Run <command role="hg-cmd" moreinfo="none">hg serve</command> inside a
  5.5808 +      repository, and in under a second it will bring up a specialised
  5.5809 +      HTTP server; this will accept connections from any client, and
  5.5810 +      serve up data for that repository until you terminate it.
  5.5811 +      Anyone who knows the URL of the server you just started, and can
  5.5812 +      talk to your computer over the network, can then use a web
  5.5813 +      browser or Mercurial to read data from that repository.  A URL
  5.5814 +      for a <command role="hg-cmd" moreinfo="none">hg serve</command> instance running
  5.5815 +      on a laptop is likely to look something like
  5.5816 +      <literal moreinfo="none">http://my-laptop.local:8000/</literal>.</para>
  5.5817 +
  5.5818 +    <para id="x_47d">The <command role="hg-cmd" moreinfo="none">hg serve</command> command is
  5.5819 +      <emphasis>not</emphasis> a general-purpose web server. It can do
  5.5820 +      only two things:</para>
  5.5821 +    <itemizedlist>
  5.5822 +      <listitem><para id="x_47e">Allow people to browse the history of the
  5.5823 +	  repository it's serving, from their normal web
  5.5824 +	  browsers.</para>
  5.5825 +      </listitem>
  5.5826 +      <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people
  5.5827 +	  can <command role="hg-cmd" moreinfo="none">hg clone</command> or <command role="hg-cmd" moreinfo="none">hg pull</command> changes from that
  5.5828 +	  repository.</para>
  5.5829 +      </listitem></itemizedlist>
  5.5830 +    <para id="x_480">In particular, <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.5831 +      won't allow remote users to <emphasis>modify</emphasis> your
  5.5832 +      repository.  It's intended for read-only use.</para>
  5.5833 +
  5.5834 +    <para id="x_481">If you're getting started with Mercurial, there's nothing to
  5.5835 +      prevent you from using <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.5836 +      to serve up a repository on your own computer, then use commands
  5.5837 +      like <command role="hg-cmd" moreinfo="none">hg clone</command>, <command role="hg-cmd" moreinfo="none">hg incoming</command>, and so on to talk to that
  5.5838 +      server as if the repository was hosted remotely. This can help
  5.5839 +      you to quickly get acquainted with using commands on
  5.5840 +      network-hosted repositories.</para>
  5.5841 +
  5.5842 +    <sect2>
  5.5843 +      <title>A few things to keep in mind</title>
  5.5844 +
  5.5845 +      <para id="x_482">Because it provides unauthenticated read access to all
  5.5846 +	clients, you should only use <command role="hg-cmd" moreinfo="none">hg
  5.5847 +	  serve</command> in an environment where you either don't
  5.5848 +	care, or have complete control over, who can access your
  5.5849 +	network and pull data from your repository.</para>
  5.5850 +
  5.5851 +      <para id="x_483">The <command role="hg-cmd" moreinfo="none">hg serve</command> command
  5.5852 +	knows nothing about any firewall software you might have
  5.5853 +	installed on your system or network.  It cannot detect or
  5.5854 +	control your firewall software.  If other people are unable to
  5.5855 +	talk to a running <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.5856 +	instance, the second thing you should do
  5.5857 +	(<emphasis>after</emphasis> you make sure that they're using
  5.5858 +	the correct URL) is check your firewall configuration.</para>
  5.5859 +
  5.5860 +      <para id="x_484">By default, <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.5861 +	listens for incoming connections on port 8000.  If another
  5.5862 +	process is already listening on the port you want to use, you
  5.5863 +	can specify a different port to listen on using the <option role="hg-opt-serve">-p</option> option.</para>
  5.5864 +
  5.5865 +      <para id="x_485">Normally, when <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.5866 +	starts, it prints no output, which can be a bit unnerving.  If
  5.5867 +	you'd like to confirm that it is indeed running correctly, and
  5.5868 +	find out what URL you should send to your collaborators, start
  5.5869 +	it with the <option role="hg-opt-global">-v</option>
  5.5870 +	option.</para>
  5.5871 +    </sect2>
  5.5872 +  </sect1>
  5.5873 +
  5.5874 +  <sect1 id="sec:collab:ssh">
  5.5875 +    <title>Using the Secure Shell (ssh) protocol</title>
  5.5876 +
  5.5877 +    <para id="x_486">You can pull and push changes securely over a network
  5.5878 +      connection using the Secure Shell (<literal moreinfo="none">ssh</literal>)
  5.5879 +      protocol.  To use this successfully, you may have to do a little
  5.5880 +      bit of configuration on the client or server sides.</para>
  5.5881 +
  5.5882 +    <para id="x_487">If you're not familiar with ssh, it's the name of
  5.5883 +      both a command and a network protocol that let you securely
  5.5884 +      communicate with another computer.  To use it with Mercurial,
  5.5885 +      you'll be setting up one or more user accounts on a server so
  5.5886 +      that remote users can log in and execute commands.</para>
  5.5887 +
  5.5888 +    <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll
  5.5889 +      probably find some of the material that follows to be elementary
  5.5890 +      in nature.)</para>
  5.5891 +
  5.5892 +    <sect2>
  5.5893 +      <title>How to read and write ssh URLs</title>
  5.5894 +
  5.5895 +      <para id="x_489">An ssh URL tends to look like this:</para>
  5.5896 +      <programlisting format="linespecific">ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
  5.5897 +      <orderedlist inheritnum="ignore" continuation="restarts">
  5.5898 +	<listitem><para id="x_48a">The <quote><literal moreinfo="none">ssh://</literal></quote>
  5.5899 +	    part tells Mercurial to use the ssh protocol.</para>
  5.5900 +	</listitem>
  5.5901 +	<listitem><para id="x_48b">The <quote><literal moreinfo="none">bos@</literal></quote>
  5.5902 +	    component indicates what username to log into the server
  5.5903 +	    as.  You can leave this out if the remote username is the
  5.5904 +	    same as your local username.</para>
  5.5905 +	</listitem>
  5.5906 +	<listitem><para id="x_48c">The
  5.5907 +	    <quote><literal moreinfo="none">hg.serpentine.com</literal></quote> gives
  5.5908 +	    the hostname of the server to log into.</para>
  5.5909 +	</listitem>
  5.5910 +	<listitem><para id="x_48d">The <quote>:22</quote> identifies the port
  5.5911 +	    number to connect to the server on.  The default port is
  5.5912 +	    22, so you only need to specify a colon and port number if
  5.5913 +	    you're <emphasis>not</emphasis> using port 22.</para>
  5.5914 +	</listitem>
  5.5915 +	<listitem><para id="x_48e">The remainder of the URL is the local path to
  5.5916 +	    the repository on the server.</para>
  5.5917 +	</listitem></orderedlist>
  5.5918 +
  5.5919 +      <para id="x_48f">There's plenty of scope for confusion with the path
  5.5920 +	component of ssh URLs, as there is no standard way for tools
  5.5921 +	to interpret it.  Some programs behave differently than others
  5.5922 +	when dealing with these paths. This isn't an ideal situation,
  5.5923 +	but it's unlikely to change.  Please read the following
  5.5924 +	paragraphs carefully.</para>
  5.5925 +
  5.5926 +      <para id="x_490">Mercurial treats the path to a repository on the server as
  5.5927 +	relative to the remote user's home directory.  For example, if
  5.5928 +	user <literal moreinfo="none">foo</literal> on the server has a home directory
  5.5929 +	of <filename class="directory" moreinfo="none">/home/foo</filename>, then an
  5.5930 +	ssh URL that contains a path component of <filename class="directory" moreinfo="none">bar</filename> <emphasis>really</emphasis>
  5.5931 +	refers to the directory <filename class="directory" moreinfo="none">/home/foo/bar</filename>.</para>
  5.5932 +
  5.5933 +      <para id="x_491">If you want to specify a path relative to another user's
  5.5934 +	home directory, you can use a path that starts with a tilde
  5.5935 +	character followed by the user's name (let's call them
  5.5936 +	<literal moreinfo="none">otheruser</literal>), like this.</para>
  5.5937 +      <programlisting format="linespecific">ssh://server/~otheruser/hg/repo</programlisting>
  5.5938 +
  5.5939 +      <para id="x_492">And if you really want to specify an
  5.5940 +	<emphasis>absolute</emphasis> path on the server, begin the
  5.5941 +	path component with two slashes, as in this example.</para>
  5.5942 +      <programlisting format="linespecific">ssh://server//absolute/path</programlisting>
  5.5943 +    </sect2>
  5.5944 +
  5.5945 +    <sect2>
  5.5946 +      <title>Finding an ssh client for your system</title>
  5.5947 +
  5.5948 +      <para id="x_493">Almost every Unix-like system comes with OpenSSH
  5.5949 +	preinstalled.  If you're using such a system, run
  5.5950 +	<literal moreinfo="none">which ssh</literal> to find out if the
  5.5951 +	<command moreinfo="none">ssh</command> command is installed (it's usually in
  5.5952 +	<filename class="directory" moreinfo="none">/usr/bin</filename>).  In the
  5.5953 +	unlikely event that it isn't present, take a look at your
  5.5954 +	system documentation to figure out how to install it.</para>
  5.5955 +
  5.5956 +      <para id="x_494">On Windows, the TortoiseHg package is bundled
  5.5957 +	with a version of Simon Tatham's excellent
  5.5958 +	<command moreinfo="none">plink</command> command, and you should not need to
  5.5959 +	do any further configuration.</para>
  5.5960 +    </sect2>
  5.5961 +
  5.5962 +    <sect2>
  5.5963 +      <title>Generating a key pair</title>
  5.5964 +
  5.5965 +      <para id="x_499">To avoid the need to repetitively type a
  5.5966 +	password every time you need to use your ssh client, I
  5.5967 +	recommend generating a key pair.</para>
  5.5968 +
  5.5969 +      <tip>
  5.5970 +	<title>Key pairs are not mandatory</title>
  5.5971 +
  5.5972 +	<para id="x_6a4">Mercurial knows nothing about ssh authentication or key
  5.5973 +	  pairs.  You can, if you like, safely ignore this section and
  5.5974 +	  the one that follows until you grow tired of repeatedly
  5.5975 +	  typing ssh passwords.</para>
  5.5976 +      </tip>
  5.5977 +
  5.5978 +      <itemizedlist>
  5.5979 +	<listitem>
  5.5980 +	  <para id="x_6a5">On a Unix-like system, the
  5.5981 +	    <command moreinfo="none">ssh-keygen</command> command will do the
  5.5982 +	    trick.</para>
  5.5983 +	  <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need
  5.5984 +	    to download a command named <command moreinfo="none">puttygen</command>
  5.5985 +	    from <ulink url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 
  5.5986 +	      PuTTY web site</ulink> to generate a key pair.  See
  5.5987 +	    <ulink url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 
  5.5988 +	      <command moreinfo="none">puttygen</command> documentation</ulink> for
  5.5989 +	    details of how use the command.</para>
  5.5990 +	</listitem>
  5.5991 +      </itemizedlist>
  5.5992 +
  5.5993 +      <para id="x_49a">When you generate a key pair, it's usually
  5.5994 +	<emphasis>highly</emphasis> advisable to protect it with a
  5.5995 +	passphrase.  (The only time that you might not want to do this
  5.5996 +	is when you're using the ssh protocol for automated tasks on a
  5.5997 +	secure network.)</para>
  5.5998 +
  5.5999 +      <para id="x_49b">Simply generating a key pair isn't enough, however.
  5.6000 +	You'll need to add the public key to the set of authorised
  5.6001 +	keys for whatever user you're logging in remotely as.  For
  5.6002 +	servers using OpenSSH (the vast majority), this will mean
  5.6003 +	adding the public key to a list in a file called <filename role="special" moreinfo="none">authorized_keys</filename> in their <filename role="special" class="directory" moreinfo="none">.ssh</filename>
  5.6004 +	directory.</para>
  5.6005 +
  5.6006 +      <para id="x_49c">On a Unix-like system, your public key will have a
  5.6007 +	<filename moreinfo="none">.pub</filename> extension.  If you're using
  5.6008 +	<command moreinfo="none">puttygen</command> on Windows, you can save the
  5.6009 +	public key to a file of your choosing, or paste it from the
  5.6010 +	window it's displayed in straight into the <filename role="special" moreinfo="none">authorized_keys</filename> file.</para>
  5.6011 +    </sect2>
  5.6012 +    <sect2>
  5.6013 +      <title>Using an authentication agent</title>
  5.6014 +
  5.6015 +      <para id="x_49d">An authentication agent is a daemon that stores
  5.6016 +	passphrases in memory (so it will forget passphrases if you
  5.6017 +	log out and log back in again). An ssh client will notice if
  5.6018 +	it's running, and query it for a passphrase.  If there's no
  5.6019 +	authentication agent running, or the agent doesn't store the
  5.6020 +	necessary passphrase, you'll have to type your passphrase
  5.6021 +	every time Mercurial tries to communicate with a server on
  5.6022 +	your behalf (e.g. whenever you pull or push changes).</para>
  5.6023 +
  5.6024 +      <para id="x_49e">The downside of storing passphrases in an agent is that
  5.6025 +	it's possible for a well-prepared attacker to recover the
  5.6026 +	plain text of your passphrases, in some cases even if your
  5.6027 +	system has been power-cycled. You should make your own
  5.6028 +	judgment as to whether this is an acceptable risk.  It
  5.6029 +	certainly saves a lot of repeated typing.</para>
  5.6030 +
  5.6031 +      <itemizedlist>
  5.6032 +	<listitem>
  5.6033 +	  <para id="x_49f">On Unix-like systems, the agent is called
  5.6034 +	    <command moreinfo="none">ssh-agent</command>, and it's often run
  5.6035 +	    automatically for you when you log in.  You'll need to use
  5.6036 +	    the <command moreinfo="none">ssh-add</command> command to add passphrases
  5.6037 +	    to the agent's store.</para>
  5.6038 +	</listitem>
  5.6039 +	<listitem>
  5.6040 +	  <para id="x_6a7">On Windows, if you're using TortoiseHg, the
  5.6041 +	    <command moreinfo="none">pageant</command> command acts as the agent.  As
  5.6042 +	    with <command moreinfo="none">puttygen</command>, you'll need to <ulink url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 
  5.6043 +	      <command moreinfo="none">pageant</command></ulink> from the PuTTY web
  5.6044 +	    site and read <ulink url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 
  5.6045 +	      documentation</ulink>.  The <command moreinfo="none">pageant</command>
  5.6046 +	    command adds an icon to your system tray that will let you
  5.6047 +	    manage stored passphrases.</para>
  5.6048 +	</listitem>
  5.6049 +      </itemizedlist>
  5.6050 +    </sect2>
  5.6051 +
  5.6052 +    <sect2>
  5.6053 +      <title>Configuring the server side properly</title>
  5.6054 +
  5.6055 +      <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it,
  5.6056 +	a variety of things can go wrong.  Add Mercurial
  5.6057 +	on top, and there's plenty more scope for head-scratching.
  5.6058 +	Most of these potential problems occur on the server side, not
  5.6059 +	the client side.  The good news is that once you've gotten a
  5.6060 +	configuration working, it will usually continue to work
  5.6061 +	indefinitely.</para>
  5.6062 +
  5.6063 +      <para id="x_4a1">Before you try using Mercurial to talk to an ssh server,
  5.6064 +	it's best to make sure that you can use the normal
  5.6065 +	<command moreinfo="none">ssh</command> or <command moreinfo="none">putty</command> command to
  5.6066 +	talk to the server first.  If you run into problems with using
  5.6067 +	these commands directly, Mercurial surely won't work.  Worse,
  5.6068 +	it will obscure the underlying problem.  Any time you want to
  5.6069 +	debug ssh-related Mercurial problems, you should drop back to
  5.6070 +	making sure that plain ssh client commands work first,
  5.6071 +	<emphasis>before</emphasis> you worry about whether there's a
  5.6072 +	problem with Mercurial.</para>
  5.6073 +
  5.6074 +      <para id="x_4a2">The first thing to be sure of on the server side is that
  5.6075 +	you can actually log in from another machine at all.  If you
  5.6076 +	can't use <command moreinfo="none">ssh</command> or <command moreinfo="none">putty</command>
  5.6077 +	to log in, the error message you get may give you a few hints
  5.6078 +	as to what's wrong.  The most common problems are as
  5.6079 +	follows.</para>
  5.6080 +      <itemizedlist>
  5.6081 +	<listitem><para id="x_4a3">If you get a <quote>connection refused</quote>
  5.6082 +	    error, either there isn't an SSH daemon running on the
  5.6083 +	    server at all, or it's inaccessible due to firewall
  5.6084 +	    configuration.</para>
  5.6085 +	</listitem>
  5.6086 +	<listitem><para id="x_4a4">If you get a <quote>no route to host</quote>
  5.6087 +	    error, you either have an incorrect address for the server
  5.6088 +	    or a seriously locked down firewall that won't admit its
  5.6089 +	    existence at all.</para>
  5.6090 +	</listitem>
  5.6091 +	<listitem><para id="x_4a5">If you get a <quote>permission denied</quote>
  5.6092 +	    error, you may have mistyped the username on the server,
  5.6093 +	    or you could have mistyped your key's passphrase or the
  5.6094 +	    remote user's password.</para>
  5.6095 +	</listitem></itemizedlist>
  5.6096 +      <para id="x_4a6">In summary, if you're having trouble talking to the
  5.6097 +	server's ssh daemon, first make sure that one is running at
  5.6098 +	all.  On many systems it will be installed, but disabled, by
  5.6099 +	default.  Once you're done with this step, you should then
  5.6100 +	check that the server's firewall is configured to allow
  5.6101 +	incoming connections on the port the ssh daemon is listening
  5.6102 +	on (usually 22).  Don't worry about more exotic possibilities
  5.6103 +	for misconfiguration until you've checked these two
  5.6104 +	first.</para>
  5.6105 +
  5.6106 +      <para id="x_4a7">If you're using an authentication agent on the client side
  5.6107 +	to store passphrases for your keys, you ought to be able to
  5.6108 +	log into the server without being prompted for a passphrase or
  5.6109 +	a password.  If you're prompted for a passphrase, there are a
  5.6110 +	few possible culprits.</para>
  5.6111 +      <itemizedlist>
  5.6112 +	<listitem><para id="x_4a8">You might have forgotten to use
  5.6113 +	    <command moreinfo="none">ssh-add</command> or <command moreinfo="none">pageant</command>
  5.6114 +	    to store the passphrase.</para>
  5.6115 +	</listitem>
  5.6116 +	<listitem><para id="x_4a9">You might have stored the passphrase for the
  5.6117 +	    wrong key.</para>
  5.6118 +	</listitem></itemizedlist>
  5.6119 +      <para id="x_4aa">If you're being prompted for the remote user's password,
  5.6120 +	there are another few possible problems to check.</para>
  5.6121 +      <itemizedlist>
  5.6122 +	<listitem><para id="x_4ab">Either the user's home directory or their
  5.6123 +	    <filename role="special" class="directory" moreinfo="none">.ssh</filename>
  5.6124 +	    directory might have excessively liberal permissions.  As
  5.6125 +	    a result, the ssh daemon will not trust or read their
  5.6126 +	    <filename role="special" moreinfo="none">authorized_keys</filename> file.
  5.6127 +	    For example, a group-writable home or <filename role="special" class="directory" moreinfo="none">.ssh</filename>
  5.6128 +	    directory will often cause this symptom.</para>
  5.6129 +	</listitem>
  5.6130 +	<listitem><para id="x_4ac">The user's <filename role="special" moreinfo="none">authorized_keys</filename> file may have
  5.6131 +	    a problem. If anyone other than the user owns or can write
  5.6132 +	    to that file, the ssh daemon will not trust or read
  5.6133 +	    it.</para>
  5.6134 +	</listitem></itemizedlist>
  5.6135 +
  5.6136 +      <para id="x_4ad">In the ideal world, you should be able to run the
  5.6137 +	following command successfully, and it should print exactly
  5.6138 +	one line of output, the current date and time.</para>
  5.6139 +      <programlisting format="linespecific">ssh myserver date</programlisting>
  5.6140 +
  5.6141 +      <para id="x_4ae">If, on your server, you have login scripts that print
  5.6142 +	banners or other junk even when running non-interactive
  5.6143 +	commands like this, you should fix them before you continue,
  5.6144 +	so that they only print output if they're run interactively.
  5.6145 +	Otherwise these banners will at least clutter up Mercurial's
  5.6146 +	output.  Worse, they could potentially cause problems with
  5.6147 +	running Mercurial commands remotely.  Mercurial tries to
  5.6148 +	detect and ignore banners in non-interactive
  5.6149 +	<command moreinfo="none">ssh</command> sessions, but it is not foolproof.  (If
  5.6150 +	you're editing your login scripts on your server, the usual
  5.6151 +	way to see if a login script is running in an interactive
  5.6152 +	shell is to check the return code from the command
  5.6153 +	<literal moreinfo="none">tty -s</literal>.)</para>
  5.6154 +
  5.6155 +      <para id="x_4af">Once you've verified that plain old ssh is working with
  5.6156 +	your server, the next step is to ensure that Mercurial runs on
  5.6157 +	the server.  The following command should run
  5.6158 +	successfully:</para>
  5.6159 +
  5.6160 +      <programlisting format="linespecific">ssh myserver hg version</programlisting>
  5.6161 +
  5.6162 +      <para id="x_4b0">If you see an error message instead of normal <command role="hg-cmd" moreinfo="none">hg version</command> output, this is usually
  5.6163 +	because you haven't installed Mercurial to <filename class="directory" moreinfo="none">/usr/bin</filename>.  Don't worry if this
  5.6164 +	is the case; you don't need to do that.  But you should check
  5.6165 +	for a few possible problems.</para>
  5.6166 +      <itemizedlist>
  5.6167 +	<listitem><para id="x_4b1">Is Mercurial really installed on the server at
  5.6168 +	    all?  I know this sounds trivial, but it's worth
  5.6169 +	    checking!</para>
  5.6170 +	</listitem>
  5.6171 +	<listitem><para id="x_4b2">Maybe your shell's search path (usually set
  5.6172 +	    via the <envar>PATH</envar> environment variable) is
  5.6173 +	    simply misconfigured.</para>
  5.6174 +	</listitem>
  5.6175 +	<listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment
  5.6176 +	    variable is only being set to point to the location of the
  5.6177 +	    <command moreinfo="none">hg</command> executable if the login session is
  5.6178 +	    interactive.  This can happen if you're setting the path
  5.6179 +	    in the wrong shell login script.  See your shell's
  5.6180 +	    documentation for details.</para>
  5.6181 +	</listitem>
  5.6182 +	<listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> environment
  5.6183 +	    variable may need to contain the path to the Mercurial
  5.6184 +	    Python modules.  It might not be set at all; it could be
  5.6185 +	    incorrect; or it may be set only if the login is
  5.6186 +	    interactive.</para>
  5.6187 +	</listitem></itemizedlist>
  5.6188 +
  5.6189 +      <para id="x_4b5">If you can run <command role="hg-cmd" moreinfo="none">hg version</command>
  5.6190 +	over an ssh connection, well done! You've got the server and
  5.6191 +	client sorted out.  You should now be able to use Mercurial to
  5.6192 +	access repositories hosted by that username on that server.
  5.6193 +	If you run into problems with Mercurial and ssh at this point,
  5.6194 +	try using the <option role="hg-opt-global">--debug</option>
  5.6195 +	option to get a clearer picture of what's going on.</para>
  5.6196 +    </sect2>
  5.6197 +    <sect2>
  5.6198 +      <title>Using compression with ssh</title>
  5.6199 +
  5.6200 +      <para id="x_4b6">Mercurial does not compress data when it uses the ssh
  5.6201 +	protocol, because the ssh protocol can transparently compress
  5.6202 +	data.  However, the default behavior of ssh clients is
  5.6203 +	<emphasis>not</emphasis> to request compression.</para>
  5.6204 +
  5.6205 +      <para id="x_4b7">Over any network other than a fast LAN (even a wireless
  5.6206 +	network), using compression is likely to significantly speed
  5.6207 +	up Mercurial's network operations.  For example, over a WAN,
  5.6208 +	someone measured compression as reducing the amount of time
  5.6209 +	required to clone a particularly large repository from 51
  5.6210 +	minutes to 17 minutes.</para>
  5.6211 +
  5.6212 +      <para id="x_4b8">Both <command moreinfo="none">ssh</command> and <command moreinfo="none">plink</command>
  5.6213 +	accept a <option role="cmd-opt-ssh">-C</option> option which
  5.6214 +	turns on compression.  You can easily edit your <filename role="special" moreinfo="none">~/.hgrc</filename> to enable compression for
  5.6215 +	all of Mercurial's uses of the ssh protocol.  Here is how to
  5.6216 +	do so for regular <command moreinfo="none">ssh</command> on Unix-like systems,
  5.6217 +	for example.</para>
  5.6218 +      <programlisting format="linespecific">[ui]
  5.6219 +ssh = ssh -C</programlisting>
  5.6220 +
  5.6221 +      <para id="x_4b9">If you use <command moreinfo="none">ssh</command> on a
  5.6222 +	Unix-like system, you can configure it to always use
  5.6223 +	compression when talking to your server.  To do this, edit
  5.6224 +	your <filename role="special" moreinfo="none">.ssh/config</filename> file
  5.6225 +	(which may not yet exist), as follows.</para>
  5.6226 +
  5.6227 +      <programlisting format="linespecific">Host hg
  5.6228 +  Compression yes
  5.6229 +  HostName hg.example.com</programlisting>
  5.6230 +
  5.6231 +      <para id="x_4ba">This defines a hostname alias,
  5.6232 +	<literal moreinfo="none">hg</literal>.  When you use that hostname on the
  5.6233 +	<command moreinfo="none">ssh</command> command line or in a Mercurial
  5.6234 +	<literal moreinfo="none">ssh</literal>-protocol URL, it will cause
  5.6235 +	<command moreinfo="none">ssh</command> to connect to
  5.6236 +	<literal moreinfo="none">hg.example.com</literal> and use compression.  This
  5.6237 +	gives you both a shorter name to type and compression, each of
  5.6238 +	which is a good thing in its own right.</para>
  5.6239 +    </sect2>
  5.6240 +  </sect1>
  5.6241 +
  5.6242 +  <sect1 id="sec:collab:cgi">
  5.6243 +    <title>Serving over HTTP using CGI</title>
  5.6244 +
  5.6245 +    <para id="x_6a8">The simplest way to host one or more repositories in a
  5.6246 +      permanent way is to use a web server and Mercurial's CGI
  5.6247 +      support.</para>
  5.6248 +
  5.6249 +    <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's
  5.6250 +      CGI interface can take anything from a few moments to several
  5.6251 +      hours.</para>
  5.6252 +
  5.6253 +    <para id="x_4bc">We'll begin with the simplest of examples, and work our way
  5.6254 +      towards a more complex configuration.  Even for the most basic
  5.6255 +      case, you're almost certainly going to need to read and modify
  5.6256 +      your web server's configuration.</para>
  5.6257 +
  5.6258 +    <note>
  5.6259 +      <title>High pain tolerance required</title>
  5.6260 +
  5.6261 +      <para id="x_4bd">Configuring a web server is a complex, fiddly,
  5.6262 +	and highly system-dependent activity.  I can't possibly give
  5.6263 +	you instructions that will cover anything like all of the
  5.6264 +	cases you will encounter. Please use your discretion and
  5.6265 +	judgment in following the sections below.  Be prepared to make
  5.6266 +	plenty of mistakes, and to spend a lot of time reading your
  5.6267 +	server's error logs.</para>
  5.6268 +
  5.6269 +      <para id="x_6a9">If you don't have a strong stomach for tweaking
  5.6270 +	configurations over and over, or a compelling need to host
  5.6271 +	your own services, you might want to try one of the public
  5.6272 +	hosting services that I mentioned earlier.</para>
  5.6273 +    </note>
  5.6274 +
  5.6275 +    <sect2>
  5.6276 +      <title>Web server configuration checklist</title>
  5.6277 +
  5.6278 +      <para id="x_4be">Before you continue, do take a few moments to check a few
  5.6279 +	aspects of your system's setup.</para>
  5.6280 +
  5.6281 +      <orderedlist inheritnum="ignore" continuation="restarts">
  5.6282 +	<listitem><para id="x_4bf">Do you have a web server installed
  5.6283 +	    at all? Mac OS X and some Linux distributions ship with
  5.6284 +	    Apache, but many other systems may not have a web server
  5.6285 +	    installed.</para>
  5.6286 +	</listitem>
  5.6287 +	<listitem><para id="x_4c0">If you have a web server installed, is it
  5.6288 +	    actually running?  On most systems, even if one is
  5.6289 +	    present, it will be disabled by default.</para>
  5.6290 +	</listitem>
  5.6291 +	<listitem><para id="x_4c1">Is your server configured to allow you to run
  5.6292 +	    CGI programs in the directory where you plan to do so?
  5.6293 +	    Most servers default to explicitly disabling the ability
  5.6294 +	    to run CGI programs.</para>
  5.6295 +	</listitem></orderedlist>
  5.6296 +
  5.6297 +      <para id="x_4c2">If you don't have a web server installed, and don't have
  5.6298 +	substantial experience configuring Apache, you should consider
  5.6299 +	using the <literal moreinfo="none">lighttpd</literal> web server instead of
  5.6300 +	Apache.  Apache has a well-deserved reputation for baroque and
  5.6301 +	confusing configuration. While <literal moreinfo="none">lighttpd</literal> is
  5.6302 +	less capable in some ways than Apache, most of these
  5.6303 +	capabilities are not relevant to serving Mercurial
  5.6304 +	repositories.  And <literal moreinfo="none">lighttpd</literal> is undeniably
  5.6305 +	<emphasis>much</emphasis> easier to get started with than
  5.6306 +	Apache.</para>
  5.6307 +    </sect2>
  5.6308 +
  5.6309 +    <sect2>
  5.6310 +      <title>Basic CGI configuration</title>
  5.6311 +
  5.6312 +      <para id="x_4c3">On Unix-like systems, it's common for users to have a
  5.6313 +	subdirectory named something like <filename class="directory" moreinfo="none">public_html</filename> in their home
  5.6314 +	directory, from which they can serve up web pages.  A file
  5.6315 +	named <filename moreinfo="none">foo</filename> in this directory will be
  5.6316 +	accessible at a URL of the form
  5.6317 +	<literal moreinfo="none">http://www.example.com/username/foo</literal>.</para>
  5.6318 +
  5.6319 +      <para id="x_4c4">To get started, find the <filename role="special" moreinfo="none">hgweb.cgi</filename> script that should be
  5.6320 +	present in your Mercurial installation.  If you can't quickly
  5.6321 +	find a local copy on your system, simply download one from the
  5.6322 +	master Mercurial repository at <ulink url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para>
  5.6323 +
  5.6324 +      <para id="x_4c5">You'll need to copy this script into your <filename class="directory" moreinfo="none">public_html</filename> directory, and
  5.6325 +	ensure that it's executable.</para>
  5.6326 +      <programlisting format="linespecific">cp .../hgweb.cgi ~/public_html
  5.6327 +chmod 755 ~/public_html/hgweb.cgi</programlisting>
  5.6328 +      <para id="x_4c6">The <literal moreinfo="none">755</literal> argument to
  5.6329 +	<command moreinfo="none">chmod</command> is a little more general than just
  5.6330 +	making the script executable: it ensures that the script is
  5.6331 +	executable by anyone, and that <quote>group</quote> and
  5.6332 +	<quote>other</quote> write permissions are
  5.6333 +	<emphasis>not</emphasis> set.  If you were to leave those
  5.6334 +	write permissions enabled, Apache's <literal moreinfo="none">suexec</literal>
  5.6335 +	subsystem would likely refuse to execute the script.  In fact,
  5.6336 +	<literal moreinfo="none">suexec</literal> also insists that the
  5.6337 +	<emphasis>directory</emphasis> in which the script resides
  5.6338 +	must not be writable by others.</para>
  5.6339 +      <programlisting format="linespecific">chmod 755 ~/public_html</programlisting>
  5.6340 +
  5.6341 +      <sect3 id="sec:collab:wtf">
  5.6342 +	<title>What could <emphasis>possibly</emphasis> go
  5.6343 +	  wrong?</title>
  5.6344 +
  5.6345 +	<para id="x_4c7">Once you've copied the CGI script into place,
  5.6346 +	  go into a web browser, and try to open the URL
  5.6347 +	  <literal moreinfo="none">http://myhostname/~myuser/hgweb.cgi</literal>,
  5.6348 +	  <emphasis>but</emphasis> brace yourself for instant failure.
  5.6349 +	  There's a high probability that trying to visit this URL
  5.6350 +	  will fail, and there are many possible reasons for this.  In
  5.6351 +	  fact, you're likely to stumble over almost every one of the
  5.6352 +	  possible errors below, so please read carefully.  The
  5.6353 +	  following are all of the problems I ran into on a system
  5.6354 +	  running Fedora 7, with a fresh installation of Apache, and a
  5.6355 +	  user account that I created specially to perform this
  5.6356 +	  exercise.</para>
  5.6357 +
  5.6358 +	<para id="x_4c8">Your web server may have per-user directories disabled.
  5.6359 +	  If you're using Apache, search your config file for a
  5.6360 +	  <literal moreinfo="none">UserDir</literal> directive.  If there's none
  5.6361 +	  present, per-user directories will be disabled.  If one
  5.6362 +	  exists, but its value is <literal moreinfo="none">disabled</literal>, then
  5.6363 +	  per-user directories will be disabled.  Otherwise, the
  5.6364 +	  string after <literal moreinfo="none">UserDir</literal> gives the name of
  5.6365 +	  the subdirectory that Apache will look in under your home
  5.6366 +	  directory, for example <filename class="directory" moreinfo="none">public_html</filename>.</para>
  5.6367 +
  5.6368 +	<para id="x_4c9">Your file access permissions may be too restrictive.
  5.6369 +	  The web server must be able to traverse your home directory
  5.6370 +	  and directories under your <filename class="directory" moreinfo="none">public_html</filename> directory, and
  5.6371 +	  read files under the latter too.  Here's a quick recipe to
  5.6372 +	  help you to make your permissions more appropriate.</para>
  5.6373 +	<programlisting format="linespecific">chmod 755 ~
  5.6374 +find ~/public_html -type d -print0 | xargs -0r chmod 755
  5.6375 +find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
  5.6376 +
  5.6377 +	<para id="x_4ca">The other possibility with permissions is that you might
  5.6378 +	  get a completely empty window when you try to load the
  5.6379 +	  script.  In this case, it's likely that your access
  5.6380 +	  permissions are <emphasis>too permissive</emphasis>.  Apache's
  5.6381 +	  <literal moreinfo="none">suexec</literal> subsystem won't execute a script
  5.6382 +	  that's group- or world-writable, for example.</para>
  5.6383 +
  5.6384 +	<para id="x_4cb">Your web server may be configured to disallow execution
  5.6385 +	  of CGI programs in your per-user web directory.  Here's
  5.6386 +	  Apache's default per-user configuration from my Fedora
  5.6387 +	  system.</para>
  5.6388 +
  5.6389 +	<!-- BEGIN ch06/apache-config.lst -->
  5.6390 +<programlisting format="linespecific">&lt;Directory /home/*/public_html&gt;
  5.6391 +  AllowOverride FileInfo AuthConfig Limit
  5.6392 +  Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  5.6393 +  &lt;Limit GET POST OPTIONS&gt;
  5.6394 +    Order allow,deny
  5.6395 +    Allow from all
  5.6396 +  &lt;/Limit&gt;
  5.6397 +  &lt;LimitExcept GET POST OPTIONS&gt;
  5.6398 +    Order deny,allow Deny from all
  5.6399 +  &lt;/LimitExcept&gt;
  5.6400 +&lt;/Directory&gt;</programlisting>
  5.6401 +<!-- END ch06/apache-config.lst -->
  5.6402 +
  5.6403 +
  5.6404 +	<para id="x_4cc">If you find a similar-looking
  5.6405 +	  <literal moreinfo="none">Directory</literal> group in your Apache
  5.6406 +	  configuration, the directive to look at inside it is
  5.6407 +	  <literal moreinfo="none">Options</literal>. Add <literal moreinfo="none">ExecCGI</literal>
  5.6408 +	  to the end of this list if it's missing, and restart the web
  5.6409 +	  server.</para>
  5.6410 +
  5.6411 +	<para id="x_4cd">If you find that Apache serves you the text of the CGI
  5.6412 +	  script instead of executing it, you may need to either
  5.6413 +	  uncomment (if already present) or add a directive like
  5.6414 +	  this.</para>
  5.6415 +	<programlisting format="linespecific">AddHandler cgi-script .cgi</programlisting>
  5.6416 +
  5.6417 +	<para id="x_4ce">The next possibility is that you might be served with a
  5.6418 +	  colourful Python backtrace claiming that it can't import a
  5.6419 +	  <literal moreinfo="none">mercurial</literal>-related module.  This is
  5.6420 +	  actually progress!  The server is now capable of executing
  5.6421 +	  your CGI script.  This error is only likely to occur if
  5.6422 +	  you're running a private installation of Mercurial, instead
  5.6423 +	  of a system-wide version.  Remember that the web server runs
  5.6424 +	  the CGI program without any of the environment variables
  5.6425 +	  that you take for granted in an interactive session.  If
  5.6426 +	  this error happens to you, edit your copy of <filename role="special" moreinfo="none">hgweb.cgi</filename> and follow the
  5.6427 +	  directions inside it to correctly set your
  5.6428 +	  <envar>PYTHONPATH</envar> environment variable.</para>
  5.6429 +
  5.6430 +	<para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to be
  5.6431 +	  served with another colourful Python backtrace: this one
  5.6432 +	  will complain that it can't find <filename class="directory" moreinfo="none">/path/to/repository</filename>.  Edit
  5.6433 +	  your <filename role="special" moreinfo="none">hgweb.cgi</filename> script
  5.6434 +	  and replace the <filename class="directory" moreinfo="none">/path/to/repository</filename> string
  5.6435 +	  with the complete path to the repository you want to serve
  5.6436 +	  up.</para>
  5.6437 +
  5.6438 +	<para id="x_4d0">At this point, when you try to reload the page, you
  5.6439 +	  should be presented with a nice HTML view of your
  5.6440 +	  repository's history.  Whew!</para>
  5.6441 +      </sect3>
  5.6442 +
  5.6443 +      <sect3>
  5.6444 +	<title>Configuring lighttpd</title>
  5.6445 +
  5.6446 +	<para id="x_4d1">To be exhaustive in my experiments, I tried configuring
  5.6447 +	  the increasingly popular <literal moreinfo="none">lighttpd</literal> web
  5.6448 +	  server to serve the same repository as I described with
  5.6449 +	  Apache above.  I had already overcome all of the problems I
  5.6450 +	  outlined with Apache, many of which are not server-specific.
  5.6451 +	  As a result, I was fairly sure that my file and directory
  5.6452 +	  permissions were good, and that my <filename role="special" moreinfo="none">hgweb.cgi</filename> script was properly
  5.6453 +	  edited.</para>
  5.6454 +
  5.6455 +	<para id="x_4d2">Once I had Apache running, getting
  5.6456 +	  <literal moreinfo="none">lighttpd</literal> to serve the repository was a
  5.6457 +	  snap (in other words, even if you're trying to use
  5.6458 +	  <literal moreinfo="none">lighttpd</literal>, you should read the Apache
  5.6459 +	  section).  I first had to edit the
  5.6460 +	  <literal moreinfo="none">mod_access</literal> section of its config file to
  5.6461 +	  enable <literal moreinfo="none">mod_cgi</literal> and
  5.6462 +	  <literal moreinfo="none">mod_userdir</literal>, both of which were disabled
  5.6463 +	  by default on my system.  I then added a few lines to the
  5.6464 +	  end of the config file, to configure these modules.</para>
  5.6465 +	<programlisting format="linespecific">userdir.path = "public_html"
  5.6466 +cgi.assign = (".cgi" =&gt; "" )</programlisting>
  5.6467 +	<para id="x_4d3">With this done, <literal moreinfo="none">lighttpd</literal> ran
  5.6468 +	  immediately for me.  If I had configured
  5.6469 +	  <literal moreinfo="none">lighttpd</literal> before Apache, I'd almost
  5.6470 +	  certainly have run into many of the same system-level
  5.6471 +	  configuration problems as I did with Apache.  However, I
  5.6472 +	  found <literal moreinfo="none">lighttpd</literal> to be noticeably easier to
  5.6473 +	  configure than Apache, even though I've used Apache for over
  5.6474 +	  a decade, and this was my first exposure to
  5.6475 +	  <literal moreinfo="none">lighttpd</literal>.</para>
  5.6476 +      </sect3>
  5.6477 +    </sect2>
  5.6478 +
  5.6479 +    <sect2>
  5.6480 +      <title>Sharing multiple repositories with one CGI script</title>
  5.6481 +
  5.6482 +      <para id="x_4d4">The <filename role="special" moreinfo="none">hgweb.cgi</filename> script
  5.6483 +	only lets you publish a single repository, which is an
  5.6484 +	annoying restriction.  If you want to publish more than one
  5.6485 +	without wracking yourself with multiple copies of the same
  5.6486 +	script, each with different names, a better choice is to use
  5.6487 +	the <filename role="special" moreinfo="none">hgwebdir.cgi</filename>
  5.6488 +	script.</para>
  5.6489 +
  5.6490 +      <para id="x_4d5">The procedure to configure <filename role="special" moreinfo="none">hgwebdir.cgi</filename> is only a little more
  5.6491 +	involved than for <filename role="special" moreinfo="none">hgweb.cgi</filename>.  First, you must obtain
  5.6492 +	a copy of the script.  If you don't have one handy, you can
  5.6493 +	download a copy from the master Mercurial repository at <ulink url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para>
  5.6494 +
  5.6495 +      <para id="x_4d6">You'll need to copy this script into your <filename class="directory" moreinfo="none">public_html</filename> directory, and
  5.6496 +	ensure that it's executable.</para>
  5.6497 +
  5.6498 +      <programlisting format="linespecific">cp .../hgwebdir.cgi ~/public_html
  5.6499 +chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
  5.6500 +
  5.6501 +      <para id="x_4d7">With basic configuration out of the way, try to
  5.6502 +	visit <literal moreinfo="none">http://myhostname/~myuser/hgwebdir.cgi</literal>
  5.6503 +	in your	browser.  It should
  5.6504 +	display an empty list of repositories.  If you get a blank
  5.6505 +	window or error message, try walking through the list of
  5.6506 +	potential problems in <xref linkend="sec:collab:wtf"/>.</para>
  5.6507 +
  5.6508 +      <para id="x_4d8">The <filename role="special" moreinfo="none">hgwebdir.cgi</filename>
  5.6509 +	script relies on an external configuration file.  By default,
  5.6510 +	it searches for a file named <filename role="special" moreinfo="none">hgweb.config</filename> in the same directory
  5.6511 +	as itself.  You'll need to create this file, and make it
  5.6512 +	world-readable.  The format of the file is similar to a
  5.6513 +	Windows <quote>ini</quote> file, as understood by Python's
  5.6514 +	<literal moreinfo="none">ConfigParser</literal>
  5.6515 +	<citation>web:configparser</citation> module.</para>
  5.6516 +
  5.6517 +      <para id="x_4d9">The easiest way to configure <filename role="special" moreinfo="none">hgwebdir.cgi</filename> is with a section
  5.6518 +	named <literal moreinfo="none">collections</literal>.  This will automatically
  5.6519 +	publish <emphasis>every</emphasis> repository under the
  5.6520 +	directories you name.  The section should look like
  5.6521 +	this:</para>
  5.6522 +      <programlisting format="linespecific">[collections]
  5.6523 +/my/root = /my/root</programlisting>
  5.6524 +      <para id="x_4da">Mercurial interprets this by looking at the directory name
  5.6525 +	on the <emphasis>right</emphasis> hand side of the
  5.6526 +	<quote><literal moreinfo="none">=</literal></quote> sign; finding repositories
  5.6527 +	in that directory hierarchy; and using the text on the
  5.6528 +	<emphasis>left</emphasis> to strip off matching text from the
  5.6529 +	names it will actually list in the web interface.  The
  5.6530 +	remaining component of a path after this stripping has
  5.6531 +	occurred is called a <quote>virtual path</quote>.</para>
  5.6532 +
  5.6533 +      <para id="x_4db">Given the example above, if we have a
  5.6534 +	repository whose local path is <filename class="directory" moreinfo="none">/my/root/this/repo</filename>, the CGI
  5.6535 +	script will strip the leading <filename class="directory" moreinfo="none">/my/root</filename> from the name, and
  5.6536 +	publish the repository with a virtual path of <filename class="directory" moreinfo="none">this/repo</filename>.  If the base URL for
  5.6537 +	our CGI script is
  5.6538 +	<literal moreinfo="none">http://myhostname/~myuser/hgwebdir.cgi</literal>, the
  5.6539 +	complete URL for that repository will be
  5.6540 +	<literal moreinfo="none">http://myhostname/~myuser/hgwebdir.cgi/this/repo</literal>.</para>
  5.6541 +
  5.6542 +      <para id="x_4dc">If we replace <filename class="directory" moreinfo="none">/my/root</filename> on the left hand side
  5.6543 +	of this example with <filename class="directory" moreinfo="none">/my</filename>, then <filename role="special" moreinfo="none">hgwebdir.cgi</filename> will only strip off
  5.6544 +	<filename class="directory" moreinfo="none">/my</filename> from the repository
  5.6545 +	name, and will give us a virtual path of <filename class="directory" moreinfo="none">root/this/repo</filename> instead of
  5.6546 +	<filename class="directory" moreinfo="none">this/repo</filename>.</para>
  5.6547 +
  5.6548 +      <para id="x_4dd">The <filename role="special" moreinfo="none">hgwebdir.cgi</filename>
  5.6549 +	script will recursively search each directory listed in the
  5.6550 +	<literal moreinfo="none">collections</literal> section of its configuration
  5.6551 +	file, but it will <literal moreinfo="none">not</literal> recurse into the
  5.6552 +	repositories it finds.</para>
  5.6553 +
  5.6554 +      <para id="x_4de">The <literal moreinfo="none">collections</literal> mechanism makes it easy
  5.6555 +	to publish many repositories in a <quote>fire and
  5.6556 +	  forget</quote> manner.  You only need to set up the CGI
  5.6557 +	script and configuration file one time.  Afterwards, you can
  5.6558 +	publish or unpublish a repository at any time by simply moving
  5.6559 +	it into, or out of, the directory hierarchy in which you've
  5.6560 +	configured <filename role="special" moreinfo="none">hgwebdir.cgi</filename> to
  5.6561 +	look.</para>
  5.6562 +
  5.6563 +      <sect3>
  5.6564 +	<title>Explicitly specifying which repositories to
  5.6565 +	  publish</title>
  5.6566 +
  5.6567 +	<para id="x_4df">In addition to the <literal moreinfo="none">collections</literal>
  5.6568 +	  mechanism, the <filename role="special" moreinfo="none">hgwebdir.cgi</filename> script allows you
  5.6569 +	  to publish a specific list of repositories.  To do so,
  5.6570 +	  create a <literal moreinfo="none">paths</literal> section, with contents of
  5.6571 +	  the following form.</para>
  5.6572 +	<programlisting format="linespecific">[paths]
  5.6573 +repo1 = /my/path/to/some/repo
  5.6574 +repo2 = /some/path/to/another</programlisting>
  5.6575 +	<para id="x_4e0">In this case, the virtual path (the component that will
  5.6576 +	  appear in a URL) is on the left hand side of each
  5.6577 +	  definition, while the path to the repository is on the
  5.6578 +	  right.  Notice that there does not need to be any
  5.6579 +	  relationship between the virtual path you choose and the
  5.6580 +	  location of a repository in your filesystem.</para>
  5.6581 +
  5.6582 +	<para id="x_4e1">If you wish, you can use both the
  5.6583 +	  <literal moreinfo="none">collections</literal> and <literal moreinfo="none">paths</literal>
  5.6584 +	  mechanisms simultaneously in a single configuration
  5.6585 +	  file.</para>
  5.6586 +
  5.6587 +	<note>
  5.6588 +	  <title>Beware duplicate virtual paths</title>
  5.6589 +
  5.6590 +	  <para id="x_4e2">  If several repositories have the same
  5.6591 +	    virtual path, <filename role="special" moreinfo="none">hgwebdir.cgi</filename> will not report
  5.6592 +	    an error.  Instead, it will behave unpredictably.</para>
  5.6593 +	</note>
  5.6594 +      </sect3>
  5.6595 +    </sect2>
  5.6596 +
  5.6597 +    <sect2>
  5.6598 +      <title>Downloading source archives</title>
  5.6599 +
  5.6600 +      <para id="x_4e3">Mercurial's web interface lets users download an archive
  5.6601 +	of any revision.  This archive will contain a snapshot of the
  5.6602 +	working directory as of that revision, but it will not contain
  5.6603 +	a copy of the repository data.</para>
  5.6604 +
  5.6605 +      <para id="x_4e4">By default, this feature is not enabled.  To enable it,
  5.6606 +	you'll need to add an <envar role="rc-item-web">allow_archive</envar> item to the
  5.6607 +	<literal role="rc-web" moreinfo="none">web</literal> section of your <filename role="special" moreinfo="none">~/.hgrc</filename>; see below for details.</para>
  5.6608 +    </sect2>
  5.6609 +    <sect2>
  5.6610 +      <title>Web configuration options</title>
  5.6611 +
  5.6612 +      <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd" moreinfo="none">hg
  5.6613 +	  serve</command> command, and the <filename role="special" moreinfo="none">hgweb.cgi</filename> and <filename role="special" moreinfo="none">hgwebdir.cgi</filename> scripts) have a
  5.6614 +	number of configuration options that you can set.  These
  5.6615 +	belong in a section named <literal role="rc-web" moreinfo="none">web</literal>.</para>
  5.6616 +      <itemizedlist>
  5.6617 +	<listitem><para id="x_4e6"><envar role="rc-item-web">allow_archive</envar>: Determines
  5.6618 +	    which (if any) archive download mechanisms Mercurial
  5.6619 +	    supports.  If you enable this feature, users of the web
  5.6620 +	    interface will be able to download an archive of whatever
  5.6621 +	    revision of a repository they are viewing. To enable the
  5.6622 +	    archive feature, this item must take the form of a
  5.6623 +	    sequence of words drawn from the list below.</para>
  5.6624 +	  <itemizedlist>
  5.6625 +	    <listitem><para id="x_4e7"><literal moreinfo="none">bz2</literal>: A
  5.6626 +		<command moreinfo="none">tar</command> archive, compressed using
  5.6627 +		<literal moreinfo="none">bzip2</literal> compression.  This has the
  5.6628 +		best compression ratio, but uses the most CPU time on
  5.6629 +		the server.</para>
  5.6630 +	    </listitem>
  5.6631 +	    <listitem><para id="x_4e8"><literal moreinfo="none">gz</literal>: A
  5.6632 +		<command moreinfo="none">tar</command> archive, compressed using
  5.6633 +		<literal moreinfo="none">gzip</literal> compression.</para>
  5.6634 +	    </listitem>
  5.6635 +	    <listitem><para id="x_4e9"><literal moreinfo="none">zip</literal>: A
  5.6636 +		<command moreinfo="none">zip</command> archive, compressed using LZW
  5.6637 +		compression.  This format has the worst compression
  5.6638 +		ratio, but is widely used in the Windows world.</para>
  5.6639 +	    </listitem>
  5.6640 +	  </itemizedlist>
  5.6641 +	  <para id="x_4ea">  If you provide an empty list, or don't have an
  5.6642 +	    <envar role="rc-item-web">allow_archive</envar> entry at
  5.6643 +	    all, this feature will be disabled.  Here is an example of
  5.6644 +	    how to enable all three supported formats.</para>
  5.6645 +	  <programlisting format="linespecific">[web]
  5.6646 +allow_archive = bz2 gz zip</programlisting>
  5.6647 +	</listitem>
  5.6648 +	<listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>:
  5.6649 +	    Boolean.  Determines whether the web interface allows
  5.6650 +	    remote users to <command role="hg-cmd" moreinfo="none">hg pull</command>
  5.6651 +	    and <command role="hg-cmd" moreinfo="none">hg clone</command> this
  5.6652 +	    repository over HTTP.  If set to <literal moreinfo="none">no</literal> or
  5.6653 +	    <literal moreinfo="none">false</literal>, only the
  5.6654 +	    <quote>human-oriented</quote> portion of the web interface
  5.6655 +	    is available.</para>
  5.6656 +	</listitem>
  5.6657 +	<listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>:
  5.6658 +	    String.  A free-form (but preferably brief) string
  5.6659 +	    identifying the person or group in charge of the
  5.6660 +	    repository.  This often contains the name and email
  5.6661 +	    address of a person or mailing list.  It often makes sense
  5.6662 +	    to place this entry in a repository's own <filename role="special" moreinfo="none">.hg/hgrc</filename> file, but it can make
  5.6663 +	    sense to use in a global <filename role="special" moreinfo="none">~/.hgrc</filename> if every repository
  5.6664 +	    has a single maintainer.</para>
  5.6665 +	</listitem>
  5.6666 +	<listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>:
  5.6667 +	    Integer.  The default maximum number of changesets to
  5.6668 +	    display in a single page of output.</para>
  5.6669 +	</listitem>
  5.6670 +	<listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>:
  5.6671 +	    Integer.  The default maximum number of modified files to
  5.6672 +	    display in a single page of output.</para>
  5.6673 +	</listitem>
  5.6674 +	<listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>:
  5.6675 +	    Integer.  If the web interface displays alternating
  5.6676 +	    <quote>stripes</quote> to make it easier to visually align
  5.6677 +	    rows when you are looking at a table, this number controls
  5.6678 +	    the number of rows in each stripe.</para>
  5.6679 +	</listitem>
  5.6680 +	<listitem><para id="x_4f0"><envar role="rc-item-web">style</envar>: Controls the template
  5.6681 +	    Mercurial uses to display the web interface.  Mercurial
  5.6682 +	    ships with several web templates.</para>
  5.6683 +	  <itemizedlist>
  5.6684 +	    <listitem>
  5.6685 +	      <para id="x_6aa"><literal moreinfo="none">coal</literal> is monochromatic.</para>
  5.6686 +	    </listitem>
  5.6687 +	    <listitem>
  5.6688 +	      <para id="x_6ab"><literal moreinfo="none">gitweb</literal> emulates the visual
  5.6689 +		style of git's web interface.</para>
  5.6690 +	    </listitem>
  5.6691 +	    <listitem>
  5.6692 +	      <para id="x_6ac"><literal moreinfo="none">monoblue</literal> uses solid blues and
  5.6693 +		greys.</para>
  5.6694 +	    </listitem>
  5.6695 +	    <listitem>
  5.6696 +	      <para id="x_6ad"><literal moreinfo="none">paper</literal> is the default.</para>
  5.6697 +	    </listitem>
  5.6698 +	    <listitem>
  5.6699 +	      <para id="x_6ae"><literal moreinfo="none">spartan</literal> was the default for a
  5.6700 +		long time.</para>
  5.6701 +	    </listitem>
  5.6702 +	  </itemizedlist>
  5.6703 +	  <para id="x_6af">You can
  5.6704 +	    also specify a custom template of your own; see 
  5.6705 +	    <xref linkend="chap:template"/> for details. Here, you can
  5.6706 +	    see how to enable the <literal moreinfo="none">gitweb</literal>
  5.6707 +	    style.</para>
  5.6708 +	  <programlisting format="linespecific">[web]
  5.6709 +style = gitweb</programlisting>
  5.6710 +	</listitem>
  5.6711 +	<listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>:
  5.6712 +	    Path.  The directory in which to search for template
  5.6713 +	    files.  By default, Mercurial searches in the directory in
  5.6714 +	    which it was installed.</para>
  5.6715 +	</listitem></itemizedlist>
  5.6716 +      <para id="x_4f2">If you are using <filename role="special" moreinfo="none">hgwebdir.cgi</filename>, you can place a few
  5.6717 +	configuration items in a <literal role="rc-web" moreinfo="none">web</literal>
  5.6718 +	section of the <filename role="special" moreinfo="none">hgweb.config</filename> file instead of a
  5.6719 +	<filename role="special" moreinfo="none">~/.hgrc</filename> file, for
  5.6720 +	convenience.  These items are <envar role="rc-item-web">motd</envar> and <envar role="rc-item-web">style</envar>.</para>
  5.6721 +
  5.6722 +      <sect3>
  5.6723 +	<title>Options specific to an individual repository</title>
  5.6724 +
  5.6725 +	<para id="x_4f3">A few <literal role="rc-web" moreinfo="none">web</literal> configuration
  5.6726 +	  items ought to be placed in a repository's local <filename role="special" moreinfo="none">.hg/hgrc</filename>, rather than a user's
  5.6727 +	  or global <filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
  5.6728 +	<itemizedlist>
  5.6729 +	  <listitem><para id="x_4f4"><envar role="rc-item-web">description</envar>: String.  A
  5.6730 +	      free-form (but preferably brief) string that describes
  5.6731 +	      the contents or purpose of the repository.</para>
  5.6732 +	  </listitem>
  5.6733 +	  <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>:
  5.6734 +	      String.  The name to use for the repository in the web
  5.6735 +	      interface.  This overrides the default name, which is
  5.6736 +	      the last component of the repository's path.</para>
  5.6737 +	  </listitem></itemizedlist>
  5.6738 +      </sect3>
  5.6739 +
  5.6740 +      <sect3>
  5.6741 +	<title>Options specific to the <command role="hg-cmd" moreinfo="none">hg
  5.6742 +	    serve</command> command</title>
  5.6743 +
  5.6744 +	<para id="x_4f6">Some of the items in the <literal role="rc-web" moreinfo="none">web</literal> section of a <filename role="special" moreinfo="none">~/.hgrc</filename> file are only for use
  5.6745 +	  with the <command role="hg-cmd" moreinfo="none">hg serve</command>
  5.6746 +	  command.</para>
  5.6747 +	<itemizedlist>
  5.6748 +	  <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>:
  5.6749 +	      Path.  The name of a file into which to write an access
  5.6750 +	      log.  By default, the <command role="hg-cmd" moreinfo="none">hg
  5.6751 +		serve</command> command writes this information to
  5.6752 +	      standard output, not to a file.  Log entries are written
  5.6753 +	      in the standard <quote>combined</quote> file format used
  5.6754 +	      by almost all web servers.</para>
  5.6755 +	  </listitem>
  5.6756 +	  <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>:
  5.6757 +	      String.  The local address on which the server should
  5.6758 +	      listen for incoming connections.  By default, the server
  5.6759 +	      listens on all addresses.</para>
  5.6760 +	  </listitem>
  5.6761 +	  <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>:
  5.6762 +	      Path.  The name of a file into which to write an error
  5.6763 +	      log.  By default, the <command role="hg-cmd" moreinfo="none">hg
  5.6764 +		serve</command> command writes this information to
  5.6765 +	      standard error, not to a file.</para>
  5.6766 +	  </listitem>
  5.6767 +	  <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>:
  5.6768 +	      Boolean.  Whether to use the IPv6 protocol. By default,
  5.6769 +	      IPv6 is not used.</para>
  5.6770 +	  </listitem>
  5.6771 +	  <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>:
  5.6772 +	      Integer.  The TCP port number on which the server should
  5.6773 +	      listen.  The default port number used is 8000.</para>
  5.6774 +	  </listitem></itemizedlist>
  5.6775 +      </sect3>
  5.6776 +
  5.6777 +      <sect3>
  5.6778 +	<title>Choosing the right <filename role="special" moreinfo="none">~/.hgrc</filename> file to add <literal role="rc-web" moreinfo="none">web</literal> items to</title>
  5.6779 +
  5.6780 +	<para id="x_4fc">It is important to remember that a web server like
  5.6781 +	  Apache or <literal moreinfo="none">lighttpd</literal> will run under a user
  5.6782 +	  ID that is different to yours. CGI scripts run by your
  5.6783 +	  server, such as <filename role="special" moreinfo="none">hgweb.cgi</filename>, will usually also run
  5.6784 +	  under that user ID.</para>
  5.6785 +
  5.6786 +	<para id="x_4fd">If you add <literal role="rc-web" moreinfo="none">web</literal> items to
  5.6787 +	  your own personal <filename role="special" moreinfo="none">~/.hgrc</filename> file, CGI scripts won't read that
  5.6788 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file.  Those
  5.6789 +	  settings will thus only affect the behavior of the <command role="hg-cmd" moreinfo="none">hg serve</command> command when you run it.
  5.6790 +	  To cause CGI scripts to see your settings, either create a
  5.6791 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file in the
  5.6792 +	  home directory of the user ID that runs your web server, or
  5.6793 +	  add those settings to a system-wide <filename role="special" moreinfo="none">hgrc</filename> file.</para>
  5.6794 +      </sect3>
  5.6795 +    </sect2>
  5.6796 +  </sect1>
  5.6797 +
  5.6798 +  <sect1>
  5.6799 +    <title>System-wide configuration</title>
  5.6800 +
  5.6801 +    <para id="x_6b0">On Unix-like systems shared by multiple users (such as a
  5.6802 +      server to which people publish changes), it often makes sense to
  5.6803 +      set up some global default behaviors, such as what theme to use
  5.6804 +      in web interfaces.</para>
  5.6805 +
  5.6806 +    <para id="x_6b1">If a file named <filename moreinfo="none">/etc/mercurial/hgrc</filename>
  5.6807 +      exists, Mercurial will read it at startup time and apply any
  5.6808 +      configuration settings it finds in that file.  It will also look
  5.6809 +      for files ending in a <literal moreinfo="none">.rc</literal> extension in a
  5.6810 +      directory named <filename moreinfo="none">/etc/mercurial/hgrc.d</filename>, and
  5.6811 +      apply any configuration settings it finds in each of those
  5.6812 +      files.</para>
  5.6813 +
  5.6814 +    <sect2>
  5.6815 +      <title>Making Mercurial more trusting</title>
  5.6816 +
  5.6817 +      <para id="x_6b2">One situation in which a global <filename moreinfo="none">hgrc</filename>
  5.6818 +	can be useful is if users are pulling changes owned by other
  5.6819 +	users.  By default, Mercurial will not trust most of the
  5.6820 +	configuration items in a <filename moreinfo="none">.hg/hgrc</filename> file
  5.6821 +	inside a repository that is owned by a different user. If we
  5.6822 +	clone or pull changes from such a repository, Mercurial will
  5.6823 +	print a warning stating that it does not trust their
  5.6824 +	<filename moreinfo="none">.hg/hgrc</filename>.</para>
  5.6825 +
  5.6826 +      <para id="x_6b3">If everyone in a particular Unix group is on the same team
  5.6827 +	and <emphasis>should</emphasis> trust each other's
  5.6828 +	configuration settings, or we want to trust particular users,
  5.6829 +	we can override Mercurial's skeptical defaults by creating a
  5.6830 +	system-wide <filename moreinfo="none">hgrc</filename> file such as the
  5.6831 +	following:</para>
  5.6832 +
  5.6833 +    <programlisting format="linespecific"># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc
  5.6834 +[trusted]
  5.6835 +# Trust all entries in any hgrc file owned by the "editors" or
  5.6836 +# "www-data" groups.
  5.6837 +groups = editors, www-data
  5.6838 +
  5.6839 +# Trust entries in hgrc files owned by the following users.
  5.6840 +users = apache, bobo
  5.6841 +</programlisting>
  5.6842 +    </sect2>
  5.6843 +  </sect1>
  5.6844 +</chapter>
  5.6845 +
  5.6846 +<!--
  5.6847 +local variables: 
  5.6848 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.6849 +end:
  5.6850 +-->
  5.6851 +
  5.6852 +  <!-- BEGIN ch07 -->
  5.6853 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.6854 +
  5.6855 +<chapter id="chap:names">
  5.6856 +  <?dbhtml filename="file-names-and-pattern-matching.html"?>
  5.6857 +  <title>File names and pattern matching</title>
  5.6858 +
  5.6859 +  <para id="x_543">Mercurial provides mechanisms that let you work with file
  5.6860 +    names in a consistent and expressive way.</para>
  5.6861 +
  5.6862 +  <sect1>
  5.6863 +    <title>Simple file naming</title>
  5.6864 +
  5.6865 +    <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the
  5.6866 +	hood</quote> to handle file names.  Every command behaves
  5.6867 +      uniformly with respect to file names.  The way in which commands
  5.6868 +      work with file names is as follows.</para>
  5.6869 +
  5.6870 +    <para id="x_545">If you explicitly name real files on the command line,
  5.6871 +      Mercurial works with exactly those files, as you would expect.
  5.6872 +      <!-- BEGIN filenames.files -->
  5.6873 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add COPYING README examples/simple.py</userinput>
  5.6874 +</screen>
  5.6875 +<!-- END filenames.files -->
  5.6876 +</para>
  5.6877 +
  5.6878 +    <para id="x_546">When you provide a directory name, Mercurial will interpret
  5.6879 +      this as <quote>operate on every file in this directory and its
  5.6880 +	subdirectories</quote>. Mercurial traverses the files and
  5.6881 +      subdirectories in a directory in alphabetical order.  When it
  5.6882 +      encounters a subdirectory, it will traverse that subdirectory
  5.6883 +      before continuing with the current directory.</para>
  5.6884 +
  5.6885 +      <!-- BEGIN filenames.dirs -->
  5.6886 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status src</userinput>
  5.6887 +? src/main.py
  5.6888 +? src/watcher/_watcher.c
  5.6889 +? src/watcher/watcher.py
  5.6890 +? src/xyzzy.txt
  5.6891 +</screen>
  5.6892 +<!-- END filenames.dirs -->
  5.6893 +
  5.6894 +  </sect1>
  5.6895 +
  5.6896 +  <sect1>
  5.6897 +    <title>Running commands without any file names</title>
  5.6898 +
  5.6899 +    <para id="x_547">Mercurial's commands that work with file names have useful
  5.6900 +      default behaviors when you invoke them without providing any
  5.6901 +      file names or patterns.  What kind of behavior you should
  5.6902 +      expect depends on what the command does.  Here are a few rules
  5.6903 +      of thumb you can use to predict what a command is likely to do
  5.6904 +      if you don't give it any names to work with.</para>
  5.6905 +    <itemizedlist>
  5.6906 +      <listitem><para id="x_548">Most commands will operate on the entire working
  5.6907 +	  directory. This is what the <command role="hg-cmd" moreinfo="none">hg
  5.6908 +	    add</command> command does, for example.</para>
  5.6909 +      </listitem>
  5.6910 +      <listitem><para id="x_549">If the command has effects that are difficult or
  5.6911 +	  impossible to reverse, it will force you to explicitly
  5.6912 +	  provide at least one name or pattern (see below).  This
  5.6913 +	  protects you from accidentally deleting files by running
  5.6914 +	  <command role="hg-cmd" moreinfo="none">hg remove</command> with no
  5.6915 +	  arguments, for example.</para>
  5.6916 +      </listitem></itemizedlist>
  5.6917 +
  5.6918 +    <para id="x_54a">It's easy to work around these default behaviors if they
  5.6919 +      don't suit you.  If a command normally operates on the whole
  5.6920 +      working directory, you can invoke it on just the current
  5.6921 +      directory and its subdirectories by giving it the name
  5.6922 +      <quote><filename class="directory" moreinfo="none">.</filename></quote>.</para>
  5.6923 +
  5.6924 +    <!-- BEGIN filenames.wdir-subdir -->
  5.6925 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd src</userinput>
  5.6926 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add -n</userinput>
  5.6927 +adding ../MANIFEST.in
  5.6928 +adding ../examples/performant.py
  5.6929 +adding ../setup.py
  5.6930 +adding main.py
  5.6931 +adding watcher/_watcher.c
  5.6932 +adding watcher/watcher.py
  5.6933 +adding xyzzy.txt
  5.6934 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add -n .</userinput>
  5.6935 +adding main.py
  5.6936 +adding watcher/_watcher.c
  5.6937 +adding watcher/watcher.py
  5.6938 +adding xyzzy.txt
  5.6939 +</screen>
  5.6940 +<!-- END filenames.wdir-subdir -->
  5.6941 +
  5.6942 +
  5.6943 +    <para id="x_54b">Along the same lines, some commands normally print file
  5.6944 +      names relative to the root of the repository, even if you're
  5.6945 +      invoking them from a subdirectory.  Such a command will print
  5.6946 +      file names relative to your subdirectory if you give it explicit
  5.6947 +      names.  Here, we're going to run <command role="hg-cmd" moreinfo="none">hg
  5.6948 +	status</command> from a subdirectory, and get it to operate on
  5.6949 +      the entire working directory while printing file names relative
  5.6950 +      to our subdirectory, by passing it the output of the <command role="hg-cmd" moreinfo="none">hg root</command> command.</para>
  5.6951 +
  5.6952 +      <!-- BEGIN filenames.wdir-relname -->
  5.6953 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.6954 +A COPYING
  5.6955 +A README
  5.6956 +A examples/simple.py
  5.6957 +? MANIFEST.in
  5.6958 +? examples/performant.py
  5.6959 +? setup.py
  5.6960 +? src/main.py
  5.6961 +? src/watcher/_watcher.c
  5.6962 +? src/watcher/watcher.py
  5.6963 +? src/xyzzy.txt
  5.6964 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status `hg root`</userinput>
  5.6965 +A ../COPYING
  5.6966 +A ../README
  5.6967 +A ../examples/simple.py
  5.6968 +? ../MANIFEST.in
  5.6969 +? ../examples/performant.py
  5.6970 +? ../setup.py
  5.6971 +? main.py
  5.6972 +? watcher/_watcher.c
  5.6973 +? watcher/watcher.py
  5.6974 +? xyzzy.txt
  5.6975 +</screen>
  5.6976 +<!-- END filenames.wdir-relname -->
  5.6977 +
  5.6978 +  </sect1>
  5.6979 +
  5.6980 +  <sect1>
  5.6981 +    <title>Telling you what's going on</title>
  5.6982 +
  5.6983 +    <para id="x_54c">The <command role="hg-cmd" moreinfo="none">hg add</command> example in the
  5.6984 +      preceding section illustrates something else that's helpful
  5.6985 +      about Mercurial commands.  If a command operates on a file that
  5.6986 +      you didn't name explicitly on the command line, it will usually
  5.6987 +      print the name of the file, so that you will not be surprised
  5.6988 +      what's going on.</para>
  5.6989 +
  5.6990 +    <para id="x_54d">The principle here is of <emphasis>least
  5.6991 +	surprise</emphasis>.  If you've exactly named a file on the
  5.6992 +      command line, there's no point in repeating it back at you.  If
  5.6993 +      Mercurial is acting on a file <emphasis>implicitly</emphasis>, e.g.
  5.6994 +      because you provided no names, or a directory, or a pattern (see
  5.6995 +      below), it is safest to tell you what files it's operating on.</para>
  5.6996 +
  5.6997 +    <para id="x_54e">For commands that behave this way, you can silence them
  5.6998 +      using the <option role="hg-opt-global">-q</option> option.  You
  5.6999 +      can also get them to print the name of every file, even those
  5.7000 +      you've named explicitly, using the <option role="hg-opt-global">-v</option> option.</para>
  5.7001 +  </sect1>
  5.7002 +
  5.7003 +  <sect1>
  5.7004 +    <title>Using patterns to identify files</title>
  5.7005 +
  5.7006 +    <para id="x_54f">In addition to working with file and directory names,
  5.7007 +      Mercurial lets you use <emphasis>patterns</emphasis> to identify
  5.7008 +      files.  Mercurial's pattern handling is expressive.</para>
  5.7009 +
  5.7010 +    <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of
  5.7011 +      matching file names to patterns normally falls to the shell.  On
  5.7012 +      these systems, you must explicitly tell Mercurial that a name is
  5.7013 +      a pattern.  On Windows, the shell does not expand patterns, so
  5.7014 +      Mercurial will automatically identify names that are patterns,
  5.7015 +      and expand them for you.</para>
  5.7016 +
  5.7017 +    <para id="x_551">To provide a pattern in place of a regular name on the
  5.7018 +      command line, the mechanism is simple:</para>
  5.7019 +    <programlisting format="linespecific">syntax:patternbody</programlisting>
  5.7020 +    <para id="x_552">That is, a pattern is identified by a short text string that
  5.7021 +      says what kind of pattern this is, followed by a colon, followed
  5.7022 +      by the actual pattern.</para>
  5.7023 +
  5.7024 +    <para id="x_553">Mercurial supports two kinds of pattern syntax.  The most
  5.7025 +      frequently used is called <literal moreinfo="none">glob</literal>; this is the
  5.7026 +      same kind of pattern matching used by the Unix shell, and should
  5.7027 +      be familiar to Windows command prompt users, too.</para>
  5.7028 +
  5.7029 +    <para id="x_554">When Mercurial does automatic pattern matching on Windows,
  5.7030 +      it uses <literal moreinfo="none">glob</literal> syntax.  You can thus omit the
  5.7031 +      <quote><literal moreinfo="none">glob:</literal></quote> prefix on Windows, but
  5.7032 +      it's safe to use it, too.</para>
  5.7033 +
  5.7034 +    <para id="x_555">The <literal moreinfo="none">re</literal> syntax is more powerful; it lets
  5.7035 +      you specify patterns using regular expressions, also known as
  5.7036 +      regexps.</para>
  5.7037 +
  5.7038 +    <para id="x_556">By the way, in the examples that follow, notice that I'm
  5.7039 +      careful to wrap all of my patterns in quote characters, so that
  5.7040 +      they won't get expanded by the shell before Mercurial sees
  5.7041 +      them.</para>
  5.7042 +
  5.7043 +    <sect2>
  5.7044 +      <title>Shell-style <literal moreinfo="none">glob</literal> patterns</title>
  5.7045 +
  5.7046 +      <para id="x_557">This is an overview of the kinds of patterns you can use
  5.7047 +	when you're matching on glob patterns.</para>
  5.7048 +
  5.7049 +      <para id="x_558">The <quote><literal moreinfo="none">*</literal></quote> character matches
  5.7050 +	any string, within a single directory.</para>
  5.7051 +
  5.7052 +      <!-- BEGIN filenames.glob.star -->
  5.7053 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add 'glob:*.py'</userinput>
  5.7054 +adding main.py
  5.7055 +</screen>
  5.7056 +<!-- END filenames.glob.star -->
  5.7057 +
  5.7058 +
  5.7059 +      <para id="x_559">The <quote><literal moreinfo="none">**</literal></quote> pattern matches
  5.7060 +	any string, and crosses directory boundaries.  It's not a
  5.7061 +	standard Unix glob token, but it's accepted by several popular
  5.7062 +	Unix shells, and is very useful.</para>
  5.7063 +
  5.7064 +      <!-- BEGIN filenames.glob.starstar -->
  5.7065 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.7066 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**.py'</userinput>
  5.7067 +A examples/simple.py
  5.7068 +A src/main.py
  5.7069 +? examples/performant.py
  5.7070 +? setup.py
  5.7071 +? src/watcher/watcher.py
  5.7072 +</screen>
  5.7073 +<!-- END filenames.glob.starstar -->
  5.7074 +
  5.7075 +
  5.7076 +      <para id="x_55a">The <quote><literal moreinfo="none">?</literal></quote> pattern matches
  5.7077 +	any single character.</para>
  5.7078 +
  5.7079 +      <!-- BEGIN filenames.glob.question -->
  5.7080 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**.?'</userinput>
  5.7081 +? src/watcher/_watcher.c
  5.7082 +</screen>
  5.7083 +<!-- END filenames.glob.question -->
  5.7084 +
  5.7085 +
  5.7086 +      <para id="x_55b">The <quote><literal moreinfo="none">[</literal></quote> character begins a
  5.7087 +	<emphasis>character class</emphasis>.  This matches any single
  5.7088 +	character within the class.  The class ends with a
  5.7089 +	<quote><literal moreinfo="none">]</literal></quote> character.  A class may
  5.7090 +	contain multiple <emphasis>range</emphasis>s of the form
  5.7091 +	<quote><literal moreinfo="none">a-f</literal></quote>, which is shorthand for
  5.7092 +	<quote><literal moreinfo="none">abcdef</literal></quote>.</para>
  5.7093 +
  5.7094 +	<!-- BEGIN filenames.glob.range -->
  5.7095 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**[nr-t]'</userinput>
  5.7096 +? MANIFEST.in
  5.7097 +? src/xyzzy.txt
  5.7098 +</screen>
  5.7099 +<!-- END filenames.glob.range -->
  5.7100 +
  5.7101 +
  5.7102 +      <para id="x_55c">If the first character after the
  5.7103 +	<quote><literal moreinfo="none">[</literal></quote> in a character class is a
  5.7104 +	<quote><literal moreinfo="none">!</literal></quote>, it
  5.7105 +	<emphasis>negates</emphasis> the class, making it match any
  5.7106 +	single character not in the class.</para>
  5.7107 +
  5.7108 +      <para id="x_55d">A <quote><literal moreinfo="none">{</literal></quote> begins a group of
  5.7109 +	subpatterns, where the whole group matches if any subpattern
  5.7110 +	in the group matches.  The <quote><literal moreinfo="none">,</literal></quote>
  5.7111 +	character separates subpatterns, and
  5.7112 +	<quote><literal moreinfo="none">}</literal></quote> ends the group.</para>
  5.7113 +
  5.7114 +      <!-- BEGIN filenames.glob.group -->
  5.7115 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:*.{in,py}'</userinput>
  5.7116 +? MANIFEST.in
  5.7117 +? setup.py
  5.7118 +</screen>
  5.7119 +<!-- END filenames.glob.group -->
  5.7120 +
  5.7121 +
  5.7122 +      <sect3>
  5.7123 +	<title>Watch out!</title>
  5.7124 +
  5.7125 +	<para id="x_55e">Don't forget that if you want to match a pattern in any
  5.7126 +	  directory, you should not be using the
  5.7127 +	  <quote><literal moreinfo="none">*</literal></quote> match-any token, as this
  5.7128 +	  will only match within one directory.  Instead, use the
  5.7129 +	  <quote><literal moreinfo="none">**</literal></quote> token.  This small
  5.7130 +	  example illustrates the difference between the two.</para>
  5.7131 +
  5.7132 +	  <!-- BEGIN filenames.glob.star-starstar -->
  5.7133 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:*.py'</userinput>
  5.7134 +? setup.py
  5.7135 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**.py'</userinput>
  5.7136 +A examples/simple.py
  5.7137 +A src/main.py
  5.7138 +? examples/performant.py
  5.7139 +? setup.py
  5.7140 +? src/watcher/watcher.py
  5.7141 +</screen>
  5.7142 +<!-- END filenames.glob.star-starstar -->
  5.7143 +
  5.7144 +      </sect3>
  5.7145 +    </sect2>
  5.7146 +
  5.7147 +    <sect2>
  5.7148 +      <title>Regular expression matching with <literal moreinfo="none">re</literal>
  5.7149 +	patterns</title>
  5.7150 +
  5.7151 +      <para id="x_55f">Mercurial accepts the same regular expression syntax as
  5.7152 +	the Python programming language (it uses Python's regexp
  5.7153 +	engine internally). This is based on the Perl language's
  5.7154 +	regexp syntax, which is the most popular dialect in use (it's
  5.7155 +	also used in Java, for example).</para>
  5.7156 +
  5.7157 +      <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail
  5.7158 +	here, as regexps are not often used.  Perl-style regexps are
  5.7159 +	in any case already exhaustively documented on a multitude of
  5.7160 +	web sites, and in many books.  Instead, I will focus here on a
  5.7161 +	few things you should know if you find yourself needing to use
  5.7162 +	regexps with Mercurial.</para>
  5.7163 +
  5.7164 +      <para id="x_561">A regexp is matched against an entire file name, relative
  5.7165 +	to the root of the repository.  In other words, even if you're
  5.7166 +	already in subbdirectory <filename class="directory" moreinfo="none">foo</filename>, if you want to match files
  5.7167 +	under this directory, your pattern must start with
  5.7168 +	<quote><literal moreinfo="none">foo/</literal></quote>.</para>
  5.7169 +
  5.7170 +      <para id="x_562">One thing to note, if you're familiar with Perl-style
  5.7171 +	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
  5.7172 +	That is, a regexp starts matching against the beginning of a
  5.7173 +	string; it doesn't look for a match anywhere within the
  5.7174 +	string.  To match anywhere in a string, start your pattern
  5.7175 +	with <quote><literal moreinfo="none">.*</literal></quote>.</para>
  5.7176 +    </sect2>
  5.7177 +  </sect1>
  5.7178 +
  5.7179 +  <sect1>
  5.7180 +    <title>Filtering files</title>
  5.7181 +
  5.7182 +    <para id="x_563">Not only does Mercurial give you a variety of ways to
  5.7183 +      specify files; it lets you further winnow those files using
  5.7184 +      <emphasis>filters</emphasis>.  Commands that work with file
  5.7185 +      names accept two filtering options.</para>
  5.7186 +    <itemizedlist>
  5.7187 +      <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or
  5.7188 +	  <option role="hg-opt-global">--include</option>, lets you
  5.7189 +	  specify a pattern that file names must match in order to be
  5.7190 +	  processed.</para>
  5.7191 +      </listitem>
  5.7192 +      <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or
  5.7193 +	  <option role="hg-opt-global">--exclude</option>, gives you a
  5.7194 +	  way to <emphasis>avoid</emphasis> processing files, if they
  5.7195 +	  match this pattern.</para>
  5.7196 +      </listitem></itemizedlist>
  5.7197 +    <para id="x_566">You can provide multiple <option role="hg-opt-global">-I</option> and <option role="hg-opt-global">-X</option> options on the command line,
  5.7198 +      and intermix them as you please.  Mercurial interprets the
  5.7199 +      patterns you provide using glob syntax by default (but you can
  5.7200 +      use regexps if you need to).</para>
  5.7201 +
  5.7202 +    <para id="x_567">You can read a <option role="hg-opt-global">-I</option>
  5.7203 +      filter as <quote>process only the files that match this
  5.7204 +	filter</quote>.</para>
  5.7205 +
  5.7206 +    <!-- BEGIN filenames.filter.include -->
  5.7207 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -I '*.in'</userinput>
  5.7208 +? MANIFEST.in
  5.7209 +</screen>
  5.7210 +<!-- END filenames.filter.include -->
  5.7211 +
  5.7212 +
  5.7213 +    <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best
  5.7214 +      read as <quote>process only the files that don't match this
  5.7215 +	pattern</quote>.</para>
  5.7216 +
  5.7217 +    <!-- BEGIN filenames.filter.exclude -->
  5.7218 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -X '**.py' src</userinput>
  5.7219 +? src/watcher/_watcher.c
  5.7220 +? src/xyzzy.txt
  5.7221 +</screen>
  5.7222 +<!-- END filenames.filter.exclude -->
  5.7223 +
  5.7224 +  </sect1>
  5.7225 +
  5.7226 +  <sect1>
  5.7227 +    <title>Permanently ignoring unwanted files and directories</title>
  5.7228 +
  5.7229 +    <para id="x_569">When you create a new repository, the chances are
  5.7230 +      that over time it will grow to contain files that ought to
  5.7231 +      <emphasis>not</emphasis> be managed by Mercurial, but which you
  5.7232 +      don't want to see listed every time you run <command moreinfo="none">hg
  5.7233 +	status</command>.  For instance, <quote>build products</quote>
  5.7234 +      are files that are created as part of a build but which should
  5.7235 +      not be managed by a revision control system.  The most common
  5.7236 +      build products are output files produced by software tools such
  5.7237 +      as compilers.  As another example, many text editors litter a
  5.7238 +      directory with lock files, temporary working files, and backup
  5.7239 +      files, which it also makes no sense to manage.</para>
  5.7240 +
  5.7241 +    <para id="x_6b4">To have Mercurial permanently ignore such files, create a
  5.7242 +      file named <filename moreinfo="none">.hgignore</filename> in the root of your
  5.7243 +      repository.  You <emphasis>should</emphasis> <command moreinfo="none">hg
  5.7244 +      add</command> this file so that it gets tracked with the rest of
  5.7245 +      your repository contents, since your collaborators will probably
  5.7246 +      find it useful too.</para>
  5.7247 +
  5.7248 +    <para id="x_6b5">By default, the <filename moreinfo="none">.hgignore</filename> file should
  5.7249 +      contain a list of regular expressions, one per line.  Empty
  5.7250 +      lines are skipped. Most people prefer to describe the files they
  5.7251 +      want to ignore using the <quote>glob</quote> syntax that we
  5.7252 +      described above, so a typical <filename moreinfo="none">.hgignore</filename>
  5.7253 +      file will start with this directive:</para>
  5.7254 +
  5.7255 +    <programlisting format="linespecific">syntax: glob</programlisting>
  5.7256 +
  5.7257 +    <para id="x_6b6">This tells Mercurial to interpret the lines that follow as
  5.7258 +      glob patterns, not regular expressions.</para>
  5.7259 +
  5.7260 +    <para id="x_6b7">Here is a typical-looking <filename moreinfo="none">.hgignore</filename>
  5.7261 +      file.</para>
  5.7262 +
  5.7263 +    <programlisting format="linespecific">syntax: glob
  5.7264 +# This line is a comment, and will be skipped.
  5.7265 +# Empty lines are skipped too.
  5.7266 +
  5.7267 +# Backup files left behind by the Emacs editor.
  5.7268 +*~
  5.7269 +
  5.7270 +# Lock files used by the Emacs editor.
  5.7271 +# Notice that the "#" character is quoted with a backslash.
  5.7272 +# This prevents it from being interpreted as starting a comment.
  5.7273 +.\#*
  5.7274 +
  5.7275 +# Temporary files used by the vim editor.
  5.7276 +.*.swp
  5.7277 +
  5.7278 +# A hidden file created by the Mac OS X Finder.
  5.7279 +.DS_Store
  5.7280 +</programlisting>
  5.7281 +  </sect1>
  5.7282 +
  5.7283 +  <sect1 id="sec:names:case">
  5.7284 +    <title>Case sensitivity</title>
  5.7285 +
  5.7286 +    <para id="x_56a">If you're working in a mixed development environment that
  5.7287 +      contains both Linux (or other Unix) systems and Macs or Windows
  5.7288 +      systems, you should keep in the back of your mind the knowledge
  5.7289 +      that they treat the case (<quote>N</quote> versus
  5.7290 +      <quote>n</quote>) of file names in incompatible ways.  This is
  5.7291 +      not very likely to affect you, and it's easy to deal with if it
  5.7292 +      does, but it could surprise you if you don't know about
  5.7293 +      it.</para>
  5.7294 +
  5.7295 +    <para id="x_56b">Operating systems and filesystems differ in the way they
  5.7296 +      handle the <emphasis>case</emphasis> of characters in file and
  5.7297 +      directory names.  There are three common ways to handle case in
  5.7298 +      names.</para>
  5.7299 +    <itemizedlist>
  5.7300 +      <listitem><para id="x_56c">Completely case insensitive.  Uppercase and
  5.7301 +	  lowercase versions of a letter are treated as identical,
  5.7302 +	  both when creating a file and during subsequent accesses.
  5.7303 +	  This is common on older DOS-based systems.</para>
  5.7304 +      </listitem>
  5.7305 +      <listitem><para id="x_56d">Case preserving, but insensitive.  When a file
  5.7306 +	  or directory is created, the case of its name is stored, and
  5.7307 +	  can be retrieved and displayed by the operating system.
  5.7308 +	  When an existing file is being looked up, its case is
  5.7309 +	  ignored.  This is the standard arrangement on Windows and
  5.7310 +	  MacOS.  The names <filename moreinfo="none">foo</filename> and
  5.7311 +	  <filename moreinfo="none">FoO</filename> identify the same file.  This
  5.7312 +	  treatment of uppercase and lowercase letters as
  5.7313 +	  interchangeable is also referred to as <emphasis>case
  5.7314 +	    folding</emphasis>.</para>
  5.7315 +      </listitem>
  5.7316 +      <listitem><para id="x_56e">Case sensitive.  The case of a name
  5.7317 +	  is significant at all times. The names
  5.7318 +	  <filename moreinfo="none">foo</filename> and <filename moreinfo="none">FoO</filename>
  5.7319 +	  identify different files.  This is the way Linux and Unix
  5.7320 +	  systems normally work.</para>
  5.7321 +      </listitem></itemizedlist>
  5.7322 +
  5.7323 +    <para id="x_56f">On Unix-like systems, it is possible to have any or all of
  5.7324 +      the above ways of handling case in action at once.  For example,
  5.7325 +      if you use a USB thumb drive formatted with a FAT32 filesystem
  5.7326 +      on a Linux system, Linux will handle names on that filesystem in
  5.7327 +      a case preserving, but insensitive, way.</para>
  5.7328 +
  5.7329 +    <sect2>
  5.7330 +      <title>Safe, portable repository storage</title>
  5.7331 +
  5.7332 +      <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case
  5.7333 +	  safe</emphasis>.  It translates file names so that they can
  5.7334 +	be safely stored on both case sensitive and case insensitive
  5.7335 +	filesystems.  This means that you can use normal file copying
  5.7336 +	tools to transfer a Mercurial repository onto, for example, a
  5.7337 +	USB thumb drive, and safely move that drive and repository
  5.7338 +	back and forth between a Mac, a PC running Windows, and a
  5.7339 +	Linux box.</para>
  5.7340 +
  5.7341 +    </sect2>
  5.7342 +    <sect2>
  5.7343 +      <title>Detecting case conflicts</title>
  5.7344 +
  5.7345 +      <para id="x_571">When operating in the working directory, Mercurial honours
  5.7346 +	the naming policy of the filesystem where the working
  5.7347 +	directory is located.  If the filesystem is case preserving,
  5.7348 +	but insensitive, Mercurial will treat names that differ only
  5.7349 +	in case as the same.</para>
  5.7350 +
  5.7351 +      <para id="x_572">An important aspect of this approach is that it is
  5.7352 +	possible to commit a changeset on a case sensitive (typically
  5.7353 +	Linux or Unix) filesystem that will cause trouble for users on
  5.7354 +	case insensitive (usually Windows and MacOS) users.  If a
  5.7355 +	Linux user commits changes to two files, one named
  5.7356 +	<filename moreinfo="none">myfile.c</filename> and the other named
  5.7357 +	<filename moreinfo="none">MyFile.C</filename>, they will be stored correctly
  5.7358 +	in the repository.  And in the working directories of other
  5.7359 +	Linux users, they will be correctly represented as separate
  5.7360 +	files.</para>
  5.7361 +
  5.7362 +      <para id="x_573">If a Windows or Mac user pulls this change, they will not
  5.7363 +	initially have a problem, because Mercurial's repository
  5.7364 +	storage mechanism is case safe.  However, once they try to
  5.7365 +	<command role="hg-cmd" moreinfo="none">hg update</command> the working
  5.7366 +	directory to that changeset, or <command role="hg-cmd" moreinfo="none">hg
  5.7367 +	  merge</command> with that changeset, Mercurial will spot the
  5.7368 +	conflict between the two file names that the filesystem would
  5.7369 +	treat as the same, and forbid the update or merge from
  5.7370 +	occurring.</para>
  5.7371 +    </sect2>
  5.7372 +
  5.7373 +    <sect2>
  5.7374 +      <title>Fixing a case conflict</title>
  5.7375 +
  5.7376 +      <para id="x_574">If you are using Windows or a Mac in a mixed environment
  5.7377 +	where some of your collaborators are using Linux or Unix, and
  5.7378 +	Mercurial reports a case folding conflict when you try to
  5.7379 +	<command role="hg-cmd" moreinfo="none">hg update</command> or <command role="hg-cmd" moreinfo="none">hg merge</command>, the procedure to fix the
  5.7380 +	problem is simple.</para>
  5.7381 +
  5.7382 +      <para id="x_575">Just find a nearby Linux or Unix box, clone the problem
  5.7383 +	repository onto it, and use Mercurial's <command role="hg-cmd" moreinfo="none">hg rename</command> command to change the
  5.7384 +	names of any offending files or directories so that they will
  5.7385 +	no longer cause case folding conflicts.  Commit this change,
  5.7386 +	<command role="hg-cmd" moreinfo="none">hg pull</command> or <command role="hg-cmd" moreinfo="none">hg push</command> it across to your Windows or
  5.7387 +	MacOS system, and <command role="hg-cmd" moreinfo="none">hg update</command>
  5.7388 +	to the revision with the non-conflicting names.</para>
  5.7389 +
  5.7390 +      <para id="x_576">The changeset with case-conflicting names will remain in
  5.7391 +	your project's history, and you still won't be able to
  5.7392 +	<command role="hg-cmd" moreinfo="none">hg update</command> your working
  5.7393 +	directory to that changeset on a Windows or MacOS system, but
  5.7394 +	you can continue development unimpeded.</para>
  5.7395 +    </sect2>
  5.7396 +  </sect1>
  5.7397 +</chapter>
  5.7398 +
  5.7399 +<!--
  5.7400 +local variables: 
  5.7401 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.7402 +end:
  5.7403 +-->
  5.7404 +
  5.7405 +  <!-- BEGIN ch08 -->
  5.7406 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.7407 +
  5.7408 +<chapter id="chap:branch">
  5.7409 +  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
  5.7410 +  <title>Managing releases and branchy development</title>
  5.7411 +
  5.7412 +  <para id="x_369">Mercurial provides several mechanisms for you to manage a
  5.7413 +    project that is making progress on multiple fronts at once.  To
  5.7414 +    understand these mechanisms, let's first take a brief look at a
  5.7415 +    fairly normal software project structure.</para>
  5.7416 +
  5.7417 +  <para id="x_36a">Many software projects issue periodic <quote>major</quote>
  5.7418 +    releases that contain substantial new features.  In parallel, they
  5.7419 +    may issue <quote>minor</quote> releases.  These are usually
  5.7420 +    identical to the major releases off which they're based, but with
  5.7421 +    a few bugs fixed.</para>
  5.7422 +
  5.7423 +  <para id="x_36b">In this chapter, we'll start by talking about how to keep
  5.7424 +    records of project milestones such as releases.  We'll then
  5.7425 +    continue on to talk about the flow of work between different
  5.7426 +    phases of a project, and how Mercurial can help you to isolate and
  5.7427 +    manage this work.</para>
  5.7428 +
  5.7429 +  <sect1>
  5.7430 +    <title>Giving a persistent name to a revision</title>
  5.7431 +
  5.7432 +    <para id="x_36c">Once you decide that you'd like to call a particular
  5.7433 +      revision a <quote>release</quote>, it's a good idea to record
  5.7434 +      the identity of that revision. This will let you reproduce that
  5.7435 +      release at a later date, for whatever purpose you might need at
  5.7436 +      the time (reproducing a bug, porting to a new platform, etc).
  5.7437 +      <!-- BEGIN tag.init -->
  5.7438 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init mytag</userinput>
  5.7439 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd mytag</userinput>
  5.7440 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo hello &gt; myfile</userinput>
  5.7441 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Initial commit'</userinput>
  5.7442 +adding myfile
  5.7443 +</screen>
  5.7444 +<!-- END tag.init -->
  5.7445 +</para>
  5.7446 +
  5.7447 +    <para id="x_36d">Mercurial lets you give a permanent name to any revision
  5.7448 +      using the <command role="hg-cmd" moreinfo="none">hg tag</command> command.  Not
  5.7449 +      surprisingly, these names are called <quote>tags</quote>.</para>
  5.7450 +
  5.7451 +    <!-- BEGIN tag.tag -->
  5.7452 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag v1.0</userinput>
  5.7453 +</screen>
  5.7454 +<!-- END tag.tag -->
  5.7455 +
  5.7456 +
  5.7457 +    <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote>
  5.7458 +      for a revision.  Tags exist purely for your convenience, so that
  5.7459 +      you have a handy permanent way to refer to a revision; Mercurial
  5.7460 +      doesn't interpret the tag names you use in any way.  Neither
  5.7461 +      does Mercurial place any restrictions on the name of a tag,
  5.7462 +      beyond a few that are necessary to ensure that a tag can be
  5.7463 +      parsed unambiguously.  A tag name cannot contain any of the
  5.7464 +      following characters:</para>
  5.7465 +    <itemizedlist>
  5.7466 +      <listitem><para id="x_36f">Colon (ASCII 58,
  5.7467 +	  <quote><literal moreinfo="none">:</literal></quote>)</para>
  5.7468 +      </listitem>
  5.7469 +      <listitem><para id="x_370">Carriage return (ASCII 13,
  5.7470 +	  <quote><literal moreinfo="none">\r</literal></quote>)</para>
  5.7471 +      </listitem>
  5.7472 +      <listitem><para id="x_371">Newline (ASCII 10,
  5.7473 +	  <quote><literal moreinfo="none">\n</literal></quote>)</para>
  5.7474 +      </listitem></itemizedlist>
  5.7475 +
  5.7476 +    <para id="x_372">You can use the <command role="hg-cmd" moreinfo="none">hg tags</command>
  5.7477 +      command to display the tags present in your repository.  In the
  5.7478 +      output, each tagged revision is identified first by its name,
  5.7479 +      then by revision number, and finally by the unique hash of the
  5.7480 +      revision.</para>
  5.7481 +
  5.7482 +    <!-- BEGIN tag.tags -->
  5.7483 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  5.7484 +tip                                1:f283c2669b38
  5.7485 +v1.0                               0:0c957785065f
  5.7486 +</screen>
  5.7487 +<!-- END tag.tags -->
  5.7488 +
  5.7489 +
  5.7490 +    <para id="x_373">Notice that <literal moreinfo="none">tip</literal> is listed in the output
  5.7491 +      of <command role="hg-cmd" moreinfo="none">hg tags</command>.  The
  5.7492 +      <literal moreinfo="none">tip</literal> tag is a special <quote>floating</quote>
  5.7493 +      tag, which always identifies the newest revision in the
  5.7494 +      repository.</para>
  5.7495 +
  5.7496 +    <para id="x_374">In the output of the <command role="hg-cmd" moreinfo="none">hg
  5.7497 +	tags</command> command, tags are listed in reverse order, by
  5.7498 +      revision number.  This usually means that recent tags are listed
  5.7499 +      before older tags.  It also means that <literal moreinfo="none">tip</literal> is
  5.7500 +      always going to be the first tag listed in the output of
  5.7501 +      <command role="hg-cmd" moreinfo="none">hg tags</command>.</para>
  5.7502 +
  5.7503 +    <para id="x_375">When you run <command role="hg-cmd" moreinfo="none">hg log</command>, if it
  5.7504 +      displays a revision that has tags associated with it, it will
  5.7505 +      print those tags.</para>
  5.7506 +
  5.7507 +    <!-- BEGIN tag.log -->
  5.7508 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log</userinput>
  5.7509 +changeset:   1:f283c2669b38
  5.7510 +tag:         tip
  5.7511 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7512 +date:        Sun Aug 16 14:05:16 2009 +0000
  5.7513 +summary:     Added tag v1.0 for changeset 0c957785065f
  5.7514 +
  5.7515 +changeset:   0:0c957785065f
  5.7516 +tag:         v1.0
  5.7517 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7518 +date:        Sun Aug 16 14:05:15 2009 +0000
  5.7519 +summary:     Initial commit
  5.7520 +
  5.7521 +</screen>
  5.7522 +<!-- END tag.log -->
  5.7523 +
  5.7524 +
  5.7525 +    <para id="x_376">Any time you need to provide a revision ID to a Mercurial
  5.7526 +      command, the command will accept a tag name in its place.
  5.7527 +      Internally, Mercurial will translate your tag name into the
  5.7528 +      corresponding revision ID, then use that.</para>
  5.7529 +
  5.7530 +    <!-- BEGIN tag.log.v1.0 -->
  5.7531 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo goodbye &gt; myfile2</userinput>
  5.7532 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Second commit'</userinput>
  5.7533 +adding myfile2
  5.7534 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r v1.0</userinput>
  5.7535 +changeset:   0:0c957785065f
  5.7536 +tag:         v1.0
  5.7537 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7538 +date:        Sun Aug 16 14:05:15 2009 +0000
  5.7539 +summary:     Initial commit
  5.7540 +
  5.7541 +</screen>
  5.7542 +<!-- END tag.log.v1.0 -->
  5.7543 +
  5.7544 +
  5.7545 +    <para id="x_377">There's no limit on the number of tags you can have in a
  5.7546 +      repository, or on the number of tags that a single revision can
  5.7547 +      have.  As a practical matter, it's not a great idea to have
  5.7548 +      <quote>too many</quote> (a number which will vary from project
  5.7549 +      to project), simply because tags are supposed to help you to
  5.7550 +      find revisions.  If you have lots of tags, the ease of using
  5.7551 +      them to identify revisions diminishes rapidly.</para>
  5.7552 +
  5.7553 +    <para id="x_378">For example, if your project has milestones as frequent as
  5.7554 +      every few days, it's perfectly reasonable to tag each one of
  5.7555 +      those.  But if you have a continuous build system that makes
  5.7556 +      sure every revision can be built cleanly, you'd be introducing a
  5.7557 +      lot of noise if you were to tag every clean build.  Instead, you
  5.7558 +      could tag failed builds (on the assumption that they're rare!),
  5.7559 +      or simply not use tags to track buildability.</para>
  5.7560 +
  5.7561 +    <para id="x_379">If you want to remove a tag that you no longer want, use
  5.7562 +      <command role="hg-cmd" moreinfo="none">hg tag --remove</command>.</para>
  5.7563 +
  5.7564 +    <!-- BEGIN tag.remove -->
  5.7565 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag --remove v1.0</userinput>
  5.7566 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  5.7567 +tip                                3:0f446f1d1f7f
  5.7568 +</screen>
  5.7569 +<!-- END tag.remove -->
  5.7570 +
  5.7571 +
  5.7572 +    <para id="x_37a">You can also modify a tag at any time, so that it identifies
  5.7573 +      a different revision, by simply issuing a new <command role="hg-cmd" moreinfo="none">hg tag</command> command. You'll have to use the
  5.7574 +      <option role="hg-opt-tag">-f</option> option to tell Mercurial
  5.7575 +      that you <emphasis>really</emphasis> want to update the
  5.7576 +      tag.</para>
  5.7577 +
  5.7578 +    <!-- BEGIN tag.replace -->
  5.7579 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag -r 1 v1.1</userinput>
  5.7580 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  5.7581 +tip                                4:12fc7bf92915
  5.7582 +v1.1                               1:f283c2669b38
  5.7583 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag -r 2 v1.1</userinput>
  5.7584 +abort: tag 'v1.1' already exists (use -f to force)
  5.7585 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag -f -r 2 v1.1</userinput>
  5.7586 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  5.7587 +tip                                5:17e25cf010af
  5.7588 +v1.1                               2:737882b3cc76
  5.7589 +</screen>
  5.7590 +<!-- END tag.replace -->
  5.7591 +
  5.7592 +
  5.7593 +    <para id="x_37b">There will still be a permanent record of the previous
  5.7594 +      identity of the tag, but Mercurial will no longer use it.
  5.7595 +      There's thus no penalty to tagging the wrong revision; all you
  5.7596 +      have to do is turn around and tag the correct revision once you
  5.7597 +      discover your error.</para>
  5.7598 +
  5.7599 +    <para id="x_37c">Mercurial stores tags in a normal revision-controlled file
  5.7600 +      in your repository.  If you've created any tags, you'll find
  5.7601 +      them in a file in the root of your repository named <filename role="special" moreinfo="none">.hgtags</filename>.  When you run the <command role="hg-cmd" moreinfo="none">hg tag</command> command, Mercurial modifies
  5.7602 +      this file, then automatically commits the change to it.  This
  5.7603 +      means that every time you run <command role="hg-cmd" moreinfo="none">hg
  5.7604 +	tag</command>, you'll see a corresponding changeset in the
  5.7605 +      output of <command role="hg-cmd" moreinfo="none">hg log</command>.</para>
  5.7606 +
  5.7607 +    <!-- BEGIN tag.tip -->
  5.7608 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.7609 +changeset:   5:17e25cf010af
  5.7610 +tag:         tip
  5.7611 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7612 +date:        Sun Aug 16 14:05:16 2009 +0000
  5.7613 +summary:     Added tag v1.1 for changeset 737882b3cc76
  5.7614 +
  5.7615 +</screen>
  5.7616 +<!-- END tag.tip -->
  5.7617 +
  5.7618 +
  5.7619 +    <sect2>
  5.7620 +      <title>Handling tag conflicts during a merge</title>
  5.7621 +
  5.7622 +      <para id="x_37d">You won't often need to care about the <filename role="special" moreinfo="none">.hgtags</filename> file, but it sometimes
  5.7623 +	makes its presence known during a merge.  The format of the
  5.7624 +	file is simple: it consists of a series of lines.  Each line
  5.7625 +	starts with a changeset hash, followed by a space, followed by
  5.7626 +	the name of a tag.</para>
  5.7627 +
  5.7628 +      <para id="x_37e">If you're resolving a conflict in the <filename role="special" moreinfo="none">.hgtags</filename> file during a merge,
  5.7629 +	there's one twist to modifying the <filename role="special" moreinfo="none">.hgtags</filename> file: when Mercurial is
  5.7630 +	parsing the tags in a repository, it
  5.7631 +	<emphasis>never</emphasis> reads the working copy of the
  5.7632 +	<filename role="special" moreinfo="none">.hgtags</filename> file.  Instead, it
  5.7633 +	reads the <emphasis>most recently committed</emphasis>
  5.7634 +	revision of the file.</para>
  5.7635 +
  5.7636 +      <para id="x_37f">An unfortunate consequence of this design is that you
  5.7637 +	can't actually verify that your merged <filename role="special" moreinfo="none">.hgtags</filename> file is correct until
  5.7638 +	<emphasis>after</emphasis> you've committed a change.  So if
  5.7639 +	you find yourself resolving a conflict on <filename role="special" moreinfo="none">.hgtags</filename> during a merge, be sure to
  5.7640 +	run <command role="hg-cmd" moreinfo="none">hg tags</command> after you commit.
  5.7641 +	If it finds an error in the <filename role="special" moreinfo="none">.hgtags</filename> file, it will report the
  5.7642 +	location of the error, which you can then fix and commit.  You
  5.7643 +	should then run <command role="hg-cmd" moreinfo="none">hg tags</command>
  5.7644 +	again, just to be sure that your fix is correct.</para>
  5.7645 +    </sect2>
  5.7646 +
  5.7647 +    <sect2>
  5.7648 +      <title>Tags and cloning</title>
  5.7649 +
  5.7650 +      <para id="x_380">You may have noticed that the <command role="hg-cmd" moreinfo="none">hg
  5.7651 +	  clone</command> command has a <option role="hg-opt-clone">-r</option> option that lets you clone
  5.7652 +	an exact copy of the repository as of a particular changeset.
  5.7653 +	The new clone will not contain any project history that comes
  5.7654 +	after the revision you specified.  This has an interaction
  5.7655 +	with tags that can surprise the unwary.</para>
  5.7656 +
  5.7657 +      <para id="x_381">Recall that a tag is stored as a revision to
  5.7658 +	the <filename role="special" moreinfo="none">.hgtags</filename> file. When you
  5.7659 +	create a tag, the changeset in which its recorded refers to an
  5.7660 +	older changeset.  When you run <command role="hg-cmd" moreinfo="none">hg clone
  5.7661 +	  -r foo</command> to clone a repository as of tag
  5.7662 +	<literal moreinfo="none">foo</literal>, the new clone <emphasis>will not
  5.7663 +	  contain any revision newer than the one the tag refers to,
  5.7664 +	  including the revision where the tag was created</emphasis>.
  5.7665 +	The result is that you'll get exactly the right subset of the
  5.7666 +	project's history in the new repository, but
  5.7667 +	<emphasis>not</emphasis> the tag you might have
  5.7668 +	expected.</para>
  5.7669 +    </sect2>
  5.7670 +
  5.7671 +    <sect2>
  5.7672 +      <title>When permanent tags are too much</title>
  5.7673 +
  5.7674 +      <para id="x_382">Since Mercurial's tags are revision controlled and carried
  5.7675 +	around with a project's history, everyone you work with will
  5.7676 +	see the tags you create.  But giving names to revisions has
  5.7677 +	uses beyond simply noting that revision
  5.7678 +	<literal moreinfo="none">4237e45506ee</literal> is really
  5.7679 +	<literal moreinfo="none">v2.0.2</literal>.  If you're trying to track down a
  5.7680 +	subtle bug, you might want a tag to remind you of something
  5.7681 +	like <quote>Anne saw the symptoms with this
  5.7682 +	  revision</quote>.</para>
  5.7683 +
  5.7684 +      <para id="x_383">For cases like this, what you might want to use are
  5.7685 +	<emphasis>local</emphasis> tags. You can create a local tag
  5.7686 +	with the <option role="hg-opt-tag">-l</option> option to the
  5.7687 +	<command role="hg-cmd" moreinfo="none">hg tag</command> command.  This will
  5.7688 +	store the tag in a file called <filename role="special" moreinfo="none">.hg/localtags</filename>.  Unlike <filename role="special" moreinfo="none">.hgtags</filename>, <filename role="special" moreinfo="none">.hg/localtags</filename> is not revision
  5.7689 +	controlled.  Any tags you create using <option role="hg-opt-tag">-l</option> remain strictly local to the
  5.7690 +	repository you're currently working in.</para>
  5.7691 +    </sect2>
  5.7692 +  </sect1>
  5.7693 +
  5.7694 +  <sect1>
  5.7695 +    <title>The flow of changes—big picture vs. little</title>
  5.7696 +
  5.7697 +    <para id="x_384">To return to the outline I sketched at the
  5.7698 +      beginning of the chapter, let's think about a project that has
  5.7699 +      multiple concurrent pieces of work under development at
  5.7700 +      once.</para>
  5.7701 +
  5.7702 +    <para id="x_385">There might be a push for a new <quote>main</quote> release;
  5.7703 +      a new minor bugfix release to the last main release; and an
  5.7704 +      unexpected <quote>hot fix</quote> to an old release that is now
  5.7705 +      in maintenance mode.</para>
  5.7706 +
  5.7707 +    <para id="x_386">The usual way people refer to these different concurrent
  5.7708 +      directions of development is as <quote>branches</quote>.
  5.7709 +      However, we've already seen numerous times that Mercurial treats
  5.7710 +      <emphasis>all of history</emphasis> as a series of branches and
  5.7711 +      merges.  Really, what we have here is two ideas that are
  5.7712 +      peripherally related, but which happen to share a name.</para>
  5.7713 +    <itemizedlist>
  5.7714 +      <listitem><para id="x_387"><quote>Big picture</quote> branches represent
  5.7715 +	  the sweep of a project's evolution; people give them names,
  5.7716 +	  and talk about them in conversation.</para>
  5.7717 +      </listitem>
  5.7718 +      <listitem><para id="x_388"><quote>Little picture</quote> branches are
  5.7719 +	  artefacts of the day-to-day activity of developing and
  5.7720 +	  merging changes.  They expose the narrative of how the code
  5.7721 +	  was developed.</para>
  5.7722 +      </listitem></itemizedlist>
  5.7723 +  </sect1>
  5.7724 +
  5.7725 +  <sect1>
  5.7726 +    <title>Managing big-picture branches in repositories</title>
  5.7727 +
  5.7728 +    <para id="x_389">The easiest way to isolate a <quote>big picture</quote>
  5.7729 +      branch in Mercurial is in a dedicated repository.  If you have
  5.7730 +      an existing shared repository—let's call it
  5.7731 +      <literal moreinfo="none">myproject</literal>—that reaches a
  5.7732 +      <quote>1.0</quote> milestone, you can start to prepare for
  5.7733 +      future maintenance releases on top of version 1.0 by tagging the
  5.7734 +      revision from which you prepared the 1.0 release.</para>
  5.7735 +
  5.7736 +    <!-- BEGIN branch-repo.tag -->
  5.7737 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myproject</userinput>
  5.7738 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag v1.0</userinput>
  5.7739 +</screen>
  5.7740 +<!-- END branch-repo.tag -->
  5.7741 +
  5.7742 +
  5.7743 +    <para id="x_38a">You can then clone a new shared
  5.7744 +      <literal moreinfo="none">myproject-1.0.1</literal> repository as of that
  5.7745 +      tag.</para>
  5.7746 +
  5.7747 +    <!-- BEGIN branch-repo.clone -->
  5.7748 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.7749 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject myproject-1.0.1</userinput>
  5.7750 +updating working directory
  5.7751 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.7752 +</screen>
  5.7753 +<!-- END branch-repo.clone -->
  5.7754 +
  5.7755 +
  5.7756 +    <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought
  5.7757 +      to go into an upcoming 1.0.1 minor release, they clone the
  5.7758 +      <literal moreinfo="none">myproject-1.0.1</literal> repository, make their
  5.7759 +      changes, and push them back.</para>
  5.7760 +
  5.7761 +    <!-- BEGIN branch-repo.bugfix -->
  5.7762 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject-1.0.1 my-1.0.1-bugfix</userinput>
  5.7763 +updating working directory
  5.7764 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.7765 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-1.0.1-bugfix</userinput>
  5.7766 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'I fixed a bug using only echo!' &gt;&gt; myfile</userinput>
  5.7767 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Important fix for 1.0.1'</userinput>
  5.7768 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  5.7769 +pushing to /tmp/branch-repo3rVLLS/myproject-1.0.1
  5.7770 +searching for changes
  5.7771 +adding changesets
  5.7772 +adding manifests
  5.7773 +adding file changes
  5.7774 +added 1 changesets with 1 changes to 1 files
  5.7775 +</screen>
  5.7776 +<!-- END branch-repo.bugfix -->
  5.7777 +
  5.7778 +
  5.7779 +    <para id="x_38c">Meanwhile, development for
  5.7780 +      the next major release can continue, isolated and unabated, in
  5.7781 +      the <literal moreinfo="none">myproject</literal> repository.</para>
  5.7782 +
  5.7783 +    <!-- BEGIN branch-repo.new -->
  5.7784 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.7785 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject my-feature</userinput>
  5.7786 +updating working directory
  5.7787 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.7788 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-feature</userinput>
  5.7789 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This sure is an exciting new feature!' &gt; mynewfile</userinput>
  5.7790 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'New feature'</userinput>
  5.7791 +adding mynewfile
  5.7792 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  5.7793 +pushing to /tmp/branch-repo3rVLLS/myproject
  5.7794 +searching for changes
  5.7795 +adding changesets
  5.7796 +adding manifests
  5.7797 +adding file changes
  5.7798 +added 1 changesets with 1 changes to 1 files
  5.7799 +</screen>
  5.7800 +<!-- END branch-repo.new -->
  5.7801 +
  5.7802 +  </sect1>
  5.7803 +
  5.7804 +  <sect1>
  5.7805 +    <title>Don't repeat yourself: merging across branches</title>
  5.7806 +
  5.7807 +    <para id="x_38d">In many cases, if you have a bug to fix on a maintenance
  5.7808 +      branch, the chances are good that the bug exists on your
  5.7809 +      project's main branch (and possibly other maintenance branches,
  5.7810 +      too).  It's a rare developer who wants to fix the same bug
  5.7811 +      multiple times, so let's look at a few ways that Mercurial can
  5.7812 +      help you to manage these bugfixes without duplicating your
  5.7813 +      work.</para>
  5.7814 +
  5.7815 +    <para id="x_38e">In the simplest instance, all you need to do is pull changes
  5.7816 +      from your maintenance branch into your local clone of the target
  5.7817 +      branch.</para>
  5.7818 +
  5.7819 +    <!-- BEGIN branch-repo.pull -->
  5.7820 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.7821 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject myproject-merge</userinput>
  5.7822 +updating working directory
  5.7823 +3 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.7824 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myproject-merge</userinput>
  5.7825 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../myproject-1.0.1</userinput>
  5.7826 +pulling from ../myproject-1.0.1
  5.7827 +searching for changes
  5.7828 +adding changesets
  5.7829 +adding manifests
  5.7830 +adding file changes
  5.7831 +added 1 changesets with 1 changes to 1 files (+1 heads)
  5.7832 +(run 'hg heads' to see heads, 'hg merge' to merge)
  5.7833 +</screen>
  5.7834 +<!-- END branch-repo.pull -->
  5.7835 +
  5.7836 +
  5.7837 +    <para id="x_38f">You'll then need to merge the heads of the two branches, and
  5.7838 +      push back to the main branch.</para>
  5.7839 +
  5.7840 +    <!-- BEGIN branch-repo.merge -->
  5.7841 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.7842 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.7843 +(branch merge, don't forget to commit)
  5.7844 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Merge bugfix from 1.0.1 branch'</userinput>
  5.7845 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  5.7846 +pushing to /tmp/branch-repo3rVLLS/myproject
  5.7847 +searching for changes
  5.7848 +adding changesets
  5.7849 +adding manifests
  5.7850 +adding file changes
  5.7851 +added 2 changesets with 1 changes to 1 files
  5.7852 +</screen>
  5.7853 +<!-- END branch-repo.merge -->
  5.7854 +
  5.7855 +  </sect1>
  5.7856 +
  5.7857 +  <sect1>
  5.7858 +    <title>Naming branches within one repository</title>
  5.7859 +
  5.7860 +    <para id="x_390">In most instances, isolating branches in repositories is the
  5.7861 +      right approach.  Its simplicity makes it easy to understand; and
  5.7862 +      so it's hard to make mistakes.  There's a one-to-one
  5.7863 +      relationship between branches you're working in and directories
  5.7864 +      on your system.  This lets you use normal (non-Mercurial-aware)
  5.7865 +      tools to work on files within a branch/repository.</para>
  5.7866 +
  5.7867 +    <para id="x_391">If you're more in the <quote>power user</quote> category
  5.7868 +      (<emphasis>and</emphasis> your collaborators are too), there is
  5.7869 +      an alternative way of handling branches that you can consider.
  5.7870 +      I've already mentioned the human-level distinction between
  5.7871 +      <quote>small picture</quote> and <quote>big picture</quote>
  5.7872 +      branches.  While Mercurial works with multiple <quote>small
  5.7873 +	picture</quote> branches in a repository all the time (for
  5.7874 +      example after you pull changes in, but before you merge them),
  5.7875 +      it can <emphasis>also</emphasis> work with multiple <quote>big
  5.7876 +	picture</quote> branches.</para>
  5.7877 +
  5.7878 +    <para id="x_392">The key to working this way is that Mercurial lets you
  5.7879 +      assign a persistent <emphasis>name</emphasis> to a branch.
  5.7880 +      There always exists a branch named <literal moreinfo="none">default</literal>.
  5.7881 +      Even before you start naming branches yourself, you can find
  5.7882 +      traces of the <literal moreinfo="none">default</literal> branch if you look for
  5.7883 +      them.</para>
  5.7884 +
  5.7885 +    <para id="x_393">As an example, when you run the <command role="hg-cmd" moreinfo="none">hg
  5.7886 +	commit</command> command, and it pops up your editor so that
  5.7887 +      you can enter a commit message, look for a line that contains
  5.7888 +      the text <quote><literal moreinfo="none">HG: branch default</literal></quote> at
  5.7889 +      the bottom. This is telling you that your commit will occur on
  5.7890 +      the branch named <literal moreinfo="none">default</literal>.</para>
  5.7891 +
  5.7892 +    <para id="x_394">To start working with named branches, use the <command role="hg-cmd" moreinfo="none">hg branches</command> command.  This command
  5.7893 +      lists the named branches already present in your repository,
  5.7894 +      telling you which changeset is the tip of each.</para>
  5.7895 +
  5.7896 +    <!-- BEGIN branch-named.branches -->
  5.7897 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.7898 +changeset:   0:90897f9e54e3
  5.7899 +tag:         tip
  5.7900 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7901 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.7902 +summary:     Initial commit
  5.7903 +
  5.7904 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branches</userinput>
  5.7905 +default                        0:90897f9e54e3
  5.7906 +</screen>
  5.7907 +<!-- END branch-named.branches -->
  5.7908 +
  5.7909 +
  5.7910 +    <para id="x_395">Since you haven't created any named branches yet, the only
  5.7911 +      one that exists is <literal moreinfo="none">default</literal>.</para>
  5.7912 +
  5.7913 +    <para id="x_396">To find out what the <quote>current</quote> branch is, run
  5.7914 +      the <command role="hg-cmd" moreinfo="none">hg branch</command> command, giving
  5.7915 +      it no arguments.  This tells you what branch the parent of the
  5.7916 +      current changeset is on.</para>
  5.7917 +
  5.7918 +    <!-- BEGIN branch-named.branch -->
  5.7919 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  5.7920 +default
  5.7921 +</screen>
  5.7922 +<!-- END branch-named.branch -->
  5.7923 +
  5.7924 +
  5.7925 +    <para id="x_397">To create a new branch, run the <command role="hg-cmd" moreinfo="none">hg
  5.7926 +	branch</command> command again.  This time, give it one
  5.7927 +      argument: the name of the branch you want to create.</para>
  5.7928 +
  5.7929 +    <!-- BEGIN branch-named.create -->
  5.7930 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch foo</userinput>
  5.7931 +marked working directory as branch foo
  5.7932 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  5.7933 +foo
  5.7934 +</screen>
  5.7935 +<!-- END branch-named.create -->
  5.7936 +
  5.7937 +
  5.7938 +    <para id="x_398">After you've created a branch, you might wonder what effect
  5.7939 +      the <command role="hg-cmd" moreinfo="none">hg branch</command> command has had.
  5.7940 +      What do the <command role="hg-cmd" moreinfo="none">hg status</command> and
  5.7941 +      <command role="hg-cmd" moreinfo="none">hg tip</command> commands report?</para>
  5.7942 +
  5.7943 +    <!-- BEGIN branch-named.status -->
  5.7944 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.7945 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.7946 +changeset:   0:90897f9e54e3
  5.7947 +tag:         tip
  5.7948 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7949 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.7950 +summary:     Initial commit
  5.7951 +
  5.7952 +</screen>
  5.7953 +<!-- END branch-named.status -->
  5.7954 +
  5.7955 +
  5.7956 +    <para id="x_399">Nothing has changed in the
  5.7957 +      working directory, and there's been no new history created.  As
  5.7958 +      this suggests, running the <command role="hg-cmd" moreinfo="none">hg
  5.7959 +	branch</command> command has no permanent effect; it only
  5.7960 +      tells Mercurial what branch name to use the
  5.7961 +      <emphasis>next</emphasis> time you commit a changeset.</para>
  5.7962 +
  5.7963 +    <para id="x_39a">When you commit a change, Mercurial records the name of the
  5.7964 +      branch on which you committed.  Once you've switched from the
  5.7965 +      <literal moreinfo="none">default</literal> branch to another and committed,
  5.7966 +      you'll see the name of the new branch show up in the output of
  5.7967 +      <command role="hg-cmd" moreinfo="none">hg log</command>, <command role="hg-cmd" moreinfo="none">hg tip</command>, and other commands that
  5.7968 +      display the same kind of output.</para>
  5.7969 +
  5.7970 +    <!-- BEGIN branch-named.commit -->
  5.7971 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'hello again' &gt;&gt; myfile</userinput>
  5.7972 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Second commit'</userinput>
  5.7973 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.7974 +changeset:   1:5656f8ffdd49
  5.7975 +branch:      foo
  5.7976 +tag:         tip
  5.7977 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.7978 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.7979 +summary:     Second commit
  5.7980 +
  5.7981 +</screen>
  5.7982 +<!-- END branch-named.commit -->
  5.7983 +
  5.7984 +
  5.7985 +    <para id="x_39b">The <command role="hg-cmd" moreinfo="none">hg log</command>-like commands
  5.7986 +      will print the branch name of every changeset that's not on the
  5.7987 +      <literal moreinfo="none">default</literal> branch.  As a result, if you never
  5.7988 +      use named branches, you'll never see this information.</para>
  5.7989 +
  5.7990 +    <para id="x_39c">Once you've named a branch and committed a change with that
  5.7991 +      name, every subsequent commit that descends from that change
  5.7992 +      will inherit the same branch name.  You can change the name of a
  5.7993 +      branch at any time, using the <command role="hg-cmd" moreinfo="none">hg
  5.7994 +	branch</command> command.</para>
  5.7995 +
  5.7996 +    <!-- BEGIN branch-named.rebranch -->
  5.7997 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  5.7998 +foo
  5.7999 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch bar</userinput>
  5.8000 +marked working directory as branch bar
  5.8001 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo new file &gt; newfile</userinput>
  5.8002 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Third commit'</userinput>
  5.8003 +adding newfile
  5.8004 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.8005 +changeset:   2:c59d680fc2ec
  5.8006 +branch:      bar
  5.8007 +tag:         tip
  5.8008 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8009 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.8010 +summary:     Third commit
  5.8011 +
  5.8012 +</screen>
  5.8013 +<!-- END branch-named.rebranch -->
  5.8014 +
  5.8015 +
  5.8016 +    <para id="x_39d">In practice, this is something you won't do very often, as
  5.8017 +      branch names tend to have fairly long lifetimes.  (This isn't a
  5.8018 +      rule, just an observation.)</para>
  5.8019 +  </sect1>
  5.8020 +
  5.8021 +  <sect1>
  5.8022 +    <title>Dealing with multiple named branches in a
  5.8023 +      repository</title>
  5.8024 +
  5.8025 +    <para id="x_39e">If you have more than one named branch in a repository,
  5.8026 +      Mercurial will remember the branch that your working directory
  5.8027 +      is on when you start a command like <command role="hg-cmd" moreinfo="none">hg
  5.8028 +	update</command> or <command role="hg-cmd" moreinfo="none">hg pull
  5.8029 +	-u</command>.  It will update the working directory to the tip
  5.8030 +      of this branch, no matter what the <quote>repo-wide</quote> tip
  5.8031 +      is.  To update to a revision that's on a different named branch,
  5.8032 +      you may need to use the <option role="hg-opt-update">-C</option>
  5.8033 +      option to <command role="hg-cmd" moreinfo="none">hg update</command>.</para>
  5.8034 +
  5.8035 +    <para id="x_39f">This behavior is a little subtle, so let's see it in
  5.8036 +      action.  First, let's remind ourselves what branch we're
  5.8037 +      currently on, and what branches are in our repository.</para>
  5.8038 +
  5.8039 +    <!-- BEGIN branch-named.parents -->
  5.8040 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.8041 +changeset:   2:c59d680fc2ec
  5.8042 +branch:      bar
  5.8043 +tag:         tip
  5.8044 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8045 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.8046 +summary:     Third commit
  5.8047 +
  5.8048 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branches</userinput>
  5.8049 +bar                            2:c59d680fc2ec
  5.8050 +foo                            1:5656f8ffdd49 (inactive)
  5.8051 +default                        0:90897f9e54e3 (inactive)
  5.8052 +</screen>
  5.8053 +<!-- END branch-named.parents -->
  5.8054 +
  5.8055 +
  5.8056 +    <para id="x_3a0">We're on the <literal moreinfo="none">bar</literal> branch, but there also
  5.8057 +      exists an older <command role="hg-cmd" moreinfo="none">hg foo</command>
  5.8058 +      branch.</para>
  5.8059 +
  5.8060 +    <para id="x_3a1">We can <command role="hg-cmd" moreinfo="none">hg update</command> back and
  5.8061 +      forth between the tips of the <literal moreinfo="none">foo</literal> and
  5.8062 +      <literal moreinfo="none">bar</literal> branches without needing to use the
  5.8063 +      <option role="hg-opt-update">-C</option> option, because this
  5.8064 +      only involves going backwards and forwards linearly through our
  5.8065 +      change history.</para>
  5.8066 +
  5.8067 +    <!-- BEGIN branch-named.update-switchy -->
  5.8068 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update foo</userinput>
  5.8069 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  5.8070 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.8071 +changeset:   1:5656f8ffdd49
  5.8072 +branch:      foo
  5.8073 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8074 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.8075 +summary:     Second commit
  5.8076 +
  5.8077 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update bar</userinput>
  5.8078 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.8079 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.8080 +changeset:   2:c59d680fc2ec
  5.8081 +branch:      bar
  5.8082 +tag:         tip
  5.8083 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8084 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.8085 +summary:     Third commit
  5.8086 +
  5.8087 +</screen>
  5.8088 +<!-- END branch-named.update-switchy -->
  5.8089 +
  5.8090 +
  5.8091 +    <para id="x_3a2">If we go back to the <literal moreinfo="none">foo</literal> branch and then
  5.8092 +      run <command role="hg-cmd" moreinfo="none">hg update</command>, it will keep us
  5.8093 +      on <literal moreinfo="none">foo</literal>, not move us to the tip of
  5.8094 +      <literal moreinfo="none">bar</literal>.</para>
  5.8095 +
  5.8096 +    <!-- BEGIN branch-named.update-nothing -->
  5.8097 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update foo</userinput>
  5.8098 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  5.8099 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update</userinput>
  5.8100 +0 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.8101 +</screen>
  5.8102 +<!-- END branch-named.update-nothing -->
  5.8103 +
  5.8104 +
  5.8105 +    <para id="x_3a3">Committing a new change on the <literal moreinfo="none">foo</literal> branch
  5.8106 +      introduces a new head.</para>
  5.8107 +
  5.8108 +    <!-- BEGIN branch-named.foo-commit -->
  5.8109 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo something &gt; somefile</userinput>
  5.8110 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'New file'</userinput>
  5.8111 +adding somefile
  5.8112 +created new head
  5.8113 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  5.8114 +changeset:   3:4dd2f7a37288
  5.8115 +branch:      foo
  5.8116 +tag:         tip
  5.8117 +parent:      1:5656f8ffdd49
  5.8118 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8119 +date:        Sun Aug 16 14:04:43 2009 +0000
  5.8120 +summary:     New file
  5.8121 +
  5.8122 +changeset:   2:c59d680fc2ec
  5.8123 +branch:      bar
  5.8124 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8125 +date:        Sun Aug 16 14:04:42 2009 +0000
  5.8126 +summary:     Third commit
  5.8127 +
  5.8128 +</screen>
  5.8129 +<!-- END branch-named.foo-commit -->
  5.8130 +
  5.8131 +  </sect1>
  5.8132 +
  5.8133 +  <sect1>
  5.8134 +    <title>Branch names and merging</title>
  5.8135 +
  5.8136 +    <para id="x_3a4">As you've probably noticed, merges in Mercurial are not
  5.8137 +      symmetrical. Let's say our repository has two heads, 17 and 23.
  5.8138 +      If I <command role="hg-cmd" moreinfo="none">hg update</command> to 17 and then
  5.8139 +      <command role="hg-cmd" moreinfo="none">hg merge</command> with 23, Mercurial
  5.8140 +      records 17 as the first parent of the merge, and 23 as the
  5.8141 +      second.  Whereas if I <command role="hg-cmd" moreinfo="none">hg update</command>
  5.8142 +      to 23 and then <command role="hg-cmd" moreinfo="none">hg merge</command> with
  5.8143 +      17, it records 23 as the first parent, and 17 as the
  5.8144 +      second.</para>
  5.8145 +
  5.8146 +    <para id="x_3a5">This affects Mercurial's choice of branch name when you
  5.8147 +      merge.  After a merge, Mercurial will retain the branch name of
  5.8148 +      the first parent when you commit the result of the merge.  If
  5.8149 +      your first parent's branch name is <literal moreinfo="none">foo</literal>, and
  5.8150 +      you merge with <literal moreinfo="none">bar</literal>, the branch name will
  5.8151 +      still be <literal moreinfo="none">foo</literal> after you merge.</para>
  5.8152 +
  5.8153 +    <para id="x_3a6">It's not unusual for a repository to contain multiple heads,
  5.8154 +      each with the same branch name.  Let's say I'm working on the
  5.8155 +      <literal moreinfo="none">foo</literal> branch, and so are you.  We commit
  5.8156 +      different changes; I pull your changes; I now have two heads,
  5.8157 +      each claiming to be on the <literal moreinfo="none">foo</literal> branch.  The
  5.8158 +      result of a merge will be a single head on the
  5.8159 +      <literal moreinfo="none">foo</literal> branch, as you might hope.</para>
  5.8160 +
  5.8161 +    <para id="x_3a7">But if I'm working on the <literal moreinfo="none">bar</literal> branch, and
  5.8162 +      I merge work from the <literal moreinfo="none">foo</literal> branch, the result
  5.8163 +      will remain on the <literal moreinfo="none">bar</literal> branch.</para>
  5.8164 +
  5.8165 +    <!-- BEGIN branch-named.merge -->
  5.8166 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  5.8167 +bar
  5.8168 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge foo</userinput>
  5.8169 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.8170 +(branch merge, don't forget to commit)
  5.8171 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Merge'</userinput>
  5.8172 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.8173 +changeset:   4:9f05d4ef3efe
  5.8174 +branch:      bar
  5.8175 +tag:         tip
  5.8176 +parent:      2:c59d680fc2ec
  5.8177 +parent:      3:4dd2f7a37288
  5.8178 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8179 +date:        Sun Aug 16 14:04:44 2009 +0000
  5.8180 +summary:     Merge
  5.8181 +
  5.8182 +</screen>
  5.8183 +<!-- END branch-named.merge -->
  5.8184 +
  5.8185 +
  5.8186 +    <para id="x_3a8">To give a more concrete example, if I'm working on the
  5.8187 +      <literal moreinfo="none">bleeding-edge</literal> branch, and I want to bring in
  5.8188 +      the latest fixes from the <literal moreinfo="none">stable</literal> branch,
  5.8189 +      Mercurial will choose the <quote>right</quote>
  5.8190 +      (<literal moreinfo="none">bleeding-edge</literal>) branch name when I pull and
  5.8191 +      merge from <literal moreinfo="none">stable</literal>.</para>
  5.8192 +  </sect1>
  5.8193 +
  5.8194 +  <sect1>
  5.8195 +    <title>Branch naming is generally useful</title>
  5.8196 +
  5.8197 +    <para id="x_3a9">You shouldn't think of named branches as applicable only to
  5.8198 +      situations where you have multiple long-lived branches
  5.8199 +      cohabiting in a single repository.  They're very useful even in
  5.8200 +      the one-branch-per-repository case.</para>
  5.8201 +
  5.8202 +    <para id="x_3aa">In the simplest case, giving a name to each branch gives you
  5.8203 +      a permanent record of which branch a changeset originated on.
  5.8204 +      This gives you more context when you're trying to follow the
  5.8205 +      history of a long-lived branchy project.</para>
  5.8206 +
  5.8207 +    <para id="x_3ab">If you're working with shared repositories, you can set up a
  5.8208 +      <literal role="hook" moreinfo="none">pretxnchangegroup</literal> hook on each
  5.8209 +      that will block incoming changes that have the
  5.8210 +      <quote>wrong</quote> branch name.  This provides a simple, but
  5.8211 +      effective, defence against people accidentally pushing changes
  5.8212 +      from a <quote>bleeding edge</quote> branch to a
  5.8213 +      <quote>stable</quote> branch.  Such a hook might look like this
  5.8214 +      inside the shared repo's <filename role="special" moreinfo="none">
  5.8215 +	/.hgrc</filename>.</para>
  5.8216 +    <programlisting format="linespecific">[hooks]
  5.8217 +pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
  5.8218 +  </sect1>
  5.8219 +</chapter>
  5.8220 +
  5.8221 +<!--
  5.8222 +local variables: 
  5.8223 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.8224 +end:
  5.8225 +-->
  5.8226 +
  5.8227 +  <!-- BEGIN ch09 -->
  5.8228 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.8229 +
  5.8230 +<chapter id="chap:undo">
  5.8231 +  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
  5.8232 +  <title>Finding and fixing mistakes</title>
  5.8233 +
  5.8234 +  <para id="x_d2">To err might be human, but to really handle the consequences
  5.8235 +    well takes a top-notch revision control system.  In this chapter,
  5.8236 +    we'll discuss some of the techniques you can use when you find
  5.8237 +    that a problem has crept into your project.  Mercurial has some
  5.8238 +    highly capable features that will help you to isolate the sources
  5.8239 +    of problems, and to handle them appropriately.</para>
  5.8240 +
  5.8241 +  <sect1>
  5.8242 +    <title>Erasing local history</title>
  5.8243 +
  5.8244 +    <sect2>
  5.8245 +      <title>The accidental commit</title>
  5.8246 +
  5.8247 +      <para id="x_d3">I have the occasional but persistent problem of typing
  5.8248 +	rather more quickly than I can think, which sometimes results
  5.8249 +	in me committing a changeset that is either incomplete or
  5.8250 +	plain wrong.  In my case, the usual kind of incomplete
  5.8251 +	changeset is one in which I've created a new source file, but
  5.8252 +	forgotten to <command role="hg-cmd" moreinfo="none">hg add</command> it.  A
  5.8253 +	<quote>plain wrong</quote> changeset is not as common, but no
  5.8254 +	less annoying.</para>
  5.8255 +
  5.8256 +    </sect2>
  5.8257 +    <sect2 id="sec:undo:rollback">
  5.8258 +      <title>Rolling back a transaction</title>
  5.8259 +
  5.8260 +      <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I
  5.8261 +	mentioned that Mercurial treats each modification of a
  5.8262 +	repository as a <emphasis>transaction</emphasis>.  Every time
  5.8263 +	you commit a changeset or pull changes from another
  5.8264 +	repository, Mercurial remembers what you did.  You can undo,
  5.8265 +	or <emphasis>roll back</emphasis>, exactly one of these
  5.8266 +	actions using the <command role="hg-cmd" moreinfo="none">hg rollback</command>
  5.8267 +	command.  (See <xref linkend="sec:undo:rollback-after-push"/>
  5.8268 +	for an important caveat about the use of this command.)</para>
  5.8269 +
  5.8270 +      <para id="x_d5">Here's a mistake that I often find myself making:
  5.8271 +	committing a change in which I've created a new file, but
  5.8272 +	forgotten to <command role="hg-cmd" moreinfo="none">hg add</command>
  5.8273 +	it.</para>
  5.8274 +
  5.8275 +      <!-- BEGIN rollback.commit -->
  5.8276 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8277 +M a
  5.8278 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b</userinput>
  5.8279 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Add file b'</userinput>
  5.8280 +</screen>
  5.8281 +<!-- END rollback.commit -->
  5.8282 +
  5.8283 +
  5.8284 +      <para id="x_d6">Looking at the output of <command role="hg-cmd" moreinfo="none">hg
  5.8285 +	  status</command> after the commit immediately confirms the
  5.8286 +	error.</para>
  5.8287 +
  5.8288 +      <!-- BEGIN rollback.status -->
  5.8289 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8290 +? b
  5.8291 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.8292 +changeset:   1:246e2aada1c5
  5.8293 +tag:         tip
  5.8294 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8295 +date:        Sun Aug 16 14:05:14 2009 +0000
  5.8296 +summary:     Add file b
  5.8297 +
  5.8298 +</screen>
  5.8299 +<!-- END rollback.status -->
  5.8300 +
  5.8301 +
  5.8302 +      <para id="x_d7">The commit captured the changes to the file
  5.8303 +	<filename moreinfo="none">a</filename>, but not the new file
  5.8304 +	<filename moreinfo="none">b</filename>.  If I were to push this changeset to a
  5.8305 +	repository that I shared with a colleague, the chances are
  5.8306 +	high that something in <filename moreinfo="none">a</filename> would refer to
  5.8307 +	<filename moreinfo="none">b</filename>, which would not be present in their
  5.8308 +	repository when they pulled my changes.  I would thus become
  5.8309 +	the object of some indignation.</para>
  5.8310 +
  5.8311 +      <para id="x_d8">However, luck is with me—I've caught my error
  5.8312 +	before I pushed the changeset.  I use the <command role="hg-cmd" moreinfo="none">hg rollback</command> command, and Mercurial
  5.8313 +	makes that last changeset vanish.</para>
  5.8314 +
  5.8315 +      <!-- BEGIN rollback.rollback -->
  5.8316 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rollback</userinput>
  5.8317 +rolling back last transaction
  5.8318 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  5.8319 +changeset:   0:c37ce4157509
  5.8320 +tag:         tip
  5.8321 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8322 +date:        Sun Aug 16 14:05:14 2009 +0000
  5.8323 +summary:     First commit
  5.8324 +
  5.8325 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8326 +M a
  5.8327 +? b
  5.8328 +</screen>
  5.8329 +<!-- END rollback.rollback -->
  5.8330 +
  5.8331 +
  5.8332 +      <para id="x_d9">Notice that the changeset is no longer present in the
  5.8333 +	repository's history, and the working directory once again
  5.8334 +	thinks that the file <filename moreinfo="none">a</filename> is modified.  The
  5.8335 +	commit and rollback have left the working directory exactly as
  5.8336 +	it was prior to the commit; the changeset has been completely
  5.8337 +	erased.  I can now safely <command role="hg-cmd" moreinfo="none">hg
  5.8338 +	  add</command> the file <filename moreinfo="none">b</filename>, and rerun my
  5.8339 +	commit.</para>
  5.8340 +
  5.8341 +      <!-- BEGIN rollback.add -->
  5.8342 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add b</userinput>
  5.8343 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Add file b, this time for real'</userinput>
  5.8344 +</screen>
  5.8345 +<!-- END rollback.add -->
  5.8346 +
  5.8347 +
  5.8348 +    </sect2>
  5.8349 +    <sect2>
  5.8350 +      <title>The erroneous pull</title>
  5.8351 +
  5.8352 +      <para id="x_da">It's common practice with Mercurial to maintain separate
  5.8353 +	development branches of a project in different repositories.
  5.8354 +	Your development team might have one shared repository for
  5.8355 +	your project's <quote>0.9</quote> release, and another,
  5.8356 +	containing different changes, for the <quote>1.0</quote>
  5.8357 +	release.</para>
  5.8358 +
  5.8359 +      <para id="x_db">Given this, you can imagine that the consequences could be
  5.8360 +	messy if you had a local <quote>0.9</quote> repository, and
  5.8361 +	accidentally pulled changes from the shared <quote>1.0</quote>
  5.8362 +	repository into it.  At worst, you could be paying
  5.8363 +	insufficient attention, and push those changes into the shared
  5.8364 +	<quote>0.9</quote> tree, confusing your entire team (but don't
  5.8365 +	worry, we'll return to this horror scenario later).  However,
  5.8366 +	it's more likely that you'll notice immediately, because
  5.8367 +	Mercurial will display the URL it's pulling from, or you will
  5.8368 +	see it pull a suspiciously large number of changes into the
  5.8369 +	repository.</para>
  5.8370 +
  5.8371 +      <para id="x_dc">The <command role="hg-cmd" moreinfo="none">hg rollback</command> command
  5.8372 +	will work nicely to expunge all of the changesets that you
  5.8373 +	just pulled.  Mercurial groups all changes from one <command role="hg-cmd" moreinfo="none">hg pull</command> into a single transaction,
  5.8374 +	so one <command role="hg-cmd" moreinfo="none">hg rollback</command> is all you
  5.8375 +	need to undo this mistake.</para>
  5.8376 +
  5.8377 +    </sect2>
  5.8378 +    <sect2 id="sec:undo:rollback-after-push">
  5.8379 +      <title>Rolling back is useless once you've pushed</title>
  5.8380 +
  5.8381 +      <para id="x_dd">The value of the <command role="hg-cmd" moreinfo="none">hg
  5.8382 +	  rollback</command> command drops to zero once you've pushed
  5.8383 +	your changes to another repository.  Rolling back a change
  5.8384 +	makes it disappear entirely, but <emphasis>only</emphasis> in
  5.8385 +	the repository in which you perform the <command role="hg-cmd" moreinfo="none">hg rollback</command>.  Because a rollback
  5.8386 +	eliminates history, there's no way for the disappearance of a
  5.8387 +	change to propagate between repositories.</para>
  5.8388 +
  5.8389 +      <para id="x_de">If you've pushed a change to another
  5.8390 +	repository—particularly if it's a shared
  5.8391 +	repository—it has essentially <quote>escaped into the
  5.8392 +	  wild,</quote> and you'll have to recover from your mistake
  5.8393 +	in a different way.  If you push a changeset somewhere, then
  5.8394 +	roll it back, then pull from the repository you pushed to, the
  5.8395 +	changeset you thought you'd gotten rid of will simply reappear
  5.8396 +	in your repository.</para>
  5.8397 +
  5.8398 +      <para id="x_df">(If you absolutely know for sure that the change
  5.8399 +	you want to roll back is the most recent change in the
  5.8400 +	repository that you pushed to, <emphasis>and</emphasis> you
  5.8401 +	know that nobody else could have pulled it from that
  5.8402 +	repository, you can roll back the changeset there, too, but
  5.8403 +	you really should not expect this to work reliably.  Sooner or
  5.8404 +	later a change really will make it into a repository that you
  5.8405 +	don't directly control (or have forgotten about), and come
  5.8406 +	back to bite you.)</para>
  5.8407 +
  5.8408 +    </sect2>
  5.8409 +    <sect2>
  5.8410 +      <title>You can only roll back once</title>
  5.8411 +
  5.8412 +      <para id="x_e0">Mercurial stores exactly one transaction in its
  5.8413 +	transaction log; that transaction is the most recent one that
  5.8414 +	occurred in the repository. This means that you can only roll
  5.8415 +	back one transaction.  If you expect to be able to roll back
  5.8416 +	one transaction, then its predecessor, this is not the
  5.8417 +	behavior you will get.</para>
  5.8418 +
  5.8419 +      <!-- BEGIN rollback.twice -->
  5.8420 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rollback</userinput>
  5.8421 +rolling back last transaction
  5.8422 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rollback</userinput>
  5.8423 +no rollback information available
  5.8424 +</screen>
  5.8425 +<!-- END rollback.twice -->
  5.8426 +
  5.8427 +
  5.8428 +      <para id="x_e1">Once you've rolled back one transaction in a repository,
  5.8429 +	you can't roll back again in that repository until you perform
  5.8430 +	another commit or pull.</para>
  5.8431 +
  5.8432 +    </sect2>
  5.8433 +  </sect1>
  5.8434 +  <sect1>
  5.8435 +    <title>Reverting the mistaken change</title>
  5.8436 +
  5.8437 +    <para id="x_e2">If you make a modification to a file, and decide that you
  5.8438 +      really didn't want to change the file at all, and you haven't
  5.8439 +      yet committed your changes, the <command role="hg-cmd" moreinfo="none">hg
  5.8440 +	revert</command> command is the one you'll need.  It looks at
  5.8441 +      the changeset that's the parent of the working directory, and
  5.8442 +      restores the contents of the file to their state as of that
  5.8443 +      changeset. (That's a long-winded way of saying that, in the
  5.8444 +      normal case, it undoes your modifications.)</para>
  5.8445 +
  5.8446 +    <para id="x_e3">Let's illustrate how the <command role="hg-cmd" moreinfo="none">hg
  5.8447 +	revert</command> command works with yet another small example.
  5.8448 +      We'll begin by modifying a file that Mercurial is already
  5.8449 +      tracking.</para>
  5.8450 +
  5.8451 +    <!-- BEGIN daily.revert.modify -->
  5.8452 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file</userinput>
  5.8453 +original content
  5.8454 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo unwanted change &gt;&gt; file</userinput>
  5.8455 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff file</userinput>
  5.8456 +diff -r 2eacf948d309 file
  5.8457 +--- a/file	Sun Aug 16 14:05:00 2009 +0000
  5.8458 ++++ b/file	Sun Aug 16 14:05:00 2009 +0000
  5.8459 +@@ -1,1 +1,2 @@
  5.8460 + original content
  5.8461 ++unwanted change
  5.8462 +</screen>
  5.8463 +<!-- END daily.revert.modify -->
  5.8464 +
  5.8465 +
  5.8466 +    <para id="x_e4">If we don't
  5.8467 +      want that change, we can simply <command role="hg-cmd" moreinfo="none">hg
  5.8468 +	revert</command> the file.</para>
  5.8469 +
  5.8470 +      <!-- BEGIN daily.revert.unmodify -->
  5.8471 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8472 +M file
  5.8473 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert file</userinput>
  5.8474 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file</userinput>
  5.8475 +original content
  5.8476 +</screen>
  5.8477 +<!-- END daily.revert.unmodify -->
  5.8478 +
  5.8479 +
  5.8480 +    <para id="x_e5">The <command role="hg-cmd" moreinfo="none">hg revert</command> command
  5.8481 +      provides us with an extra degree of safety by saving our
  5.8482 +      modified file with a <filename moreinfo="none">.orig</filename>
  5.8483 +      extension.</para>
  5.8484 +
  5.8485 +    <!-- BEGIN daily.revert.status -->
  5.8486 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8487 +? file.orig
  5.8488 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file.orig</userinput>
  5.8489 +original content
  5.8490 +unwanted change
  5.8491 +</screen>
  5.8492 +<!-- END daily.revert.status -->
  5.8493 +
  5.8494 +
  5.8495 +    <tip>
  5.8496 +      <title>Be careful with <filename moreinfo="none">.orig</filename> files</title>
  5.8497 +
  5.8498 +      <para id="x_6b8">It's extremely unlikely that you are either using
  5.8499 +	Mercurial to manage files with <filename moreinfo="none">.orig</filename>
  5.8500 +	extensions or that you even care about the contents of such
  5.8501 +	files.  Just in case, though, it's useful to remember that
  5.8502 +	<command role="hg-cmd" moreinfo="none">hg revert</command> will
  5.8503 +	unconditionally overwrite an existing file with a
  5.8504 +	<filename moreinfo="none">.orig</filename> extension. For instance, if you
  5.8505 +	already have a file named <filename moreinfo="none">foo.orig</filename> when
  5.8506 +	you revert <filename moreinfo="none">foo</filename>, the contents of
  5.8507 +	<filename moreinfo="none">foo.orig</filename> will be clobbered.</para>
  5.8508 +    </tip>
  5.8509 +
  5.8510 +    <para id="x_e6">Here is a summary of the cases that the <command role="hg-cmd" moreinfo="none">hg revert</command> command can deal with.  We
  5.8511 +      will describe each of these in more detail in the section that
  5.8512 +      follows.</para>
  5.8513 +    <itemizedlist>
  5.8514 +      <listitem><para id="x_e7">If you modify a file, it will restore the file
  5.8515 +	  to its unmodified state.</para>
  5.8516 +      </listitem>
  5.8517 +      <listitem><para id="x_e8">If you <command role="hg-cmd" moreinfo="none">hg add</command> a
  5.8518 +	  file, it will undo the <quote>added</quote> state of the
  5.8519 +	  file, but leave the file itself untouched.</para>
  5.8520 +      </listitem>
  5.8521 +      <listitem><para id="x_e9">If you delete a file without telling Mercurial,
  5.8522 +	  it will restore the file to its unmodified contents.</para>
  5.8523 +      </listitem>
  5.8524 +      <listitem><para id="x_ea">If you use the <command role="hg-cmd" moreinfo="none">hg
  5.8525 +	    remove</command> command to remove a file, it will undo
  5.8526 +	  the <quote>removed</quote> state of the file, and restore
  5.8527 +	  the file to its unmodified contents.</para>
  5.8528 +      </listitem></itemizedlist>
  5.8529 +
  5.8530 +    <sect2 id="sec:undo:mgmt">
  5.8531 +      <title>File management errors</title>
  5.8532 +
  5.8533 +      <para id="x_eb">The <command role="hg-cmd" moreinfo="none">hg revert</command> command is
  5.8534 +	useful for more than just modified files.  It lets you reverse
  5.8535 +	the results of all of Mercurial's file management
  5.8536 +	commands—<command role="hg-cmd" moreinfo="none">hg add</command>,
  5.8537 +	<command role="hg-cmd" moreinfo="none">hg remove</command>, and so on.</para>
  5.8538 +
  5.8539 +      <para id="x_ec">If you <command role="hg-cmd" moreinfo="none">hg add</command> a file,
  5.8540 +	then decide that in fact you don't want Mercurial to track it,
  5.8541 +	use <command role="hg-cmd" moreinfo="none">hg revert</command> to undo the
  5.8542 +	add.  Don't worry; Mercurial will not modify the file in any
  5.8543 +	way.  It will just <quote>unmark</quote> the file.</para>
  5.8544 +
  5.8545 +      <!-- BEGIN daily.revert.add -->
  5.8546 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo oops &gt; oops</userinput>
  5.8547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add oops</userinput>
  5.8548 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status oops</userinput>
  5.8549 +A oops
  5.8550 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert oops</userinput>
  5.8551 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8552 +? oops
  5.8553 +</screen>
  5.8554 +<!-- END daily.revert.add -->
  5.8555 +
  5.8556 +
  5.8557 +      <para id="x_ed">Similarly, if you ask Mercurial to <command role="hg-cmd" moreinfo="none">hg remove</command> a file, you can use
  5.8558 +	<command role="hg-cmd" moreinfo="none">hg revert</command> to restore it to
  5.8559 +	the contents it had as of the parent of the working directory.
  5.8560 +	<!-- BEGIN daily.revert.remove -->
  5.8561 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove file</userinput>
  5.8562 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8563 +R file
  5.8564 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert file</userinput>
  5.8565 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8566 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls file</userinput>
  5.8567 +file
  5.8568 +</screen>
  5.8569 +<!-- END daily.revert.remove -->
  5.8570 + This works just as
  5.8571 +	well for a file that you deleted by hand, without telling
  5.8572 +	Mercurial (recall that in Mercurial terminology, this kind of
  5.8573 +	file is called <quote>missing</quote>).</para>
  5.8574 +
  5.8575 +      <!-- BEGIN daily.revert.missing -->
  5.8576 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">rm file</userinput>
  5.8577 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8578 +! file
  5.8579 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert file</userinput>
  5.8580 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls file</userinput>
  5.8581 +file
  5.8582 +</screen>
  5.8583 +<!-- END daily.revert.missing -->
  5.8584 +
  5.8585 +
  5.8586 +      <para id="x_ee">If you revert a <command role="hg-cmd" moreinfo="none">hg copy</command>,
  5.8587 +	the copied-to file remains in your working directory
  5.8588 +	afterwards, untracked.  Since a copy doesn't affect the
  5.8589 +	copied-from file in any way, Mercurial doesn't do anything
  5.8590 +	with the copied-from file.</para>
  5.8591 +
  5.8592 +      <!-- BEGIN daily.revert.copy -->
  5.8593 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy file new-file</userinput>
  5.8594 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert new-file</userinput>
  5.8595 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  5.8596 +? new-file
  5.8597 +</screen>
  5.8598 +<!-- END daily.revert.copy -->
  5.8599 +
  5.8600 +    </sect2>
  5.8601 +  </sect1>
  5.8602 +
  5.8603 +  <sect1>
  5.8604 +    <title>Dealing with committed changes</title>
  5.8605 +
  5.8606 +    <para id="x_f5">Consider a case where you have committed a change
  5.8607 +      <emphasis>a</emphasis>, and another change
  5.8608 +      <emphasis>b</emphasis> on top of it; you then realise that
  5.8609 +      change <emphasis>a</emphasis> was incorrect.  Mercurial lets you
  5.8610 +      <quote>back out</quote> an entire changeset automatically, and
  5.8611 +      building blocks that let you reverse part of a changeset by
  5.8612 +      hand.</para>
  5.8613 +
  5.8614 +    <para id="x_f6">Before you read this section, here's something to
  5.8615 +      keep in mind: the <command role="hg-cmd" moreinfo="none">hg backout</command>
  5.8616 +      command undoes the effect of a change by
  5.8617 +      <emphasis>adding</emphasis> to your repository's history, not by
  5.8618 +      modifying or erasing it.  It's the right tool to use if you're
  5.8619 +      fixing bugs, but not if you're trying to undo some change that
  5.8620 +      has catastrophic consequences.  To deal with those, see
  5.8621 +      <xref linkend="sec:undo:aaaiiieee"/>.</para>
  5.8622 +
  5.8623 +    <sect2>
  5.8624 +      <title>Backing out a changeset</title>
  5.8625 +
  5.8626 +      <para id="x_f7">The <command role="hg-cmd" moreinfo="none">hg backout</command> command
  5.8627 +	lets you <quote>undo</quote> the effects of an entire
  5.8628 +	changeset in an automated fashion.  Because Mercurial's
  5.8629 +	history is immutable, this command <emphasis>does
  5.8630 +	  not</emphasis> get rid of the changeset you want to undo.
  5.8631 +	Instead, it creates a new changeset that
  5.8632 +	<emphasis>reverses</emphasis> the effect of the to-be-undone
  5.8633 +	changeset.</para>
  5.8634 +
  5.8635 +      <para id="x_f8">The operation of the <command role="hg-cmd" moreinfo="none">hg
  5.8636 +	  backout</command> command is a little intricate, so let's
  5.8637 +	illustrate it with some examples.  First, we'll create a
  5.8638 +	repository with some simple changes.</para>
  5.8639 +
  5.8640 +      <!-- BEGIN backout.init -->
  5.8641 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init myrepo</userinput>
  5.8642 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myrepo</userinput>
  5.8643 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo first change &gt;&gt; myfile</userinput>
  5.8644 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add myfile</userinput>
  5.8645 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'first change'</userinput>
  5.8646 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo second change &gt;&gt; myfile</userinput>
  5.8647 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'second change'</userinput>
  5.8648 +</screen>
  5.8649 +<!-- END backout.init -->
  5.8650 +
  5.8651 +
  5.8652 +      <para id="x_f9">The <command role="hg-cmd" moreinfo="none">hg backout</command> command
  5.8653 +	takes a single changeset ID as its argument; this is the
  5.8654 +	changeset to back out.  Normally, <command role="hg-cmd" moreinfo="none">hg
  5.8655 +	  backout</command> will drop you into a text editor to write
  5.8656 +	a commit message, so you can record why you're backing the
  5.8657 +	change out.  In this example, we provide a commit message on
  5.8658 +	the command line using the <option role="hg-opt-backout">-m</option> option.</para>
  5.8659 +
  5.8660 +    </sect2>
  5.8661 +    <sect2>
  5.8662 +      <title>Backing out the tip changeset</title>
  5.8663 +
  5.8664 +      <para id="x_fa">We're going to start by backing out the last changeset we
  5.8665 +	committed.</para>
  5.8666 +
  5.8667 +      <!-- BEGIN backout.simple -->
  5.8668 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg backout -m 'back out second change' tip</userinput>
  5.8669 +reverting myfile
  5.8670 +changeset 2:611a0cae251c backs out changeset 1:43700a9b3ec8
  5.8671 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.8672 +first change
  5.8673 +</screen>
  5.8674 +<!-- END backout.simple -->
  5.8675 +
  5.8676 +
  5.8677 +      <para id="x_fb">You can see that the second line from
  5.8678 +	<filename moreinfo="none">myfile</filename> is no longer present.  Taking a
  5.8679 +	look at the output of <command role="hg-cmd" moreinfo="none">hg log</command>
  5.8680 +	gives us an idea of what the <command role="hg-cmd" moreinfo="none">hg
  5.8681 +	  backout</command> command has done.
  5.8682 +	<!-- BEGIN backout.simple.log -->
  5.8683 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style compact</userinput>
  5.8684 +2[tip]   611a0cae251c   2009-08-16 14:04 +0000   bos
  5.8685 +  back out second change
  5.8686 +
  5.8687 +1   43700a9b3ec8   2009-08-16 14:04 +0000   bos
  5.8688 +  second change
  5.8689 +
  5.8690 +0   f2ef23d503fd   2009-08-16 14:04 +0000   bos
  5.8691 +  first change
  5.8692 +
  5.8693 +</screen>
  5.8694 +<!-- END backout.simple.log -->
  5.8695 + Notice that the new changeset
  5.8696 +	that <command role="hg-cmd" moreinfo="none">hg backout</command> has created
  5.8697 +	is a child of the changeset we backed out.  It's easier to see
  5.8698 +	this in <xref linkend="fig:undo:backout"/>, which presents a
  5.8699 +	graphical view of the change history.  As you can see, the
  5.8700 +	history is nice and linear.</para>
  5.8701 +
  5.8702 +      <figure id="fig:undo:backout" float="0">
  5.8703 +	<title>Backing out a change using the <command role="hg-cmd" moreinfo="none">hg backout</command> command</title>
  5.8704 +	<mediaobject>
  5.8705 +	  <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject>
  5.8706 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.8707 +	</mediaobject>
  5.8708 +      </figure>
  5.8709 +
  5.8710 +    </sect2>
  5.8711 +    <sect2>
  5.8712 +      <title>Backing out a non-tip change</title>
  5.8713 +
  5.8714 +      <para id="x_fd">If you want to back out a change other than the last one
  5.8715 +	you committed, pass the <option role="hg-opt-backout">--merge</option> option to the
  5.8716 +	<command role="hg-cmd" moreinfo="none">hg backout</command> command.</para>
  5.8717 +
  5.8718 +      <!-- BEGIN backout.non-tip.clone -->
  5.8719 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.8720 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -r1 myrepo non-tip-repo</userinput>
  5.8721 +requesting all changes
  5.8722 +adding changesets
  5.8723 +adding manifests
  5.8724 +adding file changes
  5.8725 +added 2 changesets with 2 changes to 1 files
  5.8726 +updating working directory
  5.8727 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.8728 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd non-tip-repo</userinput>
  5.8729 +</screen>
  5.8730 +<!-- END backout.non-tip.clone -->
  5.8731 +
  5.8732 +
  5.8733 +      <para id="x_fe">This makes backing out any changeset a
  5.8734 +	<quote>one-shot</quote> operation that's usually simple and
  5.8735 +	fast.</para>
  5.8736 +
  5.8737 +      <!-- BEGIN backout.non-tip.backout -->
  5.8738 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo third change &gt;&gt; myfile</userinput>
  5.8739 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'third change'</userinput>
  5.8740 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg backout --merge -m 'back out second change' 1</userinput>
  5.8741 +reverting myfile
  5.8742 +created new head
  5.8743 +changeset 3:611a0cae251c backs out changeset 1:43700a9b3ec8
  5.8744 +merging with changeset 3:611a0cae251c
  5.8745 +merging myfile
  5.8746 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  5.8747 +(branch merge, don't forget to commit)
  5.8748 +</screen>
  5.8749 +<!-- END backout.non-tip.backout -->
  5.8750 +
  5.8751 +
  5.8752 +      <para id="x_ff">If you take a look at the contents of
  5.8753 +	<filename moreinfo="none">myfile</filename> after the backout finishes, you'll
  5.8754 +	see that the first and third changes are present, but not the
  5.8755 +	second.</para>
  5.8756 +
  5.8757 +      <!-- BEGIN backout.non-tip.cat -->
  5.8758 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.8759 +first change
  5.8760 +third change
  5.8761 +</screen>
  5.8762 +<!-- END backout.non-tip.cat -->
  5.8763 +
  5.8764 +
  5.8765 +      <para id="x_100">As the graphical history in <xref linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial
  5.8766 +	still commits one change in this kind of situation (the
  5.8767 +	box-shaped node is the ones that Mercurial commits
  5.8768 +	automatically), but the revision graph now looks different.
  5.8769 +	Before Mercurial begins the backout process, it first
  5.8770 +	remembers what the current parent of the working directory is.
  5.8771 +	It then backs out the target changeset, and commits that as a
  5.8772 +	changeset.  Finally, it merges back to the previous parent of
  5.8773 +	the working directory, but notice that it <emphasis>does not
  5.8774 +	  commit</emphasis> the result of the merge.  The repository
  5.8775 +	now contains two heads, and the working directory is in a
  5.8776 +	merge state.</para>
  5.8777 +
  5.8778 +      <figure id="fig:undo:backout-non-tip" float="0">
  5.8779 +	<title>Automated backout of a non-tip change using the
  5.8780 +	  <command role="hg-cmd" moreinfo="none">hg backout</command> command</title>
  5.8781 +	<mediaobject>
  5.8782 +	  <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject>
  5.8783 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.8784 +	</mediaobject>
  5.8785 +      </figure>
  5.8786 +
  5.8787 +      <para id="x_103">The result is that you end up <quote>back where you
  5.8788 +	  were</quote>, only with some extra history that undoes the
  5.8789 +	effect of the changeset you wanted to back out.</para>
  5.8790 +
  5.8791 +      <para id="x_6b9">You might wonder why Mercurial does not commit the result
  5.8792 +	of the merge that it performed.  The reason lies in Mercurial
  5.8793 +	behaving conservatively: a merge naturally has more scope for
  5.8794 +	error than simply undoing the effect of the tip changeset,
  5.8795 +	so your work will be safest if you first inspect (and test!)
  5.8796 +	the result of the merge, <emphasis>then</emphasis> commit
  5.8797 +	it.</para>
  5.8798 +
  5.8799 +      <sect3>
  5.8800 +	<title>Always use the <option role="hg-opt-backout">--merge</option> option</title>
  5.8801 +
  5.8802 +	<para id="x_104">In fact, since the <option role="hg-opt-backout">--merge</option> option will do the
  5.8803 +	  <quote>right thing</quote> whether or not the changeset
  5.8804 +	  you're backing out is the tip (i.e. it won't try to merge if
  5.8805 +	  it's backing out the tip, since there's no need), you should
  5.8806 +	  <emphasis>always</emphasis> use this option when you run the
  5.8807 +	  <command role="hg-cmd" moreinfo="none">hg backout</command> command.</para>
  5.8808 +
  5.8809 +      </sect3>
  5.8810 +    </sect2>
  5.8811 +    <sect2>
  5.8812 +      <title>Gaining more control of the backout process</title>
  5.8813 +
  5.8814 +      <para id="x_105">While I've recommended that you always use the <option role="hg-opt-backout">--merge</option> option when backing
  5.8815 +	out a change, the <command role="hg-cmd" moreinfo="none">hg backout</command>
  5.8816 +	command lets you decide how to merge a backout changeset.
  5.8817 +	Taking control of the backout process by hand is something you
  5.8818 +	will rarely need to do, but it can be useful to understand
  5.8819 +	what the <command role="hg-cmd" moreinfo="none">hg backout</command> command
  5.8820 +	is doing for you automatically.  To illustrate this, let's
  5.8821 +	clone our first repository, but omit the backout change that
  5.8822 +	it contains.</para>
  5.8823 +
  5.8824 +      <!-- BEGIN backout.manual.clone -->
  5.8825 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  5.8826 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -r1 myrepo newrepo</userinput>
  5.8827 +requesting all changes
  5.8828 +adding changesets
  5.8829 +adding manifests
  5.8830 +adding file changes
  5.8831 +added 2 changesets with 2 changes to 1 files
  5.8832 +updating working directory
  5.8833 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.8834 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd newrepo</userinput>
  5.8835 +</screen>
  5.8836 +<!-- END backout.manual.clone -->
  5.8837 +
  5.8838 +
  5.8839 +      <para id="x_106">As with our
  5.8840 +	earlier example, We'll commit a third changeset, then back out
  5.8841 +	its parent, and see what happens.</para>
  5.8842 +
  5.8843 +      <!-- BEGIN backout.manual.backout -->
  5.8844 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo third change &gt;&gt; myfile</userinput>
  5.8845 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'third change'</userinput>
  5.8846 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg backout -m 'back out second change' 1</userinput>
  5.8847 +reverting myfile
  5.8848 +created new head
  5.8849 +changeset 3:bf906ee0baae backs out changeset 1:43700a9b3ec8
  5.8850 +the backout changeset is a new head - do not forget to merge
  5.8851 +(use "backout --merge" if you want to auto-merge)
  5.8852 +</screen>
  5.8853 +<!-- END backout.manual.backout -->
  5.8854 +
  5.8855 +
  5.8856 +      <para id="x_107">Our new changeset is again a descendant of the changeset
  5.8857 +	we backout out; it's thus a new head, <emphasis>not</emphasis>
  5.8858 +	a descendant of the changeset that was the tip.  The <command role="hg-cmd" moreinfo="none">hg backout</command> command was quite
  5.8859 +	explicit in telling us this.</para>
  5.8860 +
  5.8861 +      <!-- BEGIN backout.manual.log -->
  5.8862 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style compact</userinput>
  5.8863 +3[tip]:1   bf906ee0baae   2009-08-16 14:04 +0000   bos
  5.8864 +  back out second change
  5.8865 +
  5.8866 +2   2521379001ad   2009-08-16 14:04 +0000   bos
  5.8867 +  third change
  5.8868 +
  5.8869 +1   43700a9b3ec8   2009-08-16 14:04 +0000   bos
  5.8870 +  second change
  5.8871 +
  5.8872 +0   f2ef23d503fd   2009-08-16 14:04 +0000   bos
  5.8873 +  first change
  5.8874 +
  5.8875 +</screen>
  5.8876 +<!-- END backout.manual.log -->
  5.8877 +
  5.8878 +
  5.8879 +      <para id="x_108">Again, it's easier to see what has happened by looking at
  5.8880 +	a graph of the revision history, in <xref linkend="fig:undo:backout-manual"/>.  This makes it clear
  5.8881 +	that when we use <command role="hg-cmd" moreinfo="none">hg backout</command>
  5.8882 +	to back out a change other than the tip, Mercurial adds a new
  5.8883 +	head to the repository (the change it committed is
  5.8884 +	box-shaped).</para>
  5.8885 +
  5.8886 +      <figure id="fig:undo:backout-manual" float="0">
  5.8887 +	<title>Backing out a change using the <command role="hg-cmd" moreinfo="none">hg backout</command> command</title>
  5.8888 +	<mediaobject>
  5.8889 +	  <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject>
  5.8890 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.8891 +	</mediaobject>
  5.8892 +      </figure>
  5.8893 +
  5.8894 +      <para id="x_10a">After the <command role="hg-cmd" moreinfo="none">hg backout</command>
  5.8895 +	command has completed, it leaves the new
  5.8896 +	<quote>backout</quote> changeset as the parent of the working
  5.8897 +	directory.</para>
  5.8898 +
  5.8899 +      <!-- BEGIN backout.manual.parents -->
  5.8900 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  5.8901 +changeset:   2:2521379001ad
  5.8902 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8903 +date:        Sun Aug 16 14:04:37 2009 +0000
  5.8904 +summary:     third change
  5.8905 +
  5.8906 +</screen>
  5.8907 +<!-- END backout.manual.parents -->
  5.8908 +
  5.8909 +
  5.8910 +      <para id="x_10b">Now we have two isolated sets of changes.</para>
  5.8911 +
  5.8912 +      <!-- BEGIN backout.manual.heads -->
  5.8913 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  5.8914 +changeset:   3:bf906ee0baae
  5.8915 +tag:         tip
  5.8916 +parent:      1:43700a9b3ec8
  5.8917 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8918 +date:        Sun Aug 16 14:04:37 2009 +0000
  5.8919 +summary:     back out second change
  5.8920 +
  5.8921 +changeset:   2:2521379001ad
  5.8922 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.8923 +date:        Sun Aug 16 14:04:37 2009 +0000
  5.8924 +summary:     third change
  5.8925 +
  5.8926 +</screen>
  5.8927 +<!-- END backout.manual.heads -->
  5.8928 +
  5.8929 +
  5.8930 +      <para id="x_10c">Let's think about what we expect to see as the contents of
  5.8931 +	<filename moreinfo="none">myfile</filename> now.  The first change should be
  5.8932 +	present, because we've never backed it out.  The second change
  5.8933 +	should be missing, as that's the change we backed out.  Since
  5.8934 +	the history graph shows the third change as a separate head,
  5.8935 +	we <emphasis>don't</emphasis> expect to see the third change
  5.8936 +	present in <filename moreinfo="none">myfile</filename>.</para>
  5.8937 +
  5.8938 +      <!-- BEGIN backout.manual.cat -->
  5.8939 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.8940 +first change
  5.8941 +</screen>
  5.8942 +<!-- END backout.manual.cat -->
  5.8943 +
  5.8944 +
  5.8945 +      <para id="x_10d">To get the third change back into the file, we just do a
  5.8946 +	normal merge of our two heads.</para>
  5.8947 +
  5.8948 +      <!-- BEGIN backout.manual.merge -->
  5.8949 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  5.8950 +abort: outstanding uncommitted changes
  5.8951 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'merged backout with previous tip'</userinput>
  5.8952 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  5.8953 +first change
  5.8954 +</screen>
  5.8955 +<!-- END backout.manual.merge -->
  5.8956 +
  5.8957 +
  5.8958 +      <para id="x_10e">Afterwards, the graphical history of our
  5.8959 +	repository looks like
  5.8960 +	<xref linkend="fig:undo:backout-manual-merge"/>.</para>
  5.8961 +
  5.8962 +      <figure id="fig:undo:backout-manual-merge" float="0">
  5.8963 +	<title>Manually merging a backout change</title>
  5.8964 +	<mediaobject>
  5.8965 +	  <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject>
  5.8966 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.8967 +	</mediaobject>
  5.8968 +      </figure>
  5.8969 +
  5.8970 +    </sect2>
  5.8971 +    <sect2>
  5.8972 +      <title>Why <command role="hg-cmd" moreinfo="none">hg backout</command> works as
  5.8973 +	it does</title>
  5.8974 +
  5.8975 +      <para id="x_110">Here's a brief description of how the <command role="hg-cmd" moreinfo="none">hg backout</command> command works.</para>
  5.8976 +      <orderedlist inheritnum="ignore" continuation="restarts">
  5.8977 +	<listitem><para id="x_111">It ensures that the working directory is
  5.8978 +	    <quote>clean</quote>, i.e. that the output of <command role="hg-cmd" moreinfo="none">hg status</command> would be empty.</para>
  5.8979 +	</listitem>
  5.8980 +	<listitem><para id="x_112">It remembers the current parent of the working
  5.8981 +	    directory.  Let's call this changeset
  5.8982 +	    <literal moreinfo="none">orig</literal>.</para>
  5.8983 +	</listitem>
  5.8984 +	<listitem><para id="x_113">It does the equivalent of a <command role="hg-cmd" moreinfo="none">hg update</command> to sync the working
  5.8985 +	    directory to the changeset you want to back out.  Let's
  5.8986 +	    call this changeset <literal moreinfo="none">backout</literal>.</para>
  5.8987 +	</listitem>
  5.8988 +	<listitem><para id="x_114">It finds the parent of that changeset.  Let's
  5.8989 +	    call that changeset <literal moreinfo="none">parent</literal>.</para>
  5.8990 +	</listitem>
  5.8991 +	<listitem><para id="x_115">For each file that the
  5.8992 +	    <literal moreinfo="none">backout</literal> changeset affected, it does the
  5.8993 +	    equivalent of a <command role="hg-cmd" moreinfo="none">hg revert -r
  5.8994 +	      parent</command> on that file, to restore it to the
  5.8995 +	    contents it had before that changeset was
  5.8996 +	    committed.</para>
  5.8997 +	</listitem>
  5.8998 +	<listitem><para id="x_116">It commits the result as a new changeset.
  5.8999 +	    This changeset has <literal moreinfo="none">backout</literal> as its
  5.9000 +	    parent.</para>
  5.9001 +	</listitem>
  5.9002 +	<listitem><para id="x_117">If you specify <option role="hg-opt-backout">--merge</option> on the command
  5.9003 +	    line, it merges with <literal moreinfo="none">orig</literal>, and commits
  5.9004 +	    the result of the merge.</para>
  5.9005 +	</listitem></orderedlist>
  5.9006 +
  5.9007 +      <para id="x_118">An alternative way to implement the <command role="hg-cmd" moreinfo="none">hg backout</command> command would be to
  5.9008 +	<command role="hg-cmd" moreinfo="none">hg export</command> the
  5.9009 +	to-be-backed-out changeset as a diff, then use the <option role="cmd-opt-patch">--reverse</option> option to the
  5.9010 +	<command moreinfo="none">patch</command> command to reverse the effect of the
  5.9011 +	change without fiddling with the working directory.  This
  5.9012 +	sounds much simpler, but it would not work nearly as
  5.9013 +	well.</para>
  5.9014 +
  5.9015 +      <para id="x_119">The reason that <command role="hg-cmd" moreinfo="none">hg
  5.9016 +	  backout</command> does an update, a commit, a merge, and
  5.9017 +	another commit is to give the merge machinery the best chance
  5.9018 +	to do a good job when dealing with all the changes
  5.9019 +	<emphasis>between</emphasis> the change you're backing out and
  5.9020 +	the current tip.</para>
  5.9021 +
  5.9022 +      <para id="x_11a">If you're backing out a changeset that's 100 revisions
  5.9023 +	back in your project's history, the chances that the
  5.9024 +	<command moreinfo="none">patch</command> command will be able to apply a
  5.9025 +	reverse diff cleanly are not good, because intervening changes
  5.9026 +	are likely to have <quote>broken the context</quote> that
  5.9027 +	<command moreinfo="none">patch</command> uses to determine whether it can
  5.9028 +	apply a patch (if this sounds like gibberish, see <xref linkend="sec:mq:patch"/> for a
  5.9029 +	discussion of the <command moreinfo="none">patch</command> command).  Also,
  5.9030 +	Mercurial's merge machinery will handle files and directories
  5.9031 +	being renamed, permission changes, and modifications to binary
  5.9032 +	files, none of which <command moreinfo="none">patch</command> can deal
  5.9033 +	with.</para>
  5.9034 +
  5.9035 +    </sect2>
  5.9036 +  </sect1>
  5.9037 +  <sect1 id="sec:undo:aaaiiieee">
  5.9038 +    <title>Changes that should never have been</title>
  5.9039 +
  5.9040 +    <para id="x_11b">Most of the time, the <command role="hg-cmd" moreinfo="none">hg
  5.9041 +	backout</command> command is exactly what you need if you want
  5.9042 +      to undo the effects of a change.  It leaves a permanent record
  5.9043 +      of exactly what you did, both when committing the original
  5.9044 +      changeset and when you cleaned up after it.</para>
  5.9045 +
  5.9046 +    <para id="x_11c">On rare occasions, though, you may find that you've
  5.9047 +      committed a change that really should not be present in the
  5.9048 +      repository at all.  For example, it would be very unusual, and
  5.9049 +      usually considered a mistake, to commit a software project's
  5.9050 +      object files as well as its source files.  Object files have
  5.9051 +      almost no intrinsic value, and they're <emphasis>big</emphasis>,
  5.9052 +      so they increase the size of the repository and the amount of
  5.9053 +      time it takes to clone or pull changes.</para>
  5.9054 +
  5.9055 +    <para id="x_11d">Before I discuss the options that you have if you commit a
  5.9056 +      <quote>brown paper bag</quote> change (the kind that's so bad
  5.9057 +      that you want to pull a brown paper bag over your head), let me
  5.9058 +      first discuss some approaches that probably won't work.</para>
  5.9059 +
  5.9060 +    <para id="x_11e">Since Mercurial treats history as
  5.9061 +      accumulative—every change builds on top of all changes
  5.9062 +      that preceded it—you generally can't just make disastrous
  5.9063 +      changes disappear.  The one exception is when you've just
  5.9064 +      committed a change, and it hasn't been pushed or pulled into
  5.9065 +      another repository.  That's when you can safely use the <command role="hg-cmd" moreinfo="none">hg rollback</command> command, as I detailed in
  5.9066 +      <xref linkend="sec:undo:rollback"/>.</para>
  5.9067 +
  5.9068 +    <para id="x_11f">After you've pushed a bad change to another repository, you
  5.9069 +      <emphasis>could</emphasis> still use <command role="hg-cmd" moreinfo="none">hg
  5.9070 +	rollback</command> to make your local copy of the change
  5.9071 +      disappear, but it won't have the consequences you want.  The
  5.9072 +      change will still be present in the remote repository, so it
  5.9073 +      will reappear in your local repository the next time you
  5.9074 +      pull.</para>
  5.9075 +
  5.9076 +    <para id="x_120">If a situation like this arises, and you know which
  5.9077 +      repositories your bad change has propagated into, you can
  5.9078 +      <emphasis>try</emphasis> to get rid of the change from
  5.9079 +      <emphasis>every</emphasis> one of those repositories.  This is,
  5.9080 +      of course, not a satisfactory solution: if you miss even a
  5.9081 +      single repository while you're expunging, the change is still
  5.9082 +      <quote>in the wild</quote>, and could propagate further.</para>
  5.9083 +
  5.9084 +    <para id="x_121">If you've committed one or more changes
  5.9085 +      <emphasis>after</emphasis> the change that you'd like to see
  5.9086 +      disappear, your options are further reduced. Mercurial doesn't
  5.9087 +      provide a way to <quote>punch a hole</quote> in history, leaving
  5.9088 +      changesets intact.</para>
  5.9089 +
  5.9090 +    <sect2>
  5.9091 +      <title>Backing out a merge</title>
  5.9092 +
  5.9093 +      <para id="x_6ba">Since merges are often complicated, it is not unheard of
  5.9094 +	for a merge to be mangled badly, but committed erroneously.
  5.9095 +	Mercurial provides an important safeguard against bad merges
  5.9096 +	by refusing to commit unresolved files, but human ingenuity
  5.9097 +	guarantees that it is still possible to mess a merge up and
  5.9098 +	commit it.</para>
  5.9099 +
  5.9100 +      <para id="x_6bb">Given a bad merge that has been committed, usually the
  5.9101 +	best way to approach it is to simply try to repair the damage
  5.9102 +	by hand.  A complete disaster that cannot be easily fixed up
  5.9103 +	by hand ought to be very rare, but the <command role="hg-cmd" moreinfo="none">hg backout</command> command may help in
  5.9104 +	making the cleanup easier. It offers a <option role="hg-opt-backout">--parent</option> option, which lets
  5.9105 +	you specify which parent to revert to when backing out a
  5.9106 +	merge.</para>
  5.9107 +
  5.9108 +      <figure id="fig:undo:bad-merge-1" float="0">
  5.9109 +	<title>A bad merge</title>
  5.9110 +	<mediaobject>
  5.9111 +	  <imageobject><imagedata fileref="figs/bad-merge-1.png"/></imageobject>
  5.9112 +	  <textobject><phrase>XXX add text</phrase></textobject>
  5.9113 +	</mediaobject>
  5.9114 +      </figure>
  5.9115 +
  5.9116 +      <para id="x_6bc">Suppose we have a revision graph like that in <xref linkend="fig:undo:bad-merge-1"/>.  What we'd like is to
  5.9117 +	<emphasis>redo</emphasis> the merge of revisions 2 and
  5.9118 +	3.</para>
  5.9119 +
  5.9120 +      <para id="x_6bd">One way to do so would be as follows.</para>
  5.9121 +
  5.9122 +      <orderedlist inheritnum="ignore" continuation="restarts">
  5.9123 +	<listitem>
  5.9124 +	  <para id="x_6be">Call <command role="hg-cmd" moreinfo="none">hg backout --rev=4
  5.9125 +	      --parent=2</command>.  This tells <command role="hg-cmd" moreinfo="none">hg backout</command> to back out revision
  5.9126 +	    4, which is the bad merge, and to when deciding which
  5.9127 +	    revision to prefer, to choose parent 2, one of the parents
  5.9128 +	    of the merge.  The effect can be seen in <xref linkend="fig:undo:bad-merge-2"/>.</para>
  5.9129 +	  <figure id="fig:undo:bad-merge-2" float="0">
  5.9130 +	    <title>Backing out the merge, favoring one parent</title>
  5.9131 +	    <mediaobject>
  5.9132 +	      <imageobject><imagedata fileref="figs/bad-merge-2.png"/></imageobject>
  5.9133 +	      <textobject><phrase>XXX add text</phrase></textobject>
  5.9134 +	    </mediaobject>
  5.9135 +	  </figure>
  5.9136 +	</listitem>
  5.9137 +
  5.9138 +	<listitem>
  5.9139 +	  <para id="x_6bf">Call <command role="hg-cmd" moreinfo="none">hg backout --rev=4
  5.9140 +	      --parent=3</command>.  This tells <command role="hg-cmd" moreinfo="none">hg backout</command> to back out revision
  5.9141 +	    4 again, but this time to choose parent 3, the other
  5.9142 +	    parent of the merge.  The result is visible in <xref linkend="fig:undo:bad-merge-3"/>, in which the repository
  5.9143 +	    now contains three heads.</para>
  5.9144 +	  <figure id="fig:undo:bad-merge-3" float="0">
  5.9145 +	    <title>Backing out the merge, favoring the other
  5.9146 +	      parent</title>
  5.9147 +	    <mediaobject>
  5.9148 +	      <imageobject><imagedata fileref="figs/bad-merge-3.png"/></imageobject>
  5.9149 +	      <textobject><phrase>XXX add text</phrase></textobject>
  5.9150 +	    </mediaobject>
  5.9151 +	  </figure>
  5.9152 +	</listitem>
  5.9153 +
  5.9154 +	<listitem>
  5.9155 +	  <para id="x_6c0">Redo the bad merge by merging the two backout heads,
  5.9156 +	    which reduces the number of heads in the repository to
  5.9157 +	    two, as can be seen in <xref linkend="fig:undo:bad-merge-4"/>.</para>
  5.9158 +	  <figure id="fig:undo:bad-merge-4" float="0">
  5.9159 +	    <title>Merging the backouts</title>
  5.9160 +	    <mediaobject>
  5.9161 +	      <imageobject><imagedata fileref="figs/bad-merge-4.png"/></imageobject>
  5.9162 +	      <textobject><phrase>XXX add text</phrase></textobject>
  5.9163 +	    </mediaobject>
  5.9164 +	  </figure>
  5.9165 +	</listitem>
  5.9166 +
  5.9167 +	<listitem>
  5.9168 +	  <para id="x_6c1">Merge with the commit that was made after the bad
  5.9169 +	    merge, as shown in <xref linkend="fig:undo:bad-merge-5"/>.</para>
  5.9170 +	  <figure id="fig:undo:bad-merge-5" float="0">
  5.9171 +	    <title>Merging the backouts</title>
  5.9172 +	    <mediaobject>
  5.9173 +	      <imageobject><imagedata fileref="figs/bad-merge-5.png"/></imageobject>
  5.9174 +	      <textobject><phrase>XXX add text</phrase></textobject>
  5.9175 +	    </mediaobject>
  5.9176 +	  </figure>
  5.9177 +	</listitem>
  5.9178 +      </orderedlist>
  5.9179 +    </sect2>
  5.9180 +
  5.9181 +    <sect2>
  5.9182 +      <title>Protect yourself from <quote>escaped</quote>
  5.9183 +	changes</title>
  5.9184 +
  5.9185 +      <para id="x_123">If you've committed some changes to your local repository
  5.9186 +	and they've been pushed or pulled somewhere else, this isn't
  5.9187 +	necessarily a disaster.  You can protect yourself ahead of
  5.9188 +	time against some classes of bad changeset.  This is
  5.9189 +	particularly easy if your team usually pulls changes from a
  5.9190 +	central repository.</para>
  5.9191 +
  5.9192 +      <para id="x_124">By configuring some hooks on that repository to validate
  5.9193 +	incoming changesets (see chapter <xref linkend="chap:hook"/>),
  5.9194 +	you can
  5.9195 +	automatically prevent some kinds of bad changeset from being
  5.9196 +	pushed to the central repository at all.  With such a
  5.9197 +	configuration in place, some kinds of bad changeset will
  5.9198 +	naturally tend to <quote>die out</quote> because they can't
  5.9199 +	propagate into the central repository.  Better yet, this
  5.9200 +	happens without any need for explicit intervention.</para>
  5.9201 +
  5.9202 +      <para id="x_125">For instance, an incoming change hook that
  5.9203 +	verifies that a changeset will actually compile can prevent
  5.9204 +	people from inadvertently <quote>breaking the
  5.9205 +	  build</quote>.</para>
  5.9206 +    </sect2>
  5.9207 +
  5.9208 +    <sect2>
  5.9209 +      <title>What to do about sensitive changes that escape</title>
  5.9210 +
  5.9211 +      <para id="x_6c2">Even a carefully run project can suffer an unfortunate
  5.9212 +	event such as the committing and uncontrolled propagation of a
  5.9213 +	file that contains important passwords.</para>
  5.9214 +
  5.9215 +      <para id="x_6c3">If something like this happens to you, and the information
  5.9216 +	that gets accidentally propagated is truly sensitive, your
  5.9217 +	first step should be to mitigate the effect of the leak
  5.9218 +	without trying to control the leak itself. If you are not 100%
  5.9219 +	certain that you know exactly who could have seen the changes,
  5.9220 +	you should immediately change passwords, cancel credit cards,
  5.9221 +	or find some other way to make sure that the information that
  5.9222 +	has leaked is no longer useful.  In other words, assume that
  5.9223 +	the change has propagated far and wide, and that there's
  5.9224 +	nothing more you can do.</para>
  5.9225 +
  5.9226 +      <para id="x_6c4">You might hope that there would be mechanisms you could
  5.9227 +	use to either figure out who has seen a change or to erase the
  5.9228 +	change permanently everywhere, but there are good reasons why
  5.9229 +	these are not possible.</para>
  5.9230 +
  5.9231 +      <para id="x_6c5">Mercurial does not provide an audit trail of who has
  5.9232 +	pulled changes from a repository, because it is usually either
  5.9233 +	impossible to record such information or trivial to spoof it.
  5.9234 +	In a multi-user or networked environment, you should thus be
  5.9235 +	extremely skeptical of yourself if you think that you have
  5.9236 +	identified every place that a sensitive changeset has
  5.9237 +	propagated to.  Don't forget that people can and will send
  5.9238 +	bundles by email, have their backup software save data
  5.9239 +	offsite, carry repositories on USB sticks, and find other
  5.9240 +	completely innocent ways to confound your attempts to track
  5.9241 +	down every copy of a problematic change.</para>
  5.9242 +
  5.9243 +      <para id="x_6c6">Mercurial also does not provide a way to make a file or
  5.9244 +	changeset completely disappear from history, because there is
  5.9245 +	no way to enforce its disappearance; someone could easily
  5.9246 +	modify their copy of Mercurial to ignore such directives. In
  5.9247 +	addition, even if Mercurial provided such a capability,
  5.9248 +	someone who simply hadn't pulled a <quote>make this file
  5.9249 +	  disappear</quote> changeset wouldn't be affected by it, nor
  5.9250 +	would web crawlers visiting at the wrong time, disk backups,
  5.9251 +	or other mechanisms.  Indeed, no distributed revision control
  5.9252 +	system can make data reliably vanish. Providing the illusion
  5.9253 +	of such control could easily give a false sense of security,
  5.9254 +	and be worse than not providing it at all.</para>
  5.9255 +    </sect2>
  5.9256 +  </sect1>
  5.9257 +
  5.9258 +  <sect1 id="sec:undo:bisect">
  5.9259 +    <title>Finding the source of a bug</title>
  5.9260 +
  5.9261 +    <para id="x_126">While it's all very well to be able to back out a changeset
  5.9262 +      that introduced a bug, this requires that you know which
  5.9263 +      changeset to back out.  Mercurial provides an invaluable
  5.9264 +      command, called <command role="hg-cmd" moreinfo="none">hg bisect</command>, that
  5.9265 +      helps you to automate this process and accomplish it very
  5.9266 +      efficiently.</para>
  5.9267 +
  5.9268 +    <para id="x_127">The idea behind the <command role="hg-cmd" moreinfo="none">hg
  5.9269 +	bisect</command> command is that a changeset has introduced
  5.9270 +      some change of behavior that you can identify with a simple
  5.9271 +      pass/fail test.  You don't know which piece of code introduced the
  5.9272 +      change, but you know how to test for the presence of the bug.
  5.9273 +      The <command role="hg-cmd" moreinfo="none">hg bisect</command> command uses your
  5.9274 +      test to direct its search for the changeset that introduced the
  5.9275 +      code that caused the bug.</para>
  5.9276 +
  5.9277 +    <para id="x_128">Here are a few scenarios to help you understand how you
  5.9278 +      might apply this command.</para>
  5.9279 +    <itemizedlist>
  5.9280 +      <listitem><para id="x_129">The most recent version of your software has a
  5.9281 +	  bug that you remember wasn't present a few weeks ago, but
  5.9282 +	  you don't know when it was introduced.  Here, your binary
  5.9283 +	  test checks for the presence of that bug.</para>
  5.9284 +      </listitem>
  5.9285 +      <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to
  5.9286 +	  close the entry in your team's bug database.  The bug
  5.9287 +	  database requires a changeset ID when you close an entry,
  5.9288 +	  but you don't remember which changeset you fixed the bug in.
  5.9289 +	  Once again, your binary test checks for the presence of the
  5.9290 +	  bug.</para>
  5.9291 +      </listitem>
  5.9292 +      <listitem><para id="x_12b">Your software works correctly, but runs 15%
  5.9293 +	  slower than the last time you measured it.  You want to know
  5.9294 +	  which changeset introduced the performance regression.  In
  5.9295 +	  this case, your binary test measures the performance of your
  5.9296 +	  software, to see whether it's <quote>fast</quote> or
  5.9297 +	  <quote>slow</quote>.</para>
  5.9298 +      </listitem>
  5.9299 +      <listitem><para id="x_12c">The sizes of the components of your project that
  5.9300 +	  you ship exploded recently, and you suspect that something
  5.9301 +	  changed in the way you build your project.</para>
  5.9302 +      </listitem></itemizedlist>
  5.9303 +
  5.9304 +    <para id="x_12d">From these examples, it should be clear that the <command role="hg-cmd" moreinfo="none">hg bisect</command> command is not useful only
  5.9305 +      for finding the sources of bugs.  You can use it to find any
  5.9306 +      <quote>emergent property</quote> of a repository (anything that
  5.9307 +      you can't find from a simple text search of the files in the
  5.9308 +      tree) for which you can write a binary test.</para>
  5.9309 +
  5.9310 +    <para id="x_12e">We'll introduce a little bit of terminology here, just to
  5.9311 +      make it clear which parts of the search process are your
  5.9312 +      responsibility, and which are Mercurial's.  A
  5.9313 +      <emphasis>test</emphasis> is something that
  5.9314 +      <emphasis>you</emphasis> run when <command role="hg-cmd" moreinfo="none">hg
  5.9315 +	bisect</command> chooses a changeset.  A
  5.9316 +      <emphasis>probe</emphasis> is what <command role="hg-cmd" moreinfo="none">hg
  5.9317 +	bisect</command> runs to tell whether a revision is good.
  5.9318 +      Finally, we'll use the word <quote>bisect</quote>, as both a
  5.9319 +      noun and a verb, to stand in for the phrase <quote>search using
  5.9320 +	the <command role="hg-cmd" moreinfo="none">hg bisect</command>
  5.9321 +	command</quote>.</para>
  5.9322 +
  5.9323 +    <para id="x_12f">One simple way to automate the searching process would be
  5.9324 +      simply to probe every changeset.  However, this scales poorly.
  5.9325 +      If it took ten minutes to test a single changeset, and you had
  5.9326 +      10,000 changesets in your repository, the exhaustive approach
  5.9327 +      would take on average 35 <emphasis>days</emphasis> to find the
  5.9328 +      changeset that introduced a bug.  Even if you knew that the bug
  5.9329 +      was introduced by one of the last 500 changesets, and limited
  5.9330 +      your search to those, you'd still be looking at over 40 hours to
  5.9331 +      find the changeset that introduced your bug.</para>
  5.9332 +
  5.9333 +    <para id="x_130">What the <command role="hg-cmd" moreinfo="none">hg bisect</command> command
  5.9334 +      does is use its knowledge of the <quote>shape</quote> of your
  5.9335 +      project's revision history to perform a search in time
  5.9336 +      proportional to the <emphasis>logarithm</emphasis> of the number
  5.9337 +      of changesets to check (the kind of search it performs is called
  5.9338 +      a dichotomic search).  With this approach, searching through
  5.9339 +      10,000 changesets will take less than three hours, even at ten
  5.9340 +      minutes per test (the search will require about 14 tests).
  5.9341 +      Limit your search to the last hundred changesets, and it will
  5.9342 +      take only about an hour (roughly seven tests).</para>
  5.9343 +
  5.9344 +    <para id="x_131">The <command role="hg-cmd" moreinfo="none">hg bisect</command> command is
  5.9345 +      aware of the <quote>branchy</quote> nature of a Mercurial
  5.9346 +      project's revision history, so it has no problems dealing with
  5.9347 +      branches, merges, or multiple heads in a repository.  It can
  5.9348 +      prune entire branches of history with a single probe, which is
  5.9349 +      how it operates so efficiently.</para>
  5.9350 +
  5.9351 +    <sect2>
  5.9352 +      <title>Using the <command role="hg-cmd" moreinfo="none">hg bisect</command>
  5.9353 +	command</title>
  5.9354 +
  5.9355 +      <para id="x_132">Here's an example of <command role="hg-cmd" moreinfo="none">hg
  5.9356 +	  bisect</command> in action.</para>
  5.9357 +
  5.9358 +      <note>
  5.9359 +	<para id="x_133">  In versions 0.9.5 and earlier of Mercurial, <command role="hg-cmd" moreinfo="none">hg bisect</command> was not a core command:
  5.9360 +	  it was distributed with Mercurial as an extension. This
  5.9361 +	  section describes the built-in command, not the old
  5.9362 +	  extension.</para>
  5.9363 +      </note>
  5.9364 +
  5.9365 +      <para id="x_134">Now let's create a repository, so that we can try out the
  5.9366 +	<command role="hg-cmd" moreinfo="none">hg bisect</command> command in
  5.9367 +	isolation.</para>
  5.9368 +
  5.9369 +      <!-- BEGIN bisect.init -->
  5.9370 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init mybug</userinput>
  5.9371 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd mybug</userinput>
  5.9372 +</screen>
  5.9373 +<!-- END bisect.init -->
  5.9374 +
  5.9375 +
  5.9376 +      <para id="x_135">We'll simulate a project that has a bug in it in a
  5.9377 +	simple-minded way: create trivial changes in a loop, and
  5.9378 +	nominate one specific change that will have the
  5.9379 +	<quote>bug</quote>.  This loop creates 35 changesets, each
  5.9380 +	adding a single file to the repository. We'll represent our
  5.9381 +	<quote>bug</quote> with a file that contains the text <quote>i
  5.9382 +	  have a gub</quote>.</para>
  5.9383 +
  5.9384 +      <!-- BEGIN bisect.commits -->
  5.9385 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">buggy_change=22</userinput>
  5.9386 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">for (( i = 0; i &lt; 35; i++ )); do</userinput>
  5.9387 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  if [[ $i = $buggy_change ]]; then</userinput>
  5.9388 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    echo 'i have a gub' &gt; myfile$i</userinput>
  5.9389 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    hg commit -q -A -m 'buggy changeset'</userinput>
  5.9390 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  else</userinput>
  5.9391 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    echo 'nothing to see here, move along' &gt; myfile$i</userinput>
  5.9392 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    hg commit -q -A -m 'normal changeset'</userinput>
  5.9393 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  fi</userinput>
  5.9394 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">done</userinput>
  5.9395 +</screen>
  5.9396 +<!-- END bisect.commits -->
  5.9397 +
  5.9398 +
  5.9399 +      <para id="x_136">The next thing that we'd like to do is figure out how to
  5.9400 +	use the <command role="hg-cmd" moreinfo="none">hg bisect</command> command.
  5.9401 +	We can use Mercurial's normal built-in help mechanism for
  5.9402 +	this.</para>
  5.9403 +
  5.9404 +      <!-- BEGIN bisect.help -->
  5.9405 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg help bisect</userinput>
  5.9406 +hg bisect [-gbsr] [-c CMD] [REV]
  5.9407 +
  5.9408 +subdivision search of changesets
  5.9409 +
  5.9410 +    This command helps to find changesets which introduce problems.
  5.9411 +    To use, mark the earliest changeset you know exhibits the problem
  5.9412 +    as bad, then mark the latest changeset which is free from the
  5.9413 +    problem as good. Bisect will update your working directory to a
  5.9414 +    revision for testing (unless the --noupdate option is specified).
  5.9415 +    Once you have performed tests, mark the working directory as bad
  5.9416 +    or good and bisect will either update to another candidate changeset
  5.9417 +    or announce that it has found the bad revision.
  5.9418 +
  5.9419 +    As a shortcut, you can also use the revision argument to mark a
  5.9420 +    revision as good or bad without checking it out first.
  5.9421 +
  5.9422 +    If you supply a command it will be used for automatic bisection. Its exit
  5.9423 +    status will be used as flag to mark revision as bad or good. In case exit
  5.9424 +    status is 0 the revision is marked as good, 125 - skipped, 127 (command not
  5.9425 +    found) - bisection will be aborted; any other status bigger than 0 will
  5.9426 +    mark revision as bad.
  5.9427 +
  5.9428 +options:
  5.9429 +
  5.9430 + -r --reset     reset bisect state
  5.9431 + -g --good      mark changeset good
  5.9432 + -b --bad       mark changeset bad
  5.9433 + -s --skip      skip testing changeset
  5.9434 + -c --command   use command to check changeset state
  5.9435 + -U --noupdate  do not update to target
  5.9436 +
  5.9437 +use "hg -v help bisect" to show global options
  5.9438 +</screen>
  5.9439 +<!-- END bisect.help -->
  5.9440 +
  5.9441 +
  5.9442 +      <para id="x_137">The <command role="hg-cmd" moreinfo="none">hg bisect</command> command
  5.9443 +	works in steps.  Each step proceeds as follows.</para>
  5.9444 +      <orderedlist inheritnum="ignore" continuation="restarts">
  5.9445 +	<listitem><para id="x_138">You run your binary test.</para>
  5.9446 +	  <itemizedlist>
  5.9447 +	    <listitem><para id="x_139">If the test succeeded, you tell <command role="hg-cmd" moreinfo="none">hg bisect</command> by running the
  5.9448 +		<command role="hg-cmd" moreinfo="none">hg bisect --good</command>
  5.9449 +		command.</para>
  5.9450 +	    </listitem>
  5.9451 +	    <listitem><para id="x_13a">If it failed, run the <command role="hg-cmd" moreinfo="none">hg bisect --bad</command>
  5.9452 +		command.</para></listitem></itemizedlist>
  5.9453 +	</listitem>
  5.9454 +	<listitem><para id="x_13b">The command uses your information to decide
  5.9455 +	    which changeset to test next.</para>
  5.9456 +	</listitem>
  5.9457 +	<listitem><para id="x_13c">It updates the working directory to that
  5.9458 +	    changeset, and the process begins again.</para>
  5.9459 +	</listitem></orderedlist>
  5.9460 +      <para id="x_13d">The process ends when <command role="hg-cmd" moreinfo="none">hg
  5.9461 +	  bisect</command> identifies a unique changeset that marks
  5.9462 +	the point where your test transitioned from
  5.9463 +	<quote>succeeding</quote> to <quote>failing</quote>.</para>
  5.9464 +
  5.9465 +      <para id="x_13e">To start the search, we must run the <command role="hg-cmd" moreinfo="none">hg bisect --reset</command> command.</para>
  5.9466 +
  5.9467 +      <!-- BEGIN bisect.search.init -->
  5.9468 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --reset</userinput>
  5.9469 +</screen>
  5.9470 +<!-- END bisect.search.init -->
  5.9471 +
  5.9472 +
  5.9473 +      <para id="x_13f">In our case, the binary test we use is simple: we check to
  5.9474 +	see if any file in the repository contains the string <quote>i
  5.9475 +	  have a gub</quote>.  If it does, this changeset contains the
  5.9476 +	change that <quote>caused the bug</quote>.  By convention, a
  5.9477 +	changeset that has the property we're searching for is
  5.9478 +	<quote>bad</quote>, while one that doesn't is
  5.9479 +	<quote>good</quote>.</para>
  5.9480 +
  5.9481 +      <para id="x_140">Most of the time, the revision to which the working
  5.9482 +	directory is synced (usually the tip) already exhibits the
  5.9483 +	problem introduced by the buggy change, so we'll mark it as
  5.9484 +	<quote>bad</quote>.</para>
  5.9485 +
  5.9486 +      <!-- BEGIN bisect.search.bad-init -->
  5.9487 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --bad</userinput>
  5.9488 +</screen>
  5.9489 +<!-- END bisect.search.bad-init -->
  5.9490 +
  5.9491 +
  5.9492 +      <para id="x_141">Our next task is to nominate a changeset that we know
  5.9493 +	<emphasis>doesn't</emphasis> have the bug; the <command role="hg-cmd" moreinfo="none">hg bisect</command> command will
  5.9494 +	<quote>bracket</quote> its search between the first pair of
  5.9495 +	good and bad changesets.  In our case, we know that revision
  5.9496 +	10 didn't have the bug.  (I'll have more words about choosing
  5.9497 +	the first <quote>good</quote> changeset later.)</para>
  5.9498 +
  5.9499 +      <!-- BEGIN bisect.search.good-init -->
  5.9500 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --good 10</userinput>
  5.9501 +Testing changeset 22:69f52b967ab8 (24 changesets remaining, ~4 tests)
  5.9502 +0 files updated, 0 files merged, 12 files removed, 0 files unresolved
  5.9503 +</screen>
  5.9504 +<!-- END bisect.search.good-init -->
  5.9505 +
  5.9506 +
  5.9507 +      <para id="x_142">Notice that this command printed some output.</para>
  5.9508 +      <itemizedlist>
  5.9509 +	<listitem><para id="x_143">It told us how many changesets it must
  5.9510 +	    consider before it can identify the one that introduced
  5.9511 +	    the bug, and how many tests that will require.</para>
  5.9512 +	</listitem>
  5.9513 +	<listitem><para id="x_144">It updated the working directory to the next
  5.9514 +	    changeset to test, and told us which changeset it's
  5.9515 +	    testing.</para>
  5.9516 +	</listitem></itemizedlist>
  5.9517 +
  5.9518 +      <para id="x_145">We now run our test in the working directory.  We use the
  5.9519 +	<command moreinfo="none">grep</command> command to see if our
  5.9520 +	<quote>bad</quote> file is present in the working directory.
  5.9521 +	If it is, this revision is bad; if not, this revision is good.
  5.9522 +	<!-- BEGIN bisect.search.step1 -->
  5.9523 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">if grep -q 'i have a gub' *</userinput>
  5.9524 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">then</userinput>
  5.9525 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  result=bad</userinput>
  5.9526 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">else</userinput>
  5.9527 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  result=good</userinput>
  5.9528 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">fi</userinput>
  5.9529 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo this revision is $result</userinput>
  5.9530 +this revision is bad
  5.9531 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --$result</userinput>
  5.9532 +Testing changeset 16:f1dd8bc690ae (12 changesets remaining, ~3 tests)
  5.9533 +0 files updated, 0 files merged, 6 files removed, 0 files unresolved
  5.9534 +</screen>
  5.9535 +<!-- END bisect.search.step1 -->
  5.9536 +</para>
  5.9537 +
  5.9538 +      <para id="x_146">This test looks like a perfect candidate for automation,
  5.9539 +	so let's turn it into a shell function.</para>
  5.9540 +      <!-- BEGIN bisect.search.mytest -->
  5.9541 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest() {</userinput>
  5.9542 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  if grep -q 'i have a gub' *</userinput>
  5.9543 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  then</userinput>
  5.9544 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    result=bad</userinput>
  5.9545 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  else</userinput>
  5.9546 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    result=good</userinput>
  5.9547 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  fi</userinput>
  5.9548 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  echo this revision is $result</userinput>
  5.9549 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  hg bisect --$result</userinput>
  5.9550 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">}</userinput>
  5.9551 +</screen>
  5.9552 +<!-- END bisect.search.mytest -->
  5.9553 +
  5.9554 +
  5.9555 +      <para id="x_147">We can now run an entire test step with a single command,
  5.9556 +	<literal moreinfo="none">mytest</literal>.</para>
  5.9557 +
  5.9558 +      <!-- BEGIN bisect.search.step2 -->
  5.9559 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  5.9560 +this revision is good
  5.9561 +Testing changeset 19:88d99d97058a (6 changesets remaining, ~2 tests)
  5.9562 +3 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.9563 +</screen>
  5.9564 +<!-- END bisect.search.step2 -->
  5.9565 +
  5.9566 +
  5.9567 +      <para id="x_148">A few more invocations of our canned test step command,
  5.9568 +	and we're done.</para>
  5.9569 +
  5.9570 +      <!-- BEGIN bisect.search.rest -->
  5.9571 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  5.9572 +this revision is good
  5.9573 +Testing changeset 20:32a195a31d51 (3 changesets remaining, ~1 tests)
  5.9574 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.9575 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  5.9576 +this revision is good
  5.9577 +Testing changeset 21:a2efe8e4f624 (2 changesets remaining, ~1 tests)
  5.9578 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  5.9579 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  5.9580 +this revision is good
  5.9581 +The first bad revision is:
  5.9582 +changeset:   22:69f52b967ab8
  5.9583 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  5.9584 +date:        Sun Aug 16 14:04:39 2009 +0000
  5.9585 +summary:     buggy changeset
  5.9586 +
  5.9587 +</screen>
  5.9588 +<!-- END bisect.search.rest -->
  5.9589 +
  5.9590 +
  5.9591 +      <para id="x_149">Even though we had 40 changesets to search through, the
  5.9592 +	<command role="hg-cmd" moreinfo="none">hg bisect</command> command let us find
  5.9593 +	the changeset that introduced our <quote>bug</quote> with only
  5.9594 +	five tests.  Because the number of tests that the <command role="hg-cmd" moreinfo="none">hg bisect</command> command performs grows
  5.9595 +	logarithmically with the number of changesets to search, the
  5.9596 +	advantage that it has over the <quote>brute force</quote>
  5.9597 +	search approach increases with every changeset you add.</para>
  5.9598 +
  5.9599 +    </sect2>
  5.9600 +    <sect2>
  5.9601 +      <title>Cleaning up after your search</title>
  5.9602 +
  5.9603 +      <para id="x_14a">When you're finished using the <command role="hg-cmd" moreinfo="none">hg
  5.9604 +	  bisect</command> command in a repository, you can use the
  5.9605 +	<command role="hg-cmd" moreinfo="none">hg bisect --reset</command> command to
  5.9606 +	drop the information it was using to drive your search.  The
  5.9607 +	command doesn't use much space, so it doesn't matter if you
  5.9608 +	forget to run this command.  However, <command role="hg-cmd" moreinfo="none">hg bisect</command> won't let you start a new
  5.9609 +	search in that repository until you do a <command role="hg-cmd" moreinfo="none">hg bisect --reset</command>.</para>
  5.9610 +
  5.9611 +      <!-- BEGIN bisect.search.reset -->
  5.9612 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --reset</userinput>
  5.9613 +</screen>
  5.9614 +<!-- END bisect.search.reset -->
  5.9615 +
  5.9616 +
  5.9617 +    </sect2>
  5.9618 +  </sect1>
  5.9619 +  <sect1>
  5.9620 +    <title>Tips for finding bugs effectively</title>
  5.9621 +
  5.9622 +    <sect2>
  5.9623 +      <title>Give consistent input</title>
  5.9624 +
  5.9625 +      <para id="x_14b">The <command role="hg-cmd" moreinfo="none">hg bisect</command> command
  5.9626 +	requires that you correctly report the result of every test
  5.9627 +	you perform.  If you tell it that a test failed when it really
  5.9628 +	succeeded, it <emphasis>might</emphasis> be able to detect the
  5.9629 +	inconsistency.  If it can identify an inconsistency in your
  5.9630 +	reports, it will tell you that a particular changeset is both
  5.9631 +	good and bad. However, it can't do this perfectly; it's about
  5.9632 +	as likely to report the wrong changeset as the source of the
  5.9633 +	bug.</para>
  5.9634 +
  5.9635 +    </sect2>
  5.9636 +    <sect2>
  5.9637 +      <title>Automate as much as possible</title>
  5.9638 +
  5.9639 +      <para id="x_14c">When I started using the <command role="hg-cmd" moreinfo="none">hg
  5.9640 +	  bisect</command> command, I tried a few times to run my
  5.9641 +	tests by hand, on the command line.  This is an approach that
  5.9642 +	I, at least, am not suited to.  After a few tries, I found
  5.9643 +	that I was making enough mistakes that I was having to restart
  5.9644 +	my searches several times before finally getting correct
  5.9645 +	results.</para>
  5.9646 +
  5.9647 +      <para id="x_14d">My initial problems with driving the <command role="hg-cmd" moreinfo="none">hg bisect</command> command by hand occurred
  5.9648 +	even with simple searches on small repositories; if the
  5.9649 +	problem you're looking for is more subtle, or the number of
  5.9650 +	tests that <command role="hg-cmd" moreinfo="none">hg bisect</command> must
  5.9651 +	perform increases, the likelihood of operator error ruining
  5.9652 +	the search is much higher.  Once I started automating my
  5.9653 +	tests, I had much better results.</para>
  5.9654 +
  5.9655 +      <para id="x_14e">The key to automated testing is twofold:</para>
  5.9656 +      <itemizedlist>
  5.9657 +	<listitem><para id="x_14f">always test for the same symptom, and</para>
  5.9658 +	</listitem>
  5.9659 +	<listitem><para id="x_150">always feed consistent input to the <command role="hg-cmd" moreinfo="none">hg bisect</command> command.</para>
  5.9660 +	</listitem></itemizedlist>
  5.9661 +      <para id="x_151">In my tutorial example above, the <command moreinfo="none">grep</command>
  5.9662 +	command tests for the symptom, and the <literal moreinfo="none">if</literal>
  5.9663 +	statement takes the result of this check and ensures that we
  5.9664 +	always feed the same input to the <command role="hg-cmd" moreinfo="none">hg
  5.9665 +	  bisect</command> command.  The <literal moreinfo="none">mytest</literal>
  5.9666 +	function marries these together in a reproducible way, so that
  5.9667 +	every test is uniform and consistent.</para>
  5.9668 +
  5.9669 +    </sect2>
  5.9670 +    <sect2>
  5.9671 +      <title>Check your results</title>
  5.9672 +
  5.9673 +      <para id="x_152">Because the output of a <command role="hg-cmd" moreinfo="none">hg
  5.9674 +	  bisect</command> search is only as good as the input you
  5.9675 +	give it, don't take the changeset it reports as the absolute
  5.9676 +	truth.  A simple way to cross-check its report is to manually
  5.9677 +	run your test at each of the following changesets:</para>
  5.9678 +      <itemizedlist>
  5.9679 +	<listitem><para id="x_153">The changeset that it reports as the first bad
  5.9680 +	    revision.  Your test should still report this as
  5.9681 +	    bad.</para>
  5.9682 +	</listitem>
  5.9683 +	<listitem><para id="x_154">The parent of that changeset (either parent,
  5.9684 +	    if it's a merge). Your test should report this changeset
  5.9685 +	    as good.</para>
  5.9686 +	</listitem>
  5.9687 +	<listitem><para id="x_155">A child of that changeset.  Your test should
  5.9688 +	    report this changeset as bad.</para>
  5.9689 +	</listitem></itemizedlist>
  5.9690 +
  5.9691 +    </sect2>
  5.9692 +    <sect2>
  5.9693 +      <title>Beware interference between bugs</title>
  5.9694 +
  5.9695 +      <para id="x_156">It's possible that your search for one bug could be
  5.9696 +	disrupted by the presence of another.  For example, let's say
  5.9697 +	your software crashes at revision 100, and worked correctly at
  5.9698 +	revision 50.  Unknown to you, someone else introduced a
  5.9699 +	different crashing bug at revision 60, and fixed it at
  5.9700 +	revision 80.  This could distort your results in one of
  5.9701 +	several ways.</para>
  5.9702 +
  5.9703 +      <para id="x_157">It is possible that this other bug completely
  5.9704 +	<quote>masks</quote> yours, which is to say that it occurs
  5.9705 +	before your bug has a chance to manifest itself.  If you can't
  5.9706 +	avoid that other bug (for example, it prevents your project
  5.9707 +	from building), and so can't tell whether your bug is present
  5.9708 +	in a particular changeset, the <command role="hg-cmd" moreinfo="none">hg
  5.9709 +	  bisect</command> command cannot help you directly.  Instead,
  5.9710 +	you can mark a changeset as untested by running <command role="hg-cmd" moreinfo="none">hg bisect --skip</command>.</para>
  5.9711 +
  5.9712 +      <para id="x_158">A different problem could arise if your test for a bug's
  5.9713 +	presence is not specific enough.  If you check for <quote>my
  5.9714 +	  program crashes</quote>, then both your crashing bug and an
  5.9715 +	unrelated crashing bug that masks it will look like the same
  5.9716 +	thing, and mislead <command role="hg-cmd" moreinfo="none">hg
  5.9717 +	  bisect</command>.</para>
  5.9718 +
  5.9719 +      <para id="x_159">Another useful situation in which to use <command role="hg-cmd" moreinfo="none">hg bisect --skip</command> is if you can't
  5.9720 +	test a revision because your project was in a broken and hence
  5.9721 +	untestable state at that revision, perhaps because someone
  5.9722 +	checked in a change that prevented the project from
  5.9723 +	building.</para>
  5.9724 +
  5.9725 +    </sect2>
  5.9726 +    <sect2>
  5.9727 +      <title>Bracket your search lazily</title>
  5.9728 +
  5.9729 +      <para id="x_15a">Choosing the first <quote>good</quote> and
  5.9730 +	<quote>bad</quote> changesets that will mark the end points of
  5.9731 +	your search is often easy, but it bears a little discussion
  5.9732 +	nevertheless.  From the perspective of <command role="hg-cmd" moreinfo="none">hg bisect</command>, the <quote>newest</quote>
  5.9733 +	changeset is conventionally <quote>bad</quote>, and the older
  5.9734 +	changeset is <quote>good</quote>.</para>
  5.9735 +
  5.9736 +      <para id="x_15b">If you're having trouble remembering when a suitable
  5.9737 +	<quote>good</quote> change was, so that you can tell <command role="hg-cmd" moreinfo="none">hg bisect</command>, you could do worse than
  5.9738 +	testing changesets at random.  Just remember to eliminate
  5.9739 +	contenders that can't possibly exhibit the bug (perhaps
  5.9740 +	because the feature with the bug isn't present yet) and those
  5.9741 +	where another problem masks the bug (as I discussed
  5.9742 +	above).</para>
  5.9743 +
  5.9744 +      <para id="x_15c">Even if you end up <quote>early</quote> by thousands of
  5.9745 +	changesets or months of history, you will only add a handful
  5.9746 +	of tests to the total number that <command role="hg-cmd" moreinfo="none">hg
  5.9747 +	  bisect</command> must perform, thanks to its logarithmic
  5.9748 +	behavior.</para>
  5.9749 +
  5.9750 +    </sect2>
  5.9751 +  </sect1>
  5.9752 +</chapter>
  5.9753 +
  5.9754 +<!--
  5.9755 +local variables: 
  5.9756 +sgml-parent-document: ("00book.xml" "book" "chapter")
  5.9757 +end:
  5.9758 +-->
  5.9759 +
  5.9760 +  <!-- BEGIN ch10 -->
  5.9761 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  5.9762 +
  5.9763 +<chapter id="chap:hook">
  5.9764 +  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
  5.9765 +  <title>Handling repository events with hooks</title>
  5.9766 +
  5.9767 +  <para id="x_1e6">Mercurial offers a powerful mechanism to let you perform
  5.9768 +    automated actions in response to events that occur in a
  5.9769 +    repository.  In some cases, you can even control Mercurial's
  5.9770 +    response to those events.</para>
  5.9771 +
  5.9772 +  <para id="x_1e7">The name Mercurial uses for one of these actions is a
  5.9773 +    <emphasis>hook</emphasis>. Hooks are called
  5.9774 +    <quote>triggers</quote> in some revision control systems, but the
  5.9775 +    two names refer to the same idea.</para>
  5.9776 +
  5.9777 +  <sect1>
  5.9778 +    <title>An overview of hooks in Mercurial</title>
  5.9779 +
  5.9780 +    <para id="x_1e8">Here is a brief list of the hooks that Mercurial
  5.9781 +      supports. We will revisit each of these hooks in more detail
  5.9782 +      later, in <xref linkend="sec:hook:ref"/>.</para>
  5.9783 +
  5.9784 +    <para id="x_1f6">Each of the hooks whose description begins with the word
  5.9785 +      <quote>Controlling</quote> has the ability to determine whether
  5.9786 +      an activity can proceed.  If the hook succeeds, the activity may
  5.9787 +      proceed; if it fails, the activity is either not permitted or
  5.9788 +      undone, depending on the hook.</para>
  5.9789 +
  5.9790 +    <itemizedlist>
  5.9791 +      <listitem><para id="x_1e9"><literal role="hook" moreinfo="none">changegroup</literal>: This
  5.9792 +	  is run after a group of changesets has been brought into the
  5.9793 +	  repository from elsewhere.</para>
  5.9794 +      </listitem>
  5.9795 +      <listitem><para id="x_1ea"><literal role="hook" moreinfo="none">commit</literal>: This is
  5.9796 +	  run after a new changeset has been created in the local
  5.9797 +	  repository.</para>
  5.9798 +      </listitem>
  5.9799 +      <listitem><para id="x_1eb"><literal role="hook" moreinfo="none">incoming</literal>: This is
  5.9800 +	  run once for each new changeset that is brought into the
  5.9801 +	  repository from elsewhere.  Notice the difference from
  5.9802 +	  <literal role="hook" moreinfo="none">changegroup</literal>, which is run
  5.9803 +	  once per <emphasis>group</emphasis> of changesets brought
  5.9804 +	  in.</para>
  5.9805 +      </listitem>
  5.9806 +      <listitem><para id="x_1ec"><literal role="hook" moreinfo="none">outgoing</literal>: This is
  5.9807 +	  run after a group of changesets has been transmitted from
  5.9808 +	  this repository.</para>
  5.9809 +      </listitem>
  5.9810 +      <listitem><para id="x_1ed"><literal role="hook" moreinfo="none">prechangegroup</literal>:
  5.9811 +	  This is run before starting to bring a group of changesets
  5.9812 +	  into the repository.
  5.9813 +	</para>
  5.9814 +      </listitem>
  5.9815 +      <listitem><para id="x_1ee"><literal role="hook" moreinfo="none">precommit</literal>:
  5.9816 +	  Controlling. This is run before starting a commit.
  5.9817 +	</para>
  5.9818 +      </listitem>
  5.9819 +      <listitem><para id="x_1ef"><literal role="hook" moreinfo="none">preoutgoing</literal>:
  5.9820 +	  Controlling. This is run before starting to transmit a group
  5.9821 +	  of changesets from this repository.
  5.9822 +	</para>
  5.9823 +      </listitem>
  5.9824 +      <listitem><para id="x_1f0"><literal role="hook" moreinfo="none">pretag</literal>:
  5.9825 +	  Controlling. This is run before creating a tag.
  5.9826 +	</para>
  5.9827 +      </listitem>
  5.9828 +      <listitem><para id="x_1f1"><literal role="hook" moreinfo="none">pretxnchangegroup</literal>: Controlling. This
  5.9829 +	  is run after a group of changesets has been brought into the
  5.9830 +	  local repository from another, but before the transaction
  5.9831 +	  completes that will make the changes permanent in the
  5.9832 +	  repository.
  5.9833 +	</para>
  5.9834 +      </listitem>
  5.9835 +      <listitem><para id="x_1f2"><literal role="hook" moreinfo="none">pretxncommit</literal>:
  5.9836 +	  Controlling. This is run after a new changeset has been
  5.9837 +	  created in the local repository, but before the transaction
  5.9838 +	  completes that will make it permanent.
  5.9839 +	</para>
  5.9840 +      </listitem>
  5.9841 +      <listitem><para id="x_1f3"><literal role="hook" moreinfo="none">preupdate</literal>:
  5.9842 +	  Controlling. This is run before starting an update or merge
  5.9843 +	  of the working directory.
  5.9844 +	</para>
  5.9845 +      </listitem>
  5.9846 +      <listitem><para id="x_1f4"><literal role="hook" moreinfo="none">tag</literal>: This is run
  5.9847 +	  after a tag is created.
  5.9848 +	</para>
  5.9849 +      </listitem>
  5.9850 +      <listitem><para id="x_1f5"><literal role="hook" moreinfo="none">update</literal>: This is
  5.9851 +	  run after an update or merge of the working directory has
  5.9852 +	  finished.
  5.9853 +	</para>
  5.9854 +      </listitem></itemizedlist>
  5.9855 +
  5.9856 +  </sect1>
  5.9857 +  <sect1>
  5.9858 +    <title>Hooks and security</title>
  5.9859 +
  5.9860 +    <sect2>
  5.9861 +      <title>Hooks are run with your privileges</title>
  5.9862 +
  5.9863 +      <para id="x_1f7">When you run a Mercurial command in a repository, and the
  5.9864 +	command causes a hook to run, that hook runs on
  5.9865 +	<emphasis>your</emphasis> system, under
  5.9866 +	<emphasis>your</emphasis> user account, with
  5.9867 +	<emphasis>your</emphasis> privilege level.  Since hooks are
  5.9868 +	arbitrary pieces of executable code, you should treat them
  5.9869 +	with an appropriate level of suspicion.  Do not install a hook
  5.9870 +	unless you are confident that you know who created it and what
  5.9871 +	it does.
  5.9872 +      </para>
  5.9873 +
  5.9874 +      <para id="x_1f8">In some cases, you may be exposed to hooks that you did
  5.9875 +	not install yourself.  If you work with Mercurial on an
  5.9876 +	unfamiliar system, Mercurial will run hooks defined in that
  5.9877 +	system's global <filename role="special" moreinfo="none">~/.hgrc</filename>
  5.9878 +	file.
  5.9879 +      </para>
  5.9880 +
  5.9881 +      <para id="x_1f9">If you are working with a repository owned by another
  5.9882 +	user, Mercurial can run hooks defined in that user's
  5.9883 +	repository, but it will still run them as <quote>you</quote>.
  5.9884 +	For example, if you <command role="hg-cmd" moreinfo="none">hg pull</command>
  5.9885 +	from that repository, and its <filename role="special" moreinfo="none">.hg/hgrc</filename> defines a local <literal role="hook" moreinfo="none">outgoing</literal> hook, that hook will run
  5.9886 +	under your user account, even though you don't own that
  5.9887 +	repository.
  5.9888 +      </para>
  5.9889 +
  5.9890 +      <note>
  5.9891 +	<para id="x_1fa">  This only applies if you are pulling from a repository
  5.9892 +	  on a local or network filesystem.  If you're pulling over
  5.9893 +	  http or ssh, any <literal role="hook" moreinfo="none">outgoing</literal>
  5.9894 +	  hook will run under whatever account is executing the server
  5.9895 +	  process, on the server.
  5.9896 +	</para>
  5.9897 +      </note>
  5.9898 +
  5.9899 +      <para id="x_1fb">To see what hooks are defined in a repository,
  5.9900 +	use the <command role="hg-cmd" moreinfo="none">hg showconfig hooks</command>
  5.9901 +	command.  If you are working in one repository, but talking to
  5.9902 +	another that you do not own (e.g. using <command role="hg-cmd" moreinfo="none">hg pull</command> or <command role="hg-cmd" moreinfo="none">hg
  5.9903 +	  incoming</command>), remember that it is the other
  5.9904 +	repository's hooks you should be checking, not your own.
  5.9905 +      </para>
  5.9906 +    </sect2>
  5.9907 +
  5.9908 +    <sect2>
  5.9909 +      <title>Hooks do not propagate</title>
  5.9910 +
  5.9911 +      <para id="x_1fc">In Mercurial, hooks are not revision controlled, and do
  5.9912 +	not propagate when you clone, or pull from, a repository.  The
  5.9913 +	reason for this is simple: a hook is a completely arbitrary
  5.9914 +	piece of executable code.  It runs under your user identity,
  5.9915 +	with your privilege level, on your machine.
  5.9916 +      </para>
  5.9917 +
  5.9918 +      <para id="x_1fd">It would be extremely reckless for any distributed
  5.9919 +	revision control system to implement revision-controlled
  5.9920 +	hooks, as this would offer an easily exploitable way to
  5.9921 +	subvert the accounts of users of the revision control system.
  5.9922 +      </para>
  5.9923 +
  5.9924 +      <para id="x_1fe">Since Mercurial does not propagate hooks, if you are
  5.9925 +	collaborating with other people on a common project, you
  5.9926 +	should not assume that they are using the same Mercurial hooks
  5.9927 +	as you are, or that theirs are correctly configured.  You
  5.9928 +	should document the hooks you expect people to use.
  5.9929 +      </para>
  5.9930 +
  5.9931 +      <para id="x_1ff">In a corporate intranet, this is somewhat easier to
  5.9932 +	control, as you can for example provide a
  5.9933 +	<quote>standard</quote> installation of Mercurial on an NFS
  5.9934 +	filesystem, and use a site-wide <filename role="special" moreinfo="none">~/.hgrc</filename> file to define hooks that all users will
  5.9935 +	see.  However, this too has its limits; see below.
  5.9936 +      </para>
  5.9937 +    </sect2>
  5.9938 +
  5.9939 +    <sect2>
  5.9940 +      <title>Hooks can be overridden</title>
  5.9941 +
  5.9942 +      <para id="x_200">Mercurial allows you to override a hook definition by
  5.9943 +	redefining the hook.  You can disable it by setting its value
  5.9944 +	to the empty string, or change its behavior as you wish.
  5.9945 +      </para>
  5.9946 +
  5.9947 +      <para id="x_201">If you deploy a system- or site-wide <filename role="special" moreinfo="none">~/.hgrc</filename> file that defines some
  5.9948 +	hooks, you should thus understand that your users can disable
  5.9949 +	or override those hooks.
  5.9950 +      </para>
  5.9951 +    </sect2>
  5.9952 +
  5.9953 +    <sect2>
  5.9954 +      <title>Ensuring that critical hooks are run</title>
  5.9955 +
  5.9956 +      <para id="x_202">Sometimes you may want to enforce a policy that you do not
  5.9957 +	want others to be able to work around.  For example, you may
  5.9958 +	have a requirement that every changeset must pass a rigorous
  5.9959 +	set of tests.  Defining this requirement via a hook in a
  5.9960 +	site-wide <filename role="special" moreinfo="none">~/.hgrc</filename> won't
  5.9961 +	work for remote users on laptops, and of course local users
  5.9962 +	can subvert it at will by overriding the hook.
  5.9963 +      </para>
  5.9964 +
  5.9965 +      <para id="x_203">Instead, you can set up your policies for use of Mercurial
  5.9966 +	so that people are expected to propagate changes through a
  5.9967 +	well-known <quote>canonical</quote> server that you have
  5.9968 +	locked down and configured appropriately.
  5.9969 +      </para>
  5.9970 +
  5.9971 +      <para id="x_204">One way to do this is via a combination of social
  5.9972 +	engineering and technology.  Set up a restricted-access
  5.9973 +	account; users can push changes over the network to
  5.9974 +	repositories managed by this account, but they cannot log into
  5.9975 +	the account and run normal shell commands.  In this scenario,
  5.9976 +	a user can commit a changeset that contains any old garbage
  5.9977 +	they want.
  5.9978 +      </para>
  5.9979 +
  5.9980 +      <para id="x_205">When someone pushes a changeset to the server that
  5.9981 +	everyone pulls from, the server will test the changeset before
  5.9982 +	it accepts it as permanent, and reject it if it fails to pass
  5.9983 +	the test suite.  If people only pull changes from this
  5.9984 +	filtering server, it will serve to ensure that all changes
  5.9985 +	that people pull have been automatically vetted.
  5.9986 +      </para>
  5.9987 +
  5.9988 +    </sect2>
  5.9989 +  </sect1>
  5.9990 +
  5.9991 +  <sect1 id="sec:hook:simple">
  5.9992 +    <title>A short tutorial on using hooks</title>
  5.9993 +
  5.9994 +    <para id="x_212">It is easy to write a Mercurial hook.  Let's start with a
  5.9995 +      hook that runs when you finish a <command role="hg-cmd" moreinfo="none">hg
  5.9996 +	commit</command>, and simply prints the hash of the changeset
  5.9997 +      you just created.  The hook is called <literal role="hook" moreinfo="none">commit</literal>.
  5.9998 +    </para>
  5.9999 +
 5.10000 +    <para id="x_213">All hooks follow the pattern in this example.</para>
 5.10001 +
 5.10002 +<!-- BEGIN hook.simple.init -->
 5.10003 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init hook-test</userinput>
 5.10004 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hook-test</userinput>
 5.10005 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo '[hooks]' &gt;&gt; .hg/hgrc</userinput>
 5.10006 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'commit = echo committed $HG_NODE' &gt;&gt; .hg/hgrc</userinput>
 5.10007 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 5.10008 +[hooks]
 5.10009 +commit = echo committed $HG_NODE
 5.10010 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 5.10011 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 5.10012 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'testing commit hook'</userinput>
 5.10013 +committed 13a334d1e5ca83fea465aa779110eec3c5ddd6b1
 5.10014 +</screen>
 5.10015 +<!-- END hook.simple.init -->
 5.10016 +
 5.10017 +
 5.10018 +    <para id="x_214">You add an entry to the <literal role="rc-hooks" moreinfo="none">hooks</literal> section of your <filename role="special" moreinfo="none">~/.hgrc</filename>.  On the left is the name of
 5.10019 +      the event to trigger on; on the right is the action to take.  As
 5.10020 +      you can see, you can run an arbitrary shell command in a hook.
 5.10021 +      Mercurial passes extra information to the hook using environment
 5.10022 +      variables (look for <envar>HG_NODE</envar> in the example).
 5.10023 +    </para>
 5.10024 +
 5.10025 +    <sect2>
 5.10026 +      <title>Performing multiple actions per event</title>
 5.10027 +
 5.10028 +      <para id="x_215">Quite often, you will want to define more than one hook
 5.10029 +	for a particular kind of event, as shown below.</para>
 5.10030 +
 5.10031 +<!-- BEGIN hook.simple.ext -->
 5.10032 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'commit.when = echo -n "date of commit: "; date' &gt;&gt; .hg/hgrc</userinput>
 5.10033 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt;&gt; a</userinput>
 5.10034 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'i have two hooks'</userinput>
 5.10035 +committed 3be6e2778fb853cbc7e5138d0b9c29386504670b
 5.10036 +date of commit: Sun Aug 16 14:05:05 GMT 2009
 5.10037 +</screen>
 5.10038 +<!-- END hook.simple.ext -->
 5.10039 +
 5.10040 +
 5.10041 +      <para id="x_216">Mercurial lets you do this by adding an
 5.10042 +	<emphasis>extension</emphasis> to the end of a hook's name.
 5.10043 +	You extend a hook's name by giving the name of the hook,
 5.10044 +	followed by a full stop (the
 5.10045 +	<quote><literal moreinfo="none">.</literal></quote> character), followed by
 5.10046 +	some more text of your choosing.  For example, Mercurial will
 5.10047 +	run both <literal moreinfo="none">commit.foo</literal> and
 5.10048 +	<literal moreinfo="none">commit.bar</literal> when the
 5.10049 +	<literal moreinfo="none">commit</literal> event occurs.
 5.10050 +      </para>
 5.10051 +
 5.10052 +      <para id="x_217">To give a well-defined order of execution when there are
 5.10053 +	multiple hooks defined for an event, Mercurial sorts hooks by
 5.10054 +	extension, and executes the hook commands in this sorted
 5.10055 +	order.  In the above example, it will execute
 5.10056 +	<literal moreinfo="none">commit.bar</literal> before
 5.10057 +	<literal moreinfo="none">commit.foo</literal>, and <literal moreinfo="none">commit</literal>
 5.10058 +	before both.
 5.10059 +      </para>
 5.10060 +
 5.10061 +      <para id="x_218">It is a good idea to use a somewhat descriptive
 5.10062 +	extension when you define a new hook.  This will help you to
 5.10063 +	remember what the hook was for.  If the hook fails, you'll get
 5.10064 +	an error message that contains the hook name and extension, so
 5.10065 +	using a descriptive extension could give you an immediate hint
 5.10066 +	as to why the hook failed (see <xref linkend="sec:hook:perm"/> for an example).
 5.10067 +      </para>
 5.10068 +
 5.10069 +    </sect2>
 5.10070 +    <sect2 id="sec:hook:perm">
 5.10071 +      <title>Controlling whether an activity can proceed</title>
 5.10072 +
 5.10073 +      <para id="x_219">In our earlier examples, we used the <literal role="hook" moreinfo="none">commit</literal> hook, which is run after a
 5.10074 +	commit has completed.  This is one of several Mercurial hooks
 5.10075 +	that run after an activity finishes.  Such hooks have no way
 5.10076 +	of influencing the activity itself.
 5.10077 +      </para>
 5.10078 +
 5.10079 +      <para id="x_21a">Mercurial defines a number of events that occur before an
 5.10080 +	activity starts; or after it starts, but before it finishes.
 5.10081 +	Hooks that trigger on these events have the added ability to
 5.10082 +	choose whether the activity can continue, or will abort.
 5.10083 +      </para>
 5.10084 +
 5.10085 +      <para id="x_21b">The <literal role="hook" moreinfo="none">pretxncommit</literal> hook runs
 5.10086 +	after a commit has all but completed.  In other words, the
 5.10087 +	metadata representing the changeset has been written out to
 5.10088 +	disk, but the transaction has not yet been allowed to
 5.10089 +	complete.  The <literal role="hook" moreinfo="none">pretxncommit</literal>
 5.10090 +	hook has the ability to decide whether the transaction can
 5.10091 +	complete, or must be rolled back.
 5.10092 +      </para>
 5.10093 +
 5.10094 +      <para id="x_21c">If the <literal role="hook" moreinfo="none">pretxncommit</literal> hook
 5.10095 +	exits with a status code of zero, the transaction is allowed
 5.10096 +	to complete; the commit finishes; and the <literal role="hook" moreinfo="none">commit</literal> hook is run.  If the <literal role="hook" moreinfo="none">pretxncommit</literal> hook exits with a
 5.10097 +	non-zero status code, the transaction is rolled back; the
 5.10098 +	metadata representing the changeset is erased; and the
 5.10099 +	<literal role="hook" moreinfo="none">commit</literal> hook is not run.
 5.10100 +      </para>
 5.10101 +
 5.10102 +<!-- BEGIN hook.simple.pretxncommit -->
 5.10103 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat check_bug_id</userinput>
 5.10104 +#!/bin/sh
 5.10105 +# check that a commit comment mentions a numeric bug id
 5.10106 +hg log -r $1 --template {desc} | grep -q "\&lt;bug *[0-9]"
 5.10107 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' &gt;&gt; .hg/hgrc</userinput>
 5.10108 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt;&gt; a</userinput>
 5.10109 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'i am not mentioning a bug id'</userinput>
 5.10110 +transaction abort!
 5.10111 +rollback completed
 5.10112 +abort: pretxncommit.bug_id_required hook exited with status 1
 5.10113 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'i refer you to bug 666'</userinput>
 5.10114 +committed 1a52be73a1ca4fa05e269f99003ed00912e8e836
 5.10115 +date of commit: Sun Aug 16 14:05:05 GMT 2009
 5.10116 +</screen>
 5.10117 +<!-- END hook.simple.pretxncommit -->
 5.10118 +
 5.10119 +
 5.10120 +      <para id="x_21d">The hook in the example above checks that a commit comment
 5.10121 +	contains a bug ID.  If it does, the commit can complete.  If
 5.10122 +	not, the commit is rolled back.
 5.10123 +      </para>
 5.10124 +
 5.10125 +    </sect2>
 5.10126 +  </sect1>
 5.10127 +  <sect1>
 5.10128 +    <title>Writing your own hooks</title>
 5.10129 +
 5.10130 +    <para id="x_21e">When you are writing a hook, you might find it useful to run
 5.10131 +      Mercurial either with the <option role="hg-opt-global">-v</option> option, or the <envar role="rc-item-ui">verbose</envar> config item set to
 5.10132 +      <quote>true</quote>.  When you do so, Mercurial will print a
 5.10133 +      message before it calls each hook.
 5.10134 +    </para>
 5.10135 +
 5.10136 +    <sect2 id="sec:hook:lang">
 5.10137 +      <title>Choosing how your hook should run</title>
 5.10138 +
 5.10139 +      <para id="x_21f">You can write a hook either as a normal
 5.10140 +	program—typically a shell script—or as a Python
 5.10141 +	function that is executed within the Mercurial process.
 5.10142 +      </para>
 5.10143 +
 5.10144 +      <para id="x_220">Writing a hook as an external program has the advantage
 5.10145 +	that it requires no knowledge of Mercurial's internals.  You
 5.10146 +	can call normal Mercurial commands to get any added
 5.10147 +	information you need.  The trade-off is that external hooks
 5.10148 +	are slower than in-process hooks.
 5.10149 +      </para>
 5.10150 +
 5.10151 +      <para id="x_221">An in-process Python hook has complete access to the
 5.10152 +	Mercurial API, and does not <quote>shell out</quote> to
 5.10153 +	another process, so it is inherently faster than an external
 5.10154 +	hook.  It is also easier to obtain much of the information
 5.10155 +	that a hook requires by using the Mercurial API than by
 5.10156 +	running Mercurial commands.
 5.10157 +      </para>
 5.10158 +
 5.10159 +      <para id="x_222">If you are comfortable with Python, or require high
 5.10160 +	performance, writing your hooks in Python may be a good
 5.10161 +	choice.  However, when you have a straightforward hook to
 5.10162 +	write and you don't need to care about performance (probably
 5.10163 +	the majority of hooks), a shell script is perfectly fine.
 5.10164 +      </para>
 5.10165 +
 5.10166 +    </sect2>
 5.10167 +    <sect2 id="sec:hook:param">
 5.10168 +      <title>Hook parameters</title>
 5.10169 +
 5.10170 +      <para id="x_223">Mercurial calls each hook with a set of well-defined
 5.10171 +	parameters.  In Python, a parameter is passed as a keyword
 5.10172 +	argument to your hook function.  For an external program, a
 5.10173 +	parameter is passed as an environment variable.
 5.10174 +      </para>
 5.10175 +
 5.10176 +      <para id="x_224">Whether your hook is written in Python or as a shell
 5.10177 +	script, the hook-specific parameter names and values will be
 5.10178 +	the same.  A boolean parameter will be represented as a
 5.10179 +	boolean value in Python, but as the number 1 (for
 5.10180 +	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
 5.10181 +	environment variable for an external hook.  If a hook
 5.10182 +	parameter is named <literal moreinfo="none">foo</literal>, the keyword
 5.10183 +	argument for a Python hook will also be named
 5.10184 +	<literal moreinfo="none">foo</literal>, while the environment variable for an
 5.10185 +	external hook will be named <literal moreinfo="none">HG_FOO</literal>.
 5.10186 +      </para>
 5.10187 +    </sect2>
 5.10188 +
 5.10189 +    <sect2>
 5.10190 +      <title>Hook return values and activity control</title>
 5.10191 +
 5.10192 +      <para id="x_225">A hook that executes successfully must exit with a status
 5.10193 +	of zero if external, or return boolean <quote>false</quote> if
 5.10194 +	in-process.  Failure is indicated with a non-zero exit status
 5.10195 +	from an external hook, or an in-process hook returning boolean
 5.10196 +	<quote>true</quote>.  If an in-process hook raises an
 5.10197 +	exception, the hook is considered to have failed.
 5.10198 +      </para>
 5.10199 +
 5.10200 +      <para id="x_226">For a hook that controls whether an activity can proceed,
 5.10201 +	zero/false means <quote>allow</quote>, while
 5.10202 +	non-zero/true/exception means <quote>deny</quote>.
 5.10203 +      </para>
 5.10204 +    </sect2>
 5.10205 +
 5.10206 +    <sect2>
 5.10207 +      <title>Writing an external hook</title>
 5.10208 +
 5.10209 +      <para id="x_227">When you define an external hook in your <filename role="special" moreinfo="none">~/.hgrc</filename> and the hook is run, its
 5.10210 +	value is passed to your shell, which interprets it.  This
 5.10211 +	means that you can use normal shell constructs in the body of
 5.10212 +	the hook.
 5.10213 +      </para>
 5.10214 +
 5.10215 +      <para id="x_228">An executable hook is always run with its current
 5.10216 +	directory set to a repository's root directory.
 5.10217 +      </para>
 5.10218 +
 5.10219 +      <para id="x_229">Each hook parameter is passed in as an environment
 5.10220 +	variable; the name is upper-cased, and prefixed with the
 5.10221 +	string <quote><literal moreinfo="none">HG_</literal></quote>.
 5.10222 +      </para>
 5.10223 +
 5.10224 +      <para id="x_22a">With the exception of hook parameters, Mercurial does not
 5.10225 +	set or modify any environment variables when running a hook.
 5.10226 +	This is useful to remember if you are writing a site-wide hook
 5.10227 +	that may be run by a number of different users with differing
 5.10228 +	environment variables set. In multi-user situations, you
 5.10229 +	should not rely on environment variables being set to the
 5.10230 +	values you have in your environment when testing the hook.
 5.10231 +      </para>
 5.10232 +    </sect2>
 5.10233 +
 5.10234 +    <sect2>
 5.10235 +      <title>Telling Mercurial to use an in-process hook</title>
 5.10236 +
 5.10237 +      <para id="x_22b">The <filename role="special" moreinfo="none">~/.hgrc</filename> syntax
 5.10238 +	for defining an in-process hook is slightly different than for
 5.10239 +	an executable hook.  The value of the hook must start with the
 5.10240 +	text <quote><literal moreinfo="none">python:</literal></quote>, and continue
 5.10241 +	with the fully-qualified name of a callable object to use as
 5.10242 +	the hook's value.
 5.10243 +      </para>
 5.10244 +
 5.10245 +      <para id="x_22c">The module in which a hook lives is automatically imported
 5.10246 +	when a hook is run.  So long as you have the module name and
 5.10247 +	<envar>PYTHONPATH</envar> right, it should <quote>just
 5.10248 +	  work</quote>.
 5.10249 +      </para>
 5.10250 +
 5.10251 +      <para id="x_22d">The following <filename role="special" moreinfo="none">~/.hgrc</filename>
 5.10252 +	example snippet illustrates the syntax and meaning of the
 5.10253 +	notions we just described.
 5.10254 +      </para>
 5.10255 +      <programlisting format="linespecific">[hooks]
 5.10256 +commit.example = python:mymodule.submodule.myhook</programlisting>
 5.10257 +      <para id="x_22e">When Mercurial runs the <literal moreinfo="none">commit.example</literal>
 5.10258 +	hook, it imports <literal moreinfo="none">mymodule.submodule</literal>, looks
 5.10259 +	for the callable object named <literal moreinfo="none">myhook</literal>, and
 5.10260 +	calls it.
 5.10261 +      </para>
 5.10262 +    </sect2>
 5.10263 +
 5.10264 +    <sect2>
 5.10265 +      <title>Writing an in-process hook</title>
 5.10266 +
 5.10267 +      <para id="x_22f">The simplest in-process hook does nothing, but illustrates
 5.10268 +	the basic shape of the hook API:
 5.10269 +      </para>
 5.10270 +      <programlisting format="linespecific">def myhook(ui, repo, **kwargs):
 5.10271 +    pass</programlisting>
 5.10272 +      <para id="x_230">The first argument to a Python hook is always a <literal role="py-mod-mercurial.ui" moreinfo="none">ui</literal> object.  The second
 5.10273 +	is a repository object; at the moment, it is always an
 5.10274 +	instance of <literal role="py-mod-mercurial.localrepo" moreinfo="none">localrepository</literal>.
 5.10275 +	Following these two arguments are other keyword arguments.
 5.10276 +	Which ones are passed in depends on the hook being called, but
 5.10277 +	a hook can ignore arguments it doesn't care about by dropping
 5.10278 +	them into a keyword argument dict, as with
 5.10279 +	<literal moreinfo="none">**kwargs</literal> above.
 5.10280 +      </para>
 5.10281 +
 5.10282 +    </sect2>
 5.10283 +  </sect1>
 5.10284 +  <sect1>
 5.10285 +    <title>Some hook examples</title>
 5.10286 +
 5.10287 +    <sect2>
 5.10288 +      <title>Writing meaningful commit messages</title>
 5.10289 +
 5.10290 +      <para id="x_231">It's hard to imagine a useful commit message being very
 5.10291 +	short. The simple <literal role="hook" moreinfo="none">pretxncommit</literal>
 5.10292 +	hook of the example below will prevent you from committing a
 5.10293 +	changeset with a message that is less than ten bytes long.
 5.10294 +      </para>
 5.10295 +
 5.10296 +<!-- BEGIN hook.msglen.go -->
 5.10297 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 5.10298 +[hooks]
 5.10299 +pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10
 5.10300 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 5.10301 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 5.10302 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'too short'</userinput>
 5.10303 +transaction abort!
 5.10304 +rollback completed
 5.10305 +abort: pretxncommit.msglen hook exited with status 1
 5.10306 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'long enough'</userinput>
 5.10307 +</screen>
 5.10308 +<!-- END hook.msglen.go -->
 5.10309 +
 5.10310 +    </sect2>
 5.10311 +
 5.10312 +    <sect2>
 5.10313 +      <title>Checking for trailing whitespace</title>
 5.10314 +
 5.10315 +      <para id="x_232">An interesting use of a commit-related hook is to help you
 5.10316 +	to write cleaner code.  A simple example of <quote>cleaner
 5.10317 +	  code</quote> is the dictum that a change should not add any
 5.10318 +	new lines of text that contain <quote>trailing
 5.10319 +	  whitespace</quote>.  Trailing whitespace is a series of
 5.10320 +	space and tab characters at the end of a line of text.  In
 5.10321 +	most cases, trailing whitespace is unnecessary, invisible
 5.10322 +	noise, but it is occasionally problematic, and people often
 5.10323 +	prefer to get rid of it.
 5.10324 +      </para>
 5.10325 +
 5.10326 +      <para id="x_233">You can use either the <literal role="hook" moreinfo="none">precommit</literal> or <literal role="hook" moreinfo="none">pretxncommit</literal> hook to tell whether you
 5.10327 +	have a trailing whitespace problem.  If you use the <literal role="hook" moreinfo="none">precommit</literal> hook, the hook will not know
 5.10328 +	which files you are committing, so it will have to check every
 5.10329 +	modified file in the repository for trailing white space.  If
 5.10330 +	you want to commit a change to just the file
 5.10331 +	<filename moreinfo="none">foo</filename>, but the file
 5.10332 +	<filename moreinfo="none">bar</filename> contains trailing whitespace, doing a
 5.10333 +	check in the <literal role="hook" moreinfo="none">precommit</literal> hook
 5.10334 +	will prevent you from committing <filename moreinfo="none">foo</filename> due
 5.10335 +	to the problem with <filename moreinfo="none">bar</filename>.  This doesn't
 5.10336 +	seem right.
 5.10337 +      </para>
 5.10338 +
 5.10339 +      <para id="x_234">Should you choose the <literal role="hook" moreinfo="none">pretxncommit</literal> hook, the check won't
 5.10340 +	occur until just before the transaction for the commit
 5.10341 +	completes.  This will allow you to check for problems only the
 5.10342 +	exact files that are being committed.  However, if you entered
 5.10343 +	the commit message interactively and the hook fails, the
 5.10344 +	transaction will roll back; you'll have to re-enter the commit
 5.10345 +	message after you fix the trailing whitespace and run <command role="hg-cmd" moreinfo="none">hg commit</command> again.
 5.10346 +      </para>
 5.10347 +
 5.10348 +      <!-- BEGIN ch09/hook.ws.simple -->
 5.10349 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 5.10350 +[hooks]
 5.10351 +pretxncommit.whitespace = hg export tip | (! egrep -q '^\+.*[ \t]$')
 5.10352 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'a ' &gt; a</userinput>
 5.10353 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'test with trailing whitespace'</userinput>
 5.10354 +adding a
 5.10355 +transaction abort!
 5.10356 +rollback completed
 5.10357 +abort: pretxncommit.whitespace hook exited with status 1
 5.10358 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'a' &gt; a</userinput>
 5.10359 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'drop trailing whitespace and try again'</userinput>
 5.10360 +</screen>
 5.10361 +<!-- END ch09/hook.ws.simple -->
 5.10362 +
 5.10363 +
 5.10364 +      <para id="x_235">In this example, we introduce a simple <literal role="hook" moreinfo="none">pretxncommit</literal> hook that checks for
 5.10365 +	trailing whitespace.  This hook is short, but not very
 5.10366 +	helpful.  It exits with an error status if a change adds a
 5.10367 +	line with trailing whitespace to any file, but does not print
 5.10368 +	any information that might help us to identify the offending
 5.10369 +	file or line.  It also has the nice property of not paying
 5.10370 +	attention to unmodified lines; only lines that introduce new
 5.10371 +	trailing whitespace cause problems.
 5.10372 +      </para>
 5.10373 +
 5.10374 +      <!-- BEGIN ch09/check_whitespace.py.lst -->
 5.10375 +<programlisting format="linespecific">#!/usr/bin/env python
 5.10376 +#
 5.10377 +# save as .hg/check_whitespace.py and make executable
 5.10378 +
 5.10379 +import re
 5.10380 +
 5.10381 +def trailing_whitespace(difflines):
 5.10382 +    # 
 5.10383 +    linenum, header = 0, False
 5.10384 +
 5.10385 +    for line in difflines:
 5.10386 +        if header:
 5.10387 +            # remember the name of the file that this diff affects
 5.10388 +            m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)
 5.10389 +            if m and m.group(1) != '/dev/null':
 5.10390 +                filename = m.group(1).split('/', 1)[-1]
 5.10391 +            if line.startswith('+++ '):
 5.10392 +                header = False
 5.10393 +            continue
 5.10394 +        if line.startswith('diff '):
 5.10395 +            header = True
 5.10396 +            continue
 5.10397 +        # hunk header - save the line number
 5.10398 +        m = re.match(r'@@ -\d+,\d+ \+(\d+),', line)
 5.10399 +        if m:
 5.10400 +            linenum = int(m.group(1))
 5.10401 +            continue
 5.10402 +        # hunk body - check for an added line with trailing whitespace
 5.10403 +        m = re.match(r'\+.*\s$', line)
 5.10404 +        if m:
 5.10405 +            yield filename, linenum
 5.10406 +        if line and line[0] in ' +':
 5.10407 +            linenum += 1
 5.10408 +
 5.10409 +if __name__ == '__main__':
 5.10410 +    import os, sys
 5.10411 +    
 5.10412 +    added = 0
 5.10413 +    for filename, linenum in trailing_whitespace(os.popen('hg export tip')):
 5.10414 +        print &gt;&gt; sys.stderr, ('%s, line %d: trailing whitespace added' %
 5.10415 +                              (filename, linenum))
 5.10416 +        added += 1
 5.10417 +    if added:
 5.10418 +        # save the commit message so we don't need to retype it
 5.10419 +        os.system('hg tip --template "{desc}" &gt; .hg/commit.save')
 5.10420 +        print &gt;&gt; sys.stderr, 'commit message saved to .hg/commit.save'
 5.10421 +        sys.exit(1)</programlisting>
 5.10422 +<!-- END ch09/check_whitespace.py.lst -->
 5.10423 +
 5.10424 +
 5.10425 +      <para id="x_236">The above version is much more complex, but also more
 5.10426 +	useful.  It parses a unified diff to see if any lines add
 5.10427 +	trailing whitespace, and prints the name of the file and the
 5.10428 +	line number of each such occurrence.  Even better, if the
 5.10429 +	change adds trailing whitespace, this hook saves the commit
 5.10430 +	comment and prints the name of the save file before exiting
 5.10431 +	and telling Mercurial to roll the transaction back, so you can
 5.10432 +	use the <option role="hg-opt-commit">-l filename</option>
 5.10433 +	option to <command role="hg-cmd" moreinfo="none">hg commit</command> to reuse
 5.10434 +	the saved commit message once you've corrected the problem.
 5.10435 +      </para>
 5.10436 +
 5.10437 +      <!-- BEGIN ch09/hook.ws.better -->
 5.10438 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 5.10439 +[hooks]
 5.10440 +pretxncommit.whitespace = .hg/check_whitespace.py
 5.10441 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'a ' &gt;&gt; a</userinput>
 5.10442 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'add new line with trailing whitespace'</userinput>
 5.10443 +a, line 2: trailing whitespace added
 5.10444 +commit message saved to .hg/commit.save
 5.10445 +transaction abort!
 5.10446 +rollback completed
 5.10447 +abort: pretxncommit.whitespace hook exited with status 1
 5.10448 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">sed -i 's, *$,,' a</userinput>
 5.10449 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'trimmed trailing whitespace'</userinput>
 5.10450 +a, line 2: trailing whitespace added
 5.10451 +commit message saved to .hg/commit.save
 5.10452 +transaction abort!
 5.10453 +rollback completed
 5.10454 +abort: pretxncommit.whitespace hook exited with status 1
 5.10455 +</screen>
 5.10456 +<!-- END ch09/hook.ws.better -->
 5.10457 +
 5.10458 +
 5.10459 +      <para id="x_237">As a final aside, note in the example above the
 5.10460 +	use of <command moreinfo="none">sed</command>'s in-place editing feature to
 5.10461 +	get rid of trailing whitespace from a file.  This is concise
 5.10462 +	and useful enough that I will reproduce it here (using
 5.10463 +	<command moreinfo="none">perl</command> for good measure).</para>
 5.10464 +      <programlisting format="linespecific">perl -pi -e 's,\s+$,,' filename</programlisting>
 5.10465 +
 5.10466 +    </sect2>
 5.10467 +  </sect1>
 5.10468 +  <sect1>
 5.10469 +    <title>Bundled hooks</title>
 5.10470 +
 5.10471 +    <para id="x_238">Mercurial ships with several bundled hooks.  You can find
 5.10472 +      them in the <filename class="directory" moreinfo="none">hgext</filename>
 5.10473 +      directory of a Mercurial source tree.  If you are using a
 5.10474 +      Mercurial binary package, the hooks will be located in the
 5.10475 +      <filename class="directory" moreinfo="none">hgext</filename> directory of
 5.10476 +      wherever your package installer put Mercurial.
 5.10477 +    </para>
 5.10478 +
 5.10479 +    <sect2>
 5.10480 +      <title><literal role="hg-ext" moreinfo="none">acl</literal>—access
 5.10481 +	control for parts of a repository</title>
 5.10482 +
 5.10483 +      <para id="x_239">The <literal role="hg-ext" moreinfo="none">acl</literal> extension lets
 5.10484 +	you control which remote users are allowed to push changesets
 5.10485 +	to a networked server.  You can protect any portion of a
 5.10486 +	repository (including the entire repo), so that a specific
 5.10487 +	remote user can push changes that do not affect the protected
 5.10488 +	portion.
 5.10489 +      </para>
 5.10490 +
 5.10491 +      <para id="x_23a">This extension implements access control based on the
 5.10492 +	identity of the user performing a push,
 5.10493 +	<emphasis>not</emphasis> on who committed the changesets
 5.10494 +	they're pushing.  It makes sense to use this hook only if you
 5.10495 +	have a locked-down server environment that authenticates
 5.10496 +	remote users, and you want to be sure that only specific users
 5.10497 +	are allowed to push changes to that server.
 5.10498 +      </para>
 5.10499 +
 5.10500 +      <sect3>
 5.10501 +	<title>Configuring the <literal role="hook" moreinfo="none">acl</literal>
 5.10502 +	  hook</title>
 5.10503 +
 5.10504 +	<para id="x_23b">In order to manage incoming changesets, the <literal role="hg-ext" moreinfo="none">acl</literal> hook must be used as a
 5.10505 +	  <literal role="hook" moreinfo="none">pretxnchangegroup</literal> hook.  This
 5.10506 +	  lets it see which files are modified by each incoming
 5.10507 +	  changeset, and roll back a group of changesets if they
 5.10508 +	  modify <quote>forbidden</quote> files.  Example:
 5.10509 +	</para>
 5.10510 +	<programlisting format="linespecific">[hooks]
 5.10511 +pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
 5.10512 +
 5.10513 +	<para id="x_23c">The <literal role="hg-ext" moreinfo="none">acl</literal> extension is
 5.10514 +	  configured using three sections.
 5.10515 +	</para>
 5.10516 +
 5.10517 +	<para id="x_23d">The <literal role="rc-acl" moreinfo="none">acl</literal> section has
 5.10518 +	  only one entry, <envar role="rc-item-acl">sources</envar>,
 5.10519 +	  which lists the sources of incoming changesets that the hook
 5.10520 +	  should pay attention to.  You don't normally need to
 5.10521 +	  configure this section.
 5.10522 +	</para>
 5.10523 +	<itemizedlist>
 5.10524 +	  <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>:
 5.10525 +	      Control incoming changesets that are arriving from a
 5.10526 +	      remote repository over http or ssh.  This is the default
 5.10527 +	      value of <envar role="rc-item-acl">sources</envar>, and
 5.10528 +	      usually the only setting you'll need for this
 5.10529 +	      configuration item.
 5.10530 +	    </para>
 5.10531 +	  </listitem>
 5.10532 +	  <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>:
 5.10533 +	      Control incoming changesets that are arriving via a pull
 5.10534 +	      from a local repository.
 5.10535 +	    </para>
 5.10536 +	  </listitem>
 5.10537 +	  <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>:
 5.10538 +	      Control incoming changesets that are arriving via a push
 5.10539 +	      from a local repository.
 5.10540 +	    </para>
 5.10541 +	  </listitem>
 5.10542 +	  <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>:
 5.10543 +	      Control incoming changesets that are arriving from
 5.10544 +	      another repository via a bundle.
 5.10545 +	    </para>
 5.10546 +	  </listitem></itemizedlist>
 5.10547 +
 5.10548 +	<para id="x_242">The <literal role="rc-acl.allow" moreinfo="none">acl.allow</literal>
 5.10549 +	  section controls the users that are allowed to add
 5.10550 +	  changesets to the repository.  If this section is not
 5.10551 +	  present, all users that are not explicitly denied are
 5.10552 +	  allowed.  If this section is present, all users that are not
 5.10553 +	  explicitly allowed are denied (so an empty section means
 5.10554 +	  that all users are denied).
 5.10555 +	</para>
 5.10556 +
 5.10557 +	<para id="x_243">The <literal role="rc-acl.deny" moreinfo="none">acl.deny</literal>
 5.10558 +	  section determines which users are denied from adding
 5.10559 +	  changesets to the repository.  If this section is not
 5.10560 +	  present or is empty, no users are denied.
 5.10561 +	</para>
 5.10562 +
 5.10563 +	<para id="x_244">The syntaxes for the <literal role="rc-acl.allow" moreinfo="none">acl.allow</literal> and <literal role="rc-acl.deny" moreinfo="none">acl.deny</literal> sections are
 5.10564 +	  identical.  On the left of each entry is a glob pattern that
 5.10565 +	  matches files or directories, relative to the root of the
 5.10566 +	  repository; on the right, a user name.
 5.10567 +	</para>
 5.10568 +
 5.10569 +	<para id="x_245">In the following example, the user
 5.10570 +	  <literal moreinfo="none">docwriter</literal> can only push changes to the
 5.10571 +	  <filename class="directory" moreinfo="none">docs</filename> subtree of the
 5.10572 +	  repository, while <literal moreinfo="none">intern</literal> can push changes
 5.10573 +	  to any file or directory except <filename class="directory" moreinfo="none">source/sensitive</filename>.
 5.10574 +	</para>
 5.10575 +	<programlisting format="linespecific">[acl.allow]
 5.10576 +docs/** = docwriter
 5.10577 +[acl.deny]
 5.10578 +source/sensitive/** = intern</programlisting>
 5.10579 +
 5.10580 +      </sect3>
 5.10581 +      <sect3>
 5.10582 +	<title>Testing and troubleshooting</title>
 5.10583 +
 5.10584 +	<para id="x_246">If you want to test the <literal role="hg-ext" moreinfo="none">acl</literal> hook, run it with Mercurial's
 5.10585 +	  debugging output enabled.  Since you'll probably be running
 5.10586 +	  it on a server where it's not convenient (or sometimes
 5.10587 +	  possible) to pass in the <option role="hg-opt-global">--debug</option> option, don't forget
 5.10588 +	  that you can enable debugging output in your <filename role="special" moreinfo="none">~/.hgrc</filename>:
 5.10589 +	</para>
 5.10590 +	<programlisting format="linespecific">[ui]
 5.10591 +debug = true</programlisting>
 5.10592 +	<para id="x_247">With this enabled, the <literal role="hg-ext" moreinfo="none">acl</literal> hook will print enough
 5.10593 +	  information to let you figure out why it is allowing or
 5.10594 +	  forbidding pushes from specific users.
 5.10595 +	</para>
 5.10596 +
 5.10597 +      </sect3>    </sect2>
 5.10598 +
 5.10599 +    <sect2>
 5.10600 +      <title><literal role="hg-ext" moreinfo="none">bugzilla</literal>—integration with
 5.10601 +	Bugzilla</title>
 5.10602 +
 5.10603 +      <para id="x_248">The <literal role="hg-ext" moreinfo="none">bugzilla</literal> extension
 5.10604 +	adds a comment to a Bugzilla bug whenever it finds a reference
 5.10605 +	to that bug ID in a commit comment.  You can install this hook
 5.10606 +	on a shared server, so that any time a remote user pushes
 5.10607 +	changes to this server, the hook gets run.
 5.10608 +      </para>
 5.10609 +
 5.10610 +      <para id="x_249">It adds a comment to the bug that looks like this (you can
 5.10611 +	configure the contents of the comment—see below):
 5.10612 +      </para>
 5.10613 +      <programlisting format="linespecific">Changeset aad8b264143a, made by Joe User
 5.10614 +	&lt;joe.user@domain.com&gt; in the frobnitz repository, refers
 5.10615 +	to this bug. For complete details, see
 5.10616 +	http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
 5.10617 +	Changeset description: Fix bug 10483 by guarding against some
 5.10618 +	NULL pointers</programlisting>
 5.10619 +      <para id="x_24a">The value of this hook is that it automates the process of
 5.10620 +	updating a bug any time a changeset refers to it.  If you
 5.10621 +	configure the hook properly, it makes it easy for people to
 5.10622 +	browse straight from a Bugzilla bug to a changeset that refers
 5.10623 +	to that bug.
 5.10624 +      </para>
 5.10625 +
 5.10626 +      <para id="x_24b">You can use the code in this hook as a starting point for
 5.10627 +	some more exotic Bugzilla integration recipes.  Here are a few
 5.10628 +	possibilities:
 5.10629 +      </para>
 5.10630 +      <itemizedlist>
 5.10631 +	<listitem><para id="x_24c">Require that every changeset pushed to the
 5.10632 +	    server have a valid bug ID in its commit comment.  In this
 5.10633 +	    case, you'd want to configure the hook as a <literal role="hook" moreinfo="none">pretxncommit</literal> hook.  This would
 5.10634 +	    allow the hook to reject changes that didn't contain bug
 5.10635 +	    IDs.
 5.10636 +	  </para>
 5.10637 +	</listitem>
 5.10638 +	<listitem><para id="x_24d">Allow incoming changesets to automatically
 5.10639 +	    modify the <emphasis>state</emphasis> of a bug, as well as
 5.10640 +	    simply adding a comment.  For example, the hook could
 5.10641 +	    recognise the string <quote>fixed bug 31337</quote> as
 5.10642 +	    indicating that it should update the state of bug 31337 to
 5.10643 +	    <quote>requires testing</quote>.
 5.10644 +	  </para>
 5.10645 +	</listitem></itemizedlist>
 5.10646 +
 5.10647 +      <sect3 id="sec:hook:bugzilla:config">
 5.10648 +	<title>Configuring the <literal role="hook" moreinfo="none">bugzilla</literal>
 5.10649 +	  hook</title>
 5.10650 +
 5.10651 +	<para id="x_24e">You should configure this hook in your server's
 5.10652 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> as an <literal role="hook" moreinfo="none">incoming</literal> hook, for example as
 5.10653 +	  follows:
 5.10654 +	</para>
 5.10655 +	<programlisting format="linespecific">[hooks]
 5.10656 +incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
 5.10657 +
 5.10658 +	<para id="x_24f">Because of the specialised nature of this hook, and
 5.10659 +	  because Bugzilla was not written with this kind of
 5.10660 +	  integration in mind, configuring this hook is a somewhat
 5.10661 +	  involved process.
 5.10662 +	</para>
 5.10663 +
 5.10664 +	<para id="x_250">Before you begin, you must install the MySQL bindings
 5.10665 +	  for Python on the host(s) where you'll be running the hook.
 5.10666 +	  If this is not available as a binary package for your
 5.10667 +	  system, you can download it from
 5.10668 +	  <citation>web:mysql-python</citation>.
 5.10669 +	</para>
 5.10670 +
 5.10671 +	<para id="x_251">Configuration information for this hook lives in the
 5.10672 +	  <literal role="rc-bugzilla" moreinfo="none">bugzilla</literal> section of
 5.10673 +	  your <filename role="special" moreinfo="none">~/.hgrc</filename>.
 5.10674 +	</para>
 5.10675 +	<itemizedlist>
 5.10676 +	  <listitem><para id="x_252"><envar role="rc-item-bugzilla">version</envar>: The version
 5.10677 +	      of Bugzilla installed on the server.  The database
 5.10678 +	      schema that Bugzilla uses changes occasionally, so this
 5.10679 +	      hook has to know exactly which schema to use.</para>
 5.10680 +	  </listitem>
 5.10681 +	  <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>:
 5.10682 +	      The hostname of the MySQL server that stores your
 5.10683 +	      Bugzilla data.  The database must be configured to allow
 5.10684 +	      connections from whatever host you are running the
 5.10685 +	      <literal role="hook" moreinfo="none">bugzilla</literal> hook on.
 5.10686 +	    </para>
 5.10687 +	  </listitem>
 5.10688 +	  <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>:
 5.10689 +	      The username with which to connect to the MySQL server.
 5.10690 +	      The database must be configured to allow this user to
 5.10691 +	      connect from whatever host you are running the <literal role="hook" moreinfo="none">bugzilla</literal> hook on.  This user
 5.10692 +	      must be able to access and modify Bugzilla tables.  The
 5.10693 +	      default value of this item is <literal moreinfo="none">bugs</literal>,
 5.10694 +	      which is the standard name of the Bugzilla user in a
 5.10695 +	      MySQL database.
 5.10696 +	    </para>
 5.10697 +	  </listitem>
 5.10698 +	  <listitem><para id="x_255"><envar role="rc-item-bugzilla">password</envar>: The MySQL
 5.10699 +	      password for the user you configured above.  This is
 5.10700 +	      stored as plain text, so you should make sure that
 5.10701 +	      unauthorised users cannot read the <filename role="special" moreinfo="none">~/.hgrc</filename> file where you
 5.10702 +	      store this information.
 5.10703 +	    </para>
 5.10704 +	  </listitem>
 5.10705 +	  <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>:
 5.10706 +	      The name of the Bugzilla database on the MySQL server.
 5.10707 +	      The default value of this item is
 5.10708 +	      <literal moreinfo="none">bugs</literal>, which is the standard name of
 5.10709 +	      the MySQL database where Bugzilla stores its data.
 5.10710 +	    </para>
 5.10711 +	  </listitem>
 5.10712 +	  <listitem><para id="x_257"><envar role="rc-item-bugzilla">notify</envar>: If you want
 5.10713 +	      Bugzilla to send out a notification email to subscribers
 5.10714 +	      after this hook has added a comment to a bug, you will
 5.10715 +	      need this hook to run a command whenever it updates the
 5.10716 +	      database.  The command to run depends on where you have
 5.10717 +	      installed Bugzilla, but it will typically look something
 5.10718 +	      like this, if you have Bugzilla installed in <filename class="directory" moreinfo="none">/var/www/html/bugzilla</filename>:
 5.10719 +	    </para>
 5.10720 +	    <programlisting format="linespecific">cd /var/www/html/bugzilla &amp;&amp;
 5.10721 +	      ./processmail %s nobody@nowhere.com</programlisting>
 5.10722 +	  </listitem>
 5.10723 +	  <listitem><para id="x_258">  The Bugzilla
 5.10724 +	      <literal moreinfo="none">processmail</literal> program expects to be
 5.10725 +	      given a bug ID (the hook replaces
 5.10726 +	      <quote><literal moreinfo="none">%s</literal></quote> with the bug ID)
 5.10727 +	      and an email address.  It also expects to be able to
 5.10728 +	      write to some files in the directory that it runs in.
 5.10729 +	      If Bugzilla and this hook are not installed on the same
 5.10730 +	      machine, you will need to find a way to run
 5.10731 +	      <literal moreinfo="none">processmail</literal> on the server where
 5.10732 +	      Bugzilla is installed.
 5.10733 +	    </para>
 5.10734 +	  </listitem></itemizedlist>
 5.10735 +
 5.10736 +      </sect3>
 5.10737 +      <sect3>
 5.10738 +	<title>Mapping committer names to Bugzilla user names</title>
 5.10739 +
 5.10740 +	<para id="x_259">By default, the <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook tries to use the
 5.10741 +	  email address of a changeset's committer as the Bugzilla
 5.10742 +	  user name with which to update a bug.  If this does not suit
 5.10743 +	  your needs, you can map committer email addresses to
 5.10744 +	  Bugzilla user names using a <literal role="rc-usermap" moreinfo="none">usermap</literal> section.
 5.10745 +	</para>
 5.10746 +
 5.10747 +	<para id="x_25a">Each item in the <literal role="rc-usermap" moreinfo="none">usermap</literal> section contains an
 5.10748 +	  email address on the left, and a Bugzilla user name on the
 5.10749 +	  right.
 5.10750 +	</para>
 5.10751 +	<programlisting format="linespecific">[usermap]
 5.10752 +jane.user@example.com = jane</programlisting>
 5.10753 +	<para id="x_25b">You can either keep the <literal role="rc-usermap" moreinfo="none">usermap</literal> data in a normal
 5.10754 +	  <filename role="special" moreinfo="none">~/.hgrc</filename>, or tell the
 5.10755 +	  <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook to read the
 5.10756 +	  information from an external <filename moreinfo="none">usermap</filename>
 5.10757 +	  file.  In the latter case, you can store
 5.10758 +	  <filename moreinfo="none">usermap</filename> data by itself in (for example)
 5.10759 +	  a user-modifiable repository.  This makes it possible to let
 5.10760 +	  your users maintain their own <envar role="rc-item-bugzilla">usermap</envar> entries.  The main
 5.10761 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file might look
 5.10762 +	  like this:
 5.10763 +	</para>
 5.10764 +	<programlisting format="linespecific"># regular hgrc file refers to external usermap file
 5.10765 +[bugzilla]
 5.10766 +usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
 5.10767 +	<para id="x_25c">While the <filename moreinfo="none">usermap</filename> file that it
 5.10768 +	  refers to might look like this:
 5.10769 +	</para>
 5.10770 +	<programlisting format="linespecific"># bugzilla-usermap.conf - inside a hg repository
 5.10771 +[usermap] stephanie@example.com = steph</programlisting>
 5.10772 +
 5.10773 +      </sect3>
 5.10774 +      <sect3>
 5.10775 +	<title>Configuring the text that gets added to a bug</title>
 5.10776 +
 5.10777 +	<para id="x_25d">You can configure the text that this hook adds as a
 5.10778 +	  comment; you specify it in the form of a Mercurial template.
 5.10779 +	  Several <filename role="special" moreinfo="none">~/.hgrc</filename> entries
 5.10780 +	  (still in the <literal role="rc-bugzilla" moreinfo="none">bugzilla</literal>
 5.10781 +	  section) control this behavior.
 5.10782 +	</para>
 5.10783 +	<itemizedlist>
 5.10784 +	  <listitem><para id="x_25e"><literal moreinfo="none">strip</literal>: The number of
 5.10785 +	      leading path elements to strip from a repository's path
 5.10786 +	      name to construct a partial path for a URL. For example,
 5.10787 +	      if the repositories on your server live under <filename class="directory" moreinfo="none">/home/hg/repos</filename>, and you
 5.10788 +	      have a repository whose path is <filename class="directory" moreinfo="none">/home/hg/repos/app/tests</filename>,
 5.10789 +	      then setting <literal moreinfo="none">strip</literal> to
 5.10790 +	      <literal moreinfo="none">4</literal> will give a partial path of
 5.10791 +	      <filename class="directory" moreinfo="none">app/tests</filename>.  The
 5.10792 +	      hook will make this partial path available when
 5.10793 +	      expanding a template, as <literal moreinfo="none">webroot</literal>.
 5.10794 +	    </para>
 5.10795 +	  </listitem>
 5.10796 +	  <listitem><para id="x_25f"><literal moreinfo="none">template</literal>: The text of the
 5.10797 +	      template to use.  In addition to the usual
 5.10798 +	      changeset-related variables, this template can use
 5.10799 +	      <literal moreinfo="none">hgweb</literal> (the value of the
 5.10800 +	      <literal moreinfo="none">hgweb</literal> configuration item above) and
 5.10801 +	      <literal moreinfo="none">webroot</literal> (the path constructed using
 5.10802 +	      <literal moreinfo="none">strip</literal> above).
 5.10803 +	    </para>
 5.10804 +	  </listitem></itemizedlist>
 5.10805 +
 5.10806 +	<para id="x_260">In addition, you can add a <envar role="rc-item-web">baseurl</envar> item to the <literal role="rc-web" moreinfo="none">web</literal> section of your <filename role="special" moreinfo="none">~/.hgrc</filename>.  The <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook will make this
 5.10807 +	  available when expanding a template, as the base string to
 5.10808 +	  use when constructing a URL that will let users browse from
 5.10809 +	  a Bugzilla comment to view a changeset.  Example:
 5.10810 +	</para>
 5.10811 +	<programlisting format="linespecific">[web]
 5.10812 +baseurl = http://hg.domain.com/</programlisting>
 5.10813 +
 5.10814 +	<para id="x_261">Here is an example set of <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook config information.
 5.10815 +	</para>
 5.10816 +
 5.10817 +	<!-- BEGIN ch10/bugzilla-config.lst -->
 5.10818 +<programlisting format="linespecific">[bugzilla]
 5.10819 +host = bugzilla.example.com
 5.10820 +password = mypassword version = 2.16
 5.10821 +# server-side repos live in /home/hg/repos, so strip 4 leading
 5.10822 +# separators
 5.10823 +strip = 4
 5.10824 +hgweb = http://hg.example.com/
 5.10825 +usermap = /home/hg/repos/notify/bugzilla.conf
 5.10826 +template = Changeset {node|short}, made by {author} in the {webroot}
 5.10827 +  repo, refers to this bug.\n
 5.10828 +  For complete details, see
 5.10829 +  {hgweb}{webroot}?cmd=changeset;node={node|short}\n
 5.10830 +  Changeset description:\n
 5.10831 +  \t{desc|tabindent}</programlisting>
 5.10832 +<!-- END ch10/bugzilla-config.lst -->
 5.10833 +
 5.10834 +
 5.10835 +      </sect3>
 5.10836 +      <sect3>
 5.10837 +	<title>Testing and troubleshooting</title>
 5.10838 +
 5.10839 +	<para id="x_262">The most common problems with configuring the <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook relate to running
 5.10840 +	  Bugzilla's <filename moreinfo="none">processmail</filename> script and
 5.10841 +	  mapping committer names to user names.
 5.10842 +	</para>
 5.10843 +
 5.10844 +	<para id="x_263">Recall from <xref linkend="sec:hook:bugzilla:config"/> above that the user
 5.10845 +	  that runs the Mercurial process on the server is also the
 5.10846 +	  one that will run the <filename moreinfo="none">processmail</filename>
 5.10847 +	  script.  The <filename moreinfo="none">processmail</filename> script
 5.10848 +	  sometimes causes Bugzilla to write to files in its
 5.10849 +	  configuration directory, and Bugzilla's configuration files
 5.10850 +	  are usually owned by the user that your web server runs
 5.10851 +	  under.
 5.10852 +	</para>
 5.10853 +
 5.10854 +	<para id="x_264">You can cause <filename moreinfo="none">processmail</filename> to be run
 5.10855 +	  with the suitable user's identity using the
 5.10856 +	  <command moreinfo="none">sudo</command> command.  Here is an example entry
 5.10857 +	  for a <filename moreinfo="none">sudoers</filename> file.
 5.10858 +	</para>
 5.10859 +	<programlisting format="linespecific">hg_user = (httpd_user)
 5.10860 +NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
 5.10861 +	<para id="x_265">This allows the <literal moreinfo="none">hg_user</literal> user to run a
 5.10862 +	  <filename moreinfo="none">processmail-wrapper</filename> program under the
 5.10863 +	  identity of <literal moreinfo="none">httpd_user</literal>.
 5.10864 +	</para>
 5.10865 +
 5.10866 +	<para id="x_266">This indirection through a wrapper script is necessary,
 5.10867 +	  because <filename moreinfo="none">processmail</filename> expects to be run
 5.10868 +	  with its current directory set to wherever you installed
 5.10869 +	  Bugzilla; you can't specify that kind of constraint in a
 5.10870 +	  <filename moreinfo="none">sudoers</filename> file.  The contents of the
 5.10871 +	  wrapper script are simple:
 5.10872 +	</para>
 5.10873 +	<programlisting format="linespecific">#!/bin/sh
 5.10874 +cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
 5.10875 +	<para id="x_267">It doesn't seem to matter what email address you pass to
 5.10876 +	  <filename moreinfo="none">processmail</filename>.
 5.10877 +	</para>
 5.10878 +
 5.10879 +	<para id="x_268">If your <literal role="rc-usermap" moreinfo="none">usermap</literal> is
 5.10880 +	  not set up correctly, users will see an error message from
 5.10881 +	  the <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook when they
 5.10882 +	  push changes to the server.  The error message will look
 5.10883 +	  like this:
 5.10884 +	</para>
 5.10885 +	<programlisting format="linespecific">cannot find bugzilla user id for john.q.public@example.com</programlisting>
 5.10886 +	<para id="x_269">What this means is that the committer's address,
 5.10887 +	  <literal moreinfo="none">john.q.public@example.com</literal>, is not a valid
 5.10888 +	  Bugzilla user name, nor does it have an entry in your
 5.10889 +	  <literal role="rc-usermap" moreinfo="none">usermap</literal> that maps it to
 5.10890 +	  a valid Bugzilla user name.
 5.10891 +	</para>
 5.10892 +
 5.10893 +      </sect3>    </sect2>
 5.10894 +
 5.10895 +    <sect2>
 5.10896 +      <title><literal role="hg-ext" moreinfo="none">notify</literal>—send email
 5.10897 +	notifications</title>
 5.10898 +
 5.10899 +      <para id="x_26a">Although Mercurial's built-in web server provides RSS
 5.10900 +	feeds of changes in every repository, many people prefer to
 5.10901 +	receive change notifications via email.  The <literal role="hg-ext" moreinfo="none">notify</literal> hook lets you send out
 5.10902 +	notifications to a set of email addresses whenever changesets
 5.10903 +	arrive that those subscribers are interested in.
 5.10904 +      </para>
 5.10905 +
 5.10906 +      <para id="x_26b">As with the <literal role="hg-ext" moreinfo="none">bugzilla</literal>
 5.10907 +	hook, the <literal role="hg-ext" moreinfo="none">notify</literal> hook is
 5.10908 +	template-driven, so you can customise the contents of the
 5.10909 +	notification messages that it sends.
 5.10910 +      </para>
 5.10911 +
 5.10912 +      <para id="x_26c">By default, the <literal role="hg-ext" moreinfo="none">notify</literal>
 5.10913 +	hook includes a diff of every changeset that it sends out; you
 5.10914 +	can limit the size of the diff, or turn this feature off
 5.10915 +	entirely.  It is useful for letting subscribers review changes
 5.10916 +	immediately, rather than clicking to follow a URL.
 5.10917 +      </para>
 5.10918 +
 5.10919 +      <sect3>
 5.10920 +	<title>Configuring the <literal role="hg-ext" moreinfo="none">notify</literal>
 5.10921 +	  hook</title>
 5.10922 +
 5.10923 +	<para id="x_26d">You can set up the <literal role="hg-ext" moreinfo="none">notify</literal> hook to send one email
 5.10924 +	  message per incoming changeset, or one per incoming group of
 5.10925 +	  changesets (all those that arrived in a single pull or
 5.10926 +	  push).
 5.10927 +	</para>
 5.10928 +	<programlisting format="linespecific">[hooks]
 5.10929 +# send one email per group of changes
 5.10930 +changegroup.notify = python:hgext.notify.hook
 5.10931 +# send one email per change
 5.10932 +incoming.notify = python:hgext.notify.hook</programlisting>
 5.10933 +
 5.10934 +	<para id="x_26e">Configuration information for this hook lives in the
 5.10935 +	  <literal role="rc-notify" moreinfo="none">notify</literal> section of a
 5.10936 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file.
 5.10937 +	</para>
 5.10938 +	<itemizedlist>
 5.10939 +	  <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>:
 5.10940 +	      By default, this hook does not send out email at all;
 5.10941 +	      instead, it prints the message that it
 5.10942 +	      <emphasis>would</emphasis> send.  Set this item to
 5.10943 +	      <literal moreinfo="none">false</literal> to allow email to be sent. The
 5.10944 +	      reason that sending of email is turned off by default is
 5.10945 +	      that it takes several tries to configure this extension
 5.10946 +	      exactly as you would like, and it would be bad form to
 5.10947 +	      spam subscribers with a number of <quote>broken</quote>
 5.10948 +	      notifications while you debug your configuration.
 5.10949 +	    </para>
 5.10950 +	  </listitem>
 5.10951 +	  <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>:
 5.10952 +	      The path to a configuration file that contains
 5.10953 +	      subscription information.  This is kept separate from
 5.10954 +	      the main <filename role="special" moreinfo="none">~/.hgrc</filename> so
 5.10955 +	      that you can maintain it in a repository of its own.
 5.10956 +	      People can then clone that repository, update their
 5.10957 +	      subscriptions, and push the changes back to your server.
 5.10958 +	    </para>
 5.10959 +	  </listitem>
 5.10960 +	  <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>:
 5.10961 +	      The number of leading path separator characters to strip
 5.10962 +	      from a repository's path, when deciding whether a
 5.10963 +	      repository has subscribers.  For example, if the
 5.10964 +	      repositories on your server live in <filename class="directory" moreinfo="none">/home/hg/repos</filename>, and
 5.10965 +	      <literal role="hg-ext" moreinfo="none">notify</literal> is considering a
 5.10966 +	      repository named <filename class="directory" moreinfo="none">/home/hg/repos/shared/test</filename>, 
 5.10967 +	      setting <envar role="rc-item-notify">strip</envar> to
 5.10968 +	      <literal moreinfo="none">4</literal> will cause <literal role="hg-ext" moreinfo="none">notify</literal> to trim the path it
 5.10969 +	      considers down to <filename class="directory" moreinfo="none">shared/test</filename>, and it will
 5.10970 +	      match subscribers against that.
 5.10971 +	    </para>
 5.10972 +	  </listitem>
 5.10973 +	  <listitem><para id="x_272"><envar role="rc-item-notify">template</envar>: The template
 5.10974 +	      text to use when sending messages.  This specifies both
 5.10975 +	      the contents of the message header and its body.
 5.10976 +	    </para>
 5.10977 +	  </listitem>
 5.10978 +	  <listitem><para id="x_273"><envar role="rc-item-notify">maxdiff</envar>: The maximum
 5.10979 +	      number of lines of diff data to append to the end of a
 5.10980 +	      message.  If a diff is longer than this, it is
 5.10981 +	      truncated.  By default, this is set to 300.  Set this to
 5.10982 +	      <literal moreinfo="none">0</literal> to omit diffs from notification
 5.10983 +	      emails.
 5.10984 +	    </para>
 5.10985 +	  </listitem>
 5.10986 +	  <listitem><para id="x_274"><envar role="rc-item-notify">sources</envar>: A list of
 5.10987 +	      sources of changesets to consider.  This lets you limit
 5.10988 +	      <literal role="hg-ext" moreinfo="none">notify</literal> to only sending
 5.10989 +	      out email about changes that remote users pushed into
 5.10990 +	      this repository via a server, for example.  See 
 5.10991 +	      <xref linkend="sec:hook:sources"/> for the sources you
 5.10992 +	      can specify here.
 5.10993 +	    </para>
 5.10994 +	  </listitem></itemizedlist>
 5.10995 +
 5.10996 +	<para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar>
 5.10997 +	  item in the <literal role="rc-web" moreinfo="none">web</literal> section,
 5.10998 +	  you can use it in a template; it will be available as
 5.10999 +	  <literal moreinfo="none">webroot</literal>.
 5.11000 +	</para>
 5.11001 +
 5.11002 +	<para id="x_276">Here is an example set of <literal role="hg-ext" moreinfo="none">notify</literal> configuration information.
 5.11003 +	</para>
 5.11004 +
 5.11005 +	<!-- BEGIN ch10/notify-config.lst -->
 5.11006 +<programlisting format="linespecific">[notify]
 5.11007 +# really send email
 5.11008 +test = false
 5.11009 +# subscriber data lives in the notify repo
 5.11010 +config = /home/hg/repos/notify/notify.conf
 5.11011 +# repos live in /home/hg/repos on server, so strip 4 "/" chars
 5.11012 +strip = 4
 5.11013 +template = X-Hg-Repo: {webroot}\n
 5.11014 +  Subject: {webroot}: {desc|firstline|strip}\n
 5.11015 +  From: {author}
 5.11016 +  \n\n
 5.11017 +  changeset {node|short} in {root}
 5.11018 +  \n\ndetails:
 5.11019 +  {baseurl}{webroot}?cmd=changeset;node={node|short}
 5.11020 +  description: {desc|tabindent|strip}
 5.11021 +
 5.11022 +[web]
 5.11023 +baseurl =
 5.11024 +http://hg.example.com/</programlisting>
 5.11025 +<!-- END ch10/notify-config.lst -->
 5.11026 +
 5.11027 +
 5.11028 +	<para id="x_277">This will produce a message that looks like the
 5.11029 +	  following:
 5.11030 +	</para>
 5.11031 +
 5.11032 +	<!-- BEGIN ch10/notify-config-mail.lst -->
 5.11033 +<programlisting format="linespecific">X-Hg-Repo: tests/slave
 5.11034 +Subject: tests/slave: Handle error case when slave has no buffers
 5.11035 +Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
 5.11036 +
 5.11037 +changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
 5.11038 +
 5.11039 +details:
 5.11040 +http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5 
 5.11041 +
 5.11042 +description: Handle error case when slave has no buffers
 5.11043 +
 5.11044 +diffs (54 lines):
 5.11045 +diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
 5.11046 +--- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
 5.11047 ++++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
 5.11048 +@@ -212,6 +212,15 @@ static __inline__
 5.11049 +void test_headers(void *h)
 5.11050 +[...snip...]</programlisting>
 5.11051 +<!-- END ch10/notify-config-mail.lst -->
 5.11052 +
 5.11053 +
 5.11054 +      </sect3>
 5.11055 +      <sect3>
 5.11056 +	<title>Testing and troubleshooting</title>
 5.11057 +
 5.11058 +	<para id="x_278">Do not forget that by default, the <literal role="hg-ext" moreinfo="none">notify</literal> extension <emphasis>will not
 5.11059 +	  send any mail</emphasis> until you explicitly configure it to do so,
 5.11060 +	  by setting <envar role="rc-item-notify">test</envar> to
 5.11061 +	  <literal moreinfo="none">false</literal>.  Until you do that, it simply
 5.11062 +	  prints the message it <emphasis>would</emphasis> send.
 5.11063 +	</para>
 5.11064 +
 5.11065 +      </sect3>
 5.11066 +    </sect2>
 5.11067 +  </sect1>
 5.11068 +  <sect1 id="sec:hook:ref">
 5.11069 +    <title>Information for writers of hooks</title>
 5.11070 +
 5.11071 +    <sect2>
 5.11072 +      <title>In-process hook execution</title>
 5.11073 +
 5.11074 +      <para id="x_279">An in-process hook is called with arguments of the
 5.11075 +	following form:
 5.11076 +      </para>
 5.11077 +      <programlisting format="linespecific">def myhook(ui, repo, **kwargs): pass</programlisting>
 5.11078 +      <para id="x_27a">The <literal moreinfo="none">ui</literal> parameter is a <literal role="py-mod-mercurial.ui" moreinfo="none">ui</literal> object. The
 5.11079 +	<literal moreinfo="none">repo</literal> parameter is a <literal role="py-mod-mercurial.localrepo" moreinfo="none">localrepository</literal>
 5.11080 +	object.  The names and values of the
 5.11081 +	<literal moreinfo="none">**kwargs</literal> parameters depend on the hook
 5.11082 +	being invoked, with the following common features:
 5.11083 +      </para>
 5.11084 +      <itemizedlist>
 5.11085 +	<listitem><para id="x_27b">If a parameter is named
 5.11086 +	    <literal moreinfo="none">node</literal> or <literal moreinfo="none">parentN</literal>, it
 5.11087 +	    will contain a hexadecimal changeset ID. The empty string
 5.11088 +	    is used to represent <quote>null changeset ID</quote>
 5.11089 +	    instead of a string of zeroes.
 5.11090 +	  </para>
 5.11091 +	</listitem>
 5.11092 +	<listitem><para id="x_27c">If a parameter is named
 5.11093 +	    <literal moreinfo="none">url</literal>, it will contain the URL of a
 5.11094 +	    remote repository, if that can be determined.
 5.11095 +	  </para>
 5.11096 +	</listitem>
 5.11097 +	<listitem><para id="x_27d">Boolean-valued parameters are represented as
 5.11098 +	    Python <literal moreinfo="none">bool</literal> objects.
 5.11099 +	  </para>
 5.11100 +	</listitem></itemizedlist>
 5.11101 +
 5.11102 +      <para id="x_27e">An in-process hook is called without a change to the
 5.11103 +	process's working directory (unlike external hooks, which are
 5.11104 +	run in the root of the repository).  It must not change the
 5.11105 +	process's working directory, or it will cause any calls it
 5.11106 +	makes into the Mercurial API to fail.
 5.11107 +      </para>
 5.11108 +
 5.11109 +      <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it
 5.11110 +	is considered to have succeeded.  If it returns a boolean
 5.11111 +	<quote>true</quote> value or raises an exception, it is
 5.11112 +	considered to have failed.  A useful way to think of the
 5.11113 +	calling convention is <quote>tell me if you fail</quote>.
 5.11114 +      </para>
 5.11115 +
 5.11116 +      <para id="x_280">Note that changeset IDs are passed into Python hooks as
 5.11117 +	hexadecimal strings, not the binary hashes that Mercurial's
 5.11118 +	APIs normally use.  To convert a hash from hex to binary, use
 5.11119 +	the <literal moreinfo="none">bin</literal> function.
 5.11120 +      </para>
 5.11121 +    </sect2>
 5.11122 +
 5.11123 +    <sect2>
 5.11124 +      <title>External hook execution</title>
 5.11125 +
 5.11126 +      <para id="x_281">An external hook is passed to the shell of the user
 5.11127 +	running Mercurial. Features of that shell, such as variable
 5.11128 +	substitution and command redirection, are available.  The hook
 5.11129 +	is run in the root directory of the repository (unlike
 5.11130 +	in-process hooks, which are run in the same directory that
 5.11131 +	Mercurial was run in).
 5.11132 +      </para>
 5.11133 +
 5.11134 +      <para id="x_282">Hook parameters are passed to the hook as environment
 5.11135 +	variables.  Each environment variable's name is converted in
 5.11136 +	upper case and prefixed with the string
 5.11137 +	<quote><literal moreinfo="none">HG_</literal></quote>.  For example, if the
 5.11138 +	name of a parameter is <quote><literal moreinfo="none">node</literal></quote>,
 5.11139 +	the name of the environment variable representing that
 5.11140 +	parameter will be <quote><literal moreinfo="none">HG_NODE</literal></quote>.
 5.11141 +      </para>
 5.11142 +
 5.11143 +      <para id="x_283">A boolean parameter is represented as the string
 5.11144 +	<quote><literal moreinfo="none">1</literal></quote> for <quote>true</quote>,
 5.11145 +	<quote><literal moreinfo="none">0</literal></quote> for <quote>false</quote>.
 5.11146 +	If an environment variable is named <envar>HG_NODE</envar>,
 5.11147 +	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
 5.11148 +	contains a changeset ID represented as a hexadecimal string.
 5.11149 +	The empty string is used to represent <quote>null changeset
 5.11150 +	  ID</quote> instead of a string of zeroes.  If an environment
 5.11151 +	variable is named <envar>HG_URL</envar>, it will contain the
 5.11152 +	URL of a remote repository, if that can be determined.
 5.11153 +      </para>
 5.11154 +
 5.11155 +      <para id="x_284">If a hook exits with a status of zero, it is considered to
 5.11156 +	have succeeded.  If it exits with a non-zero status, it is
 5.11157 +	considered to have failed.
 5.11158 +      </para>
 5.11159 +    </sect2>
 5.11160 +
 5.11161 +    <sect2>
 5.11162 +      <title>Finding out where changesets come from</title>
 5.11163 +
 5.11164 +      <para id="x_285">A hook that involves the transfer of changesets between a
 5.11165 +	local repository and another may be able to find out
 5.11166 +	information about the <quote>far side</quote>.  Mercurial
 5.11167 +	knows <emphasis>how</emphasis> changes are being transferred,
 5.11168 +	and in many cases <emphasis>where</emphasis> they are being
 5.11169 +	transferred to or from.
 5.11170 +      </para>
 5.11171 +
 5.11172 +      <sect3 id="sec:hook:sources">
 5.11173 +	<title>Sources of changesets</title>
 5.11174 +
 5.11175 +	<para id="x_286">Mercurial will tell a hook what means are, or were, used
 5.11176 +	  to transfer changesets between repositories.  This is
 5.11177 +	  provided by Mercurial in a Python parameter named
 5.11178 +	  <literal moreinfo="none">source</literal>, or an environment variable named
 5.11179 +	  <envar>HG_SOURCE</envar>.
 5.11180 +	</para>
 5.11181 +
 5.11182 +	<itemizedlist>
 5.11183 +	  <listitem><para id="x_287"><literal moreinfo="none">serve</literal>: Changesets are
 5.11184 +	      transferred to or from a remote repository over http or
 5.11185 +	      ssh.
 5.11186 +	    </para>
 5.11187 +	  </listitem>
 5.11188 +	  <listitem><para id="x_288"><literal moreinfo="none">pull</literal>: Changesets are
 5.11189 +	      being transferred via a pull from one repository into
 5.11190 +	      another.
 5.11191 +	    </para>
 5.11192 +	  </listitem>
 5.11193 +	  <listitem><para id="x_289"><literal moreinfo="none">push</literal>: Changesets are
 5.11194 +	      being transferred via a push from one repository into
 5.11195 +	      another.
 5.11196 +	    </para>
 5.11197 +	  </listitem>
 5.11198 +	  <listitem><para id="x_28a"><literal moreinfo="none">bundle</literal>: Changesets are
 5.11199 +	      being transferred to or from a bundle.
 5.11200 +	    </para>
 5.11201 +	  </listitem></itemizedlist>
 5.11202 +      </sect3>
 5.11203 +
 5.11204 +      <sect3 id="sec:hook:url">
 5.11205 +	<title>Where changes are going—remote repository
 5.11206 +	  URLs</title>
 5.11207 +
 5.11208 +	<para id="x_28b">When possible, Mercurial will tell a hook the location
 5.11209 +	  of the <quote>far side</quote> of an activity that transfers
 5.11210 +	  changeset data between repositories.  This is provided by
 5.11211 +	  Mercurial in a Python parameter named
 5.11212 +	  <literal moreinfo="none">url</literal>, or an environment variable named
 5.11213 +	  <envar>HG_URL</envar>.
 5.11214 +	</para>
 5.11215 +
 5.11216 +	<para id="x_28c">This information is not always known.  If a hook is
 5.11217 +	  invoked in a repository that is being served via http or
 5.11218 +	  ssh, Mercurial cannot tell where the remote repository is,
 5.11219 +	  but it may know where the client is connecting from.  In
 5.11220 +	  such cases, the URL will take one of the following forms:
 5.11221 +	</para>
 5.11222 +	<itemizedlist>
 5.11223 +	  <listitem><para id="x_28d"><literal moreinfo="none">remote:ssh:1.2.3.4</literal>—remote 
 5.11224 +	      ssh client, at the IP address
 5.11225 +	      <literal moreinfo="none">1.2.3.4</literal>.
 5.11226 +	    </para>
 5.11227 +	  </listitem>
 5.11228 +	  <listitem><para id="x_28e"><literal moreinfo="none">remote:http:1.2.3.4</literal>—remote 
 5.11229 +	      http client, at the IP address
 5.11230 +	      <literal moreinfo="none">1.2.3.4</literal>.  If the client is using SSL,
 5.11231 +	      this will be of the form
 5.11232 +	      <literal moreinfo="none">remote:https:1.2.3.4</literal>.
 5.11233 +	    </para>
 5.11234 +	  </listitem>
 5.11235 +	  <listitem><para id="x_28f">Empty—no information could be
 5.11236 +	      discovered about the remote client.
 5.11237 +	    </para>
 5.11238 +	  </listitem></itemizedlist>
 5.11239 +      </sect3>
 5.11240 +    </sect2>
 5.11241 +  </sect1>
 5.11242 +  <sect1>
 5.11243 +    <title>Hook reference</title>
 5.11244 +
 5.11245 +    <sect2 id="sec:hook:changegroup">
 5.11246 +      <title><literal role="hook" moreinfo="none">changegroup</literal>—after
 5.11247 +	remote changesets added</title>
 5.11248 +
 5.11249 +      <para id="x_290">This hook is run after a group of pre-existing changesets
 5.11250 +	has been added to the repository, for example via a <command role="hg-cmd" moreinfo="none">hg pull</command> or <command role="hg-cmd" moreinfo="none">hg
 5.11251 +	  unbundle</command>.  This hook is run once per operation
 5.11252 +	that added one or more changesets.  This is in contrast to the
 5.11253 +	<literal role="hook" moreinfo="none">incoming</literal> hook, which is run
 5.11254 +	once per changeset, regardless of whether the changesets
 5.11255 +	arrive in a group.
 5.11256 +      </para>
 5.11257 +
 5.11258 +      <para id="x_291">Some possible uses for this hook include kicking off an
 5.11259 +	automated build or test of the added changesets, updating a
 5.11260 +	bug database, or notifying subscribers that a repository
 5.11261 +	contains new changes.
 5.11262 +      </para>
 5.11263 +
 5.11264 +      <para id="x_292">Parameters to this hook:
 5.11265 +      </para>
 5.11266 +      <itemizedlist>
 5.11267 +	<listitem><para id="x_293"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11268 +	    changeset ID of the first changeset in the group that was
 5.11269 +	    added.  All changesets between this and
 5.11270 +	    <literal role="tag" moreinfo="none">tip</literal>, inclusive, were added by a single
 5.11271 +	    <command role="hg-cmd" moreinfo="none">hg pull</command>, <command role="hg-cmd" moreinfo="none">hg push</command> or <command role="hg-cmd" moreinfo="none">hg unbundle</command>.
 5.11272 +	  </para>
 5.11273 +	</listitem>
 5.11274 +	<listitem><para id="x_294"><literal moreinfo="none">source</literal>: A
 5.11275 +	    string.  The source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 5.11276 +	  </para>
 5.11277 +	</listitem>
 5.11278 +	<listitem><para id="x_295"><literal moreinfo="none">url</literal>: A URL.  The
 5.11279 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 5.11280 +	  </para>
 5.11281 +	</listitem></itemizedlist>
 5.11282 +
 5.11283 +      <para id="x_296">See also: <literal role="hook" moreinfo="none">incoming</literal> (<xref linkend="sec:hook:incoming"/>), <literal role="hook" moreinfo="none">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>), <literal role="hook" moreinfo="none">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>)
 5.11284 +      </para>
 5.11285 +    </sect2>
 5.11286 +
 5.11287 +    <sect2 id="sec:hook:commit">
 5.11288 +      <title><literal role="hook" moreinfo="none">commit</literal>—after a new
 5.11289 +	changeset is created</title>
 5.11290 +
 5.11291 +      <para id="x_297">This hook is run after a new changeset has been created.
 5.11292 +      </para>
 5.11293 +
 5.11294 +      <para id="x_298">Parameters to this hook:
 5.11295 +      </para>
 5.11296 +      <itemizedlist>
 5.11297 +	<listitem><para id="x_299"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11298 +	    changeset ID of the newly committed changeset.
 5.11299 +	  </para>
 5.11300 +	</listitem>
 5.11301 +	<listitem><para id="x_29a"><literal moreinfo="none">parent1</literal>: A changeset ID.
 5.11302 +	    The changeset ID of the first parent of the newly
 5.11303 +	    committed changeset.
 5.11304 +	  </para>
 5.11305 +	</listitem>
 5.11306 +	<listitem><para id="x_29b"><literal moreinfo="none">parent2</literal>: A changeset ID.
 5.11307 +	    The changeset ID of the second parent of the newly
 5.11308 +	    committed changeset.
 5.11309 +	  </para>
 5.11310 +	</listitem></itemizedlist>
 5.11311 +
 5.11312 +      <para id="x_29c">See also: <literal role="hook" moreinfo="none">precommit</literal> (<xref linkend="sec:hook:precommit"/>), <literal role="hook" moreinfo="none">pretxncommit</literal> (<xref linkend="sec:hook:pretxncommit"/>)
 5.11313 +      </para>
 5.11314 +    </sect2>
 5.11315 +
 5.11316 +    <sect2 id="sec:hook:incoming">
 5.11317 +      <title><literal role="hook" moreinfo="none">incoming</literal>—after one
 5.11318 +	remote changeset is added</title>
 5.11319 +
 5.11320 +      <para id="x_29d">This hook is run after a pre-existing changeset has been
 5.11321 +	added to the repository, for example via a <command role="hg-cmd" moreinfo="none">hg push</command>.  If a group of changesets
 5.11322 +	was added in a single operation, this hook is called once for
 5.11323 +	each added changeset.
 5.11324 +      </para>
 5.11325 +
 5.11326 +      <para id="x_29e">You can use this hook for the same purposes as
 5.11327 +	the <literal role="hook" moreinfo="none">changegroup</literal> hook (<xref linkend="sec:hook:changegroup"/>); it's simply more
 5.11328 +	convenient sometimes to run a hook once per group of
 5.11329 +	changesets, while other times it's handier once per changeset.
 5.11330 +      </para>
 5.11331 +
 5.11332 +      <para id="x_29f">Parameters to this hook:
 5.11333 +      </para>
 5.11334 +      <itemizedlist>
 5.11335 +	<listitem><para id="x_2a0"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11336 +	    ID of the newly added changeset.
 5.11337 +	  </para>
 5.11338 +	</listitem>
 5.11339 +	<listitem><para id="x_2a1"><literal moreinfo="none">source</literal>: A
 5.11340 +	    string.  The source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 5.11341 +	  </para>
 5.11342 +	</listitem>
 5.11343 +	<listitem><para id="x_2a2"><literal moreinfo="none">url</literal>: A URL.  The
 5.11344 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 5.11345 +	  </para>
 5.11346 +	</listitem></itemizedlist>
 5.11347 +
 5.11348 +      <para id="x_2a3">See also: <literal role="hook" moreinfo="none">changegroup</literal> (<xref linkend="sec:hook:changegroup"/>) <literal role="hook" moreinfo="none">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>), <literal role="hook" moreinfo="none">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>)
 5.11349 +      </para>
 5.11350 +    </sect2>
 5.11351 +
 5.11352 +    <sect2 id="sec:hook:outgoing">
 5.11353 +      <title><literal role="hook" moreinfo="none">outgoing</literal>—after
 5.11354 +	changesets are propagated</title>
 5.11355 +
 5.11356 +      <para id="x_2a4">This hook is run after a group of changesets has been
 5.11357 +	propagated out of this repository, for example by a <command role="hg-cmd" moreinfo="none">hg push</command> or <command role="hg-cmd" moreinfo="none">hg
 5.11358 +	  bundle</command> command.
 5.11359 +      </para>
 5.11360 +
 5.11361 +      <para id="x_2a5">One possible use for this hook is to notify administrators
 5.11362 +	that changes have been pulled.
 5.11363 +      </para>
 5.11364 +
 5.11365 +      <para id="x_2a6">Parameters to this hook:
 5.11366 +      </para>
 5.11367 +      <itemizedlist>
 5.11368 +	<listitem><para id="x_2a7"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11369 +	    changeset ID of the first changeset of the group that was
 5.11370 +	    sent.
 5.11371 +	  </para>
 5.11372 +	</listitem>
 5.11373 +	<listitem><para id="x_2a8"><literal moreinfo="none">source</literal>: A string.  The
 5.11374 +	    source of the of the operation (see <xref linkend="sec:hook:sources"/>).  If a remote
 5.11375 +	    client pulled changes from this repository,
 5.11376 +	    <literal moreinfo="none">source</literal> will be
 5.11377 +	    <literal moreinfo="none">serve</literal>.  If the client that obtained
 5.11378 +	    changes from this repository was local,
 5.11379 +	    <literal moreinfo="none">source</literal> will be
 5.11380 +	    <literal moreinfo="none">bundle</literal>, <literal moreinfo="none">pull</literal>, or
 5.11381 +	    <literal moreinfo="none">push</literal>, depending on the operation the
 5.11382 +	    client performed.
 5.11383 +	  </para>
 5.11384 +	</listitem>
 5.11385 +	<listitem><para id="x_2a9"><literal moreinfo="none">url</literal>: A URL.  The
 5.11386 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 5.11387 +	  </para>
 5.11388 +	</listitem></itemizedlist>
 5.11389 +
 5.11390 +      <para id="x_2aa">See also: <literal role="hook" moreinfo="none">preoutgoing</literal> (<xref linkend="sec:hook:preoutgoing"/>)
 5.11391 +      </para>
 5.11392 +    </sect2>
 5.11393 +
 5.11394 +    <sect2 id="sec:hook:prechangegroup">
 5.11395 +      <title><literal role="hook" moreinfo="none">prechangegroup</literal>—before starting
 5.11396 +	to add remote changesets</title>
 5.11397 +
 5.11398 +      <para id="x_2ab">This controlling hook is run before Mercurial begins to
 5.11399 +	add a group of changesets from another repository.
 5.11400 +      </para>
 5.11401 +
 5.11402 +      <para id="x_2ac">This hook does not have any information about the
 5.11403 +	changesets to be added, because it is run before transmission
 5.11404 +	of those changesets is allowed to begin.  If this hook fails,
 5.11405 +	the changesets will not be transmitted.
 5.11406 +      </para>
 5.11407 +
 5.11408 +      <para id="x_2ad">One use for this hook is to prevent external changes from
 5.11409 +	being added to a repository.  For example, you could use this
 5.11410 +	to <quote>freeze</quote> a server-hosted branch temporarily or
 5.11411 +	permanently so that users cannot push to it, while still
 5.11412 +	allowing a local administrator to modify the repository.
 5.11413 +      </para>
 5.11414 +
 5.11415 +      <para id="x_2ae">Parameters to this hook:
 5.11416 +      </para>
 5.11417 +      <itemizedlist>
 5.11418 +	<listitem><para id="x_2af"><literal moreinfo="none">source</literal>: A string.  The
 5.11419 +	    source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 5.11420 +	  </para>
 5.11421 +	</listitem>
 5.11422 +	<listitem><para id="x_2b0"><literal moreinfo="none">url</literal>: A URL.  The
 5.11423 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 5.11424 +	  </para>
 5.11425 +	</listitem></itemizedlist>
 5.11426 +
 5.11427 +      <para id="x_2b1">See also: <literal role="hook" moreinfo="none">changegroup</literal> (<xref linkend="sec:hook:changegroup"/>), <literal role="hook" moreinfo="none">incoming</literal> (<xref linkend="sec:hook:incoming"/>), <literal role="hook" moreinfo="none">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>)
 5.11428 +      </para>
 5.11429 +    </sect2>
 5.11430 +
 5.11431 +    <sect2 id="sec:hook:precommit">
 5.11432 +      <title><literal role="hook" moreinfo="none">precommit</literal>—before
 5.11433 +	starting to commit a changeset</title>
 5.11434 +
 5.11435 +      <para id="x_2b2">This hook is run before Mercurial begins to commit a new
 5.11436 +	changeset. It is run before Mercurial has any of the metadata
 5.11437 +	for the commit, such as the files to be committed, the commit
 5.11438 +	message, or the commit date.
 5.11439 +      </para>
 5.11440 +
 5.11441 +      <para id="x_2b3">One use for this hook is to disable the ability to commit
 5.11442 +	new changesets, while still allowing incoming changesets.
 5.11443 +	Another is to run a build or test, and only allow the commit
 5.11444 +	to begin if the build or test succeeds.
 5.11445 +      </para>
 5.11446 +
 5.11447 +      <para id="x_2b4">Parameters to this hook:
 5.11448 +      </para>
 5.11449 +      <itemizedlist>
 5.11450 +	<listitem><para id="x_2b5"><literal moreinfo="none">parent1</literal>: A changeset ID.
 5.11451 +	    The changeset ID of the first parent of the working
 5.11452 +	    directory.
 5.11453 +	  </para>
 5.11454 +	</listitem>
 5.11455 +	<listitem><para id="x_2b6"><literal moreinfo="none">parent2</literal>: A changeset ID.
 5.11456 +	    The changeset ID of the second parent of the working
 5.11457 +	    directory.
 5.11458 +	  </para>
 5.11459 +	</listitem></itemizedlist>
 5.11460 +      <para id="x_2b7">If the commit proceeds, the parents of the working
 5.11461 +	directory will become the parents of the new changeset.
 5.11462 +      </para>
 5.11463 +
 5.11464 +      <para id="x_2b8">See also: <literal role="hook" moreinfo="none">commit</literal>
 5.11465 +	(<xref linkend="sec:hook:commit"/>), <literal role="hook" moreinfo="none">pretxncommit</literal> (<xref linkend="sec:hook:pretxncommit"/>)
 5.11466 +      </para>
 5.11467 +    </sect2>
 5.11468 +
 5.11469 +    <sect2 id="sec:hook:preoutgoing">
 5.11470 +      <title><literal role="hook" moreinfo="none">preoutgoing</literal>—before
 5.11471 +	starting to propagate changesets</title>
 5.11472 +
 5.11473 +      <para id="x_2b9">This hook is invoked before Mercurial knows the identities
 5.11474 +	of the changesets to be transmitted.
 5.11475 +      </para>
 5.11476 +
 5.11477 +      <para id="x_2ba">One use for this hook is to prevent changes from being
 5.11478 +	transmitted to another repository.
 5.11479 +      </para>
 5.11480 +
 5.11481 +      <para id="x_2bb">Parameters to this hook:
 5.11482 +      </para>
 5.11483 +      <itemizedlist>
 5.11484 +	<listitem><para id="x_2bc"><literal moreinfo="none">source</literal>: A
 5.11485 +	    string.  The source of the operation that is attempting to
 5.11486 +	    obtain changes from this repository (see <xref linkend="sec:hook:sources"/>).  See the documentation
 5.11487 +	    for the <literal moreinfo="none">source</literal> parameter to the
 5.11488 +	    <literal role="hook" moreinfo="none">outgoing</literal> hook, in
 5.11489 +	    <xref linkend="sec:hook:outgoing"/>, for possible values
 5.11490 +	    of this parameter.
 5.11491 +	  </para>
 5.11492 +	</listitem>
 5.11493 +	<listitem><para id="x_2bd"><literal moreinfo="none">url</literal>: A URL.  The
 5.11494 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 5.11495 +	  </para>
 5.11496 +	</listitem></itemizedlist>
 5.11497 +
 5.11498 +      <para id="x_2be">See also: <literal role="hook" moreinfo="none">outgoing</literal> (<xref linkend="sec:hook:outgoing"/>)
 5.11499 +      </para>
 5.11500 +    </sect2>
 5.11501 +
 5.11502 +    <sect2 id="sec:hook:pretag">
 5.11503 +      <title><literal role="hook" moreinfo="none">pretag</literal>—before
 5.11504 +	tagging a changeset</title>
 5.11505 +
 5.11506 +      <para id="x_2bf">This controlling hook is run before a tag is created.  If
 5.11507 +	the hook succeeds, creation of the tag proceeds.  If the hook
 5.11508 +	fails, the tag is not created.
 5.11509 +      </para>
 5.11510 +
 5.11511 +      <para id="x_2c0">Parameters to this hook:
 5.11512 +      </para>
 5.11513 +      <itemizedlist>
 5.11514 +	<listitem><para id="x_2c1"><literal moreinfo="none">local</literal>: A boolean.  Whether
 5.11515 +	    the tag is local to this repository instance (i.e. stored
 5.11516 +	    in <filename role="special" moreinfo="none">.hg/localtags</filename>) or
 5.11517 +	    managed by Mercurial (stored in <filename role="special" moreinfo="none">.hgtags</filename>).
 5.11518 +	  </para>
 5.11519 +	</listitem>
 5.11520 +	<listitem><para id="x_2c2"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11521 +	    ID of the changeset to be tagged.
 5.11522 +	  </para>
 5.11523 +	</listitem>
 5.11524 +	<listitem><para id="x_2c3"><literal moreinfo="none">tag</literal>: A string.  The name of
 5.11525 +	    the tag to be created.
 5.11526 +	  </para>
 5.11527 +	</listitem></itemizedlist>
 5.11528 +
 5.11529 +      <para id="x_2c4">If the tag to be created is
 5.11530 +	revision-controlled, the <literal role="hook" moreinfo="none">precommit</literal> and <literal role="hook" moreinfo="none">pretxncommit</literal> hooks (<xref linkend="sec:hook:commit"/> and <xref linkend="sec:hook:pretxncommit"/>) will also be run.
 5.11531 +      </para>
 5.11532 +
 5.11533 +      <para id="x_2c5">See also: <literal role="hook" moreinfo="none">tag</literal>
 5.11534 +	(<xref linkend="sec:hook:tag"/>)
 5.11535 +      </para>
 5.11536 +    </sect2>
 5.11537 +
 5.11538 +    <sect2 id="sec:hook:pretxnchangegroup">
 5.11539 +      <title><literal role="hook" moreinfo="none">pretxnchangegroup</literal>—before
 5.11540 +	completing addition of remote changesets</title>
 5.11541 +
 5.11542 +      <para id="x_2c6">This controlling hook is run before a
 5.11543 +	transaction—that manages the addition of a group of new
 5.11544 +	changesets from outside the repository—completes.  If
 5.11545 +	the hook succeeds, the transaction completes, and all of the
 5.11546 +	changesets become permanent within this repository.  If the
 5.11547 +	hook fails, the transaction is rolled back, and the data for
 5.11548 +	the changesets is erased.
 5.11549 +      </para>
 5.11550 +
 5.11551 +      <para id="x_2c7">This hook can access the metadata associated with the
 5.11552 +	almost-added changesets, but it should not do anything
 5.11553 +	permanent with this data. It must also not modify the working
 5.11554 +	directory.
 5.11555 +      </para>
 5.11556 +
 5.11557 +      <para id="x_2c8">While this hook is running, if other Mercurial processes
 5.11558 +	access this repository, they will be able to see the
 5.11559 +	almost-added changesets as if they are permanent.  This may
 5.11560 +	lead to race conditions if you do not take steps to avoid
 5.11561 +	them.
 5.11562 +      </para>
 5.11563 +
 5.11564 +      <para id="x_2c9">This hook can be used to automatically vet a group of
 5.11565 +	changesets.  If the hook fails, all of the changesets are
 5.11566 +	<quote>rejected</quote> when the transaction rolls back.
 5.11567 +      </para>
 5.11568 +
 5.11569 +      <para id="x_2ca">Parameters to this hook:
 5.11570 +      </para>
 5.11571 +      <itemizedlist>
 5.11572 +	<listitem><para id="x_2cb"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11573 +	    changeset ID of the first changeset in the group that was
 5.11574 +	    added.  All changesets between this and
 5.11575 +	    <literal role="tag" moreinfo="none">tip</literal>,
 5.11576 +	    inclusive, were added by a single <command role="hg-cmd" moreinfo="none">hg pull</command>, <command role="hg-cmd" moreinfo="none">hg push</command> or <command role="hg-cmd" moreinfo="none">hg unbundle</command>.
 5.11577 +	  </para>
 5.11578 +	</listitem>
 5.11579 +	<listitem><para id="x_2cc"><literal moreinfo="none">source</literal>: A
 5.11580 +	    string.  The source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 5.11581 +	  </para>
 5.11582 +	</listitem>
 5.11583 +	<listitem><para id="x_2cd"><literal moreinfo="none">url</literal>: A URL.  The
 5.11584 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 5.11585 +	  </para>
 5.11586 +	</listitem></itemizedlist>
 5.11587 +
 5.11588 +      <para id="x_2ce">See also: <literal role="hook" moreinfo="none">changegroup</literal> (<xref linkend="sec:hook:changegroup"/>), <literal role="hook" moreinfo="none">incoming</literal> (<xref linkend="sec:hook:incoming"/>), <literal role="hook" moreinfo="none">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>)
 5.11589 +      </para>
 5.11590 +    </sect2>
 5.11591 +
 5.11592 +    <sect2 id="sec:hook:pretxncommit">
 5.11593 +      <title><literal role="hook" moreinfo="none">pretxncommit</literal>—before
 5.11594 +	completing commit of new changeset</title>
 5.11595 +
 5.11596 +      <para id="x_2cf">This controlling hook is run before a
 5.11597 +	transaction—that manages a new commit—completes.
 5.11598 +	If the hook succeeds, the transaction completes and the
 5.11599 +	changeset becomes permanent within this repository.  If the
 5.11600 +	hook fails, the transaction is rolled back, and the commit
 5.11601 +	data is erased.
 5.11602 +      </para>
 5.11603 +
 5.11604 +      <para id="x_2d0">This hook can access the metadata associated with the
 5.11605 +	almost-new changeset, but it should not do anything permanent
 5.11606 +	with this data.  It must also not modify the working
 5.11607 +	directory.
 5.11608 +      </para>
 5.11609 +
 5.11610 +      <para id="x_2d1">While this hook is running, if other Mercurial processes
 5.11611 +	access this repository, they will be able to see the
 5.11612 +	almost-new changeset as if it is permanent.  This may lead to
 5.11613 +	race conditions if you do not take steps to avoid them.
 5.11614 +      </para>
 5.11615 +
 5.11616 +      <para id="x_2d2">Parameters to this hook:</para>
 5.11617 +
 5.11618 +      <itemizedlist>
 5.11619 +	<listitem><para id="x_2d3"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11620 +	    changeset ID of the newly committed changeset.
 5.11621 +	  </para>
 5.11622 +	</listitem>
 5.11623 +	<listitem><para id="x_2d4"><literal moreinfo="none">parent1</literal>: A changeset ID.
 5.11624 +	    The changeset ID of the first parent of the newly
 5.11625 +	    committed changeset.
 5.11626 +	  </para>
 5.11627 +	</listitem>
 5.11628 +	<listitem><para id="x_2d5"><literal moreinfo="none">parent2</literal>: A changeset ID.
 5.11629 +	    The changeset ID of the second parent of the newly
 5.11630 +	    committed changeset.
 5.11631 +	  </para>
 5.11632 +	</listitem></itemizedlist>
 5.11633 +
 5.11634 +      <para id="x_2d6">See also: <literal role="hook" moreinfo="none">precommit</literal> (<xref linkend="sec:hook:precommit"/>)
 5.11635 +      </para>
 5.11636 +    </sect2>
 5.11637 +
 5.11638 +    <sect2 id="sec:hook:preupdate">
 5.11639 +      <title><literal role="hook" moreinfo="none">preupdate</literal>—before
 5.11640 +	updating or merging working directory</title>
 5.11641 +
 5.11642 +      <para id="x_2d7">This controlling hook is run before an update
 5.11643 +	or merge of the working directory begins.  It is run only if
 5.11644 +	Mercurial's normal pre-update checks determine that the update
 5.11645 +	or merge can proceed.  If the hook succeeds, the update or
 5.11646 +	merge may proceed; if it fails, the update or merge does not
 5.11647 +	start.
 5.11648 +      </para>
 5.11649 +
 5.11650 +      <para id="x_2d8">Parameters to this hook:
 5.11651 +      </para>
 5.11652 +      <itemizedlist>
 5.11653 +	<listitem><para id="x_2d9"><literal moreinfo="none">parent1</literal>: A
 5.11654 +	    changeset ID. The ID of the parent that the working
 5.11655 +	    directory is to be updated to.  If the working directory
 5.11656 +	    is being merged, it will not change this parent.
 5.11657 +	  </para>
 5.11658 +	</listitem>
 5.11659 +	<listitem><para id="x_2da"><literal moreinfo="none">parent2</literal>: A
 5.11660 +	    changeset ID. Only set if the working directory is being
 5.11661 +	    merged.  The ID of the revision that the working directory
 5.11662 +	    is being merged with.
 5.11663 +	  </para>
 5.11664 +	</listitem></itemizedlist>
 5.11665 +
 5.11666 +      <para id="x_2db">See also: <literal role="hook" moreinfo="none">update</literal>
 5.11667 +	(<xref linkend="sec:hook:update"/>)</para>
 5.11668 +    </sect2>
 5.11669 +
 5.11670 +    <sect2 id="sec:hook:tag">
 5.11671 +      <title><literal role="hook" moreinfo="none">tag</literal>—after tagging a
 5.11672 +	changeset</title>
 5.11673 +
 5.11674 +      <para id="x_2dc">This hook is run after a tag has been created.
 5.11675 +      </para>
 5.11676 +
 5.11677 +      <para id="x_2dd">Parameters to this hook:
 5.11678 +      </para>
 5.11679 +      <itemizedlist>
 5.11680 +	<listitem><para id="x_2de"><literal moreinfo="none">local</literal>: A boolean.  Whether
 5.11681 +	    the new tag is local to this repository instance (i.e.
 5.11682 +	    stored in <filename role="special" moreinfo="none">.hg/localtags</filename>) or managed by
 5.11683 +	    Mercurial (stored in <filename role="special" moreinfo="none">.hgtags</filename>).
 5.11684 +	  </para>
 5.11685 +	</listitem>
 5.11686 +	<listitem><para id="x_2df"><literal moreinfo="none">node</literal>: A changeset ID.  The
 5.11687 +	    ID of the changeset that was tagged.
 5.11688 +	  </para>
 5.11689 +	</listitem>
 5.11690 +	<listitem><para id="x_2e0"><literal moreinfo="none">tag</literal>: A string.  The name of
 5.11691 +	    the tag that was created.
 5.11692 +	  </para>
 5.11693 +	</listitem></itemizedlist>
 5.11694 +
 5.11695 +      <para id="x_2e1">If the created tag is revision-controlled, the <literal role="hook" moreinfo="none">commit</literal> hook (section <xref linkend="sec:hook:commit"/>) is run before this hook.
 5.11696 +      </para>
 5.11697 +
 5.11698 +      <para id="x_2e2">See also: <literal role="hook" moreinfo="none">pretag</literal>
 5.11699 +	(<xref linkend="sec:hook:pretag"/>)
 5.11700 +      </para>
 5.11701 +    </sect2>
 5.11702 +
 5.11703 +    <sect2 id="sec:hook:update">
 5.11704 +      <title><literal role="hook" moreinfo="none">update</literal>—after
 5.11705 +	updating or merging working directory</title>
 5.11706 +
 5.11707 +      <para id="x_2e3">This hook is run after an update or merge of the working
 5.11708 +	directory completes.  Since a merge can fail (if the external
 5.11709 +	<command moreinfo="none">hgmerge</command> command fails to resolve conflicts
 5.11710 +	in a file), this hook communicates whether the update or merge
 5.11711 +	completed cleanly.
 5.11712 +      </para>
 5.11713 +
 5.11714 +      <itemizedlist>
 5.11715 +	<listitem><para id="x_2e4"><literal moreinfo="none">error</literal>: A boolean.
 5.11716 +	    Indicates whether the update or merge completed
 5.11717 +	    successfully.
 5.11718 +	  </para>
 5.11719 +	</listitem>
 5.11720 +	<listitem><para id="x_2e5"><literal moreinfo="none">parent1</literal>: A changeset ID.
 5.11721 +	    The ID of the parent that the working directory was
 5.11722 +	    updated to.  If the working directory was merged, it will
 5.11723 +	    not have changed this parent.
 5.11724 +	  </para>
 5.11725 +	</listitem>
 5.11726 +	<listitem><para id="x_2e6"><literal moreinfo="none">parent2</literal>: A changeset ID.
 5.11727 +	    Only set if the working directory was merged.  The ID of
 5.11728 +	    the revision that the working directory was merged with.
 5.11729 +	  </para>
 5.11730 +	</listitem></itemizedlist>
 5.11731 +
 5.11732 +      <para id="x_2e7">See also: <literal role="hook" moreinfo="none">preupdate</literal>
 5.11733 +	(<xref linkend="sec:hook:preupdate"/>)
 5.11734 +      </para>
 5.11735 +
 5.11736 +    </sect2>
 5.11737 +  </sect1>
 5.11738 +</chapter>
 5.11739 +
 5.11740 +<!--
 5.11741 +local variables: 
 5.11742 +sgml-parent-document: ("00book.xml" "book" "chapter")
 5.11743 +end:
 5.11744 +-->
 5.11745 +
 5.11746 +  <!-- BEGIN ch11 -->
 5.11747 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.11748 +
 5.11749 +<chapter id="chap:template">
 5.11750 +  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
 5.11751 +  <title>Customizing the output of Mercurial</title>
 5.11752 +
 5.11753 +  <para id="x_578">Mercurial provides a powerful mechanism to let you control how
 5.11754 +    it displays information.  The mechanism is based on templates.
 5.11755 +    You can use templates to generate specific output for a single
 5.11756 +    command, or to customize the entire appearance of the built-in web
 5.11757 +    interface.</para>
 5.11758 +
 5.11759 +  <sect1 id="sec:style">
 5.11760 +    <title>Using precanned output styles</title>
 5.11761 +
 5.11762 +    <para id="x_579">Packaged with Mercurial are some output styles that you can
 5.11763 +      use immediately.  A style is simply a precanned template that
 5.11764 +      someone wrote and installed somewhere that Mercurial can
 5.11765 +      find.</para>
 5.11766 +
 5.11767 +    <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
 5.11768 +      review its normal output.</para>
 5.11769 +
 5.11770 +    <!-- BEGIN template.simple.normal -->
 5.11771 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1</userinput>
 5.11772 +changeset:   1:e3d2468ca47c
 5.11773 +tag:         mytag
 5.11774 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.11775 +date:        Sun Aug 16 14:05:17 2009 +0000
 5.11776 +summary:     added line to end of &lt;&lt;hello&gt;&gt; file.
 5.11777 +
 5.11778 +</screen>
 5.11779 +<!-- END template.simple.normal -->
 5.11780 +
 5.11781 +
 5.11782 +    <para id="x_57b">This is somewhat informative, but it takes up a lot of
 5.11783 +      space—five lines of output per changeset.  The
 5.11784 +      <literal moreinfo="none">compact</literal> style reduces this to three lines,
 5.11785 +      presented in a sparse manner.</para>
 5.11786 +
 5.11787 +    <!-- BEGIN template.simple.compact -->
 5.11788 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style compact</userinput>
 5.11789 +3[tip]   d3cc7424d32c   2009-08-16 14:05 +0000   bos
 5.11790 +  Added tag v0.1 for changeset a5dd5392119b
 5.11791 +
 5.11792 +2[v0.1]   a5dd5392119b   2009-08-16 14:05 +0000   bos
 5.11793 +  Added tag mytag for changeset e3d2468ca47c
 5.11794 +
 5.11795 +1[mytag]   e3d2468ca47c   2009-08-16 14:05 +0000   bos
 5.11796 +  added line to end of &lt;&lt;hello&gt;&gt; file.
 5.11797 +
 5.11798 +0   1cf727e9fc61   2009-08-16 14:05 +0000   bos
 5.11799 +  added hello
 5.11800 +
 5.11801 +</screen>
 5.11802 +<!-- END template.simple.compact -->
 5.11803 +
 5.11804 +
 5.11805 +    <para id="x_57c">The <literal moreinfo="none">changelog</literal> style hints at the
 5.11806 +      expressive power of Mercurial's templating engine.  This style
 5.11807 +      attempts to follow the GNU Project's changelog
 5.11808 +      guidelines<citation>web:changelog</citation>.</para>
 5.11809 +
 5.11810 +    <!-- BEGIN template.simple.changelog -->
 5.11811 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style changelog</userinput>
 5.11812 +2009-08-16  Bryan O'Sullivan  &lt;bos@serpentine.com&gt;
 5.11813 +
 5.11814 +	* .hgtags:
 5.11815 +	Added tag v0.1 for changeset a5dd5392119b
 5.11816 +	[d3cc7424d32c] [tip]
 5.11817 +
 5.11818 +	* .hgtags:
 5.11819 +	Added tag mytag for changeset e3d2468ca47c
 5.11820 +	[a5dd5392119b] [v0.1]
 5.11821 +
 5.11822 +	* goodbye, hello:
 5.11823 +	added line to end of &lt;&lt;hello&gt;&gt; file.
 5.11824 +
 5.11825 +	in addition, added a file with the helpful name (at least i hope
 5.11826 +	that some might consider it so) of goodbye.
 5.11827 +	[e3d2468ca47c] [mytag]
 5.11828 +
 5.11829 +	* hello:
 5.11830 +	added hello
 5.11831 +	[1cf727e9fc61]
 5.11832 +
 5.11833 +</screen>
 5.11834 +<!-- END template.simple.changelog -->
 5.11835 +
 5.11836 +
 5.11837 +    <para id="x_57d">You will not be shocked to learn that Mercurial's default
 5.11838 +      output style is named <literal moreinfo="none">default</literal>.</para>
 5.11839 +
 5.11840 +    <sect2>
 5.11841 +      <title>Setting a default style</title>
 5.11842 +
 5.11843 +      <para id="x_57e">You can modify the output style that Mercurial will use
 5.11844 +	for every command by editing your <filename role="special" moreinfo="none">~/.hgrc</filename> file, naming the style
 5.11845 +	you would prefer to use.</para>
 5.11846 +
 5.11847 +      <programlisting format="linespecific">[ui]
 5.11848 +style = compact</programlisting>
 5.11849 +
 5.11850 +      <para id="x_57f">If you write a style of your own, you can use it by either
 5.11851 +	providing the path to your style file, or copying your style
 5.11852 +	file into a location where Mercurial can find it (typically
 5.11853 +	the <literal moreinfo="none">templates</literal> subdirectory of your
 5.11854 +	Mercurial install directory).</para>
 5.11855 +    </sect2>
 5.11856 +  </sect1>
 5.11857 +
 5.11858 +  <sect1>
 5.11859 +    <title>Commands that support styles and templates</title>
 5.11860 +
 5.11861 +    <para id="x_580">All of Mercurial's
 5.11862 +      <quote><literal moreinfo="none">log</literal>-like</quote> commands let you use
 5.11863 +      styles and templates: <command role="hg-cmd" moreinfo="none">hg
 5.11864 +	incoming</command>, <command role="hg-cmd" moreinfo="none">hg log</command>,
 5.11865 +      <command role="hg-cmd" moreinfo="none">hg outgoing</command>, and <command role="hg-cmd" moreinfo="none">hg tip</command>.</para>
 5.11866 +
 5.11867 +    <para id="x_581">As I write this manual, these are so far the only commands
 5.11868 +      that support styles and templates.  Since these are the most
 5.11869 +      important commands that need customizable output, there has been
 5.11870 +      little pressure from the Mercurial user community to add style
 5.11871 +      and template support to other commands.</para>
 5.11872 +  </sect1>
 5.11873 +
 5.11874 +  <sect1>
 5.11875 +    <title>The basics of templating</title>
 5.11876 +
 5.11877 +    <para id="x_582">At its simplest, a Mercurial template is a piece of text.
 5.11878 +      Some of the text never changes, while other parts are
 5.11879 +      <emphasis>expanded</emphasis>, or replaced with new text, when
 5.11880 +      necessary.</para>
 5.11881 +
 5.11882 +    <para id="x_583">Before we continue, let's look again at a simple example of
 5.11883 +      Mercurial's normal output.</para>
 5.11884 +
 5.11885 +    <!-- BEGIN template.simple.normal -->
 5.11886 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1</userinput>
 5.11887 +changeset:   1:e3d2468ca47c
 5.11888 +tag:         mytag
 5.11889 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.11890 +date:        Sun Aug 16 14:05:17 2009 +0000
 5.11891 +summary:     added line to end of &lt;&lt;hello&gt;&gt; file.
 5.11892 +
 5.11893 +</screen>
 5.11894 +<!-- END template.simple.normal -->
 5.11895 +
 5.11896 +
 5.11897 +    <para id="x_584">Now, let's run the same command, but using a template to
 5.11898 +      change its output.</para>
 5.11899 +
 5.11900 +    <!-- BEGIN template.simple.simplest -->
 5.11901 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'i saw a changeset\n'</userinput>
 5.11902 +i saw a changeset
 5.11903 +</screen>
 5.11904 +<!-- END template.simple.simplest -->
 5.11905 +
 5.11906 +
 5.11907 +    <para id="x_585">The example above illustrates the simplest possible
 5.11908 +      template; it's just a piece of static text, printed once for
 5.11909 +      each changeset.  The <option role="hg-opt-log">--template</option> option to the <command role="hg-cmd" moreinfo="none">hg log</command> command tells Mercurial to use
 5.11910 +      the given text as the template when printing each
 5.11911 +      changeset.</para>
 5.11912 +
 5.11913 +    <para id="x_586">Notice that the template string above ends with the text
 5.11914 +      <quote><literal moreinfo="none">\n</literal></quote>.  This is an
 5.11915 +      <emphasis>escape sequence</emphasis>, telling Mercurial to print
 5.11916 +      a newline at the end of each template item.  If you omit this
 5.11917 +      newline, Mercurial will run each piece of output together.  See
 5.11918 +      <xref linkend="sec:template:escape"/> for more details
 5.11919 +      of escape sequences.</para>
 5.11920 +
 5.11921 +    <para id="x_587">A template that prints a fixed string of text all the time
 5.11922 +      isn't very useful; let's try something a bit more
 5.11923 +      complex.</para>
 5.11924 +
 5.11925 +    <!-- BEGIN template.simple.simplesub -->
 5.11926 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --template 'i saw a changeset: {desc}\n'</userinput>
 5.11927 +i saw a changeset: Added tag v0.1 for changeset a5dd5392119b
 5.11928 +i saw a changeset: Added tag mytag for changeset e3d2468ca47c
 5.11929 +i saw a changeset: added line to end of &lt;&lt;hello&gt;&gt; file.
 5.11930 +
 5.11931 +in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.
 5.11932 +i saw a changeset: added hello
 5.11933 +</screen>
 5.11934 +<!-- END template.simple.simplesub -->
 5.11935 +
 5.11936 +
 5.11937 +    <para id="x_588">As you can see, the string
 5.11938 +      <quote><literal moreinfo="none">{desc}</literal></quote> in the template has
 5.11939 +      been replaced in the output with the description of each
 5.11940 +      changeset.  Every time Mercurial finds text enclosed in curly
 5.11941 +      braces (<quote><literal moreinfo="none">{</literal></quote> and
 5.11942 +      <quote><literal moreinfo="none">}</literal></quote>), it will try to replace the
 5.11943 +      braces and text with the expansion of whatever is inside.  To
 5.11944 +      print a literal curly brace, you must escape it, as described in
 5.11945 +      <xref linkend="sec:template:escape"/>.</para>
 5.11946 +  </sect1>
 5.11947 +
 5.11948 +  <sect1 id="sec:template:keyword">
 5.11949 +    <title>Common template keywords</title>
 5.11950 +
 5.11951 +    <para id="x_589">You can start writing simple templates immediately using the
 5.11952 +      keywords below.</para>
 5.11953 +
 5.11954 +    <itemizedlist>
 5.11955 +      <listitem><para id="x_58a"><literal role="template-keyword" moreinfo="none">author</literal>: String.  The
 5.11956 +	  unmodified author of the changeset.</para>
 5.11957 +      </listitem>
 5.11958 +      <listitem><para id="x_58b"><literal role="template-keyword" moreinfo="none">branches</literal>: String.  The
 5.11959 +	  name of the branch on which the changeset was committed.
 5.11960 +	  Will be empty if the branch name was
 5.11961 +	  <literal moreinfo="none">default</literal>.</para>
 5.11962 +      </listitem>
 5.11963 +      <listitem><para id="x_58c"><literal role="template-keyword" moreinfo="none">date</literal>:
 5.11964 +	  Date information.  The date when the changeset was
 5.11965 +	  committed.  This is <emphasis>not</emphasis> human-readable;
 5.11966 +	  you must pass it through a filter that will render it
 5.11967 +	  appropriately.  See <xref linkend="sec:template:filter"/> for more information
 5.11968 +	  on filters. The date is expressed as a pair of numbers.  The
 5.11969 +	  first number is a Unix UTC timestamp (seconds since January
 5.11970 +	  1, 1970); the second is the offset of the committer's
 5.11971 +	  timezone from UTC, in seconds.</para>
 5.11972 +      </listitem>
 5.11973 +      <listitem><para id="x_58d"><literal role="template-keyword" moreinfo="none">desc</literal>:
 5.11974 +	  String.  The text of the changeset description.</para>
 5.11975 +      </listitem>
 5.11976 +      <listitem><para id="x_58e"><literal role="template-keyword" moreinfo="none">files</literal>: List of strings.
 5.11977 +	  All files modified, added, or removed by this
 5.11978 +	  changeset.</para>
 5.11979 +      </listitem>
 5.11980 +      <listitem><para id="x_58f"><literal role="template-keyword" moreinfo="none">file_adds</literal>: List of
 5.11981 +	  strings.  Files added by this changeset.</para>
 5.11982 +      </listitem>
 5.11983 +      <listitem><para id="x_590"><literal role="template-keyword" moreinfo="none">file_dels</literal>: List of
 5.11984 +	  strings.  Files removed by this changeset.</para>
 5.11985 +      </listitem>
 5.11986 +      <listitem><para id="x_591"><literal role="template-keyword" moreinfo="none">node</literal>:
 5.11987 +	  String.  The changeset identification hash, as a
 5.11988 +	  40-character hexadecimal string.</para>
 5.11989 +      </listitem>
 5.11990 +      <listitem><para id="x_592"><literal role="template-keyword" moreinfo="none">parents</literal>: List of
 5.11991 +	  strings.  The parents of the changeset.</para>
 5.11992 +      </listitem>
 5.11993 +      <listitem><para id="x_593"><literal role="template-keyword" moreinfo="none">rev</literal>:
 5.11994 +	  Integer.  The repository-local changeset revision
 5.11995 +	  number.</para>
 5.11996 +      </listitem>
 5.11997 +      <listitem><para id="x_594"><literal role="template-keyword" moreinfo="none">tags</literal>:
 5.11998 +	  List of strings.  Any tags associated with the
 5.11999 +	  changeset.</para>
 5.12000 +      </listitem>
 5.12001 +    </itemizedlist>
 5.12002 +
 5.12003 +    <para id="x_595">A few simple experiments will show us what to expect when we
 5.12004 +      use these keywords; you can see the results below.</para>
 5.12005 +
 5.12006 +    <!-- BEGIN template.simple.keywords -->
 5.12007 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'author: {author}\n'</userinput>
 5.12008 +author: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.12009 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'desc:\n{desc}\n'</userinput>
 5.12010 +desc:
 5.12011 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12012 +
 5.12013 +in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.
 5.12014 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'files: {files}\n'</userinput>
 5.12015 +files: goodbye hello
 5.12016 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'file_adds: {file_adds}\n'</userinput>
 5.12017 +file_adds: goodbye
 5.12018 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'file_dels: {file_dels}\n'</userinput>
 5.12019 +file_dels: 
 5.12020 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'node: {node}\n'</userinput>
 5.12021 +node: e3d2468ca47c10bdfbbb41b367a0c84509862197
 5.12022 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'parents: {parents}\n'</userinput>
 5.12023 +parents: 
 5.12024 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'rev: {rev}\n'</userinput>
 5.12025 +rev: 1
 5.12026 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'tags: {tags}\n'</userinput>
 5.12027 +tags: mytag
 5.12028 +</screen>
 5.12029 +<!-- END template.simple.keywords -->
 5.12030 +
 5.12031 +
 5.12032 +    <para id="x_596">As we noted above, the date keyword does not produce
 5.12033 +      human-readable output, so we must treat it specially.  This
 5.12034 +      involves using a <emphasis>filter</emphasis>, about which more
 5.12035 +      in <xref linkend="sec:template:filter"/>.</para>
 5.12036 +
 5.12037 +    <!-- BEGIN template.simple.datekeyword -->
 5.12038 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'date: {date}\n'</userinput>
 5.12039 +date: 1250431517.00
 5.12040 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'date: {date|isodate}\n'</userinput>
 5.12041 +date: 2009-08-16 14:05 +0000
 5.12042 +</screen>
 5.12043 +<!-- END template.simple.datekeyword -->
 5.12044 +
 5.12045 +  </sect1>
 5.12046 +
 5.12047 +  <sect1 id="sec:template:escape">
 5.12048 +    <title>Escape sequences</title>
 5.12049 +
 5.12050 +    <para id="x_597">Mercurial's templating engine recognises the most commonly
 5.12051 +      used escape sequences in strings.  When it sees a backslash
 5.12052 +      (<quote><literal moreinfo="none">\</literal></quote>) character, it looks at the
 5.12053 +      following character and substitutes the two characters with a
 5.12054 +      single replacement, as described below.</para>
 5.12055 +
 5.12056 +    <itemizedlist>
 5.12057 +      <listitem><para id="x_598"><literal moreinfo="none">\</literal>:
 5.12058 +	  Backslash, <quote><literal moreinfo="none">\</literal></quote>, ASCII
 5.12059 +	  134.</para>
 5.12060 +      </listitem>
 5.12061 +      <listitem><para id="x_599"><literal moreinfo="none">\n</literal>: Newline,
 5.12062 +	  ASCII 12.</para>
 5.12063 +      </listitem>
 5.12064 +      <listitem><para id="x_59a"><literal moreinfo="none">\r</literal>: Carriage
 5.12065 +	  return, ASCII 15.</para>
 5.12066 +      </listitem>
 5.12067 +      <listitem><para id="x_59b"><literal moreinfo="none">\t</literal>: Tab, ASCII
 5.12068 +	  11.</para>
 5.12069 +      </listitem>
 5.12070 +      <listitem><para id="x_59c"><literal moreinfo="none">\v</literal>: Vertical
 5.12071 +	  tab, ASCII 13.</para>
 5.12072 +      </listitem>
 5.12073 +      <listitem><para id="x_59d"><literal moreinfo="none">\{</literal>: Open curly
 5.12074 +	  brace, <quote><literal moreinfo="none">{</literal></quote>, ASCII
 5.12075 +	  173.</para>
 5.12076 +      </listitem>
 5.12077 +      <listitem><para id="x_59e"><literal moreinfo="none">\}</literal>: Close curly
 5.12078 +	  brace, <quote><literal moreinfo="none">}</literal></quote>, ASCII
 5.12079 +	  175.</para>
 5.12080 +      </listitem></itemizedlist>
 5.12081 +
 5.12082 +    <para id="x_59f">As indicated above, if you want the expansion of a template
 5.12083 +      to contain a literal <quote><literal moreinfo="none">\</literal></quote>,
 5.12084 +      <quote><literal moreinfo="none">{</literal></quote>, or
 5.12085 +      <quote><literal moreinfo="none">{</literal></quote> character, you must escape
 5.12086 +      it.</para>
 5.12087 +  </sect1>
 5.12088 +
 5.12089 +  <sect1 id="sec:template:filter">
 5.12090 +    <title>Filtering keywords to change their results</title>
 5.12091 +
 5.12092 +    <para id="x_5a0">Some of the results of template expansion are not
 5.12093 +      immediately easy to use.  Mercurial lets you specify an optional
 5.12094 +      chain of <emphasis>filters</emphasis> to modify the result of
 5.12095 +      expanding a keyword.  You have already seen a common filter,
 5.12096 +      <literal role="template-kw-filt-date" moreinfo="none">isodate</literal>, in
 5.12097 +      action above, to make a date readable.</para>
 5.12098 +
 5.12099 +    <para id="x_5a1">Below is a list of the most commonly used filters that
 5.12100 +      Mercurial supports.  While some filters can be applied to any
 5.12101 +      text, others can only be used in specific circumstances.  The
 5.12102 +      name of each filter is followed first by an indication of where
 5.12103 +      it can be used, then a description of its effect.</para>
 5.12104 +
 5.12105 +    <itemizedlist>
 5.12106 +      <listitem><para id="x_5a2"><literal role="template-filter" moreinfo="none">addbreaks</literal>: Any text. Add
 5.12107 +	  an XHTML <quote><literal moreinfo="none">&lt;br/&gt;</literal></quote> tag
 5.12108 +	  before the end of every line except the last.  For example,
 5.12109 +	  <quote><literal moreinfo="none">foo\nbar</literal></quote> becomes
 5.12110 +	  <quote><literal moreinfo="none">foo&lt;br/&gt;\nbar</literal></quote>.</para>
 5.12111 +      </listitem>
 5.12112 +      <listitem><para id="x_5a3"><literal role="template-kw-filt-date" moreinfo="none">age</literal>: <literal role="template-keyword" moreinfo="none">date</literal> keyword.  Render
 5.12113 +	  the age of the date, relative to the current time.  Yields a
 5.12114 +	  string like <quote><literal moreinfo="none">10
 5.12115 +	      minutes</literal></quote>.</para>
 5.12116 +      </listitem>
 5.12117 +      <listitem><para id="x_5a4"><literal role="template-filter" moreinfo="none">basename</literal>: Any text, but
 5.12118 +	  most useful for the <literal role="template-keyword" moreinfo="none">files</literal> keyword and its
 5.12119 +	  relatives.  Treat the text as a path, and return the
 5.12120 +	  basename. For example,
 5.12121 +	  <quote><literal moreinfo="none">foo/bar/baz</literal></quote> becomes
 5.12122 +	  <quote><literal moreinfo="none">baz</literal></quote>.</para>
 5.12123 +      </listitem>
 5.12124 +      <listitem><para id="x_5a5"><literal role="template-kw-filt-date" moreinfo="none">date</literal>: <literal role="template-keyword" moreinfo="none">date</literal> keyword.  Render a
 5.12125 +	  date in a similar format to the Unix <literal role="template-keyword" moreinfo="none">date</literal> command, but with
 5.12126 +	  timezone included.  Yields a string like <quote><literal moreinfo="none">Mon
 5.12127 +	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
 5.12128 +      </listitem>
 5.12129 +      <listitem><para id="x_5a6"><literal role="template-kw-filt-author" moreinfo="none">domain</literal>: Any text,
 5.12130 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Finds
 5.12131 +	  the first string that looks like an email address, and
 5.12132 +	  extract just the domain component.  For example,
 5.12133 +	  <quote><literal moreinfo="none">Bryan O'Sullivan
 5.12134 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 5.12135 +	  <quote><literal moreinfo="none">serpentine.com</literal></quote>.</para>
 5.12136 +      </listitem>
 5.12137 +      <listitem><para id="x_5a7"><literal role="template-kw-filt-author" moreinfo="none">email</literal>: Any text,
 5.12138 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Extract
 5.12139 +	  the first string that looks like an email address.  For
 5.12140 +	  example, <quote><literal moreinfo="none">Bryan O'Sullivan
 5.12141 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 5.12142 +	  <quote><literal moreinfo="none">bos@serpentine.com</literal></quote>.</para>
 5.12143 +      </listitem>
 5.12144 +      <listitem><para id="x_5a8"><literal role="template-filter" moreinfo="none">escape</literal>: Any text.
 5.12145 +	  Replace the special XML/XHTML characters
 5.12146 +	  <quote><literal moreinfo="none">&amp;</literal></quote>,
 5.12147 +	  <quote><literal moreinfo="none">&lt;</literal></quote> and
 5.12148 +	  <quote><literal moreinfo="none">&gt;</literal></quote> with XML
 5.12149 +	  entities.</para>
 5.12150 +      </listitem>
 5.12151 +      <listitem><para id="x_5a9"><literal role="template-filter" moreinfo="none">fill68</literal>: Any text.  Wrap
 5.12152 +	  the text to fit in 68 columns.  This is useful before you
 5.12153 +	  pass text through the <literal role="template-filter" moreinfo="none">tabindent</literal> filter, and
 5.12154 +	  still want it to fit in an 80-column fixed-font
 5.12155 +	  window.</para>
 5.12156 +      </listitem>
 5.12157 +      <listitem><para id="x_5aa"><literal role="template-filter" moreinfo="none">fill76</literal>: Any text.  Wrap
 5.12158 +	  the text to fit in 76 columns.</para>
 5.12159 +      </listitem>
 5.12160 +      <listitem><para id="x_5ab"><literal role="template-filter" moreinfo="none">firstline</literal>: Any text.
 5.12161 +	  Yield the first line of text, without any trailing
 5.12162 +	  newlines.</para>
 5.12163 +      </listitem>
 5.12164 +      <listitem><para id="x_5ac"><literal role="template-kw-filt-date" moreinfo="none">hgdate</literal>: <literal role="template-keyword" moreinfo="none">date</literal> keyword.  Render
 5.12165 +	  the date as a pair of readable numbers.  Yields a string
 5.12166 +	  like <quote><literal moreinfo="none">1157407993
 5.12167 +	      25200</literal></quote>.</para>
 5.12168 +      </listitem>
 5.12169 +      <listitem><para id="x_5ad"><literal role="template-kw-filt-date" moreinfo="none">isodate</literal>: <literal role="template-keyword" moreinfo="none">date</literal> keyword.  Render
 5.12170 +	  the date as a text string in ISO 8601 format.  Yields a
 5.12171 +	  string like <quote><literal moreinfo="none">2006-09-04 15:13:13
 5.12172 +	      -0700</literal></quote>.</para>
 5.12173 +      </listitem>
 5.12174 +      <listitem><para id="x_5ae"><literal role="template-filter" moreinfo="none">obfuscate</literal>: Any text, but
 5.12175 +	  most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Yield
 5.12176 +	  the input text rendered as a sequence of XML entities.  This
 5.12177 +	  helps to defeat some particularly stupid screen-scraping
 5.12178 +	  email harvesting spambots.</para>
 5.12179 +      </listitem>
 5.12180 +      <listitem><para id="x_5af"><literal role="template-kw-filt-author" moreinfo="none">person</literal>: Any text,
 5.12181 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Yield
 5.12182 +	  the text before an email address. For example,
 5.12183 +	  <quote><literal moreinfo="none">Bryan O'Sullivan
 5.12184 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 5.12185 +	  <quote><literal moreinfo="none">Bryan O'Sullivan</literal></quote>.</para>
 5.12186 +      </listitem>
 5.12187 +      <listitem><para id="x_5b0"><literal role="template-kw-filt-date" moreinfo="none">rfc822date</literal>:
 5.12188 +	  <literal role="template-keyword" moreinfo="none">date</literal> keyword.
 5.12189 +	  Render a date using the same format used in email headers.
 5.12190 +	  Yields a string like <quote><literal moreinfo="none">Mon, 04 Sep 2006
 5.12191 +	      15:13:13 -0700</literal></quote>.</para>
 5.12192 +      </listitem>
 5.12193 +      <listitem><para id="x_5b1"><literal role="template-kw-filt-node" moreinfo="none">short</literal>: Changeset
 5.12194 +	  hash.  Yield the short form of a changeset hash, i.e. a
 5.12195 +	  12-character hexadecimal string.</para>
 5.12196 +      </listitem>
 5.12197 +      <listitem><para id="x_5b2"><literal role="template-kw-filt-date" moreinfo="none">shortdate</literal>: <literal role="template-keyword" moreinfo="none">date</literal> keyword.  Render
 5.12198 +	  the year, month, and day of the date.  Yields a string like
 5.12199 +	  <quote><literal moreinfo="none">2006-09-04</literal></quote>.</para>
 5.12200 +      </listitem>
 5.12201 +      <listitem><para id="x_5b3"><literal role="template-filter" moreinfo="none">strip</literal>:
 5.12202 +	  Any text.  Strip all leading and trailing whitespace from
 5.12203 +	  the string.</para>
 5.12204 +      </listitem>
 5.12205 +      <listitem><para id="x_5b4"><literal role="template-filter" moreinfo="none">tabindent</literal>: Any text.
 5.12206 +	  Yield the text, with every line except the first starting
 5.12207 +	  with a tab character.</para>
 5.12208 +      </listitem>
 5.12209 +      <listitem><para id="x_5b5"><literal role="template-filter" moreinfo="none">urlescape</literal>: Any text.
 5.12210 +	  Escape all characters that are considered
 5.12211 +	  <quote>special</quote> by URL parsers.  For example,
 5.12212 +	  <literal moreinfo="none">foo bar</literal> becomes
 5.12213 +	  <literal moreinfo="none">foo%20bar</literal>.</para>
 5.12214 +      </listitem>
 5.12215 +      <listitem><para id="x_5b6"><literal role="template-kw-filt-author" moreinfo="none">user</literal>: Any text,
 5.12216 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Return
 5.12217 +	  the <quote>user</quote> portion of an email address.  For
 5.12218 +	  example, <quote><literal moreinfo="none">Bryan O'Sullivan
 5.12219 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 5.12220 +	  <quote><literal moreinfo="none">bos</literal></quote>.</para>
 5.12221 +      </listitem>
 5.12222 +    </itemizedlist>
 5.12223 +
 5.12224 +    <!-- BEGIN template.simple.manyfilters -->
 5.12225 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author}\n'</userinput>
 5.12226 +Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.12227 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|domain}\n'</userinput>
 5.12228 +serpentine.com
 5.12229 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|email}\n'</userinput>
 5.12230 +bos@serpentine.com
 5.12231 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|obfuscate}\n' | cut -c-76</userinput>
 5.12232 +&amp;#66;&amp;#114;&amp;#121;&amp;#97;&amp;#110;&amp;#32;&amp;#79;&amp;#39;&amp;#83;&amp;#117;&amp;#108;&amp;#108;&amp;#105;&amp;#11
 5.12233 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|person}\n'</userinput>
 5.12234 +Bryan O'Sullivan
 5.12235 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|user}\n'</userinput>
 5.12236 +bos
 5.12237 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'looks almost right, but actually garbage: {date}\n'</userinput>
 5.12238 +looks almost right, but actually garbage: 1250431517.00
 5.12239 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|age}\n'</userinput>
 5.12240 +3 seconds
 5.12241 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|date}\n'</userinput>
 5.12242 +Sun Aug 16 14:05:17 2009 +0000
 5.12243 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|hgdate}\n'</userinput>
 5.12244 +1250431517 0
 5.12245 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|isodate}\n'</userinput>
 5.12246 +2009-08-16 14:05 +0000
 5.12247 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|rfc822date}\n'</userinput>
 5.12248 +Sun, 16 Aug 2009 14:05:17 +0000
 5.12249 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|shortdate}\n'</userinput>
 5.12250 +2009-08-16
 5.12251 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc}\n' | cut -c-76</userinput>
 5.12252 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12253 +
 5.12254 +in addition, added a file with the helpful name (at least i hope that some m
 5.12255 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|addbreaks}\n' | cut -c-76</userinput>
 5.12256 +added line to end of &lt;&lt;hello&gt;&gt; file.&lt;br/&gt;
 5.12257 +&lt;br/&gt;
 5.12258 +in addition, added a file with the helpful name (at least i hope that some m
 5.12259 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|escape}\n' | cut -c-76</userinput>
 5.12260 +added line to end of &amp;lt;&amp;lt;hello&amp;gt;&amp;gt; file.
 5.12261 +
 5.12262 +in addition, added a file with the helpful name (at least i hope that some m
 5.12263 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|fill68}\n'</userinput>
 5.12264 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12265 +
 5.12266 +in addition, added a file with the helpful name (at least i hope
 5.12267 +that some might consider it so) of goodbye.
 5.12268 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|fill76}\n'</userinput>
 5.12269 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12270 +
 5.12271 +in addition, added a file with the helpful name (at least i hope that some
 5.12272 +might consider it so) of goodbye.
 5.12273 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|firstline}\n'</userinput>
 5.12274 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12275 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|strip}\n' | cut -c-76</userinput>
 5.12276 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12277 +
 5.12278 +in addition, added a file with the helpful name (at least i hope that some m
 5.12279 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|tabindent}\n' | expand | cut -c-76</userinput>
 5.12280 +added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12281 +
 5.12282 +        in addition, added a file with the helpful name (at least i hope tha
 5.12283 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{node}\n'</userinput>
 5.12284 +e3d2468ca47c10bdfbbb41b367a0c84509862197
 5.12285 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{node|short}\n'</userinput>
 5.12286 +e3d2468ca47c
 5.12287 +</screen>
 5.12288 +<!-- END template.simple.manyfilters -->
 5.12289 +
 5.12290 +
 5.12291 +    <note>
 5.12292 +      <para id="x_5b7">  If you try to apply a filter to a piece of data that it
 5.12293 +	cannot process, Mercurial will fail and print a Python
 5.12294 +	exception.  For example, trying to run the output of the
 5.12295 +	<literal role="template-keyword" moreinfo="none">desc</literal> keyword into
 5.12296 +	the <literal role="template-kw-filt-date" moreinfo="none">isodate</literal>
 5.12297 +	filter is not a good idea.</para>
 5.12298 +    </note>
 5.12299 +
 5.12300 +    <sect2>
 5.12301 +      <title>Combining filters</title>
 5.12302 +
 5.12303 +      <para id="x_5b8">It is easy to combine filters to yield output in the form
 5.12304 +	you would like.  The following chain of filters tidies up a
 5.12305 +	description, then makes sure that it fits cleanly into 68
 5.12306 +	columns, then indents it by a further 8 characters (at least
 5.12307 +	on Unix-like systems, where a tab is conventionally 8
 5.12308 +	characters wide).</para>
 5.12309 +
 5.12310 +      <!-- BEGIN template.simple.combine -->
 5.12311 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'description:\n\t{desc|strip|fill68|tabindent}\n'</userinput>
 5.12312 +description:
 5.12313 +	added line to end of &lt;&lt;hello&gt;&gt; file.
 5.12314 +
 5.12315 +	in addition, added a file with the helpful name (at least i hope
 5.12316 +	that some might consider it so) of goodbye.
 5.12317 +</screen>
 5.12318 +<!-- END template.simple.combine -->
 5.12319 +
 5.12320 +
 5.12321 +      <para id="x_5b9">Note the use of <quote><literal moreinfo="none">\t</literal></quote> (a
 5.12322 +	tab character) in the template to force the first line to be
 5.12323 +	indented; this is necessary since <literal role="template-keyword" moreinfo="none">tabindent</literal> indents all
 5.12324 +	lines <emphasis>except</emphasis> the first.</para>
 5.12325 +
 5.12326 +      <para id="x_5ba">Keep in mind that the order of filters in a chain is
 5.12327 +	significant.  The first filter is applied to the result of the
 5.12328 +	keyword; the second to the result of the first filter; and so
 5.12329 +	on.  For example, using <literal moreinfo="none">fill68|tabindent</literal>
 5.12330 +	gives very different results from
 5.12331 +	<literal moreinfo="none">tabindent|fill68</literal>.</para>
 5.12332 +    </sect2>
 5.12333 +  </sect1>
 5.12334 +
 5.12335 +  <sect1>
 5.12336 +    <title>From templates to styles</title>
 5.12337 +
 5.12338 +    <para id="x_5bb">A command line template provides a quick and simple way to
 5.12339 +      format some output.  Templates can become verbose, though, and
 5.12340 +      it's useful to be able to give a template a name.  A style file
 5.12341 +      is a template with a name, stored in a file.</para>
 5.12342 +
 5.12343 +    <para id="x_5bc">More than that, using a style file unlocks the power of
 5.12344 +      Mercurial's templating engine in ways that are not possible
 5.12345 +      using the command line <option role="hg-opt-log">--template</option> option.</para>
 5.12346 +
 5.12347 +    <sect2>
 5.12348 +      <title>The simplest of style files</title>
 5.12349 +
 5.12350 +      <para id="x_5bd">Our simple style file contains just one line:</para>
 5.12351 +
 5.12352 +      <!-- BEGIN template.simple.rev -->
 5.12353 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'changeset = "rev: {rev}\n"' &gt; rev</userinput>
 5.12354 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -l1 --style ./rev</userinput>
 5.12355 +rev: 3
 5.12356 +</screen>
 5.12357 +<!-- END template.simple.rev -->
 5.12358 +
 5.12359 +
 5.12360 +      <para id="x_5be">This tells Mercurial, <quote>if you're printing a
 5.12361 +	  changeset, use the text on the right as the
 5.12362 +	  template</quote>.</para>
 5.12363 +    </sect2>
 5.12364 +
 5.12365 +    <sect2>
 5.12366 +      <title>Style file syntax</title>
 5.12367 +
 5.12368 +      <para id="x_5bf">The syntax rules for a style file are simple.</para>
 5.12369 +
 5.12370 +      <itemizedlist>
 5.12371 +	<listitem><para id="x_5c0">The file is processed one line at a
 5.12372 +	    time.</para>
 5.12373 +	</listitem>
 5.12374 +	<listitem><para id="x_5c1">Leading and trailing white space are
 5.12375 +	    ignored.</para>
 5.12376 +	</listitem>
 5.12377 +	<listitem><para id="x_5c2">Empty lines are skipped.</para>
 5.12378 +	</listitem>
 5.12379 +	<listitem><para id="x_5c3">If a line starts with either of the characters
 5.12380 +	    <quote><literal moreinfo="none">#</literal></quote> or
 5.12381 +	    <quote><literal moreinfo="none">;</literal></quote>, the entire line is
 5.12382 +	    treated as a comment, and skipped as if empty.</para>
 5.12383 +	</listitem>
 5.12384 +	<listitem><para id="x_5c4">A line starts with a keyword.  This must start
 5.12385 +	    with an alphabetic character or underscore, and can
 5.12386 +	    subsequently contain any alphanumeric character or
 5.12387 +	    underscore.  (In regexp notation, a keyword must match
 5.12388 +	    <literal moreinfo="none">[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
 5.12389 +	</listitem>
 5.12390 +	<listitem><para id="x_5c5">The next element must be an
 5.12391 +	    <quote><literal moreinfo="none">=</literal></quote> character, which can
 5.12392 +	    be preceded or followed by an arbitrary amount of white
 5.12393 +	    space.</para>
 5.12394 +	</listitem>
 5.12395 +	<listitem><para id="x_5c6">If the rest of the line starts and ends with
 5.12396 +	    matching quote characters (either single or double quote),
 5.12397 +	    it is treated as a template body.</para>
 5.12398 +	</listitem>
 5.12399 +	<listitem><para id="x_5c7">If the rest of the line <emphasis>does
 5.12400 +	      not</emphasis> start with a quote character, it is
 5.12401 +	    treated as the name of a file; the contents of this file
 5.12402 +	    will be read and used as a template body.</para>
 5.12403 +	</listitem></itemizedlist>
 5.12404 +    </sect2>
 5.12405 +  </sect1>
 5.12406 +
 5.12407 +  <sect1>
 5.12408 +    <title>Style files by example</title>
 5.12409 +
 5.12410 +    <para id="x_5c8">To illustrate how to write a style file, we will construct a
 5.12411 +      few by example.  Rather than provide a complete style file and
 5.12412 +      walk through it, we'll mirror the usual process of developing a
 5.12413 +      style file by starting with something very simple, and walking
 5.12414 +      through a series of successively more complete examples.</para>
 5.12415 +
 5.12416 +    <sect2>
 5.12417 +      <title>Identifying mistakes in style files</title>
 5.12418 +
 5.12419 +      <para id="x_5c9">If Mercurial encounters a problem in a style file you are
 5.12420 +	working on, it prints a terse error message that, once you
 5.12421 +	figure out what it means, is actually quite useful.</para>
 5.12422 +
 5.12423 +<!-- BEGIN template.svnstyle.syntax.input -->
 5.12424 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat broken.style</userinput>
 5.12425 +changeset =
 5.12426 +</screen>
 5.12427 +<!-- END template.svnstyle.syntax.input -->
 5.12428 +
 5.12429 +
 5.12430 +      <para id="x_5ca">Notice that <filename moreinfo="none">broken.style</filename> attempts to
 5.12431 +	define a <literal moreinfo="none">changeset</literal> keyword, but forgets to
 5.12432 +	give any content for it. When instructed to use this style
 5.12433 +	file, Mercurial promptly complains.</para>
 5.12434 +
 5.12435 +      <!-- BEGIN template.svnstyle.syntax.error -->
 5.12436 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --style broken.style</userinput>
 5.12437 +abort: broken.style:1: parse error
 5.12438 +</screen>
 5.12439 +<!-- END template.svnstyle.syntax.error -->
 5.12440 +
 5.12441 +
 5.12442 +      <para id="x_5cb">This error message looks intimidating, but it is not too
 5.12443 +	hard to follow.</para>
 5.12444 +
 5.12445 +      <itemizedlist>
 5.12446 +	<listitem><para id="x_5cc">The first component is simply Mercurial's way
 5.12447 +	    of saying <quote>I am giving up</quote>.</para>
 5.12448 +	  <programlisting format="linespecific">___abort___: broken.style:1: parse error</programlisting>
 5.12449 +	</listitem>
 5.12450 +	<listitem><para id="x_5cd">Next comes the name of the style file that
 5.12451 +	    contains the error.</para>
 5.12452 +	  <programlisting format="linespecific">abort: ___broken.style___:1: parse error</programlisting>
 5.12453 +	</listitem>
 5.12454 +	<listitem><para id="x_5ce">Following the file name is the line number
 5.12455 +	    where the error was encountered.</para>
 5.12456 +	  <programlisting format="linespecific">abort: broken.style:___1___: parse error</programlisting>
 5.12457 +	</listitem>
 5.12458 +	<listitem><para id="x_5cf">Finally, a description of what went
 5.12459 +	    wrong.</para>
 5.12460 +	  <programlisting format="linespecific">abort: broken.style:1: ___parse error___</programlisting>
 5.12461 +	</listitem>
 5.12462 +	<listitem><para id="x_5d0">The description of the problem is not always
 5.12463 +	    clear (as in this case), but even when it is cryptic, it
 5.12464 +	    is almost always trivial to visually inspect the offending
 5.12465 +	    line in the style file and see what is wrong.</para>
 5.12466 +	</listitem>
 5.12467 +      </itemizedlist>
 5.12468 +    </sect2>
 5.12469 +
 5.12470 +    <sect2>
 5.12471 +      <title>Uniquely identifying a repository</title>
 5.12472 +
 5.12473 +      <para id="x_5d1">If you would like to be able to identify a Mercurial
 5.12474 +	repository <quote>fairly uniquely</quote> using a short string
 5.12475 +	as an identifier, you can use the first revision in the
 5.12476 +	repository.</para>
 5.12477 +
 5.12478 +      <!-- BEGIN template.svnstyle.id -->
 5.12479 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r0 --template '{node}'</userinput>
 5.12480 +02b4f9d8a52a6da645e20fa7df0accc8aa33b650</screen>
 5.12481 +<!-- END template.svnstyle.id -->
 5.12482 +
 5.12483 +
 5.12484 +      <para id="x_5d2">This is likely to be unique, and so it is
 5.12485 +	useful in many cases.  There are a few caveats.</para>
 5.12486 +      <itemizedlist>
 5.12487 +	<listitem><para id="x_5d3">It will not work in a completely empty
 5.12488 +	    repository, because such a repository does not have a
 5.12489 +	    revision zero.</para>
 5.12490 +	</listitem>
 5.12491 +	<listitem><para id="x_5d4">Neither will it work in the (extremely rare)
 5.12492 +	    case where a repository is a merge of two or more formerly
 5.12493 +	    independent repositories, and you still have those
 5.12494 +	    repositories around.</para>
 5.12495 +	</listitem></itemizedlist>
 5.12496 +      <para id="x_5d5">Here are some uses to which you could put this
 5.12497 +	identifier:</para>
 5.12498 +      <itemizedlist>
 5.12499 +	<listitem><para id="x_5d6">As a key into a table for a database that
 5.12500 +	    manages repositories on a server.</para>
 5.12501 +	</listitem>
 5.12502 +	<listitem><para id="x_5d7">As half of a {<emphasis>repository
 5.12503 +	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
 5.12504 +	    Save this information away when you run an automated build
 5.12505 +	    or other activity, so that you can <quote>replay</quote>
 5.12506 +	    the build later if necessary.</para>
 5.12507 +	</listitem>
 5.12508 +      </itemizedlist>
 5.12509 +    </sect2>
 5.12510 +
 5.12511 +    <sect2>
 5.12512 +      <title>Listing files on multiple lines</title>
 5.12513 +
 5.12514 +      <para id="x_714">Suppose we want to list the files changed by a changeset,
 5.12515 +	one per line, with a little indentation before each file
 5.12516 +	name.</para>
 5.12517 +
 5.12518 +      <!-- BEGIN ch10/multiline.go -->
 5.12519 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; multiline &lt;&lt; EOF</userinput>
 5.12520 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">changeset = "Changed in {node|short}:\n{files}"</userinput>
 5.12521 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">file = "  {file}\n"</userinput>
 5.12522 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
 5.12523 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style multiline</userinput>
 5.12524 +Changed in badb58085712:
 5.12525 +  .bashrc
 5.12526 +  .hgrc
 5.12527 +  test.c
 5.12528 +</screen>
 5.12529 +<!-- END ch10/multiline.go -->
 5.12530 +
 5.12531 +    </sect2>
 5.12532 +
 5.12533 +    <sect2>
 5.12534 +      <title>Mimicking Subversion's output</title>
 5.12535 +
 5.12536 +      <para id="x_5d8">Let's try to emulate the default output format used by
 5.12537 +	another revision control tool, Subversion.</para>
 5.12538 +
 5.12539 +      <!-- BEGIN template.svnstyle.short -->
 5.12540 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svn log -r9653</userinput>
 5.12541 +------------------------------------------------------------------------
 5.12542 +r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines
 5.12543 +
 5.12544 +On reporting a route error, also include the status for the error,
 5.12545 +rather than indicating a status of 0 when an error has occurred.
 5.12546 +
 5.12547 +Signed-off-by: Sean Hefty &lt;sean.hefty@intel.com&gt;
 5.12548 +
 5.12549 +------------------------------------------------------------------------
 5.12550 +</screen>
 5.12551 +<!-- END template.svnstyle.short -->
 5.12552 +
 5.12553 +
 5.12554 +      <para id="x_5d9">Since Subversion's output style is fairly simple, it is
 5.12555 +	easy to copy-and-paste a hunk of its output into a file, and
 5.12556 +	replace the text produced above by Subversion with the
 5.12557 +	template values we'd like to see expanded.</para>
 5.12558 +
 5.12559 +      <!-- BEGIN template.svnstyle.template -->
 5.12560 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat svn.template</userinput>
 5.12561 +r{rev} | {author|user} | {date|isodate} ({date|rfc822date})
 5.12562 +
 5.12563 +{desc|strip|fill76}
 5.12564 +
 5.12565 +------------------------------------------------------------------------
 5.12566 +</screen>
 5.12567 +<!-- END template.svnstyle.template -->
 5.12568 +
 5.12569 +
 5.12570 +      <para id="x_5da">There are a few small ways in which this template deviates
 5.12571 +	from the output produced by Subversion.</para>
 5.12572 +      <itemizedlist>
 5.12573 +	<listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
 5.12574 +	    date (the <quote><literal moreinfo="none">Wed, 27 Sep 2006</literal></quote> in the
 5.12575 +	    example output above) in parentheses.  Mercurial's
 5.12576 +	    templating engine does not provide a way to display a date
 5.12577 +	    in this format without also printing the time and time
 5.12578 +	    zone.</para>
 5.12579 +	</listitem>
 5.12580 +	<listitem><para id="x_5dc">We emulate Subversion's printing of
 5.12581 +	    <quote>separator</quote> lines full of
 5.12582 +	    <quote><literal moreinfo="none">-</literal></quote> characters by ending
 5.12583 +	    the template with such a line. We use the templating
 5.12584 +	    engine's <literal role="template-keyword" moreinfo="none">header</literal>
 5.12585 +	    keyword to print a separator line as the first line of
 5.12586 +	    output (see below), thus achieving similar output to
 5.12587 +	    Subversion.</para>
 5.12588 +	</listitem>
 5.12589 +	<listitem><para id="x_5dd">Subversion's output includes a count in the
 5.12590 +	    header of the number of lines in the commit message.  We
 5.12591 +	    cannot replicate this in Mercurial; the templating engine
 5.12592 +	    does not currently provide a filter that counts the number
 5.12593 +	    of lines the template generates.</para>
 5.12594 +	</listitem></itemizedlist>
 5.12595 +      <para id="x_5de">It took me no more than a minute or two of work to replace
 5.12596 +	literal text from an example of Subversion's output with some
 5.12597 +	keywords and filters to give the template above.  The style
 5.12598 +	file simply refers to the template.</para>
 5.12599 +
 5.12600 +      <!-- BEGIN template.svnstyle.style -->
 5.12601 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat svn.style</userinput>
 5.12602 +header = '------------------------------------------------------------------------\n\n'
 5.12603 +changeset = svn.template
 5.12604 +</screen>
 5.12605 +<!-- END template.svnstyle.style -->
 5.12606 +
 5.12607 +
 5.12608 +      <para id="x_5df">We could have included the text of the template file
 5.12609 +	directly in the style file by enclosing it in quotes and
 5.12610 +	replacing the newlines with
 5.12611 +	<quote><literal moreinfo="none">\n</literal></quote> sequences, but it would
 5.12612 +	have made the style file too difficult to read.  Readability
 5.12613 +	is a good guide when you're trying to decide whether some text
 5.12614 +	belongs in a style file, or in a template file that the style
 5.12615 +	file points to.  If the style file will look too big or
 5.12616 +	cluttered if you insert a literal piece of text, drop it into
 5.12617 +	a template instead.</para>
 5.12618 +    </sect2>
 5.12619 +  </sect1>
 5.12620 +</chapter>
 5.12621 +
 5.12622 +<!--
 5.12623 +local variables: 
 5.12624 +sgml-parent-document: ("00book.xml" "book" "chapter")
 5.12625 +end:
 5.12626 +-->
 5.12627 +
 5.12628 +  <!-- BEGIN ch12 -->
 5.12629 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.12630 +
 5.12631 +<chapter id="chap:mq">
 5.12632 +  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
 5.12633 +  <title>Managing change with Mercurial Queues</title>
 5.12634 +
 5.12635 +  <sect1 id="sec:mq:patch-mgmt">
 5.12636 +    <title>The patch management problem</title>
 5.12637 +
 5.12638 +    <para id="x_3ac">Here is a common scenario: you need to install a software
 5.12639 +      package from source, but you find a bug that you must fix in the
 5.12640 +      source before you can start using the package.  You make your
 5.12641 +      changes, forget about the package for a while, and a few months
 5.12642 +      later you need to upgrade to a newer version of the package.  If
 5.12643 +      the newer version of the package still has the bug, you must
 5.12644 +      extract your fix from the older source tree and apply it against
 5.12645 +      the newer version.  This is a tedious task, and it's easy to
 5.12646 +      make mistakes.</para>
 5.12647 +
 5.12648 +    <para id="x_3ad">This is a simple case of the <quote>patch management</quote>
 5.12649 +      problem.  You have an <quote>upstream</quote> source tree that
 5.12650 +      you can't change; you need to make some local changes on top of
 5.12651 +      the upstream tree; and you'd like to be able to keep those
 5.12652 +      changes separate, so that you can apply them to newer versions
 5.12653 +      of the upstream source.</para>
 5.12654 +
 5.12655 +    <para id="x_3ae">The patch management problem arises in many situations.
 5.12656 +      Probably the most visible is that a user of an open source
 5.12657 +      software project will contribute a bug fix or new feature to the
 5.12658 +      project's maintainers in the form of a patch.</para>
 5.12659 +
 5.12660 +    <para id="x_3af">Distributors of operating systems that include open source
 5.12661 +      software often need to make changes to the packages they
 5.12662 +      distribute so that they will build properly in their
 5.12663 +      environments.</para>
 5.12664 +
 5.12665 +    <para id="x_3b0">When you have few changes to maintain, it is easy to manage
 5.12666 +      a single patch using the standard <command moreinfo="none">diff</command> and
 5.12667 +      <command moreinfo="none">patch</command> programs (see <xref linkend="sec:mq:patch"/> for a discussion of these
 5.12668 +      tools). Once the number of changes grows, it starts to make
 5.12669 +      sense to maintain patches as discrete <quote>chunks of
 5.12670 +	work,</quote> so that for example a single patch will contain
 5.12671 +      only one bug fix (the patch might modify several files, but it's
 5.12672 +      doing <quote>only one thing</quote>), and you may have a number
 5.12673 +      of such patches for different bugs you need fixed and local
 5.12674 +      changes you require.  In this situation, if you submit a bug fix
 5.12675 +      patch to the upstream maintainers of a package and they include
 5.12676 +      your fix in a subsequent release, you can simply drop that
 5.12677 +      single patch when you're updating to the newer release.</para>
 5.12678 +
 5.12679 +    <para id="x_3b1">Maintaining a single patch against an upstream tree is a
 5.12680 +      little tedious and error-prone, but not difficult.  However, the
 5.12681 +      complexity of the problem grows rapidly as the number of patches
 5.12682 +      you have to maintain increases.  With more than a tiny number of
 5.12683 +      patches in hand, understanding which ones you have applied and
 5.12684 +      maintaining them moves from messy to overwhelming.</para>
 5.12685 +
 5.12686 +    <para id="x_3b2">Fortunately, Mercurial includes a powerful extension,
 5.12687 +      Mercurial Queues (or simply <quote>MQ</quote>), that massively
 5.12688 +      simplifies the patch management problem.</para>
 5.12689 +
 5.12690 +  </sect1>
 5.12691 +  <sect1 id="sec:mq:history">
 5.12692 +    <title>The prehistory of Mercurial Queues</title>
 5.12693 +
 5.12694 +    <para id="x_3b3">During the late 1990s, several Linux kernel developers
 5.12695 +      started to maintain <quote>patch series</quote> that modified
 5.12696 +      the behavior of the Linux kernel.  Some of these series were
 5.12697 +      focused on stability, some on feature coverage, and others were
 5.12698 +      more speculative.</para>
 5.12699 +
 5.12700 +    <para id="x_3b4">The sizes of these patch series grew rapidly.  In 2002,
 5.12701 +      Andrew Morton published some shell scripts he had been using to
 5.12702 +      automate the task of managing his patch queues.  Andrew was
 5.12703 +      successfully using these scripts to manage hundreds (sometimes
 5.12704 +      thousands) of patches on top of the Linux kernel.</para>
 5.12705 +
 5.12706 +    <sect2 id="sec:mq:quilt">
 5.12707 +      <title>A patchwork quilt</title>
 5.12708 +
 5.12709 +      <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson
 5.12710 +	borrowed the approach of Andrew's scripts and published a tool
 5.12711 +	called <quote>patchwork quilt</quote>
 5.12712 +	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
 5.12713 +	(see <citation>gruenbacher:2005</citation> for a paper
 5.12714 +	describing it).  Because quilt substantially automated patch
 5.12715 +	management, it rapidly gained a large following among open
 5.12716 +	source software developers.</para>
 5.12717 +
 5.12718 +      <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> on
 5.12719 +	top of a directory tree. To begin, you tell quilt to manage a
 5.12720 +	directory tree, and tell it which files you want to manage; it
 5.12721 +	stores away the names and contents of those files.  To fix a
 5.12722 +	bug, you create a new patch (using a single command), edit the
 5.12723 +	files you need to fix, then <quote>refresh</quote> the
 5.12724 +	patch.</para>
 5.12725 +
 5.12726 +      <para id="x_3b7">The refresh step causes quilt to scan the directory tree;
 5.12727 +	it updates the patch with all of the changes you have made.
 5.12728 +	You can create another patch on top of the first, which will
 5.12729 +	track the changes required to modify the tree from <quote>tree
 5.12730 +	  with one patch applied</quote> to <quote>tree with two
 5.12731 +	  patches applied</quote>.</para>
 5.12732 +
 5.12733 +      <para id="x_3b8">You can <emphasis>change</emphasis> which patches are
 5.12734 +	applied to the tree.  If you <quote>pop</quote> a patch, the
 5.12735 +	changes made by that patch will vanish from the directory
 5.12736 +	tree.  Quilt remembers which patches you have popped, though,
 5.12737 +	so you can <quote>push</quote> a popped patch again, and the
 5.12738 +	directory tree will be restored to contain the modifications
 5.12739 +	in the patch.  Most importantly, you can run the
 5.12740 +	<quote>refresh</quote> command at any time, and the topmost
 5.12741 +	applied patch will be updated.  This means that you can, at
 5.12742 +	any time, change both which patches are applied and what
 5.12743 +	modifications those patches make.</para>
 5.12744 +
 5.12745 +      <para id="x_3b9">Quilt knows nothing about revision control tools, so it
 5.12746 +	works equally well on top of an unpacked tarball or a
 5.12747 +	Subversion working copy.</para>
 5.12748 +    </sect2>
 5.12749 +
 5.12750 +    <sect2 id="sec:mq:quilt-mq">
 5.12751 +      <title>From patchwork quilt to Mercurial Queues</title>
 5.12752 +
 5.12753 +      <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and
 5.12754 +	wrote an extension that he called Mercurial Queues, which
 5.12755 +	added quilt-like behavior to Mercurial.</para>
 5.12756 +
 5.12757 +      <para id="x_3bb">The key difference between quilt and MQ is that quilt
 5.12758 +	knows nothing about revision control systems, while MQ is
 5.12759 +	<emphasis>integrated</emphasis> into Mercurial.  Each patch
 5.12760 +	that you push is represented as a Mercurial changeset.  Pop a
 5.12761 +	patch, and the changeset goes away.</para>
 5.12762 +
 5.12763 +      <para id="x_3bc">Because quilt does not care about revision control tools,
 5.12764 +	it is still a tremendously useful piece of software to know
 5.12765 +	about for situations where you cannot use Mercurial and
 5.12766 +	MQ.</para>
 5.12767 +
 5.12768 +    </sect2>
 5.12769 +  </sect1>
 5.12770 +  <sect1>
 5.12771 +    <title>The huge advantage of MQ</title>
 5.12772 +
 5.12773 +    <para id="x_3bd">I cannot overstate the value that MQ offers through the
 5.12774 +      unification of patches and revision control.</para>
 5.12775 +
 5.12776 +    <para id="x_3be">A major reason that patches have persisted in the free
 5.12777 +      software and open source world—in spite of the
 5.12778 +      availability of increasingly capable revision control tools over
 5.12779 +      the years—is the <emphasis>agility</emphasis> they
 5.12780 +      offer.</para>
 5.12781 +
 5.12782 +    <para id="x_3bf">Traditional revision control tools make a permanent,
 5.12783 +      irreversible record of everything that you do.  While this has
 5.12784 +      great value, it's also somewhat stifling.  If you want to
 5.12785 +      perform a wild-eyed experiment, you have to be careful in how
 5.12786 +      you go about it, or you risk leaving unneeded—or worse,
 5.12787 +      misleading or destabilising—traces of your missteps and
 5.12788 +      errors in the permanent revision record.</para>
 5.12789 +
 5.12790 +    <para id="x_3c0">By contrast, MQ's marriage of distributed revision control
 5.12791 +      with patches makes it much easier to isolate your work.  Your
 5.12792 +      patches live on top of normal revision history, and you can make
 5.12793 +      them disappear or reappear at will.  If you don't like a patch,
 5.12794 +      you can drop it.  If a patch isn't quite as you want it to be,
 5.12795 +      simply fix it—as many times as you need to, until you
 5.12796 +      have refined it into the form you desire.</para>
 5.12797 +
 5.12798 +    <para id="x_3c1">As an example, the integration of patches with revision
 5.12799 +      control makes understanding patches and debugging their
 5.12800 +      effects—and their interplay with the code they're based
 5.12801 +      on—<emphasis>enormously</emphasis> easier. Since every
 5.12802 +      applied patch has an associated changeset, you can give <command role="hg-cmd" moreinfo="none">hg log</command> a file name to see which
 5.12803 +      changesets and patches affected the file.  You can use the
 5.12804 +      <command role="hg-cmd" moreinfo="none">hg bisect</command> command to
 5.12805 +      binary-search through all changesets and applied patches to see
 5.12806 +      where a bug got introduced or fixed.  You can use the <command role="hg-cmd" moreinfo="none">hg annotate</command> command to see which
 5.12807 +      changeset or patch modified a particular line of a source file.
 5.12808 +      And so on.</para>
 5.12809 +  </sect1>
 5.12810 +
 5.12811 +  <sect1 id="sec:mq:patch">
 5.12812 +    <title>Understanding patches</title>
 5.12813 +
 5.12814 +    <para id="x_3c2">Because MQ doesn't hide its patch-oriented nature, it is
 5.12815 +      helpful to understand what patches are, and a little about the
 5.12816 +      tools that work with them.</para>
 5.12817 +
 5.12818 +    <para id="x_3c3">The traditional Unix <command moreinfo="none">diff</command> command
 5.12819 +      compares two files, and prints a list of differences between
 5.12820 +      them. The <command moreinfo="none">patch</command> command understands these
 5.12821 +      differences as <emphasis>modifications</emphasis> to make to a
 5.12822 +      file.  Take a look below for a simple example of these commands
 5.12823 +      in action.</para>
 5.12824 +
 5.12825 +      <!-- BEGIN mq.dodiff.diff -->
 5.12826 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'this is my original thought' &gt; oldfile</userinput>
 5.12827 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'i have changed my mind' &gt; newfile</userinput>
 5.12828 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">diff -u oldfile newfile &gt; tiny.patch</userinput>
 5.12829 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat tiny.patch</userinput>
 5.12830 +--- oldfile	2009-08-16 14:05:06.000000000 +0000
 5.12831 ++++ newfile	2009-08-16 14:05:06.000000000 +0000
 5.12832 +@@ -1 +1 @@
 5.12833 +-this is my original thought
 5.12834 ++i have changed my mind
 5.12835 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">patch &lt; tiny.patch</userinput>
 5.12836 +patching file oldfile
 5.12837 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat oldfile</userinput>
 5.12838 +i have changed my mind
 5.12839 +</screen>
 5.12840 +<!-- END mq.dodiff.diff -->
 5.12841 +
 5.12842 +
 5.12843 +    <para id="x_3c4">The type of file that <command moreinfo="none">diff</command> generates (and
 5.12844 +      <command moreinfo="none">patch</command> takes as input) is called a
 5.12845 +      <quote>patch</quote> or a <quote>diff</quote>; there is no
 5.12846 +      difference between a patch and a diff.  (We'll use the term
 5.12847 +      <quote>patch</quote>, since it's more commonly used.)</para>
 5.12848 +
 5.12849 +    <para id="x_3c5">A patch file can start with arbitrary text; the
 5.12850 +      <command moreinfo="none">patch</command> command ignores this text, but MQ uses
 5.12851 +      it as the commit message when creating changesets.  To find the
 5.12852 +      beginning of the patch content, <command moreinfo="none">patch</command>
 5.12853 +      searches for the first line that starts with the string
 5.12854 +      <quote><literal moreinfo="none">diff -</literal></quote>.</para>
 5.12855 +
 5.12856 +    <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs
 5.12857 +      (<command moreinfo="none">patch</command> can accept several other diff formats,
 5.12858 +      but MQ doesn't).  A unified diff contains two kinds of header.
 5.12859 +      The <emphasis>file header</emphasis> describes the file being
 5.12860 +      modified; it contains the name of the file to modify.  When
 5.12861 +      <command moreinfo="none">patch</command> sees a new file header, it looks for a
 5.12862 +      file with that name to start modifying.</para>
 5.12863 +
 5.12864 +    <para id="x_3c7">After the file header comes a series of
 5.12865 +      <emphasis>hunks</emphasis>.  Each hunk starts with a header;
 5.12866 +      this identifies the range of line numbers within the file that
 5.12867 +      the hunk should modify.  Following the header, a hunk starts and
 5.12868 +      ends with a few (usually three) lines of text from the
 5.12869 +      unmodified file; these are called the
 5.12870 +      <emphasis>context</emphasis> for the hunk.  If there's only a
 5.12871 +      small amount of context between successive hunks,
 5.12872 +      <command moreinfo="none">diff</command> doesn't print a new hunk header; it just
 5.12873 +      runs the hunks together, with a few lines of context between
 5.12874 +      modifications.</para>
 5.12875 +
 5.12876 +    <para id="x_3c8">Each line of context begins with a space character.  Within
 5.12877 +      the hunk, a line that begins with
 5.12878 +      <quote><literal moreinfo="none">-</literal></quote> means <quote>remove this
 5.12879 +	line,</quote> while a line that begins with
 5.12880 +      <quote><literal moreinfo="none">+</literal></quote> means <quote>insert this
 5.12881 +	line.</quote>  For example, a line that is modified is
 5.12882 +      represented by one deletion and one insertion.</para>
 5.12883 +
 5.12884 +    <para id="x_3c9">We will return to some of the more subtle aspects of patches
 5.12885 +      later (in <xref linkend="sec:mq:adv-patch"/>), but you
 5.12886 +      should have
 5.12887 +      enough information now to use MQ.</para>
 5.12888 +  </sect1>
 5.12889 +
 5.12890 +  <sect1 id="sec:mq:start">
 5.12891 +    <title>Getting started with Mercurial Queues</title>
 5.12892 +
 5.12893 +    <para id="x_3ca">Because MQ is implemented as an extension, you must
 5.12894 +      explicitly enable before you can use it.  (You don't need to
 5.12895 +      download anything; MQ ships with the standard Mercurial
 5.12896 +      distribution.)  To enable MQ, edit your <filename role="home" moreinfo="none">~/.hgrc</filename> file, and add the lines
 5.12897 +      below.</para>
 5.12898 +
 5.12899 +    <programlisting format="linespecific">[extensions]
 5.12900 +hgext.mq =</programlisting>
 5.12901 +
 5.12902 +    <para id="x_3cb">Once the extension is enabled, it will make a number of new
 5.12903 +      commands available.  To verify that the extension is working,
 5.12904 +      you can use <command role="hg-cmd" moreinfo="none">hg help</command> to see if
 5.12905 +      the <command role="hg-ext-mq" moreinfo="none">qinit</command> command is now
 5.12906 +      available.</para>
 5.12907 +
 5.12908 +    <!-- BEGIN mq.qinit-help.help -->
 5.12909 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg help qinit</userinput>
 5.12910 +hg qinit [-c]
 5.12911 +
 5.12912 +init a new queue repository
 5.12913 +
 5.12914 +    The queue repository is unversioned by default. If -c is
 5.12915 +    specified, qinit will create a separate nested repository
 5.12916 +    for patches (qinit -c may also be run later to convert
 5.12917 +    an unversioned patch repository into a versioned one).
 5.12918 +    You can use qcommit to commit changes to this queue repository.
 5.12919 +
 5.12920 +options:
 5.12921 +
 5.12922 + -c --create-repo  create queue repository
 5.12923 +
 5.12924 +use "hg -v help qinit" to show global options
 5.12925 +</screen>
 5.12926 +<!-- END mq.qinit-help.help -->
 5.12927 +
 5.12928 +
 5.12929 +    <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial
 5.12930 +      repository, and its commands only operate within that
 5.12931 +      repository.  To get started, simply prepare the repository using
 5.12932 +      the <command role="hg-ext-mq" moreinfo="none">qinit</command> command.</para>
 5.12933 +
 5.12934 +    <!-- BEGIN mq.tutorial.qinit -->
 5.12935 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init mq-sandbox</userinput>
 5.12936 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd mq-sandbox</userinput>
 5.12937 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 1' &gt; file1</userinput>
 5.12938 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'another line 1' &gt; file2</userinput>
 5.12939 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add file1 file2</userinput>
 5.12940 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m'first change'</userinput>
 5.12941 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 5.12942 +</screen>
 5.12943 +<!-- END mq.tutorial.qinit -->
 5.12944 +
 5.12945 +
 5.12946 +    <para id="x_3cd">This command creates an empty directory called <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>, where
 5.12947 +      MQ will keep its metadata.  As with many Mercurial commands, the
 5.12948 +      <command role="hg-ext-mq" moreinfo="none">qinit</command> command prints nothing
 5.12949 +      if it succeeds.</para>
 5.12950 +
 5.12951 +    <sect2>
 5.12952 +      <title>Creating a new patch</title>
 5.12953 +
 5.12954 +      <para id="x_3ce">To begin work on a new patch, use the <command role="hg-ext-mq" moreinfo="none">qnew</command> command.  This command takes
 5.12955 +	one argument, the name of the patch to create.</para>
 5.12956 +
 5.12957 +      <para id="x_3cf">MQ will use this as the name of an actual file in the
 5.12958 +	<filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory, as you
 5.12959 +	can see below.</para>
 5.12960 +
 5.12961 +      <!-- BEGIN mq.tutorial.qnew -->
 5.12962 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
 5.12963 +changeset:   0:5d84c303994b
 5.12964 +tag:         tip
 5.12965 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.12966 +date:        Sun Aug 16 14:05:11 2009 +0000
 5.12967 +summary:     first change
 5.12968 +
 5.12969 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew first.patch</userinput>
 5.12970 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
 5.12971 +changeset:   1:ba4d7a3f2149
 5.12972 +tag:         qtip
 5.12973 +tag:         first.patch
 5.12974 +tag:         tip
 5.12975 +tag:         qbase
 5.12976 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.12977 +date:        Sun Aug 16 14:05:11 2009 +0000
 5.12978 +summary:     [mq]: first.patch
 5.12979 +
 5.12980 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls .hg/patches</userinput>
 5.12981 +first.patch  series  status
 5.12982 +</screen>
 5.12983 +<!-- END mq.tutorial.qnew -->
 5.12984 +
 5.12985 +
 5.12986 +      <para id="x_3d0">Also newly present in the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory are two
 5.12987 +	other files, <filename role="special" moreinfo="none">series</filename> and
 5.12988 +	<filename role="special" moreinfo="none">status</filename>.  The <filename role="special" moreinfo="none">series</filename> file lists all of the
 5.12989 +	patches that MQ knows about for this repository, with one
 5.12990 +	patch per line.  Mercurial uses the <filename role="special" moreinfo="none">status</filename> file for internal
 5.12991 +	book-keeping; it tracks all of the patches that MQ has
 5.12992 +	<emphasis>applied</emphasis> in this repository.</para>
 5.12993 +
 5.12994 +      <note>
 5.12995 +	<para id="x_3d1">  You may sometimes want to edit the <filename role="special" moreinfo="none">series</filename> file by hand; for
 5.12996 +	  example, to change the sequence in which some patches are
 5.12997 +	  applied.  However, manually editing the <filename role="special" moreinfo="none">status</filename> file is almost always a
 5.12998 +	  bad idea, as it's easy to corrupt MQ's idea of what is
 5.12999 +	  happening.</para>
 5.13000 +      </note>
 5.13001 +
 5.13002 +      <para id="x_3d2">Once you have created your new patch, you can edit files
 5.13003 +	in the working directory as you usually would.  All of the
 5.13004 +	normal Mercurial commands, such as <command role="hg-cmd" moreinfo="none">hg
 5.13005 +	  diff</command> and <command role="hg-cmd" moreinfo="none">hg
 5.13006 +	  annotate</command>, work exactly as they did before.</para>
 5.13007 +    </sect2>
 5.13008 +
 5.13009 +    <sect2>
 5.13010 +      <title>Refreshing a patch</title>
 5.13011 +
 5.13012 +      <para id="x_3d3">When you reach a point where you want to save your work,
 5.13013 +	use the <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 5.13014 +	to update the patch you are working on.</para>
 5.13015 +
 5.13016 +      <!-- BEGIN mq.tutorial.qrefresh -->
 5.13017 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 2' &gt;&gt; file1</userinput>
 5.13018 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
 5.13019 +diff -r ba4d7a3f2149 file1
 5.13020 +--- a/file1	Sun Aug 16 14:05:11 2009 +0000
 5.13021 ++++ b/file1	Sun Aug 16 14:05:11 2009 +0000
 5.13022 +@@ -1,1 +1,2 @@
 5.13023 + line 1
 5.13024 ++line 2
 5.13025 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.13026 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
 5.13027 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact --patch</userinput>
 5.13028 +1[qtip,first.patch,tip,qbase]   1aa236e17e55   2009-08-16 14:05 +0000   bos
 5.13029 +  [mq]: first.patch
 5.13030 +
 5.13031 +diff -r 5d84c303994b -r 1aa236e17e55 file1
 5.13032 +--- a/file1	Sun Aug 16 14:05:11 2009 +0000
 5.13033 ++++ b/file1	Sun Aug 16 14:05:11 2009 +0000
 5.13034 +@@ -1,1 +1,2 @@
 5.13035 + line 1
 5.13036 ++line 2
 5.13037 +
 5.13038 +</screen>
 5.13039 +<!-- END mq.tutorial.qrefresh -->
 5.13040 +
 5.13041 +
 5.13042 +      <para id="x_3d4">This command folds the changes you have made in the
 5.13043 +	working directory into your patch, and updates its
 5.13044 +	corresponding changeset to contain those changes.</para>
 5.13045 +
 5.13046 +      <para id="x_3d5">You can run <command role="hg-ext-mq" moreinfo="none">qrefresh</command>
 5.13047 +	as often as you like, so it's a good way to
 5.13048 +	<quote>checkpoint</quote> your work.  Refresh your patch at an
 5.13049 +	opportune time; try an experiment; and if the experiment
 5.13050 +	doesn't work out, <command role="hg-cmd" moreinfo="none">hg revert</command>
 5.13051 +	your modifications back to the last time you refreshed.</para>
 5.13052 +
 5.13053 +      <!-- BEGIN mq.tutorial.qrefresh2 -->
 5.13054 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 3' &gt;&gt; file1</userinput>
 5.13055 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
 5.13056 +M file1
 5.13057 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.13058 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact --patch</userinput>
 5.13059 +1[qtip,first.patch,tip,qbase]   ebec7ce95e11   2009-08-16 14:05 +0000   bos
 5.13060 +  [mq]: first.patch
 5.13061 +
 5.13062 +diff -r 5d84c303994b -r ebec7ce95e11 file1
 5.13063 +--- a/file1	Sun Aug 16 14:05:11 2009 +0000
 5.13064 ++++ b/file1	Sun Aug 16 14:05:12 2009 +0000
 5.13065 +@@ -1,1 +1,3 @@
 5.13066 + line 1
 5.13067 ++line 2
 5.13068 ++line 3
 5.13069 +
 5.13070 +</screen>
 5.13071 +<!-- END mq.tutorial.qrefresh2 -->
 5.13072 +
 5.13073 +    </sect2>
 5.13074 +
 5.13075 +    <sect2>
 5.13076 +      <title>Stacking and tracking patches</title>
 5.13077 +
 5.13078 +      <para id="x_3d6">Once you have finished working on a patch, or need to work
 5.13079 +	on another, you can use the <command role="hg-ext-mq" moreinfo="none">qnew</command> command again to create a
 5.13080 +	new patch. Mercurial will apply this patch on top of your
 5.13081 +	existing patch.</para>
 5.13082 +
 5.13083 +      <!-- BEGIN mq.tutorial.qnew2 -->
 5.13084 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew second.patch</userinput>
 5.13085 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style=compact --limit=2</userinput>
 5.13086 +2[qtip,second.patch,tip]   dffbc4265523   2009-08-16 14:05 +0000   bos
 5.13087 +  [mq]: second.patch
 5.13088 +
 5.13089 +1[first.patch,qbase]   ebec7ce95e11   2009-08-16 14:05 +0000   bos
 5.13090 +  [mq]: first.patch
 5.13091 +
 5.13092 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 4' &gt;&gt; file1</userinput>
 5.13093 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.13094 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact --patch</userinput>
 5.13095 +2[qtip,second.patch,tip]   fdacb9b232ac   2009-08-16 14:05 +0000   bos
 5.13096 +  [mq]: second.patch
 5.13097 +
 5.13098 +diff -r ebec7ce95e11 -r fdacb9b232ac file1
 5.13099 +--- a/file1	Sun Aug 16 14:05:12 2009 +0000
 5.13100 ++++ b/file1	Sun Aug 16 14:05:12 2009 +0000
 5.13101 +@@ -1,3 +1,4 @@
 5.13102 + line 1
 5.13103 + line 2
 5.13104 + line 3
 5.13105 ++line 4
 5.13106 +
 5.13107 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg annotate file1</userinput>
 5.13108 +0: line 1
 5.13109 +1: line 2
 5.13110 +1: line 3
 5.13111 +2: line 4
 5.13112 +</screen>
 5.13113 +<!-- END mq.tutorial.qnew2 -->
 5.13114 +
 5.13115 +
 5.13116 +      <para id="x_3d7">Notice that the patch contains the changes in our prior
 5.13117 +	patch as part of its context (you can see this more clearly in
 5.13118 +	the output of <command role="hg-cmd" moreinfo="none">hg
 5.13119 +	  annotate</command>).</para>
 5.13120 +
 5.13121 +      <para id="x_3d8">So far, with the exception of <command role="hg-ext-mq" moreinfo="none">qnew</command> and <command role="hg-ext-mq" moreinfo="none">qrefresh</command>, we've been careful to
 5.13122 +	only use regular Mercurial commands.  However, MQ provides
 5.13123 +	many commands that are easier to use when you are thinking
 5.13124 +	about patches, as illustrated below.</para>
 5.13125 +
 5.13126 +      <!-- BEGIN mq.tutorial.qseries -->
 5.13127 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qseries</userinput>
 5.13128 +first.patch
 5.13129 +second.patch
 5.13130 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 5.13131 +first.patch
 5.13132 +second.patch
 5.13133 +</screen>
 5.13134 +<!-- END mq.tutorial.qseries -->
 5.13135 +
 5.13136 +
 5.13137 +      <itemizedlist>
 5.13138 +	<listitem><para id="x_3d9">The <command role="hg-ext-mq" moreinfo="none">qseries</command> command lists every
 5.13139 +	    patch that MQ knows about in this repository, from oldest
 5.13140 +	    to newest (most recently
 5.13141 +	    <emphasis>created</emphasis>).</para>
 5.13142 +	</listitem>
 5.13143 +	<listitem><para id="x_3da">The <command role="hg-ext-mq" moreinfo="none">qapplied</command> command lists every
 5.13144 +	    patch that MQ has <emphasis>applied</emphasis> in this
 5.13145 +	    repository, again from oldest to newest (most recently
 5.13146 +	    applied).</para>
 5.13147 +	</listitem></itemizedlist>
 5.13148 +    </sect2>
 5.13149 +
 5.13150 +    <sect2>
 5.13151 +      <title>Manipulating the patch stack</title>
 5.13152 +
 5.13153 +      <para id="x_3db">The previous discussion implied that there must be a
 5.13154 +	difference between <quote>known</quote> and
 5.13155 +	<quote>applied</quote> patches, and there is.  MQ can manage a
 5.13156 +	patch without it being applied in the repository.</para>
 5.13157 +
 5.13158 +      <para id="x_3dc">An <emphasis>applied</emphasis> patch has a corresponding
 5.13159 +	changeset in the repository, and the effects of the patch and
 5.13160 +	changeset are visible in the working directory.  You can undo
 5.13161 +	the application of a patch using the <command role="hg-ext-mq" moreinfo="none">qpop</command> command.  MQ still
 5.13162 +	<emphasis>knows about</emphasis>, or manages, a popped patch,
 5.13163 +	but the patch no longer has a corresponding changeset in the
 5.13164 +	repository, and the working directory does not contain the
 5.13165 +	changes made by the patch.  <xref linkend="fig:mq:stack"/> illustrates
 5.13166 +	the difference between applied and tracked patches.</para>
 5.13167 +
 5.13168 +      <figure id="fig:mq:stack" float="0">
 5.13169 +	<title>Applied and unapplied patches in the MQ patch
 5.13170 +	  stack</title>
 5.13171 +	<mediaobject>
 5.13172 +	  <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
 5.13173 +	  <textobject><phrase>XXX add text</phrase></textobject>
 5.13174 +	</mediaobject>
 5.13175 +      </figure>
 5.13176 +
 5.13177 +      <para id="x_3de">You can reapply an unapplied, or popped, patch using the
 5.13178 +	<command role="hg-ext-mq" moreinfo="none">qpush</command> command.  This
 5.13179 +	creates a new changeset to correspond to the patch, and the
 5.13180 +	patch's changes once again become present in the working
 5.13181 +	directory.  See below for examples of <command role="hg-ext-mq" moreinfo="none">qpop</command> and <command role="hg-ext-mq" moreinfo="none">qpush</command> in action.</para>
 5.13182 +
 5.13183 +      <!-- BEGIN mq.tutorial.qpop -->
 5.13184 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 5.13185 +first.patch
 5.13186 +second.patch
 5.13187 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop</userinput>
 5.13188 +now at: first.patch
 5.13189 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qseries</userinput>
 5.13190 +first.patch
 5.13191 +second.patch
 5.13192 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 5.13193 +first.patch
 5.13194 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file1</userinput>
 5.13195 +line 1
 5.13196 +line 2
 5.13197 +line 3
 5.13198 +</screen>
 5.13199 +<!-- END mq.tutorial.qpop -->
 5.13200 +
 5.13201 +
 5.13202 +      <para id="x_3df">Notice that once we have popped a patch or two patches,
 5.13203 +	the output of <command role="hg-ext-mq" moreinfo="none">qseries</command>
 5.13204 +	remains the same, while that of <command role="hg-ext-mq" moreinfo="none">qapplied</command> has changed.</para>
 5.13205 +
 5.13206 +    </sect2>
 5.13207 +
 5.13208 +    <sect2>
 5.13209 +      <title>Pushing and popping many patches</title>
 5.13210 +
 5.13211 +      <para id="x_3e0">While <command role="hg-ext-mq" moreinfo="none">qpush</command> and
 5.13212 +	<command role="hg-ext-mq" moreinfo="none">qpop</command> each operate on a
 5.13213 +	single patch at a time by default, you can push and pop many
 5.13214 +	patches in one go.  The <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
 5.13215 +	<command role="hg-ext-mq" moreinfo="none">qpush</command> causes it to push
 5.13216 +	all unapplied patches, while the <option role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command role="hg-ext-mq" moreinfo="none">qpop</command> causes it to pop all applied
 5.13217 +	patches.  (For some more ways to push and pop many patches,
 5.13218 +	see <xref linkend="sec:mq:perf"/> below.)</para>
 5.13219 +
 5.13220 +      <!-- BEGIN mq.tutorial.qpush-a -->
 5.13221 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 5.13222 +applying second.patch
 5.13223 +now at: second.patch
 5.13224 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file1</userinput>
 5.13225 +line 1
 5.13226 +line 2
 5.13227 +line 3
 5.13228 +line 4
 5.13229 +</screen>
 5.13230 +<!-- END mq.tutorial.qpush-a -->
 5.13231 +
 5.13232 +    </sect2>
 5.13233 +
 5.13234 +    <sect2>
 5.13235 +      <title>Safety checks, and overriding them</title>
 5.13236 +
 5.13237 +      <para id="x_3e1">Several MQ commands check the working directory before
 5.13238 +	they do anything, and fail if they find any modifications.
 5.13239 +	They do this to ensure that you won't lose any changes that
 5.13240 +	you have made, but not yet incorporated into a patch.  The
 5.13241 +	example below illustrates this; the <command role="hg-ext-mq" moreinfo="none">qnew</command> command will not create a
 5.13242 +	new patch if there are outstanding changes, caused in this
 5.13243 +	case by the <command role="hg-cmd" moreinfo="none">hg add</command> of
 5.13244 +	<filename moreinfo="none">file3</filename>.</para>
 5.13245 +
 5.13246 +      <!-- BEGIN mq.tutorial.add -->
 5.13247 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'file 3, line 1' &gt;&gt; file3</userinput>
 5.13248 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew add-file3.patch</userinput>
 5.13249 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew -f add-file3.patch</userinput>
 5.13250 +abort: patch "add-file3.patch" already exists
 5.13251 +</screen>
 5.13252 +<!-- END mq.tutorial.add -->
 5.13253 +
 5.13254 +
 5.13255 +      <para id="x_3e2">Commands that check the working directory all take an
 5.13256 +	<quote>I know what I'm doing</quote> option, which is always
 5.13257 +	named <option>-f</option>.  The exact meaning of
 5.13258 +	<option>-f</option> depends on the command.  For example,
 5.13259 +	<command role="hg-cmd" moreinfo="none">hg qnew <option role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
 5.13260 +	will incorporate any outstanding changes into the new patch it
 5.13261 +	creates, but <command role="hg-cmd" moreinfo="none">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
 5.13262 +	will revert modifications to any files affected by the patch
 5.13263 +	that it is popping.  Be sure to read the documentation for a
 5.13264 +	command's <option>-f</option> option before you use it!</para>
 5.13265 +    </sect2>
 5.13266 +
 5.13267 +    <sect2>
 5.13268 +      <title>Working on several patches at once</title>
 5.13269 +
 5.13270 +      <para id="x_3e3">The <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 5.13271 +	always refreshes the <emphasis>topmost</emphasis> applied
 5.13272 +	patch.  This means that you can suspend work on one patch (by
 5.13273 +	refreshing it), pop or push to make a different patch the top,
 5.13274 +	and work on <emphasis>that</emphasis> patch for a
 5.13275 +	while.</para>
 5.13276 +
 5.13277 +      <para id="x_3e4">Here's an example that illustrates how you can use this
 5.13278 +	ability. Let's say you're developing a new feature as two
 5.13279 +	patches.  The first is a change to the core of your software,
 5.13280 +	and the second—layered on top of the
 5.13281 +	first—changes the user interface to use the code you
 5.13282 +	just added to the core.  If you notice a bug in the core while
 5.13283 +	you're working on the UI patch, it's easy to fix the core.
 5.13284 +	Simply <command role="hg-ext-mq" moreinfo="none">qrefresh</command> the UI
 5.13285 +	patch to save your in-progress changes, and <command role="hg-ext-mq" moreinfo="none">qpop</command> down to the core patch.  Fix
 5.13286 +	the core bug, <command role="hg-ext-mq" moreinfo="none">qrefresh</command> the
 5.13287 +	core patch, and <command role="hg-ext-mq" moreinfo="none">qpush</command> back
 5.13288 +	to the UI patch to continue where you left off.</para>
 5.13289 +    </sect2>
 5.13290 +  </sect1>
 5.13291 +
 5.13292 +  <sect1 id="sec:mq:adv-patch">
 5.13293 +    <title>More about patches</title>
 5.13294 +
 5.13295 +    <para id="x_3e5">MQ uses the GNU <command moreinfo="none">patch</command> command to apply
 5.13296 +      patches, so it's helpful to know a few more detailed aspects of
 5.13297 +      how <command moreinfo="none">patch</command> works, and about patches
 5.13298 +      themselves.</para>
 5.13299 +
 5.13300 +    <sect2>
 5.13301 +      <title>The strip count</title>
 5.13302 +
 5.13303 +      <para id="x_3e6">If you look at the file headers in a patch, you will
 5.13304 +	notice that the pathnames usually have an extra component on
 5.13305 +	the front that isn't present in the actual path name.  This is
 5.13306 +	a holdover from the way that people used to generate patches
 5.13307 +	(people still do this, but it's somewhat rare with modern
 5.13308 +	revision control tools).</para>
 5.13309 +
 5.13310 +      <para id="x_3e7">Alice would unpack a tarball, edit her files, then decide
 5.13311 +	that she wanted to create a patch.  So she'd rename her
 5.13312 +	working directory, unpack the tarball again (hence the need
 5.13313 +	for the rename), and use the <option role="cmd-opt-diff">-r</option> and <option role="cmd-opt-diff">-N</option> options to
 5.13314 +	<command moreinfo="none">diff</command> to recursively generate a patch
 5.13315 +	between the unmodified directory and the modified one.  The
 5.13316 +	result would be that the name of the unmodified directory
 5.13317 +	would be at the front of the left-hand path in every file
 5.13318 +	header, and the name of the modified directory would be at the
 5.13319 +	front of the right-hand path.</para>
 5.13320 +
 5.13321 +      <para id="x_3e8">Since someone receiving a patch from the Alices of the net
 5.13322 +	would be unlikely to have unmodified and modified directories
 5.13323 +	with exactly the same names, the <command moreinfo="none">patch</command>
 5.13324 +	command has a <option role="cmd-opt-patch">-p</option> option
 5.13325 +	that indicates the number of leading path name components to
 5.13326 +	strip when trying to apply a patch.  This number is called the
 5.13327 +	<emphasis>strip count</emphasis>.</para>
 5.13328 +
 5.13329 +      <para id="x_3e9">An option of <quote><literal moreinfo="none">-p1</literal></quote> means
 5.13330 +	<quote>use a strip count of one</quote>.  If
 5.13331 +	<command moreinfo="none">patch</command> sees a file name
 5.13332 +	<filename moreinfo="none">foo/bar/baz</filename> in a file header, it will
 5.13333 +	strip <filename moreinfo="none">foo</filename> and try to patch a file named
 5.13334 +	<filename moreinfo="none">bar/baz</filename>.  (Strictly speaking, the strip
 5.13335 +	count refers to the number of <emphasis>path
 5.13336 +	  separators</emphasis> (and the components that go with them
 5.13337 +	) to strip.  A strip count of one will turn
 5.13338 +	<filename moreinfo="none">foo/bar</filename> into <filename moreinfo="none">bar</filename>,
 5.13339 +	but <filename moreinfo="none">/foo/bar</filename> (notice the extra leading
 5.13340 +	slash) into <filename moreinfo="none">foo/bar</filename>.)</para>
 5.13341 +
 5.13342 +      <para id="x_3ea">The <quote>standard</quote> strip count for patches is
 5.13343 +	one; almost all patches contain one leading path name
 5.13344 +	component that needs to be stripped. Mercurial's <command role="hg-cmd" moreinfo="none">hg diff</command> command generates path names
 5.13345 +	in this form, and the <command role="hg-cmd" moreinfo="none">hg
 5.13346 +	  import</command> command and MQ expect patches to have a
 5.13347 +	strip count of one.</para>
 5.13348 +
 5.13349 +      <para id="x_3eb">If you receive a patch from someone that you want to add
 5.13350 +	to your patch queue, and the patch needs a strip count other
 5.13351 +	than one, you cannot just <command role="hg-ext-mq" moreinfo="none">qimport</command> the patch, because
 5.13352 +	<command role="hg-ext-mq" moreinfo="none">qimport</command> does not yet have
 5.13353 +	a <literal moreinfo="none">-p</literal> option (see <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">issue
 5.13354 +	  311</ulink>).  Your best bet is to <command role="hg-ext-mq" moreinfo="none">qnew</command> a patch of your own, then
 5.13355 +	use <command moreinfo="none">patch -pN</command> to apply their patch,
 5.13356 +	followed by <command role="hg-cmd" moreinfo="none">hg addremove</command> to
 5.13357 +	pick up any files added or removed by the patch, followed by
 5.13358 +	<command role="hg-ext-mq" moreinfo="none">hg qrefresh</command>. This
 5.13359 +	complexity may become unnecessary; see <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">issue
 5.13360 +	  311</ulink> for details.
 5.13361 +      </para>
 5.13362 +    </sect2>
 5.13363 +
 5.13364 +    <sect2>
 5.13365 +      <title>Strategies for applying a patch</title>
 5.13366 +
 5.13367 +      <para id="x_3ec">When <command moreinfo="none">patch</command> applies a hunk, it tries a
 5.13368 +	handful of successively less accurate strategies to try to
 5.13369 +	make the hunk apply. This falling-back technique often makes
 5.13370 +	it possible to take a patch that was generated against an old
 5.13371 +	version of a file, and apply it against a newer version of
 5.13372 +	that file.</para>
 5.13373 +
 5.13374 +      <para id="x_3ed">First, <command moreinfo="none">patch</command> tries an exact match,
 5.13375 +	where the line numbers, the context, and the text to be
 5.13376 +	modified must apply exactly.  If it cannot make an exact
 5.13377 +	match, it tries to find an exact match for the context,
 5.13378 +	without honouring the line numbering information.  If this
 5.13379 +	succeeds, it prints a line of output saying that the hunk was
 5.13380 +	applied, but at some <emphasis>offset</emphasis> from the
 5.13381 +	original line number.</para>
 5.13382 +
 5.13383 +      <para id="x_3ee">If a context-only match fails, <command moreinfo="none">patch</command>
 5.13384 +	removes the first and last lines of the context, and tries a
 5.13385 +	<emphasis>reduced</emphasis> context-only match.  If the hunk
 5.13386 +	with reduced context succeeds, it prints a message saying that
 5.13387 +	it applied the hunk with a <emphasis>fuzz factor</emphasis>
 5.13388 +	(the number after the fuzz factor indicates how many lines of
 5.13389 +	context <command moreinfo="none">patch</command> had to trim before the patch
 5.13390 +	applied).</para>
 5.13391 +
 5.13392 +      <para id="x_3ef">When neither of these techniques works,
 5.13393 +	<command moreinfo="none">patch</command> prints a message saying that the hunk
 5.13394 +	in question was rejected.  It saves rejected hunks (also
 5.13395 +	simply called <quote>rejects</quote>) to a file with the same
 5.13396 +	name, and an added <filename role="special" moreinfo="none">.rej</filename>
 5.13397 +	extension.  It also saves an unmodified copy of the file with
 5.13398 +	a <filename role="special" moreinfo="none">.orig</filename> extension; the
 5.13399 +	copy of the file without any extensions will contain any
 5.13400 +	changes made by hunks that <emphasis>did</emphasis> apply
 5.13401 +	cleanly.  If you have a patch that modifies
 5.13402 +	<filename moreinfo="none">foo</filename> with six hunks, and one of them fails
 5.13403 +	to apply, you will have: an unmodified
 5.13404 +	<filename moreinfo="none">foo.orig</filename>, a <filename moreinfo="none">foo.rej</filename>
 5.13405 +	containing one hunk, and <filename moreinfo="none">foo</filename>, containing
 5.13406 +	the changes made by the five successful hunks.</para>
 5.13407 +    </sect2>
 5.13408 +
 5.13409 +    <sect2>
 5.13410 +      <title>Some quirks of patch representation</title>
 5.13411 +
 5.13412 +      <para id="x_3f0">There are a few useful things to know about how
 5.13413 +	<command moreinfo="none">patch</command> works with files.</para>
 5.13414 +      <itemizedlist>
 5.13415 +	<listitem><para id="x_3f1">This should already be obvious, but
 5.13416 +	    <command moreinfo="none">patch</command> cannot handle binary
 5.13417 +	    files.</para>
 5.13418 +	</listitem>
 5.13419 +	<listitem><para id="x_3f2">Neither does it care about the executable bit;
 5.13420 +	    it creates new files as readable, but not
 5.13421 +	    executable.</para>
 5.13422 +	</listitem>
 5.13423 +	<listitem><para id="x_3f3"><command moreinfo="none">patch</command> treats the removal of
 5.13424 +	    a file as a diff between the file to be removed and the
 5.13425 +	    empty file.  So your idea of <quote>I deleted this
 5.13426 +	      file</quote> looks like <quote>every line of this file
 5.13427 +	      was deleted</quote> in a patch.</para>
 5.13428 +	</listitem>
 5.13429 +	<listitem><para id="x_3f4">It treats the addition of a file as a diff
 5.13430 +	    between the empty file and the file to be added.  So in a
 5.13431 +	    patch, your idea of <quote>I added this file</quote> looks
 5.13432 +	    like <quote>every line of this file was
 5.13433 +	      added</quote>.</para>
 5.13434 +	</listitem>
 5.13435 +	<listitem><para id="x_3f5">It treats a renamed file as the removal of the
 5.13436 +	    old name, and the addition of the new name.  This means
 5.13437 +	    that renamed files have a big footprint in patches.  (Note
 5.13438 +	    also that Mercurial does not currently try to infer when
 5.13439 +	    files have been renamed or copied in a patch.)</para>
 5.13440 +	</listitem>
 5.13441 +	<listitem><para id="x_3f6"><command moreinfo="none">patch</command> cannot represent
 5.13442 +	    empty files, so you cannot use a patch to represent the
 5.13443 +	    notion <quote>I added this empty file to the
 5.13444 +	      tree</quote>.</para>
 5.13445 +	</listitem></itemizedlist>
 5.13446 +    </sect2>
 5.13447 +
 5.13448 +    <sect2>
 5.13449 +      <title>Beware the fuzz</title>
 5.13450 +
 5.13451 +      <para id="x_3f7">While applying a hunk at an offset, or with a fuzz factor,
 5.13452 +	will often be completely successful, these inexact techniques
 5.13453 +	naturally leave open the possibility of corrupting the patched
 5.13454 +	file.  The most common cases typically involve applying a
 5.13455 +	patch twice, or at an incorrect location in the file.  If
 5.13456 +	<command moreinfo="none">patch</command> or <command role="hg-ext-mq" moreinfo="none">qpush</command> ever mentions an offset or
 5.13457 +	fuzz factor, you should make sure that the modified files are
 5.13458 +	correct afterwards.</para>
 5.13459 +
 5.13460 +      <para id="x_3f8">It's often a good idea to refresh a patch that has applied
 5.13461 +	with an offset or fuzz factor; refreshing the patch generates
 5.13462 +	new context information that will make it apply cleanly.  I
 5.13463 +	say <quote>often,</quote> not <quote>always,</quote> because
 5.13464 +	sometimes refreshing a patch will make it fail to apply
 5.13465 +	against a different revision of the underlying files.  In some
 5.13466 +	cases, such as when you're maintaining a patch that must sit
 5.13467 +	on top of multiple versions of a source tree, it's acceptable
 5.13468 +	to have a patch apply with some fuzz, provided you've verified
 5.13469 +	the results of the patching process in such cases.</para>
 5.13470 +    </sect2>
 5.13471 +
 5.13472 +    <sect2>
 5.13473 +      <title>Handling rejection</title>
 5.13474 +
 5.13475 +      <para id="x_3f9">If <command role="hg-ext-mq" moreinfo="none">qpush</command> fails to
 5.13476 +	apply a patch, it will print an error message and exit.  If it
 5.13477 +	has left <filename role="special" moreinfo="none">.rej</filename> files
 5.13478 +	behind, it is usually best to fix up the rejected hunks before
 5.13479 +	you push more patches or do any further work.</para>
 5.13480 +
 5.13481 +      <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly,
 5.13482 +	and no longer does because you've changed the underlying code
 5.13483 +	that your patches are based on, Mercurial Queues can help; see
 5.13484 +	<xref linkend="sec:mq:merge"/> for details.</para>
 5.13485 +
 5.13486 +      <para id="x_3fb">Unfortunately, there aren't any great techniques for
 5.13487 +	dealing with rejected hunks.  Most often, you'll need to view
 5.13488 +	the <filename role="special" moreinfo="none">.rej</filename> file and edit the
 5.13489 +	target file, applying the rejected hunks by hand.</para>
 5.13490 +
 5.13491 +      <para id="x_3fd">A Linux kernel hacker, Chris Mason (the author
 5.13492 +	of Mercurial Queues), wrote a tool called
 5.13493 +	<command moreinfo="none">mpatch</command> (<ulink url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>), 
 5.13494 +	which takes a simple approach to automating the application of
 5.13495 +	hunks rejected by <command moreinfo="none">patch</command>.  The
 5.13496 +	<command moreinfo="none">mpatch</command> command can help with four common
 5.13497 +	reasons that a hunk may be rejected:</para>
 5.13498 +
 5.13499 +      <itemizedlist>
 5.13500 +	<listitem><para id="x_3fe">The context in the middle of a hunk has
 5.13501 +	    changed.</para>
 5.13502 +	</listitem>
 5.13503 +	<listitem><para id="x_3ff">A hunk is missing some context at the
 5.13504 +	    beginning or end.</para>
 5.13505 +	</listitem>
 5.13506 +	<listitem><para id="x_400">A large hunk might apply better—either
 5.13507 +	    entirely or in part—if it was broken up into
 5.13508 +	    smaller hunks.</para>
 5.13509 +	</listitem>
 5.13510 +	<listitem><para id="x_401">A hunk removes lines with slightly different
 5.13511 +	    content than those currently present in the file.</para>
 5.13512 +	</listitem></itemizedlist>
 5.13513 +
 5.13514 +      <para id="x_402">If you use <command moreinfo="none">mpatch</command>, you
 5.13515 +	should be doubly careful to check your results when you're
 5.13516 +	done.  In fact, <command moreinfo="none">mpatch</command> enforces this method
 5.13517 +	of double-checking the tool's output, by automatically
 5.13518 +	dropping you into a merge program when it has done its job, so
 5.13519 +	that you can verify its work and finish off any remaining
 5.13520 +	merges.</para>
 5.13521 +    </sect2>
 5.13522 +  </sect1>
 5.13523 +
 5.13524 +  <sect1>
 5.13525 +    <title>More on patch management</title>
 5.13526 +
 5.13527 +    <para id="x_6db">As you grow familiar with MQ, you will find yourself wanting
 5.13528 +      to perform other kinds of patch management operations.</para>
 5.13529 +
 5.13530 +    <sect2>
 5.13531 +      <title>Deleting unwanted patches</title>
 5.13532 +
 5.13533 +      <para id="x_6dc">If you want to get rid of a patch, use the <command role="hg-ext-mq" moreinfo="none">hg qdelete</command> command to delete the
 5.13534 +	patch file and remove its entry from the patch series.  If you
 5.13535 +	try to delete a patch that is still applied, <command role="hg-ext-mq" moreinfo="none">hg qdelete</command> will refuse.</para>
 5.13536 +
 5.13537 +      <!-- BEGIN ch11/qdelete.go -->
 5.13538 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init myrepo</userinput>
 5.13539 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myrepo</userinput>
 5.13540 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 5.13541 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew bad.patch</userinput>
 5.13542 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 5.13543 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 5.13544 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.13545 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qdelete bad.patch</userinput>
 5.13546 +abort: cannot delete applied patch bad.patch
 5.13547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop</userinput>
 5.13548 +patch queue now empty
 5.13549 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qdelete bad.patch</userinput>
 5.13550 +</screen>
 5.13551 +<!-- END ch11/qdelete.go -->
 5.13552 +
 5.13553 +    </sect2>
 5.13554 +
 5.13555 +    <sect2>
 5.13556 +      <title>Converting to and from permanent revisions</title>
 5.13557 +
 5.13558 +      <para id="x_6dd">Once you're done working on a patch and want to
 5.13559 +      turn it into a permanent changeset, use the <command role="hg-ext-mq" moreinfo="none">hg qfinish</command> command. Pass a revision
 5.13560 +      to the command to identify the patch that you want to turn into
 5.13561 +      a regular changeset; this patch must already be applied.</para>
 5.13562 +
 5.13563 +      <!-- BEGIN ch11/qdelete.convert -->
 5.13564 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew good.patch</userinput>
 5.13565 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 5.13566 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 5.13567 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh -m 'Good change'</userinput>
 5.13568 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qfinish tip</userinput>
 5.13569 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 5.13570 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact</userinput>
 5.13571 +0[tip]   32fc5ce6b092   2009-08-16 14:04 +0000   bos
 5.13572 +  Good change
 5.13573 +
 5.13574 +</screen>
 5.13575 +<!-- END ch11/qdelete.convert -->
 5.13576 +
 5.13577 +
 5.13578 +      <para id="x_6e0">The <command role="hg-ext-mq" moreinfo="none">hg qfinish</command> command
 5.13579 +        accepts an <option>--all</option> or <option>-a</option>
 5.13580 +        option, which turns all applied patches into regular
 5.13581 +        changesets.</para>
 5.13582 +
 5.13583 +      <para id="x_6de">It is also possible to turn an existing changeset into a
 5.13584 +	patch, by passing the <option>-r</option> option to <command role="hg-ext-mq" moreinfo="none">hg qimport</command>.</para>
 5.13585 +
 5.13586 +      <!-- BEGIN ch11/qdelete.import -->
 5.13587 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qimport -r tip</userinput>
 5.13588 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 5.13589 +0.diff
 5.13590 +</screen>
 5.13591 +<!-- END ch11/qdelete.import -->
 5.13592 +
 5.13593 +
 5.13594 +      <para id="x_6df">Note that it only makes sense to convert a changeset into
 5.13595 +	a patch if you have not propagated that changeset into any
 5.13596 +	other repositories.  The imported changeset's ID will change
 5.13597 +	every time you refresh the patch, which will make Mercurial
 5.13598 +	treat it as unrelated to the original changeset if you have
 5.13599 +	pushed it somewhere else.</para>
 5.13600 +    </sect2>
 5.13601 +  </sect1>
 5.13602 +
 5.13603 +  <sect1 id="sec:mq:perf">
 5.13604 +    <title>Getting the best performance out of MQ</title>
 5.13605 +
 5.13606 +    <para id="x_403">MQ is very efficient at handling a large number
 5.13607 +      of patches. I ran some performance experiments in mid-2006 for a
 5.13608 +      talk that I gave at the 2006 EuroPython conference (on modern
 5.13609 +      hardware, you should expect better performance than you'll see
 5.13610 +      below).  I used as my data set the Linux 2.6.17-mm1 patch
 5.13611 +      series, which consists of 1,738 patches. I applied these on top
 5.13612 +      of a Linux kernel repository containing all 27,472 revisions
 5.13613 +      between Linux 2.6.12-rc2 and Linux 2.6.17.</para>
 5.13614 +
 5.13615 +    <para id="x_404">On my old, slow laptop, I was able to <command role="hg-cmd" moreinfo="none">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
 5.13616 +      1,738 patches in 3.5 minutes, and <command role="hg-cmd" moreinfo="none">hg qpop
 5.13617 +	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
 5.13618 +      them all in 30 seconds.  (On a newer laptop, the time to push
 5.13619 +      all patches dropped to two minutes.)  I could <command role="hg-ext-mq" moreinfo="none">qrefresh</command> one of the biggest patches
 5.13620 +      (which made 22,779 lines of changes to 287 files) in 6.6
 5.13621 +      seconds.</para>
 5.13622 +
 5.13623 +    <para id="x_405">Clearly, MQ is well suited to working in large trees, but
 5.13624 +      there are a few tricks you can use to get the best performance
 5.13625 +      of it.</para>
 5.13626 +
 5.13627 +    <para id="x_406">First of all, try to <quote>batch</quote> operations
 5.13628 +      together.  Every time you run <command role="hg-ext-mq" moreinfo="none">qpush</command> or <command role="hg-ext-mq" moreinfo="none">qpop</command>, these commands scan the
 5.13629 +      working directory once to make sure you haven't made some
 5.13630 +      changes and then forgotten to run <command role="hg-ext-mq" moreinfo="none">qrefresh</command>.  On a small tree, the
 5.13631 +      time that this scan takes is unnoticeable.  However, on a
 5.13632 +      medium-sized tree (containing tens of thousands of files), it
 5.13633 +      can take a second or more.</para>
 5.13634 +
 5.13635 +    <para id="x_407">The <command role="hg-ext-mq" moreinfo="none">qpush</command> and <command role="hg-ext-mq" moreinfo="none">qpop</command> commands allow you to push and
 5.13636 +      pop multiple patches at a time.  You can identify the
 5.13637 +      <quote>destination patch</quote> that you want to end up at.
 5.13638 +      When you <command role="hg-ext-mq" moreinfo="none">qpush</command> with a
 5.13639 +      destination specified, it will push patches until that patch is
 5.13640 +      at the top of the applied stack.  When you <command role="hg-ext-mq" moreinfo="none">qpop</command> to a destination, MQ will pop
 5.13641 +      patches until the destination patch is at the top.</para>
 5.13642 +
 5.13643 +    <para id="x_408">You can identify a destination patch using either the name
 5.13644 +      of the patch, or by number.  If you use numeric addressing,
 5.13645 +      patches are counted from zero; this means that the first patch
 5.13646 +      is zero, the second is one, and so on.</para>
 5.13647 +  </sect1>
 5.13648 +
 5.13649 +  <sect1 id="sec:mq:merge">
 5.13650 +    <title>Updating your patches when the underlying code
 5.13651 +      changes</title>
 5.13652 +
 5.13653 +    <para id="x_409">It's common to have a stack of patches on top of an
 5.13654 +      underlying repository that you don't modify directly.  If you're
 5.13655 +      working on changes to third-party code, or on a feature that is
 5.13656 +      taking longer to develop than the rate of change of the code
 5.13657 +      beneath, you will often need to sync up with the underlying
 5.13658 +      code, and fix up any hunks in your patches that no longer apply.
 5.13659 +      This is called <emphasis>rebasing</emphasis> your patch
 5.13660 +      series.</para>
 5.13661 +
 5.13662 +    <para id="x_40a">The simplest way to do this is to <command role="hg-cmd" moreinfo="none">hg
 5.13663 +	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
 5.13664 +	  -a</option></command> your patches, then <command role="hg-cmd" moreinfo="none">hg pull</command> changes into the underlying
 5.13665 +      repository, and finally <command role="hg-cmd" moreinfo="none">hg qpush <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
 5.13666 +      patches again.  MQ will stop pushing any time it runs across a
 5.13667 +      patch that fails to apply during conflicts, allowing you to fix
 5.13668 +      your conflicts, <command role="hg-ext-mq" moreinfo="none">qrefresh</command> the
 5.13669 +      affected patch, and continue pushing until you have fixed your
 5.13670 +      entire stack.</para>
 5.13671 +
 5.13672 +    <para id="x_40b">This approach is easy to use and works well if you don't
 5.13673 +      expect changes to the underlying code to affect how well your
 5.13674 +      patches apply. If your patch stack touches code that is modified
 5.13675 +      frequently or invasively in the underlying repository, however,
 5.13676 +      fixing up rejected hunks by hand quickly becomes
 5.13677 +      tiresome.</para>
 5.13678 +
 5.13679 +    <para id="x_40c">It's possible to partially automate the rebasing process.
 5.13680 +      If your patches apply cleanly against some revision of the
 5.13681 +      underlying repo, MQ can use this information to help you to
 5.13682 +      resolve conflicts between your patches and a different
 5.13683 +      revision.</para>
 5.13684 +
 5.13685 +    <para id="x_40d">The process is a little involved.</para>
 5.13686 +    <orderedlist inheritnum="ignore" continuation="restarts">
 5.13687 +      <listitem><para id="x_40e">To begin, <command role="hg-cmd" moreinfo="none">hg qpush
 5.13688 +	    -a</command> all of your patches on top of the revision
 5.13689 +	  where you know that they apply cleanly.</para>
 5.13690 +      </listitem>
 5.13691 +      <listitem><para id="x_40f">Save a backup copy of your patch directory using
 5.13692 +	  <command role="hg-cmd" moreinfo="none">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>.
 5.13693 +	  This prints the name of the directory that it has saved the
 5.13694 +	  patches in.  It will save the patches to a directory called
 5.13695 +	  <filename role="special" class="directory" moreinfo="none">.hg/patches.N</filename>, where
 5.13696 +	  <literal moreinfo="none">N</literal> is a small integer.  It also commits a
 5.13697 +	  <quote>save changeset</quote> on top of your applied
 5.13698 +	  patches; this is for internal book-keeping, and records the
 5.13699 +	  states of the <filename role="special" moreinfo="none">series</filename> and
 5.13700 +	  <filename role="special" moreinfo="none">status</filename> files.</para>
 5.13701 +      </listitem>
 5.13702 +      <listitem><para id="x_410">Use <command role="hg-cmd" moreinfo="none">hg pull</command> to
 5.13703 +	  bring new changes into the underlying repository.  (Don't
 5.13704 +	  run <command role="hg-cmd" moreinfo="none">hg pull -u</command>; see below
 5.13705 +	  for why.)</para>
 5.13706 +      </listitem>
 5.13707 +      <listitem><para id="x_411">Update to the new tip revision, using <command role="hg-cmd" moreinfo="none">hg update <option role="hg-opt-update">-C</option></command> to override
 5.13708 +	  the patches you have pushed.</para>
 5.13709 +      </listitem>
 5.13710 +      <listitem><para id="x_412">Merge all patches using <command moreinfo="none">hg qpush -m
 5.13711 +	    -a</command>.  The <option role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
 5.13712 +	  <command role="hg-ext-mq" moreinfo="none">qpush</command> tells MQ to
 5.13713 +	  perform a three-way merge if the patch fails to
 5.13714 +	  apply.</para>
 5.13715 +      </listitem></orderedlist>
 5.13716 +
 5.13717 +    <para id="x_413">During the <command role="hg-cmd" moreinfo="none">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
 5.13718 +      each patch in the <filename role="special" moreinfo="none">series</filename>
 5.13719 +      file is applied normally.  If a patch applies with fuzz or
 5.13720 +      rejects, MQ looks at the queue you <command role="hg-ext-mq" moreinfo="none">qsave</command>d, and performs a three-way
 5.13721 +      merge with the corresponding changeset.  This merge uses
 5.13722 +      Mercurial's normal merge machinery, so it may pop up a GUI merge
 5.13723 +      tool to help you to resolve problems.</para>
 5.13724 +
 5.13725 +    <para id="x_414">When you finish resolving the effects of a patch, MQ
 5.13726 +      refreshes your patch based on the result of the merge.</para>
 5.13727 +
 5.13728 +    <para id="x_415">At the end of this process, your repository will have one
 5.13729 +      extra head from the old patch queue, and a copy of the old patch
 5.13730 +      queue will be in <filename role="special" class="directory" moreinfo="none">.hg/patches.N</filename>. You can remove the
 5.13731 +      extra head using <command role="hg-cmd" moreinfo="none">hg qpop -a -n
 5.13732 +	patches.N</command> or <command role="hg-cmd" moreinfo="none">hg
 5.13733 +	strip</command>.  You can delete <filename role="special" class="directory" moreinfo="none">.hg/patches.N</filename> once you are sure
 5.13734 +      that you no longer need it as a backup.</para>
 5.13735 +  </sect1>
 5.13736 +
 5.13737 +  <sect1>
 5.13738 +    <title>Identifying patches</title>
 5.13739 +
 5.13740 +    <para id="x_416">MQ commands that work with patches let you refer to a patch
 5.13741 +      either by using its name or by a number.  By name is obvious
 5.13742 +      enough; pass the name <filename moreinfo="none">foo.patch</filename> to <command role="hg-ext-mq" moreinfo="none">qpush</command>, for example, and it will
 5.13743 +      push patches until <filename moreinfo="none">foo.patch</filename> is
 5.13744 +      applied.</para>
 5.13745 +
 5.13746 +    <para id="x_417">As a shortcut, you can refer to a patch using both a name
 5.13747 +      and a numeric offset; <literal moreinfo="none">foo.patch-2</literal> means
 5.13748 +      <quote>two patches before <literal moreinfo="none">foo.patch</literal></quote>,
 5.13749 +      while <literal moreinfo="none">bar.patch+4</literal> means <quote>four patches
 5.13750 +	after <literal moreinfo="none">bar.patch</literal></quote>.</para>
 5.13751 +
 5.13752 +    <para id="x_418">Referring to a patch by index isn't much different.  The
 5.13753 +      first patch printed in the output of <command role="hg-ext-mq" moreinfo="none">qseries</command> is patch zero (yes, it's
 5.13754 +      one of those start-at-zero counting systems); the second is
 5.13755 +      patch one; and so on.</para>
 5.13756 +
 5.13757 +    <para id="x_419">MQ also makes it easy to work with patches when you are
 5.13758 +      using normal Mercurial commands.  Every command that accepts a
 5.13759 +      changeset ID will also accept the name of an applied patch.  MQ
 5.13760 +      augments the tags normally in the repository with an eponymous
 5.13761 +      one for each applied patch.  In addition, the special tags
 5.13762 +      <literal role="tag" moreinfo="none">qbase</literal> and
 5.13763 +      <literal role="tag" moreinfo="none">qtip</literal> identify
 5.13764 +      the <quote>bottom-most</quote> and topmost applied patches,
 5.13765 +      respectively.</para>
 5.13766 +
 5.13767 +    <para id="x_41a">These additions to Mercurial's normal tagging capabilities
 5.13768 +      make dealing with patches even more of a breeze.</para>
 5.13769 +    <itemizedlist>
 5.13770 +      <listitem><para id="x_41b">Want to patchbomb a mailing list with your
 5.13771 +	  latest series of changes?</para>
 5.13772 +	<programlisting format="linespecific">hg email qbase:qtip</programlisting>
 5.13773 +	<para id="x_41c">  (Don't know what <quote>patchbombing</quote> is?  See
 5.13774 +	  <xref linkend="sec:hgext:patchbomb"/>.)</para>
 5.13775 +      </listitem>
 5.13776 +      <listitem><para id="x_41d">Need to see all of the patches since
 5.13777 +	  <literal moreinfo="none">foo.patch</literal> that have touched files in a
 5.13778 +	  subdirectory of your tree?</para>
 5.13779 +	<programlisting format="linespecific">hg log -r foo.patch:qtip subdir</programlisting>
 5.13780 +      </listitem>
 5.13781 +    </itemizedlist>
 5.13782 +
 5.13783 +    <para id="x_41e">Because MQ makes the names of patches available to the rest
 5.13784 +      of Mercurial through its normal internal tag machinery, you
 5.13785 +      don't need to type in the entire name of a patch when you want
 5.13786 +      to identify it by name.</para>
 5.13787 +
 5.13788 +    <para id="x_41f">Another nice consequence of representing patch names as tags
 5.13789 +      is that when you run the <command role="hg-cmd" moreinfo="none">hg log</command>
 5.13790 +      command, it will display a patch's name as a tag, simply as part
 5.13791 +      of its normal output.  This makes it easy to visually
 5.13792 +      distinguish applied patches from underlying
 5.13793 +      <quote>normal</quote> revisions.  The following example shows a
 5.13794 +      few normal Mercurial commands in use with applied
 5.13795 +      patches.</para>
 5.13796 +
 5.13797 +    <!-- BEGIN mq.id.output -->
 5.13798 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 5.13799 +first.patch
 5.13800 +second.patch
 5.13801 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r qbase:qtip</userinput>
 5.13802 +changeset:   1:c3bcf3b7335a
 5.13803 +tag:         first.patch
 5.13804 +tag:         qbase
 5.13805 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.13806 +date:        Sun Aug 16 14:05:08 2009 +0000
 5.13807 +summary:     [mq]: first.patch
 5.13808 +
 5.13809 +changeset:   2:d189ba63b5f7
 5.13810 +tag:         qtip
 5.13811 +tag:         second.patch
 5.13812 +tag:         tip
 5.13813 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.13814 +date:        Sun Aug 16 14:05:09 2009 +0000
 5.13815 +summary:     [mq]: second.patch
 5.13816 +
 5.13817 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg export second.patch</userinput>
 5.13818 +# HG changeset patch
 5.13819 +# User Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.13820 +# Date 1250431509 0
 5.13821 +# Node ID d189ba63b5f7427f9644663c01fc16fe80399c65
 5.13822 +# Parent  c3bcf3b7335afc0a250e85c51a1266d35d43a545
 5.13823 +[mq]: second.patch
 5.13824 +
 5.13825 +diff -r c3bcf3b7335a -r d189ba63b5f7 other.c
 5.13826 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 5.13827 ++++ b/other.c	Sun Aug 16 14:05:09 2009 +0000
 5.13828 +@@ -0,0 +1,1 @@
 5.13829 ++double u;
 5.13830 +</screen>
 5.13831 +<!-- END mq.id.output -->
 5.13832 +
 5.13833 +  </sect1>
 5.13834 +
 5.13835 +  <sect1>
 5.13836 +    <title>Useful things to know about</title>
 5.13837 +
 5.13838 +    <para id="x_420">There are a number of aspects of MQ usage that don't fit
 5.13839 +      tidily into sections of their own, but that are good to know.
 5.13840 +      Here they are, in one place.</para>
 5.13841 +
 5.13842 +    <itemizedlist>
 5.13843 +      <listitem><para id="x_421">Normally, when you <command role="hg-ext-mq" moreinfo="none">qpop</command> a patch and <command role="hg-ext-mq" moreinfo="none">qpush</command> it again, the changeset
 5.13844 +	  that represents the patch after the pop/push will have a
 5.13845 +	  <emphasis>different identity</emphasis> than the changeset
 5.13846 +	  that represented the hash beforehand.  See <xref linkend="sec:mqref:cmd:qpush"/> for
 5.13847 +	  information as to why this is.</para>
 5.13848 +      </listitem>
 5.13849 +      <listitem><para id="x_422">It's not a good idea to <command role="hg-cmd" moreinfo="none">hg merge</command> changes from another
 5.13850 +	  branch with a patch changeset, at least if you want to
 5.13851 +	  maintain the <quote>patchiness</quote> of that changeset and
 5.13852 +	  changesets below it on the patch stack.  If you try to do
 5.13853 +	  this, it will appear to succeed, but MQ will become
 5.13854 +	  confused.</para>
 5.13855 +      </listitem></itemizedlist>
 5.13856 +  </sect1>
 5.13857 +
 5.13858 +  <sect1 id="sec:mq:repo">
 5.13859 +    <title>Managing patches in a repository</title>
 5.13860 +
 5.13861 +    <para id="x_423">Because MQ's <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory resides
 5.13862 +      outside a Mercurial repository's working directory, the
 5.13863 +      <quote>underlying</quote> Mercurial repository knows nothing
 5.13864 +      about the management or presence of patches.</para>
 5.13865 +
 5.13866 +    <para id="x_424">This presents the interesting possibility of managing the
 5.13867 +      contents of the patch directory as a Mercurial repository in its
 5.13868 +      own right.  This can be a useful way to work.  For example, you
 5.13869 +      can work on a patch for a while, <command role="hg-ext-mq" moreinfo="none">qrefresh</command> it, then <command role="hg-cmd" moreinfo="none">hg commit</command> the current state of the
 5.13870 +      patch.  This lets you <quote>roll back</quote> to that version
 5.13871 +      of the patch later on.</para>
 5.13872 +
 5.13873 +    <para id="x_425">You can then share different versions of the same patch
 5.13874 +      stack among multiple underlying repositories.  I use this when I
 5.13875 +      am developing a Linux kernel feature.  I have a pristine copy of
 5.13876 +      my kernel sources for each of several CPU architectures, and a
 5.13877 +      cloned repository under each that contains the patches I am
 5.13878 +      working on.  When I want to test a change on a different
 5.13879 +      architecture, I push my current patches to the patch repository
 5.13880 +      associated with that kernel tree, pop and push all of my
 5.13881 +      patches, and build and test that kernel.</para>
 5.13882 +
 5.13883 +    <para id="x_426">Managing patches in a repository makes it possible for
 5.13884 +      multiple developers to work on the same patch series without
 5.13885 +      colliding with each other, all on top of an underlying source
 5.13886 +      base that they may or may not control.</para>
 5.13887 +
 5.13888 +    <sect2>
 5.13889 +      <title>MQ support for patch repositories</title>
 5.13890 +
 5.13891 +      <para id="x_427">MQ helps you to work with the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory as a
 5.13892 +	repository; when you prepare a repository for working with
 5.13893 +	patches using <command role="hg-ext-mq" moreinfo="none">qinit</command>, you
 5.13894 +	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
 5.13895 +	  -c</option> option to create the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory as a
 5.13896 +	Mercurial repository.</para>
 5.13897 +
 5.13898 +      <note>
 5.13899 +	<para id="x_428">  If you forget to use the <option role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
 5.13900 +	  can simply go into the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory at any
 5.13901 +	  time and run <command role="hg-cmd" moreinfo="none">hg init</command>.
 5.13902 +	  Don't forget to add an entry for the <filename role="special" moreinfo="none">status</filename> file to the <filename role="special" moreinfo="none">.hgignore</filename> file, though</para>
 5.13903 +
 5.13904 +	<para id="x_429">  (<command role="hg-cmd" moreinfo="none">hg qinit <option role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
 5.13905 +	  does this for you automatically); you
 5.13906 +	  <emphasis>really</emphasis> don't want to manage the
 5.13907 +	  <filename role="special" moreinfo="none">status</filename> file.</para>
 5.13908 +      </note>
 5.13909 +
 5.13910 +      <para id="x_42a">As a convenience, if MQ notices that the <filename class="directory" moreinfo="none">.hg/patches</filename> directory is a
 5.13911 +	repository, it will automatically <command role="hg-cmd" moreinfo="none">hg
 5.13912 +	  add</command> every patch that you create and import.</para>
 5.13913 +
 5.13914 +      <para id="x_42b">MQ provides a shortcut command, <command role="hg-ext-mq" moreinfo="none">qcommit</command>, that runs <command role="hg-cmd" moreinfo="none">hg commit</command> in the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>
 5.13915 +	directory.  This saves some bothersome typing.</para>
 5.13916 +
 5.13917 +      <para id="x_42c">Finally, as a convenience to manage the patch directory,
 5.13918 +	you can define the alias <command moreinfo="none">mq</command> on Unix
 5.13919 +	systems. For example, on Linux systems using the
 5.13920 +	<command moreinfo="none">bash</command> shell, you can include the following
 5.13921 +	snippet in your <filename role="home" moreinfo="none">~/.bashrc</filename>.</para>
 5.13922 +
 5.13923 +      <programlisting format="linespecific">alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
 5.13924 +
 5.13925 +      <para id="x_42d">You can then issue commands of the form <command moreinfo="none">mq
 5.13926 +	  pull</command> from the main repository.</para>
 5.13927 +    </sect2>
 5.13928 +
 5.13929 +    <sect2>
 5.13930 +      <title>A few things to watch out for</title>
 5.13931 +
 5.13932 +      <para id="x_42e">MQ's support for working with a repository full of patches
 5.13933 +	is limited in a few small respects.</para>
 5.13934 +
 5.13935 +      <para id="x_42f">MQ cannot automatically detect changes that you make to
 5.13936 +	the patch directory.  If you <command role="hg-cmd" moreinfo="none">hg
 5.13937 +	  pull</command>, manually edit, or <command role="hg-cmd" moreinfo="none">hg
 5.13938 +	  update</command> changes to patches or the <filename role="special" moreinfo="none">series</filename> file, you will have to
 5.13939 +	<command role="hg-cmd" moreinfo="none">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
 5.13940 +	then <command role="hg-cmd" moreinfo="none">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
 5.13941 +	the underlying repository to see those changes show up there.
 5.13942 +	If you forget to do this, you can confuse MQ's idea of which
 5.13943 +	patches are applied.</para>
 5.13944 +
 5.13945 +    </sect2>
 5.13946 +  </sect1>
 5.13947 +  <sect1 id="sec:mq:tools">
 5.13948 +    <title>Third party tools for working with patches</title>
 5.13949 +
 5.13950 +    <para id="x_430">Once you've been working with patches for a while, you'll
 5.13951 +      find yourself hungry for tools that will help you to understand
 5.13952 +      and manipulate the patches you're dealing with.</para>
 5.13953 +
 5.13954 +    <para id="x_431">The <command moreinfo="none">diffstat</command> command
 5.13955 +      <citation>web:diffstat</citation> generates a histogram of the
 5.13956 +      modifications made to each file in a patch.  It provides a good
 5.13957 +      way to <quote>get a sense of</quote> a patch—which files
 5.13958 +      it affects, and how much change it introduces to each file and
 5.13959 +      as a whole.  (I find that it's a good idea to use
 5.13960 +      <command moreinfo="none">diffstat</command>'s <option role="cmd-opt-diffstat">-p</option> option as a matter of
 5.13961 +      course, as otherwise it will try to do clever things with
 5.13962 +      prefixes of file names that inevitably confuse at least
 5.13963 +      me.)</para>
 5.13964 +
 5.13965 +<!-- BEGIN mq.tools.tools -->
 5.13966 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">diffstat -p1 remove-redundant-null-checks.patch</userinput>
 5.13967 + drivers/char/agp/sgi-agp.c        |    5 ++---
 5.13968 + drivers/char/hvcs.c               |   11 +++++------
 5.13969 + drivers/message/fusion/mptfc.c    |    6 ++----
 5.13970 + drivers/message/fusion/mptsas.c   |    3 +--
 5.13971 + drivers/net/fs_enet/fs_enet-mii.c |    3 +--
 5.13972 + drivers/net/wireless/ipw2200.c    |   22 ++++++----------------
 5.13973 + drivers/scsi/libata-scsi.c        |    4 +---
 5.13974 + drivers/video/au1100fb.c          |    3 +--
 5.13975 + 8 files changed, 19 insertions(+), 38 deletions(-)
 5.13976 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">filterdiff -i '*/video/*' remove-redundant-null-checks.patch</userinput>
 5.13977 +--- a/drivers/video/au1100fb.c~remove-redundant-null-checks-before-free-in-drivers
 5.13978 ++++ a/drivers/video/au1100fb.c
 5.13979 +@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void)
 5.13980 + {
 5.13981 + 	driver_unregister(&amp;au1100fb_driver);
 5.13982 + 
 5.13983 +-	if (drv_info.opt_mode)
 5.13984 +-		kfree(drv_info.opt_mode);
 5.13985 ++	kfree(drv_info.opt_mode);
 5.13986 + }
 5.13987 + 
 5.13988 + module_init(au1100fb_init);
 5.13989 +</screen>
 5.13990 +<!-- END mq.tools.tools -->
 5.13991 +
 5.13992 +
 5.13993 +    <para id="x_432">The <literal role="package" moreinfo="none">patchutils</literal> package
 5.13994 +      <citation>web:patchutils</citation> is invaluable. It provides a
 5.13995 +      set of small utilities that follow the <quote>Unix
 5.13996 +	philosophy;</quote> each does one useful thing with a patch.
 5.13997 +      The <literal role="package" moreinfo="none">patchutils</literal> command I use
 5.13998 +      most is <command moreinfo="none">filterdiff</command>, which extracts subsets
 5.13999 +      from a patch file.  For example, given a patch that modifies
 5.14000 +      hundreds of files across dozens of directories, a single
 5.14001 +      invocation of <command moreinfo="none">filterdiff</command> can generate a
 5.14002 +      smaller patch that only touches files whose names match a
 5.14003 +      particular glob pattern.  See <xref linkend="mq-collab:tips:interdiff"/> for another
 5.14004 +      example.</para>
 5.14005 +
 5.14006 +  </sect1>
 5.14007 +  <sect1>
 5.14008 +    <title>Good ways to work with patches</title>
 5.14009 +
 5.14010 +    <para id="x_433">Whether you are working on a patch series to submit to a
 5.14011 +      free software or open source project, or a series that you
 5.14012 +      intend to treat as a sequence of regular changesets when you're
 5.14013 +      done, you can use some simple techniques to keep your work well
 5.14014 +      organized.</para>
 5.14015 +
 5.14016 +    <para id="x_434">Give your patches descriptive names.  A good name for a
 5.14017 +      patch might be <filename moreinfo="none">rework-device-alloc.patch</filename>,
 5.14018 +      because it will immediately give you a hint what the purpose of
 5.14019 +      the patch is.  Long names shouldn't be a problem; you won't be
 5.14020 +      typing the names often, but you <emphasis>will</emphasis> be
 5.14021 +      running commands like <command role="hg-ext-mq" moreinfo="none">qapplied</command> and <command role="hg-ext-mq" moreinfo="none">qtop</command> over and over. Good naming
 5.14022 +      becomes especially important when you have a number of patches
 5.14023 +      to work with, or if you are juggling a number of different tasks
 5.14024 +      and your patches only get a fraction of your attention.</para>
 5.14025 +
 5.14026 +    <para id="x_435">Be aware of what patch you're working on.  Use the <command role="hg-ext-mq" moreinfo="none">qtop</command> command and skim over the text
 5.14027 +      of your patches frequently—for example, using <command role="hg-cmd" moreinfo="none">hg tip <option role="hg-opt-tip">-p</option></command>)—to be sure
 5.14028 +      of where you stand.  I have several times worked on and <command role="hg-ext-mq" moreinfo="none">qrefresh</command>ed a patch other than the
 5.14029 +      one I intended, and it's often tricky to migrate changes into
 5.14030 +      the right patch after making them in the wrong one.</para>
 5.14031 +
 5.14032 +    <para id="x_436">For this reason, it is very much worth investing a little
 5.14033 +      time to learn how to use some of the third-party tools I
 5.14034 +      described in <xref linkend="sec:mq:tools"/>,
 5.14035 +      particularly
 5.14036 +      <command moreinfo="none">diffstat</command> and <command moreinfo="none">filterdiff</command>.
 5.14037 +      The former will give you a quick idea of what changes your patch
 5.14038 +      is making, while the latter makes it easy to splice hunks
 5.14039 +      selectively out of one patch and into another.</para>
 5.14040 +
 5.14041 +  </sect1>
 5.14042 +  <sect1>
 5.14043 +    <title>MQ cookbook</title>
 5.14044 +
 5.14045 +    <sect2>
 5.14046 +      <title>Manage <quote>trivial</quote> patches</title>
 5.14047 +
 5.14048 +      <para id="x_437">Because the overhead of dropping files into a new
 5.14049 +	Mercurial repository is so low, it makes a lot of sense to
 5.14050 +	manage patches this way even if you simply want to make a few
 5.14051 +	changes to a source tarball that you downloaded.</para>
 5.14052 +
 5.14053 +      <para id="x_438">Begin by downloading and unpacking the source tarball, and
 5.14054 +	turning it into a Mercurial repository.</para>
 5.14055 +
 5.14056 +      <!-- BEGIN mq.tarball.download -->
 5.14057 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">download netplug-1.2.5.tar.bz2</userinput>
 5.14058 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">tar jxf netplug-1.2.5.tar.bz2</userinput>
 5.14059 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug-1.2.5</userinput>
 5.14060 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init</userinput>
 5.14061 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -q --addremove --message netplug-1.2.5</userinput>
 5.14062 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
 5.14063 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone netplug-1.2.5 netplug</userinput>
 5.14064 +updating working directory
 5.14065 +18 files updated, 0 files merged, 0 files removed, 0 files unresolved
 5.14066 +</screen>
 5.14067 +<!-- END mq.tarball.download -->
 5.14068 +
 5.14069 +
 5.14070 +      <para id="x_439">Continue by creating a patch stack and making your
 5.14071 +	changes.</para>
 5.14072 +
 5.14073 +      <!-- BEGIN mq.tarball.qinit -->
 5.14074 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug</userinput>
 5.14075 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 5.14076 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew -m 'fix build problem with gcc 4' build-fix.patch</userinput>
 5.14077 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">perl -pi -e 's/int addr_len/socklen_t addr_len/' netlink.c</userinput>
 5.14078 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.14079 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip -p</userinput>
 5.14080 +changeset:   1:eeab56666c54
 5.14081 +tag:         qtip
 5.14082 +tag:         build-fix.patch
 5.14083 +tag:         tip
 5.14084 +tag:         qbase
 5.14085 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 5.14086 +date:        Sun Aug 16 14:05:10 2009 +0000
 5.14087 +summary:     fix build problem with gcc 4
 5.14088 +
 5.14089 +diff -r 1f6afe9a2d68 -r eeab56666c54 netlink.c
 5.14090 +--- a/netlink.c	Sun Aug 16 14:05:09 2009 +0000
 5.14091 ++++ b/netlink.c	Sun Aug 16 14:05:10 2009 +0000
 5.14092 +@@ -275,7 +275,7 @@
 5.14093 +         exit(1);
 5.14094 +     }
 5.14095 + 
 5.14096 +-    int addr_len = sizeof(addr);
 5.14097 ++    socklen_t addr_len = sizeof(addr);
 5.14098 + 
 5.14099 +     if (getsockname(fd, (struct sockaddr *) &amp;addr, &amp;addr_len) == -1) {
 5.14100 +         do_log(LOG_ERR, "Could not get socket details: %m");
 5.14101 +
 5.14102 +</screen>
 5.14103 +<!-- END mq.tarball.qinit -->
 5.14104 +
 5.14105 +
 5.14106 +      <para id="x_43a">Let's say a few weeks or months pass, and your package
 5.14107 +	author releases a new version.  First, bring their changes
 5.14108 +	into the repository.</para>
 5.14109 +
 5.14110 +      <!-- BEGIN mq.tarball.newsource -->
 5.14111 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 5.14112 +patch queue now empty
 5.14113 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
 5.14114 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">download netplug-1.2.8.tar.bz2</userinput>
 5.14115 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone netplug-1.2.5 netplug-1.2.8</userinput>
 5.14116 +updating working directory
 5.14117 +18 files updated, 0 files merged, 0 files removed, 0 files unresolved
 5.14118 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug-1.2.8</userinput>
 5.14119 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg locate -0 | xargs -0 rm</userinput>
 5.14120 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
 5.14121 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">tar jxf netplug-1.2.8.tar.bz2</userinput>
 5.14122 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug-1.2.8</userinput>
 5.14123 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit --addremove --message netplug-1.2.8</userinput>
 5.14124 +</screen>
 5.14125 +<!-- END mq.tarball.newsource -->
 5.14126 +
 5.14127 +
 5.14128 +      <para id="x_43b">The pipeline starting with <command role="hg-cmd" moreinfo="none">hg
 5.14129 +	  locate</command> above deletes all files in the working
 5.14130 +	directory, so that <command role="hg-cmd" moreinfo="none">hg
 5.14131 +	  commit</command>'s <option role="hg-opt-commit">--addremove</option> option can
 5.14132 +	actually tell which files have really been removed in the
 5.14133 +	newer version of the source.</para>
 5.14134 +
 5.14135 +      <para id="x_43c">Finally, you can apply your patches on top of the new
 5.14136 +	tree.</para>
 5.14137 +
 5.14138 +      <!-- BEGIN mq.tarball.repush -->
 5.14139 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../netplug</userinput>
 5.14140 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../netplug-1.2.8</userinput>
 5.14141 +pulling from ../netplug-1.2.8
 5.14142 +searching for changes
 5.14143 +adding changesets
 5.14144 +adding manifests
 5.14145 +adding file changes
 5.14146 +added 1 changesets with 12 changes to 12 files
 5.14147 +(run 'hg update' to get a working copy)
 5.14148 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 5.14149 +(working directory not at tip)
 5.14150 +applying build-fix.patch
 5.14151 +now at: build-fix.patch
 5.14152 +</screen>
 5.14153 +<!-- END mq.tarball.repush -->
 5.14154 +
 5.14155 +    </sect2>
 5.14156 +
 5.14157 +    <sect2 id="sec:mq:combine">
 5.14158 +      <title>Combining entire patches</title>
 5.14159 +
 5.14160 +      <para id="x_43d">MQ provides a command, <command role="hg-ext-mq" moreinfo="none">qfold</command> that lets you combine
 5.14161 +	entire patches.  This <quote>folds</quote> the patches you
 5.14162 +	name, in the order you name them, into the topmost applied
 5.14163 +	patch, and concatenates their descriptions onto the end of its
 5.14164 +	description.  The patches that you fold must be unapplied
 5.14165 +	before you fold them.</para>
 5.14166 +
 5.14167 +      <para id="x_43e">The order in which you fold patches matters.  If your
 5.14168 +	topmost applied patch is <literal moreinfo="none">foo</literal>, and you
 5.14169 +	<command role="hg-ext-mq" moreinfo="none">qfold</command>
 5.14170 +	<literal moreinfo="none">bar</literal> and <literal moreinfo="none">quux</literal> into it,
 5.14171 +	you will end up with a patch that has the same effect as if
 5.14172 +	you applied first <literal moreinfo="none">foo</literal>, then
 5.14173 +	<literal moreinfo="none">bar</literal>, followed by
 5.14174 +	<literal moreinfo="none">quux</literal>.</para>
 5.14175 +    </sect2>
 5.14176 +
 5.14177 +    <sect2>
 5.14178 +      <title>Merging part of one patch into another</title>
 5.14179 +
 5.14180 +      <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into
 5.14181 +	another is more difficult than combining entire
 5.14182 +	patches.</para>
 5.14183 +
 5.14184 +      <para id="x_440">If you want to move changes to entire files, you can use
 5.14185 +	<command moreinfo="none">filterdiff</command>'s <option role="cmd-opt-filterdiff">-i</option> and <option role="cmd-opt-filterdiff">-x</option> options to choose the
 5.14186 +	modifications to snip out of one patch, concatenating its
 5.14187 +	output onto the end of the patch you want to merge into.  You
 5.14188 +	usually won't need to modify the patch you've merged the
 5.14189 +	changes from.  Instead, MQ will report some rejected hunks
 5.14190 +	when you <command role="hg-ext-mq" moreinfo="none">qpush</command> it (from
 5.14191 +	the hunks you moved into the other patch), and you can simply
 5.14192 +	<command role="hg-ext-mq" moreinfo="none">qrefresh</command> the patch to drop
 5.14193 +	the duplicate hunks.</para>
 5.14194 +
 5.14195 +      <para id="x_441">If you have a patch that has multiple hunks modifying a
 5.14196 +	file, and you only want to move a few of those hunks, the job
 5.14197 +	becomes more messy, but you can still partly automate it.  Use
 5.14198 +	<command moreinfo="none">lsdiff -nvv</command> to print some metadata about
 5.14199 +	the patch.</para>
 5.14200 +
 5.14201 +      <!-- BEGIN mq.tools.lsdiff -->
 5.14202 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">lsdiff -nvv remove-redundant-null-checks.patch</userinput>
 5.14203 +22	File #1  	a/drivers/char/agp/sgi-agp.c
 5.14204 +	24	Hunk #1	static int __devinit agp_sgi_init(void)
 5.14205 +37	File #2  	a/drivers/char/hvcs.c
 5.14206 +	39	Hunk #1	static struct tty_operations hvcs_ops = 
 5.14207 +	53	Hunk #2	static int hvcs_alloc_index_list(int n)
 5.14208 +69	File #3  	a/drivers/message/fusion/mptfc.c
 5.14209 +	71	Hunk #1	mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, in
 5.14210 +85	File #4  	a/drivers/message/fusion/mptsas.c
 5.14211 +	87	Hunk #1	mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
 5.14212 +98	File #5  	a/drivers/net/fs_enet/fs_enet-mii.c
 5.14213 +	100	Hunk #1	static struct fs_enet_mii_bus *create_bu
 5.14214 +111	File #6  	a/drivers/net/wireless/ipw2200.c
 5.14215 +	113	Hunk #1	static struct ipw_fw_error *ipw_alloc_er
 5.14216 +	126	Hunk #2	static ssize_t clear_error(struct device
 5.14217 +	140	Hunk #3	static void ipw_irq_tasklet(struct ipw_p
 5.14218 +	150	Hunk #4	static void ipw_pci_remove(struct pci_de
 5.14219 +164	File #7  	a/drivers/scsi/libata-scsi.c
 5.14220 +	166	Hunk #1	int ata_cmd_ioctl(struct scsi_device *sc
 5.14221 +178	File #8  	a/drivers/video/au1100fb.c
 5.14222 +	180	Hunk #1	void __exit au1100fb_cleanup(void)
 5.14223 +</screen>
 5.14224 +<!-- END mq.tools.lsdiff -->
 5.14225 +
 5.14226 +
 5.14227 +      <para id="x_442">This command prints three different kinds of
 5.14228 +	number:</para>
 5.14229 +      <itemizedlist>
 5.14230 +	<listitem><para id="x_443">(in the first column) a <emphasis>file
 5.14231 +	      number</emphasis> to identify each file modified in the
 5.14232 +	    patch;</para>
 5.14233 +	</listitem>
 5.14234 +	<listitem><para id="x_444">(on the next line, indented) the line number
 5.14235 +	    within a modified file where a hunk starts; and</para>
 5.14236 +	</listitem>
 5.14237 +	<listitem><para id="x_445">(on the same line) a <emphasis>hunk
 5.14238 +	      number</emphasis> to identify that hunk.</para>
 5.14239 +	</listitem></itemizedlist>
 5.14240 +
 5.14241 +      <para id="x_446">You'll have to use some visual inspection, and reading of
 5.14242 +	the patch, to identify the file and hunk numbers you'll want,
 5.14243 +	but you can then pass them to to
 5.14244 +	<command moreinfo="none">filterdiff</command>'s <option role="cmd-opt-filterdiff">--files</option> and <option role="cmd-opt-filterdiff">--hunks</option> options, to
 5.14245 +	select exactly the file and hunk you want to extract.</para>
 5.14246 +
 5.14247 +      <para id="x_447">Once you have this hunk, you can concatenate it onto the
 5.14248 +	end of your destination patch and continue with the remainder
 5.14249 +	of <xref linkend="sec:mq:combine"/>.</para>
 5.14250 +
 5.14251 +    </sect2>
 5.14252 +  </sect1>
 5.14253 +  <sect1>
 5.14254 +    <title>Differences between quilt and MQ</title>
 5.14255 +
 5.14256 +    <para id="x_448">If you are already familiar with quilt, MQ provides a
 5.14257 +      similar command set.  There are a few differences in the way
 5.14258 +      that it works.</para>
 5.14259 +
 5.14260 +    <para id="x_449">You will already have noticed that most quilt commands have
 5.14261 +      MQ counterparts that simply begin with a
 5.14262 +      <quote><literal moreinfo="none">q</literal></quote>.  The exceptions are quilt's
 5.14263 +      <literal moreinfo="none">add</literal> and <literal moreinfo="none">remove</literal> commands,
 5.14264 +      the counterparts for which are the normal Mercurial <command role="hg-cmd" moreinfo="none">hg add</command> and <command role="hg-cmd" moreinfo="none">hg
 5.14265 +	remove</command> commands.  There is no MQ equivalent of the
 5.14266 +      quilt <literal moreinfo="none">edit</literal> command.</para>
 5.14267 +
 5.14268 +  </sect1>
 5.14269 +</chapter>
 5.14270 +
 5.14271 +<!--
 5.14272 +local variables: 
 5.14273 +sgml-parent-document: ("00book.xml" "book" "chapter")
 5.14274 +end:
 5.14275 +-->
 5.14276 +
 5.14277 +  <!-- BEGIN ch13 -->
 5.14278 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.14279 +
 5.14280 +<chapter id="chap:mq-collab">
 5.14281 +  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
 5.14282 +  <title>Advanced uses of Mercurial Queues</title>
 5.14283 +
 5.14284 +  <para id="x_15d">While it's easy to pick up straightforward uses of Mercurial
 5.14285 +    Queues, use of a little discipline and some of MQ's less
 5.14286 +    frequently used capabilities makes it possible to work in
 5.14287 +    complicated development environments.</para>
 5.14288 +
 5.14289 +  <para id="x_15e">In this chapter, I will use as an example a technique I have
 5.14290 +    used to manage the development of an Infiniband device driver for
 5.14291 +    the Linux kernel.  The driver in question is large (at least as
 5.14292 +    drivers go), with 25,000 lines of code spread across 35 source
 5.14293 +    files.  It is maintained by a small team of developers.</para>
 5.14294 +
 5.14295 +  <para id="x_15f">While much of the material in this chapter is specific to
 5.14296 +    Linux, the same principles apply to any code base for which you're
 5.14297 +    not the primary owner, and upon which you need to do a lot of
 5.14298 +    development.</para>
 5.14299 +
 5.14300 +  <sect1>
 5.14301 +    <title>The problem of many targets</title>
 5.14302 +
 5.14303 +    <para id="x_160">The Linux kernel changes rapidly, and has never been
 5.14304 +      internally stable; developers frequently make drastic changes
 5.14305 +      between releases. This means that a version of the driver that
 5.14306 +      works well with a particular released version of the kernel will
 5.14307 +      not even <emphasis>compile</emphasis> correctly against,
 5.14308 +      typically, any other version.</para>
 5.14309 +
 5.14310 +    <para id="x_161">To maintain a driver, we have to keep a number of distinct
 5.14311 +      versions of Linux in mind.</para>
 5.14312 +    <itemizedlist>
 5.14313 +      <listitem><para id="x_162">One target is the main Linux kernel development
 5.14314 +	  tree. Maintenance of the code is in this case partly shared
 5.14315 +	  by other developers in the kernel community, who make
 5.14316 +	  <quote>drive-by</quote> modifications to the driver as they
 5.14317 +	  develop and refine kernel subsystems.</para>
 5.14318 +      </listitem>
 5.14319 +      <listitem><para id="x_163">We also maintain a number of
 5.14320 +	  <quote>backports</quote> to older versions of the Linux
 5.14321 +	  kernel, to support the needs of customers who are running
 5.14322 +	  older Linux distributions that do not incorporate our
 5.14323 +	  drivers.  (To <emphasis>backport</emphasis> a piece of code
 5.14324 +	  is to modify it to work in an older version of its target
 5.14325 +	  environment than the version it was developed for.)</para>
 5.14326 +      </listitem>
 5.14327 +      <listitem><para id="x_164">Finally, we make software releases on a schedule
 5.14328 +	  that is necessarily not aligned with those used by Linux
 5.14329 +	  distributors and kernel developers, so that we can deliver
 5.14330 +	  new features to customers without forcing them to upgrade
 5.14331 +	  their entire kernels or distributions.</para>
 5.14332 +      </listitem></itemizedlist>
 5.14333 +
 5.14334 +    <sect2>
 5.14335 +      <title>Tempting approaches that don't work well</title>
 5.14336 +
 5.14337 +      <para id="x_165">There are two <quote>standard</quote> ways to maintain a
 5.14338 +	piece of software that has to target many different
 5.14339 +	environments.</para>
 5.14340 +
 5.14341 +      <para id="x_166">The first is to maintain a number of branches, each
 5.14342 +	intended for a single target.  The trouble with this approach
 5.14343 +	is that you must maintain iron discipline in the flow of
 5.14344 +	changes between repositories. A new feature or bug fix must
 5.14345 +	start life in a <quote>pristine</quote> repository, then
 5.14346 +	percolate out to every backport repository.  Backport changes
 5.14347 +	are more limited in the branches they should propagate to; a
 5.14348 +	backport change that is applied to a branch where it doesn't
 5.14349 +	belong will probably stop the driver from compiling.</para>
 5.14350 +
 5.14351 +      <para id="x_167">The second is to maintain a single source tree filled with
 5.14352 +	conditional statements that turn chunks of code on or off
 5.14353 +	depending on the intended target.  Because these
 5.14354 +	<quote>ifdefs</quote> are not allowed in the Linux kernel
 5.14355 +	tree, a manual or automatic process must be followed to strip
 5.14356 +	them out and yield a clean tree.  A code base maintained in
 5.14357 +	this fashion rapidly becomes a rat's nest of conditional
 5.14358 +	blocks that are difficult to understand and maintain.</para>
 5.14359 +
 5.14360 +      <para id="x_168">Neither of these approaches is well suited to a situation
 5.14361 +	where you don't <quote>own</quote> the canonical copy of a
 5.14362 +	source tree.  In the case of a Linux driver that is
 5.14363 +	distributed with the standard kernel, Linus's tree contains
 5.14364 +	the copy of the code that will be treated by the world as
 5.14365 +	canonical.  The upstream version of <quote>my</quote> driver
 5.14366 +	can be modified by people I don't know, without me even
 5.14367 +	finding out about it until after the changes show up in
 5.14368 +	Linus's tree.</para>
 5.14369 +
 5.14370 +      <para id="x_169">These approaches have the added weakness of making it
 5.14371 +	difficult to generate well-formed patches to submit
 5.14372 +	upstream.</para>
 5.14373 +
 5.14374 +      <para id="x_16a">In principle, Mercurial Queues seems like a good candidate
 5.14375 +	to manage a development scenario such as the above.  While
 5.14376 +	this is indeed the case, MQ contains a few added features that
 5.14377 +	make the job more pleasant.</para>
 5.14378 +
 5.14379 +    </sect2>
 5.14380 +  </sect1>
 5.14381 +  <sect1>
 5.14382 +    <title>Conditionally applying patches with guards</title>
 5.14383 +
 5.14384 +    <para id="x_16b">Perhaps the best way to maintain sanity with so many targets
 5.14385 +      is to be able to choose specific patches to apply for a given
 5.14386 +      situation.  MQ provides a feature called <quote>guards</quote>
 5.14387 +      (which originates with quilt's <literal moreinfo="none">guards</literal>
 5.14388 +      command) that does just this.  To start off, let's create a
 5.14389 +      simple repository for experimenting in.</para>
 5.14390 +
 5.14391 +    <!-- BEGIN mq.guards.init -->
 5.14392 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 5.14393 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew hello.patch</userinput>
 5.14394 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo hello &gt; hello</userinput>
 5.14395 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add hello</userinput>
 5.14396 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.14397 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew goodbye.patch</userinput>
 5.14398 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo goodbye &gt; goodbye</userinput>
 5.14399 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add goodbye</userinput>
 5.14400 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 5.14401 +</screen>
 5.14402 +<!-- END mq.guards.init -->
 5.14403 +
 5.14404 +
 5.14405 +    <para id="x_16c">This gives us a tiny repository that contains two patches
 5.14406 +      that don't have any dependencies on each other, because they
 5.14407 +      touch different files.</para>
 5.14408 +
 5.14409 +    <para id="x_16d">The idea behind conditional application is that you can
 5.14410 +      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
 5.14411 +      which is simply a text string of your choosing, then tell MQ to
 5.14412 +      select specific guards to use when applying patches.  MQ will
 5.14413 +      then either apply, or skip over, a guarded patch, depending on
 5.14414 +      the guards that you have selected.</para>
 5.14415 +
 5.14416 +    <para id="x_16e">A patch can have an arbitrary number of guards; each one is
 5.14417 +      <emphasis>positive</emphasis> (<quote>apply this patch if this
 5.14418 +	guard is selected</quote>) or <emphasis>negative</emphasis>
 5.14419 +      (<quote>skip this patch if this guard is selected</quote>).  A
 5.14420 +      patch with no guards is always applied.</para>
 5.14421 +
 5.14422 +  </sect1>
 5.14423 +  <sect1>
 5.14424 +    <title>Controlling the guards on a patch</title>
 5.14425 +
 5.14426 +    <para id="x_16f">The <command role="hg-ext-mq" moreinfo="none">qguard</command> command lets
 5.14427 +      you determine which guards should apply to a patch, or display
 5.14428 +      the guards that are already in effect. Without any arguments, it
 5.14429 +      displays the guards on the current topmost patch.</para>
 5.14430 +
 5.14431 +      <!-- BEGIN mq.guards.qguard -->
 5.14432 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard</userinput>
 5.14433 +goodbye.patch: unguarded
 5.14434 +</screen>
 5.14435 +<!-- END mq.guards.qguard -->
 5.14436 +
 5.14437 +
 5.14438 +    <para id="x_170">To set a positive guard on a patch, prefix the name of the
 5.14439 +      guard with a <quote><literal moreinfo="none">+</literal></quote>.</para>
 5.14440 +
 5.14441 +      <!-- BEGIN mq.guards.qguard.pos -->
 5.14442 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard +foo</userinput>
 5.14443 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard</userinput>
 5.14444 +goodbye.patch: +foo
 5.14445 +</screen>
 5.14446 +<!-- END mq.guards.qguard.pos -->
 5.14447 +
 5.14448 +
 5.14449 +    <para id="x_171">To set a negative guard
 5.14450 +      on a patch, prefix the name of the guard with a
 5.14451 +      <quote><literal moreinfo="none">-</literal></quote>.</para>
 5.14452 +
 5.14453 +    <!-- BEGIN mq.guards.qguard.neg -->
 5.14454 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard -- hello.patch -quux</userinput>
 5.14455 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard hello.patch</userinput>
 5.14456 +hello.patch: -quux
 5.14457 +</screen>
 5.14458 +<!-- END mq.guards.qguard.neg -->
 5.14459 +
 5.14460 +
 5.14461 +    <para id="x_74a">Notice that we prefixed the arguments to the <command moreinfo="none">hg
 5.14462 +	qguard</command> command with a <literal moreinfo="none">--</literal> here, so
 5.14463 +      that Mercurial would not interpret the text
 5.14464 +      <literal moreinfo="none">-quux</literal> as an option.</para>
 5.14465 +
 5.14466 +    <note>
 5.14467 +      <title>Setting vs. modifying</title>
 5.14468 +
 5.14469 +      <para id="x_172">  The <command role="hg-ext-mq" moreinfo="none">qguard</command> command
 5.14470 +	<emphasis>sets</emphasis> the guards on a patch; it doesn't
 5.14471 +	<emphasis>modify</emphasis> them.  What this means is that if
 5.14472 +	you run <command role="hg-cmd" moreinfo="none">hg qguard +a +b</command> on a
 5.14473 +	patch, then <command role="hg-cmd" moreinfo="none">hg qguard +c</command> on
 5.14474 +	the same patch, the <emphasis>only</emphasis> guard that will
 5.14475 +	be set on it afterwards is <literal moreinfo="none">+c</literal>.</para>
 5.14476 +    </note>
 5.14477 +
 5.14478 +    <para id="x_173">Mercurial stores guards in the <filename role="special" moreinfo="none">series</filename> file; the form in which they
 5.14479 +      are stored is easy both to understand and to edit by hand. (In
 5.14480 +      other words, you don't have to use the <command role="hg-ext-mq" moreinfo="none">qguard</command> command if you don't want
 5.14481 +      to; it's okay to simply edit the <filename role="special" moreinfo="none">series</filename> file.)</para>
 5.14482 +
 5.14483 +    <!-- BEGIN mq.guards.series -->
 5.14484 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/patches/series</userinput>
 5.14485 +hello.patch #-quux
 5.14486 +goodbye.patch #+foo
 5.14487 +</screen>
 5.14488 +<!-- END mq.guards.series -->
 5.14489 +
 5.14490 +
 5.14491 +  </sect1>
 5.14492 +  <sect1>
 5.14493 +    <title>Selecting the guards to use</title>
 5.14494 +
 5.14495 +    <para id="x_174">The <command role="hg-ext-mq" moreinfo="none">qselect</command> command
 5.14496 +      determines which guards are active at a given time.  The effect
 5.14497 +      of this is to determine which patches MQ will apply the next
 5.14498 +      time you run <command role="hg-ext-mq" moreinfo="none">qpush</command>.  It has
 5.14499 +      no other effect; in particular, it doesn't do anything to
 5.14500 +      patches that are already applied.</para>
 5.14501 +
 5.14502 +    <para id="x_175">With no arguments, the <command role="hg-ext-mq" moreinfo="none">qselect</command> command lists the guards
 5.14503 +      currently in effect, one per line of output.  Each argument is
 5.14504 +      treated as the name of a guard to apply.</para>
 5.14505 +
 5.14506 +      <!-- BEGIN mq.guards.qselect.foo -->
 5.14507 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 5.14508 +patch queue now empty
 5.14509 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect</userinput>
 5.14510 +no active guards
 5.14511 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect foo</userinput>
 5.14512 +number of unguarded, unapplied patches has changed from 1 to 2
 5.14513 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect</userinput>
 5.14514 +foo
 5.14515 +</screen>
 5.14516 +<!-- END mq.guards.qselect.foo -->
 5.14517 +
 5.14518 +
 5.14519 +    <para id="x_176">In case you're interested, the currently selected guards are
 5.14520 +      stored in the <filename role="special" moreinfo="none">guards</filename> file.</para>
 5.14521 +
 5.14522 +    <!-- BEGIN mq.guards.qselect.cat -->
 5.14523 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/patches/guards</userinput>
 5.14524 +foo
 5.14525 +</screen>
 5.14526 +<!-- END mq.guards.qselect.cat -->
 5.14527 +
 5.14528 +
 5.14529 +    <para id="x_177">We can see the effect the selected guards have when we run
 5.14530 +      <command role="hg-ext-mq" moreinfo="none">qpush</command>.</para>
 5.14531 +
 5.14532 +    <!-- BEGIN mq.guards.qselect.qpush -->
 5.14533 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 5.14534 +applying hello.patch
 5.14535 +applying goodbye.patch
 5.14536 +now at: goodbye.patch
 5.14537 +</screen>
 5.14538 +<!-- END mq.guards.qselect.qpush -->
 5.14539 +
 5.14540 +
 5.14541 +    <para id="x_178">A guard cannot start with a
 5.14542 +      <quote><literal moreinfo="none">+</literal></quote> or
 5.14543 +      <quote><literal moreinfo="none">-</literal></quote> character.  The name of a
 5.14544 +      guard must not contain white space, but most other characters
 5.14545 +      are acceptable.  If you try to use a guard with an invalid name,
 5.14546 +      MQ will complain:</para>
 5.14547 +
 5.14548 +    <!-- BEGIN mq.guards.qselect.error -->
 5.14549 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect +foo</userinput>
 5.14550 +abort: guard '+foo' starts with invalid character: '+'
 5.14551 +</screen>
 5.14552 +<!-- END mq.guards.qselect.error -->
 5.14553 +
 5.14554 +      
 5.14555 +    <para id="x_179">Changing the selected guards changes the patches that are
 5.14556 +      applied.</para>
 5.14557 +
 5.14558 +    <!-- BEGIN mq.guards.qselect.quux -->
 5.14559 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect quux</userinput>
 5.14560 +number of guarded, applied patches has changed from 0 to 2
 5.14561 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 5.14562 +patch queue now empty
 5.14563 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 5.14564 +patch series already fully applied
 5.14565 +</screen>
 5.14566 +<!-- END mq.guards.qselect.quux -->
 5.14567 +
 5.14568 +
 5.14569 +    <para id="x_17a">You can see in the example below that negative guards take
 5.14570 +      precedence over positive guards.</para>
 5.14571 +
 5.14572 +    <!-- BEGIN mq.guards.qselect.foobar -->
 5.14573 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect foo bar</userinput>
 5.14574 +number of unguarded, unapplied patches has changed from 0 to 2
 5.14575 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 5.14576 +no patches applied
 5.14577 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 5.14578 +applying hello.patch
 5.14579 +applying goodbye.patch
 5.14580 +now at: goodbye.patch
 5.14581 +</screen>
 5.14582 +<!-- END mq.guards.qselect.foobar -->
 5.14583 +
 5.14584 +
 5.14585 +  </sect1>
 5.14586 +  <sect1>
 5.14587 +    <title>MQ's rules for applying patches</title>
 5.14588 +
 5.14589 +    <para id="x_17b">The rules that MQ uses when deciding whether to apply a
 5.14590 +      patch are as follows.</para>
 5.14591 +    <itemizedlist>
 5.14592 +      <listitem><para id="x_17c">A patch that has no guards is always
 5.14593 +	  applied.</para>
 5.14594 +      </listitem>
 5.14595 +      <listitem><para id="x_17d">If the patch has any negative guard that matches
 5.14596 +	  any currently selected guard, the patch is skipped.</para>
 5.14597 +      </listitem>
 5.14598 +      <listitem><para id="x_17e">If the patch has any positive guard that matches
 5.14599 +	  any currently selected guard, the patch is applied.</para>
 5.14600 +      </listitem>
 5.14601 +      <listitem><para id="x_17f">If the patch has positive or negative guards,
 5.14602 +	  but none matches any currently selected guard, the patch is
 5.14603 +	  skipped.</para>
 5.14604 +      </listitem></itemizedlist>
 5.14605 +
 5.14606 +  </sect1>
 5.14607 +  <sect1>
 5.14608 +    <title>Trimming the work environment</title>
 5.14609 +
 5.14610 +    <para id="x_180">In working on the device driver I mentioned earlier, I don't
 5.14611 +      apply the patches to a normal Linux kernel tree.  Instead, I use
 5.14612 +      a repository that contains only a snapshot of the source files
 5.14613 +      and headers that are relevant to Infiniband development.  This
 5.14614 +      repository is 1% the size of a kernel repository, so it's easier
 5.14615 +      to work with.</para>
 5.14616 +
 5.14617 +    <para id="x_181">I then choose a <quote>base</quote> version on top of which
 5.14618 +      the patches are applied.  This is a snapshot of the Linux kernel
 5.14619 +      tree as of a revision of my choosing.  When I take the snapshot,
 5.14620 +      I record the changeset ID from the kernel repository in the
 5.14621 +      commit message.  Since the snapshot preserves the
 5.14622 +      <quote>shape</quote> and content of the relevant parts of the
 5.14623 +      kernel tree, I can apply my patches on top of either my tiny
 5.14624 +      repository or a normal kernel tree.</para>
 5.14625 +
 5.14626 +    <para id="x_182">Normally, the base tree atop which the patches apply should
 5.14627 +      be a snapshot of a very recent upstream tree.  This best
 5.14628 +      facilitates the development of patches that can easily be
 5.14629 +      submitted upstream with few or no modifications.</para>
 5.14630 +
 5.14631 +  </sect1>
 5.14632 +  <sect1>
 5.14633 +    <title>Dividing up the <filename role="special" moreinfo="none">series</filename>
 5.14634 +      file</title>
 5.14635 +
 5.14636 +    <para id="x_183">I categorise the patches in the <filename role="special" moreinfo="none">series</filename> file into a number of logical
 5.14637 +      groups.  Each section of like patches begins with a block of
 5.14638 +      comments that describes the purpose of the patches that
 5.14639 +      follow.</para>
 5.14640 +
 5.14641 +    <para id="x_184">The sequence of patch groups that I maintain follows.  The
 5.14642 +      ordering of these groups is important; I'll describe why after I
 5.14643 +      introduce the groups.</para>
 5.14644 +    <itemizedlist>
 5.14645 +      <listitem><para id="x_185">The <quote>accepted</quote> group.  Patches that
 5.14646 +	  the development team has submitted to the maintainer of the
 5.14647 +	  Infiniband subsystem, and which he has accepted, but which
 5.14648 +	  are not present in the snapshot that the tiny repository is
 5.14649 +	  based on.  These are <quote>read only</quote> patches,
 5.14650 +	  present only to transform the tree into a similar state as
 5.14651 +	  it is in the upstream maintainer's repository.</para>
 5.14652 +      </listitem>
 5.14653 +      <listitem><para id="x_186">The <quote>rework</quote> group.  Patches that I
 5.14654 +	  have submitted, but that the upstream maintainer has
 5.14655 +	  requested modifications to before he will accept
 5.14656 +	  them.</para>
 5.14657 +      </listitem>
 5.14658 +      <listitem><para id="x_187">The <quote>pending</quote> group.  Patches that
 5.14659 +	  I have not yet submitted to the upstream maintainer, but
 5.14660 +	  which we have finished working on. These will be <quote>read
 5.14661 +	    only</quote> for a while.  If the upstream maintainer
 5.14662 +	  accepts them upon submission, I'll move them to the end of
 5.14663 +	  the <quote>accepted</quote> group.  If he requests that I
 5.14664 +	  modify any, I'll move them to the beginning of the
 5.14665 +	  <quote>rework</quote> group.</para>
 5.14666 +      </listitem>
 5.14667 +      <listitem><para id="x_188">The <quote>in progress</quote> group.  Patches
 5.14668 +	  that are actively being developed, and should not be
 5.14669 +	  submitted anywhere yet.</para>
 5.14670 +      </listitem>
 5.14671 +      <listitem><para id="x_189">The <quote>backport</quote> group.  Patches that
 5.14672 +	  adapt the source tree to older versions of the kernel
 5.14673 +	  tree.</para>
 5.14674 +      </listitem>
 5.14675 +      <listitem><para id="x_18a">The <quote>do not ship</quote> group.  Patches
 5.14676 +	  that for some reason should never be submitted upstream.
 5.14677 +	  For example, one such patch might change embedded driver
 5.14678 +	  identification strings to make it easier to distinguish, in
 5.14679 +	  the field, between an out-of-tree version of the driver and
 5.14680 +	  a version shipped by a distribution vendor.</para>
 5.14681 +      </listitem></itemizedlist>
 5.14682 +
 5.14683 +    <para id="x_18b">Now to return to the reasons for ordering groups of patches
 5.14684 +      in this way.  We would like the lowest patches in the stack to
 5.14685 +      be as stable as possible, so that we will not need to rework
 5.14686 +      higher patches due to changes in context.  Putting patches that
 5.14687 +      will never be changed first in the <filename role="special" moreinfo="none">series</filename> file serves this
 5.14688 +      purpose.</para>
 5.14689 +
 5.14690 +    <para id="x_18c">We would also like the patches that we know we'll need to
 5.14691 +      modify to be applied on top of a source tree that resembles the
 5.14692 +      upstream tree as closely as possible.  This is why we keep
 5.14693 +      accepted patches around for a while.</para>
 5.14694 +
 5.14695 +    <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote>
 5.14696 +      patches float at the end of the <filename role="special" moreinfo="none">series</filename> file.  The backport patches
 5.14697 +      must be applied on top of all other patches, and the <quote>do
 5.14698 +	not ship</quote> patches might as well stay out of harm's
 5.14699 +      way.</para>
 5.14700 +
 5.14701 +  </sect1>
 5.14702 +  <sect1>
 5.14703 +    <title>Maintaining the patch series</title>
 5.14704 +
 5.14705 +    <para id="x_18e">In my work, I use a number of guards to control which
 5.14706 +      patches are to be applied.</para>
 5.14707 +
 5.14708 +    <itemizedlist>
 5.14709 +      <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with
 5.14710 +	  <literal moreinfo="none">accepted</literal>.  I enable this guard most of
 5.14711 +	  the time.  When I'm applying the patches on top of a tree
 5.14712 +	  where the patches are already present, I can turn this patch
 5.14713 +	  off, and the patches that follow it will apply
 5.14714 +	  cleanly.</para>
 5.14715 +      </listitem>
 5.14716 +      <listitem><para id="x_190">Patches that are <quote>finished</quote>, but
 5.14717 +	  not yet submitted, have no guards.  If I'm applying the
 5.14718 +	  patch stack to a copy of the upstream tree, I don't need to
 5.14719 +	  enable any guards in order to get a reasonably safe source
 5.14720 +	  tree.</para>
 5.14721 +      </listitem>
 5.14722 +      <listitem><para id="x_191">Those patches that need reworking before being
 5.14723 +	  resubmitted are guarded with
 5.14724 +	  <literal moreinfo="none">rework</literal>.</para>
 5.14725 +      </listitem>
 5.14726 +      <listitem><para id="x_192">For those patches that are still under
 5.14727 +	  development, I use <literal moreinfo="none">devel</literal>.</para>
 5.14728 +      </listitem>
 5.14729 +      <listitem><para id="x_193">A backport patch may have several guards, one
 5.14730 +	  for each version of the kernel to which it applies.  For
 5.14731 +	  example, a patch that backports a piece of code to 2.6.9
 5.14732 +	  will have a <literal moreinfo="none">2.6.9</literal> guard.</para>
 5.14733 +      </listitem></itemizedlist>
 5.14734 +    <para id="x_194">This variety of guards gives me considerable flexibility in
 5.14735 +      determining what kind of source tree I want to end up with.  For
 5.14736 +      most situations, the selection of appropriate guards is
 5.14737 +      automated during the build process, but I can manually tune the
 5.14738 +      guards to use for less common circumstances.</para>
 5.14739 +
 5.14740 +    <sect2>
 5.14741 +      <title>The art of writing backport patches</title>
 5.14742 +
 5.14743 +      <para id="x_195">Using MQ, writing a backport patch is a simple process.
 5.14744 +	All such a patch has to do is modify a piece of code that uses
 5.14745 +	a kernel feature not present in the older version of the
 5.14746 +	kernel, so that the driver continues to work correctly under
 5.14747 +	that older version.</para>
 5.14748 +
 5.14749 +      <para id="x_196">A useful goal when writing a good backport patch is to
 5.14750 +	make your code look as if it was written for the older version
 5.14751 +	of the kernel you're targeting.  The less obtrusive the patch,
 5.14752 +	the easier it will be to understand and maintain.  If you're
 5.14753 +	writing a collection of backport patches to avoid the
 5.14754 +	<quote>rat's nest</quote> effect of lots of
 5.14755 +	<literal moreinfo="none">#ifdef</literal>s (hunks of source code that are only
 5.14756 +	used conditionally) in your code, don't introduce
 5.14757 +	version-dependent <literal moreinfo="none">#ifdef</literal>s into the patches.
 5.14758 +	Instead, write several patches, each of which makes
 5.14759 +	unconditional changes, and control their application using
 5.14760 +	guards.</para>
 5.14761 +
 5.14762 +      <para id="x_197">There are two reasons to divide backport patches into a
 5.14763 +	distinct group, away from the <quote>regular</quote> patches
 5.14764 +	whose effects they modify. The first is that intermingling the
 5.14765 +	two makes it more difficult to use a tool like the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension to automate the
 5.14766 +	process of submitting the patches to an upstream maintainer.
 5.14767 +	The second is that a backport patch could perturb the context
 5.14768 +	in which a subsequent regular patch is applied, making it
 5.14769 +	impossible to apply the regular patch cleanly
 5.14770 +	<emphasis>without</emphasis> the earlier backport patch
 5.14771 +	already being applied.</para>
 5.14772 +
 5.14773 +    </sect2>
 5.14774 +  </sect1>
 5.14775 +  <sect1>
 5.14776 +    <title>Useful tips for developing with MQ</title>
 5.14777 +
 5.14778 +    <sect2>
 5.14779 +      <title>Organising patches in directories</title>
 5.14780 +
 5.14781 +      <para id="x_198">If you're working on a substantial project with MQ, it's
 5.14782 +	not difficult to accumulate a large number of patches.  For
 5.14783 +	example, I have one patch repository that contains over 250
 5.14784 +	patches.</para>
 5.14785 +
 5.14786 +      <para id="x_199">If you can group these patches into separate logical
 5.14787 +	categories, you can if you like store them in different
 5.14788 +	directories; MQ has no problems with patch names that contain
 5.14789 +	path separators.</para>
 5.14790 +
 5.14791 +    </sect2>
 5.14792 +    <sect2 id="mq-collab:tips:interdiff">
 5.14793 +      <title>Viewing the history of a patch</title>
 5.14794 +
 5.14795 +      <para id="x_19a">If you're developing a set of patches over a long time,
 5.14796 +	it's a good idea to maintain them in a repository, as
 5.14797 +	discussed in <xref linkend="sec:mq:repo"/>.  If you do
 5.14798 +	so, you'll quickly
 5.14799 +	discover that using the <command role="hg-cmd" moreinfo="none">hg
 5.14800 +	  diff</command> command to look at the history of changes to
 5.14801 +	a patch is unworkable.  This is in part because you're looking
 5.14802 +	at the second derivative of the real code (a diff of a diff),
 5.14803 +	but also because MQ adds noise to the process by modifying
 5.14804 +	time stamps and directory names when it updates a
 5.14805 +	patch.</para>
 5.14806 +
 5.14807 +      <para id="x_19b">However, you can use the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension, which is bundled
 5.14808 +	with Mercurial, to turn a diff of two versions of a patch into
 5.14809 +	something readable.  To do this, you will need a third-party
 5.14810 +	package called <literal role="package" moreinfo="none">patchutils</literal>
 5.14811 +	<citation>web:patchutils</citation>.  This provides a command
 5.14812 +	named <command moreinfo="none">interdiff</command>, which shows the
 5.14813 +	differences between two diffs as a diff.  Used on two versions
 5.14814 +	of the same diff, it generates a diff that represents the diff
 5.14815 +	from the first to the second version.</para>
 5.14816 +
 5.14817 +      <para id="x_19c">You can enable the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension in the usual way,
 5.14818 +	by adding a line to the <literal role="rc-extensions" moreinfo="none">extensions</literal> section of your
 5.14819 +	<filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
 5.14820 +      <programlisting format="linespecific">[extensions]
 5.14821 +extdiff =</programlisting>
 5.14822 +      <para id="x_19d">The <command moreinfo="none">interdiff</command> command expects to be
 5.14823 +	passed the names of two files, but the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension passes the program
 5.14824 +	it runs a pair of directories, each of which can contain an
 5.14825 +	arbitrary number of files.  We thus need a small program that
 5.14826 +	will run <command moreinfo="none">interdiff</command> on each pair of files in
 5.14827 +	these two directories.  This program is available as <filename role="special" moreinfo="none">hg-interdiff</filename> in the <filename class="directory" moreinfo="none">examples</filename> directory of the
 5.14828 +	source code repository that accompanies this book. <!--
 5.14829 +	&example.hg-interdiff; --></para>
 5.14830 +
 5.14831 +      <para id="x_19e">With the <filename role="special" moreinfo="none">hg-interdiff</filename>
 5.14832 +	program in your shell's search path, you can run it as
 5.14833 +	follows, from inside an MQ patch directory:</para>
 5.14834 +      <programlisting format="linespecific">hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
 5.14835 +      <para id="x_19f">Since you'll probably want to use this long-winded command
 5.14836 +	a lot, you can get <literal role="hg-ext" moreinfo="none">hgext</literal> to
 5.14837 +	make it available as a normal Mercurial command, again by
 5.14838 +	editing your <filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
 5.14839 +      <programlisting format="linespecific">[extdiff]
 5.14840 +cmd.interdiff = hg-interdiff</programlisting>
 5.14841 +      <para id="x_1a0">This directs <literal role="hg-ext" moreinfo="none">hgext</literal> to
 5.14842 +	make an <literal moreinfo="none">interdiff</literal> command available, so you
 5.14843 +	can now shorten the previous invocation of <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> to something a
 5.14844 +	little more wieldy.</para>
 5.14845 +      <programlisting format="linespecific">hg interdiff -r A:B my-change.patch</programlisting>
 5.14846 +
 5.14847 +      <note>
 5.14848 +	<para id="x_1a1">  The <command moreinfo="none">interdiff</command> command works well
 5.14849 +	  only if the underlying files against which versions of a
 5.14850 +	  patch are generated remain the same.  If you create a patch,
 5.14851 +	  modify the underlying files, and then regenerate the patch,
 5.14852 +	  <command moreinfo="none">interdiff</command> may not produce useful
 5.14853 +	  output.</para>
 5.14854 +      </note>
 5.14855 +
 5.14856 +      <para id="x_1a2">The <literal role="hg-ext" moreinfo="none">extdiff</literal> extension is
 5.14857 +	useful for more than merely improving the presentation of MQ
 5.14858 +	patches.  To read more about it, go to <xref linkend="sec:hgext:extdiff"/>.</para>
 5.14859 +
 5.14860 +    </sect2>
 5.14861 +  </sect1>
 5.14862 +</chapter>
 5.14863 +
 5.14864 +<!--
 5.14865 +local variables: 
 5.14866 +sgml-parent-document: ("00book.xml" "book" "chapter")
 5.14867 +end:
 5.14868 +-->
 5.14869 +
 5.14870 +  <!-- BEGIN ch14 -->
 5.14871 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.14872 +
 5.14873 +<chapter id="chap:hgext">
 5.14874 +  <?dbhtml filename="adding-functionality-with-extensions.html"?>
 5.14875 +  <title>Adding functionality with extensions</title>
 5.14876 +
 5.14877 +  <para id="x_4fe">While the core of Mercurial is quite complete from a
 5.14878 +    functionality standpoint, it's deliberately shorn of fancy
 5.14879 +    features.  This approach of preserving simplicity keeps the
 5.14880 +    software easy to deal with for both maintainers and users.</para>
 5.14881 +
 5.14882 +  <para id="x_4ff">However, Mercurial doesn't box you in with an inflexible
 5.14883 +    command set: you can add features to it as
 5.14884 +    <emphasis>extensions</emphasis> (sometimes known as
 5.14885 +    <emphasis>plugins</emphasis>).  We've already discussed a few of
 5.14886 +    these extensions in earlier chapters.</para>
 5.14887 +  <itemizedlist>
 5.14888 +    <listitem><para id="x_500"><xref linkend="sec:tour-merge:fetch"/>
 5.14889 +	covers the <literal role="hg-ext" moreinfo="none">fetch</literal> extension;
 5.14890 +	this combines pulling new changes and merging them with local
 5.14891 +	changes into a single command, <command role="hg-ext-fetch" moreinfo="none">fetch</command>.</para>
 5.14892 +    </listitem>
 5.14893 +    <listitem><para id="x_501">In <xref linkend="chap:hook"/>, we covered
 5.14894 +	several extensions that are useful for hook-related
 5.14895 +	functionality: <literal role="hg-ext" moreinfo="none">acl</literal> adds
 5.14896 +	access control lists; <literal role="hg-ext" moreinfo="none">bugzilla</literal> adds integration with the
 5.14897 +	Bugzilla bug tracking system; and <literal role="hg-ext" moreinfo="none">notify</literal> sends notification emails on
 5.14898 +	new changes.</para>
 5.14899 +    </listitem>
 5.14900 +    <listitem><para id="x_502">The Mercurial Queues patch management extension is
 5.14901 +	so invaluable that it merits two chapters and an appendix all
 5.14902 +	to itself. <xref linkend="chap:mq"/> covers the
 5.14903 +	basics; <xref linkend="chap:mq-collab"/> discusses advanced topics;
 5.14904 +	and <xref linkend="chap:mqref"/> goes into detail on
 5.14905 +	each
 5.14906 +	command.</para>
 5.14907 +    </listitem></itemizedlist>
 5.14908 +
 5.14909 +  <para id="x_503">In this chapter, we'll cover some of the other extensions that
 5.14910 +    are available for Mercurial, and briefly touch on some of the
 5.14911 +    machinery you'll need to know about if you want to write an
 5.14912 +    extension of your own.</para>
 5.14913 +  <itemizedlist>
 5.14914 +    <listitem><para id="x_504">In <xref linkend="sec:hgext:inotify"/>,
 5.14915 +	we'll discuss the possibility of <emphasis>huge</emphasis>
 5.14916 +	performance improvements using the <literal role="hg-ext" moreinfo="none">inotify</literal> extension.</para>
 5.14917 +    </listitem></itemizedlist>
 5.14918 +
 5.14919 +  <sect1 id="sec:hgext:inotify">
 5.14920 +    <title>Improve performance with the <literal role="hg-ext" moreinfo="none">inotify</literal> extension</title>
 5.14921 +
 5.14922 +    <para id="x_505">Are you interested in having some of the most common
 5.14923 +      Mercurial operations run as much as a hundred times faster?
 5.14924 +      Read on!</para>
 5.14925 +
 5.14926 +    <para id="x_506">Mercurial has great performance under normal circumstances.
 5.14927 +      For example, when you run the <command role="hg-cmd" moreinfo="none">hg
 5.14928 +	status</command> command, Mercurial has to scan almost every
 5.14929 +      directory and file in your repository so that it can display
 5.14930 +      file status.  Many other Mercurial commands need to do the same
 5.14931 +      work behind the scenes; for example, the <command role="hg-cmd" moreinfo="none">hg diff</command> command uses the status
 5.14932 +      machinery to avoid doing an expensive comparison operation on
 5.14933 +      files that obviously haven't changed.</para>
 5.14934 +
 5.14935 +    <para id="x_507">Because obtaining file status is crucial to good
 5.14936 +      performance, the authors of Mercurial have optimised this code
 5.14937 +      to within an inch of its life.  However, there's no avoiding the
 5.14938 +      fact that when you run <command role="hg-cmd" moreinfo="none">hg
 5.14939 +	status</command>, Mercurial is going to have to perform at
 5.14940 +      least one expensive system call for each managed file to
 5.14941 +      determine whether it's changed since the last time Mercurial
 5.14942 +      checked.  For a sufficiently large repository, this can take a
 5.14943 +      long time.</para>
 5.14944 +
 5.14945 +    <para id="x_508">To put a number on the magnitude of this effect, I created a
 5.14946 +      repository containing 150,000 managed files.  I timed <command role="hg-cmd" moreinfo="none">hg status</command> as taking ten seconds to
 5.14947 +      run, even when <emphasis>none</emphasis> of those files had been
 5.14948 +      modified.</para>
 5.14949 +
 5.14950 +    <para id="x_509">Many modern operating systems contain a file notification
 5.14951 +      facility. If a program signs up to an appropriate service, the
 5.14952 +      operating system will notify it every time a file of interest is
 5.14953 +      created, modified, or deleted.  On Linux systems, the kernel
 5.14954 +      component that does this is called
 5.14955 +      <literal moreinfo="none">inotify</literal>.</para>
 5.14956 +
 5.14957 +    <para id="x_50a">Mercurial's <literal role="hg-ext" moreinfo="none">inotify</literal>
 5.14958 +      extension talks to the kernel's <literal moreinfo="none">inotify</literal>
 5.14959 +      component to optimise <command role="hg-cmd" moreinfo="none">hg status</command>
 5.14960 +      commands.  The extension has two components.  A daemon sits in
 5.14961 +      the background and receives notifications from the
 5.14962 +      <literal moreinfo="none">inotify</literal> subsystem.  It also listens for
 5.14963 +      connections from a regular Mercurial command.  The extension
 5.14964 +      modifies Mercurial's behavior so that instead of scanning the
 5.14965 +      filesystem, it queries the daemon.  Since the daemon has perfect
 5.14966 +      information about the state of the repository, it can respond
 5.14967 +      with a result instantaneously, avoiding the need to scan every
 5.14968 +      directory and file in the repository.</para>
 5.14969 +
 5.14970 +    <para id="x_50b">Recall the ten seconds that I measured plain Mercurial as
 5.14971 +      taking to run <command role="hg-cmd" moreinfo="none">hg status</command> on a
 5.14972 +      150,000 file repository.  With the <literal role="hg-ext" moreinfo="none">inotify</literal> extension enabled, the time
 5.14973 +      dropped to 0.1 seconds, a factor of <emphasis>one
 5.14974 +	hundred</emphasis> faster.</para>
 5.14975 +
 5.14976 +    <para id="x_50c">Before we continue, please pay attention to some
 5.14977 +      caveats.</para>
 5.14978 +    <itemizedlist>
 5.14979 +      <listitem><para id="x_50d">The <literal role="hg-ext" moreinfo="none">inotify</literal>
 5.14980 +	  extension is Linux-specific.  Because it interfaces directly
 5.14981 +	  to the Linux kernel's <literal moreinfo="none">inotify</literal> subsystem,
 5.14982 +	  it does not work on other operating systems.</para>
 5.14983 +      </listitem>
 5.14984 +      <listitem><para id="x_50e">It should work on any Linux distribution that
 5.14985 +	  was released after early 2005.  Older distributions are
 5.14986 +	  likely to have a kernel that lacks
 5.14987 +	  <literal moreinfo="none">inotify</literal>, or a version of
 5.14988 +	  <literal moreinfo="none">glibc</literal> that does not have the necessary
 5.14989 +	  interfacing support.</para>
 5.14990 +      </listitem>
 5.14991 +      <listitem><para id="x_50f">Not all filesystems are suitable for use with
 5.14992 +	  the <literal role="hg-ext" moreinfo="none">inotify</literal> extension.
 5.14993 +	  Network filesystems such as NFS are a non-starter, for
 5.14994 +	  example, particularly if you're running Mercurial on several
 5.14995 +	  systems, all mounting the same network filesystem.  The
 5.14996 +	  kernel's <literal moreinfo="none">inotify</literal> system has no way of
 5.14997 +	  knowing about changes made on another system.  Most local
 5.14998 +	  filesystems (e.g. ext3, XFS, ReiserFS) should work
 5.14999 +	  fine.</para>
 5.15000 +      </listitem></itemizedlist>
 5.15001 +
 5.15002 +    <para id="x_510">The <literal role="hg-ext" moreinfo="none">inotify</literal> extension is
 5.15003 +      not yet shipped with Mercurial as of May 2007, so it's a little
 5.15004 +      more involved to set up than other extensions.  But the
 5.15005 +      performance improvement is worth it!</para>
 5.15006 +
 5.15007 +    <para id="x_511">The extension currently comes in two parts: a set of patches
 5.15008 +      to the Mercurial source code, and a library of Python bindings
 5.15009 +      to the <literal moreinfo="none">inotify</literal> subsystem.</para>
 5.15010 +    <note>
 5.15011 +      <para id="x_512">  There are <emphasis>two</emphasis> Python
 5.15012 +	<literal moreinfo="none">inotify</literal> binding libraries.  One of them is
 5.15013 +	called <literal moreinfo="none">pyinotify</literal>, and is packaged by some
 5.15014 +	Linux distributions as <literal moreinfo="none">python-inotify</literal>.
 5.15015 +	This is <emphasis>not</emphasis> the one you'll need, as it is
 5.15016 +	too buggy and inefficient to be practical.</para>
 5.15017 +    </note>
 5.15018 +    <para id="x_513">To get going, it's best to already have a functioning copy
 5.15019 +      of Mercurial installed.</para>
 5.15020 +    <note>
 5.15021 +      <para id="x_514">  If you follow the instructions below, you'll be
 5.15022 +	<emphasis>replacing</emphasis> and overwriting any existing
 5.15023 +	installation of Mercurial that you might already have, using
 5.15024 +	the latest <quote>bleeding edge</quote> Mercurial code. Don't
 5.15025 +	say you weren't warned!</para>
 5.15026 +    </note>
 5.15027 +    <orderedlist inheritnum="ignore" continuation="restarts">
 5.15028 +      <listitem><para id="x_515">Clone the Python <literal moreinfo="none">inotify</literal>
 5.15029 +	  binding repository.  Build and install it.</para>
 5.15030 +	<programlisting format="linespecific">hg clone http://hg.kublai.com/python/inotify
 5.15031 +cd inotify
 5.15032 +python setup.py build --force
 5.15033 +sudo python setup.py install --skip-build</programlisting>
 5.15034 +      </listitem>
 5.15035 +      <listitem><para id="x_516">Clone the <filename class="directory" moreinfo="none">crew</filename> Mercurial repository.
 5.15036 +	  Clone the <literal role="hg-ext" moreinfo="none">inotify</literal> patch
 5.15037 +	  repository so that Mercurial Queues will be able to apply
 5.15038 +	  patches to your cope of the <filename class="directory" moreinfo="none">crew</filename> repository.</para>
 5.15039 +	<programlisting format="linespecific">hg clone http://hg.intevation.org/mercurial/crew
 5.15040 +hg clone crew inotify
 5.15041 +hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
 5.15042 +      </listitem>
 5.15043 +      <listitem><para id="x_517">Make sure that you have the Mercurial Queues
 5.15044 +	  extension, <literal role="hg-ext" moreinfo="none">mq</literal>, enabled.  If
 5.15045 +	  you've never used MQ, read <xref linkend="sec:mq:start"/> to get started
 5.15046 +	  quickly.</para>
 5.15047 +      </listitem>
 5.15048 +      <listitem><para id="x_518">Go into the <filename class="directory" moreinfo="none">inotify</filename> repo, and apply all
 5.15049 +	  of the <literal role="hg-ext" moreinfo="none">inotify</literal> patches
 5.15050 +	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
 5.15051 +	    -a</option> option to the <command role="hg-ext-mq" moreinfo="none">qpush</command> command.</para>
 5.15052 +	<programlisting format="linespecific">cd inotify
 5.15053 +hg qpush -a</programlisting>
 5.15054 +      </listitem>
 5.15055 +      <listitem><para id="x_519">  If you get an error message from <command role="hg-ext-mq" moreinfo="none">qpush</command>, you should not continue.
 5.15056 +	  Instead, ask for help.</para>
 5.15057 +      </listitem>
 5.15058 +      <listitem><para id="x_51a">Build and install the patched version of
 5.15059 +	  Mercurial.</para>
 5.15060 +	<programlisting format="linespecific">python setup.py build --force
 5.15061 +sudo python setup.py install --skip-build</programlisting>
 5.15062 +      </listitem>
 5.15063 +    </orderedlist>
 5.15064 +    <para id="x_51b">Once you've build a suitably patched version of Mercurial,
 5.15065 +      all you need to do to enable the <literal role="hg-ext" moreinfo="none">inotify</literal> extension is add an entry to
 5.15066 +      your <filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
 5.15067 +    <programlisting format="linespecific">[extensions] inotify =</programlisting>
 5.15068 +    <para id="x_51c">When the <literal role="hg-ext" moreinfo="none">inotify</literal> extension
 5.15069 +      is enabled, Mercurial will automatically and transparently start
 5.15070 +      the status daemon the first time you run a command that needs
 5.15071 +      status in a repository.  It runs one status daemon per
 5.15072 +      repository.</para>
 5.15073 +
 5.15074 +    <para id="x_51d">The status daemon is started silently, and runs in the
 5.15075 +      background.  If you look at a list of running processes after
 5.15076 +      you've enabled the <literal role="hg-ext" moreinfo="none">inotify</literal>
 5.15077 +      extension and run a few commands in different repositories,
 5.15078 +      you'll thus see a few <literal moreinfo="none">hg</literal> processes sitting
 5.15079 +      around, waiting for updates from the kernel and queries from
 5.15080 +      Mercurial.</para>
 5.15081 +
 5.15082 +    <para id="x_51e">The first time you run a Mercurial command in a repository
 5.15083 +      when you have the <literal role="hg-ext" moreinfo="none">inotify</literal>
 5.15084 +      extension enabled, it will run with about the same performance
 5.15085 +      as a normal Mercurial command.  This is because the status
 5.15086 +      daemon needs to perform a normal status scan so that it has a
 5.15087 +      baseline against which to apply later updates from the kernel.
 5.15088 +      However, <emphasis>every</emphasis> subsequent command that does
 5.15089 +      any kind of status check should be noticeably faster on
 5.15090 +      repositories of even fairly modest size.  Better yet, the bigger
 5.15091 +      your repository is, the greater a performance advantage you'll
 5.15092 +      see.  The <literal role="hg-ext" moreinfo="none">inotify</literal> daemon makes
 5.15093 +      status operations almost instantaneous on repositories of all
 5.15094 +      sizes!</para>
 5.15095 +
 5.15096 +    <para id="x_51f">If you like, you can manually start a status daemon using
 5.15097 +      the <command role="hg-ext-inotify" moreinfo="none">inserve</command> command.
 5.15098 +      This gives you slightly finer control over how the daemon ought
 5.15099 +      to run.  This command will of course only be available when the
 5.15100 +      <literal role="hg-ext" moreinfo="none">inotify</literal> extension is
 5.15101 +      enabled.</para>
 5.15102 +
 5.15103 +    <para id="x_520">When you're using the <literal role="hg-ext" moreinfo="none">inotify</literal> extension, you should notice
 5.15104 +      <emphasis>no difference at all</emphasis> in Mercurial's
 5.15105 +      behavior, with the sole exception of status-related commands
 5.15106 +      running a whole lot faster than they used to.  You should
 5.15107 +      specifically expect that commands will not print different
 5.15108 +      output; neither should they give different results. If either of
 5.15109 +      these situations occurs, please report a bug.</para>
 5.15110 +
 5.15111 +  </sect1>
 5.15112 +  <sect1 id="sec:hgext:extdiff">
 5.15113 +    <title>Flexible diff support with the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension</title>
 5.15114 +
 5.15115 +    <para id="x_521">Mercurial's built-in <command role="hg-cmd" moreinfo="none">hg
 5.15116 +	diff</command> command outputs plaintext unified diffs.</para>
 5.15117 +
 5.15118 +    <!-- BEGIN extdiff.diff -->
 5.15119 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
 5.15120 +diff -r 801b35c37d8b myfile
 5.15121 +--- a/myfile	Sun Aug 16 14:05:02 2009 +0000
 5.15122 ++++ b/myfile	Sun Aug 16 14:05:02 2009 +0000
 5.15123 +@@ -1,1 +1,2 @@
 5.15124 + The first line.
 5.15125 ++The second line.
 5.15126 +</screen>
 5.15127 +<!-- END extdiff.diff -->
 5.15128 +
 5.15129 +
 5.15130 +    <para id="x_522">If you would like to use an external tool to display
 5.15131 +      modifications, you'll want to use the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension.  This will let you
 5.15132 +      use, for example, a graphical diff tool.</para>
 5.15133 +
 5.15134 +    <para id="x_523">The <literal role="hg-ext" moreinfo="none">extdiff</literal> extension is
 5.15135 +      bundled with Mercurial, so it's easy to set up.  In the <literal role="rc-extensions" moreinfo="none">extensions</literal> section of your
 5.15136 +      <filename role="special" moreinfo="none">~/.hgrc</filename>, simply add a
 5.15137 +      one-line entry to enable the extension.</para>
 5.15138 +    <programlisting format="linespecific">[extensions]
 5.15139 +extdiff =</programlisting>
 5.15140 +    <para id="x_524">This introduces a command named <command role="hg-ext-extdiff" moreinfo="none">extdiff</command>, which by default uses
 5.15141 +      your system's <command moreinfo="none">diff</command> command to generate a
 5.15142 +      unified diff in the same form as the built-in <command role="hg-cmd" moreinfo="none">hg diff</command> command.</para>
 5.15143 +    
 5.15144 +    <!-- BEGIN extdiff.extdiff -->
 5.15145 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg extdiff</userinput>
 5.15146 +--- a.801b35c37d8b/myfile	2009-08-16 14:05:02.000000000 +0000
 5.15147 ++++ /tmp/extdiffl1y_s9/a/myfile	2009-08-16 14:05:02.000000000 +0000
 5.15148 +@@ -1 +1,2 @@
 5.15149 + The first line.
 5.15150 ++The second line.
 5.15151 +</screen>
 5.15152 +<!-- END extdiff.extdiff -->
 5.15153 +
 5.15154 +
 5.15155 +    <para id="x_525">The result won't be exactly the same as with the built-in
 5.15156 +      <command role="hg-cmd" moreinfo="none">hg diff</command> variations, because the
 5.15157 +      output of <command moreinfo="none">diff</command> varies from one system to
 5.15158 +      another, even when passed the same options.</para>
 5.15159 +
 5.15160 +    <para id="x_526">As the <quote><literal moreinfo="none">making snapshot</literal></quote>
 5.15161 +      lines of output above imply, the <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command works by
 5.15162 +      creating two snapshots of your source tree.  The first snapshot
 5.15163 +      is of the source revision; the second, of the target revision or
 5.15164 +      working directory.  The <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command generates
 5.15165 +      these snapshots in a temporary directory, passes the name of
 5.15166 +      each directory to an external diff viewer, then deletes the
 5.15167 +      temporary directory.  For efficiency, it only snapshots the
 5.15168 +      directories and files that have changed between the two
 5.15169 +      revisions.</para>
 5.15170 +
 5.15171 +    <para id="x_527">Snapshot directory names have the same base name as your
 5.15172 +      repository. If your repository path is <filename class="directory" moreinfo="none">/quux/bar/foo</filename>, then <filename class="directory" moreinfo="none">foo</filename> will be the name of each
 5.15173 +      snapshot directory.  Each snapshot directory name has its
 5.15174 +      changeset ID appended, if appropriate.  If a snapshot is of
 5.15175 +      revision <literal moreinfo="none">a631aca1083f</literal>, the directory will be
 5.15176 +      named <filename class="directory" moreinfo="none">foo.a631aca1083f</filename>.
 5.15177 +      A snapshot of the working directory won't have a changeset ID
 5.15178 +      appended, so it would just be <filename class="directory" moreinfo="none">foo</filename> in this example.  To see what
 5.15179 +      this looks like in practice, look again at the <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> example above.  Notice
 5.15180 +      that the diff has the snapshot directory names embedded in its
 5.15181 +      header.</para>
 5.15182 +
 5.15183 +    <para id="x_528">The <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command
 5.15184 +      accepts two important options. The <option role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
 5.15185 +      lets you choose a program to view differences with, instead of
 5.15186 +      <command moreinfo="none">diff</command>.  With the <option role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
 5.15187 +      you can change the options that <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> passes to the program
 5.15188 +      (by default, these options are
 5.15189 +      <quote><literal moreinfo="none">-Npru</literal></quote>, which only make sense
 5.15190 +      if you're running <command moreinfo="none">diff</command>).  In other respects,
 5.15191 +      the <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command
 5.15192 +      acts similarly to the built-in <command role="hg-cmd" moreinfo="none">hg
 5.15193 +	diff</command> command: you use the same option names, syntax,
 5.15194 +      and arguments to specify the revisions you want, the files you
 5.15195 +      want, and so on.</para>
 5.15196 +
 5.15197 +    <para id="x_529">As an example, here's how to run the normal system
 5.15198 +      <command moreinfo="none">diff</command> command, getting it to generate context
 5.15199 +      diffs (using the <option role="cmd-opt-diff">-c</option> option)
 5.15200 +      instead of unified diffs, and five lines of context instead of
 5.15201 +      the default three (passing <literal moreinfo="none">5</literal> as the argument
 5.15202 +      to the <option role="cmd-opt-diff">-C</option> option).</para>
 5.15203 +
 5.15204 +      <!-- BEGIN extdiff.extdiff-ctx -->
 5.15205 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg extdiff -o -NprcC5</userinput>
 5.15206 +*** a.801b35c37d8b/myfile	Sun Aug 16 14:05:02 2009
 5.15207 +--- /tmp/extdiffl1y_s9/a/myfile	Sun Aug 16 14:05:02 2009
 5.15208 +***************
 5.15209 +*** 1 ****
 5.15210 +--- 1,2 ----
 5.15211 +  The first line.
 5.15212 ++ The second line.
 5.15213 +</screen>
 5.15214 +<!-- END extdiff.extdiff-ctx -->
 5.15215 +
 5.15216 +
 5.15217 +    <para id="x_52a">Launching a visual diff tool is just as easy.  Here's how to
 5.15218 +      launch the <command moreinfo="none">kdiff3</command> viewer.</para>
 5.15219 +    <programlisting format="linespecific">hg extdiff -p kdiff3 -o</programlisting>
 5.15220 +
 5.15221 +    <para id="x_52b">If your diff viewing command can't deal with directories,
 5.15222 +      you can easily work around this with a little scripting.  For an
 5.15223 +      example of such scripting in action with the <literal role="hg-ext" moreinfo="none">mq</literal> extension and the
 5.15224 +      <command moreinfo="none">interdiff</command> command, see <xref linkend="mq-collab:tips:interdiff"/>.</para>
 5.15225 +
 5.15226 +    <sect2>
 5.15227 +      <title>Defining command aliases</title>
 5.15228 +
 5.15229 +      <para id="x_52c">It can be cumbersome to remember the options to both the
 5.15230 +	<command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command and
 5.15231 +	the diff viewer you want to use, so the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension lets you define
 5.15232 +	<emphasis>new</emphasis> commands that will invoke your diff
 5.15233 +	viewer with exactly the right options.</para>
 5.15234 +
 5.15235 +      <para id="x_52d">All you need to do is edit your <filename role="special" moreinfo="none">~/.hgrc</filename>, and add a section named
 5.15236 +	<literal role="rc-extdiff" moreinfo="none">extdiff</literal>.  Inside this
 5.15237 +	section, you can define multiple commands.  Here's how to add
 5.15238 +	a <literal moreinfo="none">kdiff3</literal> command.  Once you've defined
 5.15239 +	this, you can type <quote><literal moreinfo="none">hg kdiff3</literal></quote>
 5.15240 +	and the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension
 5.15241 +	will run <command moreinfo="none">kdiff3</command> for you.</para>
 5.15242 +      <programlisting format="linespecific">[extdiff]
 5.15243 +cmd.kdiff3 =</programlisting>
 5.15244 +      <para id="x_52e">If you leave the right hand side of the definition empty,
 5.15245 +	as above, the <literal role="hg-ext" moreinfo="none">extdiff</literal>
 5.15246 +	extension uses the name of the command you defined as the name
 5.15247 +	of the external program to run.  But these names don't have to
 5.15248 +	be the same.  Here, we define a command named
 5.15249 +	<quote><literal moreinfo="none">hg wibble</literal></quote>, which runs
 5.15250 +	<command moreinfo="none">kdiff3</command>.</para>
 5.15251 +      <programlisting format="linespecific">[extdiff]
 5.15252 + cmd.wibble = kdiff3</programlisting>
 5.15253 +
 5.15254 +      <para id="x_52f">You can also specify the default options that you want to
 5.15255 +	invoke your diff viewing program with.  The prefix to use is
 5.15256 +	<quote><literal moreinfo="none">opts.</literal></quote>, followed by the name
 5.15257 +	of the command to which the options apply.  This example
 5.15258 +	defines a <quote><literal moreinfo="none">hg vimdiff</literal></quote> command
 5.15259 +	that runs the <command moreinfo="none">vim</command> editor's
 5.15260 +	<literal moreinfo="none">DirDiff</literal> extension.</para>
 5.15261 +      <programlisting format="linespecific">[extdiff]
 5.15262 + cmd.vimdiff = vim
 5.15263 +opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
 5.15264 +
 5.15265 +    </sect2>
 5.15266 +  </sect1>
 5.15267 +  <sect1 id="sec:hgext:transplant">
 5.15268 +    <title>Cherrypicking changes with the <literal role="hg-ext" moreinfo="none">transplant</literal> extension</title>
 5.15269 +
 5.15270 +    <para id="x_530">Need to have a long chat with Brendan about this.</para>
 5.15271 +
 5.15272 +  </sect1>
 5.15273 +  <sect1 id="sec:hgext:patchbomb">
 5.15274 +    <title>Send changes via email with the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension</title>
 5.15275 +
 5.15276 +    <para id="x_531">Many projects have a culture of <quote>change
 5.15277 +	review</quote>, in which people send their modifications to a
 5.15278 +      mailing list for others to read and comment on before they
 5.15279 +      commit the final version to a shared repository.  Some projects
 5.15280 +      have people who act as gatekeepers; they apply changes from
 5.15281 +      other people to a repository to which those others don't have
 5.15282 +      access.</para>
 5.15283 +
 5.15284 +    <para id="x_532">Mercurial makes it easy to send changes over email for
 5.15285 +      review or application, via its <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension.  The extension is
 5.15286 +      so named because changes are formatted as patches, and it's usual
 5.15287 +      to send one changeset per email message.  Sending a long series
 5.15288 +      of changes by email is thus much like <quote>bombing</quote> the
 5.15289 +      recipient's inbox, hence <quote>patchbomb</quote>.</para>
 5.15290 +
 5.15291 +    <para id="x_533">As usual, the basic configuration of the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension takes just one or
 5.15292 +      two lines in your <filename role="special" moreinfo="none">
 5.15293 +	/.hgrc</filename>.</para>
 5.15294 +    <programlisting format="linespecific">[extensions]
 5.15295 +patchbomb =</programlisting>
 5.15296 +    <para id="x_534">Once you've enabled the extension, you will have a new
 5.15297 +      command available, named <command role="hg-ext-patchbomb" moreinfo="none">email</command>.</para>
 5.15298 +
 5.15299 +    <para id="x_535">The safest and best way to invoke the <command role="hg-ext-patchbomb" moreinfo="none">email</command> command is to
 5.15300 +      <emphasis>always</emphasis> run it first with the <option role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
 5.15301 +      This will show you what the command <emphasis>would</emphasis>
 5.15302 +      send, without actually sending anything.  Once you've had a
 5.15303 +      quick glance over the changes and verified that you are sending
 5.15304 +      the right ones, you can rerun the same command, with the <option role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
 5.15305 +      removed.</para>
 5.15306 +
 5.15307 +    <para id="x_536">The <command role="hg-ext-patchbomb" moreinfo="none">email</command> command
 5.15308 +      accepts the same kind of revision syntax as every other
 5.15309 +      Mercurial command.  For example, this command will send every
 5.15310 +      revision between 7 and <literal moreinfo="none">tip</literal>, inclusive.</para>
 5.15311 +    <programlisting format="linespecific">hg email -n 7:tip</programlisting>
 5.15312 +    <para id="x_537">You can also specify a <emphasis>repository</emphasis> to
 5.15313 +      compare with.  If you provide a repository but no revisions, the
 5.15314 +      <command role="hg-ext-patchbomb" moreinfo="none">email</command> command will
 5.15315 +      send all revisions in the local repository that are not present
 5.15316 +      in the remote repository.  If you additionally specify revisions
 5.15317 +      or a branch name (the latter using the <option role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
 5.15318 +      this will constrain the revisions sent.</para>
 5.15319 +
 5.15320 +    <para id="x_538">It's perfectly safe to run the <command role="hg-ext-patchbomb" moreinfo="none">email</command> command without the
 5.15321 +      names of the people you want to send to: if you do this, it will
 5.15322 +      just prompt you for those values interactively.  (If you're
 5.15323 +      using a Linux or Unix-like system, you should have enhanced
 5.15324 +      <literal moreinfo="none">readline</literal>-style editing capabilities when
 5.15325 +      entering those headers, too, which is useful.)</para>
 5.15326 +
 5.15327 +    <para id="x_539">When you are sending just one revision, the <command role="hg-ext-patchbomb" moreinfo="none">email</command> command will by
 5.15328 +      default use the first line of the changeset description as the
 5.15329 +      subject of the single email message it sends.</para>
 5.15330 +
 5.15331 +    <para id="x_53a">If you send multiple revisions, the <command role="hg-ext-patchbomb" moreinfo="none">email</command> command will usually
 5.15332 +      send one message per changeset.  It will preface the series with
 5.15333 +      an introductory message, in which you should describe the
 5.15334 +      purpose of the series of changes you're sending.</para>
 5.15335 +
 5.15336 +    <sect2>
 5.15337 +      <title>Changing the behavior of patchbombs</title>
 5.15338 +
 5.15339 +      <para id="x_53b">Not every project has exactly the same conventions for
 5.15340 +	sending changes in email; the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension tries to
 5.15341 +	accommodate a number of variations through command line
 5.15342 +	options.</para>
 5.15343 +      <itemizedlist>
 5.15344 +	<listitem><para id="x_53c">You can write a subject for the introductory
 5.15345 +	    message on the command line using the <option role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
 5.15346 +	    option.  This takes one argument, the text of the subject
 5.15347 +	    to use.</para>
 5.15348 +	</listitem>
 5.15349 +	<listitem><para id="x_53d">To change the email address from which the
 5.15350 +	    messages originate, use the <option role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
 5.15351 +	    option.  This takes one argument, the email address to
 5.15352 +	    use.</para>
 5.15353 +	</listitem>
 5.15354 +	<listitem><para id="x_53e">The default behavior is to send unified diffs
 5.15355 +	    (see <xref linkend="sec:mq:patch"/> for a
 5.15356 +	    description of the
 5.15357 +	    format), one per message.  You can send a binary bundle
 5.15358 +	    instead with the <option role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
 5.15359 +	    option.</para>
 5.15360 +	</listitem>
 5.15361 +	<listitem><para id="x_53f">Unified diffs are normally prefaced with a
 5.15362 +	    metadata header.  You can omit this, and send unadorned
 5.15363 +	    diffs, with the <option role="hg-ext-patchbomb-cmd-email-opt">hg
 5.15364 +	      --plain</option> option.</para>
 5.15365 +	</listitem>
 5.15366 +	<listitem><para id="x_540">Diffs are normally sent <quote>inline</quote>,
 5.15367 +	    in the same body part as the description of a patch.  This
 5.15368 +	    makes it easiest for the largest number of readers to
 5.15369 +	    quote and respond to parts of a diff, as some mail clients
 5.15370 +	    will only quote the first MIME body part in a message. If
 5.15371 +	    you'd prefer to send the description and the diff in
 5.15372 +	    separate body parts, use the <option role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
 5.15373 +	    option.</para>
 5.15374 +	</listitem>
 5.15375 +	<listitem><para id="x_541">Instead of sending mail messages, you can
 5.15376 +	    write them to an <literal moreinfo="none">mbox</literal>-format mail
 5.15377 +	    folder using the <option role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
 5.15378 +	    option.  That option takes one argument, the name of the
 5.15379 +	    file to write to.</para>
 5.15380 +	</listitem>
 5.15381 +	<listitem><para id="x_542">If you would like to add a
 5.15382 +	    <command moreinfo="none">diffstat</command>-format summary to each patch,
 5.15383 +	    and one to the introductory message, use the <option role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
 5.15384 +	    option.  The <command moreinfo="none">diffstat</command> command displays
 5.15385 +	    a table containing the name of each file patched, the
 5.15386 +	    number of lines affected, and a histogram showing how much
 5.15387 +	    each file is modified.  This gives readers a qualitative
 5.15388 +	    glance at how complex a patch is.</para>
 5.15389 +	</listitem></itemizedlist>
 5.15390 +
 5.15391 +    </sect2>
 5.15392 +  </sect1>
 5.15393 +</chapter>
 5.15394 +
 5.15395 +<!--
 5.15396 +local variables: 
 5.15397 +sgml-parent-document: ("00book.xml" "book" "chapter")
 5.15398 +end:
 5.15399 +-->
 5.15400 +
 5.15401 +  <!-- BEGIN appA -->
 5.15402 +  
 5.15403 +
 5.15404 +<appendix id="svn">
 5.15405 +  <?dbhtml filename="migrating-to-mercurial.html"?>
 5.15406 +<title>Migrer vers Mercurial</title>
 5.15407 +
 5.15408 +  <para id="x_6e1">Une manière courante de s'essayer à un nouveau
 5.15409 +  gestionnaire de révisions est d'expérimenter en migrant un
 5.15410 +  projet existant, plutôt que le faire avec un nouveau projet.
 5.15411 +  </para>
 5.15412 +
 5.15413 +  <para id="x_6e2">Dans cette annexe, nous discuterons comment importer
 5.15414 +  l'historique d'un projet dans Mercurial, et à quoi faire attention
 5.15415 +  si vous êtes habitués à un autre outil de gestion de révisions.
 5.15416 +   </para>
 5.15417 +
 5.15418 +  <sect1>
 5.15419 +    <title>Importer l'historique depuis un autre système</title>
 5.15420 +
 5.15421 +    <para id="x_6e3">Mercurial est livré avec une extension nommée
 5.15422 +      <literal moreinfo="none">convert</literal>, qui permet d'importer un historique
 5.15423 +      depuis les gestionnaire de révisions les plus courants. Au moment de 
 5.15424 +      l'écriture de ce livre, il pouvait importer l'historique depuis:
 5.15425 +      </para>
 5.15426 +    <itemizedlist>
 5.15427 +      <listitem>
 5.15428 +	<para id="x_6e4">Subversion</para>
 5.15429 +      </listitem>
 5.15430 +      <listitem>
 5.15431 +	<para id="x_6e5">CVS</para>
 5.15432 +      </listitem>
 5.15433 +      <listitem>
 5.15434 +	<para id="x_6e6">git</para>
 5.15435 +      </listitem>
 5.15436 +      <listitem>
 5.15437 +	<para id="x_6e7">Darcs</para>
 5.15438 +      </listitem>
 5.15439 +      <listitem>
 5.15440 +	<para id="x_6e8">Bazaar</para>
 5.15441 +      </listitem>
 5.15442 +      <listitem>
 5.15443 +	<para id="x_6e9">Monotone</para>
 5.15444 +      </listitem>
 5.15445 +      <listitem>
 5.15446 +	<para id="x_6ea">GNU Arch</para>
 5.15447 +      </listitem>
 5.15448 +      <listitem>
 5.15449 +	<para id="x_6eb">Mercurial</para>
 5.15450 +      </listitem>
 5.15451 +    </itemizedlist>
 5.15452 +
 5.15453 +    <para id="x_6ec">(Pour savoir pourquoi Mercurial lui même est supporté
 5.15454 +    comme source, voir <xref linkend="svn.filemap"/>.)</para>
 5.15455 +
 5.15456 +    <para id="x_6ed">Vous pouvez activer l'extension de la manière
 5.15457 +    habituelle, en éditant votre fichier <filename moreinfo="none">~/.hgrc</filename></para>
 5.15458 +
 5.15459 +    <programlisting format="linespecific">[extensions]
 5.15460 +convert =</programlisting>
 5.15461 +
 5.15462 +    <para id="x_6ee">Ceci rendra la commande <command moreinfo="none">hg convert</command>
 5.15463 +    disponible. La commande est facile à utiliser. Par exemple, la 
 5.15464 +    commande suivante va importer l'historique Subversion du <emphasis remap="it">framework</emphasis> de test <quote>Nose Unit</quote> dans Mercurial.
 5.15465 +      </para>
 5.15466 +
 5.15467 +    <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg convert http://python-nose.googlecode.com/svn/trunk</userinput></screen>
 5.15468 +
 5.15469 +    <para id="x_6ef">L'extension <literal moreinfo="none">convert</literal> opère de 
 5.15470 +    manière incrémentale. En d'autres mots, après une première exécution de
 5.15471 +    la commande <command moreinfo="none">hg convert</command>, les exécutions ultérieures
 5.15472 +    importeront les révisions ultérieures à l'exécution précédente.
 5.15473 +    La conversion incrémentale ne réussira que si
 5.15474 +    vous exécutez <command moreinfo="none">hg convert</command> dans le même dépôt que vous
 5.15475 +    aviez utilisé à l'origine, ceci parce que l'extension <literal moreinfo="none">convert</literal> 
 5.15476 +    sauvegarde un certain nombre de méta-données privées dans le fichier
 5.15477 +    <filename moreinfo="none">.hg/shamap</filename> (non versioné) au sein du dépôt cible.
 5.15478 +    </para>
 5.15479 +
 5.15480 +    <para id="x_707">Lorsque vous voulez faire des modifications en utilisant
 5.15481 +    Mercurial, le mieux est de faire un clone de l'ensemble de l'arborescence 
 5.15482 +    que vous souhaitez convertir, et de laisser l'arborescence d'origine pour
 5.15483 +    de futures conversions incrémentales. C'est la manière la plus sûre pour vous laisser
 5.15484 +    récupérer et fusionner les modifications futures depuis l'outil de gestion
 5.15485 +    de révisions dans votre nouveau dépôt Mercurial.</para>
 5.15486 +
 5.15487 +    <sect2>
 5.15488 +      <title>Convertir plusieurs branches</title>
 5.15489 +
 5.15490 +      <para id="x_708">La commande <command moreinfo="none">hg convert</command> citée 
 5.15491 +      ci-dessus convertit seulement l'historique de la <literal moreinfo="none">branche
 5.15492 +      principale (trunk)</literal> du dépôt Subversion. Si nous utilisons
 5.15493 +      à la place l'URL <literal moreinfo="none">http://python-nose.googlecode.com/svn</literal>,
 5.15494 +      Mercurial va automatiquement détecter la  
 5.15495 +      <literal moreinfo="none">branche principale (trunk)</literal>, les <literal moreinfo="none">étiquettes 
 5.15496 +      (tags)</literal>, et les <literal moreinfo="none">branches</literal>  que les dépôts
 5.15497 +      Subversion utilisent généralement, et les importera chacun dans
 5.15498 +      une branche Mercurial distincte.</para>
 5.15499 +
 5.15500 +      <para id="x_709">Par défaut, chaque branche Subversion importée 
 5.15501 +     dans Mercurial se voit attribuer un nom de branche. Une fois la
 5.15502 +     conversion achevée, vous pouvez obtenir la liste des noms des branches 
 5.15503 +     actives dans le dépôt Mercurial en utilisant la commande
 5.15504 +     <command moreinfo="none">hg branches -a</command>. Si vous préférez importer les 
 5.15505 +     branches Subversion sans noms, ajoutez l'option <option>--config
 5.15506 +     convert.hg.usebranches=false</option> à la commande 
 5.15507 +     <command moreinfo="none">hg convert</command>.</para>
 5.15508 +
 5.15509 +      <para id="x_70a">Une fois votre arborescence convertie, 
 5.15510 +      si vous souhaitez travailler selon la pratique habituelle sous Mercurial
 5.15511 +      avec une arborescence qui ne contient qu'une seule branche, vous pouvez cloner
 5.15512 +      cette seule branche en utilisant 
 5.15513 +      <command moreinfo="none">hg clone -r nomdemabranche</command>.</para>
 5.15514 +    </sect2>
 5.15515 +
 5.15516 +    <sect2>
 5.15517 +      <title>Associer les noms d'utilisateurs</title>
 5.15518 +
 5.15519 +      <para id="x_6f0">Certains outils de gestion de révisions
 5.15520 +      ne sauvegardent, avec les modifications, que les noms 
 5.15521 +      d'utilisateurs raccourcis. Ceux-ci peuvent être difficiles à 
 5.15522 +      interpréter. La norme avec Mercurial est de sauvegarder le 
 5.15523 +      nom du <emphasis remap="it">committeur</emphasis> et son adresse
 5.15524 +      mail, ce qui est beaucoup plus utile pour discuter avec lui
 5.15525 +      par la suite.</para>
 5.15526 +
 5.15527 +      <para id="x_6f1">Si vous convertissez une arborescence depuis
 5.15528 +      un gestionnaire de révisions qui utilise seulement les noms
 5.15529 +      raccourcis, vous pouvez associer ces noms à des équivalents 
 5.15530 +      plus détaillés en passant l'option <option>--authors</option>
 5.15531 +      à la commande <command moreinfo="none">hg convert</command>. Cette option
 5.15532 +      attend un fichier qui contient des entrées sous la forme suivante:
 5.15533 +      </para>
 5.15534 +
 5.15535 +      <programlisting format="linespecific">arist = Aristotle &lt;aristotle@phil.example.gr&gt;
 5.15536 +soc = Socrates &lt;socrates@phil.example.gr&gt;</programlisting>
 5.15537 +
 5.15538 +      <para id="x_6f2">Quand <literal moreinfo="none">convert</literal> trouve une
 5.15539 +      modification associée au nom <literal moreinfo="none">arist</literal> dans le
 5.15540 +      dépôt de source, il va utiliser le nom <literal moreinfo="none">Aristotle
 5.15541 +      &lt;aristotle@phil.example.gr&gt;</literal> dans les révisions
 5.15542 +      Mercurial. Si aucune correspondance n'est trouvé, il utilise
 5.15543 +      le nom tel quel.</para>
 5.15544 +    </sect2>
 5.15545 +
 5.15546 +    <sect2 id="svn.filemap">
 5.15547 +      <title>Nettoyer l'arboresence</title>
 5.15548 +
 5.15549 +      <para id="x_6f3">Tous les projets n'ont pas un historique parfait.
 5.15550 +      Il peut y avoir des répertoires qui n'auraient jamais dû être ajoutés,
 5.15551 +      un fichier qui est trop volumineux, ou même une partie de la
 5.15552 +      hiérarchie qui devrait être réorganisée.</para>
 5.15553 +
 5.15554 +      <para id="x_6f4">L'extension <literal moreinfo="none">convert</literal> permet
 5.15555 +      d'utiliser un <quote>fichier d'association</quote> qui peut 
 5.15556 +      réorganiser les fichiers et les répertoires dans un projet lors de
 5.15557 +      l'importation de son historique. Ceci est utile non seulement quand vous
 5.15558 +      importez l'historique d'un autre gestionnaire de révisions, mais
 5.15559 +      aussi pour nettoyer ou réorganiser l'arborescence d'un projet
 5.15560 +      Mercurial.</para>
 5.15561 +
 5.15562 +      <para id="x_6f5">Pour indiquer le fichier d'association, on utilise
 5.15563 +      l'option <option>--filemap</option> en lui fournissant un nom de
 5.15564 +      fichier. Le fichier d'association contient des lignes de la forme
 5.15565 +      suivante :</para>
 5.15566 +
 5.15567 +      <programlisting format="linespecific"># Ceci est un commentaire.
 5.15568 +# Les lignes vides sont ignorées.
 5.15569 +
 5.15570 +include path/to/file
 5.15571 +
 5.15572 +exclude path/to/file
 5.15573 +
 5.15574 +rename from/some/path to/some/other/place
 5.15575 +</programlisting>
 5.15576 +      
 5.15577 +      <para id="x_6f6">La directive <literal moreinfo="none">include</literal> inclut un
 5.15578 +      fichier, ou l'ensemble des fichiers d'un répertoire, dans le dépôt
 5.15579 +      de destination. La directive <literal moreinfo="none">exclude</literal> omet les
 5.15580 +      fichiers ou répertoires du dépôt. Ceci inclut aussi les autres
 5.15581 +      fichiers et répertoires qui ne sont pas explicitement inclus.
 5.15582 +      La directive <literal moreinfo="none">exclude</literal> entraine l'omission
 5.15583 +      des fichiers ou répertoires, et autres fichiers qui ne sont pas
 5.15584 +      explicitement inclus.</para>
 5.15585 +
 5.15586 +      <para id="x_6f7">Pour déplacer un fichier ou un répertoire d'un
 5.15587 +      emplacement à un autre, utilisez la directive
 5.15588 +      <literal moreinfo="none">rename</literal>. Si vous avez besoin de déplacer un 
 5.15589 +      fichier ou un répertoire depuis un sous répertoire dans la racine
 5.15590 +      du dépôt, utilisez <literal moreinfo="none">.</literal> comme second argument de 
 5.15591 +      la directive <literal moreinfo="none">rename</literal>.</para>
 5.15592 +    </sect2>
 5.15593 +
 5.15594 +    <sect2>
 5.15595 +      <title>Améliorer les performances de la conversion Subversion</title>
 5.15596 +
 5.15597 +      <para id="x_70b">Vous aurez souvent besoin de plusieurs essais
 5.15598 +      avant d'arriver à la parfaite combinaison de fichier d'association de fichiers,
 5.15599 +      de fichier d'association de noms d'utilisateurs et des autres paramètres. Or,
 5.15600 +      convertir un dépôt Mercurial via un protocole comme <literal moreinfo="none">ssh</literal>
 5.15601 +      ou <literal moreinfo="none">http</literal> peut être des milliers de fois plus long
 5.15602 +      que ce dont le système d'exploitation est en fait capable de faire,
 5.15603 +      à cause des latence réseau. Ceci peut rendre la conception de cette
 5.15604 +      combinaison parfaite très douloureuse.</para>
 5.15605 +
 5.15606 +      <para id="x_70c">La commande <ulink url="http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt"><command moreinfo="none">svnsync</command></ulink> 
 5.15607 +	peut grandement améliorer la vitesse de conversion d'un dépôt
 5.15608 +        Subversion. Il s'agit d'un programme de miroir de dépôt Subversion
 5.15609 +        en lecture seule. L'idée est de créer un miroir local d'une
 5.15610 +        arborescence Subversion, puis de convertir ce miroir en dépôt
 5.15611 +        Mercurial.</para>
 5.15612 +      
 5.15613 +      <para id="x_70d">Supposez que nous voulions convertir le dépôt 
 5.15614 +      Subversion du populaire projet Memcached en une arborescence Mercurial.
 5.15615 +      Tout d'abord, nous créons un dépôt Subversion local.</para>
 5.15616 +
 5.15617 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svnadmin create memcached-mirror</userinput></screen>
 5.15618 +
 5.15619 +      <para id="x_70e">Puis, nous allons mettre en place un <quote>hook</quote> Subversion
 5.15620 +      dont <command moreinfo="none">svnsync</command> a besoin.</para>
 5.15621 +
 5.15622 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo '#!/bin/sh' &gt; memcached-mirror/hooks/pre-revprop-change</userinput>
 5.15623 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">chmod +x memcached-mirror/hooks/pre-revprop-change</userinput></screen>
 5.15624 +
 5.15625 +      <para id="x_70f">Nous initialisons ensuite <command moreinfo="none">svnsync</command> dans ce
 5.15626 +      dépôt.</para>
 5.15627 +
 5.15628 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svnsync --init file://`pwd`/memcached-mirror \
 5.15629 +  http://code.sixapart.com/svn/memcached</userinput></screen>
 5.15630 +
 5.15631 +      <para id="x_710">La prochaine étape est de commencer le processus de
 5.15632 +      mirroring de <command moreinfo="none">svnsync</command>.</para>
 5.15633 +
 5.15634 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svnsync sync file://`pwd`/memcached-mirror</userinput></screen>
 5.15635 +
 5.15636 +      <para id="x_711">Enfin, nous importons l'historique de notre dépôt
 5.15637 +      local Subversion dans Mercurial.</para>
 5.15638 +
 5.15639 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg convert memcached-mirror</userinput></screen>
 5.15640 +      
 5.15641 +      <para id="x_712">Nous pouvons utiliser ce processus de manière
 5.15642 +      incrémentale, si le dépôt Subversion est toujours en activité.
 5.15643 +      Il suffit d'exécuter de nouveau <command moreinfo="none">svnsync</command> pour
 5.15644 +      récupérer les récentes modifications dans notre miroir, puis <command moreinfo="none">hg 
 5.15645 +      convert</command>
 5.15646 +      les importe dans notre arborescence Mercurial.</para>
 5.15647 +
 5.15648 +      <para id="x_713">Il y a deux avantages à utiliser un import à deux
 5.15649 +      étages comme avec <command moreinfo="none">svnsync</command>. Le premier
 5.15650 +      est qu'il utilise du code de synchronisation réseau de Subversion 
 5.15651 +      plus efficace que la commande <command moreinfo="none">hg convert</command>,
 5.15652 +      et donc transfère moins de données par le réseau. Le deuxième
 5.15653 +      est que l'import depuis un dépôt Subversion local est si rapide que
 5.15654 +      vous pouvez peaufiner et réitérer les paramètres de conversion de 
 5.15655 +      ce dernier sans souffrir de la qualité de la connexion réseau.</para>
 5.15656 +    </sect2>
 5.15657 +  </sect1>
 5.15658 +
 5.15659 +  <sect1>
 5.15660 +    <title>Migrer depuis Subversion</title>
 5.15661 +
 5.15662 +    <para id="x_6f8">Subversion est le système de gestion de versions
 5.15663 +    open source le plus populaire aujourd'hui. Bien qu'il y ait des
 5.15664 +    différences entre Mercurial et Subversion, faire la transition de
 5.15665 +    l'un à l'autre n'est pas très difficile. Les deux disposent en effet 
 5.15666 +    de jeux de commandes similaires et d'interfaces similaires.</para>
 5.15667 +
 5.15668 +    <sect2>
 5.15669 +      <title>Différences philosophiques</title>
 5.15670 +
 5.15671 +      <para id="x_6f9">La différence fondamentale entre Subversion et
 5.15672 +      Mercurial est bien évidement que Subversion est centralisé, alors 
 5.15673 +      que Mercurial est distribué. Puisque que Mercurial enregistre tout
 5.15674 +      l'historique d'un projet sur votre disque dur local, il n'a besoin
 5.15675 +      d'effectuer des accès au réseau que lorsque vous voulez
 5.15676 +      explicitement communiquer avec un autre dépôt. Subversion, par contre,
 5.15677 +      ne conserve que peu d'informations localement, et le client
 5.15678 +      doit donc communiquer avec le serveur central pour la
 5.15679 +      plupart des opérations communes.</para>
 5.15680 +
 5.15681 +      <para id="x_6fa">Subversion s'en tire plus ou moins bien sans notion
 5.15682 +      de branche réellement bien définie : quelle portion de l'espace de nommage
 5.15683 +      du serveur est une branche est une simple question de convention, le
 5.15684 +      logiciel n'imposant rien à ce sujet. Mercurial considère
 5.15685 +      un dépôt comme un élément de la gestion des branches.</para>
 5.15686 +      
 5.15687 +      <sect3>
 5.15688 +	<title>Portée des commandes</title>
 5.15689 +
 5.15690 +	<para id="x_6fb">Puisque que Subversion ne sait pas réellement
 5.15691 +        quelle partie de son espace de nommage est en fait une branche, il
 5.15692 +        traite la plupart des commandes comme des requêtes à exécuter sur le
 5.15693 +        répertoire où vous vous situez, et ses sous répertoires. Par exemple,
 5.15694 +        si vous exécutez <command moreinfo="none">svn log</command>, vous verrez l'historique 
 5.15695 +        de la partie de l'arborescence où vous vous situez, et non de la
 5.15696 +        hiérarchie entière.</para>
 5.15697 +
 5.15698 +	<para id="x_6fc">Les commandes de Mercurial ont un comportement
 5.15699 +        différent : toutes les commandes s'appliquent à l'ensemble de l'arborescence
 5.15700 +        du dépôt. Exécutez la commande <command moreinfo="none">hg log</command> et elle vous
 5.15701 +        donnera l'historique de l'ensemble de l'arborescence, quel que soit le
 5.15702 +        sous-répertoire où vous vous situez. Si
 5.15703 +        vous souhaitez obtenir l'historique d'un répertoire ou seulement d'un
 5.15704 +        fichier, ajouter simplement le nom de celui-ci à la commande, par
 5.15705 +        exemple <command moreinfo="none">hg log src</command>.</para>
 5.15706 +
 5.15707 +	<para id="x_6fd">De ma propre expérience, cette différence dans leur
 5.15708 +        comportement par défaut est probablement ce qui risque de vous
 5.15709 +        surprendre le plus si vous passez régulièrement d'un outil à l'autre.</para>
 5.15710 +      </sect3>
 5.15711 +
 5.15712 +      <sect3>
 5.15713 +	<title>Opération multi utilisateur et sécurité</title>
 5.15714 +
 5.15715 +	<para id="x_6fe">Avec Subversion, il est normal (bien que légèrement
 5.15716 +        désapprouvé) que différentes personnes collaborent sur une seule
 5.15717 +        branche. Si Alice et Bob travaillent ensemble, et Alice ajoute ses
 5.15718 +        modifications à leur branche partagée, Bob doit alors mettre à jour
 5.15719 +        sa vue de la branche avant de pouvoir appliquer un commit.
 5.15720 +        Puisqu'il n'a, à ce moment, pas effectué de commit
 5.15721 +        des modifications qu'il a faites, il se peut qu'il ne corrompe 
 5.15722 +        ou ne perde
 5.15723 +        ses modifications pendant ou après la mise à jour.</para>
 5.15724 +
 5.15725 +	<para id="x_6ff">Mercurial encourage, à l'inverse, un modèle 
 5.15726 +        "commit-puis-merge". Avant de récupérer des modifications depuis le 
 5.15727 +        serveur, ou avant d'y envoyer les siennes, Bob enregistre ses 
 5.15728 +        modifications de manière locale en appliquant un commit. C'est à dire
 5.15729 +        que si Alice avait envoyé ses modifications sur le serveur avant
 5.15730 +        que Bob n'envoie les siennes, ce dernier ne pourra le faire
 5.15731 +        qu'après avoir récupéré et fusionné celles d'Alice avec les siennes. 
 5.15732 +        Si Bob fait alors une
 5.15733 +        erreur lors de la fusion, il pourra toujours restaurer sa version, pour
 5.15734 +        laquelle il avait appliqué le commit.</para>
 5.15735 +          
 5.15736 +	<para id="x_700">Il est important de souligner qu'il s'agit de la
 5.15737 +        manière habituelle de travailler avec ces outils. Subversion propose
 5.15738 +        une manière plus sûre de "travailler-dans-votre-propre-branche", mais elle
 5.15739 +        est assez complexe pour que, en pratique, elle ne soit que rarement utilisé.
 5.15740 +        Mercurial propose de son côté un mode un peu moins sûr, permettant de
 5.15741 +        récupérer des modifications par dessus des modifications non
 5.15742 +        committées, qui reste toutefois très peu répandu.</para> 
 5.15743 +      </sect3>
 5.15744 +
 5.15745 +      <sect3>
 5.15746 +	<title>Publication vs changement locaux</title>
 5.15747 +
 5.15748 +	<para id="x_701">Une commande Subversion <command moreinfo="none">svn
 5.15749 +        commit</command> publie immédiatement les modifications sur le
 5.15750 +        serveur, où elles peuvent être vu par n'importe qui doté d'un privilège
 5.15751 +        de lecture.</para>
 5.15752 +
 5.15753 +	<para id="x_702">Avec Mercurial, les modifications sont toujours d'abord
 5.15754 +        enregistrées localement, et doivent être par la suite transférés par
 5.15755 +        la commande <command moreinfo="none">hg push</command>.</para>
 5.15756 +
 5.15757 +	<para id="x_703">Chaque approche a ses avantages et ses inconvénients.
 5.15758 +        Le modèle Subversion implique que les modifications soient publiées, et
 5.15759 +        donc disponibles immédiatement. D'un autre coté, cela implique aussi
 5.15760 +        que, pour pouvoir utiliser le logiciel normalement, un utilisateur doit 
 5.15761 +        avoir les droits d'écriture dans le dépôt, et ce privilège n'est pas concédé 
 5.15762 +        facilement par la plupart des projets Open Source.</para>
 5.15763 +
 5.15764 +	<para id="x_704">L'approche de Mercurial permet à quiconque de faire
 5.15765 +        un clone du dépôt et d'y ajouter ses modifications sans jamais avoir
 5.15766 +        besoin de la permission de quiconque, et l'on peut même publier ses
 5.15767 +        modifications et continuer à participer comme on le désire. Toutefois, la
 5.15768 +        distinction entre les commits et le transfert de ces derniers présente
 5.15769 +        le risque que quelqu'un applique ses modifications par un commit local
 5.15770 +        sur son portable et parte se promener pendant quelques jours en ayant
 5.15771 +        oublié de les transférer, ce qui peut, dans certains rares cas,
 5.15772 +        bloquer temporairement ses collaborateurs.</para>
 5.15773 +      </sect3>
 5.15774 +    </sect2>
 5.15775 +
 5.15776 +    <sect2>
 5.15777 +      <title>Références des commandes</title>
 5.15778 +
 5.15779 +      <table>
 5.15780 +	<title>Commandes Subversion et leurs équivalents Mercurial</title>
 5.15781 +	<tgroup cols="3">
 5.15782 +	  <thead>
 5.15783 +	    <row>
 5.15784 +	      <entry>Subversion</entry>
 5.15785 +	      <entry>Mercurial</entry>
 5.15786 +	      <entry>Notes</entry>
 5.15787 +	    </row>
 5.15788 +	  </thead>
 5.15789 +	  <tbody>
 5.15790 +	    <row>
 5.15791 +	      <entry><command moreinfo="none">svn add</command></entry>
 5.15792 +	      <entry><command moreinfo="none">hg add</command></entry>
 5.15793 +	      <entry/>
 5.15794 +	    </row>
 5.15795 +	    <row>
 5.15796 +	      <entry><command moreinfo="none">svn blame</command></entry>
 5.15797 +	      <entry><command moreinfo="none">hg annotate</command></entry>
 5.15798 +	      <entry/>
 5.15799 +	    </row>
 5.15800 +	    <row>
 5.15801 +	      <entry><command moreinfo="none">svn cat</command></entry>
 5.15802 +	      <entry><command moreinfo="none">hg cat</command></entry>
 5.15803 +	      <entry/>
 5.15804 +	    </row>
 5.15805 +	    <row>
 5.15806 +	      <entry><command moreinfo="none">svn checkout</command></entry>
 5.15807 +	      <entry><command moreinfo="none">hg clone</command></entry>
 5.15808 +	      <entry/>
 5.15809 +	    </row>
 5.15810 +	    <row>
 5.15811 +	      <entry><command moreinfo="none">svn cleanup</command></entry>
 5.15812 +	      <entry>n/a</entry>
 5.15813 +	      <entry>Aucun nettoyage nécessaire.</entry>
 5.15814 +	    </row>
 5.15815 +	    <row>
 5.15816 +	      <entry><command moreinfo="none">svn commit</command></entry>
 5.15817 +	      <entry><command moreinfo="none">hg commit</command>; <command moreinfo="none">hg
 5.15818 +		  push</command></entry>
 5.15819 +	      <entry><command moreinfo="none">hg push</command> publie les modifications
 5.15820 +              après un commit.</entry>
 5.15821 +	    </row>
 5.15822 +	    <row>
 5.15823 +	      <entry><command moreinfo="none">svn copy</command></entry>
 5.15824 +	      <entry><command moreinfo="none">hg clone</command></entry>
 5.15825 +	      <entry>Pour créer une nouvelle branche</entry>
 5.15826 +	    </row>
 5.15827 +	    <row>
 5.15828 +	      <entry><command moreinfo="none">svn copy</command></entry>
 5.15829 +	      <entry><command moreinfo="none">hg copy</command></entry>
 5.15830 +	      <entry>Pour copier des fichiers ou des répertoires</entry>
 5.15831 +	    </row>
 5.15832 +	    <row>
 5.15833 +	      <entry><command moreinfo="none">svn delete</command> (<command moreinfo="none">svn
 5.15834 +		  remove</command>)</entry>
 5.15835 +	      <entry><command moreinfo="none">hg remove</command></entry>
 5.15836 +	      <entry/>
 5.15837 +	    </row>
 5.15838 +	    <row>
 5.15839 +	      <entry><command moreinfo="none">svn diff</command></entry>
 5.15840 +	      <entry><command moreinfo="none">hg diff</command></entry>
 5.15841 +	      <entry/>
 5.15842 +	    </row>
 5.15843 +	    <row>
 5.15844 +	      <entry><command moreinfo="none">svn export</command></entry>
 5.15845 +	      <entry><command moreinfo="none">hg archive</command></entry>
 5.15846 +	      <entry/>
 5.15847 +	    </row>
 5.15848 +	    <row>
 5.15849 +	      <entry><command moreinfo="none">svn help</command></entry>
 5.15850 +	      <entry><command moreinfo="none">hg help</command></entry>
 5.15851 +	      <entry/>
 5.15852 +	    </row>
 5.15853 +	    <row>
 5.15854 +	      <entry><command moreinfo="none">svn import</command></entry>
 5.15855 +	      <entry><command moreinfo="none">hg addremove</command>; <command moreinfo="none">hg
 5.15856 +		  commit</command></entry>
 5.15857 +	      <entry/>
 5.15858 +	    </row>
 5.15859 +	    <row>
 5.15860 +	      <entry><command moreinfo="none">svn info</command></entry>
 5.15861 +	      <entry><command moreinfo="none">hg parents</command></entry>
 5.15862 +	      <entry>Affiche la version sur la base de laquelle on travaille</entry>
 5.15863 +	    </row>
 5.15864 +	    <row>
 5.15865 +	      <entry><command moreinfo="none">svn info</command></entry>
 5.15866 +	      <entry><command moreinfo="none">hg showconfig
 5.15867 +		  paths.default</command></entry>
 5.15868 +	      <entry>Affiche de quelle URL est extrait ce dépôt</entry>
 5.15869 +	    </row>
 5.15870 +	    <row>
 5.15871 +	      <entry><command moreinfo="none">svn list</command></entry>
 5.15872 +	      <entry><command moreinfo="none">hg manifest</command></entry>
 5.15873 +	      <entry/>
 5.15874 +	    </row>
 5.15875 +	    <row>
 5.15876 +	      <entry><command moreinfo="none">svn log</command></entry>
 5.15877 +	      <entry><command moreinfo="none">hg log</command></entry>
 5.15878 +	      <entry/>
 5.15879 +	    </row>
 5.15880 +	    <row>
 5.15881 +	      <entry><command moreinfo="none">svn merge</command></entry>
 5.15882 +	      <entry><command moreinfo="none">hg merge</command></entry>
 5.15883 +	      <entry/>
 5.15884 +	    </row>
 5.15885 +	    <row>
 5.15886 +	      <entry><command moreinfo="none">svn mkdir</command></entry>
 5.15887 +	      <entry>n/a</entry>
 5.15888 +	      <entry>Mercurial ne versionne pas les répertoires</entry>
 5.15889 +	    </row>
 5.15890 +	    <row>
 5.15891 +	      <entry><command moreinfo="none">svn move</command> (<command moreinfo="none">svn
 5.15892 +		  rename</command>)</entry>
 5.15893 +	      <entry><command moreinfo="none">hg rename</command></entry>
 5.15894 +	      <entry/>
 5.15895 +	    </row>
 5.15896 +	    <row>
 5.15897 +	      <entry><command moreinfo="none">svn resolved</command></entry>
 5.15898 +	      <entry><command moreinfo="none">hg resolve -m</command></entry>
 5.15899 +	      <entry/>
 5.15900 +	    </row>
 5.15901 +	    <row>
 5.15902 +	      <entry><command moreinfo="none">svn revert</command></entry>
 5.15903 +	      <entry><command moreinfo="none">hg revert</command></entry>
 5.15904 +	      <entry/>
 5.15905 +	    </row>
 5.15906 +	    <row>
 5.15907 +	      <entry><command moreinfo="none">svn status</command></entry>
 5.15908 +	      <entry><command moreinfo="none">hg status</command></entry>
 5.15909 +	      <entry/>
 5.15910 +	    </row>
 5.15911 +	    <row>
 5.15912 +	      <entry><command moreinfo="none">svn update</command></entry>
 5.15913 +	      <entry><command moreinfo="none">hg pull -u</command></entry>
 5.15914 +	      <entry/>
 5.15915 +	    </row>
 5.15916 +	  </tbody>
 5.15917 +	</tgroup>
 5.15918 +      </table>
 5.15919 +    </sect2>
 5.15920 +  </sect1>
 5.15921 +
 5.15922 +  <sect1>
 5.15923 +    <title>Conseils utiles pour les débutants</title>
 5.15924 +
 5.15925 +    <para id="x_705">Avec la plupart des gestionnaire de versions, afficher
 5.15926 +    un diff associé à une révision peut être assez douloureux. Par exemple,
 5.15927 +    avec Subversion, pour voir ce qui a été modifiée dans la révision 104654,
 5.15928 +    vous devez saisir <command moreinfo="none">svn diff -r104653:104654</command>. Mercurial
 5.15929 +    élimine le besoin de saisir l'identifiant d'une révision deux fois dans
 5.15930 +    ce cas classique. Pour un simple diff, <command moreinfo="none">hg
 5.15931 +    export 104654</command> suffit. Pour obtenir une entrée du journal suivie d'un diff,
 5.15932 +    <command moreinfo="none">hg log -r104654 -p</command>.</para>
 5.15933 +
 5.15934 +    <para id="x_706">Quand vous exécutez la commande <command moreinfo="none">hg status</command>
 5.15935 +    sans aucun argument, elle affiche l'état de l'ensemble de l'arborescence,
 5.15936 +    avec des chemins relatifs partant de la racine du dépôt. Ceci rend
 5.15937 +    difficile de copier un nom de fichier depuis la sortie de la commande
 5.15938 +    <command moreinfo="none">hg status</command> dans une autre ligne de commande. Si vous
 5.15939 +    fournissez un fichier ou un répertoire à la commande <command moreinfo="none">hg
 5.15940 +    status</command>, elle va afficher les chemins relatif depuis votre
 5.15941 +    répertoire courant à la place. Ainsi, pour avoir un état sur l'ensemble
 5.15942 +    de l'arborescence à l'aide  de <command moreinfo="none">hg status</command>, avec des
 5.15943 +    chemins relatifs à votre répertoire courant, et non la racine du dépôt,
 5.15944 +    ajoutez la sortie de <command moreinfo="none">hg root</command> à la commande
 5.15945 +    <command moreinfo="none">hg status</command>. Vous pouvez le faire aisément sur un
 5.15946 +    système Unix ainsi :</para>
 5.15947 +
 5.15948 +    <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status `hg root`</userinput></screen>
 5.15949 +  </sect1>
 5.15950 +</appendix>
 5.15951 +
 5.15952 +<!--
 5.15953 +local variables: 
 5.15954 +sgml-parent-document: ("00book.xml" "book" "appendix")
 5.15955 +end:
 5.15956 +-->
 5.15957 +
 5.15958 +  <!-- BEGIN appB -->
 5.15959 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.15960 +
 5.15961 +<appendix id="chap:mqref">
 5.15962 +  <?dbhtml filename="mercurial-queues-reference.html"?>
 5.15963 +  <title>Mercurial Queues reference</title>
 5.15964 +
 5.15965 +  <sect1 id="sec:mqref:cmdref">
 5.15966 +    <title>MQ command reference</title>
 5.15967 +
 5.15968 +    <para id="x_5e8">For an overview of the commands provided by MQ, use the
 5.15969 +      command <command role="hg-cmd" moreinfo="none">hg help mq</command>.</para>
 5.15970 +
 5.15971 +    <sect2>
 5.15972 +      <title><command role="hg-ext-mq" moreinfo="none">qapplied</command>—print
 5.15973 +	applied patches</title>
 5.15974 +
 5.15975 +      <para id="x_5e9">The <command role="hg-ext-mq" moreinfo="none">qapplied</command> command
 5.15976 +	prints the current stack of applied patches.  Patches are
 5.15977 +	printed in oldest-to-newest order, so the last patch in the
 5.15978 +	list is the <quote>top</quote> patch.</para>
 5.15979 +
 5.15980 +    </sect2>
 5.15981 +    <sect2>
 5.15982 +      <title><command role="hg-ext-mq" moreinfo="none">qcommit</command>—commit
 5.15983 +	changes in the queue repository</title>
 5.15984 +
 5.15985 +      <para id="x_5ea">The <command role="hg-ext-mq" moreinfo="none">qcommit</command> command
 5.15986 +	commits any outstanding changes in the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>
 5.15987 +	repository.  This command only works if the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>
 5.15988 +	directory is a repository, i.e. you created the directory
 5.15989 +	using <command role="hg-cmd" moreinfo="none">hg qinit <option role="hg-ext-mq-cmd-qinit-opt">-c</option></command> or
 5.15990 +	ran <command role="hg-cmd" moreinfo="none">hg init</command> in the directory
 5.15991 +	after running <command role="hg-ext-mq" moreinfo="none">qinit</command>.</para>
 5.15992 +
 5.15993 +      <para id="x_5eb">This command is shorthand for <command role="hg-cmd" moreinfo="none">hg
 5.15994 +	  commit --cwd .hg/patches</command>.</para>
 5.15995 +    </sect2>
 5.15996 +    <sect2>
 5.15997 +	<title><command role="hg-ext-mq" moreinfo="none">qdelete</command>—delete a patch
 5.15998 +	from the <filename role="special" moreinfo="none">series</filename>
 5.15999 +	file</title>
 5.16000 +
 5.16001 +      <para id="x_5ec">The <command role="hg-ext-mq" moreinfo="none">qdelete</command> command
 5.16002 +	removes the entry for a patch from the <filename role="special" moreinfo="none">series</filename> file in the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>
 5.16003 +	directory.  It does not pop the patch if the patch is already
 5.16004 +	applied.  By default, it does not delete the patch file; use
 5.16005 +	the <option role="hg-ext-mq-cmd-qdel-opt">-f</option> option
 5.16006 +	to do that.</para>
 5.16007 +
 5.16008 +      <para id="x_5ed">Options:</para>
 5.16009 +      <itemizedlist>
 5.16010 +	<listitem><para id="x_5ee"><option role="hg-ext-mq-cmd-qdel-opt">-f</option>: Delete the
 5.16011 +	    patch file.</para>
 5.16012 +	</listitem></itemizedlist>
 5.16013 +
 5.16014 +    </sect2>
 5.16015 +    <sect2>
 5.16016 +      <title><command role="hg-ext-mq" moreinfo="none">qdiff</command>—print a
 5.16017 +	diff of the topmost applied patch</title>
 5.16018 +
 5.16019 +      <para id="x_5ef">The <command role="hg-ext-mq" moreinfo="none">qdiff</command> command
 5.16020 +	prints a diff of the topmost applied patch. It is equivalent
 5.16021 +	to <command role="hg-cmd" moreinfo="none">hg diff -r-2:-1</command>.</para>
 5.16022 +
 5.16023 +    </sect2>
 5.16024 +    <sect2>
 5.16025 +      <title><command role="hg-ext-mq" moreinfo="none">qfold</command>—move
 5.16026 +	applied patches into repository history</title>
 5.16027 +
 5.16028 +      <para id="x_72d">The <command moreinfo="none">hg qfinish</command> command converts the
 5.16029 +	specified applied patches into permanent changes by moving
 5.16030 +	them out of MQ's control so that they will be treated as
 5.16031 +	normal repository history.</para>
 5.16032 +    </sect2>
 5.16033 +
 5.16034 +    <sect2>
 5.16035 +      <title><command role="hg-ext-mq" moreinfo="none">qfold</command>—merge
 5.16036 +	(<quote>fold</quote>) several patches into one</title>
 5.16037 +
 5.16038 +      <para id="x_5f0">The <command role="hg-ext-mq" moreinfo="none">qfold</command> command
 5.16039 +	merges multiple patches into the topmost applied patch, so
 5.16040 +	that the topmost applied patch makes the union of all of the
 5.16041 +	changes in the patches in question.</para>
 5.16042 +
 5.16043 +      <para id="x_5f1">The patches to fold must not be applied; <command role="hg-ext-mq" moreinfo="none">qfold</command> will exit with an error if
 5.16044 +	any is.  The order in which patches are folded is significant;
 5.16045 +	<command role="hg-cmd" moreinfo="none">hg qfold a b</command> means
 5.16046 +	<quote>apply the current topmost patch, followed by
 5.16047 +	  <literal moreinfo="none">a</literal>, followed by
 5.16048 +	  <literal moreinfo="none">b</literal></quote>.</para>
 5.16049 +
 5.16050 +      <para id="x_5f2">The comments from the folded patches are appended to the
 5.16051 +	comments of the destination patch, with each block of comments
 5.16052 +	separated by three asterisk
 5.16053 +	(<quote><literal moreinfo="none">*</literal></quote>) characters.  Use the
 5.16054 +	<option role="hg-ext-mq-cmd-qfold-opt">-e</option> option to
 5.16055 +	edit the commit message for the combined patch/changeset after
 5.16056 +	the folding has completed.</para>
 5.16057 +
 5.16058 +      <para id="x_5f3">Options:</para>
 5.16059 +      <itemizedlist>
 5.16060 +	<listitem><para id="x_5f4"><option role="hg-ext-mq-cmd-qfold-opt">-e</option>: Edit the
 5.16061 +	    commit message and patch description for the newly folded
 5.16062 +	    patch.</para>
 5.16063 +	</listitem>
 5.16064 +	<listitem><para id="x_5f5"><option role="hg-ext-mq-cmd-qfold-opt">-l</option>: Use the
 5.16065 +	    contents of the given file as the new commit message and
 5.16066 +	    patch description for the folded patch.</para>
 5.16067 +	</listitem>
 5.16068 +	<listitem><para id="x_5f6"><option role="hg-ext-mq-cmd-qfold-opt">-m</option>: Use the
 5.16069 +	    given text as the new commit message and patch description
 5.16070 +	    for the folded patch.</para>
 5.16071 +	</listitem></itemizedlist>
 5.16072 +
 5.16073 +    </sect2>
 5.16074 +    <sect2>
 5.16075 +      <title><command role="hg-ext-mq" moreinfo="none">qheader</command>—display the
 5.16076 +	header/description of a patch</title>
 5.16077 +
 5.16078 +      <para id="x_5f7">The <command role="hg-ext-mq" moreinfo="none">qheader</command> command
 5.16079 +	prints the header, or description, of a patch.  By default, it
 5.16080 +	prints the header of the topmost applied patch. Given an
 5.16081 +	argument, it prints the header of the named patch.</para>
 5.16082 +
 5.16083 +    </sect2>
 5.16084 +    <sect2>
 5.16085 +      <title><command role="hg-ext-mq" moreinfo="none">qimport</command>—import
 5.16086 +	a third-party patch into the queue</title>
 5.16087 +
 5.16088 +      <para id="x_5f8">The <command role="hg-ext-mq" moreinfo="none">qimport</command> command
 5.16089 +	adds an entry for an external patch to the <filename role="special" moreinfo="none">series</filename> file, and copies the patch
 5.16090 +	into the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory.  It adds
 5.16091 +	the entry immediately after the topmost applied patch, but
 5.16092 +	does not push the patch.</para>
 5.16093 +
 5.16094 +      <para id="x_5f9">If the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory is a
 5.16095 +	repository, <command role="hg-ext-mq" moreinfo="none">qimport</command>
 5.16096 +	automatically does an <command role="hg-cmd" moreinfo="none">hg add</command>
 5.16097 +	of the imported patch.</para>
 5.16098 +
 5.16099 +    </sect2>
 5.16100 +    <sect2>
 5.16101 +      <title><command role="hg-ext-mq" moreinfo="none">qinit</command>—prepare
 5.16102 +	a repository to work with MQ</title>
 5.16103 +
 5.16104 +      <para id="x_5fa">The <command role="hg-ext-mq" moreinfo="none">qinit</command> command
 5.16105 +	prepares a repository to work with MQ.  It creates a directory
 5.16106 +	called <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>.</para>
 5.16107 +
 5.16108 +      <para id="x_5fb">Options:</para>
 5.16109 +      <itemizedlist>
 5.16110 +	<listitem><para id="x_5fc"><option role="hg-ext-mq-cmd-qinit-opt">-c</option>: Create
 5.16111 +	    <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> as a repository
 5.16112 +	    in its own right.  Also creates a <filename role="special" moreinfo="none">.hgignore</filename> file that will
 5.16113 +	    ignore the <filename role="special" moreinfo="none">status</filename>
 5.16114 +	    file.</para>
 5.16115 +	</listitem></itemizedlist>
 5.16116 +
 5.16117 +      <para id="x_5fd">When the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory is a
 5.16118 +	repository, the <command role="hg-ext-mq" moreinfo="none">qimport</command>
 5.16119 +	and <command role="hg-ext-mq" moreinfo="none">qnew</command> commands
 5.16120 +	automatically <command role="hg-cmd" moreinfo="none">hg add</command> new
 5.16121 +	patches.</para>
 5.16122 +
 5.16123 +    </sect2>
 5.16124 +    <sect2>
 5.16125 +      <title><command role="hg-ext-mq" moreinfo="none">qnew</command>—create a
 5.16126 +	new patch</title>
 5.16127 +
 5.16128 +      <para id="x_5fe">The <command role="hg-ext-mq" moreinfo="none">qnew</command> command
 5.16129 +	creates a new patch.  It takes one mandatory argument, the
 5.16130 +	name to use for the patch file.  The newly created patch is
 5.16131 +	created empty by default.  It is added to the <filename role="special" moreinfo="none">series</filename> file after the current
 5.16132 +	topmost applied patch, and is immediately pushed on top of
 5.16133 +	that patch.</para>
 5.16134 +
 5.16135 +      <para id="x_5ff">If <command role="hg-ext-mq" moreinfo="none">qnew</command> finds modified
 5.16136 +	files in the working directory, it will refuse to create a new
 5.16137 +	patch unless the <option role="hg-ext-mq-cmd-qnew-opt">-f</option> option is used
 5.16138 +	(see below).  This behavior allows you to <command role="hg-ext-mq" moreinfo="none">qrefresh</command> your topmost applied
 5.16139 +	patch before you apply a new patch on top of it.</para>
 5.16140 +
 5.16141 +      <para id="x_600">Options:</para>
 5.16142 +      <itemizedlist>
 5.16143 +	<listitem><para id="x_601"><option role="hg-ext-mq-cmd-qnew-opt">-f</option>: Create a new
 5.16144 +	    patch if the contents of the working directory are
 5.16145 +	    modified.  Any outstanding modifications are added to the
 5.16146 +	    newly created patch, so after this command completes, the
 5.16147 +	    working directory will no longer be modified.</para>
 5.16148 +	</listitem>
 5.16149 +	<listitem><para id="x_602"><option role="hg-ext-mq-cmd-qnew-opt">-m</option>: Use the given
 5.16150 +	    text as the commit message. This text will be stored at
 5.16151 +	    the beginning of the patch file, before the patch
 5.16152 +	    data.</para>
 5.16153 +	</listitem></itemizedlist>
 5.16154 +
 5.16155 +    </sect2>
 5.16156 +    <sect2>
 5.16157 +      <title><command role="hg-ext-mq" moreinfo="none">qnext</command>—print
 5.16158 +	the name of the next patch</title>
 5.16159 +
 5.16160 +      <para id="x_603">The <command role="hg-ext-mq" moreinfo="none">qnext</command> command
 5.16161 +	prints the name name of the next patch in the <filename role="special" moreinfo="none">series</filename> file after the topmost
 5.16162 +	applied patch.  This patch will become the topmost applied
 5.16163 +	patch if you run <command role="hg-ext-mq" moreinfo="none">qpush</command>.</para>
 5.16164 +
 5.16165 +    </sect2>
 5.16166 +    <sect2>
 5.16167 +      <title><command role="hg-ext-mq" moreinfo="none">qpop</command>—pop
 5.16168 +	patches off the stack</title>
 5.16169 +
 5.16170 +      <para id="x_604">The <command role="hg-ext-mq" moreinfo="none">qpop</command> command
 5.16171 +	removes applied patches from the top of the stack of applied
 5.16172 +	patches.  By default, it removes only one patch.</para>
 5.16173 +
 5.16174 +      <para id="x_605">This command removes the changesets that represent the
 5.16175 +	popped patches from the repository, and updates the working
 5.16176 +	directory to undo the effects of the patches.</para>
 5.16177 +
 5.16178 +      <para id="x_606">This command takes an optional argument, which it uses as
 5.16179 +	the name or index of the patch to pop to.  If given a name, it
 5.16180 +	will pop patches until the named patch is the topmost applied
 5.16181 +	patch.  If given a number, <command role="hg-ext-mq" moreinfo="none">qpop</command> treats the number as an
 5.16182 +	index into the entries in the series file, counting from zero
 5.16183 +	(empty lines and lines containing only comments do not count).
 5.16184 +	It pops patches until the patch identified by the given index
 5.16185 +	is the topmost applied patch.</para>
 5.16186 +
 5.16187 +      <para id="x_607">The <command role="hg-ext-mq" moreinfo="none">qpop</command> command does
 5.16188 +	not read or write patches or the <filename role="special" moreinfo="none">series</filename> file.  It is thus safe to
 5.16189 +	<command role="hg-ext-mq" moreinfo="none">qpop</command> a patch that you have
 5.16190 +	removed from the <filename role="special" moreinfo="none">series</filename>
 5.16191 +	file, or a patch that you have renamed or deleted entirely.
 5.16192 +	In the latter two cases, use the name of the patch as it was
 5.16193 +	when you applied it.</para>
 5.16194 +
 5.16195 +      <para id="x_608">By default, the <command role="hg-ext-mq" moreinfo="none">qpop</command>
 5.16196 +	command will not pop any patches if the working directory has
 5.16197 +	been modified.  You can override this behavior using the
 5.16198 +	<option role="hg-ext-mq-cmd-qpop-opt">-f</option> option,
 5.16199 +	which reverts all modifications in the working
 5.16200 +	directory.</para>
 5.16201 +
 5.16202 +      <para id="x_609">Options:</para>
 5.16203 +      <itemizedlist>
 5.16204 +	<listitem><para id="x_60a"><option role="hg-ext-mq-cmd-qpop-opt">-a</option>: Pop all
 5.16205 +	    applied patches.  This returns the repository to its state
 5.16206 +	    before you applied any patches.</para>
 5.16207 +	</listitem>
 5.16208 +	<listitem><para id="x_60b"><option role="hg-ext-mq-cmd-qpop-opt">-f</option>: Forcibly
 5.16209 +	    revert any modifications to the working directory when
 5.16210 +	    popping.</para>
 5.16211 +	</listitem>
 5.16212 +	<listitem><para id="x_60c"><option role="hg-ext-mq-cmd-qpop-opt">-n</option>: Pop a patch
 5.16213 +	    from the named queue.</para>
 5.16214 +	</listitem></itemizedlist>
 5.16215 +
 5.16216 +      <para id="x_60d">The <command role="hg-ext-mq" moreinfo="none">qpop</command> command
 5.16217 +	removes one line from the end of the <filename role="special" moreinfo="none">status</filename> file for each patch that it
 5.16218 +	pops.</para>
 5.16219 +
 5.16220 +    </sect2>
 5.16221 +    <sect2>
 5.16222 +      <title><command role="hg-ext-mq" moreinfo="none">qprev</command>—print
 5.16223 +	the name of the previous patch</title>
 5.16224 +
 5.16225 +      <para id="x_60e">The <command role="hg-ext-mq" moreinfo="none">qprev</command> command
 5.16226 +	prints the name of the patch in the <filename role="special" moreinfo="none">series</filename> file that comes before the
 5.16227 +	topmost applied patch. This will become the topmost applied
 5.16228 +	patch if you run <command role="hg-ext-mq" moreinfo="none">qpop</command>.</para>
 5.16229 +
 5.16230 +    </sect2>
 5.16231 +    <sect2 id="sec:mqref:cmd:qpush">
 5.16232 +      <title><command role="hg-ext-mq" moreinfo="none">qpush</command>—push
 5.16233 +	patches onto the stack</title>
 5.16234 +
 5.16235 +      <para id="x_60f">The <command role="hg-ext-mq" moreinfo="none">qpush</command> command adds
 5.16236 +	patches onto the applied stack.  By default, it adds only one
 5.16237 +	patch.</para>
 5.16238 +
 5.16239 +      <para id="x_610">This command creates a new changeset to represent each
 5.16240 +	applied patch, and updates the working directory to apply the
 5.16241 +	effects of the patches.</para>
 5.16242 +
 5.16243 +      <para id="x_611">The default data used when creating a changeset are as
 5.16244 +	follows:</para>
 5.16245 +      <itemizedlist>
 5.16246 +	<listitem><para id="x_612">The commit date and time zone are the current
 5.16247 +	    date and time zone.  Because these data are used to
 5.16248 +	    compute the identity of a changeset, this means that if
 5.16249 +	    you <command role="hg-ext-mq" moreinfo="none">qpop</command> a patch and
 5.16250 +	    <command role="hg-ext-mq" moreinfo="none">qpush</command> it again, the
 5.16251 +	    changeset that you push will have a different identity
 5.16252 +	    than the changeset you popped.</para>
 5.16253 +	</listitem>
 5.16254 +	<listitem><para id="x_613">The author is the same as the default used by
 5.16255 +	    the <command role="hg-cmd" moreinfo="none">hg commit</command>
 5.16256 +	    command.</para>
 5.16257 +	</listitem>
 5.16258 +	<listitem><para id="x_614">The commit message is any text from the patch
 5.16259 +	    file that comes before the first diff header.  If there is
 5.16260 +	    no such text, a default commit message is used that
 5.16261 +	    identifies the name of the patch.</para>
 5.16262 +	</listitem></itemizedlist>
 5.16263 +      <para id="x_615">If a patch contains a Mercurial patch header,
 5.16264 +	the information in the patch header overrides these
 5.16265 +	defaults.</para>
 5.16266 +
 5.16267 +      <para id="x_616">Options:</para>
 5.16268 +      <itemizedlist>
 5.16269 +	<listitem><para id="x_617"><option role="hg-ext-mq-cmd-qpush-opt">-a</option>: Push all
 5.16270 +	    unapplied patches from the <filename role="special" moreinfo="none">series</filename> file until there are
 5.16271 +	    none left to push.</para>
 5.16272 +	</listitem>
 5.16273 +	<listitem><para id="x_618"><option role="hg-ext-mq-cmd-qpush-opt">-l</option>: Add the name
 5.16274 +	    of the patch to the end of the commit message.</para>
 5.16275 +	</listitem>
 5.16276 +	<listitem><para id="x_619"><option role="hg-ext-mq-cmd-qpush-opt">-m</option>: If a patch
 5.16277 +	    fails to apply cleanly, use the entry for the patch in
 5.16278 +	    another saved queue to compute the parameters for a
 5.16279 +	    three-way merge, and perform a three-way merge using the
 5.16280 +	    normal Mercurial merge machinery.  Use the resolution of
 5.16281 +	    the merge as the new patch content.</para>
 5.16282 +	</listitem>
 5.16283 +	<listitem><para id="x_61a"><option role="hg-ext-mq-cmd-qpush-opt">-n</option>: Use the
 5.16284 +	    named queue if merging while pushing.</para>
 5.16285 +	</listitem></itemizedlist>
 5.16286 +
 5.16287 +      <para id="x_61b">The <command role="hg-ext-mq" moreinfo="none">qpush</command> command
 5.16288 +	reads, but does not modify, the <filename role="special" moreinfo="none">series</filename> file.  It appends one line
 5.16289 +	to the <command role="hg-cmd" moreinfo="none">hg status</command> file for
 5.16290 +	each patch that it pushes.</para>
 5.16291 +
 5.16292 +    </sect2>
 5.16293 +    <sect2>
 5.16294 +      <title><command role="hg-ext-mq" moreinfo="none">qrefresh</command>—update the
 5.16295 +	topmost applied patch</title>
 5.16296 +
 5.16297 +      <para id="x_61c">The <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 5.16298 +	updates the topmost applied patch.  It modifies the patch,
 5.16299 +	removes the old changeset that represented the patch, and
 5.16300 +	creates a new changeset to represent the modified
 5.16301 +	patch.</para>
 5.16302 +
 5.16303 +      <para id="x_61d">The <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 5.16304 +	looks for the following modifications:</para>
 5.16305 +      <itemizedlist>
 5.16306 +	<listitem><para id="x_61e">Changes to the commit message, i.e. the text
 5.16307 +	    before the first diff header in the patch file, are
 5.16308 +	    reflected in the new changeset that represents the
 5.16309 +	    patch.</para>
 5.16310 +	</listitem>
 5.16311 +	<listitem><para id="x_61f">Modifications to tracked files in the working
 5.16312 +	    directory are added to the patch.</para>
 5.16313 +	</listitem>
 5.16314 +	<listitem><para id="x_620">Changes to the files tracked using <command role="hg-cmd" moreinfo="none">hg add</command>, <command role="hg-cmd" moreinfo="none">hg copy</command>, <command role="hg-cmd" moreinfo="none">hg remove</command>, or <command role="hg-cmd" moreinfo="none">hg rename</command>.  Added files and copy
 5.16315 +	    and rename destinations are added to the patch, while
 5.16316 +	    removed files and rename sources are removed.</para>
 5.16317 +	</listitem></itemizedlist>
 5.16318 +
 5.16319 +      <para id="x_621">Even if <command role="hg-ext-mq" moreinfo="none">qrefresh</command>
 5.16320 +	detects no changes, it still recreates the changeset that
 5.16321 +	represents the patch.  This causes the identity of the
 5.16322 +	changeset to differ from the previous changeset that
 5.16323 +	identified the patch.</para>
 5.16324 +
 5.16325 +      <para id="x_622">Options:</para>
 5.16326 +      <itemizedlist>
 5.16327 +	<listitem><para id="x_623"><option role="hg-ext-mq-cmd-qrefresh-opt">-e</option>: Modify
 5.16328 +	    the commit and patch description, using the preferred text
 5.16329 +	    editor.</para>
 5.16330 +	</listitem>
 5.16331 +	<listitem><para id="x_624"><option role="hg-ext-mq-cmd-qrefresh-opt">-m</option>: Modify
 5.16332 +	    the commit message and patch description, using the given
 5.16333 +	    text.</para>
 5.16334 +	</listitem>
 5.16335 +	<listitem><para id="x_625"><option role="hg-ext-mq-cmd-qrefresh-opt">-l</option>: Modify
 5.16336 +	    the commit message and patch description, using text from
 5.16337 +	    the given file.</para>
 5.16338 +	</listitem></itemizedlist>
 5.16339 +
 5.16340 +    </sect2>
 5.16341 +    <sect2>
 5.16342 +      <title><command role="hg-ext-mq" moreinfo="none">qrename</command>—rename
 5.16343 +	a patch</title>
 5.16344 +
 5.16345 +      <para id="x_626">The <command role="hg-ext-mq" moreinfo="none">qrename</command> command
 5.16346 +	renames a patch, and changes the entry for the patch in the
 5.16347 +	<filename role="special" moreinfo="none">series</filename> file.</para>
 5.16348 +
 5.16349 +      <para id="x_627">With a single argument, <command role="hg-ext-mq" moreinfo="none">qrename</command> renames the topmost
 5.16350 +	applied patch.  With two arguments, it renames its first
 5.16351 +	argument to its second.</para>
 5.16352 +
 5.16353 +    </sect2>
 5.16354 +    <sect2>
 5.16355 +      <title><command role="hg-ext-mq" moreinfo="none">qseries</command>—print
 5.16356 +	the entire patch series</title>
 5.16357 +
 5.16358 +      <para id="x_62a">The <command role="hg-ext-mq" moreinfo="none">qseries</command> command
 5.16359 +	prints the entire patch series from the <filename role="special" moreinfo="none">series</filename> file.  It prints only patch
 5.16360 +	names, not empty lines or comments.  It prints in order from
 5.16361 +	first to be applied to last.</para>
 5.16362 +
 5.16363 +    </sect2>
 5.16364 +    <sect2>
 5.16365 +      <title><command role="hg-ext-mq" moreinfo="none">qtop</command>—print the
 5.16366 +	name of the current patch</title>
 5.16367 +
 5.16368 +      <para id="x_62b">The <command role="hg-ext-mq" moreinfo="none">qtop</command> prints the
 5.16369 +	name of the topmost currently applied patch.</para>
 5.16370 +
 5.16371 +    </sect2>
 5.16372 +    <sect2>
 5.16373 +      <title><command role="hg-ext-mq" moreinfo="none">qunapplied</command>—print patches
 5.16374 +	not yet applied</title>
 5.16375 +
 5.16376 +      <para id="x_62c">The <command role="hg-ext-mq" moreinfo="none">qunapplied</command> command
 5.16377 +	prints the names of patches from the <filename role="special" moreinfo="none">series</filename> file that are not yet
 5.16378 +	applied.  It prints them in order from the next patch that
 5.16379 +	will be pushed to the last.</para>
 5.16380 +
 5.16381 +    </sect2>
 5.16382 +    <sect2>
 5.16383 +      <title><command role="hg-cmd" moreinfo="none">hg strip</command>—remove a
 5.16384 +	revision and descendants</title>
 5.16385 +
 5.16386 +      <para id="x_62d">The <command role="hg-cmd" moreinfo="none">hg strip</command> command
 5.16387 +	removes a revision, and all of its descendants, from the
 5.16388 +	repository.  It undoes the effects of the removed revisions
 5.16389 +	from the repository, and updates the working directory to the
 5.16390 +	first parent of the removed revision.</para>
 5.16391 +
 5.16392 +      <para id="x_62e">The <command role="hg-cmd" moreinfo="none">hg strip</command> command
 5.16393 +	saves a backup of the removed changesets in a bundle, so that
 5.16394 +	they can be reapplied if removed in error.</para>
 5.16395 +
 5.16396 +      <para id="x_62f">Options:</para>
 5.16397 +      <itemizedlist>
 5.16398 +	<listitem><para id="x_630"><option role="hg-opt-strip">-b</option>: Save
 5.16399 +	    unrelated changesets that are intermixed with the stripped
 5.16400 +	    changesets in the backup bundle.</para>
 5.16401 +	</listitem>
 5.16402 +	<listitem><para id="x_631"><option role="hg-opt-strip">-f</option>: If a
 5.16403 +	    branch has multiple heads, remove all heads.</para>
 5.16404 +	</listitem>
 5.16405 +	<listitem><para id="x_632"><option role="hg-opt-strip">-n</option>: Do
 5.16406 +	    not save a backup bundle.</para>
 5.16407 +	</listitem></itemizedlist>
 5.16408 +
 5.16409 +    </sect2>
 5.16410 +  </sect1>
 5.16411 +  <sect1>
 5.16412 +    <title>MQ file reference</title>
 5.16413 +
 5.16414 +    <sect2>
 5.16415 +      <title>The <filename role="special" moreinfo="none">series</filename>
 5.16416 +	file</title>
 5.16417 +
 5.16418 +      <para id="x_633">The <filename role="special" moreinfo="none">series</filename> file
 5.16419 +	contains a list of the names of all patches that MQ can apply.
 5.16420 +	It is represented as a list of names, with one name saved per
 5.16421 +	line.  Leading and trailing white space in each line are
 5.16422 +	ignored.</para>
 5.16423 +
 5.16424 +      <para id="x_634">Lines may contain comments.  A comment begins with the
 5.16425 +	<quote><literal moreinfo="none">#</literal></quote> character, and extends to
 5.16426 +	the end of the line.  Empty lines, and lines that contain only
 5.16427 +	comments, are ignored.</para>
 5.16428 +
 5.16429 +      <para id="x_635">You will often need to edit the <filename role="special" moreinfo="none">series</filename> file by hand, hence the
 5.16430 +	support for comments and empty lines noted above.  For
 5.16431 +	example, you can comment out a patch temporarily, and <command role="hg-ext-mq" moreinfo="none">qpush</command> will skip over that patch
 5.16432 +	when applying patches.  You can also change the order in which
 5.16433 +	patches are applied by reordering their entries in the
 5.16434 +	<filename role="special" moreinfo="none">series</filename> file.</para>
 5.16435 +
 5.16436 +      <para id="x_636">Placing the <filename role="special" moreinfo="none">series</filename>
 5.16437 +	file under revision control is also supported; it is a good
 5.16438 +	idea to place all of the patches that it refers to under
 5.16439 +	revision control, as well.  If you create a patch directory
 5.16440 +	using the <option role="hg-ext-mq-cmd-qinit-opt">-c</option>
 5.16441 +	option to <command role="hg-ext-mq" moreinfo="none">qinit</command>, this will
 5.16442 +	be done for you automatically.</para>
 5.16443 +
 5.16444 +    </sect2>
 5.16445 +    <sect2>
 5.16446 +      <title>The <filename role="special" moreinfo="none">status</filename>
 5.16447 +	file</title>
 5.16448 +
 5.16449 +      <para id="x_637">The <filename role="special" moreinfo="none">status</filename> file
 5.16450 +	contains the names and changeset hashes of all patches that MQ
 5.16451 +	currently has applied.  Unlike the <filename role="special" moreinfo="none">series</filename> file, this file is not
 5.16452 +	intended for editing.  You should not place this file under
 5.16453 +	revision control, or modify it in any way.  It is used by MQ
 5.16454 +	strictly for internal book-keeping.</para>
 5.16455 +
 5.16456 +    </sect2>
 5.16457 +  </sect1>
 5.16458 +</appendix>
 5.16459 +
 5.16460 +<!--
 5.16461 +local variables: 
 5.16462 +sgml-parent-document: ("00book.xml" "book" "appendix")
 5.16463 +end:
 5.16464 +-->
 5.16465 +
 5.16466 +  <!-- BEGIN appC -->
 5.16467 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.16468 +
 5.16469 +<appendix id="chap:srcinstall">
 5.16470 +  <?dbhtml filename="installing-mercurial-from-source.html"?>
 5.16471 +  <title>Installer Mercurial à partir des sources</title>
 5.16472 +
 5.16473 +  <sect1 id="sec:srcinstall:unixlike">
 5.16474 +    <title>Pour un système Unix ou similaire</title>
 5.16475 +
 5.16476 +    <para id="x_5e0">Si vous utilisez un système Unix ou similaire, pour lequel
 5.16477 +      une version récente de Python (2.3 ou plus) est disponible, l'installation
 5.16478 +      de Mercurial à partir des sources est simple.</para>
 5.16479 +    <orderedlist inheritnum="ignore" continuation="restarts">
 5.16480 +      <listitem><para id="x_5e1">Téléchargez un paquet récent depuis <ulink url="http://www.selenic.com/mercurial/download">http://www.selenic.com/mercurial/download</ulink>.</para>
 5.16481 +      </listitem>
 5.16482 +      <listitem><para id="x_5e2">Extrayez le paquet : </para>
 5.16483 +	<programlisting format="linespecific">gzip -dc mercurial-MYVERSION.tar.gz | tar xf -</programlisting>
 5.16484 +      </listitem>
 5.16485 +      <listitem><para id="x_5e3">Allez dans le répertoires où les sources ont
 5.16486 +    été extraites et exécutez le script d'installation. Ce dernier compilera
 5.16487 +    Mercurial et l'installera dans votre répertoire utilisateur.</para>
 5.16488 +	<programlisting format="linespecific">cd mercurial-MYVERSION
 5.16489 +python setup.py install --force --home=$HOME</programlisting>
 5.16490 +      </listitem>
 5.16491 +    </orderedlist>
 5.16492 +    <para id="x_5e4">Lorsque l'installation est terminée, Mercurial se
 5.16493 +      trouvera dans le répertoire <literal moreinfo="none">bin</literal> de votre répertoire
 5.16494 +      utilisateur.
 5.16495 +      N'oubliez pas de vérifier que ce répertoire se trouve dans la liste
 5.16496 +      des répertoires où votre shell recherche les exécutables.</para>
 5.16497 +
 5.16498 +    <para id="x_5e5">Vous devrez vraisemblablement définir la variable
 5.16499 +      d'environnement <envar>PYTHONPATH</envar> de manière à ce que
 5.16500 +      l'exécutable de Mercurial puisse trouver le reste des paquets logiciels.
 5.16501 +      Par exemple, sur mon ordinateur portable, je dois le définir ainsi:
 5.16502 +      <literal moreinfo="none">/home/bos/lib/python</literal>. Le chemin exact à utiliser
 5.16503 +      dépendra de la manière dont Python aura été construit pour votre 
 5.16504 +      système. Il ne devrait pas être difficile de le trouver. En cas de
 5.16505 +      doute, lisez le texte généré lors de l'installation ci-dessus, et
 5.16506 +      recherchez l'emplacement où le contenu du répertoire
 5.16507 +      <literal moreinfo="none">mercurial</literal> a été installé.</para>
 5.16508 +
 5.16509 +  </sect1>
 5.16510 +  <sect1>
 5.16511 +    <title>Pour Windows</title>
 5.16512 +
 5.16513 +    <para id="x_5e6">Construire et installer Mercurial sous Windows nécessite
 5.16514 +      des outils logiciels divers, une certaine connaissance technique et une
 5.16515 +      bonne dose de patience. Je vous <emphasis>déconseille fortement</emphasis> 
 5.16516 +      de tenter de le faire si vous êtes un <quote>simple utilisateur</quote>.
 5.16517 +      A moins que vous n'ayez l'intention de "hacker" Mercurial, je vous
 5.16518 +      suggère d'avoir recours à un paquet d'installation de la version binaire.</para>
 5.16519 +
 5.16520 +    <para id="x_5e7">Si vous avez vraiment l'intention de construire
 5.16521 +      Mercurial à partir des sources sous Windows, suivez les indications pour 
 5.16522 +      ce <quote>chemin laborieux</quote> sur le wiki de Mercurial : <ulink url="http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall">http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall</ulink>, 
 5.16523 +      et préparez vous à un travail épineux.</para>
 5.16524 +
 5.16525 +  </sect1>
 5.16526 +</appendix>
 5.16527 +
 5.16528 +<!--
 5.16529 +local variables: 
 5.16530 +sgml-parent-document: ("00book.xml" "book" "appendix")
 5.16531 +end:
 5.16532 +-->
 5.16533 +
 5.16534 +  <!-- BEGIN appD -->
 5.16535 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 5.16536 +
 5.16537 +<appendix id="cha:opl">
 5.16538 +  <?dbhtml filename="open-publication-license.html"?>
 5.16539 +  <title>Open Publication License</title>
 5.16540 +
 5.16541 +  <para id="x_638">Version 1.0, 8 June 1999</para>
 5.16542 +
 5.16543 +  <sect1>
 5.16544 +    <title>Requirements on both unmodified and modified
 5.16545 +      versions</title>
 5.16546 +
 5.16547 +    <para id="x_639">The Open Publication works may be reproduced and distributed
 5.16548 +      in whole or in part, in any medium physical or electronic,
 5.16549 +      provided that the terms of this license are adhered to, and that
 5.16550 +      this license or an incorporation of it by reference (with any
 5.16551 +      options elected by the author(s) and/or publisher) is displayed
 5.16552 +      in the reproduction.</para>
 5.16553 +
 5.16554 +    <para id="x_63a">Proper form for an incorporation by reference is as
 5.16555 +      follows:</para>
 5.16556 +
 5.16557 +    <blockquote>
 5.16558 +      <para id="x_63b">  Copyright (c) <emphasis>year</emphasis> by
 5.16559 +	<emphasis>author's name or designee</emphasis>. This material
 5.16560 +	may be distributed only subject to the terms and conditions
 5.16561 +	set forth in the Open Publication License,
 5.16562 +	v<emphasis>x.y</emphasis> or later (the latest version is
 5.16563 +	presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
 5.16564 +    </blockquote>
 5.16565 +
 5.16566 +    <para id="x_63c">The reference must be immediately followed with any options
 5.16567 +      elected by the author(s) and/or publisher of the document (see
 5.16568 +      <xref linkend="sec:opl:options"/>).</para>
 5.16569 +
 5.16570 +    <para id="x_63d">Commercial redistribution of Open Publication-licensed
 5.16571 +      material is permitted.</para>
 5.16572 +
 5.16573 +    <para id="x_63e">Any publication in standard (paper) book form shall require
 5.16574 +      the citation of the original publisher and author. The publisher
 5.16575 +      and author's names shall appear on all outer surfaces of the
 5.16576 +      book. On all outer surfaces of the book the original publisher's
 5.16577 +      name shall be as large as the title of the work and cited as
 5.16578 +      possessive with respect to the title.</para>
 5.16579 +
 5.16580 +  </sect1>
 5.16581 +  <sect1>
 5.16582 +    <title>Copyright</title>
 5.16583 +
 5.16584 +    <para id="x_63f">The copyright to each Open Publication is owned by its
 5.16585 +      author(s) or designee.</para>
 5.16586 +
 5.16587 +  </sect1>
 5.16588 +  <sect1>
 5.16589 +    <title>Scope of license</title>
 5.16590 +
 5.16591 +    <para id="x_640">The following license terms apply to all Open Publication
 5.16592 +      works, unless otherwise explicitly stated in the
 5.16593 +      document.</para>
 5.16594 +
 5.16595 +    <para id="x_641">Mere aggregation of Open Publication works or a portion of
 5.16596 +      an Open Publication work with other works or programs on the
 5.16597 +      same media shall not cause this license to apply to those other
 5.16598 +      works. The aggregate work shall contain a notice specifying the
 5.16599 +      inclusion of the Open Publication material and appropriate
 5.16600 +      copyright notice.</para>
 5.16601 +
 5.16602 +    <para id="x_642"><emphasis role="bold">Severability</emphasis>. If any part
 5.16603 +      of this license is found to be unenforceable in any
 5.16604 +      jurisdiction, the remaining portions of the license remain in
 5.16605 +      force.</para>
 5.16606 +
 5.16607 +    <para id="x_643"><emphasis role="bold">No warranty</emphasis>. Open
 5.16608 +      Publication works are licensed and provided <quote>as is</quote>
 5.16609 +      without warranty of any kind, express or implied, including, but
 5.16610 +      not limited to, the implied warranties of merchantability and
 5.16611 +      fitness for a particular purpose or a warranty of
 5.16612 +      non-infringement.</para>
 5.16613 +
 5.16614 +  </sect1>
 5.16615 +  <sect1>
 5.16616 +    <title>Requirements on modified works</title>
 5.16617 +
 5.16618 +    <para id="x_644">All modified versions of documents covered by this license,
 5.16619 +      including translations, anthologies, compilations and partial
 5.16620 +      documents, must meet the following requirements:</para>
 5.16621 +
 5.16622 +    <orderedlist inheritnum="ignore" continuation="restarts">
 5.16623 +      <listitem><para id="x_645">The modified version must be labeled as
 5.16624 +	  such.</para>
 5.16625 +      </listitem>
 5.16626 +      <listitem><para id="x_646">The person making the modifications must be
 5.16627 +	  identified and the modifications dated.</para>
 5.16628 +      </listitem>
 5.16629 +      <listitem><para id="x_647">Acknowledgement of the original author and
 5.16630 +	  publisher if applicable must be retained according to normal
 5.16631 +	  academic citation practices.</para>
 5.16632 +      </listitem>
 5.16633 +      <listitem><para id="x_648">The location of the original unmodified document
 5.16634 +	  must be identified.</para>
 5.16635 +      </listitem>
 5.16636 +      <listitem><para id="x_649">The original author's (or authors') name(s) may
 5.16637 +	  not be used to assert or imply endorsement of the resulting
 5.16638 +	  document without the original author's (or authors')
 5.16639 +	  permission.</para>
 5.16640 +      </listitem></orderedlist>
 5.16641 +
 5.16642 +  </sect1>
 5.16643 +  <sect1>
 5.16644 +    <title>Good-practice recommendations</title>
 5.16645 +
 5.16646 +    <para id="x_64a">In addition to the requirements of this license, it is
 5.16647 +      requested from and strongly recommended of redistributors
 5.16648 +      that:</para>
 5.16649 +
 5.16650 +    <orderedlist inheritnum="ignore" continuation="restarts">
 5.16651 +      <listitem><para id="x_64b">If you are distributing Open Publication works
 5.16652 +	  on hardcopy or CD-ROM, you provide email notification to the
 5.16653 +	  authors of your intent to redistribute at least thirty days
 5.16654 +	  before your manuscript or media freeze, to give the authors
 5.16655 +	  time to provide updated documents. This notification should
 5.16656 +	  describe modifications, if any, made to the document.</para>
 5.16657 +      </listitem>
 5.16658 +      <listitem><para id="x_64c">All substantive modifications (including
 5.16659 +	  deletions) be either clearly marked up in the document or
 5.16660 +	  else described in an attachment to the document.</para>
 5.16661 +      </listitem>
 5.16662 +      <listitem><para id="x_64d">Finally, while it is not mandatory under this
 5.16663 +	  license, it is considered good form to offer a free copy of
 5.16664 +	  any hardcopy and CD-ROM expression of an Open
 5.16665 +	  Publication-licensed work to its author(s).</para>
 5.16666 +      </listitem></orderedlist>
 5.16667 +
 5.16668 +  </sect1>
 5.16669 +  <sect1 id="sec:opl:options">
 5.16670 +    <title>License options</title>
 5.16671 +
 5.16672 +    <para id="x_64e">The author(s) and/or publisher of an Open
 5.16673 +      Publication-licensed document may elect certain options by
 5.16674 +      appending language to the reference to or copy of the license.
 5.16675 +      These options are considered part of the license instance and
 5.16676 +      must be included with the license (or its incorporation by
 5.16677 +      reference) in derived works.</para>
 5.16678 +
 5.16679 +    <orderedlist inheritnum="ignore" continuation="restarts">
 5.16680 +      <listitem><para id="x_64f">To prohibit distribution of substantively
 5.16681 +	  modified versions without the explicit permission of the
 5.16682 +	  author(s). <quote>Substantive modification</quote> is
 5.16683 +	  defined as a change to the semantic content of the document,
 5.16684 +	  and excludes mere changes in format or typographical
 5.16685 +	  corrections.</para>
 5.16686 +      </listitem>
 5.16687 +      <listitem><para id="x_650">  To accomplish this, add the phrase
 5.16688 +	  <quote>Distribution of substantively modified versions of
 5.16689 +	    this document is prohibited without the explicit
 5.16690 +	    permission of the copyright holder.</quote> to the license
 5.16691 +	  reference or copy.</para>
 5.16692 +      </listitem>
 5.16693 +      <listitem><para id="x_651">To prohibit any publication of this work or
 5.16694 +	  derivative works in whole or in part in standard (paper)
 5.16695 +	  book form for commercial purposes is prohibited unless prior
 5.16696 +	  permission is obtained from the copyright holder.</para>
 5.16697 +      </listitem>
 5.16698 +      <listitem><para id="x_652">To accomplish this, add the phrase
 5.16699 +	  <quote>Distribution of the work or derivative of the work in
 5.16700 +	    any standard (paper) book form is prohibited unless prior
 5.16701 +	    permission is obtained from the copyright holder.</quote>
 5.16702 +	  to the license reference or copy.</para>
 5.16703 +      </listitem></orderedlist>
 5.16704 +
 5.16705 +  </sect1>
 5.16706 +</appendix>
 5.16707 +
 5.16708 +<!--
 5.16709 +local variables: 
 5.16710 +sgml-parent-document: ("00book.xml" "book" "appendix")
 5.16711 +end:
 5.16712 +-->
 5.16713 +
 5.16714 +</book>
     6.1 --- a/it/web/index-home.html.in	Mon Sep 14 01:18:56 2009 +0200
     6.2 +++ b/it/web/index-home.html.in	Mon Sep 14 01:31:50 2009 +0200
     6.3 @@ -27,7 +27,7 @@
     6.4  
     6.5    <p>Mercurial è un progetto membro della <a href="http://conservancy.softwarefreedom.org/">Software Freedom Conservancy</a> (SFC), una meravigliosa organizzazione no-profit che offre ai progetti membro un supporto legale e amministrativo.</p>
     6.6  
     6.7 -  <p>Bryan O\&#8217;Sullivan, ha deciso di donare le proprie royalty sulle vendite di questo libro alla Software Freedom Conservancy e incoraggia anche i lettori a supportare il lavoro di questa organizzazione.</p>
     6.8 +  <p>Bryan O\&#8217;Sullivan ha deciso di donare le proprie royalty sulle vendite di questo libro alla Software Freedom Conservancy e incoraggia anche i lettori a supportare il lavoro di questa organizzazione.</p>
     6.9  
    6.10    <p>La SFC può <a href="http://conservancy.softwarefreedom.org/?donate">accettare donazioni</a> (esenti dalle tasse secondo la disposizione IRS 501(c)(3), all\&#8217;interno degli Stati Uniti) per conto dei suoi progetti membro. Se volete supportare Mercurial direttamente, considerate la possibilità di fare una donazione alla SFC per destinarla al progetto.</p>
    6.11  
     7.1 --- a/web/index.html.in	Mon Sep 14 01:18:56 2009 +0200
     7.2 +++ b/web/index.html.in	Mon Sep 14 01:31:50 2009 +0200
     7.3 @@ -9,24 +9,46 @@
     7.4  
     7.5    <p>This is the online home of the book &#8220;Mercurial: The
     7.6      Definitive Guide&#8221;.  
     7.7 -    It will be published in 2009 by O'Reilly Media.</p>
     7.8 +    It was published in 2009 by O'Reilly Media.</p>
     7.9  
    7.10 -  <p>I make the content <a href="/read/">freely available
    7.11 -      online</a>.  If you like it, please make a note to buy a copy!</p>
    7.12 +  <p><a href="http://www.selenic.com/mercurial">Mercurial</a> is a
    7.13 +    fast, lightweight source control management system
    7.14 +    designed for easy and efficient handling of very large distributed
    7.15 +    projects.  My book tells you what it is, why you should care, and
    7.16 +    how you can use it effectively.</p>
    7.17 +
    7.18 +  <h2>Read it online</h2>
    7.19 +
    7.20 +  <p>I make the content freely available online: you
    7.21 +    can <a href="/read/"><i>read it here</i></a>.  If you like it,
    7.22 +    please <a href="#buy">buy a copy</a>!</p>
    7.23  
    7.24    <p>For news updates, please
    7.25 -    visit <a href="http://www.serpentine.com/blog/">my blog</a>.</p>
    7.26 +    visit <a href="http://www.serpentine.com/blog/">my blog</a>.  You
    7.27 +    should follow me on
    7.28 +    Twitter <a href="http://twitter.com/bos31337">here</a>.</p>
    7.29  
    7.30 -  <h2>You can contribute!</h2>
    7.31 +  <h2><a name="#buy">How</a> to buy</h2>
    7.32 +
    7.33 +  <p>If you like the book, please support the work of the Software
    7.34 +    Freedom Conservancy (<a href="#sfc">see below</a>) by buying a
    7.35 +    copy.</p>
    7.36 +
    7.37 +  <ul>
    7.38 +    <li><a href="http://www.amazon.com/gp/product/0596800673?ie=UTF8&tag=reaworhas-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0596800673">Amazon.com</a><img src="http://www.assoc-amazon.com/e/ir?t=reaworhas-20&l=as2&o=1&a=0596800673" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></li>
    7.39 +    <li><a href="http://oreilly.com/catalog/9780596800673/">O'Reilly Media</a></li>
    7.40 +  </ul>
    7.41 +
    7.42 +  <h2>You should contribute!</h2>
    7.43  
    7.44    <p>I publish the source code for this book
    7.45 -    as <a href="http://hg.serpentine.com/mercurial/book">a
    7.46 +    as <a href="http://bitbucket.org/bos/hgbook">a
    7.47        Mercurial repository</a>.  Please feel
    7.48      welcome to clone it, make modifications to your copy, and send me
    7.49      changes.  Getting a copy of the source takes just a few seconds if
    7.50      you have Mercurial installed:</p>
    7.51  
    7.52 -  <pre class="screen">hg clone http://hg.serpentine.com/mercurial/book</pre>
    7.53 +  <pre class="screen">hg clone http://bitbucket.org/bos/hgbook</pre>
    7.54  
    7.55    <p>The online version of the book includes a comment system
    7.56      that you can use to send feedback involving errors, omissions, and
    7.57 @@ -36,22 +58,16 @@
    7.58      publishing project of your own, the source for the web application
    7.59      is included with the book source at the link above.)</p>
    7.60  
    7.61 -  <h2>What is Mercurial?</h2>
    7.62 -
    7.63 -  <p><a href="http://www.selenic.com/mercurial">Mercurial</a> is a
    7.64 -    fast, lightweight source control management system
    7.65 -    designed for easy and efficient handling of very large distributed
    7.66 -    projects.</p>
    7.67 -
    7.68 -  <h2>How I help Mercurial and free software, and you can too</h2>
    7.69 +  <h2><a name="sfc">How</a> I help Mercurial and free software, and
    7.70 +    you can too</h2>
    7.71  
    7.72    <p>Mercurial is a member of the <a href="http://conservancy.softwarefreedom.org/">Software Freedom Conservancy</a>, a
    7.73      wonderful non-profit organisation that offers its member projects
    7.74      legal and administrative advice.</p>
    7.75  
    7.76 -  <p>I am donating my royalties from the sales of this book (once it is
    7.77 -    published) to the Software Freedom Conservancy, and I encourage
    7.78 -    you to support their work, too.</p>
    7.79 +  <p>I donate my royalties from the sales of this book to the
    7.80 +    Software Freedom Conservancy, and I encourage you to support their
    7.81 +    work, too.</p>
    7.82  
    7.83    <p>The SFC can
    7.84      accept <a href="http://conservancy.softwarefreedom.org/?donate">accept