hgbook

changeset 999:a6b81cd31cfd french-xdoc-build-fixed

adding complete.xml - which generated but Bryan did add it also - as I have absolutly no personnality I do as he does
author Romain PELISSE <belaran@gmail.com>
date Sat Sep 12 20:53:36 2009 +0200 (2009-09-12)
parents 9d32b10fdb1e
children 0fba9db5e75c
files fr/complete.xml
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/fr/complete.xml	Sat Sep 12 20:53:36 2009 +0200
     1.3 @@ -0,0 +1,16711 @@
     1.4 +<?xml version="1.0"?>
     1.5 +
     1.6 +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
     1.7 + "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
     1.8 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     1.9 +<book id="hg">
    1.10 +  <title>Mercurial: The Definitive Guide</title>
    1.11 +  
    1.12 +  <!-- hg parents &#x2d;&#x2d;template '{node|short} ({date|shortdate})' 
    1.13 +  <subtitle>Compiled from 8a1d3f1aff17 (2009-03-10)</subtitle>
    1.14 +  -->
    1.15 +  <subtitle>Compiled from $rev_id$</subtitle>
    1.16 +  <bookinfo>
    1.17 +    <edition>1</edition>
    1.18 +    <isbn>9780596800673</isbn>
    1.19 +    <authorgroup>
    1.20 +      <author>
    1.21 +        <firstname>Bryan</firstname>
    1.22 +        <surname>O'Sullivan</surname>
    1.23 +      </author>
    1.24 +    </authorgroup>
    1.25 +
    1.26 +    <editor>
    1.27 +      <firstname>Mike</firstname>
    1.28 +      <surname>Loukides</surname>
    1.29 +    </editor>
    1.30 +
    1.31 +    <copyright>
    1.32 +      <year>2006</year>
    1.33 +      <year>2007</year>
    1.34 +      <year>2008</year>
    1.35 +      <year>2009</year>
    1.36 +      <holder>Bryan O'Sullivan</holder>
    1.37 +    </copyright>
    1.38 +  </bookinfo>
    1.39 +
    1.40 +  <!-- BEGIN ch00 -->
    1.41 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    1.42 +
    1.43 +<preface id="chap:preface">
    1.44 +  <?dbhtml filename="preface.html"?>
    1.45 +  <title>Preface</title>
    1.46 +
    1.47 +  <sect1>
    1.48 +    <title>Un conte technique</title>
    1.49 +
    1.50 +    <para id="x_72e">Il y a quelques années, quand j'ai voulu expliqué
    1.51 +    pourquoi je pensais que le gestion de révision distribuée est importante,
    1.52 +    le domaine était encore si nouveau qu'il n'y avait presque aucune 
    1.53 +    littérature publiée pour servir de référence aux personnes intéressées.</para>
    1.54 +
    1.55 +    <para id="x_72f">Bien qu'à cette époque je passais beaucoup de temps
    1.56 +    à travailler sur les entrailles de Mercurial, je me suis mis à la 
    1.57 +    rédaction de ce livre parce qu'il me semblait la manière la plus efficace
    1.58 +    d'aider notre logiciel à atteindre un vaste auditoire, toujours avec 
    1.59 +    l'idée que la gestion de révision devrait être distribuée par nature. J'ai 
    1.60 +    publié ce libre en ligne sous une licence libre pour la même raison : pour 
    1.61 +    diffuser la parole auprès du monde.</para>
    1.62 +
    1.63 +    <para id="x_730">Il y a un rythme familier à un bon livre sur un logiciel 
    1.64 +    qui ressemble de près au fait de conter une histoire : Pourquoi ceci est ? 
    1.65 +    Pourquoi ceci est important ? Comment peut il m'aider ? Comment m'en 
    1.66 +    servir ? Dans ce livre, j'essaye de répondre à toutes ces questions pour
    1.67 +    la gestion de révision distribuée en général, et pour Mercurial en 
    1.68 +    particulier.</para>
    1.69 +  </sect1>
    1.70 +    
    1.71 +  <sect1>
    1.72 +    <title>Merci de votre soutien à Mercurial</title>
    1.73 +
    1.74 +    <para id="x_731">En achetant une copie de ce livre, vous soutenez le
    1.75 +    développement et la liberté de Mercurial en particulier, et dans 
    1.76 +    l'Open Source, au logiciel libre en général. O'Reilly Media et 
    1.77 +    moi-même donnons les revenus issus des ventes de ce livre à la
    1.78 +    Software Freedom Conservancy (<ulink url="http://www.softwarefreedom.org/">http://www.softwarefreedom.org/</ulink>) 
    1.79 +      qui fournit un support juridique à Mercurial et à de 
    1.80 +      nombreux autres projets Open Source proéminents et de qualité.</para>
    1.81 +  </sect1>
    1.82 +
    1.83 +  <sect1>
    1.84 +    <title>Remerciements</title>
    1.85 +
    1.86 +    <para id="x_732">Ce livre n'aurait pas vu le jour sans les
    1.87 +    efforts de Matt Mackal, l'auteur et le chef du projet Mercurial.
    1.88 +    Il est assisté très efficacement par des centaines de contributeurs
    1.89 +    volontaires à travers le monde.</para>
    1.90 +
    1.91 +    <para id="x_733">Les enfants, Cian et Ruairi, ont toujours été prêt
    1.92 +    à m'aider à me reposer avec de merveilleux et impulsif jeux d'enfants. 
    1.93 +    Je tiens aussi à remercier mon ex-femme, Shannon, pour son soutien.
    1.94 +    </para>
    1.95 +
    1.96 +    <para id="x_734">Mes collègues et amis m'ont aidé et assisté de 
    1.97 +    de nombreuses manières. Cette liste de personne est nécessaire mais très
    1.98 +    incomplète : Stephen Hahn, Karyn Ritter, Bonnie Corwin, James Vasile,
    1.99 +    Matt Norwood, Eben Moglen, Bradley Kuhn, Robert Walsh, Jeremy
   1.100 +    Fitzhardinge, Rachel Chalmers.</para>
   1.101 +
   1.102 +    <para id="x_735">J'ai conçu ce livre de manière ouverte, en publiant
   1.103 +    des brouillons des chapitres du livre sur des site web, au fur et à 
   1.104 +    mesure que je les réalisais. Leurs lecteurs m'ont fait des retours 
   1.105 +    utilisant l'application web que j'avais développée. A la fin de sa
   1.106 +    conception, plus de 100 personnes m'avaient fait des commentaires, 
   1.107 +    un chiffre incroyable quand l'on considère que ce système de 
   1.108 +    commentaire n'a tourné que dans les deux derniers mois de la 
   1.109 +    rédaction du livre.</para>
   1.110 +
   1.111 +    <para id="x_736">J'aimerais particulièrement remercier les 
   1.112 +    personnes suivantes, dont les commentaires représentent plus
   1.113 +    d'un tiers de l'ensemble de ces derniers. Je voudrais les 
   1.114 +    remercier pour leur attention et effort à me faire des retours
   1.115 +    très détaillés.</para>
   1.116 +
   1.117 +    <para id="x_737">Martin Geisler, Damien Cassou, Alexey Bakhirkin, Till Plewe,
   1.118 +      Dan Himes, Paul Sargent, Gokberk Hamurcu, Matthijs van der
   1.119 +      Vleuten, Michael Chermside, John Mulligan, Jordi Fita, Jon
   1.120 +      Parise.</para>
   1.121 +
   1.122 +    <para id="x_738">Je souhaite aussi remercier l'aide des personnes
   1.123 +    qui ont découvert des erreurs et fournit des suggestions avisées
   1.124 +    à travers tout le livre.</para>
   1.125 +
   1.126 +    <para id="x_739">Jeremy W. Sherman, Brian Mearns, Vincent Furia, Iwan
   1.127 +      Luijks, Billy Edwards, Andreas Sliwka, Paweł Sołyga, Eric
   1.128 +      Hanchrow, Steve Nicolai, Michał Masłowski, Kevin Fitch, Johan
   1.129 +      Holmberg, Hal Wine, Volker Simonis, Thomas P Jakobsen, Ted
   1.130 +      Stresen-Reuter, Stephen Rasku, Raphael Das Gupta, Ned
   1.131 +      Batchelder, Lou Keeble, Li Linxiao, Kao Cardoso Félix, Joseph
   1.132 +      Wecker, Jon Prescot, Jon Maken, John Yeary, Jason Harris,
   1.133 +      Geoffrey Zheng, Fredrik Jonson, Ed Davies, David Zumbrunnen,
   1.134 +      David Mercer, David Cabana, Ben Karel, Alan Franzoni, Yousry
   1.135 +      Abdallah, Whitney Young, Vinay Sajip, Tom Towle, Tim Ottinger,
   1.136 +      Thomas Schraitle, Tero Saarni, Ted Mielczarek, Svetoslav
   1.137 +      Agafonkin, Shaun Rowland, Rocco Rutte, Polo-Francois Poli,
   1.138 +      Philip Jenvey, Petr Tesałék, Peter R. Annema, Paul Bonser,
   1.139 +      Olivier Scherler, Olivier Fournier, Nick Parker, Nick Fabry,
   1.140 +      Nicholas Guarracino, Mike Driscoll, Mike Coleman, Mietek Bák,
   1.141 +      Michael Maloney, László Nagy, Kent Johnson, Julio Nobrega, Jord
   1.142 +      Fita, Jonathan March, Jonas Nockert, Jim Tittsler, Jeduan
   1.143 +      Cornejo Legorreta, Jan Larres, James Murphy, Henri Wiechers,
   1.144 +      Hagen Möbius, Gábor Farkas, Fabien Engels, Evert Rol, Evan
   1.145 +      Willms, Eduardo Felipe Castegnaro, Dennis Decker Jensen, Deniz
   1.146 +      Dogan, David Smith, Daed Lee, Christine Slotty, Charles Merriam,
   1.147 +      Guillaume Catto, Brian Dorsey, Bob Nystrom, Benoit Boissinot,
   1.148 +      Avi Rosenschein, Andrew Watts, Andrew Donkin, Alexey Rodriguez,
   1.149 +      Ahmed Chaudhary.</para>
   1.150 +  </sect1>
   1.151 +
   1.152 +  <sect1>
   1.153 +    <title>Conventions utilisées dans ce livre</title>
   1.154 +
   1.155 +    <para id="x_73a">Les conventions typographiques suivantes sont utilisées dans ce livre :</para>
   1.156 +
   1.157 +    <variablelist>
   1.158 +      <varlistentry>
   1.159 +        <term>Italique</term>
   1.160 +
   1.161 +        <listitem>
   1.162 +          <para id="x_73b">Indique les termes nouveaux, les URLs, les
   1.163 +            adresses mail, les noms de fichiers et les extensions de
   1.164 +            fichier.</para>
   1.165 +        </listitem>
   1.166 +      </varlistentry>
   1.167 +
   1.168 +      <varlistentry>
   1.169 +        <term><literal moreinfo="none">Taille constante</literal></term>
   1.170 +
   1.171 +        <listitem>
   1.172 +          <para id="x_73c">Utilisé pour les extraits de code, comme 
   1.173 +          dans les paragraphes pour référer aux éléments du programme,
   1.174 +          tels que les variables ou les noms de fonctions, de bases
   1.175 +          de données, de types de données, de variables d'environnement,
   1.176 +          d'instructions, et de mots clés.</para>
   1.177 +        </listitem>
   1.178 +      </varlistentry>
   1.179 +
   1.180 +      <varlistentry>
   1.181 +        <term><userinput moreinfo="none">Taille constante avec gras</userinput></term>
   1.182 +
   1.183 +        <listitem>
   1.184 +          <para id="x_73d">Afficher les commandes ou autres textes qui
   1.185 +          devraient être saisis par l'utilisateur.</para>
   1.186 +        </listitem>
   1.187 +      </varlistentry>
   1.188 +
   1.189 +      <varlistentry>
   1.190 +        <term><replaceable>Constante avec italique</replaceable></term>
   1.191 +
   1.192 +        <listitem>
   1.193 +          <para id="x_73e">Affiche les textes qui devraient être remplacés 
   1.194 +          par une valeur définie par l'utilisateur ou des valeurs définies
   1.195 +          selon le contexte.</para>
   1.196 +        </listitem>
   1.197 +      </varlistentry>
   1.198 +    </variablelist>
   1.199 +
   1.200 +    <tip>
   1.201 +      <para id="x_73f">Cette icône indique une astuce, une suggestion ou 
   1.202 +      une note d'ordre général.</para>
   1.203 +    </tip>
   1.204 +
   1.205 +    <caution>
   1.206 +      <para id="x_740">Cette icône est un message d'alerte ou de prudence.</para>
   1.207 +    </caution>
   1.208 +  </sect1>
   1.209 +
   1.210 +  <sect1>
   1.211 +    <title>Utiliser les exemples de code</title>
   1.212 +
   1.213 +    <para id="x_741">Ce livre est ici pour vous aider dans votre
   1.214 +    travail. De manière générale, vous pouvez donc utiliser le code
   1.215 +    de ce livre dans vos programmes et votre documentation. Vous
   1.216 +    n'avez pas à nous contacter pour nous demander la permission
   1.217 +    de le faire, à moins que vous ne reproduisiez une partie significative
   1.218 +    du code. Par exemple, écrire un programme qui utilise plusieurs 
   1.219 +    extraits de code du livre ne demande aucune autorisation particulière.
   1.220 +    Vendre ou distribuer un CD-ROM provenant des livres O'Reilly demande
   1.221 +    à l'inverse une autorisation. Répondre à une question en citant ce 
   1.222 +    livre ou ses exemples de code ne demande aucune autorisation préalable.
   1.223 +    Intégrer une grande quantité des codes d'exemples de ce livre dans
   1.224 +    votre propre ouvrage demande une autorisation de notre part.</para>
   1.225 +
   1.226 +    <para id="x_742">Nous apprécions, sans l'exiger, que vous citiez 
   1.227 +    l'ouvrage dans vos écrits l'utilisant, en indiquant le titre, 
   1.228 +    l'auteur, l'éditeur et son ISBN. Par exemple: “<emphasis>Titre du 
   1.229 +    livre</emphasis> par Son Auteur. Copyright 2008 O’Reilly Media, Inc.,
   1.230 +    978-0-596-xxxx-x.”</para>
   1.231 +
   1.232 +    <para id="x_743">Si vous estimez que votre usage des exemples de code
   1.233 +    dépasse le cadre défini ci dessus, n'hésitez pas à nous contacter :
   1.234 +      <email>permissions@oreilly.com</email>.</para>
   1.235 +  </sect1>
   1.236 +
   1.237 +  <sect1>
   1.238 +    <title>Safari® Books Online</title>
   1.239 +
   1.240 +    <note role="safarienabled">
   1.241 +      <para id="x_744">Quand vous voyez l'icône de Safari® Books Online 
   1.242 +      sur la couverture d'un de vos livres techniques préférés, cela signifie
   1.243 +      que le livre est disponible, en ligne, à travers le O’Reilly Network Safari
   1.244 +        Bookshelf.</para>
   1.245 +    </note>
   1.246 +
   1.247 +    <para id="x_745">Safari offre une solution qui est meilleure que
   1.248 +    les e-books. C'est une bibliothèque virtuelle qui vous laisse
   1.249 +    aisément rechercher dans des milliers de livres, mais aussi 
   1.250 +    copier-coller leurs exemples, télécharger des chapitres, et 
   1.251 +    trouver des réponses rapides quand vous avez besoin d'une 
   1.252 +    information précise et à jour. Essayez le gratuitement :
   1.253 +    <ulink role="orm:hideurl:ital" url="http://my.safaribooksonline.com/?portal=oreilly">http://my.safaribooksonline.com</ulink>.</para>
   1.254 +  </sect1>
   1.255 +
   1.256 +  <sect1>
   1.257 +    <title>Comment nous contacter</title>
   1.258 +
   1.259 +    <para id="x_746">Merci d'adresser vos commentaires et vos questions
   1.260 +    sur ce livre à son éditeur:</para>
   1.261 +
   1.262 +    <simplelist type="vert">
   1.263 +      <member>O’Reilly Media, Inc.</member>
   1.264 +
   1.265 +      <member>1005 Gravenstein Highway North</member>
   1.266 +
   1.267 +      <member>Sebastopol, CA 95472</member>
   1.268 +
   1.269 +      <member>800-998-9938 (in the United States or Canada)</member>
   1.270 +
   1.271 +      <member>707-829-0515 (international or local)</member>
   1.272 +
   1.273 +      <member>707 829-0104 (fax)</member>
   1.274 +    </simplelist>
   1.275 +
   1.276 +    <para id="x_747">Nous avons une page web pour cet ouvrage, où nous
   1.277 +    publions des errata, des exemples, et encore d'autres informations
   1.278 +    additionnelles. Vous pouvez accéder à cette page par l'URL suivante:
   1.279 +    </para>
   1.280 +
   1.281 +    <simplelist type="vert">
   1.282 +      <member><ulink url="http://www.oreilly.com/catalog/&lt;catalog           page&gt;"/></member>
   1.283 +    </simplelist>
   1.284 +
   1.285 +    <remark>N'oubliez pas de mettre à jour l'attribut &lt;url&gt; aussi.</remark>
   1.286 +
   1.287 +    <para id="x_748">Pour commenter ou poser des questions techniques 
   1.288 +    sur cet ouvrage, envoyez un email à :</para>
   1.289 +
   1.290 +    <simplelist type="vert">
   1.291 +      <member><email>bookquestions@oreilly.com</email></member>
   1.292 +    </simplelist>
   1.293 +
   1.294 +    <para id="x_749">Pour plus d'informations sur nos livres, nos
   1.295 +    conférences, nos centres d'informations, et le réseau O’Reilly, 
   1.296 +    voyez notre site web :</para>
   1.297 +
   1.298 +    <simplelist type="vert">
   1.299 +      <member><ulink url="http://www.oreilly.com"/></member>
   1.300 +    </simplelist>
   1.301 +  </sect1>
   1.302 +</preface>
   1.303 +
   1.304 +<!--
   1.305 +local variables: 
   1.306 +sgml-parent-document: ("00book.xml" "book" "preface")
   1.307 +end:
   1.308 +-->
   1.309 +
   1.310 +  <!-- BEGIN ch01 -->
   1.311 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
   1.312 +
   1.313 +<chapter id="chap:intro">
   1.314 +  <?dbhtml filename="how-did-we-get-here.html"?>
   1.315 +  <title>Comment en est on arrivé là ?</title>
   1.316 +
   1.317 +<sect1>
   1.318 +<title>À propos de la gestion source</title>
   1.319 +
   1.320 +    <para id="x_6d">La gestion de sources est un processus permettant de gérer différentes
   1.321 +versions de la même information. Dans sa forme la plus simple, c'est
   1.322 +ce que tout le monde fait manuellement : quand vous modifiez
   1.323 +un fichier, vous le sauvegardez sous un nouveau nom contenant un numéro,
   1.324 +à chaque fois plus grand que celui de la version précédente.</para>
   1.325 +
   1.326 +    <para id="x_6e">Ce genre de gestion de version manuelle est cependant facilement sujette
   1.327 +aux erreurs, ainsi, depuis longtemps, des logiciels existent pour
   1.328 +résoudre cette problématique. Les premiers outils de gestion de sources
   1.329 +étaient destinés à aider un seul utilisateur, à automatiser la gestion
   1.330 +des versions d'un seul fichier. Dans les dernières décades, cette cible
   1.331 +s'est largement agrandie, ils gèrent désormais de multiples fichiers, et
   1.332 +aident un grand nombre de personnes à travailler ensemble. Les outils les
   1.333 +plus modernes n'ont aucune difficulté à gérer plusieurs milliers de
   1.334 +personnes travaillant ensemble sur des projets regroupant plusieurs
   1.335 +centaines de milliers de fichiers.</para>
   1.336 +
   1.337 +    <para id="x_6f">L'arrivée de la gestion de révision distribuée est
   1.338 +    relativement récente, et, pour le moment, ce nouveau domaine a grandi
   1.339 +    grâce à la volonté des gens d'explorer ces territoires encore inconnus.
   1.340 +    </para>
   1.341 +
   1.342 +    <para id="x_70">J'écris un livre sur la gestion de révision distribuée
   1.343 +    parce que je pense qu'il s'agit d'un sujet important qui mérite un guide
   1.344 +    du terrain. J'ai choisi d'écrire un livre sur Mercurial car il est
   1.345 +    l'outil le plus facile pour découvrir ce nouveau domaine, tout en étant
   1.346 +    un outil efficace qui répond aux demandes d'environnements réels et
   1.347 +    difficiles, là où d'autres outils de gestions de versions s'effondrent.</para>
   1.348 +
   1.349 +    <sect2>
   1.350 +      <title>Pourquoi utiliser un gestionnaire de source ?</title>
   1.351 +
   1.352 +      <para id="x_71">Il y a de nombreuses raisons pour que vous ou votre équipe souhaitiez
   1.353 +utiliser un outil automatisant la gestion de version pour votre projet.</para>
   1.354 +
   1.355 +      <itemizedlist>
   1.356 +	<listitem><para id="x_72">L'outil se chargera de suivre l'évolution de votre projet, sans
   1.357 +que vous ayez à le faire. Pour chaque modification, vous aurez à votre
   1.358 +disposition un journal indiquant <emphasis>qui</emphasis> a fait quoi, <emphasis>pourquoi</emphasis>
   1.359 +il l'a fait, <emphasis>quand</emphasis> il l'a fait, et
   1.360 +<emphasis>ce</emphasis> qu'il a modifié.</para>
   1.361 +</listitem>
   1.362 +<listitem><para id="x_73">Quand vous travaillez avec d'autres personnes, les logiciels de
   1.363 +gestion de source facilitent le travail collaboratif. Par exemple, quand
   1.364 +plusieurs personnes font, plus ou moins simultanément, des modifications
   1.365 +incompatibles, le logiciel vous aidera à identifier et à résoudre les conflits.</para>
   1.366 +</listitem>
   1.367 +<listitem><para id="x_74">L'outil vous aidera à réparer vos erreurs. Si vous effectuez un changement
   1.368 +qui se révèle être une erreur, vous pourrez revenir à une version
   1.369 +antérieure d'un fichier ou même d'un ensemble de fichiers. En fait, un outil de
   1.370 +gestion de source <emphasis>vraiment</emphasis> efficace vous permettra d'identifier à quel
   1.371 +moment le problème est apparu (voir la section <xref linkend="sec:undo:bisect"/> pour plus
   1.372 +de détails).</para>
   1.373 +</listitem>
   1.374 +<listitem><para id="x_75">L'outil vous permettra aussi de travailler sur plusieurs versions différentes
   1.375 +de votre projet et de gérer l'écart entre chacune.</para>
   1.376 +</listitem></itemizedlist>
   1.377 +<para id="x_76">La plupart de ces raisons ont autant d'importances —du
   1.378 +  moins en théorie— que vous travailliez sur un projet pour vous, ou
   1.379 +  avec une centaine d'autres personnes.
   1.380 +</para>
   1.381 +
   1.382 +<para id="x_77">Une question fondamentale à propos des outils de gestion de
   1.383 +  source, qu'il s'agisse du projet d'une personne ou d'une grande équipe, est
   1.384 +  quels sont ses <emphasis>avantages</emphasis> par rapport à ses
   1.385 +  <emphasis>coûts</emphasis>. Un outil qui est difficile à utiliser ou à
   1.386 +  comprendre exigera un lourd effort d'adaptation.
   1.387 +</para>
   1.388 +
   1.389 +<para id="x_78">)Un projet de cinq milles personnes s'effondrera très
   1.390 +  certainement de lui même sans aucun processus et outil de gestion de
   1.391 +  source. Dans ce cas, le coût d'utilisation d'un logiciel de gestion de
   1.392 +  source est dérisoire puisque <emphasis>sans</emphasis>, l'échec est presque
   1.393 +  garanti.
   1.394 +</para>
   1.395 +
   1.396 +<para id="x_79">D'un autre coté, un <quote>rapide hack</quote> d'une personne
   1.397 +  peut sembler un contexte bien pauvre pour utiliser un outil de gestion de
   1.398 +  source, car, bien évidement le coût d'utilisation dépasse le coût total du
   1.399 +  projet. N'est ce pas ?
   1.400 +</para>
   1.401 +
   1.402 +      <para id="x_7a">Mercurial supporte ces <emphasis>deux</emphasis>
   1.403 +        échelles de travail. Vous pouvez apprendre les bases en quelques
   1.404 +        minutes seulement, et, grâce à sa performance, vous pouvez l'utiliser
   1.405 +        avec facilité sur le plus petit des projets. Cette simplicité
   1.406 +        signifie que vous n'avez pas de concept obscurs ou de séquence de
   1.407 +        commandes défiant l'imagination, sans aucune corrélation avec
   1.408 +        <emphasis>ce que vous êtes entrain de faire</emphasis>. En même
   1.409 +        temps, ces mêmes performances et sa nature
   1.410 +        <quote>peer-to-peer</quote> vous permettent d'adapter, sans
   1.411 +        difficulté, son utilisation à de très grands projets.
   1.412 +</para>
   1.413 +
   1.414 +      <para id="x_7b">Aucun outil de gestion de source ne peut sauver un
   1.415 +        projet mal mené, mais un bon outil peut rendre beaucoup plus fluide
   1.416 +        votre travail.
   1.417 +</para>
   1.418 +
   1.419 +    </sect2>
   1.420 +
   1.421 +    <sect2>
   1.422 +      <title>Les multiples noms de la gestion de source</title>
   1.423 +
   1.424 +      <para id="x_7c">La gestion de source
   1.425 +        <!-- TODO:<footnote><J'ai utilisé systématiquement le terme
   1.426 +            <quote>gestion de source</quote> à travers tout l'ouvrage. Ce
   1.427 +            n'est pas forcement la meilleure traduction, et ceci peut rendre
   1.428 +            la lecture un peu lourde, mais je pense que le document y gagne
   1.429 +            en clarté et en précision. -->
   1.430 +        est un domaine tellement large qu'il n'existe pas qu'un seul nom ou
   1.431 +        acronyme pour le désigner. Voici quelques noms ou acronymes que vous
   1.432 +        rencontrerez le plus souvent.
   1.433 +        <!-- TODO:<footnote> J'ai conservé la liste des noms en anglais pour
   1.434 +          des raisons de commodité (ils sont plus <quote>googelable</quote>).
   1.435 +          En outre, j'ai opté  pour conserver l'ensemble des opérations de
   1.436 +          Mercurial (\textit{commit},\textit{push}, \textit{pull},...) en
   1.437 +          anglais, là aussi pour faciliter la lecture d'autres documents en
   1.438 +          anglais, ainsi que l'utilisation de Mercurial. -->
   1.439 +</para>
   1.440 +
   1.441 +<para>:
   1.442 +</para>
   1.443 +
   1.444 +      <itemizedlist>
   1.445 +	<listitem><para id="x_7d">Revision control (RCS)</para></listitem>
   1.446 +	<listitem><para id="x_7e">Software configuration management (SCM), ou
   1.447 +	    configuration management</para></listitem>
   1.448 +	<listitem><para id="x_7f">Source code management</para></listitem>
   1.449 +	<listitem><para id="x_80">Source code control, ou source control</para></listitem>
   1.450 +	<listitem><para id="x_81">Version control (VCS)</para></listitem></itemizedlist>
   1.451 +
   1.452 + <para id="x_82">Certaines personnes prétendent que ces termes ont en fait
   1.453 +   des sens différents mais en pratique ils se recouvrent tellement qu'il n'y
   1.454 +   a pas réellement de manière pertinente de les distinguer. </para>
   1.455 +
   1.456 +    </sect2>
   1.457 +  </sect1>
   1.458 +
   1.459 +  <sect1>
   1.460 +
   1.461 +<title>A propos des exemples dans ce livre</title>
   1.462 +
   1.463 +    <para id="x_84">Ce livre prend une approche non usuel pour les exemples
   1.464 +      de code. Tous les exemples sont en <quote>live</quote> — Chacun
   1.465 +      est actuellement le résultat d'un script shell qui exécute les
   1.466 +      commandes Mercurial que vous voyez. A chaque fois qu'une image du livre
   1.467 +      est construite à partir des sources, tous les scripts d'exemple sont
   1.468 +      lancés automatiquement, et leurs résultats effectifs sont comparés aux
   1.469 +      résultats attendus.</para>
   1.470 +
   1.471 +    <para id="x_85">L'avantage de dette approche est que les exemples sont
   1.472 +      toujours précis ; ils décrivent <emphasis>exactement</emphasis> la
   1.473 +      conduite de la version de Mercurial qui est mentionnée en entête du
   1.474 +      livre. Si je met à jour la version de Mercurial que je suis en train de
   1.475 +      documenter, et que la sortie de certaines commandes change, la
   1.476 +      construction du livre échoue.</para>
   1.477 +
   1.478 +    <para id="x_86">
   1.479 +      Il existe un petit désavantage à cette approche qui est que les dates et
   1.480 +      heures que vous verrez dans les exemples tendent à être
   1.481 +      <quote>écrasés</quote> ensemble, dans le sens où elles ne sont pas
   1.482 +      celles qu'elles auraient été si un humain avait tapé les commandes. En
   1.483 +      effet, humain ne peut pas taper plus d'une commande toutes les quelques
   1.484 +      secondes, avec le temps qui s'écoule, mes scripts d'exemples exécutent
   1.485 +      plusieurs commandes en une seconde.
   1.486 +    </para>
   1.487 +
   1.488 +    <para id="x_87">Une circonstance de ceci est que plusieurs commits
   1.489 +      consécutifs dans un exemple peuvent apparaître comme ayant eu lieu
   1.490 +      durant la même seconde.
   1.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"/>
   1.492 +    </para>
   1.493 +
   1.494 +    <para id="x_88">Donc, lorsque vous lisez ces exemples, ne prêtez pas trop
   1.495 +      d'importance aux dates et heures que vous voyez dans la sortie des
   1.496 +      commandes. Cependant, <emphasis>soyez</emphasis> confiants que le
   1.497 +      comportement que vous voyez est consistent et reproductible 
   1.498 +    </para>
   1.499 +
   1.500 +  </sect1>
   1.501 +
   1.502 +<!-- The next section has disapper from this part of the book. it may be splaced somewhere else... t-->
   1.503 +
   1.504 +  <sect1>
   1.505 +    <title>Tendances de la gestion de source</title>
   1.506 +
   1.507 +    <para id="x_89">Il y a eu une tendance évidente dans le développement et
   1.508 +      l'utilisation d'outils de gestion de source depuis les quatre dernières
   1.509 +      décades, au fur et à mesure que les utilisateurs se sont habitués à
   1.510 +      leur outils et se sont sentis contraints par leurs limitations.
   1.511 +    </para>
   1.512 +
   1.513 +    <para id="x_8a">La première génération commença simplement par gérer un
   1.514 +      fichier unique sur un ordinateur individuel. Cependant, même si ces
   1.515 +      outils présentaient une grande avancée par rapport à la gestion
   1.516 +      manuelle des versions, leur modèle de verrouillage et leur utilisation
   1.517 +      limitée à un seul ordinateur rendaient leur utilisation possible
   1.518 +      uniquement dans une très petite équipe.
   1.519 +    </para>
   1.520 +
   1.521 +    <para id="x_8b">La seconde génération a assoupli ces contraintes en
   1.522 +      adoptant une architecture réseau et centralisée, permettant de gérer
   1.523 +      plusieurs projets entiers en même temps. Alors que les projets
   1.524 +      grandirent en taille, ils rencontrèrent de nouveaux problèmes. Avec les
   1.525 +      clients discutant régulièrement avec le serveurs, la montée en charge
   1.526 +      devint un réel problème sur les gros projets. Une connexion réseau peu
   1.527 +      fiable pouvait complètement empêcher les utilisateurs distants de
   1.528 +      dialoguer avec le serveur. Alors que les projets <emphasis remap="it">Open Source</emphasis> commencèrent à mettre en place des
   1.529 +      accès en lecture seule disponible anonymement, les utilisateurs sans
   1.530 +      les privilèges de <quote>commit</quote> réalisèrent qu'ils ne pouvaient
   1.531 +      pas utiliser les outils pour collaborer naturellement avec le projet,
   1.532 +      comme ils ne pouvaient pas non plus enregistrer leurs modifications.
   1.533 +    </para>
   1.534 +
   1.535 +    <para id="x_8c">La génération actuelle des outils de gestion de source
   1.536 +      est <quote>peer-to-peer</quote> par nature. Tous ces systèmes ont
   1.537 +      abandonné la dépendance à un serveur central, et ont permis à leur
   1.538 +      utilisateur de distribuer les données de leur gestion de source à qui
   1.539 +      en a besoin. La collaboration à travers Internet a transformé la
   1.540 +      contrainte technologique en une simple question de choix et de
   1.541 +      consensus. Les outils modernes peuvent maintenant fonctionner en mode
   1.542 +      déconnecté sans limite et de manière autonome, la connexion au réseau
   1.543 +      n'étant nécessaire que pour synchroniser les modifications avec les
   1.544 +      autres dépôts.
   1.545 +    </para>
   1.546 +  </sect1>
   1.547 +    
   1.548 +  <sect1>
   1.549 +    <title>Quelques avantages des gestionnaires de source distribués</title>
   1.550 +      
   1.551 +    <para id="x_8d">Même si les gestionnaire de source distribués sont depuis
   1.552 +      plusieurs années assez robustes et aussi utilisables que leurs
   1.553 +      prédécesseurs, les utilisateurs d'autres outils n'y ont pas encore été
   1.554 +      sensibilisés. Les gestionnaires de source distribués se distinguent
   1.555 +      particulièrement de leurs équivalents centralisés de nombreuses
   1.556 +      manières.
   1.557 +    </para>
   1.558 +
   1.559 +    <para id="x_8e">Pour un développeur individuel, ils restent beaucoup plus
   1.560 +      rapides que les outils centralisés. Cela pour une raison simple : un
   1.561 +      outil centralisé doit toujours dialoguer à travers le réseau pour la
   1.562 +      plupart des opérations, car presque toutes les métadonnées sont
   1.563 +      stockées sur la seule copie du serveur central. Un outil distribué
   1.564 +      stocke toute ses métadonnées localement. À tâche égale, effectuer un
   1.565 +      échange avec le réseau ajoute un délai aux outils centralisés. Ne
   1.566 +      sous-estimez pas la valeur d'un outil rapide : vous allez passer
   1.567 +      beaucoup de temps à interagir avec un logiciel de gestion de source.
   1.568 +    </para>
   1.569 +
   1.570 +    <para id="x_8f">Les outils distribués sont complètement indépendants des
   1.571 +      aléas de votre serveur, d'autant plus qu'ils répliquent les métadonnées
   1.572 +      à beaucoup d'endroits. Si votre serveur central prend feu, vous avez
   1.573 +      intérêt à ce que les médias de sauvegardes soient fiables, et que votre
   1.574 +      dernier <quote>backup</quote> soit récent et fonctionne sans problème.
   1.575 +      Avec un outil distribué, vous avez autant de <quote>backup</quote> que
   1.576 +      de contributeurs.
   1.577 +    </para>
   1.578 +
   1.579 +    <para id="x_90">En outre, la fiabilité de votre réseau affectera beaucoup
   1.580 +      moins les outils distribués. Vous ne pouvez même pas utiliser un outil
   1.581 +      centralisé sans connexion réseau, à l'exception de quelques commandes,
   1.582 +      très limitées. Avec un outil distribué, si votre connexion réseau tombe
   1.583 +      pendant que vous travaillez, vous pouvez ne même pas vous en rendre
   1.584 +      compte. La seule chose que vous ne serez pas capable de faire sera de
   1.585 +      communiquer avec des dépôts distants, opération somme toute assez rare
   1.586 +      en comparaison aux opérations locales. Si vous avez une équipe de
   1.587 +      collaborateurs très dispersée ceci peut être significatif.
   1.588 +    </para>
   1.589 +
   1.590 +    <sect2>
   1.591 +      <title>Avantages pour les projets Open Source</title>
   1.592 +
   1.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
   1.594 +        à toucher à son code, et que le projet utilise un gestionnaire de
   1.595 +        source distribué, vous êtes immédiatement un "pair" avec les
   1.596 +        personnes formant le <quote>cœur</quote> du projet. S'ils publient
   1.597 +        leurs dépôts, vous pouvez immédiatement copier leurs historiques de
   1.598 +        projet, faire des modifications, enregistrer votre travail en
   1.599 +        utilisant les mêmes outils qu'eux. Par comparaison avec un outil
   1.600 +        centralisé, vous devez utiliser un logiciel en mode <quote>lecture
   1.601 +          seule</quote> à moins que quelqu'un ne vous donne les privilèges de
   1.602 +        <quote>commit</quote> sur le serveur central. Avant ça, vous ne serez
   1.603 +        pas capable d'enregistrer vos modifications, et vos propres
   1.604 +        modifications risqueront de se corrompre chaque fois que vous
   1.605 +        essayerez de mettre à jour à votre espace de travail avec le serveur
   1.606 +        central.
   1.607 +      </para>
   1.608 +
   1.609 +    <sect3>
   1.610 +      <title>Le non-problème du "fork"</title>
   1.611 +      
   1.612 +      <para id="x_92">Il a été souvent suggéré que les gestionnaires de
   1.613 +        source distribués posent un risque pour les projets <emphasis remap="it">Open Source</emphasis> car ils facilitent grandement la
   1.614 +        création de <quote>fork</quote>.
   1.615 +        <!--footnote{NdT:Création d'une <ulink url="version alternative du
   1.616 +          logiciel">version alternative du
   1.617 +          logiciel</ulink>{http://fr.wikipedia.org/wiki/Fork#Embranchement_d.27un_projet_informatique}
   1.618 +        -->
   1.619 +        Un <quote>fork</quote> apparait quand il y des divergences d'opinion
   1.620 +        ou d'attitude au sein d'un groupe de développeurs qui aboutissent à
   1.621 +        la décision de ne plus travailler ensemble. Chaque parti s'empare
   1.622 +        d'une copie plus ou moins complète du code source du projet et
   1.623 +        continue dans sa propre direction.
   1.624 +      </para>
   1.625 +
   1.626 +
   1.627 +      <para id="x_93">Parfois ces différents partis décident de se
   1.628 +        réconcilier. Avec un serveur central, l'aspect
   1.629 +        <emphasis>technique</emphasis> de cette réconciliation est un
   1.630 +        processus douloureux, et essentiellement manuel. Vous devez décider
   1.631 +        quelle modification est <quote>la gagnante</quote>, et replacer, par
   1.632 +        un moyen ou un autre, les modifications de l'autre équipe dans
   1.633 +        l'arborescence du projet. Ceci implique généralement la perte d'une
   1.634 +        partie de l'historique d'un des partis, ou même des deux.
   1.635 +      </para>
   1.636 +    
   1.637 +      <para id="x_94">Ce que les outils distribués permettent à ce sujet est
   1.638 +        probablement la <emphasis>meilleure</emphasis> façon de développer un
   1.639 +        projet. Chaque modification que vous effectuez est potentiellement un
   1.640 +        <quote>fork</quote>. La grande force de cette approche est que les
   1.641 +        gestionnaires de source distribués doivent être vraiment très
   1.642 +        efficaces pour <emphasis>fusionner (merge)</emphasis>
   1.643 +        <!-- TODO footnote{NdT:j'ai choisi de traduire ici <emphasis
   1.644 +          remap="it">merging</emphasis> par <quote>fusionner</quote> pour des
   1.645 +        raisons de clarté} -->
   1.646 +        des <quote>forks</quote>, car les <quote>forks</quote>, dans ce
   1.647 +        contexte, arrivent tout le temps.
   1.648 +      </para>
   1.649 +      
   1.650 +      <para id="x_95">Si chaque altération que n'importe qui effectue, à tout
   1.651 +        moment, est vue comme un <quote>fork</quote> à fusionner, alors ce
   1.652 +        que le monde de l'<emphasis remap="it">Open Source</emphasis> voit
   1.653 +        comme un <quote>fork</quote> devient <emphasis>uniquement</emphasis>
   1.654 +        une problématique sociale. En fait, les outils de gestions de source
   1.655 +        distribués <emphasis>réduisent</emphasis> les chances de
   1.656 +        <quote>fork</quote> :
   1.657 +      </para>
   1.658 +        
   1.659 +      <itemizedlist>
   1.660 +        <listitem>
   1.661 +        <para>Ils éliminent la distinction sociale qu'imposent les outils
   1.662 +          centralisés entre les membres du projets (ceux qui ont accès au
   1.663 +          <quote>commit</quote>) et ceux de l'extérieur (ce qui ne l'ont
   1.664 +          pas).
   1.665 +        </para>
   1.666 +        <para>Ils rendent plus facile la réconciliation après un
   1.667 +          <quote>fork</quote> social, car tout ce qu'elle implique est une
   1.668 +          simple fusion.
   1.669 +        </para>
   1.670 +        </listitem>
   1.671 +      </itemizedlist>
   1.672 +
   1.673 +      <para id="x_98">Certaines personnes font de la résistance envers les
   1.674 +        gestionnaires de source distribués parce qu'ils veulent garder un
   1.675 +        contrôle ferme sur leur projet, et ils pensent que les outils
   1.676 +        centralisés leur fournissent ce contrôle. Néanmoins, si c'est votre
   1.677 +        cas, sachez que si vous publiez votre dépôt CVS ou Subversion de
   1.678 +        manière publique, il existe une quantité d'outils disponibles pour
   1.679 +        récupérer entièrement votre projet et son historique (quoique
   1.680 +        lentement) et le récréer ailleurs, sans votre contrôle. En fait,
   1.681 +        votre contrôle sur votre projet est illusoire, vous ne faites
   1.682 +        qu'interdire à vos collaborateurs de travailler de manière fluide, en
   1.683 +        disposant d'un miroir ou d'un <quote>fork</quote> de votre
   1.684 +        historique.
   1.685 +      </para>
   1.686 +
   1.687 +    </sect3>
   1.688 +    </sect2>
   1.689 +    <sect2>
   1.690 +      <title>Avantages pour les projets commerciaux</title>
   1.691 +
   1.692 +      <para id="x_99">Beaucoup de projets commerciaux sont réalisés par des
   1.693 +        équipes éparpillées à travers le globe. Les contributeurs qui sont
   1.694 +        loin du serveur central devront subir des commandes lentes et même
   1.695 +        parfois peu fiables. Les solutions propriétaires de gestion de source
   1.696 +        tentent de palier ce problème avec des réplications de sites distants
   1.697 +        qui sont à la fois coûteuses à mettre en place et lourdes à
   1.698 +        administrer. Un système distribué ne souffre pas de ce genre de
   1.699 +        problèmes. En outre, il est très aisé de mettre en place plusieurs
   1.700 +        serveurs de références, disons un par site, de manière à ce qu'il n'y
   1.701 +        ait pas de communication redondante entre les dépôts, sur une
   1.702 +        connexion longue distance souvent onéreuse.
   1.703 +      </para>
   1.704 +
   1.705 +      <para id="x_9a">Les systèmes de gestion de source supportent
   1.706 +        généralement assez mal la monté en charge. Il n'est pas rare pour un
   1.707 +        gestionnaire de source centralisé pourtant onéreux de s'effondrer
   1.708 +        sous la charge combinée d'une douzaine d'utilisateurs concurrents
   1.709 +        seulement. Une fois encore, la réponse à cette problématique est
   1.710 +        généralement encore la mise en place d'un ensemble complexe de
   1.711 +        serveurs synchronisés par un mécanisme de réplication. Dans le cas
   1.712 +        d'un gestionnaire de source distribué, la charge du serveur central
   1.713 +        — si vous avez un— est plusieurs fois inférieure (car
   1.714 +        toutes les données sont déjà répliquées ailleurs), un simple serveur,
   1.715 +        pas très cher, peut gérer les besoins d'une plus grande équipe, et la
   1.716 +        réplication pour balancer la charge devient le travail d'un simple
   1.717 +        script.
   1.718 +      </para>
   1.719 +
   1.720 +      <para id="x_9b">Si vous avez des employés sur le terrain, en train de
   1.721 +        chercher à résoudre un souci sur le site d'un client, ils
   1.722 +        bénéficieront aussi d'un gestionnaire de source distribué. Cet outil
   1.723 +        leur permettra de générer des versions personnalisées, d'essayer
   1.724 +        différentes solutions, en les isolant aisément les unes des autres,
   1.725 +        et de rechercher efficacement à travers l'historique des sources, la
   1.726 +        cause des bugs ou des régressions, tout ceci sans avoir besoin de la
   1.727 +        moindre connexion au réseau de votre compagnie.
   1.728 +      </para>
   1.729 +
   1.730 +    </sect2>
   1.731 +    </sect1>
   1.732 +    <sect1>
   1.733 +      <title>Pourquoi choisir Mercurial?</title>
   1.734 +
   1.735 +      <para id="x_9c">Mercurial a plusieurs caractéristiques qui en font un
   1.736 +        choix particulièrement pertinent pour la gestion de source :
   1.737 +      </para>
   1.738 +    <itemizedlist>
   1.739 +      <listitem><para id="x_9d">Il est simple à apprendre et à utiliser.</para></listitem>
   1.740 +      <listitem><para id="x_9e">Il est léger.</para></listitem>
   1.741 +      <listitem><para id="x_9f">Il s'adapte très bien à la charge.</para></listitem>
   1.742 +      <listitem><para id="x_a0">Il se personnalise facilement.</para></listitem>
   1.743 +    </itemizedlist>
   1.744 +
   1.745 +    <para id="x_a1">Si vous êtes déjà familier d'un outil de gestion de
   1.746 +      source, vous serez capable de l'utiliser en moins de 5 minutes. Sinon,
   1.747 +      ça ne sera pas beaucoup plus long. Les commandes utilisées par
   1.748 +      Mercurial, comme ses fonctionnalités, sont généralement uniformes et
   1.749 +      cohérentes, et vous pouvez ainsi garder en tête simplement quelques
   1.750 +      règles générales, plutôt qu'un lot complexe d'exceptions.
   1.751 +    </para>
   1.752 +
   1.753 +    <para id="x_a2">Sur un petit projet, vous pouvez commencer à travailler
   1.754 +      avec Mercurial en quelques instants. Ajouter des modifications ou des
   1.755 +      branches, transférer ces modifications (localement ou via le réseau),
   1.756 +      et les opérations d'historique ou de statut sont aussi très rapides.
   1.757 +      Mercurial reste hors de votre chemin grâce à sa simplicité
   1.758 +      d'utilisation et sa rapidité d'exécution.
   1.759 +    </para>
   1.760 +
   1.761 +    <para id="x_a3">L'utilité de Mercurial ne se limite pas à de petits
   1.762 +      projets: il est aussi utilisé par des projets ayant des centaines ou
   1.763 +      même des milliers de contributeurs, avec plusieurs dizaines de milliers
   1.764 +      de fichiers, et des centaines de méga octets de code source.
   1.765 +    </para>
   1.766 +
   1.767 +    <para id="x_a4">Si les fonctionnalités au cœur de Mercurial ne sont pas
   1.768 +      suffisantes pour vous, il est très aisé d'en construire d'autres.
   1.769 +      Mercurial est adapté à l'utilisation de scripts, et son implémentation
   1.770 +      interne en Python, propre et claire, rend encore plus facile l'ajout de
   1.771 +      fonctionnalités sous forme d'extensions. Il en existe déjà un certain
   1.772 +      nombre de très populaires et très utiles, dont le périmètre va de la
   1.773 +      recherche de bugs à l'amélioration des performances.
   1.774 +    </para>
   1.775 +
   1.776 +  </sect1>
   1.777 +  <sect1>
   1.778 +    <title>Mercurial comparé aux autres outils</title>
   1.779 +
   1.780 +    <para id="x_a5">Avant que vous n'alliez plus loin, comprenez bien que
   1.781 +      cette section reflète mes propres expériences, et elle est donc (j'ose
   1.782 +      le dire) peu objective. Néanmoins, j'ai utilisé les outils de gestion
   1.783 +      de source listés ci dessous, dans la plupart des cas, pendant plusieurs
   1.784 +      années.
   1.785 +    </para>
   1.786 +
   1.787 +    <sect2>
   1.788 +      <title>Subversion</title>
   1.789 +
   1.790 +      <para id="x_a6">Subversion est un des outils de gestion de source les
   1.791 +        plus populaire, il fût développé pour remplacer CVS. Il a une
   1.792 +        architecture client/server centralisée.
   1.793 +      </para>
   1.794 +
   1.795 +      <para id="x_a7">Subversion et Mercurial ont des noms de commandes très
   1.796 +        similaires pour les mêmes opérations, ainsi si vous êtes familier
   1.797 +        avec l'un, c'est facile d'apprendre l'autre. Ces deux outils sont
   1.798 +        portables sur les systèmes d'exploitation les plus populaires.
   1.799 +      </para>
   1.800 +
   1.801 +      <para id="x_a8">Avant la version 1.5, Subversion n'offrait aucune forme
   1.802 +        de support pour les fusions. Lors de l'écriture de ce livre, ses
   1.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">
   1.804 +          complexes et buguées</ulink>.
   1.805 +      </para>
   1.806 +
   1.807 +      <para id="x_a9">Mercurial dispose d'un avantage substantiel en terme de
   1.808 +        performance par rapport à Subversion sur la plupart des opérations
   1.809 +        que j'ai pu tester. J'ai mesuré une différence de performance allant
   1.810 +        de deux à six fois plus rapide avec le système de stockage de fichier
   1.811 +        local de Subversion 1.4.3 (<emphasis>ra_local</emphasis>), qui est la
   1.812 +        méthode d'accès la plus rapide disponible. Dans un déploiement plus
   1.813 +        réaliste, impliquant un stockage réseau, Subversion serait encore
   1.814 +        plus désavantagé. Parce que la plupart des commandes Subversion
   1.815 +        doivent communiquer avec le serveur et que Subversion n'a pas de
   1.816 +        mécanisme de réplication, la capacité du serveur et la bande passante
   1.817 +        sont devenues des goulots d'étranglement pour les projets de taille
   1.818 +        moyenne ou grande.
   1.819 +      </para>
   1.820 +
   1.821 +      <para id="x_aa">En outre, Subversion implique une surcharge
   1.822 +        substantielle dans le stockage local de certaines données, pour
   1.823 +        éviter des transactions avec le serveur, pour certaines opérations
   1.824 +        communes, telles que la recherche des fichiers modifiés
   1.825 +        (<literal moreinfo="none">status</literal>) et l'affichage des modifications par
   1.826 +        rapport à la révision courante (<literal moreinfo="none">diff</literal>). En
   1.827 +        conséquence, un répertoire de travail Subversion a souvent la même
   1.828 +        taille, ou est plus grand, qu'un dépôt Mercurial et son espace de
   1.829 +        travail, et ceci bien que le dépôt Mercurial contienne l'intégralité
   1.830 +        de l'historique.
   1.831 +      </para>
   1.832 +
   1.833 +      <para id="x_ab">Subversion est largement supporté par les outils
   1.834 +        tierces. Mercurial est actuellement encore en retrait de ce point de
   1.835 +        vue. L'écart se réduit néanmoins, en effet, certains des outils
   1.836 +        graphiques sont maintenant supérieurs à leurs équivalents Subversion.
   1.837 +        Comme Mercurial, Subversion dispose d'un excellent manuel
   1.838 +        utilisateur.
   1.839 +      </para>
   1.840 +
   1.841 +      <para id="x_ac">Parce que Subversion ne stocke pas l'historique chez
   1.842 +        ses clients, il est parfaitement adapté à la gestion de projets qui
   1.843 +        doivent suivre un ensemble de larges fichiers binaires et opaques. Si
   1.844 +        vous suivez une cinquantaine de versions d'un fichier incompressible
   1.845 +        de 10MB, l'occupation disque coté client d'un projet sous Subversion
   1.846 +        restera à peu près constante. A l'inverse, l'occupation disque du
   1.847 +        même projet sous n'importe lequel des gestionnaires de source
   1.848 +        distribués grandira rapidement, proportionnellement aux nombres de
   1.849 +        versions, car les différences entre chaque révisions seront très
   1.850 +        grandes.
   1.851 +      </para>
   1.852 +
   1.853 +      <para id="x_ad">En outre, c'est souvent difficile ou, généralement,
   1.854 +        impossible de fusionner des différences dans un fichier binaire. La
   1.855 +        capacité de Subversion de verrouiller des fichiers, pour permettre à
   1.856 +        l'utilisateur d'être le seul à le mettre à jour
   1.857 +        (<quote>commit</quote>) temporairement, est un avantage significatif
   1.858 +        dans un projet doté de beaucoup de fichiers binaires.
   1.859 +      </para>
   1.860 +
   1.861 +      <para id="x_ae">Mercurial peut importer l'historique depuis un dépôt
   1.862 +        Subversion. Il peut aussi exporter l'ensemble des révisions d'un
   1.863 +        projet vers un dépôt Subversion. Ceci rend très facile de
   1.864 +        <quote>prendre la température</quote> et d'utiliser Mercurial et
   1.865 +        Subversion en parallèle, avant de décider de migrer vers Mercurial.
   1.866 +        La conversion de l'historique est incrémentale, donc vous pouvez
   1.867 +        effectuer une conversion initiale, puis de petites additions par la
   1.868 +        suite pour ajouter les nouvelle modifications.
   1.869 +      </para>
   1.870 +
   1.871 +
   1.872 +    </sect2>
   1.873 +    <sect2>
   1.874 +      <title>Git</title>
   1.875 +
   1.876 +      <para id="x_af">Git est un outil de gestion de source distribué qui fût
   1.877 +        développé pour gérer le code source de noyau de Linux. Comme
   1.878 +        Mercurial, sa conception initiale a été inspirée par Monotone.
   1.879 +      </para>
   1.880 +
   1.881 +      <para id="x_b0">Git dispose d'un ensemble conséquent de commandes, avec
   1.882 +        plus de 139 commandes individuelles pour la version 1.5.0. Il a aussi
   1.883 +        la réputation d'être difficile à apprendre. Comparé à Git, le point
   1.884 +        fort de Mercurial est clairement sa simplicité.
   1.885 +      </para>
   1.886 +
   1.887 +      <para id="x_b1">En terme de performance, Git est extrêmement rapide.
   1.888 +        Dans la plupart des cas, il est plus rapide que Mercurial, tout du
   1.889 +        moins sur Linux, alors que Mercurial peut être plus performant sur
   1.890 +        d'autres opérations. Néanmoins, sur Windows, les performances et le
   1.891 +        niveau de support général fourni par Git, au moment de l'écriture de
   1.892 +        cet ouvrage, est bien derrière celui de Mercurial.
   1.893 +      </para>
   1.894 +
   1.895 +      <para id="x_b2">Alors que le dépôt Mercurial ne demande aucune
   1.896 +        maintenance, un dépôt Git exige d'exécuter manuellement et
   1.897 +        régulièrement la commande <quote>repacks</quote> sur ses métadonnées.
   1.898 +        Sans ceci, les performances de git se dégradent et la consommation de
   1.899 +        l'espace disque augmente rapidement. Un serveur qui contient
   1.900 +        plusieurs dépôts Git qui ne sont pas régulièrement et fréquemment
   1.901 +        <quote>repacked</quote> deviendra un vrai problème lors des
   1.902 +        <quote>backups</quote> du disque, et il y eu des cas, où un
   1.903 +        <quote>backup</quote> journalier pouvait durer plus de 24 heures. Un
   1.904 +        dépôt fraichement <quote>repacked</quote> sera légèrement plus petit
   1.905 +        qu'un dépôt Mercurial, mais un dépôt non <quote>repacked</quote> est
   1.906 +        beaucoup plus grand.
   1.907 +      </para>
   1.908 +
   1.909 +      <para id="x_b3">Le cœur de Git est écrit en C. La plupart des commandes
   1.910 +        Git sont implémentées sous forme de scripts Shell ou Perl, et la
   1.911 +        qualité de ces scripts varie grandement. J'ai plusieurs fois constaté
   1.912 +        que certains de ces scripts étaient chargés en mémoire aveuglément et
   1.913 +        que la présence d'erreurs pouvait s'avérer fatal.
   1.914 +      </para>
   1.915 +
   1.916 +      <para id="x_b4">Mercurial peut importer l'historique d'un dépôt Git.</para>
   1.917 +
   1.918 +    </sect2>
   1.919 +    <sect2>
   1.920 +      <title>CVS</title>
   1.921 +
   1.922 +      <para id="x_b5">CVS est probablement l'outil de gestion de source le
   1.923 +        plus utilisé aujourd'hui dans le monde. À cause de son manque de
   1.924 +        clarté interne, il n'est plus maintenu depuis plusieurs années.
   1.925 +      </para>
   1.926 +
   1.927 +      <para id="x_b6">Il a une architecture client/serveur centralisée. Il ne
   1.928 +        regroupe pas les modifications de fichiers dans une opération de
   1.929 +        <quote>commit</quote> atomique, ce qui permet à ses utilisateurs de
   1.930 +        <quote>casser le <emphasis>build</emphasis></quote> assez facilement
   1.931 +        : une personne peut effectuer une opération de <quote>commit</quote>
   1.932 +        sans problème puis être bloquée par besoin de fusion, avec comme
   1.933 +        conséquence néfaste, que les autres utilisateurs ne récupèreront
   1.934 +        qu'une partie de ses modifications. Ce problème affecte aussi la
   1.935 +        manière de travailler avec l'historique du projet. Si vous voulez
   1.936 +        voir toutes les modifications d'une personne du projet, vous devrez
   1.937 +        injecter manuellement les descriptions et les <emphasis remap="it">timestamps</emphasis> des modifications de chacun des
   1.938 +        fichiers impliqués (si vous savez au moins quels sont ces fichiers).
   1.939 +      </para>
   1.940 +
   1.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
   1.942 +        pas de décrire ici. Il ne supporte pas bien les opérations de
   1.943 +        renommage d'un fichier ou d'un répertoire, ce qui facilite la
   1.944 +        corruption de son dépôt. Il n'a presque pas pour ainsi dire de
   1.945 +        contrôle de cohérence interne, il est donc pratiquement impossible de
   1.946 +        dire si un dépôt est corrompu ni à quel point. Je ne recommanderai
   1.947 +        pas CVS pour un projet existant ou nouveau.
   1.948 +      </para>
   1.949 +
   1.950 +      <para id="x_b8">Mercurial peut importer l'historique d'un projet CVS.
   1.951 +        Néanmoins, il y a quelques principes à respecter; ce qui est vrai
   1.952 +        aussi pour les autres outils d'import de projet CVS. À cause de
   1.953 +        l'absence de <quote>commit</quote> atomique et gestion de version de
   1.954 +        l'arborescence, il n'est pas possible de reconstruire de manière
   1.955 +        précise l'ensemble de l'historique. Un travail de
   1.956 +        <quote>devinette</quote> est donc nécessaire, et les fichiers
   1.957 +        renommés ne sont pas détectés. Parce qu'une bonne part de
   1.958 +        l'administration d'un dépôt CVS est effectuée manuellement, et est
   1.959 +        donc, sujette à erreur, il est courant que les imports CVS
   1.960 +        rencontrent de nombreux problèmes avec les dépôt corrompus (des
   1.961 +        <emphasis remap="it">timestamps</emphasis> de révision complètement
   1.962 +        buggés et des fichiers verrouillés depuis des années sont deux des
   1.963 +        problèmes les moins intéressants dont je me souvienne).
   1.964 +      </para>
   1.965 +
   1.966 +      <para id="x_b9">Mercurial peut importer l'historique depuis un dépôt CVS.
   1.967 +      </para>
   1.968 +
   1.969 +
   1.970 +    </sect2>
   1.971 +    <sect2>
   1.972 +      <title>Outils propriétaires</title>
   1.973 +
   1.974 +      <para id="x_ba">Perforce a une architecture client/serveur centralisée,
   1.975 +        sans aucun mécanisme de mise en cache de données coté client.
   1.976 +        Contrairement à la plupart des outils modernes de gestion de source,
   1.977 +        Perforce exige de ses utilisateurs d'exécuter une commande pour
   1.978 +        informer le serveur central de tout fichier qu'ils souhaitent
   1.979 +        modifier.
   1.980 +      </para>
   1.981 +
   1.982 +      <para id="x_bb">Les performances de Perforce sont plutôt bonnes pour
   1.983 +        des petites équipes, mais elles s'effondrent rapidement lorsque le
   1.984 +        nombre d'utilisateurs augmente au delà de la douzaine. Des
   1.985 +        installations de Perforce assez larges nécessitent le déploiement de
   1.986 +        proxies pour supporter la montée en charge associée.
   1.987 +      </para>
   1.988 +
   1.989 +    </sect2>
   1.990 +    <sect2>
   1.991 +      <title>Choisir un outil de gestion de source</title>
   1.992 +
   1.993 +      <para id="x_bc">A l'exception de CVS, tous les outils listés ci-dessus
   1.994 +        ont des forces qui leur sont propres et qui correspondent à certaines
   1.995 +        formes de projet. Il n'y a pas un seul meilleur outil de gestion de
   1.996 +        source qui correspondrait le mieux à toutes les situations.
   1.997 +      </para>
   1.998 +
   1.999 +      <para id="x_bd">En guise exemple, Subversion est un très bon choix
  1.1000 +        lorsqu'on travaille avec beaucoup de fichiers binaires, qui évoluent
  1.1001 +        régulièrement, grâce à sa nature centralisée et sa capacité à
  1.1002 +        verrouiller des fichiers.
  1.1003 +      </para>
  1.1004 +
  1.1005 +      <para id="x_be">Personnellement, je préfère Mercurial pour sa
  1.1006 +        simplicité, ses performances et sa bonne capacité de fusion, et il
  1.1007 +        m'a très bien rendu service de plusieurs années maintenant.
  1.1008 +      </para>
  1.1009 +
  1.1010 +    </sect2>
  1.1011 +  </sect1>
  1.1012 +  <sect1>
  1.1013 +    <title>Migrer depuis un outil à Mercurial</title>
  1.1014 +
  1.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
  1.1016 +      importer des révisions depuis différents autres outils de gestion de
  1.1017 +      source. Par <quote>incrémental</quote>, j'entends que vous pouvez
  1.1018 +      convertir l'historique entier du projet en une seule fois, puis
  1.1019 +      relancer l'outil d'import plus tard pour obtenir les modifications
  1.1020 +      effectuées depuis votre import initial.
  1.1021 +    </para>
  1.1022 +
  1.1023 +    <para id="x_c0">Les outils de gestion de source supportés par <literal role="hg-ext" moreinfo="none">convert</literal> sont :
  1.1024 +    </para>
  1.1025 +    <itemizedlist>
  1.1026 +      <listitem><para id="x_c1">Subversion</para></listitem>
  1.1027 +      <listitem><para id="x_c2">CVS</para></listitem>
  1.1028 +      <listitem><para id="x_c3">Git</para></listitem>
  1.1029 +      <listitem><para id="x_c4">Darcs</para></listitem>
  1.1030 +    </itemizedlist>
  1.1031 +
  1.1032 +    <para id="x_c5">En outre, <literal role="hg-ext" moreinfo="none">convert</literal> peut
  1.1033 +      exporter les modifications depuis Mercurial vers Subversion. Ceci rend
  1.1034 +      possible d'essayer Subversion en parallèle avant de choisir une
  1.1035 +      solution définitive, sans aucun risque de perte de données.
  1.1036 +    </para>
  1.1037 +
  1.1038 +    <para id="x_c6">La commande <command role="hg-ext-conver" moreinfo="none">convert</command> est très simple à utiliser.
  1.1039 +      Simplement, indiquez le chemin ou l'URL du dépôt de source, en lui
  1.1040 +      indiquant éventuellement le nom du chemin de destination, et la
  1.1041 +      conversion se met en route. Après cet import initial, il suffit de
  1.1042 +      relancer la commande encore une fois pour importer les modifications
  1.1043 +      effectuées depuis.
  1.1044 +    </para>
  1.1045 +  </sect1>
  1.1046 +
  1.1047 +  <sect1>
  1.1048 +    <title>Une courte histoire de la gestion de source</title>
  1.1049 +
  1.1050 +    <para id="x_c7">Le plus célèbre des anciens outils de gestion de source
  1.1051 +      est <emphasis remap="it">SCCS</emphasis> (Source Code Control System)},
  1.1052 +      que Marc Rochkind conçu dans les laboratoires de recherche de Bell
  1.1053 +      (<emphasis remap="it">Bell Labs</emphasis>), dans le début des années
  1.1054 +      70. <emphasis remap="it">SCCS</emphasis> ne fonctionnait que sur des
  1.1055 +      fichiers individuels, et obligeait chaque personne travaillant sur le
  1.1056 +      projet d'avoir un accès à un répertoire de travail commun, sur le même
  1.1057 +      système. Seulement une seule personne pouvait modifier un fichier au
  1.1058 +      même moment, ce fonctionnement était assuré par l'utilisation de verrou
  1.1059 +      (<quote>lock</quote>). Il était courant que des personnes verrouillent
  1.1060 +      des fichiers, et plus tard, oublient de le déverrouiller ; empêchant
  1.1061 +      n'importe qui d'autre de travailler sur ces fichiers sans l'aide de
  1.1062 +      l'administrateur...
  1.1063 +    </para>
  1.1064 +
  1.1065 +    <para id="x_c8">Walter Tichy a développé une alternative libre à
  1.1066 +      <emphasis remap="it">SCCS</emphasis> au début des années 80, qu'il
  1.1067 +      nomma <emphasis remap="it">RCS (Revision Control System)</emphasis>.
  1.1068 +      Comme <emphasis remap="it">SCCS</emphasis>, <emphasis remap="it">RCS</emphasis> demandait aux développeurs de travailler
  1.1069 +      sur le même répertoire partagé, et de verrouiller les fichiers pour se
  1.1070 +      prémunir de tout conflit issu de modifications concurrentes.
  1.1071 +    </para>
  1.1072 +
  1.1073 +    <para id="x_c9">Un peu plus tard dans les années 1980, Dick Grune utilisa
  1.1074 +      <emphasis remap="it">RCS</emphasis> comme une brique de base pour un
  1.1075 +      ensemble de scripts <emphasis remap="it">shell</emphasis> qu'il
  1.1076 +      intitula cmt, avant de la renommer en <emphasis remap="it">CVS
  1.1077 +        (Concurrent Versions System)</emphasis>.  La grande innovation de CVS
  1.1078 +      était que les développeurs pouvaient travailler simultanément et
  1.1079 +      indépendamment dans leur propre espace de travail. Ces espaces de
  1.1080 +      travail privés assuraient que les développeurs ne se marchent pas
  1.1081 +      mutuellement sur les pieds, comme c'était souvent le cas avec RCS et
  1.1082 +      SCCS. Tous les développeurs disposaient donc de leur copie de tous les
  1.1083 +      fichiers du projet, et ils pouvaient donc librement les modifier. Ils
  1.1084 +      devaient néanmoins effectuer la <quote>fusion</quote> (<emphasis remap="it"><quote>merge</quote></emphasis>) de leurs fichiers, avant
  1.1085 +      d'effectuer le <quote>commit</quote> de leurs modifications sur le dépôt
  1.1086 +      central.
  1.1087 +    </para>
  1.1088 +    
  1.1089 +    <para>Brian Berliner reprit les scripts de Grune's et les réécrit en C,
  1.1090 +      qu'il publia en 1989. Depuis, ce code a été modifié jusqu'à devenir la
  1.1091 +      version moderne de CVS. CVS a acquis ainsi la capacité de fonctionner
  1.1092 +      en réseau, transformant son architecture en client/serveur.
  1.1093 +      L'architecture de CVS est centralisée, seul le serveur a une copie de
  1.1094 +      l'historique du projet. L'espace de travail client ne contient qu'une
  1.1095 +      copie de la dernière version du projet, et quelques métadonnées pour
  1.1096 +      indiquer où le serveur se trouve. CVS a été un grand succès,
  1.1097 +      aujourd'hui il est probablement l'outil de gestion de contrôle le plus
  1.1098 +      utilisé au monde.
  1.1099 +    </para>
  1.1100 +    
  1.1101 +    <para>Au début des années 1990, Sun Microsystems développa un premier
  1.1102 +      outil de gestion de source distribué, nommé TeamWare. Un espace de
  1.1103 +      travail TeamWare contient une copie complète de l'historique du projet.
  1.1104 +      TeamWare n'a pas de notion de dépôt central. (CVS utilisait RCS pour le
  1.1105 +      stockage de l'historique, TeamWare utilisait SCCS).
  1.1106 +    </para>
  1.1107 +    
  1.1108 +    <para>Alors que les années 1990 avançaient, les utilisateurs ont pris
  1.1109 +      conscience d'un certain nombre de problèmes avec CVS. Il enregistrait
  1.1110 +      simultanément des modifications sur différents fichiers
  1.1111 +      individuellement, au lieu de les regrouper dans une seule opération
  1.1112 +      cohérente et atomique. Il ne gère pas bien sa hiérarchie de fichier, il
  1.1113 +      est donc assez aisé de créer le chaos en renommant les fichiers et les
  1.1114 +      répertoires. Pire encore, son code source est difficile à lire et à
  1.1115 +      maintenir, ce qui agrandit largement le <quote>niveau de
  1.1116 +        souffrance</quote> associé à la réparation de ces problèmes
  1.1117 +      d'architecture de manière prohibitive.
  1.1118 +    </para>
  1.1119 +    
  1.1120 +    <para>En 2001, Jim Blandy et Karl Fogel, deux développeurs qui avaient
  1.1121 +      travaillé sur CVS, initièrent un projet pour le remplacer par un outil
  1.1122 +      qui aurait une meilleure architecture et un code plus propre. Le
  1.1123 +      résultat, Subversion, ne quitte pas le modèle centralisé et
  1.1124 +      client/server de CVS, mais ajoute les opérations de
  1.1125 +      <quote>commit</quote> atomique sur de multiples fichiers, une meilleure
  1.1126 +      gestion des espaces de noms, et d'autres fonctionnalités qui en font un
  1.1127 +      meilleur outil que CVS. Depuis sa première publication, il est
  1.1128 +      rapidement devenu très populaire.
  1.1129 +    </para>
  1.1130 +    
  1.1131 +    <para>Plus ou moins simultanément, Graydon Hoare a commencé sur
  1.1132 +      l'ambitieux système de gestion distribué Monotone. Bien que Monotone
  1.1133 +      corrige plusieurs défauts de CVS tout en offrant une architecture
  1.1134 +      <quote>peer-to-peer</quote>, il va aussi plus loin que la plupart des
  1.1135 +      outils de révision de manière assez innovante. Il utilise des
  1.1136 +      <quote>hashs</quote> cryptographiques comme identifiants, et il a une
  1.1137 +      notion complète de <quote>confiance</quote> du code issu des
  1.1138 +      différentes sources.
  1.1139 +    </para>
  1.1140 +    
  1.1141 +    <para>Mercurial est né en 2005. Bien que très influencé par Monotone,
  1.1142 +      Mercurial se concentre sur la facilité d'utilisation, les performances
  1.1143 +      et la capacité à monter en charge pour de très gros projets.
  1.1144 +    </para>
  1.1145 +  
  1.1146 +  </sect1>
  1.1147 +
  1.1148 +</chapter>
  1.1149 +
  1.1150 +<!--
  1.1151 +local variables: 
  1.1152 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.1153 +end:
  1.1154 +-->
  1.1155 +
  1.1156 +  <!-- BEGIN ch02 -->
  1.1157 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.1158 +
  1.1159 +<chapter id="chap:tour-basic">
  1.1160 +  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
  1.1161 +  <title>Une rapide présentation de Mercurial : les bases</title>
  1.1162 +
  1.1163 +  <sect1>
  1.1164 +    <title>Installer Mercurial sur votre système</title>
  1.1165 +
  1.1166 +    <para id="x_1">Des paquetages binaires de Mercurial sont disponibles pour la
  1.1167 +      plupart des systèmes d'exploitation, ce qui rend facile l'utilisation
  1.1168 +      immédiate de Mercurial sur votre ordinateur.</para>
  1.1169 +
  1.1170 +    <sect2>
  1.1171 +      <title>Windows</title>
  1.1172 +
  1.1173 +      <para id="x_c">La meilleur version de Mercurial pour Windows est
  1.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>.
  1.1175 +        Ce logiciel n'a aucune dépendance exterieure; il fonctionne <quote>et
  1.1176 +          c'est tout</quote>. Il fournit aussi bien les outils en ligne de
  1.1177 +        commmande qu'une interface graphique.</para>
  1.1178 + 
  1.1179 +    </sect2>
  1.1180 +
  1.1181 +    <sect2>
  1.1182 +      <title>Mac OS X</title>
  1.1183 +  
  1.1184 +      <para id="x_a">Lee Cantey publie un installeur de Mercurial pour Mac OS
  1.1185 +        X sur <ulink url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para>
  1.1186 +    </sect2>
  1.1187 +      
  1.1188 +    <sect2>
  1.1189 +      <title>Linux</title>
  1.1190 +
  1.1191 +      <para id="x_2">Parce que chaque distribution de Linux a ses propres
  1.1192 +        outils de gestion de paquets, politiques et rythmes de
  1.1193 +        développements, il est difficile de donner un ensemble
  1.1194 +        d'instructions unique pour installer les binaires de Mercurial. La
  1.1195 +        version de Mercurial avec laquelle vous vous retrouverez dépendra
  1.1196 +        grandement de l'activité de la personne en charge du paquetage pour
  1.1197 +        la distribution.</para>
  1.1198 +
  1.1199 +      <para id="x_3">Pour rester simple, je me concentrerai sur
  1.1200 +        l'installation de Mercurial en ligne de commande, sous les
  1.1201 +        distributions les plus courantes. La plupart des distributions
  1.1202 +        fournissent des gestionnaires graphiques de paquetage qui vous
  1.1203 +        permettront d'installer Mercurial en quelques clicks. Le paquetage
  1.1204 +        devrait se nommer <literal moreinfo="none">mercurial</literal>.</para>
  1.1205 +
  1.1206 +      <itemizedlist>
  1.1207 +        <listitem><para id="x_4">Ubuntu et Debian:</para>
  1.1208 +          <programlisting format="linespecific">apt-get install mercurial</programlisting></listitem>
  1.1209 +        <listitem><para id="x_5">Fedora:</para>
  1.1210 +          <programlisting format="linespecific">yum install mercurial</programlisting></listitem>
  1.1211 +        <listitem><para id="x_6">Gentoo:</para>
  1.1212 +           <programlisting format="linespecific">emerge mercurial</programlisting></listitem>
  1.1213 +        <listitem><para id="x_715">OpenSUSE:</para>
  1.1214 +          <programlisting format="linespecific">zypper install
  1.1215 +          mercurial</programlisting></listitem>
  1.1216 +      </itemizedlist>
  1.1217 +
  1.1218 +    </sect2>
  1.1219 +    <sect2>
  1.1220 +      <title>Solaris</title>
  1.1221 +
  1.1222 +      <para id="x_09">SunFreeWare, à <ulink url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>,
  1.1223 +      fournit des paquets précompilés pour Mercurial.</para>
  1.1224 +    </sect2>
  1.1225 +  </sect1>
  1.1226 +
  1.1227 +  <sect1>
  1.1228 +    <title>Commencer à utiliser Mercurial</title>
  1.1229 +
  1.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
  1.1231 +      installé proprement. Les informations affichées sur la version ne sont
  1.1232 +      pas réellement importantes en soit, c'est surtout de savoir si elles
  1.1233 +      s'affichent qui nous intéresse.</para>
  1.1234 +
  1.1235 +    <!-- BEGIN tour.version -->
  1.1236 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg version</userinput>
  1.1237 +Mercurial Distributed SCM (version 1.2.1)
  1.1238 +
  1.1239 +Copyright (C) 2005-2009 Matt Mackall &lt;mpm@selenic.com&gt; and others
  1.1240 +This is free software; see the source for copying conditions. There is NO
  1.1241 +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  1.1242 +</screen>
  1.1243 +<!-- END tour.version -->
  1.1244 +
  1.1245 +
  1.1246 +    <sect2>
  1.1247 +      <title>L'aide intégrée</title>
  1.1248 +
  1.1249 +      <para id="x_f">Mercurial fournit un système d'aide intégré, ce qui est
  1.1250 +        inestimable quand vous vous retrouvez coincé à essayer de vous
  1.1251 +        rappeler comment lancer une commande. Si vous êtes bloqué, exécutez
  1.1252 +        simplement <command role="hg-cmd" moreinfo="none">hg help</command>; elle affichera
  1.1253 +        une brève liste des commandes, avec une description pour chacune. Si
  1.1254 +        vous demandez de l'aide sur une commande spécifique (voir
  1.1255 +        ci-dessous), elle affichera des informations plus détaillées.</para>
  1.1256 +
  1.1257 +      <!-- BEGIN tour.help -->
  1.1258 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg help init</userinput>
  1.1259 +hg init [-e CMD] [--remotecmd CMD] [DEST]
  1.1260 +
  1.1261 +create a new repository in the given directory
  1.1262 +
  1.1263 +    Initialize a new repository in the given directory. If the given
  1.1264 +    directory does not exist, it is created.
  1.1265 +
  1.1266 +    If no directory is given, the current directory is used.
  1.1267 +
  1.1268 +    It is possible to specify an ssh:// URL as the destination.
  1.1269 +    See 'hg help urls' for more information.
  1.1270 +
  1.1271 +options:
  1.1272 +
  1.1273 + -e --ssh        specify ssh command to use
  1.1274 +    --remotecmd  specify hg command to run on the remote side
  1.1275 +
  1.1276 +use "hg -v help init" to show global options
  1.1277 +</screen>
  1.1278 +<!-- END tour.help -->
  1.1279 +
  1.1280 +
  1.1281 +      <para id="x_10">Pour un niveau d'informations encore plus détaillé 
  1.1282 +        (ce dont vous aurez rarement besoin), exécuter <command role="hg-cmd" moreinfo="none">hg 
  1.1283 +        help <option role="hg-opt-global">-v</option></command>.  L'option 
  1.1284 +        <option role="hg-opt-global">-v</option> est l'abréviation de 
  1.1285 +        <option role="hg-opt-global">--verbose</option>, et indique à Mercurial 
  1.1286 +        d'ficher plus d'informations que d'habitude.</para>
  1.1287 +
  1.1288 +     </sect2>
  1.1289 +  </sect1>
  1.1290 +  <sect1>
  1.1291 +    <title>Travailler avec un dépôt</title>
  1.1292 +
  1.1293 +    <para id="x_11">Avec Mercurial, tout se déroule au sein du 
  1.1294 +      <emphasis>dépôt</emphasis>. Le dépôt d'un projet contient tous 
  1.1295 +      les fichiers qui <quote>appartiennent</quote> au projet.</para>
  1.1296 +
  1.1297 +    <para id="x_12">Il n'y a rien de particulièrement magique au sujet de 
  1.1298 +      ce dépôt, c'est simplement une arborescence sur votre système de fichiers 
  1.1299 +      que Mercurial traite de manière spéciale. Vous pouvez renommer ou effacer 
  1.1300 +      ce répertoire à n'impporte quel moment, en utilisant la ligne de commande 
  1.1301 +      ou votre explorateur de fichiers.</para>
  1.1302 +
  1.1303 +    <sect2>
  1.1304 +      <title>Faire une copie locale de votre dépôt</title>
  1.1305 +      
  1.1306 +      <para id="x_13"><emphasis>Copier</emphasis> un dépôt est juste un 
  1.1307 +        peu spécial. Bien que vous puissiez utiliser une commande habituelle de 
  1.1308 +        copie pour copier votre dépôt, il vaut mieux utiliser une commande fournie par
  1.1309 +        Mercurial. Cette commande est appelée <command role="hg-cmd" moreinfo="none">hg clone</command>, 
  1.1310 +        car elle crée une copie identique à un dépôt existant.</para>
  1.1311 +
  1.1312 +      <!-- BEGIN tour.clone -->
  1.1313 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone http://hg.serpentine.com/tutorial/hello</userinput>
  1.1314 +destination directory: hello
  1.1315 +requesting all changes
  1.1316 +adding changesets
  1.1317 +adding manifests
  1.1318 +adding file changes
  1.1319 +added 5 changesets with 5 changes to 2 files
  1.1320 +updating working directory
  1.1321 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.1322 +</screen>
  1.1323 +<!-- END tour.clone -->
  1.1324 +
  1.1325 +
  1.1326 +      <para id="x_67c">Un avantage de la commande <command role="hg-cmd" moreinfo="none">hg
  1.1327 +          clone</command> est que, comme nous l'avons vu ci dessus, elle nous
  1.1328 +        permet de faire de cloner les dépôts à travers le réseau. Un autre
  1.1329 +        est qu'elle se rappelle d'où a été cloné un dépôt, ce qui est utile
  1.1330 +        quand on veut mettre à jour le clone.</para>
  1.1331 +
  1.1332 +      <para id="x_14">Si votre opération de clonage réussit, vous devriez maintenant
  1.1333 +        avoir un répertoire local appelé <filename class="directory" moreinfo="none">hello</filename>. 
  1.1334 +        Ce répertoire contiendra quelques fichiers.</para>
  1.1335 +
  1.1336 +      <!-- BEGIN tour.ls -->
  1.1337 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -l</userinput>
  1.1338 +total 4
  1.1339 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:05 hello
  1.1340 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls hello</userinput>
  1.1341 +Makefile  hello.c
  1.1342 +</screen>
  1.1343 +<!-- END tour.ls -->
  1.1344 +
  1.1345 +
  1.1346 +      <para id="x_15">Ces fichiers ont le même contenu et historique dans votre dépôt
  1.1347 +        qu'ils ont dans le dépôt que vous avez cloné.</para>
  1.1348 +
  1.1349 +      <para id="x_16">Chaque dépôt Mercurial est complet, autonome et
  1.1350 +        indépendant. Il contient sa propre copie privée des fichiers du
  1.1351 +        projet et de leur historique. Le clone d'un dépôt se souvient de la
  1.1352 +        localisation du dépôt à partir duquel il a été clôné, mais il ne
  1.1353 +        communique pas avec ce dernier, ou un autre, à moins que vous ne lui
  1.1354 +        demandiez.</para>
  1.1355 +
  1.1356 +      <para id="x_17">Ce que tout ceci signifie pour le moment est que nous
  1.1357 +        sommes libres d'expérimenter avec ce dépôt, confiants dans le fait
  1.1358 +        qu'il s'agit d'un <quote>bac à sable</quote> qui n'affectera personne
  1.1359 +        d'autre.</para>
  1.1360 +
  1.1361 +    </sect2>  
  1.1362 +    <sect2>
  1.1363 +      <title>Quel est le contenu d'un dépôt ?</title>
  1.1364 +
  1.1365 +      <para id="x_18">Prêtons plus attention un instant au contenu d'un dépôt. 
  1.1366 +        Nous voyons qu'il contient un répertoire nommé <filename class="directory" moreinfo="none">.hg
  1.1367 +        </filename>. C'est ici que Mercurial conserve toutes ses
  1.1368 +        métadonnées.</para>
  1.1369 +
  1.1370 +      <!-- BEGIN tour.ls-a -->
  1.1371 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hello</userinput>
  1.1372 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -a</userinput>
  1.1373 +.  ..  .hg  Makefile  hello.c
  1.1374 +</screen>
  1.1375 +<!-- END tour.ls-a -->
  1.1376 + 
  1.1377 +
  1.1378 +      <para id="x_19">Le contenu du répertoire <filename class="directory" moreinfo="none">.hg
  1.1379 +        </filename> et ses sous répertoires sont les seuls propres à Mercurial. 
  1.1380 +        Tous les autres fichiers et répertoires dans le dépôt sont à vous, et 
  1.1381 +        vous pouvez en faire ce que vous voulez.</para>
  1.1382 +
  1.1383 +      <para id="x_1a">Pour introduire un peu de terminologie, le répertoire 
  1.1384 +        <filename class="directory" moreinfo="none">.hg</filename> est un <quote>vrai</quote> 
  1.1385 +        dépôt, et tous les fichiers et les répertoires qui coexistent avec lui, 
  1.1386 +        sont désignés sous le nom <emphasis>espace de travail</emphasis>. Une 
  1.1387 +        manière facile de se rappeler cette distinction est de retenir que le 
  1.1388 +        <emphasis>dépôt</emphasis> contient l'<emphasis>historique</emphasis>
  1.1389 +        de votre projet, alors que l'<emphasis>espace de travail</emphasis> 
  1.1390 +        contient un "<emphasis>snapshot</emphasis>"  de votre projet à un certain 
  1.1391 +        point de son historique.</para>
  1.1392 +
  1.1393 +    </sect2>
  1.1394 +  </sect1>
  1.1395 +  <sect1>
  1.1396 +    <title>Une promenade dans l'historique</title>
  1.1397 +
  1.1398 +    <para id="x_1b">Une des premières choses que vous aurez envie 
  1.1399 +      de faire avec un nouveau dépôt, sera de comprendre son historique. 
  1.1400 +      La commande <command role="hg-cmd" moreinfo="none">hg log</command> vous donne une 
  1.1401 +      vue de l'historique.</para>
  1.1402 +
  1.1403 +    <!-- BEGIN tour.log -->
  1.1404 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log</userinput>
  1.1405 +changeset:   4:2278160e78d4
  1.1406 +tag:         tip
  1.1407 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1408 +date:        Sat Aug 16 22:16:53 2008 +0200
  1.1409 +summary:     Trim comments.
  1.1410 +
  1.1411 +changeset:   3:0272e0d5a517
  1.1412 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1413 +date:        Sat Aug 16 22:08:02 2008 +0200
  1.1414 +summary:     Get make to generate the final binary from a .o file.
  1.1415 +
  1.1416 +changeset:   2:fef857204a0c
  1.1417 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1418 +date:        Sat Aug 16 22:05:04 2008 +0200
  1.1419 +summary:     Introduce a typo into hello.c.
  1.1420 +
  1.1421 +changeset:   1:82e55d328c8c
  1.1422 +user:        mpm@selenic.com
  1.1423 +date:        Fri Aug 26 01:21:28 2005 -0700
  1.1424 +summary:     Create a makefile
  1.1425 +
  1.1426 +changeset:   0:0a04b987be5a
  1.1427 +user:        mpm@selenic.com
  1.1428 +date:        Fri Aug 26 01:20:50 2005 -0700
  1.1429 +summary:     Create a standard "hello, world" program
  1.1430 +
  1.1431 +</screen>
  1.1432 +<!-- END tour.log -->
  1.1433 +
  1.1434 +
  1.1435 +    <para id="x_1c">Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque
  1.1436 +      révision enregistrée pour ce projet. Dans la terminologie de Mercurial, nous
  1.1437 +      appelons chacun de ces évènements enregistrés un <emphasis>changeset</emphasis>, parce
  1.1438 +      qu'il contient un ensemble de modifications sur plusieurs fichiers.</para>
  1.1439 +
  1.1440 +    <para id="x_1d">La commande <command role="hg-cmd" moreinfo="none">hg log</command> affiche 
  1.1441 +    ainsi ces informations :</para>
  1.1442 +
  1.1443 +    <itemizedlist>
  1.1444 +      <listitem><para id="x_1e"><literal moreinfo="none">changeset</literal> : Ce champ contient 
  1.1445 +        un nombre, séparé par deux points (:), d'une chaine hexadécimale. Il 
  1.1446 +        s'agit en fait d'<emphasis>identifiants</emphasis>  d'un changeset. Il y a 
  1.1447 +        deux identifiants car le numéro de la révision est plus court et plus à 
  1.1448 +        facile à saisir qu'une séquence hexadécimale.</para>
  1.1449 +      </listitem>
  1.1450 +      <listitem><para id="x_1f"><literal moreinfo="none">user</literal> : L'identité de la personne 
  1.1451 +        qui a créée ce  %%% laisser le terme anglais car il sera affiché
  1.1452 +        changeset. C'est un champ libre de forme, mais la plupart du
  1.1453 +        temps il contient le nom et l'email de la personne.</para>
  1.1454 +      </listitem>
  1.1455 +      <listitem><para id="x_20"><literal moreinfo="none">date</literal> : La date et l'heure à 
  1.1456 +        laquelle le \textit{changeset} a été créé, ainsi que le fuseau horaire dans 
  1.1457 +        lequelle il a été créé. (La date et l'heure sont locales à ce
  1.1458 +        \textit{fuseau}, elles indiquent donc quelle date et heure il était
  1.1459 +        pour la personne qui a créé ce changeset.</para>
  1.1460 +      </listitem>
  1.1461 +      <listitem><para id="x_21"><literal moreinfo="none">résumé</literal>: La première ligne du 
  1.1462 +        message que le créateur a associé à son changeset pour le décrire.</para>
  1.1463 +      </listitem>
  1.1464 +      <listitem><para id="x_67d">Certains changesets, comme le premier de la
  1.1465 +        liste ci-dessus ont un champ <literal moreinfo="none">tag</literal>. Le tag est une autre
  1.1466 +        façon d'identifier un changeset en lui donnant un nom simple à retenir.
  1.1467 +        (Le tag nommé <literal moreinfo="none">tip</literal> est spécial : il fait toujours
  1.1468 +        référence aux derniers changements dans le dépôt.)</para></listitem>
  1.1469 +    </itemizedlist>
  1.1470 +
  1.1471 +    <para id="x_22">Par défaut, la commande <command role="hg-cmd" moreinfo="none">hg log</command> 
  1.1472 +      n'affiche qu'un résumé, il manque beaucoup de détails.</para>
  1.1473 +
  1.1474 +    <para id="x_23">La figure <xref linkend="fig:tour-basic:history"/> fournit une 
  1.1475 +      représentation graphique de l'historique du dépôt <filename class="directory" moreinfo="none">hello
  1.1476 +      </filename>, pour rendre plus facile de voir dans quelle direction 
  1.1477 +      l'historique se <quote>déroule</quote>. Nous reviendrons régulièrement 
  1.1478 +      sur cette représentation dans ce chapitre et ceux qui suivent.</para>
  1.1479 +
  1.1480 +
  1.1481 +    <figure id="fig:tour-basic:history" float="0">
  1.1482 +      <title>Graphical history of the <filename class="directory" moreinfo="none">hello</filename> repository</title>
  1.1483 +      <mediaobject>
  1.1484 +        <imageobject><imagedata fileref="figs/tour-history.png"/></imageobject>
  1.1485 +        <textobject><phrase>XXX add text</phrase></textobject>
  1.1486 +      </mediaobject>
  1.1487 +    </figure>
  1.1488 +
  1.1489 +
  1.1490 +    <sect2>
  1.1491 +      <title>Changesets, révisions, et collaboration</title>
  1.1492 +      
  1.1493 +      <para id="x_25">Comme l'anglais est réputé pour être un langage maladroit,
  1.1494 +        et que l'informatique est la source de bien des erreurs de terminologie
  1.1495 +        (pourquoi utiliser un seul terme quand quatre feront l'affaire ?), la
  1.1496 +        gestion de version a une variété de mots et de phrases qui veulent dire
  1.1497 +        la même chose. Si vous discutez d'historique de Mercurial avec d'autres
  1.1498 +        personnes, vous constaterez que souvent, le mot <quote>changeset</quote>
  1.1499 +        est contracté simplement en <quote>change</quote> ou (à l'écrit)
  1.1500 +        <quote>cset</quote>, et même parfois un changeset
  1.1501 +        <quote>révision</quote>, abrégé en <quote>rev</quote>.</para>
  1.1502 +
  1.1503 +      <para id="x_26">Bien que le <emphasis>mot</emphasis> que vous utilisez pour 
  1.1504 +        désigner le concept de changeset importe peu, l'<emphasis>identifiant</emphasis> 
  1.1505 +        que vous utilisez pour désigner un <emphasis>changeset</emphasis> spécifique 
  1.1506 +        a une grande importance. Rappelez vous que le champ changeset affiché par la
  1.1507 +        commande <command role="hg-cmd" moreinfo="none">hg log</command> identifie un changeset à
  1.1508 +        la fois avec un numéro de révision et une séquence hexadécimale.</para>
  1.1509 +
  1.1510 +      <itemizedlist>
  1.1511 +        <listitem><para id="x_27">Le numéro de révision est <emphasis>seulement 
  1.1512 +        valable dans ce dépôt</emphasis>,</para></listitem>
  1.1513 +        <listitem><para id="x_28">La séquence hexadécimale est un
  1.1514 +        <emphasis>identifiant permanent, et invariant</emphasis> qui 
  1.1515 +        pourra toujours être associé au changeset exact de <emphasis>chaque</emphasis> 
  1.1516 +        copie de votre dépôt.</para></listitem></itemizedlist>
  1.1517 +
  1.1518 +      <para id="x_29">La distinction est importante. Si vous envoyez un email 
  1.1519 +         à quelqu'un en parlant de la <quote>révision 33</quote>, il est très 
  1.1520 +         probable que sa révision 33 <emphasis>ne sera pas la même</emphasis> 
  1.1521 +         que la votre. La raison de ceci est que le numéro de révision dépend 
  1.1522 +         de l'ordre dans lequel les modifications sont arrivées dans le dépôt, 
  1.1523 +         et il n'y a aucune garantie que les mêmes changements soient arrivés 
  1.1524 +         dans le même ordre dans différents dépôts. Trois modifications
  1.1525 +         <literal moreinfo="none">a,b,c</literal> peuvent aisément apparaitre dans un dépôt 
  1.1526 +         comme <literal moreinfo="none">0,1,2</literal>, et dans un autre comme <literal moreinfo="none">0,2,1
  1.1527 +         </literal>.</para>
  1.1528 +
  1.1529 +      <para id="x_2a">Mercurial utilise les numéros de révision uniquement comme des raccourcis
  1.1530 +        pratiques. Si vous devez discuter d'un \textit{changeset} avec quelqu'un,
  1.1531 +        ou identifer un \textit{changeset} pour une quelconque raison (par exemple,
  1.1532 +        un rapport de \textit{bug}), utilisez la séquence hexadécimale.</para>
  1.1533 +
  1.1534 +    </sect2>
  1.1535 +    <sect2>
  1.1536 +      <title>Afficher une révision spécifique</title>
  1.1537 +
  1.1538 +      <para id="x_2b">Pour réduire la sortie de <command role="hg-cmd" moreinfo="none">hg log
  1.1539 +        </command> à une seule révision, utilisez l'option <option role="hg-opt-log">-r
  1.1540 +        </option> (ou <option role="hg-opt-log">--rev</option>). Vous pouvez utiliser
  1.1541 +        le numéro de révision ou la séquence hexadécimale comme identifiant, et
  1.1542 +        demander autant de révisions que vous le souhaitez.</para>
  1.1543 +
  1.1544 +      <!-- BEGIN tour.log-r -->
  1.1545 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 3</userinput>
  1.1546 +changeset:   3:0272e0d5a517
  1.1547 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1548 +date:        Sat Aug 16 22:08:02 2008 +0200
  1.1549 +summary:     Get make to generate the final binary from a .o file.
  1.1550 +
  1.1551 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 0272e0d5a517</userinput>
  1.1552 +changeset:   3:0272e0d5a517
  1.1553 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1554 +date:        Sat Aug 16 22:08:02 2008 +0200
  1.1555 +summary:     Get make to generate the final binary from a .o file.
  1.1556 +
  1.1557 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 1 -r 4</userinput>
  1.1558 +changeset:   1:82e55d328c8c
  1.1559 +user:        mpm@selenic.com
  1.1560 +date:        Fri Aug 26 01:21:28 2005 -0700
  1.1561 +summary:     Create a makefile
  1.1562 +
  1.1563 +changeset:   4:2278160e78d4
  1.1564 +tag:         tip
  1.1565 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1566 +date:        Sat Aug 16 22:16:53 2008 +0200
  1.1567 +summary:     Trim comments.
  1.1568 +
  1.1569 +</screen>
  1.1570 +<!-- END tour.log-r -->
  1.1571 +
  1.1572 +
  1.1573 +      <para id="x_2c">Si vous voulez voir l'historique de plusieurs révisions
  1.1574 +        sans avoir à les énumérer, vous pouvez utiliser la <emphasis>intervalle
  1.1575 +        de numérotation</emphasis> qui vous permet d'exprimer l'idée <quote>je
  1.1576 +        veux toutes les révisions entre $a$ et $b$, inclus</quote></para>
  1.1577 +
  1.1578 +      <!-- BEGIN tour.log.range -->
  1.1579 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r 2:4</userinput>
  1.1580 +changeset:   2:fef857204a0c
  1.1581 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1582 +date:        Sat Aug 16 22:05:04 2008 +0200
  1.1583 +summary:     Introduce a typo into hello.c.
  1.1584 +
  1.1585 +changeset:   3:0272e0d5a517
  1.1586 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1587 +date:        Sat Aug 16 22:08:02 2008 +0200
  1.1588 +summary:     Get make to generate the final binary from a .o file.
  1.1589 +
  1.1590 +changeset:   4:2278160e78d4
  1.1591 +tag:         tip
  1.1592 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1593 +date:        Sat Aug 16 22:16:53 2008 +0200
  1.1594 +summary:     Trim comments.
  1.1595 +
  1.1596 +</screen>
  1.1597 +<!-- END tour.log.range -->
  1.1598 +
  1.1599 +
  1.1600 +      <para id="x_2d">Mercurial respecte aussi l'ordre dans lequel vous spécifiez
  1.1601 +        les révisions, ainsi <command role="hg-cmd" moreinfo="none">hg log -r 2:4</command>
  1.1602 +        affichera <literal moreinfo="none">2,3,4</literal> alors que <command role="hg-cmd" moreinfo="none">hg
  1.1603 +        log -r 4:2</command> affichera <literal moreinfo="none">4,3,2</literal>.</para>
  1.1604 +
  1.1605 +    </sect2>  
  1.1606 +    <sect2>
  1.1607 +      <title>Informations détaillées</title>
  1.1608 +
  1.1609 +      <para id="x_2e">Le résumé affiché par <command role="hg-cmd" moreinfo="none">hg log</command> 
  1.1610 +        est suffisant si vous savez déjà ce que vous cherchez. En 
  1.1611 +        revanche, vous aurez probablement besoin de voir une description 
  1.1612 +        complète du changement, ou une liste des fichiers modifiés si vous 
  1.1613 +        cherchez à déterminer qu'un changeset est bien celui que vous
  1.1614 +        recherchez. L'option \hgopt{-v} de la commande <command role="hg-cmd" moreinfo="none">hg 
  1.1615 +        log</command> (ou <option role="hp-opt-global">--verbose</option>) vous 
  1.1616 +        donne ces informations supplémentaires.</para>
  1.1617 +
  1.1618 +      <!-- BEGIN tour.log-v -->
  1.1619 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -v -r 3</userinput>
  1.1620 +changeset:   3:0272e0d5a517
  1.1621 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1622 +date:        Sat Aug 16 22:08:02 2008 +0200
  1.1623 +files:       Makefile
  1.1624 +description:
  1.1625 +Get make to generate the final binary from a .o file.
  1.1626 +
  1.1627 +
  1.1628 +</screen>
  1.1629 +<!-- END tour.log-v -->
  1.1630 +
  1.1631 +
  1.1632 +      <para id="x_2f">Si vous voulez voir à la fois la description 
  1.1633 +        et le contenu d'une modification, ajouter l'option <option role="hg-opt-log">-p</option> (ou <option role="hg-opt-log">
  1.1634 +        --patch</option>). Ceci affiche le contenu d'une modification 
  1.1635 +        comme un <emphasis>diff unifié</emphasis>
  1.1636 +        <!-- \footnote{NdT: \textit{unified diff}} -->
  1.1637 +        (si vous n'avez jamais vu de diff unifié avant, consultez la 
  1.1638 +        section <xref linkend="sec:mq:patch"/> pour un rapide 
  1.1639 +        survol).</para>
  1.1640 +
  1.1641 +      <!-- BEGIN tour.log-vp -->
  1.1642 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -v -p -r 2</userinput>
  1.1643 +changeset:   2:fef857204a0c
  1.1644 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.1645 +date:        Sat Aug 16 22:05:04 2008 +0200
  1.1646 +files:       hello.c
  1.1647 +description:
  1.1648 +Introduce a typo into hello.c.
  1.1649 +
  1.1650 +
  1.1651 +diff -r 82e55d328c8c -r fef857204a0c hello.c
  1.1652 +--- a/hello.c	Fri Aug 26 01:21:28 2005 -0700
  1.1653 ++++ b/hello.c	Sat Aug 16 22:05:04 2008 +0200
  1.1654 +@@ -11,6 +11,6 @@
  1.1655 + 
  1.1656 + int main(int argc, char **argv)
  1.1657 + {
  1.1658 +-	printf("hello, world!\n");
  1.1659 ++	printf("hello, world!\");
  1.1660 + 	return 0;
  1.1661 + }
  1.1662 +
  1.1663 +</screen>
  1.1664 +<!-- END tour.log-vp -->
  1.1665 +
  1.1666 +
  1.1667 +      <para id="x_67e">L'option <option role="hg-opt-log">-p</option> est
  1.1668 +        incroyablement utile, il est donc important dans s'en rappeller.</para>
  1.1669 +
  1.1670 +    </sect2>
  1.1671 +  </sect1>
  1.1672 +  <sect1>
  1.1673 +    <title>Tout sur les options de commandes</title>
  1.1674 +    
  1.1675 +    <para id="x_30">Avant d'aller plus loin sur le fonctionnement 
  1.1676 +      des commandes de Mercurial, étudions un moment comment elles 
  1.1677 +      fonctionnent de manière générale. Vous trouverez ça probablement 
  1.1678 +      utile pour la suite de notre parcours.</para>
  1.1679 +
  1.1680 +    <para id="x_31">Mercurial utilise une approche directe et cohérente 
  1.1681 +      pour interpréter les options que vous passez aux commandes. Il suit une
  1.1682 +      convention commune à la plupart des systèmes Unix et Linux modernes.</para>
  1.1683 +
  1.1684 +    <itemizedlist>
  1.1685 +      <listitem><para id="x_32">Chaque option a un nom complet. Par exemple, 
  1.1686 +        comme nous l'avons déjà vu, la commande <command role="hg-cmd" moreinfo="none">hg 
  1.1687 +        log</command> accepte l'option <option role="hg-opt-log">--rev
  1.1688 +        </option>.</para>
  1.1689 +      </listitem>
  1.1690 +      <listitem><para id="x_33">La plupart des options disposent de 
  1.1691 +        noms abrégés. Aussi, au lieu d'utiliser <option role="hg-opt-log">--rev
  1.1692 +        </option>, vous pouvez utiliser <option role="hg-opt-log">-r</option>. 
  1.1693 +        (Les options qui  n'ont pas de noms abrégés sont généralement 
  1.1694 +        rarement utilisées).</para>
  1.1695 +      </listitem>
  1.1696 +      <listitem><para id="x_34">Les noms complets commencent par deux 
  1.1697 +        tirets (i.e. <option role="hg-opt-log">--rev</option>),
  1.1698 +        alors que les options courtes commencent avec un seul (i.e. 
  1.1699 +        <option role="hg-opt-log">-r</option>).</para>
  1.1700 +      </listitem>
  1.1701 +     <listitem><para id="x_35">Les noms des options sont cohérents 
  1.1702 +       entre les commandes. Par exemple, chaque commande qui accepte 
  1.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
  1.1704 +       </option> comme arguments.</para>
  1.1705 +     </listitem>
  1.1706 +   </itemizedlist>
  1.1707 +
  1.1708 +   <para id="x_36">Dans les exemples de ce livre, j'utilise les noms abrégés 
  1.1709 +     plutôt que les noms complets. Ceci est une préférence personnelle, pas 
  1.1710 +     une recommandation.</para>
  1.1711 +
  1.1712 +   <para id="x_37">La plupart des commandes qui affichent une quelconque sortie 
  1.1713 +     à l'écran, afficheront davantage avec l'option <option role="hg-opt-global">
  1.1714 +     -v</option> (ou <option role="hg-opt-global">--verbose</option>), et
  1.1715 +     moins avec l'option <option role="hg-opt-global">-q</option> (ou 
  1.1716 +     <option role="hg-opt-global">--quiet</option>).</para>
  1.1717 +
  1.1718 +    <note>
  1.1719 +      <title>Option naming consistency</title>
  1.1720 +      
  1.1721 +      <para id="x_680">Presque toujours, les commandes de Mercurial utilisent
  1.1722 +      des noms d'options cohérentes pour référer à des concepts identiques.
  1.1723 +      Par exemple, si une commande concerne les changesets, vous les
  1.1724 +      identifierez toujours avec l'option <option role="hg-opt-log">-r</option>.
  1.1725 +      Cette utilisation cohérente des noms d'options permet de mémoriser plus
  1.1726 +      facilement quelles options accepte une commande.</para>
  1.1727 +   </note>
  1.1728 +
  1.1729 +
  1.1730 +  </sect1>
  1.1731 +  <sect1>
  1.1732 +    <title>Faire et vérifier des modifications</title>
  1.1733 +
  1.1734 +    <para id="x_38">Maintenant que nous avons une bonne idée des 
  1.1735 +      commandes pour consulter l'historique de Mercurial, regardons 
  1.1736 +      comment faire des modifications et les examiner.</para>
  1.1737 +     
  1.1738 +    <para id="x_39">La première chose que nous allons faire c'est isoler notre
  1.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
  1.1740 +      une copie de dépôt distant. Comme nous avons déjà une copie locale, nous
  1.1741 +      pouvons juste faire un clone de celle-ci à la place. C'est beaucoup plus
  1.1742 +      rapide que de faire une copie à travers le réseau, et un dépôt cloné
  1.1743 +      localement prend également moins d'espace disque<footnote>
  1.1744 +      <para id="x_681">L'économie d'espace disque apparait clairement quand les
  1.1745 +        dépôts source et destination sont sur le même système de fichier, où, dans
  1.1746 +        ce cas, Mercurial utilisera des liens physiques pour effectuer des partages
  1.1747 +        copie-lors-des-écritures de ses métadonnées internes. Si cette explication
  1.1748 +        ne signifie rien pour vous, ne vous inquietez pas : tout ceci se passe de
  1.1749 +        manière transparente et automatiquement. Vous n'avez pas du tout besoin de
  1.1750 +        comprendre ceci.</para></footnote>.</para>
  1.1751 +  
  1.1752 +    <!-- BEGIN tour.reclone -->
  1.1753 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.1754 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello my-hello</userinput>
  1.1755 +updating working directory
  1.1756 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.1757 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-hello</userinput>
  1.1758 +</screen>
  1.1759 +<!-- END tour.reclone -->
  1.1760 +
  1.1761 +
  1.1762 +    <para id="x_3a">On notera au passage qu'il est souvent considéré comme
  1.1763 +      une bonne pratique de conserver une copie <quote>immaculée</quote>
  1.1764 +      du dépôt distant, à partir de laquelle vous pourrez faire des 
  1.1765 +      copies locales temporaires pour créer des <quote>bacs à sable</quote> 
  1.1766 +      pour chaque tâche sur laquelle vous souhaitez travailler. Ceci 
  1.1767 +      vous permet de travailler sur plusieurs choses en parallèle, 
  1.1768 +      chacune isolée les unes des autres en attendant que ces tâches 
  1.1769 +      soient finies et que vous soyez prêt à les réintégrer. Parce 
  1.1770 +      que les copies locales sont peu coûteuses, il est très rapide 
  1.1771 +      de créer ou détruire des dépôts dès que vous n'en avez plus
  1.1772 +      besoin.</para>
  1.1773 +
  1.1774 +    <para id="x_3b">Dans notre dépôt <filename class="directory" moreinfo="none">my-hello</filename>, nous avons un fichier
  1.1775 +      <filename moreinfo="none">hello.c</filename> qui contient le classique <quote>hello,
  1.1776 +        world</quote>.</para>
  1.1777 +   
  1.1778 +    <!-- BEGIN tour.cat1 -->
  1.1779 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  1.1780 +/*
  1.1781 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  1.1782 + * not covered by patents in the United States or other countries.
  1.1783 + */
  1.1784 +
  1.1785 +#include &lt;stdio.h&gt;
  1.1786 +
  1.1787 +int main(int argc, char **argv)
  1.1788 +{
  1.1789 +	printf("hello, world!\");
  1.1790 +	return 0;
  1.1791 +}
  1.1792 +</screen>
  1.1793 +<!-- END tour.cat1 -->
  1.1794 +
  1.1795 +
  1.1796 +    <para id="x_682">Editons ce fichier pour qu'il affiche une autre ligne
  1.1797 +      sur la sortie standard.</para>
  1.1798 +    
  1.1799 +    <!-- BEGIN tour.cat2 -->
  1.1800 +<screen format="linespecific"># ... edit edit edit ...
  1.1801 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  1.1802 +/*
  1.1803 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  1.1804 + * not covered by patents in the United States or other countries.
  1.1805 + */
  1.1806 +
  1.1807 +#include &lt;stdio.h&gt;
  1.1808 +
  1.1809 +int main(int argc, char **argv)
  1.1810 +{
  1.1811 +	printf("hello, world!\");
  1.1812 +	printf("hello again!\n");
  1.1813 +	return 0;
  1.1814 +}
  1.1815 +</screen>
  1.1816 +<!-- END tour.cat2 -->
  1.1817 +
  1.1818 +
  1.1819 +    <para id="x_3c">La commande Mercurial <command role="hg-cmd" moreinfo="none">hg
  1.1820 +        status</command> nous dira ce que Mercurial sait des fichiers du
  1.1821 +      dépôts.</para>
  1.1822 +
  1.1823 +    <!-- BEGIN tour.status -->
  1.1824 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls</userinput>
  1.1825 +Makefile  hello.c
  1.1826 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.1827 +M hello.c
  1.1828 +</screen>
  1.1829 +<!-- END tour.status -->
  1.1830 +
  1.1831 +
  1.1832 +    <para id="x_3d">La commande <command role="hg-cmd" moreinfo="none">hg status</command>
  1.1833 +      n'affichera pas le contenu des fichiers, mais une ligne commençant par
  1.1834 +      <quote><literal moreinfo="none">M</literal></quote> pour <filename moreinfo="none">hello.c</filename>.
  1.1835 +      A moins que vous lui demandiez, la commande <command role="hg-cmd" moreinfo="none">hg
  1.1836 +        status</command> n'affichera aucune information sur les fichiers que
  1.1837 +      vous n'avez pas modifiés.</para>
  1.1838 + 
  1.1839 +    <para id="x_3e">Le <quote><literal moreinfo="none">M</literal></quote> indique que
  1.1840 +      Mercurial a remarqué que nous avons modifié le fichier
  1.1841 +      <filename moreinfo="none">hello.c</filename>. Nous n'avons pas besoin
  1.1842 +      <emphasis>d'informer</emphasis> Mercurial que nous allons modifier un
  1.1843 +      fichier avant de commencer à le faire, ou que nous avons modifié un
  1.1844 +      fichier après avoir commencé à le faire, il est capable de découvrir ça
  1.1845 +      tout seul. </para>
  1.1846 +
  1.1847 +    <para id="x_3f">C'est déjà pratique de savoir que nous avons modifié le
  1.1848 +      fichier <filename moreinfo="none">hello.c</filename>, mais nous préférerions savoir
  1.1849 +      exactement <emphasis>ce que</emphasis> nous avons changé. Pour ceci, nous
  1.1850 +      utilisons la commande <command role="hg-cmd" moreinfo="none">hg diff</command>.</para>
  1.1851 +
  1.1852 +    <!-- BEGIN tour.diff -->
  1.1853 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
  1.1854 +diff -r 2278160e78d4 hello.c
  1.1855 +--- a/hello.c	Sat Aug 16 22:16:53 2008 +0200
  1.1856 ++++ b/hello.c	Sun Aug 16 14:05:26 2009 +0000
  1.1857 +@@ -8,5 +8,6 @@
  1.1858 + int main(int argc, char **argv)
  1.1859 + {
  1.1860 + 	printf("hello, world!\");
  1.1861 ++	printf("hello again!\n");
  1.1862 + 	return 0;
  1.1863 + }
  1.1864 +</screen>
  1.1865 +<!-- END tour.diff -->
  1.1866 +
  1.1867 +
  1.1868 +    <tip>
  1.1869 +      <title>Comprendre les patches</title>
  1.1870 +   
  1.1871 +      <para id="x_683">Penser à jeter un oeil à <xref linkend="sec:mq:patch"/> si vous n'arrivez pas à lire la sortie
  1.1872 +        ci-dessus.</para>
  1.1873 +    </tip>
  1.1874 +  </sect1>
  1.1875 +  <sect1>
  1.1876 +    <title>Enregister vos modifications dans une nouvelle révision</title>
  1.1877 +   
  1.1878 +    <para id="x_40">Nous pouvons modifier des fichiers, compiler et tester
  1.1879 +      nos modifications, et utiliser les commandes <command role="hg-cmd" moreinfo="none">hg
  1.1880 +        status</command> et <command role="hg-cmd" moreinfo="none">hg diff</command> pour
  1.1881 +      voir les modifications effectuées, jusqu'à ce que nous soyons assez
  1.1882 +      satisfaits pour décider d'enregistrer notre travail dans un
  1.1883 +      \textit{changeset}.</para>
  1.1884 +
  1.1885 +    <para id="x_41">La commande <command role="hg-cmd" moreinfo="none">hg commit</command>
  1.1886 +      vous laisse créer une nouvelle révision, nous désignerons généralement
  1.1887 +      cette opération par <quote>faire un commit</quote> ou
  1.1888 +      <quote>committer</quote>.</para>
  1.1889 +
  1.1890 +    <sect2>
  1.1891 +    <title>Définir le nom d'utilisateur</title>
  1.1892 +
  1.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
  1.1894 +        pas garanti qu'elle réussisse du premier coup. En effet, Mercurial
  1.1895 +        enregistre votre nom et votre adresse avec chaque modification que
  1.1896 +        vous effectuez, de manière à ce que vous soyez capable (ou d'autres
  1.1897 +        le soient) de savoir qui a fait quelle modification. Mercurial essaye
  1.1898 +        automatiquement de découvrir un nom d'utilisateur qui ait un minimum
  1.1899 +        de sens pour effectuer l'opération de commit avec. Il va essayer
  1.1900 +        chacune des méthodes suivantes, dans l'ordre :</para>
  1.1901 +
  1.1902 +      <orderedlist inheritnum="ignore" continuation="restarts">
  1.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
  1.1904 +            d'utilisateur, ceci aura toujours la priorité sur les autres
  1.1905 +            méthodes ci dessous.</para></listitem>
  1.1906 +        <listitem><para id="x_44">Si vous avez défini une variable
  1.1907 +            d'environnement <envar>HGUSER</envar>, c'est cette valeur qui est
  1.1908 +            alors utilisée.</para></listitem>
  1.1909 +        <listitem><para id="x_45">Si vous créez un fichier nommé <filename role="special" moreinfo="none">.hgrc</filename> dans votre répertoire
  1.1910 +            \textit{home}, avec une entrée <envar role="rc-item-ui">username</envar>, c'est la valeur associée
  1.1911 +            qui sera utilisée. Pour voir à quoi ressemble le contenu de ce
  1.1912 +            fichier regardez la section <xref linkend="sec:tour-basic:username"/>
  1.1913 +            ci-dessous.</para></listitem>
  1.1914 +        <listitem><para id="x_46">Si vous avez défini une variable
  1.1915 +            d'environnement <envar>EMAIL</envar> celle ci sera utilisée
  1.1916 +            ensuite.</para></listitem>
  1.1917 +        <listitem><para id="x_47">Enfin, Mercurial interrogera votre système
  1.1918 +            pour trouver votre nom d'utilisateur local ainsi que le nom de la
  1.1919 +            machine hôte, et il fabriquera un nom d'utilisateur à partir de
  1.1920 +            ces données. Comme il arrive souvent que ce genre de noms soit
  1.1921 +            totalement inutile, il vous préviendra en affichant un message
  1.1922 +            d'avertissement.</para></listitem>
  1.1923 +      </orderedlist>
  1.1924 +   
  1.1925 +      <para id="x_48">Si tous ces mécanismes échouent, Mercurial n'exécutera
  1.1926 +        pas la commande, affichant un message d'erreur. Dans ce cas, il ne
  1.1927 +        vous laissera pas effectuer de commit tant que vous n'aurez pas
  1.1928 +        défini un nom d'utilisateur.</para>
  1.1929 +   
  1.1930 +      <para id="x_49">Vous devriez penser à utiliser la variable
  1.1931 +        d'environement <envar>HGUSER</envar> et l'option <option role="hg-opt-commit">-u</option> comme moyen pour
  1.1932 +        <emphasis>changer</emphasis> le nom d'utilisateur par défaut. Pour
  1.1933 +        une utilisation normale, la manière la plus simple et robuste
  1.1934 +        d'opérer est de créer un fichier <filename role="special" moreinfo="none">.hgrc</filename>, voir ci-dessous pour  les détails
  1.1935 +        à ce sujet.</para>
  1.1936 +
  1.1937 +      <sect3 id="sec:tour-basic:username">
  1.1938 +        <title>Créer un fichier de configuration pour Mercurial</title>
  1.1939 +
  1.1940 +        <para id="x_4a">Pour définir un nom d'utilisateur, utilisez votre 
  1.1941 +          éditeur de texte favori pour créer un fichier <filename role="special" moreinfo="none">.hgrc</filename> dans votre répertoire home. 
  1.1942 +          Mercurial va utiliser ce fichier pour retrouver votre 
  1.1943 +          configuration personnelle. Le contenu initial devrait
  1.1944 +          ressembler à ceci :</para>
  1.1945 +   
  1.1946 +        <tip>
  1.1947 +          <title><quote>Home directory</quote> sous Windows</title>
  1.1948 +   
  1.1949 +          <para id="x_716">Quand on parle de répertoire home, sur une version
  1.1950 +            anglaise d'une installation de Windows, il s'agira habituellement
  1.1951 +            d'un répertoire nommée comme votre nom dans <filename moreinfo="none">C:\Documents 
  1.1952 +              and Settings</filename>. Vous pouvez trouver de quelle répertoire
  1.1953 +            il s'agit en lançant une fenêtre d'interpréteur de commande et en
  1.1954 +            exécutant la commande suivante :</para>
  1.1955 +          
  1.1956 +          <screen format="linespecific"><prompt moreinfo="none">C:\</prompt> <userinput moreinfo="none">echo
  1.1957 +              %UserProfile</userinput></screen>
  1.1958 +        </tip>
  1.1959 +   
  1.1960 +        <programlisting format="linespecific"># This is a Mercurial configuration file.
  1.1961 +[ui]
  1.1962 +username = Firstname Lastname &lt;email.address@domain.net&gt;</programlisting>
  1.1963 +
  1.1964 +        <para id="x_4b">La ligne avec <literal moreinfo="none">[ui]</literal> commence une
  1.1965 +          <emphasis>section</emphasis> du fichier de configuration, ainsi la ligne
  1.1966 +          <quote><literal moreinfo="none">username = ...</literal></quote> signifie <quote>
  1.1967 +            définir la valeur de l'élément <literal moreinfo="none">username</literal> dans la
  1.1968 +            section <literal moreinfo="none">ui</literal></quote>. Une section continue jusqu'à ce
  1.1969 +          qu'une nouvelle commence, ou que la fin du fichier soit atteinte.
  1.1970 +          Mercurial ignore les lignes vides et traite tout texte situé à la suite
  1.1971 +          d'un <quote><literal moreinfo="none">#</literal></quote> jusqu'à la fin de la ligne
  1.1972 +          comme un commentaire.</para>
  1.1973 +
  1.1974 +      </sect3>
  1.1975 +      <sect3>
  1.1976 +        <title>Choisir un nom d'utilisateur</title>
  1.1977 + 
  1.1978 +        <para id="x_4c">Vous pouvez utiliser n'importe quelle valeur 
  1.1979 +          pour votre <literal moreinfo="none">username</literal>, car cette information 
  1.1980 +          est destinée à d'autres personnes et non à être interprétée 
  1.1981 +          par Mercurial. La convention que la plupart des personnes
  1.1982 +          suivent est d'utiliser leurs noms suivies de leurs adresses emails,
  1.1983 +          comme montré ci-dessus :</para>
  1.1984 +        <note>
  1.1985 +          <para id="x_4d">Le mécanisme interne du serveur web intégré à Mercurial,
  1.1986 +            masque les adresses emails, pour rendre plus difficile leurs
  1.1987 +            récupérations par les outils utilisés par les spammmers.
  1.1988 +            Ceci réduit la probabilité que de recevoir encore plus de
  1.1989 +            spam si vous vous publiez un dépôt sur internet.</para>
  1.1990 +        </note>
  1.1991 +      </sect3>
  1.1992 +    </sect2>
  1.1993 +    <sect2>
  1.1994 +      <title>Rédiger un message de \textit{commit}</title>
  1.1995 +  
  1.1996 +      <para id="x_4e">Lorsqu'on effectue une opération de commit, Mercurial
  1.1997 +        lance automatiquement un éditeur de texte pour permettre de saisir
  1.1998 +        un message qui décrira les modifications effectuées dans cette
  1.1999 +        révision. Ce message est nommé le <emphasis>message de commit</emphasis>. 
  1.2000 +        Ce sera un enregistrement pour tout lecteur expliquant le pourquoi 
  1.2001 +        et le comment de vos modifications, et il sera affiché par la 
  1.2002 +        commande <command role="hg-cmd" moreinfo="none">hg log</command>.</para>
  1.2003 + 
  1.2004 +      <!-- BEGIN tour.commit -->
  1.2005 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit</userinput>
  1.2006 +</screen>
  1.2007 +<!-- END tour.commit -->
  1.2008 + 
  1.2009 +  
  1.2010 +      <para id="x_4f">L'éditeur que la commande <command role="hg-cmd" moreinfo="none">hg 
  1.2011 +          commit</command> déclenche ne contiendra qu'une ligne vide suivi 
  1.2012 +        d'un certain nombre de lignes commençant par <quote><literal moreinfo="none">HG:
  1.2013 +        </literal></quote>.</para>
  1.2014 +    
  1.2015 +        <programlisting format="linespecific">
  1.2016 +    This is where I type my commit comment.
  1.2017 +    
  1.2018 +    HG: Enter commit message.  Lines beginning with 'HG:' are removed.
  1.2019 +    HG: --
  1.2020 +    HG: user: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2021 +    HG: branch 'default'
  1.2022 +    HG: changed hello.c</programlisting>
  1.2023 +
  1.2024 +
  1.2025 +      <para id="x_50">Mercurial ignore les lignes qui commencent 
  1.2026 +        avec <quote><literal moreinfo="none">HG:</literal></quote>, il ne les 
  1.2027 +        utilise que pour nous indiquer quels fichiers modifiés il se
  1.2028 +        prépare à \textit{commiter}. Modifier ou effacer ces lignes n'a
  1.2029 +        aucune conséquence sur l'opération de commit.
  1.2030 +      </para>
  1.2031 +
  1.2032 +    </sect2>
  1.2033 +    <sect2>
  1.2034 +      <title>Rédiger un message \textit{approprié}</title>
  1.2035 +  
  1.2036 +      <para id="x_51">Comme <command role="hg-cmd" moreinfo="none">hg log</command> n'affiche
  1.2037 +        que la première ligne du message de commit par défaut, il est souvent
  1.2038 +        considéré comme une bonne pratique de rédiger des messages de commit
  1.2039 +        qui tiennent sur une seule ligne. Voilà un exemple concret de message 
  1.2040 +        de commit qui <emphasis>ne suit pas</emphasis> cette directive, et
  1.2041 +        qui a donc un résumé peu lisible.</para>
  1.2042 +
  1.2043 +      <programlisting format="linespecific">
  1.2044 +changeset:   73:584af0e231be
  1.2045 +user:        Censored Person &lt;censored.person@example.org&gt;
  1.2046 +date:        Tue Sep 26 21:37:07 2006 -0700
  1.2047 +summary:     include buildmeister/commondefs.   Add an exports and install
  1.2048 +      </programlisting>
  1.2049 +  
  1.2050 +      <para id="x_52">A ce sujet, il faut noter qu'il n'existe pas de règle 
  1.2051 +        absolue dans ce domaine. Mercurial lui-même n'interprète pas les 
  1.2052 +        contenus des messages de commit, ainsi votre projet est libre de 
  1.2053 +        concevoir différentes politiques de mise en page des messages.</para>
  1.2054 +      
  1.2055 +      <para id="x_53">Ma préférence personnelle va au message court, mais 
  1.2056 +        informatif, qui offre des précisions supplémentaires par rapport à ce 
  1.2057 +        que pourrait m'apprendre une commande <command role="hg-cmd" moreinfo="none">hg log 
  1.2058 +          --patch</command>.</para>
  1.2059 +      
  1.2060 +      <para id="x_55">Si vous exécutez la commande <command role="hg-cmd" moreinfo="none">hg
  1.2061 +          commit</command> sans aucun argument, elle enregistre tous les 
  1.2062 +        changements qui ont été fait, et qui sont indiqué par les commandes
  1.2063 +        <command role="hg-cmd" moreinfo="none">hg status</command> et  <command role="hg-cmd" moreinfo="none">hg diff</command>.</para>
  1.2064 +      
  1.2065 +      <note>
  1.2066 +        <title>Une surprise pour les utilisateurs habitués à Subversion</title>
  1.2067 +   
  1.2068 +        <para id="x_717">Comme n'importe quel autre commande de Mercurial, si
  1.2069 +          vous soumettez pas de manière explicite les noms des fichiers à
  1.2070 +          committer à la commande <command role="hg-cmd" moreinfo="none">hg commit</command>, elle
  1.2071 +          va travailler sur l'ensemble du répertoire de travail. Soyez conscient
  1.2072 +          de ceci si vous venez du monde Subversion ou CVS, car vous pourriez
  1.2073 +          attendre qu'elle opère uniquement le répertoire courant et ses sous
  1.2074 +          répertoires.</para>
  1.2075 +      </note>
  1.2076 +    </sect2>
  1.2077 +    <sect2>
  1.2078 +      <title>Annuler un \textit{commit}</title>
  1.2079 +
  1.2080 +      <para id="x_54">Si, en rédigeant le message, vous décidez que 
  1.2081 +        finalement vous ne voulez pas effectuer ce commit, il suffit 
  1.2082 +        de quitter simplement l'éditeur sans sauver. Ceci n'aura aucune 
  1.2083 +        conséquence sur le dépôt ou les fichiers du répertoire de 
  1.2084 +        travail.</para>
  1.2085 +    </sect2>
  1.2086 +  
  1.2087 +    <sect2>
  1.2088 +      <title>Admirer votre travail</title>
  1.2089 +  
  1.2090 +      <para id="x_56">Une fois que votre \textit{commit} est terminé, vous
  1.2091 +        pouvez utiliser la commande <command role="hg-cmd" moreinfo="none">hg tip</command>
  1.2092 +        pour afficher le \textit{changeset} que vous venez de créer. Cette
  1.2093 +        commande produit  une sortie à l'écran qui est identique à celle du
  1.2094 +        <command role="hg-cmd" moreinfo="none">hg log</command>, mais qui n'affiche que la
  1.2095 +        dernière révision du dépôt.</para>
  1.2096 + 
  1.2097 +      <!-- BEGIN tour.tip -->
  1.2098 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip -vp</userinput>
  1.2099 +changeset:   5:c94f208d1dfb
  1.2100 +tag:         tip
  1.2101 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2102 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2103 +files:       hello.c
  1.2104 +description:
  1.2105 +Added an extra line of output
  1.2106 +
  1.2107 +
  1.2108 +diff -r 2278160e78d4 -r c94f208d1dfb hello.c
  1.2109 +--- a/hello.c	Sat Aug 16 22:16:53 2008 +0200
  1.2110 ++++ b/hello.c	Sun Aug 16 14:05:26 2009 +0000
  1.2111 +@@ -8,5 +8,6 @@
  1.2112 + int main(int argc, char **argv)
  1.2113 + {
  1.2114 + 	printf("hello, world!\");
  1.2115 ++	printf("hello again!\n");
  1.2116 + 	return 0;
  1.2117 + }
  1.2118 +
  1.2119 +</screen>
  1.2120 +<!-- END tour.tip -->
  1.2121 + 
  1.2122 +  
  1.2123 +      <para id="x_57">On fait couramment référence à la dernière révision 
  1.2124 +        du dépôt comme étant la <emphasis>révision tip</emphasis>, ou plus
  1.2125 +        simplement le <emphasis>tip</emphasis>.</para>
  1.2126 +  
  1.2127 +      <para id="x_684">Au passage, la commande <command role="hg-cmd" moreinfo="none">hg
  1.2128 +          tip</command> accepte la plupart des options qu'accepte 
  1.2129 +        <command role="hg-cmd" moreinfo="none">hg log</command>. Ainsi <option role="hg-opt-global">-v</option> ci dessus implique <quote>soit
  1.2130 +          verbeux</quote>, <option role="hg-opt-tip">-p</option>
  1.2131 +        veux dire <quote>affiche le patch</quote>. L'utilisation de l'option
  1.2132 +        <option role="hg-opt-tip">-p</option> pour afficher un patch est un
  1.2133 +        autre exemple de la cohérence des commandes évoquée plus tôt.</para>
  1.2134 +
  1.2135 +    </sect2>
  1.2136 +  </sect1>
  1.2137 +  <sect1>
  1.2138 +    <title>Partager ses modifications</title>
  1.2139 +
  1.2140 +    <para id="x_58">Nous avons mentionné plus haut que les dépôts 
  1.2141 +      de Mercurial sont autosuffisants. Ce qui signifie que la nouvelle
  1.2142 +      révision que vous venez de créer existe seulement dans votre 
  1.2143 +      répertoire <filename class="directory" moreinfo="none">my-hello</filename>. Étudions 
  1.2144 +      comment propager cette modification dans d'autres dépôts.</para>
  1.2145 +
  1.2146 +    <sect2 id="sec:tour:pull">
  1.2147 +      <title>Récupérer les modifications d'autres dépôts</title>
  1.2148 +
  1.2149 +      <para id="x_59">Pour commencer, construisons un clone de notre dépôt 
  1.2150 +        <filename class="directory" moreinfo="none">hello</filename> qui ne contiendra pas 
  1.2151 +        le changement que nous venons d'effectuer. Nous l'appellerons notre 
  1.2152 +        dépôt temporaire <filename class="directory" moreinfo="none">hello-pull</filename>.</para>
  1.2153 + 
  1.2154 +      <!-- BEGIN tour.clone-pull -->
  1.2155 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.2156 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello hello-pull</userinput>
  1.2157 +updating working directory
  1.2158 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.2159 +</screen>
  1.2160 +<!-- END tour.clone-pull -->
  1.2161 +
  1.2162 + 
  1.2163 +      <para id="x_5a">Nous allons utiliser la commande <command role="hg-cmd" moreinfo="none">hg pull</command> pour envoyer les modifications
  1.2164 +        depuis <filename class="directory" moreinfo="none">my-hello</filename> dans <filename class="directory" moreinfo="none">hello-pull</filename>. Néanmoins, récupérer
  1.2165 +        aveuglement des modifications depuis un dépôt a quelque chose d'un
  1.2166 +        peu effrayant. Mercurial propose donc une commande <command role="hg-cmd" moreinfo="none">hg incoming</command> qui permet de savoir quelles
  1.2167 +        modifications la commande <command role="hg-cmd" moreinfo="none">hg pull</command>
  1.2168 +        <emphasis>pourrait</emphasis> entraîner dans notre dépôt, et ceci
  1.2169 +        sans effectuer réellement de modification dessus.</para>
  1.2170 +
  1.2171 +      <!-- BEGIN tour.incoming -->
  1.2172 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hello-pull</userinput>
  1.2173 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg incoming ../my-hello</userinput>
  1.2174 +comparing with ../my-hello
  1.2175 +searching for changes
  1.2176 +changeset:   5:c94f208d1dfb
  1.2177 +tag:         tip
  1.2178 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2179 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2180 +summary:     Added an extra line of output
  1.2181 +
  1.2182 +</screen>
  1.2183 +<!-- END tour.incoming -->
  1.2184 + 
  1.2185 +  
  1.2186 +      <para id="x_5c">Apporter les modifications rapatriées dans un dépôt se
  1.2187 +        résume donc à exécuter la commande <command role="hg-cmd" moreinfo="none">hg
  1.2188 +          pull</command>, et préciser depuis quel dépôt effectuer le <command role="hg-cmd" moreinfo="none">hg pull</command>.</para>
  1.2189 +      
  1.2190 +      <!-- BEGIN tour.pull -->
  1.2191 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.2192 +changeset:   4:2278160e78d4
  1.2193 +tag:         tip
  1.2194 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2195 +date:        Sat Aug 16 22:16:53 2008 +0200
  1.2196 +summary:     Trim comments.
  1.2197 +
  1.2198 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../my-hello</userinput>
  1.2199 +pulling from ../my-hello
  1.2200 +searching for changes
  1.2201 +adding changesets
  1.2202 +adding manifests
  1.2203 +adding file changes
  1.2204 +added 1 changesets with 1 changes to 1 files
  1.2205 +(run 'hg update' to get a working copy)
  1.2206 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.2207 +changeset:   5:c94f208d1dfb
  1.2208 +tag:         tip
  1.2209 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2210 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2211 +summary:     Added an extra line of output
  1.2212 +
  1.2213 +</screen>
  1.2214 +<!-- END tour.pull -->
  1.2215 +
  1.2216 +  
  1.2217 +      <para id="x_5d">Comme vous le voyez avec une sortie avant et après de la
  1.2218 +        commande <command role="hg-cmd" moreinfo="none">hg tip</command>, nous avons réussi à
  1.2219 +        récupérer aisément les modifications dans notre dépôt. Il reste néanmoins
  1.2220 +        quelque chose à faire avant de placer ces modifications dans l'espace de
  1.2221 +        travail.</para>
  1.2222 +   
  1.2223 +      <tip>
  1.2224 +        <title>Récupérer des changements précis</title>
  1.2225 +   
  1.2226 +        <para id="x_5b">Il est possible à cause du délai entre l'exécution de la
  1.2227 +          commande <command role="hg-cmd" moreinfo="none">hg incoming</command> et l'exécution de
  1.2228 +          la commande <command role="hg-cmd" moreinfo="none">hg pull</command>, que vous ne
  1.2229 +          puissiez pas voir toutes les modifications que vous rapporterez d'un
  1.2230 +          autre dépôt. Supposons que vous récupériez les modifications d'un dépôt
  1.2231 +          situé quelque part sur le réseau. Alors que vous regardez le résultat de
  1.2232 +          la commande <command role="hg-cmd" moreinfo="none">hg incoming</command>, et avant que
  1.2233 +          vous ne décidiez de récupérer ces modifications, quelqu'un peut ajouter
  1.2234 +          de nouvelles révisions dans le dépôt distant. Ce qui signifie que vous
  1.2235 +          récupérez plus de révision que ce que vous aviez regardées en utilisant
  1.2236 +          la commande <command role="hg-cmd" moreinfo="none">hg incoming</command>.</para>
  1.2237 +
  1.2238 +        <para id="x_718">Si vous voulez seulement récupérer ce que vous aviez
  1.2239 +          vérifier à l'aide de la commande <command role="hg-cmd" moreinfo="none">hg
  1.2240 +            incoming</command>, ou que pour d'autres raisons vous souhaitiez ne
  1.2241 +          récupérer qu'un sous ensemble des révisions supplémentaires
  1.2242 +          disponibles, indiquant simplement les modifications que vous souhaitez
  1.2243 +          récupérer par leurs ID de révision, soit <command moreinfo="none">hg pull
  1.2244 +            -r7e95bb</command>. </para>
  1.2245 +      </tip>
  1.2246 +  
  1.2247 +    </sect2>
  1.2248 +    <sect2>
  1.2249 +      <title>Mise à jour de l'espace de travail</title>
  1.2250 +  
  1.2251 +      <para id="x_5e">Nous avons jusqu'à maintenant grossièrement défini la
  1.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 
  1.2253 +        <xref linkend="sec:tour:pull"/> a apporté des modifications, que nous
  1.2254 +        avons vérifiées, dans notre dépôt, mais il n'y a aucune trace de ces
  1.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
  1.2256 +        de travail. C'est la commande <command role="hg-cmd" moreinfo="none">hg update</command>
  1.2257 +        qui s'en charge.</para>
  1.2258 + 
  1.2259 +      <!-- BEGIN tour.update -->
  1.2260 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">grep printf hello.c</userinput>
  1.2261 +	printf("hello, world!\");
  1.2262 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update tip</userinput>
  1.2263 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.2264 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">grep printf hello.c</userinput>
  1.2265 +	printf("hello, world!\");
  1.2266 +	printf("hello again!\n");
  1.2267 +</screen>
  1.2268 +<!-- END tour.update -->
  1.2269 +
  1.2270 +  
  1.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
  1.2272 +        automatiquement. Il y a en fait une très bonne raison à cela : vous
  1.2273 +        pouvez utilisez la commande <command role="hg-cmd" moreinfo="none">hg update</command>
  1.2274 +        pour mettre à jour votre espace de travail à l'état dans lequel il était 
  1.2275 +        à <emphasis>n'importe quelle révision</emphasis> de l'historique du dépôt. 
  1.2276 +        Si vous aviez un espace de travail contenant une ancienne
  1.2277 +        révision—pour chercher l'origine d'un bug, par exemple—et
  1.2278 +        que vous effectuiez un <command role="hg-cmd" moreinfo="none">hg pull</command> qui
  1.2279 +        mettrait à jour automatiquement votre espace de travail, vous ne seriez
  1.2280 +        probablement pas très satisfait.</para>
  1.2281 +  
  1.2282 +      <para id="x_60">Néanmoins, comme les opérations de pull sont très souvent
  1.2283 +        suivies d'un update, Mercurial vous permet de combiner les
  1.2284 +        deux aisément en passant l'option <option role="hg-opt-pull">-u</option> 
  1.2285 +        à la commande <command role="hg-cmd" moreinfo="none">hg pull</command>.</para>
  1.2286 +  
  1.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
  1.2288 +        <option role="hg-opt-pull">-u</option>, vous pouvez constater qu'elle a
  1.2289 +        affiché un rappel assez utile : vous devez encore effectuer une
  1.2290 +        opération pour mettre à jour votre espace de travail.</para>
  1.2291 +
  1.2292 +      <para id="x_62">Pour découvrir sur quelle révision de l'espace de 
  1.2293 +        travail on se trouve, utilisez la commande <command role="hg-cmd" moreinfo="none">hg
  1.2294 +          parents</command>.</para>
  1.2295 + 
  1.2296 +      <!-- BEGIN tour.parents -->
  1.2297 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.2298 +changeset:   5:c94f208d1dfb
  1.2299 +tag:         tip
  1.2300 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2301 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2302 +summary:     Added an extra line of output
  1.2303 +
  1.2304 +</screen>
  1.2305 +<!-- END tour.parents -->
  1.2306 +
  1.2307 +   
  1.2308 +      <para id="x_63">Si vous regardez de nouveau le dessin <xref linkend="fig:tour-basic:history"/>, vous verrez les flèches reliant
  1.2309 +        entre elles les révisions. Le nœud d'où la flèche
  1.2310 +        <emphasis>part</emphasis> est dans chaque cas un parent,
  1.2311 +        et le nœud où la flèche <emphasis>arrive</emphasis> est un
  1.2312 +        enfant.</para>
  1.2313 +
  1.2314 +      <para id="x_64">Pour mettre à jour l'espace de travail d'une révision
  1.2315 +        particulière, indiquez un numéro de révision ou un \textit{changeset
  1.2316 +        ID} à la commande <command role="hg-cmd" moreinfo="none">hg update</command>.</para>
  1.2317 +  
  1.2318 +      <!-- BEGIN tour.older -->
  1.2319 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update 2</userinput>
  1.2320 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.2321 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.2322 +changeset:   2:fef857204a0c
  1.2323 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2324 +date:        Sat Aug 16 22:05:04 2008 +0200
  1.2325 +summary:     Introduce a typo into hello.c.
  1.2326 +
  1.2327 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update</userinput>
  1.2328 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.2329 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.2330 +changeset:   5:c94f208d1dfb
  1.2331 +tag:         tip
  1.2332 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2333 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2334 +summary:     Added an extra line of output
  1.2335 +
  1.2336 +</screen>
  1.2337 +<!-- END tour.older -->
  1.2338 +
  1.2339 +   
  1.2340 +      <para id="x_65">Si vous ne précisez pas de manière explicite de numéro 
  1.2341 +        de révision la commande <command role="hg-cmd" moreinfo="none">hg update</command>
  1.2342 +        mettra à jour votre espace de travail avec le contenu de la révison
  1.2343 +        \textit{tip}, comme montré dans l'exemple ci dessus lors du second
  1.2344 +        appel à <command role="hg-cmd" moreinfo="none">hg update</command>.</para>
  1.2345 +    
  1.2346 +    </sect2>
  1.2347 +    <sect2>
  1.2348 +      <title>Transférer les modifications vers un autre dépôt</title>
  1.2349 +  
  1.2350 +      <para id="x_66">Mercurial vous laisse transférer les modifications vers
  1.2351 +        un autre dépôt, depuis votre dépôt actuel. Comme dans l'exemple du
  1.2352 +        <command role="hg-cmd" moreinfo="none">hg pull</command> ci-dessus, nous allons créer
  1.2353 +        un dépôt temporaire vers lequel transférer nos modifications.</para>
  1.2354 +        
  1.2355 +      <!-- BEGIN tour.clone-push -->
  1.2356 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.2357 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello hello-push</userinput>
  1.2358 +updating working directory
  1.2359 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.2360 +</screen>
  1.2361 +<!-- END tour.clone-push -->
  1.2362 +
  1.2363 +  
  1.2364 +      <para id="x_67">La commande <command role="hg-cmd" moreinfo="none">hg outgoing</command>
  1.2365 +        nous indique quels changements nous allons transférer vers l'autre
  1.2366 +        serveur.</para>
  1.2367 + 
  1.2368 +      <!-- BEGIN tour.outgoing -->
  1.2369 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-hello</userinput>
  1.2370 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg outgoing ../hello-push</userinput>
  1.2371 +comparing with ../hello-push
  1.2372 +searching for changes
  1.2373 +changeset:   5:c94f208d1dfb
  1.2374 +tag:         tip
  1.2375 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2376 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2377 +summary:     Added an extra line of output
  1.2378 +
  1.2379 +</screen>
  1.2380 +<!-- END tour.outgoing -->
  1.2381 +
  1.2382 +  
  1.2383 +      <para id="x_68">Et la commande <command role="hg-cmd" moreinfo="none">hg push</command> 
  1.2384 +        effectue réellement le transfert.</para>
  1.2385 + 
  1.2386 +      <!-- BEGIN tour.push -->
  1.2387 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push ../hello-push</userinput>
  1.2388 +pushing to ../hello-push
  1.2389 +searching for changes
  1.2390 +adding changesets
  1.2391 +adding manifests
  1.2392 +adding file changes
  1.2393 +added 1 changesets with 1 changes to 1 files
  1.2394 +</screen>
  1.2395 +<!-- END tour.push -->
  1.2396 +
  1.2397 +  
  1.2398 +      <para id="x_69">Comme avec <command role="hg-cmd" moreinfo="none">hg pull</command>, la
  1.2399 +        commande <command role="hg-cmd" moreinfo="none">hg push</command> ne met pas à jour
  1.2400 +        le répertoire de travail du dépôt dans lequel il transfère les
  1.2401 +        modifications. À l'inverse de <command role="hg-cmd" moreinfo="none">hg
  1.2402 +          pull</command>, <command role="hg-cmd" moreinfo="none">hg push</command> ne fournit
  1.2403 +        pas d'option <literal moreinfo="none">-u</literal> pour forcer la mise à jour de
  1.2404 +        l'espace de travail cible. Cette asymétrie est délibéré : le dépot
  1.2405 +        vers lequel nous transférons peut très bien être un serveur distant
  1.2406 +        et partagé par plusieurs personnes. Si nous devions mettre à jour son
  1.2407 +        répertoire de travail alors que quelqu'un d'autre travaille dessus,
  1.2408 +        nous risquerions de perturber son travail.</para>
  1.2409 +  
  1.2410 +      <para id="x_6a">Qu'est ce qui se passe lorsque vous essayez de récupérer
  1.2411 +        ou de transférer vos modifications et que le dépôt cible a déjà reçu
  1.2412 +        ces modifications ? Rien de bien excitant.</para>
  1.2413 + 
  1.2414 +      <!-- BEGIN tour.push.nothing -->
  1.2415 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push ../hello-push</userinput>
  1.2416 +pushing to ../hello-push
  1.2417 +searching for changes
  1.2418 +no changes found
  1.2419 +</screen>
  1.2420 +<!-- END tour.push.nothing -->
  1.2421 +
  1.2422 +  
  1.2423 +    </sect2>
  1.2424 +  
  1.2425 +    <sect2>
  1.2426 +      <title>Emplacements par défaut</title>
  1.2427 +
  1.2428 +      <para id="x_719">Quand nous faisons un clone d'un dépôt, Mercurial
  1.2429 +        enregistre l'emplacement du dépôt d'origine dans le fichier
  1.2430 +        <filename moreinfo="none">.hg/hgrc</filename> de notre nouveau dépôt. Si nous ne
  1.2431 +        fournissons pas d'emplacement à la commande <command moreinfo="none">hg
  1.2432 +          pull</command> ou à la commande <command moreinfo="none">hg push</command>, ces
  1.2433 +        commandes utiliseront alors cet emplacement comme valeur par défaut.
  1.2434 +        Les commandes <command moreinfo="none">hg incoming</command> et <command moreinfo="none">hg
  1.2435 +          outgoing</command> feront de même.</para>
  1.2436 +  
  1.2437 +      <para id="x_71a">Si vous regardez le fichier
  1.2438 +        <filename moreinfo="none">.hg/hgrc</filename>, vous constaterez que son contenu
  1.2439 +        ressemble à ce qui suit.</para>
  1.2440 +  
  1.2441 +      <programlisting format="linespecific">[paths]
  1.2442 +default = http://www.selenic.com/repo/hg</programlisting>
  1.2443 +      
  1.2444 +      <para id="x_71b">Il est possible—et souvent
  1.2445 +        pratique—d'avoir un emplacement par défaut pour les commandes
  1.2446 +        <command moreinfo="none">hg push</command> et <command moreinfo="none">hg outgoing</command>
  1.2447 +        différent de celui des commandes <command moreinfo="none">hg pull</command> et
  1.2448 +        <command moreinfo="none">hg incoming</command>. C'est faisable en ajoutant une entrée
  1.2449 +        <literal moreinfo="none">default-push</literal> à la section
  1.2450 +        <literal moreinfo="none">[paths]</literal> du <filename moreinfo="none">.hg/hgrc</filename>, comme
  1.2451 +        suit.</para>
  1.2452 +   
  1.2453 +      <programlisting format="linespecific">[paths]
  1.2454 +default = http://www.selenic.com/repo/hg
  1.2455 +default-push = http://hg.example.com/hg</programlisting>
  1.2456 +
  1.2457 +    </sect2>
  1.2458 +    <sect2>
  1.2459 +      <title>Partager ses modifications à travers le réseau</title>
  1.2460 +  
  1.2461 +      <para id="x_6b">Les commandes que nous avons étudiées dans les sections
  1.2462 +        précédentes ne sont pas limitées aux dépôts locaux. Chacune fonctionne 
  1.2463 +        de la même manière à travers une connexion réseau, il suffit de lui 
  1.2464 +        passer une URL à la place d'un chemin de fichier local.</para>
  1.2465 + 
  1.2466 +      <!-- BEGIN tour.outgoing.net -->
  1.2467 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg outgoing http://hg.serpentine.com/tutorial/hello</userinput>
  1.2468 +comparing with http://hg.serpentine.com/tutorial/hello
  1.2469 +searching for changes
  1.2470 +changeset:   5:c94f208d1dfb
  1.2471 +tag:         tip
  1.2472 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2473 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2474 +summary:     Added an extra line of output
  1.2475 +
  1.2476 +</screen>
  1.2477 +<!-- END tour.outgoing.net -->
  1.2478 +
  1.2479 +  
  1.2480 +      <para id="x_6c">Dans cet exemple, nous allons voir quels changements 
  1.2481 +        nous pourrions transférer vers le dépôt distant, mais le dépôt est, 
  1.2482 +        de manière tout à fait compréhensible, pas configuré pour accepter 
  1.2483 +        des modifications d'utilisateurs anonymes.</para>
  1.2484 + 
  1.2485 +      <!-- BEGIN tour.push.net -->
  1.2486 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push http://hg.serpentine.com/tutorial/hello</userinput>
  1.2487 +pushing to http://hg.serpentine.com/tutorial/hello
  1.2488 +searching for changes
  1.2489 +ssl required
  1.2490 +</screen>
  1.2491 +<!-- END tour.push.net -->
  1.2492 + 
  1.2493 +    
  1.2494 +    </sect2>
  1.2495 +
  1.2496 +  </sect1>
  1.2497 +
  1.2498 +  <sect1>
  1.2499 +    <title>Commencer un nouveau projet</title>
  1.2500 +
  1.2501 +    <para id="x_71c">Il est tout aussi aisé de commencer un nouveau projet
  1.2502 +      que de travailler sur un qui existe déjà. La commande <command moreinfo="none">hg
  1.2503 +        init</command> crée un nouveau dépôt Mercurial vide.</para>
  1.2504 +
  1.2505 +    <!-- BEGIN ch01/new.init -->
  1.2506 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init myproject</userinput>
  1.2507 +</screen>
  1.2508 +<!-- END ch01/new.init -->
  1.2509 +
  1.2510 +
  1.2511 +    <para id="x_71d">Ceci crée simplement un répertoire nommé
  1.2512 +      <filename moreinfo="none">myproject</filename> dans le répertoire courant.</para>
  1.2513 +
  1.2514 +    <!-- BEGIN ch01/new.ls -->
  1.2515 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -l</userinput>
  1.2516 +total 12
  1.2517 +-rw-r--r-- 1 rpelisse rpelisse   47 Aug 16 14:04 goodbye.c
  1.2518 +-rw-r--r-- 1 rpelisse rpelisse   45 Aug 16 14:04 hello.c
  1.2519 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:04 myproject
  1.2520 +</screen>
  1.2521 +<!-- END ch01/new.ls -->
  1.2522 +
  1.2523 +
  1.2524 +    <para id="x_71e">Nous pouvons dire que <filename moreinfo="none">myproject</filename> est
  1.2525 +      un dépôt Mercurial car il contient un répertoire
  1.2526 +      <filename moreinfo="none">.hg</filename>.</para>
  1.2527 +
  1.2528 +    <!-- BEGIN ch01/new.ls2 -->
  1.2529 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls -al myproject</userinput>
  1.2530 +total 12
  1.2531 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:04 .
  1.2532 +drwx------ 3 rpelisse rpelisse 4096 Aug 16 14:04 ..
  1.2533 +drwxr-xr-x 3 rpelisse rpelisse 4096 Aug 16 14:04 .hg
  1.2534 +</screen>
  1.2535 +<!-- END ch01/new.ls2 -->
  1.2536 +
  1.2537 +
  1.2538 +    <para id="x_71f">Si vous voulons ajouter quelques fichiers préexistants
  1.2539 +      dans ce dépôt, il suffit de les recopier dans le répertoire de travail,
  1.2540 +      et demander à Mercurial de commencer à les suivre en utilisant la
  1.2541 +      commande <command moreinfo="none">hg add</command>.</para>
  1.2542 +
  1.2543 +    <!-- BEGIN ch01/new.add -->
  1.2544 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myproject</userinput>
  1.2545 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cp ../hello.c .</userinput>
  1.2546 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cp ../goodbye.c .</userinput>
  1.2547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add</userinput>
  1.2548 +adding goodbye.c
  1.2549 +adding hello.c
  1.2550 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.2551 +A goodbye.c
  1.2552 +A hello.c
  1.2553 +</screen>
  1.2554 +<!-- END ch01/new.add -->
  1.2555 +
  1.2556 +
  1.2557 +    <para id="x_720">Une fois que nous sommes satisfaits de notre projet,
  1.2558 +      nous pouvons commencer à ajouter nos révisions.</para>
  1.2559 +
  1.2560 +    <!-- BEGIN ch01/new.commit -->
  1.2561 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Initial commit'</userinput>
  1.2562 +</screen>
  1.2563 +<!-- END ch01/new.commit -->
  1.2564 +
  1.2565 +
  1.2566 +    <para id="x_721">Il ne prend que quelques instants pour commencer à
  1.2567 +      utiliser Mercurial sur un nouveau projet, ce qui fait aussi de ses
  1.2568 +      points forts. Travailler avec une gestion de révision devient très
  1.2569 +      facile, nous pouvons même l'utiliser pour les plus petits projets où
  1.2570 +      nous aurions probablement jamais penser utiliser un outils aussi
  1.2571 +      complexe.</para>
  1.2572 +  </sect1>
  1.2573 +</chapter>
  1.2574 +
  1.2575 +<!--
  1.2576 +local variables: 
  1.2577 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.2578 +end:
  1.2579 +-->
  1.2580 +
  1.2581 +  <!-- BEGIN ch03 -->
  1.2582 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.2583 +
  1.2584 +<chapter id="chap:tour-merge">
  1.2585 +  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
  1.2586 +  <title>Un rapide tour de Mercurial: fusionner les travaux</title>
  1.2587 +  
  1.2588 +  <para id="x_338">Nous avons maintenant étudié comment cloner un dépôt, effectuer
  1.2589 +    des changements dedans, et récupérer ou transférer depuis un
  1.2590 +    autre dépôt. La prochaine étape est donc de <emphasis>fusionner</emphasis> les
  1.2591 +    modifications de différents dépôts.</para>
  1.2592 +
  1.2593 +  <sect1>
  1.2594 +    <title>Fusionner différents travaux</title>
  1.2595 +      <para id="x_339">La fusion  est un aspect fondamental lorsqu'on
  1.2596 +      travaille iavec un gestionnaire de source distribué.</para>
  1.2597 +
  1.2598 +      <itemizedlist>
  1.2599 +        <listitem>
  1.2600 +          <para id="x_33a">Alice et Bob ont chacun une copie personnelle du dépôt d'un
  1.2601 +            projet sur lequel ils collaborent. Alice corrige un bug
  1.2602 +            dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
  1.2603 +            sien. Ils veulent un dépôt partagé avec à la fois le correctif du
  1.2604 +            bug et la nouvelle fonctionnalité.</para>
  1.2605 +       </listitem>
  1.2606 +       <listitem>
  1.2607 +         <para id="x_33b">Je travaille régulièrement sur plusieurs tâches différentes sur
  1.2608 +           un seul projet en même temps, chacun isolé dans son propre dépôt.
  1.2609 +           Travailler ainsi signifie que je dois régulièrement fusionner une
  1.2610 +           partie de mon code avec celui des autres.</para>
  1.2611 +       </listitem>
  1.2612 +     </itemizedlist>
  1.2613 +
  1.2614 +     <para id="x_33c">Parce que la fusion est une opération si commune à réaliser,
  1.2615 +       Mercurial la rend facile. Étudions ensemble le déroulement des
  1.2616 +       opérations. Nous commencerons encore par faire un clone d'un autre
  1.2617 +       dépôt (vous voyez que l'on fait ça tout le temps ?) puis nous ferons 
  1.2618 +       quelques modifications dessus.</para>
  1.2619 +       
  1.2620 +       <!-- BEGIN tour.merge.clone -->
  1.2621 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.2622 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hello my-new-hello</userinput>
  1.2623 +updating working directory
  1.2624 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.2625 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-new-hello</userinput>
  1.2626 +# Make some simple edits to hello.c.
  1.2627 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">my-text-editor hello.c</userinput>
  1.2628 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'A new hello for a new day.'</userinput>
  1.2629 +</screen>
  1.2630 +<!-- END tour.merge.clone -->
  1.2631 +
  1.2632 +       
  1.2633 +     <para id="x_33d">Nous devrions avoir maintenant deux copies de
  1.2634 +       <filename moreinfo="none">hello.c</filename> avec des contenus différents. Les
  1.2635 +       historiques de ces deux dépôts ont aussi divergés, comme illustré dans
  1.2636 +       la figure <xref linkend="fig:tour-merge:sep-repos"/>.</para>
  1.2637 +
  1.2638 +      <!-- BEGIN tour.merge.cat1 -->
  1.2639 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  1.2640 +/*
  1.2641 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  1.2642 + * not covered by patents in the United States or other countries.
  1.2643 + */
  1.2644 +
  1.2645 +#include &lt;stdio.h&gt;
  1.2646 +
  1.2647 +int main(int argc, char **argv)
  1.2648 +{
  1.2649 +	printf("once more, hello.\n");
  1.2650 +	printf("hello, world!\");
  1.2651 +	printf("hello again!\n");
  1.2652 +	return 0;
  1.2653 +}
  1.2654 +</screen>
  1.2655 +<!-- END tour.merge.cat1 -->
  1.2656 +
  1.2657 +     
  1.2658 +     <para id="x_722">Et ici est notre légèrement différente version du
  1.2659 +       dépôt.</para>
  1.2660 +     
  1.2661 +      <!-- BEGIN tour.merge.cat2 -->
  1.2662 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat ../my-hello/hello.c</userinput>
  1.2663 +/*
  1.2664 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  1.2665 + * not covered by patents in the United States or other countries.
  1.2666 + */
  1.2667 +
  1.2668 +#include &lt;stdio.h&gt;
  1.2669 +
  1.2670 +int main(int argc, char **argv)
  1.2671 +{
  1.2672 +	printf("hello, world!\");
  1.2673 +	printf("hello again!\n");
  1.2674 +	return 0;
  1.2675 +}
  1.2676 +</screen>
  1.2677 +<!-- END tour.merge.cat2 -->
  1.2678 +
  1.2679 +     
  1.2680 +     <figure id="fig:tour-merge:sep-repos" float="0">
  1.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>
  1.2682 +       <mediaobject>
  1.2683 +         <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
  1.2684 +         <textobject><phrase>XXX ajoute un test</phrase></textobject>
  1.2685 +       </mediaobject>
  1.2686 +     </figure>
  1.2687 +
  1.2688 +     <para id="x_33f">Nous savons déjà que récupérer les modifications depuis
  1.2689 +       notre dépôt <filename class="directory" moreinfo="none">my-hello</filename> n'aura
  1.2690 +       aucun effet sur l'espace de travail.</para>
  1.2691 +
  1.2692 +      <!-- BEGIN tour.merge.pull -->
  1.2693 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../my-hello</userinput>
  1.2694 +pulling from ../my-hello
  1.2695 +searching for changes
  1.2696 +adding changesets
  1.2697 +adding manifests
  1.2698 +adding file changes
  1.2699 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.2700 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.2701 +</screen>
  1.2702 +<!-- END tour.merge.pull -->
  1.2703 +
  1.2704 +
  1.2705 +     <para id="x_340">Néanmoins, la commande <command role="hg-cmd" moreinfo="none">hg
  1.2706 +       pull</command> nous indique quelque chose au sujet des 
  1.2707 +       <quote>heads</quote>.</para>
  1.2708 +
  1.2709 +     <sect2>
  1.2710 +       <title>Les révisions 'heads'</title>
  1.2711 +
  1.2712 +       <para id="x_341">Rappellez vous que Mercurial enregistre quelle révision
  1.2713 +         est le parent de chaque révision. Si une révision a un parent, nous
  1.2714 +         l'appelons un enfant(child) ou un descendant de ce parent. Une
  1.2715 +         "head" est une révision qui n'a donc pas d'enfant. La révision tip
  1.2716 +         est donc une "head", car c'est la révision la plus récente du dépôt
  1.2717 +         qui n'a pas d'enfant. Il y a des moments où un dépôt peut contenir
  1.2718 +         plusieurs "head".</para>
  1.2719 +
  1.2720 +       <figure id="fig:tour-merge:pull" float="0">
  1.2721 +         <title>Contenu du dépôt après une récupération ("pull") depuis le
  1.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>
  1.2723 +         <mediaobject>
  1.2724 +           <imageobject>
  1.2725 +             <imagedata fileref="tour-merge-pull"/>
  1.2726 +           </imageobject>
  1.2727 +           <textobject><phrase>XXX ajoute un texte</phrase></textobject>
  1.2728 +         </mediaobject>
  1.2729 +       </figure>
  1.2730 +
  1.2731 +       <para id="x_343">Dans la figure <xref linkend="fig:tour-merge:pull"/>,
  1.2732 +         vous pouvez constater l'effet d'un \textit{pull} depuis le dépôt
  1.2733 +         <filename class="directory" moreinfo="none">my-hello</filename> dans le dépôt
  1.2734 +         <filename class="directory" moreinfo="none">my-new-hello</filename>. L'historique qui
  1.2735 +         était déjà présent dans le dépôt <filename class="directory" moreinfo="none">my-new-hello</filename> reste intact, mais une
  1.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
  1.2737 +         <emphasis>ID de révision (changeset ID)</emphasis> reste le même dans
  1.2738 +         le nouveau dépôt, mais que le <emphasis>numéro de
  1.2739 +         révision</emphasis> reste le même. (Ceci est un parfait exemple de
  1.2740 +         pourquoi il n'est fiable d'utiliser les numéros de révision lorsque
  1.2741 +         l'on discute d'un \textit{changeset}.) Vous pouvez voir les "heads"
  1.2742 +         présentes dans le dépôt en utilisant la commande <command role="hg-cmd" moreinfo="none">hg heads</command>.</para>
  1.2743 +
  1.2744 +        <!-- BEGIN tour.merge.heads -->
  1.2745 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  1.2746 +changeset:   6:c94f208d1dfb
  1.2747 +tag:         tip
  1.2748 +parent:      4:2278160e78d4
  1.2749 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2750 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2751 +summary:     Added an extra line of output
  1.2752 +
  1.2753 +changeset:   5:5f06f94fbeca
  1.2754 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2755 +date:        Sun Aug 16 14:05:31 2009 +0000
  1.2756 +summary:     A new hello for a new day.
  1.2757 +
  1.2758 +</screen>
  1.2759 +<!-- END tour.merge.heads -->
  1.2760 +
  1.2761 +      </sect2>
  1.2762 +
  1.2763 +      <sect2>
  1.2764 +        <title>Effectuer la fusion</title>
  1.2765 +
  1.2766 +        <para id="x_344">Que se passe-t-il quand vous essayez d'utiliser la
  1.2767 +          commande <command role="hg-cmd" moreinfo="none">hg update</command> pour mettre à
  1.2768 +          jour votre espace de travail au nouveau "tip"</para>
  1.2769 +         
  1.2770 +         <!-- BEGIN tour.merge.update -->
  1.2771 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update</userinput>
  1.2772 +abort: crosses branches (use 'hg merge' or 'hg update -C')
  1.2773 +</screen>
  1.2774 +<!-- END tour.merge.update -->
  1.2775 +
  1.2776 +
  1.2777 +         
  1.2778 +        <para id="x_345">Mercurial nous prévient que la commande <command role="hg-cmd" moreinfo="none">hg update</command> n'effectuera pas
  1.2779 +          la fusion, il ne veut pas mettre à jour l'espace de travail quand il
  1.2780 +          estime que nous pourrions avoir besoin d'une fusion, à moins de lui
  1.2781 +          forcer la main. À la place, il faut utiliser la commande <command role="hg-cmd" moreinfo="none">hg merge</command> pour fusionner les deux
  1.2782 +          "heads".</para>
  1.2783 +
  1.2784 +       <para id="x_723">Pour commencer une fusion (merge) entre deux "heads",
  1.2785 +       nous utilisons la commande <command role="hg-cmd" moreinfo="none">hg merge</command>.</para>
  1.2786 +
  1.2787 +        <!-- BEGIN tour.merge.merge -->
  1.2788 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.2789 +merging hello.c
  1.2790 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  1.2791 +(branch merge, don't forget to commit)
  1.2792 +</screen>
  1.2793 +<!-- END tour.merge.merge -->
  1.2794 + 
  1.2795 +      
  1.2796 +       <para id="x_347">Nous résolvons les conflits dans le fichier
  1.2797 +         <filename moreinfo="none">hello.c</filename>. Ceci met à jour le répertoire de travail
  1.2798 +         de sorte qu'il ne contienne les modifications ne provenance des
  1.2799 +         <emphasis>deux</emphasis> "heads", ce qui est indiqué par la
  1.2800 +         la sortie de la commande <command role="hg-cmd" moreinfo="none">hg
  1.2801 +         parents</command> et le contenu du fichier
  1.2802 +         <filename moreinfo="none">hello.c</filename>.</para>
  1.2803 +
  1.2804 +        <!-- BEGIN tour.merge.parents -->
  1.2805 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.2806 +changeset:   5:5f06f94fbeca
  1.2807 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2808 +date:        Sun Aug 16 14:05:31 2009 +0000
  1.2809 +summary:     A new hello for a new day.
  1.2810 +
  1.2811 +changeset:   6:c94f208d1dfb
  1.2812 +tag:         tip
  1.2813 +parent:      4:2278160e78d4
  1.2814 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2815 +date:        Sun Aug 16 14:05:26 2009 +0000
  1.2816 +summary:     Added an extra line of output
  1.2817 +
  1.2818 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat hello.c</userinput>
  1.2819 +/*
  1.2820 + * Placed in the public domain by Bryan O'Sullivan.  This program is
  1.2821 + * not covered by patents in the United States or other countries.
  1.2822 + */
  1.2823 +
  1.2824 +#include &lt;stdio.h&gt;
  1.2825 +
  1.2826 +int main(int argc, char **argv)
  1.2827 +{
  1.2828 +	printf("once more, hello.\n");
  1.2829 +	printf("hello, world!\");
  1.2830 +	printf("hello again!\n");
  1.2831 +	return 0;
  1.2832 +}
  1.2833 +</screen>
  1.2834 +<!-- END tour.merge.parents -->
  1.2835 +
  1.2836 +     </sect2>
  1.2837 +
  1.2838 +     <sect2>
  1.2839 +       <title>Effectuer l'ajout (commit) du résultat de la fusion</title>
  1.2840 +
  1.2841 +       <para id="x_348">Dès l'instant où vous avez effectué une fusion
  1.2842 +         (merge), <command role="hg-cmd" moreinfo="none">hg parents</command> vous
  1.2843 +         affichera deux parents, avant que vous n'exécutiez la commande
  1.2844 +         <command role="hg-cmd" moreinfo="none">hg commit</command> sur le résultat de la
  1.2845 +         fusion.</para>
  1.2846 +
  1.2847 +        <!-- BEGIN tour.merge.commit -->
  1.2848 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Merged changes'</userinput>
  1.2849 +</screen>
  1.2850 +<!-- END tour.merge.commit -->
  1.2851 +
  1.2852 +
  1.2853 +      <para id="x_349">Nous avons maintenant un nouveau tip, remarquer qu'il
  1.2854 +        contient <emphasis>à la fois</emphasis> nos anciennes "heads" et leurs
  1.2855 +        parents. Ce sont les mêmes révisions que nous avions affichées avec
  1.2856 +        la commande <command role="hg-cmd" moreinfo="none">hg parents</command>.</para>
  1.2857 +
  1.2858 +       <!-- BEGIN tour.merge.tip -->
  1.2859 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.2860 +changeset:   7:b8e1e756ef55
  1.2861 +tag:         tip
  1.2862 +parent:      5:5f06f94fbeca
  1.2863 +parent:      6:c94f208d1dfb
  1.2864 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.2865 +date:        Sun Aug 16 14:05:33 2009 +0000
  1.2866 +summary:     Merged changes
  1.2867 +
  1.2868 +</screen>
  1.2869 +<!-- END tour.merge.tip -->
  1.2870 +
  1.2871 +
  1.2872 +      <para id="x_34a">Dans la figure <xref linkend="fig:tour-merge:merge"/>,
  1.2873 +        vous pouvez voir une représentation de ce qui se passe dans l'espace
  1.2874 +        de travail pendant la fusion, et comment ceci affecte le dépôt lors
  1.2875 +        du "commit". Pendant la fusion, l'espace de travail, qui a deux
  1.2876 +        révisions (changesets) comme parents, voit ces derniers devenir le parent
  1.2877 +        d'une nouvelle révision (changeset).</para>
  1.2878 +
  1.2879 +      <figure id="fig:tour-merge:merge" float="0">
  1.2880 +        <title>Working directory and repository during merge, and
  1.2881 +          following commit</title>
  1.2882 +        <mediaobject>
  1.2883 +          <imageobject>
  1.2884 +            <imagedata fileref="figs/tour-merge-merge.png"/>
  1.2885 +          </imageobject>
  1.2886 +          <textobject><phrase>XXX ajoute texte</phrase></textobject>
  1.2887 +        </mediaobject>
  1.2888 +      </figure>
  1.2889 +
  1.2890 +    </sect2>
  1.2891 +  </sect1>
  1.2892 +
  1.2893 +  <sect1>
  1.2894 +    <title>Fusionner les modifications en conflit</title>
  1.2895 +
  1.2896 +    <para id="x_34b">La plupart des fusions sont assez simple à réaliser, mais 
  1.2897 +      parfois vous vous retrouverez à fusionner des fichiers où la modification 
  1.2898 +      touche la même portion de code, au sein d'un même fichier. À moins 
  1.2899 +      que ces modification ne soient identiques, ceci aboutira à un 
  1.2900 +      <emphasis>conflit</emphasis>, et vous devrez décider comment réconcilier 
  1.2901 +      les différentes modifications dans un tout cohérent.</para>
  1.2902 +
  1.2903 +    <figure id="fig:tour-merge:conflict" float="0">
  1.2904 +      <title>Modifications en conflits dans un document</title>
  1.2905 +      <mediaobject>
  1.2906 +        <imageobject><imagedata fileref="tour-merge-conflict"/></imageobject>
  1.2907 +        <textobject><phrase>XXX ajoute texte</phrase></textobject>
  1.2908 +      </mediaobject>
  1.2909 +    </figure>
  1.2910 +
  1.2911 +    <para id="x_34d">La figure <xref linkend="fig:tour-merge:conflict"/>
  1.2912 +      illustre un cas de modifications conflictuelles dans un document. Nous
  1.2913 +      avons commencé avec une version simple de ce fichier, puis nous avons
  1.2914 +      ajouté des modifications, pendant que quelqu'un d'autre modifiait le même
  1.2915 +      texte. Notre tâche dans la résolution du conflit est de décider à quoi le
  1.2916 +      fichier devrait ressembler.</para>
  1.2917 +
  1.2918 +    <para id="x_34e">Mercurial n'a pas de mécanisme interne pour gérer 
  1.2919 +      les conflits. À la place, il exécute un programme externe appelé 
  1.2920 +      <command moreinfo="none">hgmerge</command>. Il s'agit d'un script shell qui est 
  1.2921 +      embarqué par Mercurial, vous pouvez le modifier si vous le voulez. 
  1.2922 +      Ce qu'il fait par défaut est d'essayer de trouver un des différents 
  1.2923 +      outils de fusion qui seront probablement installés sur le système. 
  1.2924 +      Il commence par les outils totalement automatiques, et si ils 
  1.2925 +      échouent (parce que la résolution du conflit nécessite une
  1.2926 +      intervention humaine) ou si ils sont absents, le script tente
  1.2927 +      d'exécuter certains outils graphiques de fusion.</para>
  1.2928 +
  1.2929 +    <para id="x_34f">Il est aussi possible de demander à Mercurial d'exécuter
  1.2930 +      un autre programme ou un autre script en définissant la variable
  1.2931 +      d'environnement <envar>HGMERGE</envar> avec le nom
  1.2932 +      du programme de votre choix.</para>
  1.2933 +
  1.2934 +    <sect2>
  1.2935 +      <title>Utiliser un outil graphique de fusion</title>
  1.2936 +
  1.2937 +      <para id="x_350">Mon outil de fusion préféré est
  1.2938 +      <command moreinfo="none">kdiff3</command>, que j'utilise ici pour illustrer les
  1.2939 +        fonctionnalités classiques des outils graphiques de fusion. Vous pouvez
  1.2940 +        voir une capture d'écran de l'utilisation de <command moreinfo="none">kdiff3</command>
  1.2941 +        dans la figure <xref linkend="fig:tour-merge:kdiff3"/>. Cet outil
  1.2942 +        effectue une <emphasis>fusion \textit{three-way</emphasis>}, car il y a
  1.2943 +        trois différentes versions du fichier qui nous intéresse. Le fichier
  1.2944 +        découpe la partie supérieure de la fenêtre en trois panneaux:</para>
  1.2945 +      <itemizedlist>
  1.2946 +        <listitem><para id="x_351">A gauche on la version de
  1.2947 +          <emphasis>base</emphasis> du fichier, soit la plus récente version
  1.2948 +          des deux versions qu'on souhaite fusionner.</para></listitem>
  1.2949 +        <listitem><para id="x_352">Au centre, il y a <quote>notre</quote>
  1.2950 +          version du fichier, avec le contenu que nous avons modifié.</para></listitem>
  1.2951 +        <listitem><para id="x_353">Sur la droite, on trouve
  1.2952 +        <quote>leur</quote> version du fichier, celui qui contient la
  1.2953 +        révision que nous souhaitons intégré.</para>
  1.2954 +        </listitem></itemizedlist>
  1.2955 +      <para id="x_354">Dans le panneau en dessous, on trouve le
  1.2956 +        <emphasis>résultat</emphasis> actuel de notre fusion. Notre tâche
  1.2957 +        consiste donc à remplacement tous les textes en rouges,
  1.2958 +        qui indiquent des conflits non résolus, avec une fusion manuelle et 
  1.2959 +        pertinente de <quote>notre</quote> version et de la <quote>leur</quote>.
  1.2960 +      </para>
  1.2961 +
  1.2962 +      <para id="x_355">Tous les quatre panneaux sont <emphasis>accrochés ensemble</emphasis>, 
  1.2963 +        si nous déroulons les ascenseurs verticalement ou horizontalement dans chacun 
  1.2964 +        d'entre eux, les autres sont mis à jour avec la section correspondante dans leurs 
  1.2965 +        fichiers respectifs.</para>
  1.2966 +
  1.2967 +      <figure id="fig:tour-merge:kdiff3" float="0">
  1.2968 +        <title>Utiliser <command moreinfo="none">kdiff3</command> pour fusionner les
  1.2969 +          différentes version d'un fichier.</title>
  1.2970 +        <mediaobject>
  1.2971 +          <imageobject>
  1.2972 +            <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
  1.2973 +            <textobject>
  1.2974 +              <phrase>XXX ajoute texte</phrase>
  1.2975 +            </textobject>
  1.2976 +          </mediaobject>
  1.2977 +       </figure>
  1.2978 +
  1.2979 +       <para id="x_357">Pour chaque portion de fichier posant problème, nous
  1.2980 +         pouvons choisir de résoudre le conflit en utilisant une combinaison de
  1.2981 +         texte depuis la version de base, la notre, ou la leur. Nous pouvons
  1.2982 +         aussi éditer manuellement les fichiers à tout moment, si c'est nécessaire.</para>
  1.2983 +
  1.2984 +       <para id="x_358">Il y a <emphasis>beaucoup</emphasis> d'outils de
  1.2985 +         fusion disponibles, bien trop pour en parler de tous ici. Leurs
  1.2986 +         disponibilités varient selon les plate formes  ainsi que leurs
  1.2987 +         avantages et inconvénients. La plupart sont optimisé pour
  1.2988 +         la fusion de fichier contenant un texte plat, certains sont spécialisé
  1.2989 +         dans un format de fichier précis (généralement XML).</para>
  1.2990 +    </sect2>
  1.2991 +
  1.2992 +    <sect2>
  1.2993 +      <title>Un exemple concret</title>
  1.2994 +
  1.2995 +      <para id="x_359">Dans cet exemple, nous allons reproduire la
  1.2996 +        modification de l'historique du fichier de la figure <xref linkend="fig:tour-merge:conflict"/> ci dessus. Commençons par créer
  1.2997 +        un dépôt avec une version de base de notre document.</para>
  1.2998 +
  1.2999 +      <!-- BEGIN tour-merge-conflict.wife -->
  1.3000 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  1.3001 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  1.3002 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Mariam Abacha, the wife of former</userinput>
  1.3003 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  1.3004 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  1.3005 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add letter.txt</userinput>
  1.3006 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m '419 scam, first draft'</userinput>
  1.3007 +</screen>
  1.3008 +<!-- END tour-merge-conflict.wife -->
  1.3009 + 
  1.3010 +
  1.3011 +      <para id="x_35a">Créons un clone de ce dépôt et faisons une
  1.3012 +        modification dans le fichier.</para>
  1.3013 +
  1.3014 +      <!-- BEGIN tour-merge-conflict.cousin -->
  1.3015 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.3016 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone scam scam-cousin</userinput>
  1.3017 +updating working directory
  1.3018 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.3019 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd scam-cousin</userinput>
  1.3020 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  1.3021 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  1.3022 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Shehu Musa Abacha, cousin to the former</userinput>
  1.3023 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  1.3024 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  1.3025 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m '419 scam, with cousin'</userinput>
  1.3026 +</screen>
  1.3027 +<!-- END tour-merge-conflict.cousin -->
  1.3028 +
  1.3029 +      
  1.3030 +      <para id="x_35b">Et un autre clone, pour simuler que quelqu'un d'autre effectue une
  1.3031 +        modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
  1.3032 +        de devoir effectuer des fusions (merges) avec vos propres travaux quand
  1.3033 +        vous isolez les tâches dans des dépôts distincts. En effet, vous
  1.3034 +        aurez alors à trouver et résoudre certains conflits).</para>
  1.3035 +
  1.3036 +      <!-- BEGIN tour-merge-conflict.son -->
  1.3037 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.3038 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone scam scam-son</userinput>
  1.3039 +updating working directory
  1.3040 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.3041 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd scam-son</userinput>
  1.3042 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  1.3043 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  1.3044 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Alhaji Abba Abacha, son of the former</userinput>
  1.3045 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  1.3046 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  1.3047 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m '419 scam, with son'</userinput>
  1.3048 +</screen>
  1.3049 +<!-- END tour-merge-conflict.son -->
  1.3050 +
  1.3051 +
  1.3052 +      <para id="x_35c">Maintenant que ces deux versions différentes du même fichier sont
  1.3053 +        créées, nous allons configurer l'environnement de manière appropriée pour
  1.3054 +        exécuter notre fusion (merge).</para>
  1.3055 +
  1.3056 +      <!-- BEGIN tour-merge-conflict.pull -->
  1.3057 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.3058 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone scam-cousin scam-merge</userinput>
  1.3059 +updating working directory
  1.3060 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.3061 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd scam-merge</userinput>
  1.3062 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../scam-son</userinput>
  1.3063 +pulling from ../scam-son
  1.3064 +searching for changes
  1.3065 +adding changesets
  1.3066 +adding manifests
  1.3067 +adding file changes
  1.3068 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.3069 +not updating, since new heads added
  1.3070 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.3071 +</screen>
  1.3072 +<!-- END tour-merge-conflict.pull -->
  1.3073 +
  1.3074 +
  1.3075 +      <para id="x_35d">Dans cette exemple, je n'utiliserais pas la commande Mercurial
  1.3076 +        habituelle <command moreinfo="none">hgmerge</command> pour effectuer le
  1.3077 +        fusion (merge), car il me faudrait abandonner ce joli petit exemple automatisé
  1.3078 +        pour utiliser un outil graphique. À la place, je vais définir la
  1.3079 +        variable d'environnement <envar>HGMERGE</envar> pour indiquer à
  1.3080 +        Mercurial d'utiliser la commande non-interactive <command moreinfo="none">merge</command>.
  1.3081 +        Cette dernière est embarquée par de nombreux systèmes <quote>à la Unix</quote>.
  1.3082 +        Si vous exécutez cet exemple depuis votre ordinateur, ne vous
  1.3083 +        occupez pas de définir <envar>HGMERGE</envar>.</para>
  1.3084 +
  1.3085 +     <!-- BEGIN tour-merge-conflict.merge -->
  1.3086 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">export HGMERGE=merge</userinput>
  1.3087 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.3088 +merging letter.txt
  1.3089 +merge: warning: conflicts during merge
  1.3090 +merging letter.txt failed!
  1.3091 +0 files updated, 0 files merged, 0 files removed, 1 files unresolved
  1.3092 +use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
  1.3093 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat letter.txt</userinput>
  1.3094 +Greetings!
  1.3095 +&lt;&lt;&lt;&lt;&lt;&lt;&lt; /tmp/tour-merge-conflictk3twLJ/scam-merge/letter.txt
  1.3096 +I am Shehu Musa Abacha, cousin to the former
  1.3097 +=======
  1.3098 +I am Alhaji Abba Abacha, son of the former
  1.3099 +&gt;&gt;&gt;&gt;&gt;&gt;&gt; /tmp/letter.txt~other.4O623C
  1.3100 +Nigerian dictator Sani Abacha.
  1.3101 +</screen>
  1.3102 +<!-- END tour-merge-conflict.merge -->
  1.3103 + 
  1.3104 +
  1.3105 +
  1.3106 +     <para id="x_35f">Parce que <command moreinfo="none">merge</command> ne peut pas résoudre
  1.3107 +       les modifications conflictuelles, il laisse des <emphasis>marqueurs de
  1.3108 +       différences</emphasis> à l'intérieur du fichier qui a des conflits,
  1.3109 +       indiquant clairement quelles lignes sont en conflits, et si elles
  1.3110 +       viennent de notre fichier ou du fichier externe.
  1.3111 +     </para>
  1.3112 +
  1.3113 +     <para id="x_360">Mercurial peut distinguer, à la manière dont la
  1.3114 +       commande <command moreinfo="none">merge</command> se termine, qu'elle n'a pas été
  1.3115 +       capable d'effectuer la fusion (merge), alors il nous indique que nous
  1.3116 +       devons effectuer de nouveau cette opération. Ceci peut être très utile
  1.3117 +       si, par exemple, nous exécutons un outil graphique de fusion et que
  1.3118 +       nous le quittons sans nous rendre compte qu'il reste des conflits ou 
  1.3119 +       simplement par erreur.</para>
  1.3120 +
  1.3121 +     <para id="x_361">Si la fusion (merge) automatique ou manuelle échoue, 
  1.3122 +       il n'y a rien pour nous empêcher de <quote>corriger le tir</quote> en
  1.3123 +       modifiant nous même les fichiers, et enfin effectuer le "commit" du 
  1.3124 +       fichier:</para>
  1.3125 +
  1.3126 +     <!-- BEGIN tour-merge-conflict.commit -->
  1.3127 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; letter.txt &lt;&lt;EOF</userinput>
  1.3128 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Greetings!</userinput>
  1.3129 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">I am Bryan O'Sullivan, no relation of the former</userinput>
  1.3130 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">Nigerian dictator Sani Abacha.</userinput>
  1.3131 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
  1.3132 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg resolve -m letter.txt</userinput>
  1.3133 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Send me your money'</userinput>
  1.3134 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.3135 +changeset:   3:0954bda76c6b
  1.3136 +tag:         tip
  1.3137 +parent:      1:1ac156b6e708
  1.3138 +parent:      2:7ee20631b33b
  1.3139 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.3140 +date:        Sun Aug 16 14:05:34 2009 +0000
  1.3141 +summary:     Send me your money
  1.3142 +
  1.3143 +</screen>
  1.3144 +<!-- END tour-merge-conflict.commit -->
  1.3145 +
  1.3146 +
  1.3147 +     <note>
  1.3148 +       <title>Où est la <command moreinfo="none">hg resolve</command> ?</title>
  1.3149 +       
  1.3150 +       <para id="x_724">La commande <command moreinfo="none">hg resolve</command> a été
  1.3151 +         introduit dans la version 1.1 de Mercurial, qui a été publié en
  1.3152 +         décembre 2008. Si vous utilisez une version plus anciennne de
  1.3153 +         Mercurial (exécutez la command <command moreinfo="none">hg version</command> pour en
  1.3154 +         avoir le coeur net), cette commande ne sera pas disponible. Si votre
  1.3155 +         version de Mercurial est plus ancienne que la 1.1, vous devriez très
  1.3156 +         fortement considérer une mise à jour à une version plus récente avant
  1.3157 +         d'essayer de régler des fusions complexes.</para>
  1.3158 +       </note>
  1.3159 +     </sect2>
  1.3160 +   </sect1>
  1.3161 +
  1.3162 +   <sect1 id="sec:tour-merge:fetch">
  1.3163 +     <title>Simplification de la séquence pull-merge-commit</title>
  1.3164 +
  1.3165 +     <para id="x_362">La procédure pour effectuer la fusion indiquée
  1.3166 +       ci-dessus est simple, mais requiert le lancement de trois commandes à la
  1.3167 +       suite.</para>
  1.3168 +
  1.3169 +     <programlisting format="linespecific">hg pull -u
  1.3170 +hg merge
  1.3171 +hg commit -m 'Merged remote changes'</programlisting>
  1.3172 +
  1.3173 +     <para id="x_363">Lors du "commit" final, vous devez également saisir un
  1.3174 +       message, qui aura vraisemblablement assez peu d'intérêt.</para>
  1.3175 +
  1.3176 +     <para id="x_364">Il serait assez sympathique de pouvoir réduire le
  1.3177 +       nombre d'opérations nécessaire, si possible. De fait Mercurial est
  1.3178 +       fourni avec une extension appelé <literal role="hg-ext" moreinfo="none">fetch</literal>
  1.3179 +       qui fait justement cela.</para>
  1.3180 +
  1.3181 +     <para id="x_365">Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
  1.3182 +       d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
  1.3183 +       léger et facile à utiliser. Certains extensions ajoutent de nouvelles
  1.3184 +       commandes que vous pouvez utiliser en ligne de commande, alors que
  1.3185 +       d'autres travaillent <quote>en coulisse,</quote> par exemple en ajoutant des
  1.3186 +       possibilités au serveur.</para>
  1.3187 +
  1.3188 +     <para id="x_366">L'extension <literal role="hg-ext" moreinfo="none">fetch</literal>
  1.3189 +       ajoute une nouvelle commande nommée, sans surprise, <command role="hg-cmd" moreinfo="none">hg fetch</command>. Cette extension résulte en une
  1.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
  1.3191 +       merge</command>. Elle commence par récupérer les modifications d'un
  1.3192 +       autre dépôt dans le dépôt courant. Si elle trouve que les
  1.3193 +       modifications ajoutent une nouvelle "head", elle effectue un "merge",
  1.3194 +       et ensuite "commit" le résultat du "merge" avec un message généré
  1.3195 +       automatiquement. Si aucune "head" n'ont été ajouté, elle met à jour le
  1.3196 +       répertoire de travail au niveau de la nouvelle révision tip.</para>
  1.3197 +     
  1.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
  1.3199 +       <literal role="rc-extensions" moreinfo="none">extensions</literal>. Ensuite ajoutez
  1.3200 +       une ligne qui consiste simplement en <quote>\Verb+fetch =</quote>.</para>
  1.3201 +
  1.3202 +     <programlisting format="linespecific">[extensions]
  1.3203 +fetch =</programlisting>
  1.3204 +
  1.3205 +    <para id="x_368">(Normalement, sur la partie droite de
  1.3206 +      <quote><literal moreinfo="none">=</literal></quote> devrait apparaître le chemin de
  1.3207 +      l'extension, mais étant donné que l'extension <literal role="hg-ext" moreinfo="none">fetch</literal> fait partie de la distribution standard,
  1.3208 +      Mercurial sait où la trouver.) </para>
  1.3209 +
  1.3210 +  </sect1>
  1.3211 +  
  1.3212 +  <sect1>
  1.3213 +    <title>Renommer, copier, et fusionner (merge)</title>
  1.3214 +
  1.3215 +    <para id="x_729">En cours de la vie d'un projet, nous allons souvent 
  1.3216 +      vouloir changer la disposition de ses fichiers et de ses répertoires. 
  1.3217 +      Ceci peut être aussi simple que de changer le nom d'un seul fichier, 
  1.3218 +      et aussi compliqué que de restructurer une hiérarchie entiere de fichier
  1.3219 +      au sein du projet.</para>
  1.3220 +
  1.3221 +    <para id="x_72a">Mercurial permet de faire ce genre de modification de
  1.3222 +      manière fluide, à condition de l'informer de ce que nous faisons. Si 
  1.3223 +      vous voulez renommenr un ficher, vous devriez utiliser les commande
  1.3224 +      <command moreinfo="none">hg rename</command><footnote>
  1.3225 +        <para id="x_72b">Si vous un utilisateur de Unix, vous serez content
  1.3226 +          de savoir que la commande  <command moreinfo="none">hg rename</command> command 
  1.3227 +          peut être abrégée en <command moreinfo="none">hg mv</command>.</para>
  1.3228 +      </footnote> pour changer son nom, ainsi Mercurial peut ensuite prendre
  1.3229 +      la bonne décision, plus tard, en cas de fusionv (merge).</para>
  1.3230 +
  1.3231 +    <para id="x_72c">Nous étudierojns en détail l'utilisation de ces commandes, 
  1.3232 +      en détail, dans le chapitre <xref linkend="chap:daily.copy"/>.</para>
  1.3233 +  </sect1>
  1.3234 +</chapter>
  1.3235 +
  1.3236 +<!--
  1.3237 +local variables: 
  1.3238 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.3239 +end:
  1.3240 +-->
  1.3241 +
  1.3242 +  <!-- BEGIN ch04 -->
  1.3243 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.3244 +
  1.3245 +<chapter id="chap:concepts">
  1.3246 +  <?dbhtml filename="behind-the-scenes.html"?>
  1.3247 +  <title>Derrière le décor</title>
  1.3248 +  
  1.3249 +  <para id="x_2e8">À la différence de beaucoup d'outils de gestion de versions,
  1.3250 +    les concepts sur lesquels se base Mercurial sont assez simples pour
  1.3251 +    qu'il soit facile de comprendre comment le logiciel fonctionne.
  1.3252 +    Bien que leur connaissance ne soit pas nécéssaire, je trouve utile
  1.3253 +    d'avoir un <quote>modèle mental</quote> de ce qui se passe.</para>
  1.3254 +
  1.3255 +  <para id="x_2e9">En effet, cette compréhension m'apporte la confiance que
  1.3256 +    Mercurial a été développé avec soin pour être à la fois
  1.3257 +    <emphasis>sûr</emphasis> et <emphasis>efficace</emphasis>. De surcroît,
  1.3258 +    si il m'est facile de garder en tête ce que le logiciel fait lorsque
  1.3259 +    j'accompli des tâches de révision, j'aurai moins de risques d'être
  1.3260 +    surpris par son comportement.</para>
  1.3261 +
  1.3262 +  <para id="x_2ea">Dans ce chapitre, nous décrirons tout d'abord les concepts
  1.3263 +    essentiels de l'architecture de Mercurial, pour ensuite discuter quelques
  1.3264 +    uns des détails intéressants de son implémentation.</para>
  1.3265 +
  1.3266 +  <sect1>
  1.3267 +    <title>Conservation de l'historique sous Mercurial</title>
  1.3268 +    <sect2>
  1.3269 +      <title>Suivi de l'historique pour un seul fichier</title>
  1.3270 +      
  1.3271 +      <para id="x_2eb">Lorsque Mercurial effectue un suivi des modifications
  1.3272 +        faites à un fichier, il conserve l'historique pour ce fichier dans un
  1.3273 +        <emphasis>filelog</emphasis> sous forme de métadonnées. Chaque entrée
  1.3274 +        dans le filelog contient assez d'informations pour reconstituer une
  1.3275 +        révision du fichier correspondant. Les filelogs sont des fichiers
  1.3276 +        stockés dans le répertoire  <filename role="special" class="directory" moreinfo="none">.hg/store/data</filename>. Un filelog contient
  1.3277 +        des informations de deux types: les données de révision, et un index
  1.3278 +        pour permettre à Mercurial une recherche efficace d'une révision
  1.3279 +        donnée.</para>
  1.3280 +
  1.3281 +      <para id="x_2ec">Lorsqu'un fichier devient trop gros ou a un long
  1.3282 +        historique, son filelog se voit stocker dans un fichier de données
  1.3283 +        (avec un suffixe <quote><literal moreinfo="none">.d</literal></quote>) et un fichier
  1.3284 +        index (avec un suffixe<quote><literal moreinfo="none">.i</literal></quote>)
  1.3285 +        distincts. La relation entre un fichier dans le répertoire de travail
  1.3286 +        et le  filelog couvrant le suivi de son historique dans le dépôt est
  1.3287 +        illustré à la figure <xref linkend="fig:concepts:filelog"/>.</para>
  1.3288 +
  1.3289 +      <figure id="fig:concepts:filelog" float="0">
  1.3290 +        <title>Relations entre les fichiers dans le répertoire de travail et
  1.3291 +        leurs filelogs dans le dépôt</title> 
  1.3292 +        <mediaobject> <imageobject><imagedata fileref="figs/filelog.png"/></imageobject>
  1.3293 +          <textobject><phrase>XXX add text</phrase></textobject>
  1.3294 +        </mediaobject> </figure>
  1.3295 +
  1.3296 +    </sect2>
  1.3297 +    <sect2>
  1.3298 +      <title>Gestion des fichiers suivis</title>
  1.3299 +      
  1.3300 +      <para id="x_2ee">Mercurial a recours à une structure nommée
  1.3301 +        <emphasis>manifest</emphasis> pour rassembler les informations sur
  1.3302 +        les fichiers dont il gère le suivi. Chaque entrée dans ce manifest
  1.3303 +        contient des informations sur les fichiers présents dans une révision
  1.3304 +        donnée. Une entrée store la liste des fichiers faisant partie de la
  1.3305 +        révision, la version de chaque fichier, et quelques autres
  1.3306 +        métadonnées sur ces fichiers.</para>
  1.3307 +
  1.3308 +    </sect2>
  1.3309 +    <sect2>
  1.3310 +      <title>Recording changeset information</title>
  1.3311 +
  1.3312 +      <para id="x_2ef">The <emphasis>changelog</emphasis> contains
  1.3313 +        information about each changeset.  Each revision records who
  1.3314 +        committed a change, the changeset comment, other pieces of
  1.3315 +        changeset-related information, and the revision of the manifest to
  1.3316 +        use.</para>
  1.3317 +
  1.3318 +    </sect2>
  1.3319 +    <sect2>
  1.3320 +      <title>Relationships between revisions</title>
  1.3321 +
  1.3322 +      <para id="x_2f0">Within a changelog, a manifest, or a filelog, each
  1.3323 +	revision stores a pointer to its immediate parent (or to its
  1.3324 +	two parents, if it's a merge revision).  As I mentioned above,
  1.3325 +	there are also relationships between revisions
  1.3326 +	<emphasis>across</emphasis> these structures, and they are
  1.3327 +	hierarchical in nature.</para>
  1.3328 +
  1.3329 +      <para id="x_2f1">For every changeset in a repository, there is exactly one
  1.3330 +	revision stored in the changelog.  Each revision of the
  1.3331 +	changelog contains a pointer to a single revision of the
  1.3332 +	manifest.  A revision of the manifest stores a pointer to a
  1.3333 +	single revision of each filelog tracked when that changeset
  1.3334 +	was created.  These relationships are illustrated in
  1.3335 +	<xref linkend="fig:concepts:metadata"/>.</para>
  1.3336 +
  1.3337 +      <figure id="fig:concepts:metadata" float="0">
  1.3338 +	<title>Metadata relationships</title>
  1.3339 +	<mediaobject>
  1.3340 +	  <imageobject><imagedata fileref="figs/metadata.png"/></imageobject>
  1.3341 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3342 +	</mediaobject>
  1.3343 +      </figure>
  1.3344 +
  1.3345 +      <para id="x_2f3">As the illustration shows, there is
  1.3346 +	<emphasis>not</emphasis> a <quote>one to one</quote>
  1.3347 +	relationship between revisions in the changelog, manifest, or
  1.3348 +	filelog. If a file that
  1.3349 +	Mercurial tracks hasn't changed between two changesets, the
  1.3350 +	entry for that file in the two revisions of the manifest will
  1.3351 +	point to the same revision of its filelog<footnote>
  1.3352 +	  <para id="x_725">It is possible (though unusual) for the manifest to
  1.3353 +	    remain the same between two changesets, in which case the
  1.3354 +	    changelog entries for those changesets will point to the
  1.3355 +	    same revision of the manifest.</para>
  1.3356 +	</footnote>.</para>
  1.3357 +
  1.3358 +    </sect2>
  1.3359 +  </sect1>
  1.3360 +  <sect1>
  1.3361 +    <title>Safe, efficient storage</title>
  1.3362 +
  1.3363 +    <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are
  1.3364 +      provided by a single structure called the
  1.3365 +      <emphasis>revlog</emphasis>.</para>
  1.3366 +
  1.3367 +    <sect2>
  1.3368 +      <title>Efficient storage</title>
  1.3369 +
  1.3370 +      <para id="x_2f5">The revlog provides efficient storage of revisions using a
  1.3371 +	<emphasis>delta</emphasis> mechanism.  Instead of storing a
  1.3372 +	complete copy of a file for each revision, it stores the
  1.3373 +	changes needed to transform an older revision into the new
  1.3374 +	revision.  For many kinds of file data, these deltas are
  1.3375 +	typically a fraction of a percent of the size of a full copy
  1.3376 +	of a file.</para>
  1.3377 +
  1.3378 +      <para id="x_2f6">Some obsolete revision control systems can only work with
  1.3379 +	deltas of text files.  They must either store binary files as
  1.3380 +	complete snapshots or encoded into a text representation, both
  1.3381 +	of which are wasteful approaches.  Mercurial can efficiently
  1.3382 +	handle deltas of files with arbitrary binary contents; it
  1.3383 +	doesn't need to treat text as special.</para>
  1.3384 +
  1.3385 +    </sect2>
  1.3386 +    <sect2 id="sec:concepts:txn">
  1.3387 +      <title>Safe operation</title>
  1.3388 +
  1.3389 +      <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to
  1.3390 +	the end of a revlog file. It never modifies a section of a
  1.3391 +	file after it has written it.  This is both more robust and
  1.3392 +	efficient than schemes that need to modify or rewrite
  1.3393 +	data.</para>
  1.3394 +
  1.3395 +      <para id="x_2f8">In addition, Mercurial treats every write as part of a
  1.3396 +	<emphasis>transaction</emphasis> that can span a number of
  1.3397 +	files.  A transaction is <emphasis>atomic</emphasis>: either
  1.3398 +	the entire transaction succeeds and its effects are all
  1.3399 +	visible to readers in one go, or the whole thing is undone.
  1.3400 +	This guarantee of atomicity means that if you're running two
  1.3401 +	copies of Mercurial, where one is reading data and one is
  1.3402 +	writing it, the reader will never see a partially written
  1.3403 +	result that might confuse it.</para>
  1.3404 +
  1.3405 +      <para id="x_2f9">The fact that Mercurial only appends to files makes it
  1.3406 +	easier to provide this transactional guarantee.  The easier it
  1.3407 +	is to do stuff like this, the more confident you should be
  1.3408 +	that it's done correctly.</para>
  1.3409 +
  1.3410 +    </sect2>
  1.3411 +    <sect2>
  1.3412 +      <title>Fast retrieval</title>
  1.3413 +
  1.3414 +      <para id="x_2fa">Mercurial cleverly avoids a pitfall common to
  1.3415 +	all earlier revision control systems: the problem of
  1.3416 +	<emphasis>inefficient retrieval</emphasis>. Most revision
  1.3417 +	control systems store the contents of a revision as an
  1.3418 +	incremental series of modifications against a
  1.3419 +	<quote>snapshot</quote>.  (Some base the snapshot on the
  1.3420 +	oldest revision, others on the newest.)  To reconstruct a
  1.3421 +	specific revision, you must first read the snapshot, and then
  1.3422 +	every one of the revisions between the snapshot and your
  1.3423 +	target revision.  The more history that a file accumulates,
  1.3424 +	the more revisions you must read, hence the longer it takes to
  1.3425 +	reconstruct a particular revision.</para>
  1.3426 +
  1.3427 +      <figure id="fig:concepts:snapshot" float="0">
  1.3428 +	<title>Snapshot of a revlog, with incremental deltas</title>
  1.3429 +	<mediaobject>
  1.3430 +	  <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject>
  1.3431 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3432 +	</mediaobject>
  1.3433 +      </figure>
  1.3434 +
  1.3435 +      <para id="x_2fc">The innovation that Mercurial applies to this problem is
  1.3436 +	simple but effective.  Once the cumulative amount of delta
  1.3437 +	information stored since the last snapshot exceeds a fixed
  1.3438 +	threshold, it stores a new snapshot (compressed, of course),
  1.3439 +	instead of another delta.  This makes it possible to
  1.3440 +	reconstruct <emphasis>any</emphasis> revision of a file
  1.3441 +	quickly.  This approach works so well that it has since been
  1.3442 +	copied by several other revision control systems.</para>
  1.3443 +
  1.3444 +      <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates
  1.3445 +	the idea.  In an entry in a revlog's index file, Mercurial
  1.3446 +	stores the range of entries from the data file that it must
  1.3447 +	read to reconstruct a particular revision.</para>
  1.3448 +
  1.3449 +      <sect3>
  1.3450 +	<title>Aside: the influence of video compression</title>
  1.3451 +
  1.3452 +	<para id="x_2fe">If you're familiar with video compression or
  1.3453 +	  have ever watched a TV feed through a digital cable or
  1.3454 +	  satellite service, you may know that most video compression
  1.3455 +	  schemes store each frame of video as a delta against its
  1.3456 +	  predecessor frame.</para>
  1.3457 +
  1.3458 +	<para id="x_2ff">Mercurial borrows this idea to make it
  1.3459 +	  possible to reconstruct a revision from a snapshot and a
  1.3460 +	  small number of deltas.</para>
  1.3461 +
  1.3462 +      </sect3>
  1.3463 +    </sect2>
  1.3464 +    <sect2>
  1.3465 +      <title>Identification and strong integrity</title>
  1.3466 +
  1.3467 +      <para id="x_300">Along with delta or snapshot information, a revlog entry
  1.3468 +	contains a cryptographic hash of the data that it represents.
  1.3469 +	This makes it difficult to forge the contents of a revision,
  1.3470 +	and easy to detect accidental corruption.</para>
  1.3471 +
  1.3472 +      <para id="x_301">Hashes provide more than a mere check against corruption;
  1.3473 +	they are used as the identifiers for revisions.  The changeset
  1.3474 +	identification hashes that you see as an end user are from
  1.3475 +	revisions of the changelog.  Although filelogs and the
  1.3476 +	manifest also use hashes, Mercurial only uses these behind the
  1.3477 +	scenes.</para>
  1.3478 +
  1.3479 +      <para id="x_302">Mercurial verifies that hashes are correct when it
  1.3480 +	retrieves file revisions and when it pulls changes from
  1.3481 +	another repository.  If it encounters an integrity problem, it
  1.3482 +	will complain and stop whatever it's doing.</para>
  1.3483 +
  1.3484 +      <para id="x_303">In addition to the effect it has on retrieval efficiency,
  1.3485 +	Mercurial's use of periodic snapshots makes it more robust
  1.3486 +	against partial data corruption.  If a revlog becomes partly
  1.3487 +	corrupted due to a hardware error or system bug, it's often
  1.3488 +	possible to reconstruct some or most revisions from the
  1.3489 +	uncorrupted sections of the revlog, both before and after the
  1.3490 +	corrupted section.  This would not be possible with a
  1.3491 +	delta-only storage model.</para>
  1.3492 +    </sect2>
  1.3493 +  </sect1>
  1.3494 +
  1.3495 +  <sect1>
  1.3496 +    <title>Revision history, branching, and merging</title>
  1.3497 +
  1.3498 +    <para id="x_304">Every entry in a Mercurial revlog knows the identity of its
  1.3499 +      immediate ancestor revision, usually referred to as its
  1.3500 +      <emphasis>parent</emphasis>.  In fact, a revision contains room
  1.3501 +      for not one parent, but two.  Mercurial uses a special hash,
  1.3502 +      called the <quote>null ID</quote>, to represent the idea
  1.3503 +      <quote>there is no parent here</quote>.  This hash is simply a
  1.3504 +      string of zeroes.</para>
  1.3505 +
  1.3506 +    <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see
  1.3507 +      an example of the conceptual structure of a revlog.  Filelogs,
  1.3508 +      manifests, and changelogs all have this same structure; they
  1.3509 +      differ only in the kind of data stored in each delta or
  1.3510 +      snapshot.</para>
  1.3511 +
  1.3512 +    <para id="x_306">The first revision in a revlog (at the bottom of the image)
  1.3513 +      has the null ID in both of its parent slots.  For a
  1.3514 +      <quote>normal</quote> revision, its first parent slot contains
  1.3515 +      the ID of its parent revision, and its second contains the null
  1.3516 +      ID, indicating that the revision has only one real parent.  Any
  1.3517 +      two revisions that have the same parent ID are branches.  A
  1.3518 +      revision that represents a merge between branches has two normal
  1.3519 +      revision IDs in its parent slots.</para>
  1.3520 +
  1.3521 +    <figure id="fig:concepts:revlog" float="0">
  1.3522 +      <title>The conceptual structure of a revlog</title>
  1.3523 +      <mediaobject>
  1.3524 +	<imageobject><imagedata fileref="figs/revlog.png"/></imageobject>
  1.3525 +	<textobject><phrase>XXX add text</phrase></textobject>
  1.3526 +      </mediaobject>
  1.3527 +    </figure>
  1.3528 +
  1.3529 +  </sect1>
  1.3530 +  <sect1>
  1.3531 +    <title>The working directory</title>
  1.3532 +
  1.3533 +    <para id="x_307">In the working directory, Mercurial stores a snapshot of the
  1.3534 +      files from the repository as of a particular changeset.</para>
  1.3535 +
  1.3536 +    <para id="x_308">The working directory <quote>knows</quote> which changeset
  1.3537 +      it contains.  When you update the working directory to contain a
  1.3538 +      particular changeset, Mercurial looks up the appropriate
  1.3539 +      revision of the manifest to find out which files it was tracking
  1.3540 +      at the time that changeset was committed, and which revision of
  1.3541 +      each file was then current.  It then recreates a copy of each of
  1.3542 +      those files, with the same contents it had when the changeset
  1.3543 +      was committed.</para>
  1.3544 +
  1.3545 +    <para id="x_309">The <emphasis>dirstate</emphasis> is a special
  1.3546 +      structure that contains Mercurial's knowledge of the working
  1.3547 +      directory.  It is maintained as a file named
  1.3548 +      <filename moreinfo="none">.hg/dirstate</filename> inside a repository.  The
  1.3549 +      dirstate details which changeset the working directory is
  1.3550 +      updated to, and all of the files that Mercurial is tracking in
  1.3551 +      the working directory. It also lets Mercurial quickly notice
  1.3552 +      changed files, by recording their checkout times and
  1.3553 +      sizes.</para>
  1.3554 +
  1.3555 +    <para id="x_30a">Just as a revision of a revlog has room for two parents, so
  1.3556 +      that it can represent either a normal revision (with one parent)
  1.3557 +      or a merge of two earlier revisions, the dirstate has slots for
  1.3558 +      two parents.  When you use the <command role="hg-cmd" moreinfo="none">hg
  1.3559 +	update</command> command, the changeset that you update to is
  1.3560 +      stored in the <quote>first parent</quote> slot, and the null ID
  1.3561 +      in the second. When you <command role="hg-cmd" moreinfo="none">hg
  1.3562 +	merge</command> with another changeset, the first parent
  1.3563 +      remains unchanged, and the second parent is filled in with the
  1.3564 +      changeset you're merging with.  The <command role="hg-cmd" moreinfo="none">hg
  1.3565 +	parents</command> command tells you what the parents of the
  1.3566 +      dirstate are.</para>
  1.3567 +
  1.3568 +    <sect2>
  1.3569 +      <title>What happens when you commit</title>
  1.3570 +
  1.3571 +      <para id="x_30b">The dirstate stores parent information for more than just
  1.3572 +	book-keeping purposes.  Mercurial uses the parents of the
  1.3573 +	dirstate as <emphasis>the parents of a new
  1.3574 +	  changeset</emphasis> when you perform a commit.</para>
  1.3575 +
  1.3576 +      <figure id="fig:concepts:wdir" float="0">
  1.3577 +	<title>The working directory can have two parents</title>
  1.3578 +	<mediaobject>
  1.3579 +	  <imageobject><imagedata fileref="figs/wdir.png"/></imageobject>
  1.3580 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3581 +	</mediaobject>
  1.3582 +      </figure>
  1.3583 +
  1.3584 +      <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the
  1.3585 +	normal state of the working directory, where it has a single
  1.3586 +	changeset as parent.  That changeset is the
  1.3587 +	<emphasis>tip</emphasis>, the newest changeset in the
  1.3588 +	repository that has no children.</para>
  1.3589 +
  1.3590 +      <figure id="fig:concepts:wdir-after-commit" float="0">
  1.3591 +	<title>The working directory gains new parents after a
  1.3592 +	  commit</title>
  1.3593 +	<mediaobject>
  1.3594 +	  <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject>
  1.3595 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3596 +	</mediaobject>
  1.3597 +      </figure>
  1.3598 +
  1.3599 +      <para id="x_30f">It's useful to think of the working directory as
  1.3600 +	<quote>the changeset I'm about to commit</quote>.  Any files
  1.3601 +	that you tell Mercurial that you've added, removed, renamed,
  1.3602 +	or copied will be reflected in that changeset, as will
  1.3603 +	modifications to any files that Mercurial is already tracking;
  1.3604 +	the new changeset will have the parents of the working
  1.3605 +	directory as its parents.</para>
  1.3606 +
  1.3607 +      <para id="x_310">After a commit, Mercurial will update the
  1.3608 +	parents of the working directory, so that the first parent is
  1.3609 +	the ID of the new changeset, and the second is the null ID.
  1.3610 +	This is shown in <xref linkend="fig:concepts:wdir-after-commit"/>. Mercurial
  1.3611 +	doesn't touch any of the files in the working directory when
  1.3612 +	you commit; it just modifies the dirstate to note its new
  1.3613 +	parents.</para>
  1.3614 +
  1.3615 +    </sect2>
  1.3616 +    <sect2>
  1.3617 +      <title>Creating a new head</title>
  1.3618 +
  1.3619 +      <para id="x_311">It's perfectly normal to update the working directory to a
  1.3620 +	changeset other than the current tip.  For example, you might
  1.3621 +	want to know what your project looked like last Tuesday, or
  1.3622 +	you could be looking through changesets to see which one
  1.3623 +	introduced a bug.  In cases like this, the natural thing to do
  1.3624 +	is update the working directory to the changeset you're
  1.3625 +	interested in, and then examine the files in the working
  1.3626 +	directory directly to see their contents as they were when you
  1.3627 +	committed that changeset.  The effect of this is shown in
  1.3628 +	<xref linkend="fig:concepts:wdir-pre-branch"/>.</para>
  1.3629 +
  1.3630 +      <figure id="fig:concepts:wdir-pre-branch" float="0">
  1.3631 +	<title>The working directory, updated to an older
  1.3632 +	  changeset</title>
  1.3633 +	<mediaobject>
  1.3634 +	  <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject>
  1.3635 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3636 +	</mediaobject>
  1.3637 +      </figure>
  1.3638 +
  1.3639 +      <para id="x_313">Having updated the working directory to an
  1.3640 +	older changeset, what happens if you make some changes, and
  1.3641 +	then commit?  Mercurial behaves in the same way as I outlined
  1.3642 +	above.  The parents of the working directory become the
  1.3643 +	parents of the new changeset.  This new changeset has no
  1.3644 +	children, so it becomes the new tip.  And the repository now
  1.3645 +	contains two changesets that have no children; we call these
  1.3646 +	<emphasis>heads</emphasis>.  You can see the structure that
  1.3647 +	this creates in <xref linkend="fig:concepts:wdir-branch"/>.</para>
  1.3648 +
  1.3649 +      <figure id="fig:concepts:wdir-branch" float="0">
  1.3650 +	<title>After a commit made while synced to an older
  1.3651 +	  changeset</title>
  1.3652 +	<mediaobject>
  1.3653 +	  <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject>
  1.3654 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3655 +	</mediaobject>
  1.3656 +      </figure>
  1.3657 +
  1.3658 +      <note>
  1.3659 +	<para id="x_315">If you're new to Mercurial, you should keep
  1.3660 +	  in mind a common <quote>error</quote>, which is to use the
  1.3661 +	  <command role="hg-cmd" moreinfo="none">hg pull</command> command without any
  1.3662 +	  options.  By default, the <command role="hg-cmd" moreinfo="none">hg
  1.3663 +	    pull</command> command <emphasis>does not</emphasis>
  1.3664 +	  update the working directory, so you'll bring new changesets
  1.3665 +	  into your repository, but the working directory will stay
  1.3666 +	  synced at the same changeset as before the pull.  If you
  1.3667 +	  make some changes and commit afterwards, you'll thus create
  1.3668 +	  a new head, because your working directory isn't synced to
  1.3669 +	  whatever the current tip is.  To combine the operation of a
  1.3670 +	  pull, followed by an update, run <command moreinfo="none">hg pull
  1.3671 +	    -u</command>.</para>
  1.3672 +
  1.3673 +	<para id="x_316">I put the word <quote>error</quote> in quotes
  1.3674 +	  because all that you need to do to rectify the situation
  1.3675 +	  where you created a new head by accident is
  1.3676 +	  <command role="hg-cmd" moreinfo="none">hg merge</command>, then <command role="hg-cmd" moreinfo="none">hg commit</command>.  In other words, this
  1.3677 +	  almost never has negative consequences; it's just something
  1.3678 +	  of a surprise for newcomers.  I'll discuss other ways to
  1.3679 +	  avoid this behavior, and why Mercurial behaves in this
  1.3680 +	  initially surprising way, later on.</para>
  1.3681 +      </note>
  1.3682 +
  1.3683 +    </sect2>
  1.3684 +    <sect2>
  1.3685 +      <title>Merging changes</title>
  1.3686 +
  1.3687 +      <para id="x_317">When you run the <command role="hg-cmd" moreinfo="none">hg
  1.3688 +	  merge</command> command, Mercurial leaves the first parent
  1.3689 +	of the working directory unchanged, and sets the second parent
  1.3690 +	to the changeset you're merging with, as shown in <xref linkend="fig:concepts:wdir-merge"/>.</para>
  1.3691 +
  1.3692 +      <figure id="fig:concepts:wdir-merge" float="0">
  1.3693 +	<title>Merging two heads</title>
  1.3694 +	<mediaobject>
  1.3695 +	  <imageobject>
  1.3696 +	    <imagedata fileref="figs/wdir-merge.png"/>
  1.3697 +	  </imageobject>
  1.3698 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.3699 +	</mediaobject>
  1.3700 +      </figure>
  1.3701 +
  1.3702 +      <para id="x_319">Mercurial also has to modify the working directory, to
  1.3703 +	merge the files managed in the two changesets.  Simplified a
  1.3704 +	little, the merging process goes like this, for every file in
  1.3705 +	the manifests of both changesets.</para>
  1.3706 +      <itemizedlist>
  1.3707 +	<listitem><para id="x_31a">If neither changeset has modified a file, do
  1.3708 +	    nothing with that file.</para>
  1.3709 +	</listitem>
  1.3710 +	<listitem><para id="x_31b">If one changeset has modified a file, and the
  1.3711 +	    other hasn't, create the modified copy of the file in the
  1.3712 +	    working directory.</para>
  1.3713 +	</listitem>
  1.3714 +	<listitem><para id="x_31c">If one changeset has removed a file, and the
  1.3715 +	    other hasn't (or has also deleted it), delete the file
  1.3716 +	    from the working directory.</para>
  1.3717 +	</listitem>
  1.3718 +	<listitem><para id="x_31d">If one changeset has removed a file, but the
  1.3719 +	    other has modified the file, ask the user what to do: keep
  1.3720 +	    the modified file, or remove it?</para>
  1.3721 +	</listitem>
  1.3722 +	<listitem><para id="x_31e">If both changesets have modified a file,
  1.3723 +	    invoke an external merge program to choose the new
  1.3724 +	    contents for the merged file.  This may require input from
  1.3725 +	    the user.</para>
  1.3726 +	</listitem>
  1.3727 +	<listitem><para id="x_31f">If one changeset has modified a file, and the
  1.3728 +	    other has renamed or copied the file, make sure that the
  1.3729 +	    changes follow the new name of the file.</para>
  1.3730 +	</listitem></itemizedlist>
  1.3731 +      <para id="x_320">There are more details—merging has plenty of corner
  1.3732 +	cases—but these are the most common choices that are
  1.3733 +	involved in a merge.  As you can see, most cases are
  1.3734 +	completely automatic, and indeed most merges finish
  1.3735 +	automatically, without requiring your input to resolve any
  1.3736 +	conflicts.</para>
  1.3737 +
  1.3738 +      <para id="x_321">When you're thinking about what happens when you commit
  1.3739 +	after a merge, once again the working directory is <quote>the
  1.3740 +	  changeset I'm about to commit</quote>.  After the <command role="hg-cmd" moreinfo="none">hg merge</command> command completes, the
  1.3741 +	working directory has two parents; these will become the
  1.3742 +	parents of the new changeset.</para>
  1.3743 +
  1.3744 +      <para id="x_322">Mercurial lets you perform multiple merges, but
  1.3745 +	you must commit the results of each individual merge as you
  1.3746 +	go.  This is necessary because Mercurial only tracks two
  1.3747 +	parents for both revisions and the working directory.  While
  1.3748 +	it would be technically feasible to merge multiple changesets
  1.3749 +	at once, Mercurial avoids this for simplicity.  With multi-way
  1.3750 +	merges, the risks of user confusion, nasty conflict
  1.3751 +	resolution, and making a terrible mess of a merge would grow
  1.3752 +	intolerable.</para>
  1.3753 +
  1.3754 +    </sect2>
  1.3755 +
  1.3756 +    <sect2>
  1.3757 +      <title>Merging and renames</title>
  1.3758 +
  1.3759 +      <para id="x_69a">A surprising number of revision control systems pay little
  1.3760 +	or no attention to a file's <emphasis>name</emphasis> over
  1.3761 +	time.  For instance, it used to be common that if a file got
  1.3762 +	renamed on one side of a merge, the changes from the other
  1.3763 +	side would be silently dropped.</para>
  1.3764 +
  1.3765 +      <para id="x_69b">Mercurial records metadata when you tell it to perform a
  1.3766 +	rename or copy. It uses this metadata during a merge to do the
  1.3767 +	right thing in the case of a merge.  For instance, if I rename
  1.3768 +	a file, and you edit it without renaming it, when we merge our
  1.3769 +	work the file will be renamed and have your edits
  1.3770 +	applied.</para>
  1.3771 +    </sect2>
  1.3772 +  </sect1>
  1.3773 +
  1.3774 +  <sect1>
  1.3775 +    <title>Other interesting design features</title>
  1.3776 +
  1.3777 +    <para id="x_323">In the sections above, I've tried to highlight some of the
  1.3778 +      most important aspects of Mercurial's design, to illustrate that
  1.3779 +      it pays careful attention to reliability and performance.
  1.3780 +      However, the attention to detail doesn't stop there.  There are
  1.3781 +      a number of other aspects of Mercurial's construction that I
  1.3782 +      personally find interesting.  I'll detail a few of them here,
  1.3783 +      separate from the <quote>big ticket</quote> items above, so that
  1.3784 +      if you're interested, you can gain a better idea of the amount
  1.3785 +      of thinking that goes into a well-designed system.</para>
  1.3786 +
  1.3787 +    <sect2>
  1.3788 +      <title>Clever compression</title>
  1.3789 +
  1.3790 +      <para id="x_324">When appropriate, Mercurial will store both snapshots and
  1.3791 +	deltas in compressed form.  It does this by always
  1.3792 +	<emphasis>trying to</emphasis> compress a snapshot or delta,
  1.3793 +	but only storing the compressed version if it's smaller than
  1.3794 +	the uncompressed version.</para>
  1.3795 +
  1.3796 +      <para id="x_325">This means that Mercurial does <quote>the right
  1.3797 +	  thing</quote> when storing a file whose native form is
  1.3798 +	compressed, such as a <literal moreinfo="none">zip</literal> archive or a JPEG
  1.3799 +	image.  When these types of files are compressed a second
  1.3800 +	time, the resulting file is usually bigger than the
  1.3801 +	once-compressed form, and so Mercurial will store the plain
  1.3802 +	<literal moreinfo="none">zip</literal> or JPEG.</para>
  1.3803 +
  1.3804 +      <para id="x_326">Deltas between revisions of a compressed file are usually
  1.3805 +	larger than snapshots of the file, and Mercurial again does
  1.3806 +	<quote>the right thing</quote> in these cases.  It finds that
  1.3807 +	such a delta exceeds the threshold at which it should store a
  1.3808 +	complete snapshot of the file, so it stores the snapshot,
  1.3809 +	again saving space compared to a naive delta-only
  1.3810 +	approach.</para>
  1.3811 +
  1.3812 +      <sect3>
  1.3813 +	<title>Network recompression</title>
  1.3814 +
  1.3815 +	<para id="x_327">When storing revisions on disk, Mercurial uses the
  1.3816 +	  <quote>deflate</quote> compression algorithm (the same one
  1.3817 +	  used by the popular <literal moreinfo="none">zip</literal> archive format),
  1.3818 +	  which balances good speed with a respectable compression
  1.3819 +	  ratio.  However, when transmitting revision data over a
  1.3820 +	  network connection, Mercurial uncompresses the compressed
  1.3821 +	  revision data.</para>
  1.3822 +
  1.3823 +	<para id="x_328">If the connection is over HTTP, Mercurial recompresses
  1.3824 +	  the entire stream of data using a compression algorithm that
  1.3825 +	  gives a better compression ratio (the Burrows-Wheeler
  1.3826 +	  algorithm from the widely used <literal moreinfo="none">bzip2</literal>
  1.3827 +	  compression package).  This combination of algorithm and
  1.3828 +	  compression of the entire stream (instead of a revision at a
  1.3829 +	  time) substantially reduces the number of bytes to be
  1.3830 +	  transferred, yielding better network performance over most
  1.3831 +	  kinds of network.</para>
  1.3832 +
  1.3833 +	<para id="x_329">If the connection is over
  1.3834 +	  <command moreinfo="none">ssh</command>, Mercurial
  1.3835 +	  <emphasis>doesn't</emphasis> recompress the stream, because
  1.3836 +	  <command moreinfo="none">ssh</command> can already do this itself.  You can
  1.3837 +	  tell Mercurial to always use <command moreinfo="none">ssh</command>'s
  1.3838 +	  compression feature by editing the
  1.3839 +	  <filename moreinfo="none">.hgrc</filename> file in your home directory as
  1.3840 +	  follows.</para>
  1.3841 +
  1.3842 +	<programlisting format="linespecific">[ui]
  1.3843 +ssh = ssh -C</programlisting>
  1.3844 +
  1.3845 +      </sect3>
  1.3846 +    </sect2>
  1.3847 +    <sect2>
  1.3848 +      <title>Read/write ordering and atomicity</title>
  1.3849 +
  1.3850 +      <para id="x_32a">Appending to files isn't the whole story when
  1.3851 +	it comes to guaranteeing that a reader won't see a partial
  1.3852 +	write.  If you recall <xref linkend="fig:concepts:metadata"/>,
  1.3853 +	revisions in the changelog point to revisions in the manifest,
  1.3854 +	and revisions in the manifest point to revisions in filelogs.
  1.3855 +	This hierarchy is deliberate.</para>
  1.3856 +
  1.3857 +      <para id="x_32b">A writer starts a transaction by writing filelog and
  1.3858 +	manifest data, and doesn't write any changelog data until
  1.3859 +	those are finished.  A reader starts by reading changelog
  1.3860 +	data, then manifest data, followed by filelog data.</para>
  1.3861 +
  1.3862 +      <para id="x_32c">Since the writer has always finished writing filelog and
  1.3863 +	manifest data before it writes to the changelog, a reader will
  1.3864 +	never read a pointer to a partially written manifest revision
  1.3865 +	from the changelog, and it will never read a pointer to a
  1.3866 +	partially written filelog revision from the manifest.</para>
  1.3867 +
  1.3868 +    </sect2>
  1.3869 +    <sect2>
  1.3870 +      <title>Concurrent access</title>
  1.3871 +
  1.3872 +      <para id="x_32d">The read/write ordering and atomicity guarantees mean that
  1.3873 +	Mercurial never needs to <emphasis>lock</emphasis> a
  1.3874 +	repository when it's reading data, even if the repository is
  1.3875 +	being written to while the read is occurring. This has a big
  1.3876 +	effect on scalability; you can have an arbitrary number of
  1.3877 +	Mercurial processes safely reading data from a repository
  1.3878 +	all at once, no matter whether it's being written to or
  1.3879 +	not.</para>
  1.3880 +
  1.3881 +      <para id="x_32e">The lockless nature of reading means that if you're
  1.3882 +	sharing a repository on a multi-user system, you don't need to
  1.3883 +	grant other local users permission to
  1.3884 +	<emphasis>write</emphasis> to your repository in order for
  1.3885 +	them to be able to clone it or pull changes from it; they only
  1.3886 +	need <emphasis>read</emphasis> permission.  (This is
  1.3887 +	<emphasis>not</emphasis> a common feature among revision
  1.3888 +	control systems, so don't take it for granted!  Most require
  1.3889 +	readers to be able to lock a repository to access it safely,
  1.3890 +	and this requires write permission on at least one directory,
  1.3891 +	which of course makes for all kinds of nasty and annoying
  1.3892 +	security and administrative problems.)</para>
  1.3893 +
  1.3894 +      <para id="x_32f">Mercurial uses locks to ensure that only one process can
  1.3895 +	write to a repository at a time (the locking mechanism is safe
  1.3896 +	even over filesystems that are notoriously hostile to locking,
  1.3897 +	such as NFS).  If a repository is locked, a writer will wait
  1.3898 +	for a while to retry if the repository becomes unlocked, but
  1.3899 +	if the repository remains locked for too long, the process
  1.3900 +	attempting to write will time out after a while. This means
  1.3901 +	that your daily automated scripts won't get stuck forever and
  1.3902 +	pile up if a system crashes unnoticed, for example.  (Yes, the
  1.3903 +	timeout is configurable, from zero to infinity.)</para>
  1.3904 +
  1.3905 +      <sect3>
  1.3906 +	<title>Safe dirstate access</title>
  1.3907 +
  1.3908 +	<para id="x_330">As with revision data, Mercurial doesn't take a lock to
  1.3909 +	  read the dirstate file; it does acquire a lock to write it.
  1.3910 +	  To avoid the possibility of reading a partially written copy
  1.3911 +	  of the dirstate file, Mercurial writes to a file with a
  1.3912 +	  unique name in the same directory as the dirstate file, then
  1.3913 +	  renames the temporary file atomically to
  1.3914 +	  <filename moreinfo="none">dirstate</filename>.  The file named
  1.3915 +	  <filename moreinfo="none">dirstate</filename> is thus guaranteed to be
  1.3916 +	  complete, not partially written.</para>
  1.3917 +
  1.3918 +      </sect3>
  1.3919 +    </sect2>
  1.3920 +    <sect2>
  1.3921 +      <title>Avoiding seeks</title>
  1.3922 +
  1.3923 +      <para id="x_331">Critical to Mercurial's performance is the avoidance of
  1.3924 +	seeks of the disk head, since any seek is far more expensive
  1.3925 +	than even a comparatively large read operation.</para>
  1.3926 +
  1.3927 +      <para id="x_332">This is why, for example, the dirstate is stored in a
  1.3928 +	single file.  If there were a dirstate file per directory that
  1.3929 +	Mercurial tracked, the disk would seek once per directory.
  1.3930 +	Instead, Mercurial reads the entire single dirstate file in
  1.3931 +	one step.</para>
  1.3932 +
  1.3933 +      <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme
  1.3934 +	when cloning a repository on local storage.  Instead of
  1.3935 +	copying every revlog file from the old repository into the new
  1.3936 +	repository, it makes a <quote>hard link</quote>, which is a
  1.3937 +	shorthand way to say <quote>these two names point to the same
  1.3938 +	  file</quote>.  When Mercurial is about to write to one of a
  1.3939 +	revlog's files, it checks to see if the number of names
  1.3940 +	pointing at the file is greater than one.  If it is, more than
  1.3941 +	one repository is using the file, so Mercurial makes a new
  1.3942 +	copy of the file that is private to this repository.</para>
  1.3943 +
  1.3944 +      <para id="x_334">A few revision control developers have pointed out that
  1.3945 +	this idea of making a complete private copy of a file is not
  1.3946 +	very efficient in its use of storage.  While this is true,
  1.3947 +	storage is cheap, and this method gives the highest
  1.3948 +	performance while deferring most book-keeping to the operating
  1.3949 +	system.  An alternative scheme would most likely reduce
  1.3950 +	performance and increase the complexity of the software, but
  1.3951 +	speed and simplicity are key to the <quote>feel</quote> of
  1.3952 +	day-to-day use.</para>
  1.3953 +
  1.3954 +    </sect2>
  1.3955 +    <sect2>
  1.3956 +      <title>Other contents of the dirstate</title>
  1.3957 +
  1.3958 +      <para id="x_335">Because Mercurial doesn't force you to tell it when you're
  1.3959 +	modifying a file, it uses the dirstate to store some extra
  1.3960 +	information so it can determine efficiently whether you have
  1.3961 +	modified a file.  For each file in the working directory, it
  1.3962 +	stores the time that it last modified the file itself, and the
  1.3963 +	size of the file at that time.</para>
  1.3964 +
  1.3965 +      <para id="x_336">When you explicitly <command role="hg-cmd" moreinfo="none">hg
  1.3966 +	  add</command>, <command role="hg-cmd" moreinfo="none">hg remove</command>,
  1.3967 +	<command role="hg-cmd" moreinfo="none">hg rename</command> or <command role="hg-cmd" moreinfo="none">hg copy</command> files, Mercurial updates the
  1.3968 +	dirstate so that it knows what to do with those files when you
  1.3969 +	commit.</para>
  1.3970 +
  1.3971 +      <para id="x_337">The dirstate helps Mercurial to efficiently
  1.3972 +	  check the status of files in a repository.</para>
  1.3973 +
  1.3974 +      <itemizedlist>
  1.3975 +	<listitem>
  1.3976 +	  <para id="x_726">When Mercurial checks the state of a file in the
  1.3977 +	    working directory, it first checks a file's modification
  1.3978 +	    time against the time in the dirstate that records when
  1.3979 +	    Mercurial last wrote the file. If the last modified time
  1.3980 +	    is the same as the time when Mercurial wrote the file, the
  1.3981 +	    file must not have been modified, so Mercurial does not
  1.3982 +	    need to check any further.</para>
  1.3983 +	</listitem>
  1.3984 +	<listitem>
  1.3985 +	  <para id="x_727">If the file's size has changed, the file must have
  1.3986 +	    been modified.  If the modification time has changed, but
  1.3987 +	    the size has not, only then does Mercurial need to
  1.3988 +	    actually read the contents of the file to see if it has
  1.3989 +	    changed.</para>
  1.3990 +	</listitem>
  1.3991 +      </itemizedlist>
  1.3992 +
  1.3993 +      <para id="x_728">Storing the modification time and size dramatically
  1.3994 +	reduces the number of read operations that Mercurial needs to
  1.3995 +	perform when we run commands like <command moreinfo="none">hg status</command>.
  1.3996 +	This results in large performance improvements.</para>
  1.3997 +    </sect2>
  1.3998 +  </sect1>
  1.3999 +</chapter>
  1.4000 +
  1.4001 +<!--
  1.4002 +local variables: 
  1.4003 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.4004 +end:
  1.4005 +-->
  1.4006 +
  1.4007 +  <!-- BEGIN ch05 -->
  1.4008 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.4009 +
  1.4010 +<chapter id="chap:daily">
  1.4011 +  <?dbhtml filename="mercurial-in-daily-use.html"?>
  1.4012 +  <title>Mercurial pour une utilisation de tous les jours</title>
  1.4013 +
  1.4014 +  <sect1>
  1.4015 +    <title>Informer Mercurial des fichier à suivre</title>
  1.4016 +
  1.4017 +    <para id="x_1a3">Mercurial ne suit pas les fichiers de votre dépôt tant
  1.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
  1.4019 +      inconnus de Mercurial. Il utilise un
  1.4020 +      <quote><literal moreinfo="none">?</literal></quote> pour montrer ces fichiers.</para>
  1.4021 +
  1.4022 +    <para id="x_1a4">Pour informer Mercurial de suivre un fichier, utilisez
  1.4023 +      la commande <command role="hg-cmd" moreinfo="none">hg add</command>. Une fois que vous
  1.4024 +      avez ajouté un fichier, la ligne correspondante à ce fichier dans la
  1.4025 +      sortie de <command role="hg-cmd" moreinfo="none">hg status</command> change de
  1.4026 +      <quote><literal moreinfo="none">?</literal></quote> à
  1.4027 +      <quote><literal moreinfo="none">A</literal></quote>.</para>
  1.4028 +
  1.4029 +    <!-- BEGIN daily.files.add -->
  1.4030 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init add-example</userinput>
  1.4031 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd add-example</userinput>
  1.4032 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; myfile.txt</userinput>
  1.4033 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4034 +? myfile.txt
  1.4035 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add myfile.txt</userinput>
  1.4036 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4037 +A myfile.txt
  1.4038 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Added one file'</userinput>
  1.4039 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4040 +</screen>
  1.4041 +<!-- END daily.files.add -->
  1.4042 +
  1.4043 +
  1.4044 +    <para id="x_1a5">Après avoir exécuté un <command role="hg-cmd" moreinfo="none">hg
  1.4045 +        commit</command>, les fichiers que vous avez ajoutés avant le commit
  1.4046 +      ne seront plus listés dans la sortie de <command role="hg-cmd" moreinfo="none">hg
  1.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
  1.4048 +      <quote>intéressants</quote> —ceux que vous avez (par exemple)
  1.4049 +      modifiés, supprimés ou renommés. Si vous aviez un dépôt qui contient un
  1.4050 +      millier de fichiers, vous ne voudriez certainement que rarement entendre
  1.4051 +      parler des fichiers que Mercurial suit, mais qui n'ont pas changés.
  1.4052 +      (Vous pouvez quand même avoir cette information, nous y reviendrons
  1.4053 +      plus tard.)</para>
  1.4054 +
  1.4055 +    <para id="x_1a6">Une fois que vous ajoutez un fichier, Mercurial ne fait
  1.4056 +      rien du tout avec celui-ci immédiatement. Au lieu de ça, il va prendre
  1.4057 +      un "snapshot" de l'état du fichier la prochaine fois que vous
  1.4058 +      exécuterez un commit. Il continuera ensuite à suivre les changements
  1.4059 +      que vous avez fait au fichier chaque fois que vous committerez, et ce,
  1.4060 +      jusqu'à ce que vous supprimiez le fichier.</para>
  1.4061 +
  1.4062 +    <sect2>
  1.4063 +      <title>Nommage des fichiers explicite versus implicite</title>
  1.4064 +
  1.4065 +      <para id="x_1a7">Un comportement utile que Mercurial possède est que si
  1.4066 +        vous passez le nom d'un répertoire à une commande, toute commande
  1.4067 +        Mercurial la traitera comme : <quote>Je veux opérer sur chaque fichier
  1.4068 +          dans ce répertoire et ses sous-répertoires</quote>.</para>
  1.4069 +
  1.4070 +      <!-- BEGIN daily.files.add-dir -->
  1.4071 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b</userinput>
  1.4072 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b/somefile.txt</userinput>
  1.4073 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo c &gt; b/source.cpp</userinput>
  1.4074 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b/d</userinput>
  1.4075 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo d &gt; b/d/test.h</userinput>
  1.4076 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add b</userinput>
  1.4077 +adding b/d/test.h
  1.4078 +adding b/somefile.txt
  1.4079 +adding b/source.cpp
  1.4080 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Added all files in subdirectory'</userinput>
  1.4081 +</screen>
  1.4082 +<!-- END daily.files.add-dir -->
  1.4083 +
  1.4084 +
  1.4085 +      <para id="x_1a8">Remarquez que dans cet exemple, Mercurial affiche le
  1.4086 +        nom des fichiers qu'il a ajouté, alors qu'il ne l'a pas fait lorsque
  1.4087 +        nous avons ajouté le fichier nommé <filename moreinfo="none">myfile.txt</filename>
  1.4088 +        dans l'exemple précédent.</para>
  1.4089 +
  1.4090 +      <para id="x_1a9">Ce qu'il se passe est que dans le premier cas, nous
  1.4091 +        avons nommé explicitement le fichier à ajouter sur la ligne de
  1.4092 +        commande. Ce que Mercurial suppose dans ce cas est que nous savons ce
  1.4093 +        que nous faisons, il n'affiche donc rien en sortie.</para>
  1.4094 +
  1.4095 +      <para id="x_1aa">Cependant, lorsque nous avons
  1.4096 +        <emphasis>implicitement</emphasis> donné les fichiers à l'aide du nom
  1.4097 +        d'un répertoire, Mercurial prend l'initiative d'afficher le nom de
  1.4098 +        chaque fichier avec lequel il fait quelque chose. Ceci clarifie ce
  1.4099 +        qu'il se passe et réduit la probabilité d'une mauvaise surprise
  1.4100 +        restée silencieuse. Ce comportement est commun à la plupart des
  1.4101 +        commandes Mercurial.</para>
  1.4102 +    </sect2>
  1.4103 +    <sect2>
  1.4104 +      <title>Mercurial suit les fichiers, pas les répertoires</title>
  1.4105 +
  1.4106 +      <para id="x_1ab">Mercurial ne suit pas les informations sur les
  1.4107 +        répertoires. En contrepartie, il suit le chemin vers un fichier. Avant
  1.4108 +        de créer un fichier, il crée au préalable les répertoires manquants
  1.4109 +        dans le chemin. Après avoir supprimé un fichier, il supprime chaque
  1.4110 +        répertoire vide qui apparaît dans le chemin du fichier. Ceci apparaît
  1.4111 +        comme une distinction triviale, cependant, cela a une conséquence
  1.4112 +        pratique mineure : il n'est pas possible de représenter un répertoire
  1.4113 +        totalement vide dans Mercurial.</para>
  1.4114 +
  1.4115 +      <para id="x_1ac">Les répertoires vides sont rarement utiles. Il existe
  1.4116 +        cependant des solutions alternatives et non intrusives que vous
  1.4117 +        pouvez utiliser pour obtenir l'effet approprié. Les développeurs de
  1.4118 +        Mercurial ont ainsi pensé que la complexité requise pour gérer les
  1.4119 +        répertoires n'était pas aussi importante que le bénéfice que cette
  1.4120 +        fonctionnalité apporterait.</para>
  1.4121 +
  1.4122 +      <para id="x_1ad">Si vous avez besoin d'un répertoire vide dans votre
  1.4123 +        dépôt, il existe quelques façons d'y arriver. L'une d'elles est de
  1.4124 +        créer un répertoire et ensuite, de faire un <command role="hg-cmd" moreinfo="none">hg
  1.4125 +          add</command> sur un fichier <quote>caché</quote> dans ce
  1.4126 +        répertoire. Sur les systèmes de type Unix, tout fichier dont le nom
  1.4127 +        commence avec un point (<quote><literal moreinfo="none">.</literal></quote>) est
  1.4128 +        considéré comme caché par la plupart des commandes et outils
  1.4129 +        graphiques. Cette approche est illustrée ci-après.</para>
  1.4130 +      
  1.4131 +      <!-- BEGIN daily.files.hidden -->
  1.4132 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init hidden-example</userinput>
  1.4133 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hidden-example</userinput>
  1.4134 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir empty</userinput>
  1.4135 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">touch empty/.hidden</userinput>
  1.4136 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add empty/.hidden</userinput>
  1.4137 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Manage an empty-looking directory'</userinput>
  1.4138 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls empty</userinput>
  1.4139 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.4140 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone hidden-example tmp</userinput>
  1.4141 +updating working directory
  1.4142 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4143 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls tmp</userinput>
  1.4144 +empty
  1.4145 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls tmp/empty</userinput>
  1.4146 +</screen>
  1.4147 +<!-- END daily.files.hidden -->
  1.4148 +
  1.4149 +
  1.4150 +      <para id="x_1ae">Une autre façon de s'attaquer au besoin d'un
  1.4151 +        répertoire vide est de simplement d'en créer un dans vos scripts
  1.4152 +        de construction avant qu'ils n'en aient le besoin.</para>
  1.4153 +    </sect2>
  1.4154 +  </sect1>
  1.4155 +
  1.4156 +  <sect1>
  1.4157 +    <title>Comment arrêter de suivre un fichier</title>
  1.4158 +
  1.4159 +    <para id="x_1af">Une fois que vous décidez qu'un fichier n'appartient
  1.4160 +      plus à votre dépôt, utilisez la commande <command role="hg-cmd" moreinfo="none">hg
  1.4161 +        remove</command>. Ceci supprime le fichier et informe Mercurial
  1.4162 +      d'arrêter de le suivre (ce qui prendra effet lors du prochain commit).
  1.4163 +      Un fichier supprimé est représenté dans la sortie de la commande
  1.4164 +      <command role="hg-cmd" moreinfo="none">hg status</command> par un
  1.4165 +      <quote><literal moreinfo="none">R</literal></quote>.</para>
  1.4166 +
  1.4167 +    <!-- BEGIN daily.files.remove -->
  1.4168 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init remove-example</userinput>
  1.4169 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd remove-example</userinput>
  1.4170 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  1.4171 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b</userinput>
  1.4172 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b/b</userinput>
  1.4173 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a b</userinput>
  1.4174 +adding b/b
  1.4175 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Small example for file removal'</userinput>
  1.4176 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove a</userinput>
  1.4177 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4178 +R a
  1.4179 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove b</userinput>
  1.4180 +removing b/b
  1.4181 +</screen>
  1.4182 +<!-- END daily.files.remove -->
  1.4183 +
  1.4184 +
  1.4185 +    <para id="x_1b0">Après avoir fait un <command role="hg-cmd" moreinfo="none">hg
  1.4186 +        remove</command> sur un fichier, Mercurial ne suivra plus aucun
  1.4187 +      changement sur ce fichier, même si vous recréez un fichier avec le même
  1.4188 +      nom dans votre répertoire de travail. Si vous recréez un fichier avec le
  1.4189 +      même nom et que vous désirez que Mercurial suive ce dernier, faite
  1.4190 +      simplement un <command role="hg-cmd" moreinfo="none">hg add</command> sur celui-ci.
  1.4191 +      Mercurial saura alors que le nouveau fichier ne fait pas référence à
  1.4192 +      l'ancien fichier qui portait le même nom.</para>
  1.4193 +
  1.4194 +    <sect2>
  1.4195 +      <title>Supprimer un fichier n'affecte pas son historique</title>
  1.4196 +
  1.4197 +      <para id="x_1b1">Il est important de comprendre que supprimer un fichier
  1.4198 +        n'a que deux effets.</para>
  1.4199 +
  1.4200 +      <itemizedlist>
  1.4201 +        <listitem><para id="x_1b2">Il supprime la version actuelle de ce
  1.4202 +            fichier du répertoire de travail.</para>
  1.4203 +        </listitem>
  1.4204 +        <listitem><para id="x_1b3">Il arrête, à partir du prochain commit, le
  1.4205 +            suivi de Mercurial sur les changements qui ont lieu sur ce
  1.4206 +            fichier.</para>
  1.4207 +        </listitem></itemizedlist>
  1.4208 +        
  1.4209 +      <para id="x_1b4">Supprimer un fichier <emphasis>n'</emphasis>affecte en
  1.4210 +        <emphasis>aucun</emphasis> cas l'<emphasis>historique</emphasis> du
  1.4211 +        fichier.</para>
  1.4212 +
  1.4213 +      <para id="x_1b5">Si vous mettez à jour le répertoire de travail à un
  1.4214 +        changeset qui a été committé alors que le fichier que vous venez de
  1.4215 +        supprimer était encore suivi, ce fichier réapparaîtra dans le
  1.4216 +        répertoire de travail, avec le contenu qu'il avait lorsque vous aviez
  1.4217 +        committé ce changeset. Si vous mettez à jour (update) le répertoire de
  1.4218 +        travail à un changeset ultérieur dans lequel le fichier a été
  1.4219 +        supprimé, Mercurial supprimera une nouvelle fois le fichier du
  1.4220 +        répertoire de travail.</para>
  1.4221 +    </sect2>
  1.4222 +
  1.4223 +    <sect2>
  1.4224 +      <title>Fichiers manquants</title>
  1.4225 +
  1.4226 +      <para id="x_1b6">Mercurial considère qu'un fichier que vous avez
  1.4227 +        supprimé sans utiliser<command role="hg-cmd" moreinfo="none">hg remove</command>
  1.4228 +        comme étant <emphasis>manquant</emphasis>.  Un fichier manquant est
  1.4229 +        représenté avec un <quote><literal moreinfo="none">!</literal></quote> en sortie de
  1.4230 +        <command role="hg-cmd" moreinfo="none">hg status</command>.
  1.4231 +        Les commandes Mercurial ne feront rien avec les fichiers
  1.4232 +        manquants.</para>
  1.4233 +
  1.4234 +      <!-- BEGIN daily.files.missing -->
  1.4235 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init missing-example</userinput>
  1.4236 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd missing-example</userinput>
  1.4237 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  1.4238 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
  1.4239 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'File about to be missing'</userinput>
  1.4240 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">rm a</userinput>
  1.4241 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4242 +! a
  1.4243 +</screen>
  1.4244 +<!-- END daily.files.missing -->
  1.4245 +
  1.4246 +
  1.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
  1.4248 +        vous voulez que ce fichier reste supprimé, vous pouvez exécuter
  1.4249 +        <command role="hg-cmd" moreinfo="none">hg remove <option role="hg-opt-remove">--after</option></command> à tout moment
  1.4250 +        pour dire à Mercurial que vous aviez bien voulu supprimer ce
  1.4251 +        fichier.</para>
  1.4252 +
  1.4253 +      <!-- BEGIN daily.files.remove-after -->
  1.4254 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove --after a</userinput>
  1.4255 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4256 +R a
  1.4257 +</screen>
  1.4258 +<!-- END daily.files.remove-after -->
  1.4259 +
  1.4260 +
  1.4261 +      <para id="x_1b8">D'un autre coté, si vous avez supprimé le fichier
  1.4262 +        manquant par accident, donnez à la commande <command role="hg-cmd" moreinfo="none">hg
  1.4263 +          revert</command> le nom du fichier à retrouver. Il réapparaitra dans
  1.4264 +        sa forme non modifiée.</para>
  1.4265 +
  1.4266 +      <!-- BEGIN daily.files.recover-missing -->
  1.4267 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert a</userinput>
  1.4268 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat a</userinput>
  1.4269 +a
  1.4270 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4271 +</screen>
  1.4272 +<!-- END daily.files.recover-missing -->
  1.4273 +
  1.4274 +    
  1.4275 +    </sect2>
  1.4276 +
  1.4277 +    <sect2>
  1.4278 +      <title>Entre nous : Pourquoi dire explicitement à Mercurial de supprimer un
  1.4279 +      fichier ?</title>
  1.4280 +
  1.4281 +      <para id="x_1b9">Vous pourriez vous demander pourquoi il est nécessaire
  1.4282 +        de dire explicitement à Mercurial que vous souhaitez supprimer un
  1.4283 +        fichier. Au début du développement de Mercurial, celui ci vous
  1.4284 +        laissait pourtant supprimer un fichier sans soucis ; Mercurial vous
  1.4285 +        aurait automatiquement informé de l'absence du fichier lorsque vous
  1.4286 +        auriez lancé un <command role="hg-cmd" moreinfo="none">hg commit</command> et arrêté
  1.4287 +        de le suivre. En pratique, ceci a montré qu'il était trop facile de
  1.4288 +        supprimer accidentellement un fichier sans le remarquer.</para>
  1.4289 +    </sect2>
  1.4290 +
  1.4291 +    <sect2>
  1.4292 +      <title>Raccourci utile—ajouter et supprimer des fichiers en une
  1.4293 +      seule étape.</title>
  1.4294 +
  1.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
  1.4296 +        suivis et marque les fichiers manquants comme supprimés.</para>
  1.4297 +
  1.4298 +      <!-- BEGIN daily.files.addremove -->
  1.4299 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init addremove-example</userinput>
  1.4300 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd addremove-example</userinput>
  1.4301 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  1.4302 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b</userinput>
  1.4303 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg addremove</userinput>
  1.4304 +adding a
  1.4305 +adding b
  1.4306 +</screen>
  1.4307 +<!-- END daily.files.addremove -->
  1.4308 +
  1.4309 +
  1.4310 +      <para id="x_1bb">La commande <command role="hg-cmd" moreinfo="none">hg commit</command>
  1.4311 +        fournit aussi une option <option role="hg-opt-commit">-A</option> qui
  1.4312 +        exécute le même ajouter-et-supprimer, immédiatement suivi d'un
  1.4313 +        commit.</para>
  1.4314 +
  1.4315 +      <!-- BEGIN daily.files.commit-addremove -->
  1.4316 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo c &gt; c</userinput>
  1.4317 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Commit with addremove'</userinput>
  1.4318 +adding c
  1.4319 +</screen>
  1.4320 +<!-- END daily.files.commit-addremove -->
  1.4321 +
  1.4322 +    
  1.4323 +    </sect2>
  1.4324 +  </sect1>
  1.4325 +
  1.4326 +  <sect1 id="chap:daily.copy">
  1.4327 +    <title>Copier des fichiers</title>
  1.4328 +
  1.4329 +    <para id="x_1bc">Mercurial fournit une commande <command role="hg-cmd" moreinfo="none">hg
  1.4330 +        copy</command> qui vous permet de faire une nouvelle copie d'un
  1.4331 +      fichier. Lorsque vous copiez un fichier en utilisant cette commande,
  1.4332 +      Mercurial crée un enregistrement du fait que ce nouveau fichier est une
  1.4333 +      copie du fichier originel. Il traite ces fichiers copiés spécialement
  1.4334 +      lorsque vous fusionnez (merge) votre travail avec quelqu'un
  1.4335 +      d'autre.</para>
  1.4336 +
  1.4337 +    <sect2>
  1.4338 +      <title>Les résultats d'une copie durant une fusion (merge)</title>
  1.4339 +
  1.4340 +      <para id="x_1bd">Ce qu'il se passe durant une fusion (merge) est que
  1.4341 +        les changements <quote>suivent</quote> une copie. Pour illustrer ce
  1.4342 +        que cela veut dire de la meilleure façon, créons un exemple. Nous
  1.4343 +        allons commencer avec le mini dépôt usuel qui contient un simple
  1.4344 +        fichier.</para>
  1.4345 +
  1.4346 +      <!-- BEGIN daily.copy.init -->
  1.4347 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init my-copy</userinput>
  1.4348 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-copy</userinput>
  1.4349 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo line &gt; file</userinput>
  1.4350 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add file</userinput>
  1.4351 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Added a file'</userinput>
  1.4352 +</screen>
  1.4353 +<!-- END daily.copy.init -->
  1.4354 +
  1.4355 +
  1.4356 +      <para id="x_1be">Nous devons faire du travail en parallèle, ainsi,
  1.4357 +        nous aurons quelque chose à fusionner (merge). Donc clonons notre
  1.4358 +        dépôt.</para>
  1.4359 +
  1.4360 +      <!-- BEGIN daily.copy.clone -->
  1.4361 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.4362 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone my-copy your-copy</userinput>
  1.4363 +updating working directory
  1.4364 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4365 +</screen>
  1.4366 +<!-- END daily.copy.clone -->
  1.4367 +
  1.4368 +
  1.4369 +      <para id="x_1bf">De retour dans notre dépôt initial, utilisons la
  1.4370 +        commande <command role="hg-cmd" moreinfo="none">hg copy</command> pour faire une
  1.4371 +        copie du premier fichier que nous avons créé.</para>
  1.4372 +
  1.4373 +      <!-- BEGIN daily.copy.copy -->
  1.4374 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-copy</userinput>
  1.4375 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy file new-file</userinput>
  1.4376 +</screen>
  1.4377 +<!-- END daily.copy.copy -->
  1.4378 +
  1.4379 +
  1.4380 +      <para id="x_1c0">Si nous regardons ensuite à la sortie de la commande
  1.4381 +        <command role="hg-cmd" moreinfo="none">hg status</command>, les fichiers copiés
  1.4382 +        ont l'air de fichiers normalement ajoutés.</para>
  1.4383 +
  1.4384 +      <!-- BEGIN daily.copy.status -->
  1.4385 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4386 +A new-file
  1.4387 +</screen>
  1.4388 +<!-- END daily.copy.status -->
  1.4389 +
  1.4390 +
  1.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
  1.4392 +          status</command>, il affiche une autre ligne de sortie : il s'agit
  1.4393 +        du fichier <emphasis>source</emphasis> pour notre copie.</para>
  1.4394 +
  1.4395 +      <!-- BEGIN daily.copy.status-copy -->
  1.4396 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -C</userinput>
  1.4397 +A new-file
  1.4398 +  file
  1.4399 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Copied file'</userinput>
  1.4400 +</screen>
  1.4401 +<!-- END daily.copy.status-copy -->
  1.4402 +
  1.4403 +
  1.4404 +      <para id="x_1c2">Maintenant, de retour dans le dépôt que nous avons
  1.4405 +        cloné, créons un changement en parallèle. Nous allons ajouter une
  1.4406 +        ligne de contenu au fichier original qui a été créé.</para>
  1.4407 +
  1.4408 +      <!-- BEGIN daily.copy.other -->
  1.4409 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../your-copy</userinput>
  1.4410 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'new contents' &gt;&gt; file</userinput>
  1.4411 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Changed file'</userinput>
  1.4412 +</screen>
  1.4413 +<!-- END daily.copy.other -->
  1.4414 +
  1.4415 +
  1.4416 +      <para id="x_1c3">Nous avons alors un fichier <filename moreinfo="none">file</filename>
  1.4417 +        modifié dans ce dépôt. Lorsque nous récupérons (pull) les changements
  1.4418 +        depuis le premier répertoire et fusionnons (merge) les deux "heads",
  1.4419 +        Mercurial propagera les changements que nous avons faits localement
  1.4420 +        au fichier <filename moreinfo="none">file</filename> dans sa copie
  1.4421 +        <filename moreinfo="none">new-file</filename>.</para>
  1.4422 +
  1.4423 +      <!-- BEGIN daily.copy.merge -->
  1.4424 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../my-copy</userinput>
  1.4425 +pulling from ../my-copy
  1.4426 +searching for changes
  1.4427 +adding changesets
  1.4428 +adding manifests
  1.4429 +adding file changes
  1.4430 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.4431 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.4432 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.4433 +merging file and new-file to new-file
  1.4434 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  1.4435 +(branch merge, don't forget to commit)
  1.4436 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat new-file</userinput>
  1.4437 +line
  1.4438 +new contents
  1.4439 +</screen>
  1.4440 +<!-- END daily.copy.merge -->
  1.4441 +
  1.4442 +    
  1.4443 +    </sect2>
  1.4444 +    <sect2 id="sec:daily:why-copy">
  1.4445 +      <title>Pourquoi est-ce que les changements devraient suivre les copies
  1.4446 +        ?</title>
  1.4447 +
  1.4448 +      <para id="x_1c4">Ce comportement—des changements d'un fichiers
  1.4449 +        qui se propagent aux copies de ce fichier—peut sembler
  1.4450 +        ésotérique, mais, dans la plupart des cas, c'est hautement
  1.4451 +        désirable.</para>
  1.4452 +
  1.4453 +      <para id="x_1c5">Pour commencer, souvenez vous que cette propagation
  1.4454 +        a lieue <emphasis>seulement</emphasis> lors des fusions (merge).
  1.4455 +        Donc, si vous faites un	<command role="hg-cmd" moreinfo="none">hg copy</command> sur
  1.4456 +        un fichier, et par la suite modifiez le fichier original durant le
  1.4457 +        cours normal de votre travail, rien n'a lieu.</para>
  1.4458 +
  1.4459 +      <para id="x_1c6">La deuxième chose à savoir c'est que les modifications
  1.4460 +        ne se propageront à travers une copie que si le changeset à partir
  1.4461 +        duquel vous faites une fusion (merge) <emphasis>n'a pas encore
  1.4462 +          vu</emphasis> la copie.</para>
  1.4463 +          
  1.4464 +      <para id="x_1c7">La raison pour laquelle Mercurial fait ainsi est une
  1.4465 +        règle. Imaginons que je corrige un important bug dans un fichier source
  1.4466 +        et que je commit mes changements. Pendant ce temps, vous avez décidé de
  1.4467 +        faire un <command role="hg-cmd" moreinfo="none">hg copy</command> du fichier dans
  1.4468 +        votre dépôt, sans rien savoir au sujet du bug ou à propos de la
  1.4469 +        correction. Vous avez alors commencé à "hacker" sur votre copie du
  1.4470 +        fichier.</para>
  1.4471 +
  1.4472 +      <para id="x_1c8">Si vous aviez récupéré (pull) et fusionné (merge) mes
  1.4473 +        changements, et que Mercurial <emphasis>n'avait pas</emphasis>
  1.4474 +        propagé les changements à travers les copies, votre nouveau fichier
  1.4475 +        source contiendrait maintenant le bug, et à moins que vous ne sachiez
  1.4476 +        qu'il faille propager la correction du bug à la main, le bug aurait
  1.4477 +        <emphasis>subsisté</emphasis> dans votre copie du fichier.</para>
  1.4478 +
  1.4479 +      <para id="x_1c9">En propageant automatiquement les changements qui
  1.4480 +        fixent les bugs à partir du fichier original vers les copies,
  1.4481 +        Mercurial prévient ce type de problèmes. A ma connaissance, Mercurial
  1.4482 +        est le <emphasis>seul</emphasis> système de gestion de révisions qui
  1.4483 +        propage les changements à travers les copies comme ceci.</para>
  1.4484 +
  1.4485 +      <para id="x_1ca">Une fois que votre historique des changements a un
  1.4486 +        enregistrement concernant une copie et qu'une fusion postérieure a
  1.4487 +        eu lieue, il n'y a d'habitude pas d'autre besoin de propager les
  1.4488 +        changements du fichier originel vers le fichier copié. C'est pourquoi
  1.4489 +        Mercurial ne propage les changements à travers les copies qu'à la
  1.4490 +        première fusion, et pas d'avantage.</para>
  1.4491 +    </sect2>
  1.4492 +
  1.4493 +    <sect2>
  1.4494 +      <title>Comment faire des changements qui <emphasis>ne</emphasis>
  1.4495 +      suivent <emphasis>pas</emphasis> une copie</title>
  1.4496 +
  1.4497 +      <para id="x_1cb">Si pour une raison ou une autre, vous décidez que
  1.4498 +        cette fonctionnalité de propager automatiquement les changements à
  1.4499 +        travers les copies n'est pas pour vous, utilisez simplement la
  1.4500 +        commande normale de copie de votre système (sur les systèmes de type
  1.4501 +        Unix, il s'agit de <command moreinfo="none">cp</command>) pour faire une copie d'un
  1.4502 +        fichier. Utilisez ensuite <command role="hg-cmd" moreinfo="none">hg add</command>
  1.4503 +        pour ajouter les nouveaux fichiers à la main. Cependant, avant d'en
  1.4504 +        faire ainsi, relisez <xref linkend="sec:daily:why-copy"/>, et faites
  1.4505 +        un choix en connaissance de cause comme quoi cette fonctionnalité
  1.4506 +        n'est pas appropriée à votre cas spécifique.</para>
  1.4507 +
  1.4508 +    </sect2>
  1.4509 +    <sect2>
  1.4510 +      <title>Comportement de la commande <command role="hg-cmd" moreinfo="none">hg copy</command></title>
  1.4511 +
  1.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
  1.4513 +        fichier source tel qu'il est actuellement dans le répertoire de
  1.4514 +        travail. Cela signifie que si vous effectuez des modifications sur un
  1.4515 +        fichier, puis faites un <command role="hg-cmd" moreinfo="none">hg copy</command> sur
  1.4516 +        celui-ci sans avoir au préalable committé ces changements, la nouvelle
  1.4517 +        copie contiendra aussi les modifications que vous avez fait jusqu'à
  1.4518 +        ce point.	(Je trouve ce comportement quelque peu contre intuitif,
  1.4519 +        c'est pourquoi j'en fais mention ici.)</para>
  1.4520 +      <!-- Vérifier que je n'ai pas fait de contre sens en relisant la
  1.4521 +      version anglaise, ce que je comprend ici me paraît un peu bizarre -->
  1.4522 +
  1.4523 +      <para id="x_1cd">La commande <command role="hg-cmd" moreinfo="none">hg copy</command>
  1.4524 +        agit comme la commande Unix <command moreinfo="none">cp</command> (vous pouvez
  1.4525 +        utilisez l'alias <command role="hg-cmd" moreinfo="none">hg cp</command> si vous
  1.4526 +        préférez).  Nous devons lui donner deux ou plus arguments où le
  1.4527 +        dernier est considéré comme la <emphasis>destination</emphasis>, et
  1.4528 +        les autres comme les <emphasis>sources</emphasis>.</para>
  1.4529 +
  1.4530 +      <para id="x_685">Si vous passez à <command role="hg-cmd" moreinfo="none">hg
  1.4531 +          copy</command> un seul fichier source, et que la destination
  1.4532 +        n'existe pas, ceci créera un nouveau fichier avec ce nom.</para>
  1.4533 +
  1.4534 +      <!-- BEGIN daily.copy.simple -->
  1.4535 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir k</userinput>
  1.4536 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy a k</userinput>
  1.4537 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls k</userinput>
  1.4538 +a
  1.4539 +</screen>
  1.4540 +<!-- END daily.copy.simple -->
  1.4541 +
  1.4542 +
  1.4543 +      <para id="x_1ce">Si la destination est un répertoire, Mercurial copie
  1.4544 +        les sources dans ce répertoire.</para>
  1.4545 +
  1.4546 +      <!-- BEGIN daily.copy.dir-dest -->
  1.4547 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir d</userinput>
  1.4548 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy a b d</userinput>
  1.4549 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls d</userinput>
  1.4550 +a  b
  1.4551 +</screen>
  1.4552 +<!-- END daily.copy.dir-dest -->
  1.4553 +
  1.4554 +
  1.4555 +      <para id="x_1cf">La copie de répertoire est récursive et préserve la
  1.4556 +        structure du répertoire source.</para>
  1.4557 +
  1.4558 +      <!-- BEGIN daily.copy.dir-src -->
  1.4559 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy z e</userinput>
  1.4560 +copying z/a/c to e/a/c
  1.4561 +</screen>
  1.4562 +<!-- END daily.copy.dir-src -->
  1.4563 +
  1.4564 +
  1.4565 +      <para id="x_1d0">Si la source et la destination sont tous deux des
  1.4566 +        répertoires, l'arborescence de la source est recréée dans le
  1.4567 +        répertoire destination.</para>
  1.4568 +    
  1.4569 +      <!-- BEGIN daily.copy.dir-src-dest -->
  1.4570 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy z d</userinput>
  1.4571 +copying z/a/c to d/z/a/c
  1.4572 +</screen>
  1.4573 +<!-- END daily.copy.dir-src-dest -->
  1.4574 +
  1.4575 +
  1.4576 +      <para id="x_1d1">Comme avec la commande <command role="hg-cmd" moreinfo="none">hg
  1.4577 +          remove</command>, si vous copiez un fichier manuellement et voulez
  1.4578 +        que Mercurial sache qu'il s'agit d'une copie, utilisez simplement
  1.4579 +        l'option <option role="hg-opt-copy">--after</option> avec <command role="hg-cmd" moreinfo="none">hg copy</command>.</para>
  1.4580 +
  1.4581 +      <!-- BEGIN daily.copy.after -->
  1.4582 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cp a n</userinput>
  1.4583 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy --after a n</userinput>
  1.4584 +</screen>
  1.4585 +<!-- END daily.copy.after -->
  1.4586 +
  1.4587 +    </sect2>
  1.4588 +  </sect1>
  1.4589 +
  1.4590 +  <sect1>
  1.4591 +    <title>Renommer les fichiers</title>
  1.4592 +
  1.4593 +    <para id="x_1d2">Il est plus commun d'avoir besoin de renommer un
  1.4594 +      fichier que d'en faire une copie. La raison pour laquelle j'ai discuté
  1.4595 +      de la commande <command role="hg-cmd" moreinfo="none">hg copy</command> avant de parler
  1.4596 +      de renommage des fichiers est que Mercurial traite les renommages
  1.4597 +      essentiellement comme une copie. Ainsi, savoir comment Mercurial traite
  1.4598 +      les copies de fichiers vous informe sur ce que vous êtes en droit
  1.4599 +      d'attendre lorsque vous renommez un fichier.</para>
  1.4600 +
  1.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
  1.4602 +      les fichiers sources, les supprime et marque ces fichiers comme étant
  1.4603 +      supprimés.</para>
  1.4604 +
  1.4605 +    <!-- BEGIN daily.rename.rename -->
  1.4606 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rename a b</userinput>
  1.4607 +</screen>
  1.4608 +<!-- END daily.rename.rename -->
  1.4609 +
  1.4610 +
  1.4611 +    <para id="x_1d4">La commande <command role="hg-cmd" moreinfo="none">hg status</command>
  1.4612 +      montre les nouveaux fichiers comme ajoutés et les fichiers originaux
  1.4613 +      comme supprimés.</para>
  1.4614 +
  1.4615 +    <!-- BEGIN daily.rename.status -->
  1.4616 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.4617 +A b
  1.4618 +R a
  1.4619 +</screen>
  1.4620 +<!-- END daily.rename.status -->
  1.4621 +
  1.4622 +
  1.4623 +    <para id="x_1d5">A cause du <command role="hg-cmd" moreinfo="none">hg	copy</command>,
  1.4624 +      nous devons utiliser l'option <option role="hg-opt-status">-C</option>
  1.4625 +      pour la commande <command role="hg-cmd" moreinfo="none">hg status</command> afin
  1.4626 +      d'observer que le fichier ajouté est bien suivi par Mercurial comme
  1.4627 +      étant une copie de l'original maintenant supprimé.</para>
  1.4628 +
  1.4629 +    <!-- BEGIN daily.rename.status-copy -->
  1.4630 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -C</userinput>
  1.4631 +A b
  1.4632 +  a
  1.4633 +R a
  1.4634 +</screen>
  1.4635 +<!-- END daily.rename.status-copy -->
  1.4636 +
  1.4637 +
  1.4638 +    <para id="x_1d6">Comme avec <command role="hg-cmd" moreinfo="none">hg remove</command> et
  1.4639 +      <command role="hg-cmd" moreinfo="none">hg copy</command>, vous pouvez informer
  1.4640 +      Mercurial au sujet d'un renommage après coup en utilisant l'option
  1.4641 +      <option role="hg-opt-rename">--after</option>. Dans le plus grand
  1.4642 +      respect, le comportement de la commande <command role="hg-cmd" moreinfo="none">hg
  1.4643 +        rename</command>, et les options qu'il accepte sont similaires à la
  1.4644 +      commande <command role="hg-cmd" moreinfo="none">hg copy</command>.</para>
  1.4645 +
  1.4646 +    <para id="x_686">Si vous êtes familier avec la ligne de commande Unix,
  1.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>
  1.4648 +
  1.4649 +    <sect2>
  1.4650 +      <title>Renommer les fichiers et fusionner (merge) les changements</title>
  1.4651 +
  1.4652 +      <para id="x_1d7">Puise que le "rename" de Mercurial est implanté comme un
  1.4653 +        "copy-and-remove", la même propagation des changements a lieue après
  1.4654 +        un "rename" qu'après un "copy" lorsque vous fusionnez (merge).</para>
  1.4655 +
  1.4656 +      <para id="x_1d8">Si je modifie un fichier et que vous le renommez, si
  1.4657 +        ensuite nous fusionnons nos changements respectifs, mes modifications
  1.4658 +        sur le fichier sous son nom originel seront propagés vers le même
  1.4659 +        fichier sous son nouveau nom. (C'est quelque chose que vous pourriez
  1.4660 +        espérer voir <quote>fonctionner simplement</quote>, mais tous les
  1.4661 +        systèmes de gestion de version ne le font pas.)</para>
  1.4662 +
  1.4663 +      <para id="x_1d9">Tandis qu'avoir des changements qui suivent une copie
  1.4664 +        est une fonctionnalité où vous hocheriez sûrement la tête en disant
  1.4665 +        <quote>oui, cela pourrait être utile</quote>, il est clair que les
  1.4666 +        voir suivre un renommage est définitivement important. Sans cette
  1.4667 +        aptitude, il serait vraiment trop facile d'avoir des changements
  1.4668 +        qui deviennent orphelins lorsque des fichiers sont renommés.</para>
  1.4669 +    </sect2>
  1.4670 +
  1.4671 +    <sect2>
  1.4672 +      <title>Renommages divergeants et fusion (merge)</title>
  1.4673 +
  1.4674 +      <para id="x_1da">Le cas de noms divergeants a lieu lorsque deux
  1.4675 +        développeurs commencent avec un fichier—appelons le
  1.4676 +        <filename moreinfo="none">foo</filename>—dans leurs dépôts respectifs.</para>
  1.4677 +
  1.4678 +      <!-- BEGIN rename.divergent.clone -->
  1.4679 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone orig anne</userinput>
  1.4680 +updating working directory
  1.4681 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4682 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone orig bob</userinput>
  1.4683 +updating working directory
  1.4684 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4685 +</screen>
  1.4686 +<!-- END rename.divergent.clone -->
  1.4687 +
  1.4688 +
  1.4689 +      <para id="x_1db">Anne renomme le fichier en
  1.4690 +        <filename moreinfo="none">bar</filename>.</para>
  1.4691 +
  1.4692 +      <!-- BEGIN rename.divergent.rename.anne -->
  1.4693 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd anne</userinput>
  1.4694 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rename foo bar</userinput>
  1.4695 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m 'Rename foo to bar'</userinput>
  1.4696 +</screen>
  1.4697 +<!-- END rename.divergent.rename.anne -->
  1.4698 +
  1.4699 +
  1.4700 +      <para id="x_1dc">Pendant ce temps, Bob le renomme en
  1.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>
  1.4702 +    
  1.4703 +      <!-- BEGIN rename.divergent.rename.bob -->
  1.4704 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../bob</userinput>
  1.4705 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg mv foo quux</userinput>
  1.4706 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m 'Rename foo to quux'</userinput>
  1.4707 +</screen>
  1.4708 +<!-- END rename.divergent.rename.bob -->
  1.4709 +
  1.4710 +
  1.4711 +      <para id="x_1dd">J'aime à penser qu'il s'agit d'un conflit puisque
  1.4712 +        chaque développeur a exprimé différentes intentions au sujet de ce
  1.4713 +        que le nom de ce fichier aurait du être.</para>
  1.4714 +
  1.4715 +      <para id="x_1de">Que pensez vous qu'il devrait se produire lorsqu'ils
  1.4716 +        fusionnent (merge) leurs travaux ? Le comportement actuel de
  1.4717 +        Mercurial est qu'il préserve toujours les <emphasis>deux</emphasis>
  1.4718 +        noms lorsqu'il fusionne (merge) des changesets qui contiennent des
  1.4719 +        renommages divergeants.</para>
  1.4720 +
  1.4721 +      <!-- BEGIN rename.divergent.merge -->
  1.4722 +<screen format="linespecific"># See http://www.selenic.com/mercurial/bts/issue455
  1.4723 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../orig</userinput>
  1.4724 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../anne</userinput>
  1.4725 +pulling from ../anne
  1.4726 +searching for changes
  1.4727 +adding changesets
  1.4728 +adding manifests
  1.4729 +adding file changes
  1.4730 +added 1 changesets with 1 changes to 1 files
  1.4731 +1 files updated, 0 files merged, 1 files removed, 0 files unresolved
  1.4732 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../bob</userinput>
  1.4733 +pulling from ../bob
  1.4734 +searching for changes
  1.4735 +adding changesets
  1.4736 +adding manifests
  1.4737 +adding file changes
  1.4738 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.4739 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.4740 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.4741 +warning: detected divergent renames of foo to:
  1.4742 + bar
  1.4743 + quux
  1.4744 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4745 +(branch merge, don't forget to commit)
  1.4746 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls</userinput>
  1.4747 +bar  quux
  1.4748 +</screen>
  1.4749 +<!-- END rename.divergent.merge -->
  1.4750 +
  1.4751 +
  1.4752 +      <para id="x_1df">Remarquez que bien que Mercurial vous avertisse au
  1.4753 +        sujet de la divergeance des renommages, il vous laisse faire quelque
  1.4754 +        chose au sujet de la divergeance après la fusion (merge).</para>
  1.4755 +    </sect2>
  1.4756 +
  1.4757 +    <sect2>
  1.4758 +      <title>Renommages et fusion convergeants</title>
  1.4759 +
  1.4760 +      <para id="x_1e0">Un autre type de conflit de renommage intervient
  1.4761 +        lorsque deux personne choisissent de renommer différents fichiers
  1.4762 +        <emphasis>source</emphasis> vers la même
  1.4763 +        <emphasis>destination</emphasis>. Dans ce cas, Mercurial exécute la
  1.4764 +        machinerie normale de fusion (merge) et vous guide vers une
  1.4765 +        solution convenable.</para>
  1.4766 +    </sect2>
  1.4767 +
  1.4768 +    <sect2>
  1.4769 +      <title>Autres cas anguleux relatifs aux noms</title>
  1.4770 +
  1.4771 +      <para id="x_1e1">Mercurial possède un bug de longue date dans lequel il
  1.4772 +        échoue à traiter une fusion (merge) où un coté a un fichier avec un
  1.4773 +        nom donné, alors que l'autre coté possède un répertoire avec le même nom.
  1.4774 +        Ceci est documenté dans l'<ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue29">issue
  1.4775 +          29</ulink>.</para>
  1.4776 +
  1.4777 +      <!-- BEGIN issue29.go -->
  1.4778 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init issue29</userinput>
  1.4779 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd issue29</userinput>
  1.4780 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
  1.4781 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -Ama</userinput>
  1.4782 +adding a
  1.4783 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b</userinput>
  1.4784 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -Amb</userinput>
  1.4785 +adding b
  1.4786 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg up 0</userinput>
  1.4787 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  1.4788 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mkdir b</userinput>
  1.4789 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b/b</userinput>
  1.4790 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -Amc</userinput>
  1.4791 +adding b/b
  1.4792 +created new head
  1.4793 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.4794 +abort: Is a directory: /tmp/issue29vhrzWD/issue29/b
  1.4795 +</screen>
  1.4796 +<!-- END issue29.go -->
  1.4797 +
  1.4798 +
  1.4799 +    </sect2>
  1.4800 +  </sect1>
  1.4801 +
  1.4802 +  <sect1>
  1.4803 +    <title>Récupération d'erreurs</title>
  1.4804 +
  1.4805 +    <para id="x_1e2">Mercurial possède certaines commandes utiles qui vont
  1.4806 +      vous aider à récupérer de certaines erreurs communes.</para>
  1.4807 +
  1.4808 +    <para id="x_1e3">La commande <command role="hg-cmd" moreinfo="none">hg revert</command>
  1.4809 +      vous permet d'annuler les changements que vous avez faits dans votre
  1.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
  1.4811 +      juste <command role="hg-cmd" moreinfo="none">hg	revert</command> avec le nom du fichier
  1.4812 +      que vous avez ajouté et tandis que le fichier ne sera touché d'une
  1.4813 +      quelconque manière, il ne sera plus suivi comme ajouté par Mercurial.
  1.4814 +      Vous pouvez aussi utiliser la commande <command role="hg-cmd" moreinfo="none">hg
  1.4815 +        revert</command> pour vous débarrasser de modifications erronés
  1.4816 +      apportées à un fichier.</para>
  1.4817 +
  1.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
  1.4819 +      qui n'ont pas encore été committées. Une fois que vous avez committé un
  1.4820 +      changement, si vous décidez qu'il s'agissait d'une erreur, vous pouvez
  1.4821 +      toujours faire quelque chose à ce sujet, bien que vos options soient
  1.4822 +      un peu plus limitées.</para>
  1.4823 +
  1.4824 +    <para id="x_1e5">Pour plus d'informations au sujet de la commande
  1.4825 +      <command role="hg-cmd" moreinfo="none">hg revert</command>, et des détails sur comment
  1.4826 +      traiter les modifications que vous avez déjà committées, référez vous à
  1.4827 +      <xref linkend="chap:undo"/>.</para>
  1.4828 +  </sect1>
  1.4829 +
  1.4830 +  <sect1>
  1.4831 +    <title>Traiter avec les fusions (merge) malicieuses</title>
  1.4832 +
  1.4833 +    <para id="x_687">Dans des projets compliqués ou conséquents, il n'est pas
  1.4834 +      rare qu'une fusion (merge) de deux changesets finisse par une migraine.
  1.4835 +      Supposez qu'il y ait un gros fichier source qui ait été largement édité de
  1.4836 +      chaque coté de la fusion (merge) : ceci va inévitablement résulter en
  1.4837 +      conflits, dont certains peuvent prendre plusieurs essais pour s'en
  1.4838 +      sortir.</para>
  1.4839 +
  1.4840 +    <para id="x_688">Développons en un cas simple pour voir comment le gérer.
  1.4841 +      Nous allons commencer avec un dépôt contenant un fichier, et le
  1.4842 +      cloner deux fois.</para>
  1.4843 +
  1.4844 +    <!-- BEGIN ch04/resolve.init -->
  1.4845 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init conflict</userinput>
  1.4846 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd conflict</userinput>
  1.4847 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo first &gt; myfile.txt</userinput>
  1.4848 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -A -m first</userinput>
  1.4849 +adding myfile.txt
  1.4850 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.4851 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone conflict left</userinput>
  1.4852 +updating working directory
  1.4853 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4854 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone conflict right</userinput>
  1.4855 +updating working directory
  1.4856 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4857 +</screen>
  1.4858 +<!-- END ch04/resolve.init -->
  1.4859 +
  1.4860 +
  1.4861 +    <para id="x_689">Dans un des clones, nous allons modifier le fichier
  1.4862 +      d'une façon.</para>
  1.4863 +
  1.4864 +    <!-- BEGIN ch04/resolve.left -->
  1.4865 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd left</userinput>
  1.4866 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo left &gt;&gt; myfile.txt</userinput>
  1.4867 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m left</userinput>
  1.4868 +</screen>
  1.4869 +<!-- END ch04/resolve.left -->
  1.4870 +
  1.4871 +
  1.4872 +    <para id="x_68a">Dans un autre, nous allons modifier le fichier
  1.4873 +      différemment.</para>
  1.4874 +
  1.4875 +    <!-- BEGIN ch04/resolve.right -->
  1.4876 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../right</userinput>
  1.4877 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo right &gt;&gt; myfile.txt</userinput>
  1.4878 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg ci -m right</userinput>
  1.4879 +</screen>
  1.4880 +<!-- END ch04/resolve.right -->
  1.4881 +
  1.4882 +
  1.4883 +    <para id="x_68b">Ensuite, nous allons récupérer (pull) chaque ensemble de
  1.4884 +      changement dans notre dépôt original.</para>
  1.4885 +
  1.4886 +    <!-- BEGIN ch04/resolve.pull -->
  1.4887 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../conflict</userinput>
  1.4888 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../left</userinput>
  1.4889 +pulling from ../left
  1.4890 +searching for changes
  1.4891 +adding changesets
  1.4892 +adding manifests
  1.4893 +adding file changes
  1.4894 +added 1 changesets with 1 changes to 1 files
  1.4895 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.4896 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull -u ../right</userinput>
  1.4897 +pulling from ../right
  1.4898 +searching for changes
  1.4899 +adding changesets
  1.4900 +adding manifests
  1.4901 +adding file changes
  1.4902 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.4903 +not updating, since new heads added
  1.4904 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.4905 +</screen>
  1.4906 +<!-- END ch04/resolve.pull -->
  1.4907 +
  1.4908 +
  1.4909 +    <para id="x_68c">Nous nous attendons à ce que notre dépôt contienne deux
  1.4910 +      "heads".</para>
  1.4911 +
  1.4912 +    <!-- BEGIN ch04/resolve.heads -->
  1.4913 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  1.4914 +changeset:   2:85f1afc84c33
  1.4915 +tag:         tip
  1.4916 +parent:      0:14a820f81f48
  1.4917 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.4918 +date:        Sun Aug 16 14:04:51 2009 +0000
  1.4919 +summary:     right
  1.4920 +
  1.4921 +changeset:   1:085ebbf44348
  1.4922 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.4923 +date:        Sun Aug 16 14:04:51 2009 +0000
  1.4924 +summary:     left
  1.4925 +
  1.4926 +</screen>
  1.4927 +<!-- END ch04/resolve.heads -->
  1.4928 +
  1.4929 +
  1.4930 +    <para id="x_68d">Normalement, si nous lançons <command role="hg-cmd" moreinfo="none">hg
  1.4931 +        merge</command> à ce point, il nous renverra vers une interface
  1.4932 +      utilisateur qui nous permettra de résoudre manuellement les éditions
  1.4933 +      conflictuelles sur le fichier <filename moreinfo="none">myfile.txt</filename>.
  1.4934 +      Cependant, pour simplifier ici les choses dans la présentation, nous
  1.4935 +      aimerions plutôt que la fusion (merge) échoue immédiatement. Voici une
  1.4936 +      façon de le faire.</para>
  1.4937 +
  1.4938 +    <!-- BEGIN ch04/resolve.export -->
  1.4939 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">export HGMERGE=false</userinput>
  1.4940 +</screen>
  1.4941 +<!-- END ch04/resolve.export -->
  1.4942 +
  1.4943 +
  1.4944 +    <para id="x_68e">Nous avons dit au processus de fusion de Mercurial
  1.4945 +      d'exécuter la commande <command moreinfo="none">false</command> (qui échoue
  1.4946 +      immédiatement, à la demande) s'il détecte une fusion (merge) qu'il ne
  1.4947 +      peut pas arranger automatiquement.</para>
  1.4948 +
  1.4949 +    <para id="x_68f">Si nous appelons maintenant <command role="hg-cmd" moreinfo="none">hg
  1.4950 +        merge</command>, il devrait échouer et reporter une erreur.</para>
  1.4951 +
  1.4952 +    <!-- BEGIN ch04/resolve.merge -->
  1.4953 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.4954 +merging myfile.txt
  1.4955 +merging myfile.txt failed!
  1.4956 +0 files updated, 0 files merged, 0 files removed, 1 files unresolved
  1.4957 +use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
  1.4958 +</screen>
  1.4959 +<!-- END ch04/resolve.merge -->
  1.4960 +
  1.4961 +
  1.4962 +    <para id="x_690">Même si nous ne remarquons pas qu'une fusion (merge) a
  1.4963 +      échoué, Mercurial nous empêchera de committer le résultat d'une fusion
  1.4964 +      ratée.</para>
  1.4965 +
  1.4966 +    <!-- BEGIN ch04/resolve.cifail -->
  1.4967 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Attempt to commit a failed merge'</userinput>
  1.4968 +abort: unresolved merge conflicts (see hg resolve)
  1.4969 +</screen>
  1.4970 +<!-- END ch04/resolve.cifail -->
  1.4971 +
  1.4972 +
  1.4973 +    <para id="x_691">Lorsque <command role="hg-cmd" moreinfo="none">hg commit</command>
  1.4974 +      échoue dans ce cas, il suggère que nous utilisons la commande peu
  1.4975 +      connue <command role="hg-cmd" moreinfo="none">hg resolve</command>.  Comme d'habitude,
  1.4976 +      <command role="hg-cmd" moreinfo="none">hg help resolve</command> affichera une aide
  1.4977 +      sommaire.</para>
  1.4978 +
  1.4979 +    <sect2>
  1.4980 +      <title>États de résolution des fichiers</title>
  1.4981 +      <!-- TODO Vérifier traduction : File resolution states -->
  1.4982 +
  1.4983 +      <para id="x_692">Lorsqu'une fusion intervient, la plupart des fichiers
  1.4984 +        vont, la plupart du temps, rester sans modification. Pour chaque
  1.4985 +        fichier sur lequel Mercurial doit faire quelque chose, il suit l'état
  1.4986 +        de celui-ci.</para>
  1.4987 +
  1.4988 +      <itemizedlist>
  1.4989 +        <listitem><para id="x_693">Un fichier
  1.4990 +            <quote><emphasis>resolved</emphasis></quote> a été fusionné
  1.4991 +            (merge) avec succès, que ce soit automatiquement par Mercurial ou
  1.4992 +            manuellement par une intervention humaine.</para></listitem>
  1.4993 +        <listitem><para id="x_694">Un fichier
  1.4994 +            <quote><emphasis>unresolved</emphasis></quote> n'a pas été
  1.4995 +            fusionné (merge) correctement et a besoin de plus
  1.4996 +            d'attention.</para>
  1.4997 +        </listitem>
  1.4998 +      </itemizedlist>
  1.4999 +
  1.5000 +      <para id="x_695">Si Mercurial voit un fichier
  1.5001 +        <emphasis>quelconque</emphasis> dans un état
  1.5002 +        <quote>unresolved</quote> après une fusion (merge), il considère que
  1.5003 +        la fusion (merge) a échoué. Heureusement, nous n'avons pas à
  1.5004 +        recommencer la procédure à partir du début.</para>
  1.5005 +
  1.5006 +      <para id="x_696">L'option <option role="hg-opt-resolve">--list</option>
  1.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
  1.5008 +        fusionné (merge).</para>
  1.5009 +
  1.5010 +      <!-- BEGIN ch04/resolve.list -->
  1.5011 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg resolve -l</userinput>
  1.5012 +U myfile.txt
  1.5013 +</screen>
  1.5014 +<!-- END ch04/resolve.list -->
  1.5015 +
  1.5016 +
  1.5017 +      <para id="x_697">En sortie de <command role="hg-cmd" moreinfo="none">hg
  1.5018 +          resolve</command>, un fichier "resolved" est marqué avec un
  1.5019 +        <literal moreinfo="none">R</literal>, alors qu'un fichier "unresolved" est marqué
  1.5020 +        d'un <literal moreinfo="none">U</literal>.  S'il existe un fichier listé avec un
  1.5021 +        <literal moreinfo="none">U</literal>, nous savons qu'essayer de committer le résultat
  1.5022 +        de la fusion (merge) échouera.</para>
  1.5023 +    </sect2>
  1.5024 +
  1.5025 +    <sect2>
  1.5026 +      <title>Résoudre une fusion de fichier</title>
  1.5027 +
  1.5028 +      <para id="x_698">Nous avons plusieurs options pour changer l'état d'un
  1.5029 +        fichier de "unresolved" à "resolved". Le plus commun est de relancer
  1.5030 +        <command role="hg-cmd" moreinfo="none">hg resolve</command>. Si nous passons les noms
  1.5031 +        des fichiers individuels ou des répertoires, ceci retentera la fusion
  1.5032 +        de tous les fichiers présents à cet endroit. Nous pouvons aussi
  1.5033 +        passer l'option <option role="hg-opt-resolve">--all</option> ou
  1.5034 +        <option role="hg-opt-resolve">-a</option> qui tentera de fusionner
  1.5035 +        <emphasis>tous</emphasis> les fichiers "unresolved".</para>
  1.5036 +
  1.5037 +      <para id="x_699">Mercurial nous laisse aussi modifier la résolution
  1.5038 +        d'un fichier directement. Nous pouvons marquer un fichier "resolved"
  1.5039 +        en utilisant l'option <option role="hg-opt-resolve">--mark</option>,
  1.5040 +        ou "unresolved" en utilisant l'option <option role="hg-opt-resolve">--unmark</option>. Ceci nous autorise à
  1.5041 +        nettoyer une fusion particulièrement compliquée à la main, et de
  1.5042 +        garder un suivi de nos progrès avec chaque fichier pendant que nous
  1.5043 +        procédons.</para>
  1.5044 +    </sect2>
  1.5045 +  </sect1>
  1.5046 +
  1.5047 +  <sect1>
  1.5048 +    <title>Des "diffs" plus utiles</title>
  1.5049 +
  1.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
  1.5051 +      la commande régulière <command moreinfo="none">diff</command>, mais ceci a quelques
  1.5052 +      inconvénients.</para>
  1.5053 +
  1.5054 +    <para id="x_6c8">Considérez le cas où nous utilisons <command role="hg-cmd" moreinfo="none">hg
  1.5055 +        rename</command> pour renommer un fichier.</para>
  1.5056 +
  1.5057 +    <!-- BEGIN ch04/diff.rename.basic -->
  1.5058 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rename a b</userinput>
  1.5059 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
  1.5060 +diff -r f5deb7868663 a
  1.5061 +--- a/a	Sun Aug 16 14:04:49 2009 +0000
  1.5062 ++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.5063 +@@ -1,1 +0,0 @@
  1.5064 +-a
  1.5065 +diff -r f5deb7868663 b
  1.5066 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  1.5067 ++++ b/b	Sun Aug 16 14:04:49 2009 +0000
  1.5068 +@@ -0,0 +1,1 @@
  1.5069 ++a
  1.5070 +</screen>
  1.5071 +<!-- END ch04/diff.rename.basic -->
  1.5072 +
  1.5073 +
  1.5074 +    <para id="x_6c9">La sortie de <command role="hg-cmd" moreinfo="none">hg diff</command>
  1.5075 +      ci-dessus cache le fait que nous avons simplement renommé un fichier.
  1.5076 +      La commande <command role="hg-cmd" moreinfo="none">hg diff</command> accepte l'option
  1.5077 +      <option>--git</option> ou <option>-g</option> pour utiliser un nouveau
  1.5078 +      format de diff qui montre ces informations sous une forme plus
  1.5079 +      expressive.</para>
  1.5080 +
  1.5081 +    <!-- BEGIN ch04/diff.rename.git -->
  1.5082 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff -g</userinput>
  1.5083 +diff --git a/a b/b
  1.5084 +rename from a
  1.5085 +rename to b
  1.5086 +</screen>
  1.5087 +<!-- END ch04/diff.rename.git -->
  1.5088 +
  1.5089 +
  1.5090 +    <para id="x_6ca">Cette option peut aussi aider avec le cas autrement
  1.5091 +      confus : un fichier qui apparaît comme étant modifié en accord avec
  1.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
  1.5093 +      survenir si nous changeons les permissions d'exécution du
  1.5094 +      fichier.</para>
  1.5095 +
  1.5096 +    <!-- BEGIN ch04/diff.chmod -->
  1.5097 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">chmod +x a</userinput>
  1.5098 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg st</userinput>
  1.5099 +M a
  1.5100 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
  1.5101 +</screen>
  1.5102 +<!-- END ch04/diff.chmod -->
  1.5103 +
  1.5104 +
  1.5105 +    <para id="x_6cb">La commande normale <command moreinfo="none">diff</command> ne fait pas
  1.5106 +      attention aux permissions des fichiers, ce qui explique pourquoi
  1.5107 +      <command role="hg-cmd" moreinfo="none">hg diff</command> n'affiche rien du tout par
  1.5108 +      défaut. Si nous lui passons l'option <option>-g</option>, ceci nous
  1.5109 +      informe de ce qu'il s'est vraiment passé.</para>
  1.5110 +
  1.5111 +    <!-- BEGIN ch04/diff.chmod.git -->
  1.5112 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff -g</userinput>
  1.5113 +diff --git a/a b/a
  1.5114 +old mode 100644
  1.5115 +new mode 100755
  1.5116 +</screen>
  1.5117 +<!-- END ch04/diff.chmod.git -->
  1.5118 +
  1.5119 +  </sect1>
  1.5120 +
  1.5121 +  <sect1>
  1.5122 +    <title>Quels fichiers suivre et lesquels éviter</title>
  1.5123 +
  1.5124 +    <para id="x_6cc">Les systèmes de gestion de révisions sont en général
  1.5125 +      meilleurs pour gérer les fichiers textes qui sont écrits par les
  1.5126 +      humains, comme le code source, où les fichiers ne changent pas
  1.5127 +      énormément d'une révision à l'autre. Certains systèmes de gestion de
  1.5128 +      révisions centralisés peuvent aussi traiter très convenablement les
  1.5129 +      fichiers binaires, tels que les images bitmap.</para>
  1.5130 +
  1.5131 +    <para id="x_6cd">Par exemple, une équipe de développement de jeux va
  1.5132 +      probablement gérer les deux types : ses codes source et tous ses binaires
  1.5133 +      (ex. données géométriques, textures, schémas de cartes) dans un système
  1.5134 +      de contrôle de révisions.</para>
  1.5135 +    <!-- Vérifier la traduction de map layouts que j'ai traduit par schémas
  1.5136 +    de cartes -->
  1.5137 +
  1.5138 +    <para id="x_6ce">Puisqu'il est d'habitude impossible de fusionner (merge)
  1.5139 +      deux modifications conflictuelles sur un fichier binaire, les systèmes
  1.5140 +      de version centralisés offrent souvent un mécanisme de verrou (lock) qui
  1.5141 +      permet à un utilisateur de dire <quote>Je suis la seule personne qui
  1.5142 +        peut éditer ce fichier</quote>.</para>
  1.5143 +
  1.5144 +    <para id="x_6cf">En comparaison avec un système centralisé, un système
  1.5145 +      décentralisé de gestion de révision change certains facteurs qui
  1.5146 +      guident les décisions sur quels fichiers gérer et comment.</para>
  1.5147 +
  1.5148 +    <para id="x_6d0">Par exemple, un système distribué de gestion de révisions
  1.5149 +      ne peut pas, par sa nature, offrir un système de véroux (lock) sur les
  1.5150 +      fichiers. Il n'y a donc pas de mécanisme inclus pour empêcher deux
  1.5151 +      personnes de faire des modifications conflictuelles sur un fichier
  1.5152 +      binaire. Si vous avez une équipe où plusieurs personnes peuvent souvent
  1.5153 +      éditer un fichier binaire, cela ne serait pas une très bonne idée
  1.5154 +      d'utiliser Mercurial —ou tout autre système distribué de gestion
  1.5155 +      de révisions—pour gérer ces fichiers.</para>
  1.5156 +
  1.5157 +    <para id="x_6d1">Lorsque vous sauvegardez les modifications sur un
  1.5158 +      fichier, Mercurial ne sauvegarde d'habitude que les différences entre
  1.5159 +      la version précédente et la version actuelle d'un fichier. Pour la
  1.5160 +      plupart des fichiers texte, ceci est très efficace. Cependant, certains
  1.5161 +      fichiers (en particulier les fichiers binaires) sont construits d'une
  1.5162 +      façon que même un petit changement sur un contenu logique résulte sur
  1.5163 +      un changement de la plupart des octets du fichier. Par exemple, les
  1.5164 +      fichiers compressés sont particulièrement sujets à ce comportement. Si
  1.5165 +      les différences entre deux versions successives d'un fichier sont
  1.5166 +      toujours très grandes, Mercurial ne sera pas capable de sauvegarder
  1.5167 +      l'historique des révisions sur le fichier très efficacement. Ceci peut
  1.5168 +      affecter aussi bien les besoins pour la sauvegarde locale que le temps
  1.5169 +      nécessaire à cloner le dépôt.</para>
  1.5170 +
  1.5171 +    <para id="x_6d2">Pour avoir une idée de comment ceci pourrait vous
  1.5172 +      affecter en pratique, supposez que nous voulions que Mercurial gère des
  1.5173 +      documents OpenOffice. OpenOffice sauvegarde les documents sur le disque
  1.5174 +      comme des fichiers compressés zip. Même le fait d'éditer ces fichiers
  1.5175 +      d'une seule lettre, changera les bits de la quasi totalité du fichier
  1.5176 +      lorsque vous le sauvegarderez. Maintenant, supposez que ce fichier
  1.5177 +      fasse une taille de 2Mo. Puisque la plupart du fichier change à chaque
  1.5178 +      fois que vous sauvegardez, Mercurial aura à sauvegarder tous les 2Mo du
  1.5179 +      fichier à chaque commit, alors que de votre point de vue, il n'y a
  1.5180 +      que peu de mots qui changent à chaque fois. Un seul fichier
  1.5181 +      souvent édité qui n'est pas bien traité par les hypothèses que Mercurial
  1.5182 +      fait sur les sauvegardes peut facilement avoir un effet colossal sur la
  1.5183 +      taille du dépôt.</para>
  1.5184 +
  1.5185 +    <para id="x_6d3">Même pire, si vous et quelqu'un d'autre éditez le même
  1.5186 +      document OpenOffice sur lequel vous travaillez, il n'y a pas de façon
  1.5187 +      utile pour fusionner votre travail. En fait, il n'y a pas de moyen
  1.5188 +      utile de montrer que les différences sont faites à partir de votre
  1.5189 +      vision des modifications.</para>
  1.5190 +
  1.5191 +    <para id="x_6d4">Il y a ainsi quelques recommandations claires sur les
  1.5192 +      types de fichiers spécifiques avec lesquels faire très
  1.5193 +      attention.</para>
  1.5194 +
  1.5195 +    <itemizedlist>
  1.5196 +      <listitem><para id="x_6d5">Les fichier qui sont très gros et
  1.5197 +          incompressibles, comme les images ISO de CD-ROM, sont, par
  1.5198 +          construction très gros et les cloner à travers un réseau sera très
  1.5199 +          long.</para></listitem>
  1.5200 +     <!-- TODO : Trouver une meilleure traduction pour : ISO CD-ROM images, will by
  1.5201 +     virtue of sheer size make clones over a network very slow. -->
  1.5202 +      <listitem><para id="x_6d6">Les fichiers qui changent beaucoup d'une
  1.5203 +          révision à l'autre peuvent être très chers à sauvegarder si vous
  1.5204 +          les éditez fréquemment, de même que les conflits entre deux éditions
  1.5205 +          concurrentes peuvent être difficiles à résoudre.</para>
  1.5206 +      </listitem>
  1.5207 +    </itemizedlist>
  1.5208 +  </sect1>
  1.5209 +
  1.5210 +  <sect1>
  1.5211 +    <title>Sauvegardes et miroirs</title>
  1.5212 +
  1.5213 +    <para id="x_6d7">Puisque Mercurial maintient une copie complète de
  1.5214 +      l'historique de chaque clone, toute personne qui utilise Mercurial pour
  1.5215 +      collaborer à un projet peut potentiellement agir comme une source de
  1.5216 +      sauvegarde si une catastrophe survenait. Si un dépôt central devient
  1.5217 +      indisponible, vous pouvez construire un remplaçant en clonant une copie
  1.5218 +      du dépôt à partir d'un des contributeurs en récupérant (pull) tous les
  1.5219 +      changements qui n'auraient pas été vus par les autres.</para>
  1.5220 +
  1.5221 +    <para id="x_6d8">Il est simple d'utiliser Mercurial pour construire des
  1.5222 +      serveurs hors site de sauvegarde et des miroirs distants. Initiez une
  1.5223 +      tâche périodique (ex. via la commande <command moreinfo="none">cron</command>) sur un
  1.5224 +      serveur distant pour récupérer (pull) les changements de votre dépôt
  1.5225 +      distant chaque heure. Ceci sera difficile seulement dans le cas
  1.5226 +      improbable où le nombre des dépôts maîtres que vous maintenez change
  1.5227 +      souvent, auquel cas vous aurez besoin de faire un peu de scripting pour
  1.5228 +      rafraichir la liste des dépôt à sauvegarder.</para>
  1.5229 +
  1.5230 +    <para id="x_6d9">Si vous exécutez des sauvegardes traditionnelles de
  1.5231 +      votre dépôt maître sur bande ou disque, et que vous voulez sauvegarder
  1.5232 +      un dépôt nommé <filename moreinfo="none">myrepo</filename>, utilisez la commande
  1.5233 +      <command moreinfo="none">hg clone -U myrepo myrepo.bak</command> pour créer un clone de
  1.5234 +      <filename moreinfo="none">myrepo</filename> avant de commencer vos backups.
  1.5235 +      L'option <option>-U</option> ne crée pas de répertoire de travail après
  1.5236 +      que le clone soit accompli, puisque ceci serait superflu et ferait que
  1.5237 +      la sauvegarde prenne plus de temps.</para>
  1.5238 +
  1.5239 +    <para id="x_6da">Si vous voulez ensuite sauvegarder
  1.5240 +      <filename moreinfo="none">myrepo.bak</filename> au lieu de <filename moreinfo="none">myrepo</filename>,
  1.5241 +      vous aurez la garantie d'avoir une image (snapshot) consistante de
  1.5242 +      votre dépôt sur lequel un développeur insomniaque n'enverra (push) pas de
  1.5243 +      changements en milieu de sauvegarde.</para>
  1.5244 +  </sect1>
  1.5245 +</chapter>
  1.5246 +
  1.5247 +<!--
  1.5248 +local variables: 
  1.5249 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.5250 +end:
  1.5251 +-->
  1.5252 +
  1.5253 +  <!-- BEGIN ch06 -->
  1.5254 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.5255 +
  1.5256 +<chapter id="cha:collab">
  1.5257 +  <?dbhtml filename="collaborating-with-other-people.html"?>
  1.5258 +  <title>Collaborating with other people</title>
  1.5259 +
  1.5260 +  <para id="x_44a">As a completely decentralised tool, Mercurial doesn't impose
  1.5261 +    any policy on how people ought to work with each other.  However,
  1.5262 +    if you're new to distributed revision control, it helps to have
  1.5263 +    some tools and examples in mind when you're thinking about
  1.5264 +    possible workflow models.</para>
  1.5265 +
  1.5266 +  <sect1>
  1.5267 +    <title>Mercurial's web interface</title>
  1.5268 +
  1.5269 +    <para id="x_44b">Mercurial has a powerful web interface that provides several
  1.5270 +      useful capabilities.</para>
  1.5271 +
  1.5272 +    <para id="x_44c">For interactive use, the web interface lets you browse a
  1.5273 +      single repository or a collection of repositories.  You can view
  1.5274 +      the history of a repository, examine each change (comments and
  1.5275 +      diffs), and view the contents of each directory and file.  You
  1.5276 +      can even get a view of history that gives a graphical view of
  1.5277 +      the relationships between individual changes and merges.</para>
  1.5278 +
  1.5279 +    <para id="x_44d">Also for human consumption, the web interface provides
  1.5280 +      Atom and RSS feeds of the changes in a repository.  This lets you
  1.5281 +      <quote>subscribe</quote> to a repository using your favorite
  1.5282 +      feed reader, and be automatically notified of activity in that
  1.5283 +      repository as soon as it happens.  I find this capability much
  1.5284 +      more convenient than the model of subscribing to a mailing list
  1.5285 +      to which notifications are sent, as it requires no additional
  1.5286 +      configuration on the part of whoever is serving the
  1.5287 +      repository.</para>
  1.5288 +
  1.5289 +    <para id="x_44e">The web interface also lets remote users clone a repository,
  1.5290 +      pull changes from it, and (when the server is configured to
  1.5291 +      permit it) push changes back to it.  Mercurial's HTTP tunneling
  1.5292 +      protocol aggressively compresses data, so that it works
  1.5293 +      efficiently even over low-bandwidth network connections.</para>
  1.5294 +
  1.5295 +    <para id="x_44f">The easiest way to get started with the web interface is to
  1.5296 +      use your web browser to visit an existing repository, such as
  1.5297 +      the master Mercurial repository at <ulink url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para>
  1.5298 +
  1.5299 +    <para id="x_450">If you're interested in providing a web interface
  1.5300 +      to your own repositories, there are several good ways to do
  1.5301 +      this.</para>
  1.5302 +
  1.5303 +    <para id="x_69d">The easiest and fastest way to get started in an informal
  1.5304 +      environment is to use the <command role="hg-cmd" moreinfo="none">hg
  1.5305 +	serve</command> command, which is best suited to short-term
  1.5306 +      <quote>lightweight</quote> serving.  See <xref linkend="sec:collab:serve"/> below for details of how to use
  1.5307 +      this command.</para>
  1.5308 +
  1.5309 +    <para id="x_69e">For longer-lived repositories that you'd like to
  1.5310 +      have permanently available, there are several public hosting
  1.5311 +      services available.  Some are free to open source projects,
  1.5312 +      while others offer paid commercial hosting.  An up-to-date list
  1.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>
  1.5314 +
  1.5315 +    <para id="x_6a0">If you would prefer to host your own repositories, Mercurial
  1.5316 +      has built-in support for several popular hosting technologies,
  1.5317 +      most notably CGI (Common Gateway Interface), and WSGI (Web
  1.5318 +      Services Gateway Interface).  See <xref linkend="sec:collab:cgi"/> for details of CGI and WSGI
  1.5319 +      configuration.</para>
  1.5320 +  </sect1>
  1.5321 +
  1.5322 +  <sect1>
  1.5323 +    <title>Collaboration models</title>
  1.5324 +
  1.5325 +    <para id="x_451">With a suitably flexible tool, making decisions about
  1.5326 +      workflow is much more of a social engineering challenge than a
  1.5327 +      technical one. Mercurial imposes few limitations on how you can
  1.5328 +      structure the flow of work in a project, so it's up to you and
  1.5329 +      your group to set up and live with a model that matches your own
  1.5330 +      particular needs.</para>
  1.5331 +
  1.5332 +    <sect2>
  1.5333 +      <title>Factors to keep in mind</title>
  1.5334 +
  1.5335 +      <para id="x_452">The most important aspect of any model that you must keep
  1.5336 +	in mind is how well it matches the needs and capabilities of
  1.5337 +	the people who will be using it.  This might seem
  1.5338 +	self-evident; even so, you still can't afford to forget it for
  1.5339 +	a moment.</para>
  1.5340 +
  1.5341 +      <para id="x_453">I once put together a workflow model that seemed to make
  1.5342 +	perfect sense to me, but that caused a considerable amount of
  1.5343 +	consternation and strife within my development team.  In spite
  1.5344 +	of my attempts to explain why we needed a complex set of
  1.5345 +	branches, and how changes ought to flow between them, a few
  1.5346 +	team members revolted.  Even though they were smart people,
  1.5347 +	they didn't want to pay attention to the constraints we were
  1.5348 +	operating under, or face the consequences of those constraints
  1.5349 +	in the details of the model that I was advocating.</para>
  1.5350 +
  1.5351 +      <para id="x_454">Don't sweep foreseeable social or technical problems under
  1.5352 +	the rug. Whatever scheme you put into effect, you should plan
  1.5353 +	for mistakes and problem scenarios.  Consider adding automated
  1.5354 +	machinery to prevent, or quickly recover from, trouble that
  1.5355 +	you can anticipate.  As an example, if you intend to have a
  1.5356 +	branch with not-for-release changes in it, you'd do well to
  1.5357 +	think early about the possibility that someone might
  1.5358 +	accidentally merge those changes into a release branch.  You
  1.5359 +	could avoid this particular problem by writing a hook that
  1.5360 +	prevents changes from being merged from an inappropriate
  1.5361 +	branch.</para>
  1.5362 +    </sect2>
  1.5363 +
  1.5364 +    <sect2>
  1.5365 +      <title>Informal anarchy</title>
  1.5366 +
  1.5367 +      <para id="x_455">I wouldn't suggest an <quote>anything goes</quote>
  1.5368 +	approach as something sustainable, but it's a model that's
  1.5369 +	easy to grasp, and it works perfectly well in a few unusual
  1.5370 +	situations.</para>
  1.5371 +
  1.5372 +      <para id="x_456">As one example, many projects have a loose-knit group of
  1.5373 +	collaborators who rarely physically meet each other.  Some
  1.5374 +	groups like to overcome the isolation of working at a distance
  1.5375 +	by organizing occasional <quote>sprints</quote>.  In a sprint,
  1.5376 +	a number of people get together in a single location (a
  1.5377 +	company's conference room, a hotel meeting room, that kind of
  1.5378 +	place) and spend several days more or less locked in there,
  1.5379 +	hacking intensely on a handful of projects.</para>
  1.5380 +
  1.5381 +      <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the
  1.5382 +	<command role="hg-cmd" moreinfo="none">hg serve</command> command, since
  1.5383 +	<command role="hg-cmd" moreinfo="none">hg serve</command> does not require any
  1.5384 +	fancy server infrastructure.  You can get started with
  1.5385 +	<command role="hg-cmd" moreinfo="none">hg serve</command> in moments, by
  1.5386 +	reading <xref linkend="sec:collab:serve"/> below.  Then simply
  1.5387 +	tell the person next to you that you're running a server, send
  1.5388 +	the URL to them in an instant message, and you immediately
  1.5389 +	have a quick-turnaround way to work together.  They can type
  1.5390 +	your URL into their web browser and quickly review your
  1.5391 +	changes; or they can pull a bugfix from you and verify it; or
  1.5392 +	they can clone a branch containing a new feature and try it
  1.5393 +	out.</para>
  1.5394 +
  1.5395 +      <para id="x_458">The charm, and the problem, with doing things
  1.5396 +	in an ad hoc fashion like this is that only people who know
  1.5397 +	about your changes, and where they are, can see them.  Such an
  1.5398 +	informal approach simply doesn't scale beyond a handful
  1.5399 +	people, because each individual needs to know about
  1.5400 +	<emphasis>n</emphasis> different repositories to pull
  1.5401 +	from.</para>
  1.5402 +    </sect2>
  1.5403 +
  1.5404 +    <sect2>
  1.5405 +      <title>A single central repository</title>
  1.5406 +
  1.5407 +      <para id="x_459">For smaller projects migrating from a centralised revision
  1.5408 +	control tool, perhaps the easiest way to get started is to
  1.5409 +	have changes flow through a single shared central repository.
  1.5410 +	This is also the most common <quote>building block</quote> for
  1.5411 +	more ambitious workflow schemes.</para>
  1.5412 +
  1.5413 +      <para id="x_45a">Contributors start by cloning a copy of this repository.
  1.5414 +	They can pull changes from it whenever they need to, and some
  1.5415 +	(perhaps all) developers have permission to push a change back
  1.5416 +	when they're ready for other people to see it.</para>
  1.5417 +
  1.5418 +      <para id="x_45b">Under this model, it can still often make sense for people
  1.5419 +	to pull changes directly from each other, without going
  1.5420 +	through the central repository.  Consider a case in which I
  1.5421 +	have a tentative bug fix, but I am worried that if I were to
  1.5422 +	publish it to the central repository, it might subsequently
  1.5423 +	break everyone else's trees as they pull it.  To reduce the
  1.5424 +	potential for damage, I can ask you to clone my repository
  1.5425 +	into a temporary repository of your own and test it.  This
  1.5426 +	lets us put off publishing the potentially unsafe change until
  1.5427 +	it has had a little testing.</para>
  1.5428 +
  1.5429 +      <para id="x_45c">If a team is hosting its own repository in this
  1.5430 +	kind of scenario, people will usually use the
  1.5431 +	<command moreinfo="none">ssh</command> protocol to securely push changes to
  1.5432 +	the central repository, as documented in <xref linkend="sec:collab:ssh"/>.  It's also usual to publish a
  1.5433 +	read-only copy of the repository over HTTP, as in
  1.5434 +	<xref linkend="sec:collab:cgi"/>. Publishing over HTTP
  1.5435 +	satisfies the needs of people who don't have push access, and
  1.5436 +	those who want to use web browsers to browse the repository's
  1.5437 +	history.</para>
  1.5438 +    </sect2>
  1.5439 +
  1.5440 +    <sect2>
  1.5441 +      <title>A hosted central repository</title>
  1.5442 +
  1.5443 +      <para id="x_6a1">A wonderful thing about public hosting services like
  1.5444 +	<ulink url="http://bitbucket.org/">Bitbucket</ulink> is that
  1.5445 +	not only do they handle the fiddly server configuration
  1.5446 +	details, such as user accounts, authentication, and secure
  1.5447 +	wire protocols, they provide additional infrastructure to make
  1.5448 +	this model work well.</para>
  1.5449 +
  1.5450 +      <para id="x_6a2">For instance, a well-engineered hosting service will let
  1.5451 +	people clone their own copies of a repository with a single
  1.5452 +	click.  This lets people work in separate spaces and share
  1.5453 +	their changes when they're ready.</para>
  1.5454 +
  1.5455 +      <para id="x_6a3">In addition, a good hosting service will let people
  1.5456 +	communicate with each other, for instance to say <quote>there
  1.5457 +	  are changes ready for you to review in this
  1.5458 +	  tree</quote>.</para>
  1.5459 +    </sect2>
  1.5460 +
  1.5461 +    <sect2>
  1.5462 +      <title>Working with multiple branches</title>
  1.5463 +
  1.5464 +      <para id="x_45d">Projects of any significant size naturally tend to make
  1.5465 +	progress on several fronts simultaneously.  In the case of
  1.5466 +	software, it's common for a project to go through periodic
  1.5467 +	official releases.  A release might then go into
  1.5468 +	<quote>maintenance mode</quote> for a while after its first
  1.5469 +	publication; maintenance releases tend to contain only bug
  1.5470 +	fixes, not new features.  In parallel with these maintenance
  1.5471 +	releases, one or more future releases may be under
  1.5472 +	development.  People normally use the word
  1.5473 +	<quote>branch</quote> to refer to one of these many slightly
  1.5474 +	different directions in which development is
  1.5475 +	proceeding.</para>
  1.5476 +
  1.5477 +      <para id="x_45e">Mercurial is particularly well suited to managing a number
  1.5478 +	of simultaneous, but not identical, branches.  Each
  1.5479 +	<quote>development direction</quote> can live in its own
  1.5480 +	central repository, and you can merge changes from one to
  1.5481 +	another as the need arises.  Because repositories are
  1.5482 +	independent of each other, unstable changes in a development
  1.5483 +	branch will never affect a stable branch unless someone
  1.5484 +	explicitly merges those changes into the stable branch.</para>
  1.5485 +
  1.5486 +      <para id="x_45f">Here's an example of how this can work in practice.  Let's
  1.5487 +	say you have one <quote>main branch</quote> on a central
  1.5488 +	server.</para>
  1.5489 +
  1.5490 +      <!-- BEGIN branching.init -->
  1.5491 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init main</userinput>
  1.5492 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd main</userinput>
  1.5493 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This is a boring feature.' &gt; myfile</userinput>
  1.5494 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'We have reached an important milestone!'</userinput>
  1.5495 +adding myfile
  1.5496 +</screen>
  1.5497 +<!-- END branching.init -->
  1.5498 +
  1.5499 +
  1.5500 +      <para id="x_460">People clone it, make changes locally, test them, and push
  1.5501 +	them back.</para>
  1.5502 +
  1.5503 +      <para id="x_461">Once the main branch reaches a release milestone, you can
  1.5504 +	use the <command role="hg-cmd" moreinfo="none">hg tag</command> command to
  1.5505 +	give a permanent name to the milestone revision.</para>
  1.5506 +
  1.5507 +	<!-- BEGIN branching.tag -->
  1.5508 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag v1.0</userinput>
  1.5509 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.5510 +changeset:   1:5e447fdaf941
  1.5511 +tag:         tip
  1.5512 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.5513 +date:        Sun Aug 16 14:04:47 2009 +0000
  1.5514 +summary:     Added tag v1.0 for changeset 6412b791fd06
  1.5515 +
  1.5516 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  1.5517 +tip                                1:5e447fdaf941
  1.5518 +v1.0                               0:6412b791fd06
  1.5519 +</screen>
  1.5520 +<!-- END branching.tag -->
  1.5521 +
  1.5522 +
  1.5523 +      <para id="x_462">Let's say some ongoing
  1.5524 +	development occurs on the main branch.</para>
  1.5525 +
  1.5526 +      <!-- BEGIN branching.main -->
  1.5527 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../main</userinput>
  1.5528 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This is exciting and new!' &gt;&gt; myfile</userinput>
  1.5529 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Add a new feature'</userinput>
  1.5530 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.5531 +This is a boring feature.
  1.5532 +This is exciting and new!
  1.5533 +</screen>
  1.5534 +<!-- END branching.main -->
  1.5535 +
  1.5536 +
  1.5537 +      <para id="x_463">Using the tag that was recorded at the milestone, people
  1.5538 +	who clone that repository at any time in the future can use
  1.5539 +	<command role="hg-cmd" moreinfo="none">hg update</command> to get a copy of
  1.5540 +	the working directory exactly as it was when that tagged
  1.5541 +	revision was committed.</para>
  1.5542 +
  1.5543 +      <!-- BEGIN branching.update -->
  1.5544 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.5545 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -U main main-old</userinput>
  1.5546 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd main-old</userinput>
  1.5547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update v1.0</userinput>
  1.5548 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.5549 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.5550 +This is a boring feature.
  1.5551 +</screen>
  1.5552 +<!-- END branching.update -->
  1.5553 +
  1.5554 +
  1.5555 +      <para id="x_464">In addition, immediately after the main branch is tagged,
  1.5556 +	we can then clone the main branch on the server to a new
  1.5557 +	<quote>stable</quote> branch, also on the server.</para>
  1.5558 +
  1.5559 +      <!-- BEGIN branching.clone -->
  1.5560 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.5561 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -rv1.0 main stable</userinput>
  1.5562 +requesting all changes
  1.5563 +adding changesets
  1.5564 +adding manifests
  1.5565 +adding file changes
  1.5566 +added 1 changesets with 1 changes to 1 files
  1.5567 +updating working directory
  1.5568 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.5569 +</screen>
  1.5570 +<!-- END branching.clone -->
  1.5571 +
  1.5572 +
  1.5573 +      <para id="x_465">If we need to make a change to the stable
  1.5574 +	branch, we can then clone <emphasis>that</emphasis>
  1.5575 +	repository, make our changes, commit, and push our changes
  1.5576 +	back there.</para>
  1.5577 +
  1.5578 +      <!-- BEGIN branching.stable -->
  1.5579 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone stable stable-fix</userinput>
  1.5580 +updating working directory
  1.5581 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.5582 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd stable-fix</userinput>
  1.5583 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This is a fix to a boring feature.' &gt; myfile</userinput>
  1.5584 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Fix a bug'</userinput>
  1.5585 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  1.5586 +pushing to /tmp/branchingPsTziR/stable
  1.5587 +searching for changes
  1.5588 +adding changesets
  1.5589 +adding manifests
  1.5590 +adding file changes
  1.5591 +added 1 changesets with 1 changes to 1 files
  1.5592 +</screen>
  1.5593 +<!-- END branching.stable -->
  1.5594 +
  1.5595 +
  1.5596 +      <para id="x_466">Because Mercurial repositories are independent, and
  1.5597 +	Mercurial doesn't move changes around automatically, the
  1.5598 +	stable and main branches are <emphasis>isolated</emphasis>
  1.5599 +	from each other.  The changes that we made on the main branch
  1.5600 +	don't <quote>leak</quote> to the stable branch, and vice
  1.5601 +	versa.</para>
  1.5602 +
  1.5603 +      <para id="x_467">We'll often want all of our bugfixes on the stable
  1.5604 +	branch to show up on the main branch, too.  Rather than
  1.5605 +	rewrite a bugfix on the main branch, we can simply pull and
  1.5606 +	merge changes from the stable to the main branch, and
  1.5607 +	Mercurial will bring those bugfixes in for us.</para>
  1.5608 +
  1.5609 +      <!-- BEGIN branching.merge -->
  1.5610 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../main</userinput>
  1.5611 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../stable</userinput>
  1.5612 +pulling from ../stable
  1.5613 +searching for changes
  1.5614 +adding changesets
  1.5615 +adding manifests
  1.5616 +adding file changes
  1.5617 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.5618 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.5619 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.5620 +merging myfile
  1.5621 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  1.5622 +(branch merge, don't forget to commit)
  1.5623 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Bring in bugfix from stable branch'</userinput>
  1.5624 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.5625 +This is a fix to a boring feature.
  1.5626 +This is exciting and new!
  1.5627 +</screen>
  1.5628 +<!-- END branching.merge -->
  1.5629 +
  1.5630 +
  1.5631 +      <para id="x_468">The main branch will still contain changes that
  1.5632 +	are not on the stable branch, but it will also contain all of
  1.5633 +	the bugfixes from the stable branch.  The stable branch
  1.5634 +	remains unaffected by these changes, since changes are only
  1.5635 +	flowing from the stable to the main branch, and not the other
  1.5636 +	way.</para>
  1.5637 +    </sect2>
  1.5638 +
  1.5639 +    <sect2>
  1.5640 +      <title>Feature branches</title>
  1.5641 +
  1.5642 +      <para id="x_469">For larger projects, an effective way to manage change is
  1.5643 +	to break up a team into smaller groups.  Each group has a
  1.5644 +	shared branch of its own, cloned from a single
  1.5645 +	<quote>master</quote> branch used by the entire project.
  1.5646 +	People working on an individual branch are typically quite
  1.5647 +	isolated from developments on other branches.</para>
  1.5648 +
  1.5649 +      <figure id="fig:collab:feature-branches" float="0">
  1.5650 +	<title>Feature branches</title>
  1.5651 +	<mediaobject>
  1.5652 +	  <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject>
  1.5653 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.5654 +	</mediaobject>
  1.5655 +      </figure>
  1.5656 +
  1.5657 +      <para id="x_46b">When a particular feature is deemed to be in suitable
  1.5658 +	shape, someone on that feature team pulls and merges from the
  1.5659 +	master branch into the feature branch, then pushes back up to
  1.5660 +	the master branch.</para>
  1.5661 +    </sect2>
  1.5662 +
  1.5663 +    <sect2>
  1.5664 +      <title>The release train</title>
  1.5665 +
  1.5666 +      <para id="x_46c">Some projects are organized on a <quote>train</quote>
  1.5667 +	basis: a release is scheduled to happen every few months, and
  1.5668 +	whatever features are ready when the <quote>train</quote> is
  1.5669 +	ready to leave are allowed in.</para>
  1.5670 +
  1.5671 +      <para id="x_46d">This model resembles working with feature branches.  The
  1.5672 +	difference is that when a feature branch misses a train,
  1.5673 +	someone on the feature team pulls and merges the changes that
  1.5674 +	went out on that train release into the feature branch, and
  1.5675 +	the team continues its work on top of that release so that
  1.5676 +	their feature can make the next release.</para>
  1.5677 +    </sect2>
  1.5678 +
  1.5679 +    <sect2>
  1.5680 +      <title>The Linux kernel model</title>
  1.5681 +
  1.5682 +      <para id="x_46e">The development of the Linux kernel has a shallow
  1.5683 +	hierarchical structure, surrounded by a cloud of apparent
  1.5684 +	chaos.  Because most Linux developers use
  1.5685 +	<command moreinfo="none">git</command>, a distributed revision control tool
  1.5686 +	with capabilities similar to Mercurial, it's useful to
  1.5687 +	describe the way work flows in that environment; if you like
  1.5688 +	the ideas, the approach translates well across tools.</para>
  1.5689 +
  1.5690 +      <para id="x_46f">At the center of the community sits Linus Torvalds, the
  1.5691 +	creator of Linux.  He publishes a single source repository
  1.5692 +	that is considered the <quote>authoritative</quote> current
  1.5693 +	tree by the entire developer community. Anyone can clone
  1.5694 +	Linus's tree, but he is very choosy about whose trees he pulls
  1.5695 +	from.</para>
  1.5696 +
  1.5697 +      <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>.
  1.5698 +	As a general rule, he pulls whatever changes they publish, in
  1.5699 +	most cases without even reviewing those changes.  Some of
  1.5700 +	those lieutenants are generally agreed to be
  1.5701 +	<quote>maintainers</quote>, responsible for specific
  1.5702 +	subsystems within the kernel.  If a random kernel hacker wants
  1.5703 +	to make a change to a subsystem that they want to end up in
  1.5704 +	Linus's tree, they must find out who the subsystem's
  1.5705 +	maintainer is, and ask that maintainer to take their change.
  1.5706 +	If the maintainer reviews their changes and agrees to take
  1.5707 +	them, they'll pass them along to Linus in due course.</para>
  1.5708 +
  1.5709 +      <para id="x_471">Individual lieutenants have their own approaches to
  1.5710 +	reviewing, accepting, and publishing changes; and for deciding
  1.5711 +	when to feed them to Linus.  In addition, there are several
  1.5712 +	well known branches that people use for different purposes.
  1.5713 +	For example, a few people maintain <quote>stable</quote>
  1.5714 +	repositories of older versions of the kernel, to which they
  1.5715 +	apply critical fixes as needed.  Some maintainers publish
  1.5716 +	multiple trees: one for experimental changes; one for changes
  1.5717 +	that they are about to feed upstream; and so on.  Others just
  1.5718 +	publish a single tree.</para>
  1.5719 +
  1.5720 +      <para id="x_472">This model has two notable features.  The first is that
  1.5721 +	it's <quote>pull only</quote>.  You have to ask, convince, or
  1.5722 +	beg another developer to take a change from you, because there
  1.5723 +	are almost no trees to which more than one person can push,
  1.5724 +	and there's no way to push changes into a tree that someone
  1.5725 +	else controls.</para>
  1.5726 +
  1.5727 +      <para id="x_473">The second is that it's based on reputation and acclaim.
  1.5728 +	If you're an unknown, Linus will probably ignore changes from
  1.5729 +	you without even responding.  But a subsystem maintainer will
  1.5730 +	probably review them, and will likely take them if they pass
  1.5731 +	their criteria for suitability. The more <quote>good</quote>
  1.5732 +	changes you contribute to a maintainer, the more likely they
  1.5733 +	are to trust your judgment and accept your changes.  If you're
  1.5734 +	well-known and maintain a long-lived branch for something
  1.5735 +	Linus hasn't yet accepted, people with similar interests may
  1.5736 +	pull your changes regularly to keep up with your work.</para>
  1.5737 +
  1.5738 +      <para id="x_474">Reputation and acclaim don't necessarily cross subsystem
  1.5739 +	or <quote>people</quote> boundaries.  If you're a respected
  1.5740 +	but specialised storage hacker, and you try to fix a
  1.5741 +	networking bug, that change will receive a level of scrutiny
  1.5742 +	from a network maintainer comparable to a change from a
  1.5743 +	complete stranger.</para>
  1.5744 +
  1.5745 +      <para id="x_475">To people who come from more orderly project backgrounds,
  1.5746 +	the comparatively chaotic Linux kernel development process
  1.5747 +	often seems completely insane.  It's subject to the whims of
  1.5748 +	individuals; people make sweeping changes whenever they deem
  1.5749 +	it appropriate; and the pace of development is astounding.
  1.5750 +	And yet Linux is a highly successful, well-regarded piece of
  1.5751 +	software.</para>
  1.5752 +    </sect2>
  1.5753 +
  1.5754 +    <sect2>
  1.5755 +      <title>Pull-only versus shared-push collaboration</title>
  1.5756 +
  1.5757 +      <para id="x_476">A perpetual source of heat in the open source community is
  1.5758 +	whether a development model in which people only ever pull
  1.5759 +	changes from others is <quote>better than</quote> one in which
  1.5760 +	multiple people can push changes to a shared
  1.5761 +	repository.</para>
  1.5762 +
  1.5763 +      <para id="x_477">Typically, the backers of the shared-push model use tools
  1.5764 +	that actively enforce this approach.  If you're using a
  1.5765 +	centralised revision control tool such as Subversion, there's
  1.5766 +	no way to make a choice over which model you'll use: the tool
  1.5767 +	gives you shared-push, and if you want to do anything else,
  1.5768 +	you'll have to roll your own approach on top (such as applying
  1.5769 +	a patch by hand).</para>
  1.5770 +
  1.5771 +      <para id="x_478">A good distributed revision control tool will
  1.5772 +	support both models.  You and your collaborators can then
  1.5773 +	structure how you work together based on your own needs and
  1.5774 +	preferences, not on what contortions your tools force you
  1.5775 +	into.</para>
  1.5776 +    </sect2>
  1.5777 +    <sect2>
  1.5778 +      <title>Where collaboration meets branch management</title>
  1.5779 +
  1.5780 +      <para id="x_479">Once you and your team set up some shared
  1.5781 +	repositories and start propagating changes back and forth
  1.5782 +	between local and shared repos, you begin to face a related,
  1.5783 +	but slightly different challenge: that of managing the
  1.5784 +	multiple directions in which your team may be moving at once.
  1.5785 +	Even though this subject is intimately related to how your
  1.5786 +	team collaborates, it's dense enough to merit treatment of its
  1.5787 +	own, in <xref linkend="chap:branch"/>.</para>
  1.5788 +    </sect2>
  1.5789 +  </sect1>
  1.5790 +
  1.5791 +  <sect1>
  1.5792 +    <title>The technical side of sharing</title>
  1.5793 +
  1.5794 +    <para id="x_47a">The remainder of this chapter is devoted to the question of
  1.5795 +      sharing changes with your collaborators.</para>
  1.5796 +  </sect1>
  1.5797 +
  1.5798 +  <sect1 id="sec:collab:serve">
  1.5799 +    <title>Informal sharing with <command role="hg-cmd" moreinfo="none">hg
  1.5800 +	serve</command></title>
  1.5801 +
  1.5802 +    <para id="x_47b">Mercurial's <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.5803 +      command is wonderfully suited to small, tight-knit, and
  1.5804 +      fast-paced group environments.  It also provides a great way to
  1.5805 +      get a feel for using Mercurial commands over a network.</para>
  1.5806 +
  1.5807 +    <para id="x_47c">Run <command role="hg-cmd" moreinfo="none">hg serve</command> inside a
  1.5808 +      repository, and in under a second it will bring up a specialised
  1.5809 +      HTTP server; this will accept connections from any client, and
  1.5810 +      serve up data for that repository until you terminate it.
  1.5811 +      Anyone who knows the URL of the server you just started, and can
  1.5812 +      talk to your computer over the network, can then use a web
  1.5813 +      browser or Mercurial to read data from that repository.  A URL
  1.5814 +      for a <command role="hg-cmd" moreinfo="none">hg serve</command> instance running
  1.5815 +      on a laptop is likely to look something like
  1.5816 +      <literal moreinfo="none">http://my-laptop.local:8000/</literal>.</para>
  1.5817 +
  1.5818 +    <para id="x_47d">The <command role="hg-cmd" moreinfo="none">hg serve</command> command is
  1.5819 +      <emphasis>not</emphasis> a general-purpose web server. It can do
  1.5820 +      only two things:</para>
  1.5821 +    <itemizedlist>
  1.5822 +      <listitem><para id="x_47e">Allow people to browse the history of the
  1.5823 +	  repository it's serving, from their normal web
  1.5824 +	  browsers.</para>
  1.5825 +      </listitem>
  1.5826 +      <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people
  1.5827 +	  can <command role="hg-cmd" moreinfo="none">hg clone</command> or <command role="hg-cmd" moreinfo="none">hg pull</command> changes from that
  1.5828 +	  repository.</para>
  1.5829 +      </listitem></itemizedlist>
  1.5830 +    <para id="x_480">In particular, <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.5831 +      won't allow remote users to <emphasis>modify</emphasis> your
  1.5832 +      repository.  It's intended for read-only use.</para>
  1.5833 +
  1.5834 +    <para id="x_481">If you're getting started with Mercurial, there's nothing to
  1.5835 +      prevent you from using <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.5836 +      to serve up a repository on your own computer, then use commands
  1.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
  1.5838 +      server as if the repository was hosted remotely. This can help
  1.5839 +      you to quickly get acquainted with using commands on
  1.5840 +      network-hosted repositories.</para>
  1.5841 +
  1.5842 +    <sect2>
  1.5843 +      <title>A few things to keep in mind</title>
  1.5844 +
  1.5845 +      <para id="x_482">Because it provides unauthenticated read access to all
  1.5846 +	clients, you should only use <command role="hg-cmd" moreinfo="none">hg
  1.5847 +	  serve</command> in an environment where you either don't
  1.5848 +	care, or have complete control over, who can access your
  1.5849 +	network and pull data from your repository.</para>
  1.5850 +
  1.5851 +      <para id="x_483">The <command role="hg-cmd" moreinfo="none">hg serve</command> command
  1.5852 +	knows nothing about any firewall software you might have
  1.5853 +	installed on your system or network.  It cannot detect or
  1.5854 +	control your firewall software.  If other people are unable to
  1.5855 +	talk to a running <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.5856 +	instance, the second thing you should do
  1.5857 +	(<emphasis>after</emphasis> you make sure that they're using
  1.5858 +	the correct URL) is check your firewall configuration.</para>
  1.5859 +
  1.5860 +      <para id="x_484">By default, <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.5861 +	listens for incoming connections on port 8000.  If another
  1.5862 +	process is already listening on the port you want to use, you
  1.5863 +	can specify a different port to listen on using the <option role="hg-opt-serve">-p</option> option.</para>
  1.5864 +
  1.5865 +      <para id="x_485">Normally, when <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.5866 +	starts, it prints no output, which can be a bit unnerving.  If
  1.5867 +	you'd like to confirm that it is indeed running correctly, and
  1.5868 +	find out what URL you should send to your collaborators, start
  1.5869 +	it with the <option role="hg-opt-global">-v</option>
  1.5870 +	option.</para>
  1.5871 +    </sect2>
  1.5872 +  </sect1>
  1.5873 +
  1.5874 +  <sect1 id="sec:collab:ssh">
  1.5875 +    <title>Using the Secure Shell (ssh) protocol</title>
  1.5876 +
  1.5877 +    <para id="x_486">You can pull and push changes securely over a network
  1.5878 +      connection using the Secure Shell (<literal moreinfo="none">ssh</literal>)
  1.5879 +      protocol.  To use this successfully, you may have to do a little
  1.5880 +      bit of configuration on the client or server sides.</para>
  1.5881 +
  1.5882 +    <para id="x_487">If you're not familiar with ssh, it's the name of
  1.5883 +      both a command and a network protocol that let you securely
  1.5884 +      communicate with another computer.  To use it with Mercurial,
  1.5885 +      you'll be setting up one or more user accounts on a server so
  1.5886 +      that remote users can log in and execute commands.</para>
  1.5887 +
  1.5888 +    <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll
  1.5889 +      probably find some of the material that follows to be elementary
  1.5890 +      in nature.)</para>
  1.5891 +
  1.5892 +    <sect2>
  1.5893 +      <title>How to read and write ssh URLs</title>
  1.5894 +
  1.5895 +      <para id="x_489">An ssh URL tends to look like this:</para>
  1.5896 +      <programlisting format="linespecific">ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
  1.5897 +      <orderedlist inheritnum="ignore" continuation="restarts">
  1.5898 +	<listitem><para id="x_48a">The <quote><literal moreinfo="none">ssh://</literal></quote>
  1.5899 +	    part tells Mercurial to use the ssh protocol.</para>
  1.5900 +	</listitem>
  1.5901 +	<listitem><para id="x_48b">The <quote><literal moreinfo="none">bos@</literal></quote>
  1.5902 +	    component indicates what username to log into the server
  1.5903 +	    as.  You can leave this out if the remote username is the
  1.5904 +	    same as your local username.</para>
  1.5905 +	</listitem>
  1.5906 +	<listitem><para id="x_48c">The
  1.5907 +	    <quote><literal moreinfo="none">hg.serpentine.com</literal></quote> gives
  1.5908 +	    the hostname of the server to log into.</para>
  1.5909 +	</listitem>
  1.5910 +	<listitem><para id="x_48d">The <quote>:22</quote> identifies the port
  1.5911 +	    number to connect to the server on.  The default port is
  1.5912 +	    22, so you only need to specify a colon and port number if
  1.5913 +	    you're <emphasis>not</emphasis> using port 22.</para>
  1.5914 +	</listitem>
  1.5915 +	<listitem><para id="x_48e">The remainder of the URL is the local path to
  1.5916 +	    the repository on the server.</para>
  1.5917 +	</listitem></orderedlist>
  1.5918 +
  1.5919 +      <para id="x_48f">There's plenty of scope for confusion with the path
  1.5920 +	component of ssh URLs, as there is no standard way for tools
  1.5921 +	to interpret it.  Some programs behave differently than others
  1.5922 +	when dealing with these paths. This isn't an ideal situation,
  1.5923 +	but it's unlikely to change.  Please read the following
  1.5924 +	paragraphs carefully.</para>
  1.5925 +
  1.5926 +      <para id="x_490">Mercurial treats the path to a repository on the server as
  1.5927 +	relative to the remote user's home directory.  For example, if
  1.5928 +	user <literal moreinfo="none">foo</literal> on the server has a home directory
  1.5929 +	of <filename class="directory" moreinfo="none">/home/foo</filename>, then an
  1.5930 +	ssh URL that contains a path component of <filename class="directory" moreinfo="none">bar</filename> <emphasis>really</emphasis>
  1.5931 +	refers to the directory <filename class="directory" moreinfo="none">/home/foo/bar</filename>.</para>
  1.5932 +
  1.5933 +      <para id="x_491">If you want to specify a path relative to another user's
  1.5934 +	home directory, you can use a path that starts with a tilde
  1.5935 +	character followed by the user's name (let's call them
  1.5936 +	<literal moreinfo="none">otheruser</literal>), like this.</para>
  1.5937 +      <programlisting format="linespecific">ssh://server/~otheruser/hg/repo</programlisting>
  1.5938 +
  1.5939 +      <para id="x_492">And if you really want to specify an
  1.5940 +	<emphasis>absolute</emphasis> path on the server, begin the
  1.5941 +	path component with two slashes, as in this example.</para>
  1.5942 +      <programlisting format="linespecific">ssh://server//absolute/path</programlisting>
  1.5943 +    </sect2>
  1.5944 +
  1.5945 +    <sect2>
  1.5946 +      <title>Finding an ssh client for your system</title>
  1.5947 +
  1.5948 +      <para id="x_493">Almost every Unix-like system comes with OpenSSH
  1.5949 +	preinstalled.  If you're using such a system, run
  1.5950 +	<literal moreinfo="none">which ssh</literal> to find out if the
  1.5951 +	<command moreinfo="none">ssh</command> command is installed (it's usually in
  1.5952 +	<filename class="directory" moreinfo="none">/usr/bin</filename>).  In the
  1.5953 +	unlikely event that it isn't present, take a look at your
  1.5954 +	system documentation to figure out how to install it.</para>
  1.5955 +
  1.5956 +      <para id="x_494">On Windows, the TortoiseHg package is bundled
  1.5957 +	with a version of Simon Tatham's excellent
  1.5958 +	<command moreinfo="none">plink</command> command, and you should not need to
  1.5959 +	do any further configuration.</para>
  1.5960 +    </sect2>
  1.5961 +
  1.5962 +    <sect2>
  1.5963 +      <title>Generating a key pair</title>
  1.5964 +
  1.5965 +      <para id="x_499">To avoid the need to repetitively type a
  1.5966 +	password every time you need to use your ssh client, I
  1.5967 +	recommend generating a key pair.</para>
  1.5968 +
  1.5969 +      <tip>
  1.5970 +	<title>Key pairs are not mandatory</title>
  1.5971 +
  1.5972 +	<para id="x_6a4">Mercurial knows nothing about ssh authentication or key
  1.5973 +	  pairs.  You can, if you like, safely ignore this section and
  1.5974 +	  the one that follows until you grow tired of repeatedly
  1.5975 +	  typing ssh passwords.</para>
  1.5976 +      </tip>
  1.5977 +
  1.5978 +      <itemizedlist>
  1.5979 +	<listitem>
  1.5980 +	  <para id="x_6a5">On a Unix-like system, the
  1.5981 +	    <command moreinfo="none">ssh-keygen</command> command will do the
  1.5982 +	    trick.</para>
  1.5983 +	  <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need
  1.5984 +	    to download a command named <command moreinfo="none">puttygen</command>
  1.5985 +	    from <ulink url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 
  1.5986 +	      PuTTY web site</ulink> to generate a key pair.  See
  1.5987 +	    <ulink url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 
  1.5988 +	      <command moreinfo="none">puttygen</command> documentation</ulink> for
  1.5989 +	    details of how use the command.</para>
  1.5990 +	</listitem>
  1.5991 +      </itemizedlist>
  1.5992 +
  1.5993 +      <para id="x_49a">When you generate a key pair, it's usually
  1.5994 +	<emphasis>highly</emphasis> advisable to protect it with a
  1.5995 +	passphrase.  (The only time that you might not want to do this
  1.5996 +	is when you're using the ssh protocol for automated tasks on a
  1.5997 +	secure network.)</para>
  1.5998 +
  1.5999 +      <para id="x_49b">Simply generating a key pair isn't enough, however.
  1.6000 +	You'll need to add the public key to the set of authorised
  1.6001 +	keys for whatever user you're logging in remotely as.  For
  1.6002 +	servers using OpenSSH (the vast majority), this will mean
  1.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>
  1.6004 +	directory.</para>
  1.6005 +
  1.6006 +      <para id="x_49c">On a Unix-like system, your public key will have a
  1.6007 +	<filename moreinfo="none">.pub</filename> extension.  If you're using
  1.6008 +	<command moreinfo="none">puttygen</command> on Windows, you can save the
  1.6009 +	public key to a file of your choosing, or paste it from the
  1.6010 +	window it's displayed in straight into the <filename role="special" moreinfo="none">authorized_keys</filename> file.</para>
  1.6011 +    </sect2>
  1.6012 +    <sect2>
  1.6013 +      <title>Using an authentication agent</title>
  1.6014 +
  1.6015 +      <para id="x_49d">An authentication agent is a daemon that stores
  1.6016 +	passphrases in memory (so it will forget passphrases if you
  1.6017 +	log out and log back in again). An ssh client will notice if
  1.6018 +	it's running, and query it for a passphrase.  If there's no
  1.6019 +	authentication agent running, or the agent doesn't store the
  1.6020 +	necessary passphrase, you'll have to type your passphrase
  1.6021 +	every time Mercurial tries to communicate with a server on
  1.6022 +	your behalf (e.g. whenever you pull or push changes).</para>
  1.6023 +
  1.6024 +      <para id="x_49e">The downside of storing passphrases in an agent is that
  1.6025 +	it's possible for a well-prepared attacker to recover the
  1.6026 +	plain text of your passphrases, in some cases even if your
  1.6027 +	system has been power-cycled. You should make your own
  1.6028 +	judgment as to whether this is an acceptable risk.  It
  1.6029 +	certainly saves a lot of repeated typing.</para>
  1.6030 +
  1.6031 +      <itemizedlist>
  1.6032 +	<listitem>
  1.6033 +	  <para id="x_49f">On Unix-like systems, the agent is called
  1.6034 +	    <command moreinfo="none">ssh-agent</command>, and it's often run
  1.6035 +	    automatically for you when you log in.  You'll need to use
  1.6036 +	    the <command moreinfo="none">ssh-add</command> command to add passphrases
  1.6037 +	    to the agent's store.</para>
  1.6038 +	</listitem>
  1.6039 +	<listitem>
  1.6040 +	  <para id="x_6a7">On Windows, if you're using TortoiseHg, the
  1.6041 +	    <command moreinfo="none">pageant</command> command acts as the agent.  As
  1.6042 +	    with <command moreinfo="none">puttygen</command>, you'll need to <ulink url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 
  1.6043 +	      <command moreinfo="none">pageant</command></ulink> from the PuTTY web
  1.6044 +	    site and read <ulink url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 
  1.6045 +	      documentation</ulink>.  The <command moreinfo="none">pageant</command>
  1.6046 +	    command adds an icon to your system tray that will let you
  1.6047 +	    manage stored passphrases.</para>
  1.6048 +	</listitem>
  1.6049 +      </itemizedlist>
  1.6050 +    </sect2>
  1.6051 +
  1.6052 +    <sect2>
  1.6053 +      <title>Configuring the server side properly</title>
  1.6054 +
  1.6055 +      <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it,
  1.6056 +	a variety of things can go wrong.  Add Mercurial
  1.6057 +	on top, and there's plenty more scope for head-scratching.
  1.6058 +	Most of these potential problems occur on the server side, not
  1.6059 +	the client side.  The good news is that once you've gotten a
  1.6060 +	configuration working, it will usually continue to work
  1.6061 +	indefinitely.</para>
  1.6062 +
  1.6063 +      <para id="x_4a1">Before you try using Mercurial to talk to an ssh server,
  1.6064 +	it's best to make sure that you can use the normal
  1.6065 +	<command moreinfo="none">ssh</command> or <command moreinfo="none">putty</command> command to
  1.6066 +	talk to the server first.  If you run into problems with using
  1.6067 +	these commands directly, Mercurial surely won't work.  Worse,
  1.6068 +	it will obscure the underlying problem.  Any time you want to
  1.6069 +	debug ssh-related Mercurial problems, you should drop back to
  1.6070 +	making sure that plain ssh client commands work first,
  1.6071 +	<emphasis>before</emphasis> you worry about whether there's a
  1.6072 +	problem with Mercurial.</para>
  1.6073 +
  1.6074 +      <para id="x_4a2">The first thing to be sure of on the server side is that
  1.6075 +	you can actually log in from another machine at all.  If you
  1.6076 +	can't use <command moreinfo="none">ssh</command> or <command moreinfo="none">putty</command>
  1.6077 +	to log in, the error message you get may give you a few hints
  1.6078 +	as to what's wrong.  The most common problems are as
  1.6079 +	follows.</para>
  1.6080 +      <itemizedlist>
  1.6081 +	<listitem><para id="x_4a3">If you get a <quote>connection refused</quote>
  1.6082 +	    error, either there isn't an SSH daemon running on the
  1.6083 +	    server at all, or it's inaccessible due to firewall
  1.6084 +	    configuration.</para>
  1.6085 +	</listitem>
  1.6086 +	<listitem><para id="x_4a4">If you get a <quote>no route to host</quote>
  1.6087 +	    error, you either have an incorrect address for the server
  1.6088 +	    or a seriously locked down firewall that won't admit its
  1.6089 +	    existence at all.</para>
  1.6090 +	</listitem>
  1.6091 +	<listitem><para id="x_4a5">If you get a <quote>permission denied</quote>
  1.6092 +	    error, you may have mistyped the username on the server,
  1.6093 +	    or you could have mistyped your key's passphrase or the
  1.6094 +	    remote user's password.</para>
  1.6095 +	</listitem></itemizedlist>
  1.6096 +      <para id="x_4a6">In summary, if you're having trouble talking to the
  1.6097 +	server's ssh daemon, first make sure that one is running at
  1.6098 +	all.  On many systems it will be installed, but disabled, by
  1.6099 +	default.  Once you're done with this step, you should then
  1.6100 +	check that the server's firewall is configured to allow
  1.6101 +	incoming connections on the port the ssh daemon is listening
  1.6102 +	on (usually 22).  Don't worry about more exotic possibilities
  1.6103 +	for misconfiguration until you've checked these two
  1.6104 +	first.</para>
  1.6105 +
  1.6106 +      <para id="x_4a7">If you're using an authentication agent on the client side
  1.6107 +	to store passphrases for your keys, you ought to be able to
  1.6108 +	log into the server without being prompted for a passphrase or
  1.6109 +	a password.  If you're prompted for a passphrase, there are a
  1.6110 +	few possible culprits.</para>
  1.6111 +      <itemizedlist>
  1.6112 +	<listitem><para id="x_4a8">You might have forgotten to use
  1.6113 +	    <command moreinfo="none">ssh-add</command> or <command moreinfo="none">pageant</command>
  1.6114 +	    to store the passphrase.</para>
  1.6115 +	</listitem>
  1.6116 +	<listitem><para id="x_4a9">You might have stored the passphrase for the
  1.6117 +	    wrong key.</para>
  1.6118 +	</listitem></itemizedlist>
  1.6119 +      <para id="x_4aa">If you're being prompted for the remote user's password,
  1.6120 +	there are another few possible problems to check.</para>
  1.6121 +      <itemizedlist>
  1.6122 +	<listitem><para id="x_4ab">Either the user's home directory or their
  1.6123 +	    <filename role="special" class="directory" moreinfo="none">.ssh</filename>
  1.6124 +	    directory might have excessively liberal permissions.  As
  1.6125 +	    a result, the ssh daemon will not trust or read their
  1.6126 +	    <filename role="special" moreinfo="none">authorized_keys</filename> file.
  1.6127 +	    For example, a group-writable home or <filename role="special" class="directory" moreinfo="none">.ssh</filename>
  1.6128 +	    directory will often cause this symptom.</para>
  1.6129 +	</listitem>
  1.6130 +	<listitem><para id="x_4ac">The user's <filename role="special" moreinfo="none">authorized_keys</filename> file may have
  1.6131 +	    a problem. If anyone other than the user owns or can write
  1.6132 +	    to that file, the ssh daemon will not trust or read
  1.6133 +	    it.</para>
  1.6134 +	</listitem></itemizedlist>
  1.6135 +
  1.6136 +      <para id="x_4ad">In the ideal world, you should be able to run the
  1.6137 +	following command successfully, and it should print exactly
  1.6138 +	one line of output, the current date and time.</para>
  1.6139 +      <programlisting format="linespecific">ssh myserver date</programlisting>
  1.6140 +
  1.6141 +      <para id="x_4ae">If, on your server, you have login scripts that print
  1.6142 +	banners or other junk even when running non-interactive
  1.6143 +	commands like this, you should fix them before you continue,
  1.6144 +	so that they only print output if they're run interactively.
  1.6145 +	Otherwise these banners will at least clutter up Mercurial's
  1.6146 +	output.  Worse, they could potentially cause problems with
  1.6147 +	running Mercurial commands remotely.  Mercurial tries to
  1.6148 +	detect and ignore banners in non-interactive
  1.6149 +	<command moreinfo="none">ssh</command> sessions, but it is not foolproof.  (If
  1.6150 +	you're editing your login scripts on your server, the usual
  1.6151 +	way to see if a login script is running in an interactive
  1.6152 +	shell is to check the return code from the command
  1.6153 +	<literal moreinfo="none">tty -s</literal>.)</para>
  1.6154 +
  1.6155 +      <para id="x_4af">Once you've verified that plain old ssh is working with
  1.6156 +	your server, the next step is to ensure that Mercurial runs on
  1.6157 +	the server.  The following command should run
  1.6158 +	successfully:</para>
  1.6159 +
  1.6160 +      <programlisting format="linespecific">ssh myserver hg version</programlisting>
  1.6161 +
  1.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
  1.6163 +	because you haven't installed Mercurial to <filename class="directory" moreinfo="none">/usr/bin</filename>.  Don't worry if this
  1.6164 +	is the case; you don't need to do that.  But you should check
  1.6165 +	for a few possible problems.</para>
  1.6166 +      <itemizedlist>
  1.6167 +	<listitem><para id="x_4b1">Is Mercurial really installed on the server at
  1.6168 +	    all?  I know this sounds trivial, but it's worth
  1.6169 +	    checking!</para>
  1.6170 +	</listitem>
  1.6171 +	<listitem><para id="x_4b2">Maybe your shell's search path (usually set
  1.6172 +	    via the <envar>PATH</envar> environment variable) is
  1.6173 +	    simply misconfigured.</para>
  1.6174 +	</listitem>
  1.6175 +	<listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment
  1.6176 +	    variable is only being set to point to the location of the
  1.6177 +	    <command moreinfo="none">hg</command> executable if the login session is
  1.6178 +	    interactive.  This can happen if you're setting the path
  1.6179 +	    in the wrong shell login script.  See your shell's
  1.6180 +	    documentation for details.</para>
  1.6181 +	</listitem>
  1.6182 +	<listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> environment
  1.6183 +	    variable may need to contain the path to the Mercurial
  1.6184 +	    Python modules.  It might not be set at all; it could be
  1.6185 +	    incorrect; or it may be set only if the login is
  1.6186 +	    interactive.</para>
  1.6187 +	</listitem></itemizedlist>
  1.6188 +
  1.6189 +      <para id="x_4b5">If you can run <command role="hg-cmd" moreinfo="none">hg version</command>
  1.6190 +	over an ssh connection, well done! You've got the server and
  1.6191 +	client sorted out.  You should now be able to use Mercurial to
  1.6192 +	access repositories hosted by that username on that server.
  1.6193 +	If you run into problems with Mercurial and ssh at this point,
  1.6194 +	try using the <option role="hg-opt-global">--debug</option>
  1.6195 +	option to get a clearer picture of what's going on.</para>
  1.6196 +    </sect2>
  1.6197 +    <sect2>
  1.6198 +      <title>Using compression with ssh</title>
  1.6199 +
  1.6200 +      <para id="x_4b6">Mercurial does not compress data when it uses the ssh
  1.6201 +	protocol, because the ssh protocol can transparently compress
  1.6202 +	data.  However, the default behavior of ssh clients is
  1.6203 +	<emphasis>not</emphasis> to request compression.</para>
  1.6204 +
  1.6205 +      <para id="x_4b7">Over any network other than a fast LAN (even a wireless
  1.6206 +	network), using compression is likely to significantly speed
  1.6207 +	up Mercurial's network operations.  For example, over a WAN,
  1.6208 +	someone measured compression as reducing the amount of time
  1.6209 +	required to clone a particularly large repository from 51
  1.6210 +	minutes to 17 minutes.</para>
  1.6211 +
  1.6212 +      <para id="x_4b8">Both <command moreinfo="none">ssh</command> and <command moreinfo="none">plink</command>
  1.6213 +	accept a <option role="cmd-opt-ssh">-C</option> option which
  1.6214 +	turns on compression.  You can easily edit your <filename role="special" moreinfo="none">~/.hgrc</filename> to enable compression for
  1.6215 +	all of Mercurial's uses of the ssh protocol.  Here is how to
  1.6216 +	do so for regular <command moreinfo="none">ssh</command> on Unix-like systems,
  1.6217 +	for example.</para>
  1.6218 +      <programlisting format="linespecific">[ui]
  1.6219 +ssh = ssh -C</programlisting>
  1.6220 +
  1.6221 +      <para id="x_4b9">If you use <command moreinfo="none">ssh</command> on a
  1.6222 +	Unix-like system, you can configure it to always use
  1.6223 +	compression when talking to your server.  To do this, edit
  1.6224 +	your <filename role="special" moreinfo="none">.ssh/config</filename> file
  1.6225 +	(which may not yet exist), as follows.</para>
  1.6226 +
  1.6227 +      <programlisting format="linespecific">Host hg
  1.6228 +  Compression yes
  1.6229 +  HostName hg.example.com</programlisting>
  1.6230 +
  1.6231 +      <para id="x_4ba">This defines a hostname alias,
  1.6232 +	<literal moreinfo="none">hg</literal>.  When you use that hostname on the
  1.6233 +	<command moreinfo="none">ssh</command> command line or in a Mercurial
  1.6234 +	<literal moreinfo="none">ssh</literal>-protocol URL, it will cause
  1.6235 +	<command moreinfo="none">ssh</command> to connect to
  1.6236 +	<literal moreinfo="none">hg.example.com</literal> and use compression.  This
  1.6237 +	gives you both a shorter name to type and compression, each of
  1.6238 +	which is a good thing in its own right.</para>
  1.6239 +    </sect2>
  1.6240 +  </sect1>
  1.6241 +
  1.6242 +  <sect1 id="sec:collab:cgi">
  1.6243 +    <title>Serving over HTTP using CGI</title>
  1.6244 +
  1.6245 +    <para id="x_6a8">The simplest way to host one or more repositories in a
  1.6246 +      permanent way is to use a web server and Mercurial's CGI
  1.6247 +      support.</para>
  1.6248 +
  1.6249 +    <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's
  1.6250 +      CGI interface can take anything from a few moments to several
  1.6251 +      hours.</para>
  1.6252 +
  1.6253 +    <para id="x_4bc">We'll begin with the simplest of examples, and work our way
  1.6254 +      towards a more complex configuration.  Even for the most basic
  1.6255 +      case, you're almost certainly going to need to read and modify
  1.6256 +      your web server's configuration.</para>
  1.6257 +
  1.6258 +    <note>
  1.6259 +      <title>High pain tolerance required</title>
  1.6260 +
  1.6261 +      <para id="x_4bd">Configuring a web server is a complex, fiddly,
  1.6262 +	and highly system-dependent activity.  I can't possibly give
  1.6263 +	you instructions that will cover anything like all of the
  1.6264 +	cases you will encounter. Please use your discretion and
  1.6265 +	judgment in following the sections below.  Be prepared to make
  1.6266 +	plenty of mistakes, and to spend a lot of time reading your
  1.6267 +	server's error logs.</para>
  1.6268 +
  1.6269 +      <para id="x_6a9">If you don't have a strong stomach for tweaking
  1.6270 +	configurations over and over, or a compelling need to host
  1.6271 +	your own services, you might want to try one of the public
  1.6272 +	hosting services that I mentioned earlier.</para>
  1.6273 +    </note>
  1.6274 +
  1.6275 +    <sect2>
  1.6276 +      <title>Web server configuration checklist</title>
  1.6277 +
  1.6278 +      <para id="x_4be">Before you continue, do take a few moments to check a few
  1.6279 +	aspects of your system's setup.</para>
  1.6280 +
  1.6281 +      <orderedlist inheritnum="ignore" continuation="restarts">
  1.6282 +	<listitem><para id="x_4bf">Do you have a web server installed
  1.6283 +	    at all? Mac OS X and some Linux distributions ship with
  1.6284 +	    Apache, but many other systems may not have a web server
  1.6285 +	    installed.</para>
  1.6286 +	</listitem>
  1.6287 +	<listitem><para id="x_4c0">If you have a web server installed, is it
  1.6288 +	    actually running?  On most systems, even if one is
  1.6289 +	    present, it will be disabled by default.</para>
  1.6290 +	</listitem>
  1.6291 +	<listitem><para id="x_4c1">Is your server configured to allow you to run
  1.6292 +	    CGI programs in the directory where you plan to do so?
  1.6293 +	    Most servers default to explicitly disabling the ability
  1.6294 +	    to run CGI programs.</para>
  1.6295 +	</listitem></orderedlist>
  1.6296 +
  1.6297 +      <para id="x_4c2">If you don't have a web server installed, and don't have
  1.6298 +	substantial experience configuring Apache, you should consider
  1.6299 +	using the <literal moreinfo="none">lighttpd</literal> web server instead of
  1.6300 +	Apache.  Apache has a well-deserved reputation for baroque and
  1.6301 +	confusing configuration. While <literal moreinfo="none">lighttpd</literal> is
  1.6302 +	less capable in some ways than Apache, most of these
  1.6303 +	capabilities are not relevant to serving Mercurial
  1.6304 +	repositories.  And <literal moreinfo="none">lighttpd</literal> is undeniably
  1.6305 +	<emphasis>much</emphasis> easier to get started with than
  1.6306 +	Apache.</para>
  1.6307 +    </sect2>
  1.6308 +
  1.6309 +    <sect2>
  1.6310 +      <title>Basic CGI configuration</title>
  1.6311 +
  1.6312 +      <para id="x_4c3">On Unix-like systems, it's common for users to have a
  1.6313 +	subdirectory named something like <filename class="directory" moreinfo="none">public_html</filename> in their home
  1.6314 +	directory, from which they can serve up web pages.  A file
  1.6315 +	named <filename moreinfo="none">foo</filename> in this directory will be
  1.6316 +	accessible at a URL of the form
  1.6317 +	<literal moreinfo="none">http://www.example.com/username/foo</literal>.</para>
  1.6318 +
  1.6319 +      <para id="x_4c4">To get started, find the <filename role="special" moreinfo="none">hgweb.cgi</filename> script that should be
  1.6320 +	present in your Mercurial installation.  If you can't quickly
  1.6321 +	find a local copy on your system, simply download one from the
  1.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>
  1.6323 +
  1.6324 +      <para id="x_4c5">You'll need to copy this script into your <filename class="directory" moreinfo="none">public_html</filename> directory, and
  1.6325 +	ensure that it's executable.</para>
  1.6326 +      <programlisting format="linespecific">cp .../hgweb.cgi ~/public_html
  1.6327 +chmod 755 ~/public_html/hgweb.cgi</programlisting>
  1.6328 +      <para id="x_4c6">The <literal moreinfo="none">755</literal> argument to
  1.6329 +	<command moreinfo="none">chmod</command> is a little more general than just
  1.6330 +	making the script executable: it ensures that the script is
  1.6331 +	executable by anyone, and that <quote>group</quote> and
  1.6332 +	<quote>other</quote> write permissions are
  1.6333 +	<emphasis>not</emphasis> set.  If you were to leave those
  1.6334 +	write permissions enabled, Apache's <literal moreinfo="none">suexec</literal>
  1.6335 +	subsystem would likely refuse to execute the script.  In fact,
  1.6336 +	<literal moreinfo="none">suexec</literal> also insists that the
  1.6337 +	<emphasis>directory</emphasis> in which the script resides
  1.6338 +	must not be writable by others.</para>
  1.6339 +      <programlisting format="linespecific">chmod 755 ~/public_html</programlisting>
  1.6340 +
  1.6341 +      <sect3 id="sec:collab:wtf">
  1.6342 +	<title>What could <emphasis>possibly</emphasis> go
  1.6343 +	  wrong?</title>
  1.6344 +
  1.6345 +	<para id="x_4c7">Once you've copied the CGI script into place,
  1.6346 +	  go into a web browser, and try to open the URL
  1.6347 +	  <literal moreinfo="none">http://myhostname/~myuser/hgweb.cgi</literal>,
  1.6348 +	  <emphasis>but</emphasis> brace yourself for instant failure.
  1.6349 +	  There's a high probability that trying to visit this URL
  1.6350 +	  will fail, and there are many possible reasons for this.  In
  1.6351 +	  fact, you're likely to stumble over almost every one of the
  1.6352 +	  possible errors below, so please read carefully.  The
  1.6353 +	  following are all of the problems I ran into on a system
  1.6354 +	  running Fedora 7, with a fresh installation of Apache, and a
  1.6355 +	  user account that I created specially to perform this
  1.6356 +	  exercise.</para>
  1.6357 +
  1.6358 +	<para id="x_4c8">Your web server may have per-user directories disabled.
  1.6359 +	  If you're using Apache, search your config file for a
  1.6360 +	  <literal moreinfo="none">UserDir</literal> directive.  If there's none
  1.6361 +	  present, per-user directories will be disabled.  If one
  1.6362 +	  exists, but its value is <literal moreinfo="none">disabled</literal>, then
  1.6363 +	  per-user directories will be disabled.  Otherwise, the
  1.6364 +	  string after <literal moreinfo="none">UserDir</literal> gives the name of
  1.6365 +	  the subdirectory that Apache will look in under your home
  1.6366 +	  directory, for example <filename class="directory" moreinfo="none">public_html</filename>.</para>
  1.6367 +
  1.6368 +	<para id="x_4c9">Your file access permissions may be too restrictive.
  1.6369 +	  The web server must be able to traverse your home directory
  1.6370 +	  and directories under your <filename class="directory" moreinfo="none">public_html</filename> directory, and
  1.6371 +	  read files under the latter too.  Here's a quick recipe to
  1.6372 +	  help you to make your permissions more appropriate.</para>
  1.6373 +	<programlisting format="linespecific">chmod 755 ~
  1.6374 +find ~/public_html -type d -print0 | xargs -0r chmod 755
  1.6375 +find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
  1.6376 +
  1.6377 +	<para id="x_4ca">The other possibility with permissions is that you might
  1.6378 +	  get a completely empty window when you try to load the
  1.6379 +	  script.  In this case, it's likely that your access
  1.6380 +	  permissions are <emphasis>too permissive</emphasis>.  Apache's
  1.6381 +	  <literal moreinfo="none">suexec</literal> subsystem won't execute a script
  1.6382 +	  that's group- or world-writable, for example.</para>
  1.6383 +
  1.6384 +	<para id="x_4cb">Your web server may be configured to disallow execution
  1.6385 +	  of CGI programs in your per-user web directory.  Here's
  1.6386 +	  Apache's default per-user configuration from my Fedora
  1.6387 +	  system.</para>
  1.6388 +
  1.6389 +	<!-- BEGIN ch06/apache-config.lst -->
  1.6390 +<programlisting format="linespecific">&lt;Directory /home/*/public_html&gt;
  1.6391 +  AllowOverride FileInfo AuthConfig Limit
  1.6392 +  Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  1.6393 +  &lt;Limit GET POST OPTIONS&gt;
  1.6394 +    Order allow,deny
  1.6395 +    Allow from all
  1.6396 +  &lt;/Limit&gt;
  1.6397 +  &lt;LimitExcept GET POST OPTIONS&gt;
  1.6398 +    Order deny,allow Deny from all
  1.6399 +  &lt;/LimitExcept&gt;
  1.6400 +&lt;/Directory&gt;</programlisting>
  1.6401 +<!-- END ch06/apache-config.lst -->
  1.6402 +
  1.6403 +
  1.6404 +	<para id="x_4cc">If you find a similar-looking
  1.6405 +	  <literal moreinfo="none">Directory</literal> group in your Apache
  1.6406 +	  configuration, the directive to look at inside it is
  1.6407 +	  <literal moreinfo="none">Options</literal>. Add <literal moreinfo="none">ExecCGI</literal>
  1.6408 +	  to the end of this list if it's missing, and restart the web
  1.6409 +	  server.</para>
  1.6410 +
  1.6411 +	<para id="x_4cd">If you find that Apache serves you the text of the CGI
  1.6412 +	  script instead of executing it, you may need to either
  1.6413 +	  uncomment (if already present) or add a directive like
  1.6414 +	  this.</para>
  1.6415 +	<programlisting format="linespecific">AddHandler cgi-script .cgi</programlisting>
  1.6416 +
  1.6417 +	<para id="x_4ce">The next possibility is that you might be served with a
  1.6418 +	  colourful Python backtrace claiming that it can't import a
  1.6419 +	  <literal moreinfo="none">mercurial</literal>-related module.  This is
  1.6420 +	  actually progress!  The server is now capable of executing
  1.6421 +	  your CGI script.  This error is only likely to occur if
  1.6422 +	  you're running a private installation of Mercurial, instead
  1.6423 +	  of a system-wide version.  Remember that the web server runs
  1.6424 +	  the CGI program without any of the environment variables
  1.6425 +	  that you take for granted in an interactive session.  If
  1.6426 +	  this error happens to you, edit your copy of <filename role="special" moreinfo="none">hgweb.cgi</filename> and follow the
  1.6427 +	  directions inside it to correctly set your
  1.6428 +	  <envar>PYTHONPATH</envar> environment variable.</para>
  1.6429 +
  1.6430 +	<para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to be
  1.6431 +	  served with another colourful Python backtrace: this one
  1.6432 +	  will complain that it can't find <filename class="directory" moreinfo="none">/path/to/repository</filename>.  Edit
  1.6433 +	  your <filename role="special" moreinfo="none">hgweb.cgi</filename> script
  1.6434 +	  and replace the <filename class="directory" moreinfo="none">/path/to/repository</filename> string
  1.6435 +	  with the complete path to the repository you want to serve
  1.6436 +	  up.</para>
  1.6437 +
  1.6438 +	<para id="x_4d0">At this point, when you try to reload the page, you
  1.6439 +	  should be presented with a nice HTML view of your
  1.6440 +	  repository's history.  Whew!</para>
  1.6441 +      </sect3>
  1.6442 +
  1.6443 +      <sect3>
  1.6444 +	<title>Configuring lighttpd</title>
  1.6445 +
  1.6446 +	<para id="x_4d1">To be exhaustive in my experiments, I tried configuring
  1.6447 +	  the increasingly popular <literal moreinfo="none">lighttpd</literal> web
  1.6448 +	  server to serve the same repository as I described with
  1.6449 +	  Apache above.  I had already overcome all of the problems I
  1.6450 +	  outlined with Apache, many of which are not server-specific.
  1.6451 +	  As a result, I was fairly sure that my file and directory
  1.6452 +	  permissions were good, and that my <filename role="special" moreinfo="none">hgweb.cgi</filename> script was properly
  1.6453 +	  edited.</para>
  1.6454 +
  1.6455 +	<para id="x_4d2">Once I had Apache running, getting
  1.6456 +	  <literal moreinfo="none">lighttpd</literal> to serve the repository was a
  1.6457 +	  snap (in other words, even if you're trying to use
  1.6458 +	  <literal moreinfo="none">lighttpd</literal>, you should read the Apache
  1.6459 +	  section).  I first had to edit the
  1.6460 +	  <literal moreinfo="none">mod_access</literal> section of its config file to
  1.6461 +	  enable <literal moreinfo="none">mod_cgi</literal> and
  1.6462 +	  <literal moreinfo="none">mod_userdir</literal>, both of which were disabled
  1.6463 +	  by default on my system.  I then added a few lines to the
  1.6464 +	  end of the config file, to configure these modules.</para>
  1.6465 +	<programlisting format="linespecific">userdir.path = "public_html"
  1.6466 +cgi.assign = (".cgi" =&gt; "" )</programlisting>
  1.6467 +	<para id="x_4d3">With this done, <literal moreinfo="none">lighttpd</literal> ran
  1.6468 +	  immediately for me.  If I had configured
  1.6469 +	  <literal moreinfo="none">lighttpd</literal> before Apache, I'd almost
  1.6470 +	  certainly have run into many of the same system-level
  1.6471 +	  configuration problems as I did with Apache.  However, I
  1.6472 +	  found <literal moreinfo="none">lighttpd</literal> to be noticeably easier to
  1.6473 +	  configure than Apache, even though I've used Apache for over
  1.6474 +	  a decade, and this was my first exposure to
  1.6475 +	  <literal moreinfo="none">lighttpd</literal>.</para>
  1.6476 +      </sect3>
  1.6477 +    </sect2>
  1.6478 +
  1.6479 +    <sect2>
  1.6480 +      <title>Sharing multiple repositories with one CGI script</title>
  1.6481 +
  1.6482 +      <para id="x_4d4">The <filename role="special" moreinfo="none">hgweb.cgi</filename> script
  1.6483 +	only lets you publish a single repository, which is an
  1.6484 +	annoying restriction.  If you want to publish more than one
  1.6485 +	without wracking yourself with multiple copies of the same
  1.6486 +	script, each with different names, a better choice is to use
  1.6487 +	the <filename role="special" moreinfo="none">hgwebdir.cgi</filename>
  1.6488 +	script.</para>
  1.6489 +
  1.6490 +      <para id="x_4d5">The procedure to configure <filename role="special" moreinfo="none">hgwebdir.cgi</filename> is only a little more
  1.6491 +	involved than for <filename role="special" moreinfo="none">hgweb.cgi</filename>.  First, you must obtain
  1.6492 +	a copy of the script.  If you don't have one handy, you can
  1.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>
  1.6494 +
  1.6495 +      <para id="x_4d6">You'll need to copy this script into your <filename class="directory" moreinfo="none">public_html</filename> directory, and
  1.6496 +	ensure that it's executable.</para>
  1.6497 +
  1.6498 +      <programlisting format="linespecific">cp .../hgwebdir.cgi ~/public_html
  1.6499 +chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
  1.6500 +
  1.6501 +      <para id="x_4d7">With basic configuration out of the way, try to
  1.6502 +	visit <literal moreinfo="none">http://myhostname/~myuser/hgwebdir.cgi</literal>
  1.6503 +	in your	browser.  It should
  1.6504 +	display an empty list of repositories.  If you get a blank
  1.6505 +	window or error message, try walking through the list of
  1.6506 +	potential problems in <xref linkend="sec:collab:wtf"/>.</para>
  1.6507 +
  1.6508 +      <para id="x_4d8">The <filename role="special" moreinfo="none">hgwebdir.cgi</filename>
  1.6509 +	script relies on an external configuration file.  By default,
  1.6510 +	it searches for a file named <filename role="special" moreinfo="none">hgweb.config</filename> in the same directory
  1.6511 +	as itself.  You'll need to create this file, and make it
  1.6512 +	world-readable.  The format of the file is similar to a
  1.6513 +	Windows <quote>ini</quote> file, as understood by Python's
  1.6514 +	<literal moreinfo="none">ConfigParser</literal>
  1.6515 +	<citation>web:configparser</citation> module.</para>
  1.6516 +
  1.6517 +      <para id="x_4d9">The easiest way to configure <filename role="special" moreinfo="none">hgwebdir.cgi</filename> is with a section
  1.6518 +	named <literal moreinfo="none">collections</literal>.  This will automatically
  1.6519 +	publish <emphasis>every</emphasis> repository under the
  1.6520 +	directories you name.  The section should look like
  1.6521 +	this:</para>
  1.6522 +      <programlisting format="linespecific">[collections]
  1.6523 +/my/root = /my/root</programlisting>
  1.6524 +      <para id="x_4da">Mercurial interprets this by looking at the directory name
  1.6525 +	on the <emphasis>right</emphasis> hand side of the
  1.6526 +	<quote><literal moreinfo="none">=</literal></quote> sign; finding repositories
  1.6527 +	in that directory hierarchy; and using the text on the
  1.6528 +	<emphasis>left</emphasis> to strip off matching text from the
  1.6529 +	names it will actually list in the web interface.  The
  1.6530 +	remaining component of a path after this stripping has
  1.6531 +	occurred is called a <quote>virtual path</quote>.</para>
  1.6532 +
  1.6533 +      <para id="x_4db">Given the example above, if we have a
  1.6534 +	repository whose local path is <filename class="directory" moreinfo="none">/my/root/this/repo</filename>, the CGI
  1.6535 +	script will strip the leading <filename class="directory" moreinfo="none">/my/root</filename> from the name, and
  1.6536 +	publish the repository with a virtual path of <filename class="directory" moreinfo="none">this/repo</filename>.  If the base URL for
  1.6537 +	our CGI script is
  1.6538 +	<literal moreinfo="none">http://myhostname/~myuser/hgwebdir.cgi</literal>, the
  1.6539 +	complete URL for that repository will be
  1.6540 +	<literal moreinfo="none">http://myhostname/~myuser/hgwebdir.cgi/this/repo</literal>.</para>
  1.6541 +
  1.6542 +      <para id="x_4dc">If we replace <filename class="directory" moreinfo="none">/my/root</filename> on the left hand side
  1.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
  1.6544 +	<filename class="directory" moreinfo="none">/my</filename> from the repository
  1.6545 +	name, and will give us a virtual path of <filename class="directory" moreinfo="none">root/this/repo</filename> instead of
  1.6546 +	<filename class="directory" moreinfo="none">this/repo</filename>.</para>
  1.6547 +
  1.6548 +      <para id="x_4dd">The <filename role="special" moreinfo="none">hgwebdir.cgi</filename>
  1.6549 +	script will recursively search each directory listed in the
  1.6550 +	<literal moreinfo="none">collections</literal> section of its configuration
  1.6551 +	file, but it will <literal moreinfo="none">not</literal> recurse into the
  1.6552 +	repositories it finds.</para>
  1.6553 +
  1.6554 +      <para id="x_4de">The <literal moreinfo="none">collections</literal> mechanism makes it easy
  1.6555 +	to publish many repositories in a <quote>fire and
  1.6556 +	  forget</quote> manner.  You only need to set up the CGI
  1.6557 +	script and configuration file one time.  Afterwards, you can
  1.6558 +	publish or unpublish a repository at any time by simply moving
  1.6559 +	it into, or out of, the directory hierarchy in which you've
  1.6560 +	configured <filename role="special" moreinfo="none">hgwebdir.cgi</filename> to
  1.6561 +	look.</para>
  1.6562 +
  1.6563 +      <sect3>
  1.6564 +	<title>Explicitly specifying which repositories to
  1.6565 +	  publish</title>
  1.6566 +
  1.6567 +	<para id="x_4df">In addition to the <literal moreinfo="none">collections</literal>
  1.6568 +	  mechanism, the <filename role="special" moreinfo="none">hgwebdir.cgi</filename> script allows you
  1.6569 +	  to publish a specific list of repositories.  To do so,
  1.6570 +	  create a <literal moreinfo="none">paths</literal> section, with contents of
  1.6571 +	  the following form.</para>
  1.6572 +	<programlisting format="linespecific">[paths]
  1.6573 +repo1 = /my/path/to/some/repo
  1.6574 +repo2 = /some/path/to/another</programlisting>
  1.6575 +	<para id="x_4e0">In this case, the virtual path (the component that will
  1.6576 +	  appear in a URL) is on the left hand side of each
  1.6577 +	  definition, while the path to the repository is on the
  1.6578 +	  right.  Notice that there does not need to be any
  1.6579 +	  relationship between the virtual path you choose and the
  1.6580 +	  location of a repository in your filesystem.</para>
  1.6581 +
  1.6582 +	<para id="x_4e1">If you wish, you can use both the
  1.6583 +	  <literal moreinfo="none">collections</literal> and <literal moreinfo="none">paths</literal>
  1.6584 +	  mechanisms simultaneously in a single configuration
  1.6585 +	  file.</para>
  1.6586 +
  1.6587 +	<note>
  1.6588 +	  <title>Beware duplicate virtual paths</title>
  1.6589 +
  1.6590 +	  <para id="x_4e2">  If several repositories have the same
  1.6591 +	    virtual path, <filename role="special" moreinfo="none">hgwebdir.cgi</filename> will not report
  1.6592 +	    an error.  Instead, it will behave unpredictably.</para>
  1.6593 +	</note>
  1.6594 +      </sect3>
  1.6595 +    </sect2>
  1.6596 +
  1.6597 +    <sect2>
  1.6598 +      <title>Downloading source archives</title>
  1.6599 +
  1.6600 +      <para id="x_4e3">Mercurial's web interface lets users download an archive
  1.6601 +	of any revision.  This archive will contain a snapshot of the
  1.6602 +	working directory as of that revision, but it will not contain
  1.6603 +	a copy of the repository data.</para>
  1.6604 +
  1.6605 +      <para id="x_4e4">By default, this feature is not enabled.  To enable it,
  1.6606 +	you'll need to add an <envar role="rc-item-web">allow_archive</envar> item to the
  1.6607 +	<literal role="rc-web" moreinfo="none">web</literal> section of your <filename role="special" moreinfo="none">~/.hgrc</filename>; see below for details.</para>
  1.6608 +    </sect2>
  1.6609 +    <sect2>
  1.6610 +      <title>Web configuration options</title>
  1.6611 +
  1.6612 +      <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd" moreinfo="none">hg
  1.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
  1.6614 +	number of configuration options that you can set.  These
  1.6615 +	belong in a section named <literal role="rc-web" moreinfo="none">web</literal>.</para>
  1.6616 +      <itemizedlist>
  1.6617 +	<listitem><para id="x_4e6"><envar role="rc-item-web">allow_archive</envar>: Determines
  1.6618 +	    which (if any) archive download mechanisms Mercurial
  1.6619 +	    supports.  If you enable this feature, users of the web
  1.6620 +	    interface will be able to download an archive of whatever
  1.6621 +	    revision of a repository they are viewing. To enable the
  1.6622 +	    archive feature, this item must take the form of a
  1.6623 +	    sequence of words drawn from the list below.</para>
  1.6624 +	  <itemizedlist>
  1.6625 +	    <listitem><para id="x_4e7"><literal moreinfo="none">bz2</literal>: A
  1.6626 +		<command moreinfo="none">tar</command> archive, compressed using
  1.6627 +		<literal moreinfo="none">bzip2</literal> compression.  This has the
  1.6628 +		best compression ratio, but uses the most CPU time on
  1.6629 +		the server.</para>
  1.6630 +	    </listitem>
  1.6631 +	    <listitem><para id="x_4e8"><literal moreinfo="none">gz</literal>: A
  1.6632 +		<command moreinfo="none">tar</command> archive, compressed using
  1.6633 +		<literal moreinfo="none">gzip</literal> compression.</para>
  1.6634 +	    </listitem>
  1.6635 +	    <listitem><para id="x_4e9"><literal moreinfo="none">zip</literal>: A
  1.6636 +		<command moreinfo="none">zip</command> archive, compressed using LZW
  1.6637 +		compression.  This format has the worst compression
  1.6638 +		ratio, but is widely used in the Windows world.</para>
  1.6639 +	    </listitem>
  1.6640 +	  </itemizedlist>
  1.6641 +	  <para id="x_4ea">  If you provide an empty list, or don't have an
  1.6642 +	    <envar role="rc-item-web">allow_archive</envar> entry at
  1.6643 +	    all, this feature will be disabled.  Here is an example of
  1.6644 +	    how to enable all three supported formats.</para>
  1.6645 +	  <programlisting format="linespecific">[web]
  1.6646 +allow_archive = bz2 gz zip</programlisting>
  1.6647 +	</listitem>
  1.6648 +	<listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>:
  1.6649 +	    Boolean.  Determines whether the web interface allows
  1.6650 +	    remote users to <command role="hg-cmd" moreinfo="none">hg pull</command>
  1.6651 +	    and <command role="hg-cmd" moreinfo="none">hg clone</command> this
  1.6652 +	    repository over HTTP.  If set to <literal moreinfo="none">no</literal> or
  1.6653 +	    <literal moreinfo="none">false</literal>, only the
  1.6654 +	    <quote>human-oriented</quote> portion of the web interface
  1.6655 +	    is available.</para>
  1.6656 +	</listitem>
  1.6657 +	<listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>:
  1.6658 +	    String.  A free-form (but preferably brief) string
  1.6659 +	    identifying the person or group in charge of the
  1.6660 +	    repository.  This often contains the name and email
  1.6661 +	    address of a person or mailing list.  It often makes sense
  1.6662 +	    to place this entry in a repository's own <filename role="special" moreinfo="none">.hg/hgrc</filename> file, but it can make
  1.6663 +	    sense to use in a global <filename role="special" moreinfo="none">~/.hgrc</filename> if every repository
  1.6664 +	    has a single maintainer.</para>
  1.6665 +	</listitem>
  1.6666 +	<listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>:
  1.6667 +	    Integer.  The default maximum number of changesets to
  1.6668 +	    display in a single page of output.</para>
  1.6669 +	</listitem>
  1.6670 +	<listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>:
  1.6671 +	    Integer.  The default maximum number of modified files to
  1.6672 +	    display in a single page of output.</para>
  1.6673 +	</listitem>
  1.6674 +	<listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>:
  1.6675 +	    Integer.  If the web interface displays alternating
  1.6676 +	    <quote>stripes</quote> to make it easier to visually align
  1.6677 +	    rows when you are looking at a table, this number controls
  1.6678 +	    the number of rows in each stripe.</para>
  1.6679 +	</listitem>
  1.6680 +	<listitem><para id="x_4f0"><envar role="rc-item-web">style</envar>: Controls the template
  1.6681 +	    Mercurial uses to display the web interface.  Mercurial
  1.6682 +	    ships with several web templates.</para>
  1.6683 +	  <itemizedlist>
  1.6684 +	    <listitem>
  1.6685 +	      <para id="x_6aa"><literal moreinfo="none">coal</literal> is monochromatic.</para>
  1.6686 +	    </listitem>
  1.6687 +	    <listitem>
  1.6688 +	      <para id="x_6ab"><literal moreinfo="none">gitweb</literal> emulates the visual
  1.6689 +		style of git's web interface.</para>
  1.6690 +	    </listitem>
  1.6691 +	    <listitem>
  1.6692 +	      <para id="x_6ac"><literal moreinfo="none">monoblue</literal> uses solid blues and
  1.6693 +		greys.</para>
  1.6694 +	    </listitem>
  1.6695 +	    <listitem>
  1.6696 +	      <para id="x_6ad"><literal moreinfo="none">paper</literal> is the default.</para>
  1.6697 +	    </listitem>
  1.6698 +	    <listitem>
  1.6699 +	      <para id="x_6ae"><literal moreinfo="none">spartan</literal> was the default for a
  1.6700 +		long time.</para>
  1.6701 +	    </listitem>
  1.6702 +	  </itemizedlist>
  1.6703 +	  <para id="x_6af">You can
  1.6704 +	    also specify a custom template of your own; see 
  1.6705 +	    <xref linkend="chap:template"/> for details. Here, you can
  1.6706 +	    see how to enable the <literal moreinfo="none">gitweb</literal>
  1.6707 +	    style.</para>
  1.6708 +	  <programlisting format="linespecific">[web]
  1.6709 +style = gitweb</programlisting>
  1.6710 +	</listitem>
  1.6711 +	<listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>:
  1.6712 +	    Path.  The directory in which to search for template
  1.6713 +	    files.  By default, Mercurial searches in the directory in
  1.6714 +	    which it was installed.</para>
  1.6715 +	</listitem></itemizedlist>
  1.6716 +      <para id="x_4f2">If you are using <filename role="special" moreinfo="none">hgwebdir.cgi</filename>, you can place a few
  1.6717 +	configuration items in a <literal role="rc-web" moreinfo="none">web</literal>
  1.6718 +	section of the <filename role="special" moreinfo="none">hgweb.config</filename> file instead of a
  1.6719 +	<filename role="special" moreinfo="none">~/.hgrc</filename> file, for
  1.6720 +	convenience.  These items are <envar role="rc-item-web">motd</envar> and <envar role="rc-item-web">style</envar>.</para>
  1.6721 +
  1.6722 +      <sect3>
  1.6723 +	<title>Options specific to an individual repository</title>
  1.6724 +
  1.6725 +	<para id="x_4f3">A few <literal role="rc-web" moreinfo="none">web</literal> configuration
  1.6726 +	  items ought to be placed in a repository's local <filename role="special" moreinfo="none">.hg/hgrc</filename>, rather than a user's
  1.6727 +	  or global <filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
  1.6728 +	<itemizedlist>
  1.6729 +	  <listitem><para id="x_4f4"><envar role="rc-item-web">description</envar>: String.  A
  1.6730 +	      free-form (but preferably brief) string that describes
  1.6731 +	      the contents or purpose of the repository.</para>
  1.6732 +	  </listitem>
  1.6733 +	  <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>:
  1.6734 +	      String.  The name to use for the repository in the web
  1.6735 +	      interface.  This overrides the default name, which is
  1.6736 +	      the last component of the repository's path.</para>
  1.6737 +	  </listitem></itemizedlist>
  1.6738 +      </sect3>
  1.6739 +
  1.6740 +      <sect3>
  1.6741 +	<title>Options specific to the <command role="hg-cmd" moreinfo="none">hg
  1.6742 +	    serve</command> command</title>
  1.6743 +
  1.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
  1.6745 +	  with the <command role="hg-cmd" moreinfo="none">hg serve</command>
  1.6746 +	  command.</para>
  1.6747 +	<itemizedlist>
  1.6748 +	  <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>:
  1.6749 +	      Path.  The name of a file into which to write an access
  1.6750 +	      log.  By default, the <command role="hg-cmd" moreinfo="none">hg
  1.6751 +		serve</command> command writes this information to
  1.6752 +	      standard output, not to a file.  Log entries are written
  1.6753 +	      in the standard <quote>combined</quote> file format used
  1.6754 +	      by almost all web servers.</para>
  1.6755 +	  </listitem>
  1.6756 +	  <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>:
  1.6757 +	      String.  The local address on which the server should
  1.6758 +	      listen for incoming connections.  By default, the server
  1.6759 +	      listens on all addresses.</para>
  1.6760 +	  </listitem>
  1.6761 +	  <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>:
  1.6762 +	      Path.  The name of a file into which to write an error
  1.6763 +	      log.  By default, the <command role="hg-cmd" moreinfo="none">hg
  1.6764 +		serve</command> command writes this information to
  1.6765 +	      standard error, not to a file.</para>
  1.6766 +	  </listitem>
  1.6767 +	  <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>:
  1.6768 +	      Boolean.  Whether to use the IPv6 protocol. By default,
  1.6769 +	      IPv6 is not used.</para>
  1.6770 +	  </listitem>
  1.6771 +	  <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>:
  1.6772 +	      Integer.  The TCP port number on which the server should
  1.6773 +	      listen.  The default port number used is 8000.</para>
  1.6774 +	  </listitem></itemizedlist>
  1.6775 +      </sect3>
  1.6776 +
  1.6777 +      <sect3>
  1.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>
  1.6779 +
  1.6780 +	<para id="x_4fc">It is important to remember that a web server like
  1.6781 +	  Apache or <literal moreinfo="none">lighttpd</literal> will run under a user
  1.6782 +	  ID that is different to yours. CGI scripts run by your
  1.6783 +	  server, such as <filename role="special" moreinfo="none">hgweb.cgi</filename>, will usually also run
  1.6784 +	  under that user ID.</para>
  1.6785 +
  1.6786 +	<para id="x_4fd">If you add <literal role="rc-web" moreinfo="none">web</literal> items to
  1.6787 +	  your own personal <filename role="special" moreinfo="none">~/.hgrc</filename> file, CGI scripts won't read that
  1.6788 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file.  Those
  1.6789 +	  settings will thus only affect the behavior of the <command role="hg-cmd" moreinfo="none">hg serve</command> command when you run it.
  1.6790 +	  To cause CGI scripts to see your settings, either create a
  1.6791 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file in the
  1.6792 +	  home directory of the user ID that runs your web server, or
  1.6793 +	  add those settings to a system-wide <filename role="special" moreinfo="none">hgrc</filename> file.</para>
  1.6794 +      </sect3>
  1.6795 +    </sect2>
  1.6796 +  </sect1>
  1.6797 +
  1.6798 +  <sect1>
  1.6799 +    <title>System-wide configuration</title>
  1.6800 +
  1.6801 +    <para id="x_6b0">On Unix-like systems shared by multiple users (such as a
  1.6802 +      server to which people publish changes), it often makes sense to
  1.6803 +      set up some global default behaviors, such as what theme to use
  1.6804 +      in web interfaces.</para>
  1.6805 +
  1.6806 +    <para id="x_6b1">If a file named <filename moreinfo="none">/etc/mercurial/hgrc</filename>
  1.6807 +      exists, Mercurial will read it at startup time and apply any
  1.6808 +      configuration settings it finds in that file.  It will also look
  1.6809 +      for files ending in a <literal moreinfo="none">.rc</literal> extension in a
  1.6810 +      directory named <filename moreinfo="none">/etc/mercurial/hgrc.d</filename>, and
  1.6811 +      apply any configuration settings it finds in each of those
  1.6812 +      files.</para>
  1.6813 +
  1.6814 +    <sect2>
  1.6815 +      <title>Making Mercurial more trusting</title>
  1.6816 +
  1.6817 +      <para id="x_6b2">One situation in which a global <filename moreinfo="none">hgrc</filename>
  1.6818 +	can be useful is if users are pulling changes owned by other
  1.6819 +	users.  By default, Mercurial will not trust most of the
  1.6820 +	configuration items in a <filename moreinfo="none">.hg/hgrc</filename> file
  1.6821 +	inside a repository that is owned by a different user. If we
  1.6822 +	clone or pull changes from such a repository, Mercurial will
  1.6823 +	print a warning stating that it does not trust their
  1.6824 +	<filename moreinfo="none">.hg/hgrc</filename>.</para>
  1.6825 +
  1.6826 +      <para id="x_6b3">If everyone in a particular Unix group is on the same team
  1.6827 +	and <emphasis>should</emphasis> trust each other's
  1.6828 +	configuration settings, or we want to trust particular users,
  1.6829 +	we can override Mercurial's skeptical defaults by creating a
  1.6830 +	system-wide <filename moreinfo="none">hgrc</filename> file such as the
  1.6831 +	following:</para>
  1.6832 +
  1.6833 +    <programlisting format="linespecific"># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc
  1.6834 +[trusted]
  1.6835 +# Trust all entries in any hgrc file owned by the "editors" or
  1.6836 +# "www-data" groups.
  1.6837 +groups = editors, www-data
  1.6838 +
  1.6839 +# Trust entries in hgrc files owned by the following users.
  1.6840 +users = apache, bobo
  1.6841 +</programlisting>
  1.6842 +    </sect2>
  1.6843 +  </sect1>
  1.6844 +</chapter>
  1.6845 +
  1.6846 +<!--
  1.6847 +local variables: 
  1.6848 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.6849 +end:
  1.6850 +-->
  1.6851 +
  1.6852 +  <!-- BEGIN ch07 -->
  1.6853 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.6854 +
  1.6855 +<chapter id="chap:names">
  1.6856 +  <?dbhtml filename="file-names-and-pattern-matching.html"?>
  1.6857 +  <title>File names and pattern matching</title>
  1.6858 +
  1.6859 +  <para id="x_543">Mercurial provides mechanisms that let you work with file
  1.6860 +    names in a consistent and expressive way.</para>
  1.6861 +
  1.6862 +  <sect1>
  1.6863 +    <title>Simple file naming</title>
  1.6864 +
  1.6865 +    <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the
  1.6866 +	hood</quote> to handle file names.  Every command behaves
  1.6867 +      uniformly with respect to file names.  The way in which commands
  1.6868 +      work with file names is as follows.</para>
  1.6869 +
  1.6870 +    <para id="x_545">If you explicitly name real files on the command line,
  1.6871 +      Mercurial works with exactly those files, as you would expect.
  1.6872 +      <!-- BEGIN filenames.files -->
  1.6873 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add COPYING README examples/simple.py</userinput>
  1.6874 +</screen>
  1.6875 +<!-- END filenames.files -->
  1.6876 +</para>
  1.6877 +
  1.6878 +    <para id="x_546">When you provide a directory name, Mercurial will interpret
  1.6879 +      this as <quote>operate on every file in this directory and its
  1.6880 +	subdirectories</quote>. Mercurial traverses the files and
  1.6881 +      subdirectories in a directory in alphabetical order.  When it
  1.6882 +      encounters a subdirectory, it will traverse that subdirectory
  1.6883 +      before continuing with the current directory.</para>
  1.6884 +
  1.6885 +      <!-- BEGIN filenames.dirs -->
  1.6886 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status src</userinput>
  1.6887 +? src/main.py
  1.6888 +? src/watcher/_watcher.c
  1.6889 +? src/watcher/watcher.py
  1.6890 +? src/xyzzy.txt
  1.6891 +</screen>
  1.6892 +<!-- END filenames.dirs -->
  1.6893 +
  1.6894 +  </sect1>
  1.6895 +
  1.6896 +  <sect1>
  1.6897 +    <title>Running commands without any file names</title>
  1.6898 +
  1.6899 +    <para id="x_547">Mercurial's commands that work with file names have useful
  1.6900 +      default behaviors when you invoke them without providing any
  1.6901 +      file names or patterns.  What kind of behavior you should
  1.6902 +      expect depends on what the command does.  Here are a few rules
  1.6903 +      of thumb you can use to predict what a command is likely to do
  1.6904 +      if you don't give it any names to work with.</para>
  1.6905 +    <itemizedlist>
  1.6906 +      <listitem><para id="x_548">Most commands will operate on the entire working
  1.6907 +	  directory. This is what the <command role="hg-cmd" moreinfo="none">hg
  1.6908 +	    add</command> command does, for example.</para>
  1.6909 +      </listitem>
  1.6910 +      <listitem><para id="x_549">If the command has effects that are difficult or
  1.6911 +	  impossible to reverse, it will force you to explicitly
  1.6912 +	  provide at least one name or pattern (see below).  This
  1.6913 +	  protects you from accidentally deleting files by running
  1.6914 +	  <command role="hg-cmd" moreinfo="none">hg remove</command> with no
  1.6915 +	  arguments, for example.</para>
  1.6916 +      </listitem></itemizedlist>
  1.6917 +
  1.6918 +    <para id="x_54a">It's easy to work around these default behaviors if they
  1.6919 +      don't suit you.  If a command normally operates on the whole
  1.6920 +      working directory, you can invoke it on just the current
  1.6921 +      directory and its subdirectories by giving it the name
  1.6922 +      <quote><filename class="directory" moreinfo="none">.</filename></quote>.</para>
  1.6923 +
  1.6924 +    <!-- BEGIN filenames.wdir-subdir -->
  1.6925 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd src</userinput>
  1.6926 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add -n</userinput>
  1.6927 +adding ../MANIFEST.in
  1.6928 +adding ../examples/performant.py
  1.6929 +adding ../setup.py
  1.6930 +adding main.py
  1.6931 +adding watcher/_watcher.c
  1.6932 +adding watcher/watcher.py
  1.6933 +adding xyzzy.txt
  1.6934 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add -n .</userinput>
  1.6935 +adding main.py
  1.6936 +adding watcher/_watcher.c
  1.6937 +adding watcher/watcher.py
  1.6938 +adding xyzzy.txt
  1.6939 +</screen>
  1.6940 +<!-- END filenames.wdir-subdir -->
  1.6941 +
  1.6942 +
  1.6943 +    <para id="x_54b">Along the same lines, some commands normally print file
  1.6944 +      names relative to the root of the repository, even if you're
  1.6945 +      invoking them from a subdirectory.  Such a command will print
  1.6946 +      file names relative to your subdirectory if you give it explicit
  1.6947 +      names.  Here, we're going to run <command role="hg-cmd" moreinfo="none">hg
  1.6948 +	status</command> from a subdirectory, and get it to operate on
  1.6949 +      the entire working directory while printing file names relative
  1.6950 +      to our subdirectory, by passing it the output of the <command role="hg-cmd" moreinfo="none">hg root</command> command.</para>
  1.6951 +
  1.6952 +      <!-- BEGIN filenames.wdir-relname -->
  1.6953 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.6954 +A COPYING
  1.6955 +A README
  1.6956 +A examples/simple.py
  1.6957 +? MANIFEST.in
  1.6958 +? examples/performant.py
  1.6959 +? setup.py
  1.6960 +? src/main.py
  1.6961 +? src/watcher/_watcher.c
  1.6962 +? src/watcher/watcher.py
  1.6963 +? src/xyzzy.txt
  1.6964 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status `hg root`</userinput>
  1.6965 +A ../COPYING
  1.6966 +A ../README
  1.6967 +A ../examples/simple.py
  1.6968 +? ../MANIFEST.in
  1.6969 +? ../examples/performant.py
  1.6970 +? ../setup.py
  1.6971 +? main.py
  1.6972 +? watcher/_watcher.c
  1.6973 +? watcher/watcher.py
  1.6974 +? xyzzy.txt
  1.6975 +</screen>
  1.6976 +<!-- END filenames.wdir-relname -->
  1.6977 +
  1.6978 +  </sect1>
  1.6979 +
  1.6980 +  <sect1>
  1.6981 +    <title>Telling you what's going on</title>
  1.6982 +
  1.6983 +    <para id="x_54c">The <command role="hg-cmd" moreinfo="none">hg add</command> example in the
  1.6984 +      preceding section illustrates something else that's helpful
  1.6985 +      about Mercurial commands.  If a command operates on a file that
  1.6986 +      you didn't name explicitly on the command line, it will usually
  1.6987 +      print the name of the file, so that you will not be surprised
  1.6988 +      what's going on.</para>
  1.6989 +
  1.6990 +    <para id="x_54d">The principle here is of <emphasis>least
  1.6991 +	surprise</emphasis>.  If you've exactly named a file on the
  1.6992 +      command line, there's no point in repeating it back at you.  If
  1.6993 +      Mercurial is acting on a file <emphasis>implicitly</emphasis>, e.g.
  1.6994 +      because you provided no names, or a directory, or a pattern (see
  1.6995 +      below), it is safest to tell you what files it's operating on.</para>
  1.6996 +
  1.6997 +    <para id="x_54e">For commands that behave this way, you can silence them
  1.6998 +      using the <option role="hg-opt-global">-q</option> option.  You
  1.6999 +      can also get them to print the name of every file, even those
  1.7000 +      you've named explicitly, using the <option role="hg-opt-global">-v</option> option.</para>
  1.7001 +  </sect1>
  1.7002 +
  1.7003 +  <sect1>
  1.7004 +    <title>Using patterns to identify files</title>
  1.7005 +
  1.7006 +    <para id="x_54f">In addition to working with file and directory names,
  1.7007 +      Mercurial lets you use <emphasis>patterns</emphasis> to identify
  1.7008 +      files.  Mercurial's pattern handling is expressive.</para>
  1.7009 +
  1.7010 +    <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of
  1.7011 +      matching file names to patterns normally falls to the shell.  On
  1.7012 +      these systems, you must explicitly tell Mercurial that a name is
  1.7013 +      a pattern.  On Windows, the shell does not expand patterns, so
  1.7014 +      Mercurial will automatically identify names that are patterns,
  1.7015 +      and expand them for you.</para>
  1.7016 +
  1.7017 +    <para id="x_551">To provide a pattern in place of a regular name on the
  1.7018 +      command line, the mechanism is simple:</para>
  1.7019 +    <programlisting format="linespecific">syntax:patternbody</programlisting>
  1.7020 +    <para id="x_552">That is, a pattern is identified by a short text string that
  1.7021 +      says what kind of pattern this is, followed by a colon, followed
  1.7022 +      by the actual pattern.</para>
  1.7023 +
  1.7024 +    <para id="x_553">Mercurial supports two kinds of pattern syntax.  The most
  1.7025 +      frequently used is called <literal moreinfo="none">glob</literal>; this is the
  1.7026 +      same kind of pattern matching used by the Unix shell, and should
  1.7027 +      be familiar to Windows command prompt users, too.</para>
  1.7028 +
  1.7029 +    <para id="x_554">When Mercurial does automatic pattern matching on Windows,
  1.7030 +      it uses <literal moreinfo="none">glob</literal> syntax.  You can thus omit the
  1.7031 +      <quote><literal moreinfo="none">glob:</literal></quote> prefix on Windows, but
  1.7032 +      it's safe to use it, too.</para>
  1.7033 +
  1.7034 +    <para id="x_555">The <literal moreinfo="none">re</literal> syntax is more powerful; it lets
  1.7035 +      you specify patterns using regular expressions, also known as
  1.7036 +      regexps.</para>
  1.7037 +
  1.7038 +    <para id="x_556">By the way, in the examples that follow, notice that I'm
  1.7039 +      careful to wrap all of my patterns in quote characters, so that
  1.7040 +      they won't get expanded by the shell before Mercurial sees
  1.7041 +      them.</para>
  1.7042 +
  1.7043 +    <sect2>
  1.7044 +      <title>Shell-style <literal moreinfo="none">glob</literal> patterns</title>
  1.7045 +
  1.7046 +      <para id="x_557">This is an overview of the kinds of patterns you can use
  1.7047 +	when you're matching on glob patterns.</para>
  1.7048 +
  1.7049 +      <para id="x_558">The <quote><literal moreinfo="none">*</literal></quote> character matches
  1.7050 +	any string, within a single directory.</para>
  1.7051 +
  1.7052 +      <!-- BEGIN filenames.glob.star -->
  1.7053 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add 'glob:*.py'</userinput>
  1.7054 +adding main.py
  1.7055 +</screen>
  1.7056 +<!-- END filenames.glob.star -->
  1.7057 +
  1.7058 +
  1.7059 +      <para id="x_559">The <quote><literal moreinfo="none">**</literal></quote> pattern matches
  1.7060 +	any string, and crosses directory boundaries.  It's not a
  1.7061 +	standard Unix glob token, but it's accepted by several popular
  1.7062 +	Unix shells, and is very useful.</para>
  1.7063 +
  1.7064 +      <!-- BEGIN filenames.glob.starstar -->
  1.7065 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.7066 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**.py'</userinput>
  1.7067 +A examples/simple.py
  1.7068 +A src/main.py
  1.7069 +? examples/performant.py
  1.7070 +? setup.py
  1.7071 +? src/watcher/watcher.py
  1.7072 +</screen>
  1.7073 +<!-- END filenames.glob.starstar -->
  1.7074 +
  1.7075 +
  1.7076 +      <para id="x_55a">The <quote><literal moreinfo="none">?</literal></quote> pattern matches
  1.7077 +	any single character.</para>
  1.7078 +
  1.7079 +      <!-- BEGIN filenames.glob.question -->
  1.7080 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**.?'</userinput>
  1.7081 +? src/watcher/_watcher.c
  1.7082 +</screen>
  1.7083 +<!-- END filenames.glob.question -->
  1.7084 +
  1.7085 +
  1.7086 +      <para id="x_55b">The <quote><literal moreinfo="none">[</literal></quote> character begins a
  1.7087 +	<emphasis>character class</emphasis>.  This matches any single
  1.7088 +	character within the class.  The class ends with a
  1.7089 +	<quote><literal moreinfo="none">]</literal></quote> character.  A class may
  1.7090 +	contain multiple <emphasis>range</emphasis>s of the form
  1.7091 +	<quote><literal moreinfo="none">a-f</literal></quote>, which is shorthand for
  1.7092 +	<quote><literal moreinfo="none">abcdef</literal></quote>.</para>
  1.7093 +
  1.7094 +	<!-- BEGIN filenames.glob.range -->
  1.7095 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**[nr-t]'</userinput>
  1.7096 +? MANIFEST.in
  1.7097 +? src/xyzzy.txt
  1.7098 +</screen>
  1.7099 +<!-- END filenames.glob.range -->
  1.7100 +
  1.7101 +
  1.7102 +      <para id="x_55c">If the first character after the
  1.7103 +	<quote><literal moreinfo="none">[</literal></quote> in a character class is a
  1.7104 +	<quote><literal moreinfo="none">!</literal></quote>, it
  1.7105 +	<emphasis>negates</emphasis> the class, making it match any
  1.7106 +	single character not in the class.</para>
  1.7107 +
  1.7108 +      <para id="x_55d">A <quote><literal moreinfo="none">{</literal></quote> begins a group of
  1.7109 +	subpatterns, where the whole group matches if any subpattern
  1.7110 +	in the group matches.  The <quote><literal moreinfo="none">,</literal></quote>
  1.7111 +	character separates subpatterns, and
  1.7112 +	<quote><literal moreinfo="none">}</literal></quote> ends the group.</para>
  1.7113 +
  1.7114 +      <!-- BEGIN filenames.glob.group -->
  1.7115 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:*.{in,py}'</userinput>
  1.7116 +? MANIFEST.in
  1.7117 +? setup.py
  1.7118 +</screen>
  1.7119 +<!-- END filenames.glob.group -->
  1.7120 +
  1.7121 +
  1.7122 +      <sect3>
  1.7123 +	<title>Watch out!</title>
  1.7124 +
  1.7125 +	<para id="x_55e">Don't forget that if you want to match a pattern in any
  1.7126 +	  directory, you should not be using the
  1.7127 +	  <quote><literal moreinfo="none">*</literal></quote> match-any token, as this
  1.7128 +	  will only match within one directory.  Instead, use the
  1.7129 +	  <quote><literal moreinfo="none">**</literal></quote> token.  This small
  1.7130 +	  example illustrates the difference between the two.</para>
  1.7131 +
  1.7132 +	  <!-- BEGIN filenames.glob.star-starstar -->
  1.7133 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:*.py'</userinput>
  1.7134 +? setup.py
  1.7135 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status 'glob:**.py'</userinput>
  1.7136 +A examples/simple.py
  1.7137 +A src/main.py
  1.7138 +? examples/performant.py
  1.7139 +? setup.py
  1.7140 +? src/watcher/watcher.py
  1.7141 +</screen>
  1.7142 +<!-- END filenames.glob.star-starstar -->
  1.7143 +
  1.7144 +      </sect3>
  1.7145 +    </sect2>
  1.7146 +
  1.7147 +    <sect2>
  1.7148 +      <title>Regular expression matching with <literal moreinfo="none">re</literal>
  1.7149 +	patterns</title>
  1.7150 +
  1.7151 +      <para id="x_55f">Mercurial accepts the same regular expression syntax as
  1.7152 +	the Python programming language (it uses Python's regexp
  1.7153 +	engine internally). This is based on the Perl language's
  1.7154 +	regexp syntax, which is the most popular dialect in use (it's
  1.7155 +	also used in Java, for example).</para>
  1.7156 +
  1.7157 +      <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail
  1.7158 +	here, as regexps are not often used.  Perl-style regexps are
  1.7159 +	in any case already exhaustively documented on a multitude of
  1.7160 +	web sites, and in many books.  Instead, I will focus here on a
  1.7161 +	few things you should know if you find yourself needing to use
  1.7162 +	regexps with Mercurial.</para>
  1.7163 +
  1.7164 +      <para id="x_561">A regexp is matched against an entire file name, relative
  1.7165 +	to the root of the repository.  In other words, even if you're
  1.7166 +	already in subbdirectory <filename class="directory" moreinfo="none">foo</filename>, if you want to match files
  1.7167 +	under this directory, your pattern must start with
  1.7168 +	<quote><literal moreinfo="none">foo/</literal></quote>.</para>
  1.7169 +
  1.7170 +      <para id="x_562">One thing to note, if you're familiar with Perl-style
  1.7171 +	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
  1.7172 +	That is, a regexp starts matching against the beginning of a
  1.7173 +	string; it doesn't look for a match anywhere within the
  1.7174 +	string.  To match anywhere in a string, start your pattern
  1.7175 +	with <quote><literal moreinfo="none">.*</literal></quote>.</para>
  1.7176 +    </sect2>
  1.7177 +  </sect1>
  1.7178 +
  1.7179 +  <sect1>
  1.7180 +    <title>Filtering files</title>
  1.7181 +
  1.7182 +    <para id="x_563">Not only does Mercurial give you a variety of ways to
  1.7183 +      specify files; it lets you further winnow those files using
  1.7184 +      <emphasis>filters</emphasis>.  Commands that work with file
  1.7185 +      names accept two filtering options.</para>
  1.7186 +    <itemizedlist>
  1.7187 +      <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or
  1.7188 +	  <option role="hg-opt-global">--include</option>, lets you
  1.7189 +	  specify a pattern that file names must match in order to be
  1.7190 +	  processed.</para>
  1.7191 +      </listitem>
  1.7192 +      <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or
  1.7193 +	  <option role="hg-opt-global">--exclude</option>, gives you a
  1.7194 +	  way to <emphasis>avoid</emphasis> processing files, if they
  1.7195 +	  match this pattern.</para>
  1.7196 +      </listitem></itemizedlist>
  1.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,
  1.7198 +      and intermix them as you please.  Mercurial interprets the
  1.7199 +      patterns you provide using glob syntax by default (but you can
  1.7200 +      use regexps if you need to).</para>
  1.7201 +
  1.7202 +    <para id="x_567">You can read a <option role="hg-opt-global">-I</option>
  1.7203 +      filter as <quote>process only the files that match this
  1.7204 +	filter</quote>.</para>
  1.7205 +
  1.7206 +    <!-- BEGIN filenames.filter.include -->
  1.7207 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -I '*.in'</userinput>
  1.7208 +? MANIFEST.in
  1.7209 +</screen>
  1.7210 +<!-- END filenames.filter.include -->
  1.7211 +
  1.7212 +
  1.7213 +    <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best
  1.7214 +      read as <quote>process only the files that don't match this
  1.7215 +	pattern</quote>.</para>
  1.7216 +
  1.7217 +    <!-- BEGIN filenames.filter.exclude -->
  1.7218 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status -X '**.py' src</userinput>
  1.7219 +? src/watcher/_watcher.c
  1.7220 +? src/xyzzy.txt
  1.7221 +</screen>
  1.7222 +<!-- END filenames.filter.exclude -->
  1.7223 +
  1.7224 +  </sect1>
  1.7225 +
  1.7226 +  <sect1>
  1.7227 +    <title>Permanently ignoring unwanted files and directories</title>
  1.7228 +
  1.7229 +    <para id="x_569">When you create a new repository, the chances are
  1.7230 +      that over time it will grow to contain files that ought to
  1.7231 +      <emphasis>not</emphasis> be managed by Mercurial, but which you
  1.7232 +      don't want to see listed every time you run <command moreinfo="none">hg
  1.7233 +	status</command>.  For instance, <quote>build products</quote>
  1.7234 +      are files that are created as part of a build but which should
  1.7235 +      not be managed by a revision control system.  The most common
  1.7236 +      build products are output files produced by software tools such
  1.7237 +      as compilers.  As another example, many text editors litter a
  1.7238 +      directory with lock files, temporary working files, and backup
  1.7239 +      files, which it also makes no sense to manage.</para>
  1.7240 +
  1.7241 +    <para id="x_6b4">To have Mercurial permanently ignore such files, create a
  1.7242 +      file named <filename moreinfo="none">.hgignore</filename> in the root of your
  1.7243 +      repository.  You <emphasis>should</emphasis> <command moreinfo="none">hg
  1.7244 +      add</command> this file so that it gets tracked with the rest of
  1.7245 +      your repository contents, since your collaborators will probably
  1.7246 +      find it useful too.</para>
  1.7247 +
  1.7248 +    <para id="x_6b5">By default, the <filename moreinfo="none">.hgignore</filename> file should
  1.7249 +      contain a list of regular expressions, one per line.  Empty
  1.7250 +      lines are skipped. Most people prefer to describe the files they
  1.7251 +      want to ignore using the <quote>glob</quote> syntax that we
  1.7252 +      described above, so a typical <filename moreinfo="none">.hgignore</filename>
  1.7253 +      file will start with this directive:</para>
  1.7254 +
  1.7255 +    <programlisting format="linespecific">syntax: glob</programlisting>
  1.7256 +
  1.7257 +    <para id="x_6b6">This tells Mercurial to interpret the lines that follow as
  1.7258 +      glob patterns, not regular expressions.</para>
  1.7259 +
  1.7260 +    <para id="x_6b7">Here is a typical-looking <filename moreinfo="none">.hgignore</filename>
  1.7261 +      file.</para>
  1.7262 +
  1.7263 +    <programlisting format="linespecific">syntax: glob
  1.7264 +# This line is a comment, and will be skipped.
  1.7265 +# Empty lines are skipped too.
  1.7266 +
  1.7267 +# Backup files left behind by the Emacs editor.
  1.7268 +*~
  1.7269 +
  1.7270 +# Lock files used by the Emacs editor.
  1.7271 +# Notice that the "#" character is quoted with a backslash.
  1.7272 +# This prevents it from being interpreted as starting a comment.
  1.7273 +.\#*
  1.7274 +
  1.7275 +# Temporary files used by the vim editor.
  1.7276 +.*.swp
  1.7277 +
  1.7278 +# A hidden file created by the Mac OS X Finder.
  1.7279 +.DS_Store
  1.7280 +</programlisting>
  1.7281 +  </sect1>
  1.7282 +
  1.7283 +  <sect1 id="sec:names:case">
  1.7284 +    <title>Case sensitivity</title>
  1.7285 +
  1.7286 +    <para id="x_56a">If you're working in a mixed development environment that
  1.7287 +      contains both Linux (or other Unix) systems and Macs or Windows
  1.7288 +      systems, you should keep in the back of your mind the knowledge
  1.7289 +      that they treat the case (<quote>N</quote> versus
  1.7290 +      <quote>n</quote>) of file names in incompatible ways.  This is
  1.7291 +      not very likely to affect you, and it's easy to deal with if it
  1.7292 +      does, but it could surprise you if you don't know about
  1.7293 +      it.</para>
  1.7294 +
  1.7295 +    <para id="x_56b">Operating systems and filesystems differ in the way they
  1.7296 +      handle the <emphasis>case</emphasis> of characters in file and
  1.7297 +      directory names.  There are three common ways to handle case in
  1.7298 +      names.</para>
  1.7299 +    <itemizedlist>
  1.7300 +      <listitem><para id="x_56c">Completely case insensitive.  Uppercase and
  1.7301 +	  lowercase versions of a letter are treated as identical,
  1.7302 +	  both when creating a file and during subsequent accesses.
  1.7303 +	  This is common on older DOS-based systems.</para>
  1.7304 +      </listitem>
  1.7305 +      <listitem><para id="x_56d">Case preserving, but insensitive.  When a file
  1.7306 +	  or directory is created, the case of its name is stored, and
  1.7307 +	  can be retrieved and displayed by the operating system.
  1.7308 +	  When an existing file is being looked up, its case is
  1.7309 +	  ignored.  This is the standard arrangement on Windows and
  1.7310 +	  MacOS.  The names <filename moreinfo="none">foo</filename> and
  1.7311 +	  <filename moreinfo="none">FoO</filename> identify the same file.  This
  1.7312 +	  treatment of uppercase and lowercase letters as
  1.7313 +	  interchangeable is also referred to as <emphasis>case
  1.7314 +	    folding</emphasis>.</para>
  1.7315 +      </listitem>
  1.7316 +      <listitem><para id="x_56e">Case sensitive.  The case of a name
  1.7317 +	  is significant at all times. The names
  1.7318 +	  <filename moreinfo="none">foo</filename> and <filename moreinfo="none">FoO</filename>
  1.7319 +	  identify different files.  This is the way Linux and Unix
  1.7320 +	  systems normally work.</para>
  1.7321 +      </listitem></itemizedlist>
  1.7322 +
  1.7323 +    <para id="x_56f">On Unix-like systems, it is possible to have any or all of
  1.7324 +      the above ways of handling case in action at once.  For example,
  1.7325 +      if you use a USB thumb drive formatted with a FAT32 filesystem
  1.7326 +      on a Linux system, Linux will handle names on that filesystem in
  1.7327 +      a case preserving, but insensitive, way.</para>
  1.7328 +
  1.7329 +    <sect2>
  1.7330 +      <title>Safe, portable repository storage</title>
  1.7331 +
  1.7332 +      <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case
  1.7333 +	  safe</emphasis>.  It translates file names so that they can
  1.7334 +	be safely stored on both case sensitive and case insensitive
  1.7335 +	filesystems.  This means that you can use normal file copying
  1.7336 +	tools to transfer a Mercurial repository onto, for example, a
  1.7337 +	USB thumb drive, and safely move that drive and repository
  1.7338 +	back and forth between a Mac, a PC running Windows, and a
  1.7339 +	Linux box.</para>
  1.7340 +
  1.7341 +    </sect2>
  1.7342 +    <sect2>
  1.7343 +      <title>Detecting case conflicts</title>
  1.7344 +
  1.7345 +      <para id="x_571">When operating in the working directory, Mercurial honours
  1.7346 +	the naming policy of the filesystem where the working
  1.7347 +	directory is located.  If the filesystem is case preserving,
  1.7348 +	but insensitive, Mercurial will treat names that differ only
  1.7349 +	in case as the same.</para>
  1.7350 +
  1.7351 +      <para id="x_572">An important aspect of this approach is that it is
  1.7352 +	possible to commit a changeset on a case sensitive (typically
  1.7353 +	Linux or Unix) filesystem that will cause trouble for users on
  1.7354 +	case insensitive (usually Windows and MacOS) users.  If a
  1.7355 +	Linux user commits changes to two files, one named
  1.7356 +	<filename moreinfo="none">myfile.c</filename> and the other named
  1.7357 +	<filename moreinfo="none">MyFile.C</filename>, they will be stored correctly
  1.7358 +	in the repository.  And in the working directories of other
  1.7359 +	Linux users, they will be correctly represented as separate
  1.7360 +	files.</para>
  1.7361 +
  1.7362 +      <para id="x_573">If a Windows or Mac user pulls this change, they will not
  1.7363 +	initially have a problem, because Mercurial's repository
  1.7364 +	storage mechanism is case safe.  However, once they try to
  1.7365 +	<command role="hg-cmd" moreinfo="none">hg update</command> the working
  1.7366 +	directory to that changeset, or <command role="hg-cmd" moreinfo="none">hg
  1.7367 +	  merge</command> with that changeset, Mercurial will spot the
  1.7368 +	conflict between the two file names that the filesystem would
  1.7369 +	treat as the same, and forbid the update or merge from
  1.7370 +	occurring.</para>
  1.7371 +    </sect2>
  1.7372 +
  1.7373 +    <sect2>
  1.7374 +      <title>Fixing a case conflict</title>
  1.7375 +
  1.7376 +      <para id="x_574">If you are using Windows or a Mac in a mixed environment
  1.7377 +	where some of your collaborators are using Linux or Unix, and
  1.7378 +	Mercurial reports a case folding conflict when you try to
  1.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
  1.7380 +	problem is simple.</para>
  1.7381 +
  1.7382 +      <para id="x_575">Just find a nearby Linux or Unix box, clone the problem
  1.7383 +	repository onto it, and use Mercurial's <command role="hg-cmd" moreinfo="none">hg rename</command> command to change the
  1.7384 +	names of any offending files or directories so that they will
  1.7385 +	no longer cause case folding conflicts.  Commit this change,
  1.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
  1.7387 +	MacOS system, and <command role="hg-cmd" moreinfo="none">hg update</command>
  1.7388 +	to the revision with the non-conflicting names.</para>
  1.7389 +
  1.7390 +      <para id="x_576">The changeset with case-conflicting names will remain in
  1.7391 +	your project's history, and you still won't be able to
  1.7392 +	<command role="hg-cmd" moreinfo="none">hg update</command> your working
  1.7393 +	directory to that changeset on a Windows or MacOS system, but
  1.7394 +	you can continue development unimpeded.</para>
  1.7395 +    </sect2>
  1.7396 +  </sect1>
  1.7397 +</chapter>
  1.7398 +
  1.7399 +<!--
  1.7400 +local variables: 
  1.7401 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.7402 +end:
  1.7403 +-->
  1.7404 +
  1.7405 +  <!-- BEGIN ch08 -->
  1.7406 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.7407 +
  1.7408 +<chapter id="chap:branch">
  1.7409 +  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
  1.7410 +  <title>Managing releases and branchy development</title>
  1.7411 +
  1.7412 +  <para id="x_369">Mercurial provides several mechanisms for you to manage a
  1.7413 +    project that is making progress on multiple fronts at once.  To
  1.7414 +    understand these mechanisms, let's first take a brief look at a
  1.7415 +    fairly normal software project structure.</para>
  1.7416 +
  1.7417 +  <para id="x_36a">Many software projects issue periodic <quote>major</quote>
  1.7418 +    releases that contain substantial new features.  In parallel, they
  1.7419 +    may issue <quote>minor</quote> releases.  These are usually
  1.7420 +    identical to the major releases off which they're based, but with
  1.7421 +    a few bugs fixed.</para>
  1.7422 +
  1.7423 +  <para id="x_36b">In this chapter, we'll start by talking about how to keep
  1.7424 +    records of project milestones such as releases.  We'll then
  1.7425 +    continue on to talk about the flow of work between different
  1.7426 +    phases of a project, and how Mercurial can help you to isolate and
  1.7427 +    manage this work.</para>
  1.7428 +
  1.7429 +  <sect1>
  1.7430 +    <title>Giving a persistent name to a revision</title>
  1.7431 +
  1.7432 +    <para id="x_36c">Once you decide that you'd like to call a particular
  1.7433 +      revision a <quote>release</quote>, it's a good idea to record
  1.7434 +      the identity of that revision. This will let you reproduce that
  1.7435 +      release at a later date, for whatever purpose you might need at
  1.7436 +      the time (reproducing a bug, porting to a new platform, etc).
  1.7437 +      <!-- BEGIN tag.init -->
  1.7438 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init mytag</userinput>
  1.7439 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd mytag</userinput>
  1.7440 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo hello &gt; myfile</userinput>
  1.7441 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Initial commit'</userinput>
  1.7442 +adding myfile
  1.7443 +</screen>
  1.7444 +<!-- END tag.init -->
  1.7445 +</para>
  1.7446 +
  1.7447 +    <para id="x_36d">Mercurial lets you give a permanent name to any revision
  1.7448 +      using the <command role="hg-cmd" moreinfo="none">hg tag</command> command.  Not
  1.7449 +      surprisingly, these names are called <quote>tags</quote>.</para>
  1.7450 +
  1.7451 +    <!-- BEGIN tag.tag -->
  1.7452 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag v1.0</userinput>
  1.7453 +</screen>
  1.7454 +<!-- END tag.tag -->
  1.7455 +
  1.7456 +
  1.7457 +    <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote>
  1.7458 +      for a revision.  Tags exist purely for your convenience, so that
  1.7459 +      you have a handy permanent way to refer to a revision; Mercurial
  1.7460 +      doesn't interpret the tag names you use in any way.  Neither
  1.7461 +      does Mercurial place any restrictions on the name of a tag,
  1.7462 +      beyond a few that are necessary to ensure that a tag can be
  1.7463 +      parsed unambiguously.  A tag name cannot contain any of the
  1.7464 +      following characters:</para>
  1.7465 +    <itemizedlist>
  1.7466 +      <listitem><para id="x_36f">Colon (ASCII 58,
  1.7467 +	  <quote><literal moreinfo="none">:</literal></quote>)</para>
  1.7468 +      </listitem>
  1.7469 +      <listitem><para id="x_370">Carriage return (ASCII 13,
  1.7470 +	  <quote><literal moreinfo="none">\r</literal></quote>)</para>
  1.7471 +      </listitem>
  1.7472 +      <listitem><para id="x_371">Newline (ASCII 10,
  1.7473 +	  <quote><literal moreinfo="none">\n</literal></quote>)</para>
  1.7474 +      </listitem></itemizedlist>
  1.7475 +
  1.7476 +    <para id="x_372">You can use the <command role="hg-cmd" moreinfo="none">hg tags</command>
  1.7477 +      command to display the tags present in your repository.  In the
  1.7478 +      output, each tagged revision is identified first by its name,
  1.7479 +      then by revision number, and finally by the unique hash of the
  1.7480 +      revision.</para>
  1.7481 +
  1.7482 +    <!-- BEGIN tag.tags -->
  1.7483 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  1.7484 +tip                                1:f283c2669b38
  1.7485 +v1.0                               0:0c957785065f
  1.7486 +</screen>
  1.7487 +<!-- END tag.tags -->
  1.7488 +
  1.7489 +
  1.7490 +    <para id="x_373">Notice that <literal moreinfo="none">tip</literal> is listed in the output
  1.7491 +      of <command role="hg-cmd" moreinfo="none">hg tags</command>.  The
  1.7492 +      <literal moreinfo="none">tip</literal> tag is a special <quote>floating</quote>
  1.7493 +      tag, which always identifies the newest revision in the
  1.7494 +      repository.</para>
  1.7495 +
  1.7496 +    <para id="x_374">In the output of the <command role="hg-cmd" moreinfo="none">hg
  1.7497 +	tags</command> command, tags are listed in reverse order, by
  1.7498 +      revision number.  This usually means that recent tags are listed
  1.7499 +      before older tags.  It also means that <literal moreinfo="none">tip</literal> is
  1.7500 +      always going to be the first tag listed in the output of
  1.7501 +      <command role="hg-cmd" moreinfo="none">hg tags</command>.</para>
  1.7502 +
  1.7503 +    <para id="x_375">When you run <command role="hg-cmd" moreinfo="none">hg log</command>, if it
  1.7504 +      displays a revision that has tags associated with it, it will
  1.7505 +      print those tags.</para>
  1.7506 +
  1.7507 +    <!-- BEGIN tag.log -->
  1.7508 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log</userinput>
  1.7509 +changeset:   1:f283c2669b38
  1.7510 +tag:         tip
  1.7511 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7512 +date:        Sun Aug 16 14:05:16 2009 +0000
  1.7513 +summary:     Added tag v1.0 for changeset 0c957785065f
  1.7514 +
  1.7515 +changeset:   0:0c957785065f
  1.7516 +tag:         v1.0
  1.7517 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7518 +date:        Sun Aug 16 14:05:15 2009 +0000
  1.7519 +summary:     Initial commit
  1.7520 +
  1.7521 +</screen>
  1.7522 +<!-- END tag.log -->
  1.7523 +
  1.7524 +
  1.7525 +    <para id="x_376">Any time you need to provide a revision ID to a Mercurial
  1.7526 +      command, the command will accept a tag name in its place.
  1.7527 +      Internally, Mercurial will translate your tag name into the
  1.7528 +      corresponding revision ID, then use that.</para>
  1.7529 +
  1.7530 +    <!-- BEGIN tag.log.v1.0 -->
  1.7531 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo goodbye &gt; myfile2</userinput>
  1.7532 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Second commit'</userinput>
  1.7533 +adding myfile2
  1.7534 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r v1.0</userinput>
  1.7535 +changeset:   0:0c957785065f
  1.7536 +tag:         v1.0
  1.7537 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7538 +date:        Sun Aug 16 14:05:15 2009 +0000
  1.7539 +summary:     Initial commit
  1.7540 +
  1.7541 +</screen>
  1.7542 +<!-- END tag.log.v1.0 -->
  1.7543 +
  1.7544 +
  1.7545 +    <para id="x_377">There's no limit on the number of tags you can have in a
  1.7546 +      repository, or on the number of tags that a single revision can
  1.7547 +      have.  As a practical matter, it's not a great idea to have
  1.7548 +      <quote>too many</quote> (a number which will vary from project
  1.7549 +      to project), simply because tags are supposed to help you to
  1.7550 +      find revisions.  If you have lots of tags, the ease of using
  1.7551 +      them to identify revisions diminishes rapidly.</para>
  1.7552 +
  1.7553 +    <para id="x_378">For example, if your project has milestones as frequent as
  1.7554 +      every few days, it's perfectly reasonable to tag each one of
  1.7555 +      those.  But if you have a continuous build system that makes
  1.7556 +      sure every revision can be built cleanly, you'd be introducing a
  1.7557 +      lot of noise if you were to tag every clean build.  Instead, you
  1.7558 +      could tag failed builds (on the assumption that they're rare!),
  1.7559 +      or simply not use tags to track buildability.</para>
  1.7560 +
  1.7561 +    <para id="x_379">If you want to remove a tag that you no longer want, use
  1.7562 +      <command role="hg-cmd" moreinfo="none">hg tag --remove</command>.</para>
  1.7563 +
  1.7564 +    <!-- BEGIN tag.remove -->
  1.7565 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag --remove v1.0</userinput>
  1.7566 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  1.7567 +tip                                3:0f446f1d1f7f
  1.7568 +</screen>
  1.7569 +<!-- END tag.remove -->
  1.7570 +
  1.7571 +
  1.7572 +    <para id="x_37a">You can also modify a tag at any time, so that it identifies
  1.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
  1.7574 +      <option role="hg-opt-tag">-f</option> option to tell Mercurial
  1.7575 +      that you <emphasis>really</emphasis> want to update the
  1.7576 +      tag.</para>
  1.7577 +
  1.7578 +    <!-- BEGIN tag.replace -->
  1.7579 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag -r 1 v1.1</userinput>
  1.7580 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  1.7581 +tip                                4:12fc7bf92915
  1.7582 +v1.1                               1:f283c2669b38
  1.7583 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag -r 2 v1.1</userinput>
  1.7584 +abort: tag 'v1.1' already exists (use -f to force)
  1.7585 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag -f -r 2 v1.1</userinput>
  1.7586 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tags</userinput>
  1.7587 +tip                                5:17e25cf010af
  1.7588 +v1.1                               2:737882b3cc76
  1.7589 +</screen>
  1.7590 +<!-- END tag.replace -->
  1.7591 +
  1.7592 +
  1.7593 +    <para id="x_37b">There will still be a permanent record of the previous
  1.7594 +      identity of the tag, but Mercurial will no longer use it.
  1.7595 +      There's thus no penalty to tagging the wrong revision; all you
  1.7596 +      have to do is turn around and tag the correct revision once you
  1.7597 +      discover your error.</para>
  1.7598 +
  1.7599 +    <para id="x_37c">Mercurial stores tags in a normal revision-controlled file
  1.7600 +      in your repository.  If you've created any tags, you'll find
  1.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
  1.7602 +      this file, then automatically commits the change to it.  This
  1.7603 +      means that every time you run <command role="hg-cmd" moreinfo="none">hg
  1.7604 +	tag</command>, you'll see a corresponding changeset in the
  1.7605 +      output of <command role="hg-cmd" moreinfo="none">hg log</command>.</para>
  1.7606 +
  1.7607 +    <!-- BEGIN tag.tip -->
  1.7608 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.7609 +changeset:   5:17e25cf010af
  1.7610 +tag:         tip
  1.7611 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7612 +date:        Sun Aug 16 14:05:16 2009 +0000
  1.7613 +summary:     Added tag v1.1 for changeset 737882b3cc76
  1.7614 +
  1.7615 +</screen>
  1.7616 +<!-- END tag.tip -->
  1.7617 +
  1.7618 +
  1.7619 +    <sect2>
  1.7620 +      <title>Handling tag conflicts during a merge</title>
  1.7621 +
  1.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
  1.7623 +	makes its presence known during a merge.  The format of the
  1.7624 +	file is simple: it consists of a series of lines.  Each line
  1.7625 +	starts with a changeset hash, followed by a space, followed by
  1.7626 +	the name of a tag.</para>
  1.7627 +
  1.7628 +      <para id="x_37e">If you're resolving a conflict in the <filename role="special" moreinfo="none">.hgtags</filename> file during a merge,
  1.7629 +	there's one twist to modifying the <filename role="special" moreinfo="none">.hgtags</filename> file: when Mercurial is
  1.7630 +	parsing the tags in a repository, it
  1.7631 +	<emphasis>never</emphasis> reads the working copy of the
  1.7632 +	<filename role="special" moreinfo="none">.hgtags</filename> file.  Instead, it
  1.7633 +	reads the <emphasis>most recently committed</emphasis>
  1.7634 +	revision of the file.</para>
  1.7635 +
  1.7636 +      <para id="x_37f">An unfortunate consequence of this design is that you
  1.7637 +	can't actually verify that your merged <filename role="special" moreinfo="none">.hgtags</filename> file is correct until
  1.7638 +	<emphasis>after</emphasis> you've committed a change.  So if
  1.7639 +	you find yourself resolving a conflict on <filename role="special" moreinfo="none">.hgtags</filename> during a merge, be sure to
  1.7640 +	run <command role="hg-cmd" moreinfo="none">hg tags</command> after you commit.
  1.7641 +	If it finds an error in the <filename role="special" moreinfo="none">.hgtags</filename> file, it will report the
  1.7642 +	location of the error, which you can then fix and commit.  You
  1.7643 +	should then run <command role="hg-cmd" moreinfo="none">hg tags</command>
  1.7644 +	again, just to be sure that your fix is correct.</para>
  1.7645 +    </sect2>
  1.7646 +
  1.7647 +    <sect2>
  1.7648 +      <title>Tags and cloning</title>
  1.7649 +
  1.7650 +      <para id="x_380">You may have noticed that the <command role="hg-cmd" moreinfo="none">hg
  1.7651 +	  clone</command> command has a <option role="hg-opt-clone">-r</option> option that lets you clone
  1.7652 +	an exact copy of the repository as of a particular changeset.
  1.7653 +	The new clone will not contain any project history that comes
  1.7654 +	after the revision you specified.  This has an interaction
  1.7655 +	with tags that can surprise the unwary.</para>
  1.7656 +
  1.7657 +      <para id="x_381">Recall that a tag is stored as a revision to
  1.7658 +	the <filename role="special" moreinfo="none">.hgtags</filename> file. When you
  1.7659 +	create a tag, the changeset in which its recorded refers to an
  1.7660 +	older changeset.  When you run <command role="hg-cmd" moreinfo="none">hg clone
  1.7661 +	  -r foo</command> to clone a repository as of tag
  1.7662 +	<literal moreinfo="none">foo</literal>, the new clone <emphasis>will not
  1.7663 +	  contain any revision newer than the one the tag refers to,
  1.7664 +	  including the revision where the tag was created</emphasis>.
  1.7665 +	The result is that you'll get exactly the right subset of the
  1.7666 +	project's history in the new repository, but
  1.7667 +	<emphasis>not</emphasis> the tag you might have
  1.7668 +	expected.</para>
  1.7669 +    </sect2>
  1.7670 +
  1.7671 +    <sect2>
  1.7672 +      <title>When permanent tags are too much</title>
  1.7673 +
  1.7674 +      <para id="x_382">Since Mercurial's tags are revision controlled and carried
  1.7675 +	around with a project's history, everyone you work with will
  1.7676 +	see the tags you create.  But giving names to revisions has
  1.7677 +	uses beyond simply noting that revision
  1.7678 +	<literal moreinfo="none">4237e45506ee</literal> is really
  1.7679 +	<literal moreinfo="none">v2.0.2</literal>.  If you're trying to track down a
  1.7680 +	subtle bug, you might want a tag to remind you of something
  1.7681 +	like <quote>Anne saw the symptoms with this
  1.7682 +	  revision</quote>.</para>
  1.7683 +
  1.7684 +      <para id="x_383">For cases like this, what you might want to use are
  1.7685 +	<emphasis>local</emphasis> tags. You can create a local tag
  1.7686 +	with the <option role="hg-opt-tag">-l</option> option to the
  1.7687 +	<command role="hg-cmd" moreinfo="none">hg tag</command> command.  This will
  1.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
  1.7689 +	controlled.  Any tags you create using <option role="hg-opt-tag">-l</option> remain strictly local to the
  1.7690 +	repository you're currently working in.</para>
  1.7691 +    </sect2>
  1.7692 +  </sect1>
  1.7693 +
  1.7694 +  <sect1>
  1.7695 +    <title>The flow of changes—big picture vs. little</title>
  1.7696 +
  1.7697 +    <para id="x_384">To return to the outline I sketched at the
  1.7698 +      beginning of the chapter, let's think about a project that has
  1.7699 +      multiple concurrent pieces of work under development at
  1.7700 +      once.</para>
  1.7701 +
  1.7702 +    <para id="x_385">There might be a push for a new <quote>main</quote> release;
  1.7703 +      a new minor bugfix release to the last main release; and an
  1.7704 +      unexpected <quote>hot fix</quote> to an old release that is now
  1.7705 +      in maintenance mode.</para>
  1.7706 +
  1.7707 +    <para id="x_386">The usual way people refer to these different concurrent
  1.7708 +      directions of development is as <quote>branches</quote>.
  1.7709 +      However, we've already seen numerous times that Mercurial treats
  1.7710 +      <emphasis>all of history</emphasis> as a series of branches and
  1.7711 +      merges.  Really, what we have here is two ideas that are
  1.7712 +      peripherally related, but which happen to share a name.</para>
  1.7713 +    <itemizedlist>
  1.7714 +      <listitem><para id="x_387"><quote>Big picture</quote> branches represent
  1.7715 +	  the sweep of a project's evolution; people give them names,
  1.7716 +	  and talk about them in conversation.</para>
  1.7717 +      </listitem>
  1.7718 +      <listitem><para id="x_388"><quote>Little picture</quote> branches are
  1.7719 +	  artefacts of the day-to-day activity of developing and
  1.7720 +	  merging changes.  They expose the narrative of how the code
  1.7721 +	  was developed.</para>
  1.7722 +      </listitem></itemizedlist>
  1.7723 +  </sect1>
  1.7724 +
  1.7725 +  <sect1>
  1.7726 +    <title>Managing big-picture branches in repositories</title>
  1.7727 +
  1.7728 +    <para id="x_389">The easiest way to isolate a <quote>big picture</quote>
  1.7729 +      branch in Mercurial is in a dedicated repository.  If you have
  1.7730 +      an existing shared repository—let's call it
  1.7731 +      <literal moreinfo="none">myproject</literal>—that reaches a
  1.7732 +      <quote>1.0</quote> milestone, you can start to prepare for
  1.7733 +      future maintenance releases on top of version 1.0 by tagging the
  1.7734 +      revision from which you prepared the 1.0 release.</para>
  1.7735 +
  1.7736 +    <!-- BEGIN branch-repo.tag -->
  1.7737 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myproject</userinput>
  1.7738 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tag v1.0</userinput>
  1.7739 +</screen>
  1.7740 +<!-- END branch-repo.tag -->
  1.7741 +
  1.7742 +
  1.7743 +    <para id="x_38a">You can then clone a new shared
  1.7744 +      <literal moreinfo="none">myproject-1.0.1</literal> repository as of that
  1.7745 +      tag.</para>
  1.7746 +
  1.7747 +    <!-- BEGIN branch-repo.clone -->
  1.7748 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.7749 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject myproject-1.0.1</userinput>
  1.7750 +updating working directory
  1.7751 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.7752 +</screen>
  1.7753 +<!-- END branch-repo.clone -->
  1.7754 +
  1.7755 +
  1.7756 +    <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought
  1.7757 +      to go into an upcoming 1.0.1 minor release, they clone the
  1.7758 +      <literal moreinfo="none">myproject-1.0.1</literal> repository, make their
  1.7759 +      changes, and push them back.</para>
  1.7760 +
  1.7761 +    <!-- BEGIN branch-repo.bugfix -->
  1.7762 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject-1.0.1 my-1.0.1-bugfix</userinput>
  1.7763 +updating working directory
  1.7764 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.7765 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-1.0.1-bugfix</userinput>
  1.7766 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'I fixed a bug using only echo!' &gt;&gt; myfile</userinput>
  1.7767 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Important fix for 1.0.1'</userinput>
  1.7768 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  1.7769 +pushing to /tmp/branch-repo3rVLLS/myproject-1.0.1
  1.7770 +searching for changes
  1.7771 +adding changesets
  1.7772 +adding manifests
  1.7773 +adding file changes
  1.7774 +added 1 changesets with 1 changes to 1 files
  1.7775 +</screen>
  1.7776 +<!-- END branch-repo.bugfix -->
  1.7777 +
  1.7778 +
  1.7779 +    <para id="x_38c">Meanwhile, development for
  1.7780 +      the next major release can continue, isolated and unabated, in
  1.7781 +      the <literal moreinfo="none">myproject</literal> repository.</para>
  1.7782 +
  1.7783 +    <!-- BEGIN branch-repo.new -->
  1.7784 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.7785 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject my-feature</userinput>
  1.7786 +updating working directory
  1.7787 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.7788 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd my-feature</userinput>
  1.7789 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'This sure is an exciting new feature!' &gt; mynewfile</userinput>
  1.7790 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'New feature'</userinput>
  1.7791 +adding mynewfile
  1.7792 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  1.7793 +pushing to /tmp/branch-repo3rVLLS/myproject
  1.7794 +searching for changes
  1.7795 +adding changesets
  1.7796 +adding manifests
  1.7797 +adding file changes
  1.7798 +added 1 changesets with 1 changes to 1 files
  1.7799 +</screen>
  1.7800 +<!-- END branch-repo.new -->
  1.7801 +
  1.7802 +  </sect1>
  1.7803 +
  1.7804 +  <sect1>
  1.7805 +    <title>Don't repeat yourself: merging across branches</title>
  1.7806 +
  1.7807 +    <para id="x_38d">In many cases, if you have a bug to fix on a maintenance
  1.7808 +      branch, the chances are good that the bug exists on your
  1.7809 +      project's main branch (and possibly other maintenance branches,
  1.7810 +      too).  It's a rare developer who wants to fix the same bug
  1.7811 +      multiple times, so let's look at a few ways that Mercurial can
  1.7812 +      help you to manage these bugfixes without duplicating your
  1.7813 +      work.</para>
  1.7814 +
  1.7815 +    <para id="x_38e">In the simplest instance, all you need to do is pull changes
  1.7816 +      from your maintenance branch into your local clone of the target
  1.7817 +      branch.</para>
  1.7818 +
  1.7819 +    <!-- BEGIN branch-repo.pull -->
  1.7820 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.7821 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone myproject myproject-merge</userinput>
  1.7822 +updating working directory
  1.7823 +3 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.7824 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myproject-merge</userinput>
  1.7825 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../myproject-1.0.1</userinput>
  1.7826 +pulling from ../myproject-1.0.1
  1.7827 +searching for changes
  1.7828 +adding changesets
  1.7829 +adding manifests
  1.7830 +adding file changes
  1.7831 +added 1 changesets with 1 changes to 1 files (+1 heads)
  1.7832 +(run 'hg heads' to see heads, 'hg merge' to merge)
  1.7833 +</screen>
  1.7834 +<!-- END branch-repo.pull -->
  1.7835 +
  1.7836 +
  1.7837 +    <para id="x_38f">You'll then need to merge the heads of the two branches, and
  1.7838 +      push back to the main branch.</para>
  1.7839 +
  1.7840 +    <!-- BEGIN branch-repo.merge -->
  1.7841 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.7842 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.7843 +(branch merge, don't forget to commit)
  1.7844 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Merge bugfix from 1.0.1 branch'</userinput>
  1.7845 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg push</userinput>
  1.7846 +pushing to /tmp/branch-repo3rVLLS/myproject
  1.7847 +searching for changes
  1.7848 +adding changesets
  1.7849 +adding manifests
  1.7850 +adding file changes
  1.7851 +added 2 changesets with 1 changes to 1 files
  1.7852 +</screen>
  1.7853 +<!-- END branch-repo.merge -->
  1.7854 +
  1.7855 +  </sect1>
  1.7856 +
  1.7857 +  <sect1>
  1.7858 +    <title>Naming branches within one repository</title>
  1.7859 +
  1.7860 +    <para id="x_390">In most instances, isolating branches in repositories is the
  1.7861 +      right approach.  Its simplicity makes it easy to understand; and
  1.7862 +      so it's hard to make mistakes.  There's a one-to-one
  1.7863 +      relationship between branches you're working in and directories
  1.7864 +      on your system.  This lets you use normal (non-Mercurial-aware)
  1.7865 +      tools to work on files within a branch/repository.</para>
  1.7866 +
  1.7867 +    <para id="x_391">If you're more in the <quote>power user</quote> category
  1.7868 +      (<emphasis>and</emphasis> your collaborators are too), there is
  1.7869 +      an alternative way of handling branches that you can consider.
  1.7870 +      I've already mentioned the human-level distinction between
  1.7871 +      <quote>small picture</quote> and <quote>big picture</quote>
  1.7872 +      branches.  While Mercurial works with multiple <quote>small
  1.7873 +	picture</quote> branches in a repository all the time (for
  1.7874 +      example after you pull changes in, but before you merge them),
  1.7875 +      it can <emphasis>also</emphasis> work with multiple <quote>big
  1.7876 +	picture</quote> branches.</para>
  1.7877 +
  1.7878 +    <para id="x_392">The key to working this way is that Mercurial lets you
  1.7879 +      assign a persistent <emphasis>name</emphasis> to a branch.
  1.7880 +      There always exists a branch named <literal moreinfo="none">default</literal>.
  1.7881 +      Even before you start naming branches yourself, you can find
  1.7882 +      traces of the <literal moreinfo="none">default</literal> branch if you look for
  1.7883 +      them.</para>
  1.7884 +
  1.7885 +    <para id="x_393">As an example, when you run the <command role="hg-cmd" moreinfo="none">hg
  1.7886 +	commit</command> command, and it pops up your editor so that
  1.7887 +      you can enter a commit message, look for a line that contains
  1.7888 +      the text <quote><literal moreinfo="none">HG: branch default</literal></quote> at
  1.7889 +      the bottom. This is telling you that your commit will occur on
  1.7890 +      the branch named <literal moreinfo="none">default</literal>.</para>
  1.7891 +
  1.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
  1.7893 +      lists the named branches already present in your repository,
  1.7894 +      telling you which changeset is the tip of each.</para>
  1.7895 +
  1.7896 +    <!-- BEGIN branch-named.branches -->
  1.7897 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.7898 +changeset:   0:90897f9e54e3
  1.7899 +tag:         tip
  1.7900 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7901 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.7902 +summary:     Initial commit
  1.7903 +
  1.7904 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branches</userinput>
  1.7905 +default                        0:90897f9e54e3
  1.7906 +</screen>
  1.7907 +<!-- END branch-named.branches -->
  1.7908 +
  1.7909 +
  1.7910 +    <para id="x_395">Since you haven't created any named branches yet, the only
  1.7911 +      one that exists is <literal moreinfo="none">default</literal>.</para>
  1.7912 +
  1.7913 +    <para id="x_396">To find out what the <quote>current</quote> branch is, run
  1.7914 +      the <command role="hg-cmd" moreinfo="none">hg branch</command> command, giving
  1.7915 +      it no arguments.  This tells you what branch the parent of the
  1.7916 +      current changeset is on.</para>
  1.7917 +
  1.7918 +    <!-- BEGIN branch-named.branch -->
  1.7919 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  1.7920 +default
  1.7921 +</screen>
  1.7922 +<!-- END branch-named.branch -->
  1.7923 +
  1.7924 +
  1.7925 +    <para id="x_397">To create a new branch, run the <command role="hg-cmd" moreinfo="none">hg
  1.7926 +	branch</command> command again.  This time, give it one
  1.7927 +      argument: the name of the branch you want to create.</para>
  1.7928 +
  1.7929 +    <!-- BEGIN branch-named.create -->
  1.7930 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch foo</userinput>
  1.7931 +marked working directory as branch foo
  1.7932 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  1.7933 +foo
  1.7934 +</screen>
  1.7935 +<!-- END branch-named.create -->
  1.7936 +
  1.7937 +
  1.7938 +    <para id="x_398">After you've created a branch, you might wonder what effect
  1.7939 +      the <command role="hg-cmd" moreinfo="none">hg branch</command> command has had.
  1.7940 +      What do the <command role="hg-cmd" moreinfo="none">hg status</command> and
  1.7941 +      <command role="hg-cmd" moreinfo="none">hg tip</command> commands report?</para>
  1.7942 +
  1.7943 +    <!-- BEGIN branch-named.status -->
  1.7944 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.7945 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.7946 +changeset:   0:90897f9e54e3
  1.7947 +tag:         tip
  1.7948 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7949 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.7950 +summary:     Initial commit
  1.7951 +
  1.7952 +</screen>
  1.7953 +<!-- END branch-named.status -->
  1.7954 +
  1.7955 +
  1.7956 +    <para id="x_399">Nothing has changed in the
  1.7957 +      working directory, and there's been no new history created.  As
  1.7958 +      this suggests, running the <command role="hg-cmd" moreinfo="none">hg
  1.7959 +	branch</command> command has no permanent effect; it only
  1.7960 +      tells Mercurial what branch name to use the
  1.7961 +      <emphasis>next</emphasis> time you commit a changeset.</para>
  1.7962 +
  1.7963 +    <para id="x_39a">When you commit a change, Mercurial records the name of the
  1.7964 +      branch on which you committed.  Once you've switched from the
  1.7965 +      <literal moreinfo="none">default</literal> branch to another and committed,
  1.7966 +      you'll see the name of the new branch show up in the output of
  1.7967 +      <command role="hg-cmd" moreinfo="none">hg log</command>, <command role="hg-cmd" moreinfo="none">hg tip</command>, and other commands that
  1.7968 +      display the same kind of output.</para>
  1.7969 +
  1.7970 +    <!-- BEGIN branch-named.commit -->
  1.7971 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'hello again' &gt;&gt; myfile</userinput>
  1.7972 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Second commit'</userinput>
  1.7973 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.7974 +changeset:   1:5656f8ffdd49
  1.7975 +branch:      foo
  1.7976 +tag:         tip
  1.7977 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.7978 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.7979 +summary:     Second commit
  1.7980 +
  1.7981 +</screen>
  1.7982 +<!-- END branch-named.commit -->
  1.7983 +
  1.7984 +
  1.7985 +    <para id="x_39b">The <command role="hg-cmd" moreinfo="none">hg log</command>-like commands
  1.7986 +      will print the branch name of every changeset that's not on the
  1.7987 +      <literal moreinfo="none">default</literal> branch.  As a result, if you never
  1.7988 +      use named branches, you'll never see this information.</para>
  1.7989 +
  1.7990 +    <para id="x_39c">Once you've named a branch and committed a change with that
  1.7991 +      name, every subsequent commit that descends from that change
  1.7992 +      will inherit the same branch name.  You can change the name of a
  1.7993 +      branch at any time, using the <command role="hg-cmd" moreinfo="none">hg
  1.7994 +	branch</command> command.</para>
  1.7995 +
  1.7996 +    <!-- BEGIN branch-named.rebranch -->
  1.7997 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  1.7998 +foo
  1.7999 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch bar</userinput>
  1.8000 +marked working directory as branch bar
  1.8001 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo new file &gt; newfile</userinput>
  1.8002 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'Third commit'</userinput>
  1.8003 +adding newfile
  1.8004 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.8005 +changeset:   2:c59d680fc2ec
  1.8006 +branch:      bar
  1.8007 +tag:         tip
  1.8008 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8009 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.8010 +summary:     Third commit
  1.8011 +
  1.8012 +</screen>
  1.8013 +<!-- END branch-named.rebranch -->
  1.8014 +
  1.8015 +
  1.8016 +    <para id="x_39d">In practice, this is something you won't do very often, as
  1.8017 +      branch names tend to have fairly long lifetimes.  (This isn't a
  1.8018 +      rule, just an observation.)</para>
  1.8019 +  </sect1>
  1.8020 +
  1.8021 +  <sect1>
  1.8022 +    <title>Dealing with multiple named branches in a
  1.8023 +      repository</title>
  1.8024 +
  1.8025 +    <para id="x_39e">If you have more than one named branch in a repository,
  1.8026 +      Mercurial will remember the branch that your working directory
  1.8027 +      is on when you start a command like <command role="hg-cmd" moreinfo="none">hg
  1.8028 +	update</command> or <command role="hg-cmd" moreinfo="none">hg pull
  1.8029 +	-u</command>.  It will update the working directory to the tip
  1.8030 +      of this branch, no matter what the <quote>repo-wide</quote> tip
  1.8031 +      is.  To update to a revision that's on a different named branch,
  1.8032 +      you may need to use the <option role="hg-opt-update">-C</option>
  1.8033 +      option to <command role="hg-cmd" moreinfo="none">hg update</command>.</para>
  1.8034 +
  1.8035 +    <para id="x_39f">This behavior is a little subtle, so let's see it in
  1.8036 +      action.  First, let's remind ourselves what branch we're
  1.8037 +      currently on, and what branches are in our repository.</para>
  1.8038 +
  1.8039 +    <!-- BEGIN branch-named.parents -->
  1.8040 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.8041 +changeset:   2:c59d680fc2ec
  1.8042 +branch:      bar
  1.8043 +tag:         tip
  1.8044 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8045 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.8046 +summary:     Third commit
  1.8047 +
  1.8048 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branches</userinput>
  1.8049 +bar                            2:c59d680fc2ec
  1.8050 +foo                            1:5656f8ffdd49 (inactive)
  1.8051 +default                        0:90897f9e54e3 (inactive)
  1.8052 +</screen>
  1.8053 +<!-- END branch-named.parents -->
  1.8054 +
  1.8055 +
  1.8056 +    <para id="x_3a0">We're on the <literal moreinfo="none">bar</literal> branch, but there also
  1.8057 +      exists an older <command role="hg-cmd" moreinfo="none">hg foo</command>
  1.8058 +      branch.</para>
  1.8059 +
  1.8060 +    <para id="x_3a1">We can <command role="hg-cmd" moreinfo="none">hg update</command> back and
  1.8061 +      forth between the tips of the <literal moreinfo="none">foo</literal> and
  1.8062 +      <literal moreinfo="none">bar</literal> branches without needing to use the
  1.8063 +      <option role="hg-opt-update">-C</option> option, because this
  1.8064 +      only involves going backwards and forwards linearly through our
  1.8065 +      change history.</para>
  1.8066 +
  1.8067 +    <!-- BEGIN branch-named.update-switchy -->
  1.8068 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update foo</userinput>
  1.8069 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  1.8070 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.8071 +changeset:   1:5656f8ffdd49
  1.8072 +branch:      foo
  1.8073 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8074 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.8075 +summary:     Second commit
  1.8076 +
  1.8077 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update bar</userinput>
  1.8078 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.8079 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.8080 +changeset:   2:c59d680fc2ec
  1.8081 +branch:      bar
  1.8082 +tag:         tip
  1.8083 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8084 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.8085 +summary:     Third commit
  1.8086 +
  1.8087 +</screen>
  1.8088 +<!-- END branch-named.update-switchy -->
  1.8089 +
  1.8090 +
  1.8091 +    <para id="x_3a2">If we go back to the <literal moreinfo="none">foo</literal> branch and then
  1.8092 +      run <command role="hg-cmd" moreinfo="none">hg update</command>, it will keep us
  1.8093 +      on <literal moreinfo="none">foo</literal>, not move us to the tip of
  1.8094 +      <literal moreinfo="none">bar</literal>.</para>
  1.8095 +
  1.8096 +    <!-- BEGIN branch-named.update-nothing -->
  1.8097 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update foo</userinput>
  1.8098 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  1.8099 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg update</userinput>
  1.8100 +0 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.8101 +</screen>
  1.8102 +<!-- END branch-named.update-nothing -->
  1.8103 +
  1.8104 +
  1.8105 +    <para id="x_3a3">Committing a new change on the <literal moreinfo="none">foo</literal> branch
  1.8106 +      introduces a new head.</para>
  1.8107 +
  1.8108 +    <!-- BEGIN branch-named.foo-commit -->
  1.8109 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo something &gt; somefile</userinput>
  1.8110 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'New file'</userinput>
  1.8111 +adding somefile
  1.8112 +created new head
  1.8113 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  1.8114 +changeset:   3:4dd2f7a37288
  1.8115 +branch:      foo
  1.8116 +tag:         tip
  1.8117 +parent:      1:5656f8ffdd49
  1.8118 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8119 +date:        Sun Aug 16 14:04:43 2009 +0000
  1.8120 +summary:     New file
  1.8121 +
  1.8122 +changeset:   2:c59d680fc2ec
  1.8123 +branch:      bar
  1.8124 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8125 +date:        Sun Aug 16 14:04:42 2009 +0000
  1.8126 +summary:     Third commit
  1.8127 +
  1.8128 +</screen>
  1.8129 +<!-- END branch-named.foo-commit -->
  1.8130 +
  1.8131 +  </sect1>
  1.8132 +
  1.8133 +  <sect1>
  1.8134 +    <title>Branch names and merging</title>
  1.8135 +
  1.8136 +    <para id="x_3a4">As you've probably noticed, merges in Mercurial are not
  1.8137 +      symmetrical. Let's say our repository has two heads, 17 and 23.
  1.8138 +      If I <command role="hg-cmd" moreinfo="none">hg update</command> to 17 and then
  1.8139 +      <command role="hg-cmd" moreinfo="none">hg merge</command> with 23, Mercurial
  1.8140 +      records 17 as the first parent of the merge, and 23 as the
  1.8141 +      second.  Whereas if I <command role="hg-cmd" moreinfo="none">hg update</command>
  1.8142 +      to 23 and then <command role="hg-cmd" moreinfo="none">hg merge</command> with
  1.8143 +      17, it records 23 as the first parent, and 17 as the
  1.8144 +      second.</para>
  1.8145 +
  1.8146 +    <para id="x_3a5">This affects Mercurial's choice of branch name when you
  1.8147 +      merge.  After a merge, Mercurial will retain the branch name of
  1.8148 +      the first parent when you commit the result of the merge.  If
  1.8149 +      your first parent's branch name is <literal moreinfo="none">foo</literal>, and
  1.8150 +      you merge with <literal moreinfo="none">bar</literal>, the branch name will
  1.8151 +      still be <literal moreinfo="none">foo</literal> after you merge.</para>
  1.8152 +
  1.8153 +    <para id="x_3a6">It's not unusual for a repository to contain multiple heads,
  1.8154 +      each with the same branch name.  Let's say I'm working on the
  1.8155 +      <literal moreinfo="none">foo</literal> branch, and so are you.  We commit
  1.8156 +      different changes; I pull your changes; I now have two heads,
  1.8157 +      each claiming to be on the <literal moreinfo="none">foo</literal> branch.  The
  1.8158 +      result of a merge will be a single head on the
  1.8159 +      <literal moreinfo="none">foo</literal> branch, as you might hope.</para>
  1.8160 +
  1.8161 +    <para id="x_3a7">But if I'm working on the <literal moreinfo="none">bar</literal> branch, and
  1.8162 +      I merge work from the <literal moreinfo="none">foo</literal> branch, the result
  1.8163 +      will remain on the <literal moreinfo="none">bar</literal> branch.</para>
  1.8164 +
  1.8165 +    <!-- BEGIN branch-named.merge -->
  1.8166 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg branch</userinput>
  1.8167 +bar
  1.8168 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge foo</userinput>
  1.8169 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.8170 +(branch merge, don't forget to commit)
  1.8171 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Merge'</userinput>
  1.8172 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.8173 +changeset:   4:9f05d4ef3efe
  1.8174 +branch:      bar
  1.8175 +tag:         tip
  1.8176 +parent:      2:c59d680fc2ec
  1.8177 +parent:      3:4dd2f7a37288
  1.8178 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8179 +date:        Sun Aug 16 14:04:44 2009 +0000
  1.8180 +summary:     Merge
  1.8181 +
  1.8182 +</screen>
  1.8183 +<!-- END branch-named.merge -->
  1.8184 +
  1.8185 +
  1.8186 +    <para id="x_3a8">To give a more concrete example, if I'm working on the
  1.8187 +      <literal moreinfo="none">bleeding-edge</literal> branch, and I want to bring in
  1.8188 +      the latest fixes from the <literal moreinfo="none">stable</literal> branch,
  1.8189 +      Mercurial will choose the <quote>right</quote>
  1.8190 +      (<literal moreinfo="none">bleeding-edge</literal>) branch name when I pull and
  1.8191 +      merge from <literal moreinfo="none">stable</literal>.</para>
  1.8192 +  </sect1>
  1.8193 +
  1.8194 +  <sect1>
  1.8195 +    <title>Branch naming is generally useful</title>
  1.8196 +
  1.8197 +    <para id="x_3a9">You shouldn't think of named branches as applicable only to
  1.8198 +      situations where you have multiple long-lived branches
  1.8199 +      cohabiting in a single repository.  They're very useful even in
  1.8200 +      the one-branch-per-repository case.</para>
  1.8201 +
  1.8202 +    <para id="x_3aa">In the simplest case, giving a name to each branch gives you
  1.8203 +      a permanent record of which branch a changeset originated on.
  1.8204 +      This gives you more context when you're trying to follow the
  1.8205 +      history of a long-lived branchy project.</para>
  1.8206 +
  1.8207 +    <para id="x_3ab">If you're working with shared repositories, you can set up a
  1.8208 +      <literal role="hook" moreinfo="none">pretxnchangegroup</literal> hook on each
  1.8209 +      that will block incoming changes that have the
  1.8210 +      <quote>wrong</quote> branch name.  This provides a simple, but
  1.8211 +      effective, defence against people accidentally pushing changes
  1.8212 +      from a <quote>bleeding edge</quote> branch to a
  1.8213 +      <quote>stable</quote> branch.  Such a hook might look like this
  1.8214 +      inside the shared repo's <filename role="special" moreinfo="none">
  1.8215 +	/.hgrc</filename>.</para>
  1.8216 +    <programlisting format="linespecific">[hooks]
  1.8217 +pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
  1.8218 +  </sect1>
  1.8219 +</chapter>
  1.8220 +
  1.8221 +<!--
  1.8222 +local variables: 
  1.8223 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.8224 +end:
  1.8225 +-->
  1.8226 +
  1.8227 +  <!-- BEGIN ch09 -->
  1.8228 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.8229 +
  1.8230 +<chapter id="chap:undo">
  1.8231 +  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
  1.8232 +  <title>Finding and fixing mistakes</title>
  1.8233 +
  1.8234 +  <para id="x_d2">To err might be human, but to really handle the consequences
  1.8235 +    well takes a top-notch revision control system.  In this chapter,
  1.8236 +    we'll discuss some of the techniques you can use when you find
  1.8237 +    that a problem has crept into your project.  Mercurial has some
  1.8238 +    highly capable features that will help you to isolate the sources
  1.8239 +    of problems, and to handle them appropriately.</para>
  1.8240 +
  1.8241 +  <sect1>
  1.8242 +    <title>Erasing local history</title>
  1.8243 +
  1.8244 +    <sect2>
  1.8245 +      <title>The accidental commit</title>
  1.8246 +
  1.8247 +      <para id="x_d3">I have the occasional but persistent problem of typing
  1.8248 +	rather more quickly than I can think, which sometimes results
  1.8249 +	in me committing a changeset that is either incomplete or
  1.8250 +	plain wrong.  In my case, the usual kind of incomplete
  1.8251 +	changeset is one in which I've created a new source file, but
  1.8252 +	forgotten to <command role="hg-cmd" moreinfo="none">hg add</command> it.  A
  1.8253 +	<quote>plain wrong</quote> changeset is not as common, but no
  1.8254 +	less annoying.</para>
  1.8255 +
  1.8256 +    </sect2>
  1.8257 +    <sect2 id="sec:undo:rollback">
  1.8258 +      <title>Rolling back a transaction</title>
  1.8259 +
  1.8260 +      <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I
  1.8261 +	mentioned that Mercurial treats each modification of a
  1.8262 +	repository as a <emphasis>transaction</emphasis>.  Every time
  1.8263 +	you commit a changeset or pull changes from another
  1.8264 +	repository, Mercurial remembers what you did.  You can undo,
  1.8265 +	or <emphasis>roll back</emphasis>, exactly one of these
  1.8266 +	actions using the <command role="hg-cmd" moreinfo="none">hg rollback</command>
  1.8267 +	command.  (See <xref linkend="sec:undo:rollback-after-push"/>
  1.8268 +	for an important caveat about the use of this command.)</para>
  1.8269 +
  1.8270 +      <para id="x_d5">Here's a mistake that I often find myself making:
  1.8271 +	committing a change in which I've created a new file, but
  1.8272 +	forgotten to <command role="hg-cmd" moreinfo="none">hg add</command>
  1.8273 +	it.</para>
  1.8274 +
  1.8275 +      <!-- BEGIN rollback.commit -->
  1.8276 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8277 +M a
  1.8278 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo b &gt; b</userinput>
  1.8279 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Add file b'</userinput>
  1.8280 +</screen>
  1.8281 +<!-- END rollback.commit -->
  1.8282 +
  1.8283 +
  1.8284 +      <para id="x_d6">Looking at the output of <command role="hg-cmd" moreinfo="none">hg
  1.8285 +	  status</command> after the commit immediately confirms the
  1.8286 +	error.</para>
  1.8287 +
  1.8288 +      <!-- BEGIN rollback.status -->
  1.8289 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8290 +? b
  1.8291 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.8292 +changeset:   1:246e2aada1c5
  1.8293 +tag:         tip
  1.8294 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8295 +date:        Sun Aug 16 14:05:14 2009 +0000
  1.8296 +summary:     Add file b
  1.8297 +
  1.8298 +</screen>
  1.8299 +<!-- END rollback.status -->
  1.8300 +
  1.8301 +
  1.8302 +      <para id="x_d7">The commit captured the changes to the file
  1.8303 +	<filename moreinfo="none">a</filename>, but not the new file
  1.8304 +	<filename moreinfo="none">b</filename>.  If I were to push this changeset to a
  1.8305 +	repository that I shared with a colleague, the chances are
  1.8306 +	high that something in <filename moreinfo="none">a</filename> would refer to
  1.8307 +	<filename moreinfo="none">b</filename>, which would not be present in their
  1.8308 +	repository when they pulled my changes.  I would thus become
  1.8309 +	the object of some indignation.</para>
  1.8310 +
  1.8311 +      <para id="x_d8">However, luck is with me—I've caught my error
  1.8312 +	before I pushed the changeset.  I use the <command role="hg-cmd" moreinfo="none">hg rollback</command> command, and Mercurial
  1.8313 +	makes that last changeset vanish.</para>
  1.8314 +
  1.8315 +      <!-- BEGIN rollback.rollback -->
  1.8316 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rollback</userinput>
  1.8317 +rolling back last transaction
  1.8318 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
  1.8319 +changeset:   0:c37ce4157509
  1.8320 +tag:         tip
  1.8321 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8322 +date:        Sun Aug 16 14:05:14 2009 +0000
  1.8323 +summary:     First commit
  1.8324 +
  1.8325 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8326 +M a
  1.8327 +? b
  1.8328 +</screen>
  1.8329 +<!-- END rollback.rollback -->
  1.8330 +
  1.8331 +
  1.8332 +      <para id="x_d9">Notice that the changeset is no longer present in the
  1.8333 +	repository's history, and the working directory once again
  1.8334 +	thinks that the file <filename moreinfo="none">a</filename> is modified.  The
  1.8335 +	commit and rollback have left the working directory exactly as
  1.8336 +	it was prior to the commit; the changeset has been completely
  1.8337 +	erased.  I can now safely <command role="hg-cmd" moreinfo="none">hg
  1.8338 +	  add</command> the file <filename moreinfo="none">b</filename>, and rerun my
  1.8339 +	commit.</para>
  1.8340 +
  1.8341 +      <!-- BEGIN rollback.add -->
  1.8342 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add b</userinput>
  1.8343 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'Add file b, this time for real'</userinput>
  1.8344 +</screen>
  1.8345 +<!-- END rollback.add -->
  1.8346 +
  1.8347 +
  1.8348 +    </sect2>
  1.8349 +    <sect2>
  1.8350 +      <title>The erroneous pull</title>
  1.8351 +
  1.8352 +      <para id="x_da">It's common practice with Mercurial to maintain separate
  1.8353 +	development branches of a project in different repositories.
  1.8354 +	Your development team might have one shared repository for
  1.8355 +	your project's <quote>0.9</quote> release, and another,
  1.8356 +	containing different changes, for the <quote>1.0</quote>
  1.8357 +	release.</para>
  1.8358 +
  1.8359 +      <para id="x_db">Given this, you can imagine that the consequences could be
  1.8360 +	messy if you had a local <quote>0.9</quote> repository, and
  1.8361 +	accidentally pulled changes from the shared <quote>1.0</quote>
  1.8362 +	repository into it.  At worst, you could be paying
  1.8363 +	insufficient attention, and push those changes into the shared
  1.8364 +	<quote>0.9</quote> tree, confusing your entire team (but don't
  1.8365 +	worry, we'll return to this horror scenario later).  However,
  1.8366 +	it's more likely that you'll notice immediately, because
  1.8367 +	Mercurial will display the URL it's pulling from, or you will
  1.8368 +	see it pull a suspiciously large number of changes into the
  1.8369 +	repository.</para>
  1.8370 +
  1.8371 +      <para id="x_dc">The <command role="hg-cmd" moreinfo="none">hg rollback</command> command
  1.8372 +	will work nicely to expunge all of the changesets that you
  1.8373 +	just pulled.  Mercurial groups all changes from one <command role="hg-cmd" moreinfo="none">hg pull</command> into a single transaction,
  1.8374 +	so one <command role="hg-cmd" moreinfo="none">hg rollback</command> is all you
  1.8375 +	need to undo this mistake.</para>
  1.8376 +
  1.8377 +    </sect2>
  1.8378 +    <sect2 id="sec:undo:rollback-after-push">
  1.8379 +      <title>Rolling back is useless once you've pushed</title>
  1.8380 +
  1.8381 +      <para id="x_dd">The value of the <command role="hg-cmd" moreinfo="none">hg
  1.8382 +	  rollback</command> command drops to zero once you've pushed
  1.8383 +	your changes to another repository.  Rolling back a change
  1.8384 +	makes it disappear entirely, but <emphasis>only</emphasis> in
  1.8385 +	the repository in which you perform the <command role="hg-cmd" moreinfo="none">hg rollback</command>.  Because a rollback
  1.8386 +	eliminates history, there's no way for the disappearance of a
  1.8387 +	change to propagate between repositories.</para>
  1.8388 +
  1.8389 +      <para id="x_de">If you've pushed a change to another
  1.8390 +	repository—particularly if it's a shared
  1.8391 +	repository—it has essentially <quote>escaped into the
  1.8392 +	  wild,</quote> and you'll have to recover from your mistake
  1.8393 +	in a different way.  If you push a changeset somewhere, then
  1.8394 +	roll it back, then pull from the repository you pushed to, the
  1.8395 +	changeset you thought you'd gotten rid of will simply reappear
  1.8396 +	in your repository.</para>
  1.8397 +
  1.8398 +      <para id="x_df">(If you absolutely know for sure that the change
  1.8399 +	you want to roll back is the most recent change in the
  1.8400 +	repository that you pushed to, <emphasis>and</emphasis> you
  1.8401 +	know that nobody else could have pulled it from that
  1.8402 +	repository, you can roll back the changeset there, too, but
  1.8403 +	you really should not expect this to work reliably.  Sooner or
  1.8404 +	later a change really will make it into a repository that you
  1.8405 +	don't directly control (or have forgotten about), and come
  1.8406 +	back to bite you.)</para>
  1.8407 +
  1.8408 +    </sect2>
  1.8409 +    <sect2>
  1.8410 +      <title>You can only roll back once</title>
  1.8411 +
  1.8412 +      <para id="x_e0">Mercurial stores exactly one transaction in its
  1.8413 +	transaction log; that transaction is the most recent one that
  1.8414 +	occurred in the repository. This means that you can only roll
  1.8415 +	back one transaction.  If you expect to be able to roll back
  1.8416 +	one transaction, then its predecessor, this is not the
  1.8417 +	behavior you will get.</para>
  1.8418 +
  1.8419 +      <!-- BEGIN rollback.twice -->
  1.8420 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rollback</userinput>
  1.8421 +rolling back last transaction
  1.8422 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg rollback</userinput>
  1.8423 +no rollback information available
  1.8424 +</screen>
  1.8425 +<!-- END rollback.twice -->
  1.8426 +
  1.8427 +
  1.8428 +      <para id="x_e1">Once you've rolled back one transaction in a repository,
  1.8429 +	you can't roll back again in that repository until you perform
  1.8430 +	another commit or pull.</para>
  1.8431 +
  1.8432 +    </sect2>
  1.8433 +  </sect1>
  1.8434 +  <sect1>
  1.8435 +    <title>Reverting the mistaken change</title>
  1.8436 +
  1.8437 +    <para id="x_e2">If you make a modification to a file, and decide that you
  1.8438 +      really didn't want to change the file at all, and you haven't
  1.8439 +      yet committed your changes, the <command role="hg-cmd" moreinfo="none">hg
  1.8440 +	revert</command> command is the one you'll need.  It looks at
  1.8441 +      the changeset that's the parent of the working directory, and
  1.8442 +      restores the contents of the file to their state as of that
  1.8443 +      changeset. (That's a long-winded way of saying that, in the
  1.8444 +      normal case, it undoes your modifications.)</para>
  1.8445 +
  1.8446 +    <para id="x_e3">Let's illustrate how the <command role="hg-cmd" moreinfo="none">hg
  1.8447 +	revert</command> command works with yet another small example.
  1.8448 +      We'll begin by modifying a file that Mercurial is already
  1.8449 +      tracking.</para>
  1.8450 +
  1.8451 +    <!-- BEGIN daily.revert.modify -->
  1.8452 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file</userinput>
  1.8453 +original content
  1.8454 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo unwanted change &gt;&gt; file</userinput>
  1.8455 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff file</userinput>
  1.8456 +diff -r 2eacf948d309 file
  1.8457 +--- a/file	Sun Aug 16 14:05:00 2009 +0000
  1.8458 ++++ b/file	Sun Aug 16 14:05:00 2009 +0000
  1.8459 +@@ -1,1 +1,2 @@
  1.8460 + original content
  1.8461 ++unwanted change
  1.8462 +</screen>
  1.8463 +<!-- END daily.revert.modify -->
  1.8464 +
  1.8465 +
  1.8466 +    <para id="x_e4">If we don't
  1.8467 +      want that change, we can simply <command role="hg-cmd" moreinfo="none">hg
  1.8468 +	revert</command> the file.</para>
  1.8469 +
  1.8470 +      <!-- BEGIN daily.revert.unmodify -->
  1.8471 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8472 +M file
  1.8473 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert file</userinput>
  1.8474 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file</userinput>
  1.8475 +original content
  1.8476 +</screen>
  1.8477 +<!-- END daily.revert.unmodify -->
  1.8478 +
  1.8479 +
  1.8480 +    <para id="x_e5">The <command role="hg-cmd" moreinfo="none">hg revert</command> command
  1.8481 +      provides us with an extra degree of safety by saving our
  1.8482 +      modified file with a <filename moreinfo="none">.orig</filename>
  1.8483 +      extension.</para>
  1.8484 +
  1.8485 +    <!-- BEGIN daily.revert.status -->
  1.8486 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8487 +? file.orig
  1.8488 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file.orig</userinput>
  1.8489 +original content
  1.8490 +unwanted change
  1.8491 +</screen>
  1.8492 +<!-- END daily.revert.status -->
  1.8493 +
  1.8494 +
  1.8495 +    <tip>
  1.8496 +      <title>Be careful with <filename moreinfo="none">.orig</filename> files</title>
  1.8497 +
  1.8498 +      <para id="x_6b8">It's extremely unlikely that you are either using
  1.8499 +	Mercurial to manage files with <filename moreinfo="none">.orig</filename>
  1.8500 +	extensions or that you even care about the contents of such
  1.8501 +	files.  Just in case, though, it's useful to remember that
  1.8502 +	<command role="hg-cmd" moreinfo="none">hg revert</command> will
  1.8503 +	unconditionally overwrite an existing file with a
  1.8504 +	<filename moreinfo="none">.orig</filename> extension. For instance, if you
  1.8505 +	already have a file named <filename moreinfo="none">foo.orig</filename> when
  1.8506 +	you revert <filename moreinfo="none">foo</filename>, the contents of
  1.8507 +	<filename moreinfo="none">foo.orig</filename> will be clobbered.</para>
  1.8508 +    </tip>
  1.8509 +
  1.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
  1.8511 +      will describe each of these in more detail in the section that
  1.8512 +      follows.</para>
  1.8513 +    <itemizedlist>
  1.8514 +      <listitem><para id="x_e7">If you modify a file, it will restore the file
  1.8515 +	  to its unmodified state.</para>
  1.8516 +      </listitem>
  1.8517 +      <listitem><para id="x_e8">If you <command role="hg-cmd" moreinfo="none">hg add</command> a
  1.8518 +	  file, it will undo the <quote>added</quote> state of the
  1.8519 +	  file, but leave the file itself untouched.</para>
  1.8520 +      </listitem>
  1.8521 +      <listitem><para id="x_e9">If you delete a file without telling Mercurial,
  1.8522 +	  it will restore the file to its unmodified contents.</para>
  1.8523 +      </listitem>
  1.8524 +      <listitem><para id="x_ea">If you use the <command role="hg-cmd" moreinfo="none">hg
  1.8525 +	    remove</command> command to remove a file, it will undo
  1.8526 +	  the <quote>removed</quote> state of the file, and restore
  1.8527 +	  the file to its unmodified contents.</para>
  1.8528 +      </listitem></itemizedlist>
  1.8529 +
  1.8530 +    <sect2 id="sec:undo:mgmt">
  1.8531 +      <title>File management errors</title>
  1.8532 +
  1.8533 +      <para id="x_eb">The <command role="hg-cmd" moreinfo="none">hg revert</command> command is
  1.8534 +	useful for more than just modified files.  It lets you reverse
  1.8535 +	the results of all of Mercurial's file management
  1.8536 +	commands—<command role="hg-cmd" moreinfo="none">hg add</command>,
  1.8537 +	<command role="hg-cmd" moreinfo="none">hg remove</command>, and so on.</para>
  1.8538 +
  1.8539 +      <para id="x_ec">If you <command role="hg-cmd" moreinfo="none">hg add</command> a file,
  1.8540 +	then decide that in fact you don't want Mercurial to track it,
  1.8541 +	use <command role="hg-cmd" moreinfo="none">hg revert</command> to undo the
  1.8542 +	add.  Don't worry; Mercurial will not modify the file in any
  1.8543 +	way.  It will just <quote>unmark</quote> the file.</para>
  1.8544 +
  1.8545 +      <!-- BEGIN daily.revert.add -->
  1.8546 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo oops &gt; oops</userinput>
  1.8547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add oops</userinput>
  1.8548 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status oops</userinput>
  1.8549 +A oops
  1.8550 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert oops</userinput>
  1.8551 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8552 +? oops
  1.8553 +</screen>
  1.8554 +<!-- END daily.revert.add -->
  1.8555 +
  1.8556 +
  1.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
  1.8558 +	<command role="hg-cmd" moreinfo="none">hg revert</command> to restore it to
  1.8559 +	the contents it had as of the parent of the working directory.
  1.8560 +	<!-- BEGIN daily.revert.remove -->
  1.8561 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg remove file</userinput>
  1.8562 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8563 +R file
  1.8564 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert file</userinput>
  1.8565 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8566 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls file</userinput>
  1.8567 +file
  1.8568 +</screen>
  1.8569 +<!-- END daily.revert.remove -->
  1.8570 + This works just as
  1.8571 +	well for a file that you deleted by hand, without telling
  1.8572 +	Mercurial (recall that in Mercurial terminology, this kind of
  1.8573 +	file is called <quote>missing</quote>).</para>
  1.8574 +
  1.8575 +      <!-- BEGIN daily.revert.missing -->
  1.8576 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">rm file</userinput>
  1.8577 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8578 +! file
  1.8579 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert file</userinput>
  1.8580 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls file</userinput>
  1.8581 +file
  1.8582 +</screen>
  1.8583 +<!-- END daily.revert.missing -->
  1.8584 +
  1.8585 +
  1.8586 +      <para id="x_ee">If you revert a <command role="hg-cmd" moreinfo="none">hg copy</command>,
  1.8587 +	the copied-to file remains in your working directory
  1.8588 +	afterwards, untracked.  Since a copy doesn't affect the
  1.8589 +	copied-from file in any way, Mercurial doesn't do anything
  1.8590 +	with the copied-from file.</para>
  1.8591 +
  1.8592 +      <!-- BEGIN daily.revert.copy -->
  1.8593 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg copy file new-file</userinput>
  1.8594 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg revert new-file</userinput>
  1.8595 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
  1.8596 +? new-file
  1.8597 +</screen>
  1.8598 +<!-- END daily.revert.copy -->
  1.8599 +
  1.8600 +    </sect2>
  1.8601 +  </sect1>
  1.8602 +
  1.8603 +  <sect1>
  1.8604 +    <title>Dealing with committed changes</title>
  1.8605 +
  1.8606 +    <para id="x_f5">Consider a case where you have committed a change
  1.8607 +      <emphasis>a</emphasis>, and another change
  1.8608 +      <emphasis>b</emphasis> on top of it; you then realise that
  1.8609 +      change <emphasis>a</emphasis> was incorrect.  Mercurial lets you
  1.8610 +      <quote>back out</quote> an entire changeset automatically, and
  1.8611 +      building blocks that let you reverse part of a changeset by
  1.8612 +      hand.</para>
  1.8613 +
  1.8614 +    <para id="x_f6">Before you read this section, here's something to
  1.8615 +      keep in mind: the <command role="hg-cmd" moreinfo="none">hg backout</command>
  1.8616 +      command undoes the effect of a change by
  1.8617 +      <emphasis>adding</emphasis> to your repository's history, not by
  1.8618 +      modifying or erasing it.  It's the right tool to use if you're
  1.8619 +      fixing bugs, but not if you're trying to undo some change that
  1.8620 +      has catastrophic consequences.  To deal with those, see
  1.8621 +      <xref linkend="sec:undo:aaaiiieee"/>.</para>
  1.8622 +
  1.8623 +    <sect2>
  1.8624 +      <title>Backing out a changeset</title>
  1.8625 +
  1.8626 +      <para id="x_f7">The <command role="hg-cmd" moreinfo="none">hg backout</command> command
  1.8627 +	lets you <quote>undo</quote> the effects of an entire
  1.8628 +	changeset in an automated fashion.  Because Mercurial's
  1.8629 +	history is immutable, this command <emphasis>does
  1.8630 +	  not</emphasis> get rid of the changeset you want to undo.
  1.8631 +	Instead, it creates a new changeset that
  1.8632 +	<emphasis>reverses</emphasis> the effect of the to-be-undone
  1.8633 +	changeset.</para>
  1.8634 +
  1.8635 +      <para id="x_f8">The operation of the <command role="hg-cmd" moreinfo="none">hg
  1.8636 +	  backout</command> command is a little intricate, so let's
  1.8637 +	illustrate it with some examples.  First, we'll create a
  1.8638 +	repository with some simple changes.</para>
  1.8639 +
  1.8640 +      <!-- BEGIN backout.init -->
  1.8641 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init myrepo</userinput>
  1.8642 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myrepo</userinput>
  1.8643 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo first change &gt;&gt; myfile</userinput>
  1.8644 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add myfile</userinput>
  1.8645 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'first change'</userinput>
  1.8646 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo second change &gt;&gt; myfile</userinput>
  1.8647 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'second change'</userinput>
  1.8648 +</screen>
  1.8649 +<!-- END backout.init -->
  1.8650 +
  1.8651 +
  1.8652 +      <para id="x_f9">The <command role="hg-cmd" moreinfo="none">hg backout</command> command
  1.8653 +	takes a single changeset ID as its argument; this is the
  1.8654 +	changeset to back out.  Normally, <command role="hg-cmd" moreinfo="none">hg
  1.8655 +	  backout</command> will drop you into a text editor to write
  1.8656 +	a commit message, so you can record why you're backing the
  1.8657 +	change out.  In this example, we provide a commit message on
  1.8658 +	the command line using the <option role="hg-opt-backout">-m</option> option.</para>
  1.8659 +
  1.8660 +    </sect2>
  1.8661 +    <sect2>
  1.8662 +      <title>Backing out the tip changeset</title>
  1.8663 +
  1.8664 +      <para id="x_fa">We're going to start by backing out the last changeset we
  1.8665 +	committed.</para>
  1.8666 +
  1.8667 +      <!-- BEGIN backout.simple -->
  1.8668 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg backout -m 'back out second change' tip</userinput>
  1.8669 +reverting myfile
  1.8670 +changeset 2:611a0cae251c backs out changeset 1:43700a9b3ec8
  1.8671 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.8672 +first change
  1.8673 +</screen>
  1.8674 +<!-- END backout.simple -->
  1.8675 +
  1.8676 +
  1.8677 +      <para id="x_fb">You can see that the second line from
  1.8678 +	<filename moreinfo="none">myfile</filename> is no longer present.  Taking a
  1.8679 +	look at the output of <command role="hg-cmd" moreinfo="none">hg log</command>
  1.8680 +	gives us an idea of what the <command role="hg-cmd" moreinfo="none">hg
  1.8681 +	  backout</command> command has done.
  1.8682 +	<!-- BEGIN backout.simple.log -->
  1.8683 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style compact</userinput>
  1.8684 +2[tip]   611a0cae251c   2009-08-16 14:04 +0000   bos
  1.8685 +  back out second change
  1.8686 +
  1.8687 +1   43700a9b3ec8   2009-08-16 14:04 +0000   bos
  1.8688 +  second change
  1.8689 +
  1.8690 +0   f2ef23d503fd   2009-08-16 14:04 +0000   bos
  1.8691 +  first change
  1.8692 +
  1.8693 +</screen>
  1.8694 +<!-- END backout.simple.log -->
  1.8695 + Notice that the new changeset
  1.8696 +	that <command role="hg-cmd" moreinfo="none">hg backout</command> has created
  1.8697 +	is a child of the changeset we backed out.  It's easier to see
  1.8698 +	this in <xref linkend="fig:undo:backout"/>, which presents a
  1.8699 +	graphical view of the change history.  As you can see, the
  1.8700 +	history is nice and linear.</para>
  1.8701 +
  1.8702 +      <figure id="fig:undo:backout" float="0">
  1.8703 +	<title>Backing out a change using the <command role="hg-cmd" moreinfo="none">hg backout</command> command</title>
  1.8704 +	<mediaobject>
  1.8705 +	  <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject>
  1.8706 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.8707 +	</mediaobject>
  1.8708 +      </figure>
  1.8709 +
  1.8710 +    </sect2>
  1.8711 +    <sect2>
  1.8712 +      <title>Backing out a non-tip change</title>
  1.8713 +
  1.8714 +      <para id="x_fd">If you want to back out a change other than the last one
  1.8715 +	you committed, pass the <option role="hg-opt-backout">--merge</option> option to the
  1.8716 +	<command role="hg-cmd" moreinfo="none">hg backout</command> command.</para>
  1.8717 +
  1.8718 +      <!-- BEGIN backout.non-tip.clone -->
  1.8719 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.8720 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -r1 myrepo non-tip-repo</userinput>
  1.8721 +requesting all changes
  1.8722 +adding changesets
  1.8723 +adding manifests
  1.8724 +adding file changes
  1.8725 +added 2 changesets with 2 changes to 1 files
  1.8726 +updating working directory
  1.8727 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.8728 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd non-tip-repo</userinput>
  1.8729 +</screen>
  1.8730 +<!-- END backout.non-tip.clone -->
  1.8731 +
  1.8732 +
  1.8733 +      <para id="x_fe">This makes backing out any changeset a
  1.8734 +	<quote>one-shot</quote> operation that's usually simple and
  1.8735 +	fast.</para>
  1.8736 +
  1.8737 +      <!-- BEGIN backout.non-tip.backout -->
  1.8738 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo third change &gt;&gt; myfile</userinput>
  1.8739 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'third change'</userinput>
  1.8740 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg backout --merge -m 'back out second change' 1</userinput>
  1.8741 +reverting myfile
  1.8742 +created new head
  1.8743 +changeset 3:611a0cae251c backs out changeset 1:43700a9b3ec8
  1.8744 +merging with changeset 3:611a0cae251c
  1.8745 +merging myfile
  1.8746 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  1.8747 +(branch merge, don't forget to commit)
  1.8748 +</screen>
  1.8749 +<!-- END backout.non-tip.backout -->
  1.8750 +
  1.8751 +
  1.8752 +      <para id="x_ff">If you take a look at the contents of
  1.8753 +	<filename moreinfo="none">myfile</filename> after the backout finishes, you'll
  1.8754 +	see that the first and third changes are present, but not the
  1.8755 +	second.</para>
  1.8756 +
  1.8757 +      <!-- BEGIN backout.non-tip.cat -->
  1.8758 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.8759 +first change
  1.8760 +third change
  1.8761 +</screen>
  1.8762 +<!-- END backout.non-tip.cat -->
  1.8763 +
  1.8764 +
  1.8765 +      <para id="x_100">As the graphical history in <xref linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial
  1.8766 +	still commits one change in this kind of situation (the
  1.8767 +	box-shaped node is the ones that Mercurial commits
  1.8768 +	automatically), but the revision graph now looks different.
  1.8769 +	Before Mercurial begins the backout process, it first
  1.8770 +	remembers what the current parent of the working directory is.
  1.8771 +	It then backs out the target changeset, and commits that as a
  1.8772 +	changeset.  Finally, it merges back to the previous parent of
  1.8773 +	the working directory, but notice that it <emphasis>does not
  1.8774 +	  commit</emphasis> the result of the merge.  The repository
  1.8775 +	now contains two heads, and the working directory is in a
  1.8776 +	merge state.</para>
  1.8777 +
  1.8778 +      <figure id="fig:undo:backout-non-tip" float="0">
  1.8779 +	<title>Automated backout of a non-tip change using the
  1.8780 +	  <command role="hg-cmd" moreinfo="none">hg backout</command> command</title>
  1.8781 +	<mediaobject>
  1.8782 +	  <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject>
  1.8783 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.8784 +	</mediaobject>
  1.8785 +      </figure>
  1.8786 +
  1.8787 +      <para id="x_103">The result is that you end up <quote>back where you
  1.8788 +	  were</quote>, only with some extra history that undoes the
  1.8789 +	effect of the changeset you wanted to back out.</para>
  1.8790 +
  1.8791 +      <para id="x_6b9">You might wonder why Mercurial does not commit the result
  1.8792 +	of the merge that it performed.  The reason lies in Mercurial
  1.8793 +	behaving conservatively: a merge naturally has more scope for
  1.8794 +	error than simply undoing the effect of the tip changeset,
  1.8795 +	so your work will be safest if you first inspect (and test!)
  1.8796 +	the result of the merge, <emphasis>then</emphasis> commit
  1.8797 +	it.</para>
  1.8798 +
  1.8799 +      <sect3>
  1.8800 +	<title>Always use the <option role="hg-opt-backout">--merge</option> option</title>
  1.8801 +
  1.8802 +	<para id="x_104">In fact, since the <option role="hg-opt-backout">--merge</option> option will do the
  1.8803 +	  <quote>right thing</quote> whether or not the changeset
  1.8804 +	  you're backing out is the tip (i.e. it won't try to merge if
  1.8805 +	  it's backing out the tip, since there's no need), you should
  1.8806 +	  <emphasis>always</emphasis> use this option when you run the
  1.8807 +	  <command role="hg-cmd" moreinfo="none">hg backout</command> command.</para>
  1.8808 +
  1.8809 +      </sect3>
  1.8810 +    </sect2>
  1.8811 +    <sect2>
  1.8812 +      <title>Gaining more control of the backout process</title>
  1.8813 +
  1.8814 +      <para id="x_105">While I've recommended that you always use the <option role="hg-opt-backout">--merge</option> option when backing
  1.8815 +	out a change, the <command role="hg-cmd" moreinfo="none">hg backout</command>
  1.8816 +	command lets you decide how to merge a backout changeset.
  1.8817 +	Taking control of the backout process by hand is something you
  1.8818 +	will rarely need to do, but it can be useful to understand
  1.8819 +	what the <command role="hg-cmd" moreinfo="none">hg backout</command> command
  1.8820 +	is doing for you automatically.  To illustrate this, let's
  1.8821 +	clone our first repository, but omit the backout change that
  1.8822 +	it contains.</para>
  1.8823 +
  1.8824 +      <!-- BEGIN backout.manual.clone -->
  1.8825 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
  1.8826 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone -r1 myrepo newrepo</userinput>
  1.8827 +requesting all changes
  1.8828 +adding changesets
  1.8829 +adding manifests
  1.8830 +adding file changes
  1.8831 +added 2 changesets with 2 changes to 1 files
  1.8832 +updating working directory
  1.8833 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.8834 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd newrepo</userinput>
  1.8835 +</screen>
  1.8836 +<!-- END backout.manual.clone -->
  1.8837 +
  1.8838 +
  1.8839 +      <para id="x_106">As with our
  1.8840 +	earlier example, We'll commit a third changeset, then back out
  1.8841 +	its parent, and see what happens.</para>
  1.8842 +
  1.8843 +      <!-- BEGIN backout.manual.backout -->
  1.8844 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo third change &gt;&gt; myfile</userinput>
  1.8845 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'third change'</userinput>
  1.8846 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg backout -m 'back out second change' 1</userinput>
  1.8847 +reverting myfile
  1.8848 +created new head
  1.8849 +changeset 3:bf906ee0baae backs out changeset 1:43700a9b3ec8
  1.8850 +the backout changeset is a new head - do not forget to merge
  1.8851 +(use "backout --merge" if you want to auto-merge)
  1.8852 +</screen>
  1.8853 +<!-- END backout.manual.backout -->
  1.8854 +
  1.8855 +
  1.8856 +      <para id="x_107">Our new changeset is again a descendant of the changeset
  1.8857 +	we backout out; it's thus a new head, <emphasis>not</emphasis>
  1.8858 +	a descendant of the changeset that was the tip.  The <command role="hg-cmd" moreinfo="none">hg backout</command> command was quite
  1.8859 +	explicit in telling us this.</para>
  1.8860 +
  1.8861 +      <!-- BEGIN backout.manual.log -->
  1.8862 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style compact</userinput>
  1.8863 +3[tip]:1   bf906ee0baae   2009-08-16 14:04 +0000   bos
  1.8864 +  back out second change
  1.8865 +
  1.8866 +2   2521379001ad   2009-08-16 14:04 +0000   bos
  1.8867 +  third change
  1.8868 +
  1.8869 +1   43700a9b3ec8   2009-08-16 14:04 +0000   bos
  1.8870 +  second change
  1.8871 +
  1.8872 +0   f2ef23d503fd   2009-08-16 14:04 +0000   bos
  1.8873 +  first change
  1.8874 +
  1.8875 +</screen>
  1.8876 +<!-- END backout.manual.log -->
  1.8877 +
  1.8878 +
  1.8879 +      <para id="x_108">Again, it's easier to see what has happened by looking at
  1.8880 +	a graph of the revision history, in <xref linkend="fig:undo:backout-manual"/>.  This makes it clear
  1.8881 +	that when we use <command role="hg-cmd" moreinfo="none">hg backout</command>
  1.8882 +	to back out a change other than the tip, Mercurial adds a new
  1.8883 +	head to the repository (the change it committed is
  1.8884 +	box-shaped).</para>
  1.8885 +
  1.8886 +      <figure id="fig:undo:backout-manual" float="0">
  1.8887 +	<title>Backing out a change using the <command role="hg-cmd" moreinfo="none">hg backout</command> command</title>
  1.8888 +	<mediaobject>
  1.8889 +	  <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject>
  1.8890 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.8891 +	</mediaobject>
  1.8892 +      </figure>
  1.8893 +
  1.8894 +      <para id="x_10a">After the <command role="hg-cmd" moreinfo="none">hg backout</command>
  1.8895 +	command has completed, it leaves the new
  1.8896 +	<quote>backout</quote> changeset as the parent of the working
  1.8897 +	directory.</para>
  1.8898 +
  1.8899 +      <!-- BEGIN backout.manual.parents -->
  1.8900 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg parents</userinput>
  1.8901 +changeset:   2:2521379001ad
  1.8902 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8903 +date:        Sun Aug 16 14:04:37 2009 +0000
  1.8904 +summary:     third change
  1.8905 +
  1.8906 +</screen>
  1.8907 +<!-- END backout.manual.parents -->
  1.8908 +
  1.8909 +
  1.8910 +      <para id="x_10b">Now we have two isolated sets of changes.</para>
  1.8911 +
  1.8912 +      <!-- BEGIN backout.manual.heads -->
  1.8913 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg heads</userinput>
  1.8914 +changeset:   3:bf906ee0baae
  1.8915 +tag:         tip
  1.8916 +parent:      1:43700a9b3ec8
  1.8917 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8918 +date:        Sun Aug 16 14:04:37 2009 +0000
  1.8919 +summary:     back out second change
  1.8920 +
  1.8921 +changeset:   2:2521379001ad
  1.8922 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.8923 +date:        Sun Aug 16 14:04:37 2009 +0000
  1.8924 +summary:     third change
  1.8925 +
  1.8926 +</screen>
  1.8927 +<!-- END backout.manual.heads -->
  1.8928 +
  1.8929 +
  1.8930 +      <para id="x_10c">Let's think about what we expect to see as the contents of
  1.8931 +	<filename moreinfo="none">myfile</filename> now.  The first change should be
  1.8932 +	present, because we've never backed it out.  The second change
  1.8933 +	should be missing, as that's the change we backed out.  Since
  1.8934 +	the history graph shows the third change as a separate head,
  1.8935 +	we <emphasis>don't</emphasis> expect to see the third change
  1.8936 +	present in <filename moreinfo="none">myfile</filename>.</para>
  1.8937 +
  1.8938 +      <!-- BEGIN backout.manual.cat -->
  1.8939 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.8940 +first change
  1.8941 +</screen>
  1.8942 +<!-- END backout.manual.cat -->
  1.8943 +
  1.8944 +
  1.8945 +      <para id="x_10d">To get the third change back into the file, we just do a
  1.8946 +	normal merge of our two heads.</para>
  1.8947 +
  1.8948 +      <!-- BEGIN backout.manual.merge -->
  1.8949 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg merge</userinput>
  1.8950 +abort: outstanding uncommitted changes
  1.8951 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'merged backout with previous tip'</userinput>
  1.8952 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat myfile</userinput>
  1.8953 +first change
  1.8954 +</screen>
  1.8955 +<!-- END backout.manual.merge -->
  1.8956 +
  1.8957 +
  1.8958 +      <para id="x_10e">Afterwards, the graphical history of our
  1.8959 +	repository looks like
  1.8960 +	<xref linkend="fig:undo:backout-manual-merge"/>.</para>
  1.8961 +
  1.8962 +      <figure id="fig:undo:backout-manual-merge" float="0">
  1.8963 +	<title>Manually merging a backout change</title>
  1.8964 +	<mediaobject>
  1.8965 +	  <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject>
  1.8966 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.8967 +	</mediaobject>
  1.8968 +      </figure>
  1.8969 +
  1.8970 +    </sect2>
  1.8971 +    <sect2>
  1.8972 +      <title>Why <command role="hg-cmd" moreinfo="none">hg backout</command> works as
  1.8973 +	it does</title>
  1.8974 +
  1.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>
  1.8976 +      <orderedlist inheritnum="ignore" continuation="restarts">
  1.8977 +	<listitem><para id="x_111">It ensures that the working directory is
  1.8978 +	    <quote>clean</quote>, i.e. that the output of <command role="hg-cmd" moreinfo="none">hg status</command> would be empty.</para>
  1.8979 +	</listitem>
  1.8980 +	<listitem><para id="x_112">It remembers the current parent of the working
  1.8981 +	    directory.  Let's call this changeset
  1.8982 +	    <literal moreinfo="none">orig</literal>.</para>
  1.8983 +	</listitem>
  1.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
  1.8985 +	    directory to the changeset you want to back out.  Let's
  1.8986 +	    call this changeset <literal moreinfo="none">backout</literal>.</para>
  1.8987 +	</listitem>
  1.8988 +	<listitem><para id="x_114">It finds the parent of that changeset.  Let's
  1.8989 +	    call that changeset <literal moreinfo="none">parent</literal>.</para>
  1.8990 +	</listitem>
  1.8991 +	<listitem><para id="x_115">For each file that the
  1.8992 +	    <literal moreinfo="none">backout</literal> changeset affected, it does the
  1.8993 +	    equivalent of a <command role="hg-cmd" moreinfo="none">hg revert -r
  1.8994 +	      parent</command> on that file, to restore it to the
  1.8995 +	    contents it had before that changeset was
  1.8996 +	    committed.</para>
  1.8997 +	</listitem>
  1.8998 +	<listitem><para id="x_116">It commits the result as a new changeset.
  1.8999 +	    This changeset has <literal moreinfo="none">backout</literal> as its
  1.9000 +	    parent.</para>
  1.9001 +	</listitem>
  1.9002 +	<listitem><para id="x_117">If you specify <option role="hg-opt-backout">--merge</option> on the command
  1.9003 +	    line, it merges with <literal moreinfo="none">orig</literal>, and commits
  1.9004 +	    the result of the merge.</para>
  1.9005 +	</listitem></orderedlist>
  1.9006 +
  1.9007 +      <para id="x_118">An alternative way to implement the <command role="hg-cmd" moreinfo="none">hg backout</command> command would be to
  1.9008 +	<command role="hg-cmd" moreinfo="none">hg export</command> the
  1.9009 +	to-be-backed-out changeset as a diff, then use the <option role="cmd-opt-patch">--reverse</option> option to the
  1.9010 +	<command moreinfo="none">patch</command> command to reverse the effect of the
  1.9011 +	change without fiddling with the working directory.  This
  1.9012 +	sounds much simpler, but it would not work nearly as
  1.9013 +	well.</para>
  1.9014 +
  1.9015 +      <para id="x_119">The reason that <command role="hg-cmd" moreinfo="none">hg
  1.9016 +	  backout</command> does an update, a commit, a merge, and
  1.9017 +	another commit is to give the merge machinery the best chance
  1.9018 +	to do a good job when dealing with all the changes
  1.9019 +	<emphasis>between</emphasis> the change you're backing out and
  1.9020 +	the current tip.</para>
  1.9021 +
  1.9022 +      <para id="x_11a">If you're backing out a changeset that's 100 revisions
  1.9023 +	back in your project's history, the chances that the
  1.9024 +	<command moreinfo="none">patch</command> command will be able to apply a
  1.9025 +	reverse diff cleanly are not good, because intervening changes
  1.9026 +	are likely to have <quote>broken the context</quote> that
  1.9027 +	<command moreinfo="none">patch</command> uses to determine whether it can
  1.9028 +	apply a patch (if this sounds like gibberish, see <xref linkend="sec:mq:patch"/> for a
  1.9029 +	discussion of the <command moreinfo="none">patch</command> command).  Also,
  1.9030 +	Mercurial's merge machinery will handle files and directories
  1.9031 +	being renamed, permission changes, and modifications to binary
  1.9032 +	files, none of which <command moreinfo="none">patch</command> can deal
  1.9033 +	with.</para>
  1.9034 +
  1.9035 +    </sect2>
  1.9036 +  </sect1>
  1.9037 +  <sect1 id="sec:undo:aaaiiieee">
  1.9038 +    <title>Changes that should never have been</title>
  1.9039 +
  1.9040 +    <para id="x_11b">Most of the time, the <command role="hg-cmd" moreinfo="none">hg
  1.9041 +	backout</command> command is exactly what you need if you want
  1.9042 +      to undo the effects of a change.  It leaves a permanent record
  1.9043 +      of exactly what you did, both when committing the original
  1.9044 +      changeset and when you cleaned up after it.</para>
  1.9045 +
  1.9046 +    <para id="x_11c">On rare occasions, though, you may find that you've
  1.9047 +      committed a change that really should not be present in the
  1.9048 +      repository at all.  For example, it would be very unusual, and
  1.9049 +      usually considered a mistake, to commit a software project's
  1.9050 +      object files as well as its source files.  Object files have
  1.9051 +      almost no intrinsic value, and they're <emphasis>big</emphasis>,
  1.9052 +      so they increase the size of the repository and the amount of
  1.9053 +      time it takes to clone or pull changes.</para>
  1.9054 +
  1.9055 +    <para id="x_11d">Before I discuss the options that you have if you commit a
  1.9056 +      <quote>brown paper bag</quote> change (the kind that's so bad
  1.9057 +      that you want to pull a brown paper bag over your head), let me
  1.9058 +      first discuss some approaches that probably won't work.</para>
  1.9059 +
  1.9060 +    <para id="x_11e">Since Mercurial treats history as
  1.9061 +      accumulative—every change builds on top of all changes
  1.9062 +      that preceded it—you generally can't just make disastrous
  1.9063 +      changes disappear.  The one exception is when you've just
  1.9064 +      committed a change, and it hasn't been pushed or pulled into
  1.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
  1.9066 +      <xref linkend="sec:undo:rollback"/>.</para>
  1.9067 +
  1.9068 +    <para id="x_11f">After you've pushed a bad change to another repository, you
  1.9069 +      <emphasis>could</emphasis> still use <command role="hg-cmd" moreinfo="none">hg
  1.9070 +	rollback</command> to make your local copy of the change
  1.9071 +      disappear, but it won't have the consequences you want.  The
  1.9072 +      change will still be present in the remote repository, so it
  1.9073 +      will reappear in your local repository the next time you
  1.9074 +      pull.</para>
  1.9075 +
  1.9076 +    <para id="x_120">If a situation like this arises, and you know which
  1.9077 +      repositories your bad change has propagated into, you can
  1.9078 +      <emphasis>try</emphasis> to get rid of the change from
  1.9079 +      <emphasis>every</emphasis> one of those repositories.  This is,
  1.9080 +      of course, not a satisfactory solution: if you miss even a
  1.9081 +      single repository while you're expunging, the change is still
  1.9082 +      <quote>in the wild</quote>, and could propagate further.</para>
  1.9083 +
  1.9084 +    <para id="x_121">If you've committed one or more changes
  1.9085 +      <emphasis>after</emphasis> the change that you'd like to see
  1.9086 +      disappear, your options are further reduced. Mercurial doesn't
  1.9087 +      provide a way to <quote>punch a hole</quote> in history, leaving
  1.9088 +      changesets intact.</para>
  1.9089 +
  1.9090 +    <sect2>
  1.9091 +      <title>Backing out a merge</title>
  1.9092 +
  1.9093 +      <para id="x_6ba">Since merges are often complicated, it is not unheard of
  1.9094 +	for a merge to be mangled badly, but committed erroneously.
  1.9095 +	Mercurial provides an important safeguard against bad merges
  1.9096 +	by refusing to commit unresolved files, but human ingenuity
  1.9097 +	guarantees that it is still possible to mess a merge up and
  1.9098 +	commit it.</para>
  1.9099 +
  1.9100 +      <para id="x_6bb">Given a bad merge that has been committed, usually the
  1.9101 +	best way to approach it is to simply try to repair the damage
  1.9102 +	by hand.  A complete disaster that cannot be easily fixed up
  1.9103 +	by hand ought to be very rare, but the <command role="hg-cmd" moreinfo="none">hg backout</command> command may help in
  1.9104 +	making the cleanup easier. It offers a <option role="hg-opt-backout">--parent</option> option, which lets
  1.9105 +	you specify which parent to revert to when backing out a
  1.9106 +	merge.</para>
  1.9107 +
  1.9108 +      <figure id="fig:undo:bad-merge-1" float="0">
  1.9109 +	<title>A bad merge</title>
  1.9110 +	<mediaobject>
  1.9111 +	  <imageobject><imagedata fileref="figs/bad-merge-1.png"/></imageobject>
  1.9112 +	  <textobject><phrase>XXX add text</phrase></textobject>
  1.9113 +	</mediaobject>
  1.9114 +      </figure>
  1.9115 +
  1.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
  1.9117 +	<emphasis>redo</emphasis> the merge of revisions 2 and
  1.9118 +	3.</para>
  1.9119 +
  1.9120 +      <para id="x_6bd">One way to do so would be as follows.</para>
  1.9121 +
  1.9122 +      <orderedlist inheritnum="ignore" continuation="restarts">
  1.9123 +	<listitem>
  1.9124 +	  <para id="x_6be">Call <command role="hg-cmd" moreinfo="none">hg backout --rev=4
  1.9125 +	      --parent=2</command>.  This tells <command role="hg-cmd" moreinfo="none">hg backout</command> to back out revision
  1.9126 +	    4, which is the bad merge, and to when deciding which
  1.9127 +	    revision to prefer, to choose parent 2, one of the parents
  1.9128 +	    of the merge.  The effect can be seen in <xref linkend="fig:undo:bad-merge-2"/>.</para>
  1.9129 +	  <figure id="fig:undo:bad-merge-2" float="0">
  1.9130 +	    <title>Backing out the merge, favoring one parent</title>
  1.9131 +	    <mediaobject>
  1.9132 +	      <imageobject><imagedata fileref="figs/bad-merge-2.png"/></imageobject>
  1.9133 +	      <textobject><phrase>XXX add text</phrase></textobject>
  1.9134 +	    </mediaobject>
  1.9135 +	  </figure>
  1.9136 +	</listitem>
  1.9137 +
  1.9138 +	<listitem>
  1.9139 +	  <para id="x_6bf">Call <command role="hg-cmd" moreinfo="none">hg backout --rev=4
  1.9140 +	      --parent=3</command>.  This tells <command role="hg-cmd" moreinfo="none">hg backout</command> to back out revision
  1.9141 +	    4 again, but this time to choose parent 3, the other
  1.9142 +	    parent of the merge.  The result is visible in <xref linkend="fig:undo:bad-merge-3"/>, in which the repository
  1.9143 +	    now contains three heads.</para>
  1.9144 +	  <figure id="fig:undo:bad-merge-3" float="0">
  1.9145 +	    <title>Backing out the merge, favoring the other
  1.9146 +	      parent</title>
  1.9147 +	    <mediaobject>
  1.9148 +	      <imageobject><imagedata fileref="figs/bad-merge-3.png"/></imageobject>
  1.9149 +	      <textobject><phrase>XXX add text</phrase></textobject>
  1.9150 +	    </mediaobject>
  1.9151 +	  </figure>
  1.9152 +	</listitem>
  1.9153 +
  1.9154 +	<listitem>
  1.9155 +	  <para id="x_6c0">Redo the bad merge by merging the two backout heads,
  1.9156 +	    which reduces the number of heads in the repository to
  1.9157 +	    two, as can be seen in <xref linkend="fig:undo:bad-merge-4"/>.</para>
  1.9158 +	  <figure id="fig:undo:bad-merge-4" float="0">
  1.9159 +	    <title>Merging the backouts</title>
  1.9160 +	    <mediaobject>
  1.9161 +	      <imageobject><imagedata fileref="figs/bad-merge-4.png"/></imageobject>
  1.9162 +	      <textobject><phrase>XXX add text</phrase></textobject>
  1.9163 +	    </mediaobject>
  1.9164 +	  </figure>
  1.9165 +	</listitem>
  1.9166 +
  1.9167 +	<listitem>
  1.9168 +	  <para id="x_6c1">Merge with the commit that was made after the bad
  1.9169 +	    merge, as shown in <xref linkend="fig:undo:bad-merge-5"/>.</para>
  1.9170 +	  <figure id="fig:undo:bad-merge-5" float="0">
  1.9171 +	    <title>Merging the backouts</title>
  1.9172 +	    <mediaobject>
  1.9173 +	      <imageobject><imagedata fileref="figs/bad-merge-5.png"/></imageobject>
  1.9174 +	      <textobject><phrase>XXX add text</phrase></textobject>
  1.9175 +	    </mediaobject>
  1.9176 +	  </figure>
  1.9177 +	</listitem>
  1.9178 +      </orderedlist>
  1.9179 +    </sect2>
  1.9180 +
  1.9181 +    <sect2>
  1.9182 +      <title>Protect yourself from <quote>escaped</quote>
  1.9183 +	changes</title>
  1.9184 +
  1.9185 +      <para id="x_123">If you've committed some changes to your local repository
  1.9186 +	and they've been pushed or pulled somewhere else, this isn't
  1.9187 +	necessarily a disaster.  You can protect yourself ahead of
  1.9188 +	time against some classes of bad changeset.  This is
  1.9189 +	particularly easy if your team usually pulls changes from a
  1.9190 +	central repository.</para>
  1.9191 +
  1.9192 +      <para id="x_124">By configuring some hooks on that repository to validate
  1.9193 +	incoming changesets (see chapter <xref linkend="chap:hook"/>),
  1.9194 +	you can
  1.9195 +	automatically prevent some kinds of bad changeset from being
  1.9196 +	pushed to the central repository at all.  With such a
  1.9197 +	configuration in place, some kinds of bad changeset will
  1.9198 +	naturally tend to <quote>die out</quote> because they can't
  1.9199 +	propagate into the central repository.  Better yet, this
  1.9200 +	happens without any need for explicit intervention.</para>
  1.9201 +
  1.9202 +      <para id="x_125">For instance, an incoming change hook that
  1.9203 +	verifies that a changeset will actually compile can prevent
  1.9204 +	people from inadvertently <quote>breaking the
  1.9205 +	  build</quote>.</para>
  1.9206 +    </sect2>
  1.9207 +
  1.9208 +    <sect2>
  1.9209 +      <title>What to do about sensitive changes that escape</title>
  1.9210 +
  1.9211 +      <para id="x_6c2">Even a carefully run project can suffer an unfortunate
  1.9212 +	event such as the committing and uncontrolled propagation of a
  1.9213 +	file that contains important passwords.</para>
  1.9214 +
  1.9215 +      <para id="x_6c3">If something like this happens to you, and the information
  1.9216 +	that gets accidentally propagated is truly sensitive, your
  1.9217 +	first step should be to mitigate the effect of the leak
  1.9218 +	without trying to control the leak itself. If you are not 100%
  1.9219 +	certain that you know exactly who could have seen the changes,
  1.9220 +	you should immediately change passwords, cancel credit cards,
  1.9221 +	or find some other way to make sure that the information that
  1.9222 +	has leaked is no longer useful.  In other words, assume that
  1.9223 +	the change has propagated far and wide, and that there's
  1.9224 +	nothing more you can do.</para>
  1.9225 +
  1.9226 +      <para id="x_6c4">You might hope that there would be mechanisms you could
  1.9227 +	use to either figure out who has seen a change or to erase the
  1.9228 +	change permanently everywhere, but there are good reasons why
  1.9229 +	these are not possible.</para>
  1.9230 +
  1.9231 +      <para id="x_6c5">Mercurial does not provide an audit trail of who has
  1.9232 +	pulled changes from a repository, because it is usually either
  1.9233 +	impossible to record such information or trivial to spoof it.
  1.9234 +	In a multi-user or networked environment, you should thus be
  1.9235 +	extremely skeptical of yourself if you think that you have
  1.9236 +	identified every place that a sensitive changeset has
  1.9237 +	propagated to.  Don't forget that people can and will send
  1.9238 +	bundles by email, have their backup software save data
  1.9239 +	offsite, carry repositories on USB sticks, and find other
  1.9240 +	completely innocent ways to confound your attempts to track
  1.9241 +	down every copy of a problematic change.</para>
  1.9242 +
  1.9243 +      <para id="x_6c6">Mercurial also does not provide a way to make a file or
  1.9244 +	changeset completely disappear from history, because there is
  1.9245 +	no way to enforce its disappearance; someone could easily
  1.9246 +	modify their copy of Mercurial to ignore such directives. In
  1.9247 +	addition, even if Mercurial provided such a capability,
  1.9248 +	someone who simply hadn't pulled a <quote>make this file
  1.9249 +	  disappear</quote> changeset wouldn't be affected by it, nor
  1.9250 +	would web crawlers visiting at the wrong time, disk backups,
  1.9251 +	or other mechanisms.  Indeed, no distributed revision control
  1.9252 +	system can make data reliably vanish. Providing the illusion
  1.9253 +	of such control could easily give a false sense of security,
  1.9254 +	and be worse than not providing it at all.</para>
  1.9255 +    </sect2>
  1.9256 +  </sect1>
  1.9257 +
  1.9258 +  <sect1 id="sec:undo:bisect">
  1.9259 +    <title>Finding the source of a bug</title>
  1.9260 +
  1.9261 +    <para id="x_126">While it's all very well to be able to back out a changeset
  1.9262 +      that introduced a bug, this requires that you know which
  1.9263 +      changeset to back out.  Mercurial provides an invaluable
  1.9264 +      command, called <command role="hg-cmd" moreinfo="none">hg bisect</command>, that
  1.9265 +      helps you to automate this process and accomplish it very
  1.9266 +      efficiently.</para>
  1.9267 +
  1.9268 +    <para id="x_127">The idea behind the <command role="hg-cmd" moreinfo="none">hg
  1.9269 +	bisect</command> command is that a changeset has introduced
  1.9270 +      some change of behavior that you can identify with a simple
  1.9271 +      pass/fail test.  You don't know which piece of code introduced the
  1.9272 +      change, but you know how to test for the presence of the bug.
  1.9273 +      The <command role="hg-cmd" moreinfo="none">hg bisect</command> command uses your
  1.9274 +      test to direct its search for the changeset that introduced the
  1.9275 +      code that caused the bug.</para>
  1.9276 +
  1.9277 +    <para id="x_128">Here are a few scenarios to help you understand how you
  1.9278 +      might apply this command.</para>
  1.9279 +    <itemizedlist>
  1.9280 +      <listitem><para id="x_129">The most recent version of your software has a
  1.9281 +	  bug that you remember wasn't present a few weeks ago, but
  1.9282 +	  you don't know when it was introduced.  Here, your binary
  1.9283 +	  test checks for the presence of that bug.</para>
  1.9284 +      </listitem>
  1.9285 +      <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to
  1.9286 +	  close the entry in your team's bug database.  The bug
  1.9287 +	  database requires a changeset ID when you close an entry,
  1.9288 +	  but you don't remember which changeset you fixed the bug in.
  1.9289 +	  Once again, your binary test checks for the presence of the
  1.9290 +	  bug.</para>
  1.9291 +      </listitem>
  1.9292 +      <listitem><para id="x_12b">Your software works correctly, but runs 15%
  1.9293 +	  slower than the last time you measured it.  You want to know
  1.9294 +	  which changeset introduced the performance regression.  In
  1.9295 +	  this case, your binary test measures the performance of your
  1.9296 +	  software, to see whether it's <quote>fast</quote> or
  1.9297 +	  <quote>slow</quote>.</para>
  1.9298 +      </listitem>
  1.9299 +      <listitem><para id="x_12c">The sizes of the components of your project that
  1.9300 +	  you ship exploded recently, and you suspect that something
  1.9301 +	  changed in the way you build your project.</para>
  1.9302 +      </listitem></itemizedlist>
  1.9303 +
  1.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
  1.9305 +      for finding the sources of bugs.  You can use it to find any
  1.9306 +      <quote>emergent property</quote> of a repository (anything that
  1.9307 +      you can't find from a simple text search of the files in the
  1.9308 +      tree) for which you can write a binary test.</para>
  1.9309 +
  1.9310 +    <para id="x_12e">We'll introduce a little bit of terminology here, just to
  1.9311 +      make it clear which parts of the search process are your
  1.9312 +      responsibility, and which are Mercurial's.  A
  1.9313 +      <emphasis>test</emphasis> is something that
  1.9314 +      <emphasis>you</emphasis> run when <command role="hg-cmd" moreinfo="none">hg
  1.9315 +	bisect</command> chooses a changeset.  A
  1.9316 +      <emphasis>probe</emphasis> is what <command role="hg-cmd" moreinfo="none">hg
  1.9317 +	bisect</command> runs to tell whether a revision is good.
  1.9318 +      Finally, we'll use the word <quote>bisect</quote>, as both a
  1.9319 +      noun and a verb, to stand in for the phrase <quote>search using
  1.9320 +	the <command role="hg-cmd" moreinfo="none">hg bisect</command>
  1.9321 +	command</quote>.</para>
  1.9322 +
  1.9323 +    <para id="x_12f">One simple way to automate the searching process would be
  1.9324 +      simply to probe every changeset.  However, this scales poorly.
  1.9325 +      If it took ten minutes to test a single changeset, and you had
  1.9326 +      10,000 changesets in your repository, the exhaustive approach
  1.9327 +      would take on average 35 <emphasis>days</emphasis> to find the
  1.9328 +      changeset that introduced a bug.  Even if you knew that the bug
  1.9329 +      was introduced by one of the last 500 changesets, and limited
  1.9330 +      your search to those, you'd still be looking at over 40 hours to
  1.9331 +      find the changeset that introduced your bug.</para>
  1.9332 +
  1.9333 +    <para id="x_130">What the <command role="hg-cmd" moreinfo="none">hg bisect</command> command
  1.9334 +      does is use its knowledge of the <quote>shape</quote> of your
  1.9335 +      project's revision history to perform a search in time
  1.9336 +      proportional to the <emphasis>logarithm</emphasis> of the number
  1.9337 +      of changesets to check (the kind of search it performs is called
  1.9338 +      a dichotomic search).  With this approach, searching through
  1.9339 +      10,000 changesets will take less than three hours, even at ten
  1.9340 +      minutes per test (the search will require about 14 tests).
  1.9341 +      Limit your search to the last hundred changesets, and it will
  1.9342 +      take only about an hour (roughly seven tests).</para>
  1.9343 +
  1.9344 +    <para id="x_131">The <command role="hg-cmd" moreinfo="none">hg bisect</command> command is
  1.9345 +      aware of the <quote>branchy</quote> nature of a Mercurial
  1.9346 +      project's revision history, so it has no problems dealing with
  1.9347 +      branches, merges, or multiple heads in a repository.  It can
  1.9348 +      prune entire branches of history with a single probe, which is
  1.9349 +      how it operates so efficiently.</para>
  1.9350 +
  1.9351 +    <sect2>
  1.9352 +      <title>Using the <command role="hg-cmd" moreinfo="none">hg bisect</command>
  1.9353 +	command</title>
  1.9354 +
  1.9355 +      <para id="x_132">Here's an example of <command role="hg-cmd" moreinfo="none">hg
  1.9356 +	  bisect</command> in action.</para>
  1.9357 +
  1.9358 +      <note>
  1.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:
  1.9360 +	  it was distributed with Mercurial as an extension. This
  1.9361 +	  section describes the built-in command, not the old
  1.9362 +	  extension.</para>
  1.9363 +      </note>
  1.9364 +
  1.9365 +      <para id="x_134">Now let's create a repository, so that we can try out the
  1.9366 +	<command role="hg-cmd" moreinfo="none">hg bisect</command> command in
  1.9367 +	isolation.</para>
  1.9368 +
  1.9369 +      <!-- BEGIN bisect.init -->
  1.9370 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init mybug</userinput>
  1.9371 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd mybug</userinput>
  1.9372 +</screen>
  1.9373 +<!-- END bisect.init -->
  1.9374 +
  1.9375 +
  1.9376 +      <para id="x_135">We'll simulate a project that has a bug in it in a
  1.9377 +	simple-minded way: create trivial changes in a loop, and
  1.9378 +	nominate one specific change that will have the
  1.9379 +	<quote>bug</quote>.  This loop creates 35 changesets, each
  1.9380 +	adding a single file to the repository. We'll represent our
  1.9381 +	<quote>bug</quote> with a file that contains the text <quote>i
  1.9382 +	  have a gub</quote>.</para>
  1.9383 +
  1.9384 +      <!-- BEGIN bisect.commits -->
  1.9385 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">buggy_change=22</userinput>
  1.9386 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">for (( i = 0; i &lt; 35; i++ )); do</userinput>
  1.9387 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  if [[ $i = $buggy_change ]]; then</userinput>
  1.9388 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    echo 'i have a gub' &gt; myfile$i</userinput>
  1.9389 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    hg commit -q -A -m 'buggy changeset'</userinput>
  1.9390 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  else</userinput>
  1.9391 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    echo 'nothing to see here, move along' &gt; myfile$i</userinput>
  1.9392 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    hg commit -q -A -m 'normal changeset'</userinput>
  1.9393 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  fi</userinput>
  1.9394 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">done</userinput>
  1.9395 +</screen>
  1.9396 +<!-- END bisect.commits -->
  1.9397 +
  1.9398 +
  1.9399 +      <para id="x_136">The next thing that we'd like to do is figure out how to
  1.9400 +	use the <command role="hg-cmd" moreinfo="none">hg bisect</command> command.
  1.9401 +	We can use Mercurial's normal built-in help mechanism for
  1.9402 +	this.</para>
  1.9403 +
  1.9404 +      <!-- BEGIN bisect.help -->
  1.9405 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg help bisect</userinput>
  1.9406 +hg bisect [-gbsr] [-c CMD] [REV]
  1.9407 +
  1.9408 +subdivision search of changesets
  1.9409 +
  1.9410 +    This command helps to find changesets which introduce problems.
  1.9411 +    To use, mark the earliest changeset you know exhibits the problem
  1.9412 +    as bad, then mark the latest changeset which is free from the
  1.9413 +    problem as good. Bisect will update your working directory to a
  1.9414 +    revision for testing (unless the --noupdate option is specified).
  1.9415 +    Once you have performed tests, mark the working directory as bad
  1.9416 +    or good and bisect will either update to another candidate changeset
  1.9417 +    or announce that it has found the bad revision.
  1.9418 +
  1.9419 +    As a shortcut, you can also use the revision argument to mark a
  1.9420 +    revision as good or bad without checking it out first.
  1.9421 +
  1.9422 +    If you supply a command it will be used for automatic bisection. Its exit
  1.9423 +    status will be used as flag to mark revision as bad or good. In case exit
  1.9424 +    status is 0 the revision is marked as good, 125 - skipped, 127 (command not
  1.9425 +    found) - bisection will be aborted; any other status bigger than 0 will
  1.9426 +    mark revision as bad.
  1.9427 +
  1.9428 +options:
  1.9429 +
  1.9430 + -r --reset     reset bisect state
  1.9431 + -g --good      mark changeset good
  1.9432 + -b --bad       mark changeset bad
  1.9433 + -s --skip      skip testing changeset
  1.9434 + -c --command   use command to check changeset state
  1.9435 + -U --noupdate  do not update to target
  1.9436 +
  1.9437 +use "hg -v help bisect" to show global options
  1.9438 +</screen>
  1.9439 +<!-- END bisect.help -->
  1.9440 +
  1.9441 +
  1.9442 +      <para id="x_137">The <command role="hg-cmd" moreinfo="none">hg bisect</command> command
  1.9443 +	works in steps.  Each step proceeds as follows.</para>
  1.9444 +      <orderedlist inheritnum="ignore" continuation="restarts">
  1.9445 +	<listitem><para id="x_138">You run your binary test.</para>
  1.9446 +	  <itemizedlist>
  1.9447 +	    <listitem><para id="x_139">If the test succeeded, you tell <command role="hg-cmd" moreinfo="none">hg bisect</command> by running the
  1.9448 +		<command role="hg-cmd" moreinfo="none">hg bisect --good</command>
  1.9449 +		command.</para>
  1.9450 +	    </listitem>
  1.9451 +	    <listitem><para id="x_13a">If it failed, run the <command role="hg-cmd" moreinfo="none">hg bisect --bad</command>
  1.9452 +		command.</para></listitem></itemizedlist>
  1.9453 +	</listitem>
  1.9454 +	<listitem><para id="x_13b">The command uses your information to decide
  1.9455 +	    which changeset to test next.</para>
  1.9456 +	</listitem>
  1.9457 +	<listitem><para id="x_13c">It updates the working directory to that
  1.9458 +	    changeset, and the process begins again.</para>
  1.9459 +	</listitem></orderedlist>
  1.9460 +      <para id="x_13d">The process ends when <command role="hg-cmd" moreinfo="none">hg
  1.9461 +	  bisect</command> identifies a unique changeset that marks
  1.9462 +	the point where your test transitioned from
  1.9463 +	<quote>succeeding</quote> to <quote>failing</quote>.</para>
  1.9464 +
  1.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>
  1.9466 +
  1.9467 +      <!-- BEGIN bisect.search.init -->
  1.9468 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --reset</userinput>
  1.9469 +</screen>
  1.9470 +<!-- END bisect.search.init -->
  1.9471 +
  1.9472 +
  1.9473 +      <para id="x_13f">In our case, the binary test we use is simple: we check to
  1.9474 +	see if any file in the repository contains the string <quote>i
  1.9475 +	  have a gub</quote>.  If it does, this changeset contains the
  1.9476 +	change that <quote>caused the bug</quote>.  By convention, a
  1.9477 +	changeset that has the property we're searching for is
  1.9478 +	<quote>bad</quote>, while one that doesn't is
  1.9479 +	<quote>good</quote>.</para>
  1.9480 +
  1.9481 +      <para id="x_140">Most of the time, the revision to which the working
  1.9482 +	directory is synced (usually the tip) already exhibits the
  1.9483 +	problem introduced by the buggy change, so we'll mark it as
  1.9484 +	<quote>bad</quote>.</para>
  1.9485 +
  1.9486 +      <!-- BEGIN bisect.search.bad-init -->
  1.9487 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --bad</userinput>
  1.9488 +</screen>
  1.9489 +<!-- END bisect.search.bad-init -->
  1.9490 +
  1.9491 +
  1.9492 +      <para id="x_141">Our next task is to nominate a changeset that we know
  1.9493 +	<emphasis>doesn't</emphasis> have the bug; the <command role="hg-cmd" moreinfo="none">hg bisect</command> command will
  1.9494 +	<quote>bracket</quote> its search between the first pair of
  1.9495 +	good and bad changesets.  In our case, we know that revision
  1.9496 +	10 didn't have the bug.  (I'll have more words about choosing
  1.9497 +	the first <quote>good</quote> changeset later.)</para>
  1.9498 +
  1.9499 +      <!-- BEGIN bisect.search.good-init -->
  1.9500 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --good 10</userinput>
  1.9501 +Testing changeset 22:69f52b967ab8 (24 changesets remaining, ~4 tests)
  1.9502 +0 files updated, 0 files merged, 12 files removed, 0 files unresolved
  1.9503 +</screen>
  1.9504 +<!-- END bisect.search.good-init -->
  1.9505 +
  1.9506 +
  1.9507 +      <para id="x_142">Notice that this command printed some output.</para>
  1.9508 +      <itemizedlist>
  1.9509 +	<listitem><para id="x_143">It told us how many changesets it must
  1.9510 +	    consider before it can identify the one that introduced
  1.9511 +	    the bug, and how many tests that will require.</para>
  1.9512 +	</listitem>
  1.9513 +	<listitem><para id="x_144">It updated the working directory to the next
  1.9514 +	    changeset to test, and told us which changeset it's
  1.9515 +	    testing.</para>
  1.9516 +	</listitem></itemizedlist>
  1.9517 +
  1.9518 +      <para id="x_145">We now run our test in the working directory.  We use the
  1.9519 +	<command moreinfo="none">grep</command> command to see if our
  1.9520 +	<quote>bad</quote> file is present in the working directory.
  1.9521 +	If it is, this revision is bad; if not, this revision is good.
  1.9522 +	<!-- BEGIN bisect.search.step1 -->
  1.9523 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">if grep -q 'i have a gub' *</userinput>
  1.9524 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">then</userinput>
  1.9525 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  result=bad</userinput>
  1.9526 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">else</userinput>
  1.9527 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  result=good</userinput>
  1.9528 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">fi</userinput>
  1.9529 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo this revision is $result</userinput>
  1.9530 +this revision is bad
  1.9531 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --$result</userinput>
  1.9532 +Testing changeset 16:f1dd8bc690ae (12 changesets remaining, ~3 tests)
  1.9533 +0 files updated, 0 files merged, 6 files removed, 0 files unresolved
  1.9534 +</screen>
  1.9535 +<!-- END bisect.search.step1 -->
  1.9536 +</para>
  1.9537 +
  1.9538 +      <para id="x_146">This test looks like a perfect candidate for automation,
  1.9539 +	so let's turn it into a shell function.</para>
  1.9540 +      <!-- BEGIN bisect.search.mytest -->
  1.9541 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest() {</userinput>
  1.9542 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  if grep -q 'i have a gub' *</userinput>
  1.9543 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  then</userinput>
  1.9544 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    result=bad</userinput>
  1.9545 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  else</userinput>
  1.9546 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">    result=good</userinput>
  1.9547 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  fi</userinput>
  1.9548 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  echo this revision is $result</userinput>
  1.9549 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">  hg bisect --$result</userinput>
  1.9550 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">}</userinput>
  1.9551 +</screen>
  1.9552 +<!-- END bisect.search.mytest -->
  1.9553 +
  1.9554 +
  1.9555 +      <para id="x_147">We can now run an entire test step with a single command,
  1.9556 +	<literal moreinfo="none">mytest</literal>.</para>
  1.9557 +
  1.9558 +      <!-- BEGIN bisect.search.step2 -->
  1.9559 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  1.9560 +this revision is good
  1.9561 +Testing changeset 19:88d99d97058a (6 changesets remaining, ~2 tests)
  1.9562 +3 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.9563 +</screen>
  1.9564 +<!-- END bisect.search.step2 -->
  1.9565 +
  1.9566 +
  1.9567 +      <para id="x_148">A few more invocations of our canned test step command,
  1.9568 +	and we're done.</para>
  1.9569 +
  1.9570 +      <!-- BEGIN bisect.search.rest -->
  1.9571 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  1.9572 +this revision is good
  1.9573 +Testing changeset 20:32a195a31d51 (3 changesets remaining, ~1 tests)
  1.9574 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.9575 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  1.9576 +this revision is good
  1.9577 +Testing changeset 21:a2efe8e4f624 (2 changesets remaining, ~1 tests)
  1.9578 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  1.9579 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">mytest</userinput>
  1.9580 +this revision is good
  1.9581 +The first bad revision is:
  1.9582 +changeset:   22:69f52b967ab8
  1.9583 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
  1.9584 +date:        Sun Aug 16 14:04:39 2009 +0000
  1.9585 +summary:     buggy changeset
  1.9586 +
  1.9587 +</screen>
  1.9588 +<!-- END bisect.search.rest -->
  1.9589 +
  1.9590 +
  1.9591 +      <para id="x_149">Even though we had 40 changesets to search through, the
  1.9592 +	<command role="hg-cmd" moreinfo="none">hg bisect</command> command let us find
  1.9593 +	the changeset that introduced our <quote>bug</quote> with only
  1.9594 +	five tests.  Because the number of tests that the <command role="hg-cmd" moreinfo="none">hg bisect</command> command performs grows
  1.9595 +	logarithmically with the number of changesets to search, the
  1.9596 +	advantage that it has over the <quote>brute force</quote>
  1.9597 +	search approach increases with every changeset you add.</para>
  1.9598 +
  1.9599 +    </sect2>
  1.9600 +    <sect2>
  1.9601 +      <title>Cleaning up after your search</title>
  1.9602 +
  1.9603 +      <para id="x_14a">When you're finished using the <command role="hg-cmd" moreinfo="none">hg
  1.9604 +	  bisect</command> command in a repository, you can use the
  1.9605 +	<command role="hg-cmd" moreinfo="none">hg bisect --reset</command> command to
  1.9606 +	drop the information it was using to drive your search.  The
  1.9607 +	command doesn't use much space, so it doesn't matter if you
  1.9608 +	forget to run this command.  However, <command role="hg-cmd" moreinfo="none">hg bisect</command> won't let you start a new
  1.9609 +	search in that repository until you do a <command role="hg-cmd" moreinfo="none">hg bisect --reset</command>.</para>
  1.9610 +
  1.9611 +      <!-- BEGIN bisect.search.reset -->
  1.9612 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg bisect --reset</userinput>
  1.9613 +</screen>
  1.9614 +<!-- END bisect.search.reset -->
  1.9615 +
  1.9616 +
  1.9617 +    </sect2>
  1.9618 +  </sect1>
  1.9619 +  <sect1>
  1.9620 +    <title>Tips for finding bugs effectively</title>
  1.9621 +
  1.9622 +    <sect2>
  1.9623 +      <title>Give consistent input</title>
  1.9624 +
  1.9625 +      <para id="x_14b">The <command role="hg-cmd" moreinfo="none">hg bisect</command> command
  1.9626 +	requires that you correctly report the result of every test
  1.9627 +	you perform.  If you tell it that a test failed when it really
  1.9628 +	succeeded, it <emphasis>might</emphasis> be able to detect the
  1.9629 +	inconsistency.  If it can identify an inconsistency in your
  1.9630 +	reports, it will tell you that a particular changeset is both
  1.9631 +	good and bad. However, it can't do this perfectly; it's about
  1.9632 +	as likely to report the wrong changeset as the source of the
  1.9633 +	bug.</para>
  1.9634 +
  1.9635 +    </sect2>
  1.9636 +    <sect2>
  1.9637 +      <title>Automate as much as possible</title>
  1.9638 +
  1.9639 +      <para id="x_14c">When I started using the <command role="hg-cmd" moreinfo="none">hg
  1.9640 +	  bisect</command> command, I tried a few times to run my
  1.9641 +	tests by hand, on the command line.  This is an approach that
  1.9642 +	I, at least, am not suited to.  After a few tries, I found
  1.9643 +	that I was making enough mistakes that I was having to restart
  1.9644 +	my searches several times before finally getting correct
  1.9645 +	results.</para>
  1.9646 +
  1.9647 +      <para id="x_14d">My initial problems with driving the <command role="hg-cmd" moreinfo="none">hg bisect</command> command by hand occurred
  1.9648 +	even with simple searches on small repositories; if the
  1.9649 +	problem you're looking for is more subtle, or the number of
  1.9650 +	tests that <command role="hg-cmd" moreinfo="none">hg bisect</command> must
  1.9651 +	perform increases, the likelihood of operator error ruining
  1.9652 +	the search is much higher.  Once I started automating my
  1.9653 +	tests, I had much better results.</para>
  1.9654 +
  1.9655 +      <para id="x_14e">The key to automated testing is twofold:</para>
  1.9656 +      <itemizedlist>
  1.9657 +	<listitem><para id="x_14f">always test for the same symptom, and</para>
  1.9658 +	</listitem>
  1.9659 +	<listitem><para id="x_150">always feed consistent input to the <command role="hg-cmd" moreinfo="none">hg bisect</command> command.</para>
  1.9660 +	</listitem></itemizedlist>
  1.9661 +      <para id="x_151">In my tutorial example above, the <command moreinfo="none">grep</command>
  1.9662 +	command tests for the symptom, and the <literal moreinfo="none">if</literal>
  1.9663 +	statement takes the result of this check and ensures that we
  1.9664 +	always feed the same input to the <command role="hg-cmd" moreinfo="none">hg
  1.9665 +	  bisect</command> command.  The <literal moreinfo="none">mytest</literal>
  1.9666 +	function marries these together in a reproducible way, so that
  1.9667 +	every test is uniform and consistent.</para>
  1.9668 +
  1.9669 +    </sect2>
  1.9670 +    <sect2>
  1.9671 +      <title>Check your results</title>
  1.9672 +
  1.9673 +      <para id="x_152">Because the output of a <command role="hg-cmd" moreinfo="none">hg
  1.9674 +	  bisect</command> search is only as good as the input you
  1.9675 +	give it, don't take the changeset it reports as the absolute
  1.9676 +	truth.  A simple way to cross-check its report is to manually
  1.9677 +	run your test at each of the following changesets:</para>
  1.9678 +      <itemizedlist>
  1.9679 +	<listitem><para id="x_153">The changeset that it reports as the first bad
  1.9680 +	    revision.  Your test should still report this as
  1.9681 +	    bad.</para>
  1.9682 +	</listitem>
  1.9683 +	<listitem><para id="x_154">The parent of that changeset (either parent,
  1.9684 +	    if it's a merge). Your test should report this changeset
  1.9685 +	    as good.</para>
  1.9686 +	</listitem>
  1.9687 +	<listitem><para id="x_155">A child of that changeset.  Your test should
  1.9688 +	    report this changeset as bad.</para>
  1.9689 +	</listitem></itemizedlist>
  1.9690 +
  1.9691 +    </sect2>
  1.9692 +    <sect2>
  1.9693 +      <title>Beware interference between bugs</title>
  1.9694 +
  1.9695 +      <para id="x_156">It's possible that your search for one bug could be
  1.9696 +	disrupted by the presence of another.  For example, let's say
  1.9697 +	your software crashes at revision 100, and worked correctly at
  1.9698 +	revision 50.  Unknown to you, someone else introduced a
  1.9699 +	different crashing bug at revision 60, and fixed it at
  1.9700 +	revision 80.  This could distort your results in one of
  1.9701 +	several ways.</para>
  1.9702 +
  1.9703 +      <para id="x_157">It is possible that this other bug completely
  1.9704 +	<quote>masks</quote> yours, which is to say that it occurs
  1.9705 +	before your bug has a chance to manifest itself.  If you can't
  1.9706 +	avoid that other bug (for example, it prevents your project
  1.9707 +	from building), and so can't tell whether your bug is present
  1.9708 +	in a particular changeset, the <command role="hg-cmd" moreinfo="none">hg
  1.9709 +	  bisect</command> command cannot help you directly.  Instead,
  1.9710 +	you can mark a changeset as untested by running <command role="hg-cmd" moreinfo="none">hg bisect --skip</command>.</para>
  1.9711 +
  1.9712 +      <para id="x_158">A different problem could arise if your test for a bug's
  1.9713 +	presence is not specific enough.  If you check for <quote>my
  1.9714 +	  program crashes</quote>, then both your crashing bug and an
  1.9715 +	unrelated crashing bug that masks it will look like the same
  1.9716 +	thing, and mislead <command role="hg-cmd" moreinfo="none">hg
  1.9717 +	  bisect</command>.</para>
  1.9718 +
  1.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
  1.9720 +	test a revision because your project was in a broken and hence
  1.9721 +	untestable state at that revision, perhaps because someone
  1.9722 +	checked in a change that prevented the project from
  1.9723 +	building.</para>
  1.9724 +
  1.9725 +    </sect2>
  1.9726 +    <sect2>
  1.9727 +      <title>Bracket your search lazily</title>
  1.9728 +
  1.9729 +      <para id="x_15a">Choosing the first <quote>good</quote> and
  1.9730 +	<quote>bad</quote> changesets that will mark the end points of
  1.9731 +	your search is often easy, but it bears a little discussion
  1.9732 +	nevertheless.  From the perspective of <command role="hg-cmd" moreinfo="none">hg bisect</command>, the <quote>newest</quote>
  1.9733 +	changeset is conventionally <quote>bad</quote>, and the older
  1.9734 +	changeset is <quote>good</quote>.</para>
  1.9735 +
  1.9736 +      <para id="x_15b">If you're having trouble remembering when a suitable
  1.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
  1.9738 +	testing changesets at random.  Just remember to eliminate
  1.9739 +	contenders that can't possibly exhibit the bug (perhaps
  1.9740 +	because the feature with the bug isn't present yet) and those
  1.9741 +	where another problem masks the bug (as I discussed
  1.9742 +	above).</para>
  1.9743 +
  1.9744 +      <para id="x_15c">Even if you end up <quote>early</quote> by thousands of
  1.9745 +	changesets or months of history, you will only add a handful
  1.9746 +	of tests to the total number that <command role="hg-cmd" moreinfo="none">hg
  1.9747 +	  bisect</command> must perform, thanks to its logarithmic
  1.9748 +	behavior.</para>
  1.9749 +
  1.9750 +    </sect2>
  1.9751 +  </sect1>
  1.9752 +</chapter>
  1.9753 +
  1.9754 +<!--
  1.9755 +local variables: 
  1.9756 +sgml-parent-document: ("00book.xml" "book" "chapter")
  1.9757 +end:
  1.9758 +-->
  1.9759 +
  1.9760 +  <!-- BEGIN ch10 -->
  1.9761 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
  1.9762 +
  1.9763 +<chapter id="chap:hook">
  1.9764 +  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
  1.9765 +  <title>Handling repository events with hooks</title>
  1.9766 +
  1.9767 +  <para id="x_1e6">Mercurial offers a powerful mechanism to let you perform
  1.9768 +    automated actions in response to events that occur in a
  1.9769 +    repository.  In some cases, you can even control Mercurial's
  1.9770 +    response to those events.</para>
  1.9771 +
  1.9772 +  <para id="x_1e7">The name Mercurial uses for one of these actions is a
  1.9773 +    <emphasis>hook</emphasis>. Hooks are called
  1.9774 +    <quote>triggers</quote> in some revision control systems, but the
  1.9775 +    two names refer to the same idea.</para>
  1.9776 +
  1.9777 +  <sect1>
  1.9778 +    <title>An overview of hooks in Mercurial</title>
  1.9779 +
  1.9780 +    <para id="x_1e8">Here is a brief list of the hooks that Mercurial
  1.9781 +      supports. We will revisit each of these hooks in more detail
  1.9782 +      later, in <xref linkend="sec:hook:ref"/>.</para>
  1.9783 +
  1.9784 +    <para id="x_1f6">Each of the hooks whose description begins with the word
  1.9785 +      <quote>Controlling</quote> has the ability to determine whether
  1.9786 +      an activity can proceed.  If the hook succeeds, the activity may
  1.9787 +      proceed; if it fails, the activity is either not permitted or
  1.9788 +      undone, depending on the hook.</para>
  1.9789 +
  1.9790 +    <itemizedlist>
  1.9791 +      <listitem><para id="x_1e9"><literal role="hook" moreinfo="none">changegroup</literal>: This
  1.9792 +	  is run after a group of changesets has been brought into the
  1.9793 +	  repository from elsewhere.</para>
  1.9794 +      </listitem>
  1.9795 +      <listitem><para id="x_1ea"><literal role="hook" moreinfo="none">commit</literal>: This is
  1.9796 +	  run after a new changeset has been created in the local
  1.9797 +	  repository.</para>
  1.9798 +      </listitem>
  1.9799 +      <listitem><para id="x_1eb"><literal role="hook" moreinfo="none">incoming</literal>: This is
  1.9800 +	  run once for each new changeset that is brought into the
  1.9801 +	  repository from elsewhere.  Notice the difference from
  1.9802 +	  <literal role="hook" moreinfo="none">changegroup</literal>, which is run
  1.9803 +	  once per <emphasis>group</emphasis> of changesets brought
  1.9804 +	  in.</para>
  1.9805 +      </listitem>
  1.9806 +      <listitem><para id="x_1ec"><literal role="hook" moreinfo="none">outgoing</literal>: This is
  1.9807 +	  run after a group of changesets has been transmitted from
  1.9808 +	  this repository.</para>
  1.9809 +      </listitem>
  1.9810 +      <listitem><para id="x_1ed"><literal role="hook" moreinfo="none">prechangegroup</literal>:
  1.9811 +	  This is run before starting to bring a group of changesets
  1.9812 +	  into the repository.
  1.9813 +	</para>
  1.9814 +      </listitem>
  1.9815 +      <listitem><para id="x_1ee"><literal role="hook" moreinfo="none">precommit</literal>:
  1.9816 +	  Controlling. This is run before starting a commit.
  1.9817 +	</para>
  1.9818 +      </listitem>
  1.9819 +      <listitem><para id="x_1ef"><literal role="hook" moreinfo="none">preoutgoing</literal>:
  1.9820 +	  Controlling. This is run before starting to transmit a group
  1.9821 +	  of changesets from this repository.
  1.9822 +	</para>
  1.9823 +      </listitem>
  1.9824 +      <listitem><para id="x_1f0"><literal role="hook" moreinfo="none">pretag</literal>:
  1.9825 +	  Controlling. This is run before creating a tag.
  1.9826 +	</para>
  1.9827 +      </listitem>
  1.9828 +      <listitem><para id="x_1f1"><literal role="hook" moreinfo="none">pretxnchangegroup</literal>: Controlling. This
  1.9829 +	  is run after a group of changesets has been brought into the
  1.9830 +	  local repository from another, but before the transaction
  1.9831 +	  completes that will make the changes permanent in the
  1.9832 +	  repository.
  1.9833 +	</para>
  1.9834 +      </listitem>
  1.9835 +      <listitem><para id="x_1f2"><literal role="hook" moreinfo="none">pretxncommit</literal>:
  1.9836 +	  Controlling. This is run after a new changeset has been
  1.9837 +	  created in the local repository, but before the transaction
  1.9838 +	  completes that will make it permanent.
  1.9839 +	</para>
  1.9840 +      </listitem>
  1.9841 +      <listitem><para id="x_1f3"><literal role="hook" moreinfo="none">preupdate</literal>:
  1.9842 +	  Controlling. This is run before starting an update or merge
  1.9843 +	  of the working directory.
  1.9844 +	</para>
  1.9845 +      </listitem>
  1.9846 +      <listitem><para id="x_1f4"><literal role="hook" moreinfo="none">tag</literal>: This is run
  1.9847 +	  after a tag is created.
  1.9848 +	</para>
  1.9849 +      </listitem>
  1.9850 +      <listitem><para id="x_1f5"><literal role="hook" moreinfo="none">update</literal>: This is
  1.9851 +	  run after an update or merge of the working directory has
  1.9852 +	  finished.
  1.9853 +	</para>
  1.9854 +      </listitem></itemizedlist>
  1.9855 +
  1.9856 +  </sect1>
  1.9857 +  <sect1>
  1.9858 +    <title>Hooks and security</title>
  1.9859 +
  1.9860 +    <sect2>
  1.9861 +      <title>Hooks are run with your privileges</title>
  1.9862 +
  1.9863 +      <para id="x_1f7">When you run a Mercurial command in a repository, and the
  1.9864 +	command causes a hook to run, that hook runs on
  1.9865 +	<emphasis>your</emphasis> system, under
  1.9866 +	<emphasis>your</emphasis> user account, with
  1.9867 +	<emphasis>your</emphasis> privilege level.  Since hooks are
  1.9868 +	arbitrary pieces of executable code, you should treat them
  1.9869 +	with an appropriate level of suspicion.  Do not install a hook
  1.9870 +	unless you are confident that you know who created it and what
  1.9871 +	it does.
  1.9872 +      </para>
  1.9873 +
  1.9874 +      <para id="x_1f8">In some cases, you may be exposed to hooks that you did
  1.9875 +	not install yourself.  If you work with Mercurial on an
  1.9876 +	unfamiliar system, Mercurial will run hooks defined in that
  1.9877 +	system's global <filename role="special" moreinfo="none">~/.hgrc</filename>
  1.9878 +	file.
  1.9879 +      </para>
  1.9880 +
  1.9881 +      <para id="x_1f9">If you are working with a repository owned by another
  1.9882 +	user, Mercurial can run hooks defined in that user's
  1.9883 +	repository, but it will still run them as <quote>you</quote>.
  1.9884 +	For example, if you <command role="hg-cmd" moreinfo="none">hg pull</command>
  1.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
  1.9886 +	under your user account, even though you don't own that
  1.9887 +	repository.
  1.9888 +      </para>
  1.9889 +
  1.9890 +      <note>
  1.9891 +	<para id="x_1fa">  This only applies if you are pulling from a repository
  1.9892 +	  on a local or network filesystem.  If you're pulling over
  1.9893 +	  http or ssh, any <literal role="hook" moreinfo="none">outgoing</literal>
  1.9894 +	  hook will run under whatever account is executing the server
  1.9895 +	  process, on the server.
  1.9896 +	</para>
  1.9897 +      </note>
  1.9898 +
  1.9899 +      <para id="x_1fb">To see what hooks are defined in a repository,
  1.9900 +	use the <command role="hg-cmd" moreinfo="none">hg showconfig hooks</command>
  1.9901 +	command.  If you are working in one repository, but talking to
  1.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
  1.9903 +	  incoming</command>), remember that it is the other
  1.9904 +	repository's hooks you should be checking, not your own.
  1.9905 +      </para>
  1.9906 +    </sect2>
  1.9907 +
  1.9908 +    <sect2>
  1.9909 +      <title>Hooks do not propagate</title>
  1.9910 +
  1.9911 +      <para id="x_1fc">In Mercurial, hooks are not revision controlled, and do
  1.9912 +	not propagate when you clone, or pull from, a repository.  The
  1.9913 +	reason for this is simple: a hook is a completely arbitrary
  1.9914 +	piece of executable code.  It runs under your user identity,
  1.9915 +	with your privilege level, on your machine.
  1.9916 +      </para>
  1.9917 +
  1.9918 +      <para id="x_1fd">It would be extremely reckless for any distributed
  1.9919 +	revision control system to implement revision-controlled
  1.9920 +	hooks, as this would offer an easily exploitable way to
  1.9921 +	subvert the accounts of users of the revision control system.
  1.9922 +      </para>
  1.9923 +
  1.9924 +      <para id="x_1fe">Since Mercurial does not propagate hooks, if you are
  1.9925 +	collaborating with other people on a common project, you
  1.9926 +	should not assume that they are using the same Mercurial hooks
  1.9927 +	as you are, or that theirs are correctly configured.  You
  1.9928 +	should document the hooks you expect people to use.
  1.9929 +      </para>
  1.9930 +
  1.9931 +      <para id="x_1ff">In a corporate intranet, this is somewhat easier to
  1.9932 +	control, as you can for example provide a
  1.9933 +	<quote>standard</quote> installation of Mercurial on an NFS
  1.9934 +	filesystem, and use a site-wide <filename role="special" moreinfo="none">~/.hgrc</filename> file to define hooks that all users will
  1.9935 +	see.  However, this too has its limits; see below.
  1.9936 +      </para>
  1.9937 +    </sect2>
  1.9938 +
  1.9939 +    <sect2>
  1.9940 +      <title>Hooks can be overridden</title>
  1.9941 +
  1.9942 +      <para id="x_200">Mercurial allows you to override a hook definition by
  1.9943 +	redefining the hook.  You can disable it by setting its value
  1.9944 +	to the empty string, or change its behavior as you wish.
  1.9945 +      </para>
  1.9946 +
  1.9947 +      <para id="x_201">If you deploy a system- or site-wide <filename role="special" moreinfo="none">~/.hgrc</filename> file that defines some
  1.9948 +	hooks, you should thus understand that your users can disable
  1.9949 +	or override those hooks.
  1.9950 +      </para>
  1.9951 +    </sect2>
  1.9952 +
  1.9953 +    <sect2>
  1.9954 +      <title>Ensuring that critical hooks are run</title>
  1.9955 +
  1.9956 +      <para id="x_202">Sometimes you may want to enforce a policy that you do not
  1.9957 +	want others to be able to work around.  For example, you may
  1.9958 +	have a requirement that every changeset must pass a rigorous
  1.9959 +	set of tests.  Defining this requirement via a hook in a
  1.9960 +	site-wide <filename role="special" moreinfo="none">~/.hgrc</filename> won't
  1.9961 +	work for remote users on laptops, and of course local users
  1.9962 +	can subvert it at will by overriding the hook.
  1.9963 +      </para>
  1.9964 +
  1.9965 +      <para id="x_203">Instead, you can set up your policies for use of Mercurial
  1.9966 +	so that people are expected to propagate changes through a
  1.9967 +	well-known <quote>canonical</quote> server that you have
  1.9968 +	locked down and configured appropriately.
  1.9969 +      </para>
  1.9970 +
  1.9971 +      <para id="x_204">One way to do this is via a combination of social
  1.9972 +	engineering and technology.  Set up a restricted-access
  1.9973 +	account; users can push changes over the network to
  1.9974 +	repositories managed by this account, but they cannot log into
  1.9975 +	the account and run normal shell commands.  In this scenario,
  1.9976 +	a user can commit a changeset that contains any old garbage
  1.9977 +	they want.
  1.9978 +      </para>
  1.9979 +
  1.9980 +      <para id="x_205">When someone pushes a changeset to the server that
  1.9981 +	everyone pulls from, the server will test the changeset before
  1.9982 +	it accepts it as permanent, and reject it if it fails to pass
  1.9983 +	the test suite.  If people only pull changes from this
  1.9984 +	filtering server, it will serve to ensure that all changes
  1.9985 +	that people pull have been automatically vetted.
  1.9986 +      </para>
  1.9987 +
  1.9988 +    </sect2>
  1.9989 +  </sect1>
  1.9990 +
  1.9991 +  <sect1 id="sec:hook:simple">
  1.9992 +    <title>A short tutorial on using hooks</title>
  1.9993 +
  1.9994 +    <para id="x_212">It is easy to write a Mercurial hook.  Let's start with a
  1.9995 +      hook that runs when you finish a <command role="hg-cmd" moreinfo="none">hg
  1.9996 +	commit</command>, and simply prints the hash of the changeset
  1.9997 +      you just created.  The hook is called <literal role="hook" moreinfo="none">commit</literal>.
  1.9998 +    </para>
  1.9999 +
 1.10000 +    <para id="x_213">All hooks follow the pattern in this example.</para>
 1.10001 +
 1.10002 +<!-- BEGIN hook.simple.init -->
 1.10003 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init hook-test</userinput>
 1.10004 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd hook-test</userinput>
 1.10005 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo '[hooks]' &gt;&gt; .hg/hgrc</userinput>
 1.10006 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'commit = echo committed $HG_NODE' &gt;&gt; .hg/hgrc</userinput>
 1.10007 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 1.10008 +[hooks]
 1.10009 +commit = echo committed $HG_NODE
 1.10010 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 1.10011 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 1.10012 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'testing commit hook'</userinput>
 1.10013 +committed 13a334d1e5ca83fea465aa779110eec3c5ddd6b1
 1.10014 +</screen>
 1.10015 +<!-- END hook.simple.init -->
 1.10016 +
 1.10017 +
 1.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
 1.10019 +      the event to trigger on; on the right is the action to take.  As
 1.10020 +      you can see, you can run an arbitrary shell command in a hook.
 1.10021 +      Mercurial passes extra information to the hook using environment
 1.10022 +      variables (look for <envar>HG_NODE</envar> in the example).
 1.10023 +    </para>
 1.10024 +
 1.10025 +    <sect2>
 1.10026 +      <title>Performing multiple actions per event</title>
 1.10027 +
 1.10028 +      <para id="x_215">Quite often, you will want to define more than one hook
 1.10029 +	for a particular kind of event, as shown below.</para>
 1.10030 +
 1.10031 +<!-- BEGIN hook.simple.ext -->
 1.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>
 1.10033 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt;&gt; a</userinput>
 1.10034 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'i have two hooks'</userinput>
 1.10035 +committed 3be6e2778fb853cbc7e5138d0b9c29386504670b
 1.10036 +date of commit: Sun Aug 16 14:05:05 GMT 2009
 1.10037 +</screen>
 1.10038 +<!-- END hook.simple.ext -->
 1.10039 +
 1.10040 +
 1.10041 +      <para id="x_216">Mercurial lets you do this by adding an
 1.10042 +	<emphasis>extension</emphasis> to the end of a hook's name.
 1.10043 +	You extend a hook's name by giving the name of the hook,
 1.10044 +	followed by a full stop (the
 1.10045 +	<quote><literal moreinfo="none">.</literal></quote> character), followed by
 1.10046 +	some more text of your choosing.  For example, Mercurial will
 1.10047 +	run both <literal moreinfo="none">commit.foo</literal> and
 1.10048 +	<literal moreinfo="none">commit.bar</literal> when the
 1.10049 +	<literal moreinfo="none">commit</literal> event occurs.
 1.10050 +      </para>
 1.10051 +
 1.10052 +      <para id="x_217">To give a well-defined order of execution when there are
 1.10053 +	multiple hooks defined for an event, Mercurial sorts hooks by
 1.10054 +	extension, and executes the hook commands in this sorted
 1.10055 +	order.  In the above example, it will execute
 1.10056 +	<literal moreinfo="none">commit.bar</literal> before
 1.10057 +	<literal moreinfo="none">commit.foo</literal>, and <literal moreinfo="none">commit</literal>
 1.10058 +	before both.
 1.10059 +      </para>
 1.10060 +
 1.10061 +      <para id="x_218">It is a good idea to use a somewhat descriptive
 1.10062 +	extension when you define a new hook.  This will help you to
 1.10063 +	remember what the hook was for.  If the hook fails, you'll get
 1.10064 +	an error message that contains the hook name and extension, so
 1.10065 +	using a descriptive extension could give you an immediate hint
 1.10066 +	as to why the hook failed (see <xref linkend="sec:hook:perm"/> for an example).
 1.10067 +      </para>
 1.10068 +
 1.10069 +    </sect2>
 1.10070 +    <sect2 id="sec:hook:perm">
 1.10071 +      <title>Controlling whether an activity can proceed</title>
 1.10072 +
 1.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
 1.10074 +	commit has completed.  This is one of several Mercurial hooks
 1.10075 +	that run after an activity finishes.  Such hooks have no way
 1.10076 +	of influencing the activity itself.
 1.10077 +      </para>
 1.10078 +
 1.10079 +      <para id="x_21a">Mercurial defines a number of events that occur before an
 1.10080 +	activity starts; or after it starts, but before it finishes.
 1.10081 +	Hooks that trigger on these events have the added ability to
 1.10082 +	choose whether the activity can continue, or will abort.
 1.10083 +      </para>
 1.10084 +
 1.10085 +      <para id="x_21b">The <literal role="hook" moreinfo="none">pretxncommit</literal> hook runs
 1.10086 +	after a commit has all but completed.  In other words, the
 1.10087 +	metadata representing the changeset has been written out to
 1.10088 +	disk, but the transaction has not yet been allowed to
 1.10089 +	complete.  The <literal role="hook" moreinfo="none">pretxncommit</literal>
 1.10090 +	hook has the ability to decide whether the transaction can
 1.10091 +	complete, or must be rolled back.
 1.10092 +      </para>
 1.10093 +
 1.10094 +      <para id="x_21c">If the <literal role="hook" moreinfo="none">pretxncommit</literal> hook
 1.10095 +	exits with a status code of zero, the transaction is allowed
 1.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
 1.10097 +	non-zero status code, the transaction is rolled back; the
 1.10098 +	metadata representing the changeset is erased; and the
 1.10099 +	<literal role="hook" moreinfo="none">commit</literal> hook is not run.
 1.10100 +      </para>
 1.10101 +
 1.10102 +<!-- BEGIN hook.simple.pretxncommit -->
 1.10103 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat check_bug_id</userinput>
 1.10104 +#!/bin/sh
 1.10105 +# check that a commit comment mentions a numeric bug id
 1.10106 +hg log -r $1 --template {desc} | grep -q "\&lt;bug *[0-9]"
 1.10107 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' &gt;&gt; .hg/hgrc</userinput>
 1.10108 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt;&gt; a</userinput>
 1.10109 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'i am not mentioning a bug id'</userinput>
 1.10110 +transaction abort!
 1.10111 +rollback completed
 1.10112 +abort: pretxncommit.bug_id_required hook exited with status 1
 1.10113 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m 'i refer you to bug 666'</userinput>
 1.10114 +committed 1a52be73a1ca4fa05e269f99003ed00912e8e836
 1.10115 +date of commit: Sun Aug 16 14:05:05 GMT 2009
 1.10116 +</screen>
 1.10117 +<!-- END hook.simple.pretxncommit -->
 1.10118 +
 1.10119 +
 1.10120 +      <para id="x_21d">The hook in the example above checks that a commit comment
 1.10121 +	contains a bug ID.  If it does, the commit can complete.  If
 1.10122 +	not, the commit is rolled back.
 1.10123 +      </para>
 1.10124 +
 1.10125 +    </sect2>
 1.10126 +  </sect1>
 1.10127 +  <sect1>
 1.10128 +    <title>Writing your own hooks</title>
 1.10129 +
 1.10130 +    <para id="x_21e">When you are writing a hook, you might find it useful to run
 1.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
 1.10132 +      <quote>true</quote>.  When you do so, Mercurial will print a
 1.10133 +      message before it calls each hook.
 1.10134 +    </para>
 1.10135 +
 1.10136 +    <sect2 id="sec:hook:lang">
 1.10137 +      <title>Choosing how your hook should run</title>
 1.10138 +
 1.10139 +      <para id="x_21f">You can write a hook either as a normal
 1.10140 +	program—typically a shell script—or as a Python
 1.10141 +	function that is executed within the Mercurial process.
 1.10142 +      </para>
 1.10143 +
 1.10144 +      <para id="x_220">Writing a hook as an external program has the advantage
 1.10145 +	that it requires no knowledge of Mercurial's internals.  You
 1.10146 +	can call normal Mercurial commands to get any added
 1.10147 +	information you need.  The trade-off is that external hooks
 1.10148 +	are slower than in-process hooks.
 1.10149 +      </para>
 1.10150 +
 1.10151 +      <para id="x_221">An in-process Python hook has complete access to the
 1.10152 +	Mercurial API, and does not <quote>shell out</quote> to
 1.10153 +	another process, so it is inherently faster than an external
 1.10154 +	hook.  It is also easier to obtain much of the information
 1.10155 +	that a hook requires by using the Mercurial API than by
 1.10156 +	running Mercurial commands.
 1.10157 +      </para>
 1.10158 +
 1.10159 +      <para id="x_222">If you are comfortable with Python, or require high
 1.10160 +	performance, writing your hooks in Python may be a good
 1.10161 +	choice.  However, when you have a straightforward hook to
 1.10162 +	write and you don't need to care about performance (probably
 1.10163 +	the majority of hooks), a shell script is perfectly fine.
 1.10164 +      </para>
 1.10165 +
 1.10166 +    </sect2>
 1.10167 +    <sect2 id="sec:hook:param">
 1.10168 +      <title>Hook parameters</title>
 1.10169 +
 1.10170 +      <para id="x_223">Mercurial calls each hook with a set of well-defined
 1.10171 +	parameters.  In Python, a parameter is passed as a keyword
 1.10172 +	argument to your hook function.  For an external program, a
 1.10173 +	parameter is passed as an environment variable.
 1.10174 +      </para>
 1.10175 +
 1.10176 +      <para id="x_224">Whether your hook is written in Python or as a shell
 1.10177 +	script, the hook-specific parameter names and values will be
 1.10178 +	the same.  A boolean parameter will be represented as a
 1.10179 +	boolean value in Python, but as the number 1 (for
 1.10180 +	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
 1.10181 +	environment variable for an external hook.  If a hook
 1.10182 +	parameter is named <literal moreinfo="none">foo</literal>, the keyword
 1.10183 +	argument for a Python hook will also be named
 1.10184 +	<literal moreinfo="none">foo</literal>, while the environment variable for an
 1.10185 +	external hook will be named <literal moreinfo="none">HG_FOO</literal>.
 1.10186 +      </para>
 1.10187 +    </sect2>
 1.10188 +
 1.10189 +    <sect2>
 1.10190 +      <title>Hook return values and activity control</title>
 1.10191 +
 1.10192 +      <para id="x_225">A hook that executes successfully must exit with a status
 1.10193 +	of zero if external, or return boolean <quote>false</quote> if
 1.10194 +	in-process.  Failure is indicated with a non-zero exit status
 1.10195 +	from an external hook, or an in-process hook returning boolean
 1.10196 +	<quote>true</quote>.  If an in-process hook raises an
 1.10197 +	exception, the hook is considered to have failed.
 1.10198 +      </para>
 1.10199 +
 1.10200 +      <para id="x_226">For a hook that controls whether an activity can proceed,
 1.10201 +	zero/false means <quote>allow</quote>, while
 1.10202 +	non-zero/true/exception means <quote>deny</quote>.
 1.10203 +      </para>
 1.10204 +    </sect2>
 1.10205 +
 1.10206 +    <sect2>
 1.10207 +      <title>Writing an external hook</title>
 1.10208 +
 1.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
 1.10210 +	value is passed to your shell, which interprets it.  This
 1.10211 +	means that you can use normal shell constructs in the body of
 1.10212 +	the hook.
 1.10213 +      </para>
 1.10214 +
 1.10215 +      <para id="x_228">An executable hook is always run with its current
 1.10216 +	directory set to a repository's root directory.
 1.10217 +      </para>
 1.10218 +
 1.10219 +      <para id="x_229">Each hook parameter is passed in as an environment
 1.10220 +	variable; the name is upper-cased, and prefixed with the
 1.10221 +	string <quote><literal moreinfo="none">HG_</literal></quote>.
 1.10222 +      </para>
 1.10223 +
 1.10224 +      <para id="x_22a">With the exception of hook parameters, Mercurial does not
 1.10225 +	set or modify any environment variables when running a hook.
 1.10226 +	This is useful to remember if you are writing a site-wide hook
 1.10227 +	that may be run by a number of different users with differing
 1.10228 +	environment variables set. In multi-user situations, you
 1.10229 +	should not rely on environment variables being set to the
 1.10230 +	values you have in your environment when testing the hook.
 1.10231 +      </para>
 1.10232 +    </sect2>
 1.10233 +
 1.10234 +    <sect2>
 1.10235 +      <title>Telling Mercurial to use an in-process hook</title>
 1.10236 +
 1.10237 +      <para id="x_22b">The <filename role="special" moreinfo="none">~/.hgrc</filename> syntax
 1.10238 +	for defining an in-process hook is slightly different than for
 1.10239 +	an executable hook.  The value of the hook must start with the
 1.10240 +	text <quote><literal moreinfo="none">python:</literal></quote>, and continue
 1.10241 +	with the fully-qualified name of a callable object to use as
 1.10242 +	the hook's value.
 1.10243 +      </para>
 1.10244 +
 1.10245 +      <para id="x_22c">The module in which a hook lives is automatically imported
 1.10246 +	when a hook is run.  So long as you have the module name and
 1.10247 +	<envar>PYTHONPATH</envar> right, it should <quote>just
 1.10248 +	  work</quote>.
 1.10249 +      </para>
 1.10250 +
 1.10251 +      <para id="x_22d">The following <filename role="special" moreinfo="none">~/.hgrc</filename>
 1.10252 +	example snippet illustrates the syntax and meaning of the
 1.10253 +	notions we just described.
 1.10254 +      </para>
 1.10255 +      <programlisting format="linespecific">[hooks]
 1.10256 +commit.example = python:mymodule.submodule.myhook</programlisting>
 1.10257 +      <para id="x_22e">When Mercurial runs the <literal moreinfo="none">commit.example</literal>
 1.10258 +	hook, it imports <literal moreinfo="none">mymodule.submodule</literal>, looks
 1.10259 +	for the callable object named <literal moreinfo="none">myhook</literal>, and
 1.10260 +	calls it.
 1.10261 +      </para>
 1.10262 +    </sect2>
 1.10263 +
 1.10264 +    <sect2>
 1.10265 +      <title>Writing an in-process hook</title>
 1.10266 +
 1.10267 +      <para id="x_22f">The simplest in-process hook does nothing, but illustrates
 1.10268 +	the basic shape of the hook API:
 1.10269 +      </para>
 1.10270 +      <programlisting format="linespecific">def myhook(ui, repo, **kwargs):
 1.10271 +    pass</programlisting>
 1.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
 1.10273 +	is a repository object; at the moment, it is always an
 1.10274 +	instance of <literal role="py-mod-mercurial.localrepo" moreinfo="none">localrepository</literal>.
 1.10275 +	Following these two arguments are other keyword arguments.
 1.10276 +	Which ones are passed in depends on the hook being called, but
 1.10277 +	a hook can ignore arguments it doesn't care about by dropping
 1.10278 +	them into a keyword argument dict, as with
 1.10279 +	<literal moreinfo="none">**kwargs</literal> above.
 1.10280 +      </para>
 1.10281 +
 1.10282 +    </sect2>
 1.10283 +  </sect1>
 1.10284 +  <sect1>
 1.10285 +    <title>Some hook examples</title>
 1.10286 +
 1.10287 +    <sect2>
 1.10288 +      <title>Writing meaningful commit messages</title>
 1.10289 +
 1.10290 +      <para id="x_231">It's hard to imagine a useful commit message being very
 1.10291 +	short. The simple <literal role="hook" moreinfo="none">pretxncommit</literal>
 1.10292 +	hook of the example below will prevent you from committing a
 1.10293 +	changeset with a message that is less than ten bytes long.
 1.10294 +      </para>
 1.10295 +
 1.10296 +<!-- BEGIN hook.msglen.go -->
 1.10297 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 1.10298 +[hooks]
 1.10299 +pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10
 1.10300 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 1.10301 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 1.10302 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'too short'</userinput>
 1.10303 +transaction abort!
 1.10304 +rollback completed
 1.10305 +abort: pretxncommit.msglen hook exited with status 1
 1.10306 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'long enough'</userinput>
 1.10307 +</screen>
 1.10308 +<!-- END hook.msglen.go -->
 1.10309 +
 1.10310 +    </sect2>
 1.10311 +
 1.10312 +    <sect2>
 1.10313 +      <title>Checking for trailing whitespace</title>
 1.10314 +
 1.10315 +      <para id="x_232">An interesting use of a commit-related hook is to help you
 1.10316 +	to write cleaner code.  A simple example of <quote>cleaner
 1.10317 +	  code</quote> is the dictum that a change should not add any
 1.10318 +	new lines of text that contain <quote>trailing
 1.10319 +	  whitespace</quote>.  Trailing whitespace is a series of
 1.10320 +	space and tab characters at the end of a line of text.  In
 1.10321 +	most cases, trailing whitespace is unnecessary, invisible
 1.10322 +	noise, but it is occasionally problematic, and people often
 1.10323 +	prefer to get rid of it.
 1.10324 +      </para>
 1.10325 +
 1.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
 1.10327 +	have a trailing whitespace problem.  If you use the <literal role="hook" moreinfo="none">precommit</literal> hook, the hook will not know
 1.10328 +	which files you are committing, so it will have to check every
 1.10329 +	modified file in the repository for trailing white space.  If
 1.10330 +	you want to commit a change to just the file
 1.10331 +	<filename moreinfo="none">foo</filename>, but the file
 1.10332 +	<filename moreinfo="none">bar</filename> contains trailing whitespace, doing a
 1.10333 +	check in the <literal role="hook" moreinfo="none">precommit</literal> hook
 1.10334 +	will prevent you from committing <filename moreinfo="none">foo</filename> due
 1.10335 +	to the problem with <filename moreinfo="none">bar</filename>.  This doesn't
 1.10336 +	seem right.
 1.10337 +      </para>
 1.10338 +
 1.10339 +      <para id="x_234">Should you choose the <literal role="hook" moreinfo="none">pretxncommit</literal> hook, the check won't
 1.10340 +	occur until just before the transaction for the commit
 1.10341 +	completes.  This will allow you to check for problems only the
 1.10342 +	exact files that are being committed.  However, if you entered
 1.10343 +	the commit message interactively and the hook fails, the
 1.10344 +	transaction will roll back; you'll have to re-enter the commit
 1.10345 +	message after you fix the trailing whitespace and run <command role="hg-cmd" moreinfo="none">hg commit</command> again.
 1.10346 +      </para>
 1.10347 +
 1.10348 +      <!-- BEGIN ch09/hook.ws.simple -->
 1.10349 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 1.10350 +[hooks]
 1.10351 +pretxncommit.whitespace = hg export tip | (! egrep -q '^\+.*[ \t]$')
 1.10352 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'a ' &gt; a</userinput>
 1.10353 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'test with trailing whitespace'</userinput>
 1.10354 +adding a
 1.10355 +transaction abort!
 1.10356 +rollback completed
 1.10357 +abort: pretxncommit.whitespace hook exited with status 1
 1.10358 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'a' &gt; a</userinput>
 1.10359 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'drop trailing whitespace and try again'</userinput>
 1.10360 +</screen>
 1.10361 +<!-- END ch09/hook.ws.simple -->
 1.10362 +
 1.10363 +
 1.10364 +      <para id="x_235">In this example, we introduce a simple <literal role="hook" moreinfo="none">pretxncommit</literal> hook that checks for
 1.10365 +	trailing whitespace.  This hook is short, but not very
 1.10366 +	helpful.  It exits with an error status if a change adds a
 1.10367 +	line with trailing whitespace to any file, but does not print
 1.10368 +	any information that might help us to identify the offending
 1.10369 +	file or line.  It also has the nice property of not paying
 1.10370 +	attention to unmodified lines; only lines that introduce new
 1.10371 +	trailing whitespace cause problems.
 1.10372 +      </para>
 1.10373 +
 1.10374 +      <!-- BEGIN ch09/check_whitespace.py.lst -->
 1.10375 +<programlisting format="linespecific">#!/usr/bin/env python
 1.10376 +#
 1.10377 +# save as .hg/check_whitespace.py and make executable
 1.10378 +
 1.10379 +import re
 1.10380 +
 1.10381 +def trailing_whitespace(difflines):
 1.10382 +    # 
 1.10383 +    linenum, header = 0, False
 1.10384 +
 1.10385 +    for line in difflines:
 1.10386 +        if header:
 1.10387 +            # remember the name of the file that this diff affects
 1.10388 +            m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)
 1.10389 +            if m and m.group(1) != '/dev/null':
 1.10390 +                filename = m.group(1).split('/', 1)[-1]
 1.10391 +            if line.startswith('+++ '):
 1.10392 +                header = False
 1.10393 +            continue
 1.10394 +        if line.startswith('diff '):
 1.10395 +            header = True
 1.10396 +            continue
 1.10397 +        # hunk header - save the line number
 1.10398 +        m = re.match(r'@@ -\d+,\d+ \+(\d+),', line)
 1.10399 +        if m:
 1.10400 +            linenum = int(m.group(1))
 1.10401 +            continue
 1.10402 +        # hunk body - check for an added line with trailing whitespace
 1.10403 +        m = re.match(r'\+.*\s$', line)
 1.10404 +        if m:
 1.10405 +            yield filename, linenum
 1.10406 +        if line and line[0] in ' +':
 1.10407 +            linenum += 1
 1.10408 +
 1.10409 +if __name__ == '__main__':
 1.10410 +    import os, sys
 1.10411 +    
 1.10412 +    added = 0
 1.10413 +    for filename, linenum in trailing_whitespace(os.popen('hg export tip')):
 1.10414 +        print &gt;&gt; sys.stderr, ('%s, line %d: trailing whitespace added' %
 1.10415 +                              (filename, linenum))
 1.10416 +        added += 1
 1.10417 +    if added:
 1.10418 +        # save the commit message so we don't need to retype it
 1.10419 +        os.system('hg tip --template "{desc}" &gt; .hg/commit.save')
 1.10420 +        print &gt;&gt; sys.stderr, 'commit message saved to .hg/commit.save'
 1.10421 +        sys.exit(1)</programlisting>
 1.10422 +<!-- END ch09/check_whitespace.py.lst -->
 1.10423 +
 1.10424 +
 1.10425 +      <para id="x_236">The above version is much more complex, but also more
 1.10426 +	useful.  It parses a unified diff to see if any lines add
 1.10427 +	trailing whitespace, and prints the name of the file and the
 1.10428 +	line number of each such occurrence.  Even better, if the
 1.10429 +	change adds trailing whitespace, this hook saves the commit
 1.10430 +	comment and prints the name of the save file before exiting
 1.10431 +	and telling Mercurial to roll the transaction back, so you can
 1.10432 +	use the <option role="hg-opt-commit">-l filename</option>
 1.10433 +	option to <command role="hg-cmd" moreinfo="none">hg commit</command> to reuse
 1.10434 +	the saved commit message once you've corrected the problem.
 1.10435 +      </para>
 1.10436 +
 1.10437 +      <!-- BEGIN ch09/hook.ws.better -->
 1.10438 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/hgrc</userinput>
 1.10439 +[hooks]
 1.10440 +pretxncommit.whitespace = .hg/check_whitespace.py
 1.10441 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'a ' &gt;&gt; a</userinput>
 1.10442 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'add new line with trailing whitespace'</userinput>
 1.10443 +a, line 2: trailing whitespace added
 1.10444 +commit message saved to .hg/commit.save
 1.10445 +transaction abort!
 1.10446 +rollback completed
 1.10447 +abort: pretxncommit.whitespace hook exited with status 1
 1.10448 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">sed -i 's, *$,,' a</userinput>
 1.10449 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -A -m 'trimmed trailing whitespace'</userinput>
 1.10450 +a, line 2: trailing whitespace added
 1.10451 +commit message saved to .hg/commit.save
 1.10452 +transaction abort!
 1.10453 +rollback completed
 1.10454 +abort: pretxncommit.whitespace hook exited with status 1
 1.10455 +</screen>
 1.10456 +<!-- END ch09/hook.ws.better -->
 1.10457 +
 1.10458 +
 1.10459 +      <para id="x_237">As a final aside, note in the example above the
 1.10460 +	use of <command moreinfo="none">sed</command>'s in-place editing feature to
 1.10461 +	get rid of trailing whitespace from a file.  This is concise
 1.10462 +	and useful enough that I will reproduce it here (using
 1.10463 +	<command moreinfo="none">perl</command> for good measure).</para>
 1.10464 +      <programlisting format="linespecific">perl -pi -e 's,\s+$,,' filename</programlisting>
 1.10465 +
 1.10466 +    </sect2>
 1.10467 +  </sect1>
 1.10468 +  <sect1>
 1.10469 +    <title>Bundled hooks</title>
 1.10470 +
 1.10471 +    <para id="x_238">Mercurial ships with several bundled hooks.  You can find
 1.10472 +      them in the <filename class="directory" moreinfo="none">hgext</filename>
 1.10473 +      directory of a Mercurial source tree.  If you are using a
 1.10474 +      Mercurial binary package, the hooks will be located in the
 1.10475 +      <filename class="directory" moreinfo="none">hgext</filename> directory of
 1.10476 +      wherever your package installer put Mercurial.
 1.10477 +    </para>
 1.10478 +
 1.10479 +    <sect2>
 1.10480 +      <title><literal role="hg-ext" moreinfo="none">acl</literal>—access
 1.10481 +	control for parts of a repository</title>
 1.10482 +
 1.10483 +      <para id="x_239">The <literal role="hg-ext" moreinfo="none">acl</literal> extension lets
 1.10484 +	you control which remote users are allowed to push changesets
 1.10485 +	to a networked server.  You can protect any portion of a
 1.10486 +	repository (including the entire repo), so that a specific
 1.10487 +	remote user can push changes that do not affect the protected
 1.10488 +	portion.
 1.10489 +      </para>
 1.10490 +
 1.10491 +      <para id="x_23a">This extension implements access control based on the
 1.10492 +	identity of the user performing a push,
 1.10493 +	<emphasis>not</emphasis> on who committed the changesets
 1.10494 +	they're pushing.  It makes sense to use this hook only if you
 1.10495 +	have a locked-down server environment that authenticates
 1.10496 +	remote users, and you want to be sure that only specific users
 1.10497 +	are allowed to push changes to that server.
 1.10498 +      </para>
 1.10499 +
 1.10500 +      <sect3>
 1.10501 +	<title>Configuring the <literal role="hook" moreinfo="none">acl</literal>
 1.10502 +	  hook</title>
 1.10503 +
 1.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
 1.10505 +	  <literal role="hook" moreinfo="none">pretxnchangegroup</literal> hook.  This
 1.10506 +	  lets it see which files are modified by each incoming
 1.10507 +	  changeset, and roll back a group of changesets if they
 1.10508 +	  modify <quote>forbidden</quote> files.  Example:
 1.10509 +	</para>
 1.10510 +	<programlisting format="linespecific">[hooks]
 1.10511 +pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
 1.10512 +
 1.10513 +	<para id="x_23c">The <literal role="hg-ext" moreinfo="none">acl</literal> extension is
 1.10514 +	  configured using three sections.
 1.10515 +	</para>
 1.10516 +
 1.10517 +	<para id="x_23d">The <literal role="rc-acl" moreinfo="none">acl</literal> section has
 1.10518 +	  only one entry, <envar role="rc-item-acl">sources</envar>,
 1.10519 +	  which lists the sources of incoming changesets that the hook
 1.10520 +	  should pay attention to.  You don't normally need to
 1.10521 +	  configure this section.
 1.10522 +	</para>
 1.10523 +	<itemizedlist>
 1.10524 +	  <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>:
 1.10525 +	      Control incoming changesets that are arriving from a
 1.10526 +	      remote repository over http or ssh.  This is the default
 1.10527 +	      value of <envar role="rc-item-acl">sources</envar>, and
 1.10528 +	      usually the only setting you'll need for this
 1.10529 +	      configuration item.
 1.10530 +	    </para>
 1.10531 +	  </listitem>
 1.10532 +	  <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>:
 1.10533 +	      Control incoming changesets that are arriving via a pull
 1.10534 +	      from a local repository.
 1.10535 +	    </para>
 1.10536 +	  </listitem>
 1.10537 +	  <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>:
 1.10538 +	      Control incoming changesets that are arriving via a push
 1.10539 +	      from a local repository.
 1.10540 +	    </para>
 1.10541 +	  </listitem>
 1.10542 +	  <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>:
 1.10543 +	      Control incoming changesets that are arriving from
 1.10544 +	      another repository via a bundle.
 1.10545 +	    </para>
 1.10546 +	  </listitem></itemizedlist>
 1.10547 +
 1.10548 +	<para id="x_242">The <literal role="rc-acl.allow" moreinfo="none">acl.allow</literal>
 1.10549 +	  section controls the users that are allowed to add
 1.10550 +	  changesets to the repository.  If this section is not
 1.10551 +	  present, all users that are not explicitly denied are
 1.10552 +	  allowed.  If this section is present, all users that are not
 1.10553 +	  explicitly allowed are denied (so an empty section means
 1.10554 +	  that all users are denied).
 1.10555 +	</para>
 1.10556 +
 1.10557 +	<para id="x_243">The <literal role="rc-acl.deny" moreinfo="none">acl.deny</literal>
 1.10558 +	  section determines which users are denied from adding
 1.10559 +	  changesets to the repository.  If this section is not
 1.10560 +	  present or is empty, no users are denied.
 1.10561 +	</para>
 1.10562 +
 1.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
 1.10564 +	  identical.  On the left of each entry is a glob pattern that
 1.10565 +	  matches files or directories, relative to the root of the
 1.10566 +	  repository; on the right, a user name.
 1.10567 +	</para>
 1.10568 +
 1.10569 +	<para id="x_245">In the following example, the user
 1.10570 +	  <literal moreinfo="none">docwriter</literal> can only push changes to the
 1.10571 +	  <filename class="directory" moreinfo="none">docs</filename> subtree of the
 1.10572 +	  repository, while <literal moreinfo="none">intern</literal> can push changes
 1.10573 +	  to any file or directory except <filename class="directory" moreinfo="none">source/sensitive</filename>.
 1.10574 +	</para>
 1.10575 +	<programlisting format="linespecific">[acl.allow]
 1.10576 +docs/** = docwriter
 1.10577 +[acl.deny]
 1.10578 +source/sensitive/** = intern</programlisting>
 1.10579 +
 1.10580 +      </sect3>
 1.10581 +      <sect3>
 1.10582 +	<title>Testing and troubleshooting</title>
 1.10583 +
 1.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
 1.10585 +	  debugging output enabled.  Since you'll probably be running
 1.10586 +	  it on a server where it's not convenient (or sometimes
 1.10587 +	  possible) to pass in the <option role="hg-opt-global">--debug</option> option, don't forget
 1.10588 +	  that you can enable debugging output in your <filename role="special" moreinfo="none">~/.hgrc</filename>:
 1.10589 +	</para>
 1.10590 +	<programlisting format="linespecific">[ui]
 1.10591 +debug = true</programlisting>
 1.10592 +	<para id="x_247">With this enabled, the <literal role="hg-ext" moreinfo="none">acl</literal> hook will print enough
 1.10593 +	  information to let you figure out why it is allowing or
 1.10594 +	  forbidding pushes from specific users.
 1.10595 +	</para>
 1.10596 +
 1.10597 +      </sect3>    </sect2>
 1.10598 +
 1.10599 +    <sect2>
 1.10600 +      <title><literal role="hg-ext" moreinfo="none">bugzilla</literal>—integration with
 1.10601 +	Bugzilla</title>
 1.10602 +
 1.10603 +      <para id="x_248">The <literal role="hg-ext" moreinfo="none">bugzilla</literal> extension
 1.10604 +	adds a comment to a Bugzilla bug whenever it finds a reference
 1.10605 +	to that bug ID in a commit comment.  You can install this hook
 1.10606 +	on a shared server, so that any time a remote user pushes
 1.10607 +	changes to this server, the hook gets run.
 1.10608 +      </para>
 1.10609 +
 1.10610 +      <para id="x_249">It adds a comment to the bug that looks like this (you can
 1.10611 +	configure the contents of the comment—see below):
 1.10612 +      </para>
 1.10613 +      <programlisting format="linespecific">Changeset aad8b264143a, made by Joe User
 1.10614 +	&lt;joe.user@domain.com&gt; in the frobnitz repository, refers
 1.10615 +	to this bug. For complete details, see
 1.10616 +	http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
 1.10617 +	Changeset description: Fix bug 10483 by guarding against some
 1.10618 +	NULL pointers</programlisting>
 1.10619 +      <para id="x_24a">The value of this hook is that it automates the process of
 1.10620 +	updating a bug any time a changeset refers to it.  If you
 1.10621 +	configure the hook properly, it makes it easy for people to
 1.10622 +	browse straight from a Bugzilla bug to a changeset that refers
 1.10623 +	to that bug.
 1.10624 +      </para>
 1.10625 +
 1.10626 +      <para id="x_24b">You can use the code in this hook as a starting point for
 1.10627 +	some more exotic Bugzilla integration recipes.  Here are a few
 1.10628 +	possibilities:
 1.10629 +      </para>
 1.10630 +      <itemizedlist>
 1.10631 +	<listitem><para id="x_24c">Require that every changeset pushed to the
 1.10632 +	    server have a valid bug ID in its commit comment.  In this
 1.10633 +	    case, you'd want to configure the hook as a <literal role="hook" moreinfo="none">pretxncommit</literal> hook.  This would
 1.10634 +	    allow the hook to reject changes that didn't contain bug
 1.10635 +	    IDs.
 1.10636 +	  </para>
 1.10637 +	</listitem>
 1.10638 +	<listitem><para id="x_24d">Allow incoming changesets to automatically
 1.10639 +	    modify the <emphasis>state</emphasis> of a bug, as well as
 1.10640 +	    simply adding a comment.  For example, the hook could
 1.10641 +	    recognise the string <quote>fixed bug 31337</quote> as
 1.10642 +	    indicating that it should update the state of bug 31337 to
 1.10643 +	    <quote>requires testing</quote>.
 1.10644 +	  </para>
 1.10645 +	</listitem></itemizedlist>
 1.10646 +
 1.10647 +      <sect3 id="sec:hook:bugzilla:config">
 1.10648 +	<title>Configuring the <literal role="hook" moreinfo="none">bugzilla</literal>
 1.10649 +	  hook</title>
 1.10650 +
 1.10651 +	<para id="x_24e">You should configure this hook in your server's
 1.10652 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> as an <literal role="hook" moreinfo="none">incoming</literal> hook, for example as
 1.10653 +	  follows:
 1.10654 +	</para>
 1.10655 +	<programlisting format="linespecific">[hooks]
 1.10656 +incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
 1.10657 +
 1.10658 +	<para id="x_24f">Because of the specialised nature of this hook, and
 1.10659 +	  because Bugzilla was not written with this kind of
 1.10660 +	  integration in mind, configuring this hook is a somewhat
 1.10661 +	  involved process.
 1.10662 +	</para>
 1.10663 +
 1.10664 +	<para id="x_250">Before you begin, you must install the MySQL bindings
 1.10665 +	  for Python on the host(s) where you'll be running the hook.
 1.10666 +	  If this is not available as a binary package for your
 1.10667 +	  system, you can download it from
 1.10668 +	  <citation>web:mysql-python</citation>.
 1.10669 +	</para>
 1.10670 +
 1.10671 +	<para id="x_251">Configuration information for this hook lives in the
 1.10672 +	  <literal role="rc-bugzilla" moreinfo="none">bugzilla</literal> section of
 1.10673 +	  your <filename role="special" moreinfo="none">~/.hgrc</filename>.
 1.10674 +	</para>
 1.10675 +	<itemizedlist>
 1.10676 +	  <listitem><para id="x_252"><envar role="rc-item-bugzilla">version</envar>: The version
 1.10677 +	      of Bugzilla installed on the server.  The database
 1.10678 +	      schema that Bugzilla uses changes occasionally, so this
 1.10679 +	      hook has to know exactly which schema to use.</para>
 1.10680 +	  </listitem>
 1.10681 +	  <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>:
 1.10682 +	      The hostname of the MySQL server that stores your
 1.10683 +	      Bugzilla data.  The database must be configured to allow
 1.10684 +	      connections from whatever host you are running the
 1.10685 +	      <literal role="hook" moreinfo="none">bugzilla</literal> hook on.
 1.10686 +	    </para>
 1.10687 +	  </listitem>
 1.10688 +	  <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>:
 1.10689 +	      The username with which to connect to the MySQL server.
 1.10690 +	      The database must be configured to allow this user to
 1.10691 +	      connect from whatever host you are running the <literal role="hook" moreinfo="none">bugzilla</literal> hook on.  This user
 1.10692 +	      must be able to access and modify Bugzilla tables.  The
 1.10693 +	      default value of this item is <literal moreinfo="none">bugs</literal>,
 1.10694 +	      which is the standard name of the Bugzilla user in a
 1.10695 +	      MySQL database.
 1.10696 +	    </para>
 1.10697 +	  </listitem>
 1.10698 +	  <listitem><para id="x_255"><envar role="rc-item-bugzilla">password</envar>: The MySQL
 1.10699 +	      password for the user you configured above.  This is
 1.10700 +	      stored as plain text, so you should make sure that
 1.10701 +	      unauthorised users cannot read the <filename role="special" moreinfo="none">~/.hgrc</filename> file where you
 1.10702 +	      store this information.
 1.10703 +	    </para>
 1.10704 +	  </listitem>
 1.10705 +	  <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>:
 1.10706 +	      The name of the Bugzilla database on the MySQL server.
 1.10707 +	      The default value of this item is
 1.10708 +	      <literal moreinfo="none">bugs</literal>, which is the standard name of
 1.10709 +	      the MySQL database where Bugzilla stores its data.
 1.10710 +	    </para>
 1.10711 +	  </listitem>
 1.10712 +	  <listitem><para id="x_257"><envar role="rc-item-bugzilla">notify</envar>: If you want
 1.10713 +	      Bugzilla to send out a notification email to subscribers
 1.10714 +	      after this hook has added a comment to a bug, you will
 1.10715 +	      need this hook to run a command whenever it updates the
 1.10716 +	      database.  The command to run depends on where you have
 1.10717 +	      installed Bugzilla, but it will typically look something
 1.10718 +	      like this, if you have Bugzilla installed in <filename class="directory" moreinfo="none">/var/www/html/bugzilla</filename>:
 1.10719 +	    </para>
 1.10720 +	    <programlisting format="linespecific">cd /var/www/html/bugzilla &amp;&amp;
 1.10721 +	      ./processmail %s nobody@nowhere.com</programlisting>
 1.10722 +	  </listitem>
 1.10723 +	  <listitem><para id="x_258">  The Bugzilla
 1.10724 +	      <literal moreinfo="none">processmail</literal> program expects to be
 1.10725 +	      given a bug ID (the hook replaces
 1.10726 +	      <quote><literal moreinfo="none">%s</literal></quote> with the bug ID)
 1.10727 +	      and an email address.  It also expects to be able to
 1.10728 +	      write to some files in the directory that it runs in.
 1.10729 +	      If Bugzilla and this hook are not installed on the same
 1.10730 +	      machine, you will need to find a way to run
 1.10731 +	      <literal moreinfo="none">processmail</literal> on the server where
 1.10732 +	      Bugzilla is installed.
 1.10733 +	    </para>
 1.10734 +	  </listitem></itemizedlist>
 1.10735 +
 1.10736 +      </sect3>
 1.10737 +      <sect3>
 1.10738 +	<title>Mapping committer names to Bugzilla user names</title>
 1.10739 +
 1.10740 +	<para id="x_259">By default, the <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook tries to use the
 1.10741 +	  email address of a changeset's committer as the Bugzilla
 1.10742 +	  user name with which to update a bug.  If this does not suit
 1.10743 +	  your needs, you can map committer email addresses to
 1.10744 +	  Bugzilla user names using a <literal role="rc-usermap" moreinfo="none">usermap</literal> section.
 1.10745 +	</para>
 1.10746 +
 1.10747 +	<para id="x_25a">Each item in the <literal role="rc-usermap" moreinfo="none">usermap</literal> section contains an
 1.10748 +	  email address on the left, and a Bugzilla user name on the
 1.10749 +	  right.
 1.10750 +	</para>
 1.10751 +	<programlisting format="linespecific">[usermap]
 1.10752 +jane.user@example.com = jane</programlisting>
 1.10753 +	<para id="x_25b">You can either keep the <literal role="rc-usermap" moreinfo="none">usermap</literal> data in a normal
 1.10754 +	  <filename role="special" moreinfo="none">~/.hgrc</filename>, or tell the
 1.10755 +	  <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook to read the
 1.10756 +	  information from an external <filename moreinfo="none">usermap</filename>
 1.10757 +	  file.  In the latter case, you can store
 1.10758 +	  <filename moreinfo="none">usermap</filename> data by itself in (for example)
 1.10759 +	  a user-modifiable repository.  This makes it possible to let
 1.10760 +	  your users maintain their own <envar role="rc-item-bugzilla">usermap</envar> entries.  The main
 1.10761 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file might look
 1.10762 +	  like this:
 1.10763 +	</para>
 1.10764 +	<programlisting format="linespecific"># regular hgrc file refers to external usermap file
 1.10765 +[bugzilla]
 1.10766 +usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
 1.10767 +	<para id="x_25c">While the <filename moreinfo="none">usermap</filename> file that it
 1.10768 +	  refers to might look like this:
 1.10769 +	</para>
 1.10770 +	<programlisting format="linespecific"># bugzilla-usermap.conf - inside a hg repository
 1.10771 +[usermap] stephanie@example.com = steph</programlisting>
 1.10772 +
 1.10773 +      </sect3>
 1.10774 +      <sect3>
 1.10775 +	<title>Configuring the text that gets added to a bug</title>
 1.10776 +
 1.10777 +	<para id="x_25d">You can configure the text that this hook adds as a
 1.10778 +	  comment; you specify it in the form of a Mercurial template.
 1.10779 +	  Several <filename role="special" moreinfo="none">~/.hgrc</filename> entries
 1.10780 +	  (still in the <literal role="rc-bugzilla" moreinfo="none">bugzilla</literal>
 1.10781 +	  section) control this behavior.
 1.10782 +	</para>
 1.10783 +	<itemizedlist>
 1.10784 +	  <listitem><para id="x_25e"><literal moreinfo="none">strip</literal>: The number of
 1.10785 +	      leading path elements to strip from a repository's path
 1.10786 +	      name to construct a partial path for a URL. For example,
 1.10787 +	      if the repositories on your server live under <filename class="directory" moreinfo="none">/home/hg/repos</filename>, and you
 1.10788 +	      have a repository whose path is <filename class="directory" moreinfo="none">/home/hg/repos/app/tests</filename>,
 1.10789 +	      then setting <literal moreinfo="none">strip</literal> to
 1.10790 +	      <literal moreinfo="none">4</literal> will give a partial path of
 1.10791 +	      <filename class="directory" moreinfo="none">app/tests</filename>.  The
 1.10792 +	      hook will make this partial path available when
 1.10793 +	      expanding a template, as <literal moreinfo="none">webroot</literal>.
 1.10794 +	    </para>
 1.10795 +	  </listitem>
 1.10796 +	  <listitem><para id="x_25f"><literal moreinfo="none">template</literal>: The text of the
 1.10797 +	      template to use.  In addition to the usual
 1.10798 +	      changeset-related variables, this template can use
 1.10799 +	      <literal moreinfo="none">hgweb</literal> (the value of the
 1.10800 +	      <literal moreinfo="none">hgweb</literal> configuration item above) and
 1.10801 +	      <literal moreinfo="none">webroot</literal> (the path constructed using
 1.10802 +	      <literal moreinfo="none">strip</literal> above).
 1.10803 +	    </para>
 1.10804 +	  </listitem></itemizedlist>
 1.10805 +
 1.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
 1.10807 +	  available when expanding a template, as the base string to
 1.10808 +	  use when constructing a URL that will let users browse from
 1.10809 +	  a Bugzilla comment to view a changeset.  Example:
 1.10810 +	</para>
 1.10811 +	<programlisting format="linespecific">[web]
 1.10812 +baseurl = http://hg.domain.com/</programlisting>
 1.10813 +
 1.10814 +	<para id="x_261">Here is an example set of <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook config information.
 1.10815 +	</para>
 1.10816 +
 1.10817 +	<!-- BEGIN ch10/bugzilla-config.lst -->
 1.10818 +<programlisting format="linespecific">[bugzilla]
 1.10819 +host = bugzilla.example.com
 1.10820 +password = mypassword version = 2.16
 1.10821 +# server-side repos live in /home/hg/repos, so strip 4 leading
 1.10822 +# separators
 1.10823 +strip = 4
 1.10824 +hgweb = http://hg.example.com/
 1.10825 +usermap = /home/hg/repos/notify/bugzilla.conf
 1.10826 +template = Changeset {node|short}, made by {author} in the {webroot}
 1.10827 +  repo, refers to this bug.\n
 1.10828 +  For complete details, see
 1.10829 +  {hgweb}{webroot}?cmd=changeset;node={node|short}\n
 1.10830 +  Changeset description:\n
 1.10831 +  \t{desc|tabindent}</programlisting>
 1.10832 +<!-- END ch10/bugzilla-config.lst -->
 1.10833 +
 1.10834 +
 1.10835 +      </sect3>
 1.10836 +      <sect3>
 1.10837 +	<title>Testing and troubleshooting</title>
 1.10838 +
 1.10839 +	<para id="x_262">The most common problems with configuring the <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook relate to running
 1.10840 +	  Bugzilla's <filename moreinfo="none">processmail</filename> script and
 1.10841 +	  mapping committer names to user names.
 1.10842 +	</para>
 1.10843 +
 1.10844 +	<para id="x_263">Recall from <xref linkend="sec:hook:bugzilla:config"/> above that the user
 1.10845 +	  that runs the Mercurial process on the server is also the
 1.10846 +	  one that will run the <filename moreinfo="none">processmail</filename>
 1.10847 +	  script.  The <filename moreinfo="none">processmail</filename> script
 1.10848 +	  sometimes causes Bugzilla to write to files in its
 1.10849 +	  configuration directory, and Bugzilla's configuration files
 1.10850 +	  are usually owned by the user that your web server runs
 1.10851 +	  under.
 1.10852 +	</para>
 1.10853 +
 1.10854 +	<para id="x_264">You can cause <filename moreinfo="none">processmail</filename> to be run
 1.10855 +	  with the suitable user's identity using the
 1.10856 +	  <command moreinfo="none">sudo</command> command.  Here is an example entry
 1.10857 +	  for a <filename moreinfo="none">sudoers</filename> file.
 1.10858 +	</para>
 1.10859 +	<programlisting format="linespecific">hg_user = (httpd_user)
 1.10860 +NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
 1.10861 +	<para id="x_265">This allows the <literal moreinfo="none">hg_user</literal> user to run a
 1.10862 +	  <filename moreinfo="none">processmail-wrapper</filename> program under the
 1.10863 +	  identity of <literal moreinfo="none">httpd_user</literal>.
 1.10864 +	</para>
 1.10865 +
 1.10866 +	<para id="x_266">This indirection through a wrapper script is necessary,
 1.10867 +	  because <filename moreinfo="none">processmail</filename> expects to be run
 1.10868 +	  with its current directory set to wherever you installed
 1.10869 +	  Bugzilla; you can't specify that kind of constraint in a
 1.10870 +	  <filename moreinfo="none">sudoers</filename> file.  The contents of the
 1.10871 +	  wrapper script are simple:
 1.10872 +	</para>
 1.10873 +	<programlisting format="linespecific">#!/bin/sh
 1.10874 +cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
 1.10875 +	<para id="x_267">It doesn't seem to matter what email address you pass to
 1.10876 +	  <filename moreinfo="none">processmail</filename>.
 1.10877 +	</para>
 1.10878 +
 1.10879 +	<para id="x_268">If your <literal role="rc-usermap" moreinfo="none">usermap</literal> is
 1.10880 +	  not set up correctly, users will see an error message from
 1.10881 +	  the <literal role="hg-ext" moreinfo="none">bugzilla</literal> hook when they
 1.10882 +	  push changes to the server.  The error message will look
 1.10883 +	  like this:
 1.10884 +	</para>
 1.10885 +	<programlisting format="linespecific">cannot find bugzilla user id for john.q.public@example.com</programlisting>
 1.10886 +	<para id="x_269">What this means is that the committer's address,
 1.10887 +	  <literal moreinfo="none">john.q.public@example.com</literal>, is not a valid
 1.10888 +	  Bugzilla user name, nor does it have an entry in your
 1.10889 +	  <literal role="rc-usermap" moreinfo="none">usermap</literal> that maps it to
 1.10890 +	  a valid Bugzilla user name.
 1.10891 +	</para>
 1.10892 +
 1.10893 +      </sect3>    </sect2>
 1.10894 +
 1.10895 +    <sect2>
 1.10896 +      <title><literal role="hg-ext" moreinfo="none">notify</literal>—send email
 1.10897 +	notifications</title>
 1.10898 +
 1.10899 +      <para id="x_26a">Although Mercurial's built-in web server provides RSS
 1.10900 +	feeds of changes in every repository, many people prefer to
 1.10901 +	receive change notifications via email.  The <literal role="hg-ext" moreinfo="none">notify</literal> hook lets you send out
 1.10902 +	notifications to a set of email addresses whenever changesets
 1.10903 +	arrive that those subscribers are interested in.
 1.10904 +      </para>
 1.10905 +
 1.10906 +      <para id="x_26b">As with the <literal role="hg-ext" moreinfo="none">bugzilla</literal>
 1.10907 +	hook, the <literal role="hg-ext" moreinfo="none">notify</literal> hook is
 1.10908 +	template-driven, so you can customise the contents of the
 1.10909 +	notification messages that it sends.
 1.10910 +      </para>
 1.10911 +
 1.10912 +      <para id="x_26c">By default, the <literal role="hg-ext" moreinfo="none">notify</literal>
 1.10913 +	hook includes a diff of every changeset that it sends out; you
 1.10914 +	can limit the size of the diff, or turn this feature off
 1.10915 +	entirely.  It is useful for letting subscribers review changes
 1.10916 +	immediately, rather than clicking to follow a URL.
 1.10917 +      </para>
 1.10918 +
 1.10919 +      <sect3>
 1.10920 +	<title>Configuring the <literal role="hg-ext" moreinfo="none">notify</literal>
 1.10921 +	  hook</title>
 1.10922 +
 1.10923 +	<para id="x_26d">You can set up the <literal role="hg-ext" moreinfo="none">notify</literal> hook to send one email
 1.10924 +	  message per incoming changeset, or one per incoming group of
 1.10925 +	  changesets (all those that arrived in a single pull or
 1.10926 +	  push).
 1.10927 +	</para>
 1.10928 +	<programlisting format="linespecific">[hooks]
 1.10929 +# send one email per group of changes
 1.10930 +changegroup.notify = python:hgext.notify.hook
 1.10931 +# send one email per change
 1.10932 +incoming.notify = python:hgext.notify.hook</programlisting>
 1.10933 +
 1.10934 +	<para id="x_26e">Configuration information for this hook lives in the
 1.10935 +	  <literal role="rc-notify" moreinfo="none">notify</literal> section of a
 1.10936 +	  <filename role="special" moreinfo="none">~/.hgrc</filename> file.
 1.10937 +	</para>
 1.10938 +	<itemizedlist>
 1.10939 +	  <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>:
 1.10940 +	      By default, this hook does not send out email at all;
 1.10941 +	      instead, it prints the message that it
 1.10942 +	      <emphasis>would</emphasis> send.  Set this item to
 1.10943 +	      <literal moreinfo="none">false</literal> to allow email to be sent. The
 1.10944 +	      reason that sending of email is turned off by default is
 1.10945 +	      that it takes several tries to configure this extension
 1.10946 +	      exactly as you would like, and it would be bad form to
 1.10947 +	      spam subscribers with a number of <quote>broken</quote>
 1.10948 +	      notifications while you debug your configuration.
 1.10949 +	    </para>
 1.10950 +	  </listitem>
 1.10951 +	  <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>:
 1.10952 +	      The path to a configuration file that contains
 1.10953 +	      subscription information.  This is kept separate from
 1.10954 +	      the main <filename role="special" moreinfo="none">~/.hgrc</filename> so
 1.10955 +	      that you can maintain it in a repository of its own.
 1.10956 +	      People can then clone that repository, update their
 1.10957 +	      subscriptions, and push the changes back to your server.
 1.10958 +	    </para>
 1.10959 +	  </listitem>
 1.10960 +	  <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>:
 1.10961 +	      The number of leading path separator characters to strip
 1.10962 +	      from a repository's path, when deciding whether a
 1.10963 +	      repository has subscribers.  For example, if the
 1.10964 +	      repositories on your server live in <filename class="directory" moreinfo="none">/home/hg/repos</filename>, and
 1.10965 +	      <literal role="hg-ext" moreinfo="none">notify</literal> is considering a
 1.10966 +	      repository named <filename class="directory" moreinfo="none">/home/hg/repos/shared/test</filename>, 
 1.10967 +	      setting <envar role="rc-item-notify">strip</envar> to
 1.10968 +	      <literal moreinfo="none">4</literal> will cause <literal role="hg-ext" moreinfo="none">notify</literal> to trim the path it
 1.10969 +	      considers down to <filename class="directory" moreinfo="none">shared/test</filename>, and it will
 1.10970 +	      match subscribers against that.
 1.10971 +	    </para>
 1.10972 +	  </listitem>
 1.10973 +	  <listitem><para id="x_272"><envar role="rc-item-notify">template</envar>: The template
 1.10974 +	      text to use when sending messages.  This specifies both
 1.10975 +	      the contents of the message header and its body.
 1.10976 +	    </para>
 1.10977 +	  </listitem>
 1.10978 +	  <listitem><para id="x_273"><envar role="rc-item-notify">maxdiff</envar>: The maximum
 1.10979 +	      number of lines of diff data to append to the end of a
 1.10980 +	      message.  If a diff is longer than this, it is
 1.10981 +	      truncated.  By default, this is set to 300.  Set this to
 1.10982 +	      <literal moreinfo="none">0</literal> to omit diffs from notification
 1.10983 +	      emails.
 1.10984 +	    </para>
 1.10985 +	  </listitem>
 1.10986 +	  <listitem><para id="x_274"><envar role="rc-item-notify">sources</envar>: A list of
 1.10987 +	      sources of changesets to consider.  This lets you limit
 1.10988 +	      <literal role="hg-ext" moreinfo="none">notify</literal> to only sending
 1.10989 +	      out email about changes that remote users pushed into
 1.10990 +	      this repository via a server, for example.  See 
 1.10991 +	      <xref linkend="sec:hook:sources"/> for the sources you
 1.10992 +	      can specify here.
 1.10993 +	    </para>
 1.10994 +	  </listitem></itemizedlist>
 1.10995 +
 1.10996 +	<para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar>
 1.10997 +	  item in the <literal role="rc-web" moreinfo="none">web</literal> section,
 1.10998 +	  you can use it in a template; it will be available as
 1.10999 +	  <literal moreinfo="none">webroot</literal>.
 1.11000 +	</para>
 1.11001 +
 1.11002 +	<para id="x_276">Here is an example set of <literal role="hg-ext" moreinfo="none">notify</literal> configuration information.
 1.11003 +	</para>
 1.11004 +
 1.11005 +	<!-- BEGIN ch10/notify-config.lst -->
 1.11006 +<programlisting format="linespecific">[notify]
 1.11007 +# really send email
 1.11008 +test = false
 1.11009 +# subscriber data lives in the notify repo
 1.11010 +config = /home/hg/repos/notify/notify.conf
 1.11011 +# repos live in /home/hg/repos on server, so strip 4 "/" chars
 1.11012 +strip = 4
 1.11013 +template = X-Hg-Repo: {webroot}\n
 1.11014 +  Subject: {webroot}: {desc|firstline|strip}\n
 1.11015 +  From: {author}
 1.11016 +  \n\n
 1.11017 +  changeset {node|short} in {root}
 1.11018 +  \n\ndetails:
 1.11019 +  {baseurl}{webroot}?cmd=changeset;node={node|short}
 1.11020 +  description: {desc|tabindent|strip}
 1.11021 +
 1.11022 +[web]
 1.11023 +baseurl =
 1.11024 +http://hg.example.com/</programlisting>
 1.11025 +<!-- END ch10/notify-config.lst -->
 1.11026 +
 1.11027 +
 1.11028 +	<para id="x_277">This will produce a message that looks like the
 1.11029 +	  following:
 1.11030 +	</para>
 1.11031 +
 1.11032 +	<!-- BEGIN ch10/notify-config-mail.lst -->
 1.11033 +<programlisting format="linespecific">X-Hg-Repo: tests/slave
 1.11034 +Subject: tests/slave: Handle error case when slave has no buffers
 1.11035 +Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
 1.11036 +
 1.11037 +changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
 1.11038 +
 1.11039 +details:
 1.11040 +http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5 
 1.11041 +
 1.11042 +description: Handle error case when slave has no buffers
 1.11043 +
 1.11044 +diffs (54 lines):
 1.11045 +diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
 1.11046 +--- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
 1.11047 ++++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
 1.11048 +@@ -212,6 +212,15 @@ static __inline__
 1.11049 +void test_headers(void *h)
 1.11050 +[...snip...]</programlisting>
 1.11051 +<!-- END ch10/notify-config-mail.lst -->
 1.11052 +
 1.11053 +
 1.11054 +      </sect3>
 1.11055 +      <sect3>
 1.11056 +	<title>Testing and troubleshooting</title>
 1.11057 +
 1.11058 +	<para id="x_278">Do not forget that by default, the <literal role="hg-ext" moreinfo="none">notify</literal> extension <emphasis>will not
 1.11059 +	  send any mail</emphasis> until you explicitly configure it to do so,
 1.11060 +	  by setting <envar role="rc-item-notify">test</envar> to
 1.11061 +	  <literal moreinfo="none">false</literal>.  Until you do that, it simply
 1.11062 +	  prints the message it <emphasis>would</emphasis> send.
 1.11063 +	</para>
 1.11064 +
 1.11065 +      </sect3>
 1.11066 +    </sect2>
 1.11067 +  </sect1>
 1.11068 +  <sect1 id="sec:hook:ref">
 1.11069 +    <title>Information for writers of hooks</title>
 1.11070 +
 1.11071 +    <sect2>
 1.11072 +      <title>In-process hook execution</title>
 1.11073 +
 1.11074 +      <para id="x_279">An in-process hook is called with arguments of the
 1.11075 +	following form:
 1.11076 +      </para>
 1.11077 +      <programlisting format="linespecific">def myhook(ui, repo, **kwargs): pass</programlisting>
 1.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
 1.11079 +	<literal moreinfo="none">repo</literal> parameter is a <literal role="py-mod-mercurial.localrepo" moreinfo="none">localrepository</literal>
 1.11080 +	object.  The names and values of the
 1.11081 +	<literal moreinfo="none">**kwargs</literal> parameters depend on the hook
 1.11082 +	being invoked, with the following common features:
 1.11083 +      </para>
 1.11084 +      <itemizedlist>
 1.11085 +	<listitem><para id="x_27b">If a parameter is named
 1.11086 +	    <literal moreinfo="none">node</literal> or <literal moreinfo="none">parentN</literal>, it
 1.11087 +	    will contain a hexadecimal changeset ID. The empty string
 1.11088 +	    is used to represent <quote>null changeset ID</quote>
 1.11089 +	    instead of a string of zeroes.
 1.11090 +	  </para>
 1.11091 +	</listitem>
 1.11092 +	<listitem><para id="x_27c">If a parameter is named
 1.11093 +	    <literal moreinfo="none">url</literal>, it will contain the URL of a
 1.11094 +	    remote repository, if that can be determined.
 1.11095 +	  </para>
 1.11096 +	</listitem>
 1.11097 +	<listitem><para id="x_27d">Boolean-valued parameters are represented as
 1.11098 +	    Python <literal moreinfo="none">bool</literal> objects.
 1.11099 +	  </para>
 1.11100 +	</listitem></itemizedlist>
 1.11101 +
 1.11102 +      <para id="x_27e">An in-process hook is called without a change to the
 1.11103 +	process's working directory (unlike external hooks, which are
 1.11104 +	run in the root of the repository).  It must not change the
 1.11105 +	process's working directory, or it will cause any calls it
 1.11106 +	makes into the Mercurial API to fail.
 1.11107 +      </para>
 1.11108 +
 1.11109 +      <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it
 1.11110 +	is considered to have succeeded.  If it returns a boolean
 1.11111 +	<quote>true</quote> value or raises an exception, it is
 1.11112 +	considered to have failed.  A useful way to think of the
 1.11113 +	calling convention is <quote>tell me if you fail</quote>.
 1.11114 +      </para>
 1.11115 +
 1.11116 +      <para id="x_280">Note that changeset IDs are passed into Python hooks as
 1.11117 +	hexadecimal strings, not the binary hashes that Mercurial's
 1.11118 +	APIs normally use.  To convert a hash from hex to binary, use
 1.11119 +	the <literal moreinfo="none">bin</literal> function.
 1.11120 +      </para>
 1.11121 +    </sect2>
 1.11122 +
 1.11123 +    <sect2>
 1.11124 +      <title>External hook execution</title>
 1.11125 +
 1.11126 +      <para id="x_281">An external hook is passed to the shell of the user
 1.11127 +	running Mercurial. Features of that shell, such as variable
 1.11128 +	substitution and command redirection, are available.  The hook
 1.11129 +	is run in the root directory of the repository (unlike
 1.11130 +	in-process hooks, which are run in the same directory that
 1.11131 +	Mercurial was run in).
 1.11132 +      </para>
 1.11133 +
 1.11134 +      <para id="x_282">Hook parameters are passed to the hook as environment
 1.11135 +	variables.  Each environment variable's name is converted in
 1.11136 +	upper case and prefixed with the string
 1.11137 +	<quote><literal moreinfo="none">HG_</literal></quote>.  For example, if the
 1.11138 +	name of a parameter is <quote><literal moreinfo="none">node</literal></quote>,
 1.11139 +	the name of the environment variable representing that
 1.11140 +	parameter will be <quote><literal moreinfo="none">HG_NODE</literal></quote>.
 1.11141 +      </para>
 1.11142 +
 1.11143 +      <para id="x_283">A boolean parameter is represented as the string
 1.11144 +	<quote><literal moreinfo="none">1</literal></quote> for <quote>true</quote>,
 1.11145 +	<quote><literal moreinfo="none">0</literal></quote> for <quote>false</quote>.
 1.11146 +	If an environment variable is named <envar>HG_NODE</envar>,
 1.11147 +	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
 1.11148 +	contains a changeset ID represented as a hexadecimal string.
 1.11149 +	The empty string is used to represent <quote>null changeset
 1.11150 +	  ID</quote> instead of a string of zeroes.  If an environment
 1.11151 +	variable is named <envar>HG_URL</envar>, it will contain the
 1.11152 +	URL of a remote repository, if that can be determined.
 1.11153 +      </para>
 1.11154 +
 1.11155 +      <para id="x_284">If a hook exits with a status of zero, it is considered to
 1.11156 +	have succeeded.  If it exits with a non-zero status, it is
 1.11157 +	considered to have failed.
 1.11158 +      </para>
 1.11159 +    </sect2>
 1.11160 +
 1.11161 +    <sect2>
 1.11162 +      <title>Finding out where changesets come from</title>
 1.11163 +
 1.11164 +      <para id="x_285">A hook that involves the transfer of changesets between a
 1.11165 +	local repository and another may be able to find out
 1.11166 +	information about the <quote>far side</quote>.  Mercurial
 1.11167 +	knows <emphasis>how</emphasis> changes are being transferred,
 1.11168 +	and in many cases <emphasis>where</emphasis> they are being
 1.11169 +	transferred to or from.
 1.11170 +      </para>
 1.11171 +
 1.11172 +      <sect3 id="sec:hook:sources">
 1.11173 +	<title>Sources of changesets</title>
 1.11174 +
 1.11175 +	<para id="x_286">Mercurial will tell a hook what means are, or were, used
 1.11176 +	  to transfer changesets between repositories.  This is
 1.11177 +	  provided by Mercurial in a Python parameter named
 1.11178 +	  <literal moreinfo="none">source</literal>, or an environment variable named
 1.11179 +	  <envar>HG_SOURCE</envar>.
 1.11180 +	</para>
 1.11181 +
 1.11182 +	<itemizedlist>
 1.11183 +	  <listitem><para id="x_287"><literal moreinfo="none">serve</literal>: Changesets are
 1.11184 +	      transferred to or from a remote repository over http or
 1.11185 +	      ssh.
 1.11186 +	    </para>
 1.11187 +	  </listitem>
 1.11188 +	  <listitem><para id="x_288"><literal moreinfo="none">pull</literal>: Changesets are
 1.11189 +	      being transferred via a pull from one repository into
 1.11190 +	      another.
 1.11191 +	    </para>
 1.11192 +	  </listitem>
 1.11193 +	  <listitem><para id="x_289"><literal moreinfo="none">push</literal>: Changesets are
 1.11194 +	      being transferred via a push from one repository into
 1.11195 +	      another.
 1.11196 +	    </para>
 1.11197 +	  </listitem>
 1.11198 +	  <listitem><para id="x_28a"><literal moreinfo="none">bundle</literal>: Changesets are
 1.11199 +	      being transferred to or from a bundle.
 1.11200 +	    </para>
 1.11201 +	  </listitem></itemizedlist>
 1.11202 +      </sect3>
 1.11203 +
 1.11204 +      <sect3 id="sec:hook:url">
 1.11205 +	<title>Where changes are going—remote repository
 1.11206 +	  URLs</title>
 1.11207 +
 1.11208 +	<para id="x_28b">When possible, Mercurial will tell a hook the location
 1.11209 +	  of the <quote>far side</quote> of an activity that transfers
 1.11210 +	  changeset data between repositories.  This is provided by
 1.11211 +	  Mercurial in a Python parameter named
 1.11212 +	  <literal moreinfo="none">url</literal>, or an environment variable named
 1.11213 +	  <envar>HG_URL</envar>.
 1.11214 +	</para>
 1.11215 +
 1.11216 +	<para id="x_28c">This information is not always known.  If a hook is
 1.11217 +	  invoked in a repository that is being served via http or
 1.11218 +	  ssh, Mercurial cannot tell where the remote repository is,
 1.11219 +	  but it may know where the client is connecting from.  In
 1.11220 +	  such cases, the URL will take one of the following forms:
 1.11221 +	</para>
 1.11222 +	<itemizedlist>
 1.11223 +	  <listitem><para id="x_28d"><literal moreinfo="none">remote:ssh:1.2.3.4</literal>—remote 
 1.11224 +	      ssh client, at the IP address
 1.11225 +	      <literal moreinfo="none">1.2.3.4</literal>.
 1.11226 +	    </para>
 1.11227 +	  </listitem>
 1.11228 +	  <listitem><para id="x_28e"><literal moreinfo="none">remote:http:1.2.3.4</literal>—remote 
 1.11229 +	      http client, at the IP address
 1.11230 +	      <literal moreinfo="none">1.2.3.4</literal>.  If the client is using SSL,
 1.11231 +	      this will be of the form
 1.11232 +	      <literal moreinfo="none">remote:https:1.2.3.4</literal>.
 1.11233 +	    </para>
 1.11234 +	  </listitem>
 1.11235 +	  <listitem><para id="x_28f">Empty—no information could be
 1.11236 +	      discovered about the remote client.
 1.11237 +	    </para>
 1.11238 +	  </listitem></itemizedlist>
 1.11239 +      </sect3>
 1.11240 +    </sect2>
 1.11241 +  </sect1>
 1.11242 +  <sect1>
 1.11243 +    <title>Hook reference</title>
 1.11244 +
 1.11245 +    <sect2 id="sec:hook:changegroup">
 1.11246 +      <title><literal role="hook" moreinfo="none">changegroup</literal>—after
 1.11247 +	remote changesets added</title>
 1.11248 +
 1.11249 +      <para id="x_290">This hook is run after a group of pre-existing changesets
 1.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
 1.11251 +	  unbundle</command>.  This hook is run once per operation
 1.11252 +	that added one or more changesets.  This is in contrast to the
 1.11253 +	<literal role="hook" moreinfo="none">incoming</literal> hook, which is run
 1.11254 +	once per changeset, regardless of whether the changesets
 1.11255 +	arrive in a group.
 1.11256 +      </para>
 1.11257 +
 1.11258 +      <para id="x_291">Some possible uses for this hook include kicking off an
 1.11259 +	automated build or test of the added changesets, updating a
 1.11260 +	bug database, or notifying subscribers that a repository
 1.11261 +	contains new changes.
 1.11262 +      </para>
 1.11263 +
 1.11264 +      <para id="x_292">Parameters to this hook:
 1.11265 +      </para>
 1.11266 +      <itemizedlist>
 1.11267 +	<listitem><para id="x_293"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11268 +	    changeset ID of the first changeset in the group that was
 1.11269 +	    added.  All changesets between this and
 1.11270 +	    <literal role="tag" moreinfo="none">tip</literal>, inclusive, were added by a single
 1.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>.
 1.11272 +	  </para>
 1.11273 +	</listitem>
 1.11274 +	<listitem><para id="x_294"><literal moreinfo="none">source</literal>: A
 1.11275 +	    string.  The source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 1.11276 +	  </para>
 1.11277 +	</listitem>
 1.11278 +	<listitem><para id="x_295"><literal moreinfo="none">url</literal>: A URL.  The
 1.11279 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 1.11280 +	  </para>
 1.11281 +	</listitem></itemizedlist>
 1.11282 +
 1.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"/>)
 1.11284 +      </para>
 1.11285 +    </sect2>
 1.11286 +
 1.11287 +    <sect2 id="sec:hook:commit">
 1.11288 +      <title><literal role="hook" moreinfo="none">commit</literal>—after a new
 1.11289 +	changeset is created</title>
 1.11290 +
 1.11291 +      <para id="x_297">This hook is run after a new changeset has been created.
 1.11292 +      </para>
 1.11293 +
 1.11294 +      <para id="x_298">Parameters to this hook:
 1.11295 +      </para>
 1.11296 +      <itemizedlist>
 1.11297 +	<listitem><para id="x_299"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11298 +	    changeset ID of the newly committed changeset.
 1.11299 +	  </para>
 1.11300 +	</listitem>
 1.11301 +	<listitem><para id="x_29a"><literal moreinfo="none">parent1</literal>: A changeset ID.
 1.11302 +	    The changeset ID of the first parent of the newly
 1.11303 +	    committed changeset.
 1.11304 +	  </para>
 1.11305 +	</listitem>
 1.11306 +	<listitem><para id="x_29b"><literal moreinfo="none">parent2</literal>: A changeset ID.
 1.11307 +	    The changeset ID of the second parent of the newly
 1.11308 +	    committed changeset.
 1.11309 +	  </para>
 1.11310 +	</listitem></itemizedlist>
 1.11311 +
 1.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"/>)
 1.11313 +      </para>
 1.11314 +    </sect2>
 1.11315 +
 1.11316 +    <sect2 id="sec:hook:incoming">
 1.11317 +      <title><literal role="hook" moreinfo="none">incoming</literal>—after one
 1.11318 +	remote changeset is added</title>
 1.11319 +
 1.11320 +      <para id="x_29d">This hook is run after a pre-existing changeset has been
 1.11321 +	added to the repository, for example via a <command role="hg-cmd" moreinfo="none">hg push</command>.  If a group of changesets
 1.11322 +	was added in a single operation, this hook is called once for
 1.11323 +	each added changeset.
 1.11324 +      </para>
 1.11325 +
 1.11326 +      <para id="x_29e">You can use this hook for the same purposes as
 1.11327 +	the <literal role="hook" moreinfo="none">changegroup</literal> hook (<xref linkend="sec:hook:changegroup"/>); it's simply more
 1.11328 +	convenient sometimes to run a hook once per group of
 1.11329 +	changesets, while other times it's handier once per changeset.
 1.11330 +      </para>
 1.11331 +
 1.11332 +      <para id="x_29f">Parameters to this hook:
 1.11333 +      </para>
 1.11334 +      <itemizedlist>
 1.11335 +	<listitem><para id="x_2a0"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11336 +	    ID of the newly added changeset.
 1.11337 +	  </para>
 1.11338 +	</listitem>
 1.11339 +	<listitem><para id="x_2a1"><literal moreinfo="none">source</literal>: A
 1.11340 +	    string.  The source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 1.11341 +	  </para>
 1.11342 +	</listitem>
 1.11343 +	<listitem><para id="x_2a2"><literal moreinfo="none">url</literal>: A URL.  The
 1.11344 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 1.11345 +	  </para>
 1.11346 +	</listitem></itemizedlist>
 1.11347 +
 1.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"/>)
 1.11349 +      </para>
 1.11350 +    </sect2>
 1.11351 +
 1.11352 +    <sect2 id="sec:hook:outgoing">
 1.11353 +      <title><literal role="hook" moreinfo="none">outgoing</literal>—after
 1.11354 +	changesets are propagated</title>
 1.11355 +
 1.11356 +      <para id="x_2a4">This hook is run after a group of changesets has been
 1.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
 1.11358 +	  bundle</command> command.
 1.11359 +      </para>
 1.11360 +
 1.11361 +      <para id="x_2a5">One possible use for this hook is to notify administrators
 1.11362 +	that changes have been pulled.
 1.11363 +      </para>
 1.11364 +
 1.11365 +      <para id="x_2a6">Parameters to this hook:
 1.11366 +      </para>
 1.11367 +      <itemizedlist>
 1.11368 +	<listitem><para id="x_2a7"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11369 +	    changeset ID of the first changeset of the group that was
 1.11370 +	    sent.
 1.11371 +	  </para>
 1.11372 +	</listitem>
 1.11373 +	<listitem><para id="x_2a8"><literal moreinfo="none">source</literal>: A string.  The
 1.11374 +	    source of the of the operation (see <xref linkend="sec:hook:sources"/>).  If a remote
 1.11375 +	    client pulled changes from this repository,
 1.11376 +	    <literal moreinfo="none">source</literal> will be
 1.11377 +	    <literal moreinfo="none">serve</literal>.  If the client that obtained
 1.11378 +	    changes from this repository was local,
 1.11379 +	    <literal moreinfo="none">source</literal> will be
 1.11380 +	    <literal moreinfo="none">bundle</literal>, <literal moreinfo="none">pull</literal>, or
 1.11381 +	    <literal moreinfo="none">push</literal>, depending on the operation the
 1.11382 +	    client performed.
 1.11383 +	  </para>
 1.11384 +	</listitem>
 1.11385 +	<listitem><para id="x_2a9"><literal moreinfo="none">url</literal>: A URL.  The
 1.11386 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 1.11387 +	  </para>
 1.11388 +	</listitem></itemizedlist>
 1.11389 +
 1.11390 +      <para id="x_2aa">See also: <literal role="hook" moreinfo="none">preoutgoing</literal> (<xref linkend="sec:hook:preoutgoing"/>)
 1.11391 +      </para>
 1.11392 +    </sect2>
 1.11393 +
 1.11394 +    <sect2 id="sec:hook:prechangegroup">
 1.11395 +      <title><literal role="hook" moreinfo="none">prechangegroup</literal>—before starting
 1.11396 +	to add remote changesets</title>
 1.11397 +
 1.11398 +      <para id="x_2ab">This controlling hook is run before Mercurial begins to
 1.11399 +	add a group of changesets from another repository.
 1.11400 +      </para>
 1.11401 +
 1.11402 +      <para id="x_2ac">This hook does not have any information about the
 1.11403 +	changesets to be added, because it is run before transmission
 1.11404 +	of those changesets is allowed to begin.  If this hook fails,
 1.11405 +	the changesets will not be transmitted.
 1.11406 +      </para>
 1.11407 +
 1.11408 +      <para id="x_2ad">One use for this hook is to prevent external changes from
 1.11409 +	being added to a repository.  For example, you could use this
 1.11410 +	to <quote>freeze</quote> a server-hosted branch temporarily or
 1.11411 +	permanently so that users cannot push to it, while still
 1.11412 +	allowing a local administrator to modify the repository.
 1.11413 +      </para>
 1.11414 +
 1.11415 +      <para id="x_2ae">Parameters to this hook:
 1.11416 +      </para>
 1.11417 +      <itemizedlist>
 1.11418 +	<listitem><para id="x_2af"><literal moreinfo="none">source</literal>: A string.  The
 1.11419 +	    source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 1.11420 +	  </para>
 1.11421 +	</listitem>
 1.11422 +	<listitem><para id="x_2b0"><literal moreinfo="none">url</literal>: A URL.  The
 1.11423 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 1.11424 +	  </para>
 1.11425 +	</listitem></itemizedlist>
 1.11426 +
 1.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"/>)
 1.11428 +      </para>
 1.11429 +    </sect2>
 1.11430 +
 1.11431 +    <sect2 id="sec:hook:precommit">
 1.11432 +      <title><literal role="hook" moreinfo="none">precommit</literal>—before
 1.11433 +	starting to commit a changeset</title>
 1.11434 +
 1.11435 +      <para id="x_2b2">This hook is run before Mercurial begins to commit a new
 1.11436 +	changeset. It is run before Mercurial has any of the metadata
 1.11437 +	for the commit, such as the files to be committed, the commit
 1.11438 +	message, or the commit date.
 1.11439 +      </para>
 1.11440 +
 1.11441 +      <para id="x_2b3">One use for this hook is to disable the ability to commit
 1.11442 +	new changesets, while still allowing incoming changesets.
 1.11443 +	Another is to run a build or test, and only allow the commit
 1.11444 +	to begin if the build or test succeeds.
 1.11445 +      </para>
 1.11446 +
 1.11447 +      <para id="x_2b4">Parameters to this hook:
 1.11448 +      </para>
 1.11449 +      <itemizedlist>
 1.11450 +	<listitem><para id="x_2b5"><literal moreinfo="none">parent1</literal>: A changeset ID.
 1.11451 +	    The changeset ID of the first parent of the working
 1.11452 +	    directory.
 1.11453 +	  </para>
 1.11454 +	</listitem>
 1.11455 +	<listitem><para id="x_2b6"><literal moreinfo="none">parent2</literal>: A changeset ID.
 1.11456 +	    The changeset ID of the second parent of the working
 1.11457 +	    directory.
 1.11458 +	  </para>
 1.11459 +	</listitem></itemizedlist>
 1.11460 +      <para id="x_2b7">If the commit proceeds, the parents of the working
 1.11461 +	directory will become the parents of the new changeset.
 1.11462 +      </para>
 1.11463 +
 1.11464 +      <para id="x_2b8">See also: <literal role="hook" moreinfo="none">commit</literal>
 1.11465 +	(<xref linkend="sec:hook:commit"/>), <literal role="hook" moreinfo="none">pretxncommit</literal> (<xref linkend="sec:hook:pretxncommit"/>)
 1.11466 +      </para>
 1.11467 +    </sect2>
 1.11468 +
 1.11469 +    <sect2 id="sec:hook:preoutgoing">
 1.11470 +      <title><literal role="hook" moreinfo="none">preoutgoing</literal>—before
 1.11471 +	starting to propagate changesets</title>
 1.11472 +
 1.11473 +      <para id="x_2b9">This hook is invoked before Mercurial knows the identities
 1.11474 +	of the changesets to be transmitted.
 1.11475 +      </para>
 1.11476 +
 1.11477 +      <para id="x_2ba">One use for this hook is to prevent changes from being
 1.11478 +	transmitted to another repository.
 1.11479 +      </para>
 1.11480 +
 1.11481 +      <para id="x_2bb">Parameters to this hook:
 1.11482 +      </para>
 1.11483 +      <itemizedlist>
 1.11484 +	<listitem><para id="x_2bc"><literal moreinfo="none">source</literal>: A
 1.11485 +	    string.  The source of the operation that is attempting to
 1.11486 +	    obtain changes from this repository (see <xref linkend="sec:hook:sources"/>).  See the documentation
 1.11487 +	    for the <literal moreinfo="none">source</literal> parameter to the
 1.11488 +	    <literal role="hook" moreinfo="none">outgoing</literal> hook, in
 1.11489 +	    <xref linkend="sec:hook:outgoing"/>, for possible values
 1.11490 +	    of this parameter.
 1.11491 +	  </para>
 1.11492 +	</listitem>
 1.11493 +	<listitem><para id="x_2bd"><literal moreinfo="none">url</literal>: A URL.  The
 1.11494 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 1.11495 +	  </para>
 1.11496 +	</listitem></itemizedlist>
 1.11497 +
 1.11498 +      <para id="x_2be">See also: <literal role="hook" moreinfo="none">outgoing</literal> (<xref linkend="sec:hook:outgoing"/>)
 1.11499 +      </para>
 1.11500 +    </sect2>
 1.11501 +
 1.11502 +    <sect2 id="sec:hook:pretag">
 1.11503 +      <title><literal role="hook" moreinfo="none">pretag</literal>—before
 1.11504 +	tagging a changeset</title>
 1.11505 +
 1.11506 +      <para id="x_2bf">This controlling hook is run before a tag is created.  If
 1.11507 +	the hook succeeds, creation of the tag proceeds.  If the hook
 1.11508 +	fails, the tag is not created.
 1.11509 +      </para>
 1.11510 +
 1.11511 +      <para id="x_2c0">Parameters to this hook:
 1.11512 +      </para>
 1.11513 +      <itemizedlist>
 1.11514 +	<listitem><para id="x_2c1"><literal moreinfo="none">local</literal>: A boolean.  Whether
 1.11515 +	    the tag is local to this repository instance (i.e. stored
 1.11516 +	    in <filename role="special" moreinfo="none">.hg/localtags</filename>) or
 1.11517 +	    managed by Mercurial (stored in <filename role="special" moreinfo="none">.hgtags</filename>).
 1.11518 +	  </para>
 1.11519 +	</listitem>
 1.11520 +	<listitem><para id="x_2c2"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11521 +	    ID of the changeset to be tagged.
 1.11522 +	  </para>
 1.11523 +	</listitem>
 1.11524 +	<listitem><para id="x_2c3"><literal moreinfo="none">tag</literal>: A string.  The name of
 1.11525 +	    the tag to be created.
 1.11526 +	  </para>
 1.11527 +	</listitem></itemizedlist>
 1.11528 +
 1.11529 +      <para id="x_2c4">If the tag to be created is
 1.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.
 1.11531 +      </para>
 1.11532 +
 1.11533 +      <para id="x_2c5">See also: <literal role="hook" moreinfo="none">tag</literal>
 1.11534 +	(<xref linkend="sec:hook:tag"/>)
 1.11535 +      </para>
 1.11536 +    </sect2>
 1.11537 +
 1.11538 +    <sect2 id="sec:hook:pretxnchangegroup">
 1.11539 +      <title><literal role="hook" moreinfo="none">pretxnchangegroup</literal>—before
 1.11540 +	completing addition of remote changesets</title>
 1.11541 +
 1.11542 +      <para id="x_2c6">This controlling hook is run before a
 1.11543 +	transaction—that manages the addition of a group of new
 1.11544 +	changesets from outside the repository—completes.  If
 1.11545 +	the hook succeeds, the transaction completes, and all of the
 1.11546 +	changesets become permanent within this repository.  If the
 1.11547 +	hook fails, the transaction is rolled back, and the data for
 1.11548 +	the changesets is erased.
 1.11549 +      </para>
 1.11550 +
 1.11551 +      <para id="x_2c7">This hook can access the metadata associated with the
 1.11552 +	almost-added changesets, but it should not do anything
 1.11553 +	permanent with this data. It must also not modify the working
 1.11554 +	directory.
 1.11555 +      </para>
 1.11556 +
 1.11557 +      <para id="x_2c8">While this hook is running, if other Mercurial processes
 1.11558 +	access this repository, they will be able to see the
 1.11559 +	almost-added changesets as if they are permanent.  This may
 1.11560 +	lead to race conditions if you do not take steps to avoid
 1.11561 +	them.
 1.11562 +      </para>
 1.11563 +
 1.11564 +      <para id="x_2c9">This hook can be used to automatically vet a group of
 1.11565 +	changesets.  If the hook fails, all of the changesets are
 1.11566 +	<quote>rejected</quote> when the transaction rolls back.
 1.11567 +      </para>
 1.11568 +
 1.11569 +      <para id="x_2ca">Parameters to this hook:
 1.11570 +      </para>
 1.11571 +      <itemizedlist>
 1.11572 +	<listitem><para id="x_2cb"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11573 +	    changeset ID of the first changeset in the group that was
 1.11574 +	    added.  All changesets between this and
 1.11575 +	    <literal role="tag" moreinfo="none">tip</literal>,
 1.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>.
 1.11577 +	  </para>
 1.11578 +	</listitem>
 1.11579 +	<listitem><para id="x_2cc"><literal moreinfo="none">source</literal>: A
 1.11580 +	    string.  The source of these changes.  See <xref linkend="sec:hook:sources"/> for details.
 1.11581 +	  </para>
 1.11582 +	</listitem>
 1.11583 +	<listitem><para id="x_2cd"><literal moreinfo="none">url</literal>: A URL.  The
 1.11584 +	    location of the remote repository, if known.  See <xref linkend="sec:hook:url"/> for more information.
 1.11585 +	  </para>
 1.11586 +	</listitem></itemizedlist>
 1.11587 +
 1.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"/>)
 1.11589 +      </para>
 1.11590 +    </sect2>
 1.11591 +
 1.11592 +    <sect2 id="sec:hook:pretxncommit">
 1.11593 +      <title><literal role="hook" moreinfo="none">pretxncommit</literal>—before
 1.11594 +	completing commit of new changeset</title>
 1.11595 +
 1.11596 +      <para id="x_2cf">This controlling hook is run before a
 1.11597 +	transaction—that manages a new commit—completes.
 1.11598 +	If the hook succeeds, the transaction completes and the
 1.11599 +	changeset becomes permanent within this repository.  If the
 1.11600 +	hook fails, the transaction is rolled back, and the commit
 1.11601 +	data is erased.
 1.11602 +      </para>
 1.11603 +
 1.11604 +      <para id="x_2d0">This hook can access the metadata associated with the
 1.11605 +	almost-new changeset, but it should not do anything permanent
 1.11606 +	with this data.  It must also not modify the working
 1.11607 +	directory.
 1.11608 +      </para>
 1.11609 +
 1.11610 +      <para id="x_2d1">While this hook is running, if other Mercurial processes
 1.11611 +	access this repository, they will be able to see the
 1.11612 +	almost-new changeset as if it is permanent.  This may lead to
 1.11613 +	race conditions if you do not take steps to avoid them.
 1.11614 +      </para>
 1.11615 +
 1.11616 +      <para id="x_2d2">Parameters to this hook:</para>
 1.11617 +
 1.11618 +      <itemizedlist>
 1.11619 +	<listitem><para id="x_2d3"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11620 +	    changeset ID of the newly committed changeset.
 1.11621 +	  </para>
 1.11622 +	</listitem>
 1.11623 +	<listitem><para id="x_2d4"><literal moreinfo="none">parent1</literal>: A changeset ID.
 1.11624 +	    The changeset ID of the first parent of the newly
 1.11625 +	    committed changeset.
 1.11626 +	  </para>
 1.11627 +	</listitem>
 1.11628 +	<listitem><para id="x_2d5"><literal moreinfo="none">parent2</literal>: A changeset ID.
 1.11629 +	    The changeset ID of the second parent of the newly
 1.11630 +	    committed changeset.
 1.11631 +	  </para>
 1.11632 +	</listitem></itemizedlist>
 1.11633 +
 1.11634 +      <para id="x_2d6">See also: <literal role="hook" moreinfo="none">precommit</literal> (<xref linkend="sec:hook:precommit"/>)
 1.11635 +      </para>
 1.11636 +    </sect2>
 1.11637 +
 1.11638 +    <sect2 id="sec:hook:preupdate">
 1.11639 +      <title><literal role="hook" moreinfo="none">preupdate</literal>—before
 1.11640 +	updating or merging working directory</title>
 1.11641 +
 1.11642 +      <para id="x_2d7">This controlling hook is run before an update
 1.11643 +	or merge of the working directory begins.  It is run only if
 1.11644 +	Mercurial's normal pre-update checks determine that the update
 1.11645 +	or merge can proceed.  If the hook succeeds, the update or
 1.11646 +	merge may proceed; if it fails, the update or merge does not
 1.11647 +	start.
 1.11648 +      </para>
 1.11649 +
 1.11650 +      <para id="x_2d8">Parameters to this hook:
 1.11651 +      </para>
 1.11652 +      <itemizedlist>
 1.11653 +	<listitem><para id="x_2d9"><literal moreinfo="none">parent1</literal>: A
 1.11654 +	    changeset ID. The ID of the parent that the working
 1.11655 +	    directory is to be updated to.  If the working directory
 1.11656 +	    is being merged, it will not change this parent.
 1.11657 +	  </para>
 1.11658 +	</listitem>
 1.11659 +	<listitem><para id="x_2da"><literal moreinfo="none">parent2</literal>: A
 1.11660 +	    changeset ID. Only set if the working directory is being
 1.11661 +	    merged.  The ID of the revision that the working directory
 1.11662 +	    is being merged with.
 1.11663 +	  </para>
 1.11664 +	</listitem></itemizedlist>
 1.11665 +
 1.11666 +      <para id="x_2db">See also: <literal role="hook" moreinfo="none">update</literal>
 1.11667 +	(<xref linkend="sec:hook:update"/>)</para>
 1.11668 +    </sect2>
 1.11669 +
 1.11670 +    <sect2 id="sec:hook:tag">
 1.11671 +      <title><literal role="hook" moreinfo="none">tag</literal>—after tagging a
 1.11672 +	changeset</title>
 1.11673 +
 1.11674 +      <para id="x_2dc">This hook is run after a tag has been created.
 1.11675 +      </para>
 1.11676 +
 1.11677 +      <para id="x_2dd">Parameters to this hook:
 1.11678 +      </para>
 1.11679 +      <itemizedlist>
 1.11680 +	<listitem><para id="x_2de"><literal moreinfo="none">local</literal>: A boolean.  Whether
 1.11681 +	    the new tag is local to this repository instance (i.e.
 1.11682 +	    stored in <filename role="special" moreinfo="none">.hg/localtags</filename>) or managed by
 1.11683 +	    Mercurial (stored in <filename role="special" moreinfo="none">.hgtags</filename>).
 1.11684 +	  </para>
 1.11685 +	</listitem>
 1.11686 +	<listitem><para id="x_2df"><literal moreinfo="none">node</literal>: A changeset ID.  The
 1.11687 +	    ID of the changeset that was tagged.
 1.11688 +	  </para>
 1.11689 +	</listitem>
 1.11690 +	<listitem><para id="x_2e0"><literal moreinfo="none">tag</literal>: A string.  The name of
 1.11691 +	    the tag that was created.
 1.11692 +	  </para>
 1.11693 +	</listitem></itemizedlist>
 1.11694 +
 1.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.
 1.11696 +      </para>
 1.11697 +
 1.11698 +      <para id="x_2e2">See also: <literal role="hook" moreinfo="none">pretag</literal>
 1.11699 +	(<xref linkend="sec:hook:pretag"/>)
 1.11700 +      </para>
 1.11701 +    </sect2>
 1.11702 +
 1.11703 +    <sect2 id="sec:hook:update">
 1.11704 +      <title><literal role="hook" moreinfo="none">update</literal>—after
 1.11705 +	updating or merging working directory</title>
 1.11706 +
 1.11707 +      <para id="x_2e3">This hook is run after an update or merge of the working
 1.11708 +	directory completes.  Since a merge can fail (if the external
 1.11709 +	<command moreinfo="none">hgmerge</command> command fails to resolve conflicts
 1.11710 +	in a file), this hook communicates whether the update or merge
 1.11711 +	completed cleanly.
 1.11712 +      </para>
 1.11713 +
 1.11714 +      <itemizedlist>
 1.11715 +	<listitem><para id="x_2e4"><literal moreinfo="none">error</literal>: A boolean.
 1.11716 +	    Indicates whether the update or merge completed
 1.11717 +	    successfully.
 1.11718 +	  </para>
 1.11719 +	</listitem>
 1.11720 +	<listitem><para id="x_2e5"><literal moreinfo="none">parent1</literal>: A changeset ID.
 1.11721 +	    The ID of the parent that the working directory was
 1.11722 +	    updated to.  If the working directory was merged, it will
 1.11723 +	    not have changed this parent.
 1.11724 +	  </para>
 1.11725 +	</listitem>
 1.11726 +	<listitem><para id="x_2e6"><literal moreinfo="none">parent2</literal>: A changeset ID.
 1.11727 +	    Only set if the working directory was merged.  The ID of
 1.11728 +	    the revision that the working directory was merged with.
 1.11729 +	  </para>
 1.11730 +	</listitem></itemizedlist>
 1.11731 +
 1.11732 +      <para id="x_2e7">See also: <literal role="hook" moreinfo="none">preupdate</literal>
 1.11733 +	(<xref linkend="sec:hook:preupdate"/>)
 1.11734 +      </para>
 1.11735 +
 1.11736 +    </sect2>
 1.11737 +  </sect1>
 1.11738 +</chapter>
 1.11739 +
 1.11740 +<!--
 1.11741 +local variables: 
 1.11742 +sgml-parent-document: ("00book.xml" "book" "chapter")
 1.11743 +end:
 1.11744 +-->
 1.11745 +
 1.11746 +  <!-- BEGIN ch11 -->
 1.11747 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.11748 +
 1.11749 +<chapter id="chap:template">
 1.11750 +  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
 1.11751 +  <title>Customizing the output of Mercurial</title>
 1.11752 +
 1.11753 +  <para id="x_578">Mercurial provides a powerful mechanism to let you control how
 1.11754 +    it displays information.  The mechanism is based on templates.
 1.11755 +    You can use templates to generate specific output for a single
 1.11756 +    command, or to customize the entire appearance of the built-in web
 1.11757 +    interface.</para>
 1.11758 +
 1.11759 +  <sect1 id="sec:style">
 1.11760 +    <title>Using precanned output styles</title>
 1.11761 +
 1.11762 +    <para id="x_579">Packaged with Mercurial are some output styles that you can
 1.11763 +      use immediately.  A style is simply a precanned template that
 1.11764 +      someone wrote and installed somewhere that Mercurial can
 1.11765 +      find.</para>
 1.11766 +
 1.11767 +    <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
 1.11768 +      review its normal output.</para>
 1.11769 +
 1.11770 +    <!-- BEGIN template.simple.normal -->
 1.11771 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1</userinput>
 1.11772 +changeset:   1:e3d2468ca47c
 1.11773 +tag:         mytag
 1.11774 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.11775 +date:        Sun Aug 16 14:05:17 2009 +0000
 1.11776 +summary:     added line to end of &lt;&lt;hello&gt;&gt; file.
 1.11777 +
 1.11778 +</screen>
 1.11779 +<!-- END template.simple.normal -->
 1.11780 +
 1.11781 +
 1.11782 +    <para id="x_57b">This is somewhat informative, but it takes up a lot of
 1.11783 +      space—five lines of output per changeset.  The
 1.11784 +      <literal moreinfo="none">compact</literal> style reduces this to three lines,
 1.11785 +      presented in a sparse manner.</para>
 1.11786 +
 1.11787 +    <!-- BEGIN template.simple.compact -->
 1.11788 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style compact</userinput>
 1.11789 +3[tip]   d3cc7424d32c   2009-08-16 14:05 +0000   bos
 1.11790 +  Added tag v0.1 for changeset a5dd5392119b
 1.11791 +
 1.11792 +2[v0.1]   a5dd5392119b   2009-08-16 14:05 +0000   bos
 1.11793 +  Added tag mytag for changeset e3d2468ca47c
 1.11794 +
 1.11795 +1[mytag]   e3d2468ca47c   2009-08-16 14:05 +0000   bos
 1.11796 +  added line to end of &lt;&lt;hello&gt;&gt; file.
 1.11797 +
 1.11798 +0   1cf727e9fc61   2009-08-16 14:05 +0000   bos
 1.11799 +  added hello
 1.11800 +
 1.11801 +</screen>
 1.11802 +<!-- END template.simple.compact -->
 1.11803 +
 1.11804 +
 1.11805 +    <para id="x_57c">The <literal moreinfo="none">changelog</literal> style hints at the
 1.11806 +      expressive power of Mercurial's templating engine.  This style
 1.11807 +      attempts to follow the GNU Project's changelog
 1.11808 +      guidelines<citation>web:changelog</citation>.</para>
 1.11809 +
 1.11810 +    <!-- BEGIN template.simple.changelog -->
 1.11811 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style changelog</userinput>
 1.11812 +2009-08-16  Bryan O'Sullivan  &lt;bos@serpentine.com&gt;
 1.11813 +
 1.11814 +	* .hgtags:
 1.11815 +	Added tag v0.1 for changeset a5dd5392119b
 1.11816 +	[d3cc7424d32c] [tip]
 1.11817 +
 1.11818 +	* .hgtags:
 1.11819 +	Added tag mytag for changeset e3d2468ca47c
 1.11820 +	[a5dd5392119b] [v0.1]
 1.11821 +
 1.11822 +	* goodbye, hello:
 1.11823 +	added line to end of &lt;&lt;hello&gt;&gt; file.
 1.11824 +
 1.11825 +	in addition, added a file with the helpful name (at least i hope
 1.11826 +	that some might consider it so) of goodbye.
 1.11827 +	[e3d2468ca47c] [mytag]
 1.11828 +
 1.11829 +	* hello:
 1.11830 +	added hello
 1.11831 +	[1cf727e9fc61]
 1.11832 +
 1.11833 +</screen>
 1.11834 +<!-- END template.simple.changelog -->
 1.11835 +
 1.11836 +
 1.11837 +    <para id="x_57d">You will not be shocked to learn that Mercurial's default
 1.11838 +      output style is named <literal moreinfo="none">default</literal>.</para>
 1.11839 +
 1.11840 +    <sect2>
 1.11841 +      <title>Setting a default style</title>
 1.11842 +
 1.11843 +      <para id="x_57e">You can modify the output style that Mercurial will use
 1.11844 +	for every command by editing your <filename role="special" moreinfo="none">~/.hgrc</filename> file, naming the style
 1.11845 +	you would prefer to use.</para>
 1.11846 +
 1.11847 +      <programlisting format="linespecific">[ui]
 1.11848 +style = compact</programlisting>
 1.11849 +
 1.11850 +      <para id="x_57f">If you write a style of your own, you can use it by either
 1.11851 +	providing the path to your style file, or copying your style
 1.11852 +	file into a location where Mercurial can find it (typically
 1.11853 +	the <literal moreinfo="none">templates</literal> subdirectory of your
 1.11854 +	Mercurial install directory).</para>
 1.11855 +    </sect2>
 1.11856 +  </sect1>
 1.11857 +
 1.11858 +  <sect1>
 1.11859 +    <title>Commands that support styles and templates</title>
 1.11860 +
 1.11861 +    <para id="x_580">All of Mercurial's
 1.11862 +      <quote><literal moreinfo="none">log</literal>-like</quote> commands let you use
 1.11863 +      styles and templates: <command role="hg-cmd" moreinfo="none">hg
 1.11864 +	incoming</command>, <command role="hg-cmd" moreinfo="none">hg log</command>,
 1.11865 +      <command role="hg-cmd" moreinfo="none">hg outgoing</command>, and <command role="hg-cmd" moreinfo="none">hg tip</command>.</para>
 1.11866 +
 1.11867 +    <para id="x_581">As I write this manual, these are so far the only commands
 1.11868 +      that support styles and templates.  Since these are the most
 1.11869 +      important commands that need customizable output, there has been
 1.11870 +      little pressure from the Mercurial user community to add style
 1.11871 +      and template support to other commands.</para>
 1.11872 +  </sect1>
 1.11873 +
 1.11874 +  <sect1>
 1.11875 +    <title>The basics of templating</title>
 1.11876 +
 1.11877 +    <para id="x_582">At its simplest, a Mercurial template is a piece of text.
 1.11878 +      Some of the text never changes, while other parts are
 1.11879 +      <emphasis>expanded</emphasis>, or replaced with new text, when
 1.11880 +      necessary.</para>
 1.11881 +
 1.11882 +    <para id="x_583">Before we continue, let's look again at a simple example of
 1.11883 +      Mercurial's normal output.</para>
 1.11884 +
 1.11885 +    <!-- BEGIN template.simple.normal -->
 1.11886 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1</userinput>
 1.11887 +changeset:   1:e3d2468ca47c
 1.11888 +tag:         mytag
 1.11889 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.11890 +date:        Sun Aug 16 14:05:17 2009 +0000
 1.11891 +summary:     added line to end of &lt;&lt;hello&gt;&gt; file.
 1.11892 +
 1.11893 +</screen>
 1.11894 +<!-- END template.simple.normal -->
 1.11895 +
 1.11896 +
 1.11897 +    <para id="x_584">Now, let's run the same command, but using a template to
 1.11898 +      change its output.</para>
 1.11899 +
 1.11900 +    <!-- BEGIN template.simple.simplest -->
 1.11901 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'i saw a changeset\n'</userinput>
 1.11902 +i saw a changeset
 1.11903 +</screen>
 1.11904 +<!-- END template.simple.simplest -->
 1.11905 +
 1.11906 +
 1.11907 +    <para id="x_585">The example above illustrates the simplest possible
 1.11908 +      template; it's just a piece of static text, printed once for
 1.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
 1.11910 +      the given text as the template when printing each
 1.11911 +      changeset.</para>
 1.11912 +
 1.11913 +    <para id="x_586">Notice that the template string above ends with the text
 1.11914 +      <quote><literal moreinfo="none">\n</literal></quote>.  This is an
 1.11915 +      <emphasis>escape sequence</emphasis>, telling Mercurial to print
 1.11916 +      a newline at the end of each template item.  If you omit this
 1.11917 +      newline, Mercurial will run each piece of output together.  See
 1.11918 +      <xref linkend="sec:template:escape"/> for more details
 1.11919 +      of escape sequences.</para>
 1.11920 +
 1.11921 +    <para id="x_587">A template that prints a fixed string of text all the time
 1.11922 +      isn't very useful; let's try something a bit more
 1.11923 +      complex.</para>
 1.11924 +
 1.11925 +    <!-- BEGIN template.simple.simplesub -->
 1.11926 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --template 'i saw a changeset: {desc}\n'</userinput>
 1.11927 +i saw a changeset: Added tag v0.1 for changeset a5dd5392119b
 1.11928 +i saw a changeset: Added tag mytag for changeset e3d2468ca47c
 1.11929 +i saw a changeset: added line to end of &lt;&lt;hello&gt;&gt; file.
 1.11930 +
 1.11931 +in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.
 1.11932 +i saw a changeset: added hello
 1.11933 +</screen>
 1.11934 +<!-- END template.simple.simplesub -->
 1.11935 +
 1.11936 +
 1.11937 +    <para id="x_588">As you can see, the string
 1.11938 +      <quote><literal moreinfo="none">{desc}</literal></quote> in the template has
 1.11939 +      been replaced in the output with the description of each
 1.11940 +      changeset.  Every time Mercurial finds text enclosed in curly
 1.11941 +      braces (<quote><literal moreinfo="none">{</literal></quote> and
 1.11942 +      <quote><literal moreinfo="none">}</literal></quote>), it will try to replace the
 1.11943 +      braces and text with the expansion of whatever is inside.  To
 1.11944 +      print a literal curly brace, you must escape it, as described in
 1.11945 +      <xref linkend="sec:template:escape"/>.</para>
 1.11946 +  </sect1>
 1.11947 +
 1.11948 +  <sect1 id="sec:template:keyword">
 1.11949 +    <title>Common template keywords</title>
 1.11950 +
 1.11951 +    <para id="x_589">You can start writing simple templates immediately using the
 1.11952 +      keywords below.</para>
 1.11953 +
 1.11954 +    <itemizedlist>
 1.11955 +      <listitem><para id="x_58a"><literal role="template-keyword" moreinfo="none">author</literal>: String.  The
 1.11956 +	  unmodified author of the changeset.</para>
 1.11957 +      </listitem>
 1.11958 +      <listitem><para id="x_58b"><literal role="template-keyword" moreinfo="none">branches</literal>: String.  The
 1.11959 +	  name of the branch on which the changeset was committed.
 1.11960 +	  Will be empty if the branch name was
 1.11961 +	  <literal moreinfo="none">default</literal>.</para>
 1.11962 +      </listitem>
 1.11963 +      <listitem><para id="x_58c"><literal role="template-keyword" moreinfo="none">date</literal>:
 1.11964 +	  Date information.  The date when the changeset was
 1.11965 +	  committed.  This is <emphasis>not</emphasis> human-readable;
 1.11966 +	  you must pass it through a filter that will render it
 1.11967 +	  appropriately.  See <xref linkend="sec:template:filter"/> for more information
 1.11968 +	  on filters. The date is expressed as a pair of numbers.  The
 1.11969 +	  first number is a Unix UTC timestamp (seconds since January
 1.11970 +	  1, 1970); the second is the offset of the committer's
 1.11971 +	  timezone from UTC, in seconds.</para>
 1.11972 +      </listitem>
 1.11973 +      <listitem><para id="x_58d"><literal role="template-keyword" moreinfo="none">desc</literal>:
 1.11974 +	  String.  The text of the changeset description.</para>
 1.11975 +      </listitem>
 1.11976 +      <listitem><para id="x_58e"><literal role="template-keyword" moreinfo="none">files</literal>: List of strings.
 1.11977 +	  All files modified, added, or removed by this
 1.11978 +	  changeset.</para>
 1.11979 +      </listitem>
 1.11980 +      <listitem><para id="x_58f"><literal role="template-keyword" moreinfo="none">file_adds</literal>: List of
 1.11981 +	  strings.  Files added by this changeset.</para>
 1.11982 +      </listitem>
 1.11983 +      <listitem><para id="x_590"><literal role="template-keyword" moreinfo="none">file_dels</literal>: List of
 1.11984 +	  strings.  Files removed by this changeset.</para>
 1.11985 +      </listitem>
 1.11986 +      <listitem><para id="x_591"><literal role="template-keyword" moreinfo="none">node</literal>:
 1.11987 +	  String.  The changeset identification hash, as a
 1.11988 +	  40-character hexadecimal string.</para>
 1.11989 +      </listitem>
 1.11990 +      <listitem><para id="x_592"><literal role="template-keyword" moreinfo="none">parents</literal>: List of
 1.11991 +	  strings.  The parents of the changeset.</para>
 1.11992 +      </listitem>
 1.11993 +      <listitem><para id="x_593"><literal role="template-keyword" moreinfo="none">rev</literal>:
 1.11994 +	  Integer.  The repository-local changeset revision
 1.11995 +	  number.</para>
 1.11996 +      </listitem>
 1.11997 +      <listitem><para id="x_594"><literal role="template-keyword" moreinfo="none">tags</literal>:
 1.11998 +	  List of strings.  Any tags associated with the
 1.11999 +	  changeset.</para>
 1.12000 +      </listitem>
 1.12001 +    </itemizedlist>
 1.12002 +
 1.12003 +    <para id="x_595">A few simple experiments will show us what to expect when we
 1.12004 +      use these keywords; you can see the results below.</para>
 1.12005 +
 1.12006 +    <!-- BEGIN template.simple.keywords -->
 1.12007 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'author: {author}\n'</userinput>
 1.12008 +author: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.12009 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'desc:\n{desc}\n'</userinput>
 1.12010 +desc:
 1.12011 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12012 +
 1.12013 +in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.
 1.12014 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'files: {files}\n'</userinput>
 1.12015 +files: goodbye hello
 1.12016 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'file_adds: {file_adds}\n'</userinput>
 1.12017 +file_adds: goodbye
 1.12018 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'file_dels: {file_dels}\n'</userinput>
 1.12019 +file_dels: 
 1.12020 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'node: {node}\n'</userinput>
 1.12021 +node: e3d2468ca47c10bdfbbb41b367a0c84509862197
 1.12022 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'parents: {parents}\n'</userinput>
 1.12023 +parents: 
 1.12024 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'rev: {rev}\n'</userinput>
 1.12025 +rev: 1
 1.12026 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'tags: {tags}\n'</userinput>
 1.12027 +tags: mytag
 1.12028 +</screen>
 1.12029 +<!-- END template.simple.keywords -->
 1.12030 +
 1.12031 +
 1.12032 +    <para id="x_596">As we noted above, the date keyword does not produce
 1.12033 +      human-readable output, so we must treat it specially.  This
 1.12034 +      involves using a <emphasis>filter</emphasis>, about which more
 1.12035 +      in <xref linkend="sec:template:filter"/>.</para>
 1.12036 +
 1.12037 +    <!-- BEGIN template.simple.datekeyword -->
 1.12038 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'date: {date}\n'</userinput>
 1.12039 +date: 1250431517.00
 1.12040 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'date: {date|isodate}\n'</userinput>
 1.12041 +date: 2009-08-16 14:05 +0000
 1.12042 +</screen>
 1.12043 +<!-- END template.simple.datekeyword -->
 1.12044 +
 1.12045 +  </sect1>
 1.12046 +
 1.12047 +  <sect1 id="sec:template:escape">
 1.12048 +    <title>Escape sequences</title>
 1.12049 +
 1.12050 +    <para id="x_597">Mercurial's templating engine recognises the most commonly
 1.12051 +      used escape sequences in strings.  When it sees a backslash
 1.12052 +      (<quote><literal moreinfo="none">\</literal></quote>) character, it looks at the
 1.12053 +      following character and substitutes the two characters with a
 1.12054 +      single replacement, as described below.</para>
 1.12055 +
 1.12056 +    <itemizedlist>
 1.12057 +      <listitem><para id="x_598"><literal moreinfo="none">\</literal>:
 1.12058 +	  Backslash, <quote><literal moreinfo="none">\</literal></quote>, ASCII
 1.12059 +	  134.</para>
 1.12060 +      </listitem>
 1.12061 +      <listitem><para id="x_599"><literal moreinfo="none">\n</literal>: Newline,
 1.12062 +	  ASCII 12.</para>
 1.12063 +      </listitem>
 1.12064 +      <listitem><para id="x_59a"><literal moreinfo="none">\r</literal>: Carriage
 1.12065 +	  return, ASCII 15.</para>
 1.12066 +      </listitem>
 1.12067 +      <listitem><para id="x_59b"><literal moreinfo="none">\t</literal>: Tab, ASCII
 1.12068 +	  11.</para>
 1.12069 +      </listitem>
 1.12070 +      <listitem><para id="x_59c"><literal moreinfo="none">\v</literal>: Vertical
 1.12071 +	  tab, ASCII 13.</para>
 1.12072 +      </listitem>
 1.12073 +      <listitem><para id="x_59d"><literal moreinfo="none">\{</literal>: Open curly
 1.12074 +	  brace, <quote><literal moreinfo="none">{</literal></quote>, ASCII
 1.12075 +	  173.</para>
 1.12076 +      </listitem>
 1.12077 +      <listitem><para id="x_59e"><literal moreinfo="none">\}</literal>: Close curly
 1.12078 +	  brace, <quote><literal moreinfo="none">}</literal></quote>, ASCII
 1.12079 +	  175.</para>
 1.12080 +      </listitem></itemizedlist>
 1.12081 +
 1.12082 +    <para id="x_59f">As indicated above, if you want the expansion of a template
 1.12083 +      to contain a literal <quote><literal moreinfo="none">\</literal></quote>,
 1.12084 +      <quote><literal moreinfo="none">{</literal></quote>, or
 1.12085 +      <quote><literal moreinfo="none">{</literal></quote> character, you must escape
 1.12086 +      it.</para>
 1.12087 +  </sect1>
 1.12088 +
 1.12089 +  <sect1 id="sec:template:filter">
 1.12090 +    <title>Filtering keywords to change their results</title>
 1.12091 +
 1.12092 +    <para id="x_5a0">Some of the results of template expansion are not
 1.12093 +      immediately easy to use.  Mercurial lets you specify an optional
 1.12094 +      chain of <emphasis>filters</emphasis> to modify the result of
 1.12095 +      expanding a keyword.  You have already seen a common filter,
 1.12096 +      <literal role="template-kw-filt-date" moreinfo="none">isodate</literal>, in
 1.12097 +      action above, to make a date readable.</para>
 1.12098 +
 1.12099 +    <para id="x_5a1">Below is a list of the most commonly used filters that
 1.12100 +      Mercurial supports.  While some filters can be applied to any
 1.12101 +      text, others can only be used in specific circumstances.  The
 1.12102 +      name of each filter is followed first by an indication of where
 1.12103 +      it can be used, then a description of its effect.</para>
 1.12104 +
 1.12105 +    <itemizedlist>
 1.12106 +      <listitem><para id="x_5a2"><literal role="template-filter" moreinfo="none">addbreaks</literal>: Any text. Add
 1.12107 +	  an XHTML <quote><literal moreinfo="none">&lt;br/&gt;</literal></quote> tag
 1.12108 +	  before the end of every line except the last.  For example,
 1.12109 +	  <quote><literal moreinfo="none">foo\nbar</literal></quote> becomes
 1.12110 +	  <quote><literal moreinfo="none">foo&lt;br/&gt;\nbar</literal></quote>.</para>
 1.12111 +      </listitem>
 1.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
 1.12113 +	  the age of the date, relative to the current time.  Yields a
 1.12114 +	  string like <quote><literal moreinfo="none">10
 1.12115 +	      minutes</literal></quote>.</para>
 1.12116 +      </listitem>
 1.12117 +      <listitem><para id="x_5a4"><literal role="template-filter" moreinfo="none">basename</literal>: Any text, but
 1.12118 +	  most useful for the <literal role="template-keyword" moreinfo="none">files</literal> keyword and its
 1.12119 +	  relatives.  Treat the text as a path, and return the
 1.12120 +	  basename. For example,
 1.12121 +	  <quote><literal moreinfo="none">foo/bar/baz</literal></quote> becomes
 1.12122 +	  <quote><literal moreinfo="none">baz</literal></quote>.</para>
 1.12123 +      </listitem>
 1.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
 1.12125 +	  date in a similar format to the Unix <literal role="template-keyword" moreinfo="none">date</literal> command, but with
 1.12126 +	  timezone included.  Yields a string like <quote><literal moreinfo="none">Mon
 1.12127 +	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
 1.12128 +      </listitem>
 1.12129 +      <listitem><para id="x_5a6"><literal role="template-kw-filt-author" moreinfo="none">domain</literal>: Any text,
 1.12130 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Finds
 1.12131 +	  the first string that looks like an email address, and
 1.12132 +	  extract just the domain component.  For example,
 1.12133 +	  <quote><literal moreinfo="none">Bryan O'Sullivan
 1.12134 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 1.12135 +	  <quote><literal moreinfo="none">serpentine.com</literal></quote>.</para>
 1.12136 +      </listitem>
 1.12137 +      <listitem><para id="x_5a7"><literal role="template-kw-filt-author" moreinfo="none">email</literal>: Any text,
 1.12138 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Extract
 1.12139 +	  the first string that looks like an email address.  For
 1.12140 +	  example, <quote><literal moreinfo="none">Bryan O'Sullivan
 1.12141 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 1.12142 +	  <quote><literal moreinfo="none">bos@serpentine.com</literal></quote>.</para>
 1.12143 +      </listitem>
 1.12144 +      <listitem><para id="x_5a8"><literal role="template-filter" moreinfo="none">escape</literal>: Any text.
 1.12145 +	  Replace the special XML/XHTML characters
 1.12146 +	  <quote><literal moreinfo="none">&amp;</literal></quote>,
 1.12147 +	  <quote><literal moreinfo="none">&lt;</literal></quote> and
 1.12148 +	  <quote><literal moreinfo="none">&gt;</literal></quote> with XML
 1.12149 +	  entities.</para>
 1.12150 +      </listitem>
 1.12151 +      <listitem><para id="x_5a9"><literal role="template-filter" moreinfo="none">fill68</literal>: Any text.  Wrap
 1.12152 +	  the text to fit in 68 columns.  This is useful before you
 1.12153 +	  pass text through the <literal role="template-filter" moreinfo="none">tabindent</literal> filter, and
 1.12154 +	  still want it to fit in an 80-column fixed-font
 1.12155 +	  window.</para>
 1.12156 +      </listitem>
 1.12157 +      <listitem><para id="x_5aa"><literal role="template-filter" moreinfo="none">fill76</literal>: Any text.  Wrap
 1.12158 +	  the text to fit in 76 columns.</para>
 1.12159 +      </listitem>
 1.12160 +      <listitem><para id="x_5ab"><literal role="template-filter" moreinfo="none">firstline</literal>: Any text.
 1.12161 +	  Yield the first line of text, without any trailing
 1.12162 +	  newlines.</para>
 1.12163 +      </listitem>
 1.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
 1.12165 +	  the date as a pair of readable numbers.  Yields a string
 1.12166 +	  like <quote><literal moreinfo="none">1157407993
 1.12167 +	      25200</literal></quote>.</para>
 1.12168 +      </listitem>
 1.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
 1.12170 +	  the date as a text string in ISO 8601 format.  Yields a
 1.12171 +	  string like <quote><literal moreinfo="none">2006-09-04 15:13:13
 1.12172 +	      -0700</literal></quote>.</para>
 1.12173 +      </listitem>
 1.12174 +      <listitem><para id="x_5ae"><literal role="template-filter" moreinfo="none">obfuscate</literal>: Any text, but
 1.12175 +	  most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Yield
 1.12176 +	  the input text rendered as a sequence of XML entities.  This
 1.12177 +	  helps to defeat some particularly stupid screen-scraping
 1.12178 +	  email harvesting spambots.</para>
 1.12179 +      </listitem>
 1.12180 +      <listitem><para id="x_5af"><literal role="template-kw-filt-author" moreinfo="none">person</literal>: Any text,
 1.12181 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Yield
 1.12182 +	  the text before an email address. For example,
 1.12183 +	  <quote><literal moreinfo="none">Bryan O'Sullivan
 1.12184 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 1.12185 +	  <quote><literal moreinfo="none">Bryan O'Sullivan</literal></quote>.</para>
 1.12186 +      </listitem>
 1.12187 +      <listitem><para id="x_5b0"><literal role="template-kw-filt-date" moreinfo="none">rfc822date</literal>:
 1.12188 +	  <literal role="template-keyword" moreinfo="none">date</literal> keyword.
 1.12189 +	  Render a date using the same format used in email headers.
 1.12190 +	  Yields a string like <quote><literal moreinfo="none">Mon, 04 Sep 2006
 1.12191 +	      15:13:13 -0700</literal></quote>.</para>
 1.12192 +      </listitem>
 1.12193 +      <listitem><para id="x_5b1"><literal role="template-kw-filt-node" moreinfo="none">short</literal>: Changeset
 1.12194 +	  hash.  Yield the short form of a changeset hash, i.e. a
 1.12195 +	  12-character hexadecimal string.</para>
 1.12196 +      </listitem>
 1.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
 1.12198 +	  the year, month, and day of the date.  Yields a string like
 1.12199 +	  <quote><literal moreinfo="none">2006-09-04</literal></quote>.</para>
 1.12200 +      </listitem>
 1.12201 +      <listitem><para id="x_5b3"><literal role="template-filter" moreinfo="none">strip</literal>:
 1.12202 +	  Any text.  Strip all leading and trailing whitespace from
 1.12203 +	  the string.</para>
 1.12204 +      </listitem>
 1.12205 +      <listitem><para id="x_5b4"><literal role="template-filter" moreinfo="none">tabindent</literal>: Any text.
 1.12206 +	  Yield the text, with every line except the first starting
 1.12207 +	  with a tab character.</para>
 1.12208 +      </listitem>
 1.12209 +      <listitem><para id="x_5b5"><literal role="template-filter" moreinfo="none">urlescape</literal>: Any text.
 1.12210 +	  Escape all characters that are considered
 1.12211 +	  <quote>special</quote> by URL parsers.  For example,
 1.12212 +	  <literal moreinfo="none">foo bar</literal> becomes
 1.12213 +	  <literal moreinfo="none">foo%20bar</literal>.</para>
 1.12214 +      </listitem>
 1.12215 +      <listitem><para id="x_5b6"><literal role="template-kw-filt-author" moreinfo="none">user</literal>: Any text,
 1.12216 +	  but most useful for the <literal role="template-keyword" moreinfo="none">author</literal> keyword.  Return
 1.12217 +	  the <quote>user</quote> portion of an email address.  For
 1.12218 +	  example, <quote><literal moreinfo="none">Bryan O'Sullivan
 1.12219 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
 1.12220 +	  <quote><literal moreinfo="none">bos</literal></quote>.</para>
 1.12221 +      </listitem>
 1.12222 +    </itemizedlist>
 1.12223 +
 1.12224 +    <!-- BEGIN template.simple.manyfilters -->
 1.12225 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author}\n'</userinput>
 1.12226 +Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.12227 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|domain}\n'</userinput>
 1.12228 +serpentine.com
 1.12229 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|email}\n'</userinput>
 1.12230 +bos@serpentine.com
 1.12231 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|obfuscate}\n' | cut -c-76</userinput>
 1.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
 1.12233 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|person}\n'</userinput>
 1.12234 +Bryan O'Sullivan
 1.12235 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{author|user}\n'</userinput>
 1.12236 +bos
 1.12237 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'looks almost right, but actually garbage: {date}\n'</userinput>
 1.12238 +looks almost right, but actually garbage: 1250431517.00
 1.12239 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|age}\n'</userinput>
 1.12240 +3 seconds
 1.12241 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|date}\n'</userinput>
 1.12242 +Sun Aug 16 14:05:17 2009 +0000
 1.12243 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|hgdate}\n'</userinput>
 1.12244 +1250431517 0
 1.12245 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|isodate}\n'</userinput>
 1.12246 +2009-08-16 14:05 +0000
 1.12247 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|rfc822date}\n'</userinput>
 1.12248 +Sun, 16 Aug 2009 14:05:17 +0000
 1.12249 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{date|shortdate}\n'</userinput>
 1.12250 +2009-08-16
 1.12251 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc}\n' | cut -c-76</userinput>
 1.12252 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12253 +
 1.12254 +in addition, added a file with the helpful name (at least i hope that some m
 1.12255 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|addbreaks}\n' | cut -c-76</userinput>
 1.12256 +added line to end of &lt;&lt;hello&gt;&gt; file.&lt;br/&gt;
 1.12257 +&lt;br/&gt;
 1.12258 +in addition, added a file with the helpful name (at least i hope that some m
 1.12259 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|escape}\n' | cut -c-76</userinput>
 1.12260 +added line to end of &amp;lt;&amp;lt;hello&amp;gt;&amp;gt; file.
 1.12261 +
 1.12262 +in addition, added a file with the helpful name (at least i hope that some m
 1.12263 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|fill68}\n'</userinput>
 1.12264 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12265 +
 1.12266 +in addition, added a file with the helpful name (at least i hope
 1.12267 +that some might consider it so) of goodbye.
 1.12268 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|fill76}\n'</userinput>
 1.12269 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12270 +
 1.12271 +in addition, added a file with the helpful name (at least i hope that some
 1.12272 +might consider it so) of goodbye.
 1.12273 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|firstline}\n'</userinput>
 1.12274 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12275 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|strip}\n' | cut -c-76</userinput>
 1.12276 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12277 +
 1.12278 +in addition, added a file with the helpful name (at least i hope that some m
 1.12279 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{desc|tabindent}\n' | expand | cut -c-76</userinput>
 1.12280 +added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12281 +
 1.12282 +        in addition, added a file with the helpful name (at least i hope tha
 1.12283 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{node}\n'</userinput>
 1.12284 +e3d2468ca47c10bdfbbb41b367a0c84509862197
 1.12285 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template '{node|short}\n'</userinput>
 1.12286 +e3d2468ca47c
 1.12287 +</screen>
 1.12288 +<!-- END template.simple.manyfilters -->
 1.12289 +
 1.12290 +
 1.12291 +    <note>
 1.12292 +      <para id="x_5b7">  If you try to apply a filter to a piece of data that it
 1.12293 +	cannot process, Mercurial will fail and print a Python
 1.12294 +	exception.  For example, trying to run the output of the
 1.12295 +	<literal role="template-keyword" moreinfo="none">desc</literal> keyword into
 1.12296 +	the <literal role="template-kw-filt-date" moreinfo="none">isodate</literal>
 1.12297 +	filter is not a good idea.</para>
 1.12298 +    </note>
 1.12299 +
 1.12300 +    <sect2>
 1.12301 +      <title>Combining filters</title>
 1.12302 +
 1.12303 +      <para id="x_5b8">It is easy to combine filters to yield output in the form
 1.12304 +	you would like.  The following chain of filters tidies up a
 1.12305 +	description, then makes sure that it fits cleanly into 68
 1.12306 +	columns, then indents it by a further 8 characters (at least
 1.12307 +	on Unix-like systems, where a tab is conventionally 8
 1.12308 +	characters wide).</para>
 1.12309 +
 1.12310 +      <!-- BEGIN template.simple.combine -->
 1.12311 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --template 'description:\n\t{desc|strip|fill68|tabindent}\n'</userinput>
 1.12312 +description:
 1.12313 +	added line to end of &lt;&lt;hello&gt;&gt; file.
 1.12314 +
 1.12315 +	in addition, added a file with the helpful name (at least i hope
 1.12316 +	that some might consider it so) of goodbye.
 1.12317 +</screen>
 1.12318 +<!-- END template.simple.combine -->
 1.12319 +
 1.12320 +
 1.12321 +      <para id="x_5b9">Note the use of <quote><literal moreinfo="none">\t</literal></quote> (a
 1.12322 +	tab character) in the template to force the first line to be
 1.12323 +	indented; this is necessary since <literal role="template-keyword" moreinfo="none">tabindent</literal> indents all
 1.12324 +	lines <emphasis>except</emphasis> the first.</para>
 1.12325 +
 1.12326 +      <para id="x_5ba">Keep in mind that the order of filters in a chain is
 1.12327 +	significant.  The first filter is applied to the result of the
 1.12328 +	keyword; the second to the result of the first filter; and so
 1.12329 +	on.  For example, using <literal moreinfo="none">fill68|tabindent</literal>
 1.12330 +	gives very different results from
 1.12331 +	<literal moreinfo="none">tabindent|fill68</literal>.</para>
 1.12332 +    </sect2>
 1.12333 +  </sect1>
 1.12334 +
 1.12335 +  <sect1>
 1.12336 +    <title>From templates to styles</title>
 1.12337 +
 1.12338 +    <para id="x_5bb">A command line template provides a quick and simple way to
 1.12339 +      format some output.  Templates can become verbose, though, and
 1.12340 +      it's useful to be able to give a template a name.  A style file
 1.12341 +      is a template with a name, stored in a file.</para>
 1.12342 +
 1.12343 +    <para id="x_5bc">More than that, using a style file unlocks the power of
 1.12344 +      Mercurial's templating engine in ways that are not possible
 1.12345 +      using the command line <option role="hg-opt-log">--template</option> option.</para>
 1.12346 +
 1.12347 +    <sect2>
 1.12348 +      <title>The simplest of style files</title>
 1.12349 +
 1.12350 +      <para id="x_5bd">Our simple style file contains just one line:</para>
 1.12351 +
 1.12352 +      <!-- BEGIN template.simple.rev -->
 1.12353 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'changeset = "rev: {rev}\n"' &gt; rev</userinput>
 1.12354 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -l1 --style ./rev</userinput>
 1.12355 +rev: 3
 1.12356 +</screen>
 1.12357 +<!-- END template.simple.rev -->
 1.12358 +
 1.12359 +
 1.12360 +      <para id="x_5be">This tells Mercurial, <quote>if you're printing a
 1.12361 +	  changeset, use the text on the right as the
 1.12362 +	  template</quote>.</para>
 1.12363 +    </sect2>
 1.12364 +
 1.12365 +    <sect2>
 1.12366 +      <title>Style file syntax</title>
 1.12367 +
 1.12368 +      <para id="x_5bf">The syntax rules for a style file are simple.</para>
 1.12369 +
 1.12370 +      <itemizedlist>
 1.12371 +	<listitem><para id="x_5c0">The file is processed one line at a
 1.12372 +	    time.</para>
 1.12373 +	</listitem>
 1.12374 +	<listitem><para id="x_5c1">Leading and trailing white space are
 1.12375 +	    ignored.</para>
 1.12376 +	</listitem>
 1.12377 +	<listitem><para id="x_5c2">Empty lines are skipped.</para>
 1.12378 +	</listitem>
 1.12379 +	<listitem><para id="x_5c3">If a line starts with either of the characters
 1.12380 +	    <quote><literal moreinfo="none">#</literal></quote> or
 1.12381 +	    <quote><literal moreinfo="none">;</literal></quote>, the entire line is
 1.12382 +	    treated as a comment, and skipped as if empty.</para>
 1.12383 +	</listitem>
 1.12384 +	<listitem><para id="x_5c4">A line starts with a keyword.  This must start
 1.12385 +	    with an alphabetic character or underscore, and can
 1.12386 +	    subsequently contain any alphanumeric character or
 1.12387 +	    underscore.  (In regexp notation, a keyword must match
 1.12388 +	    <literal moreinfo="none">[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
 1.12389 +	</listitem>
 1.12390 +	<listitem><para id="x_5c5">The next element must be an
 1.12391 +	    <quote><literal moreinfo="none">=</literal></quote> character, which can
 1.12392 +	    be preceded or followed by an arbitrary amount of white
 1.12393 +	    space.</para>
 1.12394 +	</listitem>
 1.12395 +	<listitem><para id="x_5c6">If the rest of the line starts and ends with
 1.12396 +	    matching quote characters (either single or double quote),
 1.12397 +	    it is treated as a template body.</para>
 1.12398 +	</listitem>
 1.12399 +	<listitem><para id="x_5c7">If the rest of the line <emphasis>does
 1.12400 +	      not</emphasis> start with a quote character, it is
 1.12401 +	    treated as the name of a file; the contents of this file
 1.12402 +	    will be read and used as a template body.</para>
 1.12403 +	</listitem></itemizedlist>
 1.12404 +    </sect2>
 1.12405 +  </sect1>
 1.12406 +
 1.12407 +  <sect1>
 1.12408 +    <title>Style files by example</title>
 1.12409 +
 1.12410 +    <para id="x_5c8">To illustrate how to write a style file, we will construct a
 1.12411 +      few by example.  Rather than provide a complete style file and
 1.12412 +      walk through it, we'll mirror the usual process of developing a
 1.12413 +      style file by starting with something very simple, and walking
 1.12414 +      through a series of successively more complete examples.</para>
 1.12415 +
 1.12416 +    <sect2>
 1.12417 +      <title>Identifying mistakes in style files</title>
 1.12418 +
 1.12419 +      <para id="x_5c9">If Mercurial encounters a problem in a style file you are
 1.12420 +	working on, it prints a terse error message that, once you
 1.12421 +	figure out what it means, is actually quite useful.</para>
 1.12422 +
 1.12423 +<!-- BEGIN template.svnstyle.syntax.input -->
 1.12424 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat broken.style</userinput>
 1.12425 +changeset =
 1.12426 +</screen>
 1.12427 +<!-- END template.svnstyle.syntax.input -->
 1.12428 +
 1.12429 +
 1.12430 +      <para id="x_5ca">Notice that <filename moreinfo="none">broken.style</filename> attempts to
 1.12431 +	define a <literal moreinfo="none">changeset</literal> keyword, but forgets to
 1.12432 +	give any content for it. When instructed to use this style
 1.12433 +	file, Mercurial promptly complains.</para>
 1.12434 +
 1.12435 +      <!-- BEGIN template.svnstyle.syntax.error -->
 1.12436 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r1 --style broken.style</userinput>
 1.12437 +abort: broken.style:1: parse error
 1.12438 +</screen>
 1.12439 +<!-- END template.svnstyle.syntax.error -->
 1.12440 +
 1.12441 +
 1.12442 +      <para id="x_5cb">This error message looks intimidating, but it is not too
 1.12443 +	hard to follow.</para>
 1.12444 +
 1.12445 +      <itemizedlist>
 1.12446 +	<listitem><para id="x_5cc">The first component is simply Mercurial's way
 1.12447 +	    of saying <quote>I am giving up</quote>.</para>
 1.12448 +	  <programlisting format="linespecific">___abort___: broken.style:1: parse error</programlisting>
 1.12449 +	</listitem>
 1.12450 +	<listitem><para id="x_5cd">Next comes the name of the style file that
 1.12451 +	    contains the error.</para>
 1.12452 +	  <programlisting format="linespecific">abort: ___broken.style___:1: parse error</programlisting>
 1.12453 +	</listitem>
 1.12454 +	<listitem><para id="x_5ce">Following the file name is the line number
 1.12455 +	    where the error was encountered.</para>
 1.12456 +	  <programlisting format="linespecific">abort: broken.style:___1___: parse error</programlisting>
 1.12457 +	</listitem>
 1.12458 +	<listitem><para id="x_5cf">Finally, a description of what went
 1.12459 +	    wrong.</para>
 1.12460 +	  <programlisting format="linespecific">abort: broken.style:1: ___parse error___</programlisting>
 1.12461 +	</listitem>
 1.12462 +	<listitem><para id="x_5d0">The description of the problem is not always
 1.12463 +	    clear (as in this case), but even when it is cryptic, it
 1.12464 +	    is almost always trivial to visually inspect the offending
 1.12465 +	    line in the style file and see what is wrong.</para>
 1.12466 +	</listitem>
 1.12467 +      </itemizedlist>
 1.12468 +    </sect2>
 1.12469 +
 1.12470 +    <sect2>
 1.12471 +      <title>Uniquely identifying a repository</title>
 1.12472 +
 1.12473 +      <para id="x_5d1">If you would like to be able to identify a Mercurial
 1.12474 +	repository <quote>fairly uniquely</quote> using a short string
 1.12475 +	as an identifier, you can use the first revision in the
 1.12476 +	repository.</para>
 1.12477 +
 1.12478 +      <!-- BEGIN template.svnstyle.id -->
 1.12479 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r0 --template '{node}'</userinput>
 1.12480 +02b4f9d8a52a6da645e20fa7df0accc8aa33b650</screen>
 1.12481 +<!-- END template.svnstyle.id -->
 1.12482 +
 1.12483 +
 1.12484 +      <para id="x_5d2">This is likely to be unique, and so it is
 1.12485 +	useful in many cases.  There are a few caveats.</para>
 1.12486 +      <itemizedlist>
 1.12487 +	<listitem><para id="x_5d3">It will not work in a completely empty
 1.12488 +	    repository, because such a repository does not have a
 1.12489 +	    revision zero.</para>
 1.12490 +	</listitem>
 1.12491 +	<listitem><para id="x_5d4">Neither will it work in the (extremely rare)
 1.12492 +	    case where a repository is a merge of two or more formerly
 1.12493 +	    independent repositories, and you still have those
 1.12494 +	    repositories around.</para>
 1.12495 +	</listitem></itemizedlist>
 1.12496 +      <para id="x_5d5">Here are some uses to which you could put this
 1.12497 +	identifier:</para>
 1.12498 +      <itemizedlist>
 1.12499 +	<listitem><para id="x_5d6">As a key into a table for a database that
 1.12500 +	    manages repositories on a server.</para>
 1.12501 +	</listitem>
 1.12502 +	<listitem><para id="x_5d7">As half of a {<emphasis>repository
 1.12503 +	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
 1.12504 +	    Save this information away when you run an automated build
 1.12505 +	    or other activity, so that you can <quote>replay</quote>
 1.12506 +	    the build later if necessary.</para>
 1.12507 +	</listitem>
 1.12508 +      </itemizedlist>
 1.12509 +    </sect2>
 1.12510 +
 1.12511 +    <sect2>
 1.12512 +      <title>Listing files on multiple lines</title>
 1.12513 +
 1.12514 +      <para id="x_714">Suppose we want to list the files changed by a changeset,
 1.12515 +	one per line, with a little indentation before each file
 1.12516 +	name.</para>
 1.12517 +
 1.12518 +      <!-- BEGIN ch10/multiline.go -->
 1.12519 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat &gt; multiline &lt;&lt; EOF</userinput>
 1.12520 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">changeset = "Changed in {node|short}:\n{files}"</userinput>
 1.12521 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">file = "  {file}\n"</userinput>
 1.12522 +<prompt moreinfo="none">&gt;</prompt> <userinput moreinfo="none">EOF</userinput>
 1.12523 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style multiline</userinput>
 1.12524 +Changed in badb58085712:
 1.12525 +  .bashrc
 1.12526 +  .hgrc
 1.12527 +  test.c
 1.12528 +</screen>
 1.12529 +<!-- END ch10/multiline.go -->
 1.12530 +
 1.12531 +    </sect2>
 1.12532 +
 1.12533 +    <sect2>
 1.12534 +      <title>Mimicking Subversion's output</title>
 1.12535 +
 1.12536 +      <para id="x_5d8">Let's try to emulate the default output format used by
 1.12537 +	another revision control tool, Subversion.</para>
 1.12538 +
 1.12539 +      <!-- BEGIN template.svnstyle.short -->
 1.12540 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svn log -r9653</userinput>
 1.12541 +------------------------------------------------------------------------
 1.12542 +r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines
 1.12543 +
 1.12544 +On reporting a route error, also include the status for the error,
 1.12545 +rather than indicating a status of 0 when an error has occurred.
 1.12546 +
 1.12547 +Signed-off-by: Sean Hefty &lt;sean.hefty@intel.com&gt;
 1.12548 +
 1.12549 +------------------------------------------------------------------------
 1.12550 +</screen>
 1.12551 +<!-- END template.svnstyle.short -->
 1.12552 +
 1.12553 +
 1.12554 +      <para id="x_5d9">Since Subversion's output style is fairly simple, it is
 1.12555 +	easy to copy-and-paste a hunk of its output into a file, and
 1.12556 +	replace the text produced above by Subversion with the
 1.12557 +	template values we'd like to see expanded.</para>
 1.12558 +
 1.12559 +      <!-- BEGIN template.svnstyle.template -->
 1.12560 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat svn.template</userinput>
 1.12561 +r{rev} | {author|user} | {date|isodate} ({date|rfc822date})
 1.12562 +
 1.12563 +{desc|strip|fill76}
 1.12564 +
 1.12565 +------------------------------------------------------------------------
 1.12566 +</screen>
 1.12567 +<!-- END template.svnstyle.template -->
 1.12568 +
 1.12569 +
 1.12570 +      <para id="x_5da">There are a few small ways in which this template deviates
 1.12571 +	from the output produced by Subversion.</para>
 1.12572 +      <itemizedlist>
 1.12573 +	<listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
 1.12574 +	    date (the <quote><literal moreinfo="none">Wed, 27 Sep 2006</literal></quote> in the
 1.12575 +	    example output above) in parentheses.  Mercurial's
 1.12576 +	    templating engine does not provide a way to display a date
 1.12577 +	    in this format without also printing the time and time
 1.12578 +	    zone.</para>
 1.12579 +	</listitem>
 1.12580 +	<listitem><para id="x_5dc">We emulate Subversion's printing of
 1.12581 +	    <quote>separator</quote> lines full of
 1.12582 +	    <quote><literal moreinfo="none">-</literal></quote> characters by ending
 1.12583 +	    the template with such a line. We use the templating
 1.12584 +	    engine's <literal role="template-keyword" moreinfo="none">header</literal>
 1.12585 +	    keyword to print a separator line as the first line of
 1.12586 +	    output (see below), thus achieving similar output to
 1.12587 +	    Subversion.</para>
 1.12588 +	</listitem>
 1.12589 +	<listitem><para id="x_5dd">Subversion's output includes a count in the
 1.12590 +	    header of the number of lines in the commit message.  We
 1.12591 +	    cannot replicate this in Mercurial; the templating engine
 1.12592 +	    does not currently provide a filter that counts the number
 1.12593 +	    of lines the template generates.</para>
 1.12594 +	</listitem></itemizedlist>
 1.12595 +      <para id="x_5de">It took me no more than a minute or two of work to replace
 1.12596 +	literal text from an example of Subversion's output with some
 1.12597 +	keywords and filters to give the template above.  The style
 1.12598 +	file simply refers to the template.</para>
 1.12599 +
 1.12600 +      <!-- BEGIN template.svnstyle.style -->
 1.12601 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat svn.style</userinput>
 1.12602 +header = '------------------------------------------------------------------------\n\n'
 1.12603 +changeset = svn.template
 1.12604 +</screen>
 1.12605 +<!-- END template.svnstyle.style -->
 1.12606 +
 1.12607 +
 1.12608 +      <para id="x_5df">We could have included the text of the template file
 1.12609 +	directly in the style file by enclosing it in quotes and
 1.12610 +	replacing the newlines with
 1.12611 +	<quote><literal moreinfo="none">\n</literal></quote> sequences, but it would
 1.12612 +	have made the style file too difficult to read.  Readability
 1.12613 +	is a good guide when you're trying to decide whether some text
 1.12614 +	belongs in a style file, or in a template file that the style
 1.12615 +	file points to.  If the style file will look too big or
 1.12616 +	cluttered if you insert a literal piece of text, drop it into
 1.12617 +	a template instead.</para>
 1.12618 +    </sect2>
 1.12619 +  </sect1>
 1.12620 +</chapter>
 1.12621 +
 1.12622 +<!--
 1.12623 +local variables: 
 1.12624 +sgml-parent-document: ("00book.xml" "book" "chapter")
 1.12625 +end:
 1.12626 +-->
 1.12627 +
 1.12628 +  <!-- BEGIN ch12 -->
 1.12629 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.12630 +
 1.12631 +<chapter id="chap:mq">
 1.12632 +  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
 1.12633 +  <title>Managing change with Mercurial Queues</title>
 1.12634 +
 1.12635 +  <sect1 id="sec:mq:patch-mgmt">
 1.12636 +    <title>The patch management problem</title>
 1.12637 +
 1.12638 +    <para id="x_3ac">Here is a common scenario: you need to install a software
 1.12639 +      package from source, but you find a bug that you must fix in the
 1.12640 +      source before you can start using the package.  You make your
 1.12641 +      changes, forget about the package for a while, and a few months
 1.12642 +      later you need to upgrade to a newer version of the package.  If
 1.12643 +      the newer version of the package still has the bug, you must
 1.12644 +      extract your fix from the older source tree and apply it against
 1.12645 +      the newer version.  This is a tedious task, and it's easy to
 1.12646 +      make mistakes.</para>
 1.12647 +
 1.12648 +    <para id="x_3ad">This is a simple case of the <quote>patch management</quote>
 1.12649 +      problem.  You have an <quote>upstream</quote> source tree that
 1.12650 +      you can't change; you need to make some local changes on top of
 1.12651 +      the upstream tree; and you'd like to be able to keep those
 1.12652 +      changes separate, so that you can apply them to newer versions
 1.12653 +      of the upstream source.</para>
 1.12654 +
 1.12655 +    <para id="x_3ae">The patch management problem arises in many situations.
 1.12656 +      Probably the most visible is that a user of an open source
 1.12657 +      software project will contribute a bug fix or new feature to the
 1.12658 +      project's maintainers in the form of a patch.</para>
 1.12659 +
 1.12660 +    <para id="x_3af">Distributors of operating systems that include open source
 1.12661 +      software often need to make changes to the packages they
 1.12662 +      distribute so that they will build properly in their
 1.12663 +      environments.</para>
 1.12664 +
 1.12665 +    <para id="x_3b0">When you have few changes to maintain, it is easy to manage
 1.12666 +      a single patch using the standard <command moreinfo="none">diff</command> and
 1.12667 +      <command moreinfo="none">patch</command> programs (see <xref linkend="sec:mq:patch"/> for a discussion of these
 1.12668 +      tools). Once the number of changes grows, it starts to make
 1.12669 +      sense to maintain patches as discrete <quote>chunks of
 1.12670 +	work,</quote> so that for example a single patch will contain
 1.12671 +      only one bug fix (the patch might modify several files, but it's
 1.12672 +      doing <quote>only one thing</quote>), and you may have a number
 1.12673 +      of such patches for different bugs you need fixed and local
 1.12674 +      changes you require.  In this situation, if you submit a bug fix
 1.12675 +      patch to the upstream maintainers of a package and they include
 1.12676 +      your fix in a subsequent release, you can simply drop that
 1.12677 +      single patch when you're updating to the newer release.</para>
 1.12678 +
 1.12679 +    <para id="x_3b1">Maintaining a single patch against an upstream tree is a
 1.12680 +      little tedious and error-prone, but not difficult.  However, the
 1.12681 +      complexity of the problem grows rapidly as the number of patches
 1.12682 +      you have to maintain increases.  With more than a tiny number of
 1.12683 +      patches in hand, understanding which ones you have applied and
 1.12684 +      maintaining them moves from messy to overwhelming.</para>
 1.12685 +
 1.12686 +    <para id="x_3b2">Fortunately, Mercurial includes a powerful extension,
 1.12687 +      Mercurial Queues (or simply <quote>MQ</quote>), that massively
 1.12688 +      simplifies the patch management problem.</para>
 1.12689 +
 1.12690 +  </sect1>
 1.12691 +  <sect1 id="sec:mq:history">
 1.12692 +    <title>The prehistory of Mercurial Queues</title>
 1.12693 +
 1.12694 +    <para id="x_3b3">During the late 1990s, several Linux kernel developers
 1.12695 +      started to maintain <quote>patch series</quote> that modified
 1.12696 +      the behavior of the Linux kernel.  Some of these series were
 1.12697 +      focused on stability, some on feature coverage, and others were
 1.12698 +      more speculative.</para>
 1.12699 +
 1.12700 +    <para id="x_3b4">The sizes of these patch series grew rapidly.  In 2002,
 1.12701 +      Andrew Morton published some shell scripts he had been using to
 1.12702 +      automate the task of managing his patch queues.  Andrew was
 1.12703 +      successfully using these scripts to manage hundreds (sometimes
 1.12704 +      thousands) of patches on top of the Linux kernel.</para>
 1.12705 +
 1.12706 +    <sect2 id="sec:mq:quilt">
 1.12707 +      <title>A patchwork quilt</title>
 1.12708 +
 1.12709 +      <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson
 1.12710 +	borrowed the approach of Andrew's scripts and published a tool
 1.12711 +	called <quote>patchwork quilt</quote>
 1.12712 +	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
 1.12713 +	(see <citation>gruenbacher:2005</citation> for a paper
 1.12714 +	describing it).  Because quilt substantially automated patch
 1.12715 +	management, it rapidly gained a large following among open
 1.12716 +	source software developers.</para>
 1.12717 +
 1.12718 +      <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> on
 1.12719 +	top of a directory tree. To begin, you tell quilt to manage a
 1.12720 +	directory tree, and tell it which files you want to manage; it
 1.12721 +	stores away the names and contents of those files.  To fix a
 1.12722 +	bug, you create a new patch (using a single command), edit the
 1.12723 +	files you need to fix, then <quote>refresh</quote> the
 1.12724 +	patch.</para>
 1.12725 +
 1.12726 +      <para id="x_3b7">The refresh step causes quilt to scan the directory tree;
 1.12727 +	it updates the patch with all of the changes you have made.
 1.12728 +	You can create another patch on top of the first, which will
 1.12729 +	track the changes required to modify the tree from <quote>tree
 1.12730 +	  with one patch applied</quote> to <quote>tree with two
 1.12731 +	  patches applied</quote>.</para>
 1.12732 +
 1.12733 +      <para id="x_3b8">You can <emphasis>change</emphasis> which patches are
 1.12734 +	applied to the tree.  If you <quote>pop</quote> a patch, the
 1.12735 +	changes made by that patch will vanish from the directory
 1.12736 +	tree.  Quilt remembers which patches you have popped, though,
 1.12737 +	so you can <quote>push</quote> a popped patch again, and the
 1.12738 +	directory tree will be restored to contain the modifications
 1.12739 +	in the patch.  Most importantly, you can run the
 1.12740 +	<quote>refresh</quote> command at any time, and the topmost
 1.12741 +	applied patch will be updated.  This means that you can, at
 1.12742 +	any time, change both which patches are applied and what
 1.12743 +	modifications those patches make.</para>
 1.12744 +
 1.12745 +      <para id="x_3b9">Quilt knows nothing about revision control tools, so it
 1.12746 +	works equally well on top of an unpacked tarball or a
 1.12747 +	Subversion working copy.</para>
 1.12748 +    </sect2>
 1.12749 +
 1.12750 +    <sect2 id="sec:mq:quilt-mq">
 1.12751 +      <title>From patchwork quilt to Mercurial Queues</title>
 1.12752 +
 1.12753 +      <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and
 1.12754 +	wrote an extension that he called Mercurial Queues, which
 1.12755 +	added quilt-like behavior to Mercurial.</para>
 1.12756 +
 1.12757 +      <para id="x_3bb">The key difference between quilt and MQ is that quilt
 1.12758 +	knows nothing about revision control systems, while MQ is
 1.12759 +	<emphasis>integrated</emphasis> into Mercurial.  Each patch
 1.12760 +	that you push is represented as a Mercurial changeset.  Pop a
 1.12761 +	patch, and the changeset goes away.</para>
 1.12762 +
 1.12763 +      <para id="x_3bc">Because quilt does not care about revision control tools,
 1.12764 +	it is still a tremendously useful piece of software to know
 1.12765 +	about for situations where you cannot use Mercurial and
 1.12766 +	MQ.</para>
 1.12767 +
 1.12768 +    </sect2>
 1.12769 +  </sect1>
 1.12770 +  <sect1>
 1.12771 +    <title>The huge advantage of MQ</title>
 1.12772 +
 1.12773 +    <para id="x_3bd">I cannot overstate the value that MQ offers through the
 1.12774 +      unification of patches and revision control.</para>
 1.12775 +
 1.12776 +    <para id="x_3be">A major reason that patches have persisted in the free
 1.12777 +      software and open source world—in spite of the
 1.12778 +      availability of increasingly capable revision control tools over
 1.12779 +      the years—is the <emphasis>agility</emphasis> they
 1.12780 +      offer.</para>
 1.12781 +
 1.12782 +    <para id="x_3bf">Traditional revision control tools make a permanent,
 1.12783 +      irreversible record of everything that you do.  While this has
 1.12784 +      great value, it's also somewhat stifling.  If you want to
 1.12785 +      perform a wild-eyed experiment, you have to be careful in how
 1.12786 +      you go about it, or you risk leaving unneeded—or worse,
 1.12787 +      misleading or destabilising—traces of your missteps and
 1.12788 +      errors in the permanent revision record.</para>
 1.12789 +
 1.12790 +    <para id="x_3c0">By contrast, MQ's marriage of distributed revision control
 1.12791 +      with patches makes it much easier to isolate your work.  Your
 1.12792 +      patches live on top of normal revision history, and you can make
 1.12793 +      them disappear or reappear at will.  If you don't like a patch,
 1.12794 +      you can drop it.  If a patch isn't quite as you want it to be,
 1.12795 +      simply fix it—as many times as you need to, until you
 1.12796 +      have refined it into the form you desire.</para>
 1.12797 +
 1.12798 +    <para id="x_3c1">As an example, the integration of patches with revision
 1.12799 +      control makes understanding patches and debugging their
 1.12800 +      effects—and their interplay with the code they're based
 1.12801 +      on—<emphasis>enormously</emphasis> easier. Since every
 1.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
 1.12803 +      changesets and patches affected the file.  You can use the
 1.12804 +      <command role="hg-cmd" moreinfo="none">hg bisect</command> command to
 1.12805 +      binary-search through all changesets and applied patches to see
 1.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
 1.12807 +      changeset or patch modified a particular line of a source file.
 1.12808 +      And so on.</para>
 1.12809 +  </sect1>
 1.12810 +
 1.12811 +  <sect1 id="sec:mq:patch">
 1.12812 +    <title>Understanding patches</title>
 1.12813 +
 1.12814 +    <para id="x_3c2">Because MQ doesn't hide its patch-oriented nature, it is
 1.12815 +      helpful to understand what patches are, and a little about the
 1.12816 +      tools that work with them.</para>
 1.12817 +
 1.12818 +    <para id="x_3c3">The traditional Unix <command moreinfo="none">diff</command> command
 1.12819 +      compares two files, and prints a list of differences between
 1.12820 +      them. The <command moreinfo="none">patch</command> command understands these
 1.12821 +      differences as <emphasis>modifications</emphasis> to make to a
 1.12822 +      file.  Take a look below for a simple example of these commands
 1.12823 +      in action.</para>
 1.12824 +
 1.12825 +      <!-- BEGIN mq.dodiff.diff -->
 1.12826 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'this is my original thought' &gt; oldfile</userinput>
 1.12827 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'i have changed my mind' &gt; newfile</userinput>
 1.12828 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">diff -u oldfile newfile &gt; tiny.patch</userinput>
 1.12829 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat tiny.patch</userinput>
 1.12830 +--- oldfile	2009-08-16 14:05:06.000000000 +0000
 1.12831 ++++ newfile	2009-08-16 14:05:06.000000000 +0000
 1.12832 +@@ -1 +1 @@
 1.12833 +-this is my original thought
 1.12834 ++i have changed my mind
 1.12835 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">patch &lt; tiny.patch</userinput>
 1.12836 +patching file oldfile
 1.12837 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat oldfile</userinput>
 1.12838 +i have changed my mind
 1.12839 +</screen>
 1.12840 +<!-- END mq.dodiff.diff -->
 1.12841 +
 1.12842 +
 1.12843 +    <para id="x_3c4">The type of file that <command moreinfo="none">diff</command> generates (and
 1.12844 +      <command moreinfo="none">patch</command> takes as input) is called a
 1.12845 +      <quote>patch</quote> or a <quote>diff</quote>; there is no
 1.12846 +      difference between a patch and a diff.  (We'll use the term
 1.12847 +      <quote>patch</quote>, since it's more commonly used.)</para>
 1.12848 +
 1.12849 +    <para id="x_3c5">A patch file can start with arbitrary text; the
 1.12850 +      <command moreinfo="none">patch</command> command ignores this text, but MQ uses
 1.12851 +      it as the commit message when creating changesets.  To find the
 1.12852 +      beginning of the patch content, <command moreinfo="none">patch</command>
 1.12853 +      searches for the first line that starts with the string
 1.12854 +      <quote><literal moreinfo="none">diff -</literal></quote>.</para>
 1.12855 +
 1.12856 +    <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs
 1.12857 +      (<command moreinfo="none">patch</command> can accept several other diff formats,
 1.12858 +      but MQ doesn't).  A unified diff contains two kinds of header.
 1.12859 +      The <emphasis>file header</emphasis> describes the file being
 1.12860 +      modified; it contains the name of the file to modify.  When
 1.12861 +      <command moreinfo="none">patch</command> sees a new file header, it looks for a
 1.12862 +      file with that name to start modifying.</para>
 1.12863 +
 1.12864 +    <para id="x_3c7">After the file header comes a series of
 1.12865 +      <emphasis>hunks</emphasis>.  Each hunk starts with a header;
 1.12866 +      this identifies the range of line numbers within the file that
 1.12867 +      the hunk should modify.  Following the header, a hunk starts and
 1.12868 +      ends with a few (usually three) lines of text from the
 1.12869 +      unmodified file; these are called the
 1.12870 +      <emphasis>context</emphasis> for the hunk.  If there's only a
 1.12871 +      small amount of context between successive hunks,
 1.12872 +      <command moreinfo="none">diff</command> doesn't print a new hunk header; it just
 1.12873 +      runs the hunks together, with a few lines of context between
 1.12874 +      modifications.</para>
 1.12875 +
 1.12876 +    <para id="x_3c8">Each line of context begins with a space character.  Within
 1.12877 +      the hunk, a line that begins with
 1.12878 +      <quote><literal moreinfo="none">-</literal></quote> means <quote>remove this
 1.12879 +	line,</quote> while a line that begins with
 1.12880 +      <quote><literal moreinfo="none">+</literal></quote> means <quote>insert this
 1.12881 +	line.</quote>  For example, a line that is modified is
 1.12882 +      represented by one deletion and one insertion.</para>
 1.12883 +
 1.12884 +    <para id="x_3c9">We will return to some of the more subtle aspects of patches
 1.12885 +      later (in <xref linkend="sec:mq:adv-patch"/>), but you
 1.12886 +      should have
 1.12887 +      enough information now to use MQ.</para>
 1.12888 +  </sect1>
 1.12889 +
 1.12890 +  <sect1 id="sec:mq:start">
 1.12891 +    <title>Getting started with Mercurial Queues</title>
 1.12892 +
 1.12893 +    <para id="x_3ca">Because MQ is implemented as an extension, you must
 1.12894 +      explicitly enable before you can use it.  (You don't need to
 1.12895 +      download anything; MQ ships with the standard Mercurial
 1.12896 +      distribution.)  To enable MQ, edit your <filename role="home" moreinfo="none">~/.hgrc</filename> file, and add the lines
 1.12897 +      below.</para>
 1.12898 +
 1.12899 +    <programlisting format="linespecific">[extensions]
 1.12900 +hgext.mq =</programlisting>
 1.12901 +
 1.12902 +    <para id="x_3cb">Once the extension is enabled, it will make a number of new
 1.12903 +      commands available.  To verify that the extension is working,
 1.12904 +      you can use <command role="hg-cmd" moreinfo="none">hg help</command> to see if
 1.12905 +      the <command role="hg-ext-mq" moreinfo="none">qinit</command> command is now
 1.12906 +      available.</para>
 1.12907 +
 1.12908 +    <!-- BEGIN mq.qinit-help.help -->
 1.12909 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg help qinit</userinput>
 1.12910 +hg qinit [-c]
 1.12911 +
 1.12912 +init a new queue repository
 1.12913 +
 1.12914 +    The queue repository is unversioned by default. If -c is
 1.12915 +    specified, qinit will create a separate nested repository
 1.12916 +    for patches (qinit -c may also be run later to convert
 1.12917 +    an unversioned patch repository into a versioned one).
 1.12918 +    You can use qcommit to commit changes to this queue repository.
 1.12919 +
 1.12920 +options:
 1.12921 +
 1.12922 + -c --create-repo  create queue repository
 1.12923 +
 1.12924 +use "hg -v help qinit" to show global options
 1.12925 +</screen>
 1.12926 +<!-- END mq.qinit-help.help -->
 1.12927 +
 1.12928 +
 1.12929 +    <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial
 1.12930 +      repository, and its commands only operate within that
 1.12931 +      repository.  To get started, simply prepare the repository using
 1.12932 +      the <command role="hg-ext-mq" moreinfo="none">qinit</command> command.</para>
 1.12933 +
 1.12934 +    <!-- BEGIN mq.tutorial.qinit -->
 1.12935 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init mq-sandbox</userinput>
 1.12936 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd mq-sandbox</userinput>
 1.12937 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 1' &gt; file1</userinput>
 1.12938 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'another line 1' &gt; file2</userinput>
 1.12939 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add file1 file2</userinput>
 1.12940 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -m'first change'</userinput>
 1.12941 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 1.12942 +</screen>
 1.12943 +<!-- END mq.tutorial.qinit -->
 1.12944 +
 1.12945 +
 1.12946 +    <para id="x_3cd">This command creates an empty directory called <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>, where
 1.12947 +      MQ will keep its metadata.  As with many Mercurial commands, the
 1.12948 +      <command role="hg-ext-mq" moreinfo="none">qinit</command> command prints nothing
 1.12949 +      if it succeeds.</para>
 1.12950 +
 1.12951 +    <sect2>
 1.12952 +      <title>Creating a new patch</title>
 1.12953 +
 1.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
 1.12955 +	one argument, the name of the patch to create.</para>
 1.12956 +
 1.12957 +      <para id="x_3cf">MQ will use this as the name of an actual file in the
 1.12958 +	<filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory, as you
 1.12959 +	can see below.</para>
 1.12960 +
 1.12961 +      <!-- BEGIN mq.tutorial.qnew -->
 1.12962 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
 1.12963 +changeset:   0:5d84c303994b
 1.12964 +tag:         tip
 1.12965 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.12966 +date:        Sun Aug 16 14:05:11 2009 +0000
 1.12967 +summary:     first change
 1.12968 +
 1.12969 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew first.patch</userinput>
 1.12970 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip</userinput>
 1.12971 +changeset:   1:ba4d7a3f2149
 1.12972 +tag:         qtip
 1.12973 +tag:         first.patch
 1.12974 +tag:         tip
 1.12975 +tag:         qbase
 1.12976 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.12977 +date:        Sun Aug 16 14:05:11 2009 +0000
 1.12978 +summary:     [mq]: first.patch
 1.12979 +
 1.12980 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">ls .hg/patches</userinput>
 1.12981 +first.patch  series  status
 1.12982 +</screen>
 1.12983 +<!-- END mq.tutorial.qnew -->
 1.12984 +
 1.12985 +
 1.12986 +      <para id="x_3d0">Also newly present in the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory are two
 1.12987 +	other files, <filename role="special" moreinfo="none">series</filename> and
 1.12988 +	<filename role="special" moreinfo="none">status</filename>.  The <filename role="special" moreinfo="none">series</filename> file lists all of the
 1.12989 +	patches that MQ knows about for this repository, with one
 1.12990 +	patch per line.  Mercurial uses the <filename role="special" moreinfo="none">status</filename> file for internal
 1.12991 +	book-keeping; it tracks all of the patches that MQ has
 1.12992 +	<emphasis>applied</emphasis> in this repository.</para>
 1.12993 +
 1.12994 +      <note>
 1.12995 +	<para id="x_3d1">  You may sometimes want to edit the <filename role="special" moreinfo="none">series</filename> file by hand; for
 1.12996 +	  example, to change the sequence in which some patches are
 1.12997 +	  applied.  However, manually editing the <filename role="special" moreinfo="none">status</filename> file is almost always a
 1.12998 +	  bad idea, as it's easy to corrupt MQ's idea of what is
 1.12999 +	  happening.</para>
 1.13000 +      </note>
 1.13001 +
 1.13002 +      <para id="x_3d2">Once you have created your new patch, you can edit files
 1.13003 +	in the working directory as you usually would.  All of the
 1.13004 +	normal Mercurial commands, such as <command role="hg-cmd" moreinfo="none">hg
 1.13005 +	  diff</command> and <command role="hg-cmd" moreinfo="none">hg
 1.13006 +	  annotate</command>, work exactly as they did before.</para>
 1.13007 +    </sect2>
 1.13008 +
 1.13009 +    <sect2>
 1.13010 +      <title>Refreshing a patch</title>
 1.13011 +
 1.13012 +      <para id="x_3d3">When you reach a point where you want to save your work,
 1.13013 +	use the <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 1.13014 +	to update the patch you are working on.</para>
 1.13015 +
 1.13016 +      <!-- BEGIN mq.tutorial.qrefresh -->
 1.13017 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 2' &gt;&gt; file1</userinput>
 1.13018 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
 1.13019 +diff -r ba4d7a3f2149 file1
 1.13020 +--- a/file1	Sun Aug 16 14:05:11 2009 +0000
 1.13021 ++++ b/file1	Sun Aug 16 14:05:11 2009 +0000
 1.13022 +@@ -1,1 +1,2 @@
 1.13023 + line 1
 1.13024 ++line 2
 1.13025 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.13026 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
 1.13027 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact --patch</userinput>
 1.13028 +1[qtip,first.patch,tip,qbase]   1aa236e17e55   2009-08-16 14:05 +0000   bos
 1.13029 +  [mq]: first.patch
 1.13030 +
 1.13031 +diff -r 5d84c303994b -r 1aa236e17e55 file1
 1.13032 +--- a/file1	Sun Aug 16 14:05:11 2009 +0000
 1.13033 ++++ b/file1	Sun Aug 16 14:05:11 2009 +0000
 1.13034 +@@ -1,1 +1,2 @@
 1.13035 + line 1
 1.13036 ++line 2
 1.13037 +
 1.13038 +</screen>
 1.13039 +<!-- END mq.tutorial.qrefresh -->
 1.13040 +
 1.13041 +
 1.13042 +      <para id="x_3d4">This command folds the changes you have made in the
 1.13043 +	working directory into your patch, and updates its
 1.13044 +	corresponding changeset to contain those changes.</para>
 1.13045 +
 1.13046 +      <para id="x_3d5">You can run <command role="hg-ext-mq" moreinfo="none">qrefresh</command>
 1.13047 +	as often as you like, so it's a good way to
 1.13048 +	<quote>checkpoint</quote> your work.  Refresh your patch at an
 1.13049 +	opportune time; try an experiment; and if the experiment
 1.13050 +	doesn't work out, <command role="hg-cmd" moreinfo="none">hg revert</command>
 1.13051 +	your modifications back to the last time you refreshed.</para>
 1.13052 +
 1.13053 +      <!-- BEGIN mq.tutorial.qrefresh2 -->
 1.13054 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 3' &gt;&gt; file1</userinput>
 1.13055 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status</userinput>
 1.13056 +M file1
 1.13057 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.13058 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact --patch</userinput>
 1.13059 +1[qtip,first.patch,tip,qbase]   ebec7ce95e11   2009-08-16 14:05 +0000   bos
 1.13060 +  [mq]: first.patch
 1.13061 +
 1.13062 +diff -r 5d84c303994b -r ebec7ce95e11 file1
 1.13063 +--- a/file1	Sun Aug 16 14:05:11 2009 +0000
 1.13064 ++++ b/file1	Sun Aug 16 14:05:12 2009 +0000
 1.13065 +@@ -1,1 +1,3 @@
 1.13066 + line 1
 1.13067 ++line 2
 1.13068 ++line 3
 1.13069 +
 1.13070 +</screen>
 1.13071 +<!-- END mq.tutorial.qrefresh2 -->
 1.13072 +
 1.13073 +    </sect2>
 1.13074 +
 1.13075 +    <sect2>
 1.13076 +      <title>Stacking and tracking patches</title>
 1.13077 +
 1.13078 +      <para id="x_3d6">Once you have finished working on a patch, or need to work
 1.13079 +	on another, you can use the <command role="hg-ext-mq" moreinfo="none">qnew</command> command again to create a
 1.13080 +	new patch. Mercurial will apply this patch on top of your
 1.13081 +	existing patch.</para>
 1.13082 +
 1.13083 +      <!-- BEGIN mq.tutorial.qnew2 -->
 1.13084 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew second.patch</userinput>
 1.13085 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log --style=compact --limit=2</userinput>
 1.13086 +2[qtip,second.patch,tip]   dffbc4265523   2009-08-16 14:05 +0000   bos
 1.13087 +  [mq]: second.patch
 1.13088 +
 1.13089 +1[first.patch,qbase]   ebec7ce95e11   2009-08-16 14:05 +0000   bos
 1.13090 +  [mq]: first.patch
 1.13091 +
 1.13092 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'line 4' &gt;&gt; file1</userinput>
 1.13093 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.13094 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact --patch</userinput>
 1.13095 +2[qtip,second.patch,tip]   fdacb9b232ac   2009-08-16 14:05 +0000   bos
 1.13096 +  [mq]: second.patch
 1.13097 +
 1.13098 +diff -r ebec7ce95e11 -r fdacb9b232ac file1
 1.13099 +--- a/file1	Sun Aug 16 14:05:12 2009 +0000
 1.13100 ++++ b/file1	Sun Aug 16 14:05:12 2009 +0000
 1.13101 +@@ -1,3 +1,4 @@
 1.13102 + line 1
 1.13103 + line 2
 1.13104 + line 3
 1.13105 ++line 4
 1.13106 +
 1.13107 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg annotate file1</userinput>
 1.13108 +0: line 1
 1.13109 +1: line 2
 1.13110 +1: line 3
 1.13111 +2: line 4
 1.13112 +</screen>
 1.13113 +<!-- END mq.tutorial.qnew2 -->
 1.13114 +
 1.13115 +
 1.13116 +      <para id="x_3d7">Notice that the patch contains the changes in our prior
 1.13117 +	patch as part of its context (you can see this more clearly in
 1.13118 +	the output of <command role="hg-cmd" moreinfo="none">hg
 1.13119 +	  annotate</command>).</para>
 1.13120 +
 1.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
 1.13122 +	only use regular Mercurial commands.  However, MQ provides
 1.13123 +	many commands that are easier to use when you are thinking
 1.13124 +	about patches, as illustrated below.</para>
 1.13125 +
 1.13126 +      <!-- BEGIN mq.tutorial.qseries -->
 1.13127 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qseries</userinput>
 1.13128 +first.patch
 1.13129 +second.patch
 1.13130 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 1.13131 +first.patch
 1.13132 +second.patch
 1.13133 +</screen>
 1.13134 +<!-- END mq.tutorial.qseries -->
 1.13135 +
 1.13136 +
 1.13137 +      <itemizedlist>
 1.13138 +	<listitem><para id="x_3d9">The <command role="hg-ext-mq" moreinfo="none">qseries</command> command lists every
 1.13139 +	    patch that MQ knows about in this repository, from oldest
 1.13140 +	    to newest (most recently
 1.13141 +	    <emphasis>created</emphasis>).</para>
 1.13142 +	</listitem>
 1.13143 +	<listitem><para id="x_3da">The <command role="hg-ext-mq" moreinfo="none">qapplied</command> command lists every
 1.13144 +	    patch that MQ has <emphasis>applied</emphasis> in this
 1.13145 +	    repository, again from oldest to newest (most recently
 1.13146 +	    applied).</para>
 1.13147 +	</listitem></itemizedlist>
 1.13148 +    </sect2>
 1.13149 +
 1.13150 +    <sect2>
 1.13151 +      <title>Manipulating the patch stack</title>
 1.13152 +
 1.13153 +      <para id="x_3db">The previous discussion implied that there must be a
 1.13154 +	difference between <quote>known</quote> and
 1.13155 +	<quote>applied</quote> patches, and there is.  MQ can manage a
 1.13156 +	patch without it being applied in the repository.</para>
 1.13157 +
 1.13158 +      <para id="x_3dc">An <emphasis>applied</emphasis> patch has a corresponding
 1.13159 +	changeset in the repository, and the effects of the patch and
 1.13160 +	changeset are visible in the working directory.  You can undo
 1.13161 +	the application of a patch using the <command role="hg-ext-mq" moreinfo="none">qpop</command> command.  MQ still
 1.13162 +	<emphasis>knows about</emphasis>, or manages, a popped patch,
 1.13163 +	but the patch no longer has a corresponding changeset in the
 1.13164 +	repository, and the working directory does not contain the
 1.13165 +	changes made by the patch.  <xref linkend="fig:mq:stack"/> illustrates
 1.13166 +	the difference between applied and tracked patches.</para>
 1.13167 +
 1.13168 +      <figure id="fig:mq:stack" float="0">
 1.13169 +	<title>Applied and unapplied patches in the MQ patch
 1.13170 +	  stack</title>
 1.13171 +	<mediaobject>
 1.13172 +	  <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
 1.13173 +	  <textobject><phrase>XXX add text</phrase></textobject>
 1.13174 +	</mediaobject>
 1.13175 +      </figure>
 1.13176 +
 1.13177 +      <para id="x_3de">You can reapply an unapplied, or popped, patch using the
 1.13178 +	<command role="hg-ext-mq" moreinfo="none">qpush</command> command.  This
 1.13179 +	creates a new changeset to correspond to the patch, and the
 1.13180 +	patch's changes once again become present in the working
 1.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>
 1.13182 +
 1.13183 +      <!-- BEGIN mq.tutorial.qpop -->
 1.13184 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 1.13185 +first.patch
 1.13186 +second.patch
 1.13187 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop</userinput>
 1.13188 +now at: first.patch
 1.13189 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qseries</userinput>
 1.13190 +first.patch
 1.13191 +second.patch
 1.13192 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 1.13193 +first.patch
 1.13194 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file1</userinput>
 1.13195 +line 1
 1.13196 +line 2
 1.13197 +line 3
 1.13198 +</screen>
 1.13199 +<!-- END mq.tutorial.qpop -->
 1.13200 +
 1.13201 +
 1.13202 +      <para id="x_3df">Notice that once we have popped a patch or two patches,
 1.13203 +	the output of <command role="hg-ext-mq" moreinfo="none">qseries</command>
 1.13204 +	remains the same, while that of <command role="hg-ext-mq" moreinfo="none">qapplied</command> has changed.</para>
 1.13205 +
 1.13206 +    </sect2>
 1.13207 +
 1.13208 +    <sect2>
 1.13209 +      <title>Pushing and popping many patches</title>
 1.13210 +
 1.13211 +      <para id="x_3e0">While <command role="hg-ext-mq" moreinfo="none">qpush</command> and
 1.13212 +	<command role="hg-ext-mq" moreinfo="none">qpop</command> each operate on a
 1.13213 +	single patch at a time by default, you can push and pop many
 1.13214 +	patches in one go.  The <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
 1.13215 +	<command role="hg-ext-mq" moreinfo="none">qpush</command> causes it to push
 1.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
 1.13217 +	patches.  (For some more ways to push and pop many patches,
 1.13218 +	see <xref linkend="sec:mq:perf"/> below.)</para>
 1.13219 +
 1.13220 +      <!-- BEGIN mq.tutorial.qpush-a -->
 1.13221 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 1.13222 +applying second.patch
 1.13223 +now at: second.patch
 1.13224 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat file1</userinput>
 1.13225 +line 1
 1.13226 +line 2
 1.13227 +line 3
 1.13228 +line 4
 1.13229 +</screen>
 1.13230 +<!-- END mq.tutorial.qpush-a -->
 1.13231 +
 1.13232 +    </sect2>
 1.13233 +
 1.13234 +    <sect2>
 1.13235 +      <title>Safety checks, and overriding them</title>
 1.13236 +
 1.13237 +      <para id="x_3e1">Several MQ commands check the working directory before
 1.13238 +	they do anything, and fail if they find any modifications.
 1.13239 +	They do this to ensure that you won't lose any changes that
 1.13240 +	you have made, but not yet incorporated into a patch.  The
 1.13241 +	example below illustrates this; the <command role="hg-ext-mq" moreinfo="none">qnew</command> command will not create a
 1.13242 +	new patch if there are outstanding changes, caused in this
 1.13243 +	case by the <command role="hg-cmd" moreinfo="none">hg add</command> of
 1.13244 +	<filename moreinfo="none">file3</filename>.</para>
 1.13245 +
 1.13246 +      <!-- BEGIN mq.tutorial.add -->
 1.13247 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo 'file 3, line 1' &gt;&gt; file3</userinput>
 1.13248 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew add-file3.patch</userinput>
 1.13249 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew -f add-file3.patch</userinput>
 1.13250 +abort: patch "add-file3.patch" already exists
 1.13251 +</screen>
 1.13252 +<!-- END mq.tutorial.add -->
 1.13253 +
 1.13254 +
 1.13255 +      <para id="x_3e2">Commands that check the working directory all take an
 1.13256 +	<quote>I know what I'm doing</quote> option, which is always
 1.13257 +	named <option>-f</option>.  The exact meaning of
 1.13258 +	<option>-f</option> depends on the command.  For example,
 1.13259 +	<command role="hg-cmd" moreinfo="none">hg qnew <option role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
 1.13260 +	will incorporate any outstanding changes into the new patch it
 1.13261 +	creates, but <command role="hg-cmd" moreinfo="none">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
 1.13262 +	will revert modifications to any files affected by the patch
 1.13263 +	that it is popping.  Be sure to read the documentation for a
 1.13264 +	command's <option>-f</option> option before you use it!</para>
 1.13265 +    </sect2>
 1.13266 +
 1.13267 +    <sect2>
 1.13268 +      <title>Working on several patches at once</title>
 1.13269 +
 1.13270 +      <para id="x_3e3">The <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 1.13271 +	always refreshes the <emphasis>topmost</emphasis> applied
 1.13272 +	patch.  This means that you can suspend work on one patch (by
 1.13273 +	refreshing it), pop or push to make a different patch the top,
 1.13274 +	and work on <emphasis>that</emphasis> patch for a
 1.13275 +	while.</para>
 1.13276 +
 1.13277 +      <para id="x_3e4">Here's an example that illustrates how you can use this
 1.13278 +	ability. Let's say you're developing a new feature as two
 1.13279 +	patches.  The first is a change to the core of your software,
 1.13280 +	and the second—layered on top of the
 1.13281 +	first—changes the user interface to use the code you
 1.13282 +	just added to the core.  If you notice a bug in the core while
 1.13283 +	you're working on the UI patch, it's easy to fix the core.
 1.13284 +	Simply <command role="hg-ext-mq" moreinfo="none">qrefresh</command> the UI
 1.13285 +	patch to save your in-progress changes, and <command role="hg-ext-mq" moreinfo="none">qpop</command> down to the core patch.  Fix
 1.13286 +	the core bug, <command role="hg-ext-mq" moreinfo="none">qrefresh</command> the
 1.13287 +	core patch, and <command role="hg-ext-mq" moreinfo="none">qpush</command> back
 1.13288 +	to the UI patch to continue where you left off.</para>
 1.13289 +    </sect2>
 1.13290 +  </sect1>
 1.13291 +
 1.13292 +  <sect1 id="sec:mq:adv-patch">
 1.13293 +    <title>More about patches</title>
 1.13294 +
 1.13295 +    <para id="x_3e5">MQ uses the GNU <command moreinfo="none">patch</command> command to apply
 1.13296 +      patches, so it's helpful to know a few more detailed aspects of
 1.13297 +      how <command moreinfo="none">patch</command> works, and about patches
 1.13298 +      themselves.</para>
 1.13299 +
 1.13300 +    <sect2>
 1.13301 +      <title>The strip count</title>
 1.13302 +
 1.13303 +      <para id="x_3e6">If you look at the file headers in a patch, you will
 1.13304 +	notice that the pathnames usually have an extra component on
 1.13305 +	the front that isn't present in the actual path name.  This is
 1.13306 +	a holdover from the way that people used to generate patches
 1.13307 +	(people still do this, but it's somewhat rare with modern
 1.13308 +	revision control tools).</para>
 1.13309 +
 1.13310 +      <para id="x_3e7">Alice would unpack a tarball, edit her files, then decide
 1.13311 +	that she wanted to create a patch.  So she'd rename her
 1.13312 +	working directory, unpack the tarball again (hence the need
 1.13313 +	for the rename), and use the <option role="cmd-opt-diff">-r</option> and <option role="cmd-opt-diff">-N</option> options to
 1.13314 +	<command moreinfo="none">diff</command> to recursively generate a patch
 1.13315 +	between the unmodified directory and the modified one.  The
 1.13316 +	result would be that the name of the unmodified directory
 1.13317 +	would be at the front of the left-hand path in every file
 1.13318 +	header, and the name of the modified directory would be at the
 1.13319 +	front of the right-hand path.</para>
 1.13320 +
 1.13321 +      <para id="x_3e8">Since someone receiving a patch from the Alices of the net
 1.13322 +	would be unlikely to have unmodified and modified directories
 1.13323 +	with exactly the same names, the <command moreinfo="none">patch</command>
 1.13324 +	command has a <option role="cmd-opt-patch">-p</option> option
 1.13325 +	that indicates the number of leading path name components to
 1.13326 +	strip when trying to apply a patch.  This number is called the
 1.13327 +	<emphasis>strip count</emphasis>.</para>
 1.13328 +
 1.13329 +      <para id="x_3e9">An option of <quote><literal moreinfo="none">-p1</literal></quote> means
 1.13330 +	<quote>use a strip count of one</quote>.  If
 1.13331 +	<command moreinfo="none">patch</command> sees a file name
 1.13332 +	<filename moreinfo="none">foo/bar/baz</filename> in a file header, it will
 1.13333 +	strip <filename moreinfo="none">foo</filename> and try to patch a file named
 1.13334 +	<filename moreinfo="none">bar/baz</filename>.  (Strictly speaking, the strip
 1.13335 +	count refers to the number of <emphasis>path
 1.13336 +	  separators</emphasis> (and the components that go with them
 1.13337 +	) to strip.  A strip count of one will turn
 1.13338 +	<filename moreinfo="none">foo/bar</filename> into <filename moreinfo="none">bar</filename>,
 1.13339 +	but <filename moreinfo="none">/foo/bar</filename> (notice the extra leading
 1.13340 +	slash) into <filename moreinfo="none">foo/bar</filename>.)</para>
 1.13341 +
 1.13342 +      <para id="x_3ea">The <quote>standard</quote> strip count for patches is
 1.13343 +	one; almost all patches contain one leading path name
 1.13344 +	component that needs to be stripped. Mercurial's <command role="hg-cmd" moreinfo="none">hg diff</command> command generates path names
 1.13345 +	in this form, and the <command role="hg-cmd" moreinfo="none">hg
 1.13346 +	  import</command> command and MQ expect patches to have a
 1.13347 +	strip count of one.</para>
 1.13348 +
 1.13349 +      <para id="x_3eb">If you receive a patch from someone that you want to add
 1.13350 +	to your patch queue, and the patch needs a strip count other
 1.13351 +	than one, you cannot just <command role="hg-ext-mq" moreinfo="none">qimport</command> the patch, because
 1.13352 +	<command role="hg-ext-mq" moreinfo="none">qimport</command> does not yet have
 1.13353 +	a <literal moreinfo="none">-p</literal> option (see <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">issue
 1.13354 +	  311</ulink>).  Your best bet is to <command role="hg-ext-mq" moreinfo="none">qnew</command> a patch of your own, then
 1.13355 +	use <command moreinfo="none">patch -pN</command> to apply their patch,
 1.13356 +	followed by <command role="hg-cmd" moreinfo="none">hg addremove</command> to
 1.13357 +	pick up any files added or removed by the patch, followed by
 1.13358 +	<command role="hg-ext-mq" moreinfo="none">hg qrefresh</command>. This
 1.13359 +	complexity may become unnecessary; see <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">issue
 1.13360 +	  311</ulink> for details.
 1.13361 +      </para>
 1.13362 +    </sect2>
 1.13363 +
 1.13364 +    <sect2>
 1.13365 +      <title>Strategies for applying a patch</title>
 1.13366 +
 1.13367 +      <para id="x_3ec">When <command moreinfo="none">patch</command> applies a hunk, it tries a
 1.13368 +	handful of successively less accurate strategies to try to
 1.13369 +	make the hunk apply. This falling-back technique often makes
 1.13370 +	it possible to take a patch that was generated against an old
 1.13371 +	version of a file, and apply it against a newer version of
 1.13372 +	that file.</para>
 1.13373 +
 1.13374 +      <para id="x_3ed">First, <command moreinfo="none">patch</command> tries an exact match,
 1.13375 +	where the line numbers, the context, and the text to be
 1.13376 +	modified must apply exactly.  If it cannot make an exact
 1.13377 +	match, it tries to find an exact match for the context,
 1.13378 +	without honouring the line numbering information.  If this
 1.13379 +	succeeds, it prints a line of output saying that the hunk was
 1.13380 +	applied, but at some <emphasis>offset</emphasis> from the
 1.13381 +	original line number.</para>
 1.13382 +
 1.13383 +      <para id="x_3ee">If a context-only match fails, <command moreinfo="none">patch</command>
 1.13384 +	removes the first and last lines of the context, and tries a
 1.13385 +	<emphasis>reduced</emphasis> context-only match.  If the hunk
 1.13386 +	with reduced context succeeds, it prints a message saying that
 1.13387 +	it applied the hunk with a <emphasis>fuzz factor</emphasis>
 1.13388 +	(the number after the fuzz factor indicates how many lines of
 1.13389 +	context <command moreinfo="none">patch</command> had to trim before the patch
 1.13390 +	applied).</para>
 1.13391 +
 1.13392 +      <para id="x_3ef">When neither of these techniques works,
 1.13393 +	<command moreinfo="none">patch</command> prints a message saying that the hunk
 1.13394 +	in question was rejected.  It saves rejected hunks (also
 1.13395 +	simply called <quote>rejects</quote>) to a file with the same
 1.13396 +	name, and an added <filename role="special" moreinfo="none">.rej</filename>
 1.13397 +	extension.  It also saves an unmodified copy of the file with
 1.13398 +	a <filename role="special" moreinfo="none">.orig</filename> extension; the
 1.13399 +	copy of the file without any extensions will contain any
 1.13400 +	changes made by hunks that <emphasis>did</emphasis> apply
 1.13401 +	cleanly.  If you have a patch that modifies
 1.13402 +	<filename moreinfo="none">foo</filename> with six hunks, and one of them fails
 1.13403 +	to apply, you will have: an unmodified
 1.13404 +	<filename moreinfo="none">foo.orig</filename>, a <filename moreinfo="none">foo.rej</filename>
 1.13405 +	containing one hunk, and <filename moreinfo="none">foo</filename>, containing
 1.13406 +	the changes made by the five successful hunks.</para>
 1.13407 +    </sect2>
 1.13408 +
 1.13409 +    <sect2>
 1.13410 +      <title>Some quirks of patch representation</title>
 1.13411 +
 1.13412 +      <para id="x_3f0">There are a few useful things to know about how
 1.13413 +	<command moreinfo="none">patch</command> works with files.</para>
 1.13414 +      <itemizedlist>
 1.13415 +	<listitem><para id="x_3f1">This should already be obvious, but
 1.13416 +	    <command moreinfo="none">patch</command> cannot handle binary
 1.13417 +	    files.</para>
 1.13418 +	</listitem>
 1.13419 +	<listitem><para id="x_3f2">Neither does it care about the executable bit;
 1.13420 +	    it creates new files as readable, but not
 1.13421 +	    executable.</para>
 1.13422 +	</listitem>
 1.13423 +	<listitem><para id="x_3f3"><command moreinfo="none">patch</command> treats the removal of
 1.13424 +	    a file as a diff between the file to be removed and the
 1.13425 +	    empty file.  So your idea of <quote>I deleted this
 1.13426 +	      file</quote> looks like <quote>every line of this file
 1.13427 +	      was deleted</quote> in a patch.</para>
 1.13428 +	</listitem>
 1.13429 +	<listitem><para id="x_3f4">It treats the addition of a file as a diff
 1.13430 +	    between the empty file and the file to be added.  So in a
 1.13431 +	    patch, your idea of <quote>I added this file</quote> looks
 1.13432 +	    like <quote>every line of this file was
 1.13433 +	      added</quote>.</para>
 1.13434 +	</listitem>
 1.13435 +	<listitem><para id="x_3f5">It treats a renamed file as the removal of the
 1.13436 +	    old name, and the addition of the new name.  This means
 1.13437 +	    that renamed files have a big footprint in patches.  (Note
 1.13438 +	    also that Mercurial does not currently try to infer when
 1.13439 +	    files have been renamed or copied in a patch.)</para>
 1.13440 +	</listitem>
 1.13441 +	<listitem><para id="x_3f6"><command moreinfo="none">patch</command> cannot represent
 1.13442 +	    empty files, so you cannot use a patch to represent the
 1.13443 +	    notion <quote>I added this empty file to the
 1.13444 +	      tree</quote>.</para>
 1.13445 +	</listitem></itemizedlist>
 1.13446 +    </sect2>
 1.13447 +
 1.13448 +    <sect2>
 1.13449 +      <title>Beware the fuzz</title>
 1.13450 +
 1.13451 +      <para id="x_3f7">While applying a hunk at an offset, or with a fuzz factor,
 1.13452 +	will often be completely successful, these inexact techniques
 1.13453 +	naturally leave open the possibility of corrupting the patched
 1.13454 +	file.  The most common cases typically involve applying a
 1.13455 +	patch twice, or at an incorrect location in the file.  If
 1.13456 +	<command moreinfo="none">patch</command> or <command role="hg-ext-mq" moreinfo="none">qpush</command> ever mentions an offset or
 1.13457 +	fuzz factor, you should make sure that the modified files are
 1.13458 +	correct afterwards.</para>
 1.13459 +
 1.13460 +      <para id="x_3f8">It's often a good idea to refresh a patch that has applied
 1.13461 +	with an offset or fuzz factor; refreshing the patch generates
 1.13462 +	new context information that will make it apply cleanly.  I
 1.13463 +	say <quote>often,</quote> not <quote>always,</quote> because
 1.13464 +	sometimes refreshing a patch will make it fail to apply
 1.13465 +	against a different revision of the underlying files.  In some
 1.13466 +	cases, such as when you're maintaining a patch that must sit
 1.13467 +	on top of multiple versions of a source tree, it's acceptable
 1.13468 +	to have a patch apply with some fuzz, provided you've verified
 1.13469 +	the results of the patching process in such cases.</para>
 1.13470 +    </sect2>
 1.13471 +
 1.13472 +    <sect2>
 1.13473 +      <title>Handling rejection</title>
 1.13474 +
 1.13475 +      <para id="x_3f9">If <command role="hg-ext-mq" moreinfo="none">qpush</command> fails to
 1.13476 +	apply a patch, it will print an error message and exit.  If it
 1.13477 +	has left <filename role="special" moreinfo="none">.rej</filename> files
 1.13478 +	behind, it is usually best to fix up the rejected hunks before
 1.13479 +	you push more patches or do any further work.</para>
 1.13480 +
 1.13481 +      <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly,
 1.13482 +	and no longer does because you've changed the underlying code
 1.13483 +	that your patches are based on, Mercurial Queues can help; see
 1.13484 +	<xref linkend="sec:mq:merge"/> for details.</para>
 1.13485 +
 1.13486 +      <para id="x_3fb">Unfortunately, there aren't any great techniques for
 1.13487 +	dealing with rejected hunks.  Most often, you'll need to view
 1.13488 +	the <filename role="special" moreinfo="none">.rej</filename> file and edit the
 1.13489 +	target file, applying the rejected hunks by hand.</para>
 1.13490 +
 1.13491 +      <para id="x_3fd">A Linux kernel hacker, Chris Mason (the author
 1.13492 +	of Mercurial Queues), wrote a tool called
 1.13493 +	<command moreinfo="none">mpatch</command> (<ulink url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>), 
 1.13494 +	which takes a simple approach to automating the application of
 1.13495 +	hunks rejected by <command moreinfo="none">patch</command>.  The
 1.13496 +	<command moreinfo="none">mpatch</command> command can help with four common
 1.13497 +	reasons that a hunk may be rejected:</para>
 1.13498 +
 1.13499 +      <itemizedlist>
 1.13500 +	<listitem><para id="x_3fe">The context in the middle of a hunk has
 1.13501 +	    changed.</para>
 1.13502 +	</listitem>
 1.13503 +	<listitem><para id="x_3ff">A hunk is missing some context at the
 1.13504 +	    beginning or end.</para>
 1.13505 +	</listitem>
 1.13506 +	<listitem><para id="x_400">A large hunk might apply better—either
 1.13507 +	    entirely or in part—if it was broken up into
 1.13508 +	    smaller hunks.</para>
 1.13509 +	</listitem>
 1.13510 +	<listitem><para id="x_401">A hunk removes lines with slightly different
 1.13511 +	    content than those currently present in the file.</para>
 1.13512 +	</listitem></itemizedlist>
 1.13513 +
 1.13514 +      <para id="x_402">If you use <command moreinfo="none">mpatch</command>, you
 1.13515 +	should be doubly careful to check your results when you're
 1.13516 +	done.  In fact, <command moreinfo="none">mpatch</command> enforces this method
 1.13517 +	of double-checking the tool's output, by automatically
 1.13518 +	dropping you into a merge program when it has done its job, so
 1.13519 +	that you can verify its work and finish off any remaining
 1.13520 +	merges.</para>
 1.13521 +    </sect2>
 1.13522 +  </sect1>
 1.13523 +
 1.13524 +  <sect1>
 1.13525 +    <title>More on patch management</title>
 1.13526 +
 1.13527 +    <para id="x_6db">As you grow familiar with MQ, you will find yourself wanting
 1.13528 +      to perform other kinds of patch management operations.</para>
 1.13529 +
 1.13530 +    <sect2>
 1.13531 +      <title>Deleting unwanted patches</title>
 1.13532 +
 1.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
 1.13534 +	patch file and remove its entry from the patch series.  If you
 1.13535 +	try to delete a patch that is still applied, <command role="hg-ext-mq" moreinfo="none">hg qdelete</command> will refuse.</para>
 1.13536 +
 1.13537 +      <!-- BEGIN ch11/qdelete.go -->
 1.13538 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init myrepo</userinput>
 1.13539 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd myrepo</userinput>
 1.13540 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 1.13541 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew bad.patch</userinput>
 1.13542 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 1.13543 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 1.13544 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.13545 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qdelete bad.patch</userinput>
 1.13546 +abort: cannot delete applied patch bad.patch
 1.13547 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop</userinput>
 1.13548 +patch queue now empty
 1.13549 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qdelete bad.patch</userinput>
 1.13550 +</screen>
 1.13551 +<!-- END ch11/qdelete.go -->
 1.13552 +
 1.13553 +    </sect2>
 1.13554 +
 1.13555 +    <sect2>
 1.13556 +      <title>Converting to and from permanent revisions</title>
 1.13557 +
 1.13558 +      <para id="x_6dd">Once you're done working on a patch and want to
 1.13559 +      turn it into a permanent changeset, use the <command role="hg-ext-mq" moreinfo="none">hg qfinish</command> command. Pass a revision
 1.13560 +      to the command to identify the patch that you want to turn into
 1.13561 +      a regular changeset; this patch must already be applied.</para>
 1.13562 +
 1.13563 +      <!-- BEGIN ch11/qdelete.convert -->
 1.13564 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew good.patch</userinput>
 1.13565 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo a &gt; a</userinput>
 1.13566 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add a</userinput>
 1.13567 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh -m 'Good change'</userinput>
 1.13568 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qfinish tip</userinput>
 1.13569 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 1.13570 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip --style=compact</userinput>
 1.13571 +0[tip]   32fc5ce6b092   2009-08-16 14:04 +0000   bos
 1.13572 +  Good change
 1.13573 +
 1.13574 +</screen>
 1.13575 +<!-- END ch11/qdelete.convert -->
 1.13576 +
 1.13577 +
 1.13578 +      <para id="x_6e0">The <command role="hg-ext-mq" moreinfo="none">hg qfinish</command> command
 1.13579 +        accepts an <option>--all</option> or <option>-a</option>
 1.13580 +        option, which turns all applied patches into regular
 1.13581 +        changesets.</para>
 1.13582 +
 1.13583 +      <para id="x_6de">It is also possible to turn an existing changeset into a
 1.13584 +	patch, by passing the <option>-r</option> option to <command role="hg-ext-mq" moreinfo="none">hg qimport</command>.</para>
 1.13585 +
 1.13586 +      <!-- BEGIN ch11/qdelete.import -->
 1.13587 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qimport -r tip</userinput>
 1.13588 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 1.13589 +0.diff
 1.13590 +</screen>
 1.13591 +<!-- END ch11/qdelete.import -->
 1.13592 +
 1.13593 +
 1.13594 +      <para id="x_6df">Note that it only makes sense to convert a changeset into
 1.13595 +	a patch if you have not propagated that changeset into any
 1.13596 +	other repositories.  The imported changeset's ID will change
 1.13597 +	every time you refresh the patch, which will make Mercurial
 1.13598 +	treat it as unrelated to the original changeset if you have
 1.13599 +	pushed it somewhere else.</para>
 1.13600 +    </sect2>
 1.13601 +  </sect1>
 1.13602 +
 1.13603 +  <sect1 id="sec:mq:perf">
 1.13604 +    <title>Getting the best performance out of MQ</title>
 1.13605 +
 1.13606 +    <para id="x_403">MQ is very efficient at handling a large number
 1.13607 +      of patches. I ran some performance experiments in mid-2006 for a
 1.13608 +      talk that I gave at the 2006 EuroPython conference (on modern
 1.13609 +      hardware, you should expect better performance than you'll see
 1.13610 +      below).  I used as my data set the Linux 2.6.17-mm1 patch
 1.13611 +      series, which consists of 1,738 patches. I applied these on top
 1.13612 +      of a Linux kernel repository containing all 27,472 revisions
 1.13613 +      between Linux 2.6.12-rc2 and Linux 2.6.17.</para>
 1.13614 +
 1.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
 1.13616 +      1,738 patches in 3.5 minutes, and <command role="hg-cmd" moreinfo="none">hg qpop
 1.13617 +	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
 1.13618 +      them all in 30 seconds.  (On a newer laptop, the time to push
 1.13619 +      all patches dropped to two minutes.)  I could <command role="hg-ext-mq" moreinfo="none">qrefresh</command> one of the biggest patches
 1.13620 +      (which made 22,779 lines of changes to 287 files) in 6.6
 1.13621 +      seconds.</para>
 1.13622 +
 1.13623 +    <para id="x_405">Clearly, MQ is well suited to working in large trees, but
 1.13624 +      there are a few tricks you can use to get the best performance
 1.13625 +      of it.</para>
 1.13626 +
 1.13627 +    <para id="x_406">First of all, try to <quote>batch</quote> operations
 1.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
 1.13629 +      working directory once to make sure you haven't made some
 1.13630 +      changes and then forgotten to run <command role="hg-ext-mq" moreinfo="none">qrefresh</command>.  On a small tree, the
 1.13631 +      time that this scan takes is unnoticeable.  However, on a
 1.13632 +      medium-sized tree (containing tens of thousands of files), it
 1.13633 +      can take a second or more.</para>
 1.13634 +
 1.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
 1.13636 +      pop multiple patches at a time.  You can identify the
 1.13637 +      <quote>destination patch</quote> that you want to end up at.
 1.13638 +      When you <command role="hg-ext-mq" moreinfo="none">qpush</command> with a
 1.13639 +      destination specified, it will push patches until that patch is
 1.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
 1.13641 +      patches until the destination patch is at the top.</para>
 1.13642 +
 1.13643 +    <para id="x_408">You can identify a destination patch using either the name
 1.13644 +      of the patch, or by number.  If you use numeric addressing,
 1.13645 +      patches are counted from zero; this means that the first patch
 1.13646 +      is zero, the second is one, and so on.</para>
 1.13647 +  </sect1>
 1.13648 +
 1.13649 +  <sect1 id="sec:mq:merge">
 1.13650 +    <title>Updating your patches when the underlying code
 1.13651 +      changes</title>
 1.13652 +
 1.13653 +    <para id="x_409">It's common to have a stack of patches on top of an
 1.13654 +      underlying repository that you don't modify directly.  If you're
 1.13655 +      working on changes to third-party code, or on a feature that is
 1.13656 +      taking longer to develop than the rate of change of the code
 1.13657 +      beneath, you will often need to sync up with the underlying
 1.13658 +      code, and fix up any hunks in your patches that no longer apply.
 1.13659 +      This is called <emphasis>rebasing</emphasis> your patch
 1.13660 +      series.</para>
 1.13661 +
 1.13662 +    <para id="x_40a">The simplest way to do this is to <command role="hg-cmd" moreinfo="none">hg
 1.13663 +	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
 1.13664 +	  -a</option></command> your patches, then <command role="hg-cmd" moreinfo="none">hg pull</command> changes into the underlying
 1.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
 1.13666 +      patches again.  MQ will stop pushing any time it runs across a
 1.13667 +      patch that fails to apply during conflicts, allowing you to fix
 1.13668 +      your conflicts, <command role="hg-ext-mq" moreinfo="none">qrefresh</command> the
 1.13669 +      affected patch, and continue pushing until you have fixed your
 1.13670 +      entire stack.</para>
 1.13671 +
 1.13672 +    <para id="x_40b">This approach is easy to use and works well if you don't
 1.13673 +      expect changes to the underlying code to affect how well your
 1.13674 +      patches apply. If your patch stack touches code that is modified
 1.13675 +      frequently or invasively in the underlying repository, however,
 1.13676 +      fixing up rejected hunks by hand quickly becomes
 1.13677 +      tiresome.</para>
 1.13678 +
 1.13679 +    <para id="x_40c">It's possible to partially automate the rebasing process.
 1.13680 +      If your patches apply cleanly against some revision of the
 1.13681 +      underlying repo, MQ can use this information to help you to
 1.13682 +      resolve conflicts between your patches and a different
 1.13683 +      revision.</para>
 1.13684 +
 1.13685 +    <para id="x_40d">The process is a little involved.</para>
 1.13686 +    <orderedlist inheritnum="ignore" continuation="restarts">
 1.13687 +      <listitem><para id="x_40e">To begin, <command role="hg-cmd" moreinfo="none">hg qpush
 1.13688 +	    -a</command> all of your patches on top of the revision
 1.13689 +	  where you know that they apply cleanly.</para>
 1.13690 +      </listitem>
 1.13691 +      <listitem><para id="x_40f">Save a backup copy of your patch directory using
 1.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>.
 1.13693 +	  This prints the name of the directory that it has saved the
 1.13694 +	  patches in.  It will save the patches to a directory called
 1.13695 +	  <filename role="special" class="directory" moreinfo="none">.hg/patches.N</filename>, where
 1.13696 +	  <literal moreinfo="none">N</literal> is a small integer.  It also commits a
 1.13697 +	  <quote>save changeset</quote> on top of your applied
 1.13698 +	  patches; this is for internal book-keeping, and records the
 1.13699 +	  states of the <filename role="special" moreinfo="none">series</filename> and
 1.13700 +	  <filename role="special" moreinfo="none">status</filename> files.</para>
 1.13701 +      </listitem>
 1.13702 +      <listitem><para id="x_410">Use <command role="hg-cmd" moreinfo="none">hg pull</command> to
 1.13703 +	  bring new changes into the underlying repository.  (Don't
 1.13704 +	  run <command role="hg-cmd" moreinfo="none">hg pull -u</command>; see below
 1.13705 +	  for why.)</para>
 1.13706 +      </listitem>
 1.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
 1.13708 +	  the patches you have pushed.</para>
 1.13709 +      </listitem>
 1.13710 +      <listitem><para id="x_412">Merge all patches using <command moreinfo="none">hg qpush -m
 1.13711 +	    -a</command>.  The <option role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
 1.13712 +	  <command role="hg-ext-mq" moreinfo="none">qpush</command> tells MQ to
 1.13713 +	  perform a three-way merge if the patch fails to
 1.13714 +	  apply.</para>
 1.13715 +      </listitem></orderedlist>
 1.13716 +
 1.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>,
 1.13718 +      each patch in the <filename role="special" moreinfo="none">series</filename>
 1.13719 +      file is applied normally.  If a patch applies with fuzz or
 1.13720 +      rejects, MQ looks at the queue you <command role="hg-ext-mq" moreinfo="none">qsave</command>d, and performs a three-way
 1.13721 +      merge with the corresponding changeset.  This merge uses
 1.13722 +      Mercurial's normal merge machinery, so it may pop up a GUI merge
 1.13723 +      tool to help you to resolve problems.</para>
 1.13724 +
 1.13725 +    <para id="x_414">When you finish resolving the effects of a patch, MQ
 1.13726 +      refreshes your patch based on the result of the merge.</para>
 1.13727 +
 1.13728 +    <para id="x_415">At the end of this process, your repository will have one
 1.13729 +      extra head from the old patch queue, and a copy of the old patch
 1.13730 +      queue will be in <filename role="special" class="directory" moreinfo="none">.hg/patches.N</filename>. You can remove the
 1.13731 +      extra head using <command role="hg-cmd" moreinfo="none">hg qpop -a -n
 1.13732 +	patches.N</command> or <command role="hg-cmd" moreinfo="none">hg
 1.13733 +	strip</command>.  You can delete <filename role="special" class="directory" moreinfo="none">.hg/patches.N</filename> once you are sure
 1.13734 +      that you no longer need it as a backup.</para>
 1.13735 +  </sect1>
 1.13736 +
 1.13737 +  <sect1>
 1.13738 +    <title>Identifying patches</title>
 1.13739 +
 1.13740 +    <para id="x_416">MQ commands that work with patches let you refer to a patch
 1.13741 +      either by using its name or by a number.  By name is obvious
 1.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
 1.13743 +      push patches until <filename moreinfo="none">foo.patch</filename> is
 1.13744 +      applied.</para>
 1.13745 +
 1.13746 +    <para id="x_417">As a shortcut, you can refer to a patch using both a name
 1.13747 +      and a numeric offset; <literal moreinfo="none">foo.patch-2</literal> means
 1.13748 +      <quote>two patches before <literal moreinfo="none">foo.patch</literal></quote>,
 1.13749 +      while <literal moreinfo="none">bar.patch+4</literal> means <quote>four patches
 1.13750 +	after <literal moreinfo="none">bar.patch</literal></quote>.</para>
 1.13751 +
 1.13752 +    <para id="x_418">Referring to a patch by index isn't much different.  The
 1.13753 +      first patch printed in the output of <command role="hg-ext-mq" moreinfo="none">qseries</command> is patch zero (yes, it's
 1.13754 +      one of those start-at-zero counting systems); the second is
 1.13755 +      patch one; and so on.</para>
 1.13756 +
 1.13757 +    <para id="x_419">MQ also makes it easy to work with patches when you are
 1.13758 +      using normal Mercurial commands.  Every command that accepts a
 1.13759 +      changeset ID will also accept the name of an applied patch.  MQ
 1.13760 +      augments the tags normally in the repository with an eponymous
 1.13761 +      one for each applied patch.  In addition, the special tags
 1.13762 +      <literal role="tag" moreinfo="none">qbase</literal> and
 1.13763 +      <literal role="tag" moreinfo="none">qtip</literal> identify
 1.13764 +      the <quote>bottom-most</quote> and topmost applied patches,
 1.13765 +      respectively.</para>
 1.13766 +
 1.13767 +    <para id="x_41a">These additions to Mercurial's normal tagging capabilities
 1.13768 +      make dealing with patches even more of a breeze.</para>
 1.13769 +    <itemizedlist>
 1.13770 +      <listitem><para id="x_41b">Want to patchbomb a mailing list with your
 1.13771 +	  latest series of changes?</para>
 1.13772 +	<programlisting format="linespecific">hg email qbase:qtip</programlisting>
 1.13773 +	<para id="x_41c">  (Don't know what <quote>patchbombing</quote> is?  See
 1.13774 +	  <xref linkend="sec:hgext:patchbomb"/>.)</para>
 1.13775 +      </listitem>
 1.13776 +      <listitem><para id="x_41d">Need to see all of the patches since
 1.13777 +	  <literal moreinfo="none">foo.patch</literal> that have touched files in a
 1.13778 +	  subdirectory of your tree?</para>
 1.13779 +	<programlisting format="linespecific">hg log -r foo.patch:qtip subdir</programlisting>
 1.13780 +      </listitem>
 1.13781 +    </itemizedlist>
 1.13782 +
 1.13783 +    <para id="x_41e">Because MQ makes the names of patches available to the rest
 1.13784 +      of Mercurial through its normal internal tag machinery, you
 1.13785 +      don't need to type in the entire name of a patch when you want
 1.13786 +      to identify it by name.</para>
 1.13787 +
 1.13788 +    <para id="x_41f">Another nice consequence of representing patch names as tags
 1.13789 +      is that when you run the <command role="hg-cmd" moreinfo="none">hg log</command>
 1.13790 +      command, it will display a patch's name as a tag, simply as part
 1.13791 +      of its normal output.  This makes it easy to visually
 1.13792 +      distinguish applied patches from underlying
 1.13793 +      <quote>normal</quote> revisions.  The following example shows a
 1.13794 +      few normal Mercurial commands in use with applied
 1.13795 +      patches.</para>
 1.13796 +
 1.13797 +    <!-- BEGIN mq.id.output -->
 1.13798 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qapplied</userinput>
 1.13799 +first.patch
 1.13800 +second.patch
 1.13801 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg log -r qbase:qtip</userinput>
 1.13802 +changeset:   1:c3bcf3b7335a
 1.13803 +tag:         first.patch
 1.13804 +tag:         qbase
 1.13805 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.13806 +date:        Sun Aug 16 14:05:08 2009 +0000
 1.13807 +summary:     [mq]: first.patch
 1.13808 +
 1.13809 +changeset:   2:d189ba63b5f7
 1.13810 +tag:         qtip
 1.13811 +tag:         second.patch
 1.13812 +tag:         tip
 1.13813 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.13814 +date:        Sun Aug 16 14:05:09 2009 +0000
 1.13815 +summary:     [mq]: second.patch
 1.13816 +
 1.13817 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg export second.patch</userinput>
 1.13818 +# HG changeset patch
 1.13819 +# User Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.13820 +# Date 1250431509 0
 1.13821 +# Node ID d189ba63b5f7427f9644663c01fc16fe80399c65
 1.13822 +# Parent  c3bcf3b7335afc0a250e85c51a1266d35d43a545
 1.13823 +[mq]: second.patch
 1.13824 +
 1.13825 +diff -r c3bcf3b7335a -r d189ba63b5f7 other.c
 1.13826 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 1.13827 ++++ b/other.c	Sun Aug 16 14:05:09 2009 +0000
 1.13828 +@@ -0,0 +1,1 @@
 1.13829 ++double u;
 1.13830 +</screen>
 1.13831 +<!-- END mq.id.output -->
 1.13832 +
 1.13833 +  </sect1>
 1.13834 +
 1.13835 +  <sect1>
 1.13836 +    <title>Useful things to know about</title>
 1.13837 +
 1.13838 +    <para id="x_420">There are a number of aspects of MQ usage that don't fit
 1.13839 +      tidily into sections of their own, but that are good to know.
 1.13840 +      Here they are, in one place.</para>
 1.13841 +
 1.13842 +    <itemizedlist>
 1.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
 1.13844 +	  that represents the patch after the pop/push will have a
 1.13845 +	  <emphasis>different identity</emphasis> than the changeset
 1.13846 +	  that represented the hash beforehand.  See <xref linkend="sec:mqref:cmd:qpush"/> for
 1.13847 +	  information as to why this is.</para>
 1.13848 +      </listitem>
 1.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
 1.13850 +	  branch with a patch changeset, at least if you want to
 1.13851 +	  maintain the <quote>patchiness</quote> of that changeset and
 1.13852 +	  changesets below it on the patch stack.  If you try to do
 1.13853 +	  this, it will appear to succeed, but MQ will become
 1.13854 +	  confused.</para>
 1.13855 +      </listitem></itemizedlist>
 1.13856 +  </sect1>
 1.13857 +
 1.13858 +  <sect1 id="sec:mq:repo">
 1.13859 +    <title>Managing patches in a repository</title>
 1.13860 +
 1.13861 +    <para id="x_423">Because MQ's <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory resides
 1.13862 +      outside a Mercurial repository's working directory, the
 1.13863 +      <quote>underlying</quote> Mercurial repository knows nothing
 1.13864 +      about the management or presence of patches.</para>
 1.13865 +
 1.13866 +    <para id="x_424">This presents the interesting possibility of managing the
 1.13867 +      contents of the patch directory as a Mercurial repository in its
 1.13868 +      own right.  This can be a useful way to work.  For example, you
 1.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
 1.13870 +      patch.  This lets you <quote>roll back</quote> to that version
 1.13871 +      of the patch later on.</para>
 1.13872 +
 1.13873 +    <para id="x_425">You can then share different versions of the same patch
 1.13874 +      stack among multiple underlying repositories.  I use this when I
 1.13875 +      am developing a Linux kernel feature.  I have a pristine copy of
 1.13876 +      my kernel sources for each of several CPU architectures, and a
 1.13877 +      cloned repository under each that contains the patches I am
 1.13878 +      working on.  When I want to test a change on a different
 1.13879 +      architecture, I push my current patches to the patch repository
 1.13880 +      associated with that kernel tree, pop and push all of my
 1.13881 +      patches, and build and test that kernel.</para>
 1.13882 +
 1.13883 +    <para id="x_426">Managing patches in a repository makes it possible for
 1.13884 +      multiple developers to work on the same patch series without
 1.13885 +      colliding with each other, all on top of an underlying source
 1.13886 +      base that they may or may not control.</para>
 1.13887 +
 1.13888 +    <sect2>
 1.13889 +      <title>MQ support for patch repositories</title>
 1.13890 +
 1.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
 1.13892 +	repository; when you prepare a repository for working with
 1.13893 +	patches using <command role="hg-ext-mq" moreinfo="none">qinit</command>, you
 1.13894 +	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
 1.13895 +	  -c</option> option to create the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory as a
 1.13896 +	Mercurial repository.</para>
 1.13897 +
 1.13898 +      <note>
 1.13899 +	<para id="x_428">  If you forget to use the <option role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
 1.13900 +	  can simply go into the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory at any
 1.13901 +	  time and run <command role="hg-cmd" moreinfo="none">hg init</command>.
 1.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>
 1.13903 +
 1.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>
 1.13905 +	  does this for you automatically); you
 1.13906 +	  <emphasis>really</emphasis> don't want to manage the
 1.13907 +	  <filename role="special" moreinfo="none">status</filename> file.</para>
 1.13908 +      </note>
 1.13909 +
 1.13910 +      <para id="x_42a">As a convenience, if MQ notices that the <filename class="directory" moreinfo="none">.hg/patches</filename> directory is a
 1.13911 +	repository, it will automatically <command role="hg-cmd" moreinfo="none">hg
 1.13912 +	  add</command> every patch that you create and import.</para>
 1.13913 +
 1.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>
 1.13915 +	directory.  This saves some bothersome typing.</para>
 1.13916 +
 1.13917 +      <para id="x_42c">Finally, as a convenience to manage the patch directory,
 1.13918 +	you can define the alias <command moreinfo="none">mq</command> on Unix
 1.13919 +	systems. For example, on Linux systems using the
 1.13920 +	<command moreinfo="none">bash</command> shell, you can include the following
 1.13921 +	snippet in your <filename role="home" moreinfo="none">~/.bashrc</filename>.</para>
 1.13922 +
 1.13923 +      <programlisting format="linespecific">alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
 1.13924 +
 1.13925 +      <para id="x_42d">You can then issue commands of the form <command moreinfo="none">mq
 1.13926 +	  pull</command> from the main repository.</para>
 1.13927 +    </sect2>
 1.13928 +
 1.13929 +    <sect2>
 1.13930 +      <title>A few things to watch out for</title>
 1.13931 +
 1.13932 +      <para id="x_42e">MQ's support for working with a repository full of patches
 1.13933 +	is limited in a few small respects.</para>
 1.13934 +
 1.13935 +      <para id="x_42f">MQ cannot automatically detect changes that you make to
 1.13936 +	the patch directory.  If you <command role="hg-cmd" moreinfo="none">hg
 1.13937 +	  pull</command>, manually edit, or <command role="hg-cmd" moreinfo="none">hg
 1.13938 +	  update</command> changes to patches or the <filename role="special" moreinfo="none">series</filename> file, you will have to
 1.13939 +	<command role="hg-cmd" moreinfo="none">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
 1.13940 +	then <command role="hg-cmd" moreinfo="none">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
 1.13941 +	the underlying repository to see those changes show up there.
 1.13942 +	If you forget to do this, you can confuse MQ's idea of which
 1.13943 +	patches are applied.</para>
 1.13944 +
 1.13945 +    </sect2>
 1.13946 +  </sect1>
 1.13947 +  <sect1 id="sec:mq:tools">
 1.13948 +    <title>Third party tools for working with patches</title>
 1.13949 +
 1.13950 +    <para id="x_430">Once you've been working with patches for a while, you'll
 1.13951 +      find yourself hungry for tools that will help you to understand
 1.13952 +      and manipulate the patches you're dealing with.</para>
 1.13953 +
 1.13954 +    <para id="x_431">The <command moreinfo="none">diffstat</command> command
 1.13955 +      <citation>web:diffstat</citation> generates a histogram of the
 1.13956 +      modifications made to each file in a patch.  It provides a good
 1.13957 +      way to <quote>get a sense of</quote> a patch—which files
 1.13958 +      it affects, and how much change it introduces to each file and
 1.13959 +      as a whole.  (I find that it's a good idea to use
 1.13960 +      <command moreinfo="none">diffstat</command>'s <option role="cmd-opt-diffstat">-p</option> option as a matter of
 1.13961 +      course, as otherwise it will try to do clever things with
 1.13962 +      prefixes of file names that inevitably confuse at least
 1.13963 +      me.)</para>
 1.13964 +
 1.13965 +<!-- BEGIN mq.tools.tools -->
 1.13966 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">diffstat -p1 remove-redundant-null-checks.patch</userinput>
 1.13967 + drivers/char/agp/sgi-agp.c        |    5 ++---
 1.13968 + drivers/char/hvcs.c               |   11 +++++------
 1.13969 + drivers/message/fusion/mptfc.c    |    6 ++----
 1.13970 + drivers/message/fusion/mptsas.c   |    3 +--
 1.13971 + drivers/net/fs_enet/fs_enet-mii.c |    3 +--
 1.13972 + drivers/net/wireless/ipw2200.c    |   22 ++++++----------------
 1.13973 + drivers/scsi/libata-scsi.c        |    4 +---
 1.13974 + drivers/video/au1100fb.c          |    3 +--
 1.13975 + 8 files changed, 19 insertions(+), 38 deletions(-)
 1.13976 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">filterdiff -i '*/video/*' remove-redundant-null-checks.patch</userinput>
 1.13977 +--- a/drivers/video/au1100fb.c~remove-redundant-null-checks-before-free-in-drivers
 1.13978 ++++ a/drivers/video/au1100fb.c
 1.13979 +@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void)
 1.13980 + {
 1.13981 + 	driver_unregister(&amp;au1100fb_driver);
 1.13982 + 
 1.13983 +-	if (drv_info.opt_mode)
 1.13984 +-		kfree(drv_info.opt_mode);
 1.13985 ++	kfree(drv_info.opt_mode);
 1.13986 + }
 1.13987 + 
 1.13988 + module_init(au1100fb_init);
 1.13989 +</screen>
 1.13990 +<!-- END mq.tools.tools -->
 1.13991 +
 1.13992 +
 1.13993 +    <para id="x_432">The <literal role="package" moreinfo="none">patchutils</literal> package
 1.13994 +      <citation>web:patchutils</citation> is invaluable. It provides a
 1.13995 +      set of small utilities that follow the <quote>Unix
 1.13996 +	philosophy;</quote> each does one useful thing with a patch.
 1.13997 +      The <literal role="package" moreinfo="none">patchutils</literal> command I use
 1.13998 +      most is <command moreinfo="none">filterdiff</command>, which extracts subsets
 1.13999 +      from a patch file.  For example, given a patch that modifies
 1.14000 +      hundreds of files across dozens of directories, a single
 1.14001 +      invocation of <command moreinfo="none">filterdiff</command> can generate a
 1.14002 +      smaller patch that only touches files whose names match a
 1.14003 +      particular glob pattern.  See <xref linkend="mq-collab:tips:interdiff"/> for another
 1.14004 +      example.</para>
 1.14005 +
 1.14006 +  </sect1>
 1.14007 +  <sect1>
 1.14008 +    <title>Good ways to work with patches</title>
 1.14009 +
 1.14010 +    <para id="x_433">Whether you are working on a patch series to submit to a
 1.14011 +      free software or open source project, or a series that you
 1.14012 +      intend to treat as a sequence of regular changesets when you're
 1.14013 +      done, you can use some simple techniques to keep your work well
 1.14014 +      organized.</para>
 1.14015 +
 1.14016 +    <para id="x_434">Give your patches descriptive names.  A good name for a
 1.14017 +      patch might be <filename moreinfo="none">rework-device-alloc.patch</filename>,
 1.14018 +      because it will immediately give you a hint what the purpose of
 1.14019 +      the patch is.  Long names shouldn't be a problem; you won't be
 1.14020 +      typing the names often, but you <emphasis>will</emphasis> be
 1.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
 1.14022 +      becomes especially important when you have a number of patches
 1.14023 +      to work with, or if you are juggling a number of different tasks
 1.14024 +      and your patches only get a fraction of your attention.</para>
 1.14025 +
 1.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
 1.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
 1.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
 1.14029 +      one I intended, and it's often tricky to migrate changes into
 1.14030 +      the right patch after making them in the wrong one.</para>
 1.14031 +
 1.14032 +    <para id="x_436">For this reason, it is very much worth investing a little
 1.14033 +      time to learn how to use some of the third-party tools I
 1.14034 +      described in <xref linkend="sec:mq:tools"/>,
 1.14035 +      particularly
 1.14036 +      <command moreinfo="none">diffstat</command> and <command moreinfo="none">filterdiff</command>.
 1.14037 +      The former will give you a quick idea of what changes your patch
 1.14038 +      is making, while the latter makes it easy to splice hunks
 1.14039 +      selectively out of one patch and into another.</para>
 1.14040 +
 1.14041 +  </sect1>
 1.14042 +  <sect1>
 1.14043 +    <title>MQ cookbook</title>
 1.14044 +
 1.14045 +    <sect2>
 1.14046 +      <title>Manage <quote>trivial</quote> patches</title>
 1.14047 +
 1.14048 +      <para id="x_437">Because the overhead of dropping files into a new
 1.14049 +	Mercurial repository is so low, it makes a lot of sense to
 1.14050 +	manage patches this way even if you simply want to make a few
 1.14051 +	changes to a source tarball that you downloaded.</para>
 1.14052 +
 1.14053 +      <para id="x_438">Begin by downloading and unpacking the source tarball, and
 1.14054 +	turning it into a Mercurial repository.</para>
 1.14055 +
 1.14056 +      <!-- BEGIN mq.tarball.download -->
 1.14057 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">download netplug-1.2.5.tar.bz2</userinput>
 1.14058 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">tar jxf netplug-1.2.5.tar.bz2</userinput>
 1.14059 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug-1.2.5</userinput>
 1.14060 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg init</userinput>
 1.14061 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit -q --addremove --message netplug-1.2.5</userinput>
 1.14062 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
 1.14063 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone netplug-1.2.5 netplug</userinput>
 1.14064 +updating working directory
 1.14065 +18 files updated, 0 files merged, 0 files removed, 0 files unresolved
 1.14066 +</screen>
 1.14067 +<!-- END mq.tarball.download -->
 1.14068 +
 1.14069 +
 1.14070 +      <para id="x_439">Continue by creating a patch stack and making your
 1.14071 +	changes.</para>
 1.14072 +
 1.14073 +      <!-- BEGIN mq.tarball.qinit -->
 1.14074 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug</userinput>
 1.14075 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 1.14076 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew -m 'fix build problem with gcc 4' build-fix.patch</userinput>
 1.14077 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">perl -pi -e 's/int addr_len/socklen_t addr_len/' netlink.c</userinput>
 1.14078 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.14079 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg tip -p</userinput>
 1.14080 +changeset:   1:eeab56666c54
 1.14081 +tag:         qtip
 1.14082 +tag:         build-fix.patch
 1.14083 +tag:         tip
 1.14084 +tag:         qbase
 1.14085 +user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
 1.14086 +date:        Sun Aug 16 14:05:10 2009 +0000
 1.14087 +summary:     fix build problem with gcc 4
 1.14088 +
 1.14089 +diff -r 1f6afe9a2d68 -r eeab56666c54 netlink.c
 1.14090 +--- a/netlink.c	Sun Aug 16 14:05:09 2009 +0000
 1.14091 ++++ b/netlink.c	Sun Aug 16 14:05:10 2009 +0000
 1.14092 +@@ -275,7 +275,7 @@
 1.14093 +         exit(1);
 1.14094 +     }
 1.14095 + 
 1.14096 +-    int addr_len = sizeof(addr);
 1.14097 ++    socklen_t addr_len = sizeof(addr);
 1.14098 + 
 1.14099 +     if (getsockname(fd, (struct sockaddr *) &amp;addr, &amp;addr_len) == -1) {
 1.14100 +         do_log(LOG_ERR, "Could not get socket details: %m");
 1.14101 +
 1.14102 +</screen>
 1.14103 +<!-- END mq.tarball.qinit -->
 1.14104 +
 1.14105 +
 1.14106 +      <para id="x_43a">Let's say a few weeks or months pass, and your package
 1.14107 +	author releases a new version.  First, bring their changes
 1.14108 +	into the repository.</para>
 1.14109 +
 1.14110 +      <!-- BEGIN mq.tarball.newsource -->
 1.14111 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 1.14112 +patch queue now empty
 1.14113 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
 1.14114 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">download netplug-1.2.8.tar.bz2</userinput>
 1.14115 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg clone netplug-1.2.5 netplug-1.2.8</userinput>
 1.14116 +updating working directory
 1.14117 +18 files updated, 0 files merged, 0 files removed, 0 files unresolved
 1.14118 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug-1.2.8</userinput>
 1.14119 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg locate -0 | xargs -0 rm</userinput>
 1.14120 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ..</userinput>
 1.14121 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">tar jxf netplug-1.2.8.tar.bz2</userinput>
 1.14122 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd netplug-1.2.8</userinput>
 1.14123 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg commit --addremove --message netplug-1.2.8</userinput>
 1.14124 +</screen>
 1.14125 +<!-- END mq.tarball.newsource -->
 1.14126 +
 1.14127 +
 1.14128 +      <para id="x_43b">The pipeline starting with <command role="hg-cmd" moreinfo="none">hg
 1.14129 +	  locate</command> above deletes all files in the working
 1.14130 +	directory, so that <command role="hg-cmd" moreinfo="none">hg
 1.14131 +	  commit</command>'s <option role="hg-opt-commit">--addremove</option> option can
 1.14132 +	actually tell which files have really been removed in the
 1.14133 +	newer version of the source.</para>
 1.14134 +
 1.14135 +      <para id="x_43c">Finally, you can apply your patches on top of the new
 1.14136 +	tree.</para>
 1.14137 +
 1.14138 +      <!-- BEGIN mq.tarball.repush -->
 1.14139 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cd ../netplug</userinput>
 1.14140 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg pull ../netplug-1.2.8</userinput>
 1.14141 +pulling from ../netplug-1.2.8
 1.14142 +searching for changes
 1.14143 +adding changesets
 1.14144 +adding manifests
 1.14145 +adding file changes
 1.14146 +added 1 changesets with 12 changes to 12 files
 1.14147 +(run 'hg update' to get a working copy)
 1.14148 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 1.14149 +(working directory not at tip)
 1.14150 +applying build-fix.patch
 1.14151 +now at: build-fix.patch
 1.14152 +</screen>
 1.14153 +<!-- END mq.tarball.repush -->
 1.14154 +
 1.14155 +    </sect2>
 1.14156 +
 1.14157 +    <sect2 id="sec:mq:combine">
 1.14158 +      <title>Combining entire patches</title>
 1.14159 +
 1.14160 +      <para id="x_43d">MQ provides a command, <command role="hg-ext-mq" moreinfo="none">qfold</command> that lets you combine
 1.14161 +	entire patches.  This <quote>folds</quote> the patches you
 1.14162 +	name, in the order you name them, into the topmost applied
 1.14163 +	patch, and concatenates their descriptions onto the end of its
 1.14164 +	description.  The patches that you fold must be unapplied
 1.14165 +	before you fold them.</para>
 1.14166 +
 1.14167 +      <para id="x_43e">The order in which you fold patches matters.  If your
 1.14168 +	topmost applied patch is <literal moreinfo="none">foo</literal>, and you
 1.14169 +	<command role="hg-ext-mq" moreinfo="none">qfold</command>
 1.14170 +	<literal moreinfo="none">bar</literal> and <literal moreinfo="none">quux</literal> into it,
 1.14171 +	you will end up with a patch that has the same effect as if
 1.14172 +	you applied first <literal moreinfo="none">foo</literal>, then
 1.14173 +	<literal moreinfo="none">bar</literal>, followed by
 1.14174 +	<literal moreinfo="none">quux</literal>.</para>
 1.14175 +    </sect2>
 1.14176 +
 1.14177 +    <sect2>
 1.14178 +      <title>Merging part of one patch into another</title>
 1.14179 +
 1.14180 +      <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into
 1.14181 +	another is more difficult than combining entire
 1.14182 +	patches.</para>
 1.14183 +
 1.14184 +      <para id="x_440">If you want to move changes to entire files, you can use
 1.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
 1.14186 +	modifications to snip out of one patch, concatenating its
 1.14187 +	output onto the end of the patch you want to merge into.  You
 1.14188 +	usually won't need to modify the patch you've merged the
 1.14189 +	changes from.  Instead, MQ will report some rejected hunks
 1.14190 +	when you <command role="hg-ext-mq" moreinfo="none">qpush</command> it (from
 1.14191 +	the hunks you moved into the other patch), and you can simply
 1.14192 +	<command role="hg-ext-mq" moreinfo="none">qrefresh</command> the patch to drop
 1.14193 +	the duplicate hunks.</para>
 1.14194 +
 1.14195 +      <para id="x_441">If you have a patch that has multiple hunks modifying a
 1.14196 +	file, and you only want to move a few of those hunks, the job
 1.14197 +	becomes more messy, but you can still partly automate it.  Use
 1.14198 +	<command moreinfo="none">lsdiff -nvv</command> to print some metadata about
 1.14199 +	the patch.</para>
 1.14200 +
 1.14201 +      <!-- BEGIN mq.tools.lsdiff -->
 1.14202 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">lsdiff -nvv remove-redundant-null-checks.patch</userinput>
 1.14203 +22	File #1  	a/drivers/char/agp/sgi-agp.c
 1.14204 +	24	Hunk #1	static int __devinit agp_sgi_init(void)
 1.14205 +37	File #2  	a/drivers/char/hvcs.c
 1.14206 +	39	Hunk #1	static struct tty_operations hvcs_ops = 
 1.14207 +	53	Hunk #2	static int hvcs_alloc_index_list(int n)
 1.14208 +69	File #3  	a/drivers/message/fusion/mptfc.c
 1.14209 +	71	Hunk #1	mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, in
 1.14210 +85	File #4  	a/drivers/message/fusion/mptsas.c
 1.14211 +	87	Hunk #1	mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
 1.14212 +98	File #5  	a/drivers/net/fs_enet/fs_enet-mii.c
 1.14213 +	100	Hunk #1	static struct fs_enet_mii_bus *create_bu
 1.14214 +111	File #6  	a/drivers/net/wireless/ipw2200.c
 1.14215 +	113	Hunk #1	static struct ipw_fw_error *ipw_alloc_er
 1.14216 +	126	Hunk #2	static ssize_t clear_error(struct device
 1.14217 +	140	Hunk #3	static void ipw_irq_tasklet(struct ipw_p
 1.14218 +	150	Hunk #4	static void ipw_pci_remove(struct pci_de
 1.14219 +164	File #7  	a/drivers/scsi/libata-scsi.c
 1.14220 +	166	Hunk #1	int ata_cmd_ioctl(struct scsi_device *sc
 1.14221 +178	File #8  	a/drivers/video/au1100fb.c
 1.14222 +	180	Hunk #1	void __exit au1100fb_cleanup(void)
 1.14223 +</screen>
 1.14224 +<!-- END mq.tools.lsdiff -->
 1.14225 +
 1.14226 +
 1.14227 +      <para id="x_442">This command prints three different kinds of
 1.14228 +	number:</para>
 1.14229 +      <itemizedlist>
 1.14230 +	<listitem><para id="x_443">(in the first column) a <emphasis>file
 1.14231 +	      number</emphasis> to identify each file modified in the
 1.14232 +	    patch;</para>
 1.14233 +	</listitem>
 1.14234 +	<listitem><para id="x_444">(on the next line, indented) the line number
 1.14235 +	    within a modified file where a hunk starts; and</para>
 1.14236 +	</listitem>
 1.14237 +	<listitem><para id="x_445">(on the same line) a <emphasis>hunk
 1.14238 +	      number</emphasis> to identify that hunk.</para>
 1.14239 +	</listitem></itemizedlist>
 1.14240 +
 1.14241 +      <para id="x_446">You'll have to use some visual inspection, and reading of
 1.14242 +	the patch, to identify the file and hunk numbers you'll want,
 1.14243 +	but you can then pass them to to
 1.14244 +	<command moreinfo="none">filterdiff</command>'s <option role="cmd-opt-filterdiff">--files</option> and <option role="cmd-opt-filterdiff">--hunks</option> options, to
 1.14245 +	select exactly the file and hunk you want to extract.</para>
 1.14246 +
 1.14247 +      <para id="x_447">Once you have this hunk, you can concatenate it onto the
 1.14248 +	end of your destination patch and continue with the remainder
 1.14249 +	of <xref linkend="sec:mq:combine"/>.</para>
 1.14250 +
 1.14251 +    </sect2>
 1.14252 +  </sect1>
 1.14253 +  <sect1>
 1.14254 +    <title>Differences between quilt and MQ</title>
 1.14255 +
 1.14256 +    <para id="x_448">If you are already familiar with quilt, MQ provides a
 1.14257 +      similar command set.  There are a few differences in the way
 1.14258 +      that it works.</para>
 1.14259 +
 1.14260 +    <para id="x_449">You will already have noticed that most quilt commands have
 1.14261 +      MQ counterparts that simply begin with a
 1.14262 +      <quote><literal moreinfo="none">q</literal></quote>.  The exceptions are quilt's
 1.14263 +      <literal moreinfo="none">add</literal> and <literal moreinfo="none">remove</literal> commands,
 1.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
 1.14265 +	remove</command> commands.  There is no MQ equivalent of the
 1.14266 +      quilt <literal moreinfo="none">edit</literal> command.</para>
 1.14267 +
 1.14268 +  </sect1>
 1.14269 +</chapter>
 1.14270 +
 1.14271 +<!--
 1.14272 +local variables: 
 1.14273 +sgml-parent-document: ("00book.xml" "book" "chapter")
 1.14274 +end:
 1.14275 +-->
 1.14276 +
 1.14277 +  <!-- BEGIN ch13 -->
 1.14278 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.14279 +
 1.14280 +<chapter id="chap:mq-collab">
 1.14281 +  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
 1.14282 +  <title>Advanced uses of Mercurial Queues</title>
 1.14283 +
 1.14284 +  <para id="x_15d">While it's easy to pick up straightforward uses of Mercurial
 1.14285 +    Queues, use of a little discipline and some of MQ's less
 1.14286 +    frequently used capabilities makes it possible to work in
 1.14287 +    complicated development environments.</para>
 1.14288 +
 1.14289 +  <para id="x_15e">In this chapter, I will use as an example a technique I have
 1.14290 +    used to manage the development of an Infiniband device driver for
 1.14291 +    the Linux kernel.  The driver in question is large (at least as
 1.14292 +    drivers go), with 25,000 lines of code spread across 35 source
 1.14293 +    files.  It is maintained by a small team of developers.</para>
 1.14294 +
 1.14295 +  <para id="x_15f">While much of the material in this chapter is specific to
 1.14296 +    Linux, the same principles apply to any code base for which you're
 1.14297 +    not the primary owner, and upon which you need to do a lot of
 1.14298 +    development.</para>
 1.14299 +
 1.14300 +  <sect1>
 1.14301 +    <title>The problem of many targets</title>
 1.14302 +
 1.14303 +    <para id="x_160">The Linux kernel changes rapidly, and has never been
 1.14304 +      internally stable; developers frequently make drastic changes
 1.14305 +      between releases. This means that a version of the driver that
 1.14306 +      works well with a particular released version of the kernel will
 1.14307 +      not even <emphasis>compile</emphasis> correctly against,
 1.14308 +      typically, any other version.</para>
 1.14309 +
 1.14310 +    <para id="x_161">To maintain a driver, we have to keep a number of distinct
 1.14311 +      versions of Linux in mind.</para>
 1.14312 +    <itemizedlist>
 1.14313 +      <listitem><para id="x_162">One target is the main Linux kernel development
 1.14314 +	  tree. Maintenance of the code is in this case partly shared
 1.14315 +	  by other developers in the kernel community, who make
 1.14316 +	  <quote>drive-by</quote> modifications to the driver as they
 1.14317 +	  develop and refine kernel subsystems.</para>
 1.14318 +      </listitem>
 1.14319 +      <listitem><para id="x_163">We also maintain a number of
 1.14320 +	  <quote>backports</quote> to older versions of the Linux
 1.14321 +	  kernel, to support the needs of customers who are running
 1.14322 +	  older Linux distributions that do not incorporate our
 1.14323 +	  drivers.  (To <emphasis>backport</emphasis> a piece of code
 1.14324 +	  is to modify it to work in an older version of its target
 1.14325 +	  environment than the version it was developed for.)</para>
 1.14326 +      </listitem>
 1.14327 +      <listitem><para id="x_164">Finally, we make software releases on a schedule
 1.14328 +	  that is necessarily not aligned with those used by Linux
 1.14329 +	  distributors and kernel developers, so that we can deliver
 1.14330 +	  new features to customers without forcing them to upgrade
 1.14331 +	  their entire kernels or distributions.</para>
 1.14332 +      </listitem></itemizedlist>
 1.14333 +
 1.14334 +    <sect2>
 1.14335 +      <title>Tempting approaches that don't work well</title>
 1.14336 +
 1.14337 +      <para id="x_165">There are two <quote>standard</quote> ways to maintain a
 1.14338 +	piece of software that has to target many different
 1.14339 +	environments.</para>
 1.14340 +
 1.14341 +      <para id="x_166">The first is to maintain a number of branches, each
 1.14342 +	intended for a single target.  The trouble with this approach
 1.14343 +	is that you must maintain iron discipline in the flow of
 1.14344 +	changes between repositories. A new feature or bug fix must
 1.14345 +	start life in a <quote>pristine</quote> repository, then
 1.14346 +	percolate out to every backport repository.  Backport changes
 1.14347 +	are more limited in the branches they should propagate to; a
 1.14348 +	backport change that is applied to a branch where it doesn't
 1.14349 +	belong will probably stop the driver from compiling.</para>
 1.14350 +
 1.14351 +      <para id="x_167">The second is to maintain a single source tree filled with
 1.14352 +	conditional statements that turn chunks of code on or off
 1.14353 +	depending on the intended target.  Because these
 1.14354 +	<quote>ifdefs</quote> are not allowed in the Linux kernel
 1.14355 +	tree, a manual or automatic process must be followed to strip
 1.14356 +	them out and yield a clean tree.  A code base maintained in
 1.14357 +	this fashion rapidly becomes a rat's nest of conditional
 1.14358 +	blocks that are difficult to understand and maintain.</para>
 1.14359 +
 1.14360 +      <para id="x_168">Neither of these approaches is well suited to a situation
 1.14361 +	where you don't <quote>own</quote> the canonical copy of a
 1.14362 +	source tree.  In the case of a Linux driver that is
 1.14363 +	distributed with the standard kernel, Linus's tree contains
 1.14364 +	the copy of the code that will be treated by the world as
 1.14365 +	canonical.  The upstream version of <quote>my</quote> driver
 1.14366 +	can be modified by people I don't know, without me even
 1.14367 +	finding out about it until after the changes show up in
 1.14368 +	Linus's tree.</para>
 1.14369 +
 1.14370 +      <para id="x_169">These approaches have the added weakness of making it
 1.14371 +	difficult to generate well-formed patches to submit
 1.14372 +	upstream.</para>
 1.14373 +
 1.14374 +      <para id="x_16a">In principle, Mercurial Queues seems like a good candidate
 1.14375 +	to manage a development scenario such as the above.  While
 1.14376 +	this is indeed the case, MQ contains a few added features that
 1.14377 +	make the job more pleasant.</para>
 1.14378 +
 1.14379 +    </sect2>
 1.14380 +  </sect1>
 1.14381 +  <sect1>
 1.14382 +    <title>Conditionally applying patches with guards</title>
 1.14383 +
 1.14384 +    <para id="x_16b">Perhaps the best way to maintain sanity with so many targets
 1.14385 +      is to be able to choose specific patches to apply for a given
 1.14386 +      situation.  MQ provides a feature called <quote>guards</quote>
 1.14387 +      (which originates with quilt's <literal moreinfo="none">guards</literal>
 1.14388 +      command) that does just this.  To start off, let's create a
 1.14389 +      simple repository for experimenting in.</para>
 1.14390 +
 1.14391 +    <!-- BEGIN mq.guards.init -->
 1.14392 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qinit</userinput>
 1.14393 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew hello.patch</userinput>
 1.14394 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo hello &gt; hello</userinput>
 1.14395 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add hello</userinput>
 1.14396 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.14397 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qnew goodbye.patch</userinput>
 1.14398 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo goodbye &gt; goodbye</userinput>
 1.14399 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg add goodbye</userinput>
 1.14400 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qrefresh</userinput>
 1.14401 +</screen>
 1.14402 +<!-- END mq.guards.init -->
 1.14403 +
 1.14404 +
 1.14405 +    <para id="x_16c">This gives us a tiny repository that contains two patches
 1.14406 +      that don't have any dependencies on each other, because they
 1.14407 +      touch different files.</para>
 1.14408 +
 1.14409 +    <para id="x_16d">The idea behind conditional application is that you can
 1.14410 +      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
 1.14411 +      which is simply a text string of your choosing, then tell MQ to
 1.14412 +      select specific guards to use when applying patches.  MQ will
 1.14413 +      then either apply, or skip over, a guarded patch, depending on
 1.14414 +      the guards that you have selected.</para>
 1.14415 +
 1.14416 +    <para id="x_16e">A patch can have an arbitrary number of guards; each one is
 1.14417 +      <emphasis>positive</emphasis> (<quote>apply this patch if this
 1.14418 +	guard is selected</quote>) or <emphasis>negative</emphasis>
 1.14419 +      (<quote>skip this patch if this guard is selected</quote>).  A
 1.14420 +      patch with no guards is always applied.</para>
 1.14421 +
 1.14422 +  </sect1>
 1.14423 +  <sect1>
 1.14424 +    <title>Controlling the guards on a patch</title>
 1.14425 +
 1.14426 +    <para id="x_16f">The <command role="hg-ext-mq" moreinfo="none">qguard</command> command lets
 1.14427 +      you determine which guards should apply to a patch, or display
 1.14428 +      the guards that are already in effect. Without any arguments, it
 1.14429 +      displays the guards on the current topmost patch.</para>
 1.14430 +
 1.14431 +      <!-- BEGIN mq.guards.qguard -->
 1.14432 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard</userinput>
 1.14433 +goodbye.patch: unguarded
 1.14434 +</screen>
 1.14435 +<!-- END mq.guards.qguard -->
 1.14436 +
 1.14437 +
 1.14438 +    <para id="x_170">To set a positive guard on a patch, prefix the name of the
 1.14439 +      guard with a <quote><literal moreinfo="none">+</literal></quote>.</para>
 1.14440 +
 1.14441 +      <!-- BEGIN mq.guards.qguard.pos -->
 1.14442 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard +foo</userinput>
 1.14443 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard</userinput>
 1.14444 +goodbye.patch: +foo
 1.14445 +</screen>
 1.14446 +<!-- END mq.guards.qguard.pos -->
 1.14447 +
 1.14448 +
 1.14449 +    <para id="x_171">To set a negative guard
 1.14450 +      on a patch, prefix the name of the guard with a
 1.14451 +      <quote><literal moreinfo="none">-</literal></quote>.</para>
 1.14452 +
 1.14453 +    <!-- BEGIN mq.guards.qguard.neg -->
 1.14454 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard -- hello.patch -quux</userinput>
 1.14455 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qguard hello.patch</userinput>
 1.14456 +hello.patch: -quux
 1.14457 +</screen>
 1.14458 +<!-- END mq.guards.qguard.neg -->
 1.14459 +
 1.14460 +
 1.14461 +    <para id="x_74a">Notice that we prefixed the arguments to the <command moreinfo="none">hg
 1.14462 +	qguard</command> command with a <literal moreinfo="none">--</literal> here, so
 1.14463 +      that Mercurial would not interpret the text
 1.14464 +      <literal moreinfo="none">-quux</literal> as an option.</para>
 1.14465 +
 1.14466 +    <note>
 1.14467 +      <title>Setting vs. modifying</title>
 1.14468 +
 1.14469 +      <para id="x_172">  The <command role="hg-ext-mq" moreinfo="none">qguard</command> command
 1.14470 +	<emphasis>sets</emphasis> the guards on a patch; it doesn't
 1.14471 +	<emphasis>modify</emphasis> them.  What this means is that if
 1.14472 +	you run <command role="hg-cmd" moreinfo="none">hg qguard +a +b</command> on a
 1.14473 +	patch, then <command role="hg-cmd" moreinfo="none">hg qguard +c</command> on
 1.14474 +	the same patch, the <emphasis>only</emphasis> guard that will
 1.14475 +	be set on it afterwards is <literal moreinfo="none">+c</literal>.</para>
 1.14476 +    </note>
 1.14477 +
 1.14478 +    <para id="x_173">Mercurial stores guards in the <filename role="special" moreinfo="none">series</filename> file; the form in which they
 1.14479 +      are stored is easy both to understand and to edit by hand. (In
 1.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
 1.14481 +      to; it's okay to simply edit the <filename role="special" moreinfo="none">series</filename> file.)</para>
 1.14482 +
 1.14483 +    <!-- BEGIN mq.guards.series -->
 1.14484 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/patches/series</userinput>
 1.14485 +hello.patch #-quux
 1.14486 +goodbye.patch #+foo
 1.14487 +</screen>
 1.14488 +<!-- END mq.guards.series -->
 1.14489 +
 1.14490 +
 1.14491 +  </sect1>
 1.14492 +  <sect1>
 1.14493 +    <title>Selecting the guards to use</title>
 1.14494 +
 1.14495 +    <para id="x_174">The <command role="hg-ext-mq" moreinfo="none">qselect</command> command
 1.14496 +      determines which guards are active at a given time.  The effect
 1.14497 +      of this is to determine which patches MQ will apply the next
 1.14498 +      time you run <command role="hg-ext-mq" moreinfo="none">qpush</command>.  It has
 1.14499 +      no other effect; in particular, it doesn't do anything to
 1.14500 +      patches that are already applied.</para>
 1.14501 +
 1.14502 +    <para id="x_175">With no arguments, the <command role="hg-ext-mq" moreinfo="none">qselect</command> command lists the guards
 1.14503 +      currently in effect, one per line of output.  Each argument is
 1.14504 +      treated as the name of a guard to apply.</para>
 1.14505 +
 1.14506 +      <!-- BEGIN mq.guards.qselect.foo -->
 1.14507 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 1.14508 +patch queue now empty
 1.14509 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect</userinput>
 1.14510 +no active guards
 1.14511 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect foo</userinput>
 1.14512 +number of unguarded, unapplied patches has changed from 1 to 2
 1.14513 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect</userinput>
 1.14514 +foo
 1.14515 +</screen>
 1.14516 +<!-- END mq.guards.qselect.foo -->
 1.14517 +
 1.14518 +
 1.14519 +    <para id="x_176">In case you're interested, the currently selected guards are
 1.14520 +      stored in the <filename role="special" moreinfo="none">guards</filename> file.</para>
 1.14521 +
 1.14522 +    <!-- BEGIN mq.guards.qselect.cat -->
 1.14523 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">cat .hg/patches/guards</userinput>
 1.14524 +foo
 1.14525 +</screen>
 1.14526 +<!-- END mq.guards.qselect.cat -->
 1.14527 +
 1.14528 +
 1.14529 +    <para id="x_177">We can see the effect the selected guards have when we run
 1.14530 +      <command role="hg-ext-mq" moreinfo="none">qpush</command>.</para>
 1.14531 +
 1.14532 +    <!-- BEGIN mq.guards.qselect.qpush -->
 1.14533 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 1.14534 +applying hello.patch
 1.14535 +applying goodbye.patch
 1.14536 +now at: goodbye.patch
 1.14537 +</screen>
 1.14538 +<!-- END mq.guards.qselect.qpush -->
 1.14539 +
 1.14540 +
 1.14541 +    <para id="x_178">A guard cannot start with a
 1.14542 +      <quote><literal moreinfo="none">+</literal></quote> or
 1.14543 +      <quote><literal moreinfo="none">-</literal></quote> character.  The name of a
 1.14544 +      guard must not contain white space, but most other characters
 1.14545 +      are acceptable.  If you try to use a guard with an invalid name,
 1.14546 +      MQ will complain:</para>
 1.14547 +
 1.14548 +    <!-- BEGIN mq.guards.qselect.error -->
 1.14549 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect +foo</userinput>
 1.14550 +abort: guard '+foo' starts with invalid character: '+'
 1.14551 +</screen>
 1.14552 +<!-- END mq.guards.qselect.error -->
 1.14553 +
 1.14554 +      
 1.14555 +    <para id="x_179">Changing the selected guards changes the patches that are
 1.14556 +      applied.</para>
 1.14557 +
 1.14558 +    <!-- BEGIN mq.guards.qselect.quux -->
 1.14559 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect quux</userinput>
 1.14560 +number of guarded, applied patches has changed from 0 to 2
 1.14561 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 1.14562 +patch queue now empty
 1.14563 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 1.14564 +patch series already fully applied
 1.14565 +</screen>
 1.14566 +<!-- END mq.guards.qselect.quux -->
 1.14567 +
 1.14568 +
 1.14569 +    <para id="x_17a">You can see in the example below that negative guards take
 1.14570 +      precedence over positive guards.</para>
 1.14571 +
 1.14572 +    <!-- BEGIN mq.guards.qselect.foobar -->
 1.14573 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qselect foo bar</userinput>
 1.14574 +number of unguarded, unapplied patches has changed from 0 to 2
 1.14575 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpop -a</userinput>
 1.14576 +no patches applied
 1.14577 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg qpush -a</userinput>
 1.14578 +applying hello.patch
 1.14579 +applying goodbye.patch
 1.14580 +now at: goodbye.patch
 1.14581 +</screen>
 1.14582 +<!-- END mq.guards.qselect.foobar -->
 1.14583 +
 1.14584 +
 1.14585 +  </sect1>
 1.14586 +  <sect1>
 1.14587 +    <title>MQ's rules for applying patches</title>
 1.14588 +
 1.14589 +    <para id="x_17b">The rules that MQ uses when deciding whether to apply a
 1.14590 +      patch are as follows.</para>
 1.14591 +    <itemizedlist>
 1.14592 +      <listitem><para id="x_17c">A patch that has no guards is always
 1.14593 +	  applied.</para>
 1.14594 +      </listitem>
 1.14595 +      <listitem><para id="x_17d">If the patch has any negative guard that matches
 1.14596 +	  any currently selected guard, the patch is skipped.</para>
 1.14597 +      </listitem>
 1.14598 +      <listitem><para id="x_17e">If the patch has any positive guard that matches
 1.14599 +	  any currently selected guard, the patch is applied.</para>
 1.14600 +      </listitem>
 1.14601 +      <listitem><para id="x_17f">If the patch has positive or negative guards,
 1.14602 +	  but none matches any currently selected guard, the patch is
 1.14603 +	  skipped.</para>
 1.14604 +      </listitem></itemizedlist>
 1.14605 +
 1.14606 +  </sect1>
 1.14607 +  <sect1>
 1.14608 +    <title>Trimming the work environment</title>
 1.14609 +
 1.14610 +    <para id="x_180">In working on the device driver I mentioned earlier, I don't
 1.14611 +      apply the patches to a normal Linux kernel tree.  Instead, I use
 1.14612 +      a repository that contains only a snapshot of the source files
 1.14613 +      and headers that are relevant to Infiniband development.  This
 1.14614 +      repository is 1% the size of a kernel repository, so it's easier
 1.14615 +      to work with.</para>
 1.14616 +
 1.14617 +    <para id="x_181">I then choose a <quote>base</quote> version on top of which
 1.14618 +      the patches are applied.  This is a snapshot of the Linux kernel
 1.14619 +      tree as of a revision of my choosing.  When I take the snapshot,
 1.14620 +      I record the changeset ID from the kernel repository in the
 1.14621 +      commit message.  Since the snapshot preserves the
 1.14622 +      <quote>shape</quote> and content of the relevant parts of the
 1.14623 +      kernel tree, I can apply my patches on top of either my tiny
 1.14624 +      repository or a normal kernel tree.</para>
 1.14625 +
 1.14626 +    <para id="x_182">Normally, the base tree atop which the patches apply should
 1.14627 +      be a snapshot of a very recent upstream tree.  This best
 1.14628 +      facilitates the development of patches that can easily be
 1.14629 +      submitted upstream with few or no modifications.</para>
 1.14630 +
 1.14631 +  </sect1>
 1.14632 +  <sect1>
 1.14633 +    <title>Dividing up the <filename role="special" moreinfo="none">series</filename>
 1.14634 +      file</title>
 1.14635 +
 1.14636 +    <para id="x_183">I categorise the patches in the <filename role="special" moreinfo="none">series</filename> file into a number of logical
 1.14637 +      groups.  Each section of like patches begins with a block of
 1.14638 +      comments that describes the purpose of the patches that
 1.14639 +      follow.</para>
 1.14640 +
 1.14641 +    <para id="x_184">The sequence of patch groups that I maintain follows.  The
 1.14642 +      ordering of these groups is important; I'll describe why after I
 1.14643 +      introduce the groups.</para>
 1.14644 +    <itemizedlist>
 1.14645 +      <listitem><para id="x_185">The <quote>accepted</quote> group.  Patches that
 1.14646 +	  the development team has submitted to the maintainer of the
 1.14647 +	  Infiniband subsystem, and which he has accepted, but which
 1.14648 +	  are not present in the snapshot that the tiny repository is
 1.14649 +	  based on.  These are <quote>read only</quote> patches,
 1.14650 +	  present only to transform the tree into a similar state as
 1.14651 +	  it is in the upstream maintainer's repository.</para>
 1.14652 +      </listitem>
 1.14653 +      <listitem><para id="x_186">The <quote>rework</quote> group.  Patches that I
 1.14654 +	  have submitted, but that the upstream maintainer has
 1.14655 +	  requested modifications to before he will accept
 1.14656 +	  them.</para>
 1.14657 +      </listitem>
 1.14658 +      <listitem><para id="x_187">The <quote>pending</quote> group.  Patches that
 1.14659 +	  I have not yet submitted to the upstream maintainer, but
 1.14660 +	  which we have finished working on. These will be <quote>read
 1.14661 +	    only</quote> for a while.  If the upstream maintainer
 1.14662 +	  accepts them upon submission, I'll move them to the end of
 1.14663 +	  the <quote>accepted</quote> group.  If he requests that I
 1.14664 +	  modify any, I'll move them to the beginning of the
 1.14665 +	  <quote>rework</quote> group.</para>
 1.14666 +      </listitem>
 1.14667 +      <listitem><para id="x_188">The <quote>in progress</quote> group.  Patches
 1.14668 +	  that are actively being developed, and should not be
 1.14669 +	  submitted anywhere yet.</para>
 1.14670 +      </listitem>
 1.14671 +      <listitem><para id="x_189">The <quote>backport</quote> group.  Patches that
 1.14672 +	  adapt the source tree to older versions of the kernel
 1.14673 +	  tree.</para>
 1.14674 +      </listitem>
 1.14675 +      <listitem><para id="x_18a">The <quote>do not ship</quote> group.  Patches
 1.14676 +	  that for some reason should never be submitted upstream.
 1.14677 +	  For example, one such patch might change embedded driver
 1.14678 +	  identification strings to make it easier to distinguish, in
 1.14679 +	  the field, between an out-of-tree version of the driver and
 1.14680 +	  a version shipped by a distribution vendor.</para>
 1.14681 +      </listitem></itemizedlist>
 1.14682 +
 1.14683 +    <para id="x_18b">Now to return to the reasons for ordering groups of patches
 1.14684 +      in this way.  We would like the lowest patches in the stack to
 1.14685 +      be as stable as possible, so that we will not need to rework
 1.14686 +      higher patches due to changes in context.  Putting patches that
 1.14687 +      will never be changed first in the <filename role="special" moreinfo="none">series</filename> file serves this
 1.14688 +      purpose.</para>
 1.14689 +
 1.14690 +    <para id="x_18c">We would also like the patches that we know we'll need to
 1.14691 +      modify to be applied on top of a source tree that resembles the
 1.14692 +      upstream tree as closely as possible.  This is why we keep
 1.14693 +      accepted patches around for a while.</para>
 1.14694 +
 1.14695 +    <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote>
 1.14696 +      patches float at the end of the <filename role="special" moreinfo="none">series</filename> file.  The backport patches
 1.14697 +      must be applied on top of all other patches, and the <quote>do
 1.14698 +	not ship</quote> patches might as well stay out of harm's
 1.14699 +      way.</para>
 1.14700 +
 1.14701 +  </sect1>
 1.14702 +  <sect1>
 1.14703 +    <title>Maintaining the patch series</title>
 1.14704 +
 1.14705 +    <para id="x_18e">In my work, I use a number of guards to control which
 1.14706 +      patches are to be applied.</para>
 1.14707 +
 1.14708 +    <itemizedlist>
 1.14709 +      <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with
 1.14710 +	  <literal moreinfo="none">accepted</literal>.  I enable this guard most of
 1.14711 +	  the time.  When I'm applying the patches on top of a tree
 1.14712 +	  where the patches are already present, I can turn this patch
 1.14713 +	  off, and the patches that follow it will apply
 1.14714 +	  cleanly.</para>
 1.14715 +      </listitem>
 1.14716 +      <listitem><para id="x_190">Patches that are <quote>finished</quote>, but
 1.14717 +	  not yet submitted, have no guards.  If I'm applying the
 1.14718 +	  patch stack to a copy of the upstream tree, I don't need to
 1.14719 +	  enable any guards in order to get a reasonably safe source
 1.14720 +	  tree.</para>
 1.14721 +      </listitem>
 1.14722 +      <listitem><para id="x_191">Those patches that need reworking before being
 1.14723 +	  resubmitted are guarded with
 1.14724 +	  <literal moreinfo="none">rework</literal>.</para>
 1.14725 +      </listitem>
 1.14726 +      <listitem><para id="x_192">For those patches that are still under
 1.14727 +	  development, I use <literal moreinfo="none">devel</literal>.</para>
 1.14728 +      </listitem>
 1.14729 +      <listitem><para id="x_193">A backport patch may have several guards, one
 1.14730 +	  for each version of the kernel to which it applies.  For
 1.14731 +	  example, a patch that backports a piece of code to 2.6.9
 1.14732 +	  will have a <literal moreinfo="none">2.6.9</literal> guard.</para>
 1.14733 +      </listitem></itemizedlist>
 1.14734 +    <para id="x_194">This variety of guards gives me considerable flexibility in
 1.14735 +      determining what kind of source tree I want to end up with.  For
 1.14736 +      most situations, the selection of appropriate guards is
 1.14737 +      automated during the build process, but I can manually tune the
 1.14738 +      guards to use for less common circumstances.</para>
 1.14739 +
 1.14740 +    <sect2>
 1.14741 +      <title>The art of writing backport patches</title>
 1.14742 +
 1.14743 +      <para id="x_195">Using MQ, writing a backport patch is a simple process.
 1.14744 +	All such a patch has to do is modify a piece of code that uses
 1.14745 +	a kernel feature not present in the older version of the
 1.14746 +	kernel, so that the driver continues to work correctly under
 1.14747 +	that older version.</para>
 1.14748 +
 1.14749 +      <para id="x_196">A useful goal when writing a good backport patch is to
 1.14750 +	make your code look as if it was written for the older version
 1.14751 +	of the kernel you're targeting.  The less obtrusive the patch,
 1.14752 +	the easier it will be to understand and maintain.  If you're
 1.14753 +	writing a collection of backport patches to avoid the
 1.14754 +	<quote>rat's nest</quote> effect of lots of
 1.14755 +	<literal moreinfo="none">#ifdef</literal>s (hunks of source code that are only
 1.14756 +	used conditionally) in your code, don't introduce
 1.14757 +	version-dependent <literal moreinfo="none">#ifdef</literal>s into the patches.
 1.14758 +	Instead, write several patches, each of which makes
 1.14759 +	unconditional changes, and control their application using
 1.14760 +	guards.</para>
 1.14761 +
 1.14762 +      <para id="x_197">There are two reasons to divide backport patches into a
 1.14763 +	distinct group, away from the <quote>regular</quote> patches
 1.14764 +	whose effects they modify. The first is that intermingling the
 1.14765 +	two makes it more difficult to use a tool like the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension to automate the
 1.14766 +	process of submitting the patches to an upstream maintainer.
 1.14767 +	The second is that a backport patch could perturb the context
 1.14768 +	in which a subsequent regular patch is applied, making it
 1.14769 +	impossible to apply the regular patch cleanly
 1.14770 +	<emphasis>without</emphasis> the earlier backport patch
 1.14771 +	already being applied.</para>
 1.14772 +
 1.14773 +    </sect2>
 1.14774 +  </sect1>
 1.14775 +  <sect1>
 1.14776 +    <title>Useful tips for developing with MQ</title>
 1.14777 +
 1.14778 +    <sect2>
 1.14779 +      <title>Organising patches in directories</title>
 1.14780 +
 1.14781 +      <para id="x_198">If you're working on a substantial project with MQ, it's
 1.14782 +	not difficult to accumulate a large number of patches.  For
 1.14783 +	example, I have one patch repository that contains over 250
 1.14784 +	patches.</para>
 1.14785 +
 1.14786 +      <para id="x_199">If you can group these patches into separate logical
 1.14787 +	categories, you can if you like store them in different
 1.14788 +	directories; MQ has no problems with patch names that contain
 1.14789 +	path separators.</para>
 1.14790 +
 1.14791 +    </sect2>
 1.14792 +    <sect2 id="mq-collab:tips:interdiff">
 1.14793 +      <title>Viewing the history of a patch</title>
 1.14794 +
 1.14795 +      <para id="x_19a">If you're developing a set of patches over a long time,
 1.14796 +	it's a good idea to maintain them in a repository, as
 1.14797 +	discussed in <xref linkend="sec:mq:repo"/>.  If you do
 1.14798 +	so, you'll quickly
 1.14799 +	discover that using the <command role="hg-cmd" moreinfo="none">hg
 1.14800 +	  diff</command> command to look at the history of changes to
 1.14801 +	a patch is unworkable.  This is in part because you're looking
 1.14802 +	at the second derivative of the real code (a diff of a diff),
 1.14803 +	but also because MQ adds noise to the process by modifying
 1.14804 +	time stamps and directory names when it updates a
 1.14805 +	patch.</para>
 1.14806 +
 1.14807 +      <para id="x_19b">However, you can use the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension, which is bundled
 1.14808 +	with Mercurial, to turn a diff of two versions of a patch into
 1.14809 +	something readable.  To do this, you will need a third-party
 1.14810 +	package called <literal role="package" moreinfo="none">patchutils</literal>
 1.14811 +	<citation>web:patchutils</citation>.  This provides a command
 1.14812 +	named <command moreinfo="none">interdiff</command>, which shows the
 1.14813 +	differences between two diffs as a diff.  Used on two versions
 1.14814 +	of the same diff, it generates a diff that represents the diff
 1.14815 +	from the first to the second version.</para>
 1.14816 +
 1.14817 +      <para id="x_19c">You can enable the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension in the usual way,
 1.14818 +	by adding a line to the <literal role="rc-extensions" moreinfo="none">extensions</literal> section of your
 1.14819 +	<filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
 1.14820 +      <programlisting format="linespecific">[extensions]
 1.14821 +extdiff =</programlisting>
 1.14822 +      <para id="x_19d">The <command moreinfo="none">interdiff</command> command expects to be
 1.14823 +	passed the names of two files, but the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension passes the program
 1.14824 +	it runs a pair of directories, each of which can contain an
 1.14825 +	arbitrary number of files.  We thus need a small program that
 1.14826 +	will run <command moreinfo="none">interdiff</command> on each pair of files in
 1.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
 1.14828 +	source code repository that accompanies this book. <!--
 1.14829 +	&example.hg-interdiff; --></para>
 1.14830 +
 1.14831 +      <para id="x_19e">With the <filename role="special" moreinfo="none">hg-interdiff</filename>
 1.14832 +	program in your shell's search path, you can run it as
 1.14833 +	follows, from inside an MQ patch directory:</para>
 1.14834 +      <programlisting format="linespecific">hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
 1.14835 +      <para id="x_19f">Since you'll probably want to use this long-winded command
 1.14836 +	a lot, you can get <literal role="hg-ext" moreinfo="none">hgext</literal> to
 1.14837 +	make it available as a normal Mercurial command, again by
 1.14838 +	editing your <filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
 1.14839 +      <programlisting format="linespecific">[extdiff]
 1.14840 +cmd.interdiff = hg-interdiff</programlisting>
 1.14841 +      <para id="x_1a0">This directs <literal role="hg-ext" moreinfo="none">hgext</literal> to
 1.14842 +	make an <literal moreinfo="none">interdiff</literal> command available, so you
 1.14843 +	can now shorten the previous invocation of <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> to something a
 1.14844 +	little more wieldy.</para>
 1.14845 +      <programlisting format="linespecific">hg interdiff -r A:B my-change.patch</programlisting>
 1.14846 +
 1.14847 +      <note>
 1.14848 +	<para id="x_1a1">  The <command moreinfo="none">interdiff</command> command works well
 1.14849 +	  only if the underlying files against which versions of a
 1.14850 +	  patch are generated remain the same.  If you create a patch,
 1.14851 +	  modify the underlying files, and then regenerate the patch,
 1.14852 +	  <command moreinfo="none">interdiff</command> may not produce useful
 1.14853 +	  output.</para>
 1.14854 +      </note>
 1.14855 +
 1.14856 +      <para id="x_1a2">The <literal role="hg-ext" moreinfo="none">extdiff</literal> extension is
 1.14857 +	useful for more than merely improving the presentation of MQ
 1.14858 +	patches.  To read more about it, go to <xref linkend="sec:hgext:extdiff"/>.</para>
 1.14859 +
 1.14860 +    </sect2>
 1.14861 +  </sect1>
 1.14862 +</chapter>
 1.14863 +
 1.14864 +<!--
 1.14865 +local variables: 
 1.14866 +sgml-parent-document: ("00book.xml" "book" "chapter")
 1.14867 +end:
 1.14868 +-->
 1.14869 +
 1.14870 +  <!-- BEGIN ch14 -->
 1.14871 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.14872 +
 1.14873 +<chapter id="chap:hgext">
 1.14874 +  <?dbhtml filename="adding-functionality-with-extensions.html"?>
 1.14875 +  <title>Adding functionality with extensions</title>
 1.14876 +
 1.14877 +  <para id="x_4fe">While the core of Mercurial is quite complete from a
 1.14878 +    functionality standpoint, it's deliberately shorn of fancy
 1.14879 +    features.  This approach of preserving simplicity keeps the
 1.14880 +    software easy to deal with for both maintainers and users.</para>
 1.14881 +
 1.14882 +  <para id="x_4ff">However, Mercurial doesn't box you in with an inflexible
 1.14883 +    command set: you can add features to it as
 1.14884 +    <emphasis>extensions</emphasis> (sometimes known as
 1.14885 +    <emphasis>plugins</emphasis>).  We've already discussed a few of
 1.14886 +    these extensions in earlier chapters.</para>
 1.14887 +  <itemizedlist>
 1.14888 +    <listitem><para id="x_500"><xref linkend="sec:tour-merge:fetch"/>
 1.14889 +	covers the <literal role="hg-ext" moreinfo="none">fetch</literal> extension;
 1.14890 +	this combines pulling new changes and merging them with local
 1.14891 +	changes into a single command, <command role="hg-ext-fetch" moreinfo="none">fetch</command>.</para>
 1.14892 +    </listitem>
 1.14893 +    <listitem><para id="x_501">In <xref linkend="chap:hook"/>, we covered
 1.14894 +	several extensions that are useful for hook-related
 1.14895 +	functionality: <literal role="hg-ext" moreinfo="none">acl</literal> adds
 1.14896 +	access control lists; <literal role="hg-ext" moreinfo="none">bugzilla</literal> adds integration with the
 1.14897 +	Bugzilla bug tracking system; and <literal role="hg-ext" moreinfo="none">notify</literal> sends notification emails on
 1.14898 +	new changes.</para>
 1.14899 +    </listitem>
 1.14900 +    <listitem><para id="x_502">The Mercurial Queues patch management extension is
 1.14901 +	so invaluable that it merits two chapters and an appendix all
 1.14902 +	to itself. <xref linkend="chap:mq"/> covers the
 1.14903 +	basics; <xref linkend="chap:mq-collab"/> discusses advanced topics;
 1.14904 +	and <xref linkend="chap:mqref"/> goes into detail on
 1.14905 +	each
 1.14906 +	command.</para>
 1.14907 +    </listitem></itemizedlist>
 1.14908 +
 1.14909 +  <para id="x_503">In this chapter, we'll cover some of the other extensions that
 1.14910 +    are available for Mercurial, and briefly touch on some of the
 1.14911 +    machinery you'll need to know about if you want to write an
 1.14912 +    extension of your own.</para>
 1.14913 +  <itemizedlist>
 1.14914 +    <listitem><para id="x_504">In <xref linkend="sec:hgext:inotify"/>,
 1.14915 +	we'll discuss the possibility of <emphasis>huge</emphasis>
 1.14916 +	performance improvements using the <literal role="hg-ext" moreinfo="none">inotify</literal> extension.</para>
 1.14917 +    </listitem></itemizedlist>
 1.14918 +
 1.14919 +  <sect1 id="sec:hgext:inotify">
 1.14920 +    <title>Improve performance with the <literal role="hg-ext" moreinfo="none">inotify</literal> extension</title>
 1.14921 +
 1.14922 +    <para id="x_505">Are you interested in having some of the most common
 1.14923 +      Mercurial operations run as much as a hundred times faster?
 1.14924 +      Read on!</para>
 1.14925 +
 1.14926 +    <para id="x_506">Mercurial has great performance under normal circumstances.
 1.14927 +      For example, when you run the <command role="hg-cmd" moreinfo="none">hg
 1.14928 +	status</command> command, Mercurial has to scan almost every
 1.14929 +      directory and file in your repository so that it can display
 1.14930 +      file status.  Many other Mercurial commands need to do the same
 1.14931 +      work behind the scenes; for example, the <command role="hg-cmd" moreinfo="none">hg diff</command> command uses the status
 1.14932 +      machinery to avoid doing an expensive comparison operation on
 1.14933 +      files that obviously haven't changed.</para>
 1.14934 +
 1.14935 +    <para id="x_507">Because obtaining file status is crucial to good
 1.14936 +      performance, the authors of Mercurial have optimised this code
 1.14937 +      to within an inch of its life.  However, there's no avoiding the
 1.14938 +      fact that when you run <command role="hg-cmd" moreinfo="none">hg
 1.14939 +	status</command>, Mercurial is going to have to perform at
 1.14940 +      least one expensive system call for each managed file to
 1.14941 +      determine whether it's changed since the last time Mercurial
 1.14942 +      checked.  For a sufficiently large repository, this can take a
 1.14943 +      long time.</para>
 1.14944 +
 1.14945 +    <para id="x_508">To put a number on the magnitude of this effect, I created a
 1.14946 +      repository containing 150,000 managed files.  I timed <command role="hg-cmd" moreinfo="none">hg status</command> as taking ten seconds to
 1.14947 +      run, even when <emphasis>none</emphasis> of those files had been
 1.14948 +      modified.</para>
 1.14949 +
 1.14950 +    <para id="x_509">Many modern operating systems contain a file notification
 1.14951 +      facility. If a program signs up to an appropriate service, the
 1.14952 +      operating system will notify it every time a file of interest is
 1.14953 +      created, modified, or deleted.  On Linux systems, the kernel
 1.14954 +      component that does this is called
 1.14955 +      <literal moreinfo="none">inotify</literal>.</para>
 1.14956 +
 1.14957 +    <para id="x_50a">Mercurial's <literal role="hg-ext" moreinfo="none">inotify</literal>
 1.14958 +      extension talks to the kernel's <literal moreinfo="none">inotify</literal>
 1.14959 +      component to optimise <command role="hg-cmd" moreinfo="none">hg status</command>
 1.14960 +      commands.  The extension has two components.  A daemon sits in
 1.14961 +      the background and receives notifications from the
 1.14962 +      <literal moreinfo="none">inotify</literal> subsystem.  It also listens for
 1.14963 +      connections from a regular Mercurial command.  The extension
 1.14964 +      modifies Mercurial's behavior so that instead of scanning the
 1.14965 +      filesystem, it queries the daemon.  Since the daemon has perfect
 1.14966 +      information about the state of the repository, it can respond
 1.14967 +      with a result instantaneously, avoiding the need to scan every
 1.14968 +      directory and file in the repository.</para>
 1.14969 +
 1.14970 +    <para id="x_50b">Recall the ten seconds that I measured plain Mercurial as
 1.14971 +      taking to run <command role="hg-cmd" moreinfo="none">hg status</command> on a
 1.14972 +      150,000 file repository.  With the <literal role="hg-ext" moreinfo="none">inotify</literal> extension enabled, the time
 1.14973 +      dropped to 0.1 seconds, a factor of <emphasis>one
 1.14974 +	hundred</emphasis> faster.</para>
 1.14975 +
 1.14976 +    <para id="x_50c">Before we continue, please pay attention to some
 1.14977 +      caveats.</para>
 1.14978 +    <itemizedlist>
 1.14979 +      <listitem><para id="x_50d">The <literal role="hg-ext" moreinfo="none">inotify</literal>
 1.14980 +	  extension is Linux-specific.  Because it interfaces directly
 1.14981 +	  to the Linux kernel's <literal moreinfo="none">inotify</literal> subsystem,
 1.14982 +	  it does not work on other operating systems.</para>
 1.14983 +      </listitem>
 1.14984 +      <listitem><para id="x_50e">It should work on any Linux distribution that
 1.14985 +	  was released after early 2005.  Older distributions are
 1.14986 +	  likely to have a kernel that lacks
 1.14987 +	  <literal moreinfo="none">inotify</literal>, or a version of
 1.14988 +	  <literal moreinfo="none">glibc</literal> that does not have the necessary
 1.14989 +	  interfacing support.</para>
 1.14990 +      </listitem>
 1.14991 +      <listitem><para id="x_50f">Not all filesystems are suitable for use with
 1.14992 +	  the <literal role="hg-ext" moreinfo="none">inotify</literal> extension.
 1.14993 +	  Network filesystems such as NFS are a non-starter, for
 1.14994 +	  example, particularly if you're running Mercurial on several
 1.14995 +	  systems, all mounting the same network filesystem.  The
 1.14996 +	  kernel's <literal moreinfo="none">inotify</literal> system has no way of
 1.14997 +	  knowing about changes made on another system.  Most local
 1.14998 +	  filesystems (e.g. ext3, XFS, ReiserFS) should work
 1.14999 +	  fine.</para>
 1.15000 +      </listitem></itemizedlist>
 1.15001 +
 1.15002 +    <para id="x_510">The <literal role="hg-ext" moreinfo="none">inotify</literal> extension is
 1.15003 +      not yet shipped with Mercurial as of May 2007, so it's a little
 1.15004 +      more involved to set up than other extensions.  But the
 1.15005 +      performance improvement is worth it!</para>
 1.15006 +
 1.15007 +    <para id="x_511">The extension currently comes in two parts: a set of patches
 1.15008 +      to the Mercurial source code, and a library of Python bindings
 1.15009 +      to the <literal moreinfo="none">inotify</literal> subsystem.</para>
 1.15010 +    <note>
 1.15011 +      <para id="x_512">  There are <emphasis>two</emphasis> Python
 1.15012 +	<literal moreinfo="none">inotify</literal> binding libraries.  One of them is
 1.15013 +	called <literal moreinfo="none">pyinotify</literal>, and is packaged by some
 1.15014 +	Linux distributions as <literal moreinfo="none">python-inotify</literal>.
 1.15015 +	This is <emphasis>not</emphasis> the one you'll need, as it is
 1.15016 +	too buggy and inefficient to be practical.</para>
 1.15017 +    </note>
 1.15018 +    <para id="x_513">To get going, it's best to already have a functioning copy
 1.15019 +      of Mercurial installed.</para>
 1.15020 +    <note>
 1.15021 +      <para id="x_514">  If you follow the instructions below, you'll be
 1.15022 +	<emphasis>replacing</emphasis> and overwriting any existing
 1.15023 +	installation of Mercurial that you might already have, using
 1.15024 +	the latest <quote>bleeding edge</quote> Mercurial code. Don't
 1.15025 +	say you weren't warned!</para>
 1.15026 +    </note>
 1.15027 +    <orderedlist inheritnum="ignore" continuation="restarts">
 1.15028 +      <listitem><para id="x_515">Clone the Python <literal moreinfo="none">inotify</literal>
 1.15029 +	  binding repository.  Build and install it.</para>
 1.15030 +	<programlisting format="linespecific">hg clone http://hg.kublai.com/python/inotify
 1.15031 +cd inotify
 1.15032 +python setup.py build --force
 1.15033 +sudo python setup.py install --skip-build</programlisting>
 1.15034 +      </listitem>
 1.15035 +      <listitem><para id="x_516">Clone the <filename class="directory" moreinfo="none">crew</filename> Mercurial repository.
 1.15036 +	  Clone the <literal role="hg-ext" moreinfo="none">inotify</literal> patch
 1.15037 +	  repository so that Mercurial Queues will be able to apply
 1.15038 +	  patches to your cope of the <filename class="directory" moreinfo="none">crew</filename> repository.</para>
 1.15039 +	<programlisting format="linespecific">hg clone http://hg.intevation.org/mercurial/crew
 1.15040 +hg clone crew inotify
 1.15041 +hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
 1.15042 +      </listitem>
 1.15043 +      <listitem><para id="x_517">Make sure that you have the Mercurial Queues
 1.15044 +	  extension, <literal role="hg-ext" moreinfo="none">mq</literal>, enabled.  If
 1.15045 +	  you've never used MQ, read <xref linkend="sec:mq:start"/> to get started
 1.15046 +	  quickly.</para>
 1.15047 +      </listitem>
 1.15048 +      <listitem><para id="x_518">Go into the <filename class="directory" moreinfo="none">inotify</filename> repo, and apply all
 1.15049 +	  of the <literal role="hg-ext" moreinfo="none">inotify</literal> patches
 1.15050 +	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
 1.15051 +	    -a</option> option to the <command role="hg-ext-mq" moreinfo="none">qpush</command> command.</para>
 1.15052 +	<programlisting format="linespecific">cd inotify
 1.15053 +hg qpush -a</programlisting>
 1.15054 +      </listitem>
 1.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.
 1.15056 +	  Instead, ask for help.</para>
 1.15057 +      </listitem>
 1.15058 +      <listitem><para id="x_51a">Build and install the patched version of
 1.15059 +	  Mercurial.</para>
 1.15060 +	<programlisting format="linespecific">python setup.py build --force
 1.15061 +sudo python setup.py install --skip-build</programlisting>
 1.15062 +      </listitem>
 1.15063 +    </orderedlist>
 1.15064 +    <para id="x_51b">Once you've build a suitably patched version of Mercurial,
 1.15065 +      all you need to do to enable the <literal role="hg-ext" moreinfo="none">inotify</literal> extension is add an entry to
 1.15066 +      your <filename role="special" moreinfo="none">~/.hgrc</filename>.</para>
 1.15067 +    <programlisting format="linespecific">[extensions] inotify =</programlisting>
 1.15068 +    <para id="x_51c">When the <literal role="hg-ext" moreinfo="none">inotify</literal> extension
 1.15069 +      is enabled, Mercurial will automatically and transparently start
 1.15070 +      the status daemon the first time you run a command that needs
 1.15071 +      status in a repository.  It runs one status daemon per
 1.15072 +      repository.</para>
 1.15073 +
 1.15074 +    <para id="x_51d">The status daemon is started silently, and runs in the
 1.15075 +      background.  If you look at a list of running processes after
 1.15076 +      you've enabled the <literal role="hg-ext" moreinfo="none">inotify</literal>
 1.15077 +      extension and run a few commands in different repositories,
 1.15078 +      you'll thus see a few <literal moreinfo="none">hg</literal> processes sitting
 1.15079 +      around, waiting for updates from the kernel and queries from
 1.15080 +      Mercurial.</para>
 1.15081 +
 1.15082 +    <para id="x_51e">The first time you run a Mercurial command in a repository
 1.15083 +      when you have the <literal role="hg-ext" moreinfo="none">inotify</literal>
 1.15084 +      extension enabled, it will run with about the same performance
 1.15085 +      as a normal Mercurial command.  This is because the status
 1.15086 +      daemon needs to perform a normal status scan so that it has a
 1.15087 +      baseline against which to apply later updates from the kernel.
 1.15088 +      However, <emphasis>every</emphasis> subsequent command that does
 1.15089 +      any kind of status check should be noticeably faster on
 1.15090 +      repositories of even fairly modest size.  Better yet, the bigger
 1.15091 +      your repository is, the greater a performance advantage you'll
 1.15092 +      see.  The <literal role="hg-ext" moreinfo="none">inotify</literal> daemon makes
 1.15093 +      status operations almost instantaneous on repositories of all
 1.15094 +      sizes!</para>
 1.15095 +
 1.15096 +    <para id="x_51f">If you like, you can manually start a status daemon using
 1.15097 +      the <command role="hg-ext-inotify" moreinfo="none">inserve</command> command.
 1.15098 +      This gives you slightly finer control over how the daemon ought
 1.15099 +      to run.  This command will of course only be available when the
 1.15100 +      <literal role="hg-ext" moreinfo="none">inotify</literal> extension is
 1.15101 +      enabled.</para>
 1.15102 +
 1.15103 +    <para id="x_520">When you're using the <literal role="hg-ext" moreinfo="none">inotify</literal> extension, you should notice
 1.15104 +      <emphasis>no difference at all</emphasis> in Mercurial's
 1.15105 +      behavior, with the sole exception of status-related commands
 1.15106 +      running a whole lot faster than they used to.  You should
 1.15107 +      specifically expect that commands will not print different
 1.15108 +      output; neither should they give different results. If either of
 1.15109 +      these situations occurs, please report a bug.</para>
 1.15110 +
 1.15111 +  </sect1>
 1.15112 +  <sect1 id="sec:hgext:extdiff">
 1.15113 +    <title>Flexible diff support with the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension</title>
 1.15114 +
 1.15115 +    <para id="x_521">Mercurial's built-in <command role="hg-cmd" moreinfo="none">hg
 1.15116 +	diff</command> command outputs plaintext unified diffs.</para>
 1.15117 +
 1.15118 +    <!-- BEGIN extdiff.diff -->
 1.15119 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg diff</userinput>
 1.15120 +diff -r 801b35c37d8b myfile
 1.15121 +--- a/myfile	Sun Aug 16 14:05:02 2009 +0000
 1.15122 ++++ b/myfile	Sun Aug 16 14:05:02 2009 +0000
 1.15123 +@@ -1,1 +1,2 @@
 1.15124 + The first line.
 1.15125 ++The second line.
 1.15126 +</screen>
 1.15127 +<!-- END extdiff.diff -->
 1.15128 +
 1.15129 +
 1.15130 +    <para id="x_522">If you would like to use an external tool to display
 1.15131 +      modifications, you'll want to use the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension.  This will let you
 1.15132 +      use, for example, a graphical diff tool.</para>
 1.15133 +
 1.15134 +    <para id="x_523">The <literal role="hg-ext" moreinfo="none">extdiff</literal> extension is
 1.15135 +      bundled with Mercurial, so it's easy to set up.  In the <literal role="rc-extensions" moreinfo="none">extensions</literal> section of your
 1.15136 +      <filename role="special" moreinfo="none">~/.hgrc</filename>, simply add a
 1.15137 +      one-line entry to enable the extension.</para>
 1.15138 +    <programlisting format="linespecific">[extensions]
 1.15139 +extdiff =</programlisting>
 1.15140 +    <para id="x_524">This introduces a command named <command role="hg-ext-extdiff" moreinfo="none">extdiff</command>, which by default uses
 1.15141 +      your system's <command moreinfo="none">diff</command> command to generate a
 1.15142 +      unified diff in the same form as the built-in <command role="hg-cmd" moreinfo="none">hg diff</command> command.</para>
 1.15143 +    
 1.15144 +    <!-- BEGIN extdiff.extdiff -->
 1.15145 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg extdiff</userinput>
 1.15146 +--- a.801b35c37d8b/myfile	2009-08-16 14:05:02.000000000 +0000
 1.15147 ++++ /tmp/extdiffl1y_s9/a/myfile	2009-08-16 14:05:02.000000000 +0000
 1.15148 +@@ -1 +1,2 @@
 1.15149 + The first line.
 1.15150 ++The second line.
 1.15151 +</screen>
 1.15152 +<!-- END extdiff.extdiff -->
 1.15153 +
 1.15154 +
 1.15155 +    <para id="x_525">The result won't be exactly the same as with the built-in
 1.15156 +      <command role="hg-cmd" moreinfo="none">hg diff</command> variations, because the
 1.15157 +      output of <command moreinfo="none">diff</command> varies from one system to
 1.15158 +      another, even when passed the same options.</para>
 1.15159 +
 1.15160 +    <para id="x_526">As the <quote><literal moreinfo="none">making snapshot</literal></quote>
 1.15161 +      lines of output above imply, the <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command works by
 1.15162 +      creating two snapshots of your source tree.  The first snapshot
 1.15163 +      is of the source revision; the second, of the target revision or
 1.15164 +      working directory.  The <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command generates
 1.15165 +      these snapshots in a temporary directory, passes the name of
 1.15166 +      each directory to an external diff viewer, then deletes the
 1.15167 +      temporary directory.  For efficiency, it only snapshots the
 1.15168 +      directories and files that have changed between the two
 1.15169 +      revisions.</para>
 1.15170 +
 1.15171 +    <para id="x_527">Snapshot directory names have the same base name as your
 1.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
 1.15173 +      snapshot directory.  Each snapshot directory name has its
 1.15174 +      changeset ID appended, if appropriate.  If a snapshot is of
 1.15175 +      revision <literal moreinfo="none">a631aca1083f</literal>, the directory will be
 1.15176 +      named <filename class="directory" moreinfo="none">foo.a631aca1083f</filename>.
 1.15177 +      A snapshot of the working directory won't have a changeset ID
 1.15178 +      appended, so it would just be <filename class="directory" moreinfo="none">foo</filename> in this example.  To see what
 1.15179 +      this looks like in practice, look again at the <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> example above.  Notice
 1.15180 +      that the diff has the snapshot directory names embedded in its
 1.15181 +      header.</para>
 1.15182 +
 1.15183 +    <para id="x_528">The <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command
 1.15184 +      accepts two important options. The <option role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
 1.15185 +      lets you choose a program to view differences with, instead of
 1.15186 +      <command moreinfo="none">diff</command>.  With the <option role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
 1.15187 +      you can change the options that <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> passes to the program
 1.15188 +      (by default, these options are
 1.15189 +      <quote><literal moreinfo="none">-Npru</literal></quote>, which only make sense
 1.15190 +      if you're running <command moreinfo="none">diff</command>).  In other respects,
 1.15191 +      the <command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command
 1.15192 +      acts similarly to the built-in <command role="hg-cmd" moreinfo="none">hg
 1.15193 +	diff</command> command: you use the same option names, syntax,
 1.15194 +      and arguments to specify the revisions you want, the files you
 1.15195 +      want, and so on.</para>
 1.15196 +
 1.15197 +    <para id="x_529">As an example, here's how to run the normal system
 1.15198 +      <command moreinfo="none">diff</command> command, getting it to generate context
 1.15199 +      diffs (using the <option role="cmd-opt-diff">-c</option> option)
 1.15200 +      instead of unified diffs, and five lines of context instead of
 1.15201 +      the default three (passing <literal moreinfo="none">5</literal> as the argument
 1.15202 +      to the <option role="cmd-opt-diff">-C</option> option).</para>
 1.15203 +
 1.15204 +      <!-- BEGIN extdiff.extdiff-ctx -->
 1.15205 +<screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg extdiff -o -NprcC5</userinput>
 1.15206 +*** a.801b35c37d8b/myfile	Sun Aug 16 14:05:02 2009
 1.15207 +--- /tmp/extdiffl1y_s9/a/myfile	Sun Aug 16 14:05:02 2009
 1.15208 +***************
 1.15209 +*** 1 ****
 1.15210 +--- 1,2 ----
 1.15211 +  The first line.
 1.15212 ++ The second line.
 1.15213 +</screen>
 1.15214 +<!-- END extdiff.extdiff-ctx -->
 1.15215 +
 1.15216 +
 1.15217 +    <para id="x_52a">Launching a visual diff tool is just as easy.  Here's how to
 1.15218 +      launch the <command moreinfo="none">kdiff3</command> viewer.</para>
 1.15219 +    <programlisting format="linespecific">hg extdiff -p kdiff3 -o</programlisting>
 1.15220 +
 1.15221 +    <para id="x_52b">If your diff viewing command can't deal with directories,
 1.15222 +      you can easily work around this with a little scripting.  For an
 1.15223 +      example of such scripting in action with the <literal role="hg-ext" moreinfo="none">mq</literal> extension and the
 1.15224 +      <command moreinfo="none">interdiff</command> command, see <xref linkend="mq-collab:tips:interdiff"/>.</para>
 1.15225 +
 1.15226 +    <sect2>
 1.15227 +      <title>Defining command aliases</title>
 1.15228 +
 1.15229 +      <para id="x_52c">It can be cumbersome to remember the options to both the
 1.15230 +	<command role="hg-ext-extdiff" moreinfo="none">extdiff</command> command and
 1.15231 +	the diff viewer you want to use, so the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension lets you define
 1.15232 +	<emphasis>new</emphasis> commands that will invoke your diff
 1.15233 +	viewer with exactly the right options.</para>
 1.15234 +
 1.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
 1.15236 +	<literal role="rc-extdiff" moreinfo="none">extdiff</literal>.  Inside this
 1.15237 +	section, you can define multiple commands.  Here's how to add
 1.15238 +	a <literal moreinfo="none">kdiff3</literal> command.  Once you've defined
 1.15239 +	this, you can type <quote><literal moreinfo="none">hg kdiff3</literal></quote>
 1.15240 +	and the <literal role="hg-ext" moreinfo="none">extdiff</literal> extension
 1.15241 +	will run <command moreinfo="none">kdiff3</command> for you.</para>
 1.15242 +      <programlisting format="linespecific">[extdiff]
 1.15243 +cmd.kdiff3 =</programlisting>
 1.15244 +      <para id="x_52e">If you leave the right hand side of the definition empty,
 1.15245 +	as above, the <literal role="hg-ext" moreinfo="none">extdiff</literal>
 1.15246 +	extension uses the name of the command you defined as the name
 1.15247 +	of the external program to run.  But these names don't have to
 1.15248 +	be the same.  Here, we define a command named
 1.15249 +	<quote><literal moreinfo="none">hg wibble</literal></quote>, which runs
 1.15250 +	<command moreinfo="none">kdiff3</command>.</para>
 1.15251 +      <programlisting format="linespecific">[extdiff]
 1.15252 + cmd.wibble = kdiff3</programlisting>
 1.15253 +
 1.15254 +      <para id="x_52f">You can also specify the default options that you want to
 1.15255 +	invoke your diff viewing program with.  The prefix to use is
 1.15256 +	<quote><literal moreinfo="none">opts.</literal></quote>, followed by the name
 1.15257 +	of the command to which the options apply.  This example
 1.15258 +	defines a <quote><literal moreinfo="none">hg vimdiff</literal></quote> command
 1.15259 +	that runs the <command moreinfo="none">vim</command> editor's
 1.15260 +	<literal moreinfo="none">DirDiff</literal> extension.</para>
 1.15261 +      <programlisting format="linespecific">[extdiff]
 1.15262 + cmd.vimdiff = vim
 1.15263 +opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
 1.15264 +
 1.15265 +    </sect2>
 1.15266 +  </sect1>
 1.15267 +  <sect1 id="sec:hgext:transplant">
 1.15268 +    <title>Cherrypicking changes with the <literal role="hg-ext" moreinfo="none">transplant</literal> extension</title>
 1.15269 +
 1.15270 +    <para id="x_530">Need to have a long chat with Brendan about this.</para>
 1.15271 +
 1.15272 +  </sect1>
 1.15273 +  <sect1 id="sec:hgext:patchbomb">
 1.15274 +    <title>Send changes via email with the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension</title>
 1.15275 +
 1.15276 +    <para id="x_531">Many projects have a culture of <quote>change
 1.15277 +	review</quote>, in which people send their modifications to a
 1.15278 +      mailing list for others to read and comment on before they
 1.15279 +      commit the final version to a shared repository.  Some projects
 1.15280 +      have people who act as gatekeepers; they apply changes from
 1.15281 +      other people to a repository to which those others don't have
 1.15282 +      access.</para>
 1.15283 +
 1.15284 +    <para id="x_532">Mercurial makes it easy to send changes over email for
 1.15285 +      review or application, via its <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension.  The extension is
 1.15286 +      so named because changes are formatted as patches, and it's usual
 1.15287 +      to send one changeset per email message.  Sending a long series
 1.15288 +      of changes by email is thus much like <quote>bombing</quote> the
 1.15289 +      recipient's inbox, hence <quote>patchbomb</quote>.</para>
 1.15290 +
 1.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
 1.15292 +      two lines in your <filename role="special" moreinfo="none">
 1.15293 +	/.hgrc</filename>.</para>
 1.15294 +    <programlisting format="linespecific">[extensions]
 1.15295 +patchbomb =</programlisting>
 1.15296 +    <para id="x_534">Once you've enabled the extension, you will have a new
 1.15297 +      command available, named <command role="hg-ext-patchbomb" moreinfo="none">email</command>.</para>
 1.15298 +
 1.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
 1.15300 +      <emphasis>always</emphasis> run it first with the <option role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
 1.15301 +      This will show you what the command <emphasis>would</emphasis>
 1.15302 +      send, without actually sending anything.  Once you've had a
 1.15303 +      quick glance over the changes and verified that you are sending
 1.15304 +      the right ones, you can rerun the same command, with the <option role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
 1.15305 +      removed.</para>
 1.15306 +
 1.15307 +    <para id="x_536">The <command role="hg-ext-patchbomb" moreinfo="none">email</command> command
 1.15308 +      accepts the same kind of revision syntax as every other
 1.15309 +      Mercurial command.  For example, this command will send every
 1.15310 +      revision between 7 and <literal moreinfo="none">tip</literal>, inclusive.</para>
 1.15311 +    <programlisting format="linespecific">hg email -n 7:tip</programlisting>
 1.15312 +    <para id="x_537">You can also specify a <emphasis>repository</emphasis> to
 1.15313 +      compare with.  If you provide a repository but no revisions, the
 1.15314 +      <command role="hg-ext-patchbomb" moreinfo="none">email</command> command will
 1.15315 +      send all revisions in the local repository that are not present
 1.15316 +      in the remote repository.  If you additionally specify revisions
 1.15317 +      or a branch name (the latter using the <option role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
 1.15318 +      this will constrain the revisions sent.</para>
 1.15319 +
 1.15320 +    <para id="x_538">It's perfectly safe to run the <command role="hg-ext-patchbomb" moreinfo="none">email</command> command without the
 1.15321 +      names of the people you want to send to: if you do this, it will
 1.15322 +      just prompt you for those values interactively.  (If you're
 1.15323 +      using a Linux or Unix-like system, you should have enhanced
 1.15324 +      <literal moreinfo="none">readline</literal>-style editing capabilities when
 1.15325 +      entering those headers, too, which is useful.)</para>
 1.15326 +
 1.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
 1.15328 +      default use the first line of the changeset description as the
 1.15329 +      subject of the single email message it sends.</para>
 1.15330 +
 1.15331 +    <para id="x_53a">If you send multiple revisions, the <command role="hg-ext-patchbomb" moreinfo="none">email</command> command will usually
 1.15332 +      send one message per changeset.  It will preface the series with
 1.15333 +      an introductory message, in which you should describe the
 1.15334 +      purpose of the series of changes you're sending.</para>
 1.15335 +
 1.15336 +    <sect2>
 1.15337 +      <title>Changing the behavior of patchbombs</title>
 1.15338 +
 1.15339 +      <para id="x_53b">Not every project has exactly the same conventions for
 1.15340 +	sending changes in email; the <literal role="hg-ext" moreinfo="none">patchbomb</literal> extension tries to
 1.15341 +	accommodate a number of variations through command line
 1.15342 +	options.</para>
 1.15343 +      <itemizedlist>
 1.15344 +	<listitem><para id="x_53c">You can write a subject for the introductory
 1.15345 +	    message on the command line using the <option role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
 1.15346 +	    option.  This takes one argument, the text of the subject
 1.15347 +	    to use.</para>
 1.15348 +	</listitem>
 1.15349 +	<listitem><para id="x_53d">To change the email address from which the
 1.15350 +	    messages originate, use the <option role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
 1.15351 +	    option.  This takes one argument, the email address to
 1.15352 +	    use.</para>
 1.15353 +	</listitem>
 1.15354 +	<listitem><para id="x_53e">The default behavior is to send unified diffs
 1.15355 +	    (see <xref linkend="sec:mq:patch"/> for a
 1.15356 +	    description of the
 1.15357 +	    format), one per message.  You can send a binary bundle
 1.15358 +	    instead with the <option role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
 1.15359 +	    option.</para>
 1.15360 +	</listitem>
 1.15361 +	<listitem><para id="x_53f">Unified diffs are normally prefaced with a
 1.15362 +	    metadata header.  You can omit this, and send unadorned
 1.15363 +	    diffs, with the <option role="hg-ext-patchbomb-cmd-email-opt">hg
 1.15364 +	      --plain</option> option.</para>
 1.15365 +	</listitem>
 1.15366 +	<listitem><para id="x_540">Diffs are normally sent <quote>inline</quote>,
 1.15367 +	    in the same body part as the description of a patch.  This
 1.15368 +	    makes it easiest for the largest number of readers to
 1.15369 +	    quote and respond to parts of a diff, as some mail clients
 1.15370 +	    will only quote the first MIME body part in a message. If
 1.15371 +	    you'd prefer to send the description and the diff in
 1.15372 +	    separate body parts, use the <option role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
 1.15373 +	    option.</para>
 1.15374 +	</listitem>
 1.15375 +	<listitem><para id="x_541">Instead of sending mail messages, you can
 1.15376 +	    write them to an <literal moreinfo="none">mbox</literal>-format mail
 1.15377 +	    folder using the <option role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
 1.15378 +	    option.  That option takes one argument, the name of the
 1.15379 +	    file to write to.</para>
 1.15380 +	</listitem>
 1.15381 +	<listitem><para id="x_542">If you would like to add a
 1.15382 +	    <command moreinfo="none">diffstat</command>-format summary to each patch,
 1.15383 +	    and one to the introductory message, use the <option role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
 1.15384 +	    option.  The <command moreinfo="none">diffstat</command> command displays
 1.15385 +	    a table containing the name of each file patched, the
 1.15386 +	    number of lines affected, and a histogram showing how much
 1.15387 +	    each file is modified.  This gives readers a qualitative
 1.15388 +	    glance at how complex a patch is.</para>
 1.15389 +	</listitem></itemizedlist>
 1.15390 +
 1.15391 +    </sect2>
 1.15392 +  </sect1>
 1.15393 +</chapter>
 1.15394 +
 1.15395 +<!--
 1.15396 +local variables: 
 1.15397 +sgml-parent-document: ("00book.xml" "book" "chapter")
 1.15398 +end:
 1.15399 +-->
 1.15400 +
 1.15401 +  <!-- BEGIN appA -->
 1.15402 +  
 1.15403 +
 1.15404 +<appendix id="svn">
 1.15405 +  <?dbhtml filename="migrating-to-mercurial.html"?>
 1.15406 +<title>Migrer vers Mercurial</title>
 1.15407 +
 1.15408 +  <para id="x_6e1">Une manière courante de s'essayer à un nouveau
 1.15409 +  gestionnaire de révisions est d'expérimenter en migrant un
 1.15410 +  projet existant, plutôt que le faire avec un nouveau projet.
 1.15411 +  </para>
 1.15412 +
 1.15413 +  <para id="x_6e2">Dans cette annexe, nous discuterons comment importer
 1.15414 +  l'historique d'un projet dans Mercurial, et à quoi faire attention
 1.15415 +  si vous êtes habitués à un autre outil de gestion de révisions.
 1.15416 +   </para>
 1.15417 +
 1.15418 +  <sect1>
 1.15419 +    <title>Importer l'historique depuis un autre système</title>
 1.15420 +
 1.15421 +    <para id="x_6e3">Mercurial est livré avec une extension nommée
 1.15422 +      <literal moreinfo="none">convert</literal>, qui permet d'importer un historique
 1.15423 +      depuis les gestionnaire de révisions les plus courants. Au moment de 
 1.15424 +      l'écriture de ce livre, il pouvait importer l'historique depuis:
 1.15425 +      </para>
 1.15426 +    <itemizedlist>
 1.15427 +      <listitem>
 1.15428 +	<para id="x_6e4">Subversion</para>
 1.15429 +      </listitem>
 1.15430 +      <listitem>
 1.15431 +	<para id="x_6e5">CVS</para>
 1.15432 +      </listitem>
 1.15433 +      <listitem>
 1.15434 +	<para id="x_6e6">git</para>
 1.15435 +      </listitem>
 1.15436 +      <listitem>
 1.15437 +	<para id="x_6e7">Darcs</para>
 1.15438 +      </listitem>
 1.15439 +      <listitem>
 1.15440 +	<para id="x_6e8">Bazaar</para>
 1.15441 +      </listitem>
 1.15442 +      <listitem>
 1.15443 +	<para id="x_6e9">Monotone</para>
 1.15444 +      </listitem>
 1.15445 +      <listitem>
 1.15446 +	<para id="x_6ea">GNU Arch</para>
 1.15447 +      </listitem>
 1.15448 +      <listitem>
 1.15449 +	<para id="x_6eb">Mercurial</para>
 1.15450 +      </listitem>
 1.15451 +    </itemizedlist>
 1.15452 +
 1.15453 +    <para id="x_6ec">(Pour savoir pourquoi Mercurial lui même est supporté
 1.15454 +    comme source, voir <xref linkend="svn.filemap"/>.)</para>
 1.15455 +
 1.15456 +    <para id="x_6ed">Vous pouvez activer l'extension de la manière
 1.15457 +    habituelle, en éditant votre fichier <filename moreinfo="none">~/.hgrc</filename></para>
 1.15458 +
 1.15459 +    <programlisting format="linespecific">[extensions]
 1.15460 +convert =</programlisting>
 1.15461 +
 1.15462 +    <para id="x_6ee">Ceci rendra la commande <command moreinfo="none">hg convert</command>
 1.15463 +    disponible. La commande est facile à utiliser. Par exemple, la 
 1.15464 +    commande suivante va importer l'historique Subversion du <emphasis remap="it">framework</emphasis> de test <quote>Nose Unit</quote> dans Mercurial.
 1.15465 +      </para>
 1.15466 +
 1.15467 +    <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg convert http://python-nose.googlecode.com/svn/trunk</userinput></screen>
 1.15468 +
 1.15469 +    <para id="x_6ef">L'extension <literal moreinfo="none">convert</literal> opère de 
 1.15470 +    manière incrémentale. En d'autres mots, après une première exécution de
 1.15471 +    la commande <command moreinfo="none">hg convert</command>, les exécutions ultérieures
 1.15472 +    importeront les révisions ultérieures à l'exécution précédente.
 1.15473 +    La conversion incrémentale ne réussira que si
 1.15474 +    vous exécutez <command moreinfo="none">hg convert</command> dans le même dépôt que vous
 1.15475 +    aviez utilisé à l'origine, ceci parce que l'extension <literal moreinfo="none">convert</literal> 
 1.15476 +    sauvegarde un certain nombre de méta-données privées dans le fichier
 1.15477 +    <filename moreinfo="none">.hg/shamap</filename> (non versioné) au sein du dépôt cible.
 1.15478 +    </para>
 1.15479 +
 1.15480 +    <para id="x_707">Lorsque vous voulez faire des modifications en utilisant
 1.15481 +    Mercurial, le mieux est de faire un clone de l'ensemble de l'arborescence 
 1.15482 +    que vous souhaitez convertir, et de laisser l'arborescence d'origine pour
 1.15483 +    de futures conversions incrémentales. C'est la manière la plus sûre pour vous laisser
 1.15484 +    récupérer et fusionner les modifications futures depuis l'outil de gestion
 1.15485 +    de révisions dans votre nouveau dépôt Mercurial.</para>
 1.15486 +
 1.15487 +    <sect2>
 1.15488 +      <title>Convertir plusieurs branches</title>
 1.15489 +
 1.15490 +      <para id="x_708">La commande <command moreinfo="none">hg convert</command> citée 
 1.15491 +      ci-dessus convertit seulement l'historique de la <literal moreinfo="none">branche
 1.15492 +      principale (trunk)</literal> du dépôt Subversion. Si nous utilisons
 1.15493 +      à la place l'URL <literal moreinfo="none">http://python-nose.googlecode.com/svn</literal>,
 1.15494 +      Mercurial va automatiquement détecter la  
 1.15495 +      <literal moreinfo="none">branche principale (trunk)</literal>, les <literal moreinfo="none">étiquettes 
 1.15496 +      (tags)</literal>, et les <literal moreinfo="none">branches</literal>  que les dépôts
 1.15497 +      Subversion utilisent généralement, et les importera chacun dans
 1.15498 +      une branche Mercurial distincte.</para>
 1.15499 +
 1.15500 +      <para id="x_709">Par défaut, chaque branche Subversion importée 
 1.15501 +     dans Mercurial se voit attribuer un nom de branche. Une fois la
 1.15502 +     conversion achevée, vous pouvez obtenir la liste des noms des branches 
 1.15503 +     actives dans le dépôt Mercurial en utilisant la commande
 1.15504 +     <command moreinfo="none">hg branches -a</command>. Si vous préférez importer les 
 1.15505 +     branches Subversion sans noms, ajoutez l'option <option>--config
 1.15506 +     convert.hg.usebranches=false</option> à la commande 
 1.15507 +     <command moreinfo="none">hg convert</command>.</para>
 1.15508 +
 1.15509 +      <para id="x_70a">Une fois votre arborescence convertie, 
 1.15510 +      si vous souhaitez travailler selon la pratique habituelle sous Mercurial
 1.15511 +      avec une arborescence qui ne contient qu'une seule branche, vous pouvez cloner
 1.15512 +      cette seule branche en utilisant 
 1.15513 +      <command moreinfo="none">hg clone -r nomdemabranche</command>.</para>
 1.15514 +    </sect2>
 1.15515 +
 1.15516 +    <sect2>
 1.15517 +      <title>Associer les noms d'utilisateurs</title>
 1.15518 +
 1.15519 +      <para id="x_6f0">Certains outils de gestion de révisions
 1.15520 +      ne sauvegardent, avec les modifications, que les noms 
 1.15521 +      d'utilisateurs raccourcis. Ceux-ci peuvent être difficiles à 
 1.15522 +      interpréter. La norme avec Mercurial est de sauvegarder le 
 1.15523 +      nom du <emphasis remap="it">committeur</emphasis> et son adresse
 1.15524 +      mail, ce qui est beaucoup plus utile pour discuter avec lui
 1.15525 +      par la suite.</para>
 1.15526 +
 1.15527 +      <para id="x_6f1">Si vous convertissez une arborescence depuis
 1.15528 +      un gestionnaire de révisions qui utilise seulement les noms
 1.15529 +      raccourcis, vous pouvez associer ces noms à des équivalents 
 1.15530 +      plus détaillés en passant l'option <option>--authors</option>
 1.15531 +      à la commande <command moreinfo="none">hg convert</command>. Cette option
 1.15532 +      attend un fichier qui contient des entrées sous la forme suivante:
 1.15533 +      </para>
 1.15534 +
 1.15535 +      <programlisting format="linespecific">arist = Aristotle &lt;aristotle@phil.example.gr&gt;
 1.15536 +soc = Socrates &lt;socrates@phil.example.gr&gt;</programlisting>
 1.15537 +
 1.15538 +      <para id="x_6f2">Quand <literal moreinfo="none">convert</literal> trouve une
 1.15539 +      modification associée au nom <literal moreinfo="none">arist</literal> dans le
 1.15540 +      dépôt de source, il va utiliser le nom <literal moreinfo="none">Aristotle
 1.15541 +      &lt;aristotle@phil.example.gr&gt;</literal> dans les révisions
 1.15542 +      Mercurial. Si aucune correspondance n'est trouvé, il utilise
 1.15543 +      le nom tel quel.</para>
 1.15544 +    </sect2>
 1.15545 +
 1.15546 +    <sect2 id="svn.filemap">
 1.15547 +      <title>Nettoyer l'arboresence</title>
 1.15548 +
 1.15549 +      <para id="x_6f3">Tous les projets n'ont pas un historique parfait.
 1.15550 +      Il peut y avoir des répertoires qui n'auraient jamais dû être ajoutés,
 1.15551 +      un fichier qui est trop volumineux, ou même une partie de la
 1.15552 +      hiérarchie qui devrait être réorganisée.</para>
 1.15553 +
 1.15554 +      <para id="x_6f4">L'extension <literal moreinfo="none">convert</literal> permet
 1.15555 +      d'utiliser un <quote>fichier d'association</quote> qui peut 
 1.15556 +      réorganiser les fichiers et les répertoires dans un projet lors de
 1.15557 +      l'importation de son historique. Ceci est utile non seulement quand vous
 1.15558 +      importez l'historique d'un autre gestionnaire de révisions, mais
 1.15559 +      aussi pour nettoyer ou réorganiser l'arborescence d'un projet
 1.15560 +      Mercurial.</para>
 1.15561 +
 1.15562 +      <para id="x_6f5">Pour indiquer le fichier d'association, on utilise
 1.15563 +      l'option <option>--filemap</option> en lui fournissant un nom de
 1.15564 +      fichier. Le fichier d'association contient des lignes de la forme
 1.15565 +      suivante :</para>
 1.15566 +
 1.15567 +      <programlisting format="linespecific"># Ceci est un commentaire.
 1.15568 +# Les lignes vides sont ignorées.
 1.15569 +
 1.15570 +include path/to/file
 1.15571 +
 1.15572 +exclude path/to/file
 1.15573 +
 1.15574 +rename from/some/path to/some/other/place
 1.15575 +</programlisting>
 1.15576 +      
 1.15577 +      <para id="x_6f6">La directive <literal moreinfo="none">include</literal> inclut un
 1.15578 +      fichier, ou l'ensemble des fichiers d'un répertoire, dans le dépôt
 1.15579 +      de destination. La directive <literal moreinfo="none">exclude</literal> omet les
 1.15580 +      fichiers ou répertoires du dépôt. Ceci inclut aussi les autres
 1.15581 +      fichiers et répertoires qui ne sont pas explicitement inclus.
 1.15582 +      La directive <literal moreinfo="none">exclude</literal> entraine l'omission
 1.15583 +      des fichiers ou répertoires, et autres fichiers qui ne sont pas
 1.15584 +      explicitement inclus.</para>
 1.15585 +
 1.15586 +      <para id="x_6f7">Pour déplacer un fichier ou un répertoire d'un
 1.15587 +      emplacement à un autre, utilisez la directive
 1.15588 +      <literal moreinfo="none">rename</literal>. Si vous avez besoin de déplacer un 
 1.15589 +      fichier ou un répertoire depuis un sous répertoire dans la racine
 1.15590 +      du dépôt, utilisez <literal moreinfo="none">.</literal> comme second argument de 
 1.15591 +      la directive <literal moreinfo="none">rename</literal>.</para>
 1.15592 +    </sect2>
 1.15593 +
 1.15594 +    <sect2>
 1.15595 +      <title>Améliorer les performances de la conversion Subversion</title>
 1.15596 +
 1.15597 +      <para id="x_70b">Vous aurez souvent besoin de plusieurs essais
 1.15598 +      avant d'arriver à la parfaite combinaison de fichier d'association de fichiers,
 1.15599 +      de fichier d'association de noms d'utilisateurs et des autres paramètres. Or,
 1.15600 +      convertir un dépôt Mercurial via un protocole comme <literal moreinfo="none">ssh</literal>
 1.15601 +      ou <literal moreinfo="none">http</literal> peut être des milliers de fois plus long
 1.15602 +      que ce dont le système d'exploitation est en fait capable de faire,
 1.15603 +      à cause des latence réseau. Ceci peut rendre la conception de cette
 1.15604 +      combinaison parfaite très douloureuse.</para>
 1.15605 +
 1.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> 
 1.15607 +	peut grandement améliorer la vitesse de conversion d'un dépôt
 1.15608 +        Subversion. Il s'agit d'un programme de miroir de dépôt Subversion
 1.15609 +        en lecture seule. L'idée est de créer un miroir local d'une
 1.15610 +        arborescence Subversion, puis de convertir ce miroir en dépôt
 1.15611 +        Mercurial.</para>
 1.15612 +      
 1.15613 +      <para id="x_70d">Supposez que nous voulions convertir le dépôt 
 1.15614 +      Subversion du populaire projet Memcached en une arborescence Mercurial.
 1.15615 +      Tout d'abord, nous créons un dépôt Subversion local.</para>
 1.15616 +
 1.15617 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svnadmin create memcached-mirror</userinput></screen>
 1.15618 +
 1.15619 +      <para id="x_70e">Puis, nous allons mettre en place un <quote>hook</quote> Subversion
 1.15620 +      dont <command moreinfo="none">svnsync</command> a besoin.</para>
 1.15621 +
 1.15622 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">echo '#!/bin/sh' &gt; memcached-mirror/hooks/pre-revprop-change</userinput>
 1.15623 +<prompt moreinfo="none">$</prompt> <userinput moreinfo="none">chmod +x memcached-mirror/hooks/pre-revprop-change</userinput></screen>
 1.15624 +
 1.15625 +      <para id="x_70f">Nous initialisons ensuite <command moreinfo="none">svnsync</command> dans ce
 1.15626 +      dépôt.</para>
 1.15627 +
 1.15628 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svnsync --init file://`pwd`/memcached-mirror \
 1.15629 +  http://code.sixapart.com/svn/memcached</userinput></screen>
 1.15630 +
 1.15631 +      <para id="x_710">La prochaine étape est de commencer le processus de
 1.15632 +      mirroring de <command moreinfo="none">svnsync</command>.</para>
 1.15633 +
 1.15634 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">svnsync sync file://`pwd`/memcached-mirror</userinput></screen>
 1.15635 +
 1.15636 +      <para id="x_711">Enfin, nous importons l'historique de notre dépôt
 1.15637 +      local Subversion dans Mercurial.</para>
 1.15638 +
 1.15639 +      <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg convert memcached-mirror</userinput></screen>
 1.15640 +      
 1.15641 +      <para id="x_712">Nous pouvons utiliser ce processus de manière
 1.15642 +      incrémentale, si le dépôt Subversion est toujours en activité.
 1.15643 +      Il suffit d'exécuter de nouveau <command moreinfo="none">svnsync</command> pour
 1.15644 +      récupérer les récentes modifications dans notre miroir, puis <command moreinfo="none">hg 
 1.15645 +      convert</command>
 1.15646 +      les importe dans notre arborescence Mercurial.</para>
 1.15647 +
 1.15648 +      <para id="x_713">Il y a deux avantages à utiliser un import à deux
 1.15649 +      étages comme avec <command moreinfo="none">svnsync</command>. Le premier
 1.15650 +      est qu'il utilise du code de synchronisation réseau de Subversion 
 1.15651 +      plus efficace que la commande <command moreinfo="none">hg convert</command>,
 1.15652 +      et donc transfère moins de données par le réseau. Le deuxième
 1.15653 +      est que l'import depuis un dépôt Subversion local est si rapide que
 1.15654 +      vous pouvez peaufiner et réitérer les paramètres de conversion de 
 1.15655 +      ce dernier sans souffrir de la qualité de la connexion réseau.</para>
 1.15656 +    </sect2>
 1.15657 +  </sect1>
 1.15658 +
 1.15659 +  <sect1>
 1.15660 +    <title>Migrer depuis Subversion</title>
 1.15661 +
 1.15662 +    <para id="x_6f8">Subversion est le système de gestion de versions
 1.15663 +    open source le plus populaire aujourd'hui. Bien qu'il y ait des
 1.15664 +    différences entre Mercurial et Subversion, faire la transition de
 1.15665 +    l'un à l'autre n'est pas très difficile. Les deux disposent en effet 
 1.15666 +    de jeux de commandes similaires et d'interfaces similaires.</para>
 1.15667 +
 1.15668 +    <sect2>
 1.15669 +      <title>Différences philosophiques</title>
 1.15670 +
 1.15671 +      <para id="x_6f9">La différence fondamentale entre Subversion et
 1.15672 +      Mercurial est bien évidement que Subversion est centralisé, alors 
 1.15673 +      que Mercurial est distribué. Puisque que Mercurial enregistre tout
 1.15674 +      l'historique d'un projet sur votre disque dur local, il n'a besoin
 1.15675 +      d'effectuer des accès au réseau que lorsque vous voulez
 1.15676 +      explicitement communiquer avec un autre dépôt. Subversion, par contre,
 1.15677 +      ne conserve que peu d'informations localement, et le client
 1.15678 +      doit donc communiquer avec le serveur central pour la
 1.15679 +      plupart des opérations communes.</para>
 1.15680 +
 1.15681 +      <para id="x_6fa">Subversion s'en tire plus ou moins bien sans notion
 1.15682 +      de branche réellement bien définie : quelle portion de l'espace de nommage
 1.15683 +      du serveur est une branche est une simple question de convention, le
 1.15684 +      logiciel n'imposant rien à ce sujet. Mercurial considère
 1.15685 +      un dépôt comme un élément de la gestion des branches.</para>
 1.15686 +      
 1.15687 +      <sect3>
 1.15688 +	<title>Portée des commandes</title>
 1.15689 +
 1.15690 +	<para id="x_6fb">Puisque que Subversion ne sait pas réellement
 1.15691 +        quelle partie de son espace de nommage est en fait une branche, il
 1.15692 +        traite la plupart des commandes comme des requêtes à exécuter sur le
 1.15693 +        répertoire où vous vous situez, et ses sous répertoires. Par exemple,
 1.15694 +        si vous exécutez <command moreinfo="none">svn log</command>, vous verrez l'historique 
 1.15695 +        de la partie de l'arborescence où vous vous situez, et non de la
 1.15696 +        hiérarchie entière.</para>
 1.15697 +
 1.15698 +	<para id="x_6fc">Les commandes de Mercurial ont un comportement
 1.15699 +        différent : toutes les commandes s'appliquent à l'ensemble de l'arborescence
 1.15700 +        du dépôt. Exécutez la commande <command moreinfo="none">hg log</command> et elle vous
 1.15701 +        donnera l'historique de l'ensemble de l'arborescence, quel que soit le
 1.15702 +        sous-répertoire où vous vous situez. Si
 1.15703 +        vous souhaitez obtenir l'historique d'un répertoire ou seulement d'un
 1.15704 +        fichier, ajouter simplement le nom de celui-ci à la commande, par
 1.15705 +        exemple <command moreinfo="none">hg log src</command>.</para>
 1.15706 +
 1.15707 +	<para id="x_6fd">De ma propre expérience, cette différence dans leur
 1.15708 +        comportement par défaut est probablement ce qui risque de vous
 1.15709 +        surprendre le plus si vous passez régulièrement d'un outil à l'autre.</para>
 1.15710 +      </sect3>
 1.15711 +
 1.15712 +      <sect3>
 1.15713 +	<title>Opération multi utilisateur et sécurité</title>
 1.15714 +
 1.15715 +	<para id="x_6fe">Avec Subversion, il est normal (bien que légèrement
 1.15716 +        désapprouvé) que différentes personnes collaborent sur une seule
 1.15717 +        branche. Si Alice et Bob travaillent ensemble, et Alice ajoute ses
 1.15718 +        modifications à leur branche partagée, Bob doit alors mettre à jour
 1.15719 +        sa vue de la branche avant de pouvoir appliquer un commit.
 1.15720 +        Puisqu'il n'a, à ce moment, pas effectué de commit
 1.15721 +        des modifications qu'il a faites, il se peut qu'il ne corrompe 
 1.15722 +        ou ne perde
 1.15723 +        ses modifications pendant ou après la mise à jour.</para>
 1.15724 +
 1.15725 +	<para id="x_6ff">Mercurial encourage, à l'inverse, un modèle 
 1.15726 +        "commit-puis-merge". Avant de récupérer des modifications depuis le 
 1.15727 +        serveur, ou avant d'y envoyer les siennes, Bob enregistre ses 
 1.15728 +        modifications de manière locale en appliquant un commit. C'est à dire
 1.15729 +        que si Alice avait envoyé ses modifications sur le serveur avant
 1.15730 +        que Bob n'envoie les siennes, ce dernier ne pourra le faire
 1.15731 +        qu'après avoir récupéré et fusionné celles d'Alice avec les siennes. 
 1.15732 +        Si Bob fait alors une
 1.15733 +        erreur lors de la fusion, il pourra toujours restaurer sa version, pour
 1.15734 +        laquelle il avait appliqué le commit.</para>
 1.15735 +          
 1.15736 +	<para id="x_700">Il est important de souligner qu'il s'agit de la
 1.15737 +        manière habituelle de travailler avec ces outils. Subversion propose
 1.15738 +        une manière plus sûre de "travailler-dans-votre-propre-branche", mais elle
 1.15739 +        est assez complexe pour que, en pratique, elle ne soit que rarement utilisé.
 1.15740 +        Mercurial propose de son côté un mode un peu moins sûr, permettant de
 1.15741 +        récupérer des modifications par dessus des modifications non
 1.15742 +        committées, qui reste toutefois très peu répandu.</para> 
 1.15743 +      </sect3>
 1.15744 +
 1.15745 +      <sect3>
 1.15746 +	<title>Publication vs changement locaux</title>
 1.15747 +
 1.15748 +	<para id="x_701">Une commande Subversion <command moreinfo="none">svn
 1.15749 +        commit</command> publie immédiatement les modifications sur le
 1.15750 +        serveur, où elles peuvent être vu par n'importe qui doté d'un privilège
 1.15751 +        de lecture.</para>
 1.15752 +
 1.15753 +	<para id="x_702">Avec Mercurial, les modifications sont toujours d'abord
 1.15754 +        enregistrées localement, et doivent être par la suite transférés par
 1.15755 +        la commande <command moreinfo="none">hg push</command>.</para>
 1.15756 +
 1.15757 +	<para id="x_703">Chaque approche a ses avantages et ses inconvénients.
 1.15758 +        Le modèle Subversion implique que les modifications soient publiées, et
 1.15759 +        donc disponibles immédiatement. D'un autre coté, cela implique aussi
 1.15760 +        que, pour pouvoir utiliser le logiciel normalement, un utilisateur doit 
 1.15761 +        avoir les droits d'écriture dans le dépôt, et ce privilège n'est pas concédé 
 1.15762 +        facilement par la plupart des projets Open Source.</para>
 1.15763 +
 1.15764 +	<para id="x_704">L'approche de Mercurial permet à quiconque de faire
 1.15765 +        un clone du dépôt et d'y ajouter ses modifications sans jamais avoir
 1.15766 +        besoin de la permission de quiconque, et l'on peut même publier ses
 1.15767 +        modifications et continuer à participer comme on le désire. Toutefois, la
 1.15768 +        distinction entre les commits et le transfert de ces derniers présente
 1.15769 +        le risque que quelqu'un applique ses modifications par un commit local
 1.15770 +        sur son portable et parte se promener pendant quelques jours en ayant
 1.15771 +        oublié de les transférer, ce qui peut, dans certains rares cas,
 1.15772 +        bloquer temporairement ses collaborateurs.</para>
 1.15773 +      </sect3>
 1.15774 +    </sect2>
 1.15775 +
 1.15776 +    <sect2>
 1.15777 +      <title>Références des commandes</title>
 1.15778 +
 1.15779 +      <table>
 1.15780 +	<title>Commandes Subversion et leurs équivalents Mercurial</title>
 1.15781 +	<tgroup cols="3">
 1.15782 +	  <thead>
 1.15783 +	    <row>
 1.15784 +	      <entry>Subversion</entry>
 1.15785 +	      <entry>Mercurial</entry>
 1.15786 +	      <entry>Notes</entry>
 1.15787 +	    </row>
 1.15788 +	  </thead>
 1.15789 +	  <tbody>
 1.15790 +	    <row>
 1.15791 +	      <entry><command moreinfo="none">svn add</command></entry>
 1.15792 +	      <entry><command moreinfo="none">hg add</command></entry>
 1.15793 +	      <entry/>
 1.15794 +	    </row>
 1.15795 +	    <row>
 1.15796 +	      <entry><command moreinfo="none">svn blame</command></entry>
 1.15797 +	      <entry><command moreinfo="none">hg annotate</command></entry>
 1.15798 +	      <entry/>
 1.15799 +	    </row>
 1.15800 +	    <row>
 1.15801 +	      <entry><command moreinfo="none">svn cat</command></entry>
 1.15802 +	      <entry><command moreinfo="none">hg cat</command></entry>
 1.15803 +	      <entry/>
 1.15804 +	    </row>
 1.15805 +	    <row>
 1.15806 +	      <entry><command moreinfo="none">svn checkout</command></entry>
 1.15807 +	      <entry><command moreinfo="none">hg clone</command></entry>
 1.15808 +	      <entry/>
 1.15809 +	    </row>
 1.15810 +	    <row>
 1.15811 +	      <entry><command moreinfo="none">svn cleanup</command></entry>
 1.15812 +	      <entry>n/a</entry>
 1.15813 +	      <entry>Aucun nettoyage nécessaire.</entry>
 1.15814 +	    </row>
 1.15815 +	    <row>
 1.15816 +	      <entry><command moreinfo="none">svn commit</command></entry>
 1.15817 +	      <entry><command moreinfo="none">hg commit</command>; <command moreinfo="none">hg
 1.15818 +		  push</command></entry>
 1.15819 +	      <entry><command moreinfo="none">hg push</command> publie les modifications
 1.15820 +              après un commit.</entry>
 1.15821 +	    </row>
 1.15822 +	    <row>
 1.15823 +	      <entry><command moreinfo="none">svn copy</command></entry>
 1.15824 +	      <entry><command moreinfo="none">hg clone</command></entry>
 1.15825 +	      <entry>Pour créer une nouvelle branche</entry>
 1.15826 +	    </row>
 1.15827 +	    <row>
 1.15828 +	      <entry><command moreinfo="none">svn copy</command></entry>
 1.15829 +	      <entry><command moreinfo="none">hg copy</command></entry>
 1.15830 +	      <entry>Pour copier des fichiers ou des répertoires</entry>
 1.15831 +	    </row>
 1.15832 +	    <row>
 1.15833 +	      <entry><command moreinfo="none">svn delete</command> (<command moreinfo="none">svn
 1.15834 +		  remove</command>)</entry>
 1.15835 +	      <entry><command moreinfo="none">hg remove</command></entry>
 1.15836 +	      <entry/>
 1.15837 +	    </row>
 1.15838 +	    <row>
 1.15839 +	      <entry><command moreinfo="none">svn diff</command></entry>
 1.15840 +	      <entry><command moreinfo="none">hg diff</command></entry>
 1.15841 +	      <entry/>
 1.15842 +	    </row>
 1.15843 +	    <row>
 1.15844 +	      <entry><command moreinfo="none">svn export</command></entry>
 1.15845 +	      <entry><command moreinfo="none">hg archive</command></entry>
 1.15846 +	      <entry/>
 1.15847 +	    </row>
 1.15848 +	    <row>
 1.15849 +	      <entry><command moreinfo="none">svn help</command></entry>
 1.15850 +	      <entry><command moreinfo="none">hg help</command></entry>
 1.15851 +	      <entry/>
 1.15852 +	    </row>
 1.15853 +	    <row>
 1.15854 +	      <entry><command moreinfo="none">svn import</command></entry>
 1.15855 +	      <entry><command moreinfo="none">hg addremove</command>; <command moreinfo="none">hg
 1.15856 +		  commit</command></entry>
 1.15857 +	      <entry/>
 1.15858 +	    </row>
 1.15859 +	    <row>
 1.15860 +	      <entry><command moreinfo="none">svn info</command></entry>
 1.15861 +	      <entry><command moreinfo="none">hg parents</command></entry>
 1.15862 +	      <entry>Affiche la version sur la base de laquelle on travaille</entry>
 1.15863 +	    </row>
 1.15864 +	    <row>
 1.15865 +	      <entry><command moreinfo="none">svn info</command></entry>
 1.15866 +	      <entry><command moreinfo="none">hg showconfig
 1.15867 +		  paths.default</command></entry>
 1.15868 +	      <entry>Affiche de quelle URL est extrait ce dépôt</entry>
 1.15869 +	    </row>
 1.15870 +	    <row>
 1.15871 +	      <entry><command moreinfo="none">svn list</command></entry>
 1.15872 +	      <entry><command moreinfo="none">hg manifest</command></entry>
 1.15873 +	      <entry/>
 1.15874 +	    </row>
 1.15875 +	    <row>
 1.15876 +	      <entry><command moreinfo="none">svn log</command></entry>
 1.15877 +	      <entry><command moreinfo="none">hg log</command></entry>
 1.15878 +	      <entry/>
 1.15879 +	    </row>
 1.15880 +	    <row>
 1.15881 +	      <entry><command moreinfo="none">svn merge</command></entry>
 1.15882 +	      <entry><command moreinfo="none">hg merge</command></entry>
 1.15883 +	      <entry/>
 1.15884 +	    </row>
 1.15885 +	    <row>
 1.15886 +	      <entry><command moreinfo="none">svn mkdir</command></entry>
 1.15887 +	      <entry>n/a</entry>
 1.15888 +	      <entry>Mercurial ne versionne pas les répertoires</entry>
 1.15889 +	    </row>
 1.15890 +	    <row>
 1.15891 +	      <entry><command moreinfo="none">svn move</command> (<command moreinfo="none">svn
 1.15892 +		  rename</command>)</entry>
 1.15893 +	      <entry><command moreinfo="none">hg rename</command></entry>
 1.15894 +	      <entry/>
 1.15895 +	    </row>
 1.15896 +	    <row>
 1.15897 +	      <entry><command moreinfo="none">svn resolved</command></entry>
 1.15898 +	      <entry><command moreinfo="none">hg resolve -m</command></entry>
 1.15899 +	      <entry/>
 1.15900 +	    </row>
 1.15901 +	    <row>
 1.15902 +	      <entry><command moreinfo="none">svn revert</command></entry>
 1.15903 +	      <entry><command moreinfo="none">hg revert</command></entry>
 1.15904 +	      <entry/>
 1.15905 +	    </row>
 1.15906 +	    <row>
 1.15907 +	      <entry><command moreinfo="none">svn status</command></entry>
 1.15908 +	      <entry><command moreinfo="none">hg status</command></entry>
 1.15909 +	      <entry/>
 1.15910 +	    </row>
 1.15911 +	    <row>
 1.15912 +	      <entry><command moreinfo="none">svn update</command></entry>
 1.15913 +	      <entry><command moreinfo="none">hg pull -u</command></entry>
 1.15914 +	      <entry/>
 1.15915 +	    </row>
 1.15916 +	  </tbody>
 1.15917 +	</tgroup>
 1.15918 +      </table>
 1.15919 +    </sect2>
 1.15920 +  </sect1>
 1.15921 +
 1.15922 +  <sect1>
 1.15923 +    <title>Conseils utiles pour les débutants</title>
 1.15924 +
 1.15925 +    <para id="x_705">Avec la plupart des gestionnaire de versions, afficher
 1.15926 +    un diff associé à une révision peut être assez douloureux. Par exemple,
 1.15927 +    avec Subversion, pour voir ce qui a été modifiée dans la révision 104654,
 1.15928 +    vous devez saisir <command moreinfo="none">svn diff -r104653:104654</command>. Mercurial
 1.15929 +    élimine le besoin de saisir l'identifiant d'une révision deux fois dans
 1.15930 +    ce cas classique. Pour un simple diff, <command moreinfo="none">hg
 1.15931 +    export 104654</command> suffit. Pour obtenir une entrée du journal suivie d'un diff,
 1.15932 +    <command moreinfo="none">hg log -r104654 -p</command>.</para>
 1.15933 +
 1.15934 +    <para id="x_706">Quand vous exécutez la commande <command moreinfo="none">hg status</command>
 1.15935 +    sans aucun argument, elle affiche l'état de l'ensemble de l'arborescence,
 1.15936 +    avec des chemins relatifs partant de la racine du dépôt. Ceci rend
 1.15937 +    difficile de copier un nom de fichier depuis la sortie de la commande
 1.15938 +    <command moreinfo="none">hg status</command> dans une autre ligne de commande. Si vous
 1.15939 +    fournissez un fichier ou un répertoire à la commande <command moreinfo="none">hg
 1.15940 +    status</command>, elle va afficher les chemins relatif depuis votre
 1.15941 +    répertoire courant à la place. Ainsi, pour avoir un état sur l'ensemble
 1.15942 +    de l'arborescence à l'aide  de <command moreinfo="none">hg status</command>, avec des
 1.15943 +    chemins relatifs à votre répertoire courant, et non la racine du dépôt,
 1.15944 +    ajoutez la sortie de <command moreinfo="none">hg root</command> à la commande
 1.15945 +    <command moreinfo="none">hg status</command>. Vous pouvez le faire aisément sur un
 1.15946 +    système Unix ainsi :</para>
 1.15947 +
 1.15948 +    <screen format="linespecific"><prompt moreinfo="none">$</prompt> <userinput moreinfo="none">hg status `hg root`</userinput></screen>
 1.15949 +  </sect1>
 1.15950 +</appendix>
 1.15951 +
 1.15952 +<!--
 1.15953 +local variables: 
 1.15954 +sgml-parent-document: ("00book.xml" "book" "appendix")
 1.15955 +end:
 1.15956 +-->
 1.15957 +
 1.15958 +  <!-- BEGIN appB -->
 1.15959 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.15960 +
 1.15961 +<appendix id="chap:mqref">
 1.15962 +  <?dbhtml filename="mercurial-queues-reference.html"?>
 1.15963 +  <title>Mercurial Queues reference</title>
 1.15964 +
 1.15965 +  <sect1 id="sec:mqref:cmdref">
 1.15966 +    <title>MQ command reference</title>
 1.15967 +
 1.15968 +    <para id="x_5e8">For an overview of the commands provided by MQ, use the
 1.15969 +      command <command role="hg-cmd" moreinfo="none">hg help mq</command>.</para>
 1.15970 +
 1.15971 +    <sect2>
 1.15972 +      <title><command role="hg-ext-mq" moreinfo="none">qapplied</command>—print
 1.15973 +	applied patches</title>
 1.15974 +
 1.15975 +      <para id="x_5e9">The <command role="hg-ext-mq" moreinfo="none">qapplied</command> command
 1.15976 +	prints the current stack of applied patches.  Patches are
 1.15977 +	printed in oldest-to-newest order, so the last patch in the
 1.15978 +	list is the <quote>top</quote> patch.</para>
 1.15979 +
 1.15980 +    </sect2>
 1.15981 +    <sect2>
 1.15982 +      <title><command role="hg-ext-mq" moreinfo="none">qcommit</command>—commit
 1.15983 +	changes in the queue repository</title>
 1.15984 +
 1.15985 +      <para id="x_5ea">The <command role="hg-ext-mq" moreinfo="none">qcommit</command> command
 1.15986 +	commits any outstanding changes in the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>
 1.15987 +	repository.  This command only works if the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>
 1.15988 +	directory is a repository, i.e. you created the directory
 1.15989 +	using <command role="hg-cmd" moreinfo="none">hg qinit <option role="hg-ext-mq-cmd-qinit-opt">-c</option></command> or
 1.15990 +	ran <command role="hg-cmd" moreinfo="none">hg init</command> in the directory
 1.15991 +	after running <command role="hg-ext-mq" moreinfo="none">qinit</command>.</para>
 1.15992 +
 1.15993 +      <para id="x_5eb">This command is shorthand for <command role="hg-cmd" moreinfo="none">hg
 1.15994 +	  commit --cwd .hg/patches</command>.</para>
 1.15995 +    </sect2>
 1.15996 +    <sect2>
 1.15997 +	<title><command role="hg-ext-mq" moreinfo="none">qdelete</command>—delete a patch
 1.15998 +	from the <filename role="special" moreinfo="none">series</filename>
 1.15999 +	file</title>
 1.16000 +
 1.16001 +      <para id="x_5ec">The <command role="hg-ext-mq" moreinfo="none">qdelete</command> command
 1.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>
 1.16003 +	directory.  It does not pop the patch if the patch is already
 1.16004 +	applied.  By default, it does not delete the patch file; use
 1.16005 +	the <option role="hg-ext-mq-cmd-qdel-opt">-f</option> option
 1.16006 +	to do that.</para>
 1.16007 +
 1.16008 +      <para id="x_5ed">Options:</para>
 1.16009 +      <itemizedlist>
 1.16010 +	<listitem><para id="x_5ee"><option role="hg-ext-mq-cmd-qdel-opt">-f</option>: Delete the
 1.16011 +	    patch file.</para>
 1.16012 +	</listitem></itemizedlist>
 1.16013 +
 1.16014 +    </sect2>
 1.16015 +    <sect2>
 1.16016 +      <title><command role="hg-ext-mq" moreinfo="none">qdiff</command>—print a
 1.16017 +	diff of the topmost applied patch</title>
 1.16018 +
 1.16019 +      <para id="x_5ef">The <command role="hg-ext-mq" moreinfo="none">qdiff</command> command
 1.16020 +	prints a diff of the topmost applied patch. It is equivalent
 1.16021 +	to <command role="hg-cmd" moreinfo="none">hg diff -r-2:-1</command>.</para>
 1.16022 +
 1.16023 +    </sect2>
 1.16024 +    <sect2>
 1.16025 +      <title><command role="hg-ext-mq" moreinfo="none">qfold</command>—move
 1.16026 +	applied patches into repository history</title>
 1.16027 +
 1.16028 +      <para id="x_72d">The <command moreinfo="none">hg qfinish</command> command converts the
 1.16029 +	specified applied patches into permanent changes by moving
 1.16030 +	them out of MQ's control so that they will be treated as
 1.16031 +	normal repository history.</para>
 1.16032 +    </sect2>
 1.16033 +
 1.16034 +    <sect2>
 1.16035 +      <title><command role="hg-ext-mq" moreinfo="none">qfold</command>—merge
 1.16036 +	(<quote>fold</quote>) several patches into one</title>
 1.16037 +
 1.16038 +      <para id="x_5f0">The <command role="hg-ext-mq" moreinfo="none">qfold</command> command
 1.16039 +	merges multiple patches into the topmost applied patch, so
 1.16040 +	that the topmost applied patch makes the union of all of the
 1.16041 +	changes in the patches in question.</para>
 1.16042 +
 1.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
 1.16044 +	any is.  The order in which patches are folded is significant;
 1.16045 +	<command role="hg-cmd" moreinfo="none">hg qfold a b</command> means
 1.16046 +	<quote>apply the current topmost patch, followed by
 1.16047 +	  <literal moreinfo="none">a</literal>, followed by
 1.16048 +	  <literal moreinfo="none">b</literal></quote>.</para>
 1.16049 +
 1.16050 +      <para id="x_5f2">The comments from the folded patches are appended to the
 1.16051 +	comments of the destination patch, with each block of comments
 1.16052 +	separated by three asterisk
 1.16053 +	(<quote><literal moreinfo="none">*</literal></quote>) characters.  Use the
 1.16054 +	<option role="hg-ext-mq-cmd-qfold-opt">-e</option> option to
 1.16055 +	edit the commit message for the combined patch/changeset after
 1.16056 +	the folding has completed.</para>
 1.16057 +
 1.16058 +      <para id="x_5f3">Options:</para>
 1.16059 +      <itemizedlist>
 1.16060 +	<listitem><para id="x_5f4"><option role="hg-ext-mq-cmd-qfold-opt">-e</option>: Edit the
 1.16061 +	    commit message and patch description for the newly folded
 1.16062 +	    patch.</para>
 1.16063 +	</listitem>
 1.16064 +	<listitem><para id="x_5f5"><option role="hg-ext-mq-cmd-qfold-opt">-l</option>: Use the
 1.16065 +	    contents of the given file as the new commit message and
 1.16066 +	    patch description for the folded patch.</para>
 1.16067 +	</listitem>
 1.16068 +	<listitem><para id="x_5f6"><option role="hg-ext-mq-cmd-qfold-opt">-m</option>: Use the
 1.16069 +	    given text as the new commit message and patch description
 1.16070 +	    for the folded patch.</para>
 1.16071 +	</listitem></itemizedlist>
 1.16072 +
 1.16073 +    </sect2>
 1.16074 +    <sect2>
 1.16075 +      <title><command role="hg-ext-mq" moreinfo="none">qheader</command>—display the
 1.16076 +	header/description of a patch</title>
 1.16077 +
 1.16078 +      <para id="x_5f7">The <command role="hg-ext-mq" moreinfo="none">qheader</command> command
 1.16079 +	prints the header, or description, of a patch.  By default, it
 1.16080 +	prints the header of the topmost applied patch. Given an
 1.16081 +	argument, it prints the header of the named patch.</para>
 1.16082 +
 1.16083 +    </sect2>
 1.16084 +    <sect2>
 1.16085 +      <title><command role="hg-ext-mq" moreinfo="none">qimport</command>—import
 1.16086 +	a third-party patch into the queue</title>
 1.16087 +
 1.16088 +      <para id="x_5f8">The <command role="hg-ext-mq" moreinfo="none">qimport</command> command
 1.16089 +	adds an entry for an external patch to the <filename role="special" moreinfo="none">series</filename> file, and copies the patch
 1.16090 +	into the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory.  It adds
 1.16091 +	the entry immediately after the topmost applied patch, but
 1.16092 +	does not push the patch.</para>
 1.16093 +
 1.16094 +      <para id="x_5f9">If the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory is a
 1.16095 +	repository, <command role="hg-ext-mq" moreinfo="none">qimport</command>
 1.16096 +	automatically does an <command role="hg-cmd" moreinfo="none">hg add</command>
 1.16097 +	of the imported patch.</para>
 1.16098 +
 1.16099 +    </sect2>
 1.16100 +    <sect2>
 1.16101 +      <title><command role="hg-ext-mq" moreinfo="none">qinit</command>—prepare
 1.16102 +	a repository to work with MQ</title>
 1.16103 +
 1.16104 +      <para id="x_5fa">The <command role="hg-ext-mq" moreinfo="none">qinit</command> command
 1.16105 +	prepares a repository to work with MQ.  It creates a directory
 1.16106 +	called <filename role="special" class="directory" moreinfo="none">.hg/patches</filename>.</para>
 1.16107 +
 1.16108 +      <para id="x_5fb">Options:</para>
 1.16109 +      <itemizedlist>
 1.16110 +	<listitem><para id="x_5fc"><option role="hg-ext-mq-cmd-qinit-opt">-c</option>: Create
 1.16111 +	    <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> as a repository
 1.16112 +	    in its own right.  Also creates a <filename role="special" moreinfo="none">.hgignore</filename> file that will
 1.16113 +	    ignore the <filename role="special" moreinfo="none">status</filename>
 1.16114 +	    file.</para>
 1.16115 +	</listitem></itemizedlist>
 1.16116 +
 1.16117 +      <para id="x_5fd">When the <filename role="special" class="directory" moreinfo="none">.hg/patches</filename> directory is a
 1.16118 +	repository, the <command role="hg-ext-mq" moreinfo="none">qimport</command>
 1.16119 +	and <command role="hg-ext-mq" moreinfo="none">qnew</command> commands
 1.16120 +	automatically <command role="hg-cmd" moreinfo="none">hg add</command> new
 1.16121 +	patches.</para>
 1.16122 +
 1.16123 +    </sect2>
 1.16124 +    <sect2>
 1.16125 +      <title><command role="hg-ext-mq" moreinfo="none">qnew</command>—create a
 1.16126 +	new patch</title>
 1.16127 +
 1.16128 +      <para id="x_5fe">The <command role="hg-ext-mq" moreinfo="none">qnew</command> command
 1.16129 +	creates a new patch.  It takes one mandatory argument, the
 1.16130 +	name to use for the patch file.  The newly created patch is
 1.16131 +	created empty by default.  It is added to the <filename role="special" moreinfo="none">series</filename> file after the current
 1.16132 +	topmost applied patch, and is immediately pushed on top of
 1.16133 +	that patch.</para>
 1.16134 +
 1.16135 +      <para id="x_5ff">If <command role="hg-ext-mq" moreinfo="none">qnew</command> finds modified
 1.16136 +	files in the working directory, it will refuse to create a new
 1.16137 +	patch unless the <option role="hg-ext-mq-cmd-qnew-opt">-f</option> option is used
 1.16138 +	(see below).  This behavior allows you to <command role="hg-ext-mq" moreinfo="none">qrefresh</command> your topmost applied
 1.16139 +	patch before you apply a new patch on top of it.</para>
 1.16140 +
 1.16141 +      <para id="x_600">Options:</para>
 1.16142 +      <itemizedlist>
 1.16143 +	<listitem><para id="x_601"><option role="hg-ext-mq-cmd-qnew-opt">-f</option>: Create a new
 1.16144 +	    patch if the contents of the working directory are
 1.16145 +	    modified.  Any outstanding modifications are added to the
 1.16146 +	    newly created patch, so after this command completes, the
 1.16147 +	    working directory will no longer be modified.</para>
 1.16148 +	</listitem>
 1.16149 +	<listitem><para id="x_602"><option role="hg-ext-mq-cmd-qnew-opt">-m</option>: Use the given
 1.16150 +	    text as the commit message. This text will be stored at
 1.16151 +	    the beginning of the patch file, before the patch
 1.16152 +	    data.</para>
 1.16153 +	</listitem></itemizedlist>
 1.16154 +
 1.16155 +    </sect2>
 1.16156 +    <sect2>
 1.16157 +      <title><command role="hg-ext-mq" moreinfo="none">qnext</command>—print
 1.16158 +	the name of the next patch</title>
 1.16159 +
 1.16160 +      <para id="x_603">The <command role="hg-ext-mq" moreinfo="none">qnext</command> command
 1.16161 +	prints the name name of the next patch in the <filename role="special" moreinfo="none">series</filename> file after the topmost
 1.16162 +	applied patch.  This patch will become the topmost applied
 1.16163 +	patch if you run <command role="hg-ext-mq" moreinfo="none">qpush</command>.</para>
 1.16164 +
 1.16165 +    </sect2>
 1.16166 +    <sect2>
 1.16167 +      <title><command role="hg-ext-mq" moreinfo="none">qpop</command>—pop
 1.16168 +	patches off the stack</title>
 1.16169 +
 1.16170 +      <para id="x_604">The <command role="hg-ext-mq" moreinfo="none">qpop</command> command
 1.16171 +	removes applied patches from the top of the stack of applied
 1.16172 +	patches.  By default, it removes only one patch.</para>
 1.16173 +
 1.16174 +      <para id="x_605">This command removes the changesets that represent the
 1.16175 +	popped patches from the repository, and updates the working
 1.16176 +	directory to undo the effects of the patches.</para>
 1.16177 +
 1.16178 +      <para id="x_606">This command takes an optional argument, which it uses as
 1.16179 +	the name or index of the patch to pop to.  If given a name, it
 1.16180 +	will pop patches until the named patch is the topmost applied
 1.16181 +	patch.  If given a number, <command role="hg-ext-mq" moreinfo="none">qpop</command> treats the number as an
 1.16182 +	index into the entries in the series file, counting from zero
 1.16183 +	(empty lines and lines containing only comments do not count).
 1.16184 +	It pops patches until the patch identified by the given index
 1.16185 +	is the topmost applied patch.</para>
 1.16186 +
 1.16187 +      <para id="x_607">The <command role="hg-ext-mq" moreinfo="none">qpop</command> command does
 1.16188 +	not read or write patches or the <filename role="special" moreinfo="none">series</filename> file.  It is thus safe to
 1.16189 +	<command role="hg-ext-mq" moreinfo="none">qpop</command> a patch that you have
 1.16190 +	removed from the <filename role="special" moreinfo="none">series</filename>
 1.16191 +	file, or a patch that you have renamed or deleted entirely.
 1.16192 +	In the latter two cases, use the name of the patch as it was
 1.16193 +	when you applied it.</para>
 1.16194 +
 1.16195 +      <para id="x_608">By default, the <command role="hg-ext-mq" moreinfo="none">qpop</command>
 1.16196 +	command will not pop any patches if the working directory has
 1.16197 +	been modified.  You can override this behavior using the
 1.16198 +	<option role="hg-ext-mq-cmd-qpop-opt">-f</option> option,
 1.16199 +	which reverts all modifications in the working
 1.16200 +	directory.</para>
 1.16201 +
 1.16202 +      <para id="x_609">Options:</para>
 1.16203 +      <itemizedlist>
 1.16204 +	<listitem><para id="x_60a"><option role="hg-ext-mq-cmd-qpop-opt">-a</option>: Pop all
 1.16205 +	    applied patches.  This returns the repository to its state
 1.16206 +	    before you applied any patches.</para>
 1.16207 +	</listitem>
 1.16208 +	<listitem><para id="x_60b"><option role="hg-ext-mq-cmd-qpop-opt">-f</option>: Forcibly
 1.16209 +	    revert any modifications to the working directory when
 1.16210 +	    popping.</para>
 1.16211 +	</listitem>
 1.16212 +	<listitem><para id="x_60c"><option role="hg-ext-mq-cmd-qpop-opt">-n</option>: Pop a patch
 1.16213 +	    from the named queue.</para>
 1.16214 +	</listitem></itemizedlist>
 1.16215 +
 1.16216 +      <para id="x_60d">The <command role="hg-ext-mq" moreinfo="none">qpop</command> command
 1.16217 +	removes one line from the end of the <filename role="special" moreinfo="none">status</filename> file for each patch that it
 1.16218 +	pops.</para>
 1.16219 +
 1.16220 +    </sect2>
 1.16221 +    <sect2>
 1.16222 +      <title><command role="hg-ext-mq" moreinfo="none">qprev</command>—print
 1.16223 +	the name of the previous patch</title>
 1.16224 +
 1.16225 +      <para id="x_60e">The <command role="hg-ext-mq" moreinfo="none">qprev</command> command
 1.16226 +	prints the name of the patch in the <filename role="special" moreinfo="none">series</filename> file that comes before the
 1.16227 +	topmost applied patch. This will become the topmost applied
 1.16228 +	patch if you run <command role="hg-ext-mq" moreinfo="none">qpop</command>.</para>
 1.16229 +
 1.16230 +    </sect2>
 1.16231 +    <sect2 id="sec:mqref:cmd:qpush">
 1.16232 +      <title><command role="hg-ext-mq" moreinfo="none">qpush</command>—push
 1.16233 +	patches onto the stack</title>
 1.16234 +
 1.16235 +      <para id="x_60f">The <command role="hg-ext-mq" moreinfo="none">qpush</command> command adds
 1.16236 +	patches onto the applied stack.  By default, it adds only one
 1.16237 +	patch.</para>
 1.16238 +
 1.16239 +      <para id="x_610">This command creates a new changeset to represent each
 1.16240 +	applied patch, and updates the working directory to apply the
 1.16241 +	effects of the patches.</para>
 1.16242 +
 1.16243 +      <para id="x_611">The default data used when creating a changeset are as
 1.16244 +	follows:</para>
 1.16245 +      <itemizedlist>
 1.16246 +	<listitem><para id="x_612">The commit date and time zone are the current
 1.16247 +	    date and time zone.  Because these data are used to
 1.16248 +	    compute the identity of a changeset, this means that if
 1.16249 +	    you <command role="hg-ext-mq" moreinfo="none">qpop</command> a patch and
 1.16250 +	    <command role="hg-ext-mq" moreinfo="none">qpush</command> it again, the
 1.16251 +	    changeset that you push will have a different identity
 1.16252 +	    than the changeset you popped.</para>
 1.16253 +	</listitem>
 1.16254 +	<listitem><para id="x_613">The author is the same as the default used by
 1.16255 +	    the <command role="hg-cmd" moreinfo="none">hg commit</command>
 1.16256 +	    command.</para>
 1.16257 +	</listitem>
 1.16258 +	<listitem><para id="x_614">The commit message is any text from the patch
 1.16259 +	    file that comes before the first diff header.  If there is
 1.16260 +	    no such text, a default commit message is used that
 1.16261 +	    identifies the name of the patch.</para>
 1.16262 +	</listitem></itemizedlist>
 1.16263 +      <para id="x_615">If a patch contains a Mercurial patch header,
 1.16264 +	the information in the patch header overrides these
 1.16265 +	defaults.</para>
 1.16266 +
 1.16267 +      <para id="x_616">Options:</para>
 1.16268 +      <itemizedlist>
 1.16269 +	<listitem><para id="x_617"><option role="hg-ext-mq-cmd-qpush-opt">-a</option>: Push all
 1.16270 +	    unapplied patches from the <filename role="special" moreinfo="none">series</filename> file until there are
 1.16271 +	    none left to push.</para>
 1.16272 +	</listitem>
 1.16273 +	<listitem><para id="x_618"><option role="hg-ext-mq-cmd-qpush-opt">-l</option>: Add the name
 1.16274 +	    of the patch to the end of the commit message.</para>
 1.16275 +	</listitem>
 1.16276 +	<listitem><para id="x_619"><option role="hg-ext-mq-cmd-qpush-opt">-m</option>: If a patch
 1.16277 +	    fails to apply cleanly, use the entry for the patch in
 1.16278 +	    another saved queue to compute the parameters for a
 1.16279 +	    three-way merge, and perform a three-way merge using the
 1.16280 +	    normal Mercurial merge machinery.  Use the resolution of
 1.16281 +	    the merge as the new patch content.</para>
 1.16282 +	</listitem>
 1.16283 +	<listitem><para id="x_61a"><option role="hg-ext-mq-cmd-qpush-opt">-n</option>: Use the
 1.16284 +	    named queue if merging while pushing.</para>
 1.16285 +	</listitem></itemizedlist>
 1.16286 +
 1.16287 +      <para id="x_61b">The <command role="hg-ext-mq" moreinfo="none">qpush</command> command
 1.16288 +	reads, but does not modify, the <filename role="special" moreinfo="none">series</filename> file.  It appends one line
 1.16289 +	to the <command role="hg-cmd" moreinfo="none">hg status</command> file for
 1.16290 +	each patch that it pushes.</para>
 1.16291 +
 1.16292 +    </sect2>
 1.16293 +    <sect2>
 1.16294 +      <title><command role="hg-ext-mq" moreinfo="none">qrefresh</command>—update the
 1.16295 +	topmost applied patch</title>
 1.16296 +
 1.16297 +      <para id="x_61c">The <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 1.16298 +	updates the topmost applied patch.  It modifies the patch,
 1.16299 +	removes the old changeset that represented the patch, and
 1.16300 +	creates a new changeset to represent the modified
 1.16301 +	patch.</para>
 1.16302 +
 1.16303 +      <para id="x_61d">The <command role="hg-ext-mq" moreinfo="none">qrefresh</command> command
 1.16304 +	looks for the following modifications:</para>
 1.16305 +      <itemizedlist>
 1.16306 +	<listitem><para id="x_61e">Changes to the commit message, i.e. the text
 1.16307 +	    before the first diff header in the patch file, are
 1.16308 +	    reflected in the new changeset that represents the
 1.16309 +	    patch.</para>
 1.16310 +	</listitem>
 1.16311 +	<listitem><para id="x_61f">Modifications to tracked files in the working
 1.16312 +	    directory are added to the patch.</para>
 1.16313 +	</listitem>
 1.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
 1.16315 +	    and rename destinations are added to the patch, while
 1.16316 +	    removed files and rename sources are removed.</para>
 1.16317 +	</listitem></itemizedlist>
 1.16318 +
 1.16319 +      <para id="x_621">Even if <command role="hg-ext-mq" moreinfo="none">qrefresh</command>
 1.16320 +	detects no changes, it still recreates the changeset that
 1.16321 +	represents the patch.  This causes the identity of the
 1.16322 +	changeset to differ from the previous changeset that
 1.16323 +	identified the patch.</para>
 1.16324 +
 1.16325 +      <para id="x_622">Options:</para>
 1.16326 +      <itemizedlist>
 1.16327 +	<listitem><para id="x_623"><option role="hg-ext-mq-cmd-qrefresh-opt">-e</option>: Modify
 1.16328 +	    the commit and patch description, using the preferred text
 1.16329 +	    editor.</para>
 1.16330 +	</listitem>
 1.16331 +	<listitem><para id="x_624"><option role="hg-ext-mq-cmd-qrefresh-opt">-m</option>: Modify
 1.16332 +	    the commit message and patch description, using the given
 1.16333 +	    text.</para>
 1.16334 +	</listitem>
 1.16335 +	<listitem><para id="x_625"><option role="hg-ext-mq-cmd-qrefresh-opt">-l</option>: Modify
 1.16336 +	    the commit message and patch description, using text from
 1.16337 +	    the given file.</para>
 1.16338 +	</listitem></itemizedlist>
 1.16339 +
 1.16340 +    </sect2>
 1.16341 +    <sect2>
 1.16342 +      <title><command role="hg-ext-mq" moreinfo="none">qrename</command>—rename
 1.16343 +	a patch</title>
 1.16344 +
 1.16345 +      <para id="x_626">The <command role="hg-ext-mq" moreinfo="none">qrename</command> command
 1.16346 +	renames a patch, and changes the entry for the patch in the
 1.16347 +	<filename role="special" moreinfo="none">series</filename> file.</para>
 1.16348 +
 1.16349 +      <para id="x_627">With a single argument, <command role="hg-ext-mq" moreinfo="none">qrename</command> renames the topmost
 1.16350 +	applied patch.  With two arguments, it renames its first
 1.16351 +	argument to its second.</para>
 1.16352 +
 1.16353 +    </sect2>
 1.16354 +    <sect2>
 1.16355 +      <title><command role="hg-ext-mq" moreinfo="none">qseries</command>—print
 1.16356 +	the entire patch series</title>
 1.16357 +
 1.16358 +      <para id="x_62a">The <command role="hg-ext-mq" moreinfo="none">qseries</command> command
 1.16359 +	prints the entire patch series from the <filename role="special" moreinfo="none">series</filename> file.  It prints only patch
 1.16360 +	names, not empty lines or comments.  It prints in order from
 1.16361 +	first to be applied to last.</para>
 1.16362 +
 1.16363 +    </sect2>
 1.16364 +    <sect2>
 1.16365 +      <title><command role="hg-ext-mq" moreinfo="none">qtop</command>—print the
 1.16366 +	name of the current patch</title>
 1.16367 +
 1.16368 +      <para id="x_62b">The <command role="hg-ext-mq" moreinfo="none">qtop</command> prints the
 1.16369 +	name of the topmost currently applied patch.</para>
 1.16370 +
 1.16371 +    </sect2>
 1.16372 +    <sect2>
 1.16373 +      <title><command role="hg-ext-mq" moreinfo="none">qunapplied</command>—print patches
 1.16374 +	not yet applied</title>
 1.16375 +
 1.16376 +      <para id="x_62c">The <command role="hg-ext-mq" moreinfo="none">qunapplied</command> command
 1.16377 +	prints the names of patches from the <filename role="special" moreinfo="none">series</filename> file that are not yet
 1.16378 +	applied.  It prints them in order from the next patch that
 1.16379 +	will be pushed to the last.</para>
 1.16380 +
 1.16381 +    </sect2>
 1.16382 +    <sect2>
 1.16383 +      <title><command role="hg-cmd" moreinfo="none">hg strip</command>—remove a
 1.16384 +	revision and descendants</title>
 1.16385 +
 1.16386 +      <para id="x_62d">The <command role="hg-cmd" moreinfo="none">hg strip</command> command
 1.16387 +	removes a revision, and all of its descendants, from the
 1.16388 +	repository.  It undoes the effects of the removed revisions
 1.16389 +	from the repository, and updates the working directory to the
 1.16390 +	first parent of the removed revision.</para>
 1.16391 +
 1.16392 +      <para id="x_62e">The <command role="hg-cmd" moreinfo="none">hg strip</command> command
 1.16393 +	saves a backup of the removed changesets in a bundle, so that
 1.16394 +	they can be reapplied if removed in error.</para>
 1.16395 +
 1.16396 +      <para id="x_62f">Options:</para>
 1.16397 +      <itemizedlist>
 1.16398 +	<listitem><para id="x_630"><option role="hg-opt-strip">-b</option>: Save
 1.16399 +	    unrelated changesets that are intermixed with the stripped
 1.16400 +	    changesets in the backup bundle.</para>
 1.16401 +	</listitem>
 1.16402 +	<listitem><para id="x_631"><option role="hg-opt-strip">-f</option>: If a
 1.16403 +	    branch has multiple heads, remove all heads.</para>
 1.16404 +	</listitem>
 1.16405 +	<listitem><para id="x_632"><option role="hg-opt-strip">-n</option>: Do
 1.16406 +	    not save a backup bundle.</para>
 1.16407 +	</listitem></itemizedlist>
 1.16408 +
 1.16409 +    </sect2>
 1.16410 +  </sect1>
 1.16411 +  <sect1>
 1.16412 +    <title>MQ file reference</title>
 1.16413 +
 1.16414 +    <sect2>
 1.16415 +      <title>The <filename role="special" moreinfo="none">series</filename>
 1.16416 +	file</title>
 1.16417 +
 1.16418 +      <para id="x_633">The <filename role="special" moreinfo="none">series</filename> file
 1.16419 +	contains a list of the names of all patches that MQ can apply.
 1.16420 +	It is represented as a list of names, with one name saved per
 1.16421 +	line.  Leading and trailing white space in each line are
 1.16422 +	ignored.</para>
 1.16423 +
 1.16424 +      <para id="x_634">Lines may contain comments.  A comment begins with the
 1.16425 +	<quote><literal moreinfo="none">#</literal></quote> character, and extends to
 1.16426 +	the end of the line.  Empty lines, and lines that contain only
 1.16427 +	comments, are ignored.</para>
 1.16428 +
 1.16429 +      <para id="x_635">You will often need to edit the <filename role="special" moreinfo="none">series</filename> file by hand, hence the
 1.16430 +	support for comments and empty lines noted above.  For
 1.16431 +	example, you can comment out a patch temporarily, and <command role="hg-ext-mq" moreinfo="none">qpush</command> will skip over that patch
 1.16432 +	when applying patches.  You can also change the order in which
 1.16433 +	patches are applied by reordering their entries in the
 1.16434 +	<filename role="special" moreinfo="none">series</filename> file.</para>
 1.16435 +
 1.16436 +      <para id="x_636">Placing the <filename role="special" moreinfo="none">series</filename>
 1.16437 +	file under revision control is also supported; it is a good
 1.16438 +	idea to place all of the patches that it refers to under
 1.16439 +	revision control, as well.  If you create a patch directory
 1.16440 +	using the <option role="hg-ext-mq-cmd-qinit-opt">-c</option>
 1.16441 +	option to <command role="hg-ext-mq" moreinfo="none">qinit</command>, this will
 1.16442 +	be done for you automatically.</para>
 1.16443 +
 1.16444 +    </sect2>
 1.16445 +    <sect2>
 1.16446 +      <title>The <filename role="special" moreinfo="none">status</filename>
 1.16447 +	file</title>
 1.16448 +
 1.16449 +      <para id="x_637">The <filename role="special" moreinfo="none">status</filename> file
 1.16450 +	contains the names and changeset hashes of all patches that MQ
 1.16451 +	currently has applied.  Unlike the <filename role="special" moreinfo="none">series</filename> file, this file is not
 1.16452 +	intended for editing.  You should not place this file under
 1.16453 +	revision control, or modify it in any way.  It is used by MQ
 1.16454 +	strictly for internal book-keeping.</para>
 1.16455 +
 1.16456 +    </sect2>
 1.16457 +  </sect1>
 1.16458 +</appendix>
 1.16459 +
 1.16460 +<!--
 1.16461 +local variables: 
 1.16462 +sgml-parent-document: ("00book.xml" "book" "appendix")
 1.16463 +end:
 1.16464 +-->
 1.16465 +
 1.16466 +  <!-- BEGIN appC -->
 1.16467 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.16468 +
 1.16469 +<appendix id="chap:srcinstall">
 1.16470 +  <?dbhtml filename="installing-mercurial-from-source.html"?>
 1.16471 +  <title>Installer Mercurial à partir des sources</title>
 1.16472 +
 1.16473 +  <sect1 id="sec:srcinstall:unixlike">
 1.16474 +    <title>Pour un système Unix ou similaire</title>
 1.16475 +
 1.16476 +    <para id="x_5e0">Si vous utilisez un système Unix ou similaire, pour lequel
 1.16477 +      une version récente de Python (2.3 ou plus) est disponible, l'installation
 1.16478 +      de Mercurial à partir des sources est simple.</para>
 1.16479 +    <orderedlist inheritnum="ignore" continuation="restarts">
 1.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>
 1.16481 +      </listitem>
 1.16482 +      <listitem><para id="x_5e2">Extrayez le paquet : </para>
 1.16483 +	<programlisting format="linespecific">gzip -dc mercurial-MYVERSION.tar.gz | tar xf -</programlisting>
 1.16484 +      </listitem>
 1.16485 +      <listitem><para id="x_5e3">Allez dans le répertoires où les sources ont
 1.16486 +    été extraites et exécutez le script d'installation. Ce dernier compilera
 1.16487 +    Mercurial et l'installera dans votre répertoire utilisateur.</para>
 1.16488 +	<programlisting format="linespecific">cd mercurial-MYVERSION
 1.16489 +python setup.py install --force --home=$HOME</programlisting>
 1.16490 +      </listitem>
 1.16491 +    </orderedlist>
 1.16492 +    <para id="x_5e4">Lorsque l'installation est terminée, Mercurial se
 1.16493 +      trouvera dans le répertoire <literal moreinfo="none">bin</literal> de votre répertoire
 1.16494 +      utilisateur.
 1.16495 +      N'oubliez pas de vérifier que ce répertoire se trouve dans la liste
 1.16496 +      des répertoires où votre shell recherche les exécutables.</para>
 1.16497 +
 1.16498 +    <para id="x_5e5">Vous devrez vraisemblablement définir la variable
 1.16499 +      d'environnement <envar>PYTHONPATH</envar> de manière à ce que
 1.16500 +      l'exécutable de Mercurial puisse trouver le reste des paquets logiciels.
 1.16501 +      Par exemple, sur mon ordinateur portable, je dois le définir ainsi:
 1.16502 +      <literal moreinfo="none">/home/bos/lib/python</literal>. Le chemin exact à utiliser
 1.16503 +      dépendra de la manière dont Python aura été construit pour votre 
 1.16504 +      système. Il ne devrait pas être difficile de le trouver. En cas de
 1.16505 +      doute, lisez le texte généré lors de l'installation ci-dessus, et
 1.16506 +      recherchez l'emplacement où le contenu du répertoire
 1.16507 +      <literal moreinfo="none">mercurial</literal> a été installé.</para>
 1.16508 +
 1.16509 +  </sect1>
 1.16510 +  <sect1>
 1.16511 +    <title>Pour Windows</title>
 1.16512 +
 1.16513 +    <para id="x_5e6">Construire et installer Mercurial sous Windows nécessite
 1.16514 +      des outils logiciels divers, une certaine connaissance technique et une
 1.16515 +      bonne dose de patience. Je vous <emphasis>déconseille fortement</emphasis> 
 1.16516 +      de tenter de le faire si vous êtes un <quote>simple utilisateur</quote>.
 1.16517 +      A moins que vous n'ayez l'intention de "hacker" Mercurial, je vous
 1.16518 +      suggère d'avoir recours à un paquet d'installation de la version binaire.</para>
 1.16519 +
 1.16520 +    <para id="x_5e7">Si vous avez vraiment l'intention de construire
 1.16521 +      Mercurial à partir des sources sous Windows, suivez les indications pour 
 1.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>, 
 1.16523 +      et préparez vous à un travail épineux.</para>
 1.16524 +
 1.16525 +  </sect1>
 1.16526 +</appendix>
 1.16527 +
 1.16528 +<!--
 1.16529 +local variables: 
 1.16530 +sgml-parent-document: ("00book.xml" "book" "appendix")
 1.16531 +end:
 1.16532 +-->
 1.16533 +
 1.16534 +  <!-- BEGIN appD -->
 1.16535 +  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 1.16536 +
 1.16537 +<appendix id="cha:opl">
 1.16538 +  <?dbhtml filename="open-publication-license.html"?>
 1.16539 +  <title>Open Publication License</title>
 1.16540 +
 1.16541 +  <para id="x_638">Version 1.0, 8 June 1999</para>
 1.16542 +
 1.16543 +  <sect1>
 1.16544 +    <title>Requirements on both unmodified and modified
 1.16545 +      versions</title>
 1.16546 +
 1.16547 +    <para id="x_639">The Open Publication works may be reproduced and distributed
 1.16548 +      in whole or in part, in any medium physical or electronic,
 1.16549 +      provided that the terms of this license are adhered to, and that
 1.16550 +      this license or an incorporation of it by reference (with any
 1.16551 +      options elected by the author(s) and/or publisher) is displayed
 1.16552 +      in the reproduction.</para>
 1.16553 +
 1.16554 +    <para id="x_63a">Proper form for an incorporation by reference is as
 1.16555 +      follows:</para>
 1.16556 +
 1.16557 +    <blockquote>
 1.16558 +      <para id="x_63b">  Copyright (c) <emphasis>year</emphasis> by
 1.16559 +	<emphasis>author's name or designee</emphasis>. This material
 1.16560 +	may be distributed only subject to the terms and conditions
 1.16561 +	set forth in the Open Publication License,
 1.16562 +	v<emphasis>x.y</emphasis> or later (the latest version is
 1.16563 +	presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
 1.16564 +    </blockquote>
 1.16565 +
 1.16566 +    <para id="x_63c">The reference must be immediately followed with any options
 1.16567 +      elected by the author(s) and/or publisher of the document (see
 1.16568 +      <xref linkend="sec:opl:options"/>).</para>
 1.16569 +
 1.16570 +    <para id="x_63d">Commercial redistribution of Open Publication-licensed
 1.16571 +      material is permitted.</para>
 1.16572 +
 1.16573 +    <para id="x_63e">Any publication in standard (paper) book form shall require
 1.16574 +      the citation of the original publisher and author. The publisher
 1.16575 +      and author's names shall appear on all outer surfaces of the
 1.16576 +      book. On all outer surfaces of the book the original publisher's
 1.16577 +      name shall be as large as the title of the work and cited as
 1.16578 +      possessive with respect to the title.</para>
 1.16579 +
 1.16580 +  </sect1>
 1.16581 +  <sect1>
 1.16582 +    <title>Copyright</title>
 1.16583 +
 1.16584 +    <para id="x_63f">The copyright to each Open Publication is owned by its
 1.16585 +      author(s) or designee.</para>
 1.16586 +
 1.16587 +  </sect1>
 1.16588 +  <sect1>
 1.16589 +    <title>Scope of license</title>
 1.16590 +
 1.16591 +    <para id="x_640">The following license terms apply to all Open Publication
 1.16592 +      works, unless otherwise explicitly stated in the
 1.16593 +      document.</para>
 1.16594 +
 1.16595 +    <para id="x_641">Mere aggregation of Open Publication works or a portion of
 1.16596 +      an Open Publication work with other works or programs on the
 1.16597 +      same media shall not cause this license to apply to those other
 1.16598 +      works. The aggregate work shall contain a notice specifying the
 1.16599 +      inclusion of the Open Publication material and appropriate
 1.16600 +      copyright notice.</para>
 1.16601 +
 1.16602 +    <para id="x_642"><emphasis role="bold">Severability</emphasis>. If any part
 1.16603 +      of this license is found to be unenforceable in any
 1.16604 +      jurisdiction, the remaining portions of the license remain in
 1.16605 +      force.</para>
 1.16606 +
 1.16607 +    <para id="x_643"><emphasis role="bold">No warranty</emphasis>. Open
 1.16608 +      Publication works are licensed and provided <quote>as is</quote>
 1.16609 +      without warranty of any kind, express or implied, including, but
 1.16610 +      not limited to, the implied warranties of merchantability and
 1.16611 +      fitness for a particular purpose or a warranty of
 1.16612 +      non-infringement.</para>
 1.16613 +
 1.16614 +  </sect1>
 1.16615 +  <sect1>
 1.16616 +    <title>Requirements on modified works</title>
 1.16617 +
 1.16618 +    <para id="x_644">All modified versions of documents covered by this license,
 1.16619 +      including translations, anthologies, compilations and partial
 1.16620 +      documents, must meet the following requirements:</para>
 1.16621 +
 1.16622 +    <orderedlist inheritnum="ignore" continuation="restarts">
 1.16623 +      <listitem><para id="x_645">The modified version must be labeled as
 1.16624 +	  such.</para>
 1.16625 +      </listitem>
 1.16626 +      <listitem><para id="x_646">The person making the modifications must be
 1.16627 +	  identified and the modifications dated.</para>
 1.16628 +      </listitem>
 1.16629 +      <listitem><para id="x_647">Acknowledgement of the original author and
 1.16630 +	  publisher if applicable must be retained according to normal
 1.16631 +	  academic citation practices.</para>
 1.16632 +      </listitem>
 1.16633 +      <listitem><para id="x_648">The location of the original unmodified document
 1.16634 +	  must be identified.</para>
 1.16635 +      </listitem>
 1.16636 +      <listitem><para id="x_649">The original author's (or authors') name(s) may
 1.16637 +	  not be used to assert or imply endorsement of the resulting
 1.16638 +	  document without the original author's (or authors')
 1.16639 +	  permission.</para>
 1.16640 +      </listitem></orderedlist>
 1.16641 +
 1.16642 +  </sect1>
 1.16643 +  <sect1>
 1.16644 +    <title>Good-practice recommendations</title>
 1.16645 +
 1.16646 +    <para id="x_64a">In addition to the requirements of this license, it is
 1.16647 +      requested from and strongly recommended of redistributors
 1.16648 +      that:</para>
 1.16649 +
 1.16650 +    <orderedlist inheritnum="ignore" continuation="restarts">
 1.16651 +      <listitem><para id="x_64b">If you are distributing Open Publication works
 1.16652 +	  on hardcopy or CD-ROM, you provide email notification to the
 1.16653 +	  authors of your intent to redistribute at least thirty days
 1.16654 +	  before your manuscript or media freeze, to give the authors
 1.16655 +	  time to provide updated documents. This notification should
 1.16656 +	  describe modifications, if any, made to the document.</para>
 1.16657 +      </listitem>
 1.16658 +      <listitem><para id="x_64c">All substantive modifications (including
 1.16659 +	  deletions) be either clearly marked up in the document or
 1.16660 +	  else described in an attachment to the document.</para>
 1.16661 +      </listitem>
 1.16662 +      <listitem><para id="x_64d">Finally, while it is not mandatory under this
 1.16663 +	  license, it is considered good form to offer a free copy of
 1.16664 +	  any hardcopy and CD-ROM expression of an Open
 1.16665 +	  Publication-licensed work to its author(s).</para>
 1.16666 +      </listitem></orderedlist>
 1.16667 +
 1.16668 +  </sect1>
 1.16669 +  <sect1 id="sec:opl:options">
 1.16670 +    <title>License options</title>
 1.16671 +
 1.16672 +    <para id="x_64e">The author(s) and/or publisher of an Open
 1.16673 +      Publication-licensed document may elect certain options by
 1.16674 +      appending language to the reference to or copy of the license.
 1.16675 +      These options are considered part of the license instance and
 1.16676 +      must be included with the license (or its incorporation by
 1.16677 +      reference) in derived works.</para>
 1.16678 +
 1.16679 +    <orderedlist inheritnum="ignore" continuation="restarts">
 1.16680 +      <listitem><para id="x_64f">To prohibit distribution of substantively
 1.16681 +	  modified versions without the explicit permission of the
 1.16682 +	  author(s). <quote>Substantive modification</quote> is
 1.16683 +	  defined as a change to the semantic content of the document,
 1.16684 +	  and excludes mere changes in format or typographical
 1.16685 +	  corrections.</para>
 1.16686 +      </listitem>
 1.16687 +      <listitem><para id="x_650">  To accomplish this, add the phrase
 1.16688 +	  <quote>Distribution of substantively modified versions of
 1.16689 +	    this document is prohibited without the explicit
 1.16690 +	    permission of the copyright holder.</quote> to the license
 1.16691 +	  reference or copy.</para>
 1.16692 +      </listitem>
 1.16693 +      <listitem><para id="x_651">To prohibit any publication of this work or
 1.16694 +	  derivative works in whole or in part in standard (paper)
 1.16695 +	  book form for commercial purposes is prohibited unless prior
 1.16696 +	  permission is obtained from the copyright holder.</para>
 1.16697 +      </listitem>
 1.16698 +      <listitem><para id="x_652">To accomplish this, add the phrase
 1.16699 +	  <quote>Distribution of the work or derivative of the work in
 1.16700 +	    any standard (paper) book form is prohibited unless prior
 1.16701 +	    permission is obtained from the copyright holder.</quote>
 1.16702 +	  to the license reference or copy.</para>
 1.16703 +      </listitem></orderedlist>
 1.16704 +
 1.16705 +  </sect1>
 1.16706 +</appendix>
 1.16707 +
 1.16708 +<!--
 1.16709 +local variables: 
 1.16710 +sgml-parent-document: ("00book.xml" "book" "appendix")
 1.16711 +end:
 1.16712 +-->
 1.16713 +
 1.16714 +</book>