hgbook

changeset 964:6b680d569bb4

deleting a bunch of files not longer necessary to build the documentation.
Adding missing newly files needed to build the documentation
author Romain PELISSE <belaran@gmail.com>
date Sun Aug 16 04:58:01 2009 +0200 (2009-08-16)
parents 1dd00abb3fa9
children 1421a5493113
files fr/00book.tex fr/00book.xml fr/99book.bib fr/99defs.tex fr/appA-svn.xml fr/appB-mq-ref.xml fr/appC-srcinstall.xml fr/appD-license.xml fr/autoid.py fr/book-shortcuts.xml fr/bookhtml.cfg fr/branch.tex fr/ch00-preface.xml fr/ch01-intro.xml fr/ch02-tour-basic.xml fr/ch03-tour-merge.xml fr/ch04-concepts.xml fr/ch05-daily.xml fr/ch06-collab.xml fr/ch07-filenames.xml fr/ch08-branch.xml fr/ch09-undo.xml fr/ch10-hook.xml fr/ch11-template.xml fr/ch12-mq.xml fr/ch13-mq-collab.xml fr/ch14-hgext.xml fr/cmdref.tex fr/collab.tex fr/concepts.tex fr/daily.tex fr/examples/auto-snippets.xml fr/examples/data/check_whitespace.py fr/examples/hook.ws fr/feature-branches.dot fr/figs/bad-merge-1.dot fr/figs/bad-merge-2.dot fr/figs/bad-merge-3.dot fr/figs/bad-merge-4.dot fr/figs/bad-merge-5.dot fr/figs/caution.png fr/figs/feature-branches.dot fr/figs/filelog.svg fr/figs/kdiff3.png fr/figs/metadata.svg fr/figs/mq-stack.svg fr/figs/note.png fr/figs/revlog.svg fr/figs/snapshot.svg fr/figs/throbber.gif fr/figs/tip.png fr/figs/tour-history.svg fr/figs/tour-merge-conflict.svg fr/figs/tour-merge-merge.svg fr/figs/tour-merge-pull.svg fr/figs/tour-merge-sep-repos.svg fr/figs/undo-manual-merge.dot fr/figs/undo-manual.dot fr/figs/undo-non-tip.dot fr/figs/undo-simple.dot fr/figs/warning.png fr/figs/wdir-after-commit.svg fr/figs/wdir-branch.svg fr/figs/wdir-merge.svg fr/figs/wdir-pre-branch.svg fr/figs/wdir.svg fr/filelog.svg fr/filenames.tex fr/fixhtml.py fr/fixsvg fr/hgbook.css fr/hgext.tex fr/hook.tex fr/htlatex.book fr/intro.tex fr/kdiff3.png fr/license.tex fr/metadata.svg fr/mq-collab.tex fr/mq-ref.tex fr/mq-stack.svg fr/mq.tex fr/note.png fr/preface.tex fr/revlog.svg fr/snapshot.svg fr/srcinstall.tex fr/template.tex fr/tour-basic.tex fr/tour-history.svg fr/tour-merge-conflict.svg fr/tour-merge-merge.svg fr/tour-merge-pull.svg fr/tour-merge-sep-repos.svg fr/tour-merge.tex fr/undo-manual-merge.dot fr/undo-manual.dot fr/undo-non-tip.dot fr/undo-simple.dot fr/undo.tex fr/wdir-after-commit.svg fr/wdir-branch.svg fr/wdir-merge.svg fr/wdir-pre-branch.svg fr/wdir.svg
line diff
     1.1 --- a/fr/00book.tex	Sun Aug 16 03:41:39 2009 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,80 +0,0 @@
     1.4 -% The use of oneside here is a temporary hack; \marginpar entries
     1.5 -% don't show up on odd pages of PDF output without it.  Sigh.
     1.6 -\documentclass[oneside]{book}
     1.7 -\usepackage{enumerate}
     1.8 -\usepackage{fullpage}
     1.9 -\usepackage{makeidx}
    1.10 -\usepackage{ifpdf}
    1.11 -\usepackage{graphicx}
    1.12 -\usepackage{pslatex}
    1.13 -\usepackage{fancyvrb}
    1.14 -% adding package specific to the french version
    1.15 -\usepackage[french]{babel}
    1.16 -\usepackage[utf8]{inputenc}
    1.17 -% leave hyperref until last
    1.18 -\usepackage[colorlinks=true,bookmarks=true,pdftitle={Distributed
    1.19 -  revision control with Mercurial},pdfsubject={Revision
    1.20 -  control},pdfkeywords={Mercurial, Revision control, Distributed
    1.21 -  revision control},pdfauthor={Bryan O'Sullivan}]{hyperref}
    1.22 -
    1.23 -\include{99defs}
    1.24 -
    1.25 -\title{Gestion de source distribué avec Mercurial} \author{Bryan
    1.26 -  O'Sullivan}
    1.27 -\date{Copyright \copyright\ 2006, 2007 Bryan O'Sullivan.\\
    1.28 -  Ce document peut être librement distribué selon les termes et 
    1.29 -  les conditions décrites dans la version 1.0 de la licence Open Publication.
    1.30 -  La licence est en annexe~\ref{cha:opl} de ce document.\\
    1.31 -  
    1.32 -  Cette traduction a été généré depuis 
    1.33 -  \href{http://hg.serpentine.com/mercurial/book/}{rev~\input{build_id}}
    1.34 -  avec \href{http://www.selenic.com/hg/}{rev~\input{hg_id}} of Mercurial.}
    1.35 -
    1.36 -\makeindex
    1.37 -
    1.38 -\begin{document}
    1.39 -
    1.40 -\maketitle
    1.41 -
    1.42 -\addcontentsline{toc}{chapter}{Contents}
    1.43 -\pagenumbering{roman}
    1.44 -\tableofcontents
    1.45 -\listoffigures
    1.46 -%\listoftables
    1.47 -
    1.48 -\pagenumbering{arabic}
    1.49 -
    1.50 -\include{preface}
    1.51 -\include{intro}
    1.52 -\include{tour-basic}
    1.53 -\include{tour-merge}
    1.54 -\include{concepts}
    1.55 -\include{daily}
    1.56 -\include{collab}
    1.57 -\include{filenames}
    1.58 -\include{branch}
    1.59 -\include{undo}
    1.60 -\include{hook}
    1.61 -\include{template}
    1.62 -\include{mq}
    1.63 -\include{mq-collab}
    1.64 -\include{hgext}
    1.65 -
    1.66 -\appendix
    1.67 -\include{cmdref}
    1.68 -\include{mq-ref}
    1.69 -\include{srcinstall}
    1.70 -\include{license}
    1.71 -\addcontentsline{toc}{chapter}{Bibliography}
    1.72 -\bibliographystyle{alpha}
    1.73 -\bibliography{99book}
    1.74 -
    1.75 -\addcontentsline{toc}{chapter}{Index}
    1.76 -\printindex
    1.77 -
    1.78 -\end{document}
    1.79 -
    1.80 -%%% Local Variables: 
    1.81 -%%% mode: latex
    1.82 -%%% TeX-master: t
    1.83 -%%% End: 
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/fr/00book.xml	Sun Aug 16 04:58:01 2009 +0200
     2.3 @@ -0,0 +1,110 @@
     2.4 +<?xml version="1.0" encoding="UTF-8"?>
     2.5 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     2.6 +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
     2.7 + "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
     2.8 +[
     2.9 +<!-- Below are references to files in this directory. -->
    2.10 +
    2.11 +<!-- Chapters. -->
    2.12 +
    2.13 +<!ENTITY ch00     SYSTEM "ch00-preface.xml">
    2.14 +<!ENTITY ch01     SYSTEM "ch01-intro.xml">
    2.15 +<!ENTITY ch02     SYSTEM "ch02-tour-basic.xml">
    2.16 +<!ENTITY ch03     SYSTEM "ch03-tour-merge.xml">
    2.17 +<!ENTITY ch04     SYSTEM "ch04-concepts.xml">
    2.18 +<!ENTITY ch05     SYSTEM "ch05-daily.xml">
    2.19 +<!ENTITY ch06     SYSTEM "ch06-collab.xml">
    2.20 +<!ENTITY ch07     SYSTEM "ch07-filenames.xml">
    2.21 +<!ENTITY ch08     SYSTEM "ch08-branch.xml">
    2.22 +<!ENTITY ch09     SYSTEM "ch09-undo.xml">
    2.23 +<!ENTITY ch10     SYSTEM "ch10-hook.xml">
    2.24 +<!ENTITY ch11     SYSTEM "ch11-template.xml">
    2.25 +<!ENTITY ch12     SYSTEM "ch12-mq.xml">
    2.26 +<!ENTITY ch13     SYSTEM "ch13-mq-collab.xml">
    2.27 +<!ENTITY ch14     SYSTEM "ch14-hgext.xml">
    2.28 +<!ENTITY appA     SYSTEM "appA-svn.xml">
    2.29 +<!ENTITY appB     SYSTEM "appB-mq-ref.xml">
    2.30 +<!ENTITY appC     SYSTEM "appC-srcinstall.xml">
    2.31 +<!ENTITY appD     SYSTEM "appD-license.xml">
    2.32 +
    2.33 +<!-- Include our standard shortcuts. -->
    2.34 +
    2.35 +<!ENTITY % SHORTCUTS SYSTEM "book-shortcuts.xml">
    2.36 +%SHORTCUTS;
    2.37 +
    2.38 +<!-- Include automatically and manually generated code snippets. -->
    2.39 +
    2.40 +<!ENTITY % AUTOSNIPPETS SYSTEM "examples/auto-snippets.xml">
    2.41 +%AUTOSNIPPETS;
    2.42 +]>
    2.43 +
    2.44 +<book id="hg">
    2.45 +  <title>Mercurial: The Definitive Guide</title>
    2.46 +  
    2.47 +  <!-- hg parents &#x2d;&#x2d;template '{node|short} ({date|shortdate})' 
    2.48 +  <subtitle>Compiled from 8a1d3f1aff17 (2009-03-10)</subtitle>
    2.49 +  -->
    2.50 +  <subtitle>Compiled from $rev_id$</subtitle>
    2.51 +  <bookinfo>
    2.52 +    <edition>1</edition>
    2.53 +    <isbn>9780596800673</isbn>
    2.54 +    <authorgroup>
    2.55 +      <author>
    2.56 +        <firstname>Bryan</firstname>
    2.57 +        <surname>O'Sullivan</surname>
    2.58 +      </author>
    2.59 +    </authorgroup>
    2.60 +
    2.61 +    <editor>
    2.62 +      <firstname>Mike</firstname>
    2.63 +      <surname>Loukides</surname>
    2.64 +    </editor>
    2.65 +
    2.66 +    <copyright>
    2.67 +      <year>2006</year>
    2.68 +      <year>2007</year>
    2.69 +      <year>2008</year>
    2.70 +      <year>2009</year>
    2.71 +      <holder>Bryan O'Sullivan</holder>
    2.72 +    </copyright>
    2.73 +  </bookinfo>
    2.74 +
    2.75 +  <!-- BEGIN ch00 -->
    2.76 +  &ch00;
    2.77 +  <!-- BEGIN ch01 -->
    2.78 +  &ch01;
    2.79 +  <!-- BEGIN ch02 -->
    2.80 +  &ch02;
    2.81 +  <!-- BEGIN ch03 -->
    2.82 +  &ch03;
    2.83 +  <!-- BEGIN ch04 -->
    2.84 +  &ch04;
    2.85 +  <!-- BEGIN ch05 -->
    2.86 +  &ch05;
    2.87 +  <!-- BEGIN ch06 -->
    2.88 +  &ch06;
    2.89 +  <!-- BEGIN ch07 -->
    2.90 +  &ch07;
    2.91 +  <!-- BEGIN ch08 -->
    2.92 +  &ch08;
    2.93 +  <!-- BEGIN ch09 -->
    2.94 +  &ch09;
    2.95 +  <!-- BEGIN ch10 -->
    2.96 +  &ch10;
    2.97 +  <!-- BEGIN ch11 -->
    2.98 +  &ch11;
    2.99 +  <!-- BEGIN ch12 -->
   2.100 +  &ch12;
   2.101 +  <!-- BEGIN ch13 -->
   2.102 +  &ch13;
   2.103 +  <!-- BEGIN ch14 -->
   2.104 +  &ch14;
   2.105 +  <!-- BEGIN appA -->
   2.106 +  &appA;
   2.107 +  <!-- BEGIN appB -->
   2.108 +  &appB;
   2.109 +  <!-- BEGIN appC -->
   2.110 +  &appC;
   2.111 +  <!-- BEGIN appD -->
   2.112 +  &appD;
   2.113 +</book>
     3.1 --- a/fr/99book.bib	Sun Aug 16 03:41:39 2009 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,76 +0,0 @@
     3.4 -@Unpublished{gruenbacher:2005,
     3.5 -  author = 	 {Andreas Gruenbacher},
     3.6 -  title = 	 {How To Survive With Many Patches (Introduction to \texttt{quilt})},
     3.7 -  year = 	 {2005},
     3.8 -  month = 	 {June},
     3.9 -  note =         {\url{http://www.suse.de/~agruen/quilt.pdf}},
    3.10 -}
    3.11 -
    3.12 -@InProceedings{web:europython,
    3.13 -  author = 	 {Bryan O'Sullivan},
    3.14 -  title = 	 {Achieving High Performance in Mercurial},
    3.15 -  booktitle = 	 {EuroPython Conference},
    3.16 -  year = 	 {2006},
    3.17 -  month = 	 {July},
    3.18 -  note = 	 {\url{XXX}},
    3.19 -}
    3.20 -
    3.21 -@Misc{web:diffstat,
    3.22 -  author = 	 {Thomas Dickey},
    3.23 -  title = 	 {\texttt{diffstat}--make a histogram of \texttt{diff} output},
    3.24 -  note = 	 {\url{http://dickey.his.com/diffstat/diffstat.html}},
    3.25 -}
    3.26 -
    3.27 -@Misc{web:quilt,
    3.28 -  author = 	 {Andreas Gruenbacher, Martin Quinson, Jean Delvare},
    3.29 -  title = 	 {Patchwork Quilt},
    3.30 -  note = 	 {\url{http://savannah.nongnu.org/projects/quilt}},
    3.31 -}
    3.32 -
    3.33 -@Misc{web:patchutils,
    3.34 -  author = 	 {Tim Waugh},
    3.35 -  title = 	 {\texttt{patchutils}--programs that operate on patch files},
    3.36 -  note = 	 {\url{http://cyberelk.net/tim/patchutils/}},
    3.37 -}
    3.38 -
    3.39 -@Misc{web:mpatch,
    3.40 -  author = 	 {Chris Mason},
    3.41 -  title = 	 {\texttt{mpatch}--help solve patch rejects},
    3.42 -  note = 	 {\url{http://oss.oracle.com/~mason/mpatch/}},
    3.43 -}
    3.44 -
    3.45 -@Misc{web:wiggle,
    3.46 -  author = 	 {Neil Brown},
    3.47 -  title = 	 {\texttt{wiggle}--apply conflicting patches},
    3.48 -  note = 	 {\url{http://cgi.cse.unsw.edu.au/~neilb/source/wiggle/}},
    3.49 -}
    3.50 -
    3.51 -@Misc{web:mysql-python,
    3.52 -  author =	 {Andy Dustman},
    3.53 -  title =	 {MySQL for Python},
    3.54 -  note =	 {\url{http://sourceforge.net/projects/mysql-python}},
    3.55 -}
    3.56 -
    3.57 -@Misc{web:changelog,
    3.58 -  author =	 {Richard Stallman, GNU Project volunteers},
    3.59 -  title =	 {GNU Coding Standards---Change Logs},
    3.60 -  note =	 {\url{http://www.gnu.org/prep/standards/html_node/Change-Logs.html}},
    3.61 -}
    3.62 -
    3.63 -@Misc{web:macpython,
    3.64 -  author =	 {Bob Ippolito, Ronald Oussoren},
    3.65 -  title =	 {Universal MacPython},
    3.66 -  note =	 {\url{http://bob.pythonmac.org/archives/2006/04/10/python-and-universal-binaries-on-mac-os-x/}},
    3.67 -}
    3.68 -
    3.69 -@Misc{web:putty,
    3.70 -  author =	 {Simon Tatham},
    3.71 -  title =	 {PuTTY---open source ssh client for Windows},
    3.72 -  note =	 {\url{http://www.chiark.greenend.org.uk/~sgtatham/putty/}},
    3.73 -}
    3.74 -
    3.75 -@Misc{web:configparser,
    3.76 -  author =       {Python.org},
    3.77 -  title =	 {\texttt{ConfigParser}---Configuration file parser},
    3.78 -  note =	 {\url{http://docs.python.org/lib/module-ConfigParser.html}},
    3.79 -}
     4.1 --- a/fr/99defs.tex	Sun Aug 16 03:41:39 2009 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,146 +0,0 @@
     4.4 -% Bug ID.
     4.5 -\newcommand{\bug}[1]{\index{Mercurial bug
     4.6 -    database!\href{http://www.selenic.com/mercurial/bts/issue#1}{bug
     4.7 -      ~#1}}\href{http://www.selenic.com/mercurial/bts/issue#1}{Mercurial
     4.8 -    bug no.~#1}}
     4.9 -
    4.10 -% File name in the user's home directory.
    4.11 -\newcommand{\tildefile}[1]{\texttt{\~{}/#1}}
    4.12 -
    4.13 -% File name.
    4.14 -\newcommand{\filename}[1]{\texttt{#1}}
    4.15 -
    4.16 -% Directory name.
    4.17 -\newcommand{\dirname}[1]{\texttt{#1}}
    4.18 -
    4.19 -% File name, with index entry.
    4.20 -% The ``s'' prefix comes from ``special''.
    4.21 -\newcommand{\sfilename}[1]{\index{\texttt{#1} file}\texttt{#1}}
    4.22 -
    4.23 -% Directory name, with index entry.
    4.24 -\newcommand{\sdirname}[1]{\index{\texttt{#1} directory}\texttt{#1}}
    4.25 -
    4.26 -% Mercurial extension.
    4.27 -\newcommand{\hgext}[1]{\index{\texttt{#1} extension}\texttt{#1}}
    4.28 -
    4.29 -% Command provided by a Mercurial extension.
    4.30 -\newcommand{\hgxcmd}[2]{\index{\texttt{#2} command (\texttt{#1}
    4.31 -      extension)}\index{\texttt{#1} extension!\texttt{#2} command}``\texttt{hg #2}''}
    4.32 -
    4.33 -% Mercurial command.
    4.34 -\newcommand{\hgcmd}[1]{\index{\texttt{#1} command}``\texttt{hg #1}''}
    4.35 -
    4.36 -% Mercurial command, with arguments.
    4.37 -\newcommand{\hgcmdargs}[2]{\index{\texttt{#1} command}``\texttt{hg #1 #2}''}
    4.38 -
    4.39 -\newcommand{\tplkword}[1]{\index{\texttt{#1} template keyword}\index{template keywords!\texttt{#1}}\texttt{#1}}
    4.40 -
    4.41 -\newcommand{\tplkwfilt}[2]{\index{\texttt{#1} template keyword!\texttt{#2}
    4.42 -    filter}\index{template filters!\texttt{#2}}\index{\texttt{#2}
    4.43 -    template filter}\texttt{#2}}
    4.44 -
    4.45 -\newcommand{\tplfilter}[1]{\index{template
    4.46 -    filters!\texttt{#1}}\index{\texttt{#1} template
    4.47 -    filter}\texttt{#1}}
    4.48 -
    4.49 -% Shell/system command.
    4.50 -\newcommand{\command}[1]{\index{\texttt{#1} system command}\texttt{#1}}
    4.51 -
    4.52 -% Shell/system command, with arguments.
    4.53 -\newcommand{\cmdargs}[2]{\index{\texttt{#1} system command}``\texttt{#1 #2}''}
    4.54 -
    4.55 -% Mercurial command option.
    4.56 -\newcommand{\hgopt}[2]{\index{\texttt{#1} command!\texttt{#2} option}\texttt{#2}}
    4.57 -
    4.58 -% Mercurial command option, provided by an extension command.
    4.59 -\newcommand{\hgxopt}[3]{\index{\texttt{#2} command (\texttt{#1} extension)!\texttt{#3} option}\index{\texttt{#1} extension!\texttt{#2} command!\texttt{#3} option}\texttt{#3}}
    4.60 -
    4.61 -% Mercurial global option.
    4.62 -\newcommand{\hggopt}[1]{\index{global options!\texttt{#1} option}\texttt{#1}}
    4.63 -
    4.64 -% Shell/system command option.
    4.65 -\newcommand{\cmdopt}[2]{\index{\texttt{#1} command!\texttt{#2} option}\texttt{#2}}
    4.66 -
    4.67 -% Command option.
    4.68 -\newcommand{\option}[1]{\texttt{#1}}
    4.69 -
    4.70 -% Software package.
    4.71 -\newcommand{\package}[1]{\index{\texttt{#1} package}\texttt{#1}}
    4.72 -
    4.73 -% Section name from a hgrc file.
    4.74 -\newcommand{\rcsection}[1]{\index{\texttt{hgrc} file!\texttt{#1} section}\texttt{[#1]}}
    4.75 -
    4.76 -% Named item in a hgrc file section.
    4.77 -\newcommand{\rcitem}[2]{\index{\texttt{hgrc} file!\texttt{#1}
    4.78 -    section!\texttt{#2} entry}\texttt{#2}}
    4.79 -
    4.80 -% hgrc file.
    4.81 -\newcommand{\hgrc}{\index{configuration file!\texttt{hgrc}
    4.82 -    (Linux/Unix)}\index{\texttt{hgrc} configuration file}\texttt{hgrc}}
    4.83 -
    4.84 -% Mercurial.ini file.
    4.85 -\newcommand{\hgini}{\index{configuration file!\texttt{Mercurial.ini}
    4.86 -    (Windows)}\index{\texttt{Mercurial.ini} configuration file}\texttt{Mercurial.ini}}
    4.87 -
    4.88 -% Hook name.
    4.89 -\newcommand{\hook}[1]{\index{\texttt{#1} hook}\index{hooks!\texttt{#1}}\texttt{#1}}
    4.90 -
    4.91 -% Environment variable.
    4.92 -\newcommand{\envar}[1]{\index{\texttt{#1} environment
    4.93 -    variable}\index{environment variables!\texttt{#1}}\texttt{#1}}
    4.94 -
    4.95 -% Python module.
    4.96 -\newcommand{\pymod}[1]{\index{\texttt{#1} module}\texttt{#1}}
    4.97 -
    4.98 -% Python class in a module.
    4.99 -\newcommand{\pymodclass}[2]{\index{\texttt{#1} module!\texttt{#2}
   4.100 -    class}\texttt{#1.#2}}
   4.101 -
   4.102 -% Python function in a module.
   4.103 -\newcommand{\pymodfunc}[2]{\index{\texttt{#1} module!\texttt{#2}
   4.104 -    function}\texttt{#1.#2}}
   4.105 -
   4.106 -% Note: blah blah.
   4.107 -\newsavebox{\notebox}
   4.108 -\newenvironment{note}%
   4.109 -  {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Note:}\space}%
   4.110 -  {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}}
   4.111 -\newenvironment{caution}%
   4.112 -  {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Caution:}\space}%
   4.113 -  {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}}
   4.114 -
   4.115 -% Code sample, eating 4 characters of leading space.
   4.116 -\DefineVerbatimEnvironment{codesample4}{Verbatim}{frame=single,gobble=4,numbers=left,commandchars=\\\{\}}
   4.117 -
   4.118 -% Code sample, eating 2 characters of leading space.
   4.119 -\DefineVerbatimEnvironment{codesample2}{Verbatim}{frame=single,gobble=2,numbers=left,commandchars=\\\{\}}
   4.120 -
   4.121 -% Interaction from the examples directory.
   4.122 -\newcommand{\interaction}[1]{\VerbatimInput[frame=single,numbers=left,commandchars=\\\{\}]{examples/#1.lxo}}
   4.123 -% Example code from the examples directory.
   4.124 -\newcommand{\excode}[1]{\VerbatimInput[frame=single,numbers=left,commandchars=\\\{\}]{../examples/#1}}
   4.125 -
   4.126 -% Graphics inclusion.
   4.127 -\ifpdf
   4.128 -  \newcommand{\grafix}[1]{\includegraphics{#1}}
   4.129 -\else
   4.130 -  \newcommand{\grafix}[1]{\includegraphics{#1.png}}
   4.131 -\fi
   4.132 -
   4.133 -% Reference entry for a command.
   4.134 -\newcommand{\cmdref}[2]{\section{\hgcmd{#1}---#2}\label{cmdref:#1}\index{\texttt{#1} command}}
   4.135 -
   4.136 -% Reference entry for a command option with long and short forms.
   4.137 -\newcommand{\optref}[3]{\subsubsection{\hgopt{#1}{--#3}, also \hgopt{#1}{-#2}}}
   4.138 -
   4.139 -% Reference entry for a command option with only long form.
   4.140 -\newcommand{\loptref}[2]{\subsubsection{\hgopt{#1}{--#2} option}}
   4.141 -
   4.142 -% command to generate a footnote to be used as a translator's note
   4.143 -\newcommand{\ndt}[1]{\footnote{\textbf{N. del T.} #1}}
   4.144 -
   4.145 -
   4.146 -%%% Local Variables: 
   4.147 -%%% mode: latex
   4.148 -%%% TeX-master: "00book"
   4.149 -%%% End: 
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/fr/appA-svn.xml	Sun Aug 16 04:58:01 2009 +0200
     5.3 @@ -0,0 +1,540 @@
     5.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     5.5 +
     5.6 +<appendix id="svn">
     5.7 +  <?dbhtml filename="migrating-to-mercurial.html"?>
     5.8 +<title>Migrating to Mercurial</title>
     5.9 +
    5.10 +  <para id="x_6e1">A common way to test the waters with a new revision control
    5.11 +    tool is to experiment with switching an existing project, rather
    5.12 +    than starting a new project from scratch.</para>
    5.13 +
    5.14 +  <para id="x_6e2">In this appendix, we discuss how to import a project's history
    5.15 +    into Mercurial, and what to look out for if you are used to a
    5.16 +    different revision control system.</para>
    5.17 +
    5.18 +  <sect1>
    5.19 +    <title>Importing history from another system</title>
    5.20 +
    5.21 +    <para id="x_6e3">Mercurial ships with an extension named
    5.22 +      <literal>convert</literal>, which can import project history
    5.23 +      from most popular revision control systems.  At the time this
    5.24 +      book was written, it could import history from the following
    5.25 +      systems:</para>
    5.26 +    <itemizedlist>
    5.27 +      <listitem>
    5.28 +	<para id="x_6e4">Subversion</para>
    5.29 +      </listitem>
    5.30 +      <listitem>
    5.31 +	<para id="x_6e5">CVS</para>
    5.32 +      </listitem>
    5.33 +      <listitem>
    5.34 +	<para id="x_6e6">git</para>
    5.35 +      </listitem>
    5.36 +      <listitem>
    5.37 +	<para id="x_6e7">Darcs</para>
    5.38 +      </listitem>
    5.39 +      <listitem>
    5.40 +	<para id="x_6e8">Bazaar</para>
    5.41 +      </listitem>
    5.42 +      <listitem>
    5.43 +	<para id="x_6e9">Monotone</para>
    5.44 +      </listitem>
    5.45 +      <listitem>
    5.46 +	<para id="x_6ea">GNU Arch</para>
    5.47 +      </listitem>
    5.48 +      <listitem>
    5.49 +	<para id="x_6eb">Mercurial</para>
    5.50 +      </listitem>
    5.51 +    </itemizedlist>
    5.52 +
    5.53 +    <para id="x_6ec">(To see why Mercurial itself is supported as a source, see
    5.54 +      <xref linkend="svn.filemap"/>.)</para>
    5.55 +
    5.56 +    <para id="x_6ed">You can enable the extension in the usual way, by editing
    5.57 +      your <filename>~/.hgrc</filename> file.</para>
    5.58 +
    5.59 +    <programlisting>[extensions]
    5.60 +convert =</programlisting>
    5.61 +
    5.62 +    <para id="x_6ee">This will make a <command>hg convert</command> command
    5.63 +      available.  The command is easy to use.  For instance, this
    5.64 +      command will import the Subversion history for the Nose unit
    5.65 +      testing framework into Mercurial.</para>
    5.66 +
    5.67 +    <screen><prompt>$</prompt> <userinput>hg convert http://python-nose.googlecode.com/svn/trunk</userinput></screen>
    5.68 +
    5.69 +    <para id="x_6ef">The <literal>convert</literal> extension operates
    5.70 +      incrementally.  In other words, after you have run <command>hg
    5.71 +	convert</command> once, running it again will import any new
    5.72 +      revisions committed after the first run began.  Incremental
    5.73 +      conversion will only work if you run <command>hg
    5.74 +	convert</command> in the same Mercurial repository that you
    5.75 +      originally used, because the <literal>convert</literal>
    5.76 +      extension saves some private metadata in a
    5.77 +      non-revision-controlled file named
    5.78 +      <filename>.hg/shamap</filename> inside the target
    5.79 +      repository.</para>
    5.80 +
    5.81 +    <para id="x_707">When you want to start making changes using Mercurial, it's
    5.82 +      best to clone the tree in which you are doing your conversions,
    5.83 +      and leave the original tree for future incremental conversions.
    5.84 +      This is the safest way to let you pull and merge future commits
    5.85 +      from the source revision control system into your newly active
    5.86 +      Mercurial project.</para>
    5.87 +
    5.88 +    <sect2>
    5.89 +      <title>Converting multiple branches</title>
    5.90 +
    5.91 +      <para id="x_708">The <command>hg convert</command> command given above
    5.92 +	converts only the history of the <literal>trunk</literal>
    5.93 +	branch of the Subversion repository.  If we instead use the
    5.94 +	URL <literal>http://python-nose.googlecode.com/svn</literal>,
    5.95 +	Mercurial will automatically detect the
    5.96 +	<literal>trunk</literal>, <literal>tags</literal> and
    5.97 +	<literal>branches</literal> layout that Subversion projects
    5.98 +	usually use, and it will import each as a separate Mercurial
    5.99 +	branch.</para>
   5.100 +
   5.101 +      <para id="x_709">By default, each Subversion branch imported into Mercurial
   5.102 +	is given a branch name.  After the conversion completes, you
   5.103 +	can get a list of the active branch names in the Mercurial
   5.104 +	repository using <command>hg branches -a</command>. If you
   5.105 +	would prefer to import the Subversion branches without names,
   5.106 +	pass the <option>--config
   5.107 +	  convert.hg.usebranchnames=false</option> option to
   5.108 +	<command>hg convert</command>.</para>
   5.109 +
   5.110 +      <para id="x_70a">Once you have converted your tree, if you want to follow
   5.111 +	the usual Mercurial practice of working in a tree that
   5.112 +	contains a single branch, you can clone that single branch
   5.113 +	using <command>hg clone -r mybranchname</command>.</para>
   5.114 +    </sect2>
   5.115 +
   5.116 +    <sect2>
   5.117 +      <title>Mapping user names</title>
   5.118 +
   5.119 +      <para id="x_6f0">Some revision control tools save only short usernames with
   5.120 +	commits, and these can be difficult to interpret.  The norm
   5.121 +	with Mercurial is to save a committer's name and email
   5.122 +	address, which is much more useful for talking to them after
   5.123 +	the fact.</para>
   5.124 +
   5.125 +      <para id="x_6f1">If you are converting a tree from a revision control
   5.126 +	system that uses short names, you can map those names to
   5.127 +	longer equivalents by passing a <option>--authors</option>
   5.128 +	option to <command>hg convert</command>.  This option accepts
   5.129 +	a file name that should contain entries of the following
   5.130 +	form.</para>
   5.131 +
   5.132 +      <programlisting>arist = Aristotle &lt;aristotle@phil.example.gr&gt;
   5.133 +soc = Socrates &lt;socrates@phil.example.gr&gt;</programlisting>
   5.134 +
   5.135 +      <para id="x_6f2">Whenever <literal>convert</literal> encounters a commit
   5.136 +	with the username <literal>arist</literal> in the source
   5.137 +	repository, it will use the name <literal>Aristotle
   5.138 +	  &lt;aristotle@phil.example.gr&gt;</literal> in the converted
   5.139 +	Mercurial revision.  If no match is found for a name, it is
   5.140 +	used verbatim.</para>
   5.141 +    </sect2>
   5.142 +
   5.143 +    <sect2 id="svn.filemap">
   5.144 +      <title>Tidying up the tree</title>
   5.145 +
   5.146 +      <para id="x_6f3">Not all projects have pristine history.  There may be a
   5.147 +	directory that should never have been checked in, a file that
   5.148 +	is too big, or a whole hierarchy that needs to be
   5.149 +	refactored.</para>
   5.150 +
   5.151 +      <para id="x_6f4">The <literal>convert</literal> extension supports the idea
   5.152 +	of a <quote>file map</quote> that can reorganize the files and
   5.153 +	directories in a project as it imports the project's history.
   5.154 +	This is useful not only when importing history from other
   5.155 +	revision control systems, but also to prune or refactor a
   5.156 +	Mercurial tree.</para>
   5.157 +
   5.158 +      <para id="x_6f5">To specify a file map, use the <option>--filemap</option>
   5.159 +	option and supply a file name.  A file map contains lines of the
   5.160 +	following forms.</para>
   5.161 +
   5.162 +      <programlisting># This is a comment.
   5.163 +# Empty lines are ignored.	
   5.164 +
   5.165 +include path/to/file
   5.166 +
   5.167 +exclude path/to/file
   5.168 +
   5.169 +rename from/some/path to/some/other/place
   5.170 +</programlisting>
   5.171 +
   5.172 +      <para id="x_6f6">The <literal>include</literal> directive causes a file, or
   5.173 +	all files under a directory, to be included in the destination
   5.174 +	repository.  This also excludes all other files and dirs not
   5.175 +	explicitely included.  The <literal>exclude</literal>
   5.176 +	directive causes files or directories to be omitted, and
   5.177 +	others not explicitly mentioned to be included.</para>
   5.178 +
   5.179 +      <para id="x_6f7">To move a file or directory from one location to another,
   5.180 +	use the <literal>rename</literal> directive.  If you need to
   5.181 +	move a file or directory from a subdirectory into the root of
   5.182 +	the repository, use <literal>.</literal> as the second
   5.183 +	argument to the <literal>rename</literal> directive.</para>
   5.184 +    </sect2>
   5.185 +
   5.186 +    <sect2>
   5.187 +      <title>Improving Subversion conversion performance</title>
   5.188 +
   5.189 +      <para id="x_70b">You will often need several attempts before you hit the
   5.190 +	perfect combination of user map, file map, and other
   5.191 +	conversion parameters.  Converting a Subversion repository
   5.192 +	over an access protocol like <literal>ssh</literal> or
   5.193 +	<literal>http</literal> can proceed thousands of times more
   5.194 +	slowly than Mercurial is capable of actually operating, due to
   5.195 +	network delays.  This can make tuning that perfect conversion
   5.196 +	recipe very painful.</para>
   5.197 +
   5.198 +      <para id="x_70c">The <ulink
   5.199 +	  url="http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt"><command>svnsync</command></ulink> 
   5.200 +	command can greatly speed up the conversion of a Subversion
   5.201 +	repository.  It is a read-only mirroring program for
   5.202 +	Subversion repositories.  The idea is that you create a local
   5.203 +	mirror of your Subversion tree, then convert the mirror into a
   5.204 +	Mercurial repository.</para>
   5.205 +
   5.206 +      <para id="x_70d">Suppose we want to convert the Subversion repository for
   5.207 +	the popular Memcached project into a Mercurial tree.  First,
   5.208 +	we create a local Subversion repository.</para>
   5.209 +
   5.210 +      <screen><prompt>$</prompt> <userinput>svnadmin create memcached-mirror</userinput></screen>
   5.211 +
   5.212 +      <para id="x_70e">Next, we set up a Subversion hook that
   5.213 +	<command>svnsync</command> needs.</para>
   5.214 +
   5.215 +      <screen><prompt>$</prompt> <userinput>echo '#!/bin/sh' > memcached-mirror/hooks/pre-revprop-change</userinput>
   5.216 +<prompt>$</prompt> <userinput>chmod +x memcached-mirror/hooks/pre-revprop-change</userinput></screen>
   5.217 +
   5.218 +      <para id="x_70f">We then initialize <command>svnsync</command> in this
   5.219 +	repository.</para>
   5.220 +
   5.221 +      <screen><prompt>$</prompt> <userinput>svnsync --init file://`pwd`/memcached-mirror \
   5.222 +  http://code.sixapart.com/svn/memcached</userinput></screen>
   5.223 +
   5.224 +      <para id="x_710">Our next step is to begin the <command>svnsync</command>
   5.225 +	mirroring process.</para>
   5.226 +
   5.227 +      <screen><prompt>$</prompt> <userinput>svnsync sync file://`pwd`/memcached-mirror</userinput></screen>
   5.228 +
   5.229 +      <para id="x_711">Finally, we import the history of our local Subversion
   5.230 +	mirror into Mercurial.</para>
   5.231 +
   5.232 +      <screen><prompt>$</prompt> <userinput>hg convert memcached-mirror</userinput></screen>
   5.233 +      
   5.234 +      <para id="x_712">We can use this process incrementally if the Subversion
   5.235 +	repository is still in use.  We run <command>svnsync</command>
   5.236 +	to pull new changes into our mirror, then <command>hg
   5.237 +	  convert</command> to import them into our Mercurial
   5.238 +	tree.</para>
   5.239 +
   5.240 +      <para id="x_713">There are two advantages to doing a two-stage import with
   5.241 +	<command>svnsync</command>.  The first is that it uses more
   5.242 +	efficient Subversion network syncing code than <command>hg
   5.243 +	  convert</command>, so it transfers less data over the
   5.244 +	network.  The second is that the import from a local
   5.245 +	Subversion tree is so fast that you can tweak your conversion
   5.246 +	setup repeatedly without having to sit through a painfully
   5.247 +	slow network-based conversion process each time.</para>
   5.248 +    </sect2>
   5.249 +  </sect1>
   5.250 +
   5.251 +  <sect1>
   5.252 +    <title>Migrating from Subversion</title>
   5.253 +
   5.254 +    <para id="x_6f8">Subversion is currently the most popular open source
   5.255 +      revision control system. Although there are many differences
   5.256 +      between Mercurial and Subversion, making the transition from
   5.257 +      Subversion to Mercurial is not particularly difficult.  The two
   5.258 +      have similar command sets and generally uniform
   5.259 +      interfaces.</para>
   5.260 +
   5.261 +    <sect2>
   5.262 +      <title>Philosophical differences</title>
   5.263 +
   5.264 +      <para id="x_6f9">The fundamental difference between Subversion and
   5.265 +	Mercurial is of course that Subversion is centralized, while
   5.266 +	Mercurial is distributed.  Since Mercurial stores all of a
   5.267 +	project's history on your local drive, it only needs to
   5.268 +	perform a network access when you want to explicitly
   5.269 +	communicate with another repository. In contrast, Subversion
   5.270 +	stores very little information locally, and the client must
   5.271 +	thus contact its server for many common operations.</para>
   5.272 +
   5.273 +      <para id="x_6fa">Subversion more or less gets away without a well-defined
   5.274 +	notion of a branch: which portion of a server's namespace
   5.275 +	qualifies as a branch is a matter of convention, with the
   5.276 +	software providing no enforcement.  Mercurial treats a
   5.277 +	repository as the unit of branch management.</para>
   5.278 +
   5.279 +      <sect3>
   5.280 +	<title>Scope of commands</title>
   5.281 +
   5.282 +	<para id="x_6fb">Since Subversion doesn't know what parts of its
   5.283 +	  namespace are really branches, it treats most commands as
   5.284 +	  requests to operate at and below whatever directory you are
   5.285 +	  currently visiting.  For instance, if you run <command>svn
   5.286 +	    log</command>, you'll get the history of whatever part of
   5.287 +	  the tree you're looking at, not the tree as a whole.</para>
   5.288 +
   5.289 +	<para id="x_6fc">Mercurial's commands behave differently, by defaulting
   5.290 +	  to operating over an entire repository.  Run <command>hg
   5.291 +	    log</command> and it will tell you the history of the
   5.292 +	  entire tree, no matter what part of the working directory
   5.293 +	  you're visiting at the time.  If you want the history of
   5.294 +	  just a particular file or directory, simply supply it by
   5.295 +	  name, e.g. <command>hg log src</command>.</para>
   5.296 +
   5.297 +	<para id="x_6fd">From my own experience, this difference in default
   5.298 +	  behaviors is probably the most likely to trip you up if you
   5.299 +	  have to switch back and forth frequently between the two
   5.300 +	  tools.</para>
   5.301 +      </sect3>
   5.302 +
   5.303 +      <sect3>
   5.304 +	<title>Multi-user operation and safety</title>
   5.305 +
   5.306 +	<para id="x_6fe">With Subversion, it is normal (though slightly frowned
   5.307 +	  upon) for multiple people to collaborate in a single branch.
   5.308 +	  If Alice and Bob are working together, and Alice commits
   5.309 +	  some changes to their shared branch, Bob must update his
   5.310 +	  client's view of the branch before he can commit.  Since at
   5.311 +	  this time he has no permanent record of the changes he has
   5.312 +	  made, he can corrupt or lose his modifications during and
   5.313 +	  after his update.</para>
   5.314 +
   5.315 +	<para id="x_6ff">Mercurial encourages a commit-then-merge model instead.
   5.316 +	  Bob commits his changes locally before pulling changes from,
   5.317 +	  or pushing them to, the server that he shares with Alice.
   5.318 +	  If Alice pushed her changes before Bob tries to push his, he
   5.319 +	  will not be able to push his changes until he pulls hers,
   5.320 +	  merges with them, and commits the result of the merge.  If
   5.321 +	  he makes a mistake during the merge, he still has the option
   5.322 +	  of reverting to the commit that recorded his changes.</para>
   5.323 +
   5.324 +	<para id="x_700">It is worth emphasizing that these are the common ways
   5.325 +	  of working with these tools. Subversion supports a safer
   5.326 +	  work-in-your-own-branch model, but it is cumbersome enough
   5.327 +	  in practice to not be widely used.  Mercurial can support
   5.328 +	  the less safe mode of allowing changes to be pulled in and
   5.329 +	  merged on top of uncommitted edits, but this is considered
   5.330 +	  highly unusual.</para>
   5.331 +      </sect3>
   5.332 +
   5.333 +      <sect3>
   5.334 +	<title>Published vs local changes</title>
   5.335 +
   5.336 +	<para id="x_701">A Subversion <command>svn commit</command> command
   5.337 +	  immediately publishes changes to a server, where they can be
   5.338 +	  seen by everyone who has read access.</para>
   5.339 +
   5.340 +	<para id="x_702">With Mercurial, commits are always local, and must be
   5.341 +	  published via a <command>hg push</command> command
   5.342 +	  afterwards.</para>
   5.343 +
   5.344 +	<para id="x_703">Each approach has its advantages and disadvantages.  The
   5.345 +	  Subversion model means that changes are published, and hence
   5.346 +	  reviewable and usable, immediately.  On the other hand, this
   5.347 +	  means that a user must have commit access to a repository in
   5.348 +	  order to use the software in a normal way, and commit access
   5.349 +	  is not lightly given out by most open source
   5.350 +	  projects.</para>
   5.351 +
   5.352 +	<para id="x_704">The Mercurial approach allows anyone who can clone a
   5.353 +	  repository to commit changes without the need for someone
   5.354 +	  else's permission, and they can then publish their changes
   5.355 +	  and continue to participate however they see fit.  The
   5.356 +	  distinction between committing and pushing does open up the
   5.357 +	  possibility of someone committing changes to their laptop
   5.358 +	  and walking away for a few days having forgotten to push
   5.359 +	  them, which in rare cases might leave collaborators
   5.360 +	  temporarily stuck.</para>
   5.361 +      </sect3>
   5.362 +    </sect2>
   5.363 +
   5.364 +    <sect2>
   5.365 +      <title>Quick reference</title>
   5.366 +
   5.367 +      <table>
   5.368 +	<title>Subversion commands and Mercurial equivalents</title>
   5.369 +	<tgroup cols="3">
   5.370 +	  <thead>
   5.371 +	    <row>
   5.372 +	      <entry>Subversion</entry>
   5.373 +	      <entry>Mercurial</entry>
   5.374 +	      <entry>Notes</entry>
   5.375 +	    </row>
   5.376 +	  </thead>
   5.377 +	  <tbody>
   5.378 +	    <row>
   5.379 +	      <entry><command>svn add</command></entry>
   5.380 +	      <entry><command>hg add</command></entry>
   5.381 +	      <entry></entry>
   5.382 +	    </row>
   5.383 +	    <row>
   5.384 +	      <entry><command>svn blame</command></entry>
   5.385 +	      <entry><command>hg annotate</command></entry>
   5.386 +	      <entry></entry>
   5.387 +	    </row>
   5.388 +	    <row>
   5.389 +	      <entry><command>svn cat</command></entry>
   5.390 +	      <entry><command>hg cat</command></entry>
   5.391 +	      <entry></entry>
   5.392 +	    </row>
   5.393 +	    <row>
   5.394 +	      <entry><command>svn checkout</command></entry>
   5.395 +	      <entry><command>hg clone</command></entry>
   5.396 +	      <entry></entry>
   5.397 +	    </row>
   5.398 +	    <row>
   5.399 +	      <entry><command>svn cleanup</command></entry>
   5.400 +	      <entry>n/a</entry>
   5.401 +	      <entry>No cleanup needed</entry>
   5.402 +	    </row>
   5.403 +	    <row>
   5.404 +	      <entry><command>svn commit</command></entry>
   5.405 +	      <entry><command>hg commit</command>; <command>hg
   5.406 +		  push</command></entry>
   5.407 +	      <entry><command>hg push</command> publishes after
   5.408 +		commit</entry>
   5.409 +	    </row>
   5.410 +	    <row>
   5.411 +	      <entry><command>svn copy</command></entry>
   5.412 +	      <entry><command>hg clone</command></entry>
   5.413 +	      <entry>To create a new branch</entry>
   5.414 +	    </row>
   5.415 +	    <row>
   5.416 +	      <entry><command>svn copy</command></entry>
   5.417 +	      <entry><command>hg copy</command></entry>
   5.418 +	      <entry>To copy files or directories</entry>
   5.419 +	    </row>
   5.420 +	    <row>
   5.421 +	      <entry><command>svn delete</command> (<command>svn
   5.422 +		  remove</command>)</entry>
   5.423 +	      <entry><command>hg remove</command></entry>
   5.424 +	      <entry></entry>
   5.425 +	    </row>
   5.426 +	    <row>
   5.427 +	      <entry><command>svn diff</command></entry>
   5.428 +	      <entry><command>hg diff</command></entry>
   5.429 +	      <entry></entry>
   5.430 +	    </row>
   5.431 +	    <row>
   5.432 +	      <entry><command>svn export</command></entry>
   5.433 +	      <entry><command>hg archive</command></entry>
   5.434 +	      <entry></entry>
   5.435 +	    </row>
   5.436 +	    <row>
   5.437 +	      <entry><command>svn help</command></entry>
   5.438 +	      <entry><command>hg help</command></entry>
   5.439 +	      <entry></entry>
   5.440 +	    </row>
   5.441 +	    <row>
   5.442 +	      <entry><command>svn import</command></entry>
   5.443 +	      <entry><command>hg addremove</command>; <command>hg
   5.444 +		  commit</command></entry>
   5.445 +	      <entry></entry>
   5.446 +	    </row>
   5.447 +	    <row>
   5.448 +	      <entry><command>svn info</command></entry>
   5.449 +	      <entry><command>hg parents</command></entry>
   5.450 +	      <entry>Shows what revision is checked out</entry>
   5.451 +	    </row>
   5.452 +	    <row>
   5.453 +	      <entry><command>svn info</command></entry>
   5.454 +	      <entry><command>hg showconfig
   5.455 +		  paths.parent</command></entry>
   5.456 +	      <entry>Shows what URL is checked out</entry>
   5.457 +	    </row>
   5.458 +	    <row>
   5.459 +	      <entry><command>svn list</command></entry>
   5.460 +	      <entry><command>hg manifest</command></entry>
   5.461 +	      <entry></entry>
   5.462 +	    </row>
   5.463 +	    <row>
   5.464 +	      <entry><command>svn log</command></entry>
   5.465 +	      <entry><command>hg log</command></entry>
   5.466 +	      <entry></entry>
   5.467 +	    </row>
   5.468 +	    <row>
   5.469 +	      <entry><command>svn merge</command></entry>
   5.470 +	      <entry><command>hg merge</command></entry>
   5.471 +	      <entry></entry>
   5.472 +	    </row>
   5.473 +	    <row>
   5.474 +	      <entry><command>svn mkdir</command></entry>
   5.475 +	      <entry>n/a</entry>
   5.476 +	      <entry>Mercurial does not track directories</entry>
   5.477 +	    </row>
   5.478 +	    <row>
   5.479 +	      <entry><command>svn move</command> (<command>svn
   5.480 +		  rename</command>)</entry>
   5.481 +	      <entry><command>hg rename</command></entry>
   5.482 +	      <entry></entry>
   5.483 +	    </row>
   5.484 +	    <row>
   5.485 +	      <entry><command>svn resolved</command></entry>
   5.486 +	      <entry><command>hg resolve -m</command></entry>
   5.487 +	      <entry></entry>
   5.488 +	    </row>
   5.489 +	    <row>
   5.490 +	      <entry><command>svn revert</command></entry>
   5.491 +	      <entry><command>hg revert</command></entry>
   5.492 +	      <entry></entry>
   5.493 +	    </row>
   5.494 +	    <row>
   5.495 +	      <entry><command>svn status</command></entry>
   5.496 +	      <entry><command>hg status</command></entry>
   5.497 +	      <entry></entry>
   5.498 +	    </row>
   5.499 +	    <row>
   5.500 +	      <entry><command>svn update</command></entry>
   5.501 +	      <entry><command>hg pull -u</command></entry>
   5.502 +	      <entry></entry>
   5.503 +	    </row>
   5.504 +	  </tbody>
   5.505 +	</tgroup>
   5.506 +      </table>
   5.507 +    </sect2>
   5.508 +  </sect1>
   5.509 +
   5.510 +  <sect1>
   5.511 +    <title>Useful tips for newcomers</title>
   5.512 +
   5.513 +    <para id="x_705">Under some revision control systems, printing a diff for a
   5.514 +      single committed revision can be painful. For instance, with
   5.515 +      Subversion, to see what changed in revision 104654, you must
   5.516 +      type <command>svn diff -r104653:104654</command>. Mercurial
   5.517 +      eliminates the need to type the revision ID twice in this common
   5.518 +      case. For a plain diff, <command>hg export 104654</command>. For
   5.519 +      a log message followed by a diff, <command>hg log -r104654
   5.520 +	-p</command>.</para>
   5.521 +
   5.522 +    <para id="x_706">When you run <command>hg status</command> without any
   5.523 +      arguments, it prints the status of the entire tree, with paths
   5.524 +      relative to the root of the repository.  This makes it tricky to
   5.525 +      copy a file name from the output of <command>hg status</command>
   5.526 +      into the command line.  If you supply a file or directory name
   5.527 +      to <command>hg status</command>, it will print paths relative to
   5.528 +      your current location instead.  So to get tree-wide status from
   5.529 +      <command>hg status</command>, with paths that are relative to
   5.530 +      your current directory and not the root of the repository, feed
   5.531 +      the output of <command>hg root</command> into <command>hg
   5.532 +	status</command>.  You can easily do this as follows on a
   5.533 +      Unix-like system:</para>
   5.534 +
   5.535 +    <screen><prompt>$</prompt> <userinput>hg status `hg root`</userinput></screen>
   5.536 +  </sect1>
   5.537 +</appendix>
   5.538 +
   5.539 +<!--
   5.540 +local variables: 
   5.541 +sgml-parent-document: ("00book.xml" "book" "appendix")
   5.542 +end:
   5.543 +-->
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/fr/appB-mq-ref.xml	Sun Aug 16 04:58:01 2009 +0200
     6.3 @@ -0,0 +1,563 @@
     6.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     6.5 +
     6.6 +<appendix id="chap:mqref">
     6.7 +  <?dbhtml filename="mercurial-queues-reference.html"?>
     6.8 +  <title>Mercurial Queues reference</title>
     6.9 +
    6.10 +  <sect1 id="sec:mqref:cmdref">
    6.11 +    <title>MQ command reference</title>
    6.12 +
    6.13 +    <para id="x_5e8">For an overview of the commands provided by MQ, use the
    6.14 +      command <command role="hg-cmd">hg help mq</command>.</para>
    6.15 +
    6.16 +    <sect2>
    6.17 +      <title><command role="hg-ext-mq">qapplied</command>&emdash;print
    6.18 +	applied patches</title>
    6.19 +
    6.20 +      <para id="x_5e9">The <command role="hg-ext-mq">qapplied</command> command
    6.21 +	prints the current stack of applied patches.  Patches are
    6.22 +	printed in oldest-to-newest order, so the last patch in the
    6.23 +	list is the <quote>top</quote> patch.</para>
    6.24 +
    6.25 +    </sect2>
    6.26 +    <sect2>
    6.27 +      <title><command role="hg-ext-mq">qcommit</command>&emdash;commit
    6.28 +	changes in the queue repository</title>
    6.29 +
    6.30 +      <para id="x_5ea">The <command role="hg-ext-mq">qcommit</command> command
    6.31 +	commits any outstanding changes in the <filename
    6.32 +	  role="special" class="directory">.hg/patches</filename>
    6.33 +	repository.  This command only works if the <filename
    6.34 +	  role="special" class="directory">.hg/patches</filename>
    6.35 +	directory is a repository, i.e. you created the directory
    6.36 +	using <command role="hg-cmd">hg qinit <option
    6.37 +	    role="hg-ext-mq-cmd-qinit-opt">-c</option></command> or
    6.38 +	ran <command role="hg-cmd">hg init</command> in the directory
    6.39 +	after running <command
    6.40 +	  role="hg-ext-mq">qinit</command>.</para>
    6.41 +
    6.42 +      <para id="x_5eb">This command is shorthand for <command role="hg-cmd">hg
    6.43 +	  commit --cwd .hg/patches</command>.</para>
    6.44 +    </sect2>
    6.45 +    <sect2>
    6.46 +	<title><command
    6.47 +	  role="hg-ext-mq">qdelete</command>&emdash;delete a patch
    6.48 +	from the <filename role="special">series</filename>
    6.49 +	file</title>
    6.50 +
    6.51 +      <para id="x_5ec">The <command role="hg-ext-mq">qdelete</command> command
    6.52 +	removes the entry for a patch from the <filename
    6.53 +	  role="special">series</filename> file in the <filename
    6.54 +	  role="special" class="directory">.hg/patches</filename>
    6.55 +	directory.  It does not pop the patch if the patch is already
    6.56 +	applied.  By default, it does not delete the patch file; use
    6.57 +	the <option role="hg-ext-mq-cmd-qdel-opt">-f</option> option
    6.58 +	to do that.</para>
    6.59 +
    6.60 +      <para id="x_5ed">Options:</para>
    6.61 +      <itemizedlist>
    6.62 +	<listitem><para id="x_5ee"><option
    6.63 +	      role="hg-ext-mq-cmd-qdel-opt">-f</option>: Delete the
    6.64 +	    patch file.</para>
    6.65 +	</listitem></itemizedlist>
    6.66 +
    6.67 +    </sect2>
    6.68 +    <sect2>
    6.69 +      <title><command role="hg-ext-mq">qdiff</command>&emdash;print a
    6.70 +	diff of the topmost applied patch</title>
    6.71 +
    6.72 +      <para id="x_5ef">The <command role="hg-ext-mq">qdiff</command> command
    6.73 +	prints a diff of the topmost applied patch. It is equivalent
    6.74 +	to <command role="hg-cmd">hg diff -r-2:-1</command>.</para>
    6.75 +
    6.76 +    </sect2>
    6.77 +    <sect2>
    6.78 +      <title><command role="hg-ext-mq">qfold</command>&emdash;move
    6.79 +	applied patches into repository history</title>
    6.80 +
    6.81 +      <para id="x_72d">The <command>hg qfinish</command> command converts the
    6.82 +	specified applied patches into permanent changes by moving
    6.83 +	them out of MQ's control so that they will be treated as
    6.84 +	normal repository history.</para>
    6.85 +    </sect2>
    6.86 +
    6.87 +    <sect2>
    6.88 +      <title><command role="hg-ext-mq">qfold</command>&emdash;merge
    6.89 +	(<quote>fold</quote>) several patches into one</title>
    6.90 +
    6.91 +      <para id="x_5f0">The <command role="hg-ext-mq">qfold</command> command
    6.92 +	merges multiple patches into the topmost applied patch, so
    6.93 +	that the topmost applied patch makes the union of all of the
    6.94 +	changes in the patches in question.</para>
    6.95 +
    6.96 +      <para id="x_5f1">The patches to fold must not be applied; <command
    6.97 +	  role="hg-ext-mq">qfold</command> will exit with an error if
    6.98 +	any is.  The order in which patches are folded is significant;
    6.99 +	<command role="hg-cmd">hg qfold a b</command> means
   6.100 +	<quote>apply the current topmost patch, followed by
   6.101 +	  <literal>a</literal>, followed by
   6.102 +	  <literal>b</literal></quote>.</para>
   6.103 +
   6.104 +      <para id="x_5f2">The comments from the folded patches are appended to the
   6.105 +	comments of the destination patch, with each block of comments
   6.106 +	separated by three asterisk
   6.107 +	(<quote><literal>*</literal></quote>) characters.  Use the
   6.108 +	<option role="hg-ext-mq-cmd-qfold-opt">-e</option> option to
   6.109 +	edit the commit message for the combined patch/changeset after
   6.110 +	the folding has completed.</para>
   6.111 +
   6.112 +      <para id="x_5f3">Options:</para>
   6.113 +      <itemizedlist>
   6.114 +	<listitem><para id="x_5f4"><option
   6.115 +	      role="hg-ext-mq-cmd-qfold-opt">-e</option>: Edit the
   6.116 +	    commit message and patch description for the newly folded
   6.117 +	    patch.</para>
   6.118 +	</listitem>
   6.119 +	<listitem><para id="x_5f5"><option
   6.120 +	      role="hg-ext-mq-cmd-qfold-opt">-l</option>: Use the
   6.121 +	    contents of the given file as the new commit message and
   6.122 +	    patch description for the folded patch.</para>
   6.123 +	</listitem>
   6.124 +	<listitem><para id="x_5f6"><option
   6.125 +	      role="hg-ext-mq-cmd-qfold-opt">-m</option>: Use the
   6.126 +	    given text as the new commit message and patch description
   6.127 +	    for the folded patch.</para>
   6.128 +	</listitem></itemizedlist>
   6.129 +
   6.130 +    </sect2>
   6.131 +    <sect2>
   6.132 +      <title><command
   6.133 +	  role="hg-ext-mq">qheader</command>&emdash;display the
   6.134 +	header/description of a patch</title>
   6.135 +
   6.136 +      <para id="x_5f7">The <command role="hg-ext-mq">qheader</command> command
   6.137 +	prints the header, or description, of a patch.  By default, it
   6.138 +	prints the header of the topmost applied patch. Given an
   6.139 +	argument, it prints the header of the named patch.</para>
   6.140 +
   6.141 +    </sect2>
   6.142 +    <sect2>
   6.143 +      <title><command role="hg-ext-mq">qimport</command>&emdash;import
   6.144 +	a third-party patch into the queue</title>
   6.145 +
   6.146 +      <para id="x_5f8">The <command role="hg-ext-mq">qimport</command> command
   6.147 +	adds an entry for an external patch to the <filename
   6.148 +	  role="special">series</filename> file, and copies the patch
   6.149 +	into the <filename role="special"
   6.150 +	  class="directory">.hg/patches</filename> directory.  It adds
   6.151 +	the entry immediately after the topmost applied patch, but
   6.152 +	does not push the patch.</para>
   6.153 +
   6.154 +      <para id="x_5f9">If the <filename role="special"
   6.155 +	  class="directory">.hg/patches</filename> directory is a
   6.156 +	repository, <command role="hg-ext-mq">qimport</command>
   6.157 +	automatically does an <command role="hg-cmd">hg add</command>
   6.158 +	of the imported patch.</para>
   6.159 +
   6.160 +    </sect2>
   6.161 +    <sect2>
   6.162 +      <title><command role="hg-ext-mq">qinit</command>&emdash;prepare
   6.163 +	a repository to work with MQ</title>
   6.164 +
   6.165 +      <para id="x_5fa">The <command role="hg-ext-mq">qinit</command> command
   6.166 +	prepares a repository to work with MQ.  It creates a directory
   6.167 +	called <filename role="special"
   6.168 +	  class="directory">.hg/patches</filename>.</para>
   6.169 +
   6.170 +      <para id="x_5fb">Options:</para>
   6.171 +      <itemizedlist>
   6.172 +	<listitem><para id="x_5fc"><option
   6.173 +	      role="hg-ext-mq-cmd-qinit-opt">-c</option>: Create
   6.174 +	    <filename role="special"
   6.175 +	      class="directory">.hg/patches</filename> as a repository
   6.176 +	    in its own right.  Also creates a <filename
   6.177 +	      role="special">.hgignore</filename> file that will
   6.178 +	    ignore the <filename role="special">status</filename>
   6.179 +	    file.</para>
   6.180 +	</listitem></itemizedlist>
   6.181 +
   6.182 +      <para id="x_5fd">When the <filename role="special"
   6.183 +	  class="directory">.hg/patches</filename> directory is a
   6.184 +	repository, the <command role="hg-ext-mq">qimport</command>
   6.185 +	and <command role="hg-ext-mq">qnew</command> commands
   6.186 +	automatically <command role="hg-cmd">hg add</command> new
   6.187 +	patches.</para>
   6.188 +
   6.189 +    </sect2>
   6.190 +    <sect2>
   6.191 +      <title><command role="hg-ext-mq">qnew</command>&emdash;create a
   6.192 +	new patch</title>
   6.193 +
   6.194 +      <para id="x_5fe">The <command role="hg-ext-mq">qnew</command> command
   6.195 +	creates a new patch.  It takes one mandatory argument, the
   6.196 +	name to use for the patch file.  The newly created patch is
   6.197 +	created empty by default.  It is added to the <filename
   6.198 +	  role="special">series</filename> file after the current
   6.199 +	topmost applied patch, and is immediately pushed on top of
   6.200 +	that patch.</para>
   6.201 +
   6.202 +      <para id="x_5ff">If <command role="hg-ext-mq">qnew</command> finds modified
   6.203 +	files in the working directory, it will refuse to create a new
   6.204 +	patch unless the <option
   6.205 +	  role="hg-ext-mq-cmd-qnew-opt">-f</option> option is used
   6.206 +	(see below).  This behavior allows you to <command
   6.207 +	  role="hg-ext-mq">qrefresh</command> your topmost applied
   6.208 +	patch before you apply a new patch on top of it.</para>
   6.209 +
   6.210 +      <para id="x_600">Options:</para>
   6.211 +      <itemizedlist>
   6.212 +	<listitem><para id="x_601"><option
   6.213 +	      role="hg-ext-mq-cmd-qnew-opt">-f</option>: Create a new
   6.214 +	    patch if the contents of the working directory are
   6.215 +	    modified.  Any outstanding modifications are added to the
   6.216 +	    newly created patch, so after this command completes, the
   6.217 +	    working directory will no longer be modified.</para>
   6.218 +	</listitem>
   6.219 +	<listitem><para id="x_602"><option
   6.220 +	      role="hg-ext-mq-cmd-qnew-opt">-m</option>: Use the given
   6.221 +	    text as the commit message. This text will be stored at
   6.222 +	    the beginning of the patch file, before the patch
   6.223 +	    data.</para>
   6.224 +	</listitem></itemizedlist>
   6.225 +
   6.226 +    </sect2>
   6.227 +    <sect2>
   6.228 +      <title><command role="hg-ext-mq">qnext</command>&emdash;print
   6.229 +	the name of the next patch</title>
   6.230 +
   6.231 +      <para id="x_603">The <command role="hg-ext-mq">qnext</command> command
   6.232 +	prints the name name of the next patch in the <filename
   6.233 +	  role="special">series</filename> file after the topmost
   6.234 +	applied patch.  This patch will become the topmost applied
   6.235 +	patch if you run <command
   6.236 +	  role="hg-ext-mq">qpush</command>.</para>
   6.237 +
   6.238 +    </sect2>
   6.239 +    <sect2>
   6.240 +      <title><command role="hg-ext-mq">qpop</command>&emdash;pop
   6.241 +	patches off the stack</title>
   6.242 +
   6.243 +      <para id="x_604">The <command role="hg-ext-mq">qpop</command> command
   6.244 +	removes applied patches from the top of the stack of applied
   6.245 +	patches.  By default, it removes only one patch.</para>
   6.246 +
   6.247 +      <para id="x_605">This command removes the changesets that represent the
   6.248 +	popped patches from the repository, and updates the working
   6.249 +	directory to undo the effects of the patches.</para>
   6.250 +
   6.251 +      <para id="x_606">This command takes an optional argument, which it uses as
   6.252 +	the name or index of the patch to pop to.  If given a name, it
   6.253 +	will pop patches until the named patch is the topmost applied
   6.254 +	patch.  If given a number, <command
   6.255 +	  role="hg-ext-mq">qpop</command> treats the number as an
   6.256 +	index into the entries in the series file, counting from zero
   6.257 +	(empty lines and lines containing only comments do not count).
   6.258 +	It pops patches until the patch identified by the given index
   6.259 +	is the topmost applied patch.</para>
   6.260 +
   6.261 +      <para id="x_607">The <command role="hg-ext-mq">qpop</command> command does
   6.262 +	not read or write patches or the <filename
   6.263 +	  role="special">series</filename> file.  It is thus safe to
   6.264 +	<command role="hg-ext-mq">qpop</command> a patch that you have
   6.265 +	removed from the <filename role="special">series</filename>
   6.266 +	file, or a patch that you have renamed or deleted entirely.
   6.267 +	In the latter two cases, use the name of the patch as it was
   6.268 +	when you applied it.</para>
   6.269 +
   6.270 +      <para id="x_608">By default, the <command role="hg-ext-mq">qpop</command>
   6.271 +	command will not pop any patches if the working directory has
   6.272 +	been modified.  You can override this behavior using the
   6.273 +	<option role="hg-ext-mq-cmd-qpop-opt">-f</option> option,
   6.274 +	which reverts all modifications in the working
   6.275 +	directory.</para>
   6.276 +
   6.277 +      <para id="x_609">Options:</para>
   6.278 +      <itemizedlist>
   6.279 +	<listitem><para id="x_60a"><option
   6.280 +	      role="hg-ext-mq-cmd-qpop-opt">-a</option>: Pop all
   6.281 +	    applied patches.  This returns the repository to its state
   6.282 +	    before you applied any patches.</para>
   6.283 +	</listitem>
   6.284 +	<listitem><para id="x_60b"><option
   6.285 +	      role="hg-ext-mq-cmd-qpop-opt">-f</option>: Forcibly
   6.286 +	    revert any modifications to the working directory when
   6.287 +	    popping.</para>
   6.288 +	</listitem>
   6.289 +	<listitem><para id="x_60c"><option
   6.290 +	      role="hg-ext-mq-cmd-qpop-opt">-n</option>: Pop a patch
   6.291 +	    from the named queue.</para>
   6.292 +	</listitem></itemizedlist>
   6.293 +
   6.294 +      <para id="x_60d">The <command role="hg-ext-mq">qpop</command> command
   6.295 +	removes one line from the end of the <filename
   6.296 +	  role="special">status</filename> file for each patch that it
   6.297 +	pops.</para>
   6.298 +
   6.299 +    </sect2>
   6.300 +    <sect2>
   6.301 +      <title><command role="hg-ext-mq">qprev</command>&emdash;print
   6.302 +	the name of the previous patch</title>
   6.303 +
   6.304 +      <para id="x_60e">The <command role="hg-ext-mq">qprev</command> command
   6.305 +	prints the name of the patch in the <filename
   6.306 +	  role="special">series</filename> file that comes before the
   6.307 +	topmost applied patch. This will become the topmost applied
   6.308 +	patch if you run <command
   6.309 +	  role="hg-ext-mq">qpop</command>.</para>
   6.310 +
   6.311 +    </sect2>
   6.312 +    <sect2 id="sec:mqref:cmd:qpush">
   6.313 +      <title><command role="hg-ext-mq">qpush</command>&emdash;push
   6.314 +	patches onto the stack</title>
   6.315 +
   6.316 +      <para id="x_60f">The <command role="hg-ext-mq">qpush</command> command adds
   6.317 +	patches onto the applied stack.  By default, it adds only one
   6.318 +	patch.</para>
   6.319 +
   6.320 +      <para id="x_610">This command creates a new changeset to represent each
   6.321 +	applied patch, and updates the working directory to apply the
   6.322 +	effects of the patches.</para>
   6.323 +
   6.324 +      <para id="x_611">The default data used when creating a changeset are as
   6.325 +	follows:</para>
   6.326 +      <itemizedlist>
   6.327 +	<listitem><para id="x_612">The commit date and time zone are the current
   6.328 +	    date and time zone.  Because these data are used to
   6.329 +	    compute the identity of a changeset, this means that if
   6.330 +	    you <command role="hg-ext-mq">qpop</command> a patch and
   6.331 +	    <command role="hg-ext-mq">qpush</command> it again, the
   6.332 +	    changeset that you push will have a different identity
   6.333 +	    than the changeset you popped.</para>
   6.334 +	</listitem>
   6.335 +	<listitem><para id="x_613">The author is the same as the default used by
   6.336 +	    the <command role="hg-cmd">hg commit</command>
   6.337 +	    command.</para>
   6.338 +	</listitem>
   6.339 +	<listitem><para id="x_614">The commit message is any text from the patch
   6.340 +	    file that comes before the first diff header.  If there is
   6.341 +	    no such text, a default commit message is used that
   6.342 +	    identifies the name of the patch.</para>
   6.343 +	</listitem></itemizedlist>
   6.344 +      <para id="x_615">If a patch contains a Mercurial patch header,
   6.345 +	the information in the patch header overrides these
   6.346 +	defaults.</para>
   6.347 +
   6.348 +      <para id="x_616">Options:</para>
   6.349 +      <itemizedlist>
   6.350 +	<listitem><para id="x_617"><option
   6.351 +	      role="hg-ext-mq-cmd-qpush-opt">-a</option>: Push all
   6.352 +	    unapplied patches from the <filename
   6.353 +	      role="special">series</filename> file until there are
   6.354 +	    none left to push.</para>
   6.355 +	</listitem>
   6.356 +	<listitem><para id="x_618"><option
   6.357 +	      role="hg-ext-mq-cmd-qpush-opt">-l</option>: Add the name
   6.358 +	    of the patch to the end of the commit message.</para>
   6.359 +	</listitem>
   6.360 +	<listitem><para id="x_619"><option
   6.361 +	      role="hg-ext-mq-cmd-qpush-opt">-m</option>: If a patch
   6.362 +	    fails to apply cleanly, use the entry for the patch in
   6.363 +	    another saved queue to compute the parameters for a
   6.364 +	    three-way merge, and perform a three-way merge using the
   6.365 +	    normal Mercurial merge machinery.  Use the resolution of
   6.366 +	    the merge as the new patch content.</para>
   6.367 +	</listitem>
   6.368 +	<listitem><para id="x_61a"><option
   6.369 +	      role="hg-ext-mq-cmd-qpush-opt">-n</option>: Use the
   6.370 +	    named queue if merging while pushing.</para>
   6.371 +	</listitem></itemizedlist>
   6.372 +
   6.373 +      <para id="x_61b">The <command role="hg-ext-mq">qpush</command> command
   6.374 +	reads, but does not modify, the <filename
   6.375 +	  role="special">series</filename> file.  It appends one line
   6.376 +	to the <command role="hg-cmd">hg status</command> file for
   6.377 +	each patch that it pushes.</para>
   6.378 +
   6.379 +    </sect2>
   6.380 +    <sect2>
   6.381 +      <title><command
   6.382 +	  role="hg-ext-mq">qrefresh</command>&emdash;update the
   6.383 +	topmost applied patch</title>
   6.384 +
   6.385 +      <para id="x_61c">The <command role="hg-ext-mq">qrefresh</command> command
   6.386 +	updates the topmost applied patch.  It modifies the patch,
   6.387 +	removes the old changeset that represented the patch, and
   6.388 +	creates a new changeset to represent the modified
   6.389 +	patch.</para>
   6.390 +
   6.391 +      <para id="x_61d">The <command role="hg-ext-mq">qrefresh</command> command
   6.392 +	looks for the following modifications:</para>
   6.393 +      <itemizedlist>
   6.394 +	<listitem><para id="x_61e">Changes to the commit message, i.e. the text
   6.395 +	    before the first diff header in the patch file, are
   6.396 +	    reflected in the new changeset that represents the
   6.397 +	    patch.</para>
   6.398 +	</listitem>
   6.399 +	<listitem><para id="x_61f">Modifications to tracked files in the working
   6.400 +	    directory are added to the patch.</para>
   6.401 +	</listitem>
   6.402 +	<listitem><para id="x_620">Changes to the files tracked using <command
   6.403 +	      role="hg-cmd">hg add</command>, <command
   6.404 +	      role="hg-cmd">hg copy</command>, <command
   6.405 +	      role="hg-cmd">hg remove</command>, or <command
   6.406 +	      role="hg-cmd">hg rename</command>.  Added files and copy
   6.407 +	    and rename destinations are added to the patch, while
   6.408 +	    removed files and rename sources are removed.</para>
   6.409 +	</listitem></itemizedlist>
   6.410 +
   6.411 +      <para id="x_621">Even if <command role="hg-ext-mq">qrefresh</command>
   6.412 +	detects no changes, it still recreates the changeset that
   6.413 +	represents the patch.  This causes the identity of the
   6.414 +	changeset to differ from the previous changeset that
   6.415 +	identified the patch.</para>
   6.416 +
   6.417 +      <para id="x_622">Options:</para>
   6.418 +      <itemizedlist>
   6.419 +	<listitem><para id="x_623"><option
   6.420 +	      role="hg-ext-mq-cmd-qrefresh-opt">-e</option>: Modify
   6.421 +	    the commit and patch description, using the preferred text
   6.422 +	    editor.</para>
   6.423 +	</listitem>
   6.424 +	<listitem><para id="x_624"><option
   6.425 +	      role="hg-ext-mq-cmd-qrefresh-opt">-m</option>: Modify
   6.426 +	    the commit message and patch description, using the given
   6.427 +	    text.</para>
   6.428 +	</listitem>
   6.429 +	<listitem><para id="x_625"><option
   6.430 +	      role="hg-ext-mq-cmd-qrefresh-opt">-l</option>: Modify
   6.431 +	    the commit message and patch description, using text from
   6.432 +	    the given file.</para>
   6.433 +	</listitem></itemizedlist>
   6.434 +
   6.435 +    </sect2>
   6.436 +    <sect2>
   6.437 +      <title><command role="hg-ext-mq">qrename</command>&emdash;rename
   6.438 +	a patch</title>
   6.439 +
   6.440 +      <para id="x_626">The <command role="hg-ext-mq">qrename</command> command
   6.441 +	renames a patch, and changes the entry for the patch in the
   6.442 +	<filename role="special">series</filename> file.</para>
   6.443 +
   6.444 +      <para id="x_627">With a single argument, <command
   6.445 +	  role="hg-ext-mq">qrename</command> renames the topmost
   6.446 +	applied patch.  With two arguments, it renames its first
   6.447 +	argument to its second.</para>
   6.448 +
   6.449 +    </sect2>
   6.450 +    <sect2>
   6.451 +      <title><command role="hg-ext-mq">qseries</command>&emdash;print
   6.452 +	the entire patch series</title>
   6.453 +
   6.454 +      <para id="x_62a">The <command role="hg-ext-mq">qseries</command> command
   6.455 +	prints the entire patch series from the <filename
   6.456 +	  role="special">series</filename> file.  It prints only patch
   6.457 +	names, not empty lines or comments.  It prints in order from
   6.458 +	first to be applied to last.</para>
   6.459 +
   6.460 +    </sect2>
   6.461 +    <sect2>
   6.462 +      <title><command role="hg-ext-mq">qtop</command>&emdash;print the
   6.463 +	name of the current patch</title>
   6.464 +
   6.465 +      <para id="x_62b">The <command role="hg-ext-mq">qtop</command> prints the
   6.466 +	name of the topmost currently applied patch.</para>
   6.467 +
   6.468 +    </sect2>
   6.469 +    <sect2>
   6.470 +      <title><command
   6.471 +	  role="hg-ext-mq">qunapplied</command>&emdash;print patches
   6.472 +	not yet applied</title>
   6.473 +
   6.474 +      <para id="x_62c">The <command role="hg-ext-mq">qunapplied</command> command
   6.475 +	prints the names of patches from the <filename
   6.476 +	  role="special">series</filename> file that are not yet
   6.477 +	applied.  It prints them in order from the next patch that
   6.478 +	will be pushed to the last.</para>
   6.479 +
   6.480 +    </sect2>
   6.481 +    <sect2>
   6.482 +      <title><command role="hg-cmd">hg strip</command>&emdash;remove a
   6.483 +	revision and descendants</title>
   6.484 +
   6.485 +      <para id="x_62d">The <command role="hg-cmd">hg strip</command> command
   6.486 +	removes a revision, and all of its descendants, from the
   6.487 +	repository.  It undoes the effects of the removed revisions
   6.488 +	from the repository, and updates the working directory to the
   6.489 +	first parent of the removed revision.</para>
   6.490 +
   6.491 +      <para id="x_62e">The <command role="hg-cmd">hg strip</command> command
   6.492 +	saves a backup of the removed changesets in a bundle, so that
   6.493 +	they can be reapplied if removed in error.</para>
   6.494 +
   6.495 +      <para id="x_62f">Options:</para>
   6.496 +      <itemizedlist>
   6.497 +	<listitem><para id="x_630"><option role="hg-opt-strip">-b</option>: Save
   6.498 +	    unrelated changesets that are intermixed with the stripped
   6.499 +	    changesets in the backup bundle.</para>
   6.500 +	</listitem>
   6.501 +	<listitem><para id="x_631"><option role="hg-opt-strip">-f</option>: If a
   6.502 +	    branch has multiple heads, remove all heads.</para>
   6.503 +	</listitem>
   6.504 +	<listitem><para id="x_632"><option role="hg-opt-strip">-n</option>: Do
   6.505 +	    not save a backup bundle.</para>
   6.506 +	</listitem></itemizedlist>
   6.507 +
   6.508 +    </sect2>
   6.509 +  </sect1>
   6.510 +  <sect1>
   6.511 +    <title>MQ file reference</title>
   6.512 +
   6.513 +    <sect2>
   6.514 +      <title>The <filename role="special">series</filename>
   6.515 +	file</title>
   6.516 +
   6.517 +      <para id="x_633">The <filename role="special">series</filename> file
   6.518 +	contains a list of the names of all patches that MQ can apply.
   6.519 +	It is represented as a list of names, with one name saved per
   6.520 +	line.  Leading and trailing white space in each line are
   6.521 +	ignored.</para>
   6.522 +
   6.523 +      <para id="x_634">Lines may contain comments.  A comment begins with the
   6.524 +	<quote><literal>#</literal></quote> character, and extends to
   6.525 +	the end of the line.  Empty lines, and lines that contain only
   6.526 +	comments, are ignored.</para>
   6.527 +
   6.528 +      <para id="x_635">You will often need to edit the <filename
   6.529 +	  role="special">series</filename> file by hand, hence the
   6.530 +	support for comments and empty lines noted above.  For
   6.531 +	example, you can comment out a patch temporarily, and <command
   6.532 +	  role="hg-ext-mq">qpush</command> will skip over that patch
   6.533 +	when applying patches.  You can also change the order in which
   6.534 +	patches are applied by reordering their entries in the
   6.535 +	<filename role="special">series</filename> file.</para>
   6.536 +
   6.537 +      <para id="x_636">Placing the <filename role="special">series</filename>
   6.538 +	file under revision control is also supported; it is a good
   6.539 +	idea to place all of the patches that it refers to under
   6.540 +	revision control, as well.  If you create a patch directory
   6.541 +	using the <option role="hg-ext-mq-cmd-qinit-opt">-c</option>
   6.542 +	option to <command role="hg-ext-mq">qinit</command>, this will
   6.543 +	be done for you automatically.</para>
   6.544 +
   6.545 +    </sect2>
   6.546 +    <sect2>
   6.547 +      <title>The <filename role="special">status</filename>
   6.548 +	file</title>
   6.549 +
   6.550 +      <para id="x_637">The <filename role="special">status</filename> file
   6.551 +	contains the names and changeset hashes of all patches that MQ
   6.552 +	currently has applied.  Unlike the <filename
   6.553 +	  role="special">series</filename> file, this file is not
   6.554 +	intended for editing.  You should not place this file under
   6.555 +	revision control, or modify it in any way.  It is used by MQ
   6.556 +	strictly for internal book-keeping.</para>
   6.557 +
   6.558 +    </sect2>
   6.559 +  </sect1>
   6.560 +</appendix>
   6.561 +
   6.562 +<!--
   6.563 +local variables: 
   6.564 +sgml-parent-document: ("00book.xml" "book" "appendix")
   6.565 +end:
   6.566 +-->
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/fr/appC-srcinstall.xml	Sun Aug 16 04:58:01 2009 +0200
     7.3 @@ -0,0 +1,66 @@
     7.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     7.5 +
     7.6 +<appendix id="chap:srcinstall">
     7.7 +  <?dbhtml filename="installing-mercurial-from-source.html"?>
     7.8 +  <title>Installing Mercurial from source</title>
     7.9 +
    7.10 +  <sect1 id="sec:srcinstall:unixlike">
    7.11 +    <title>On a Unix-like system</title>
    7.12 +
    7.13 +    <para id="x_5e0">If you are using a Unix-like system that has a sufficiently
    7.14 +      recent version of Python (2.3 or newer) available, it is easy to
    7.15 +      install Mercurial from source.</para>
    7.16 +    <orderedlist>
    7.17 +      <listitem><para id="x_5e1">Download a recent source tarball from <ulink
    7.18 +	    url="http://www.selenic.com/mercurial/download">http://www.selenic.com/mercurial/download</ulink>.</para>
    7.19 +      </listitem>
    7.20 +      <listitem><para id="x_5e2">Unpack the tarball:</para>
    7.21 +	<programlisting>gzip -dc mercurial-MYVERSION.tar.gz | tar xf -</programlisting>
    7.22 +      </listitem>
    7.23 +      <listitem><para id="x_5e3">Go into the source directory and run the
    7.24 +	  installer script.  This will build Mercurial and install it
    7.25 +	  in your home directory.</para>
    7.26 +	<programlisting>cd mercurial-MYVERSION
    7.27 +python setup.py install --force --home=$HOME</programlisting>
    7.28 +      </listitem>
    7.29 +    </orderedlist>
    7.30 +    <para id="x_5e4">Once the install finishes, Mercurial will be in the
    7.31 +      <literal>bin</literal> subdirectory of your home directory.
    7.32 +      Don't forget to make sure that this directory is present in your
    7.33 +      shell's search path.</para>
    7.34 +
    7.35 +    <para id="x_5e5">You will probably need to set the <envar>PYTHONPATH</envar>
    7.36 +      environment variable so that the Mercurial executable can find
    7.37 +      the rest of the Mercurial packages.  For example, on my laptop,
    7.38 +      I have set it to <literal>/home/bos/lib/python</literal>.  The
    7.39 +      exact path that you will need to use depends on how Python was
    7.40 +      built for your system, but should be easy to figure out.  If
    7.41 +      you're uncertain, look through the output of the installer
    7.42 +      script above, and see where the contents of the
    7.43 +      <literal>mercurial</literal> directory were installed to.</para>
    7.44 +
    7.45 +  </sect1>
    7.46 +  <sect1>
    7.47 +    <title>On Windows</title>
    7.48 +
    7.49 +    <para id="x_5e6">Building and installing Mercurial on Windows requires a
    7.50 +      variety of tools, a fair amount of technical knowledge, and
    7.51 +      considerable patience.  I very much <emphasis>do not
    7.52 +	recommend</emphasis> this route if you are a <quote>casual
    7.53 +	user</quote>.  Unless you intend to hack on Mercurial, I
    7.54 +      strongly suggest that you use a binary package instead.</para>
    7.55 +
    7.56 +    <para id="x_5e7">If you are intent on building Mercurial from source on
    7.57 +      Windows, follow the <quote>hard way</quote> directions on the
    7.58 +      Mercurial wiki at <ulink
    7.59 +	url="http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall">http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall</ulink>, 
    7.60 +      and expect the process to involve a lot of fiddly work.</para>
    7.61 +
    7.62 +  </sect1>
    7.63 +</appendix>
    7.64 +
    7.65 +<!--
    7.66 +local variables: 
    7.67 +sgml-parent-document: ("00book.xml" "book" "appendix")
    7.68 +end:
    7.69 +-->
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/fr/appD-license.xml	Sun Aug 16 04:58:01 2009 +0200
     8.3 @@ -0,0 +1,185 @@
     8.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     8.5 +
     8.6 +<chapter>
     8.7 +<title>Open Publication License</title>
     8.8 +<para>\label{cha:opl}</para>
     8.9 +
    8.10 +<para>Version 1.0, 8 June 1999</para>
    8.11 +
    8.12 +<sect1>
    8.13 +<title>Requirements on both unmodified and modified versions</title>
    8.14 +
    8.15 +<para>The Open Publication works may be reproduced and distributed in whole
    8.16 +or in part, in any medium physical or electronic, provided that the
    8.17 +terms of this license are adhered to, and that this license or an
    8.18 +incorporation of it by reference (with any options elected by the
    8.19 +author(s) and/or publisher) is displayed in the reproduction.</para>
    8.20 +
    8.21 +<para>Proper form for an incorporation by reference is as follows:</para>
    8.22 +
    8.23 +<blockquote>
    8.24 +<para>  Copyright (c) <emphasis>year</emphasis> by <emphasis>author's name or designee</emphasis>. This
    8.25 +  material may be distributed only subject to the terms and conditions
    8.26 +  set forth in the Open Publication License, v<emphasis>x.y</emphasis> or later (the
    8.27 +  latest version is presently available at
    8.28 +  <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
    8.29 +</blockquote>
    8.30 +
    8.31 +<para>The reference must be immediately followed with any options elected by
    8.32 +the author(s) and/or publisher of the document (see
    8.33 +section <xref linkend="sec:opl:options"/>).</para>
    8.34 +
    8.35 +<para>Commercial redistribution of Open Publication-licensed material is
    8.36 +permitted.</para>
    8.37 +
    8.38 +<para>Any publication in standard (paper) book form shall require the
    8.39 +citation of the original publisher and author. The publisher and
    8.40 +author's names shall appear on all outer surfaces of the book. On all
    8.41 +outer surfaces of the book the original publisher's name shall be as
    8.42 +large as the title of the work and cited as possessive with respect to
    8.43 +the title.</para>
    8.44 +
    8.45 +</sect1>
    8.46 +<sect1>
    8.47 +<title>Copyright</title>
    8.48 +
    8.49 +<para>The copyright to each Open Publication is owned by its author(s) or
    8.50 +designee.
    8.51 +</para>
    8.52 +
    8.53 +</sect1>
    8.54 +<sect1>
    8.55 +<title>Scope of license</title>
    8.56 +
    8.57 +<para>The following license terms apply to all Open Publication works,
    8.58 +unless otherwise explicitly stated in the document.
    8.59 +</para>
    8.60 +
    8.61 +<para>Mere aggregation of Open Publication works or a portion of an Open
    8.62 +Publication work with other works or programs on the same media shall
    8.63 +not cause this license to apply to those other works. The aggregate
    8.64 +work shall contain a notice specifying the inclusion of the Open
    8.65 +Publication material and appropriate copyright notice.
    8.66 +</para>
    8.67 +
    8.68 +<para><emphasis role="bold">Severability</emphasis>. If any part of this license is found to be
    8.69 +unenforceable in any jurisdiction, the remaining portions of the
    8.70 +license remain in force.
    8.71 +</para>
    8.72 +
    8.73 +<para><emphasis role="bold">No warranty</emphasis>. Open Publication works are licensed and provided
    8.74 +<quote>as is</quote> without warranty of any kind, express or implied, including,
    8.75 +but not limited to, the implied warranties of merchantability and
    8.76 +fitness for a particular purpose or a warranty of non-infringement.
    8.77 +</para>
    8.78 +
    8.79 +</sect1>
    8.80 +<sect1>
    8.81 +<title>Requirements on modified works</title>
    8.82 +
    8.83 +<para>All modified versions of documents covered by this license, including
    8.84 +translations, anthologies, compilations and partial documents, must
    8.85 +meet the following requirements:
    8.86 +</para>
    8.87 +
    8.88 +<orderedlist>
    8.89 +<listitem><para>The modified version must be labeled as such.
    8.90 +</para>
    8.91 +</listitem>
    8.92 +<listitem><para>The person making the modifications must be identified and the
    8.93 +  modifications dated.
    8.94 +</para>
    8.95 +</listitem>
    8.96 +<listitem><para>Acknowledgement of the original author and publisher if
    8.97 +  applicable must be retained according to normal academic citation
    8.98 +  practices.
    8.99 +</para>
   8.100 +</listitem>
   8.101 +<listitem><para>The location of the original unmodified document must be
   8.102 +  identified.
   8.103 +</para>
   8.104 +</listitem>
   8.105 +<listitem><para>The original author's (or authors') name(s) may not be used to
   8.106 +  assert or imply endorsement of the resulting document without the
   8.107 +  original author's (or authors') permission.
   8.108 +</para>
   8.109 +</listitem></orderedlist>
   8.110 +
   8.111 +</sect1>
   8.112 +<sect1>
   8.113 +<title>Good-practice recommendations</title>
   8.114 +
   8.115 +<para>In addition to the requirements of this license, it is requested from
   8.116 +and strongly recommended of redistributors that:
   8.117 +</para>
   8.118 +
   8.119 +<orderedlist>
   8.120 +<listitem><para>If you are distributing Open Publication works on hardcopy or
   8.121 +  CD-ROM, you provide email notification to the authors of your intent
   8.122 +  to redistribute at least thirty days before your manuscript or media
   8.123 +  freeze, to give the authors time to provide updated documents. This
   8.124 +  notification should describe modifications, if any, made to the
   8.125 +  document.
   8.126 +</para>
   8.127 +</listitem>
   8.128 +<listitem><para>All substantive modifications (including deletions) be either
   8.129 +  clearly marked up in the document or else described in an attachment
   8.130 +  to the document.
   8.131 +</para>
   8.132 +</listitem>
   8.133 +<listitem><para>Finally, while it is not mandatory under this license, it is
   8.134 +  considered good form to offer a free copy of any hardcopy and CD-ROM
   8.135 +  expression of an Open Publication-licensed work to its author(s).
   8.136 +</para>
   8.137 +</listitem></orderedlist>
   8.138 +
   8.139 +</sect1>
   8.140 +<sect1>
   8.141 +<title>License options</title>
   8.142 +<para>\label{sec:opl:options}
   8.143 +</para>
   8.144 +
   8.145 +<para>The author(s) and/or publisher of an Open Publication-licensed
   8.146 +document may elect certain options by appending language to the
   8.147 +reference to or copy of the license. These options are considered part
   8.148 +of the license instance and must be included with the license (or its
   8.149 +incorporation by reference) in derived works.
   8.150 +</para>
   8.151 +
   8.152 +<orderedlist>
   8.153 +<listitem><para>To prohibit distribution of substantively modified versions
   8.154 +  without the explicit permission of the author(s). <quote>Substantive
   8.155 +  modification</quote> is defined as a change to the semantic content of the
   8.156 +  document, and excludes mere changes in format or typographical
   8.157 +  corrections.
   8.158 +</para>
   8.159 +</listitem>
   8.160 +<listitem><para>  To accomplish this, add the phrase <quote>Distribution of substantively
   8.161 +  modified versions of this document is prohibited without the
   8.162 +  explicit permission of the copyright holder.</quote> to the license
   8.163 +  reference or copy.
   8.164 +</para>
   8.165 +</listitem>
   8.166 +</para>
   8.167 +</listitem>
   8.168 +<listitem><para>To prohibit any publication of this work or derivative works in
   8.169 +  whole or in part in standard (paper) book form for commercial
   8.170 +  purposes is prohibited unless prior permission is obtained from the
   8.171 +  copyright holder.
   8.172 +</para>
   8.173 +</listitem>
   8.174 +<listitem><para>  To accomplish this, add the phrase <quote>Distribution of the work or
   8.175 +  derivative of the work in any standard (paper) book form is
   8.176 +  prohibited unless prior permission is obtained from the copyright
   8.177 +  holder.</quote> to the license reference or copy.
   8.178 +</para>
   8.179 +</listitem></orderedlist>
   8.180 +
   8.181 +</sect1>
   8.182 +</chapter>
   8.183 +
   8.184 +<!--
   8.185 +local variables: 
   8.186 +sgml-parent-document: ("00book.xml" "book" "chapter")
   8.187 +end:
   8.188 +-->
   8.189 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/fr/autoid.py	Sun Aug 16 04:58:01 2009 +0200
     9.3 @@ -0,0 +1,47 @@
     9.4 +#!/usr/bin/env python
     9.5 +#
     9.6 +# Add unique ID attributes to para tags.  This script should only be
     9.7 +# run by one person, since otherwise it introduces the possibility of
     9.8 +# chaotic conflicts among tags.
     9.9 +
    9.10 +import glob, os, re, sys
    9.11 +
    9.12 +tagged = re.compile('<para[^>]* id="x_([0-9a-f]+)"[^>]*>', re.M)
    9.13 +untagged = re.compile('<para>')
    9.14 +
    9.15 +names = glob.glob('ch*.xml') + glob.glob('app*.xml')
    9.16 +
    9.17 +# First pass: find the highest-numbered paragraph ID.
    9.18 +
    9.19 +biggest_id = 0
    9.20 +seen = set()
    9.21 +errs = 0
    9.22 +
    9.23 +for name in names:
    9.24 +    for m in tagged.finditer(open(name).read()):
    9.25 +        i = int(m.group(1),16)
    9.26 +        if i in seen:
    9.27 +            print >> sys.stderr, '%s: duplication of ID %s' % (name, i)
    9.28 +            errs += 1
    9.29 +        seen.add(i)
    9.30 +        if i > biggest_id:
    9.31 +            biggest_id = i
    9.32 +
    9.33 +def retag(s):
    9.34 +    global biggest_id
    9.35 +    biggest_id += 1
    9.36 +    return '<para id="x_%x">' % biggest_id
    9.37 +
    9.38 +# Second pass: add IDs to paragraphs that currently lack them.
    9.39 +
    9.40 +for name in names:
    9.41 +    f = open(name).read()
    9.42 +    f1 = untagged.sub(retag, f)
    9.43 +    if f1 != f:
    9.44 +        tmpname = name + '.tmp'
    9.45 +        fp = open(tmpname, 'w')
    9.46 +        fp.write(f1)
    9.47 +        fp.close()
    9.48 +        os.rename(tmpname, name)
    9.49 +
    9.50 +sys.exit(errs)
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/fr/book-shortcuts.xml	Sun Aug 16 04:58:01 2009 +0200
    10.3 @@ -0,0 +1,3 @@
    10.4 +<!-- Please keep the contents of this file sorted. -->
    10.5 +
    10.6 +<!ENTITY emdash "&#8212;">
    11.1 --- a/fr/bookhtml.cfg	Sun Aug 16 03:41:39 2009 +0200
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,18 +0,0 @@
    11.4 -% -*- latex -*-
    11.5 -
    11.6 -\Preamble{xhtml}
    11.7 -
    11.8 -% Tex4ht's default definition of lists is complete crap.
    11.9 -% Unfortunately, it can't distinguish between "ul" and "dl" lists.
   11.10 -
   11.11 -\ConfigureList{itemize}%
   11.12 -   {\EndP\HCode{<ul>}\let\endItem=\empty}
   11.13 -   {\ifvmode \IgnorePar\fi
   11.14 -    \EndP\HCode{</li></ul>}\ShowPar}
   11.15 -   {\endItem \def\endItem{\EndP\Tg</span>}\HCode{<li><span class="dt">}}
   11.16 -   {\HCode{</span><span class="dd">}}
   11.17 -\def\textbullet{}
   11.18 -
   11.19 -\begin{document}
   11.20 -
   11.21 -\EndPreamble
    12.1 --- a/fr/branch.tex	Sun Aug 16 03:41:39 2009 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,392 +0,0 @@
    12.4 -\chapter{Managing releases and branchy development}
    12.5 -\label{chap:branch}
    12.6 -
    12.7 -Mercurial provides several mechanisms for you to manage a project that
    12.8 -is making progress on multiple fronts at once.  To understand these
    12.9 -mechanisms, let's first take a brief look at a fairly normal software
   12.10 -project structure.
   12.11 -
   12.12 -Many software projects issue periodic ``major'' releases that contain
   12.13 -substantial new features.  In parallel, they may issue ``minor''
   12.14 -releases.  These are usually identical to the major releases off which
   12.15 -they're based, but with a few bugs fixed.
   12.16 -
   12.17 -In this chapter, we'll start by talking about how to keep records of
   12.18 -project milestones such as releases.  We'll then continue on to talk
   12.19 -about the flow of work between different phases of a project, and how
   12.20 -Mercurial can help you to isolate and manage this work.
   12.21 -
   12.22 -\section{Giving a persistent name to a revision}
   12.23 -
   12.24 -Once you decide that you'd like to call a particular revision a
   12.25 -``release'', it's a good idea to record the identity of that revision.
   12.26 -This will let you reproduce that release at a later date, for whatever
   12.27 -purpose you might need at the time (reproducing a bug, porting to a
   12.28 -new platform, etc).
   12.29 -\interaction{tag.init}
   12.30 -
   12.31 -Mercurial lets you give a permanent name to any revision using the
   12.32 -\hgcmd{tag} command.  Not surprisingly, these names are called
   12.33 -``tags''.
   12.34 -\interaction{tag.tag}
   12.35 -
   12.36 -A tag is nothing more than a ``symbolic name'' for a revision.  Tags
   12.37 -exist purely for your convenience, so that you have a handy permanent
   12.38 -way to refer to a revision; Mercurial doesn't interpret the tag names
   12.39 -you use in any way.  Neither does Mercurial place any restrictions on
   12.40 -the name of a tag, beyond a few that are necessary to ensure that a
   12.41 -tag can be parsed unambiguously.  A tag name cannot contain any of the
   12.42 -following characters:
   12.43 -\begin{itemize}
   12.44 -\item Colon (ASCII 58, ``\texttt{:}'')
   12.45 -\item Carriage return (ASCII 13, ``\Verb+\r+'')
   12.46 -\item Newline (ASCII 10, ``\Verb+\n+'')
   12.47 -\end{itemize}
   12.48 -
   12.49 -You can use the \hgcmd{tags} command to display the tags present in
   12.50 -your repository.  In the output, each tagged revision is identified
   12.51 -first by its name, then by revision number, and finally by the unique
   12.52 -hash of the revision.  
   12.53 -\interaction{tag.tags}
   12.54 -Notice that \texttt{tip} is listed in the output of \hgcmd{tags}.  The
   12.55 -\texttt{tip} tag is a special ``floating'' tag, which always
   12.56 -identifies the newest revision in the repository.
   12.57 -
   12.58 -In the output of the \hgcmd{tags} command, tags are listed in reverse
   12.59 -order, by revision number.  This usually means that recent tags are
   12.60 -listed before older tags.  It also means that \texttt{tip} is always
   12.61 -going to be the first tag listed in the output of \hgcmd{tags}.
   12.62 -
   12.63 -When you run \hgcmd{log}, if it displays a revision that has tags
   12.64 -associated with it, it will print those tags.
   12.65 -\interaction{tag.log}
   12.66 -
   12.67 -Any time you need to provide a revision~ID to a Mercurial command, the
   12.68 -command will accept a tag name in its place.  Internally, Mercurial
   12.69 -will translate your tag name into the corresponding revision~ID, then
   12.70 -use that.
   12.71 -\interaction{tag.log.v1.0}
   12.72 -
   12.73 -There's no limit on the number of tags you can have in a repository,
   12.74 -or on the number of tags that a single revision can have.  As a
   12.75 -practical matter, it's not a great idea to have ``too many'' (a number
   12.76 -which will vary from project to project), simply because tags are
   12.77 -supposed to help you to find revisions.  If you have lots of tags, the
   12.78 -ease of using them to identify revisions diminishes rapidly.
   12.79 -
   12.80 -For example, if your project has milestones as frequent as every few
   12.81 -days, it's perfectly reasonable to tag each one of those.  But if you
   12.82 -have a continuous build system that makes sure every revision can be
   12.83 -built cleanly, you'd be introducing a lot of noise if you were to tag
   12.84 -every clean build.  Instead, you could tag failed builds (on the
   12.85 -assumption that they're rare!), or simply not use tags to track
   12.86 -buildability.
   12.87 -
   12.88 -If you want to remove a tag that you no longer want, use
   12.89 -\hgcmdargs{tag}{--remove}.  
   12.90 -\interaction{tag.remove}
   12.91 -You can also modify a tag at any time, so that it identifies a
   12.92 -different revision, by simply issuing a new \hgcmd{tag} command.
   12.93 -You'll have to use the \hgopt{tag}{-f} option to tell Mercurial that
   12.94 -you \emph{really} want to update the tag.
   12.95 -\interaction{tag.replace}
   12.96 -There will still be a permanent record of the previous identity of the
   12.97 -tag, but Mercurial will no longer use it.  There's thus no penalty to
   12.98 -tagging the wrong revision; all you have to do is turn around and tag
   12.99 -the correct revision once you discover your error.
  12.100 -
  12.101 -Mercurial stores tags in a normal revision-controlled file in your
  12.102 -repository.  If you've created any tags, you'll find them in a file
  12.103 -named \sfilename{.hgtags}.  When you run the \hgcmd{tag} command,
  12.104 -Mercurial modifies this file, then automatically commits the change to
  12.105 -it.  This means that every time you run \hgcmd{tag}, you'll see a
  12.106 -corresponding changeset in the output of \hgcmd{log}.
  12.107 -\interaction{tag.tip}
  12.108 -
  12.109 -\subsection{Handling tag conflicts during a merge}
  12.110 -
  12.111 -You won't often need to care about the \sfilename{.hgtags} file, but
  12.112 -it sometimes makes its presence known during a merge.  The format of
  12.113 -the file is simple: it consists of a series of lines.  Each line
  12.114 -starts with a changeset hash, followed by a space, followed by the
  12.115 -name of a tag.
  12.116 -
  12.117 -If you're resolving a conflict in the \sfilename{.hgtags} file during
  12.118 -a merge, there's one twist to modifying the \sfilename{.hgtags} file:
  12.119 -when Mercurial is parsing the tags in a repository, it \emph{never}
  12.120 -reads the working copy of the \sfilename{.hgtags} file.  Instead, it
  12.121 -reads the \emph{most recently committed} revision of the file.
  12.122 -
  12.123 -An unfortunate consequence of this design is that you can't actually
  12.124 -verify that your merged \sfilename{.hgtags} file is correct until
  12.125 -\emph{after} you've committed a change.  So if you find yourself
  12.126 -resolving a conflict on \sfilename{.hgtags} during a merge, be sure to
  12.127 -run \hgcmd{tags} after you commit.  If it finds an error in the
  12.128 -\sfilename{.hgtags} file, it will report the location of the error,
  12.129 -which you can then fix and commit.  You should then run \hgcmd{tags}
  12.130 -again, just to be sure that your fix is correct.
  12.131 -
  12.132 -\subsection{Tags and cloning}
  12.133 -
  12.134 -You may have noticed that the \hgcmd{clone} command has a
  12.135 -\hgopt{clone}{-r} option that lets you clone an exact copy of the
  12.136 -repository as of a particular changeset.  The new clone will not
  12.137 -contain any project history that comes after the revision you
  12.138 -specified.  This has an interaction with tags that can surprise the
  12.139 -unwary.
  12.140 -
  12.141 -Recall that a tag is stored as a revision to the \sfilename{.hgtags}
  12.142 -file, so that when you create a tag, the changeset in which it's
  12.143 -recorded necessarily refers to an older changeset.  When you run
  12.144 -\hgcmdargs{clone}{-r foo} to clone a repository as of tag
  12.145 -\texttt{foo}, the new clone \emph{will not contain the history that
  12.146 -  created the tag} that you used to clone the repository.  The result
  12.147 -is that you'll get exactly the right subset of the project's history
  12.148 -in the new repository, but \emph{not} the tag you might have expected.
  12.149 -
  12.150 -\subsection{When permanent tags are too much}
  12.151 -
  12.152 -Since Mercurial's tags are revision controlled and carried around with
  12.153 -a project's history, everyone you work with will see the tags you
  12.154 -create.  But giving names to revisions has uses beyond simply noting
  12.155 -that revision \texttt{4237e45506ee} is really \texttt{v2.0.2}.  If
  12.156 -you're trying to track down a subtle bug, you might want a tag to
  12.157 -remind you of something like ``Anne saw the symptoms with this
  12.158 -revision''.
  12.159 -
  12.160 -For cases like this, what you might want to use are \emph{local} tags.
  12.161 -You can create a local tag with the \hgopt{tag}{-l} option to the
  12.162 -\hgcmd{tag} command.  This will store the tag in a file called
  12.163 -\sfilename{.hg/localtags}.  Unlike \sfilename{.hgtags},
  12.164 -\sfilename{.hg/localtags} is not revision controlled.  Any tags you
  12.165 -create using \hgopt{tag}{-l} remain strictly local to the repository
  12.166 -you're currently working in.
  12.167 -
  12.168 -\section{The flow of changes---big picture vs. little}
  12.169 -
  12.170 -To return to the outline I sketched at the beginning of a chapter,
  12.171 -let's think about a project that has multiple concurrent pieces of
  12.172 -work under development at once.
  12.173 -
  12.174 -There might be a push for a new ``main'' release; a new minor bugfix
  12.175 -release to the last main release; and an unexpected ``hot fix'' to an
  12.176 -old release that is now in maintenance mode.
  12.177 -
  12.178 -The usual way people refer to these different concurrent directions of
  12.179 -development is as ``branches''.  However, we've already seen numerous
  12.180 -times that Mercurial treats \emph{all of history} as a series of
  12.181 -branches and merges.  Really, what we have here is two ideas that are
  12.182 -peripherally related, but which happen to share a name.
  12.183 -\begin{itemize}
  12.184 -\item ``Big picture'' branches represent the sweep of a project's
  12.185 -  evolution; people give them names, and talk about them in
  12.186 -  conversation.
  12.187 -\item ``Little picture'' branches are artefacts of the day-to-day
  12.188 -  activity of developing and merging changes.  They expose the
  12.189 -  narrative of how the code was developed.
  12.190 -\end{itemize}
  12.191 -
  12.192 -\section{Managing big-picture branches in repositories}
  12.193 -
  12.194 -The easiest way to isolate a ``big picture'' branch in Mercurial is in
  12.195 -a dedicated repository.  If you have an existing shared
  12.196 -repository---let's call it \texttt{myproject}---that reaches a ``1.0''
  12.197 -milestone, you can start to prepare for future maintenance releases on
  12.198 -top of version~1.0 by tagging the revision from which you prepared
  12.199 -the~1.0 release.
  12.200 -\interaction{branch-repo.tag}
  12.201 -You can then clone a new shared \texttt{myproject-1.0.1} repository as
  12.202 -of that tag.
  12.203 -\interaction{branch-repo.clone}
  12.204 -
  12.205 -Afterwards, if someone needs to work on a bug fix that ought to go
  12.206 -into an upcoming~1.0.1 minor release, they clone the
  12.207 -\texttt{myproject-1.0.1} repository, make their changes, and push them
  12.208 -back.
  12.209 -\interaction{branch-repo.bugfix}
  12.210 -Meanwhile, development for the next major release can continue,
  12.211 -isolated and unabated, in the \texttt{myproject} repository.
  12.212 -\interaction{branch-repo.new}
  12.213 -
  12.214 -\section{Don't repeat yourself: merging across branches}
  12.215 -
  12.216 -In many cases, if you have a bug to fix on a maintenance branch, the
  12.217 -chances are good that the bug exists on your project's main branch
  12.218 -(and possibly other maintenance branches, too).  It's a rare developer
  12.219 -who wants to fix the same bug multiple times, so let's look at a few
  12.220 -ways that Mercurial can help you to manage these bugfixes without
  12.221 -duplicating your work.
  12.222 -
  12.223 -In the simplest instance, all you need to do is pull changes from your
  12.224 -maintenance branch into your local clone of the target branch.
  12.225 -\interaction{branch-repo.pull}
  12.226 -You'll then need to merge the heads of the two branches, and push back
  12.227 -to the main branch.
  12.228 -\interaction{branch-repo.merge}
  12.229 -
  12.230 -\section{Naming branches within one repository}
  12.231 -
  12.232 -In most instances, isolating branches in repositories is the right
  12.233 -approach.  Its simplicity makes it easy to understand; and so it's
  12.234 -hard to make mistakes.  There's a one-to-one relationship between
  12.235 -branches you're working in and directories on your system.  This lets
  12.236 -you use normal (non-Mercurial-aware) tools to work on files within a
  12.237 -branch/repository.
  12.238 -
  12.239 -If you're more in the ``power user'' category (\emph{and} your
  12.240 -collaborators are too), there is an alternative way of handling
  12.241 -branches that you can consider.  I've already mentioned the
  12.242 -human-level distinction between ``small picture'' and ``big picture''
  12.243 -branches.  While Mercurial works with multiple ``small picture''
  12.244 -branches in a repository all the time (for example after you pull
  12.245 -changes in, but before you merge them), it can \emph{also} work with
  12.246 -multiple ``big picture'' branches.
  12.247 -
  12.248 -The key to working this way is that Mercurial lets you assign a
  12.249 -persistent \emph{name} to a branch.  There always exists a branch
  12.250 -named \texttt{default}.  Even before you start naming branches
  12.251 -yourself, you can find traces of the \texttt{default} branch if you
  12.252 -look for them.
  12.253 -
  12.254 -As an example, when you run the \hgcmd{commit} command, and it pops up
  12.255 -your editor so that you can enter a commit message, look for a line
  12.256 -that contains the text ``\texttt{HG: branch default}'' at the bottom.
  12.257 -This is telling you that your commit will occur on the branch named
  12.258 -\texttt{default}.
  12.259 -
  12.260 -To start working with named branches, use the \hgcmd{branches}
  12.261 -command.  This command lists the named branches already present in
  12.262 -your repository, telling you which changeset is the tip of each.
  12.263 -\interaction{branch-named.branches}
  12.264 -Since you haven't created any named branches yet, the only one that
  12.265 -exists is \texttt{default}.
  12.266 -
  12.267 -To find out what the ``current'' branch is, run the \hgcmd{branch}
  12.268 -command, giving it no arguments.  This tells you what branch the
  12.269 -parent of the current changeset is on.
  12.270 -\interaction{branch-named.branch}
  12.271 -
  12.272 -To create a new branch, run the \hgcmd{branch} command again.  This
  12.273 -time, give it one argument: the name of the branch you want to create.
  12.274 -\interaction{branch-named.create}
  12.275 -
  12.276 -After you've created a branch, you might wonder what effect the
  12.277 -\hgcmd{branch} command has had.  What do the \hgcmd{status} and
  12.278 -\hgcmd{tip} commands report?
  12.279 -\interaction{branch-named.status}
  12.280 -Nothing has changed in the working directory, and there's been no new
  12.281 -history created.  As this suggests, running the \hgcmd{branch} command
  12.282 -has no permanent effect; it only tells Mercurial what branch name to
  12.283 -use the \emph{next} time you commit a changeset.
  12.284 -
  12.285 -When you commit a change, Mercurial records the name of the branch on
  12.286 -which you committed.  Once you've switched from the \texttt{default}
  12.287 -branch to another and committed, you'll see the name of the new branch
  12.288 -show up in the output of \hgcmd{log}, \hgcmd{tip}, and other commands
  12.289 -that display the same kind of output.
  12.290 -\interaction{branch-named.commit}
  12.291 -The \hgcmd{log}-like commands will print the branch name of every
  12.292 -changeset that's not on the \texttt{default} branch.  As a result, if
  12.293 -you never use named branches, you'll never see this information.
  12.294 -
  12.295 -Once you've named a branch and committed a change with that name,
  12.296 -every subsequent commit that descends from that change will inherit
  12.297 -the same branch name.  You can change the name of a branch at any
  12.298 -time, using the \hgcmd{branch} command.  
  12.299 -\interaction{branch-named.rebranch}
  12.300 -In practice, this is something you won't do very often, as branch
  12.301 -names tend to have fairly long lifetimes.  (This isn't a rule, just an
  12.302 -observation.)
  12.303 -
  12.304 -\section{Dealing with multiple named branches in a repository}
  12.305 -
  12.306 -If you have more than one named branch in a repository, Mercurial will
  12.307 -remember the branch that your working directory on when you start a
  12.308 -command like \hgcmd{update} or \hgcmdargs{pull}{-u}.  It will update
  12.309 -the working directory to the tip of this branch, no matter what the
  12.310 -``repo-wide'' tip is.  To update to a revision that's on a different
  12.311 -named branch, you may need to use the \hgopt{update}{-C} option to
  12.312 -\hgcmd{update}.
  12.313 -
  12.314 -This behaviour is a little subtle, so let's see it in action.  First,
  12.315 -let's remind ourselves what branch we're currently on, and what
  12.316 -branches are in our repository.
  12.317 -\interaction{branch-named.parents}
  12.318 -We're on the \texttt{bar} branch, but there also exists an older
  12.319 -\hgcmd{foo} branch.
  12.320 -
  12.321 -We can \hgcmd{update} back and forth between the tips of the
  12.322 -\texttt{foo} and \texttt{bar} branches without needing to use the
  12.323 -\hgopt{update}{-C} option, because this only involves going backwards
  12.324 -and forwards linearly through our change history.
  12.325 -\interaction{branch-named.update-switchy}
  12.326 -
  12.327 -If we go back to the \texttt{foo} branch and then run \hgcmd{update},
  12.328 -it will keep us on \texttt{foo}, not move us to the tip of
  12.329 -\texttt{bar}.
  12.330 -\interaction{branch-named.update-nothing}
  12.331 -
  12.332 -Committing a new change on the \texttt{foo} branch introduces a new
  12.333 -head.
  12.334 -\interaction{branch-named.foo-commit}
  12.335 -
  12.336 -\section{Branch names and merging}
  12.337 -
  12.338 -As you've probably noticed, merges in Mercurial are not symmetrical.
  12.339 -Let's say our repository has two heads, 17 and 23.  If I
  12.340 -\hgcmd{update} to 17 and then \hgcmd{merge} with 23, Mercurial records
  12.341 -17 as the first parent of the merge, and 23 as the second.  Whereas if
  12.342 -I \hgcmd{update} to 23 and then \hgcmd{merge} with 17, it records 23
  12.343 -as the first parent, and 17 as the second.
  12.344 -
  12.345 -This affects Mercurial's choice of branch name when you merge.  After
  12.346 -a merge, Mercurial will retain the branch name of the first parent
  12.347 -when you commit the result of the merge.  If your first parent's
  12.348 -branch name is \texttt{foo}, and you merge with \texttt{bar}, the
  12.349 -branch name will still be \texttt{foo} after you merge.
  12.350 -
  12.351 -It's not unusual for a repository to contain multiple heads, each with
  12.352 -the same branch name.  Let's say I'm working on the \texttt{foo}
  12.353 -branch, and so are you.  We commit different changes; I pull your
  12.354 -changes; I now have two heads, each claiming to be on the \texttt{foo}
  12.355 -branch.  The result of a merge will be a single head on the
  12.356 -\texttt{foo} branch, as you might hope.
  12.357 -
  12.358 -But if I'm working on the \texttt{bar} branch, and I merge work from
  12.359 -the \texttt{foo} branch, the result will remain on the \texttt{bar}
  12.360 -branch.
  12.361 -\interaction{branch-named.merge}
  12.362 -
  12.363 -To give a more concrete example, if I'm working on the
  12.364 -\texttt{bleeding-edge} branch, and I want to bring in the latest fixes
  12.365 -from the \texttt{stable} branch, Mercurial will choose the ``right''
  12.366 -(\texttt{bleeding-edge}) branch name when I pull and merge from
  12.367 -\texttt{stable}.
  12.368 -
  12.369 -\section{Branch naming is generally useful}
  12.370 -
  12.371 -You shouldn't think of named branches as applicable only to situations
  12.372 -where you have multiple long-lived branches cohabiting in a single
  12.373 -repository.  They're very useful even in the one-branch-per-repository
  12.374 -case.  
  12.375 -
  12.376 -In the simplest case, giving a name to each branch gives you a
  12.377 -permanent record of which branch a changeset originated on.  This
  12.378 -gives you more context when you're trying to follow the history of a
  12.379 -long-lived branchy project.
  12.380 -
  12.381 -If you're working with shared repositories, you can set up a
  12.382 -\hook{pretxnchangegroup} hook on each that will block incoming changes
  12.383 -that have the ``wrong'' branch name.  This provides a simple, but
  12.384 -effective, defence against people accidentally pushing changes from a
  12.385 -``bleeding edge'' branch to a ``stable'' branch.  Such a hook might
  12.386 -look like this inside the shared repo's \hgrc.
  12.387 -\begin{codesample2}
  12.388 -  [hooks]
  12.389 -  pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch
  12.390 -\end{codesample2}
  12.391 -
  12.392 -%%% Local Variables: 
  12.393 -%%% mode: latex
  12.394 -%%% TeX-master: "00book"
  12.395 -%%% End: 
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/fr/ch00-preface.xml	Sun Aug 16 04:58:01 2009 +0200
    13.3 @@ -0,0 +1,78 @@
    13.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    13.5 +
    13.6 +<para>\chapter*{Préface}
    13.7 +\addcontentsline{toc}{chapter}{Préface}
    13.8 +\label{chap:preface}</para>
    13.9 +
   13.10 +<para>La gestion de source distribuée est encore un territoire peu exploré
   13.11 +et qui, par conséquent, a grandi très rapidement grâce à la seule
   13.12 +volonté de ses explorateurs.</para>
   13.13 +
   13.14 +<para>Je rédige un livre sur ce sujet car je crois que c'est un sujet
   13.15 +important qui mérite bien un guide du <quote>terrain</quote>. J'ai choisi d'écrire
   13.16 +ce livre sur Mercurial car c'est l'outil le plus simple pour découvrir
   13.17 +ce nouveau monde et qu'en outre, il répond très bien au besoin de
   13.18 +réels environnements, là où d'autres outils de gestion de source n'y
   13.19 +parviennent pas.</para>
   13.20 +
   13.21 +<sect1>
   13.22 +<title>Cet ouvrage est un travail en cours</title>
   13.23 +
   13.24 +<para>Je publie ce livre tout en continuant à l'écrire, dans l'espoir qu'il
   13.25 +vous sera utile. J'espère aussi que les lecteurs pourront ainsi y contribuer
   13.26 +si ils le souhaitent.</para>
   13.27 +
   13.28 +</sect1>
   13.29 +<sect1>
   13.30 +<title>À propros des exemples de ce livre</title>
   13.31 +
   13.32 +<para>Ce livre a une approche particulière des exemples d'exécution. Ils sont
   13.33 +toujours <quote>dynamiques</quote>&emdash;chacun est le résultat d'un script shell qui
   13.34 +exécute les commandes Mercurial que vous voyez. Chaque fois qu'une
   13.35 +image du livre est construite à partir des sources, tous les scripts d'exemple
   13.36 +sont exécutés automatiquement, et les résultats comparés à ceux attendus.</para>
   13.37 +
   13.38 +<para>Cette approche a l'avantage de garantir que les exemples sont toujours
   13.39 +justes ; ils montrent <emphasis>exactement</emphasis> le comportement de la version de
   13.40 +Mercurial spécifiée dans la couverture de ce livre. Si je mets à jour cette
   13.41 +version, et que les commandes changent, la génération du livre échouera.</para>
   13.42 +
   13.43 +<para>Il y a un petit désavantage à cette approche, les dates et les
   13.44 +durées que vous verrez dans ces exemples ont tendances à être
   13.45 +<quote>réduits</quote> de manière très différente d'une exécution manuelle. Un être humain
   13.46 +ne peut exécuter qu'une commande toutes les secondes, alors que mes scripts
   13.47 +automatisés en exécutent plusieurs en une seule seconde.</para>
   13.48 +
   13.49 +<para>Ainsi, en une seule seconde, plusieurs <quote>commits</quote> peuvent avoir lieu
   13.50 +au sein d'un exemple. Vous le constatez, entre autres, dans les
   13.51 +exemples sur <literal role="hg-ext">bisect</literal>, dans la section <xref linkend="sec:undo:bisect"/>.</para>
   13.52 +
   13.53 +<para>En conséquence, quand vous lisez les exemples, n'accordez pas trop
   13.54 +d'importance aux dates et aux durées d'exécution des commandes. Mais
   13.55 +<emphasis>soyez sûr</emphasis> que le comportement que vous voyez est cohérent et
   13.56 +reproductible.
   13.57 +</para>
   13.58 +
   13.59 +</sect1>
   13.60 +<sect1>
   13.61 +<title>Colophon&emdash;Cet ouvrage est libre</title>
   13.62 +
   13.63 +<para>Ce livre est publié sous la licence <quote>Open Publication License</quote>
   13.64 +\footnote{Pour plus de renseignements :
   13.65 +<ulink url="http://opencontent.org/openpub/">http://opencontent.org/openpub/</ulink>{Open Publication License} },
   13.66 +et est construit uniquement à l'aide de logiciels libres. Il est mis
   13.67 +en forme avec \LaTex{}; et les illustrations sont réalisées avec
   13.68 +<ulink url="http://www.inkscape.org/">Inkscape</ulink>.
   13.69 +</para>
   13.70 +
   13.71 +<para>L'ensemble des fichiers sources de cet ouvrage est publié dans un
   13.72 +dépot mercurial  <ulink url="http://hg.serpentine.com/mercurial/book">http://hg.serpentine.com/mercurial/book</ulink>.
   13.73 +</para>
   13.74 +
   13.75 +</sect1>
   13.76 +
   13.77 +<!--
   13.78 +local variables: 
   13.79 +sgml-parent-document: ("00book.xml" "book" "chapter")
   13.80 +end:
   13.81 +-->
   13.82 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/fr/ch01-intro.xml	Sun Aug 16 04:58:01 2009 +0200
    14.3 @@ -0,0 +1,744 @@
    14.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    14.5 +
    14.6 +<chapter>
    14.7 +<title>Introduction</title>
    14.8 +<para>\label{chap:intro}</para>
    14.9 +
   14.10 +<sect1>
   14.11 +<title>À propos de la gestion source</title>
   14.12 +
   14.13 +<para>La gestion de sources est un processus permettant de gérer différentes
   14.14 +versions de la même information. Dans sa forme la plus simple, c'est
   14.15 +ce que tout le monde fait manuellement : quand vous modifiez
   14.16 +un fichier, vous le sauvegardez sous un nouveau nom contenant un numéro,
   14.17 +à chaque fois plus grand que celui de la version précédente.</para>
   14.18 +
   14.19 +<para>Ce genre de gestion de version manuelle est cependant facilement sujette
   14.20 +à des erreurs, ainsi, depuis longtemps, des logiciels existent pour
   14.21 +résoudre cette problématique. Les premiers outils de gestion de sources
   14.22 +étaient destinés à aider un seul utilisateur, à automatiser la gestion
   14.23 +des versions d'un seul fichier. Dans les dernières décades, cette cible
   14.24 +s'est largement agrandie, ils gèrent désormais de multiples fichiers, et
   14.25 +aident un grand nombre de personnes à travailler ensemble. Les outils les
   14.26 +plus modernes n'ont aucune difficulté à gérer plusieurs milliers de
   14.27 +personnes travaillant ensemble sur des projets regroupant plusieurs
   14.28 +centaines de milliers de fichiers.</para>
   14.29 +
   14.30 +<sect2>
   14.31 +<title>Pourquoi utiliser un gestionnaire de source ?</title>
   14.32 +
   14.33 +<para>Il y a de nombreuses raisons pour que vous ou votre équipe souhaitiez
   14.34 +utiliser un outil automatisant la gestion de version pour votre projet.</para>
   14.35 +<itemizedlist>
   14.36 +<listitem><para>L'outil se chargera de suivre l'évolution de votre projet, sans
   14.37 +que vous n'ayez à le faire. Pour chaque modification, vous aurez à votre
   14.38 +disposition un journal indiquant <emphasis>qui</emphasis> a fait quoi, <emphasis>pourquoi</emphasis>
   14.39 +ils l'ont fait, <emphasis>quand</emphasis> ils l'ont fait, et <emphasis>ce</emphasis> qu'ils ont
   14.40 +modifiés.</para>
   14.41 +</listitem>
   14.42 +<listitem><para>Quand vous travaillez avec d'autres personnes, les logiciels de
   14.43 +gestion de source facilitent le travail collaboratif. Par exemple, quand
   14.44 +plusieurs personnes font, plus ou moins simultanément, des modifications
   14.45 +incompatibles, le logiciel vous aidera à identifier et à résoudre les conflits.</para>
   14.46 +</listitem>
   14.47 +<listitem><para>L'outil vous aidera à réparer vos erreurs. Si vous effectuez un changement
   14.48 +qui se révèle être une erreur, vous pourrez revenir à une version
   14.49 +antérieure d'un fichier ou même d'un ensemble de fichiers. En fait, un outil de
   14.50 +gestion de source <emphasis>vraiment</emphasis> efficace vous permettra d'identifier à quel
   14.51 +moment le problème est apparu (voir la section <xref linkend="sec:undo:bisect"/> pour plus
   14.52 +de détails).</para>
   14.53 +</listitem>
   14.54 +<listitem><para>L'outil vous permettra aussi de travailler sur plusieurs versions différentes
   14.55 +de votre projet et à gérer l'écart entre chacune.</para>
   14.56 +</listitem></itemizedlist>
   14.57 +<para>La plupart de ces raisons ont autant d'importances &emdash;du moins en théorie&emdash; que
   14.58 +vous travailliez sur un projet pour vous, ou avec une centaine d'autres
   14.59 +personnes.
   14.60 +</para>
   14.61 +
   14.62 +<para>Une question fondamentale à propos des outils de gestion de source, qu'il s'agisse
   14.63 +du projet d'une personne ou d'une grande équipe, est quels sont ses
   14.64 +<emphasis>avantages</emphasis> par rapport à ses <emphasis>coûts</emphasis>. Un outil qui est difficile à
   14.65 +utiliser ou à comprendre exigera un lourd effort d'adaptation.
   14.66 +</para>
   14.67 +
   14.68 +<para>Un projet de cinq milles personnes s'effondrera très certainement de lui même
   14.69 +sans aucun processus et outil de gestion de source. Dans ce cas, le coût
   14.70 +d'utilisation d'un logiciel de gestion de source est dérisoire puisque
   14.71 +<emphasis>sans</emphasis>, l'échec est presque garanti.
   14.72 +</para>
   14.73 +
   14.74 +<para>D'un autre coté, un <quote>rapide hack</quote> d'une personne peut sembler un contexte
   14.75 +bien pauvre pour utiliser un outil de gestion de source, car, bien évidement
   14.76 +le coût d'utilisation dépasse le coût total du projet. N'est ce pas ?
   14.77 +</para>
   14.78 +
   14.79 +<para>Mercurial supporte ces <emphasis>deux</emphasis> échelles de travail. Vous pouvez apprendre
   14.80 +les bases en quelques minutes seulement, et, grâce à sa performance, vous pouvez
   14.81 +l'utiliser avec facilité sur le plus petit des projets. Cette simplicité
   14.82 +signifie que vous n'avez pas de concept obscurs ou de séquence de commandes
   14.83 +défiant l'imagination, sans aucune corrélation avec \emph{ce que vous êtes
   14.84 +vraiment en train de faire}. En même temps, ces mêmes performances et sa
   14.85 +nature <quote>peer-to-peer</quote> vous permettent d'augmenter, sans difficulté, son
   14.86 +utilisation à de très grands projets.
   14.87 +</para>
   14.88 +
   14.89 +<para>Aucun outil de gestion de source ne peut sauver un projet mal mené, mais un
   14.90 +bon outil peut rendre beaucoup plus fluide votre travail.
   14.91 +</para>
   14.92 +
   14.93 +</sect2>
   14.94 +<sect2>
   14.95 +<title>Les multiples noms de la gestion de source</title>
   14.96 +
   14.97 +<para>La gestion de source\footnote{NdT: J'ai utilisé systématiquement le terme
   14.98 +<quote>gestion de source</quote> à travers tout l'ouvrage. Ce n'est pas forcement la
   14.99 +meilleure traduction, et ceci peut rendre la lecture un peu lourde, mais je
  14.100 +pense que le document y gagne en clarté et en précision.} est un domaine
  14.101 +divers, tellement qu'il n'existe pas une seul nom ou acronyme pour le désigner.
  14.102 +Voilà quelqu'uns des noms ou
  14.103 +acronymes que vous rencontrerez le plus souvent\footnote{NdT: J'ai conservé la
  14.104 +liste des noms en anglais pour des raisons de commodité (ils sont plus
  14.105 +<quote>googelable</quote>). En outre, j'ai opté  pour conserver l'ensemble des opérations de
  14.106 +Mercurial (\textit{commit},\textit{push}, \textit{pull},...) en anglais, là
  14.107 +aussi pour faciliter la lecture d'autres documents en anglais, ainsi que
  14.108 +l'utilisation de Mercurial}.
  14.109 +</para>
  14.110 +
  14.111 +<para>:
  14.112 +</para>
  14.113 +<itemizedlist>
  14.114 +<listitem><para>\textit{Revision control (RCS)} ;
  14.115 +</para>
  14.116 +</listitem>
  14.117 +<listitem><para>Software configuration management (SCM), ou \textit{configuration management} ;
  14.118 +</para>
  14.119 +</listitem>
  14.120 +<listitem><para>\textit{Source code management} ;
  14.121 +</para>
  14.122 +</listitem>
  14.123 +<listitem><para>\textit{Source code control}, ou \textit{source control} ;
  14.124 +</para>
  14.125 +</listitem>
  14.126 +<listitem><para>\textit{Version control (VCS)}.
  14.127 +</para>
  14.128 +</listitem></itemizedlist>
  14.129 +
  14.130 +<para>Certaines personnes prétendent que ces termes ont en fait des sens
  14.131 +différents mais en pratique ils se recouvrent tellement qu'il n'y a pas
  14.132 +réellement de manière pertinente de les distinguer.
  14.133 +</para>
  14.134 +
  14.135 +</sect2>
  14.136 +</sect1>
  14.137 +<sect1>
  14.138 +<title>Une courte histoire de la gestion de source</title>
  14.139 +
  14.140 +<para>Le plus célèbre des anciens outils de gestion de source est \textit{SCCS
  14.141 +(Source Code Control System)}, que Marc Rochkind conçu dans les laboratoires de
  14.142 +recherche de Bell (\textit{Bell Labs}), dans le début des années 70.
  14.143 +\textit{SCCS} ne fonctionnait que sur des fichiers individuels, et obligeait chaque
  14.144 +personne travaillant sur le projet d'avoir un accès à un répertoire de
  14.145 +travail commun, sur le même système. Seulement une seule personne pouvait
  14.146 +modifier un fichier au même moment, ce fonctionnement était assuré par
  14.147 +l'utilisation de verrou (<quote>lock</quote>). Il était courant que des personnes
  14.148 +verrouillent des fichiers, et plus tard, oublient de le déverrouiller;
  14.149 +empêchant n'importe qui d'autre de travailler sur ces fichiers sans l'aide de
  14.150 +l'administrateur...
  14.151 +</para>
  14.152 +
  14.153 +<para>Walter Tichy a développé une alternative libre à \textit{SCCS} au début des
  14.154 +années 80, qu'il nomma \textit{RSC (Revison Control System)}.  Comme
  14.155 +\textit{SCCS}, \textit{RCS} demandait aux développeurs de travailler sur le même
  14.156 +répertoire partagé, et de verrouiller les
  14.157 +fichiers pour se prémunir de tout conflit issu de modifications concurrentes.
  14.158 +</para>
  14.159 +
  14.160 +<para>Un peu plus tard dans les années 1980, Dick Grune utilisa \textit{RCS} comme
  14.161 +une brique de base pour un ensemble de scripts \textit{shell} qu'il intitula
  14.162 +cmt, avant de la renommer en \textit{CVS (Concurrent Versions System)}.  La
  14.163 +grande innovation de CVS était que les développeurs pouvaient travailler
  14.164 +simultanément et indépendamment dans leur propre espace de travail. Ces espaces
  14.165 +de travail privés assuraient que les développeurs ne se marchent pas
  14.166 +mutuellement sur les pieds, comme c'était souvent le cas avec RCS et SCCS.
  14.167 +Chaque développeur disposait donc de sa copie de tous les fichiers du projet,
  14.168 +et ils pouvaient donc librement les modifier. Ils devaient néanmoins effectuer
  14.169 +la <quote>fusion</quote> (\textit{<quote>merge</quote>}) de leurs fichiers, avant d'effectuer le
  14.170 +<quote>commit</quote> de leur modifications sur le dépôt central.
  14.171 +</para>
  14.172 +
  14.173 +<para>Brian Berliner reprit les scripts de Grune's et les réécrit en C, qu'il publia
  14.174 +en 1989. Depuis, ce code a été modifié jusqu'à devenir la version moderne de
  14.175 +CVS. CVS a acquis ainsi la capacité de fonctionner en réseau, transformant son
  14.176 +architecture en client/serveur. L'architecture de CVS est centralisée, seul le
  14.177 +serveur a une copie de l'historique du projet. L'espace de travail client ne
  14.178 +contient qu'une copie de la dernière version du projet, et quelques métadonnées
  14.179 +pour indiquer où le serveur se trouve. CVS a été un grand succès, aujourd'hui
  14.180 +il est probablement l'outil de gestion de contrôle le plus utilisé au monde.
  14.181 +</para>
  14.182 +
  14.183 +<para>Au début des années 1990, Sun Microsystmes développa un premier outil de
  14.184 +gestion de source distribué, nommé TeamWare. Un espace de travail TeamWare
  14.185 +contient une copie complète de l'historique du projet. TeamWare n'a pas de
  14.186 +notion de dépôt central. (CVS utilisait RCS pour le stockage de l'historique,
  14.187 +TeamWare utilisait SCCS).
  14.188 +</para>
  14.189 +
  14.190 +<para>Alors que les années 1990 avançaient, les utilisateurs ont pris conscience d'un
  14.191 +certain nombre de problèmes avec CVS. Il enregistrait simultanément des
  14.192 +modifications sur différents fichiers individuellement, au lieu de les
  14.193 +regrouper dans une seule opération cohérente et atomique. Il ne gère pas bien
  14.194 +sa hiérarchie de fichier, il est donc assez aisé de créer le chaos en renommant
  14.195 +les fichiers et les répertoires. Pire encore, son code source est difficile à
  14.196 +lire et à maintenir, ce qui agrandit largement le <quote>niveau de souffrance</quote>
  14.197 +associé à la réparation de ces problèmes d'architecture de manière prohibitive.
  14.198 +</para>
  14.199 +
  14.200 +<para>En 2001, Jim Blandy et Karl Fogel, deux développeurs qui avaient travaillé sur
  14.201 +CVS, initièrent un projet pour le remplacer par un outil qui aurait une
  14.202 +meilleure architecture et un code plus propre. Le résultat, Subversion, ne
  14.203 +quitte pas le modèle centralisé et client/server de CVS, mais ajoute les
  14.204 +opérations de <quote>commit</quote> atomique sur de multiples fichiers, une meilleure
  14.205 +gestion des espaces de noms, et d'autres fonctionnalités qui en font un
  14.206 +meilleur outil que CVS. Depuis sa première publication, il est rapidement
  14.207 +devenu très populaire.
  14.208 +</para>
  14.209 +
  14.210 +<para>Plus ou moins simultanément, Graydon Hoare a commencé sur l'ambitieux
  14.211 +système de gestion distribué Monotone. Bien que Monotone corrige plusieurs
  14.212 +défauts de CVS's tout en offrant une architecture <quote>peer-to-peer</quote>, il va aussi
  14.213 +plus loin que la plupart des outils de révision de manière assez innovante. Il
  14.214 +utilise des <quote>hash</quote> cryptographiques comme identifiants, et il a une notion
  14.215 +complète de <quote>confiance</quote> du code issu des différentes sources.
  14.216 +</para>
  14.217 +
  14.218 +<para>Mercurial est né en 2005. Bien que très influencé par Monotone, Mercurial se
  14.219 +concentre sur la facilité d'utilisation, les performances et la capacité à
  14.220 +monter en charge pour de très gros projets.
  14.221 +</para>
  14.222 +
  14.223 +</sect1>
  14.224 +<sect1>
  14.225 +<title>Tendances de la gestion de source</title>
  14.226 +
  14.227 +<para>Il y a eu une tendance évidente dans le développement et l'utilisation d'outils
  14.228 +de gestion de source depuis les quatre dernières décades, au fur et à mesure
  14.229 +que les utilisateurs se sont habitués à leur outils et se sont sentis contraints
  14.230 +par leurs limitations.
  14.231 +</para>
  14.232 +
  14.233 +<para>La première génération commença simplement par gérer un fichier unique sur un
  14.234 +ordinateur individuel. Cependant, même si ces outils présentaient une grande
  14.235 +avancée par rapport à la gestion manuelle des versions, leur modèle de
  14.236 +verrouillage et leur utilisation limitée à un seul ordinateur rendaient leur
  14.237 +utilisation possible uniquement dans une très petite équipe.
  14.238 +</para>
  14.239 +
  14.240 +<para>La seconde génération a assoupli ces contraintes en adoptant une architecture
  14.241 +réseau et centralisée, permettant de gérer plusieurs projets entiers en même
  14.242 +temps. Alors que les projets grandirent en taille, ils rencontrèrent de nouveaux
  14.243 +problèmes. Avec les clients discutant régulièrement avec le serveurs, la montée
  14.244 +en charge devint un réel problème sur les gros projets. Une connexion réseau
  14.245 +peu fiable pouvait complètement empêcher les utilisateurs distants de dialoguer
  14.246 +avec le serveur. Alors que les projets \textit{Open Source} commencèrent à
  14.247 +mettre en place des accès en lecture seule disponible anonymement, les
  14.248 +utilisateurs sans les privilèges de <quote>commit</quote> réalisèrent qu'ils ne pouvaient
  14.249 +pas utiliser les outils pour collaborer naturellement avec le projet, comme ils
  14.250 +ne pouvaient pas non plus enregistrer leurs modifications.
  14.251 +</para>
  14.252 +
  14.253 +<para>La génération actuelle des outils de gestion de source est <quote>peer-to-peer</quote> par
  14.254 +nature. Tout ces systèmes ont abandonné la dépendance à un serveur central, et
  14.255 +ont permis à leur utilisateur de distribuer les données de leur gestion de
  14.256 +source à qui en a besoin. La collaboration à travers Internet a transformé la
  14.257 +contrainte technologique en une simple question de choix et de consencus. Les
  14.258 +outils modernes peuvent maintenant fonctionner en mode déconnecté sans limite et
  14.259 +de manière autonome, la connexion au réseau n'étant nécessaire que pour
  14.260 +synchroniser les modifications avec les autres dépôts.
  14.261 +</para>
  14.262 +
  14.263 +</sect1>
  14.264 +<sect1>
  14.265 +<title>Quelques avantages des gestionnaires de source distribués</title>
  14.266 +
  14.267 +<para>Même si les gestionnaire de source distribués sont depuis plusieurs années
  14.268 +assez robustes et aussi utilisables que leurs prédécesseurs, les utilisateurs
  14.269 +d'autres outils n'y ont pas encore été sensibilisés. Les gestionnaires
  14.270 +de source distribués se distinguent particulièrement de leurs équivalents
  14.271 +centralisés de nombreuses manières.
  14.272 +</para>
  14.273 +
  14.274 +<para>Pour un développeur individuel, ils restent beaucoup plus rapides que les
  14.275 +outils centralisés. Cela pour une raison simple : un outil centralisé doit
  14.276 +toujours dialoguer à travers le réseau pour la plupart des opérations, car
  14.277 +presque toutes les métadonnées sont stockées sur la seule copie du serveur
  14.278 +central. Un outil distribué stocke toute ses métadonnées localement. À tâche
  14.279 +égale, effectuer un échange avec le réseau ajoute un délai aux outils
  14.280 +centralisés. Ne sous-estimez pas la valeur d'un outil rapide : vous allez
  14.281 +passer beaucoup de temps à interagir avec un logiciel de gestion de source.
  14.282 +</para>
  14.283 +
  14.284 +<para>Les outils distribués sont complètement indépendants des aléas de votre serveur,
  14.285 +d'autant plus qu'ils répliquent les métadonnées à beaucoup d'endroits. Si
  14.286 +votre serveur central prend feu, vous avez intérêt à ce que les médias de
  14.287 +sauvegardes soient fiables, et que votre dernier <quote>backup</quote> soit récent et
  14.288 +fonctionne sans problème. Avec un outil distribué, vous avez autant de
  14.289 +<quote>backup</quote> que de contributeurs.
  14.290 +</para>
  14.291 +
  14.292 +<para>En outre, la fiabilité de votre réseau affectera beaucoup moins les
  14.293 +outils distribués. Vous ne pouvez même pas utiliser un outil centralisé
  14.294 +sans connexion réseau, à l'exception de quelques commandes, très limitées.
  14.295 +Avec un outil distribué, si votre connexion réseau tombe pendant que vous
  14.296 +travaillez, vous pouvez ne même pas vous en rendre compte. La seule chose
  14.297 +que vous ne serez pas capable de faire sera de communiquer avec des dépôts
  14.298 +distants, opération somme toute assez rare en comparaison aux opérations
  14.299 +locales. Si vous avez une équipe de collaborateurs très dispersée ceci peut
  14.300 +être significatif.
  14.301 +</para>
  14.302 +
  14.303 +<sect2>
  14.304 +<title>Avantages pour les projets \textit{Open Source}</title>
  14.305 +
  14.306 +<para>Si vous prenez goût à un projet \textit{Open Source} et que vous
  14.307 +décidez de commencer à toucher à son code, et que le projet utilise
  14.308 +un gestionnaire de source distribué, vous êtes immédiatement un "pair"
  14.309 +avec les personnes formant le <quote>cœur</quote> du projet. Si ils publient
  14.310 +leurs dépôts, vous pouvez immédiatement copier leurs historiques de
  14.311 +projet, faire des modifications, enregistrer votre travail en utilisant
  14.312 +les même outils qu'eux. Par comparaison, avec un outil centralisé, vous
  14.313 +devez utiliser un logiciel en mode <quote>lecture seule</quote> à moins que
  14.314 +quelqu'un ne vous donne les privilèges de <quote>commit</quote> sur le serveur
  14.315 +central. Avant ça, vous ne serez pas capable d'enregistrer vos
  14.316 +modifications, et vos propres modifications risqueront de se
  14.317 +corrompre chaque fois que vous essayerez de mettre à jour à votre
  14.318 +espace de travail avec le serveur central.
  14.319 +</para>
  14.320 +
  14.321 +<sect3>
  14.322 +<title>Le non-problème du \textit{fork}</title>
  14.323 +
  14.324 +<para>Il a été souvent suggéré que les gestionnaires de source distribués
  14.325 +posent un risque pour les projets \textit{Open Source} car ils
  14.326 +facilitent grandement la création de <quote>fork</quote>\footnote{NdT:Création
  14.327 +d'une
  14.328 +<ulink url="version alternative du logiciel">version alternative du logiciel</ulink>{http://fr.wikipedia.org/wiki/Fork#Embranchement_d.27un_projet_informatique}.}
  14.329 +Un <quote>fork</quote> apparait quand il y des divergences d'opinion ou d'attitude
  14.330 +au sein d'un groupe de développeurs qui aboutissent à la décision de ne
  14.331 +plus travailler ensemble. Chaque parti s'empare d'une copie plus ou moins
  14.332 +complète du code source du projet et continue dans sa propre direction.
  14.333 +</para>
  14.334 +
  14.335 +<para>Parfois ces différents partis décident de se réconcilier. Avec un
  14.336 +serveur central, l'aspect <emphasis>technique</emphasis> de cette réconciliation
  14.337 +est un processus douloureux, et essentiellement manuel. Vous devez
  14.338 +décider quelle modification est <quote>la gagnante</quote>, et replacer, par un
  14.339 +moyen ou un autre, les modifications de l'autre équipe dans l'arborescence
  14.340 +du projet. Ceci implique généralement la perte d'une partie de l'historique
  14.341 +d'un des partis, ou même des deux.
  14.342 +</para>
  14.343 +
  14.344 +<para>Ce que les outils distribués permettent à ce sujet est probablement
  14.345 +la <emphasis>meilleure</emphasis> façon de développer un projet. Chaque modification
  14.346 +que vous effectuez est potentiellement un <quote>fork</quote>. La grande force de
  14.347 +cette approche est que les gestionnaires de source distribués doivent être
  14.348 +vraiment très efficaces pour <emphasis>fusionner</emphasis>\footnote{NdT:j'ai choisi de
  14.349 +traduire ici \textit{merging} par <quote>fusionner</quote> pour des raisons de clarté}
  14.350 +des <quote>forks</quote>, car les <quote>forks</quote>, dans ce contexte, arrivent tout le
  14.351 +temps.
  14.352 +</para>
  14.353 +
  14.354 +<para>Si chaque altération que n'importe qui effectue, à tout moment, est vue
  14.355 +comme un <quote>fork</quote> à fusionner, alors ce que le monde de l'\textit{Open
  14.356 +Source} voit comme un <quote>fork</quote> devient <emphasis>uniquement</emphasis> une problématique
  14.357 +sociale. En fait, les outils de gestions de source distribués <emphasis>réduisent</emphasis>
  14.358 +les chances de <quote>fork</quote>:
  14.359 +</para>
  14.360 +<itemizedlist>
  14.361 +<listitem><para>Ils éliminent la distinction sociale qu'imposent les outils centralisés
  14.362 +    entre les membres du projets (ceux qui ont accès au <quote>commit</quote>) et ceux de
  14.363 +    l'extérieur (ce qui ne l'ont pas).  \item Ils rendent plus facile la
  14.364 +    réconciliation après un <quote>fork</quote> social, car
  14.365 +	tout ce qu'elle implique est une simple fusion.
  14.366 +</para>
  14.367 +</listitem></itemizedlist>
  14.368 +
  14.369 +<para>Certaines personnes font de la résistance envers les gestionnaires de source
  14.370 +distribués parce qu'ils veulent garder un contrôle ferme sur leur projet, et
  14.371 +ils pensent que les outils centralisés leur fournissent ce contrôle. Néanmoins,
  14.372 +si c'est votre cas, sachez que si vous publiez votre dépôt CVS ou Subversion
  14.373 +de manière publique, il existe une quantité d'outils disponibles pour récupérer
  14.374 +entièrement votre projet et son historique (quoique lentement) et le récréer
  14.375 +ailleurs, sans votre contrôle. En fait, votre contrôle sur votre projet est
  14.376 +illusoire, vous ne faites qu'interdire à vos collaborateurs de travailler
  14.377 +de manière fluide, en disposant d'un miroir ou d'un <quote>fork</quote> de votre
  14.378 +historique.
  14.379 +%%%TODO: Fussy, those last sentences are not really well translated:
  14.380 +%%%no problem for me (wilk)
  14.381 +%However, if you're of this belief, and you publish your CVS or Subversion
  14.382 +%repositories publically, there are plenty of tools available that can pull
  14.383 +%out your entire project's history (albeit slowly) and recreate it somewhere
  14.384 +%that you don't control.  So while your control in this case is illusory, you are
  14.385 +%forgoing the ability to fluidly collaborate with whatever people feel
  14.386 +%compelled to mirror and fork your history.
  14.387 +</para>
  14.388 +
  14.389 +</sect3>
  14.390 +</sect2>
  14.391 +<sect2>
  14.392 +<title>Avantages pour les projets commerciaux</title>
  14.393 +
  14.394 +<para>Beaucoup de projets commerciaux sont réalisés par des équipes éparpillées
  14.395 +à travers le globe. Les contributeurs qui sont loin du serveur central
  14.396 +devront subir des commandes lentes et même parfois peu fiables. Les
  14.397 +solutions propriétaires de gestion de source tentent de palier ce problème
  14.398 +avec des réplications de sites distants qui sont à la fois coûteuses à mettre
  14.399 +en place et lourdes à administrer. Un système distribué ne souffre pas
  14.400 +de ce genre de problèmes. En outre, il est très aisé de mettre en place
  14.401 +plusieurs serveurs de références, disons un par site, de manière à ce qu'il
  14.402 +n'y ait pas de communication redondante entre les dépôts, sur une connexion
  14.403 +longue distance souvent onéreuse.
  14.404 +</para>
  14.405 +
  14.406 +<para>Les systèmes de gestion de source supportent généralement assez mal la
  14.407 +montée en charge. Ce n'est pas rare pour un gestionnaire de source centralisé
  14.408 +pourtant onéreux de s'effondrer sous la charge combinée d'une douzaine
  14.409 +d'utilisateurs concurrents seulement. Une fois encore, la réponse à cette problématique
  14.410 +est généralement encore la mise en place d'un ensemble complexe de serveurs
  14.411 +synchronisés par un mécanisme de réplication. Dans le cas d'un gestionnaire
  14.412 +de source distribué, la charge du serveur central &emdash; si vous avez un&emdash; est
  14.413 +plusieurs fois inférieure (car toutes les données sont déjà répliquées ailleurs),
  14.414 +un simple serveur, pas très cher, peut gérer les besoins d'une plus grande
  14.415 +équipe, et la réplication pour balancer la charge devient le
  14.416 +travail d'un simple script.
  14.417 +</para>
  14.418 +
  14.419 +<para>Si vous avez des employés sur le terrain, en train de chercher à résoudre un souci sur
  14.420 +le site d'un client, ils bénéficieront aussi d'un gestionnaire de source
  14.421 +distribué. Cet outil leur permettra de générer des versions personnalisées,
  14.422 +d'essayer différentes solutions, en les isolant aisément les unes des autres,
  14.423 +et de rechercher efficacement à travers l'historique des sources, la cause
  14.424 +des bugs ou des régressions, tout ceci sans avoir besoin de la moindre
  14.425 +connexion au réseau de votre compagnie.
  14.426 +</para>
  14.427 +
  14.428 +</sect2>
  14.429 +</sect1>
  14.430 +<sect1>
  14.431 +<title>Pourquoi choisir Mercurial?</title>
  14.432 +
  14.433 +<para>Mercurial a plusieurs caractéristiques qui en font un choix particulièrement
  14.434 +pertinent pour la gestion de source:
  14.435 +</para>
  14.436 +<itemizedlist>
  14.437 +<listitem><para>	\item Il est facile à apprendre et à utiliser ;
  14.438 +	\item Il est léger et performant ;
  14.439 +	\item Il monte facilement en charge ;
  14.440 +	\item Il est facile à personnaliser ;
  14.441 +</para>
  14.442 +</listitem></itemizedlist>
  14.443 +
  14.444 +<para>Si vous êtes déjà familier d'un outil de gestion de source, vous serez
  14.445 +capable de l'utiliser en moins de 5 minutes. Sinon, ça ne sera pas beaucoup
  14.446 +plus long\footnote{NdT: Pour appuyer le propos de l'auteur, je signale que
  14.447 +j'utilise Mercurial comme outil d'initiation à la gestion de contrôle dans
  14.448 +des travaux pratiques à l'ESME Sudria (<ulink url="http://www.esme.fr">http://www.esme.fr</ulink>) et que les
  14.449 +élèves le prennent en main sans difficulté majeure malgré l'approche distribuée.}.
  14.450 +Les commandes utilisées par Mercurial, comme ses fonctionnalités, sont
  14.451 +généralement uniformes et cohérentes, et vous pouvez donc ainsi garder en tête
  14.452 +simplement quelques règles générales, plutôt qu'un lot complexe d'exceptions.
  14.453 +</para>
  14.454 +
  14.455 +<para>Sur un petit projet, vous pouvez commencer à travailler avec Mercurial en
  14.456 +quelques instants. Ajouter des modifications ou des branches, transférer
  14.457 +ces modifications (localement ou via le réseau), et les opérations
  14.458 +d'historique ou de statut sont aussi très rapides. Mercurial reste hors de
  14.459 +votre chemin grâce à sa simplicité d'utilisation et sa rapidité d'exécution.
  14.460 +</para>
  14.461 +
  14.462 +<para>L'utilité de Mercurial ne se limite pas à de petits projets: il est
  14.463 +aussi utilisé par des projets ayant des centaines ou même des milliers
  14.464 +de contributeurs, avec plusieurs dizaines de milliers de fichiers, et des
  14.465 +centaines de méga de code source.
  14.466 +</para>
  14.467 +
  14.468 +<para>Voici une liste non exhaustive des projets complexes ou critiques utilisant
  14.469 +Mercurial :
  14.470 +%TODO
  14.471 +% For both spanish and english version, add the following examples:
  14.472 +</para>
  14.473 +<itemizedlist>
  14.474 +<listitem><para>	\item <ulink url="Firefox">Firefox</ulink>{https://developer.mozilla.org/en/Mozilla_Source_Code_(Mercurial)} ;
  14.475 +	\item <ulink url="OpenSolaris">OpenSolaris</ulink>{http://opensolaris.org/os/community/tools/scm/hg_help/} ;
  14.476 +	\item <ulink url="OpenJDK">OpenJDK</ulink>{http://hg.openjdk.java.net/} (utilisant en outre l'extension
  14.477 +	<quote>forest</quote> pour gérer ses sous modules);
  14.478 +</para>
  14.479 +</listitem></itemizedlist>
  14.480 +
  14.481 +<para>Si les fonctionnalités cœur de Mercurial ne sont pas suffisantes pour vous,
  14.482 +il est très aisé d'en construire d'autres. Mercurial est adapté à l'utilisation
  14.483 +de scripts, et son implémentation interne en Python, propre et claire,
  14.484 +rend encore plus facile l'ajout de fonctionnalités sous forme d'extensions. Il
  14.485 +en existe déjà un certain nombre de très populaires et très utiles,
  14.486 +dont le périmètre va de la recherche de bugs à l'amélioration des performances.
  14.487 +</para>
  14.488 +
  14.489 +</sect1>
  14.490 +<sect1>
  14.491 +<title>Mercurial comparé aux autres outils</title>
  14.492 +
  14.493 +<para>Avant que vous n'alliez plus loin, comprenez bien que cette section
  14.494 +reflète mes propres expériences, et elle est donc (j'ose le dire)
  14.495 +peu objective. Néanmoins, j'ai utilisé les outils de gestion de source
  14.496 +listés ci dessous, dans la plupart des cas, pendant plusieurs années.
  14.497 +%% TODO: Fussy translation.
  14.498 +</para>
  14.499 +
  14.500 +<sect2>
  14.501 +<title>Subversion</title>
  14.502 +
  14.503 +<para>Subversion est un des outils de gestion de source les plus populaire, il fût
  14.504 +développé pour remplacer CVS. Il a une architecture client/server centralisée.
  14.505 +</para>
  14.506 +
  14.507 +<para>Subversion et Mercurial ont des noms de commandes très similaires pour
  14.508 +les mêmes opérations, ainsi si vous êtes familier avec l'un, c'est facile
  14.509 +d'apprendre l'autre. Ces deux outils sont portables sur les systèmes
  14.510 +d'exploitation les plus populaires\footnote{NdT:Mercurial fonctionne sans problème
  14.511 +sur OpenVMS à l'ESME Sudria <ulink url="http://www.esme.fr">http://www.esme.fr</ulink>, compte tenu que Subversion a été
  14.512 +développé en C, je ne suis pas sûr que son portage aurait été aussi aisé.}.
  14.513 +%TODO: Backport this statement in english and spanish
  14.514 +</para>
  14.515 +
  14.516 +<para>Avant la version 1.5, Subversion n'offrait aucune forme de support pour les fusions. Lors
  14.517 +de l'écriture de ce livre, ses capacités de fusion étaient nouvelles, et réputées pour être
  14.518 +\href{http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword}{complexes
  14.519 +et bugguées}.
  14.520 +</para>
  14.521 +
  14.522 +<para>Mercurial dispose d'un avantage substantiel en terme de performance par rapport à
  14.523 +Subversion sur la plupart des opérations que j'ai pu tester. J'ai mesuré
  14.524 +une différence de performance allant de deux à six fois plus rapide avec
  14.525 +le système de stockage de fichier local de Subversion 1.4.3
  14.526 +(<emphasis>ra_local</emphasis>), qui est la méthode d'accès la plus rapide disponible. Dans
  14.527 +un déploiement plus réaliste, impliquant un stockage réseau, Subversion
  14.528 +serait encore plus désavantagé. Parce que la plupart des commandes Subversion
  14.529 +doivent communiquer avec le serveur et que Subversion n'a pas de mécanisme
  14.530 +de réplication, la capacité du serveur et la bande passante sont devenues des
  14.531 +goulots d'étranglement pour les projets de taille moyenne ou grande.
  14.532 +</para>
  14.533 +
  14.534 +<para>En outre, Subversion implique une surcharge substantielle dans le stockage local
  14.535 +de certaines données, pour éviter des transactions avec le serveur, pour
  14.536 +certaines opérations communes, telles que la recherche des fichiers modifiés
  14.537 +(<literal>status</literal>) et l'affichage des modifications par rapport à la révision
  14.538 +courante (<literal>diff</literal>). En conséquence, un répertoire de travail Subversion
  14.539 +a souvent la même taille, ou est plus grand, qu'un dépôt Mercurial et son
  14.540 +espace de travail, et ceci bien que le dépôt Mercurial contienne l'intégralité
  14.541 +de l'historique.
  14.542 +</para>
  14.543 +
  14.544 +<para>Subversion est largement supporté par les outils tierces. Mercurial est
  14.545 +actuellement encore en retrait de ce point de vue. L'écart se réduit, néanmoins,
  14.546 +et en effet certains des outils graphiques sont maintenant supérieurs à leurs
  14.547 +équivalents Subversion. Comme Mercurial, Subversion dispose d'un excellent
  14.548 +manuel utilisateur.
  14.549 +</para>
  14.550 +
  14.551 +<para>Parce que Subversion ne stocke pas l'historique chez ses clients, il est
  14.552 +parfaitement adapté à la gestion de projets qui doivent suivre un ensemble
  14.553 +de larges fichiers binaires et opaques. Si vous suivez une cinquantaine de
  14.554 +versions d'un fichier incompressible de 10MB, l'occupation disque coté client
  14.555 +d'un projet sous Subversion restera à peu près constante. A l'inverse,
  14.556 +l'occupation disque du même projet sous n'importe lequel des gestionnaires
  14.557 +de source distribués grandira rapidement, proportionnellement aux nombres
  14.558 +de versions, car les différences entre chaque révisions seront très grandes.
  14.559 +</para>
  14.560 +
  14.561 +<para>En outre, c'est souvent difficile ou, généralement, impossible de fusionner
  14.562 +des différences dans un fichier binaire. La capacité de Subversion de
  14.563 +verrouiller des fichiers, pour permettre à l'utilisateur d'être le seul
  14.564 +à le mettre à jour (<quote>commit</quote>) temporairement, est un avantage significatif
  14.565 +dans un projet doté de beaucoup de fichiers binaires.
  14.566 +</para>
  14.567 +
  14.568 +<para>Mercurial peut importer l'historique depuis un dépôt Subversion. Il peut
  14.569 +aussi exporter l'ensemble des révisions d'un projet vers un dépôt Subversion.
  14.570 +Ceci rend très facile de <quote>prendre la température</quote> et d'utiliser Mercurial et Subversion
  14.571 +en parallèle, avant de décider de migrer vers Mercurial. La conversion de
  14.572 +l'historique est incrémentale, donc vous pouvez effectuer une conversion
  14.573 +initiale, puis de petites additions par la suite pour ajouter les nouvelles
  14.574 +modifications.
  14.575 +</para>
  14.576 +
  14.577 +</sect2>
  14.578 +<sect2>
  14.579 +<title>Git</title>
  14.580 +
  14.581 +<para>Git est un outil de gestion de source distribué qui fût développé pour gérer
  14.582 +le code source de noyau de Linux. Comme Mercurial, sa conception initiale a
  14.583 +été inspirée par Monotone.
  14.584 +</para>
  14.585 +
  14.586 +<para>Git dispose d'un ensemble conséquent de commandes, avec plus de 139 commandes
  14.587 +individuelles pour la version 1.5.0. Il a aussi la réputation d'être difficile
  14.588 +à apprendre. Comparé à Git, le point fort de Mercurial est clairement sa
  14.589 +simplicité.
  14.590 +</para>
  14.591 +
  14.592 +<para>En terme de performance, Git est extrêmement rapide. Dans la plupart des
  14.593 +cas, il est plus rapide que Mercurial, tout du moins sur Linux, alors que
  14.594 +Mercurial peut être plus performant sur d'autres opérations. Néanmoins, sur
  14.595 +Windows, les performances et le niveau de support général fourni par Git,
  14.596 +au moment de l'écriture de cet ouvrage, est bien derrière celui de Mercurial.
  14.597 +</para>
  14.598 +
  14.599 +<para>Alors que le dépôt Mercurial ne demande aucune maintenance, un dépôt Git
  14.600 +exige d'exécuter manuellement et régulièrement la commande <quote>repacks</quote> sur
  14.601 +ces métadonnées. Sans ceci, les performances de git se dégradent et la
  14.602 +consommation de l'espace disque augmente rapidement. Un serveur qui contient
  14.603 +plusieurs dépôts Git qui ne sont pas régulièrement et fréquemment <quote>repacked</quote>
  14.604 +deviendra un vrai problème lors des <quote>backups</quote> du disque, et il y eu des
  14.605 +cas, où un <quote>backup</quote> journalier pouvait durer plus de 24 heures. Un dépôt
  14.606 +fraichement <quote>repacked</quote> sera légèrement plus petit qu'un dépôt Mercurial,
  14.607 +mais un dépôt non <quote>repacked</quote> est beaucoup plus grand.
  14.608 +</para>
  14.609 +
  14.610 +<para>Le cœur de Git est écrit en C. La plupart des commandes Git sont implémentées
  14.611 +sous forme de scripts Shell ou Perl, et la qualité de ces scripts varie
  14.612 +grandement. J'ai plusieurs fois constaté que certains de ces scripts étaient
  14.613 +chargés en mémoire aveuglément et que la présence d'erreurs pouvait s'avérer
  14.614 +fatal.
  14.615 +</para>
  14.616 +
  14.617 +<para>Mercurial peut importer l'historique d'un dépôt Git.
  14.618 +</para>
  14.619 +
  14.620 +</sect2>
  14.621 +<sect2>
  14.622 +<title>CVS</title>
  14.623 +
  14.624 +<para>CVS est probablement l'outil de gestion de source le plus utilisé aujourd'hui
  14.625 +dans le monde. À cause de son manque de clarté interne, il n'est plus
  14.626 +maintenu depuis plusieurs années.
  14.627 +</para>
  14.628 +
  14.629 +<para>Il a une architecture client/serveur centralisée. Il ne regroupe pas les
  14.630 +modifications de fichiers dans une opération de <quote>commit</quote> atomique, ce
  14.631 +qui permet à ses utilisateurs de <quote>casser le \textit{build}</quote> assez
  14.632 +facilement : une personne peut effectuer une opération de <quote>commit</quote>
  14.633 +sans problème puis être bloquée par besoin de fusion, avec comme conséquence
  14.634 +néfaste, que les autres utilisateurs ne récupèreront qu'une partie de ses
  14.635 +modifications. Ce problème affecte aussi la manière de travailler avec
  14.636 +l'historique du projet. Si vous voulez voir toutes les modifications d'une
  14.637 +personne du projet, vous devrez injecter manuellement les descriptions et les
  14.638 +\textit{timestamps} des modifications de chacun des fichiers impliqués (si
  14.639 +vous savez au moins quels sont ces fichiers).
  14.640 +</para>
  14.641 +
  14.642 +<para>CVS a une notion étrange des \textit{tags} et des branches que je n'essayerai
  14.643 +même pas de décrire ici. Il ne supporte pas bien les opérations de renommage d'un
  14.644 +fichier ou d'un répertoire, ce qui facilite la corruption de son dépôt. Il n'a
  14.645 +presque pas pour ainsi dire de contrôle de cohérence interne, il est donc
  14.646 +pratiquement impossible de dire si un dépôt est corrompu ni à quel point. Je
  14.647 +ne recommanderai pas CVS pour un projet existant ou nouveau.
  14.648 +</para>
  14.649 +
  14.650 +<para>Mercurial peut importer l'historique d'un projet CVS. Néanmoins, il y a
  14.651 +quelques principes à respecter; ce qui est vrai aussi pour les autres
  14.652 +outils d'import de projet CVS. À cause de l'absence de <quote>commit</quote> atomique
  14.653 +et gestion de version de l'arborescence, il n'est pas possible de reconstruire
  14.654 +de manière précise l'ensemble de l'historique. Un travail de <quote>devinette</quote>
  14.655 +est donc nécessaire, et les fichiers renommés ne sont pas détectés. Parce
  14.656 +qu'une bonne part de l'administration d'un dépôt CVS est effectuée manuellement,
  14.657 +et est donc, sujette à erreur, il est courant que les imports CVS rencontrent
  14.658 +de nombreux problèmes avec les dépôt corrompus (des \textit{timestamps}
  14.659 +de révision complètement buggés et des fichiers verrouillés depuis des années
  14.660 +sont deux des problèmes les moins intéressants dont je me souvienne).
  14.661 +</para>
  14.662 +
  14.663 +<para>Mercurial peut importer l'historique depuis un dépôt CVS.
  14.664 +</para>
  14.665 +
  14.666 +</sect2>
  14.667 +<sect2>
  14.668 +<title>Outils propriétaires</title>
  14.669 +
  14.670 +<para>Perforce a une architecture client/serveur centralisée, sans aucun
  14.671 +mécanisme de mise en cache de données coté client. Contrairement à la plupart
  14.672 +des outils modernes de gestion de source, Perforce exige de ses
  14.673 +utilisateurs d'exécuter une commande pour informer le serveur
  14.674 +central de tout fichier qu'ils souhaitent modifier.
  14.675 +</para>
  14.676 +
  14.677 +<para>Les performances de Perforce sont plutôt bonnes pour des petites
  14.678 +équipes, mais elles s'effondrent rapidement lorsque le nombre
  14.679 +d'utilisateurs augmente au delà de la douzaine. Des installations
  14.680 +de Perforce assez larges nécessitent le déploiement de proxies pour
  14.681 +supporter la montée en charge associée.
  14.682 +</para>
  14.683 +
  14.684 +</sect2>
  14.685 +<sect2>
  14.686 +<title>Choisir un outil de gestion de source</title>
  14.687 +
  14.688 +<para>A l'exception de CVS, tous les outils listés ci-dessus ont des
  14.689 +forces qui leur sont propres et qui correspondent à certaines
  14.690 +formes de projet. Il n'y a pas un seul meilleur outil de gestion
  14.691 +de source qui correspondrait le mieux à toutes les situations.
  14.692 +</para>
  14.693 +
  14.694 +<para>Par exemple, Subversion est un très bon choix lorsqu'on travaille
  14.695 +avec beaucoup de fichiers binaires, qui évoluent régulièrement, grâce
  14.696 +à sa nature centralisée et sa capacité à verrouiller des fichiers.
  14.697 +</para>
  14.698 +
  14.699 +<para>Personnellement, je préfère Mercurial pour sa simplicité, ses
  14.700 +performances et sa bonne capacité de fusion, et il m'a très bien rendu service
  14.701 +de plusieurs années maintenant.
  14.702 +</para>
  14.703 +
  14.704 +</sect2>
  14.705 +</sect1>
  14.706 +<sect1>
  14.707 +<title>Migrer depuis un outil à Mercurial</title>
  14.708 +
  14.709 +<para>Mercurial est livré avec une extension nommée <literal role="hg-ext">convert</literal>, qui
  14.710 +peut de manière incrémentale importer des révisions depuis différents
  14.711 +autres outils de gestion de source. Par <quote>incrémental</quote>, j'entends que
  14.712 +vous pouvez convertir l'historique entier du projet en une seule fois,
  14.713 +puis relancer l'outil d'import plus tard pour obtenir les modifications
  14.714 +effectuées depuis votre import initial.
  14.715 +</para>
  14.716 +
  14.717 +<para>Les outils de gestion de source supportés par <literal role="hg-ext">convert</literal> sont :
  14.718 +</para>
  14.719 +<itemizedlist>
  14.720 +<listitem><para>	\item Subversion
  14.721 +	\item CVS
  14.722 +	\item Git
  14.723 +	\item Darcs
  14.724 +</para>
  14.725 +</listitem></itemizedlist>
  14.726 +
  14.727 +<para>En outre, <literal role="hg-ext">convert</literal> peut exporter les modifications depuis Mercurial
  14.728 +vers Subversion. Ceci rend possible d'essayer Subversion en parallèle
  14.729 +avant de choisir une solution définitive, sans aucun risque de perte de
  14.730 +données.
  14.731 +</para>
  14.732 +
  14.733 +<para>La commande <command role="hg-ext-conver">convert</command> est très simple à utiliser. Simplement,
  14.734 +indiquez le chemin ou l'URL du dépôt de source, en lui indiquant éventuellement
  14.735 +le nom du chemin de destination, et la conversion se met en route. Après cet
  14.736 +import initial, il suffit de relancer la commande encore une fois pour
  14.737 +importer les modifications effectuées depuis.
  14.738 +</para>
  14.739 +
  14.740 +</sect1>
  14.741 +</chapter>
  14.742 +
  14.743 +<!--
  14.744 +local variables: 
  14.745 +sgml-parent-document: ("00book.xml" "book" "chapter")
  14.746 +end:
  14.747 +-->
  14.748 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/fr/ch02-tour-basic.xml	Sun Aug 16 04:58:01 2009 +0200
    15.3 @@ -0,0 +1,889 @@
    15.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    15.5 +
    15.6 +<chapter>
    15.7 +<title>Un rapide tour de Mercurial</title>
    15.8 +<para>\label{chap:tour-basic}</para>
    15.9 +
   15.10 +<sect1>
   15.11 +<title>Installer Mercurial sur votre système</title>
   15.12 +<para>\label{sec:tour:install}</para>
   15.13 +
   15.14 +<para>Des paquetages binaires de Mercurial sont disponibles pour la plupart
   15.15 +des systèmes d'exploitation, ce qui rend facile l'utilisation immédiate
   15.16 +de Mercurial sur votre ordinateur.</para>
   15.17 +
   15.18 +<sect2>
   15.19 +<title>Linux</title>
   15.20 +
   15.21 +<para>Parce que chaque distribution de Linux a ses propres outils de gestion
   15.22 +de paquets, politiques et rythmes de développements, il est difficile de
   15.23 +donner un ensemble d'instructions uniques pour installer les binaires de
   15.24 +Mercurial. La version de Mercurial avec laquelle vous vous retrouverez
   15.25 +dépendra grandement de l'activité de la personne en charge du paquetage
   15.26 +pour la distribution.</para>
   15.27 +
   15.28 +<para>Pour rester simple, je me concentrerai sur l'installation de Mercurial
   15.29 +en ligne de commande, sous les distributions les plus courantes. La
   15.30 +plupart des distributions fournissent des gestionnaires graphiques de
   15.31 +paquetage qui vous permettront d'installer Mercurial en quelques clicks.
   15.32 +Le paquetage devrait se nommer \textit{mercurial}.</para>
   15.33 +
   15.34 +<itemizedlist>
   15.35 +<listitem><para>Debian:</para>
   15.36 +</listitem><programlisting>
   15.37 +<listitem><para>    apt-get install mercurial</para>
   15.38 +</listitem></programlisting></para>
   15.39 +</listitem>
   15.40 +<listitem><para>Fedora Core:
   15.41 +</para>
   15.42 +</listitem><programlisting>
   15.43 +<listitem><para>    yum install mercurial
   15.44 +</para>
   15.45 +</listitem></programlisting>
   15.46 +
   15.47 +</para>
   15.48 +</listitem>
   15.49 +<listitem><para>Gentoo:
   15.50 +</para>
   15.51 +</listitem><programlisting>
   15.52 +<listitem><para>    emerge mercurial
   15.53 +</para>
   15.54 +</listitem></programlisting>
   15.55 +
   15.56 +</para>
   15.57 +</listitem>
   15.58 +<listitem><para>OpenSUSE:
   15.59 +</para>
   15.60 +</listitem><programlisting>
   15.61 +<listitem><para>    yum install mercurial
   15.62 +</para>
   15.63 +</listitem></programlisting>
   15.64 +
   15.65 +</para>
   15.66 +</listitem>
   15.67 +<listitem><para>Ubuntu: Le paquetage de Mercurial d'Ubuntu est construit sur celui de Debian.
   15.68 +              Pour l'installer, exécutez simplement les commandes suivantes:
   15.69 +</para>
   15.70 +</listitem><programlisting>
   15.71 +<listitem><para>    apt-get install mercurial
   15.72 +</para>
   15.73 +</listitem></programlisting>
   15.74 +<listitem><para>  Les paquetages Ubuntu pour Mercurial ont tendance à être un peu en retard
   15.75 +  par rapport au paquetage Debian (au moment de l'écriture de ce livre, il
   15.76 +  faut compter à peu près un retard de 7 mois), ce qui signifie que parfois
   15.77 +  sur Ubuntu, vous risquez de rencontrer des problèmes qui ont été corrigés
   15.78 +  depuis longtemps dans les paquetages Debian.
   15.79 +</para>
   15.80 +</listitem></itemizedlist>
   15.81 +
   15.82 +</sect2>
   15.83 +<sect2>
   15.84 +<title>Solaris</title>
   15.85 +
   15.86 +<para>SunFreeWare, à <ulink url="http://www.saufreeware.com">http://www.saufreeware.com</ulink>, est une bonne source
   15.87 +pour trouver un vaste nombre de paquets précompilés pour 32 ou 64 bits
   15.88 +Intel et les architecture Sparc, dont les versions courantes de Mercurial.
   15.89 +</para>
   15.90 +
   15.91 +</sect2>
   15.92 +<sect2>
   15.93 +<title>Mac OS X</title>
   15.94 +
   15.95 +<para>Lee Cantey publie un installateur de Mercurial pour Mac OS X sur le site
   15.96 +<ulink url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.  Ce paquetage fonctionne sur les
   15.97 +architectures Intel- et PowerPC. Avant de vous en servir, vous devez
   15.98 +installer une version Universelle MacPython <citation>web:macpython</citation>. C'est
   15.99 +assez facile à faire : suivez simplement les instructions sur le site
  15.100 +de Lee.
  15.101 +</para>
  15.102 +
  15.103 +<para>Il est aussi possible d'installer Mercurial en utilisant Fink ou MacPorts,
  15.104 +deux outils de gestion de paquetage libres pour Mac OS X. Si vous avez
  15.105 +Fink, utilisez <command>sudo fink install mercurial-py25</command>. Si vous avez
  15.106 +MacPorts, <command>sudo port install mercurial</command>.
  15.107 +</para>
  15.108 +
  15.109 +</sect2>
  15.110 +<sect2>
  15.111 +<title>Windows</title>
  15.112 +
  15.113 +<para>Lee Cantey publie aussi un installateur de Mercurial pour Windows sur le site
  15.114 +<ulink url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. Ce paquetage n'a aucune dépendance
  15.115 +externe, il fonctionne <quote>tout court</quote>.
  15.116 +</para>
  15.117 +
  15.118 +<note>
  15.119 +<para>  La version de Windows de Mercurial ne convertie pas automatiquement
  15.120 +  les retours chariot Windows et Unix. Si vous désirez partager votre
  15.121 +  travail avec des utilisateurs Unix, vous devez faire un peu de configuration
  15.122 +  supplémentaire. XXX En dire plus.
  15.123 +</para>
  15.124 +</note>
  15.125 +
  15.126 +</sect2>
  15.127 +</sect1>
  15.128 +<sect1>
  15.129 +<title>Commencer à utiliser Mercurial</title>
  15.130 +
  15.131 +<para>Pour commencer, nous utiliserons la commande <command role="hg-cmd">hg version</command> pour vérifier
  15.132 +si Mercurial est installé proprement. Les informations affichées sur la
  15.133 +version ne sont pas réellement importantes en soit, c'est surtout de savoir
  15.134 +si elles s'affichent qui nous intéresse.
  15.135 +<!-- &interaction.tour.version; -->
  15.136 +</para>
  15.137 +
  15.138 +<sect2>
  15.139 +<title>L'aide intégrée</title>
  15.140 +
  15.141 +<para>Mercurial fournit un système d'aide intégré, ce qui est inestimable quand
  15.142 +vous vous retrouvez coincé à essayer de vous rappeler comment lancer telle
  15.143 +ou telle commande.
  15.144 +Si c'est le cas, exécutez simplement <command role="hg-cmd">hg help</command>; il vous aidera à imprimer
  15.145 +une brève liste de commandes, avec une description de ce qu'elles font. Si vous
  15.146 +demandez de l'aide sur une commande spécifique (voir ci-dessous), il affichera
  15.147 +des informations plus détaillées.
  15.148 +<!-- &interaction.tour.help; -->
  15.149 +Pour un niveau d'informations encore plus détaillées (ce dont vous aurez rarement
  15.150 +besoin), exécuter <command role="hg-cmd">hg help <option role="hg-opt-global">-v</option></command>.  L'option <option role="hg-opt-global">-v</option> est
  15.151 +l'abréviation de <option role="hg-opt-global">--verbose</option>, et indique à Mercurial d'afficher plus
  15.152 +d'informations que d'habitude.
  15.153 +</para>
  15.154 +
  15.155 +</sect2>
  15.156 +</sect1>
  15.157 +<sect1>
  15.158 +<title>Travailler avec un dépôt</title>
  15.159 +
  15.160 +<para>Avec Mercurial, tout se déroule au sein du <emphasis>dépôt</emphasis>\footnote{NdT: Dépôt est
  15.161 +la traduction que j'ai retenue pour tout l'ouvrage du terme anglais \textit{repository}}.
  15.162 +Le dépôt d'un projet contient tous les fichiers qui <quote>appartiennent</quote> au projet.
  15.163 +</para>
  15.164 +
  15.165 +<para>Il n'y a rien de particulièrement magique au sujet de ce dépôt, c'est
  15.166 +simplement une arborescence sur votre système de fichiers que Mercurial
  15.167 +traite de manière spéciale. Vous pouvez renommer ou effacer ce répertoire
  15.168 +à n'importe quel moment, en utilisant la ligne de commande ou votre
  15.169 +explorateur de fichiers.
  15.170 +</para>
  15.171 +
  15.172 +<sect2>
  15.173 +<title>Faire une copie locale de votre dépôt</title>
  15.174 +
  15.175 +<para><emphasis>Copier</emphasis> un dépôt est juste un peu spécial. Bien que vous
  15.176 +puissiez utiliser une commande habituelle de copie pour copier
  15.177 +votre dépôt, il vaut mieux utiliser une commande fournie par
  15.178 +Mercurial. Cette commande est appelée <command role="hg-cmd">hg clone</command>, car elle
  15.179 +crée une copie identique à un dépôt existant.
  15.180 +<!-- &interaction.tour.clone; -->
  15.181 +Si votre opération de clonage réussit, vous devriez maintenant
  15.182 +avoir un répertoire local appelé <filename class="directory">hello</filename>. Ce répertoire
  15.183 +contiendra quelques fichiers.
  15.184 +<!-- &interaction.tour.ls; -->
  15.185 +Ces fichiers ont le même contenu et historique dans votre dépôt
  15.186 +qu'ils ont dans le dépôt que vous avez cloné.
  15.187 +</para>
  15.188 +
  15.189 +<para>Chaque dépôt Mercurial est complet, autonome et indépendant. Il
  15.190 +contient sa propre copie privée des fichiers du projet et de leur
  15.191 +historique. Le clone d'un dépôt se souvient de la localisation du
  15.192 +dépôt à partir duquel il a été clôné, mais il ne communique pas avec
  15.193 +ce dernier, ou un autre, à moins que vous ne lui demandiez.
  15.194 +</para>
  15.195 +
  15.196 +<para>Ce que tout ceci signifie pour le moment est que nous sommes libres
  15.197 +d'expérimenter avec ce dépôt, confiants dans le fait qu'il s'agit d'un
  15.198 +<quote>bac à sable</quote> qui n'affectera personne d'autre.
  15.199 +</para>
  15.200 +
  15.201 +</sect2>
  15.202 +<sect2>
  15.203 +<title>Quel est le contenu d'un dépôt ?</title>
  15.204 +
  15.205 +<para>Prêtons plus attention un instant au contenu d'un dépôt. Nous voyons
  15.206 +qu'il contient un répertoire nommé <filename class="directory">.hg</filename>. C'est ici que Mercurial
  15.207 +conserve toutes ses métadonnées.
  15.208 +<!-- &interaction.tour.ls-a; -->
  15.209 +</para>
  15.210 +
  15.211 +<para>Le contenu du répertoire <filename class="directory">.hg</filename> et ses sous répertoires sont les
  15.212 +seuls propres à Mercurial. Tous les autres fichiers et répertoires dans
  15.213 +le dépôt sont à vous, et vous pouvez en faire ce que vous voulez.
  15.214 +</para>
  15.215 +
  15.216 +<para>Pour introduire un peu de terminologie, le répertoire <filename class="directory">.hg</filename> est
  15.217 +un <quote>vrai</quote> dépôt, et tous les fichiers et les répertoires qui coexistent
  15.218 +avec lui, sont désignés sous le nom <emphasis>espace de travail</emphasis>\footnote{NdT:
  15.219 +\textit{working directory}}. Une manière facile de se rappeler cette
  15.220 +distinction est de retenir que le <emphasis>dépôt</emphasis> contient l'<emphasis>historique</emphasis>
  15.221 +de votre projet, alors que l'<emphasis>espace de travail</emphasis> contient une \emph{copie
  15.222 +ponctuelle}\footnote{NdT: Ce terme est une traduction du terme anglais
  15.223 +\textit{snapshot}. Il est traduit ici pour faciliter la lecture, mais ne sera
  15.224 +plus traduit par la suite.} de votre projet à un certain point de son
  15.225 +historique.
  15.226 +</para>
  15.227 +
  15.228 +</sect2>
  15.229 +</sect1>
  15.230 +<sect1>
  15.231 +<title>Une ballade dans l'historique</title>
  15.232 +
  15.233 +<para>Une des premières choses que vous aurez envie de faire avec un nouveau
  15.234 +dépôt, sera de comprendre son historique. La commande <command role="hg-cmd">hg log</command> vous
  15.235 +donne une vue de l'historique.
  15.236 +<!-- &interaction.tour.log; -->
  15.237 +Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque
  15.238 +révision enregistrée pour ce projet. Dans la terminologie de Mercurial, nous
  15.239 +appelons chacun de ces évènements enregistrés un <emphasis>changeset</emphasis>, parce
  15.240 +qu'il contient un ensemble de modifications sur plusieurs fichiers.
  15.241 +</para>
  15.242 +
  15.243 +<para>La commande <command role="hg-cmd">hg log</command> affiche ainsi ces informations:
  15.244 +</para>
  15.245 +<itemizedlist>
  15.246 +<listitem><para><literal>changeset</literal>: Ce champ contient un nombre, séparé par deux points
  15.247 +  (:), d'une chaine hexadécimale. Il s'agit en fait d'<emphasis>identifiants</emphasis>
  15.248 +  d'un \textit{changeset}. Il y a deux identifiants car le numéro de
  15.249 +  la révision est plus court et plus à facile à saisir qu'une séquence
  15.250 +  hexadécimale.
  15.251 +</para>
  15.252 +</listitem>
  15.253 +<listitem><para><literal>user</literal>: L'identité de la personne qui a créée ce  %%% laisser le terme anglais car il sera affiché
  15.254 +  \textit{changeset}. C'est un champ libre de forme, mais la plupart du
  15.255 +  temps il contient le nom et l'email de la personne.
  15.256 +</para>
  15.257 +</listitem>
  15.258 +<listitem><para><literal>date</literal>: La date et l'heure à laquelle le \textit{changeset}
  15.259 +  a été créé, ainsi que le \textit{fuseau horaire} dans laquelle il a été créé. %%%TODO: Translate 'timezone' properly : FUSEAU
  15.260 +  (La date et l'heure sont locales à ce \textit{fuseau}, elles indiquent
  15.261 +  donc quelle date et heure il était pour la personne qui a créé ce %%%TODO: je suppose (quelle "heure")  OUI
  15.262 +  \textit{changeset}.)
  15.263 +</para>
  15.264 +</listitem>
  15.265 +<listitem><para><literal>résumé</literal>: La première du message que le créateur a associé à
  15.266 +  son \textit{changeset} pour le décrire.
  15.267 +</para>
  15.268 +</listitem></itemizedlist>
  15.269 +
  15.270 +<para>Par défaut, la commande <command role="hg-cmd">hg log</command> n'affiche qu'un résumé, il manque
  15.271 +beaucoup de détails.
  15.272 +</para>
  15.273 +
  15.274 +<para>La figure <xref linkend="fig:tour-basic:history"/> fournit une représentation graphique
  15.275 +de l'historique du dépôt <filename class="directory">hello</filename>, pour rendre plus facile de voir
  15.276 +dans quelle direction l'historique se <quote>déroule</quote>\footnote{NdT: \textit{flowing in}.}.
  15.277 +Nous reviendrons régulièrement sur cette représentation dans ce chapitre et
  15.278 +ceux qui suivent.
  15.279 +</para>
  15.280 +
  15.281 +<informalfigure>
  15.282 +
  15.283 +<para>  <mediaobject><imageobject><imagedata fileref="tour-history"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  15.284 +  <caption><para>Représentation graphique du dépôt <filename class="directory">hello</para></caption> </filename>
  15.285 +  \label{fig:tour-basic:history}
  15.286 +</para>
  15.287 +</informalfigure>
  15.288 +
  15.289 +<sect2>
  15.290 +<title>Changesets, révisions, et discuter avec les autres</title>
  15.291 +<para>%%% je propose "colaboration"
  15.292 +</para>
  15.293 +
  15.294 +<para>Comme l'anglais est réputé pour être un langage maladroit, et que l'informatique
  15.295 +est la source de bien des erreurs de terminologies (pourquoi utiliser un
  15.296 +seul terme quand quatre feront l'affaire ?), la gestion de version a une
  15.297 +variété de mots et de phrases qui veulent dire la même chose. Si vous
  15.298 +discutez d'historique de Mercurial avec d'autres personnes,
  15.299 +%%%TODO: ça ne veut rien dire: il faut supprimer une des personnes : soit "quelqu'un",
  15.300 +% soit "à d'autres personnes"
  15.301 +vous constaterez que souvent le mot <quote>\textit{changeset}</quote> est contracté simplement
  15.302 +en <quote>change</quote> ou (à l'écrit) <quote>cset</quote>, et même parfois un
  15.303 +\textit{changeset} simplement <quote>révision</quote>, abrégé en <quote>rev</quote>.
  15.304 +</para>
  15.305 +
  15.306 +<para>Bien que le <emphasis>mot</emphasis> que vous utilisez pour désigner le concept de
  15.307 +\textit{changeset} importe peu, l'<emphasis>identifiant</emphasis> que vous utilisez
  15.308 +pour désigner un <emphasis>changeset</emphasis> \textit{spécifique} a une grande
  15.309 +importance. Rappelez vous que le champ \textit{changeset} affiché par la
  15.310 +commande <command role="hg-cmd">hg log</command> identifie un \textit{changeset} à la fois avec
  15.311 +un numéro de révision et une séquence hexadécimale.
  15.312 +</para>
  15.313 +
  15.314 +<itemizedlist>
  15.315 +<listitem><para>Le numéro de révision est <emphasis>seulement valable dans ce dépôt</emphasis>,
  15.316 +</para>
  15.317 +</listitem>
  15.318 +<listitem><para>alors que la séquence hexadécimale est un \emph{identifiant
  15.319 +	permanent, et invariant } qui pourra toujours être associé au
  15.320 +	\textit{changeset} exact de <emphasis>chaque</emphasis> copie de votre dépôt.
  15.321 +</para>
  15.322 +</listitem></itemizedlist>
  15.323 +
  15.324 +<para>La distinction est importante. Si vous envoyez un email à quelqu'un en
  15.325 +parlant de la <quote>révision 33</quote>, il est très probable que sa révision 33
  15.326 +<emphasis>ne sera pas la même</emphasis> que la votre. La raison de ceci est que le
  15.327 +numéro de révision dépend de l'ordre dans lequel les modifications sont
  15.328 +arrivées dans le dépôt, et il n'y a aucune garantie que les mêmes changements
  15.329 +soient arrivés dans le même ordre dans différents dépôts. Trois modifications
  15.330 +$a,b,c$ peuvent aisément apparaitre dans un dépôt comme $0,1,2$, et dans
  15.331 +un autre comme $1,0,2$.
  15.332 +</para>
  15.333 +
  15.334 +<para>Mercurial utilise les numéros de révision uniquement comme des raccourcis
  15.335 +pratiques. Si vous devez discuter d'un \textit{changeset} avec quelqu'un,
  15.336 +ou identifer un \textit{changeset} pour une quelquonque %%%TODO: our : "pour" ou "ou"
  15.337 +raison (par exemple, un rapport de \textit{bug}), utilisez la séquence
  15.338 +hexadécimale.
  15.339 +</para>
  15.340 +
  15.341 +</sect2>
  15.342 +<sect2>
  15.343 +<title>Afficher une révision spécifique</title>
  15.344 +
  15.345 +<para>Pour réduire la sortie de <command role="hg-cmd">hg log</command> à une seule révision, utilisez
  15.346 +l'option <option role="hg-opt-log">-r</option> (ou <option role="hg-opt-log">--rev</option>). Vous pouvez utiliser
  15.347 +le numéro de révision ou la séquence hexadécimale comme identifiant, et
  15.348 +demander autant de révisions que vous le souhaitez.
  15.349 +<!-- &interaction.tour.log-r; -->
  15.350 +</para>
  15.351 +
  15.352 +<para>Si vous voulez voir l'historique de plusieurs révisions sans avoir à
  15.353 +les énumérer, vous pouvez utiliser la <emphasis>\textit{range notation</emphasis>}
  15.354 +\footnote{NdT: Il n'est pas aisé de traduire ce terme, donc je le  %%%TODO : intervalle de numérotation ?
  15.355 +laisse en anglais} qui vous permet d'exprimer l'idée <quote>je veux toutes
  15.356 +les révisions entre $a$ et $b$, inclus</quote>.
  15.357 +<!-- &interaction.tour.log.range; -->
  15.358 +Mercurial respecte aussi l'ordre dans lequel vous spécifiez les
  15.359 +révisions, ainsi <command role="hg-cmd">hg log -r 2:4</command> affichera $2,3,4$ alors que
  15.360 +<command role="hg-cmd">hg log -r 4:2</command> affichera $4,3,2$.
  15.361 +</para>
  15.362 +
  15.363 +</sect2>
  15.364 +<sect2>
  15.365 +<title>Informations détaillées</title>
  15.366 +
  15.367 +
  15.368 +<para>Le résumé affiché par <command role="hg-cmd">hg log</command> est suffisant si vous savez déjà ce %%%TODO: je pense que le premier "si" est de trop : exact
  15.369 +que vous cherchez. En revanche, vous aurez probablement besoin de voir une description
  15.370 +complète du changement, ou une liste des fichiers modifiés si vous
  15.371 +cherchez à déterminer qu'un \textit{changeset} est bien celui que vous%%%TODO: les propositions sont mal construites : après un "si...." il faut une proposition sans "si... donc ici : "si ... recherchez", ben quoi ?
  15.372 +recherchez. L'option \hgopt{-v} de la commande <command role="hg-cmd">hg log</command> (ou
  15.373 +\hgopt{--verbose}) vous donne ces informations supplémentaires.
  15.374 +<!-- &interaction.tour.log-v; -->
  15.375 +</para>
  15.376 +
  15.377 +<para>Si vous voulez voir à la fois la description et le contenu d'une
  15.378 +modification, ajouter l'option <option role="hg-opt-log">-p</option> (ou <option role="hg-opt-log">--patch</option>).
  15.379 +Ceci affiche le contenu d'une modification comme un <emphasis>diff unifié</emphasis>
  15.380 +\footnote{NdT: \textit{unified diff}} (si vous n'avez jamais vu de diff
  15.381 +unifié avant, consultez la section <xref linkend="sec:mq:patch"/> pour un rapide
  15.382 +survol).
  15.383 +</para>
  15.384 +
  15.385 +<para><!-- &interaction.tour.log-vp; -->
  15.386 +</para>
  15.387 +
  15.388 +</sect2>
  15.389 +</sect1>
  15.390 +<sect1>
  15.391 +<title>Tout sur les options de commandes</title>
  15.392 +
  15.393 +
  15.394 +<para>Avant d'aller plus loin sur le fonctionnement des commandes de Mercurial,
  15.395 +étudions un moment comment elles fonctionnent de manière générale. Vous
  15.396 +trouverez ça probablement utile pour la suite de notre parcours.
  15.397 +</para>
  15.398 +
  15.399 +<para>Mercurial utilise une approche directe et cohérente pour interpréter %%%TODO: une manière d'approche ?
  15.400 +les options que vous passez aux commandes. Il suit une convention commune
  15.401 +à la plupart des systèmes Unix et Linux modernes.
  15.402 +</para>
  15.403 +
  15.404 +<itemizedlist>
  15.405 +<listitem><para>Chaque option a un nom complet. Par exemple, comme nous l'avons déjà
  15.406 +      vu, la commande <command role="hg-cmd">hg log</command> accepte l'option <option role="hg-opt-log">--rev</option>.%%%TODO: commande ou command e\hgcmd...?
  15.407 +</para>
  15.408 +</listitem>
  15.409 +<listitem><para>La plupart des options disposent de noms abrégés. Aussi, au lieu d'utiliser
  15.410 +  <option role="hg-opt-log">--rev</option>, vous pouvez utiliser <option role="hg-opt-log">-r</option>. (Les options qui
  15.411 +  n'ont pas de noms abrégés sont généralement rarement utilisées, pour cette raison).
  15.412 +</para>
  15.413 +</listitem>
  15.414 +<listitem><para>Les noms complets commencent par deux tirets (i.e. <option role="hg-opt-log">--rev</option>),
  15.415 +  alors que les options courtes commencent avec un seul (i.e. <option role="hg-opt-log">-r</option>).
  15.416 +</para>
  15.417 +</listitem>
  15.418 +<listitem><para>Les noms des options sont cohérents entre les commandes. Par exemple,
  15.419 +  chaque commande qui accepte un \textit{changeset ID} ou un numéro de révision
  15.420 +  accepte aussi <option role="hg-opt-log">-r</option> et <option role="hg-opt-log">--rev</option> comme arguments.
  15.421 +  %TODO: Small mistake here, shouldn't have log here... shouldn't it ?
  15.422 +</para>
  15.423 +</listitem></itemizedlist>
  15.424 +
  15.425 +<para>Dans les exemples de ce livre, j'utilise les noms abrégés plutôt que les noms
  15.426 +complets. Ceci est une préférence personnelle, pas une recommandation.
  15.427 +</para>
  15.428 +
  15.429 +<para>La plupart des commandes qui affichent une quelconque sortie à l'écran,
  15.430 +afficheront davantage avec l'option <option role="hg-opt-global">-v</option> (ou <option role="hg-opt-global">--verbose</option>), et
  15.431 +moins avec l'option <option role="hg-opt-global">-q</option> (ou <option role="hg-opt-global">--quiet</option>).
  15.432 +</para>
  15.433 +
  15.434 +</sect1>
  15.435 +<sect1>
  15.436 +<title>Faire et vérifier des modifications</title>
  15.437 +
  15.438 +<para>Maintenant que nous avons une bonne idée des commandes pour consulter
  15.439 +l'historique de Mercurial, regardons comment faire des modifications et
  15.440 +les examiner.
  15.441 +</para>
  15.442 +
  15.443 +
  15.444 +<para>La première chose que nous allons faire c'est isoler notre expérience dans
  15.445 +un dépôt à part. Nous allons utiliser la commande <command role="hg-cmd">hg clone</command>, mais nous
  15.446 +n'avons pas besoin de faire une copie de dépôt distant. Comme nous avons
  15.447 +déjà une copie locale, nous pouvons juste faire un clone de celle-ci à la
  15.448 +place. C'est beaucoup plus rapide que de faire une copie à travers le
  15.449 +réseau, et un dépôt cloné localement prend également moins d'espace disque.
  15.450 +</para>
  15.451 +
  15.452 +<para><!-- &interaction.tour.reclone; -->
  15.453 +</para>
  15.454 +
  15.455 +<para>On notera au passage qu'il est souvent considéré comme une bonne pratique
  15.456 +de conserver une copie <quote>immaculée</quote> du dépôt distant, à partir de laquelle
  15.457 +vous pourrez faire des copies locales temporaires pour créer des <quote>bacs à
  15.458 +sable</quote> pour chaque tâche sur laquelle vous souhaitez travailler. Ceci vous
  15.459 +permet de travailler sur plusieurs choses en parallèle, chacune isolée les
  15.460 +unes des autres en attendant que ces tâches soient finies et que vous soyez
  15.461 +prêt à les réintégrer. Parce que les copies locales sont peu coûteuses, il
  15.462 +est très rapide de créer ou détruire des dépôts dès que vous en avez besoin.
  15.463 +</para>
  15.464 +
  15.465 +<para>%% Note: la dernière phrase n'est pas une traduction littérale, mais je
  15.466 +%% pense qu'elle exprime plus clairement en français ce que veut dire son
  15.467 +%% équivalent anglais. : OUI
  15.468 +</para>
  15.469 +
  15.470 +<para>Dans notre dépôt <filename class="directory">my-hello</filename>, nous avons un fichier <filename>hello.c</filename>
  15.471 +qui contient le classique programme <quote>hello, world</quote>. Nous allons utiliser
  15.472 +l'ancienne et vénérable commande <command>sed</command> pour l'éditer afin qu'il
  15.473 +affiche une seconde ligne à l'écran. (J'utilise <command>sed</command> seulement parce
  15.474 +qu'il est ainsi facile d'écrire des exemples sous forme de script. Comme
  15.475 +vous n'avez pas ces contraintes, vous n'utiliserez probablement pas <command>sed</command>
  15.476 +mais plutôt votre éditeur de texte favori).
  15.477 +</para>
  15.478 +
  15.479 +<para><!-- &interaction.tour.sed; -->
  15.480 +</para>
  15.481 +
  15.482 +<para>La commande <command role="hg-cmd">hg status</command> de Mercurial nous dira de quels fichiers Mercurial
  15.483 +s'occupe au sein de ce dépôt.
  15.484 +<!-- &interaction.tour.status; -->
  15.485 +La commande <command role="hg-cmd">hg status</command> n'affiche rien sur la sortie pour quelques fichiers
  15.486 +mais une ligne commence par <quote><literal>M</literal></quote> for <filename>hello.c</filename>. À moins que
  15.487 +vous ne lui indiquiez de le faire, <command role="hg-cmd">hg status</command> n'affichera aucune sortie
  15.488 +pour les fichiers qui n'ont pas été modifiés.
  15.489 +</para>
  15.490 +
  15.491 +<para>Le caractère <quote><literal>M</literal></quote> indique que Mercurial a remarqué que nous avions
  15.492 +modifié le fichier <filename>hello.c</filename>. Nous n'avons pas besoin d'<emphasis>informer</emphasis>
  15.493 +Mercurial que nous allons modifier un fichier avant de le faire, ou que nous
  15.494 +venons de le modifier, il est capable de s'en rendre compte tout seul.
  15.495 +</para>
  15.496 +
  15.497 +<para>C'est pratique de savoir que nous avons modifié <filename>hello.c</filename>, mais il
  15.498 +serait encore plus pratique de savoir ce que nous avons modifié exactement. Pour
  15.499 +cela, nous avons la commande  <command role="hg-cmd">hg diff</command>.
  15.500 +</para>
  15.501 +
  15.502 +<para><!-- &interaction.tour.diff; -->
  15.503 +</para>
  15.504 +
  15.505 +</sect1>
  15.506 +<sect1>
  15.507 +<title>Enregister les modifications dans un nouveau \textit{changeset}</title>
  15.508 +
  15.509 +<para>Nous pouvons modifier des fichiers, compiler et tester nos modifications,
  15.510 +et utiliser les commandes <command role="hg-cmd">hg status</command> et <command role="hg-cmd">hg diff</command> pour voir les
  15.511 +modifications effectuées, jusqu'au moment où nous serons assez satisfaits
  15.512 +pour décider d'enregistrer notre travail dans un \textit{changeset}.
  15.513 +</para>
  15.514 +
  15.515 +<para>La commande <command role="hg-cmd">hg commit</command> vous laisse créer un nouveau \textit{changeset},
  15.516 +nous désignerons généralement cette opération par <quote>faire un commit</quote> ou
  15.517 +<quote>commiter</quote>\footnote{NdT: De mon expérience, la plupart des francophones
  15.518 +utilisent  régulièrement, à l'oral, cette expression, mais bien évidement
  15.519 +il ne s'agit pas d'un terme de terminologie correcte, ni même français.}
  15.520 +</para>
  15.521 +
  15.522 +<sect2>
  15.523 +<title>Définir le nom d'utilisateur</title>
  15.524 +
  15.525 +<para>Quand vous exécutez la commande <command role="hg-cmd">hg commit</command> pour la première fois, elle
  15.526 +n'est pas garantie de réussir. Mercurial enregistre votre nom et votre
  15.527 +adresse avec chaque modification que vous effectuez, de manière à ce que
  15.528 +vous soyez capable (ou d'autres le soient) de savoir qui a fait quelle
  15.529 +modification. Mercurial essaye automatiquement de découvrir un nom
  15.530 +d'utilisateur qui ait un minimum de sens pour effectuer l'opération
  15.531 +de \textit{commit} avec. Il va essayer chacune des méthodes suivantes,
  15.532 +dans l'ordre:
  15.533 +</para>
  15.534 +<orderedlist>
  15.535 +<listitem><para>Si vous spécifiez l'option <option role="hg-opt-commit">-u</option> avec la commande
  15.536 +  <command role="hg-cmd">hg commit</command>, suivi d'un nom d'utilisateur, ceci aura toujours la
  15.537 +  priorité sur les autres méthodes ci dessous.
  15.538 +</para>
  15.539 +</listitem>
  15.540 +<listitem><para>Si vous avez défini une variable d'environnement <envar>HGUSER</envar>,
  15.541 +  c'est cette valeur qui est alors utilisée.
  15.542 +</para>
  15.543 +</listitem>
  15.544 +<listitem><para>Si vous créez un fichier nommé <filename role="special">.hgrc</filename> dans votre
  15.545 +   répertoire \textit{home}, avec une entrée <envar role="rc-item-ui">username</envar>,
  15.546 +   c'est la valeur associée qui sera utilisée. Pour voir à quoi
  15.547 +   ressemble le contenu de ce fichier regardez la
  15.548 +   section <xref linkend="sec:tour-basic:username"/> ci-dessous.
  15.549 +</para>
  15.550 +</listitem>
  15.551 +<listitem><para>Si vous avez défini une variable d'environnement <envar>EMAIL</envar>
  15.552 +  celle ci sera utilisée ensuite.
  15.553 +</para>
  15.554 +</listitem>
  15.555 +<listitem><para>Enfin, Mercurial interrogera votre système pour trouver votre
  15.556 +  nom d'utilisateur local ainsi que le nom de la machine hôte, et il
  15.557 +  fabriquera un nom d'utilisateur à partir de ces données. Comme il arrive
  15.558 +  souvent que ce genre de noms soit totalement inutile, il vous
  15.559 +  préviendra en affichant un message d'avertissement.
  15.560 +</para>
  15.561 +</listitem></orderedlist>
  15.562 +
  15.563 +<para>Si tous ces mécanismes échouent, Mercurial n'exécutera pas la commande,
  15.564 +affichant un message d'erreur. Dans ce cas, il ne vous laissera pas
  15.565 +effectuer de \textit{commit} tant que vous n'aurez pas défini un nom
  15.566 +d'utilisateur.
  15.567 +</para>
  15.568 +
  15.569 +<para>Vous devriez penser à utiliser la variable d'environement <envar>HGUSER</envar>
  15.570 +et l'option <option role="hg-opt-commit">-u</option> comme moyen pour \emph{changer le nom
  15.571 +d'utilisateur} par défaut. Pour une utilisation normale, la manière la plus
  15.572 +simple et robuste d'opérer est de créer un fichier <filename role="special">.hgrc</filename>,
  15.573 +voir ci-dessous pour les détails à ce sujet.
  15.574 +</para>
  15.575 +
  15.576 +<sect3>
  15.577 +<title>Créer un fichier de configuration pour Mercurial</title>
  15.578 +<para>\label{sec:tour-basic:username}
  15.579 +</para>
  15.580 +
  15.581 +<para>Pour définir un nom d'utilisateur, utilisez votre éditeur de texte favori
  15.582 +pour créer un fichier <filename role="special">.hgrc</filename> dans votre répertoire \textit{home}.
  15.583 +Mercurial va utiliser ce fichier pour retrouver votre configuration personnelle.
  15.584 +Le contenu initial devrait ressembler à ceci:
  15.585 +</para>
  15.586 +<programlisting>
  15.587 +<para>  # This is a Mercurial configuration file.
  15.588 +  [ui]
  15.589 +  username = Firstname Lastname &lt;email.address@domain.net&gt;
  15.590 +</para>
  15.591 +</programlisting>
  15.592 +<para>La ligne avec <literal>[ui]</literal> commence une <emphasis>section</emphasis> du fichier de
  15.593 +configuration, ainsi la ligne <quote><literal>username = ...</literal></quote> signifie <quote>
  15.594 +définir la valeur de l'élément <literal>username</literal> dans la section
  15.595 +<literal>ui</literal></quote>. Une section continue jusqu'à ce qu'une nouvelle
  15.596 +commence, ou que la fin du fichier soit atteinte. Mercurial ignore
  15.597 +les lignes vides et traite tout texte situé à la suite d'un
  15.598 +<quote><literal>#</literal></quote> jusqu'à la fin de la ligne comme un commentaire.
  15.599 +</para>
  15.600 +
  15.601 +</sect3>
  15.602 +<sect3>
  15.603 +<title>Choisir un nom d'utilisateur</title>
  15.604 +
  15.605 +<para>Vous pouvez utiliser n'importe quelle valeur pour votre <literal>username</literal>,
  15.606 +car cette information est destinée à d'autres personnes et non à être
  15.607 +interprétée par Mercurial. La convention que la plupart des personnes
  15.608 +&lt;&lt;&lt;&lt;&lt;&lt;&lt; local
  15.609 +suivent est d'utiliser leurs noms suivies de leurs adresses emails,
  15.610 +comme montrée ci-dessus:
  15.611 +</para>
  15.612 +
  15.613 +<note>
  15.614 +<para>  Le mécanisme interne du serveur \textit{web} intégré à Mercurial,
  15.615 +  masque les adresses emails, pour rendre plus difficile leurs
  15.616 +  récupérations par les outils utilisés par les \textit{spammmers}.
  15.617 +  Ceci réduit la probabilité que de recevoir encore plus de
  15.618 +  \textit{spam} si vous vous publiez un dépôt sur internet.
  15.619 +</para>
  15.620 +</note>
  15.621 +
  15.622 +</sect3>
  15.623 +</sect2>
  15.624 +<sect2>
  15.625 +<title>Rédiger un message de \textit{commit}</title>
  15.626 +
  15.627 +<para>Lorsqu'on effectue une opération de \textit{commit}, Mercurial
  15.628 +lance automatiquement un éditeur de texte pour permettre de saisir
  15.629 +un message qui décrira les modifications effectuées dans ce
  15.630 +\textit{changeset}. Ce message est nommé le \emph{message de
  15.631 +\textit{commit}}. Ce sera un enregistrement pour tout lecteur
  15.632 +expliquant le pourquoi et le comment de vos modifications, et il sera
  15.633 +affiché par la commande <command role="hg-cmd">hg log</command>.
  15.634 +<!-- &interaction.tour.commit; -->
  15.635 +</para>
  15.636 +
  15.637 +<para>L'éditeur que la commande <command role="hg-cmd">hg commit</command> déclenche ne contiendra
  15.638 +qu'une ligne vide suivi d'un certain nombre de lignes commençant
  15.639 +par <quote><literal>HG:</literal></quote>.
  15.640 +</para>
  15.641 +<programlisting>
  15.642 +<para>  <emphasis>empty line</emphasis>
  15.643 +  HG: changed hello.c
  15.644 +</para>
  15.645 +</programlisting>
  15.646 +<para>Mercurial ignore les lignes qui commencent avec <quote><literal>HG:</literal></quote>, il
  15.647 +ne les utilise que pour nous indiquer quels fichiers modifiés il se
  15.648 +prépare à \textit{commiter}. Modifier ou effacer ces lignes n'a
  15.649 +aucune conséquence sur l'opération de \textit{commit}.
  15.650 +</para>
  15.651 +
  15.652 +</sect2>
  15.653 +<sect2>
  15.654 +<title>Rédiger un message \textit{approprié}</title>
  15.655 +
  15.656 +<para>Comme <command role="hg-cmd">hg log</command> n'affiche que la première ligne du message de
  15.657 +\textit{commit} par défaut, il est souvent considéré comme une bonne
  15.658 +pratique de rédiger des messages de \textit{commit} qui tiennent
  15.659 +sur une seule ligne. Voilà un exemple concret de message de
  15.660 +\textit{commit} qui <emphasis>ne suit pas</emphasis> cette directive, et qui a donc
  15.661 +un résumé peu lisible.
  15.662 +</para>
  15.663 +
  15.664 +<programlisting>
  15.665 +<para>  changeset:   73:584af0e231be
  15.666 +  user:        Censored Person &lt;censored.person@example.org&gt;
  15.667 +  date:        Tue Sep 26 21:37:07 2006 -0700
  15.668 +  summary:     include buildmeister/commondefs.   Add an exports and install
  15.669 +</para>
  15.670 +</programlisting>
  15.671 +
  15.672 +<para>A ce sujet, il faut noter qu'il n'existe pas de règle absolue dans ce
  15.673 +domaine. Mercurial lui-même n'interprète pas les contenus des messages
  15.674 +de \textit{commit}, ainsi votre projet est libre de concevoir différentes
  15.675 +politiques de mise en page des messages.
  15.676 +</para>
  15.677 +
  15.678 +<para>Ma préférence personnelle va au message court, mais informatif, qui offre
  15.679 +des précisions supplémentaires par rapport à ce que pourrait m'apprendre une commande
  15.680 +<command role="hg-cmd">hg log --patch</command>.
  15.681 +</para>
  15.682 +
  15.683 +</sect2>
  15.684 +<sect2>
  15.685 +<title>Annuler un \textit{commit}</title>
  15.686 +
  15.687 +<para>Si, en rédigeant le message, vous décidez que finalement vous ne
  15.688 +voulez pas effectuer ce \textit{commit}, il suffit de quitter simplement
  15.689 +l'éditeur sans sauver. Ceci n'aura aucune conséquence sur le dépôt ou
  15.690 +les fichiers de l'espace de travail.
  15.691 +</para>
  15.692 +
  15.693 +<para>Si vous exécuter la commande <command role="hg-cmd">hg commit</command> sans aucun argument, elle
  15.694 +enregistre toutes les modifications que vous avez faites, comme le montre
  15.695 +les commandes <command role="hg-cmd">hg status</command> et <command role="hg-cmd">hg diff</command>.
  15.696 +</para>
  15.697 +
  15.698 +</sect2>
  15.699 +<sect2>
  15.700 +<title>Admirer votre travail</title>
  15.701 +
  15.702 +<para>Une fois que votre \textit{commit} est terminé, vous pouvez utiliser
  15.703 +la commande <command role="hg-cmd">hg tip</command> pour afficher le \textit{changeset} que nous
  15.704 +venons de créer. Cette commande produit une sortie à l'écran qui est
  15.705 +identique à celle du <command role="hg-cmd">hg log</command>, mais qui n'affiche que la dernière
  15.706 +révision du dépôt.
  15.707 +<!-- &interaction.tour.tip; -->
  15.708 +On fait couramment référence à la dernière révision du dépôt comme
  15.709 +étant la révision \textit{tip}, ou plus simplement le \textit{tip}.
  15.710 +</para>
  15.711 +
  15.712 +</sect2>
  15.713 +</sect1>
  15.714 +<sect1>
  15.715 +<title>Partager ses modifications</title>
  15.716 +
  15.717 +<para>Nous avons mentionné plus haut que les dépôts de Mercurial
  15.718 +sont autosuffisants. Ce qui signifie que le \textit{changeset}
  15.719 +que vous venez de créer existe seulement dans votre répertoire
  15.720 +<filename class="directory">my-hello</filename>. Étudions comment propager cette modification
  15.721 +dans d'autres dépôts.
  15.722 +</para>
  15.723 +
  15.724 +<sect2>
  15.725 +<title>Récupérer les modifications d'autres dépôts</title>
  15.726 +<para>\label{sec:tour:pull}
  15.727 +</para>
  15.728 +
  15.729 +<para>Pour commencer, construisons un clone de notre dépôt <filename class="directory">hello</filename>
  15.730 +qui ne contiendra pas le changement que nous venons d'effectuer. Nous
  15.731 +l'appellerons notre dépôt temporaire <filename class="directory">hello-pull</filename>.
  15.732 +</para>
  15.733 +
  15.734 +<para><!-- &interaction.tour.clone-pull; -->
  15.735 +</para>
  15.736 +
  15.737 +<para>Nous allons utiliser la commande <command role="hg-cmd">hg pull</command> pour apporter les
  15.738 +modifications depuis <filename class="directory">my-hello</filename> dans <filename class="directory">hello-pull</filename>.
  15.739 +Néanmoins, récupérer aveuglement des modifications depuis un dépôt
  15.740 +a quelque chose d'un peu effrayant. Mercurial propose donc une
  15.741 +commande <command role="hg-cmd">hg incoming</command> qui permet de savoir quelles modifications
  15.742 +la commande <command role="hg-cmd">hg pull</command> <emphasis>pourrait</emphasis> entraîner dans notre dépôt,
  15.743 +et ceci sans effectuer réellement de modification dessus.
  15.744 +<!-- &interaction.tour.incoming; -->
  15.745 +(Bien évidement, quelqu'un pourrait ajouter des modifications
  15.746 +supplémentaires sur le dépôt que nous étudions avec <command role="hg-cmd">hg incoming</command>,
  15.747 +avant que nous ayons effectué notre <command role="hg-cmd">hg pull</command>, avec comme
  15.748 +triste conséquence que nous aurons récupéré des modifications que
  15.749 +nous n'attendions pas.)
  15.750 +</para>
  15.751 +
  15.752 +<para>Apporter les modifications rapatriées dans un dépôt se résume donc
  15.753 +à exécuter la commande <command role="hg-cmd">hg pull</command>, et préciser depuis quel dépôt
  15.754 +effectuer le <command role="hg-cmd">hg pull</command>.
  15.755 +<!-- &interaction.tour.pull; -->
  15.756 +</para>
  15.757 +
  15.758 +<para>Comme vous le voyez avec une sortie avant et après de la commande
  15.759 +<command role="hg-cmd">hg tip</command>, nous avons réussi à récupérer aisément les modifications
  15.760 +dans notre dépôt. Il reste néanmoins quelque chose à faire avant de
  15.761 +placer ces modifications dans l'espace de travail.
  15.762 +</para>
  15.763 +
  15.764 +</sect2>
  15.765 +<sect2>
  15.766 +<title>Mise à jour de l'espace de travail</title>
  15.767 +
  15.768 +<para>Nous avons jusqu'à maintenant grossièrement définie la relation
  15.769 +entre un dépôt et un espace de travail. La commande <command role="hg-cmd">hg pull</command> que
  15.770 +nous avons exécutée dans la section <xref linkend="sec:tour:pull"/> a apporté
  15.771 +des modifications, que nous avons vérifiées, dans notre dépôt, mais
  15.772 +il n'y a aucune trace de ces modifications dans notre espace de travail.
  15.773 +En effet, <command role="hg-cmd">hg pull</command> ne touche pas (par défaut) à l'espace de
  15.774 +travail. C'est la commande <command role="hg-cmd">hg update</command> qui s'en charge.
  15.775 +<!-- &interaction.tour.update; -->
  15.776 +</para>
  15.777 +
  15.778 +<para>Il peut sembler un peu étrange que la commande <command role="hg-cmd">hg pull</command> ne mette
  15.779 +pas à jour l'espace de travail automatiquement. Il y a en fait une
  15.780 +très bonne raison à cela : vous pouvez utilisez la commande
  15.781 +</para>
  15.782 +
  15.783 +<para><command role="hg-cmd">hg update</command> pour mettre à jour votre espace de travail à l'état
  15.784 +dans lequel il était à <emphasis>n'importe quelle révision</emphasis> de l'historique
  15.785 +du dépôt. Si vous aviez un espace de travail contenant une ancienne
  15.786 +révision&emdash;pour chercher l'origine d'un \textit{bug}, par exemple&emdash;et
  15.787 +que vous effectuiez un <command role="hg-cmd">hg pull</command> qui mettrait à jour automatiquement
  15.788 +votre espace de travail, vous ne seriez probablement pas très satisfait.
  15.789 +</para>
  15.790 +
  15.791 +<para>Néanmoins, comme les opérations de \textit{pull} sont très souvent
  15.792 +suivies d'un \textit{update}, Mercurial vous permet de combiner les
  15.793 +deux aisément en passant l'option <option role="hg-opt-pull">-u</option> à la commande
  15.794 +<command role="hg-cmd">hg pull</command>
  15.795 +</para>
  15.796 +<programlisting>
  15.797 +<para>  hg pull -u
  15.798 +</para>
  15.799 +</programlisting>
  15.800 +
  15.801 +<para>Si vous étudiez de nouveau la sortie de la commande <command role="hg-cmd">hg pull</command> dans
  15.802 +la section <xref linkend="sec:tour:pull"/> quand nous l'avons exécutée sans l'option
  15.803 +<option role="hg-opt-pull">-u</option>, vous pouvez constater qu'elle a affiché un rappel assez
  15.804 +utile : vous devez encore effectuer une opération pour mettre à jour
  15.805 +votre espace de travail:
  15.806 +</para>
  15.807 +
  15.808 +<programlisting>
  15.809 +<para>  (run 'hg update' to get a working copy)
  15.810 +</para>
  15.811 +</programlisting>
  15.812 +
  15.813 +<para>Pour découvrir sur quelle révision de l'espace de travail on est, utilisez
  15.814 +la commande <command role="hg-cmd">hg parents</command>.
  15.815 +<!-- &interaction.tour.parents; -->
  15.816 +Si vous regardez de nouveau le dessin <xref linkend="fig:tour-basic:history"/>, vous
  15.817 +&lt;&lt;&lt;&lt;&lt;&lt;&lt; local
  15.818 +verrez les flèches reliant entre eux les \textit{changeset}. Le nœud
  15.819 +d'où la flèche <emphasis>part</emphasis> est dans chaque cas un parent,
  15.820 +et le nœud où la flèche <emphasis>arrive</emphasis> est un enfant.
  15.821 +</para>
  15.822 +
  15.823 +<para>L'espace de travail a un parent de la même manière, c'est ce \textit{changeset}
  15.824 +que l'espace de travail contient à ce moment.
  15.825 +%%%TODO : difficile à comprendre : l'espace de travail a un parent, de la même manière, c'est ce changeset que l'espace...
  15.826 +</para>
  15.827 +
  15.828 +<para>Pour mettre à jour l'espace de travail d'une révision particulière,
  15.829 +indiquez un numéro de révision ou un \textit{changeset ID} à la commande
  15.830 +<command role="hg-cmd">hg update</command>.
  15.831 +<!-- &interaction.tour.older; -->
  15.832 +Si vous ne précisez pas de manière explicite de numéro de révision
  15.833 +la commande <command role="hg-cmd">hg update</command> mettra à jour votre espace de travail avec
  15.834 +le contenu de la révsion \textit{tip}, comme montré dans l'exemple
  15.835 +ci dessus lors du second appel à <command role="hg-cmd">hg update</command>.
  15.836 +</para>
  15.837 +
  15.838 +</sect2>
  15.839 +<sect2>
  15.840 +<title>Transférer les modifications à un autre dépôt</title>
  15.841 +
  15.842 +<para>Mercurial vous laisse transférer les modifications à un autre
  15.843 +dépôt, depuis votre dépôt actuel. Comme dans l'exemple du
  15.844 +<command role="hg-cmd">hg pull</command> ci-dessus, nous allons créer un dépôt temporaire
  15.845 +vers lequel transférer\footnote{NdT: Les francophones disent souvent
  15.846 +<quote>pousser</quote> tout simplement} nos modifications.
  15.847 +<!-- &interaction.tour.clone-push; -->
  15.848 +La commande <command role="hg-cmd">hg outgoing</command> nous indique quels changements nous
  15.849 +allons transférer vers l'autre serveur ?
  15.850 +<!-- &interaction.tour.outgoing; -->
  15.851 +Et la commande <command role="hg-cmd">hg push</command> effectue réellement le transfert.
  15.852 +<!-- &interaction.tour.push; -->
  15.853 +Comme avec <command role="hg-cmd">hg pull</command>, la commande <command role="hg-cmd">hg push</command> ne met pas à jour
  15.854 +le répertoire de travail du dépôt dans lequel il transfère les
  15.855 +modifications. (À l'inverse de <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg push</command> ne fournit
  15.856 +pas d'option <literal>-u</literal> pour forcer la mise à jour de l'espace
  15.857 +de travail cible).
  15.858 +</para>
  15.859 +
  15.860 +<para>Qu'est ce qui se passe lorsque vous essayez de récupérer ou de transférer
  15.861 +vos modifications et que le dépôt cible a déjà reçu ces modifications ?
  15.862 +Rien de bien excitant.
  15.863 +<!-- &interaction.tour.push.nothing; -->
  15.864 +</para>
  15.865 +
  15.866 +</sect2>
  15.867 +<sect2>
  15.868 +<title>Partager ses modifications à travers le réseau</title>
  15.869 +
  15.870 +<para>Les commandes que nous avons étudiées dans les sections précédentes
  15.871 +ne sont pas limitées aux dépôt locaux. Chacune fonctionne de la même
  15.872 +manière à travers une connexion réseau, il suffit de lui passer une
  15.873 +URL à la place d'un chemin de fichier local.
  15.874 +</para>
  15.875 +
  15.876 +<para><!-- &interaction.tour.outgoing.net; -->
  15.877 +Dans cet exemple, nous allons voir quels changements nous pourrions
  15.878 +transférer vers le dépôt distant, mais le dépôt est, de manière tout
  15.879 +à fait compréhensible, pas configuré pour accepter des modifications
  15.880 +d'utilisateurs anonymes.
  15.881 +<!-- &interaction.tour.push.net; -->
  15.882 +</para>
  15.883 +
  15.884 +</sect2>
  15.885 +</sect1>
  15.886 +</chapter>
  15.887 +
  15.888 +<!--
  15.889 +local variables: 
  15.890 +sgml-parent-document: ("00book.xml" "book" "chapter")
  15.891 +end:
  15.892 +-->
  15.893 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/fr/ch03-tour-merge.xml	Sun Aug 16 04:58:01 2009 +0200
    16.3 @@ -0,0 +1,384 @@
    16.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    16.5 +
    16.6 +<chapter>
    16.7 +<title>Un rapide tour de Mercurial: fusionner les travaux</title>
    16.8 +<para>\label{chap:tour-merge}</para>
    16.9 +
   16.10 +<para>Nous avons maintenant étudié comment cloner un dépôt, effectuer
   16.11 +des changements dedans, et récupérer ou transférer depuis un
   16.12 +autre dépôt. La prochaine étape est donc de <emphasis>fusionner</emphasis> les
   16.13 +modifications de différents dépôts.</para>
   16.14 +
   16.15 +<sect1>
   16.16 +<title>Fusionner différents travaux</title>
   16.17 +<para>				       %%% for 'Merging streams of work' ?
   16.18 +La fusion\footnote{NdT: Je garde fusion mais le jargon professionnel
   16.19 +emploiera généralement le terme \textit{merge}.} est un aspect
   16.20 +fondamental lorsqu'on travaille avec un gestionnaire de source
   16.21 +distribué.</para>
   16.22 +<itemizedlist>
   16.23 +<listitem><para>Alice et Bob ont chacun une copie personnelle du dépôt d'un
   16.24 +  projet sur lequel ils collaborent. Alice corrige un \textit{bug}
   16.25 +  dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
   16.26 +  sien. Ils veulent un dépôt partagé avec à la fois le correctif du
   16.27 +  \textit{bug} et la nouvelle fonctionnalité.</para>
   16.28 +</listitem>
   16.29 +<listitem><para>Je travaille régulièrement sur plusieurs tâches différentes sur
   16.30 +  un seul projet en même temps, chacun isolé dans son propre dépôt.
   16.31 +  Travailler ainsi signifie que je dois régulièrement fusionner une
   16.32 +  partie de mon code avec celui des autres.</para>
   16.33 +</listitem></itemizedlist>
   16.34 +
   16.35 +<para>Parce que la fusion est une opération si commune à réaliser,
   16.36 +Mercurial la rend facile. Étudions ensemble le déroulement des opérations.
   16.37 +Nous commencerons encore par faire un clone d'un autre dépôt (vous voyez
   16.38 +que l'on fait ça tout le temps ?) puis nous ferons quelques modifications
   16.39 +dessus.
   16.40 +<!-- &interaction.tour.merge.clone; -->
   16.41 +Nous devrions avoir maintenant deux copies de <filename>hello.c</filename> avec
   16.42 +des contenus différents. Les historiques de ces deux dépôts ont aussi
   16.43 +divergés, comme illustré dans la figure <xref linkend="fig:tour-merge:sep-repos"/>.</para>
   16.44 +
   16.45 +<para><!-- &interaction.tour.merge.cat; --></para>
   16.46 +
   16.47 +<informalfigure>
   16.48 +
   16.49 +<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-sep-repos"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   16.50 +  <caption><para>Historiques récent divergents des dépôts \dirname{my-hello</para></caption>
   16.51 +  et <filename class="directory">my-new-hello</filename>}
   16.52 +  \label{fig:tour-merge:sep-repos}</para>
   16.53 +</informalfigure>
   16.54 +
   16.55 +<para>Nous savons déjà que récupérer les modifications depuis notre dépôt
   16.56 +<filename class="directory">my-hello</filename> n'aura aucun effet sur l'espace de travail.
   16.57 +</para>
   16.58 +
   16.59 +<para><!-- &interaction.tour.merge.pull; -->
   16.60 +</para>
   16.61 +
   16.62 +<para>Néanmoins, la commande <command role="hg-cmd">hg pull</command> nous indique quelque chose au
   16.63 +sujet des <quote>heads</quote>.
   16.64 +</para>
   16.65 +
   16.66 +<sect2>
   16.67 +<title>\textit{Head changesets}</title>
   16.68 +
   16.69 +<para>Une \textit{head}\footnote{NdT: Je garde \textit{head} que j'accorde
   16.70 +au féminin comme la coutume orale l'a imposé.} est un \textit{changeset}
   16.71 +sans descendants, ou enfants, comme on les désigne parfois. La révision
   16.72 +\textit{tip} est une \textit{head}, car la dernière révision dans un dépôt
   16.73 +n'a aucun enfant, mais il est important de noter qu'un dépôt peut contenir
   16.74 +plus d'une \textit{head}.
   16.75 +</para>
   16.76 +
   16.77 +<informalfigure>
   16.78 +
   16.79 +<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-pull"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   16.80 +  \caption{Contenu d'un dépôt après avoir transféré le contenu du dépôt
   16.81 +    <filename class="directory">my-hello</filename> dans le dépôt <filename class="directory">my-new-hello</filename>}
   16.82 +  \label{fig:tour-merge:pull}
   16.83 +</para>
   16.84 +</informalfigure>
   16.85 +
   16.86 +<para>Dans la figure <xref linkend="fig:tour-merge:pull"/>, vous pouvez constater l'effet
   16.87 +d'un \textit{pull} depuis le dépôt <filename class="directory">my-hello</filename> dans le dépôt
   16.88 +<filename class="directory">my-new-hello</filename>. L'historique qui était déjà présent dans le dépôt
   16.89 +<filename class="directory">my-new-hello</filename> reste intact, mais une nouvelle révision a été
   16.90 +ajoutée. En vous reportant à la figure <xref linkend="fig:tour-merge:sep-repos"/>,
   16.91 +vous pouvez voir que le \textit{<emphasis>changeset ID</emphasis>} reste le même dans
   16.92 +le nouveau dépôt, mais que le <emphasis>numéro de révision</emphasis> reste le même.
   16.93 +(Ceci est un parfait exemple de pourquoi il n'est fiable d'utiliser les
   16.94 +numéros de révision lorsque l'on discute d'un \textit{changeset}.) Vous
   16.95 +pouvez voir les \texit{heads} présentes dans le dépôt en utilisant la
   16.96 +commande <command role="hg-cmd">hg heads</command>.
   16.97 +<!-- &interaction.tour.merge.heads; -->
   16.98 +</para>
   16.99 +
  16.100 +</sect2>
  16.101 +<sect2>
  16.102 +<title>Effectuer la fusion</title>
  16.103 +
  16.104 +<para>Que se passe-t-il quand vous essayez d'utiliser la commande <command role="hg-cmd">hg update</command>
  16.105 +pour mettre à jour votre espace de travail au nouveau \textit{tip}.
  16.106 +<!-- &interaction.tour.merge.update; -->
  16.107 +Mercurial nous prévient que la commande <command role="hg-cmd">hg update</command> n'effectuera pas
  16.108 +la fusion, il ne veut pas mettre à jour l'espace de travail quand il
  16.109 +estime que nous pourrions avoir besoin d'une fusion, à moins de lui
  16.110 +forcer la main. À la place, il faut utiliser la commande <command role="hg-cmd">hg merge</command>
  16.111 +pour fusionner les deux \textit{heads}.
  16.112 +<!-- &interaction.tour.merge.merge; -->
  16.113 +</para>
  16.114 +
  16.115 +<informalfigure>
  16.116 +
  16.117 +<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-merge"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  16.118 +  \caption{Espace de travail et dépôt lors d'une fusion, et dans le
  16.119 +    \textit{commit} qui suit.}
  16.120 +  \label{fig:tour-merge:merge}
  16.121 +</para>
  16.122 +</informalfigure>
  16.123 +
  16.124 +<para>Ceci met à jour l'espace de travail de manière à ce qu'il contienne
  16.125 +les modifications des <emphasis>deux</emphasis> \textit{heads}, ce qui apparaît dans
  16.126 +les sorties de la commande <command role="hg-cmd">hg parents</command> et le contenu de
  16.127 +<filename>hello.c</filename>.
  16.128 +<!-- &interaction.tour.merge.parents; -->
  16.129 +</para>
  16.130 +
  16.131 +</sect2>
  16.132 +<sect2>
  16.133 +<title>Effectuer le \textit{commit} du résultat de la fusion</title>
  16.134 +
  16.135 +<para>Dès l'instant où vous avez effectué une fusion, <command role="hg-cmd">hg parents</command> vous
  16.136 +affichera deux parents, avant que vous n'exécutiez la commande
  16.137 +<command role="hg-cmd">hg commit</command> sur le résultat de la fusion.
  16.138 +<!-- &interaction.tour.merge.commit; -->
  16.139 +Nous avons maintenant un nouveau \textit{tip}, remarquer qu'il contient
  16.140 +<emphasis>à la fois</emphasis> nos anciennes \textit{heads} et leurs parents. Ce sont
  16.141 +les mêmes révisions que nous avions affichées avec la commande
  16.142 +<command role="hg-cmd">hg parents</command>.
  16.143 +</para>
  16.144 +
  16.145 +<para><!-- &interaction.tour.merge.tip; -->
  16.146 +Dans la figure <xref linkend="fig:tour-merge:merge"/>, vous pouvez voir une représentation
  16.147 +de ce qui se passe dans l'espace de travail pendant la fusion, et comment ceci
  16.148 +affecte le dépôt lors du \textit{commit}. Pendant la fusion, l'espace de travail,
  16.149 +qui a deux \texit{changesets} comme parents, voit ces derniers devenir le parent
  16.150 +%%% TODO: le parent ou "les parents" : plus logique mais si il reste seulement
  16.151 +%%% un changeset, alors c'est effectivement un parent (le changeset est hermaphrodite)
  16.152 +d'un nouveau \textit{changeset}.
  16.153 +</para>
  16.154 +
  16.155 +</sect2>
  16.156 +</sect1>
  16.157 +<sect1>
  16.158 +<title>Fusionner les modifications en conflit</title>
  16.159 +
  16.160 +<para>La plupart des fusions sont assez simple à réaliser, mais parfois
  16.161 +vous vous retrouverez à fusionner des fichiers où la modification touche
  16.162 +la même portion de code, au sein d'un même fichier. À moins que ces
  16.163 +modification ne soient identiques, ceci aboutira à un <emphasis>conflit</emphasis>,
  16.164 +et vous devrez décider comment réconcilier les différentes modifications
  16.165 +dans un tout cohérent.
  16.166 +</para>
  16.167 +
  16.168 +<informalfigure>
  16.169 +
  16.170 +<para>  <mediaobject><imageobject><imagedata fileref="tour-merge-conflict"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  16.171 +  <caption><para>Modifications conflictuelles dans un document</para></caption>
  16.172 +  \label{fig:tour-merge:conflict}
  16.173 +</para>
  16.174 +</informalfigure>
  16.175 +
  16.176 +<para>La figure <xref linkend="fig:tour-merge:conflict"/> illustre un cas de modifications
  16.177 +conflictuelles dans un document. Nous avons commencé avec une version simple
  16.178 +de ce fichier, puis nous avons ajouté des modifications, pendant que
  16.179 +quelqu'un d'autre modifiait le même texte. Notre tâche dans la résolution
  16.180 +du conflit est de décider à quoi le fichier devrait ressembler.
  16.181 +</para>
  16.182 +
  16.183 +<para>Mercurial n'a pas de mécanisme interne pour gérer les conflits.
  16.184 +À la place, il exécute un programme externe appelé <command>hgmerge</command>.
  16.185 +Il s'agit d'un script shell qui est embarqué par Mercurial, vous
  16.186 +pouvez le modifier si vous le voulez. Ce qu'il fait par défaut est
  16.187 +d'essayer de trouver un des différents outils de fusion qui seront
  16.188 +probablement installés sur le système. Il commence par les outils
  16.189 +totalement automatiques, et si ils échouent (parce que la résolution
  16.190 +du conflit nécessite une intervention humaine) ou si ils sont absents,
  16.191 +le script tente d'exécuter certains outils graphiques de fusion.
  16.192 +</para>
  16.193 +
  16.194 +<para>Il est aussi possible de demander à Mercurial d'exécuter un autre
  16.195 +programme ou un autre script au lieu de la commande <command>hgmerge</command>,
  16.196 +en définissant la variable d'environnement <envar>HGMERGE</envar> avec le nom
  16.197 +du programme de votre choix.
  16.198 +</para>
  16.199 +
  16.200 +<sect2>
  16.201 +<title>Utiliser un outil graphique de fusion</title>
  16.202 +
  16.203 +<para>Mon outil de fusion préféré est <command>kdiff3</command>, que j'utilise ici
  16.204 +pour illustrer les fonctionnalités classiques des outils graphiques
  16.205 +de fusion. Vous pouvez voir une capture d'écran de l'utilisation de
  16.206 +<command>kdiff3</command> dans la figure <xref linkend="fig:tour-merge:kdiff3"/>. Cet outil
  16.207 +effectue une <emphasis>fusion \textit{three-way</emphasis>}, car il y a trois différentes
  16.208 +versions du fichier qui nous intéresse. Le fichier découpe la partie
  16.209 +supérieure de la fenêtre en trois panneaux:
  16.210 +</para>
  16.211 +
  16.212 +<itemizedlist>
  16.213 +<listitem><para>A gauche on la version de <emphasis>base</emphasis> du fichier, soit la plus
  16.214 +  récente version des deux versions qu'on souhaite fusionner.
  16.215 +</para>
  16.216 +</listitem>
  16.217 +<listitem><para>Au centre, il y a <quote>notre</quote> version du fichier, avec le contenu
  16.218 +  que nous avons modifié.
  16.219 +</para>
  16.220 +</listitem>
  16.221 +<listitem><para>Sur la droite, on trouve <quote>leur</quote> version du fichier, celui qui
  16.222 +  contient le \textit{changeset} que nous souhaitons intégré.
  16.223 +</para>
  16.224 +</listitem></itemizedlist>
  16.225 +
  16.226 +<para>Dans le panneau en dessous, on trouve le <emphasis>résultat</emphasis> actuel de notre
  16.227 +fusion. Notre tâche consiste donc à remplacement tous les textes en rouges,
  16.228 +qui indiquent des conflits non résolus, avec une fusion manuelle et pertinente
  16.229 +de <quote>notre</quote> version et de la <quote>leur</quote>.
  16.230 +</para>
  16.231 +
  16.232 +<para>Tous les quatre panneaux sont <emphasis>accrochés ensemble</emphasis>, si nous déroulons
  16.233 +les ascenseurs verticalement ou horizontalement dans chacun d'entre eux, les
  16.234 +autres sont mis à jour avec la section correspondante dans leurs fichiers
  16.235 +respectifs.
  16.236 +</para>
  16.237 +
  16.238 +<informalfigure>
  16.239 +
  16.240 +<para>  <mediaobject><imageobject><imagedata fileref="kdiff3"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  16.241 +  <caption><para>Utilisation de \command{kdiff3</para></caption> pour fusionner différentes versions
  16.242 +  d'un fichier.}
  16.243 +  \label{fig:tour-merge:kdiff3}
  16.244 +</para>
  16.245 +</informalfigure>
  16.246 +
  16.247 +<para>Pour chaque portion de fichier posant problème, nous pouvons choisir
  16.248 +de résoudre le conflit en utilisant une combinaison
  16.249 +de texte depuis la version de base, la notre, ou la leur. Nous pouvons
  16.250 +aussi éditer manuellement les fichiers à tout moment, si c'est
  16.251 +nécessaire.
  16.252 +</para>
  16.253 +
  16.254 +<para>Il y a <emphasis>beaucoup</emphasis> d'outils de fusion disponibles, bien trop pour
  16.255 +en parler de tous ici. Leurs disponibilités varient selon les plate formes
  16.256 +ainsi que leurs avantages et inconvénients. La plupart sont optimisé pour
  16.257 +la fusion de fichier contenant un texte plat, certains sont spécialisé
  16.258 +dans un format de fichier précis (généralement XML).
  16.259 +</para>
  16.260 +
  16.261 +</sect2>
  16.262 +<sect2>
  16.263 +<title>Un exemple concret</title>
  16.264 +
  16.265 +<para>Dans cet exemple, nous allons reproduire la modification de l'historique
  16.266 +du fichier de la figure <xref linkend="fig:tour-merge:conflict"/> ci dessus. Commençons
  16.267 +par créer un dépôt avec une version de base de notre document.
  16.268 +</para>
  16.269 +
  16.270 +<para><!-- &interaction.tour-merge-conflict.wife; -->
  16.271 +Créons un clone de ce dépôt et faisons une modification dans le fichier.
  16.272 +<!-- &interaction.tour-merge-conflict.cousin; -->
  16.273 +Et un autre clone, pour simuler que quelqu'un d'autre effectue une
  16.274 +modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
  16.275 +de devoir effectuer des \textit{merge} avec vos propres travaux quand
  16.276 +vous isolez les tâches dans des dépôts distincts. En effet, vous
  16.277 +aurez alors à trouver et résoudre certains conflits).
  16.278 +<!-- &interaction.tour-merge-conflict.son; -->
  16.279 +Maintenant que ces deux versions différentes du même fichier sont
  16.280 +créées, nous allons configurer l'environnement de manière appropriée pour
  16.281 +exécuter notre \textit{merge}.
  16.282 +<!-- &interaction.tour-merge-conflict.pull; -->
  16.283 +</para>
  16.284 +
  16.285 +<para>Dans cette exemple, je n'utiliserais pas la commande Mercurial
  16.286 +habituelle <command>hgmerge</command> pour effectuer le \textit{merge},
  16.287 +car il me faudrait abandonner ce joli petit exemple automatisé
  16.288 +pour utiliser un outil graphique. À la place, je vais définir
  16.289 +la variable d'environnement <envar>HGMERGE</envar> pour indiquer à
  16.290 +Mercurial d'utiliser la commande non-interactive <command>merge</command>.
  16.291 +Cette dernière est embarquée par de nombreux systèmes <quote>à la Unix</quote>.
  16.292 +Si vous exécutez cet exemple depuis votre ordinateur, ne vous
  16.293 +occupez pas de définir <envar>HGMERGE</envar>.
  16.294 +<!-- &interaction.tour-merge-conflict.merge; -->
  16.295 +Parce que <command>merge</command> ne peut pas résoudre les modifications
  16.296 +conflictuelles, il laisse des <emphasis>marqueurs de différences</emphasis>
  16.297 +\footnote{NdT: Oui, je traduis \textit{merge markers} par un sens
  16.298 +inverse en Français, mais je pense vraiment que c'est plus clair
  16.299 +comme ça...} à l'intérieur du fichier qui a des conflits, indiquant
  16.300 +clairement quelles lignes sont en conflits, et si elles viennent de
  16.301 +notre fichier ou du fichier externe.
  16.302 +</para>
  16.303 +
  16.304 +<para>Mercurial peut distinguer, à la manière dont la commande <command>merge</command>
  16.305 +se termine, qu'elle n'a pas été capable d'effectuer le \textit{merge},
  16.306 +alors il nous indique que nous devons effectuer de nouveau cette
  16.307 +opération. Ceci peut être très utile si, par exemple, nous exécutons un
  16.308 +outil graphique de fusion et que nous le quittons sans nous rendre compte
  16.309 +qu'il reste des conflits ou simplement par erreur.
  16.310 +</para>
  16.311 +
  16.312 +<para>Si le \textit{merge} automatique ou manuel échoue, il n'y a rien pour
  16.313 +nous empêcher de <quote>corriger le tir</quote> en modifiant nous même les fichiers,
  16.314 +et enfin effectuer le \textit{commit} du fichier:
  16.315 +<!-- &interaction.tour-merge-conflict.commit; -->
  16.316 +</para>
  16.317 +
  16.318 +</sect2>
  16.319 +</sect1>
  16.320 +<sect1>
  16.321 +<title>Simplification de la séquence pull-merge-commit</title>
  16.322 +<para>\label{sec:tour-merge:fetch}
  16.323 +</para>
  16.324 +
  16.325 +<para>La procédure pour effectuer la fusion indiquée ci-dessus est simple,
  16.326 +mais requiert le lancement de trois commandes à la suite.
  16.327 +</para>
  16.328 +<programlisting>
  16.329 +<para>  hg pull
  16.330 +  hg merge
  16.331 +  hg commit -m 'Merged remote changes'
  16.332 +</para>
  16.333 +</programlisting>
  16.334 +
  16.335 +<para>Lors du \textit{commit} final, vous devez également saisir un message,
  16.336 +qui aura vraisemblablement assez peu d'intérêt.
  16.337 +</para>
  16.338 +
  16.339 +<para>Il serait assez sympathique de pouvoir réduire le nombre d'opérations
  16.340 +nécessaire, si possible. De fait Mercurial est fourni avec une
  16.341 +extension appelé <literal role="hg-ext">fetch</literal> qui fait justement cela.
  16.342 +</para>
  16.343 +
  16.344 +<para>Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
  16.345 +d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
  16.346 +léger et facile à utiliser. Certains extensions ajoutent de nouvelles
  16.347 +commandes que vous pouvez utiliser en ligne de commande, alors que
  16.348 +d'autres travaillent <quote>en coulisse,</quote> par exemple en ajoutant des
  16.349 +possibilités au serveur.
  16.350 +</para>
  16.351 +
  16.352 +<para>L'extension <literal role="hg-ext">fetch</literal> ajoute une nouvelle commande nommée, sans
  16.353 +surprise, <command role="hg-cmd">hg fetch</command>. Cette extension résulte en une combinaison
  16.354 +de <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg update</command> and <command role="hg-cmd">hg merge</command>. Elle commence par
  16.355 +récupérer les modifications d'un autre dépôt dans le dépôt courant.
  16.356 +Si elle trouve que les modifications ajoutent une nouvelle \textit{head},
  16.357 +elle effectue un \textit{merge}, et ensuite \texit{commit} le résultat
  16.358 +du \textit{merge} avec un message généré automatiquement. Si aucune
  16.359 +\textit{head} n'ont été ajouté, elle met à jour le répertoire de travail
  16.360 +au niveau du nouveau \textit{changeset} \textit{tip}.
  16.361 +</para>
  16.362 +
  16.363 +
  16.364 +<para>Activer l'extension <literal role="hg-ext">fetch</literal> est facile. Modifiez votre <filename role="special">.hgrc</filename>,
  16.365 +et soit allez à la section <literal role="rc-extensions">extensions</literal> soit créer une
  16.366 +section <literal role="rc-extensions">extensions</literal>. Ensuite ajoutez une ligne qui consiste
  16.367 +simplement en <quote>\Verb+fetch =</quote>.
  16.368 +</para>
  16.369 +
  16.370 +<programlisting>
  16.371 +<para>  [extensions]
  16.372 +  fetch =
  16.373 +</para>
  16.374 +</programlisting>
  16.375 +<para>(Normalement, sur la partie droite de <quote><literal>=</literal></quote> devrait apparaître
  16.376 +le chemin de l'extension, mais étant donné que l'extension <literal role="hg-ext">fetch</literal>
  16.377 +fait partie de la distribution standard, Mercurial sait où la trouver.)
  16.378 +</para>
  16.379 +
  16.380 +</sect1>
  16.381 +</chapter>
  16.382 +
  16.383 +<!--
  16.384 +local variables: 
  16.385 +sgml-parent-document: ("00book.xml" "book" "chapter")
  16.386 +end:
  16.387 +-->
  16.388 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/fr/ch04-concepts.xml	Sun Aug 16 04:58:01 2009 +0200
    17.3 @@ -0,0 +1,710 @@
    17.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    17.5 +
    17.6 +<chapter>
    17.7 +<title>Behind the scenes</title>
    17.8 +<para>\label{chap:concepts}</para>
    17.9 +
   17.10 +<para>Unlike many revision control systems, the concepts upon which
   17.11 +Mercurial is built are simple enough that it's easy to understand how
   17.12 +the software really works.  Knowing this certainly isn't necessary,
   17.13 +but I find it useful to have a <quote>mental model</quote> of what's going on.</para>
   17.14 +
   17.15 +<para>This understanding gives me confidence that Mercurial has been
   17.16 +carefully designed to be both <emphasis>safe</emphasis> and <emphasis>efficient</emphasis>.  And
   17.17 +just as importantly, if it's easy for me to retain a good idea of what
   17.18 +the software is doing when I perform a revision control task, I'm less
   17.19 +likely to be surprised by its behaviour.</para>
   17.20 +
   17.21 +<para>In this chapter, we'll initially cover the core concepts behind
   17.22 +Mercurial's design, then continue to discuss some of the interesting
   17.23 +details of its implementation.</para>
   17.24 +
   17.25 +<sect1>
   17.26 +<title>Mercurial's historical record</title>
   17.27 +
   17.28 +<sect2>
   17.29 +<title>Tracking the history of a single file</title>
   17.30 +
   17.31 +<para>When Mercurial tracks modifications to a file, it stores the history
   17.32 +of that file in a metadata object called a <emphasis>filelog</emphasis>.  Each entry
   17.33 +in the filelog contains enough information to reconstruct one revision
   17.34 +of the file that is being tracked.  Filelogs are stored as files in
   17.35 +the <filename role="special" class="directory">.hg/store/data</filename> directory.  A filelog contains two kinds
   17.36 +of information: revision data, and an index to help Mercurial to find
   17.37 +a revision efficiently.</para>
   17.38 +
   17.39 +<para>A file that is large, or has a lot of history, has its filelog stored
   17.40 +in separate data (<quote><literal>.d</literal></quote> suffix) and index (<quote><literal>.i</literal></quote>
   17.41 +suffix) files.  For small files without much history, the revision
   17.42 +data and index are combined in a single <quote><literal>.i</literal></quote> file.  The
   17.43 +correspondence between a file in the working directory and the filelog
   17.44 +that tracks its history in the repository is illustrated in
   17.45 +figure <xref linkend="fig:concepts:filelog"/>.</para>
   17.46 +
   17.47 +<informalfigure>
   17.48 +
   17.49 +<para>  <mediaobject><imageobject><imagedata fileref="filelog"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   17.50 +  \caption{Relationships between files in working directory and
   17.51 +    filelogs in repository}
   17.52 +  \label{fig:concepts:filelog}</para>
   17.53 +</informalfigure>
   17.54 +
   17.55 +</sect2>
   17.56 +<sect2>
   17.57 +<title>Managing tracked files</title>
   17.58 +
   17.59 +<para>Mercurial uses a structure called a <emphasis>manifest</emphasis> to collect
   17.60 +together information about the files that it tracks.  Each entry in
   17.61 +the manifest contains information about the files present in a single
   17.62 +changeset.  An entry records which files are present in the changeset,
   17.63 +the revision of each file, and a few other pieces of file metadata.</para>
   17.64 +
   17.65 +</sect2>
   17.66 +<sect2>
   17.67 +<title>Recording changeset information</title>
   17.68 +
   17.69 +<para>The <emphasis>changelog</emphasis> contains information about each changeset.  Each
   17.70 +revision records who committed a change, the changeset comment, other
   17.71 +pieces of changeset-related information, and the revision of the
   17.72 +manifest to use.
   17.73 +</para>
   17.74 +
   17.75 +</sect2>
   17.76 +<sect2>
   17.77 +<title>Relationships between revisions</title>
   17.78 +
   17.79 +<para>Within a changelog, a manifest, or a filelog, each revision stores a
   17.80 +pointer to its immediate parent (or to its two parents, if it's a
   17.81 +merge revision).  As I mentioned above, there are also relationships
   17.82 +between revisions <emphasis>across</emphasis> these structures, and they are
   17.83 +hierarchical in nature.
   17.84 +</para>
   17.85 +
   17.86 +<para>For every changeset in a repository, there is exactly one revision
   17.87 +stored in the changelog.  Each revision of the changelog contains a
   17.88 +pointer to a single revision of the manifest.  A revision of the
   17.89 +manifest stores a pointer to a single revision of each filelog tracked
   17.90 +when that changeset was created.  These relationships are illustrated
   17.91 +in figure <xref linkend="fig:concepts:metadata"/>.
   17.92 +</para>
   17.93 +
   17.94 +<informalfigure>
   17.95 +
   17.96 +<para>  <mediaobject><imageobject><imagedata fileref="metadata"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
   17.97 +  <caption><para>Metadata relationships</para></caption>
   17.98 +  \label{fig:concepts:metadata}
   17.99 +</para>
  17.100 +</informalfigure>
  17.101 +
  17.102 +<para>As the illustration shows, there is <emphasis>not</emphasis> a <quote>one to one</quote>
  17.103 +relationship between revisions in the changelog, manifest, or filelog.
  17.104 +If the manifest hasn't changed between two changesets, the changelog
  17.105 +entries for those changesets will point to the same revision of the
  17.106 +manifest.  If a file that Mercurial tracks hasn't changed between two
  17.107 +changesets, the entry for that file in the two revisions of the
  17.108 +manifest will point to the same revision of its filelog.
  17.109 +</para>
  17.110 +
  17.111 +</sect2>
  17.112 +</sect1>
  17.113 +<sect1>
  17.114 +<title>Safe, efficient storage</title>
  17.115 +
  17.116 +<para>The underpinnings of changelogs, manifests, and filelogs are provided
  17.117 +by a single structure called the <emphasis>revlog</emphasis>.
  17.118 +</para>
  17.119 +
  17.120 +<sect2>
  17.121 +<title>Efficient storage</title>
  17.122 +
  17.123 +<para>The revlog provides efficient storage of revisions using a
  17.124 +<emphasis>delta</emphasis> mechanism.  Instead of storing a complete copy of a file
  17.125 +for each revision, it stores the changes needed to transform an older
  17.126 +revision into the new revision.  For many kinds of file data, these
  17.127 +deltas are typically a fraction of a percent of the size of a full
  17.128 +copy of a file.
  17.129 +</para>
  17.130 +
  17.131 +<para>Some obsolete revision control systems can only work with deltas of
  17.132 +text files.  They must either store binary files as complete snapshots
  17.133 +or encoded into a text representation, both of which are wasteful
  17.134 +approaches.  Mercurial can efficiently handle deltas of files with
  17.135 +arbitrary binary contents; it doesn't need to treat text as special.
  17.136 +</para>
  17.137 +
  17.138 +</sect2>
  17.139 +<sect2>
  17.140 +<title>Safe operation</title>
  17.141 +<para>\label{sec:concepts:txn}
  17.142 +</para>
  17.143 +
  17.144 +<para>Mercurial only ever <emphasis>appends</emphasis> data to the end of a revlog file.
  17.145 +It never modifies a section of a file after it has written it.  This
  17.146 +is both more robust and efficient than schemes that need to modify or
  17.147 +rewrite data.
  17.148 +</para>
  17.149 +
  17.150 +<para>In addition, Mercurial treats every write as part of a
  17.151 +<emphasis>transaction</emphasis> that can span a number of files.  A transaction is
  17.152 +<emphasis>atomic</emphasis>: either the entire transaction succeeds and its effects
  17.153 +are all visible to readers in one go, or the whole thing is undone.
  17.154 +This guarantee of atomicity means that if you're running two copies of
  17.155 +Mercurial, where one is reading data and one is writing it, the reader
  17.156 +will never see a partially written result that might confuse it.
  17.157 +</para>
  17.158 +
  17.159 +<para>The fact that Mercurial only appends to files makes it easier to
  17.160 +provide this transactional guarantee.  The easier it is to do stuff
  17.161 +like this, the more confident you should be that it's done correctly.
  17.162 +</para>
  17.163 +
  17.164 +</sect2>
  17.165 +<sect2>
  17.166 +<title>Fast retrieval</title>
  17.167 +
  17.168 +<para>Mercurial cleverly avoids a pitfall common to all earlier
  17.169 +revision control systems: the problem of <emphasis>inefficient retrieval</emphasis>.
  17.170 +Most revision control systems store the contents of a revision as an
  17.171 +incremental series of modifications against a <quote>snapshot</quote>.  To
  17.172 +reconstruct a specific revision, you must first read the snapshot, and
  17.173 +then every one of the revisions between the snapshot and your target
  17.174 +revision.  The more history that a file accumulates, the more
  17.175 +revisions you must read, hence the longer it takes to reconstruct a
  17.176 +particular revision.
  17.177 +</para>
  17.178 +
  17.179 +<informalfigure>
  17.180 +
  17.181 +<para>  <mediaobject><imageobject><imagedata fileref="snapshot"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.182 +  <caption><para>Snapshot of a revlog, with incremental deltas</para></caption>
  17.183 +  \label{fig:concepts:snapshot}
  17.184 +</para>
  17.185 +</informalfigure>
  17.186 +
  17.187 +<para>The innovation that Mercurial applies to this problem is simple but
  17.188 +effective.  Once the cumulative amount of delta information stored
  17.189 +since the last snapshot exceeds a fixed threshold, it stores a new
  17.190 +snapshot (compressed, of course), instead of another delta.  This
  17.191 +makes it possible to reconstruct <emphasis>any</emphasis> revision of a file
  17.192 +quickly.  This approach works so well that it has since been copied by
  17.193 +several other revision control systems.
  17.194 +</para>
  17.195 +
  17.196 +<para>Figure <xref linkend="fig:concepts:snapshot"/> illustrates the idea.  In an entry
  17.197 +in a revlog's index file, Mercurial stores the range of entries from
  17.198 +the data file that it must read to reconstruct a particular revision.
  17.199 +</para>
  17.200 +
  17.201 +<sect3>
  17.202 +<title>Aside: the influence of video compression</title>
  17.203 +
  17.204 +<para>If you're familiar with video compression or have ever watched a TV
  17.205 +feed through a digital cable or satellite service, you may know that
  17.206 +most video compression schemes store each frame of video as a delta
  17.207 +against its predecessor frame.  In addition, these schemes use
  17.208 +<quote>lossy</quote> compression techniques to increase the compression ratio, so
  17.209 +visual errors accumulate over the course of a number of inter-frame
  17.210 +deltas.
  17.211 +</para>
  17.212 +
  17.213 +<para>Because it's possible for a video stream to <quote>drop out</quote> occasionally
  17.214 +due to signal glitches, and to limit the accumulation of artefacts
  17.215 +introduced by the lossy compression process, video encoders
  17.216 +periodically insert a complete frame (called a <quote>key frame</quote>) into the
  17.217 +video stream; the next delta is generated against that frame.  This
  17.218 +means that if the video signal gets interrupted, it will resume once
  17.219 +the next key frame is received.  Also, the accumulation of encoding
  17.220 +errors restarts anew with each key frame.
  17.221 +</para>
  17.222 +
  17.223 +</sect3>
  17.224 +</sect2>
  17.225 +<sect2>
  17.226 +<title>Identification and strong integrity</title>
  17.227 +
  17.228 +<para>Along with delta or snapshot information, a revlog entry contains a
  17.229 +cryptographic hash of the data that it represents.  This makes it
  17.230 +difficult to forge the contents of a revision, and easy to detect
  17.231 +accidental corruption.
  17.232 +</para>
  17.233 +
  17.234 +<para>Hashes provide more than a mere check against corruption; they are
  17.235 +used as the identifiers for revisions.  The changeset identification
  17.236 +hashes that you see as an end user are from revisions of the
  17.237 +changelog.  Although filelogs and the manifest also use hashes,
  17.238 +Mercurial only uses these behind the scenes.
  17.239 +</para>
  17.240 +
  17.241 +<para>Mercurial verifies that hashes are correct when it retrieves file
  17.242 +revisions and when it pulls changes from another repository.  If it
  17.243 +encounters an integrity problem, it will complain and stop whatever
  17.244 +it's doing.
  17.245 +</para>
  17.246 +
  17.247 +<para>In addition to the effect it has on retrieval efficiency, Mercurial's
  17.248 +use of periodic snapshots makes it more robust against partial data
  17.249 +corruption.  If a revlog becomes partly corrupted due to a hardware
  17.250 +error or system bug, it's often possible to reconstruct some or most
  17.251 +revisions from the uncorrupted sections of the revlog, both before and
  17.252 +after the corrupted section.  This would not be possible with a
  17.253 +delta-only storage model.
  17.254 +</para>
  17.255 +
  17.256 +<para>\section{Revision history, branching,
  17.257 +  and merging}
  17.258 +</para>
  17.259 +
  17.260 +<para>Every entry in a Mercurial revlog knows the identity of its immediate
  17.261 +ancestor revision, usually referred to as its <emphasis>parent</emphasis>.  In fact,
  17.262 +a revision contains room for not one parent, but two.  Mercurial uses
  17.263 +a special hash, called the <quote>null ID</quote>, to represent the idea <quote>there
  17.264 +is no parent here</quote>.  This hash is simply a string of zeroes.
  17.265 +</para>
  17.266 +
  17.267 +<para>In figure <xref linkend="fig:concepts:revlog"/>, you can see an example of the
  17.268 +conceptual structure of a revlog.  Filelogs, manifests, and changelogs
  17.269 +all have this same structure; they differ only in the kind of data
  17.270 +stored in each delta or snapshot.
  17.271 +</para>
  17.272 +
  17.273 +<para>The first revision in a revlog (at the bottom of the image) has the
  17.274 +null ID in both of its parent slots.  For a <quote>normal</quote> revision, its
  17.275 +first parent slot contains the ID of its parent revision, and its
  17.276 +second contains the null ID, indicating that the revision has only one
  17.277 +real parent.  Any two revisions that have the same parent ID are
  17.278 +branches.  A revision that represents a merge between branches has two
  17.279 +normal revision IDs in its parent slots.
  17.280 +</para>
  17.281 +
  17.282 +<informalfigure>
  17.283 +
  17.284 +<para>  <mediaobject><imageobject><imagedata fileref="revlog"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.285 +  \caption{}
  17.286 +  \label{fig:concepts:revlog}
  17.287 +</para>
  17.288 +</informalfigure>
  17.289 +
  17.290 +</sect2>
  17.291 +</sect1>
  17.292 +<sect1>
  17.293 +<title>The working directory</title>
  17.294 +
  17.295 +<para>In the working directory, Mercurial stores a snapshot of the files
  17.296 +from the repository as of a particular changeset.
  17.297 +</para>
  17.298 +
  17.299 +<para>The working directory <quote>knows</quote> which changeset it contains.  When you
  17.300 +update the working directory to contain a particular changeset,
  17.301 +Mercurial looks up the appropriate revision of the manifest to find
  17.302 +out which files it was tracking at the time that changeset was
  17.303 +committed, and which revision of each file was then current.  It then
  17.304 +recreates a copy of each of those files, with the same contents it had
  17.305 +when the changeset was committed.
  17.306 +</para>
  17.307 +
  17.308 +<para>The <emphasis>dirstate</emphasis> contains Mercurial's knowledge of the working
  17.309 +directory.  This details which changeset the working directory is
  17.310 +updated to, and all of the files that Mercurial is tracking in the
  17.311 +working directory.
  17.312 +</para>
  17.313 +
  17.314 +<para>Just as a revision of a revlog has room for two parents, so that it
  17.315 +can represent either a normal revision (with one parent) or a merge of
  17.316 +two earlier revisions, the dirstate has slots for two parents.  When
  17.317 +you use the <command role="hg-cmd">hg update</command> command, the changeset that you update to
  17.318 +is stored in the <quote>first parent</quote> slot, and the null ID in the second.
  17.319 +When you <command role="hg-cmd">hg merge</command> with another changeset, the first parent
  17.320 +remains unchanged, and the second parent is filled in with the
  17.321 +changeset you're merging with.  The <command role="hg-cmd">hg parents</command> command tells you
  17.322 +what the parents of the dirstate are.
  17.323 +</para>
  17.324 +
  17.325 +<sect2>
  17.326 +<title>What happens when you commit</title>
  17.327 +
  17.328 +<para>The dirstate stores parent information for more than just book-keeping
  17.329 +purposes.  Mercurial uses the parents of the dirstate as \emph{the
  17.330 +  parents of a new changeset} when you perform a commit.
  17.331 +</para>
  17.332 +
  17.333 +<informalfigure>
  17.334 +
  17.335 +<para>  <mediaobject><imageobject><imagedata fileref="wdir"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.336 +  <caption><para>The working directory can have two parents</para></caption>
  17.337 +  \label{fig:concepts:wdir}
  17.338 +</para>
  17.339 +</informalfigure>
  17.340 +
  17.341 +<para>Figure <xref linkend="fig:concepts:wdir"/> shows the normal state of the working
  17.342 +directory, where it has a single changeset as parent.  That changeset
  17.343 +is the <emphasis>tip</emphasis>, the newest changeset in the repository that has no
  17.344 +children.
  17.345 +</para>
  17.346 +
  17.347 +<informalfigure>
  17.348 +
  17.349 +<para>  <mediaobject><imageobject><imagedata fileref="wdir-after-commit"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.350 +  <caption><para>The working directory gains new parents after a commit</para></caption>
  17.351 +  \label{fig:concepts:wdir-after-commit}
  17.352 +</para>
  17.353 +</informalfigure>
  17.354 +
  17.355 +<para>It's useful to think of the working directory as <quote>the changeset I'm
  17.356 +about to commit</quote>.  Any files that you tell Mercurial that you've
  17.357 +added, removed, renamed, or copied will be reflected in that
  17.358 +changeset, as will modifications to any files that Mercurial is
  17.359 +already tracking; the new changeset will have the parents of the
  17.360 +working directory as its parents.
  17.361 +</para>
  17.362 +
  17.363 +<para>After a commit, Mercurial will update the parents of the working
  17.364 +directory, so that the first parent is the ID of the new changeset,
  17.365 +and the second is the null ID.  This is shown in
  17.366 +figure <xref linkend="fig:concepts:wdir-after-commit"/>.  Mercurial doesn't touch
  17.367 +any of the files in the working directory when you commit; it just
  17.368 +modifies the dirstate to note its new parents.
  17.369 +</para>
  17.370 +
  17.371 +</sect2>
  17.372 +<sect2>
  17.373 +<title>Creating a new head</title>
  17.374 +
  17.375 +<para>It's perfectly normal to update the working directory to a changeset
  17.376 +other than the current tip.  For example, you might want to know what
  17.377 +your project looked like last Tuesday, or you could be looking through
  17.378 +changesets to see which one introduced a bug.  In cases like this, the
  17.379 +natural thing to do is update the working directory to the changeset
  17.380 +you're interested in, and then examine the files in the working
  17.381 +directory directly to see their contents as they were when you
  17.382 +committed that changeset.  The effect of this is shown in
  17.383 +figure <xref linkend="fig:concepts:wdir-pre-branch"/>.
  17.384 +</para>
  17.385 +
  17.386 +<informalfigure>
  17.387 +
  17.388 +<para>  <mediaobject><imageobject><imagedata fileref="wdir-pre-branch"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.389 +  <caption><para>The working directory, updated to an older changeset</para></caption>
  17.390 +  \label{fig:concepts:wdir-pre-branch}
  17.391 +</para>
  17.392 +</informalfigure>
  17.393 +
  17.394 +<para>Having updated the working directory to an older changeset, what
  17.395 +happens if you make some changes, and then commit?  Mercurial behaves
  17.396 +in the same way as I outlined above.  The parents of the working
  17.397 +directory become the parents of the new changeset.  This new changeset
  17.398 +has no children, so it becomes the new tip.  And the repository now
  17.399 +contains two changesets that have no children; we call these
  17.400 +<emphasis>heads</emphasis>.  You can see the structure that this creates in
  17.401 +figure <xref linkend="fig:concepts:wdir-branch"/>.
  17.402 +</para>
  17.403 +
  17.404 +<informalfigure>
  17.405 +
  17.406 +<para>  <mediaobject><imageobject><imagedata fileref="wdir-branch"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.407 +  <caption><para>After a commit made while synced to an older changeset</para></caption>
  17.408 +  \label{fig:concepts:wdir-branch}
  17.409 +</para>
  17.410 +</informalfigure>
  17.411 +
  17.412 +<note>
  17.413 +<para>  If you're new to Mercurial, you should keep in mind a common
  17.414 +  <quote>error</quote>, which is to use the <command role="hg-cmd">hg pull</command> command without any
  17.415 +  options.  By default, the <command role="hg-cmd">hg pull</command> command <emphasis>does not</emphasis>
  17.416 +  update the working directory, so you'll bring new changesets into
  17.417 +  your repository, but the working directory will stay synced at the
  17.418 +  same changeset as before the pull.  If you make some changes and
  17.419 +  commit afterwards, you'll thus create a new head, because your
  17.420 +  working directory isn't synced to whatever the current tip is.
  17.421 +</para>
  17.422 +
  17.423 +<para>  I put the word <quote>error</quote> in quotes because all that you need to do
  17.424 +  to rectify this situation is <command role="hg-cmd">hg merge</command>, then <command role="hg-cmd">hg commit</command>.  In
  17.425 +  other words, this almost never has negative consequences; it just
  17.426 +  surprises people.  I'll discuss other ways to avoid this behaviour,
  17.427 +  and why Mercurial behaves in this initially surprising way, later
  17.428 +  on.
  17.429 +</para>
  17.430 +</note>
  17.431 +
  17.432 +</sect2>
  17.433 +<sect2>
  17.434 +<title>Merging heads</title>
  17.435 +
  17.436 +<para>When you run the <command role="hg-cmd">hg merge</command> command, Mercurial leaves the first
  17.437 +parent of the working directory unchanged, and sets the second parent
  17.438 +to the changeset you're merging with, as shown in
  17.439 +figure <xref linkend="fig:concepts:wdir-merge"/>.
  17.440 +</para>
  17.441 +
  17.442 +<informalfigure>
  17.443 +
  17.444 +<para>  <mediaobject><imageobject><imagedata fileref="wdir-merge"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  17.445 +  <caption><para>Merging two heads</para></caption>
  17.446 +  \label{fig:concepts:wdir-merge}
  17.447 +</para>
  17.448 +</informalfigure>
  17.449 +
  17.450 +<para>Mercurial also has to modify the working directory, to merge the files
  17.451 +managed in the two changesets.  Simplified a little, the merging
  17.452 +process goes like this, for every file in the manifests of both
  17.453 +changesets.
  17.454 +</para>
  17.455 +<itemizedlist>
  17.456 +<listitem><para>If neither changeset has modified a file, do nothing with that
  17.457 +  file.
  17.458 +</para>
  17.459 +</listitem>
  17.460 +<listitem><para>If one changeset has modified a file, and the other hasn't,
  17.461 +  create the modified copy of the file in the working directory.
  17.462 +</para>
  17.463 +</listitem>
  17.464 +<listitem><para>If one changeset has removed a file, and the other hasn't (or
  17.465 +  has also deleted it), delete the file from the working directory.
  17.466 +</para>
  17.467 +</listitem>
  17.468 +<listitem><para>If one changeset has removed a file, but the other has modified
  17.469 +  the file, ask the user what to do: keep the modified file, or remove
  17.470 +  it?
  17.471 +</para>
  17.472 +</listitem>
  17.473 +<listitem><para>If both changesets have modified a file, invoke an external
  17.474 +  merge program to choose the new contents for the merged file.  This
  17.475 +  may require input from the user.
  17.476 +</para>
  17.477 +</listitem>
  17.478 +<listitem><para>If one changeset has modified a file, and the other has renamed
  17.479 +  or copied the file, make sure that the changes follow the new name
  17.480 +  of the file.
  17.481 +</para>
  17.482 +</listitem></itemizedlist>
  17.483 +<para>There are more details&emdash;merging has plenty of corner cases&emdash;but
  17.484 +these are the most common choices that are involved in a merge.  As
  17.485 +you can see, most cases are completely automatic, and indeed most
  17.486 +merges finish automatically, without requiring your input to resolve
  17.487 +any conflicts.
  17.488 +</para>
  17.489 +
  17.490 +<para>When you're thinking about what happens when you commit after a merge,
  17.491 +once again the working directory is <quote>the changeset I'm about to
  17.492 +commit</quote>.  After the <command role="hg-cmd">hg merge</command> command completes, the working
  17.493 +directory has two parents; these will become the parents of the new
  17.494 +changeset.
  17.495 +</para>
  17.496 +
  17.497 +<para>Mercurial lets you perform multiple merges, but you must commit the
  17.498 +results of each individual merge as you go.  This is necessary because
  17.499 +Mercurial only tracks two parents for both revisions and the working
  17.500 +directory.  While it would be technically possible to merge multiple
  17.501 +changesets at once, the prospect of user confusion and making a
  17.502 +terrible mess of a merge immediately becomes overwhelming.
  17.503 +</para>
  17.504 +
  17.505 +</sect2>
  17.506 +</sect1>
  17.507 +<sect1>
  17.508 +<title>Other interesting design features</title>
  17.509 +
  17.510 +<para>In the sections above, I've tried to highlight some of the most
  17.511 +important aspects of Mercurial's design, to illustrate that it pays
  17.512 +careful attention to reliability and performance.  However, the
  17.513 +attention to detail doesn't stop there.  There are a number of other
  17.514 +aspects of Mercurial's construction that I personally find
  17.515 +interesting.  I'll detail a few of them here, separate from the <quote>big
  17.516 +ticket</quote> items above, so that if you're interested, you can gain a
  17.517 +better idea of the amount of thinking that goes into a well-designed
  17.518 +system.
  17.519 +</para>
  17.520 +
  17.521 +<sect2>
  17.522 +<title>Clever compression</title>
  17.523 +
  17.524 +<para>When appropriate, Mercurial will store both snapshots and deltas in
  17.525 +compressed form.  It does this by always <emphasis>trying to</emphasis> compress a
  17.526 +snapshot or delta, but only storing the compressed version if it's
  17.527 +smaller than the uncompressed version.
  17.528 +</para>
  17.529 +
  17.530 +<para>This means that Mercurial does <quote>the right thing</quote> when storing a file
  17.531 +whose native form is compressed, such as a <literal>zip</literal> archive or a
  17.532 +JPEG image.  When these types of files are compressed a second time,
  17.533 +the resulting file is usually bigger than the once-compressed form,
  17.534 +and so Mercurial will store the plain <literal>zip</literal> or JPEG.
  17.535 +</para>
  17.536 +
  17.537 +<para>Deltas between revisions of a compressed file are usually larger than
  17.538 +snapshots of the file, and Mercurial again does <quote>the right thing</quote> in
  17.539 +these cases.  It finds that such a delta exceeds the threshold at
  17.540 +which it should store a complete snapshot of the file, so it stores
  17.541 +the snapshot, again saving space compared to a naive delta-only
  17.542 +approach.
  17.543 +</para>
  17.544 +
  17.545 +<sect3>
  17.546 +<title>Network recompression</title>
  17.547 +
  17.548 +<para>When storing revisions on disk, Mercurial uses the <quote>deflate</quote>
  17.549 +compression algorithm (the same one used by the popular <literal>zip</literal>
  17.550 +archive format), which balances good speed with a respectable
  17.551 +compression ratio.  However, when transmitting revision data over a
  17.552 +network connection, Mercurial uncompresses the compressed revision
  17.553 +data.
  17.554 +</para>
  17.555 +
  17.556 +<para>If the connection is over HTTP, Mercurial recompresses the entire
  17.557 +stream of data using a compression algorithm that gives a better
  17.558 +compression ratio (the Burrows-Wheeler algorithm from the widely used
  17.559 +<literal>bzip2</literal> compression package).  This combination of algorithm
  17.560 +and compression of the entire stream (instead of a revision at a time)
  17.561 +substantially reduces the number of bytes to be transferred, yielding
  17.562 +better network performance over almost all kinds of network.
  17.563 +</para>
  17.564 +
  17.565 +<para>(If the connection is over <command>ssh</command>, Mercurial <emphasis>doesn't</emphasis>
  17.566 +recompress the stream, because <command>ssh</command> can already do this
  17.567 +itself.)
  17.568 +</para>
  17.569 +
  17.570 +</sect3>
  17.571 +</sect2>
  17.572 +<sect2>
  17.573 +<title>Read/write ordering and atomicity</title>
  17.574 +
  17.575 +<para>Appending to files isn't the whole story when it comes to guaranteeing
  17.576 +that a reader won't see a partial write.  If you recall
  17.577 +figure <xref linkend="fig:concepts:metadata"/>, revisions in the changelog point to
  17.578 +revisions in the manifest, and revisions in the manifest point to
  17.579 +revisions in filelogs.  This hierarchy is deliberate.
  17.580 +</para>
  17.581 +
  17.582 +<para>A writer starts a transaction by writing filelog and manifest data,
  17.583 +and doesn't write any changelog data until those are finished.  A
  17.584 +reader starts by reading changelog data, then manifest data, followed
  17.585 +by filelog data.
  17.586 +</para>
  17.587 +
  17.588 +<para>Since the writer has always finished writing filelog and manifest data
  17.589 +before it writes to the changelog, a reader will never read a pointer
  17.590 +to a partially written manifest revision from the changelog, and it will
  17.591 +never read a pointer to a partially written filelog revision from the
  17.592 +manifest.
  17.593 +</para>
  17.594 +
  17.595 +</sect2>
  17.596 +<sect2>
  17.597 +<title>Concurrent access</title>
  17.598 +
  17.599 +<para>The read/write ordering and atomicity guarantees mean that Mercurial
  17.600 +never needs to <emphasis>lock</emphasis> a repository when it's reading data, even
  17.601 +if the repository is being written to while the read is occurring.
  17.602 +This has a big effect on scalability; you can have an arbitrary number
  17.603 +of Mercurial processes safely reading data from a repository safely
  17.604 +all at once, no matter whether it's being written to or not.
  17.605 +</para>
  17.606 +
  17.607 +<para>The lockless nature of reading means that if you're sharing a
  17.608 +repository on a multi-user system, you don't need to grant other local
  17.609 +users permission to <emphasis>write</emphasis> to your repository in order for them
  17.610 +to be able to clone it or pull changes from it; they only need
  17.611 +<emphasis>read</emphasis> permission.  (This is <emphasis>not</emphasis> a common feature among
  17.612 +revision control systems, so don't take it for granted!  Most require
  17.613 +readers to be able to lock a repository to access it safely, and this
  17.614 +requires write permission on at least one directory, which of course
  17.615 +makes for all kinds of nasty and annoying security and administrative
  17.616 +problems.)
  17.617 +</para>
  17.618 +
  17.619 +<para>Mercurial uses locks to ensure that only one process can write to a
  17.620 +repository at a time (the locking mechanism is safe even over
  17.621 +filesystems that are notoriously hostile to locking, such as NFS).  If
  17.622 +a repository is locked, a writer will wait for a while to retry if the
  17.623 +repository becomes unlocked, but if the repository remains locked for
  17.624 +too long, the process attempting to write will time out after a while.
  17.625 +This means that your daily automated scripts won't get stuck forever
  17.626 +and pile up if a system crashes unnoticed, for example.  (Yes, the
  17.627 +timeout is configurable, from zero to infinity.)
  17.628 +</para>
  17.629 +
  17.630 +<sect3>
  17.631 +<title>Safe dirstate access</title>
  17.632 +
  17.633 +<para>As with revision data, Mercurial doesn't take a lock to read the
  17.634 +dirstate file; it does acquire a lock to write it.  To avoid the
  17.635 +possibility of reading a partially written copy of the dirstate file,
  17.636 +Mercurial writes to a file with a unique name in the same directory as
  17.637 +the dirstate file, then renames the temporary file atomically to
  17.638 +<filename>dirstate</filename>.  The file named <filename>dirstate</filename> is thus
  17.639 +guaranteed to be complete, not partially written.
  17.640 +</para>
  17.641 +
  17.642 +</sect3>
  17.643 +</sect2>
  17.644 +<sect2>
  17.645 +<title>Avoiding seeks</title>
  17.646 +
  17.647 +<para>Critical to Mercurial's performance is the avoidance of seeks of the
  17.648 +disk head, since any seek is far more expensive than even a
  17.649 +comparatively large read operation.
  17.650 +</para>
  17.651 +
  17.652 +<para>This is why, for example, the dirstate is stored in a single file.  If
  17.653 +there were a dirstate file per directory that Mercurial tracked, the
  17.654 +disk would seek once per directory.  Instead, Mercurial reads the
  17.655 +entire single dirstate file in one step.
  17.656 +</para>
  17.657 +
  17.658 +<para>Mercurial also uses a <quote>copy on write</quote> scheme when cloning a
  17.659 +repository on local storage.  Instead of copying every revlog file
  17.660 +from the old repository into the new repository, it makes a <quote>hard
  17.661 +link</quote>, which is a shorthand way to say <quote>these two names point to the
  17.662 +same file</quote>.  When Mercurial is about to write to one of a revlog's
  17.663 +files, it checks to see if the number of names pointing at the file is
  17.664 +greater than one.  If it is, more than one repository is using the
  17.665 +file, so Mercurial makes a new copy of the file that is private to
  17.666 +this repository.
  17.667 +</para>
  17.668 +
  17.669 +<para>A few revision control developers have pointed out that this idea of
  17.670 +making a complete private copy of a file is not very efficient in its
  17.671 +use of storage.  While this is true, storage is cheap, and this method
  17.672 +gives the highest performance while deferring most book-keeping to the
  17.673 +operating system.  An alternative scheme would most likely reduce
  17.674 +performance and increase the complexity of the software, each of which
  17.675 +is much more important to the <quote>feel</quote> of day-to-day use.
  17.676 +</para>
  17.677 +
  17.678 +</sect2>
  17.679 +<sect2>
  17.680 +<title>Other contents of the dirstate</title>
  17.681 +
  17.682 +<para>Because Mercurial doesn't force you to tell it when you're modifying a
  17.683 +file, it uses the dirstate to store some extra information so it can
  17.684 +determine efficiently whether you have modified a file.  For each file
  17.685 +in the working directory, it stores the time that it last modified the
  17.686 +file itself, and the size of the file at that time.
  17.687 +</para>
  17.688 +
  17.689 +<para>When you explicitly <command role="hg-cmd">hg add</command>, <command role="hg-cmd">hg remove</command>, <command role="hg-cmd">hg rename</command> or
  17.690 +<command role="hg-cmd">hg copy</command> files, Mercurial updates the dirstate so that it knows
  17.691 +what to do with those files when you commit.
  17.692 +</para>
  17.693 +
  17.694 +<para>When Mercurial is checking the states of files in the working
  17.695 +directory, it first checks a file's modification time.  If that has
  17.696 +not changed, the file must not have been modified.  If the file's size
  17.697 +has changed, the file must have been modified.  If the modification
  17.698 +time has changed, but the size has not, only then does Mercurial need
  17.699 +to read the actual contents of the file to see if they've changed.
  17.700 +Storing these few extra pieces of information dramatically reduces the
  17.701 +amount of data that Mercurial needs to read, which yields large
  17.702 +performance improvements compared to other revision control systems.
  17.703 +</para>
  17.704 +
  17.705 +</sect2>
  17.706 +</sect1>
  17.707 +</chapter>
  17.708 +
  17.709 +<!--
  17.710 +local variables: 
  17.711 +sgml-parent-document: ("00book.xml" "book" "chapter")
  17.712 +end:
  17.713 +-->
  17.714 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/fr/ch05-daily.xml	Sun Aug 16 04:58:01 2009 +0200
    18.3 @@ -0,0 +1,474 @@
    18.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    18.5 +
    18.6 +<chapter>
    18.7 +<title>Mercurial in daily use</title>
    18.8 +<para>\label{chap:daily}</para>
    18.9 +
   18.10 +<sect1>
   18.11 +<title>Telling Mercurial which files to track</title>
   18.12 +
   18.13 +<para>Mercurial does not work with files in your repository unless you tell
   18.14 +it to manage them.  The <command role="hg-cmd">hg status</command> command will tell you which
   18.15 +files Mercurial doesn't know about; it uses a <quote><literal>?</literal></quote> to
   18.16 +display such files.</para>
   18.17 +
   18.18 +<para>To tell Mercurial to track a file, use the <command role="hg-cmd">hg add</command> command.  Once
   18.19 +you have added a file, the entry in the output of <command role="hg-cmd">hg status</command> for
   18.20 +that file changes from <quote><literal>?</literal></quote> to <quote><literal>A</literal></quote>.
   18.21 +<!-- &interaction.daily.files.add; --></para>
   18.22 +
   18.23 +<para>After you run a <command role="hg-cmd">hg commit</command>, the files that you added before the
   18.24 +commit will no longer be listed in the output of <command role="hg-cmd">hg status</command>.  The
   18.25 +reason for this is that <command role="hg-cmd">hg status</command> only tells you about
   18.26 +<quote>interesting</quote> files&emdash;those that you have modified or told Mercurial
   18.27 +to do something with&emdash;by default.  If you have a repository that
   18.28 +contains thousands of files, you will rarely want to know about files
   18.29 +that Mercurial is tracking, but that have not changed.  (You can still
   18.30 +get this information; we'll return to this later.)</para>
   18.31 +
   18.32 +<para>Once you add a file, Mercurial doesn't do anything with it
   18.33 +immediately.  Instead, it will take a snapshot of the file's state the
   18.34 +next time you perform a commit.  It will then continue to track the
   18.35 +changes you make to the file every time you commit, until you remove
   18.36 +the file.</para>
   18.37 +
   18.38 +<sect2>
   18.39 +<title>Explicit versus implicit file naming</title>
   18.40 +
   18.41 +<para>A useful behaviour that Mercurial has is that if you pass the name of
   18.42 +a directory to a command, every Mercurial command will treat this as
   18.43 +<quote>I want to operate on every file in this directory and its
   18.44 +subdirectories</quote>.
   18.45 +<!-- &interaction.daily.files.add-dir; -->
   18.46 +Notice in this example that Mercurial printed the names of the files
   18.47 +it added, whereas it didn't do so when we added the file named
   18.48 +<filename>a</filename> in the earlier example.</para>
   18.49 +
   18.50 +<para>What's going on is that in the former case, we explicitly named the
   18.51 +file to add on the command line, so the assumption that Mercurial
   18.52 +makes in such cases is that you know what you were doing, and it
   18.53 +doesn't print any output.</para>
   18.54 +
   18.55 +<para>However, when we <emphasis>imply</emphasis> the names of files by giving the name of
   18.56 +a directory, Mercurial takes the extra step of printing the name of
   18.57 +each file that it does something with.  This makes it more clear what
   18.58 +is happening, and reduces the likelihood of a silent and nasty
   18.59 +surprise.  This behaviour is common to most Mercurial commands.</para>
   18.60 +
   18.61 +</sect2>
   18.62 +<sect2>
   18.63 +<title>Aside: Mercurial tracks files, not directories</title>
   18.64 +
   18.65 +<para>Mercurial does not track directory information.  Instead, it tracks
   18.66 +the path to a file.  Before creating a file, it first creates any
   18.67 +missing directory components of the path.  After it deletes a file, it
   18.68 +then deletes any empty directories that were in the deleted file's
   18.69 +path.  This sounds like a trivial distinction, but it has one minor
   18.70 +practical consequence: it is not possible to represent a completely
   18.71 +empty directory in Mercurial.
   18.72 +</para>
   18.73 +
   18.74 +<para>Empty directories are rarely useful, and there are unintrusive
   18.75 +workarounds that you can use to achieve an appropriate effect.  The
   18.76 +developers of Mercurial thus felt that the complexity that would be
   18.77 +required to manage empty directories was not worth the limited benefit
   18.78 +this feature would bring.
   18.79 +</para>
   18.80 +
   18.81 +<para>If you need an empty directory in your repository, there are a few
   18.82 +ways to achieve this. One is to create a directory, then <command role="hg-cmd">hg add</command> a
   18.83 +<quote>hidden</quote> file to that directory.  On Unix-like systems, any file
   18.84 +name that begins with a period (<quote><literal>.</literal></quote>) is treated as hidden
   18.85 +by most commands and GUI tools.  This approach is illustrated in
   18.86 +figure <xref linkend="ex:daily:hidden"/>.
   18.87 +</para>
   18.88 +
   18.89 +<informalfigure>
   18.90 +<para>  <!-- &interaction.daily.files.hidden; -->
   18.91 +  <caption><para>Simulating an empty directory using a hidden file</para></caption>
   18.92 +  \label{ex:daily:hidden}
   18.93 +</para>
   18.94 +</informalfigure>
   18.95 +
   18.96 +<para>Another way to tackle a need for an empty directory is to simply
   18.97 +create one in your automated build scripts before they will need it.
   18.98 +</para>
   18.99 +
  18.100 +</sect2>
  18.101 +</sect1>
  18.102 +<sect1>
  18.103 +<title>How to stop tracking a file</title>
  18.104 +
  18.105 +<para>Once you decide that a file no longer belongs in your repository, use
  18.106 +the <command role="hg-cmd">hg remove</command> command; this deletes the file, and tells Mercurial
  18.107 +to stop tracking it.  A removed file is represented in the output of
  18.108 +<command role="hg-cmd">hg status</command> with a <quote><literal>R</literal></quote>.
  18.109 +<!-- &interaction.daily.files.remove; -->
  18.110 +</para>
  18.111 +
  18.112 +<para>After you <command role="hg-cmd">hg remove</command> a file, Mercurial will no longer track
  18.113 +changes to that file, even if you recreate a file with the same name
  18.114 +in your working directory.  If you do recreate a file with the same
  18.115 +name and want Mercurial to track the new file, simply <command role="hg-cmd">hg add</command> it.
  18.116 +Mercurial will know that the newly added file is not related to the
  18.117 +old file of the same name.
  18.118 +</para>
  18.119 +
  18.120 +<sect2>
  18.121 +<title>Removing a file does not affect its history</title>
  18.122 +
  18.123 +<para>It is important to understand that removing a file has only two
  18.124 +effects.
  18.125 +</para>
  18.126 +<itemizedlist>
  18.127 +<listitem><para>It removes the current version of the file from the working
  18.128 +  directory.
  18.129 +</para>
  18.130 +</listitem>
  18.131 +<listitem><para>It stops Mercurial from tracking changes to the file, from the
  18.132 +  time of the next commit.
  18.133 +</para>
  18.134 +</listitem></itemizedlist>
  18.135 +<para>Removing a file <emphasis>does not</emphasis> in any way alter the <emphasis>history</emphasis> of
  18.136 +the file.
  18.137 +</para>
  18.138 +
  18.139 +<para>If you update the working directory to a changeset in which a file
  18.140 +that you have removed was still tracked, it will reappear in the
  18.141 +working directory, with the contents it had when you committed that
  18.142 +changeset.  If you then update the working directory to a later
  18.143 +changeset, in which the file had been removed, Mercurial will once
  18.144 +again remove the file from the working directory.
  18.145 +</para>
  18.146 +
  18.147 +</sect2>
  18.148 +<sect2>
  18.149 +<title>Missing files</title>
  18.150 +
  18.151 +<para>Mercurial considers a file that you have deleted, but not used
  18.152 +<command role="hg-cmd">hg remove</command> to delete, to be <emphasis>missing</emphasis>.  A missing file is
  18.153 +represented with <quote><literal>!</literal></quote> in the output of <command role="hg-cmd">hg status</command>.
  18.154 +Mercurial commands will not generally do anything with missing files.
  18.155 +<!-- &interaction.daily.files.missing; -->
  18.156 +</para>
  18.157 +
  18.158 +<para>If your repository contains a file that <command role="hg-cmd">hg status</command> reports as
  18.159 +missing, and you want the file to stay gone, you can run
  18.160 +<command role="hg-cmd">hg remove <option role="hg-opt-remove">--after</option></command> at any time later on, to
  18.161 +tell Mercurial that you really did mean to remove the file.
  18.162 +<!-- &interaction.daily.files.remove-after; -->
  18.163 +</para>
  18.164 +
  18.165 +<para>On the other hand, if you deleted the missing file by accident, use
  18.166 +<command role="hg-cmd">hg revert <emphasis>filename</emphasis></command> to recover the file.  It will
  18.167 +reappear, in unmodified form.
  18.168 +<!-- &interaction.daily.files.recover-missing; -->
  18.169 +</para>
  18.170 +
  18.171 +<para>\subsection{Aside: why tell Mercurial explicitly to
  18.172 +  remove a file?}
  18.173 +</para>
  18.174 +
  18.175 +<para>You might wonder why Mercurial requires you to explicitly tell it that
  18.176 +you are deleting a file.  Early during the development of Mercurial,
  18.177 +it let you delete a file however you pleased; Mercurial would notice
  18.178 +the absence of the file automatically when you next ran a
  18.179 +<command role="hg-cmd">hg commit</command>, and stop tracking the file.  In practice, this made it
  18.180 +too easy to accidentally remove a file without noticing.
  18.181 +</para>
  18.182 +
  18.183 +<para>\subsection{Useful shorthand&emdash;adding and removing files
  18.184 +  in one step}
  18.185 +</para>
  18.186 +
  18.187 +<para>Mercurial offers a combination command, <command role="hg-cmd">hg addremove</command>, that adds
  18.188 +untracked files and marks missing files as removed.
  18.189 +<!-- &interaction.daily.files.addremove; -->
  18.190 +The <command role="hg-cmd">hg commit</command> command also provides a <option role="hg-opt-commit">-A</option> option
  18.191 +that performs this same add-and-remove, immediately followed by a
  18.192 +commit.
  18.193 +<!-- &interaction.daily.files.commit-addremove; -->
  18.194 +</para>
  18.195 +
  18.196 +</sect2>
  18.197 +</sect1>
  18.198 +<sect1>
  18.199 +<title>Copying files</title>
  18.200 +
  18.201 +<para>Mercurial provides a <command role="hg-cmd">hg copy</command> command that lets you make a new
  18.202 +copy of a file.  When you copy a file using this command, Mercurial
  18.203 +makes a record of the fact that the new file is a copy of the original
  18.204 +file.  It treats these copied files specially when you merge your work
  18.205 +with someone else's.
  18.206 +</para>
  18.207 +
  18.208 +<sect2>
  18.209 +<title>The results of copying during a merge</title>
  18.210 +
  18.211 +<para>What happens during a merge is that changes <quote>follow</quote> a copy.  To
  18.212 +best illustrate what this means, let's create an example.  We'll start
  18.213 +with the usual tiny repository that contains a single file.
  18.214 +<!-- &interaction.daily.copy.init; -->
  18.215 +We need to do some work in parallel, so that we'll have something to
  18.216 +merge.  So let's clone our repository.
  18.217 +<!-- &interaction.daily.copy.clone; -->
  18.218 +Back in our initial repository, let's use the <command role="hg-cmd">hg copy</command> command to
  18.219 +make a copy of the first file we created.
  18.220 +<!-- &interaction.daily.copy.copy; -->
  18.221 +</para>
  18.222 +
  18.223 +<para>If we look at the output of the <command role="hg-cmd">hg status</command> command afterwards, the
  18.224 +copied file looks just like a normal added file.
  18.225 +<!-- &interaction.daily.copy.status; -->
  18.226 +But if we pass the <option role="hg-opt-status">-C</option> option to <command role="hg-cmd">hg status</command>, it
  18.227 +prints another line of output: this is the file that our newly-added
  18.228 +file was copied <emphasis>from</emphasis>.
  18.229 +<!-- &interaction.daily.copy.status-copy; -->
  18.230 +</para>
  18.231 +
  18.232 +<para>Now, back in the repository we cloned, let's make a change in
  18.233 +parallel.  We'll add a line of content to the original file that we
  18.234 +created.
  18.235 +<!-- &interaction.daily.copy.other; -->
  18.236 +Now we have a modified <filename>file</filename> in this repository.  When we
  18.237 +pull the changes from the first repository, and merge the two heads,
  18.238 +Mercurial will propagate the changes that we made locally to
  18.239 +<filename>file</filename> into its copy, <filename>new-file</filename>.
  18.240 +<!-- &interaction.daily.copy.merge; -->
  18.241 +</para>
  18.242 +
  18.243 +</sect2>
  18.244 +<sect2>
  18.245 +<title>Why should changes follow copies?</title>
  18.246 +<para>\label{sec:daily:why-copy}
  18.247 +</para>
  18.248 +
  18.249 +<para>This behaviour, of changes to a file propagating out to copies of the
  18.250 +file, might seem esoteric, but in most cases it's highly desirable.
  18.251 +</para>
  18.252 +
  18.253 +<para>First of all, remember that this propagation <emphasis>only</emphasis> happens when
  18.254 +you merge.  So if you <command role="hg-cmd">hg copy</command> a file, and subsequently modify the
  18.255 +original file during the normal course of your work, nothing will
  18.256 +happen.
  18.257 +</para>
  18.258 +
  18.259 +<para>The second thing to know is that modifications will only propagate
  18.260 +across a copy as long as the repository that you're pulling changes
  18.261 +from <emphasis>doesn't know</emphasis> about the copy.
  18.262 +</para>
  18.263 +
  18.264 +<para>The reason that Mercurial does this is as follows.  Let's say I make
  18.265 +an important bug fix in a source file, and commit my changes.
  18.266 +Meanwhile, you've decided to <command role="hg-cmd">hg copy</command> the file in your repository,
  18.267 +without knowing about the bug or having seen the fix, and you have
  18.268 +started hacking on your copy of the file.
  18.269 +</para>
  18.270 +
  18.271 +<para>If you pulled and merged my changes, and Mercurial <emphasis>didn't</emphasis>
  18.272 +propagate changes across copies, your source file would now contain
  18.273 +the bug, and unless you remembered to propagate the bug fix by hand,
  18.274 +the bug would <emphasis>remain</emphasis> in your copy of the file.
  18.275 +</para>
  18.276 +
  18.277 +<para>By automatically propagating the change that fixed the bug from the
  18.278 +original file to the copy, Mercurial prevents this class of problem.
  18.279 +To my knowledge, Mercurial is the <emphasis>only</emphasis> revision control system
  18.280 +that propagates changes across copies like this.
  18.281 +</para>
  18.282 +
  18.283 +<para>Once your change history has a record that the copy and subsequent
  18.284 +merge occurred, there's usually no further need to propagate changes
  18.285 +from the original file to the copied file, and that's why Mercurial
  18.286 +only propagates changes across copies until this point, and no
  18.287 +further.
  18.288 +</para>
  18.289 +
  18.290 +</sect2>
  18.291 +<sect2>
  18.292 +<title>How to make changes <emphasis>not</emphasis> follow a copy</title>
  18.293 +
  18.294 +<para>If, for some reason, you decide that this business of automatically
  18.295 +propagating changes across copies is not for you, simply use your
  18.296 +system's normal file copy command (on Unix-like systems, that's
  18.297 +<command>cp</command>) to make a copy of a file, then <command role="hg-cmd">hg add</command> the new copy
  18.298 +by hand.  Before you do so, though, please do reread
  18.299 +section <xref linkend="sec:daily:why-copy"/>, and make an informed decision that
  18.300 +this behaviour is not appropriate to your specific case.
  18.301 +</para>
  18.302 +
  18.303 +</sect2>
  18.304 +<sect2>
  18.305 +<title>Behaviour of the <command role="hg-cmd">hg copy</command> command</title>
  18.306 +
  18.307 +<para>When you use the <command role="hg-cmd">hg copy</command> command, Mercurial makes a copy of each
  18.308 +source file as it currently stands in the working directory.  This
  18.309 +means that if you make some modifications to a file, then <command role="hg-cmd">hg copy</command>
  18.310 +it without first having committed those changes, the new copy will
  18.311 +also contain the modifications you have made up until that point.  (I
  18.312 +find this behaviour a little counterintuitive, which is why I mention
  18.313 +it here.)
  18.314 +</para>
  18.315 +
  18.316 +<para>The <command role="hg-cmd">hg copy</command> command acts similarly to the Unix <command>cp</command>
  18.317 +command (you can use the <command role="hg-cmd">hg cp</command> alias if you prefer).  The last
  18.318 +argument is the <emphasis>destination</emphasis>, and all prior arguments are
  18.319 +<emphasis>sources</emphasis>.  If you pass it a single file as the source, and the
  18.320 +destination does not exist, it creates a new file with that name.
  18.321 +<!-- &interaction.daily.copy.simple; -->
  18.322 +If the destination is a directory, Mercurial copies its sources into
  18.323 +that directory.
  18.324 +<!-- &interaction.daily.copy.dir-dest; -->
  18.325 +Copying a directory is recursive, and preserves the directory
  18.326 +structure of the source.
  18.327 +<!-- &interaction.daily.copy.dir-src; -->
  18.328 +If the source and destination are both directories, the source tree is
  18.329 +recreated in the destination directory.
  18.330 +<!-- &interaction.daily.copy.dir-src-dest; -->
  18.331 +</para>
  18.332 +
  18.333 +<para>As with the <command role="hg-cmd">hg rename</command> command, if you copy a file manually and
  18.334 +then want Mercurial to know that you've copied the file, simply use
  18.335 +the <option role="hg-opt-copy">--after</option> option to <command role="hg-cmd">hg copy</command>.
  18.336 +<!-- &interaction.daily.copy.after; -->
  18.337 +</para>
  18.338 +
  18.339 +</sect2>
  18.340 +</sect1>
  18.341 +<sect1>
  18.342 +<title>Renaming files</title>
  18.343 +
  18.344 +<para>It's rather more common to need to rename a file than to make a copy
  18.345 +of it.  The reason I discussed the <command role="hg-cmd">hg copy</command> command before talking
  18.346 +about renaming files is that Mercurial treats a rename in essentially
  18.347 +the same way as a copy.  Therefore, knowing what Mercurial does when
  18.348 +you copy a file tells you what to expect when you rename a file.
  18.349 +</para>
  18.350 +
  18.351 +<para>When you use the <command role="hg-cmd">hg rename</command> command, Mercurial makes a copy of
  18.352 +each source file, then deletes it and marks the file as removed.
  18.353 +<!-- &interaction.daily.rename.rename; -->
  18.354 +The <command role="hg-cmd">hg status</command> command shows the newly copied file as added, and
  18.355 +the copied-from file as removed.
  18.356 +<!-- &interaction.daily.rename.status; -->
  18.357 +As with the results of a <command role="hg-cmd">hg copy</command>, we must use the
  18.358 +<option role="hg-opt-status">-C</option> option to <command role="hg-cmd">hg status</command> to see that the added file
  18.359 +is really being tracked by Mercurial as a copy of the original, now
  18.360 +removed, file.
  18.361 +<!-- &interaction.daily.rename.status-copy; -->
  18.362 +</para>
  18.363 +
  18.364 +<para>As with <command role="hg-cmd">hg remove</command> and <command role="hg-cmd">hg copy</command>, you can tell Mercurial about
  18.365 +a rename after the fact using the <option role="hg-opt-rename">--after</option> option.  In
  18.366 +most other respects, the behaviour of the <command role="hg-cmd">hg rename</command> command, and
  18.367 +the options it accepts, are similar to the <command role="hg-cmd">hg copy</command> command.
  18.368 +</para>
  18.369 +
  18.370 +<sect2>
  18.371 +<title>Renaming files and merging changes</title>
  18.372 +
  18.373 +<para>Since Mercurial's rename is implemented as copy-and-remove, the same
  18.374 +propagation of changes happens when you merge after a rename as after
  18.375 +a copy.
  18.376 +</para>
  18.377 +
  18.378 +<para>If I modify a file, and you rename it to a new name, and then we merge
  18.379 +our respective changes, my modifications to the file under its
  18.380 +original name will be propagated into the file under its new name.
  18.381 +(This is something you might expect to <quote>simply work,</quote> but not all
  18.382 +revision control systems actually do this.)
  18.383 +</para>
  18.384 +
  18.385 +<para>Whereas having changes follow a copy is a feature where you can
  18.386 +perhaps nod and say <quote>yes, that might be useful,</quote> it should be clear
  18.387 +that having them follow a rename is definitely important.  Without
  18.388 +this facility, it would simply be too easy for changes to become
  18.389 +orphaned when files are renamed.
  18.390 +</para>
  18.391 +
  18.392 +</sect2>
  18.393 +<sect2>
  18.394 +<title>Divergent renames and merging</title>
  18.395 +
  18.396 +<para>The case of diverging names occurs when two developers start with a
  18.397 +file&emdash;let's call it <filename>foo</filename>&emdash;in their respective
  18.398 +repositories.
  18.399 +</para>
  18.400 +
  18.401 +<para><!-- &interaction.rename.divergent.clone; -->
  18.402 +Anne renames the file to <filename>bar</filename>.
  18.403 +<!-- &interaction.rename.divergent.rename.anne; -->
  18.404 +Meanwhile, Bob renames it to <filename>quux</filename>.
  18.405 +<!-- &interaction.rename.divergent.rename.bob; -->
  18.406 +</para>
  18.407 +
  18.408 +<para>I like to think of this as a conflict because each developer has
  18.409 +expressed different intentions about what the file ought to be named.
  18.410 +</para>
  18.411 +
  18.412 +<para>What do you think should happen when they merge their work?
  18.413 +Mercurial's actual behaviour is that it always preserves <emphasis>both</emphasis>
  18.414 +names when it merges changesets that contain divergent renames.
  18.415 +<!-- &interaction.rename.divergent.merge; -->
  18.416 +</para>
  18.417 +
  18.418 +<para>Notice that Mercurial does warn about the divergent renames, but it
  18.419 +leaves it up to you to do something about the divergence after the merge.
  18.420 +</para>
  18.421 +
  18.422 +</sect2>
  18.423 +<sect2>
  18.424 +<title>Convergent renames and merging</title>
  18.425 +
  18.426 +<para>Another kind of rename conflict occurs when two people choose to
  18.427 +rename different <emphasis>source</emphasis> files to the same <emphasis>destination</emphasis>.
  18.428 +In this case, Mercurial runs its normal merge machinery, and lets you
  18.429 +guide it to a suitable resolution.
  18.430 +</para>
  18.431 +
  18.432 +</sect2>
  18.433 +<sect2>
  18.434 +<title>Other name-related corner cases</title>
  18.435 +
  18.436 +<para>Mercurial has a longstanding bug in which it fails to handle a merge
  18.437 +where one side has a file with a given name, while another has a
  18.438 +directory with the same name.  This is documented as <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue29">issue 29</ulink>.
  18.439 +<!-- &interaction.issue29.go; -->
  18.440 +</para>
  18.441 +
  18.442 +</sect2>
  18.443 +</sect1>
  18.444 +<sect1>
  18.445 +<title>Recovering from mistakes</title>
  18.446 +
  18.447 +<para>Mercurial has some useful commands that will help you to recover from
  18.448 +some common mistakes.
  18.449 +</para>
  18.450 +
  18.451 +<para>The <command role="hg-cmd">hg revert</command> command lets you undo changes that you have made to
  18.452 +your working directory.  For example, if you <command role="hg-cmd">hg add</command> a file by
  18.453 +accident, just run <command role="hg-cmd">hg revert</command> with the name of the file you added,
  18.454 +and while the file won't be touched in any way, it won't be tracked
  18.455 +for adding by Mercurial any longer, either.  You can also use
  18.456 +<command role="hg-cmd">hg revert</command> to get rid of erroneous changes to a file.
  18.457 +</para>
  18.458 +
  18.459 +<para>It's useful to remember that the <command role="hg-cmd">hg revert</command> command is useful for
  18.460 +changes that you have not yet committed.  Once you've committed a
  18.461 +change, if you decide it was a mistake, you can still do something
  18.462 +about it, though your options may be more limited.
  18.463 +</para>
  18.464 +
  18.465 +<para>For more information about the <command role="hg-cmd">hg revert</command> command, and details
  18.466 +about how to deal with changes you have already committed, see
  18.467 +chapter <xref linkend="chap:undo"/>.
  18.468 +</para>
  18.469 +
  18.470 +</sect1>
  18.471 +</chapter>
  18.472 +
  18.473 +<!--
  18.474 +local variables: 
  18.475 +sgml-parent-document: ("00book.xml" "book" "chapter")
  18.476 +end:
  18.477 +-->
  18.478 \ No newline at end of file
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/fr/ch06-collab.xml	Sun Aug 16 04:58:01 2009 +0200
    19.3 @@ -0,0 +1,1405 @@
    19.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    19.5 +
    19.6 +<chapter>
    19.7 +<title>Collaborating with other people</title>
    19.8 +<para>\label{cha:collab}</para>
    19.9 +
   19.10 +<para>As a completely decentralised tool, Mercurial doesn't impose any
   19.11 +policy on how people ought to work with each other.  However, if
   19.12 +you're new to distributed revision control, it helps to have some
   19.13 +tools and examples in mind when you're thinking about possible
   19.14 +workflow models.</para>
   19.15 +
   19.16 +<sect1>
   19.17 +<title>Mercurial's web interface</title>
   19.18 +
   19.19 +<para>Mercurial has a powerful web interface that provides several
   19.20 +useful capabilities.</para>
   19.21 +
   19.22 +<para>For interactive use, the web interface lets you browse a single
   19.23 +repository or a collection of repositories.  You can view the history
   19.24 +of a repository, examine each change (comments and diffs), and view
   19.25 +the contents of each directory and file.</para>
   19.26 +
   19.27 +<para>Also for human consumption, the web interface provides an RSS feed of
   19.28 +the changes in a repository.  This lets you <quote>subscribe</quote> to a
   19.29 +repository using your favourite feed reader, and be automatically
   19.30 +notified of activity in that repository as soon as it happens.  I find
   19.31 +this capability much more convenient than the model of subscribing to
   19.32 +a mailing list to which notifications are sent, as it requires no
   19.33 +additional configuration on the part of whoever is serving the
   19.34 +repository.</para>
   19.35 +
   19.36 +<para>The web interface also lets remote users clone a repository, pull
   19.37 +changes from it, and (when the server is configured to permit it) push
   19.38 +changes back to it.  Mercurial's HTTP tunneling protocol aggressively
   19.39 +compresses data, so that it works efficiently even over low-bandwidth
   19.40 +network connections.</para>
   19.41 +
   19.42 +<para>The easiest way to get started with the web interface is to use your
   19.43 +web browser to visit an existing repository, such as the master
   19.44 +Mercurial repository at
   19.45 +<ulink url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para>
   19.46 +
   19.47 +<para>If you're interested in providing a web interface to your own
   19.48 +repositories, Mercurial provides two ways to do this.  The first is
   19.49 +using the <command role="hg-cmd">hg serve</command> command, which is best suited to short-term
   19.50 +<quote>lightweight</quote> serving.  See section <xref linkend="sec:collab:serve"/> below for
   19.51 +details of how to use this command.  If you have a long-lived
   19.52 +repository that you'd like to make permanently available, Mercurial
   19.53 +has built-in support for the CGI (Common Gateway Interface) standard,
   19.54 +which all common web servers support.  See
   19.55 +section <xref linkend="sec:collab:cgi"/> for details of CGI configuration.</para>
   19.56 +
   19.57 +</sect1>
   19.58 +<sect1>
   19.59 +<title>Collaboration models</title>
   19.60 +
   19.61 +<para>With a suitably flexible tool, making decisions about workflow is much
   19.62 +more of a social engineering challenge than a technical one.
   19.63 +Mercurial imposes few limitations on how you can structure the flow of
   19.64 +work in a project, so it's up to you and your group to set up and live
   19.65 +with a model that matches your own particular needs.
   19.66 +</para>
   19.67 +
   19.68 +<sect2>
   19.69 +<title>Factors to keep in mind</title>
   19.70 +
   19.71 +<para>The most important aspect of any model that you must keep in mind is
   19.72 +how well it matches the needs and capabilities of the people who will
   19.73 +be using it.  This might seem self-evident; even so, you still can't
   19.74 +afford to forget it for a moment.
   19.75 +</para>
   19.76 +
   19.77 +<para>I once put together a workflow model that seemed to make perfect sense
   19.78 +to me, but that caused a considerable amount of consternation and
   19.79 +strife within my development team.  In spite of my attempts to explain
   19.80 +why we needed a complex set of branches, and how changes ought to flow
   19.81 +between them, a few team members revolted.  Even though they were
   19.82 +smart people, they didn't want to pay attention to the constraints we
   19.83 +were operating under, or face the consequences of those constraints in
   19.84 +the details of the model that I was advocating.
   19.85 +</para>
   19.86 +
   19.87 +<para>Don't sweep foreseeable social or technical problems under the rug.
   19.88 +Whatever scheme you put into effect, you should plan for mistakes and
   19.89 +problem scenarios.  Consider adding automated machinery to prevent, or
   19.90 +quickly recover from, trouble that you can anticipate.  As an example,
   19.91 +if you intend to have a branch with not-for-release changes in it,
   19.92 +you'd do well to think early about the possibility that someone might
   19.93 +accidentally merge those changes into a release branch.  You could
   19.94 +avoid this particular problem by writing a hook that prevents changes
   19.95 +from being merged from an inappropriate branch.
   19.96 +</para>
   19.97 +
   19.98 +</sect2>
   19.99 +<sect2>
  19.100 +<title>Informal anarchy</title>
  19.101 +
  19.102 +<para>I wouldn't suggest an <quote>anything goes</quote> approach as something
  19.103 +sustainable, but it's a model that's easy to grasp, and it works
  19.104 +perfectly well in a few unusual situations.
  19.105 +</para>
  19.106 +
  19.107 +<para>As one example, many projects have a loose-knit group of collaborators
  19.108 +who rarely physically meet each other.  Some groups like to overcome
  19.109 +the isolation of working at a distance by organising occasional
  19.110 +<quote>sprints</quote>.  In a sprint, a number of people get together in a single
  19.111 +location (a company's conference room, a hotel meeting room, that kind
  19.112 +of place) and spend several days more or less locked in there, hacking
  19.113 +intensely on a handful of projects.
  19.114 +</para>
  19.115 +
  19.116 +<para>A sprint is the perfect place to use the <command role="hg-cmd">hg serve</command> command, since
  19.117 +<command role="hg-cmd">hg serve</command> does not requires any fancy server infrastructure.  You
  19.118 +can get started with <command role="hg-cmd">hg serve</command> in moments, by reading
  19.119 +section <xref linkend="sec:collab:serve"/> below.  Then simply tell the person
  19.120 +next to you that you're running a server, send the URL to them in an
  19.121 +instant message, and you immediately have a quick-turnaround way to
  19.122 +work together.  They can type your URL into their web browser and
  19.123 +quickly review your changes; or they can pull a bugfix from you and
  19.124 +verify it; or they can clone a branch containing a new feature and try
  19.125 +it out.
  19.126 +</para>
  19.127 +
  19.128 +<para>The charm, and the problem, with doing things in an ad hoc fashion
  19.129 +like this is that only people who know about your changes, and where
  19.130 +they are, can see them.  Such an informal approach simply doesn't
  19.131 +scale beyond a handful people, because each individual needs to know
  19.132 +about $n$ different repositories to pull from.
  19.133 +</para>
  19.134 +
  19.135 +</sect2>
  19.136 +<sect2>
  19.137 +<title>A single central repository</title>
  19.138 +
  19.139 +<para>For smaller projects migrating from a centralised revision control
  19.140 +tool, perhaps the easiest way to get started is to have changes flow
  19.141 +through a single shared central repository.  This is also the
  19.142 +most common <quote>building block</quote> for more ambitious workflow schemes.
  19.143 +</para>
  19.144 +
  19.145 +<para>Contributors start by cloning a copy of this repository.  They can
  19.146 +pull changes from it whenever they need to, and some (perhaps all)
  19.147 +developers have permission to push a change back when they're ready
  19.148 +for other people to see it.
  19.149 +</para>
  19.150 +
  19.151 +<para>Under this model, it can still often make sense for people to pull
  19.152 +changes directly from each other, without going through the central
  19.153 +repository.  Consider a case in which I have a tentative bug fix, but
  19.154 +I am worried that if I were to publish it to the central repository,
  19.155 +it might subsequently break everyone else's trees as they pull it.  To
  19.156 +reduce the potential for damage, I can ask you to clone my repository
  19.157 +into a temporary repository of your own and test it.  This lets us put
  19.158 +off publishing the potentially unsafe change until it has had a little
  19.159 +testing.
  19.160 +</para>
  19.161 +
  19.162 +<para>In this kind of scenario, people usually use the <command>ssh</command>
  19.163 +protocol to securely push changes to the central repository, as
  19.164 +documented in section <xref linkend="sec:collab:ssh"/>.  It's also usual to
  19.165 +publish a read-only copy of the repository over HTTP using CGI, as in
  19.166 +section <xref linkend="sec:collab:cgi"/>.  Publishing over HTTP satisfies the
  19.167 +needs of people who don't have push access, and those who want to use
  19.168 +web browsers to browse the repository's history.
  19.169 +</para>
  19.170 +
  19.171 +</sect2>
  19.172 +<sect2>
  19.173 +<title>Working with multiple branches</title>
  19.174 +
  19.175 +<para>Projects of any significant size naturally tend to make progress on
  19.176 +several fronts simultaneously.  In the case of software, it's common
  19.177 +for a project to go through periodic official releases.  A release
  19.178 +might then go into <quote>maintenance mode</quote> for a while after its first
  19.179 +publication; maintenance releases tend to contain only bug fixes, not
  19.180 +new features.  In parallel with these maintenance releases, one or
  19.181 +more future releases may be under development.  People normally use
  19.182 +the word <quote>branch</quote> to refer to one of these many slightly different
  19.183 +directions in which development is proceeding.
  19.184 +</para>
  19.185 +
  19.186 +<para>Mercurial is particularly well suited to managing a number of
  19.187 +simultaneous, but not identical, branches.  Each <quote>development
  19.188 +direction</quote> can live in its own central repository, and you can merge
  19.189 +changes from one to another as the need arises.  Because repositories
  19.190 +are independent of each other, unstable changes in a development
  19.191 +branch will never affect a stable branch unless someone explicitly
  19.192 +merges those changes in.
  19.193 +</para>
  19.194 +
  19.195 +<para>Here's an example of how this can work in practice.  Let's say you
  19.196 +have one <quote>main branch</quote> on a central server.
  19.197 +<!-- &interaction.branching.init; -->
  19.198 +People clone it, make changes locally, test them, and push them back.
  19.199 +</para>
  19.200 +
  19.201 +<para>Once the main branch reaches a release milestone, you can use the
  19.202 +<command role="hg-cmd">hg tag</command> command to give a permanent name to the milestone
  19.203 +revision.
  19.204 +<!-- &interaction.branching.tag; -->
  19.205 +Let's say some ongoing development occurs on the main branch.
  19.206 +<!-- &interaction.branching.main; -->
  19.207 +Using the tag that was recorded at the milestone, people who clone
  19.208 +that repository at any time in the future can use <command role="hg-cmd">hg update</command> to
  19.209 +get a copy of the working directory exactly as it was when that tagged
  19.210 +revision was committed.
  19.211 +<!-- &interaction.branching.update; -->
  19.212 +</para>
  19.213 +
  19.214 +<para>In addition, immediately after the main branch is tagged, someone can
  19.215 +then clone the main branch on the server to a new <quote>stable</quote> branch,
  19.216 +also on the server.
  19.217 +<!-- &interaction.branching.clone; -->
  19.218 +</para>
  19.219 +
  19.220 +<para>Someone who needs to make a change to the stable branch can then clone
  19.221 +<emphasis>that</emphasis> repository, make their changes, commit, and push their
  19.222 +changes back there.
  19.223 +<!-- &interaction.branching.stable; -->
  19.224 +Because Mercurial repositories are independent, and Mercurial doesn't
  19.225 +move changes around automatically, the stable and main branches are
  19.226 +<emphasis>isolated</emphasis> from each other.  The changes that you made on the
  19.227 +main branch don't <quote>leak</quote> to the stable branch, and vice versa.
  19.228 +</para>
  19.229 +
  19.230 +<para>You'll often want all of your bugfixes on the stable branch to show up
  19.231 +on the main branch, too.  Rather than rewrite a bugfix on the main
  19.232 +branch, you can simply pull and merge changes from the stable to the
  19.233 +main branch, and Mercurial will bring those bugfixes in for you.
  19.234 +<!-- &interaction.branching.merge; -->
  19.235 +The main branch will still contain changes that are not on the stable
  19.236 +branch, but it will also contain all of the bugfixes from the stable
  19.237 +branch.  The stable branch remains unaffected by these changes.
  19.238 +</para>
  19.239 +
  19.240 +</sect2>
  19.241 +<sect2>
  19.242 +<title>Feature branches</title>
  19.243 +
  19.244 +<para>For larger projects, an effective way to manage change is to break up
  19.245 +a team into smaller groups.  Each group has a shared branch of its
  19.246 +own, cloned from a single <quote>master</quote> branch used by the entire
  19.247 +project.  People working on an individual branch are typically quite
  19.248 +isolated from developments on other branches.
  19.249 +</para>
  19.250 +
  19.251 +<informalfigure>
  19.252 +
  19.253 +<para>  <mediaobject><imageobject><imagedata fileref="feature-branches"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  19.254 +  <caption><para>Feature branches</para></caption>
  19.255 +  \label{fig:collab:feature-branches}
  19.256 +</para>
  19.257 +</informalfigure>
  19.258 +
  19.259 +<para>When a particular feature is deemed to be in suitable shape, someone
  19.260 +on that feature team pulls and merges from the master branch into the
  19.261 +feature branch, then pushes back up to the master branch.
  19.262 +</para>
  19.263 +
  19.264 +</sect2>
  19.265 +<sect2>
  19.266 +<title>The release train</title>
  19.267 +
  19.268 +<para>Some projects are organised on a <quote>train</quote> basis: a release is
  19.269 +scheduled to happen every few months, and whatever features are ready
  19.270 +when the <quote>train</quote> is ready to leave are allowed in.
  19.271 +</para>
  19.272 +
  19.273 +<para>This model resembles working with feature branches.  The difference is
  19.274 +that when a feature branch misses a train, someone on the feature team
  19.275 +pulls and merges the changes that went out on that train release into
  19.276 +the feature branch, and the team continues its work on top of that
  19.277 +release so that their feature can make the next release.
  19.278 +</para>
  19.279 +
  19.280 +</sect2>
  19.281 +<sect2>
  19.282 +<title>The Linux kernel model</title>
  19.283 +
  19.284 +<para>The development of the Linux kernel has a shallow hierarchical
  19.285 +structure, surrounded by a cloud of apparent chaos.  Because most
  19.286 +Linux developers use <command>git</command>, a distributed revision control
  19.287 +tool with capabilities similar to Mercurial, it's useful to describe
  19.288 +the way work flows in that environment; if you like the ideas, the
  19.289 +approach translates well across tools.
  19.290 +</para>
  19.291 +
  19.292 +<para>At the center of the community sits Linus Torvalds, the creator of
  19.293 +Linux.  He publishes a single source repository that is considered the
  19.294 +<quote>authoritative</quote> current tree by the entire developer community.
  19.295 +Anyone can clone Linus's tree, but he is very choosy about whose trees
  19.296 +he pulls from.
  19.297 +</para>
  19.298 +
  19.299 +<para>Linus has a number of <quote>trusted lieutenants</quote>.  As a general rule, he
  19.300 +pulls whatever changes they publish, in most cases without even
  19.301 +reviewing those changes.  Some of those lieutenants are generally
  19.302 +agreed to be <quote>maintainers</quote>, responsible for specific subsystems
  19.303 +within the kernel.  If a random kernel hacker wants to make a change
  19.304 +to a subsystem that they want to end up in Linus's tree, they must
  19.305 +find out who the subsystem's maintainer is, and ask that maintainer to
  19.306 +take their change.  If the maintainer reviews their changes and agrees
  19.307 +to take them, they'll pass them along to Linus in due course.
  19.308 +</para>
  19.309 +
  19.310 +<para>Individual lieutenants have their own approaches to reviewing,
  19.311 +accepting, and publishing changes; and for deciding when to feed them
  19.312 +to Linus.  In addition, there are several well known branches that
  19.313 +people use for different purposes.  For example, a few people maintain
  19.314 +<quote>stable</quote> repositories of older versions of the kernel, to which they
  19.315 +apply critical fixes as needed.  Some maintainers publish multiple
  19.316 +trees: one for experimental changes; one for changes that they are
  19.317 +about to feed upstream; and so on.  Others just publish a single
  19.318 +tree.
  19.319 +</para>
  19.320 +
  19.321 +<para>This model has two notable features.  The first is that it's <quote>pull
  19.322 +only</quote>.  You have to ask, convince, or beg another developer to take a
  19.323 +change from you, because there are almost no trees to which more than
  19.324 +one person can push, and there's no way to push changes into a tree
  19.325 +that someone else controls.
  19.326 +</para>
  19.327 +
  19.328 +<para>The second is that it's based on reputation and acclaim.  If you're an
  19.329 +unknown, Linus will probably ignore changes from you without even
  19.330 +responding.  But a subsystem maintainer will probably review them, and
  19.331 +will likely take them if they pass their criteria for suitability.
  19.332 +The more <quote>good</quote> changes you contribute to a maintainer, the more
  19.333 +likely they are to trust your judgment and accept your changes.  If
  19.334 +you're well-known and maintain a long-lived branch for something Linus
  19.335 +hasn't yet accepted, people with similar interests may pull your
  19.336 +changes regularly to keep up with your work.
  19.337 +</para>
  19.338 +
  19.339 +<para>Reputation and acclaim don't necessarily cross subsystem or <quote>people</quote>
  19.340 +boundaries.  If you're a respected but specialised storage hacker, and
  19.341 +you try to fix a networking bug, that change will receive a level of
  19.342 +scrutiny from a network maintainer comparable to a change from a
  19.343 +complete stranger.
  19.344 +</para>
  19.345 +
  19.346 +<para>To people who come from more orderly project backgrounds, the
  19.347 +comparatively chaotic Linux kernel development process often seems
  19.348 +completely insane.  It's subject to the whims of individuals; people
  19.349 +make sweeping changes whenever they deem it appropriate; and the pace
  19.350 +of development is astounding.  And yet Linux is a highly successful,
  19.351 +well-regarded piece of software.
  19.352 +</para>
  19.353 +
  19.354 +</sect2>
  19.355 +<sect2>
  19.356 +<title>Pull-only versus shared-push collaboration</title>
  19.357 +
  19.358 +<para>A perpetual source of heat in the open source community is whether a
  19.359 +development model in which people only ever pull changes from others
  19.360 +is <quote>better than</quote> one in which multiple people can push changes to a
  19.361 +shared repository.
  19.362 +</para>
  19.363 +
  19.364 +<para>Typically, the backers of the shared-push model use tools that
  19.365 +actively enforce this approach.  If you're using a centralised
  19.366 +revision control tool such as Subversion, there's no way to make a
  19.367 +choice over which model you'll use: the tool gives you shared-push,
  19.368 +and if you want to do anything else, you'll have to roll your own
  19.369 +approach on top (such as applying a patch by hand).
  19.370 +</para>
  19.371 +
  19.372 +<para>A good distributed revision control tool, such as Mercurial, will
  19.373 +support both models.  You and your collaborators can then structure
  19.374 +how you work together based on your own needs and preferences, not on
  19.375 +what contortions your tools force you into.
  19.376 +</para>
  19.377 +
  19.378 +</sect2>
  19.379 +<sect2>
  19.380 +<title>Where collaboration meets branch management</title>
  19.381 +
  19.382 +<para>Once you and your team set up some shared repositories and start
  19.383 +propagating changes back and forth between local and shared repos, you
  19.384 +begin to face a related, but slightly different challenge: that of
  19.385 +managing the multiple directions in which your team may be moving at
  19.386 +once.  Even though this subject is intimately related to how your team
  19.387 +collaborates, it's dense enough to merit treatment of its own, in
  19.388 +chapter <xref linkend="chap:branch"/>.
  19.389 +</para>
  19.390 +
  19.391 +</sect2>
  19.392 +</sect1>
  19.393 +<sect1>
  19.394 +<title>The technical side of sharing</title>
  19.395 +
  19.396 +<para>The remainder of this chapter is devoted to the question of serving
  19.397 +data to your collaborators.
  19.398 +</para>
  19.399 +
  19.400 +</sect1>
  19.401 +<sect1>
  19.402 +<title>Informal sharing with <command role="hg-cmd">hg serve</command></title>
  19.403 +<para>\label{sec:collab:serve}
  19.404 +</para>
  19.405 +
  19.406 +<para>Mercurial's <command role="hg-cmd">hg serve</command> command is wonderfully suited to small,
  19.407 +tight-knit, and fast-paced group environments.  It also provides a
  19.408 +great way to get a feel for using Mercurial commands over a network.
  19.409 +</para>
  19.410 +
  19.411 +<para>Run <command role="hg-cmd">hg serve</command> inside a repository, and in under a second it will
  19.412 +bring up a specialised HTTP server; this will accept connections from
  19.413 +any client, and serve up data for that repository until you terminate
  19.414 +it.  Anyone who knows the URL of the server you just started, and can
  19.415 +talk to your computer over the network, can then use a web browser or
  19.416 +Mercurial to read data from that repository.  A URL for a
  19.417 +<command role="hg-cmd">hg serve</command> instance running on a laptop is likely to look something
  19.418 +like <literal>http://my-laptop.local:8000/</literal>.
  19.419 +</para>
  19.420 +
  19.421 +<para>The <command role="hg-cmd">hg serve</command> command is <emphasis>not</emphasis> a general-purpose web server.
  19.422 +It can do only two things:
  19.423 +</para>
  19.424 +<itemizedlist>
  19.425 +<listitem><para>Allow people to browse the history of the repository it's
  19.426 +  serving, from their normal web browsers.
  19.427 +</para>
  19.428 +</listitem>
  19.429 +<listitem><para>Speak Mercurial's wire protocol, so that people can
  19.430 +  <command role="hg-cmd">hg clone</command> or <command role="hg-cmd">hg pull</command> changes from that repository.
  19.431 +</para>
  19.432 +</listitem></itemizedlist>
  19.433 +<para>In particular, <command role="hg-cmd">hg serve</command> won't allow remote users to <emphasis>modify</emphasis>
  19.434 +your repository.  It's intended for read-only use.
  19.435 +</para>
  19.436 +
  19.437 +<para>If you're getting started with Mercurial, there's nothing to prevent
  19.438 +you from using <command role="hg-cmd">hg serve</command> to serve up a repository on your own
  19.439 +computer, then use commands like <command role="hg-cmd">hg clone</command>, <command role="hg-cmd">hg incoming</command>, and
  19.440 +so on to talk to that server as if the repository was hosted remotely.
  19.441 +This can help you to quickly get acquainted with using commands on
  19.442 +network-hosted repositories.
  19.443 +</para>
  19.444 +
  19.445 +<sect2>
  19.446 +<title>A few things to keep in mind</title>
  19.447 +
  19.448 +<para>Because it provides unauthenticated read access to all clients, you
  19.449 +should only use <command role="hg-cmd">hg serve</command> in an environment where you either don't
  19.450 +care, or have complete control over, who can access your network and
  19.451 +pull data from your repository.
  19.452 +</para>
  19.453 +
  19.454 +<para>The <command role="hg-cmd">hg serve</command> command knows nothing about any firewall software
  19.455 +you might have installed on your system or network.  It cannot detect
  19.456 +or control your firewall software.  If other people are unable to talk
  19.457 +to a running <command role="hg-cmd">hg serve</command> instance, the second thing you should do
  19.458 +(<emphasis>after</emphasis> you make sure that they're using the correct URL) is
  19.459 +check your firewall configuration.
  19.460 +</para>
  19.461 +
  19.462 +<para>By default, <command role="hg-cmd">hg serve</command> listens for incoming connections on
  19.463 +port 8000.  If another process is already listening on the port you
  19.464 +want to use, you can specify a different port to listen on using the
  19.465 +<option role="hg-opt-serve">-p</option> option.
  19.466 +</para>
  19.467 +
  19.468 +<para>Normally, when <command role="hg-cmd">hg serve</command> starts, it prints no output, which can be
  19.469 +a bit unnerving.  If you'd like to confirm that it is indeed running
  19.470 +correctly, and find out what URL you should send to your
  19.471 +collaborators, start it with the <option role="hg-opt-global">-v</option> option.
  19.472 +</para>
  19.473 +
  19.474 +</sect2>
  19.475 +</sect1>
  19.476 +<sect1>
  19.477 +<title>Using the Secure Shell (ssh) protocol</title>
  19.478 +<para>\label{sec:collab:ssh}
  19.479 +</para>
  19.480 +
  19.481 +<para>You can pull and push changes securely over a network connection using
  19.482 +the Secure Shell (<literal>ssh</literal>) protocol.  To use this successfully,
  19.483 +you may have to do a little bit of configuration on the client or
  19.484 +server sides.
  19.485 +</para>
  19.486 +
  19.487 +<para>If you're not familiar with ssh, it's a network protocol that lets you
  19.488 +securely communicate with another computer.  To use it with Mercurial,
  19.489 +you'll be setting up one or more user accounts on a server so that
  19.490 +remote users can log in and execute commands.
  19.491 +</para>
  19.492 +
  19.493 +<para>(If you <emphasis>are</emphasis> familiar with ssh, you'll probably find some of the
  19.494 +material that follows to be elementary in nature.)
  19.495 +</para>
  19.496 +
  19.497 +<sect2>
  19.498 +<title>How to read and write ssh URLs</title>
  19.499 +
  19.500 +<para>An ssh URL tends to look like this:
  19.501 +</para>
  19.502 +<programlisting>
  19.503 +<para>  ssh://bos@hg.serpentine.com:22/hg/hgbook
  19.504 +</para>
  19.505 +</programlisting>
  19.506 +<orderedlist>
  19.507 +<listitem><para>The <quote><literal>ssh://</literal></quote> part tells Mercurial to use the ssh
  19.508 +  protocol.
  19.509 +</para>
  19.510 +</listitem>
  19.511 +<listitem><para>The <quote><literal>bos@</literal></quote> component indicates what username to log
  19.512 +  into the server as.  You can leave this out if the remote username
  19.513 +  is the same as your local username.
  19.514 +</para>
  19.515 +</listitem>
  19.516 +<listitem><para>The <quote><literal>hg.serpentine.com</literal></quote> gives the hostname of the
  19.517 +  server to log into.
  19.518 +</para>
  19.519 +</listitem>
  19.520 +<listitem><para>The <quote>:22</quote> identifies the port number to connect to the server
  19.521 +  on.  The default port is 22, so you only need to specify this part
  19.522 +  if you're <emphasis>not</emphasis> using port 22.
  19.523 +</para>
  19.524 +</listitem>
  19.525 +<listitem><para>The remainder of the URL is the local path to the repository on
  19.526 +  the server.
  19.527 +</para>
  19.528 +</listitem></orderedlist>
  19.529 +
  19.530 +<para>There's plenty of scope for confusion with the path component of ssh
  19.531 +URLs, as there is no standard way for tools to interpret it.  Some
  19.532 +programs behave differently than others when dealing with these paths.
  19.533 +This isn't an ideal situation, but it's unlikely to change.  Please
  19.534 +read the following paragraphs carefully.
  19.535 +</para>
  19.536 +
  19.537 +<para>Mercurial treats the path to a repository on the server as relative to
  19.538 +the remote user's home directory.  For example, if user <literal>foo</literal>
  19.539 +on the server has a home directory of <filename class="directory">/home/foo</filename>, then an ssh
  19.540 +URL that contains a path component of <filename class="directory">bar</filename>
  19.541 +<emphasis>really</emphasis> refers to the directory <filename class="directory">/home/foo/bar</filename>.
  19.542 +</para>
  19.543 +
  19.544 +<para>If you want to specify a path relative to another user's home
  19.545 +directory, you can use a path that starts with a tilde character
  19.546 +followed by the user's name (let's call them <literal>otheruser</literal>), like
  19.547 +this.
  19.548 +</para>
  19.549 +<programlisting>
  19.550 +<para>  ssh://server/ otheruser/hg/repo
  19.551 +</para>
  19.552 +</programlisting>
  19.553 +
  19.554 +<para>And if you really want to specify an <emphasis>absolute</emphasis> path on the
  19.555 +server, begin the path component with two slashes, as in this example.
  19.556 +</para>
  19.557 +<programlisting>
  19.558 +<para>  ssh://server//absolute/path
  19.559 +</para>
  19.560 +</programlisting>
  19.561 +
  19.562 +</sect2>
  19.563 +<sect2>
  19.564 +<title>Finding an ssh client for your system</title>
  19.565 +
  19.566 +<para>Almost every Unix-like system comes with OpenSSH preinstalled.  If
  19.567 +you're using such a system, run <literal>which ssh</literal> to find out if
  19.568 +the <command>ssh</command> command is installed (it's usually in
  19.569 +<filename class="directory">/usr/bin</filename>).  In the unlikely event that it isn't present,
  19.570 +take a look at your system documentation to figure out how to install
  19.571 +it.
  19.572 +</para>
  19.573 +
  19.574 +<para>On Windows, you'll first need to download a suitable ssh
  19.575 +client.  There are two alternatives.
  19.576 +</para>
  19.577 +<itemizedlist>
  19.578 +<listitem><para>Simon Tatham's excellent PuTTY package <citation>web:putty</citation> provides
  19.579 +  a complete suite of ssh client commands.
  19.580 +</para>
  19.581 +</listitem>
  19.582 +<listitem><para>If you have a high tolerance for pain, you can use the Cygwin
  19.583 +  port of OpenSSH.
  19.584 +</para>
  19.585 +</listitem></itemizedlist>
  19.586 +<para>In either case, you'll need to edit your \hgini\ file to tell
  19.587 +Mercurial where to find the actual client command.  For example, if
  19.588 +you're using PuTTY, you'll need to use the <command>plink</command> command as
  19.589 +a command-line ssh client.
  19.590 +</para>
  19.591 +<programlisting>
  19.592 +<para>  [ui]
  19.593 +  ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"
  19.594 +</para>
  19.595 +</programlisting>
  19.596 +
  19.597 +<note>
  19.598 +<para>  The path to <command>plink</command> shouldn't contain any whitespace
  19.599 +  characters, or Mercurial may not be able to run it correctly (so
  19.600 +  putting it in <filename class="directory">C:\\Program Files</filename> is probably not a good
  19.601 +  idea).
  19.602 +</para>
  19.603 +</note>
  19.604 +
  19.605 +</sect2>
  19.606 +<sect2>
  19.607 +<title>Generating a key pair</title>
  19.608 +
  19.609 +<para>To avoid the need to repetitively type a password every time you need
  19.610 +to use your ssh client, I recommend generating a key pair.  On a
  19.611 +Unix-like system, the <command>ssh-keygen</command> command will do the trick.
  19.612 +On Windows, if you're using PuTTY, the <command>puttygen</command> command is
  19.613 +what you'll need.
  19.614 +</para>
  19.615 +
  19.616 +<para>When you generate a key pair, it's usually <emphasis>highly</emphasis> advisable to
  19.617 +protect it with a passphrase.  (The only time that you might not want
  19.618 +to do this is when you're using the ssh protocol for automated tasks
  19.619 +on a secure network.)
  19.620 +</para>
  19.621 +
  19.622 +<para>Simply generating a key pair isn't enough, however.  You'll need to
  19.623 +add the public key to the set of authorised keys for whatever user
  19.624 +you're logging in remotely as.  For servers using OpenSSH (the vast
  19.625 +majority), this will mean adding the public key to a list in a file
  19.626 +called <filename role="special">authorized_keys</filename> in their <filename role="special" class="directory">.ssh</filename>
  19.627 +directory.
  19.628 +</para>
  19.629 +
  19.630 +<para>On a Unix-like system, your public key will have a <filename>.pub</filename>
  19.631 +extension.  If you're using <command>puttygen</command> on Windows, you can
  19.632 +save the public key to a file of your choosing, or paste it from the
  19.633 +window it's displayed in straight into the
  19.634 +<filename role="special">authorized_keys</filename> file.
  19.635 +</para>
  19.636 +
  19.637 +</sect2>
  19.638 +<sect2>
  19.639 +<title>Using an authentication agent</title>
  19.640 +
  19.641 +<para>An authentication agent is a daemon that stores passphrases in memory
  19.642 +(so it will forget passphrases if you log out and log back in again).
  19.643 +An ssh client will notice if it's running, and query it for a
  19.644 +passphrase.  If there's no authentication agent running, or the agent
  19.645 +doesn't store the necessary passphrase, you'll have to type your
  19.646 +passphrase every time Mercurial tries to communicate with a server on
  19.647 +your behalf (e.g. whenever you pull or push changes).
  19.648 +</para>
  19.649 +
  19.650 +<para>The downside of storing passphrases in an agent is that it's possible
  19.651 +for a well-prepared attacker to recover the plain text of your
  19.652 +passphrases, in some cases even if your system has been power-cycled.
  19.653 +You should make your own judgment as to whether this is an acceptable
  19.654 +risk.  It certainly saves a lot of repeated typing.
  19.655 +</para>
  19.656 +
  19.657 +<para>On Unix-like systems, the agent is called <command>ssh-agent</command>, and
  19.658 +it's often run automatically for you when you log in.  You'll need to
  19.659 +use the <command>ssh-add</command> command to add passphrases to the agent's
  19.660 +store.  On Windows, if you're using PuTTY, the <command>pageant</command>
  19.661 +command acts as the agent.  It adds an icon to your system tray that
  19.662 +will let you manage stored passphrases.
  19.663 +</para>
  19.664 +
  19.665 +</sect2>
  19.666 +<sect2>
  19.667 +<title>Configuring the server side properly</title>
  19.668 +
  19.669 +<para>Because ssh can be fiddly to set up if you're new to it, there's a
  19.670 +variety of things that can go wrong.  Add Mercurial on top, and
  19.671 +there's plenty more scope for head-scratching.  Most of these
  19.672 +potential problems occur on the server side, not the client side.  The
  19.673 +good news is that once you've gotten a configuration working, it will
  19.674 +usually continue to work indefinitely.
  19.675 +</para>
  19.676 +
  19.677 +<para>Before you try using Mercurial to talk to an ssh server, it's best to
  19.678 +make sure that you can use the normal <command>ssh</command> or <command>putty</command>
  19.679 +command to talk to the server first.  If you run into problems with
  19.680 +using these commands directly, Mercurial surely won't work.  Worse, it
  19.681 +will obscure the underlying problem.  Any time you want to debug
  19.682 +ssh-related Mercurial problems, you should drop back to making sure
  19.683 +that plain ssh client commands work first, <emphasis>before</emphasis> you worry
  19.684 +about whether there's a problem with Mercurial.
  19.685 +</para>
  19.686 +
  19.687 +<para>The first thing to be sure of on the server side is that you can
  19.688 +actually log in from another machine at all.  If you can't use
  19.689 +<command>ssh</command> or <command>putty</command> to log in, the error message you get
  19.690 +may give you a few hints as to what's wrong.  The most common problems
  19.691 +are as follows.
  19.692 +</para>
  19.693 +<itemizedlist>
  19.694 +<listitem><para>If you get a <quote>connection refused</quote> error, either there isn't an
  19.695 +  SSH daemon running on the server at all, or it's inaccessible due to
  19.696 +  firewall configuration.
  19.697 +</para>
  19.698 +</listitem>
  19.699 +<listitem><para>If you get a <quote>no route to host</quote> error, you either have an
  19.700 +  incorrect address for the server or a seriously locked down firewall
  19.701 +  that won't admit its existence at all.
  19.702 +</para>
  19.703 +</listitem>
  19.704 +<listitem><para>If you get a <quote>permission denied</quote> error, you may have mistyped
  19.705 +  the username on the server, or you could have mistyped your key's
  19.706 +  passphrase or the remote user's password.
  19.707 +</para>
  19.708 +</listitem></itemizedlist>
  19.709 +<para>In summary, if you're having trouble talking to the server's ssh
  19.710 +daemon, first make sure that one is running at all.  On many systems
  19.711 +it will be installed, but disabled, by default.  Once you're done with
  19.712 +this step, you should then check that the server's firewall is
  19.713 +configured to allow incoming connections on the port the ssh daemon is
  19.714 +listening on (usually 22).  Don't worry about more exotic
  19.715 +possibilities for misconfiguration until you've checked these two
  19.716 +first.
  19.717 +</para>
  19.718 +
  19.719 +<para>If you're using an authentication agent on the client side to store
  19.720 +passphrases for your keys, you ought to be able to log into the server
  19.721 +without being prompted for a passphrase or a password.  If you're
  19.722 +prompted for a passphrase, there are a few possible culprits.
  19.723 +</para>
  19.724 +<itemizedlist>
  19.725 +<listitem><para>You might have forgotten to use <command>ssh-add</command> or
  19.726 +  <command>pageant</command> to store the passphrase.
  19.727 +</para>
  19.728 +</listitem>
  19.729 +<listitem><para>You might have stored the passphrase for the wrong key.
  19.730 +</para>
  19.731 +</listitem></itemizedlist>
  19.732 +<para>If you're being prompted for the remote user's password, there are
  19.733 +another few possible problems to check.
  19.734 +</para>
  19.735 +<itemizedlist>
  19.736 +<listitem><para>Either the user's home directory or their <filename role="special" class="directory">.ssh</filename>
  19.737 +  directory might have excessively liberal permissions.  As a result,
  19.738 +  the ssh daemon will not trust or read their
  19.739 +  <filename role="special">authorized_keys</filename> file.  For example, a group-writable
  19.740 +  home or <filename role="special" class="directory">.ssh</filename> directory will often cause this symptom.
  19.741 +</para>
  19.742 +</listitem>
  19.743 +<listitem><para>The user's <filename role="special">authorized_keys</filename> file may have a problem.
  19.744 +  If anyone other than the user owns or can write to that file, the
  19.745 +  ssh daemon will not trust or read it.
  19.746 +</para>
  19.747 +</listitem></itemizedlist>
  19.748 +
  19.749 +<para>In the ideal world, you should be able to run the following command
  19.750 +successfully, and it should print exactly one line of output, the
  19.751 +current date and time.
  19.752 +</para>
  19.753 +<programlisting>
  19.754 +<para>  ssh myserver date
  19.755 +</para>
  19.756 +</programlisting>
  19.757 +
  19.758 +<para>If, on your server, you have login scripts that print banners or other
  19.759 +junk even when running non-interactive commands like this, you should
  19.760 +fix them before you continue, so that they only print output if
  19.761 +they're run interactively.  Otherwise these banners will at least
  19.762 +clutter up Mercurial's output.  Worse, they could potentially cause
  19.763 +problems with running Mercurial commands remotely.  Mercurial makes
  19.764 +tries to detect and ignore banners in non-interactive <command>ssh</command>
  19.765 +sessions, but it is not foolproof.  (If you're editing your login
  19.766 +scripts on your server, the usual way to see if a login script is
  19.767 +running in an interactive shell is to check the return code from the
  19.768 +command <literal>tty -s</literal>.)
  19.769 +</para>
  19.770 +
  19.771 +<para>Once you've verified that plain old ssh is working with your server,
  19.772 +the next step is to ensure that Mercurial runs on the server.  The
  19.773 +following command should run successfully:
  19.774 +</para>
  19.775 +<programlisting>
  19.776 +<para>  ssh myserver hg version
  19.777 +</para>
  19.778 +</programlisting>
  19.779 +<para>If you see an error message instead of normal <command role="hg-cmd">hg version</command> output,
  19.780 +this is usually because you haven't installed Mercurial to
  19.781 +<filename class="directory">/usr/bin</filename>.  Don't worry if this is the case; you don't need
  19.782 +to do that.  But you should check for a few possible problems.
  19.783 +</para>
  19.784 +<itemizedlist>
  19.785 +<listitem><para>Is Mercurial really installed on the server at all?  I know this
  19.786 +  sounds trivial, but it's worth checking!
  19.787 +</para>
  19.788 +</listitem>
  19.789 +<listitem><para>Maybe your shell's search path (usually set via the <envar>PATH</envar>
  19.790 +  environment variable) is simply misconfigured.
  19.791 +</para>
  19.792 +</listitem>
  19.793 +<listitem><para>Perhaps your <envar>PATH</envar> environment variable is only being set
  19.794 +  to point to the location of the <command>hg</command> executable if the login
  19.795 +  session is interactive.  This can happen if you're setting the path
  19.796 +  in the wrong shell login script.  See your shell's documentation for
  19.797 +  details.
  19.798 +</para>
  19.799 +</listitem>
  19.800 +<listitem><para>The <envar>PYTHONPATH</envar> environment variable may need to contain
  19.801 +  the path to the Mercurial Python modules.  It might not be set at
  19.802 +  all; it could be incorrect; or it may be set only if the login is
  19.803 +  interactive.
  19.804 +</para>
  19.805 +</listitem></itemizedlist>
  19.806 +
  19.807 +<para>If you can run <command role="hg-cmd">hg version</command> over an ssh connection, well done!
  19.808 +You've got the server and client sorted out.  You should now be able
  19.809 +to use Mercurial to access repositories hosted by that username on
  19.810 +that server.  If you run into problems with Mercurial and ssh at this
  19.811 +point, try using the <option role="hg-opt-global">--debug</option> option to get a clearer picture
  19.812 +of what's going on.
  19.813 +</para>
  19.814 +
  19.815 +</sect2>
  19.816 +<sect2>
  19.817 +<title>Using compression with ssh</title>
  19.818 +
  19.819 +<para>Mercurial does not compress data when it uses the ssh protocol,
  19.820 +because the ssh protocol can transparently compress data.  However,
  19.821 +the default behaviour of ssh clients is <emphasis>not</emphasis> to request
  19.822 +compression.
  19.823 +</para>
  19.824 +
  19.825 +<para>Over any network other than a fast LAN (even a wireless network),
  19.826 +using compression is likely to significantly speed up Mercurial's
  19.827 +network operations.  For example, over a WAN, someone measured
  19.828 +compression as reducing the amount of time required to clone a
  19.829 +particularly large repository from 51 minutes to 17 minutes.
  19.830 +</para>
  19.831 +
  19.832 +<para>Both <command>ssh</command> and <command>plink</command> accept a <option role="cmd-opt-ssh">-C</option>
  19.833 +option which turns on compression.  You can easily edit your <filename role="special"> /.hgrc</filename>\ to
  19.834 +enable compression for all of Mercurial's uses of the ssh protocol.
  19.835 +</para>
  19.836 +<programlisting>
  19.837 +<para>  [ui]
  19.838 +  ssh = ssh -C
  19.839 +</para>
  19.840 +</programlisting>
  19.841 +
  19.842 +<para>If you use <command>ssh</command>, you can configure it to always use
  19.843 +compression when talking to your server.  To do this, edit your
  19.844 +<filename role="special">.ssh/config</filename> file (which may not yet exist), as follows.
  19.845 +</para>
  19.846 +<programlisting>
  19.847 +<para>  Host hg
  19.848 +    Compression yes
  19.849 +    HostName hg.example.com
  19.850 +</para>
  19.851 +</programlisting>
  19.852 +<para>This defines an alias, <literal>hg</literal>.  When you use it on the
  19.853 +<command>ssh</command> command line or in a Mercurial <literal>ssh</literal>-protocol
  19.854 +URL, it will cause <command>ssh</command> to connect to <literal>hg.example.com</literal>
  19.855 +and use compression.  This gives you both a shorter name to type and
  19.856 +compression, each of which is a good thing in its own right.
  19.857 +</para>
  19.858 +
  19.859 +</sect2>
  19.860 +</sect1>
  19.861 +<sect1>
  19.862 +<title>Serving over HTTP using CGI</title>
  19.863 +<para>\label{sec:collab:cgi}
  19.864 +</para>
  19.865 +
  19.866 +<para>Depending on how ambitious you are, configuring Mercurial's CGI
  19.867 +interface can take anything from a few moments to several hours.
  19.868 +</para>
  19.869 +
  19.870 +<para>We'll begin with the simplest of examples, and work our way towards a
  19.871 +more complex configuration.  Even for the most basic case, you're
  19.872 +almost certainly going to need to read and modify your web server's
  19.873 +configuration.
  19.874 +</para>
  19.875 +
  19.876 +<note>
  19.877 +<para>  Configuring a web server is a complex, fiddly, and highly
  19.878 +  system-dependent activity.  I can't possibly give you instructions
  19.879 +  that will cover anything like all of the cases you will encounter.
  19.880 +  Please use your discretion and judgment in following the sections
  19.881 +  below.  Be prepared to make plenty of mistakes, and to spend a lot
  19.882 +  of time reading your server's error logs.
  19.883 +</para>
  19.884 +</note>
  19.885 +
  19.886 +<sect2>
  19.887 +<title>Web server configuration checklist</title>
  19.888 +
  19.889 +<para>Before you continue, do take a few moments to check a few aspects of
  19.890 +your system's setup.
  19.891 +</para>
  19.892 +
  19.893 +<orderedlist>
  19.894 +<listitem><para>Do you have a web server installed at all?  Mac OS X ships with
  19.895 +  Apache, but many other systems may not have a web server installed.
  19.896 +</para>
  19.897 +</listitem>
  19.898 +<listitem><para>If you have a web server installed, is it actually running?  On
  19.899 +  most systems, even if one is present, it will be disabled by
  19.900 +  default.
  19.901 +</para>
  19.902 +</listitem>
  19.903 +<listitem><para>Is your server configured to allow you to run CGI programs in
  19.904 +  the directory where you plan to do so?  Most servers default to
  19.905 +  explicitly disabling the ability to run CGI programs.
  19.906 +</para>
  19.907 +</listitem></orderedlist>
  19.908 +
  19.909 +<para>If you don't have a web server installed, and don't have substantial
  19.910 +experience configuring Apache, you should consider using the
  19.911 +<literal>lighttpd</literal> web server instead of Apache.  Apache has a
  19.912 +well-deserved reputation for baroque and confusing configuration.
  19.913 +While <literal>lighttpd</literal> is less capable in some ways than Apache, most
  19.914 +of these capabilities are not relevant to serving Mercurial
  19.915 +repositories.  And <literal>lighttpd</literal> is undeniably <emphasis>much</emphasis> easier
  19.916 +to get started with than Apache.
  19.917 +</para>
  19.918 +
  19.919 +</sect2>
  19.920 +<sect2>
  19.921 +<title>Basic CGI configuration</title>
  19.922 +
  19.923 +<para>On Unix-like systems, it's common for users to have a subdirectory
  19.924 +named something like <filename class="directory">public_html</filename> in their home directory,
  19.925 +from which they can serve up web pages.  A file named <filename>foo</filename>
  19.926 +in this directory will be accessible at a URL of the form
  19.927 +<literal>http://www.example.com/\ {</literal>username/foo}.
  19.928 +</para>
  19.929 +
  19.930 +<para>To get started, find the <filename role="special">hgweb.cgi</filename> script that should be
  19.931 +present in your Mercurial installation.  If you can't quickly find a
  19.932 +local copy on your system, simply download one from the master
  19.933 +Mercurial repository at
  19.934 +<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>.
  19.935 +</para>
  19.936 +
  19.937 +<para>You'll need to copy this script into your <filename class="directory">public_html</filename>
  19.938 +directory, and ensure that it's executable.
  19.939 +</para>
  19.940 +<programlisting>
  19.941 +<para>  cp .../hgweb.cgi  /public_html
  19.942 +  chmod 755  /public_html/hgweb.cgi
  19.943 +</para>
  19.944 +</programlisting>
  19.945 +<para>The <literal>755</literal> argument to <command>chmod</command> is a little more general
  19.946 +than just making the script executable: it ensures that the script is
  19.947 +executable by anyone, and that <quote>group</quote> and <quote>other</quote> write
  19.948 +permissions are <emphasis>not</emphasis> set.  If you were to leave those write
  19.949 +permissions enabled, Apache's <literal>suexec</literal> subsystem would likely
  19.950 +refuse to execute the script.  In fact, <literal>suexec</literal> also insists
  19.951 +that the <emphasis>directory</emphasis> in which the script resides must not be
  19.952 +writable by others.
  19.953 +</para>
  19.954 +<programlisting>
  19.955 +<para>  chmod 755  /public_html
  19.956 +</para>
  19.957 +</programlisting>
  19.958 +
  19.959 +<sect3>
  19.960 +<title>What could <emphasis>possibly</emphasis> go wrong?</title>
  19.961 +<para>\label{sec:collab:wtf}
  19.962 +</para>
  19.963 +
  19.964 +<para>Once you've copied the CGI script into place, go into a web browser,
  19.965 +and try to open the URL <ulink url="http://myhostname/ myuser/hgweb.cgi">http://myhostname/ myuser/hgweb.cgi</ulink>,
  19.966 +<emphasis>but</emphasis> brace yourself for instant failure.  There's a high
  19.967 +probability that trying to visit this URL will fail, and there are
  19.968 +many possible reasons for this.  In fact, you're likely to stumble
  19.969 +over almost every one of the possible errors below, so please read
  19.970 +carefully.  The following are all of the problems I ran into on a
  19.971 +system running Fedora 7, with a fresh installation of Apache, and a
  19.972 +user account that I created specially to perform this exercise.
  19.973 +</para>
  19.974 +
  19.975 +<para>Your web server may have per-user directories disabled.  If you're
  19.976 +using Apache, search your config file for a <literal>UserDir</literal>
  19.977 +directive.  If there's none present, per-user directories will be
  19.978 +disabled.  If one exists, but its value is <literal>disabled</literal>, then
  19.979 +per-user directories will be disabled.  Otherwise, the string after
  19.980 +<literal>UserDir</literal> gives the name of the subdirectory that Apache will
  19.981 +look in under your home directory, for example <filename class="directory">public_html</filename>.
  19.982 +</para>
  19.983 +
  19.984 +<para>Your file access permissions may be too restrictive.  The web server
  19.985 +must be able to traverse your home directory and directories under
  19.986 +your <filename class="directory">public_html</filename> directory, and read files under the latter
  19.987 +too.  Here's a quick recipe to help you to make your permissions more
  19.988 +appropriate.
  19.989 +</para>
  19.990 +<programlisting>
  19.991 +<para>  chmod 755  
  19.992 +  find  /public_html -type d -print0 | xargs -0r chmod 755
  19.993 +  find  /public_html -type f -print0 | xargs -0r chmod 644
  19.994 +</para>
  19.995 +</programlisting>
  19.996 +
  19.997 +<para>The other possibility with permissions is that you might get a
  19.998 +completely empty window when you try to load the script.  In this
  19.999 +case, it's likely that your access permissions are \emph{too
 19.1000 +  permissive}.  Apache's <literal>suexec</literal> subsystem won't execute a
 19.1001 +script that's group- or world-writable, for example.
 19.1002 +</para>
 19.1003 +
 19.1004 +<para>Your web server may be configured to disallow execution of CGI
 19.1005 +programs in your per-user web directory.  Here's Apache's
 19.1006 +default per-user configuration from my Fedora system.
 19.1007 +</para>
 19.1008 +<programlisting>
 19.1009 +<para>  &lt;Directory /home/*/public_html&gt;
 19.1010 +      AllowOverride FileInfo AuthConfig Limit
 19.1011 +      Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
 19.1012 +      &lt;Limit GET POST OPTIONS&gt;
 19.1013 +          Order allow,deny
 19.1014 +          Allow from all
 19.1015 +      &lt;/Limit&gt;
 19.1016 +      &lt;LimitExcept GET POST OPTIONS&gt;
 19.1017 +          Order deny,allow
 19.1018 +          Deny from all
 19.1019 +      &lt;/LimitExcept&gt;
 19.1020 +  &lt;/Directory&gt;
 19.1021 +</para>
 19.1022 +</programlisting>
 19.1023 +<para>If you find a similar-looking <literal>Directory</literal> group in your Apache
 19.1024 +configuration, the directive to look at inside it is <literal>Options</literal>.
 19.1025 +Add <literal>ExecCGI</literal> to the end of this list if it's missing, and
 19.1026 +restart the web server.
 19.1027 +</para>
 19.1028 +
 19.1029 +<para>If you find that Apache serves you the text of the CGI script instead
 19.1030 +of executing it, you may need to either uncomment (if already present)
 19.1031 +or add a directive like this.
 19.1032 +</para>
 19.1033 +<programlisting>
 19.1034 +<para>  AddHandler cgi-script .cgi
 19.1035 +</para>
 19.1036 +</programlisting>
 19.1037 +
 19.1038 +<para>The next possibility is that you might be served with a colourful
 19.1039 +Python backtrace claiming that it can't import a
 19.1040 +<literal>mercurial</literal>-related module.  This is actually progress!  The
 19.1041 +server is now capable of executing your CGI script.  This error is
 19.1042 +only likely to occur if you're running a private installation of
 19.1043 +Mercurial, instead of a system-wide version.  Remember that the web
 19.1044 +server runs the CGI program without any of the environment variables
 19.1045 +that you take for granted in an interactive session.  If this error
 19.1046 +happens to you, edit your copy of <filename role="special">hgweb.cgi</filename> and follow the
 19.1047 +directions inside it to correctly set your <envar>PYTHONPATH</envar>
 19.1048 +environment variable.
 19.1049 +</para>
 19.1050 +
 19.1051 +<para>Finally, you are <emphasis>certain</emphasis> to by served with another colourful
 19.1052 +Python backtrace: this one will complain that it can't find
 19.1053 +<filename class="directory">/path/to/repository</filename>.  Edit your <filename role="special">hgweb.cgi</filename> script
 19.1054 +and replace the <filename class="directory">/path/to/repository</filename> string with the complete
 19.1055 +path to the repository you want to serve up.
 19.1056 +</para>
 19.1057 +
 19.1058 +<para>At this point, when you try to reload the page, you should be
 19.1059 +presented with a nice HTML view of your repository's history.  Whew!
 19.1060 +</para>
 19.1061 +
 19.1062 +</sect3>
 19.1063 +<sect3>
 19.1064 +<title>Configuring lighttpd</title>
 19.1065 +
 19.1066 +<para>To be exhaustive in my experiments, I tried configuring the
 19.1067 +increasingly popular <literal>lighttpd</literal> web server to serve the same
 19.1068 +repository as I described with Apache above.  I had already overcome
 19.1069 +all of the problems I outlined with Apache, many of which are not
 19.1070 +server-specific.  As a result, I was fairly sure that my file and
 19.1071 +directory permissions were good, and that my <filename role="special">hgweb.cgi</filename>
 19.1072 +script was properly edited.
 19.1073 +</para>
 19.1074 +
 19.1075 +<para>Once I had Apache running, getting <literal>lighttpd</literal> to serve the
 19.1076 +repository was a snap (in other words, even if you're trying to use
 19.1077 +<literal>lighttpd</literal>, you should read the Apache section).  I first had
 19.1078 +to edit the <literal>mod_access</literal> section of its config file to enable
 19.1079 +<literal>mod_cgi</literal> and <literal>mod_userdir</literal>, both of which were
 19.1080 +disabled by default on my system.  I then added a few lines to the end
 19.1081 +of the config file, to configure these modules.
 19.1082 +</para>
 19.1083 +<programlisting>
 19.1084 +<para>  userdir.path = "public_html"
 19.1085 +  cgi.assign = ( ".cgi" =&gt; "" )
 19.1086 +</para>
 19.1087 +</programlisting>
 19.1088 +<para>With this done, <literal>lighttpd</literal> ran immediately for me.  If I had
 19.1089 +configured <literal>lighttpd</literal> before Apache, I'd almost certainly have
 19.1090 +run into many of the same system-level configuration problems as I did
 19.1091 +with Apache.  However, I found <literal>lighttpd</literal> to be noticeably
 19.1092 +easier to configure than Apache, even though I've used Apache for over
 19.1093 +a decade, and this was my first exposure to <literal>lighttpd</literal>.
 19.1094 +</para>
 19.1095 +
 19.1096 +</sect3>
 19.1097 +</sect2>
 19.1098 +<sect2>
 19.1099 +<title>Sharing multiple repositories with one CGI script</title>
 19.1100 +
 19.1101 +<para>The <filename role="special">hgweb.cgi</filename> script only lets you publish a single
 19.1102 +repository, which is an annoying restriction.  If you want to publish
 19.1103 +more than one without wracking yourself with multiple copies of the
 19.1104 +same script, each with different names, a better choice is to use the
 19.1105 +<filename role="special">hgwebdir.cgi</filename> script.
 19.1106 +</para>
 19.1107 +
 19.1108 +<para>The procedure to configure <filename role="special">hgwebdir.cgi</filename> is only a little
 19.1109 +more involved than for <filename role="special">hgweb.cgi</filename>.  First, you must obtain
 19.1110 +a copy of the script.  If you don't have one handy, you can download a
 19.1111 +copy from the master Mercurial repository at
 19.1112 +<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>.
 19.1113 +</para>
 19.1114 +
 19.1115 +<para>You'll need to copy this script into your <filename class="directory">public_html</filename>
 19.1116 +directory, and ensure that it's executable.
 19.1117 +</para>
 19.1118 +<programlisting>
 19.1119 +<para>  cp .../hgwebdir.cgi  /public_html
 19.1120 +  chmod 755  /public_html  /public_html/hgwebdir.cgi
 19.1121 +</para>
 19.1122 +</programlisting>
 19.1123 +<para>With basic configuration out of the way, try to visit
 19.1124 +<ulink url="http://myhostname/ myuser/hgwebdir.cgi">http://myhostname/ myuser/hgwebdir.cgi</ulink> in your browser.  It
 19.1125 +should display an empty list of repositories.  If you get a blank
 19.1126 +window or error message, try walking through the list of potential
 19.1127 +problems in section <xref linkend="sec:collab:wtf"/>.
 19.1128 +</para>
 19.1129 +
 19.1130 +<para>The <filename role="special">hgwebdir.cgi</filename> script relies on an external
 19.1131 +configuration file.  By default, it searches for a file named
 19.1132 +<filename role="special">hgweb.config</filename> in the same directory as itself.  You'll need
 19.1133 +to create this file, and make it world-readable.  The format of the
 19.1134 +file is similar to a Windows <quote>ini</quote> file, as understood by Python's
 19.1135 +<literal>ConfigParser</literal> <citation>web:configparser</citation> module.
 19.1136 +</para>
 19.1137 +
 19.1138 +<para>The easiest way to configure <filename role="special">hgwebdir.cgi</filename> is with a
 19.1139 +section named <literal>collections</literal>.  This will automatically publish
 19.1140 +<emphasis>every</emphasis> repository under the directories you name.  The section
 19.1141 +should look like this:
 19.1142 +</para>
 19.1143 +<programlisting>
 19.1144 +<para>  [collections]
 19.1145 +  /my/root = /my/root
 19.1146 +</para>
 19.1147 +</programlisting>
 19.1148 +<para>Mercurial interprets this by looking at the directory name on the
 19.1149 +<emphasis>right</emphasis> hand side of the <quote><literal>=</literal></quote> sign; finding
 19.1150 +repositories in that directory hierarchy; and using the text on the
 19.1151 +<emphasis>left</emphasis> to strip off matching text from the names it will actually
 19.1152 +list in the web interface.  The remaining component of a path after
 19.1153 +this stripping has occurred is called a <quote>virtual path</quote>.
 19.1154 +</para>
 19.1155 +
 19.1156 +<para>Given the example above, if we have a repository whose local path is
 19.1157 +<filename class="directory">/my/root/this/repo</filename>, the CGI script will strip the leading
 19.1158 +<filename class="directory">/my/root</filename> from the name, and publish the repository with a
 19.1159 +virtual path of <filename class="directory">this/repo</filename>.  If the base URL for our CGI
 19.1160 +script is <ulink url="http://myhostname/ myuser/hgwebdir.cgi">http://myhostname/ myuser/hgwebdir.cgi</ulink>, the complete
 19.1161 +URL for that repository will be
 19.1162 +<ulink url="http://myhostname/ myuser/hgwebdir.cgi/this/repo">http://myhostname/ myuser/hgwebdir.cgi/this/repo</ulink>.
 19.1163 +</para>
 19.1164 +
 19.1165 +<para>If we replace <filename class="directory">/my/root</filename> on the left hand side of this example
 19.1166 +with <filename class="directory">/my</filename>, then <filename role="special">hgwebdir.cgi</filename> will only strip off
 19.1167 +<filename class="directory">/my</filename> from the repository name, and will give us a virtual
 19.1168 +path of <filename class="directory">root/this/repo</filename> instead of <filename class="directory">this/repo</filename>.
 19.1169 +</para>
 19.1170 +
 19.1171 +<para>The <filename role="special">hgwebdir.cgi</filename> script will recursively search each
 19.1172 +directory listed in the <literal>collections</literal> section of its
 19.1173 +configuration file, but it will <literal>not</literal> recurse into the
 19.1174 +repositories it finds.
 19.1175 +</para>
 19.1176 +
 19.1177 +<para>The <literal>collections</literal> mechanism makes it easy to publish many
 19.1178 +repositories in a <quote>fire and forget</quote> manner.  You only need to set up
 19.1179 +the CGI script and configuration file one time.  Afterwards, you can
 19.1180 +publish or unpublish a repository at any time by simply moving it
 19.1181 +into, or out of, the directory hierarchy in which you've configured
 19.1182 +<filename role="special">hgwebdir.cgi</filename> to look.
 19.1183 +</para>
 19.1184 +
 19.1185 +<sect3>
 19.1186 +<title>Explicitly specifying which repositories to publish</title>
 19.1187 +
 19.1188 +<para>In addition to the <literal>collections</literal> mechanism, the
 19.1189 +<filename role="special">hgwebdir.cgi</filename> script allows you to publish a specific list
 19.1190 +of repositories.  To do so, create a <literal>paths</literal> section, with
 19.1191 +contents of the following form.
 19.1192 +</para>
 19.1193 +<programlisting>
 19.1194 +<para>  [paths]
 19.1195 +  repo1 = /my/path/to/some/repo
 19.1196 +  repo2 = /some/path/to/another
 19.1197 +</para>
 19.1198 +</programlisting>
 19.1199 +<para>In this case, the virtual path (the component that will appear in a
 19.1200 +URL) is on the left hand side of each definition, while the path to
 19.1201 +the repository is on the right.  Notice that there does not need to be
 19.1202 +any relationship between the virtual path you choose and the location
 19.1203 +of a repository in your filesystem.
 19.1204 +</para>
 19.1205 +
 19.1206 +<para>If you wish, you can use both the <literal>collections</literal> and
 19.1207 +<literal>paths</literal> mechanisms simultaneously in a single configuration
 19.1208 +file.
 19.1209 +</para>
 19.1210 +
 19.1211 +<note>
 19.1212 +<para>  If multiple repositories have the same virtual path,
 19.1213 +  <filename role="special">hgwebdir.cgi</filename> will not report an error.  Instead, it will
 19.1214 +  behave unpredictably.
 19.1215 +</para>
 19.1216 +</note>
 19.1217 +
 19.1218 +</sect3>
 19.1219 +</sect2>
 19.1220 +<sect2>
 19.1221 +<title>Downloading source archives</title>
 19.1222 +
 19.1223 +<para>Mercurial's web interface lets users download an archive of any
 19.1224 +revision.  This archive will contain a snapshot of the working
 19.1225 +directory as of that revision, but it will not contain a copy of the
 19.1226 +repository data.
 19.1227 +</para>
 19.1228 +
 19.1229 +<para>By default, this feature is not enabled.  To enable it, you'll need to
 19.1230 +add an <envar role="rc-item-web">allow_archive</envar> item to the <literal role="rc-web">web</literal>
 19.1231 +section of your <filename role="special"> /.hgrc</filename>.
 19.1232 +</para>
 19.1233 +
 19.1234 +</sect2>
 19.1235 +<sect2>
 19.1236 +<title>Web configuration options</title>
 19.1237 +
 19.1238 +<para>Mercurial's web interfaces (the <command role="hg-cmd">hg serve</command> command, and the
 19.1239 +<filename role="special">hgweb.cgi</filename> and <filename role="special">hgwebdir.cgi</filename> scripts) have a
 19.1240 +number of configuration options that you can set.  These belong in a
 19.1241 +section named <literal role="rc-web">web</literal>.
 19.1242 +</para>
 19.1243 +<itemizedlist>
 19.1244 +<listitem><para><envar role="rc-item-web">allow_archive</envar>: Determines which (if any) archive
 19.1245 +  download mechanisms Mercurial supports.  If you enable this
 19.1246 +  feature, users of the web interface will be able to download an
 19.1247 +  archive of whatever revision of a repository they are viewing.
 19.1248 +  To enable the archive feature, this item must take the form of a
 19.1249 +  sequence of words drawn from the list below.
 19.1250 +</para>
 19.1251 +</listitem><itemizedlist>
 19.1252 +<listitem><para>  \item <literal>bz2</literal>: A <command>tar</command> archive, compressed using
 19.1253 +    <literal>bzip2</literal> compression.  This has the best compression ratio,
 19.1254 +    but uses the most CPU time on the server.
 19.1255 +  \item <literal>gz</literal>: A <command>tar</command> archive, compressed using
 19.1256 +    <literal>gzip</literal> compression.
 19.1257 +  \item <literal>zip</literal>: A <command>zip</command> archive, compressed using LZW
 19.1258 +    compression.  This format has the worst compression ratio, but is
 19.1259 +    widely used in the Windows world.
 19.1260 +</para>
 19.1261 +</listitem></itemizedlist>
 19.1262 +<para>  If you provide an empty list, or don't have an
 19.1263 +  <envar role="rc-item-web">allow_archive</envar> entry at all, this feature will be
 19.1264 +  disabled.  Here is an example of how to enable all three supported
 19.1265 +  formats.
 19.1266 +</para>
 19.1267 +<programlisting>
 19.1268 +<para>    [web]
 19.1269 +    allow_archive = bz2 gz zip
 19.1270 +</para>
 19.1271 +</programlisting>
 19.1272 +<listitem><para><envar role="rc-item-web">allowpull</envar>: Boolean.  Determines whether the web
 19.1273 +  interface allows remote users to <command role="hg-cmd">hg pull</command> and <command role="hg-cmd">hg clone</command> this
 19.1274 +  repository over HTTP.  If set to <literal>no</literal> or <literal>false</literal>, only
 19.1275 +  the <quote>human-oriented</quote> portion of the web interface is available.
 19.1276 +</para>
 19.1277 +</listitem>
 19.1278 +<listitem><para><envar role="rc-item-web">contact</envar>: String.  A free-form (but preferably
 19.1279 +  brief) string identifying the person or group in charge of the
 19.1280 +  repository.  This often contains the name and email address of a
 19.1281 +  person or mailing list.  It often makes sense to place this entry in
 19.1282 +  a repository's own <filename role="special">.hg/hgrc</filename> file, but it can make sense
 19.1283 +  to use in a global <filename role="special"> /.hgrc</filename>\ if every repository has a single
 19.1284 +  maintainer.
 19.1285 +</para>
 19.1286 +</listitem>
 19.1287 +<listitem><para><envar role="rc-item-web">maxchanges</envar>: Integer.  The default maximum number
 19.1288 +  of changesets to display in a single page of output.
 19.1289 +</para>
 19.1290 +</listitem>
 19.1291 +<listitem><para><envar role="rc-item-web">maxfiles</envar>: Integer.  The default maximum number
 19.1292 +  of modified files to display in a single page of output.
 19.1293 +</para>
 19.1294 +</listitem>
 19.1295 +<listitem><para><envar role="rc-item-web">stripes</envar>: Integer.  If the web interface displays
 19.1296 +  alternating <quote>stripes</quote> to make it easier to visually align rows
 19.1297 +  when you are looking at a table, this number controls the number of
 19.1298 +  rows in each stripe.
 19.1299 +</para>
 19.1300 +</listitem>
 19.1301 +<listitem><para><envar role="rc-item-web">style</envar>: Controls the template Mercurial uses to
 19.1302 +  display the web interface.  Mercurial ships with two web templates,
 19.1303 +  named <literal>default</literal> and <literal>gitweb</literal> (the latter is much more
 19.1304 +  visually attractive).  You can also specify a custom template of
 19.1305 +  your own; see chapter <xref linkend="chap:template"/> for details.  Here, you
 19.1306 +  can see how to enable the <literal>gitweb</literal> style.
 19.1307 +</para>
 19.1308 +</listitem><programlisting>
 19.1309 +<listitem><para>    [web]
 19.1310 +    style = gitweb
 19.1311 +</para>
 19.1312 +</listitem></programlisting>
 19.1313 +</para>
 19.1314 +</listitem>
 19.1315 +<listitem><para><envar role="rc-item-web">templates</envar>: Path.  The directory in which to search
 19.1316 +  for template files.  By default, Mercurial searches in the directory
 19.1317 +  in which it was installed.
 19.1318 +</para>
 19.1319 +</listitem></itemizedlist>
 19.1320 +<para>If you are using <filename role="special">hgwebdir.cgi</filename>, you can place a few
 19.1321 +configuration items in a <literal role="rc-web">web</literal> section of the
 19.1322 +<filename role="special">hgweb.config</filename> file instead of a <filename role="special"> /.hgrc</filename>\ file, for
 19.1323 +convenience.  These items are <envar role="rc-item-web">motd</envar> and
 19.1324 +<envar role="rc-item-web">style</envar>.
 19.1325 +</para>
 19.1326 +
 19.1327 +<sect3>
 19.1328 +<title>Options specific to an individual repository</title>
 19.1329 +
 19.1330 +<para>A few <literal role="rc-web">web</literal> configuration items ought to be placed in a
 19.1331 +repository's local <filename role="special">.hg/hgrc</filename>, rather than a user's or
 19.1332 +global <filename role="special"> /.hgrc</filename>.
 19.1333 +</para>
 19.1334 +<itemizedlist>
 19.1335 +<listitem><para><envar role="rc-item-web">description</envar>: String.  A free-form (but preferably
 19.1336 +  brief) string that describes the contents or purpose of the
 19.1337 +  repository.
 19.1338 +</para>
 19.1339 +</listitem>
 19.1340 +<listitem><para><envar role="rc-item-web">name</envar>: String.  The name to use for the repository
 19.1341 +  in the web interface.  This overrides the default name, which is the
 19.1342 +  last component of the repository's path.
 19.1343 +</para>
 19.1344 +</listitem></itemizedlist>
 19.1345 +
 19.1346 +</sect3>
 19.1347 +<sect3>
 19.1348 +<title>Options specific to the <command role="hg-cmd">hg serve</command> command</title>
 19.1349 +
 19.1350 +<para>Some of the items in the <literal role="rc-web">web</literal> section of a <filename role="special"> /.hgrc</filename>\ file are
 19.1351 +only for use with the <command role="hg-cmd">hg serve</command> command.
 19.1352 +</para>
 19.1353 +<itemizedlist>
 19.1354 +<listitem><para><envar role="rc-item-web">accesslog</envar>: Path.  The name of a file into which to
 19.1355 +  write an access log.  By default, the <command role="hg-cmd">hg serve</command> command writes
 19.1356 +  this information to standard output, not to a file.  Log entries are
 19.1357 +  written in the standard <quote>combined</quote> file format used by almost all
 19.1358 +  web servers.
 19.1359 +</para>
 19.1360 +</listitem>
 19.1361 +<listitem><para><envar role="rc-item-web">address</envar>: String.  The local address on which the
 19.1362 +  server should listen for incoming connections.  By default, the
 19.1363 +  server listens on all addresses.
 19.1364 +</para>
 19.1365 +</listitem>
 19.1366 +<listitem><para><envar role="rc-item-web">errorlog</envar>: Path.  The name of a file into which to
 19.1367 +  write an error log.  By default, the <command role="hg-cmd">hg serve</command> command writes this
 19.1368 +  information to standard error, not to a file.
 19.1369 +</para>
 19.1370 +</listitem>
 19.1371 +<listitem><para><envar role="rc-item-web">ipv6</envar>: Boolean.  Whether to use the IPv6 protocol.
 19.1372 +  By default, IPv6 is not used.
 19.1373 +</para>
 19.1374 +</listitem>
 19.1375 +<listitem><para><envar role="rc-item-web">port</envar>: Integer.  The TCP port number on which the
 19.1376 +  server should listen.  The default port number used is 8000.
 19.1377 +</para>
 19.1378 +</listitem></itemizedlist>
 19.1379 +
 19.1380 +<para>\subsubsection{Choosing the right <filename role="special"> /.hgrc</filename>\ file to add <literal role="rc-web">web</literal>
 19.1381 +  items to}
 19.1382 +</para>
 19.1383 +
 19.1384 +<para>It is important to remember that a web server like Apache or
 19.1385 +<literal>lighttpd</literal> will run under a user ID that is different to yours.
 19.1386 +CGI scripts run by your server, such as <filename role="special">hgweb.cgi</filename>, will
 19.1387 +usually also run under that user ID.
 19.1388 +</para>
 19.1389 +
 19.1390 +<para>If you add <literal role="rc-web">web</literal> items to your own personal <filename role="special"> /.hgrc</filename>\ file, CGI
 19.1391 +scripts won't read that <filename role="special"> /.hgrc</filename>\ file.  Those settings will thus only
 19.1392 +affect the behaviour of the <command role="hg-cmd">hg serve</command> command when you run it.  To
 19.1393 +cause CGI scripts to see your settings, either create a <filename role="special"> /.hgrc</filename>\ file in
 19.1394 +the home directory of the user ID that runs your web server, or add
 19.1395 +those settings to a system-wide <filename role="special"> /.hgrc</filename>\ file.
 19.1396 +</para>
 19.1397 +
 19.1398 +
 19.1399 +</sect3>
 19.1400 +</sect2>
 19.1401 +</sect1>
 19.1402 +</chapter>
 19.1403 +
 19.1404 +<!--
 19.1405 +local variables: 
 19.1406 +sgml-parent-document: ("00book.xml" "book" "chapter")
 19.1407 +end:
 19.1408 +-->
 19.1409 \ No newline at end of file
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/fr/ch07-filenames.xml	Sun Aug 16 04:58:01 2009 +0200
    20.3 @@ -0,0 +1,388 @@
    20.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    20.5 +
    20.6 +<chapter>
    20.7 +<title>File names and pattern matching</title>
    20.8 +<para>\label{chap:names}</para>
    20.9 +
   20.10 +<para>Mercurial provides mechanisms that let you work with file names in a
   20.11 +consistent and expressive way.</para>
   20.12 +
   20.13 +<sect1>
   20.14 +<title>Simple file naming</title>
   20.15 +
   20.16 +<para>Mercurial uses a unified piece of machinery <quote>under the hood</quote> to
   20.17 +handle file names.  Every command behaves uniformly with respect to
   20.18 +file names.  The way in which commands work with file names is as
   20.19 +follows.</para>
   20.20 +
   20.21 +<para>If you explicitly name real files on the command line, Mercurial works
   20.22 +with exactly those files, as you would expect.
   20.23 +<!-- &interaction.filenames.files; --></para>
   20.24 +
   20.25 +<para>When you provide a directory name, Mercurial will interpret this as
   20.26 +<quote>operate on every file in this directory and its subdirectories</quote>.
   20.27 +Mercurial traverses the files and subdirectories in a directory in
   20.28 +alphabetical order.  When it encounters a subdirectory, it will
   20.29 +traverse that subdirectory before continuing with the current
   20.30 +directory.
   20.31 +<!-- &interaction.filenames.dirs; --></para>
   20.32 +
   20.33 +</sect1>
   20.34 +<sect1>
   20.35 +<title>Running commands without any file names</title>
   20.36 +
   20.37 +<para>Mercurial's commands that work with file names have useful default
   20.38 +behaviours when you invoke them without providing any file names or
   20.39 +patterns.  What kind of behaviour you should expect depends on what
   20.40 +the command does.  Here are a few rules of thumb you can use to
   20.41 +predict what a command is likely to do if you don't give it any names
   20.42 +to work with.</para>
   20.43 +<itemizedlist>
   20.44 +<listitem><para>Most commands will operate on the entire working directory.
   20.45 +  This is what the <command role="hg-cmd">hg add</command> command does, for example.</para>
   20.46 +</listitem>
   20.47 +<listitem><para>If the command has effects that are difficult or impossible to
   20.48 +  reverse, it will force you to explicitly provide at least one name
   20.49 +  or pattern (see below).  This protects you from accidentally
   20.50 +  deleting files by running <command role="hg-cmd">hg remove</command> with no arguments, for
   20.51 +  example.</para>
   20.52 +</listitem></itemizedlist>
   20.53 +
   20.54 +<para>It's easy to work around these default behaviours if they don't suit
   20.55 +you.  If a command normally operates on the whole working directory,
   20.56 +you can invoke it on just the current directory and its subdirectories
   20.57 +by giving it the name <quote><filename class="directory">.</filename></quote>.
   20.58 +<!-- &interaction.filenames.wdir-subdir; -->
   20.59 +</para>
   20.60 +
   20.61 +<para>Along the same lines, some commands normally print file names relative
   20.62 +to the root of the repository, even if you're invoking them from a
   20.63 +subdirectory.  Such a command will print file names relative to your
   20.64 +subdirectory if you give it explicit names.  Here, we're going to run
   20.65 +<command role="hg-cmd">hg status</command> from a subdirectory, and get it to operate on the
   20.66 +entire working directory while printing file names relative to our
   20.67 +subdirectory, by passing it the output of the <command role="hg-cmd">hg root</command> command.
   20.68 +<!-- &interaction.filenames.wdir-relname; -->
   20.69 +</para>
   20.70 +
   20.71 +</sect1>
   20.72 +<sect1>
   20.73 +<title>Telling you what's going on</title>
   20.74 +
   20.75 +<para>The <command role="hg-cmd">hg add</command> example in the preceding section illustrates something
   20.76 +else that's helpful about Mercurial commands.  If a command operates
   20.77 +on a file that you didn't name explicitly on the command line, it will
   20.78 +usually print the name of the file, so that you will not be surprised
   20.79 +what's going on.
   20.80 +</para>
   20.81 +
   20.82 +<para>The principle here is of <emphasis>least surprise</emphasis>.  If you've exactly
   20.83 +named a file on the command line, there's no point in repeating it
   20.84 +back at you.  If Mercurial is acting on a file <emphasis>implicitly</emphasis>,
   20.85 +because you provided no names, or a directory, or a pattern (see
   20.86 +below), it's safest to tell you what it's doing.
   20.87 +</para>
   20.88 +
   20.89 +<para>For commands that behave this way, you can silence them using the
   20.90 +<option role="hg-opt-global">-q</option> option.  You can also get them to print the name of every
   20.91 +file, even those you've named explicitly, using the <option role="hg-opt-global">-v</option>
   20.92 +option.
   20.93 +</para>
   20.94 +
   20.95 +</sect1>
   20.96 +<sect1>
   20.97 +<title>Using patterns to identify files</title>
   20.98 +
   20.99 +<para>In addition to working with file and directory names, Mercurial lets
  20.100 +you use <emphasis>patterns</emphasis> to identify files.  Mercurial's pattern
  20.101 +handling is expressive.
  20.102 +</para>
  20.103 +
  20.104 +<para>On Unix-like systems (Linux, MacOS, etc.), the job of matching file
  20.105 +names to patterns normally falls to the shell.  On these systems, you
  20.106 +must explicitly tell Mercurial that a name is a pattern.  On Windows,
  20.107 +the shell does not expand patterns, so Mercurial will automatically
  20.108 +identify names that are patterns, and expand them for you.
  20.109 +</para>
  20.110 +
  20.111 +<para>To provide a pattern in place of a regular name on the command line,
  20.112 +the mechanism is simple:
  20.113 +</para>
  20.114 +<programlisting>
  20.115 +<para>  syntax:patternbody
  20.116 +</para>
  20.117 +</programlisting>
  20.118 +<para>That is, a pattern is identified by a short text string that says what
  20.119 +kind of pattern this is, followed by a colon, followed by the actual
  20.120 +pattern.
  20.121 +</para>
  20.122 +
  20.123 +<para>Mercurial supports two kinds of pattern syntax.  The most frequently
  20.124 +used is called <literal>glob</literal>; this is the same kind of pattern
  20.125 +matching used by the Unix shell, and should be familiar to Windows
  20.126 +command prompt users, too.
  20.127 +</para>
  20.128 +
  20.129 +<para>When Mercurial does automatic pattern matching on Windows, it uses
  20.130 +<literal>glob</literal> syntax.  You can thus omit the <quote><literal>glob:</literal></quote> prefix
  20.131 +on Windows, but it's safe to use it, too.
  20.132 +</para>
  20.133 +
  20.134 +<para>The <literal>re</literal> syntax is more powerful; it lets you specify patterns
  20.135 +using regular expressions, also known as regexps.
  20.136 +</para>
  20.137 +
  20.138 +<para>By the way, in the examples that follow, notice that I'm careful to
  20.139 +wrap all of my patterns in quote characters, so that they won't get
  20.140 +expanded by the shell before Mercurial sees them.
  20.141 +</para>
  20.142 +
  20.143 +<sect2>
  20.144 +<title>Shell-style <literal>glob</literal> patterns</title>
  20.145 +
  20.146 +<para>This is an overview of the kinds of patterns you can use when you're
  20.147 +matching on glob patterns.
  20.148 +</para>
  20.149 +
  20.150 +<para>The <quote><literal>*</literal></quote> character matches any string, within a single
  20.151 +directory.
  20.152 +<!-- &interaction.filenames.glob.star; -->
  20.153 +</para>
  20.154 +
  20.155 +<para>The <quote><literal>**</literal></quote> pattern matches any string, and crosses directory
  20.156 +boundaries.  It's not a standard Unix glob token, but it's accepted by
  20.157 +several popular Unix shells, and is very useful.
  20.158 +<!-- &interaction.filenames.glob.starstar; -->
  20.159 +</para>
  20.160 +
  20.161 +<para>The <quote><literal>?</literal></quote> pattern matches any single character.
  20.162 +<!-- &interaction.filenames.glob.question; -->
  20.163 +</para>
  20.164 +
  20.165 +<para>The <quote><literal>[</literal></quote> character begins a <emphasis>character class</emphasis>.  This
  20.166 +matches any single character within the class.  The class ends with a
  20.167 +<quote><literal>]</literal></quote> character.  A class may contain multiple <emphasis>range</emphasis>s
  20.168 +of the form <quote><literal>a-f</literal></quote>, which is shorthand for
  20.169 +<quote><literal>abcdef</literal></quote>.
  20.170 +<!-- &interaction.filenames.glob.range; -->
  20.171 +If the first character after the <quote><literal>[</literal></quote> in a character class
  20.172 +is a <quote><literal>!</literal></quote>, it <emphasis>negates</emphasis> the class, making it match any
  20.173 +single character not in the class.
  20.174 +</para>
  20.175 +
  20.176 +<para>A <quote><literal>{</literal></quote> begins a group of subpatterns, where the whole group
  20.177 +matches if any subpattern in the group matches.  The <quote><literal>,</literal></quote>
  20.178 +character separates subpatterns, and <quote>\texttt{}}</quote> ends the group.
  20.179 +<!-- &interaction.filenames.glob.group; -->
  20.180 +</para>
  20.181 +
  20.182 +<sect3>
  20.183 +<title>Watch out!</title>
  20.184 +
  20.185 +<para>Don't forget that if you want to match a pattern in any directory, you
  20.186 +should not be using the <quote><literal>*</literal></quote> match-any token, as this will
  20.187 +only match within one directory.  Instead, use the <quote><literal>**</literal></quote>
  20.188 +token.  This small example illustrates the difference between the two.
  20.189 +<!-- &interaction.filenames.glob.star-starstar; -->
  20.190 +</para>
  20.191 +
  20.192 +</sect3>
  20.193 +</sect2>
  20.194 +<sect2>
  20.195 +<title>Regular expression matching with <literal>re</literal> patterns</title>
  20.196 +
  20.197 +<para>Mercurial accepts the same regular expression syntax as the Python
  20.198 +programming language (it uses Python's regexp engine internally).
  20.199 +This is based on the Perl language's regexp syntax, which is the most
  20.200 +popular dialect in use (it's also used in Java, for example).
  20.201 +</para>
  20.202 +
  20.203 +<para>I won't discuss Mercurial's regexp dialect in any detail here, as
  20.204 +regexps are not often used.  Perl-style regexps are in any case
  20.205 +already exhaustively documented on a multitude of web sites, and in
  20.206 +many books.  Instead, I will focus here on a few things you should
  20.207 +know if you find yourself needing to use regexps with Mercurial.
  20.208 +</para>
  20.209 +
  20.210 +<para>A regexp is matched against an entire file name, relative to the root
  20.211 +of the repository.  In other words, even if you're already in
  20.212 +subbdirectory <filename class="directory">foo</filename>, if you want to match files under this
  20.213 +directory, your pattern must start with <quote><literal>foo/</literal></quote>.
  20.214 +</para>
  20.215 +
  20.216 +<para>One thing to note, if you're familiar with Perl-style regexps, is that
  20.217 +Mercurial's are <emphasis>rooted</emphasis>.  That is, a regexp starts matching
  20.218 +against the beginning of a string; it doesn't look for a match
  20.219 +anywhere within the string.  To match anywhere in a string, start
  20.220 +your pattern with <quote><literal>.*</literal></quote>.
  20.221 +</para>
  20.222 +
  20.223 +</sect2>
  20.224 +</sect1>
  20.225 +<sect1>
  20.226 +<title>Filtering files</title>
  20.227 +
  20.228 +<para>Not only does Mercurial give you a variety of ways to specify files;
  20.229 +it lets you further winnow those files using <emphasis>filters</emphasis>.  Commands
  20.230 +that work with file names accept two filtering options.
  20.231 +</para>
  20.232 +<itemizedlist>
  20.233 +<listitem><para><option role="hg-opt-global">-I</option>, or <option role="hg-opt-global">--include</option>, lets you specify a pattern
  20.234 +  that file names must match in order to be processed.
  20.235 +</para>
  20.236 +</listitem>
  20.237 +<listitem><para><option role="hg-opt-global">-X</option>, or <option role="hg-opt-global">--exclude</option>, gives you a way to
  20.238 +  <emphasis>avoid</emphasis> processing files, if they match this pattern.
  20.239 +</para>
  20.240 +</listitem></itemizedlist>
  20.241 +<para>You can provide multiple <option role="hg-opt-global">-I</option> and <option role="hg-opt-global">-X</option> options on the
  20.242 +command line, and intermix them as you please.  Mercurial interprets
  20.243 +the patterns you provide using glob syntax by default (but you can use
  20.244 +regexps if you need to).
  20.245 +</para>
  20.246 +
  20.247 +<para>You can read a <option role="hg-opt-global">-I</option> filter as <quote>process only the files that
  20.248 +match this filter</quote>.
  20.249 +<!-- &interaction.filenames.filter.include; -->
  20.250 +The <option role="hg-opt-global">-X</option> filter is best read as <quote>process only the files that
  20.251 +don't match this pattern</quote>.
  20.252 +<!-- &interaction.filenames.filter.exclude; -->
  20.253 +</para>
  20.254 +
  20.255 +</sect1>
  20.256 +<sect1>
  20.257 +<title>Ignoring unwanted files and directories</title>
  20.258 +
  20.259 +<para>XXX.
  20.260 +</para>
  20.261 +
  20.262 +</sect1>
  20.263 +<sect1>
  20.264 +<title>Case sensitivity</title>
  20.265 +<para>\label{sec:names:case}
  20.266 +</para>
  20.267 +
  20.268 +<para>If you're working in a mixed development environment that contains
  20.269 +both Linux (or other Unix) systems and Macs or Windows systems, you
  20.270 +should keep in the back of your mind the knowledge that they treat the
  20.271 +case (<quote>N</quote> versus <quote>n</quote>) of file names in incompatible ways.  This is
  20.272 +not very likely to affect you, and it's easy to deal with if it does,
  20.273 +but it could surprise you if you don't know about it.
  20.274 +</para>
  20.275 +
  20.276 +<para>Operating systems and filesystems differ in the way they handle the
  20.277 +<emphasis>case</emphasis> of characters in file and directory names.  There are
  20.278 +three common ways to handle case in names.
  20.279 +</para>
  20.280 +<itemizedlist>
  20.281 +<listitem><para>Completely case insensitive.  Uppercase and lowercase versions
  20.282 +  of a letter are treated as identical, both when creating a file and
  20.283 +  during subsequent accesses.  This is common on older DOS-based
  20.284 +  systems.
  20.285 +</para>
  20.286 +</listitem>
  20.287 +<listitem><para>Case preserving, but insensitive.  When a file or directory is
  20.288 +  created, the case of its name is stored, and can be retrieved and
  20.289 +  displayed by the operating system.  When an existing file is being
  20.290 +  looked up, its case is ignored.  This is the standard arrangement on
  20.291 +  Windows and MacOS.  The names <filename>foo</filename> and <filename>FoO</filename>
  20.292 +  identify the same file.  This treatment of uppercase and lowercase
  20.293 +  letters as interchangeable is also referred to as \emph{case
  20.294 +    folding}.
  20.295 +</para>
  20.296 +</listitem>
  20.297 +<listitem><para>Case sensitive.  The case of a name is significant at all times.
  20.298 +  The names <filename>foo</filename> and {FoO} identify different files.  This
  20.299 +  is the way Linux and Unix systems normally work.
  20.300 +</para>
  20.301 +</listitem></itemizedlist>
  20.302 +
  20.303 +<para>On Unix-like systems, it is possible to have any or all of the above
  20.304 +ways of handling case in action at once.  For example, if you use a
  20.305 +USB thumb drive formatted with a FAT32 filesystem on a Linux system,
  20.306 +Linux will handle names on that filesystem in a case preserving, but
  20.307 +insensitive, way.
  20.308 +</para>
  20.309 +
  20.310 +<sect2>
  20.311 +<title>Safe, portable repository storage</title>
  20.312 +
  20.313 +<para>Mercurial's repository storage mechanism is <emphasis>case safe</emphasis>.  It
  20.314 +translates file names so that they can be safely stored on both case
  20.315 +sensitive and case insensitive filesystems.  This means that you can
  20.316 +use normal file copying tools to transfer a Mercurial repository onto,
  20.317 +for example, a USB thumb drive, and safely move that drive and
  20.318 +repository back and forth between a Mac, a PC running Windows, and a
  20.319 +Linux box.
  20.320 +</para>
  20.321 +
  20.322 +</sect2>
  20.323 +<sect2>
  20.324 +<title>Detecting case conflicts</title>
  20.325 +
  20.326 +<para>When operating in the working directory, Mercurial honours the naming
  20.327 +policy of the filesystem where the working directory is located.  If
  20.328 +the filesystem is case preserving, but insensitive, Mercurial will
  20.329 +treat names that differ only in case as the same.
  20.330 +</para>
  20.331 +
  20.332 +<para>An important aspect of this approach is that it is possible to commit
  20.333 +a changeset on a case sensitive (typically Linux or Unix) filesystem
  20.334 +that will cause trouble for users on case insensitive (usually Windows
  20.335 +and MacOS) users.  If a Linux user commits changes to two files, one
  20.336 +named <filename>myfile.c</filename> and the other named <filename>MyFile.C</filename>,
  20.337 +they will be stored correctly in the repository.  And in the working
  20.338 +directories of other Linux users, they will be correctly represented
  20.339 +as separate files.
  20.340 +</para>
  20.341 +
  20.342 +<para>If a Windows or Mac user pulls this change, they will not initially
  20.343 +have a problem, because Mercurial's repository storage mechanism is
  20.344 +case safe.  However, once they try to <command role="hg-cmd">hg update</command> the working
  20.345 +directory to that changeset, or <command role="hg-cmd">hg merge</command> with that changeset,
  20.346 +Mercurial will spot the conflict between the two file names that the
  20.347 +filesystem would treat as the same, and forbid the update or merge
  20.348 +from occurring.
  20.349 +</para>
  20.350 +
  20.351 +</sect2>
  20.352 +<sect2>
  20.353 +<title>Fixing a case conflict</title>
  20.354 +
  20.355 +<para>If you are using Windows or a Mac in a mixed environment where some of
  20.356 +your collaborators are using Linux or Unix, and Mercurial reports a
  20.357 +case folding conflict when you try to <command role="hg-cmd">hg update</command> or <command role="hg-cmd">hg merge</command>,
  20.358 +the procedure to fix the problem is simple.
  20.359 +</para>
  20.360 +
  20.361 +<para>Just find a nearby Linux or Unix box, clone the problem repository
  20.362 +onto it, and use Mercurial's <command role="hg-cmd">hg rename</command> command to change the
  20.363 +names of any offending files or directories so that they will no
  20.364 +longer cause case folding conflicts.  Commit this change, <command role="hg-cmd">hg pull</command>
  20.365 +or <command role="hg-cmd">hg push</command> it across to your Windows or MacOS system, and
  20.366 +<command role="hg-cmd">hg update</command> to the revision with the non-conflicting names.
  20.367 +</para>
  20.368 +
  20.369 +<para>The changeset with case-conflicting names will remain in your
  20.370 +project's history, and you still won't be able to <command role="hg-cmd">hg update</command> your
  20.371 +working directory to that changeset on a Windows or MacOS system, but
  20.372 +you can continue development unimpeded.
  20.373 +</para>
  20.374 +
  20.375 +<note>
  20.376 +<para>  Prior to version 0.9.3, Mercurial did not use a case safe repository
  20.377 +  storage mechanism, and did not detect case folding conflicts.  If
  20.378 +  you are using an older version of Mercurial on Windows or MacOS, I
  20.379 +  strongly recommend that you upgrade.
  20.380 +</para>
  20.381 +</note>
  20.382 +
  20.383 +</sect2>
  20.384 +</sect1>
  20.385 +</chapter>
  20.386 +
  20.387 +<!--
  20.388 +local variables: 
  20.389 +sgml-parent-document: ("00book.xml" "book" "chapter")
  20.390 +end:
  20.391 +-->
  20.392 \ No newline at end of file
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/fr/ch08-branch.xml	Sun Aug 16 04:58:01 2009 +0200
    21.3 @@ -0,0 +1,473 @@
    21.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    21.5 +
    21.6 +<chapter>
    21.7 +<title>Managing releases and branchy development</title>
    21.8 +<para>\label{chap:branch}</para>
    21.9 +
   21.10 +<para>Mercurial provides several mechanisms for you to manage a project that
   21.11 +is making progress on multiple fronts at once.  To understand these
   21.12 +mechanisms, let's first take a brief look at a fairly normal software
   21.13 +project structure.</para>
   21.14 +
   21.15 +<para>Many software projects issue periodic <quote>major</quote> releases that contain
   21.16 +substantial new features.  In parallel, they may issue <quote>minor</quote>
   21.17 +releases.  These are usually identical to the major releases off which
   21.18 +they're based, but with a few bugs fixed.</para>
   21.19 +
   21.20 +<para>In this chapter, we'll start by talking about how to keep records of
   21.21 +project milestones such as releases.  We'll then continue on to talk
   21.22 +about the flow of work between different phases of a project, and how
   21.23 +Mercurial can help you to isolate and manage this work.</para>
   21.24 +
   21.25 +<sect1>
   21.26 +<title>Giving a persistent name to a revision</title>
   21.27 +
   21.28 +<para>Once you decide that you'd like to call a particular revision a
   21.29 +<quote>release</quote>, it's a good idea to record the identity of that revision.
   21.30 +This will let you reproduce that release at a later date, for whatever
   21.31 +purpose you might need at the time (reproducing a bug, porting to a
   21.32 +new platform, etc).
   21.33 +<!-- &interaction.tag.init; --></para>
   21.34 +
   21.35 +<para>Mercurial lets you give a permanent name to any revision using the
   21.36 +<command role="hg-cmd">hg tag</command> command.  Not surprisingly, these names are called
   21.37 +<quote>tags</quote>.
   21.38 +<!-- &interaction.tag.tag; --></para>
   21.39 +
   21.40 +<para>A tag is nothing more than a <quote>symbolic name</quote> for a revision.  Tags
   21.41 +exist purely for your convenience, so that you have a handy permanent
   21.42 +way to refer to a revision; Mercurial doesn't interpret the tag names
   21.43 +you use in any way.  Neither does Mercurial place any restrictions on
   21.44 +the name of a tag, beyond a few that are necessary to ensure that a
   21.45 +tag can be parsed unambiguously.  A tag name cannot contain any of the
   21.46 +following characters:</para>
   21.47 +<itemizedlist>
   21.48 +<listitem><para>Colon (ASCII 58, <quote><literal>:</literal></quote>)</para>
   21.49 +</listitem>
   21.50 +<listitem><para>Carriage return (ASCII 13, <quote><literal>\r</literal></quote>)
   21.51 +</para>
   21.52 +</listitem>
   21.53 +<listitem><para>Newline (ASCII 10, <quote><literal>\n</literal></quote>)
   21.54 +</para>
   21.55 +</listitem></itemizedlist>
   21.56 +
   21.57 +<para>You can use the <command role="hg-cmd">hg tags</command> command to display the tags present in
   21.58 +your repository.  In the output, each tagged revision is identified
   21.59 +first by its name, then by revision number, and finally by the unique
   21.60 +hash of the revision.
   21.61 +<!-- &interaction.tag.tags; -->
   21.62 +Notice that <literal>tip</literal> is listed in the output of <command role="hg-cmd">hg tags</command>.  The
   21.63 +<literal>tip</literal> tag is a special <quote>floating</quote> tag, which always
   21.64 +identifies the newest revision in the repository.
   21.65 +</para>
   21.66 +
   21.67 +<para>In the output of the <command role="hg-cmd">hg tags</command> command, tags are listed in reverse
   21.68 +order, by revision number.  This usually means that recent tags are
   21.69 +listed before older tags.  It also means that <literal>tip</literal> is always
   21.70 +going to be the first tag listed in the output of <command role="hg-cmd">hg tags</command>.
   21.71 +</para>
   21.72 +
   21.73 +<para>When you run <command role="hg-cmd">hg log</command>, if it displays a revision that has tags
   21.74 +associated with it, it will print those tags.
   21.75 +<!-- &interaction.tag.log; -->
   21.76 +</para>
   21.77 +
   21.78 +<para>Any time you need to provide a revision ID to a Mercurial command, the
   21.79 +command will accept a tag name in its place.  Internally, Mercurial
   21.80 +will translate your tag name into the corresponding revision ID, then
   21.81 +use that.
   21.82 +<!-- &interaction.tag.log.v1.0; -->
   21.83 +</para>
   21.84 +
   21.85 +<para>There's no limit on the number of tags you can have in a repository,
   21.86 +or on the number of tags that a single revision can have.  As a
   21.87 +practical matter, it's not a great idea to have <quote>too many</quote> (a number
   21.88 +which will vary from project to project), simply because tags are
   21.89 +supposed to help you to find revisions.  If you have lots of tags, the
   21.90 +ease of using them to identify revisions diminishes rapidly.
   21.91 +</para>
   21.92 +
   21.93 +<para>For example, if your project has milestones as frequent as every few
   21.94 +days, it's perfectly reasonable to tag each one of those.  But if you
   21.95 +have a continuous build system that makes sure every revision can be
   21.96 +built cleanly, you'd be introducing a lot of noise if you were to tag
   21.97 +every clean build.  Instead, you could tag failed builds (on the
   21.98 +assumption that they're rare!), or simply not use tags to track
   21.99 +buildability.
  21.100 +</para>
  21.101 +
  21.102 +<para>If you want to remove a tag that you no longer want, use
  21.103 +<command role="hg-cmd">hg tag --remove</command>.
  21.104 +<!-- &interaction.tag.remove; -->
  21.105 +You can also modify a tag at any time, so that it identifies a
  21.106 +different revision, by simply issuing a new <command role="hg-cmd">hg tag</command> command.
  21.107 +You'll have to use the <option role="hg-opt-tag">-f</option> option to tell Mercurial that
  21.108 +you <emphasis>really</emphasis> want to update the tag.
  21.109 +<!-- &interaction.tag.replace; -->
  21.110 +There will still be a permanent record of the previous identity of the
  21.111 +tag, but Mercurial will no longer use it.  There's thus no penalty to
  21.112 +tagging the wrong revision; all you have to do is turn around and tag
  21.113 +the correct revision once you discover your error.
  21.114 +</para>
  21.115 +
  21.116 +<para>Mercurial stores tags in a normal revision-controlled file in your
  21.117 +repository.  If you've created any tags, you'll find them in a file
  21.118 +named <filename role="special">.hgtags</filename>.  When you run the <command role="hg-cmd">hg tag</command> command,
  21.119 +Mercurial modifies this file, then automatically commits the change to
  21.120 +it.  This means that every time you run <command role="hg-cmd">hg tag</command>, you'll see a
  21.121 +corresponding changeset in the output of <command role="hg-cmd">hg log</command>.
  21.122 +<!-- &interaction.tag.tip; -->
  21.123 +</para>
  21.124 +
  21.125 +<sect2>
  21.126 +<title>Handling tag conflicts during a merge</title>
  21.127 +
  21.128 +<para>You won't often need to care about the <filename role="special">.hgtags</filename> file, but
  21.129 +it sometimes makes its presence known during a merge.  The format of
  21.130 +the file is simple: it consists of a series of lines.  Each line
  21.131 +starts with a changeset hash, followed by a space, followed by the
  21.132 +name of a tag.
  21.133 +</para>
  21.134 +
  21.135 +<para>If you're resolving a conflict in the <filename role="special">.hgtags</filename> file during
  21.136 +a merge, there's one twist to modifying the <filename role="special">.hgtags</filename> file:
  21.137 +when Mercurial is parsing the tags in a repository, it <emphasis>never</emphasis>
  21.138 +reads the working copy of the <filename role="special">.hgtags</filename> file.  Instead, it
  21.139 +reads the <emphasis>most recently committed</emphasis> revision of the file.
  21.140 +</para>
  21.141 +
  21.142 +<para>An unfortunate consequence of this design is that you can't actually
  21.143 +verify that your merged <filename role="special">.hgtags</filename> file is correct until
  21.144 +<emphasis>after</emphasis> you've committed a change.  So if you find yourself
  21.145 +resolving a conflict on <filename role="special">.hgtags</filename> during a merge, be sure to
  21.146 +run <command role="hg-cmd">hg tags</command> after you commit.  If it finds an error in the
  21.147 +<filename role="special">.hgtags</filename> file, it will report the location of the error,
  21.148 +which you can then fix and commit.  You should then run <command role="hg-cmd">hg tags</command>
  21.149 +again, just to be sure that your fix is correct.
  21.150 +</para>
  21.151 +
  21.152 +</sect2>
  21.153 +<sect2>
  21.154 +<title>Tags and cloning</title>
  21.155 +
  21.156 +<para>You may have noticed that the <command role="hg-cmd">hg clone</command> command has a
  21.157 +<option role="hg-opt-clone">-r</option> option that lets you clone an exact copy of the
  21.158 +repository as of a particular changeset.  The new clone will not
  21.159 +contain any project history that comes after the revision you
  21.160 +specified.  This has an interaction with tags that can surprise the
  21.161 +unwary.
  21.162 +</para>
  21.163 +
  21.164 +<para>Recall that a tag is stored as a revision to the <filename role="special">.hgtags</filename>
  21.165 +file, so that when you create a tag, the changeset in which it's
  21.166 +recorded necessarily refers to an older changeset.  When you run
  21.167 +<command role="hg-cmd">hg clone -r foo</command> to clone a repository as of tag
  21.168 +<literal>foo</literal>, the new clone \emph{will not contain the history that
  21.169 +  created the tag} that you used to clone the repository.  The result
  21.170 +is that you'll get exactly the right subset of the project's history
  21.171 +in the new repository, but <emphasis>not</emphasis> the tag you might have expected.
  21.172 +</para>
  21.173 +
  21.174 +</sect2>
  21.175 +<sect2>
  21.176 +<title>When permanent tags are too much</title>
  21.177 +
  21.178 +<para>Since Mercurial's tags are revision controlled and carried around with
  21.179 +a project's history, everyone you work with will see the tags you
  21.180 +create.  But giving names to revisions has uses beyond simply noting
  21.181 +that revision <literal>4237e45506ee</literal> is really <literal>v2.0.2</literal>.  If
  21.182 +you're trying to track down a subtle bug, you might want a tag to
  21.183 +remind you of something like <quote>Anne saw the symptoms with this
  21.184 +revision</quote>.
  21.185 +</para>
  21.186 +
  21.187 +<para>For cases like this, what you might want to use are <emphasis>local</emphasis> tags.
  21.188 +You can create a local tag with the <option role="hg-opt-tag">-l</option> option to the
  21.189 +<command role="hg-cmd">hg tag</command> command.  This will store the tag in a file called
  21.190 +<filename role="special">.hg/localtags</filename>.  Unlike <filename role="special">.hgtags</filename>,
  21.191 +<filename role="special">.hg/localtags</filename> is not revision controlled.  Any tags you
  21.192 +create using <option role="hg-opt-tag">-l</option> remain strictly local to the repository
  21.193 +you're currently working in.
  21.194 +</para>
  21.195 +
  21.196 +</sect2>
  21.197 +</sect1>
  21.198 +<sect1>
  21.199 +<title>The flow of changes&emdash;big picture vs. little</title>
  21.200 +
  21.201 +<para>To return to the outline I sketched at the beginning of a chapter,
  21.202 +let's think about a project that has multiple concurrent pieces of
  21.203 +work under development at once.
  21.204 +</para>
  21.205 +
  21.206 +<para>There might be a push for a new <quote>main</quote> release; a new minor bugfix
  21.207 +release to the last main release; and an unexpected <quote>hot fix</quote> to an
  21.208 +old release that is now in maintenance mode.
  21.209 +</para>
  21.210 +
  21.211 +<para>The usual way people refer to these different concurrent directions of
  21.212 +development is as <quote>branches</quote>.  However, we've already seen numerous
  21.213 +times that Mercurial treats <emphasis>all of history</emphasis> as a series of
  21.214 +branches and merges.  Really, what we have here is two ideas that are
  21.215 +peripherally related, but which happen to share a name.
  21.216 +</para>
  21.217 +<itemizedlist>
  21.218 +<listitem><para><quote>Big picture</quote> branches represent the sweep of a project's
  21.219 +  evolution; people give them names, and talk about them in
  21.220 +  conversation.
  21.221 +</para>
  21.222 +</listitem>
  21.223 +<listitem><para><quote>Little picture</quote> branches are artefacts of the day-to-day
  21.224 +  activity of developing and merging changes.  They expose the
  21.225 +  narrative of how the code was developed.
  21.226 +</para>
  21.227 +</listitem></itemizedlist>
  21.228 +
  21.229 +</sect1>
  21.230 +<sect1>
  21.231 +<title>Managing big-picture branches in repositories</title>
  21.232 +
  21.233 +<para>The easiest way to isolate a <quote>big picture</quote> branch in Mercurial is in
  21.234 +a dedicated repository.  If you have an existing shared
  21.235 +repository&emdash;let's call it <literal>myproject</literal>&emdash;that reaches a <quote>1.0</quote>
  21.236 +milestone, you can start to prepare for future maintenance releases on
  21.237 +top of version 1.0 by tagging the revision from which you prepared
  21.238 +the 1.0 release.
  21.239 +<!-- &interaction.branch-repo.tag; -->
  21.240 +You can then clone a new shared <literal>myproject-1.0.1</literal> repository as
  21.241 +of that tag.
  21.242 +<!-- &interaction.branch-repo.clone; -->
  21.243 +</para>
  21.244 +
  21.245 +<para>Afterwards, if someone needs to work on a bug fix that ought to go
  21.246 +into an upcoming 1.0.1 minor release, they clone the
  21.247 +<literal>myproject-1.0.1</literal> repository, make their changes, and push them
  21.248 +back.
  21.249 +<!-- &interaction.branch-repo.bugfix; -->
  21.250 +Meanwhile, development for the next major release can continue,
  21.251 +isolated and unabated, in the <literal>myproject</literal> repository.
  21.252 +<!-- &interaction.branch-repo.new; -->
  21.253 +</para>
  21.254 +
  21.255 +</sect1>
  21.256 +<sect1>
  21.257 +<title>Don't repeat yourself: merging across branches</title>
  21.258 +
  21.259 +<para>In many cases, if you have a bug to fix on a maintenance branch, the
  21.260 +chances are good that the bug exists on your project's main branch
  21.261 +(and possibly other maintenance branches, too).  It's a rare developer
  21.262 +who wants to fix the same bug multiple times, so let's look at a few
  21.263 +ways that Mercurial can help you to manage these bugfixes without
  21.264 +duplicating your work.
  21.265 +</para>
  21.266 +
  21.267 +<para>In the simplest instance, all you need to do is pull changes from your
  21.268 +maintenance branch into your local clone of the target branch.
  21.269 +<!-- &interaction.branch-repo.pull; -->
  21.270 +You'll then need to merge the heads of the two branches, and push back
  21.271 +to the main branch.
  21.272 +<!-- &interaction.branch-repo.merge; -->
  21.273 +</para>
  21.274 +
  21.275 +</sect1>
  21.276 +<sect1>
  21.277 +<title>Naming branches within one repository</title>
  21.278 +
  21.279 +<para>In most instances, isolating branches in repositories is the right
  21.280 +approach.  Its simplicity makes it easy to understand; and so it's
  21.281 +hard to make mistakes.  There's a one-to-one relationship between
  21.282 +branches you're working in and directories on your system.  This lets
  21.283 +you use normal (non-Mercurial-aware) tools to work on files within a
  21.284 +branch/repository.
  21.285 +</para>
  21.286 +
  21.287 +<para>If you're more in the <quote>power user</quote> category (<emphasis>and</emphasis> your
  21.288 +collaborators are too), there is an alternative way of handling
  21.289 +branches that you can consider.  I've already mentioned the
  21.290 +human-level distinction between <quote>small picture</quote> and <quote>big picture</quote>
  21.291 +branches.  While Mercurial works with multiple <quote>small picture</quote>
  21.292 +branches in a repository all the time (for example after you pull
  21.293 +changes in, but before you merge them), it can <emphasis>also</emphasis> work with
  21.294 +multiple <quote>big picture</quote> branches.
  21.295 +</para>
  21.296 +
  21.297 +<para>The key to working this way is that Mercurial lets you assign a
  21.298 +persistent <emphasis>name</emphasis> to a branch.  There always exists a branch
  21.299 +named <literal>default</literal>.  Even before you start naming branches
  21.300 +yourself, you can find traces of the <literal>default</literal> branch if you
  21.301 +look for them.
  21.302 +</para>
  21.303 +
  21.304 +<para>As an example, when you run the <command role="hg-cmd">hg commit</command> command, and it pops up
  21.305 +your editor so that you can enter a commit message, look for a line
  21.306 +that contains the text <quote><literal>HG: branch default</literal></quote> at the bottom.
  21.307 +This is telling you that your commit will occur on the branch named
  21.308 +<literal>default</literal>.
  21.309 +</para>
  21.310 +
  21.311 +<para>To start working with named branches, use the <command role="hg-cmd">hg branches</command>
  21.312 +command.  This command lists the named branches already present in
  21.313 +your repository, telling you which changeset is the tip of each.
  21.314 +<!-- &interaction.branch-named.branches; -->
  21.315 +Since you haven't created any named branches yet, the only one that
  21.316 +exists is <literal>default</literal>.
  21.317 +</para>
  21.318 +
  21.319 +<para>To find out what the <quote>current</quote> branch is, run the <command role="hg-cmd">hg branch</command>
  21.320 +command, giving it no arguments.  This tells you what branch the
  21.321 +parent of the current changeset is on.
  21.322 +<!-- &interaction.branch-named.branch; -->
  21.323 +</para>
  21.324 +
  21.325 +<para>To create a new branch, run the <command role="hg-cmd">hg branch</command> command again.  This
  21.326 +time, give it one argument: the name of the branch you want to create.
  21.327 +<!-- &interaction.branch-named.create; -->
  21.328 +</para>
  21.329 +
  21.330 +<para>After you've created a branch, you might wonder what effect the
  21.331 +<command role="hg-cmd">hg branch</command> command has had.  What do the <command role="hg-cmd">hg status</command> and
  21.332 +<command role="hg-cmd">hg tip</command> commands report?
  21.333 +<!-- &interaction.branch-named.status; -->
  21.334 +Nothing has changed in the working directory, and there's been no new
  21.335 +history created.  As this suggests, running the <command role="hg-cmd">hg branch</command> command
  21.336 +has no permanent effect; it only tells Mercurial what branch name to
  21.337 +use the <emphasis>next</emphasis> time you commit a changeset.
  21.338 +</para>
  21.339 +
  21.340 +<para>When you commit a change, Mercurial records the name of the branch on
  21.341 +which you committed.  Once you've switched from the <literal>default</literal>
  21.342 +branch to another and committed, you'll see the name of the new branch
  21.343 +show up in the output of <command role="hg-cmd">hg log</command>, <command role="hg-cmd">hg tip</command>, and other commands
  21.344 +that display the same kind of output.
  21.345 +<!-- &interaction.branch-named.commit; -->
  21.346 +The <command role="hg-cmd">hg log</command>-like commands will print the branch name of every
  21.347 +changeset that's not on the <literal>default</literal> branch.  As a result, if
  21.348 +you never use named branches, you'll never see this information.
  21.349 +</para>
  21.350 +
  21.351 +<para>Once you've named a branch and committed a change with that name,
  21.352 +every subsequent commit that descends from that change will inherit
  21.353 +the same branch name.  You can change the name of a branch at any
  21.354 +time, using the <command role="hg-cmd">hg branch</command> command.
  21.355 +<!-- &interaction.branch-named.rebranch; -->
  21.356 +In practice, this is something you won't do very often, as branch
  21.357 +names tend to have fairly long lifetimes.  (This isn't a rule, just an
  21.358 +observation.)
  21.359 +</para>
  21.360 +
  21.361 +</sect1>
  21.362 +<sect1>
  21.363 +<title>Dealing with multiple named branches in a repository</title>
  21.364 +
  21.365 +<para>If you have more than one named branch in a repository, Mercurial will
  21.366 +remember the branch that your working directory on when you start a
  21.367 +command like <command role="hg-cmd">hg update</command> or <command role="hg-cmd">hg pull -u</command>.  It will update
  21.368 +the working directory to the tip of this branch, no matter what the
  21.369 +<quote>repo-wide</quote> tip is.  To update to a revision that's on a different
  21.370 +named branch, you may need to use the <option role="hg-opt-update">-C</option> option to
  21.371 +<command role="hg-cmd">hg update</command>.
  21.372 +</para>
  21.373 +
  21.374 +<para>This behaviour is a little subtle, so let's see it in action.  First,
  21.375 +let's remind ourselves what branch we're currently on, and what
  21.376 +branches are in our repository.
  21.377 +<!-- &interaction.branch-named.parents; -->
  21.378 +We're on the <literal>bar</literal> branch, but there also exists an older
  21.379 +<command role="hg-cmd">hg foo</command> branch.
  21.380 +</para>
  21.381 +
  21.382 +<para>We can <command role="hg-cmd">hg update</command> back and forth between the tips of the
  21.383 +<literal>foo</literal> and <literal>bar</literal> branches without needing to use the
  21.384 +<option role="hg-opt-update">-C</option> option, because this only involves going backwards
  21.385 +and forwards linearly through our change history.
  21.386 +<!-- &interaction.branch-named.update-switchy; -->
  21.387 +</para>
  21.388 +
  21.389 +<para>If we go back to the <literal>foo</literal> branch and then run <command role="hg-cmd">hg update</command>,
  21.390 +it will keep us on <literal>foo</literal>, not move us to the tip of
  21.391 +<literal>bar</literal>.
  21.392 +<!-- &interaction.branch-named.update-nothing; -->
  21.393 +</para>
  21.394 +
  21.395 +<para>Committing a new change on the <literal>foo</literal> branch introduces a new
  21.396 +head.
  21.397 +<!-- &interaction.branch-named.foo-commit; -->
  21.398 +</para>
  21.399 +
  21.400 +</sect1>
  21.401 +<sect1>
  21.402 +<title>Branch names and merging</title>
  21.403 +
  21.404 +<para>As you've probably noticed, merges in Mercurial are not symmetrical.
  21.405 +Let's say our repository has two heads, 17 and 23.  If I
  21.406 +<command role="hg-cmd">hg update</command> to 17 and then <command role="hg-cmd">hg merge</command> with 23, Mercurial records
  21.407 +17 as the first parent of the merge, and 23 as the second.  Whereas if
  21.408 +I <command role="hg-cmd">hg update</command> to 23 and then <command role="hg-cmd">hg merge</command> with 17, it records 23
  21.409 +as the first parent, and 17 as the second.
  21.410 +</para>
  21.411 +
  21.412 +<para>This affects Mercurial's choice of branch name when you merge.  After
  21.413 +a merge, Mercurial will retain the branch name of the first parent
  21.414 +when you commit the result of the merge.  If your first parent's
  21.415 +branch name is <literal>foo</literal>, and you merge with <literal>bar</literal>, the
  21.416 +branch name will still be <literal>foo</literal> after you merge.
  21.417 +</para>
  21.418 +
  21.419 +<para>It's not unusual for a repository to contain multiple heads, each with
  21.420 +the same branch name.  Let's say I'm working on the <literal>foo</literal>
  21.421 +branch, and so are you.  We commit different changes; I pull your
  21.422 +changes; I now have two heads, each claiming to be on the <literal>foo</literal>
  21.423 +branch.  The result of a merge will be a single head on the
  21.424 +<literal>foo</literal> branch, as you might hope.
  21.425 +</para>
  21.426 +
  21.427 +<para>But if I'm working on the <literal>bar</literal> branch, and I merge work from
  21.428 +the <literal>foo</literal> branch, the result will remain on the <literal>bar</literal>
  21.429 +branch.
  21.430 +<!-- &interaction.branch-named.merge; -->
  21.431 +</para>
  21.432 +
  21.433 +<para>To give a more concrete example, if I'm working on the
  21.434 +<literal>bleeding-edge</literal> branch, and I want to bring in the latest fixes
  21.435 +from the <literal>stable</literal> branch, Mercurial will choose the <quote>right</quote>
  21.436 +(<literal>bleeding-edge</literal>) branch name when I pull and merge from
  21.437 +<literal>stable</literal>.
  21.438 +</para>
  21.439 +
  21.440 +</sect1>
  21.441 +<sect1>
  21.442 +<title>Branch naming is generally useful</title>
  21.443 +
  21.444 +<para>You shouldn't think of named branches as applicable only to situations
  21.445 +where you have multiple long-lived branches cohabiting in a single
  21.446 +repository.  They're very useful even in the one-branch-per-repository
  21.447 +case.
  21.448 +</para>
  21.449 +
  21.450 +<para>In the simplest case, giving a name to each branch gives you a
  21.451 +permanent record of which branch a changeset originated on.  This
  21.452 +gives you more context when you're trying to follow the history of a
  21.453 +long-lived branchy project.
  21.454 +</para>
  21.455 +
  21.456 +<para>If you're working with shared repositories, you can set up a
  21.457 +<literal role="hook">pretxnchangegroup</literal> hook on each that will block incoming changes
  21.458 +that have the <quote>wrong</quote> branch name.  This provides a simple, but
  21.459 +effective, defence against people accidentally pushing changes from a
  21.460 +<quote>bleeding edge</quote> branch to a <quote>stable</quote> branch.  Such a hook might
  21.461 +look like this inside the shared repo's <filename role="special"> /.hgrc</filename>.
  21.462 +</para>
  21.463 +<programlisting>
  21.464 +<para>  [hooks]
  21.465 +  pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch
  21.466 +</para>
  21.467 +</programlisting>
  21.468 +
  21.469 +</sect1>
  21.470 +</chapter>
  21.471 +
  21.472 +<!--
  21.473 +local variables: 
  21.474 +sgml-parent-document: ("00book.xml" "book" "chapter")
  21.475 +end:
  21.476 +-->
  21.477 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/fr/ch09-undo.xml	Sun Aug 16 04:58:01 2009 +0200
    22.3 @@ -0,0 +1,963 @@
    22.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    22.5 +
    22.6 +<chapter>
    22.7 +<title>Finding and fixing your mistakes</title>
    22.8 +<para>\label{chap:undo}</para>
    22.9 +
   22.10 +<para>To err might be human, but to really handle the consequences well
   22.11 +takes a top-notch revision control system.  In this chapter, we'll
   22.12 +discuss some of the techniques you can use when you find that a
   22.13 +problem has crept into your project.  Mercurial has some highly
   22.14 +capable features that will help you to isolate the sources of
   22.15 +problems, and to handle them appropriately.</para>
   22.16 +
   22.17 +<sect1>
   22.18 +<title>Erasing local history</title>
   22.19 +
   22.20 +<sect2>
   22.21 +<title>The accidental commit</title>
   22.22 +
   22.23 +<para>I have the occasional but persistent problem of typing rather more
   22.24 +quickly than I can think, which sometimes results in me committing a
   22.25 +changeset that is either incomplete or plain wrong.  In my case, the
   22.26 +usual kind of incomplete changeset is one in which I've created a new
   22.27 +source file, but forgotten to <command role="hg-cmd">hg add</command> it.  A <quote>plain wrong</quote>
   22.28 +changeset is not as common, but no less annoying.</para>
   22.29 +
   22.30 +</sect2>
   22.31 +<sect2>
   22.32 +<title>Rolling back a transaction</title>
   22.33 +<para>\label{sec:undo:rollback}</para>
   22.34 +
   22.35 +<para>In section <xref linkend="sec:concepts:txn"/>, I mentioned that Mercurial treats
   22.36 +each modification of a repository as a <emphasis>transaction</emphasis>.  Every time
   22.37 +you commit a changeset or pull changes from another repository,
   22.38 +Mercurial remembers what you did.  You can undo, or <emphasis>roll back</emphasis>,
   22.39 +exactly one of these actions using the <command role="hg-cmd">hg rollback</command> command.  (See
   22.40 +section <xref linkend="sec:undo:rollback-after-push"/> for an important caveat
   22.41 +about the use of this command.)</para>
   22.42 +
   22.43 +<para>Here's a mistake that I often find myself making: committing a change
   22.44 +in which I've created a new file, but forgotten to <command role="hg-cmd">hg add</command> it.
   22.45 +<!-- &interaction.rollback.commit; -->
   22.46 +Looking at the output of <command role="hg-cmd">hg status</command> after the commit immediately
   22.47 +confirms the error.
   22.48 +<!-- &interaction.rollback.status; -->
   22.49 +The commit captured the changes to the file <filename>a</filename>, but not the
   22.50 +new file <filename>b</filename>.  If I were to push this changeset to a
   22.51 +repository that I shared with a colleague, the chances are high that
   22.52 +something in <filename>a</filename> would refer to <filename>b</filename>, which would not
   22.53 +be present in their repository when they pulled my changes.  I would
   22.54 +thus become the object of some indignation.</para>
   22.55 +
   22.56 +<para>However, luck is with me&emdash;I've caught my error before I pushed the
   22.57 +changeset.  I use the <command role="hg-cmd">hg rollback</command> command, and Mercurial makes
   22.58 +that last changeset vanish.
   22.59 +<!-- &interaction.rollback.rollback; -->
   22.60 +Notice that the changeset is no longer present in the repository's
   22.61 +history, and the working directory once again thinks that the file
   22.62 +<filename>a</filename> is modified.  The commit and rollback have left the
   22.63 +working directory exactly as it was prior to the commit; the changeset
   22.64 +has been completely erased.  I can now safely <command role="hg-cmd">hg add</command> the file
   22.65 +<filename>b</filename>, and rerun my commit.
   22.66 +<!-- &interaction.rollback.add; --></para>
   22.67 +
   22.68 +</sect2>
   22.69 +<sect2>
   22.70 +<title>The erroneous pull</title>
   22.71 +
   22.72 +<para>It's common practice with Mercurial to maintain separate development
   22.73 +branches of a project in different repositories.  Your development
   22.74 +team might have one shared repository for your project's <quote>0.9</quote>
   22.75 +release, and another, containing different changes, for the <quote>1.0</quote>
   22.76 +release.</para>
   22.77 +
   22.78 +<para>Given this, you can imagine that the consequences could be messy if
   22.79 +you had a local <quote>0.9</quote> repository, and accidentally pulled changes
   22.80 +from the shared <quote>1.0</quote> repository into it.  At worst, you could be
   22.81 +paying insufficient attention, and push those changes into the shared
   22.82 +<quote>0.9</quote> tree, confusing your entire team (but don't worry, we'll
   22.83 +return to this horror scenario later).  However, it's more likely that
   22.84 +you'll notice immediately, because Mercurial will display the URL it's
   22.85 +pulling from, or you will see it pull a suspiciously large number of
   22.86 +changes into the repository.
   22.87 +</para>
   22.88 +
   22.89 +<para>The <command role="hg-cmd">hg rollback</command> command will work nicely to expunge all of the
   22.90 +changesets that you just pulled.  Mercurial groups all changes from
   22.91 +one <command role="hg-cmd">hg pull</command> into a single transaction, so one <command role="hg-cmd">hg rollback</command> is
   22.92 +all you need to undo this mistake.
   22.93 +</para>
   22.94 +
   22.95 +</sect2>
   22.96 +<sect2>
   22.97 +<title>Rolling back is useless once you've pushed</title>
   22.98 +<para>\label{sec:undo:rollback-after-push}
   22.99 +</para>
  22.100 +
  22.101 +<para>The value of the <command role="hg-cmd">hg rollback</command> command drops to zero once you've
  22.102 +pushed your changes to another repository.  Rolling back a change
  22.103 +makes it disappear entirely, but <emphasis>only</emphasis> in the repository in
  22.104 +which you perform the <command role="hg-cmd">hg rollback</command>.  Because a rollback eliminates
  22.105 +history, there's no way for the disappearance of a change to propagate
  22.106 +between repositories.
  22.107 +</para>
  22.108 +
  22.109 +<para>If you've pushed a change to another repository&emdash;particularly if it's
  22.110 +a shared repository&emdash;it has essentially <quote>escaped into the wild,</quote>
  22.111 +and you'll have to recover from your mistake in a different way.  What
  22.112 +will happen if you push a changeset somewhere, then roll it back, then
  22.113 +pull from the repository you pushed to, is that the changeset will
  22.114 +reappear in your repository.
  22.115 +</para>
  22.116 +
  22.117 +<para>(If you absolutely know for sure that the change you want to roll back
  22.118 +is the most recent change in the repository that you pushed to,
  22.119 +<emphasis>and</emphasis> you know that nobody else could have pulled it from that
  22.120 +repository, you can roll back the changeset there, too, but you really
  22.121 +should really not rely on this working reliably.  If you do this,
  22.122 +sooner or later a change really will make it into a repository that
  22.123 +you don't directly control (or have forgotten about), and come back to
  22.124 +bite you.)
  22.125 +</para>
  22.126 +
  22.127 +</sect2>
  22.128 +<sect2>
  22.129 +<title>You can only roll back once</title>
  22.130 +
  22.131 +<para>Mercurial stores exactly one transaction in its transaction log; that
  22.132 +transaction is the most recent one that occurred in the repository.
  22.133 +This means that you can only roll back one transaction.  If you expect
  22.134 +to be able to roll back one transaction, then its predecessor, this is
  22.135 +not the behaviour you will get.
  22.136 +<!-- &interaction.rollback.twice; -->
  22.137 +Once you've rolled back one transaction in a repository, you can't
  22.138 +roll back again in that repository until you perform another commit or
  22.139 +pull.
  22.140 +</para>
  22.141 +
  22.142 +</sect2>
  22.143 +</sect1>
  22.144 +<sect1>
  22.145 +<title>Reverting the mistaken change</title>
  22.146 +
  22.147 +<para>If you make a modification to a file, and decide that you really
  22.148 +didn't want to change the file at all, and you haven't yet committed
  22.149 +your changes, the <command role="hg-cmd">hg revert</command> command is the one you'll need.  It
  22.150 +looks at the changeset that's the parent of the working directory, and
  22.151 +restores the contents of the file to their state as of that changeset.
  22.152 +(That's a long-winded way of saying that, in the normal case, it
  22.153 +undoes your modifications.)
  22.154 +</para>
  22.155 +
  22.156 +<para>Let's illustrate how the <command role="hg-cmd">hg revert</command> command works with yet another
  22.157 +small example.  We'll begin by modifying a file that Mercurial is
  22.158 +already tracking.
  22.159 +<!-- &interaction.daily.revert.modify; -->
  22.160 +If we don't want that change, we can simply <command role="hg-cmd">hg revert</command> the file.
  22.161 +<!-- &interaction.daily.revert.unmodify; -->
  22.162 +The <command role="hg-cmd">hg revert</command> command provides us with an extra degree of safety
  22.163 +by saving our modified file with a <filename>.orig</filename> extension.
  22.164 +<!-- &interaction.daily.revert.status; -->
  22.165 +</para>
  22.166 +
  22.167 +<para>Here is a summary of the cases that the <command role="hg-cmd">hg revert</command> command can
  22.168 +deal with.  We will describe each of these in more detail in the
  22.169 +section that follows.
  22.170 +</para>
  22.171 +<itemizedlist>
  22.172 +<listitem><para>If you modify a file, it will restore the file to its unmodified
  22.173 +  state.
  22.174 +</para>
  22.175 +</listitem>
  22.176 +<listitem><para>If you <command role="hg-cmd">hg add</command> a file, it will undo the <quote>added</quote> state of
  22.177 +  the file, but leave the file itself untouched.
  22.178 +</para>
  22.179 +</listitem>
  22.180 +<listitem><para>If you delete a file without telling Mercurial, it will restore
  22.181 +  the file to its unmodified contents.
  22.182 +</para>
  22.183 +</listitem>
  22.184 +<listitem><para>If you use the <command role="hg-cmd">hg remove</command> command to remove a file, it will
  22.185 +  undo the <quote>removed</quote> state of the file, and restore the file to its
  22.186 +  unmodified contents.
  22.187 +</para>
  22.188 +</listitem></itemizedlist>
  22.189 +
  22.190 +<sect2>
  22.191 +<title>File management errors</title>
  22.192 +<para>\label{sec:undo:mgmt}
  22.193 +</para>
  22.194 +
  22.195 +<para>The <command role="hg-cmd">hg revert</command> command is useful for more than just modified
  22.196 +files.  It lets you reverse the results of all of Mercurial's file
  22.197 +management commands&emdash;<command role="hg-cmd">hg add</command>, <command role="hg-cmd">hg remove</command>, and so on.
  22.198 +</para>
  22.199 +
  22.200 +<para>If you <command role="hg-cmd">hg add</command> a file, then decide that in fact you don't want
  22.201 +Mercurial to track it, use <command role="hg-cmd">hg revert</command> to undo the add.  Don't
  22.202 +worry; Mercurial will not modify the file in any way.  It will just
  22.203 +<quote>unmark</quote> the file.
  22.204 +<!-- &interaction.daily.revert.add; -->
  22.205 +</para>
  22.206 +
  22.207 +<para>Similarly, if you ask Mercurial to <command role="hg-cmd">hg remove</command> a file, you can use
  22.208 +<command role="hg-cmd">hg revert</command> to restore it to the contents it had as of the parent
  22.209 +of the working directory.
  22.210 +<!-- &interaction.daily.revert.remove; -->
  22.211 +This works just as well for a file that you deleted by hand, without
  22.212 +telling Mercurial (recall that in Mercurial terminology, this kind of
  22.213 +file is called <quote>missing</quote>).
  22.214 +<!-- &interaction.daily.revert.missing; -->
  22.215 +</para>
  22.216 +
  22.217 +<para>If you revert a <command role="hg-cmd">hg copy</command>, the copied-to file remains in your
  22.218 +working directory afterwards, untracked.  Since a copy doesn't affect
  22.219 +the copied-from file in any way, Mercurial doesn't do anything with
  22.220 +the copied-from file.
  22.221 +<!-- &interaction.daily.revert.copy; -->
  22.222 +</para>
  22.223 +
  22.224 +<sect3>
  22.225 +<title>A slightly special case: reverting a rename</title>
  22.226 +
  22.227 +<para>If you <command role="hg-cmd">hg rename</command> a file, there is one small detail that
  22.228 +you should remember.  When you <command role="hg-cmd">hg revert</command> a rename, it's not
  22.229 +enough to provide the name of the renamed-to file, as you can see
  22.230 +here.
  22.231 +<!-- &interaction.daily.revert.rename; -->
  22.232 +As you can see from the output of <command role="hg-cmd">hg status</command>, the renamed-to file
  22.233 +is no longer identified as added, but the renamed-<emphasis>from</emphasis> file is
  22.234 +still removed!  This is counter-intuitive (at least to me), but at
  22.235 +least it's easy to deal with.
  22.236 +<!-- &interaction.daily.revert.rename-orig; -->
  22.237 +So remember, to revert a <command role="hg-cmd">hg rename</command>, you must provide <emphasis>both</emphasis>
  22.238 +the source and destination names.
  22.239 +</para>
  22.240 +
  22.241 +<para>% TODO: the output doesn't look like it will be removed!
  22.242 +</para>
  22.243 +
  22.244 +<para>(By the way, if you rename a file, then modify the renamed-to file,
  22.245 +then revert both components of the rename, when Mercurial restores the
  22.246 +file that was removed as part of the rename, it will be unmodified.
  22.247 +If you need the modifications in the renamed-to file to show up in the
  22.248 +renamed-from file, don't forget to copy them over.)
  22.249 +</para>
  22.250 +
  22.251 +<para>These fiddly aspects of reverting a rename arguably constitute a small
  22.252 +bug in Mercurial.
  22.253 +</para>
  22.254 +
  22.255 +</sect3>
  22.256 +</sect2>
  22.257 +</sect1>
  22.258 +<sect1>
  22.259 +<title>Dealing with committed changes</title>
  22.260 +
  22.261 +<para>Consider a case where you have committed a change $a$, and another
  22.262 +change $b$ on top of it; you then realise that change $a$ was
  22.263 +incorrect.  Mercurial lets you <quote>back out</quote> an entire changeset
  22.264 +automatically, and building blocks that let you reverse part of a
  22.265 +changeset by hand.
  22.266 +</para>
  22.267 +
  22.268 +<para>Before you read this section, here's something to keep in mind: the
  22.269 +<command role="hg-cmd">hg backout</command> command undoes changes by <emphasis>adding</emphasis> history, not
  22.270 +by modifying or erasing it.  It's the right tool to use if you're
  22.271 +fixing bugs, but not if you're trying to undo some change that has
  22.272 +catastrophic consequences.  To deal with those, see
  22.273 +section <xref linkend="sec:undo:aaaiiieee"/>.
  22.274 +</para>
  22.275 +
  22.276 +<sect2>
  22.277 +<title>Backing out a changeset</title>
  22.278 +
  22.279 +<para>The <command role="hg-cmd">hg backout</command> command lets you <quote>undo</quote> the effects of an entire
  22.280 +changeset in an automated fashion.  Because Mercurial's history is
  22.281 +immutable, this command <emphasis>does not</emphasis> get rid of the changeset you
  22.282 +want to undo.  Instead, it creates a new changeset that
  22.283 +<emphasis>reverses</emphasis> the effect of the to-be-undone changeset.
  22.284 +</para>
  22.285 +
  22.286 +<para>The operation of the <command role="hg-cmd">hg backout</command> command is a little intricate, so
  22.287 +let's illustrate it with some examples.  First, we'll create a
  22.288 +repository with some simple changes.
  22.289 +<!-- &interaction.backout.init; -->
  22.290 +</para>
  22.291 +
  22.292 +<para>The <command role="hg-cmd">hg backout</command> command takes a single changeset ID as its
  22.293 +argument; this is the changeset to back out.  Normally,
  22.294 +<command role="hg-cmd">hg backout</command> will drop you into a text editor to write a commit
  22.295 +message, so you can record why you're backing the change out.  In this
  22.296 +example, we provide a commit message on the command line using the
  22.297 +<option role="hg-opt-backout">-m</option> option.
  22.298 +</para>
  22.299 +
  22.300 +</sect2>
  22.301 +<sect2>
  22.302 +<title>Backing out the tip changeset</title>
  22.303 +
  22.304 +<para>We're going to start by backing out the last changeset we committed.
  22.305 +<!-- &interaction.backout.simple; -->
  22.306 +You can see that the second line from <filename>myfile</filename> is no longer
  22.307 +present.  Taking a look at the output of <command role="hg-cmd">hg log</command> gives us an idea
  22.308 +of what the <command role="hg-cmd">hg backout</command> command has done.
  22.309 +<!-- &interaction.backout.simple.log; -->
  22.310 +Notice that the new changeset that <command role="hg-cmd">hg backout</command> has created is a
  22.311 +child of the changeset we backed out.  It's easier to see this in
  22.312 +figure <xref linkend="fig:undo:backout"/>, which presents a graphical view of the
  22.313 +change history.  As you can see, the history is nice and linear.
  22.314 +</para>
  22.315 +
  22.316 +<informalfigure>
  22.317 +
  22.318 +<para>  <mediaobject><imageobject><imagedata fileref="undo-simple"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  22.319 +  <caption><para>Backing out a change using the <command role="hg-cmd">hg backout</command> command</para></caption>
  22.320 +  \label{fig:undo:backout}
  22.321 +</para>
  22.322 +</informalfigure>
  22.323 +
  22.324 +</sect2>
  22.325 +<sect2>
  22.326 +<title>Backing out a non-tip change</title>
  22.327 +
  22.328 +<para>If you want to back out a change other than the last one you
  22.329 +committed, pass the <option role="hg-opt-backout">--merge</option> option to the
  22.330 +<command role="hg-cmd">hg backout</command> command.
  22.331 +<!-- &interaction.backout.non-tip.clone; -->
  22.332 +This makes backing out any changeset a <quote>one-shot</quote> operation that's
  22.333 +usually simple and fast.
  22.334 +<!-- &interaction.backout.non-tip.backout; -->
  22.335 +</para>
  22.336 +
  22.337 +<para>If you take a look at the contents of <filename>myfile</filename> after the
  22.338 +backout finishes, you'll see that the first and third changes are
  22.339 +present, but not the second.
  22.340 +<!-- &interaction.backout.non-tip.cat; -->
  22.341 +</para>
  22.342 +
  22.343 +<para>As the graphical history in figure <xref linkend="fig:undo:backout-non-tip"/>
  22.344 +illustrates, Mercurial actually commits <emphasis>two</emphasis> changes in this
  22.345 +kind of situation (the box-shaped nodes are the ones that Mercurial
  22.346 +commits automatically).  Before Mercurial begins the backout process,
  22.347 +it first remembers what the current parent of the working directory
  22.348 +is.  It then backs out the target changeset, and commits that as a
  22.349 +changeset.  Finally, it merges back to the previous parent of the
  22.350 +working directory, and commits the result of the merge.
  22.351 +</para>
  22.352 +
  22.353 +<para>% TODO: to me it looks like mercurial doesn't commit the second merge automatically!
  22.354 +</para>
  22.355 +
  22.356 +<informalfigure>
  22.357 +
  22.358 +<para>  <mediaobject><imageobject><imagedata fileref="undo-non-tip"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  22.359 +  <caption><para>Automated backout of a non-tip change using the <command role="hg-cmd">hg backout</command> command</para></caption>
  22.360 +  \label{fig:undo:backout-non-tip}
  22.361 +</para>
  22.362 +</informalfigure>
  22.363 +
  22.364 +<para>The result is that you end up <quote>back where you were</quote>, only with some
  22.365 +extra history that undoes the effect of the changeset you wanted to
  22.366 +back out.
  22.367 +</para>
  22.368 +
  22.369 +<sect3>
  22.370 +<title>Always use the <option role="hg-opt-backout">--merge</option> option</title>
  22.371 +
  22.372 +<para>In fact, since the <option role="hg-opt-backout">--merge</option> option will do the <quote>right
  22.373 +thing</quote> whether or not the changeset you're backing out is the tip
  22.374 +(i.e. it won't try to merge if it's backing out the tip, since there's
  22.375 +no need), you should <emphasis>always</emphasis> use this option when you run the
  22.376 +<command role="hg-cmd">hg backout</command> command.
  22.377 +</para>
  22.378 +
  22.379 +</sect3>
  22.380 +</sect2>
  22.381 +<sect2>
  22.382 +<title>Gaining more control of the backout process</title>
  22.383 +
  22.384 +<para>While I've recommended that you always use the
  22.385 +<option role="hg-opt-backout">--merge</option> option when backing out a change, the
  22.386 +<command role="hg-cmd">hg backout</command> command lets you decide how to merge a backout
  22.387 +changeset.  Taking control of the backout process by hand is something
  22.388 +you will rarely need to do, but it can be useful to understand what
  22.389 +the <command role="hg-cmd">hg backout</command> command is doing for you automatically.  To
  22.390 +illustrate this, let's clone our first repository, but omit the
  22.391 +backout change that it contains.
  22.392 +</para>
  22.393 +
  22.394 +<para><!-- &interaction.backout.manual.clone; -->
  22.395 +As with our earlier example, We'll commit a third changeset, then back
  22.396 +out its parent, and see what happens.
  22.397 +<!-- &interaction.backout.manual.backout; -->
  22.398 +Our new changeset is again a descendant of the changeset we backout
  22.399 +out; it's thus a new head, <emphasis>not</emphasis> a descendant of the changeset
  22.400 +that was the tip.  The <command role="hg-cmd">hg backout</command> command was quite explicit in
  22.401 +telling us this.
  22.402 +<!-- &interaction.backout.manual.log; -->
  22.403 +</para>
  22.404 +
  22.405 +<para>Again, it's easier to see what has happened by looking at a graph of
  22.406 +the revision history, in figure <xref linkend="fig:undo:backout-manual"/>.  This
  22.407 +makes it clear that when we use <command role="hg-cmd">hg backout</command> to back out a change
  22.408 +other than the tip, Mercurial adds a new head to the repository (the
  22.409 +change it committed is box-shaped).
  22.410 +</para>
  22.411 +
  22.412 +<informalfigure>
  22.413 +
  22.414 +<para>  <mediaobject><imageobject><imagedata fileref="undo-manual"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  22.415 +  <caption><para>Backing out a change using the <command role="hg-cmd">hg backout</command> command</para></caption>
  22.416 +  \label{fig:undo:backout-manual}
  22.417 +</para>
  22.418 +</informalfigure>
  22.419 +
  22.420 +<para>After the <command role="hg-cmd">hg backout</command> command has completed, it leaves the new
  22.421 +<quote>backout</quote> changeset as the parent of the working directory.
  22.422 +<!-- &interaction.backout.manual.parents; -->
  22.423 +Now we have two isolated sets of changes.
  22.424 +<!-- &interaction.backout.manual.heads; -->
  22.425 +</para>
  22.426 +
  22.427 +<para>Let's think about what we expect to see as the contents of
  22.428 +<filename>myfile</filename> now.  The first change should be present, because
  22.429 +we've never backed it out.  The second change should be missing, as
  22.430 +that's the change we backed out.  Since the history graph shows the
  22.431 +third change as a separate head, we <emphasis>don't</emphasis> expect to see the
  22.432 +third change present in <filename>myfile</filename>.
  22.433 +<!-- &interaction.backout.manual.cat; -->
  22.434 +To get the third change back into the file, we just do a normal merge
  22.435 +of our two heads.
  22.436 +<!-- &interaction.backout.manual.merge; -->
  22.437 +Afterwards, the graphical history of our repository looks like
  22.438 +figure <xref linkend="fig:undo:backout-manual-merge"/>.
  22.439 +</para>
  22.440 +
  22.441 +<informalfigure>
  22.442 +
  22.443 +<para>  <mediaobject><imageobject><imagedata fileref="undo-manual-merge"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  22.444 +  <caption><para>Manually merging a backout change</para></caption>
  22.445 +  \label{fig:undo:backout-manual-merge}
  22.446 +</para>
  22.447 +</informalfigure>
  22.448 +
  22.449 +</sect2>
  22.450 +<sect2>
  22.451 +<title>Why <command role="hg-cmd">hg backout</command> works as it does</title>
  22.452 +
  22.453 +<para>Here's a brief description of how the <command role="hg-cmd">hg backout</command> command works.
  22.454 +</para>
  22.455 +<orderedlist>
  22.456 +<listitem><para>It ensures that the working directory is <quote>clean</quote>, i.e. that
  22.457 +  the output of <command role="hg-cmd">hg status</command> would be empty.
  22.458 +</para>
  22.459 +</listitem>
  22.460 +<listitem><para>It remembers the current parent of the working directory.  Let's
  22.461 +  call this changeset <literal>orig</literal>
  22.462 +</para>
  22.463 +</listitem>
  22.464 +<listitem><para>It does the equivalent of a <command role="hg-cmd">hg update</command> to sync the working
  22.465 +  directory to the changeset you want to back out.  Let's call this
  22.466 +  changeset <literal>backout</literal>
  22.467 +</para>
  22.468 +</listitem>
  22.469 +<listitem><para>It finds the parent of that changeset.  Let's call that
  22.470 +  changeset <literal>parent</literal>.
  22.471 +</para>
  22.472 +</listitem>
  22.473 +<listitem><para>For each file that the <literal>backout</literal> changeset affected, it
  22.474 +  does the equivalent of a <command role="hg-cmd">hg revert -r parent</command> on that file,
  22.475 +  to restore it to the contents it had before that changeset was
  22.476 +  committed.
  22.477 +</para>
  22.478 +</listitem>
  22.479 +<listitem><para>It commits the result as a new changeset.  This changeset has
  22.480 +  <literal>backout</literal> as its parent.
  22.481 +</para>
  22.482 +</listitem>
  22.483 +<listitem><para>If you specify <option role="hg-opt-backout">--merge</option> on the command line, it
  22.484 +  merges with <literal>orig</literal>, and commits the result of the merge.
  22.485 +</para>
  22.486 +</listitem></orderedlist>
  22.487 +
  22.488 +<para>An alternative way to implement the <command role="hg-cmd">hg backout</command> command would be
  22.489 +to <command role="hg-cmd">hg export</command> the to-be-backed-out changeset as a diff, then use
  22.490 +the <option role="cmd-opt-patch">--reverse</option> option to the <command>patch</command> command to
  22.491 +reverse the effect of the change without fiddling with the working
  22.492 +directory.  This sounds much simpler, but it would not work nearly as
  22.493 +well.
  22.494 +</para>
  22.495 +
  22.496 +<para>The reason that <command role="hg-cmd">hg backout</command> does an update, a commit, a merge, and
  22.497 +another commit is to give the merge machinery the best chance to do a
  22.498 +good job when dealing with all the changes <emphasis>between</emphasis> the change
  22.499 +you're backing out and the current tip.
  22.500 +</para>
  22.501 +
  22.502 +<para>If you're backing out a changeset that's 100 revisions back in your
  22.503 +project's history, the chances that the <command>patch</command> command will
  22.504 +be able to apply a reverse diff cleanly are not good, because
  22.505 +intervening changes are likely to have <quote>broken the context</quote> that
  22.506 +<command>patch</command> uses to determine whether it can apply a patch (if
  22.507 +this sounds like gibberish, see <xref linkend="sec:mq:patch"/> for a
  22.508 +discussion of the <command>patch</command> command).  Also, Mercurial's merge
  22.509 +machinery will handle files and directories being renamed, permission
  22.510 +changes, and modifications to binary files, none of which
  22.511 +<command>patch</command> can deal with.
  22.512 +</para>
  22.513 +
  22.514 +</sect2>
  22.515 +</sect1>
  22.516 +<sect1>
  22.517 +<title>Changes that should never have been</title>
  22.518 +<para>\label{sec:undo:aaaiiieee}
  22.519 +</para>
  22.520 +
  22.521 +<para>Most of the time, the <command role="hg-cmd">hg backout</command> command is exactly what you need
  22.522 +if you want to undo the effects of a change.  It leaves a permanent
  22.523 +record of exactly what you did, both when committing the original
  22.524 +changeset and when you cleaned up after it.
  22.525 +</para>
  22.526 +
  22.527 +<para>On rare occasions, though, you may find that you've committed a change
  22.528 +that really should not be present in the repository at all.  For
  22.529 +example, it would be very unusual, and usually considered a mistake,
  22.530 +to commit a software project's object files as well as its source
  22.531 +files.  Object files have almost no intrinsic value, and they're
  22.532 +<emphasis>big</emphasis>, so they increase the size of the repository and the amount
  22.533 +of time it takes to clone or pull changes.
  22.534 +</para>
  22.535 +
  22.536 +<para>Before I discuss the options that you have if you commit a <quote>brown
  22.537 +paper bag</quote> change (the kind that's so bad that you want to pull a
  22.538 +brown paper bag over your head), let me first discuss some approaches
  22.539 +that probably won't work.
  22.540 +</para>
  22.541 +
  22.542 +<para>Since Mercurial treats history as accumulative&emdash;every change builds
  22.543 +on top of all changes that preceded it&emdash;you generally can't just make
  22.544 +disastrous changes disappear.  The one exception is when you've just
  22.545 +committed a change, and it hasn't been pushed or pulled into another
  22.546 +repository.  That's when you can safely use the <command role="hg-cmd">hg rollback</command>
  22.547 +command, as I detailed in section <xref linkend="sec:undo:rollback"/>.
  22.548 +</para>
  22.549 +
  22.550 +<para>After you've pushed a bad change to another repository, you
  22.551 +<emphasis>could</emphasis> still use <command role="hg-cmd">hg rollback</command> to make your local copy of the
  22.552 +change disappear, but it won't have the consequences you want.  The
  22.553 +change will still be present in the remote repository, so it will
  22.554 +reappear in your local repository the next time you pull.
  22.555 +</para>
  22.556 +
  22.557 +<para>If a situation like this arises, and you know which repositories your
  22.558 +bad change has propagated into, you can <emphasis>try</emphasis> to get rid of the
  22.559 +changeefrom <emphasis>every</emphasis> one of those repositories.  This is, of
  22.560 +course, not a satisfactory solution: if you miss even a single
  22.561 +repository while you're expunging, the change is still <quote>in the
  22.562 +wild</quote>, and could propagate further.
  22.563 +</para>
  22.564 +
  22.565 +<para>If you've committed one or more changes <emphasis>after</emphasis> the change that
  22.566 +you'd like to see disappear, your options are further reduced.
  22.567 +Mercurial doesn't provide a way to <quote>punch a hole</quote> in history,
  22.568 +leaving changesets intact.
  22.569 +</para>
  22.570 +
  22.571 +<para>XXX This needs filling out.  The <literal>hg-replay</literal> script in the
  22.572 +<literal>examples</literal> directory works, but doesn't handle merge
  22.573 +changesets.  Kind of an important omission.
  22.574 +</para>
  22.575 +
  22.576 +<sect2>
  22.577 +<title>Protect yourself from <quote>escaped</quote> changes</title>
  22.578 +
  22.579 +<para>If you've committed some changes to your local repository and they've
  22.580 +been pushed or pulled somewhere else, this isn't necessarily a
  22.581 +disaster.  You can protect yourself ahead of time against some classes
  22.582 +of bad changeset.  This is particularly easy if your team usually
  22.583 +pulls changes from a central repository.
  22.584 +</para>
  22.585 +
  22.586 +<para>By configuring some hooks on that repository to validate incoming
  22.587 +changesets (see chapter <xref linkend="chap:hook"/>), you can automatically
  22.588 +prevent some kinds of bad changeset from being pushed to the central
  22.589 +repository at all.  With such a configuration in place, some kinds of
  22.590 +bad changeset will naturally tend to <quote>die out</quote> because they can't
  22.591 +propagate into the central repository.  Better yet, this happens
  22.592 +without any need for explicit intervention.
  22.593 +</para>
  22.594 +
  22.595 +<para>For instance, an incoming change hook that verifies that a changeset
  22.596 +will actually compile can prevent people from inadvertantly <quote>breaking
  22.597 +the build</quote>.
  22.598 +</para>
  22.599 +
  22.600 +</sect2>
  22.601 +</sect1>
  22.602 +<sect1>
  22.603 +<title>Finding the source of a bug</title>
  22.604 +<para>\label{sec:undo:bisect}
  22.605 +</para>
  22.606 +
  22.607 +<para>While it's all very well to be able to back out a changeset that
  22.608 +introduced a bug, this requires that you know which changeset to back
  22.609 +out.  Mercurial provides an invaluable command, called
  22.610 +<command role="hg-cmd">hg bisect</command>, that helps you to automate this process and accomplish
  22.611 +it very efficiently.
  22.612 +</para>
  22.613 +
  22.614 +<para>The idea behind the <command role="hg-cmd">hg bisect</command> command is that a changeset has
  22.615 +introduced some change of behaviour that you can identify with a
  22.616 +simple binary test.  You don't know which piece of code introduced the
  22.617 +change, but you know how to test for the presence of the bug.  The
  22.618 +<command role="hg-cmd">hg bisect</command> command uses your test to direct its search for the
  22.619 +changeset that introduced the code that caused the bug.
  22.620 +</para>
  22.621 +
  22.622 +<para>Here are a few scenarios to help you understand how you might apply
  22.623 +this command.
  22.624 +</para>
  22.625 +<itemizedlist>
  22.626 +<listitem><para>The most recent version of your software has a bug that you
  22.627 +  remember wasn't present a few weeks ago, but you don't know when it
  22.628 +  was introduced.  Here, your binary test checks for the presence of
  22.629 +  that bug.
  22.630 +</para>
  22.631 +</listitem>
  22.632 +<listitem><para>You fixed a bug in a rush, and now it's time to close the entry
  22.633 +  in your team's bug database.  The bug database requires a changeset
  22.634 +  ID when you close an entry, but you don't remember which changeset
  22.635 +  you fixed the bug in.  Once again, your binary test checks for the
  22.636 +  presence of the bug.
  22.637 +</para>
  22.638 +</listitem>
  22.639 +<listitem><para>Your software works correctly, but runs 15% slower than the
  22.640 +  last time you measured it.  You want to know which changeset
  22.641 +  introduced the performance regression.  In this case, your binary
  22.642 +  test measures the performance of your software, to see whether it's
  22.643 +  <quote>fast</quote> or <quote>slow</quote>.
  22.644 +</para>
  22.645 +</listitem>
  22.646 +<listitem><para>The sizes of the components of your project that you ship
  22.647 +  exploded recently, and you suspect that something changed in the way
  22.648 +  you build your project.
  22.649 +</para>
  22.650 +</listitem></itemizedlist>
  22.651 +
  22.652 +<para>From these examples, it should be clear that the <command role="hg-cmd">hg bisect</command>
  22.653 +command is not useful only for finding the sources of bugs.  You can
  22.654 +use it to find any <quote>emergent property</quote> of a repository (anything
  22.655 +that you can't find from a simple text search of the files in the
  22.656 +tree) for which you can write a binary test.
  22.657 +</para>
  22.658 +
  22.659 +<para>We'll introduce a little bit of terminology here, just to make it
  22.660 +clear which parts of the search process are your responsibility, and
  22.661 +which are Mercurial's.  A <emphasis>test</emphasis> is something that <emphasis>you</emphasis> run
  22.662 +when <command role="hg-cmd">hg bisect</command> chooses a changeset.  A <emphasis>probe</emphasis> is what
  22.663 +<command role="hg-cmd">hg bisect</command> runs to tell whether a revision is good.  Finally,
  22.664 +we'll use the word <quote>bisect</quote>, as both a noun and a verb, to stand in
  22.665 +for the phrase <quote>search using the <command role="hg-cmd">hg bisect</command> command.
  22.666 +</para>
  22.667 +
  22.668 +<para>One simple way to automate the searching process would be simply to
  22.669 +probe every changeset.  However, this scales poorly.  If it took ten
  22.670 +minutes to test a single changeset, and you had 10,000 changesets in
  22.671 +your repository, the exhaustive approach would take on average 35
  22.672 +<emphasis>days</emphasis> to find the changeset that introduced a bug.  Even if you
  22.673 +knew that the bug was introduced by one of the last 500 changesets,
  22.674 +and limited your search to those, you'd still be looking at over 40
  22.675 +hours to find the changeset that introduced your bug.
  22.676 +</para>
  22.677 +
  22.678 +<para>What the <command role="hg-cmd">hg bisect</command> command does is use its knowledge of the
  22.679 +<quote>shape</quote> of your project's revision history to perform a search in
  22.680 +time proportional to the <emphasis>logarithm</emphasis> of the number of changesets
  22.681 +to check (the kind of search it performs is called a dichotomic
  22.682 +search).  With this approach, searching through 10,000 changesets will
  22.683 +take less than three hours, even at ten minutes per test (the search
  22.684 +will require about 14 tests).  Limit your search to the last hundred
  22.685 +changesets, and it will take only about an hour (roughly seven tests).
  22.686 +</para>
  22.687 +
  22.688 +<para>The <command role="hg-cmd">hg bisect</command> command is aware of the <quote>branchy</quote> nature of a
  22.689 +Mercurial project's revision history, so it has no problems dealing
  22.690 +with branches, merges, or multiple heads in a repository.  It can
  22.691 +prune entire branches of history with a single probe, which is how it
  22.692 +operates so efficiently.
  22.693 +</para>
  22.694 +
  22.695 +<sect2>
  22.696 +<title>Using the <command role="hg-cmd">hg bisect</command> command</title>
  22.697 +
  22.698 +<para>Here's an example of <command role="hg-cmd">hg bisect</command> in action.
  22.699 +</para>
  22.700 +
  22.701 +<note>
  22.702 +<para>  In versions 0.9.5 and earlier of Mercurial, <command role="hg-cmd">hg bisect</command> was not a
  22.703 +  core command: it was distributed with Mercurial as an extension.
  22.704 +  This section describes the built-in command, not the old extension.
  22.705 +</para>
  22.706 +</note>
  22.707 +
  22.708 +<para>Now let's create a repository, so that we can try out the
  22.709 +<command role="hg-cmd">hg bisect</command> command in isolation.
  22.710 +<!-- &interaction.bisect.init; -->
  22.711 +We'll simulate a project that has a bug in it in a simple-minded way:
  22.712 +create trivial changes in a loop, and nominate one specific change
  22.713 +that will have the <quote>bug</quote>.  This loop creates 35 changesets, each
  22.714 +adding a single file to the repository.  We'll represent our <quote>bug</quote>
  22.715 +with a file that contains the text <quote>i have a gub</quote>.
  22.716 +<!-- &interaction.bisect.commits; -->
  22.717 +</para>
  22.718 +
  22.719 +<para>The next thing that we'd like to do is figure out how to use the
  22.720 +<command role="hg-cmd">hg bisect</command> command.  We can use Mercurial's normal built-in help
  22.721 +mechanism for this.
  22.722 +<!-- &interaction.bisect.help; -->
  22.723 +</para>
  22.724 +
  22.725 +<para>The <command role="hg-cmd">hg bisect</command> command works in steps.  Each step proceeds as follows.
  22.726 +</para>
  22.727 +<orderedlist>
  22.728 +<listitem><para>You run your binary test.
  22.729 +</para>
  22.730 +</listitem><itemizedlist>
  22.731 +<listitem><para>  \item If the test succeeded, you tell <command role="hg-cmd">hg bisect</command> by running the
  22.732 +    <command role="hg-cmd">hg bisect good</command> command.
  22.733 +  \item If it failed, run the <command role="hg-cmd">hg bisect --bad</command> command.
  22.734 +</para>
  22.735 +</listitem></itemizedlist>
  22.736 +<listitem><para>The command uses your information to decide which changeset to
  22.737 +  test next.
  22.738 +</para>
  22.739 +</listitem>
  22.740 +<listitem><para>It updates the working directory to that changeset, and the
  22.741 +  process begins again.
  22.742 +</para>
  22.743 +</listitem></orderedlist>
  22.744 +<para>The process ends when <command role="hg-cmd">hg bisect</command> identifies a unique changeset
  22.745 +that marks the point where your test transitioned from <quote>succeeding</quote>
  22.746 +to <quote>failing</quote>.
  22.747 +</para>
  22.748 +
  22.749 +<para>To start the search, we must run the <command role="hg-cmd">hg bisect --reset</command> command.
  22.750 +<!-- &interaction.bisect.search.init; -->
  22.751 +</para>
  22.752 +
  22.753 +<para>In our case, the binary test we use is simple: we check to see if any
  22.754 +file in the repository contains the string <quote>i have a gub</quote>.  If it
  22.755 +does, this changeset contains the change that <quote>caused the bug</quote>.  By
  22.756 +convention, a changeset that has the property we're searching for is
  22.757 +<quote>bad</quote>, while one that doesn't is <quote>good</quote>.
  22.758 +</para>
  22.759 +
  22.760 +<para>Most of the time, the revision to which the working directory is
  22.761 +synced (usually the tip) already exhibits the problem introduced by
  22.762 +the buggy change, so we'll mark it as <quote>bad</quote>.
  22.763 +<!-- &interaction.bisect.search.bad-init; -->
  22.764 +</para>
  22.765 +
  22.766 +<para>Our next task is to nominate a changeset that we know <emphasis>doesn't</emphasis>
  22.767 +have the bug; the <command role="hg-cmd">hg bisect</command> command will <quote>bracket</quote> its search
  22.768 +between the first pair of good and bad changesets.  In our case, we
  22.769 +know that revision 10 didn't have the bug.  (I'll have more words
  22.770 +about choosing the first <quote>good</quote> changeset later.)
  22.771 +<!-- &interaction.bisect.search.good-init; -->
  22.772 +</para>
  22.773 +
  22.774 +<para>Notice that this command printed some output.
  22.775 +</para>
  22.776 +<itemizedlist>
  22.777 +<listitem><para>It told us how many changesets it must consider before it can
  22.778 +  identify the one that introduced the bug, and how many tests that
  22.779 +  will require.
  22.780 +</para>
  22.781 +</listitem>
  22.782 +<listitem><para>It updated the working directory to the next changeset to test,
  22.783 +  and told us which changeset it's testing.
  22.784 +</para>
  22.785 +</listitem></itemizedlist>
  22.786 +
  22.787 +<para>We now run our test in the working directory.  We use the
  22.788 +<command>grep</command> command to see if our <quote>bad</quote> file is present in the
  22.789 +working directory.  If it is, this revision is bad; if not, this
  22.790 +revision is good.
  22.791 +<!-- &interaction.bisect.search.step1; -->
  22.792 +</para>
  22.793 +
  22.794 +<para>This test looks like a perfect candidate for automation, so let's turn
  22.795 +it into a shell function.
  22.796 +<!-- &interaction.bisect.search.mytest; -->
  22.797 +We can now run an entire test step with a single command,
  22.798 +<literal>mytest</literal>.
  22.799 +<!-- &interaction.bisect.search.step2; -->
  22.800 +A few more invocations of our canned test step command, and we're
  22.801 +done.
  22.802 +<!-- &interaction.bisect.search.rest; -->
  22.803 +</para>
  22.804 +
  22.805 +<para>Even though we had 40 changesets to search through, the <command role="hg-cmd">hg bisect</command>
  22.806 +command let us find the changeset that introduced our <quote>bug</quote> with
  22.807 +only five tests.  Because the number of tests that the <command role="hg-cmd">hg bisect</command>
  22.808 +command performs grows logarithmically with the number of changesets to
  22.809 +search, the advantage that it has over the <quote>brute force</quote> search
  22.810 +approach increases with every changeset you add.
  22.811 +</para>
  22.812 +
  22.813 +</sect2>
  22.814 +<sect2>
  22.815 +<title>Cleaning up after your search</title>
  22.816 +
  22.817 +<para>When you're finished using the <command role="hg-cmd">hg bisect</command> command in a
  22.818 +repository, you can use the <command role="hg-cmd">hg bisect reset</command> command to drop
  22.819 +the information it was using to drive your search.  The command
  22.820 +doesn't use much space, so it doesn't matter if you forget to run this
  22.821 +command.  However, <command role="hg-cmd">hg bisect</command> won't let you start a new search in
  22.822 +that repository until you do a <command role="hg-cmd">hg bisect reset</command>.
  22.823 +<!-- &interaction.bisect.search.reset; -->
  22.824 +</para>
  22.825 +
  22.826 +</sect2>
  22.827 +</sect1>
  22.828 +<sect1>
  22.829 +<title>Tips for finding bugs effectively</title>
  22.830 +
  22.831 +<sect2>
  22.832 +<title>Give consistent input</title>
  22.833 +
  22.834 +<para>The <command role="hg-cmd">hg bisect</command> command requires that you correctly report the
  22.835 +result of every test you perform.  If you tell it that a test failed
  22.836 +when it really succeeded, it <emphasis>might</emphasis> be able to detect the
  22.837 +inconsistency.  If it can identify an inconsistency in your reports,
  22.838 +it will tell you that a particular changeset is both good and bad.
  22.839 +However, it can't do this perfectly; it's about as likely to report
  22.840 +the wrong changeset as the source of the bug.
  22.841 +</para>
  22.842 +
  22.843 +</sect2>
  22.844 +<sect2>
  22.845 +<title>Automate as much as possible</title>
  22.846 +
  22.847 +<para>When I started using the <command role="hg-cmd">hg bisect</command> command, I tried a few times
  22.848 +to run my tests by hand, on the command line.  This is an approach
  22.849 +that I, at least, am not suited to.  After a few tries, I found that I
  22.850 +was making enough mistakes that I was having to restart my searches
  22.851 +several times before finally getting correct results.
  22.852 +</para>
  22.853 +
  22.854 +<para>My initial problems with driving the <command role="hg-cmd">hg bisect</command> command by hand
  22.855 +occurred even with simple searches on small repositories; if the
  22.856 +problem you're looking for is more subtle, or the number of tests that
  22.857 +<command role="hg-cmd">hg bisect</command> must perform increases, the likelihood of operator
  22.858 +error ruining the search is much higher.  Once I started automating my
  22.859 +tests, I had much better results.
  22.860 +</para>
  22.861 +
  22.862 +<para>The key to automated testing is twofold:
  22.863 +</para>
  22.864 +<itemizedlist>
  22.865 +<listitem><para>always test for the same symptom, and
  22.866 +</para>
  22.867 +</listitem>
  22.868 +<listitem><para>always feed consistent input to the <command role="hg-cmd">hg bisect</command> command.
  22.869 +</para>
  22.870 +</listitem></itemizedlist>
  22.871 +<para>In my tutorial example above, the <command>grep</command> command tests for the
  22.872 +symptom, and the <literal>if</literal> statement takes the result of this check
  22.873 +and ensures that we always feed the same input to the <command role="hg-cmd">hg bisect</command>
  22.874 +command.  The <literal>mytest</literal> function marries these together in a
  22.875 +reproducible way, so that every test is uniform and consistent.
  22.876 +</para>
  22.877 +
  22.878 +</sect2>
  22.879 +<sect2>
  22.880 +<title>Check your results</title>
  22.881 +
  22.882 +<para>Because the output of a <command role="hg-cmd">hg bisect</command> search is only as good as the
  22.883 +input you give it, don't take the changeset it reports as the
  22.884 +absolute truth.  A simple way to cross-check its report is to manually
  22.885 +run your test at each of the following changesets:
  22.886 +</para>
  22.887 +<itemizedlist>
  22.888 +<listitem><para>The changeset that it reports as the first bad revision.  Your
  22.889 +  test should still report this as bad.
  22.890 +</para>
  22.891 +</listitem>
  22.892 +<listitem><para>The parent of that changeset (either parent, if it's a merge).
  22.893 +  Your test should report this changeset as good.
  22.894 +</para>
  22.895 +</listitem>
  22.896 +<listitem><para>A child of that changeset.  Your test should report this
  22.897 +  changeset as bad.
  22.898 +</para>
  22.899 +</listitem></itemizedlist>
  22.900 +
  22.901 +</sect2>
  22.902 +<sect2>
  22.903 +<title>Beware interference between bugs</title>
  22.904 +
  22.905 +<para>It's possible that your search for one bug could be disrupted by the
  22.906 +presence of another.  For example, let's say your software crashes at
  22.907 +revision 100, and worked correctly at revision 50.  Unknown to you,
  22.908 +someone else introduced a different crashing bug at revision 60, and
  22.909 +fixed it at revision 80.  This could distort your results in one of
  22.910 +several ways.
  22.911 +</para>
  22.912 +
  22.913 +<para>It is possible that this other bug completely <quote>masks</quote> yours, which
  22.914 +is to say that it occurs before your bug has a chance to manifest
  22.915 +itself.  If you can't avoid that other bug (for example, it prevents
  22.916 +your project from building), and so can't tell whether your bug is
  22.917 +present in a particular changeset, the <command role="hg-cmd">hg bisect</command> command cannot
  22.918 +help you directly.  Instead, you can mark a changeset as untested by
  22.919 +running <command role="hg-cmd">hg bisect --skip</command>.
  22.920 +</para>
  22.921 +
  22.922 +<para>A different problem could arise if your test for a bug's presence is
  22.923 +not specific enough.  If you check for <quote>my program crashes</quote>, then
  22.924 +both your crashing bug and an unrelated crashing bug that masks it
  22.925 +will look like the same thing, and mislead <command role="hg-cmd">hg bisect</command>.
  22.926 +</para>
  22.927 +
  22.928 +<para>Another useful situation in which to use <command role="hg-cmd">hg bisect --skip</command> is
  22.929 +if you can't test a revision because your project was in a broken and
  22.930 +hence untestable state at that revision, perhaps because someone
  22.931 +checked in a change that prevented the project from building.
  22.932 +</para>
  22.933 +
  22.934 +</sect2>
  22.935 +<sect2>
  22.936 +<title>Bracket your search lazily</title>
  22.937 +
  22.938 +<para>Choosing the first <quote>good</quote> and <quote>bad</quote> changesets that will mark the
  22.939 +end points of your search is often easy, but it bears a little
  22.940 +discussion nevertheless.  From the perspective of <command role="hg-cmd">hg bisect</command>, the
  22.941 +<quote>newest</quote> changeset is conventionally <quote>bad</quote>, and the older
  22.942 +changeset is <quote>good</quote>.
  22.943 +</para>
  22.944 +
  22.945 +<para>If you're having trouble remembering when a suitable <quote>good</quote> change
  22.946 +was, so that you can tell <command role="hg-cmd">hg bisect</command>, you could do worse than
  22.947 +testing changesets at random.  Just remember to eliminate contenders
  22.948 +that can't possibly exhibit the bug (perhaps because the feature with
  22.949 +the bug isn't present yet) and those where another problem masks the
  22.950 +bug (as I discussed above).
  22.951 +</para>
  22.952 +
  22.953 +<para>Even if you end up <quote>early</quote> by thousands of changesets or months of
  22.954 +history, you will only add a handful of tests to the total number that
  22.955 +<command role="hg-cmd">hg bisect</command> must perform, thanks to its logarithmic behaviour.
  22.956 +</para>
  22.957 +
  22.958 +</sect2>
  22.959 +</sect1>
  22.960 +</chapter>
  22.961 +
  22.962 +<!--
  22.963 +local variables: 
  22.964 +sgml-parent-document: ("00book.xml" "book" "chapter")
  22.965 +end:
  22.966 +-->
  22.967 \ No newline at end of file
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/fr/ch10-hook.xml	Sun Aug 16 04:58:01 2009 +0200
    23.3 @@ -0,0 +1,1883 @@
    23.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    23.5 +
    23.6 +<chapter>
    23.7 +<title>Handling repository events with hooks</title>
    23.8 +<para>\label{chap:hook}</para>
    23.9 +
   23.10 +<para>Mercurial offers a powerful mechanism to let you perform automated
   23.11 +actions in response to events that occur in a repository.  In some
   23.12 +cases, you can even control Mercurial's response to those events.</para>
   23.13 +
   23.14 +<para>The name Mercurial uses for one of these actions is a <emphasis>hook</emphasis>.
   23.15 +Hooks are called <quote>triggers</quote> in some revision control systems, but
   23.16 +the two names refer to the same idea.</para>
   23.17 +
   23.18 +<sect1>
   23.19 +<title>An overview of hooks in Mercurial</title>
   23.20 +
   23.21 +<para>Here is a brief list of the hooks that Mercurial supports.  We will
   23.22 +revisit each of these hooks in more detail later, in
   23.23 +section <xref linkend="sec:hook:ref"/>.</para>
   23.24 +
   23.25 +<itemizedlist>
   23.26 +<listitem><para><literal role="hook">changegroup</literal>: This is run after a group of
   23.27 +  changesets has been brought into the repository from elsewhere.</para>
   23.28 +</listitem>
   23.29 +<listitem><para><literal role="hook">commit</literal>: This is run after a new changeset has been
   23.30 +  created in the local repository.</para>
   23.31 +</listitem>
   23.32 +<listitem><para><literal role="hook">incoming</literal>: This is run once for each new changeset
   23.33 +  that is brought into the repository from elsewhere.  Notice the
   23.34 +  difference from <literal role="hook">changegroup</literal>, which is run once per
   23.35 +  <emphasis>group</emphasis> of changesets brought in.</para>
   23.36 +</listitem>
   23.37 +<listitem><para><literal role="hook">outgoing</literal>: This is run after a group of changesets
   23.38 +  has been transmitted from this repository.</para>
   23.39 +</listitem>
   23.40 +<listitem><para><literal role="hook">prechangegroup</literal>: This is run before starting to
   23.41 +  bring a group of changesets into the repository.
   23.42 +</para>
   23.43 +</listitem>
   23.44 +<listitem><para><literal role="hook">precommit</literal>: Controlling. This is run before starting
   23.45 +  a commit.
   23.46 +</para>
   23.47 +</listitem>
   23.48 +<listitem><para><literal role="hook">preoutgoing</literal>: Controlling. This is run before
   23.49 +  starting to transmit a group of changesets from this repository.
   23.50 +</para>
   23.51 +</listitem>
   23.52 +<listitem><para><literal role="hook">pretag</literal>: Controlling. This is run before creating a tag.
   23.53 +</para>
   23.54 +</listitem>
   23.55 +<listitem><para><literal role="hook">pretxnchangegroup</literal>: Controlling. This is run after a
   23.56 +  group of changesets has been brought into the local repository from
   23.57 +  another, but before the transaction completes that will make the
   23.58 +  changes permanent in the repository.
   23.59 +</para>
   23.60 +</listitem>
   23.61 +<listitem><para><literal role="hook">pretxncommit</literal>: Controlling. This is run after a new
   23.62 +  changeset has been created in the local repository, but before the
   23.63 +  transaction completes that will make it permanent.
   23.64 +</para>
   23.65 +</listitem>
   23.66 +<listitem><para><literal role="hook">preupdate</literal>: Controlling. This is run before starting
   23.67 +  an update or merge of the working directory.
   23.68 +</para>
   23.69 +</listitem>
   23.70 +<listitem><para><literal role="hook">tag</literal>: This is run after a tag is created.
   23.71 +</para>
   23.72 +</listitem>
   23.73 +<listitem><para><literal role="hook">update</literal>: This is run after an update or merge of the
   23.74 +  working directory has finished.
   23.75 +</para>
   23.76 +</listitem></itemizedlist>
   23.77 +<para>Each of the hooks whose description begins with the word
   23.78 +<quote>Controlling</quote> has the ability to determine whether an activity can
   23.79 +proceed.  If the hook succeeds, the activity may proceed; if it fails,
   23.80 +the activity is either not permitted or undone, depending on the hook.
   23.81 +</para>
   23.82 +
   23.83 +</sect1>
   23.84 +<sect1>
   23.85 +<title>Hooks and security</title>
   23.86 +
   23.87 +<sect2>
   23.88 +<title>Hooks are run with your privileges</title>
   23.89 +
   23.90 +<para>When you run a Mercurial command in a repository, and the command
   23.91 +causes a hook to run, that hook runs on <emphasis>your</emphasis> system, under
   23.92 +<emphasis>your</emphasis> user account, with <emphasis>your</emphasis> privilege level.  Since
   23.93 +hooks are arbitrary pieces of executable code, you should treat them
   23.94 +with an appropriate level of suspicion.  Do not install a hook unless
   23.95 +you are confident that you know who created it and what it does.
   23.96 +</para>
   23.97 +
   23.98 +<para>In some cases, you may be exposed to hooks that you did not install
   23.99 +yourself.  If you work with Mercurial on an unfamiliar system,
  23.100 +Mercurial will run hooks defined in that system's global <filename role="special"> /.hgrc</filename>\ file.
  23.101 +</para>
  23.102 +
  23.103 +<para>If you are working with a repository owned by another user, Mercurial
  23.104 +can run hooks defined in that user's repository, but it will still run
  23.105 +them as <quote>you</quote>.  For example, if you <command role="hg-cmd">hg pull</command> from that
  23.106 +repository, and its <filename role="special">.hg/hgrc</filename> defines a local
  23.107 +<literal role="hook">outgoing</literal> hook, that hook will run under your user account, even
  23.108 +though you don't own that repository.
  23.109 +</para>
  23.110 +
  23.111 +<note>
  23.112 +<para>  This only applies if you are pulling from a repository on a local or
  23.113 +  network filesystem.  If you're pulling over http or ssh, any
  23.114 +  <literal role="hook">outgoing</literal> hook will run under whatever account is executing
  23.115 +  the server process, on the server.
  23.116 +</para>
  23.117 +</note>
  23.118 +
  23.119 +<para>XXX To see what hooks are defined in a repository, use the
  23.120 +<command role="hg-cmd">hg config hooks</command> command.  If you are working in one
  23.121 +repository, but talking to another that you do not own (e.g. using
  23.122 +<command role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg incoming</command>), remember that it is the other
  23.123 +repository's hooks you should be checking, not your own.
  23.124 +</para>
  23.125 +
  23.126 +</sect2>
  23.127 +<sect2>
  23.128 +<title>Hooks do not propagate</title>
  23.129 +
  23.130 +<para>In Mercurial, hooks are not revision controlled, and do not propagate
  23.131 +when you clone, or pull from, a repository.  The reason for this is
  23.132 +simple: a hook is a completely arbitrary piece of executable code.  It
  23.133 +runs under your user identity, with your privilege level, on your
  23.134 +machine.
  23.135 +</para>
  23.136 +
  23.137 +<para>It would be extremely reckless for any distributed revision control
  23.138 +system to implement revision-controlled hooks, as this would offer an
  23.139 +easily exploitable way to subvert the accounts of users of the
  23.140 +revision control system.
  23.141 +</para>
  23.142 +
  23.143 +<para>Since Mercurial does not propagate hooks, if you are collaborating
  23.144 +with other people on a common project, you should not assume that they
  23.145 +are using the same Mercurial hooks as you are, or that theirs are
  23.146 +correctly configured.  You should document the hooks you expect people
  23.147 +to use.
  23.148 +</para>
  23.149 +
  23.150 +<para>In a corporate intranet, this is somewhat easier to control, as you
  23.151 +can for example provide a <quote>standard</quote> installation of Mercurial on an
  23.152 +NFS filesystem, and use a site-wide <filename role="special"> /.hgrc</filename>\ file to define hooks that
  23.153 +all users will see.  However, this too has its limits; see below.
  23.154 +</para>
  23.155 +
  23.156 +</sect2>
  23.157 +<sect2>
  23.158 +<title>Hooks can be overridden</title>
  23.159 +
  23.160 +<para>Mercurial allows you to override a hook definition by redefining the
  23.161 +hook.  You can disable it by setting its value to the empty string, or
  23.162 +change its behaviour as you wish.
  23.163 +</para>
  23.164 +
  23.165 +<para>If you deploy a system- or site-wide <filename role="special"> /.hgrc</filename>\ file that defines some
  23.166 +hooks, you should thus understand that your users can disable or
  23.167 +override those hooks.
  23.168 +</para>
  23.169 +
  23.170 +</sect2>
  23.171 +<sect2>
  23.172 +<title>Ensuring that critical hooks are run</title>
  23.173 +
  23.174 +<para>Sometimes you may want to enforce a policy that you do not want others
  23.175 +to be able to work around.  For example, you may have a requirement
  23.176 +that every changeset must pass a rigorous set of tests.  Defining this
  23.177 +requirement via a hook in a site-wide <filename role="special"> /.hgrc</filename>\ won't work for remote
  23.178 +users on laptops, and of course local users can subvert it at will by
  23.179 +overriding the hook.
  23.180 +</para>
  23.181 +
  23.182 +<para>Instead, you can set up your policies for use of Mercurial so that
  23.183 +people are expected to propagate changes through a well-known
  23.184 +<quote>canonical</quote> server that you have locked down and configured
  23.185 +appropriately.
  23.186 +</para>
  23.187 +
  23.188 +<para>One way to do this is via a combination of social engineering and
  23.189 +technology.  Set up a restricted-access account; users can push
  23.190 +changes over the network to repositories managed by this account, but
  23.191 +they cannot log into the account and run normal shell commands.  In
  23.192 +this scenario, a user can commit a changeset that contains any old
  23.193 +garbage they want.
  23.194 +</para>
  23.195 +
  23.196 +<para>When someone pushes a changeset to the server that everyone pulls
  23.197 +from, the server will test the changeset before it accepts it as
  23.198 +permanent, and reject it if it fails to pass the test suite.  If
  23.199 +people only pull changes from this filtering server, it will serve to
  23.200 +ensure that all changes that people pull have been automatically
  23.201 +vetted.
  23.202 +</para>
  23.203 +
  23.204 +</sect2>
  23.205 +</sect1>
  23.206 +<sect1>
  23.207 +<title>Care with <literal>pretxn</literal> hooks in a shared-access repository</title>
  23.208 +
  23.209 +<para>If you want to use hooks to do some automated work in a repository
  23.210 +that a number of people have shared access to, you need to be careful
  23.211 +in how you do this.
  23.212 +</para>
  23.213 +
  23.214 +<para>Mercurial only locks a repository when it is writing to the
  23.215 +repository, and only the parts of Mercurial that write to the
  23.216 +repository pay attention to locks.  Write locks are necessary to
  23.217 +prevent multiple simultaneous writers from scribbling on each other's
  23.218 +work, corrupting the repository.
  23.219 +</para>
  23.220 +
  23.221 +<para>Because Mercurial is careful with the order in which it reads and
  23.222 +writes data, it does not need to acquire a lock when it wants to read
  23.223 +data from the repository.  The parts of Mercurial that read from the
  23.224 +repository never pay attention to locks.  This lockless reading scheme
  23.225 +greatly increases performance and concurrency.
  23.226 +</para>
  23.227 +
  23.228 +<para>With great performance comes a trade-off, though, one which has the
  23.229 +potential to cause you trouble unless you're aware of it.  To describe
  23.230 +this requires a little detail about how Mercurial adds changesets to a
  23.231 +repository and reads those changes.
  23.232 +</para>
  23.233 +
  23.234 +<para>When Mercurial <emphasis>writes</emphasis> metadata, it writes it straight into the
  23.235 +destination file.  It writes file data first, then manifest data
  23.236 +(which contains pointers to the new file data), then changelog data
  23.237 +(which contains pointers to the new manifest data).  Before the first
  23.238 +write to each file, it stores a record of where the end of the file
  23.239 +was in its transaction log.  If the transaction must be rolled back,
  23.240 +Mercurial simply truncates each file back to the size it was before the
  23.241 +transaction began.
  23.242 +</para>
  23.243 +
  23.244 +<para>When Mercurial <emphasis>reads</emphasis> metadata, it reads the changelog first,
  23.245 +then everything else.  Since a reader will only access parts of the
  23.246 +manifest or file metadata that it can see in the changelog, it can
  23.247 +never see partially written data.
  23.248 +</para>
  23.249 +
  23.250 +<para>Some controlling hooks (<literal role="hook">pretxncommit</literal> and
  23.251 +<literal role="hook">pretxnchangegroup</literal>) run when a transaction is almost complete.
  23.252 +All of the metadata has been written, but Mercurial can still roll the
  23.253 +transaction back and cause the newly-written data to disappear.
  23.254 +</para>
  23.255 +
  23.256 +<para>If one of these hooks runs for long, it opens a window of time during
  23.257 +which a reader can see the metadata for changesets that are not yet
  23.258 +permanent, and should not be thought of as <quote>really there</quote>.  The
  23.259 +longer the hook runs, the longer that window is open.
  23.260 +</para>
  23.261 +
  23.262 +<sect2>
  23.263 +<title>The problem illustrated</title>
  23.264 +
  23.265 +<para>In principle, a good use for the <literal role="hook">pretxnchangegroup</literal> hook would
  23.266 +be to automatically build and test incoming changes before they are
  23.267 +accepted into a central repository.  This could let you guarantee that
  23.268 +nobody can push changes to this repository that <quote>break the build</quote>.
  23.269 +But if a client can pull changes while they're being tested, the
  23.270 +usefulness of the test is zero; an unsuspecting someone can pull
  23.271 +untested changes, potentially breaking their build.
  23.272 +</para>
  23.273 +
  23.274 +<para>The safest technological answer to this challenge is to set up such a
  23.275 +<quote>gatekeeper</quote> repository as <emphasis>unidirectional</emphasis>.  Let it take
  23.276 +changes pushed in from the outside, but do not allow anyone to pull
  23.277 +changes from it (use the <literal role="hook">preoutgoing</literal> hook to lock it down).
  23.278 +Configure a <literal role="hook">changegroup</literal> hook so that if a build or test
  23.279 +succeeds, the hook will push the new changes out to another repository
  23.280 +that people <emphasis>can</emphasis> pull from.
  23.281 +</para>
  23.282 +
  23.283 +<para>In practice, putting a centralised bottleneck like this in place is
  23.284 +not often a good idea, and transaction visibility has nothing to do
  23.285 +with the problem.  As the size of a project&emdash;and the time it takes to
  23.286 +build and test&emdash;grows, you rapidly run into a wall with this <quote>try
  23.287 +before you buy</quote> approach, where you have more changesets to test than
  23.288 +time in which to deal with them.  The inevitable result is frustration
  23.289 +on the part of all involved.
  23.290 +</para>
  23.291 +
  23.292 +<para>An approach that scales better is to get people to build and test
  23.293 +before they push, then run automated builds and tests centrally
  23.294 +<emphasis>after</emphasis> a push, to be sure all is well.  The advantage of this
  23.295 +approach is that it does not impose a limit on the rate at which the
  23.296 +repository can accept changes.
  23.297 +</para>
  23.298 +
  23.299 +</sect2>
  23.300 +</sect1>
  23.301 +<sect1>
  23.302 +<title>A short tutorial on using hooks</title>
  23.303 +<para>\label{sec:hook:simple}
  23.304 +</para>
  23.305 +
  23.306 +<para>It is easy to write a Mercurial hook.  Let's start with a hook that
  23.307 +runs when you finish a <command role="hg-cmd">hg commit</command>, and simply prints the hash of
  23.308 +the changeset you just created.  The hook is called <literal role="hook">commit</literal>.
  23.309 +</para>
  23.310 +
  23.311 +<informalfigure>
  23.312 +<para>  <!-- &interaction.hook.simple.init; -->
  23.313 +  <caption><para>A simple hook that runs when a changeset is committed</para></caption>
  23.314 +  \label{ex:hook:init}
  23.315 +</para>
  23.316 +</informalfigure>
  23.317 +
  23.318 +<para>All hooks follow the pattern in example <xref linkend="ex:hook:init"/>.  You add
  23.319 +an entry to the <literal role="rc-hooks">hooks</literal> section of your <filename role="special"> /.hgrc</filename>.  On the left
  23.320 +is the name of the event to trigger on; on the right is the action to
  23.321 +take.  As you can see, you can run an arbitrary shell command in a
  23.322 +hook.  Mercurial passes extra information to the hook using
  23.323 +environment variables (look for <envar>HG_NODE</envar> in the example).
  23.324 +</para>
  23.325 +
  23.326 +<sect2>
  23.327 +<title>Performing multiple actions per event</title>
  23.328 +
  23.329 +<para>Quite often, you will want to define more than one hook for a
  23.330 +particular kind of event, as shown in example <xref linkend="ex:hook:ext"/>.
  23.331 +Mercurial lets you do this by adding an <emphasis>extension</emphasis> to the end of
  23.332 +a hook's name.  You extend a hook's name by giving the name of the
  23.333 +hook, followed by a full stop (the <quote><literal>.</literal></quote> character), followed
  23.334 +by some more text of your choosing.  For example, Mercurial will run
  23.335 +both <literal>commit.foo</literal> and <literal>commit.bar</literal> when the
  23.336 +<literal>commit</literal> event occurs.
  23.337 +</para>
  23.338 +
  23.339 +<informalfigure>
  23.340 +<para>  <!-- &interaction.hook.simple.ext; -->
  23.341 +  <caption><para>Defining a second <literal role="hook">commit</para></caption> hook</literal>
  23.342 +  \label{ex:hook:ext}
  23.343 +</para>
  23.344 +</informalfigure>
  23.345 +
  23.346 +<para>To give a well-defined order of execution when there are multiple
  23.347 +hooks defined for an event, Mercurial sorts hooks by extension, and
  23.348 +executes the hook commands in this sorted order.  In the above
  23.349 +example, it will execute <literal>commit.bar</literal> before
  23.350 +<literal>commit.foo</literal>, and <literal>commit</literal> before both.
  23.351 +</para>
  23.352 +
  23.353 +<para>It is a good idea to use a somewhat descriptive extension when you
  23.354 +define a new hook.  This will help you to remember what the hook was
  23.355 +for.  If the hook fails, you'll get an error message that contains the
  23.356 +hook name and extension, so using a descriptive extension could give
  23.357 +you an immediate hint as to why the hook failed (see
  23.358 +section <xref linkend="sec:hook:perm"/> for an example).
  23.359 +</para>
  23.360 +
  23.361 +</sect2>
  23.362 +<sect2>
  23.363 +<title>Controlling whether an activity can proceed</title>
  23.364 +<para>\label{sec:hook:perm}
  23.365 +</para>
  23.366 +
  23.367 +<para>In our earlier examples, we used the <literal role="hook">commit</literal> hook, which is
  23.368 +run after a commit has completed.  This is one of several Mercurial
  23.369 +hooks that run after an activity finishes.  Such hooks have no way of
  23.370 +influencing the activity itself.
  23.371 +</para>
  23.372 +
  23.373 +<para>Mercurial defines a number of events that occur before an activity
  23.374 +starts; or after it starts, but before it finishes.  Hooks that
  23.375 +trigger on these events have the added ability to choose whether the
  23.376 +activity can continue, or will abort.
  23.377 +</para>
  23.378 +
  23.379 +<para>The <literal role="hook">pretxncommit</literal> hook runs after a commit has all but
  23.380 +completed.  In other words, the metadata representing the changeset
  23.381 +has been written out to disk, but the transaction has not yet been
  23.382 +allowed to complete.  The <literal role="hook">pretxncommit</literal> hook has the ability to
  23.383 +decide whether the transaction can complete, or must be rolled back.
  23.384 +</para>
  23.385 +
  23.386 +<para>If the <literal role="hook">pretxncommit</literal> hook exits with a status code of zero, the
  23.387 +transaction is allowed to complete; the commit finishes; and the
  23.388 +<literal role="hook">commit</literal> hook is run.  If the <literal role="hook">pretxncommit</literal> hook exits with
  23.389 +a non-zero status code, the transaction is rolled back; the metadata
  23.390 +representing the changeset is erased; and the <literal role="hook">commit</literal> hook is
  23.391 +not run.
  23.392 +</para>
  23.393 +
  23.394 +<informalfigure>
  23.395 +<para>  <!-- &interaction.hook.simple.pretxncommit; -->
  23.396 +  <caption><para>Using the <literal role="hook">pretxncommit</para></caption> hook to control commits</literal>
  23.397 +  \label{ex:hook:pretxncommit}
  23.398 +</para>
  23.399 +</informalfigure>
  23.400 +
  23.401 +<para>The hook in example <xref linkend="ex:hook:pretxncommit"/> checks that a commit
  23.402 +comment contains a bug ID.  If it does, the commit can complete.  If
  23.403 +not, the commit is rolled back.
  23.404 +</para>
  23.405 +
  23.406 +</sect2>
  23.407 +</sect1>
  23.408 +<sect1>
  23.409 +<title>Writing your own hooks</title>
  23.410 +
  23.411 +<para>When you are writing a hook, you might find it useful to run Mercurial
  23.412 +either with the <option role="hg-opt-global">-v</option> option, or the <envar role="rc-item-ui">verbose</envar> config
  23.413 +item set to <quote>true</quote>.  When you do so, Mercurial will print a message
  23.414 +before it calls each hook.
  23.415 +</para>
  23.416 +
  23.417 +<sect2>
  23.418 +<title>Choosing how your hook should run</title>
  23.419 +<para>\label{sec:hook:lang}
  23.420 +</para>
  23.421 +
  23.422 +<para>You can write a hook either as a normal program&emdash;typically a shell
  23.423 +script&emdash;or as a Python function that is executed within the Mercurial
  23.424 +process.
  23.425 +</para>
  23.426 +
  23.427 +<para>Writing a hook as an external program has the advantage that it
  23.428 +requires no knowledge of Mercurial's internals.  You can call normal
  23.429 +Mercurial commands to get any added information you need.  The
  23.430 +trade-off is that external hooks are slower than in-process hooks.
  23.431 +</para>
  23.432 +
  23.433 +<para>An in-process Python hook has complete access to the Mercurial API,
  23.434 +and does not <quote>shell out</quote> to another process, so it is inherently
  23.435 +faster than an external hook.  It is also easier to obtain much of the
  23.436 +information that a hook requires by using the Mercurial API than by
  23.437 +running Mercurial commands.
  23.438 +</para>
  23.439 +
  23.440 +<para>If you are comfortable with Python, or require high performance,
  23.441 +writing your hooks in Python may be a good choice.  However, when you
  23.442 +have a straightforward hook to write and you don't need to care about
  23.443 +performance (probably the majority of hooks), a shell script is
  23.444 +perfectly fine.
  23.445 +</para>
  23.446 +
  23.447 +</sect2>
  23.448 +<sect2>
  23.449 +<title>Hook parameters</title>
  23.450 +<para>\label{sec:hook:param}
  23.451 +</para>
  23.452 +
  23.453 +<para>Mercurial calls each hook with a set of well-defined parameters.  In
  23.454 +Python, a parameter is passed as a keyword argument to your hook
  23.455 +function.  For an external program, a parameter is passed as an
  23.456 +environment variable.
  23.457 +</para>
  23.458 +
  23.459 +<para>Whether your hook is written in Python or as a shell script, the
  23.460 +hook-specific parameter names and values will be the same.  A boolean
  23.461 +parameter will be represented as a boolean value in Python, but as the
  23.462 +number 1 (for <quote>true</quote>) or 0 (for <quote>false</quote>) as an environment
  23.463 +variable for an external hook.  If a hook parameter is named
  23.464 +<literal>foo</literal>, the keyword argument for a Python hook will also be
  23.465 +named <literal>foo</literal>, while the environment variable for an external
  23.466 +hook will be named <literal>HG_FOO</literal>.
  23.467 +</para>
  23.468 +
  23.469 +</sect2>
  23.470 +<sect2>
  23.471 +<title>Hook return values and activity control</title>
  23.472 +
  23.473 +<para>A hook that executes successfully must exit with a status of zero if
  23.474 +external, or return boolean <quote>false</quote> if in-process.  Failure is
  23.475 +indicated with a non-zero exit status from an external hook, or an
  23.476 +in-process hook returning boolean <quote>true</quote>.  If an in-process hook
  23.477 +raises an exception, the hook is considered to have failed.
  23.478 +</para>
  23.479 +
  23.480 +<para>For a hook that controls whether an activity can proceed, zero/false
  23.481 +means <quote>allow</quote>, while non-zero/true/exception means <quote>deny</quote>.
  23.482 +</para>
  23.483 +
  23.484 +</sect2>
  23.485 +<sect2>
  23.486 +<title>Writing an external hook</title>
  23.487 +
  23.488 +<para>When you define an external hook in your <filename role="special"> /.hgrc</filename>\ and the hook is run,
  23.489 +its value is passed to your shell, which interprets it.  This means
  23.490 +that you can use normal shell constructs in the body of the hook.
  23.491 +</para>
  23.492 +
  23.493 +<para>An executable hook is always run with its current directory set to a
  23.494 +repository's root directory.
  23.495 +</para>
  23.496 +
  23.497 +<para>Each hook parameter is passed in as an environment variable; the name
  23.498 +is upper-cased, and prefixed with the string <quote><literal>HG_</literal></quote>.
  23.499 +</para>
  23.500 +
  23.501 +<para>With the exception of hook parameters, Mercurial does not set or
  23.502 +modify any environment variables when running a hook.  This is useful
  23.503 +to remember if you are writing a site-wide hook that may be run by a
  23.504 +number of different users with differing environment variables set.
  23.505 +In multi-user situations, you should not rely on environment variables
  23.506 +being set to the values you have in your environment when testing the
  23.507 +hook.
  23.508 +</para>
  23.509 +
  23.510 +</sect2>
  23.511 +<sect2>
  23.512 +<title>Telling Mercurial to use an in-process hook</title>
  23.513 +
  23.514 +<para>The <filename role="special"> /.hgrc</filename>\ syntax for defining an in-process hook is slightly
  23.515 +different than for an executable hook.  The value of the hook must
  23.516 +start with the text <quote><literal>python:</literal></quote>, and continue with the
  23.517 +fully-qualified name of a callable object to use as the hook's value.
  23.518 +</para>
  23.519 +
  23.520 +<para>The module in which a hook lives is automatically imported when a hook
  23.521 +is run.  So long as you have the module name and <envar>PYTHONPATH</envar>
  23.522 +right, it should <quote>just work</quote>.
  23.523 +</para>
  23.524 +
  23.525 +<para>The following <filename role="special"> /.hgrc</filename>\ example snippet illustrates the syntax and
  23.526 +meaning of the notions we just described.
  23.527 +</para>
  23.528 +<programlisting>
  23.529 +<para>  [hooks]
  23.530 +  commit.example = python:mymodule.submodule.myhook
  23.531 +</para>
  23.532 +</programlisting>
  23.533 +<para>When Mercurial runs the <literal>commit.example</literal> hook, it imports
  23.534 +<literal>mymodule.submodule</literal>, looks for the callable object named
  23.535 +<literal>myhook</literal>, and calls it.
  23.536 +</para>
  23.537 +
  23.538 +</sect2>
  23.539 +<sect2>
  23.540 +<title>Writing an in-process hook</title>
  23.541 +
  23.542 +<para>The simplest in-process hook does nothing, but illustrates the basic
  23.543 +shape of the hook API:
  23.544 +</para>
  23.545 +<programlisting>
  23.546 +<para>  def myhook(ui, repo, **kwargs):
  23.547 +      pass
  23.548 +</para>
  23.549 +</programlisting>
  23.550 +<para>The first argument to a Python hook is always a
  23.551 +<literal role="py-mod-mercurial.ui">ui</literal> object.  The second is a repository object;
  23.552 +at the moment, it is always an instance of
  23.553 +<literal role="py-mod-mercurial.localrepo">localrepository</literal>.  Following these two
  23.554 +arguments are other keyword arguments.  Which ones are passed in
  23.555 +depends on the hook being called, but a hook can ignore arguments it
  23.556 +doesn't care about by dropping them into a keyword argument dict, as
  23.557 +with <literal>**kwargs</literal> above.
  23.558 +</para>
  23.559 +
  23.560 +</sect2>
  23.561 +</sect1>
  23.562 +<sect1>
  23.563 +<title>Some hook examples</title>
  23.564 +
  23.565 +<sect2>
  23.566 +<title>Writing meaningful commit messages</title>
  23.567 +
  23.568 +<para>It's hard to imagine a useful commit message being very short.  The
  23.569 +simple <literal role="hook">pretxncommit</literal> hook of figure <xref linkend="ex:hook:msglen.go"/>
  23.570 +will prevent you from committing a changeset with a message that is
  23.571 +less than ten bytes long.
  23.572 +</para>
  23.573 +
  23.574 +<informalfigure>
  23.575 +<para>  <!-- &interaction.hook.msglen.go; -->
  23.576 +  <caption><para>A hook that forbids overly short commit messages</para></caption>
  23.577 +  \label{ex:hook:msglen.go}
  23.578 +</para>
  23.579 +</informalfigure>
  23.580 +
  23.581 +</sect2>
  23.582 +<sect2>
  23.583 +<title>Checking for trailing whitespace</title>
  23.584 +
  23.585 +<para>An interesting use of a commit-related hook is to help you to write
  23.586 +cleaner code.  A simple example of <quote>cleaner code</quote> is the dictum that
  23.587 +a change should not add any new lines of text that contain <quote>trailing
  23.588 +whitespace</quote>.  Trailing whitespace is a series of space and tab
  23.589 +characters at the end of a line of text.  In most cases, trailing
  23.590 +whitespace is unnecessary, invisible noise, but it is occasionally
  23.591 +problematic, and people often prefer to get rid of it.
  23.592 +</para>
  23.593 +
  23.594 +<para>You can use either the <literal role="hook">precommit</literal> or <literal role="hook">pretxncommit</literal> hook to
  23.595 +tell whether you have a trailing whitespace problem.  If you use the
  23.596 +<literal role="hook">precommit</literal> hook, the hook will not know which files you are
  23.597 +committing, so it will have to check every modified file in the
  23.598 +repository for trailing white space.  If you want to commit a change
  23.599 +to just the file <filename>foo</filename>, but the file <filename>bar</filename> contains
  23.600 +trailing whitespace, doing a check in the <literal role="hook">precommit</literal> hook will
  23.601 +prevent you from committing <filename>foo</filename> due to the problem with
  23.602 +<filename>bar</filename>.  This doesn't seem right.
  23.603 +</para>
  23.604 +
  23.605 +<para>Should you choose the <literal role="hook">pretxncommit</literal> hook, the check won't occur
  23.606 +until just before the transaction for the commit completes.  This will
  23.607 +allow you to check for problems only the exact files that are being
  23.608 +committed.  However, if you entered the commit message interactively
  23.609 +and the hook fails, the transaction will roll back; you'll have to
  23.610 +re-enter the commit message after you fix the trailing whitespace and
  23.611 +run <command role="hg-cmd">hg commit</command> again.
  23.612 +</para>
  23.613 +
  23.614 +<informalfigure>
  23.615 +<para>  <!-- &interaction.hook.ws.simple; -->
  23.616 +  <caption><para>A simple hook that checks for trailing whitespace</para></caption>
  23.617 +  \label{ex:hook:ws.simple}
  23.618 +</para>
  23.619 +</informalfigure>
  23.620 +
  23.621 +<para>Figure <xref linkend="ex:hook:ws.simple"/> introduces a simple <literal role="hook">pretxncommit</literal>
  23.622 +hook that checks for trailing whitespace.  This hook is short, but not
  23.623 +very helpful.  It exits with an error status if a change adds a line
  23.624 +with trailing whitespace to any file, but does not print any
  23.625 +information that might help us to identify the offending file or
  23.626 +line.  It also has the nice property of not paying attention to
  23.627 +unmodified lines; only lines that introduce new trailing whitespace
  23.628 +cause problems.
  23.629 +</para>
  23.630 +
  23.631 +<informalfigure>
  23.632 +<para>  <!-- &interaction.hook.ws.better; -->
  23.633 +  <caption><para>A better trailing whitespace hook</para></caption>
  23.634 +  \label{ex:hook:ws.better}
  23.635 +</para>
  23.636 +</informalfigure>
  23.637 +
  23.638 +<para>The example of figure <xref linkend="ex:hook:ws.better"/> is much more complex,
  23.639 +but also more useful.  It parses a unified diff to see if any lines
  23.640 +add trailing whitespace, and prints the name of the file and the line
  23.641 +number of each such occurrence.  Even better, if the change adds
  23.642 +trailing whitespace, this hook saves the commit comment and prints the
  23.643 +name of the save file before exiting and telling Mercurial to roll the
  23.644 +transaction back, so you can use
  23.645 +<command role="hg-cmd">hg commit <option role="hg-opt-commit">-l</option> <emphasis>filename</emphasis></command> to reuse the
  23.646 +saved commit message once you've corrected the problem.
  23.647 +</para>
  23.648 +
  23.649 +<para>As a final aside, note in figure <xref linkend="ex:hook:ws.better"/> the use of
  23.650 +<command>perl</command>'s in-place editing feature to get rid of trailing
  23.651 +whitespace from a file.  This is concise and useful enough that I will
  23.652 +reproduce it here.
  23.653 +</para>
  23.654 +<programlisting>
  23.655 +<para>  perl -pi -e 's,\textbackslash{}s+$,,' filename
  23.656 +</para>
  23.657 +</programlisting>
  23.658 +
  23.659 +</sect2>
  23.660 +</sect1>
  23.661 +<sect1>
  23.662 +<title>Bundled hooks</title>
  23.663 +
  23.664 +<para>Mercurial ships with several bundled hooks.  You can find them in the
  23.665 +<filename class="directory">hgext</filename> directory of a Mercurial source tree.  If you are
  23.666 +using a Mercurial binary package, the hooks will be located in the
  23.667 +<filename class="directory">hgext</filename> directory of wherever your package installer put
  23.668 +Mercurial.
  23.669 +</para>
  23.670 +
  23.671 +<sect2>
  23.672 +<title><literal role="hg-ext">acl</literal>&emdash;access control for parts of a repository</title>
  23.673 +
  23.674 +<para>The <literal role="hg-ext">acl</literal> extension lets you control which remote users are
  23.675 +allowed to push changesets to a networked server.  You can protect any
  23.676 +portion of a repository (including the entire repo), so that a
  23.677 +specific remote user can push changes that do not affect the protected
  23.678 +portion.
  23.679 +</para>
  23.680 +
  23.681 +<para>This extension implements access control based on the identity of the
  23.682 +user performing a push, <emphasis>not</emphasis> on who committed the changesets
  23.683 +they're pushing.  It makes sense to use this hook only if you have a
  23.684 +locked-down server environment that authenticates remote users, and
  23.685 +you want to be sure that only specific users are allowed to push
  23.686 +changes to that server.
  23.687 +</para>
  23.688 +
  23.689 +<sect3>
  23.690 +<title>Configuring the <literal role="hook">acl</literal> hook</title>
  23.691 +
  23.692 +<para>In order to manage incoming changesets, the <literal role="hg-ext">acl</literal> hook must be
  23.693 +used as a <literal role="hook">pretxnchangegroup</literal> hook.  This lets it see which files
  23.694 +are modified by each incoming changeset, and roll back a group of
  23.695 +changesets if they modify <quote>forbidden</quote> files.  Example:
  23.696 +</para>
  23.697 +<programlisting>
  23.698 +<para>  [hooks]
  23.699 +  pretxnchangegroup.acl = python:hgext.acl.hook
  23.700 +</para>
  23.701 +</programlisting>
  23.702 +
  23.703 +<para>The <literal role="hg-ext">acl</literal> extension is configured using three sections.
  23.704 +</para>
  23.705 +
  23.706 +<para>The <literal role="rc-acl">acl</literal> section has only one entry, <envar role="rc-item-acl">sources</envar>,
  23.707 +which lists the sources of incoming changesets that the hook should
  23.708 +pay attention to.  You don't normally need to configure this section.
  23.709 +</para>
  23.710 +<itemizedlist>
  23.711 +<listitem><para><envar role="rc-item-acl">serve</envar>: Control incoming changesets that are arriving
  23.712 +  from a remote repository over http or ssh.  This is the default
  23.713 +  value of <envar role="rc-item-acl">sources</envar>, and usually the only setting you'll
  23.714 +  need for this configuration item.
  23.715 +</para>
  23.716 +</listitem>
  23.717 +<listitem><para><envar role="rc-item-acl">pull</envar>: Control incoming changesets that are
  23.718 +  arriving via a pull from a local repository.
  23.719 +</para>
  23.720 +</listitem>
  23.721 +<listitem><para><envar role="rc-item-acl">push</envar>: Control incoming changesets that are
  23.722 +  arriving via a push from a local repository.
  23.723 +</para>
  23.724 +</listitem>
  23.725 +<listitem><para><envar role="rc-item-acl">bundle</envar>: Control incoming changesets that are
  23.726 +  arriving from another repository via a bundle.
  23.727 +</para>
  23.728 +</listitem></itemizedlist>
  23.729 +
  23.730 +<para>The <literal role="rc-acl.allow">acl.allow</literal> section controls the users that are allowed to
  23.731 +add changesets to the repository.  If this section is not present, all
  23.732 +users that are not explicitly denied are allowed.  If this section is
  23.733 +present, all users that are not explicitly allowed are denied (so an
  23.734 +empty section means that all users are denied).
  23.735 +</para>
  23.736 +
  23.737 +<para>The <literal role="rc-acl.deny">acl.deny</literal> section determines which users are denied
  23.738 +from adding changesets to the repository.  If this section is not
  23.739 +present or is empty, no users are denied.
  23.740 +</para>
  23.741 +
  23.742 +<para>The syntaxes for the <literal role="rc-acl.allow">acl.allow</literal> and <literal role="rc-acl.deny">acl.deny</literal>
  23.743 +sections are identical.  On the left of each entry is a glob pattern
  23.744 +that matches files or directories, relative to the root of the
  23.745 +repository; on the right, a user name.
  23.746 +</para>
  23.747 +
  23.748 +<para>In the following example, the user <literal>docwriter</literal> can only push
  23.749 +changes to the <filename class="directory">docs</filename> subtree of the repository, while
  23.750 +<literal>intern</literal> can push changes to any file or directory except
  23.751 +<filename class="directory">source/sensitive</filename>.
  23.752 +</para>
  23.753 +<programlisting>
  23.754 +<para>  [acl.allow]
  23.755 +  docs/** = docwriter
  23.756 +</para>
  23.757 +
  23.758 +<para>  [acl.deny]
  23.759 +  source/sensitive/** = intern
  23.760 +</para>
  23.761 +</programlisting>
  23.762 +
  23.763 +</sect3>
  23.764 +<sect3>
  23.765 +<title>Testing and troubleshooting</title>
  23.766 +
  23.767 +<para>If you want to test the <literal role="hg-ext">acl</literal> hook, run it with Mercurial's
  23.768 +debugging output enabled.  Since you'll probably be running it on a
  23.769 +server where it's not convenient (or sometimes possible) to pass in
  23.770 +the <option role="hg-opt-global">--debug</option> option, don't forget that you can enable
  23.771 +debugging output in your <filename role="special"> /.hgrc</filename>:
  23.772 +</para>
  23.773 +<programlisting>
  23.774 +<para>  [ui]
  23.775 +  debug = true
  23.776 +</para>
  23.777 +</programlisting>
  23.778 +<para>With this enabled, the <literal role="hg-ext">acl</literal> hook will print enough information
  23.779 +to let you figure out why it is allowing or forbidding pushes from
  23.780 +specific users.
  23.781 +</para>
  23.782 +
  23.783 +</sect3>
  23.784 +</sect2>
  23.785 +<sect2>
  23.786 +<title><literal role="hg-ext">bugzilla</literal>&emdash;integration with Bugzilla</title>
  23.787 +
  23.788 +<para>The <literal role="hg-ext">bugzilla</literal> extension adds a comment to a Bugzilla bug
  23.789 +whenever it finds a reference to that bug ID in a commit comment.  You
  23.790 +can install this hook on a shared server, so that any time a remote
  23.791 +user pushes changes to this server, the hook gets run.
  23.792 +</para>
  23.793 +
  23.794 +<para>It adds a comment to the bug that looks like this (you can configure
  23.795 +the contents of the comment&emdash;see below):
  23.796 +</para>
  23.797 +<programlisting>
  23.798 +<para>  Changeset aad8b264143a, made by Joe User &lt;joe.user@domain.com&gt; in
  23.799 +  the frobnitz repository, refers to this bug.
  23.800 +</para>
  23.801 +
  23.802 +<para>  For complete details, see
  23.803 +  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
  23.804 +</para>
  23.805 +
  23.806 +<para>  Changeset description:
  23.807 +        Fix bug 10483 by guarding against some NULL pointers
  23.808 +</para>
  23.809 +</programlisting>
  23.810 +<para>The value of this hook is that it automates the process of updating a
  23.811 +bug any time a changeset refers to it.  If you configure the hook
  23.812 +properly, it makes it easy for people to browse straight from a
  23.813 +Bugzilla bug to a changeset that refers to that bug.
  23.814 +</para>
  23.815 +
  23.816 +<para>You can use the code in this hook as a starting point for some more
  23.817 +exotic Bugzilla integration recipes.  Here are a few possibilities:
  23.818 +</para>
  23.819 +<itemizedlist>
  23.820 +<listitem><para>Require that every changeset pushed to the server have a valid
  23.821 +  bug ID in its commit comment.  In this case, you'd want to configure
  23.822 +  the hook as a <literal role="hook">pretxncommit</literal> hook.  This would allow the hook
  23.823 +  to reject changes that didn't contain bug IDs.
  23.824 +</para>
  23.825 +</listitem>
  23.826 +<listitem><para>Allow incoming changesets to automatically modify the
  23.827 +  <emphasis>state</emphasis> of a bug, as well as simply adding a comment.  For
  23.828 +  example, the hook could recognise the string <quote>fixed bug 31337</quote> as
  23.829 +  indicating that it should update the state of bug 31337 to
  23.830 +  <quote>requires testing</quote>.
  23.831 +</para>
  23.832 +</listitem></itemizedlist>
  23.833 +
  23.834 +<sect3>
  23.835 +<title>Configuring the <literal role="hook">bugzilla</literal> hook</title>
  23.836 +<para>\label{sec:hook:bugzilla:config}
  23.837 +</para>
  23.838 +
  23.839 +<para>You should configure this hook in your server's <filename role="special"> /.hgrc</filename>\ as an
  23.840 +<literal role="hook">incoming</literal> hook, for example as follows:
  23.841 +</para>
  23.842 +<programlisting>
  23.843 +<para>  [hooks]
  23.844 +  incoming.bugzilla = python:hgext.bugzilla.hook
  23.845 +</para>
  23.846 +</programlisting>
  23.847 +
  23.848 +<para>Because of the specialised nature of this hook, and because Bugzilla
  23.849 +was not written with this kind of integration in mind, configuring
  23.850 +this hook is a somewhat involved process.
  23.851 +</para>
  23.852 +
  23.853 +<para>Before you begin, you must install the MySQL bindings for Python on
  23.854 +the host(s) where you'll be running the hook.  If this is not
  23.855 +available as a binary package for your system, you can download it
  23.856 +from <citation>web:mysql-python</citation>.
  23.857 +</para>
  23.858 +
  23.859 +<para>Configuration information for this hook lives in the
  23.860 +<literal role="rc-bugzilla">bugzilla</literal> section of your <filename role="special"> /.hgrc</filename>.
  23.861 +</para>
  23.862 +<itemizedlist>
  23.863 +<listitem><para><envar role="rc-item-bugzilla">version</envar>: The version of Bugzilla installed on
  23.864 +  the server.  The database schema that Bugzilla uses changes
  23.865 +  occasionally, so this hook has to know exactly which schema to use.
  23.866 +  At the moment, the only version supported is <literal>2.16</literal>.
  23.867 +</para>
  23.868 +</listitem>
  23.869 +<listitem><para><envar role="rc-item-bugzilla">host</envar>: The hostname of the MySQL server that
  23.870 +  stores your Bugzilla data.  The database must be configured to allow
  23.871 +  connections from whatever host you are running the <literal role="hook">bugzilla</literal>
  23.872 +  hook on.
  23.873 +</para>
  23.874 +</listitem>
  23.875 +<listitem><para><envar role="rc-item-bugzilla">user</envar>: The username with which to connect to
  23.876 +  the MySQL server.  The database must be configured to allow this
  23.877 +  user to connect from whatever host you are running the
  23.878 +  <literal role="hook">bugzilla</literal> hook on.  This user must be able to access and
  23.879 +  modify Bugzilla tables.  The default value of this item is
  23.880 +  <literal>bugs</literal>, which is the standard name of the Bugzilla user in a
  23.881 +  MySQL database.
  23.882 +</para>
  23.883 +</listitem>
  23.884 +<listitem><para><envar role="rc-item-bugzilla">password</envar>: The MySQL password for the user you
  23.885 +  configured above.  This is stored as plain text, so you should make
  23.886 +  sure that unauthorised users cannot read the <filename role="special"> /.hgrc</filename>\ file where you
  23.887 +  store this information.
  23.888 +</para>
  23.889 +</listitem>
  23.890 +<listitem><para><envar role="rc-item-bugzilla">db</envar>: The name of the Bugzilla database on the
  23.891 +  MySQL server.  The default value of this item is <literal>bugs</literal>,
  23.892 +  which is the standard name of the MySQL database where Bugzilla
  23.893 +  stores its data.
  23.894 +</para>
  23.895 +</listitem>
  23.896 +<listitem><para><envar role="rc-item-bugzilla">notify</envar>: If you want Bugzilla to send out a
  23.897 +  notification email to subscribers after this hook has added a
  23.898 +  comment to a bug, you will need this hook to run a command whenever
  23.899 +  it updates the database.  The command to run depends on where you
  23.900 +  have installed Bugzilla, but it will typically look something like
  23.901 +  this, if you have Bugzilla installed in
  23.902 +  <filename class="directory">/var/www/html/bugzilla</filename>:
  23.903 +</para>
  23.904 +</listitem><programlisting>
  23.905 +<listitem><para>    cd /var/www/html/bugzilla &amp;&amp; ./processmail %s nobody@nowhere.com
  23.906 +</para>
  23.907 +</listitem></programlisting>
  23.908 +<listitem><para>  The Bugzilla <literal>processmail</literal> program expects to be given a
  23.909 +  bug ID (the hook replaces <quote><literal>%s</literal></quote> with the bug ID) and an
  23.910 +  email address.  It also expects to be able to write to some files in
  23.911 +  the directory that it runs in.  If Bugzilla and this hook are not
  23.912 +  installed on the same machine, you will need to find a way to run
  23.913 +  <literal>processmail</literal> on the server where Bugzilla is installed.
  23.914 +</para>
  23.915 +</listitem></itemizedlist>
  23.916 +
  23.917 +</sect3>
  23.918 +<sect3>
  23.919 +<title>Mapping committer names to Bugzilla user names</title>
  23.920 +
  23.921 +<para>By default, the <literal role="hg-ext">bugzilla</literal> hook tries to use the email address
  23.922 +of a changeset's committer as the Bugzilla user name with which to
  23.923 +update a bug.  If this does not suit your needs, you can map committer
  23.924 +email addresses to Bugzilla user names using a <literal role="rc-usermap">usermap</literal>
  23.925 +section.
  23.926 +</para>
  23.927 +
  23.928 +<para>Each item in the <literal role="rc-usermap">usermap</literal> section contains an email address
  23.929 +on the left, and a Bugzilla user name on the right.
  23.930 +</para>
  23.931 +<programlisting>
  23.932 +<para>  [usermap]
  23.933 +  jane.user@example.com = jane
  23.934 +</para>
  23.935 +</programlisting>
  23.936 +<para>You can either keep the <literal role="rc-usermap">usermap</literal> data in a normal <filename role="special"> /.hgrc</filename>, or
  23.937 +tell the <literal role="hg-ext">bugzilla</literal> hook to read the information from an
  23.938 +external <filename>usermap</filename> file.  In the latter case, you can store
  23.939 +<filename>usermap</filename> data by itself in (for example) a user-modifiable
  23.940 +repository.  This makes it possible to let your users maintain their
  23.941 +own <envar role="rc-item-bugzilla">usermap</envar> entries.  The main <filename role="special"> /.hgrc</filename>\ file might
  23.942 +look like this:
  23.943 +</para>
  23.944 +<programlisting>
  23.945 +<para>  # regular hgrc file refers to external usermap file
  23.946 +  [bugzilla]
  23.947 +  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
  23.948 +</para>
  23.949 +</programlisting>
  23.950 +<para>While the <filename>usermap</filename> file that it refers to might look like
  23.951 +this:
  23.952 +</para>
  23.953 +<programlisting>
  23.954 +<para>  # bugzilla-usermap.conf - inside a hg repository
  23.955 +  [usermap]
  23.956 +  stephanie@example.com = steph
  23.957 +</para>
  23.958 +</programlisting>
  23.959 +
  23.960 +</sect3>
  23.961 +<sect3>
  23.962 +<title>Configuring the text that gets added to a bug</title>
  23.963 +
  23.964 +<para>You can configure the text that this hook adds as a comment; you
  23.965 +specify it in the form of a Mercurial template.  Several <filename role="special"> /.hgrc</filename>\
  23.966 +entries (still in the <literal role="rc-bugzilla">bugzilla</literal> section) control this
  23.967 +behaviour.
  23.968 +</para>
  23.969 +<itemizedlist>
  23.970 +<listitem><para><literal>strip</literal>: The number of leading path elements to strip
  23.971 +  from a repository's path name to construct a partial path for a URL.
  23.972 +  For example, if the repositories on your server live under
  23.973 +  <filename class="directory">/home/hg/repos</filename>, and you have a repository whose path is
  23.974 +  <filename class="directory">/home/hg/repos/app/tests</filename>, then setting <literal>strip</literal> to
  23.975 +  <literal>4</literal> will give a partial path of <filename class="directory">app/tests</filename>.  The
  23.976 +  hook will make this partial path available when expanding a
  23.977 +  template, as <literal>webroot</literal>.
  23.978 +</para>
  23.979 +</listitem>
  23.980 +<listitem><para><literal>template</literal>: The text of the template to use.  In addition
  23.981 +  to the usual changeset-related variables, this template can use
  23.982 +  <literal>hgweb</literal> (the value of the <literal>hgweb</literal> configuration item
  23.983 +  above) and <literal>webroot</literal> (the path constructed using
  23.984 +  <literal>strip</literal> above).
  23.985 +</para>
  23.986 +</listitem></itemizedlist>
  23.987 +
  23.988 +<para>In addition, you can add a <envar role="rc-item-web">baseurl</envar> item to the
  23.989 +<literal role="rc-web">web</literal> section of your <filename role="special"> /.hgrc</filename>.  The <literal role="hg-ext">bugzilla</literal> hook will
  23.990 +make this available when expanding a template, as the base string to
  23.991 +use when constructing a URL that will let users browse from a Bugzilla
  23.992 +comment to view a changeset.  Example:
  23.993 +</para>
  23.994 +<programlisting>
  23.995 +<para>  [web]
  23.996 +  baseurl = http://hg.domain.com/
  23.997 +</para>
  23.998 +</programlisting>
  23.999 +
 23.1000 +<para>Here is an example set of <literal role="hg-ext">bugzilla</literal> hook config information.
 23.1001 +</para>
 23.1002 +<programlisting>
 23.1003 +<para>  [bugzilla]
 23.1004 +  host = bugzilla.example.com
 23.1005 +  password = mypassword
 23.1006 +  version = 2.16
 23.1007 +  # server-side repos live in /home/hg/repos, so strip 4 leading
 23.1008 +  # separators
 23.1009 +  strip = 4
 23.1010 +  hgweb = http://hg.example.com/
 23.1011 +  usermap = /home/hg/repos/notify/bugzilla.conf
 23.1012 +  template = Changeset {node|short}, made by {author} in the {webroot}
 23.1013 +    repo, refers to this bug.\\nFor complete details, see
 23.1014 +    {hgweb}{webroot}?cmd=changeset;node={node|short}\\nChangeset
 23.1015 +    description:\\n\\t{desc|tabindent}
 23.1016 +</para>
 23.1017 +</programlisting>
 23.1018 +
 23.1019 +</sect3>
 23.1020 +<sect3>
 23.1021 +<title>Testing and troubleshooting</title>
 23.1022 +
 23.1023 +<para>The most common problems with configuring the <literal role="hg-ext">bugzilla</literal> hook
 23.1024 +relate to running Bugzilla's <filename>processmail</filename> script and mapping
 23.1025 +committer names to user names.
 23.1026 +</para>
 23.1027 +
 23.1028 +<para>Recall from section <xref linkend="sec:hook:bugzilla:config"/> above that the user
 23.1029 +that runs the Mercurial process on the server is also the one that
 23.1030 +will run the <filename>processmail</filename> script.  The
 23.1031 +<filename>processmail</filename> script sometimes causes Bugzilla to write to
 23.1032 +files in its configuration directory, and Bugzilla's configuration
 23.1033 +files are usually owned by the user that your web server runs under.
 23.1034 +</para>
 23.1035 +
 23.1036 +<para>You can cause <filename>processmail</filename> to be run with the suitable
 23.1037 +user's identity using the <command>sudo</command> command.  Here is an example
 23.1038 +entry for a <filename>sudoers</filename> file.
 23.1039 +</para>
 23.1040 +<programlisting>
 23.1041 +<para>  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
 23.1042 +</para>
 23.1043 +</programlisting>
 23.1044 +<para>This allows the <literal>hg_user</literal> user to run a
 23.1045 +<filename>processmail-wrapper</filename> program under the identity of
 23.1046 +<literal>httpd_user</literal>.
 23.1047 +</para>
 23.1048 +
 23.1049 +<para>This indirection through a wrapper script is necessary, because
 23.1050 +<filename>processmail</filename> expects to be run with its current directory
 23.1051 +set to wherever you installed Bugzilla; you can't specify that kind of
 23.1052 +constraint in a <filename>sudoers</filename> file.  The contents of the wrapper
 23.1053 +script are simple:
 23.1054 +</para>
 23.1055 +<programlisting>
 23.1056 +<para>  #!/bin/sh
 23.1057 +  cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com
 23.1058 +</para>
 23.1059 +</programlisting>
 23.1060 +<para>It doesn't seem to matter what email address you pass to
 23.1061 +<filename>processmail</filename>.
 23.1062 +</para>
 23.1063 +
 23.1064 +<para>If your <literal role="rc-usermap">usermap</literal> is not set up correctly, users will see an
 23.1065 +error message from the <literal role="hg-ext">bugzilla</literal> hook when they push changes
 23.1066 +to the server.  The error message will look like this:
 23.1067 +</para>
 23.1068 +<programlisting>
 23.1069 +<para>  cannot find bugzilla user id for john.q.public@example.com
 23.1070 +</para>
 23.1071 +</programlisting>
 23.1072 +<para>What this means is that the committer's address,
 23.1073 +<literal>john.q.public@example.com</literal>, is not a valid Bugzilla user name,
 23.1074 +nor does it have an entry in your <literal role="rc-usermap">usermap</literal> that maps it to
 23.1075 +a valid Bugzilla user name.
 23.1076 +</para>
 23.1077 +
 23.1078 +</sect3>
 23.1079 +</sect2>
 23.1080 +<sect2>
 23.1081 +<title><literal role="hg-ext">notify</literal>&emdash;send email notifications</title>
 23.1082 +
 23.1083 +<para>Although Mercurial's built-in web server provides RSS feeds of changes
 23.1084 +in every repository, many people prefer to receive change
 23.1085 +notifications via email.  The <literal role="hg-ext">notify</literal> hook lets you send out
 23.1086 +notifications to a set of email addresses whenever changesets arrive
 23.1087 +that those subscribers are interested in.
 23.1088 +</para>
 23.1089 +
 23.1090 +<para>As with the <literal role="hg-ext">bugzilla</literal> hook, the <literal role="hg-ext">notify</literal> hook is
 23.1091 +template-driven, so you can customise the contents of the notification
 23.1092 +messages that it sends.
 23.1093 +</para>
 23.1094 +
 23.1095 +<para>By default, the <literal role="hg-ext">notify</literal> hook includes a diff of every changeset
 23.1096 +that it sends out; you can limit the size of the diff, or turn this
 23.1097 +feature off entirely.  It is useful for letting subscribers review
 23.1098 +changes immediately, rather than clicking to follow a URL.
 23.1099 +</para>
 23.1100 +
 23.1101 +<sect3>
 23.1102 +<title>Configuring the <literal role="hg-ext">notify</literal> hook</title>
 23.1103 +
 23.1104 +<para>You can set up the <literal role="hg-ext">notify</literal> hook to send one email message per
 23.1105 +incoming changeset, or one per incoming group of changesets (all those
 23.1106 +that arrived in a single pull or push).
 23.1107 +</para>
 23.1108 +<programlisting>
 23.1109 +<para>  [hooks]
 23.1110 +  # send one email per group of changes
 23.1111 +  changegroup.notify = python:hgext.notify.hook
 23.1112 +  # send one email per change
 23.1113 +  incoming.notify = python:hgext.notify.hook
 23.1114 +</para>
 23.1115 +</programlisting>
 23.1116 +
 23.1117 +<para>Configuration information for this hook lives in the
 23.1118 +<literal role="rc-notify">notify</literal> section of a <filename role="special"> /.hgrc</filename>\ file.
 23.1119 +</para>
 23.1120 +<itemizedlist>
 23.1121 +<listitem><para><envar role="rc-item-notify">test</envar>: By default, this hook does not send out
 23.1122 +  email at all; instead, it prints the message that it <emphasis>would</emphasis>
 23.1123 +  send.  Set this item to <literal>false</literal> to allow email to be sent.
 23.1124 +  The reason that sending of email is turned off by default is that it
 23.1125 +  takes several tries to configure this extension exactly as you would
 23.1126 +  like, and it would be bad form to spam subscribers with a number of
 23.1127 +  <quote>broken</quote> notifications while you debug your configuration.
 23.1128 +</para>
 23.1129 +</listitem>
 23.1130 +<listitem><para><envar role="rc-item-notify">config</envar>: The path to a configuration file that
 23.1131 +  contains subscription information.  This is kept separate from the
 23.1132 +  main <filename role="special"> /.hgrc</filename>\ so that you can maintain it in a repository of its own.
 23.1133 +  People can then clone that repository, update their subscriptions,
 23.1134 +  and push the changes back to your server.
 23.1135 +</para>
 23.1136 +</listitem>
 23.1137 +<listitem><para><envar role="rc-item-notify">strip</envar>: The number of leading path separator
 23.1138 +  characters to strip from a repository's path, when deciding whether
 23.1139 +  a repository has subscribers.  For example, if the repositories on
 23.1140 +  your server live in <filename class="directory">/home/hg/repos</filename>, and <literal role="hg-ext">notify</literal> is
 23.1141 +  considering a repository named <filename class="directory">/home/hg/repos/shared/test</filename>,
 23.1142 +  setting <envar role="rc-item-notify">strip</envar> to <literal>4</literal> will cause
 23.1143 +  <literal role="hg-ext">notify</literal> to trim the path it considers down to
 23.1144 +  <filename class="directory">shared/test</filename>, and it will match subscribers against that.
 23.1145 +</para>
 23.1146 +</listitem>
 23.1147 +<listitem><para><envar role="rc-item-notify">template</envar>: The template text to use when sending
 23.1148 +  messages.  This specifies both the contents of the message header
 23.1149 +  and its body.
 23.1150 +</para>
 23.1151 +</listitem>
 23.1152 +<listitem><para><envar role="rc-item-notify">maxdiff</envar>: The maximum number of lines of diff
 23.1153 +  data to append to the end of a message.  If a diff is longer than
 23.1154 +  this, it is truncated.  By default, this is set to 300.  Set this to
 23.1155 +  <literal>0</literal> to omit diffs from notification emails.
 23.1156 +</para>
 23.1157 +</listitem>
 23.1158 +<listitem><para><envar role="rc-item-notify">sources</envar>: A list of sources of changesets to
 23.1159 +  consider.  This lets you limit <literal role="hg-ext">notify</literal> to only sending out
 23.1160 +  email about changes that remote users pushed into this repository
 23.1161 +  via a server, for example.  See section <xref linkend="sec:hook:sources"/> for
 23.1162 +  the sources you can specify here.
 23.1163 +</para>
 23.1164 +</listitem></itemizedlist>
 23.1165 +
 23.1166 +<para>If you set the <envar role="rc-item-web">baseurl</envar> item in the <literal role="rc-web">web</literal>
 23.1167 +section, you can use it in a template; it will be available as
 23.1168 +<literal>webroot</literal>.
 23.1169 +</para>
 23.1170 +
 23.1171 +<para>Here is an example set of <literal role="hg-ext">notify</literal> configuration information.
 23.1172 +</para>
 23.1173 +<programlisting>
 23.1174 +<para>  [notify]
 23.1175 +  # really send email
 23.1176 +  test = false
 23.1177 +  # subscriber data lives in the notify repo
 23.1178 +  config = /home/hg/repos/notify/notify.conf
 23.1179 +  # repos live in /home/hg/repos on server, so strip 4 "/" chars
 23.1180 +  strip = 4
 23.1181 +  template = X-Hg-Repo: {webroot}
 23.1182 +    Subject: {webroot}: {desc|firstline|strip}
 23.1183 +    From: {author}
 23.1184 +</para>
 23.1185 +
 23.1186 +<para>    changeset {node|short} in {root}
 23.1187 +    details: {baseurl}{webroot}?cmd=changeset;node={node|short}
 23.1188 +    description:
 23.1189 +      {desc|tabindent|strip}
 23.1190 +</para>
 23.1191 +
 23.1192 +<para>  [web]
 23.1193 +  baseurl = http://hg.example.com/
 23.1194 +</para>
 23.1195 +</programlisting>
 23.1196 +
 23.1197 +<para>This will produce a message that looks like the following:
 23.1198 +</para>
 23.1199 +<programlisting>
 23.1200 +<para>  X-Hg-Repo: tests/slave
 23.1201 +  Subject: tests/slave: Handle error case when slave has no buffers
 23.1202 +  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
 23.1203 +</para>
 23.1204 +
 23.1205 +<para>  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
 23.1206 +  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
 23.1207 +  description:
 23.1208 +          Handle error case when slave has no buffers
 23.1209 +  diffs (54 lines):
 23.1210 +</para>
 23.1211 +
 23.1212 +<para>  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
 23.1213 +  &emdash; a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
 23.1214 +  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
 23.1215 +  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
 23.1216 +  [...snip...]
 23.1217 +</para>
 23.1218 +</programlisting>
 23.1219 +
 23.1220 +</sect3>
 23.1221 +<sect3>
 23.1222 +<title>Testing and troubleshooting</title>
 23.1223 +
 23.1224 +<para>Do not forget that by default, the <literal role="hg-ext">notify</literal> extension \emph{will
 23.1225 +  not send any mail} until you explicitly configure it to do so, by
 23.1226 +setting <envar role="rc-item-notify">test</envar> to <literal>false</literal>.  Until you do that,
 23.1227 +it simply prints the message it <emphasis>would</emphasis> send.
 23.1228 +</para>
 23.1229 +
 23.1230 +</sect3>
 23.1231 +</sect2>
 23.1232 +</sect1>
 23.1233 +<sect1>
 23.1234 +<title>Information for writers of hooks</title>
 23.1235 +<para>\label{sec:hook:ref}
 23.1236 +</para>
 23.1237 +
 23.1238 +<sect2>
 23.1239 +<title>In-process hook execution</title>
 23.1240 +
 23.1241 +<para>An in-process hook is called with arguments of the following form:
 23.1242 +</para>
 23.1243 +<programlisting>
 23.1244 +<para>  def myhook(ui, repo, **kwargs):
 23.1245 +      pass
 23.1246 +</para>
 23.1247 +</programlisting>
 23.1248 +<para>The <literal>ui</literal> parameter is a <literal role="py-mod-mercurial.ui">ui</literal> object.
 23.1249 +The <literal>repo</literal> parameter is a
 23.1250 +<literal role="py-mod-mercurial.localrepo">localrepository</literal> object.  The
 23.1251 +names and values of the <literal>**kwargs</literal> parameters depend on the
 23.1252 +hook being invoked, with the following common features:
 23.1253 +</para>
 23.1254 +<itemizedlist>
 23.1255 +<listitem><para>If a parameter is named <literal>node</literal> or
 23.1256 +  <literal>parent<emphasis>N</emphasis></literal>, it will contain a hexadecimal changeset ID.
 23.1257 +  The empty string is used to represent <quote>null changeset ID</quote> instead
 23.1258 +  of a string of zeroes.
 23.1259 +</para>
 23.1260 +</listitem>
 23.1261 +<listitem><para>If a parameter is named <literal>url</literal>, it will contain the URL of
 23.1262 +  a remote repository, if that can be determined.
 23.1263 +</para>
 23.1264 +</listitem>
 23.1265 +<listitem><para>Boolean-valued parameters are represented as Python
 23.1266 +  <literal>bool</literal> objects.
 23.1267 +</para>
 23.1268 +</listitem></itemizedlist>
 23.1269 +
 23.1270 +<para>An in-process hook is called without a change to the process's working
 23.1271 +directory (unlike external hooks, which are run in the root of the
 23.1272 +repository).  It must not change the process's working directory, or
 23.1273 +it will cause any calls it makes into the Mercurial API to fail.
 23.1274 +</para>
 23.1275 +
 23.1276 +<para>If a hook returns a boolean <quote>false</quote> value, it is considered to have
 23.1277 +succeeded.  If it returns a boolean <quote>true</quote> value or raises an
 23.1278 +exception, it is considered to have failed.  A useful way to think of
 23.1279 +the calling convention is <quote>tell me if you fail</quote>.
 23.1280 +</para>
 23.1281 +
 23.1282 +<para>Note that changeset IDs are passed into Python hooks as hexadecimal
 23.1283 +strings, not the binary hashes that Mercurial's APIs normally use.  To
 23.1284 +convert a hash from hex to binary, use the
 23.1285 +\pymodfunc{mercurial.node}{bin} function.
 23.1286 +</para>
 23.1287 +
 23.1288 +</sect2>
 23.1289 +<sect2>
 23.1290 +<title>External hook execution</title>
 23.1291 +
 23.1292 +<para>An external hook is passed to the shell of the user running Mercurial.
 23.1293 +Features of that shell, such as variable substitution and command
 23.1294 +redirection, are available.  The hook is run in the root directory of
 23.1295 +the repository (unlike in-process hooks, which are run in the same
 23.1296 +directory that Mercurial was run in).
 23.1297 +</para>
 23.1298 +
 23.1299 +<para>Hook parameters are passed to the hook as environment variables.  Each
 23.1300 +environment variable's name is converted in upper case and prefixed
 23.1301 +with the string <quote><literal>HG_</literal></quote>.  For example, if the name of a
 23.1302 +parameter is <quote><literal>node</literal></quote>, the name of the environment variable
 23.1303 +representing that parameter will be <quote><literal>HG_NODE</literal></quote>.
 23.1304 +</para>
 23.1305 +
 23.1306 +<para>A boolean parameter is represented as the string <quote><literal>1</literal></quote> for
 23.1307 +<quote>true</quote>, <quote><literal>0</literal></quote> for <quote>false</quote>.  If an environment variable is
 23.1308 +named <envar>HG_NODE</envar>, <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
 23.1309 +contains a changeset ID represented as a hexadecimal string.  The
 23.1310 +empty string is used to represent <quote>null changeset ID</quote> instead of a
 23.1311 +string of zeroes.  If an environment variable is named
 23.1312 +<envar>HG_URL</envar>, it will contain the URL of a remote repository, if
 23.1313 +that can be determined.
 23.1314 +</para>
 23.1315 +
 23.1316 +<para>If a hook exits with a status of zero, it is considered to have
 23.1317 +succeeded.  If it exits with a non-zero status, it is considered to
 23.1318 +have failed.
 23.1319 +</para>
 23.1320 +
 23.1321 +</sect2>
 23.1322 +<sect2>
 23.1323 +<title>Finding out where changesets come from</title>
 23.1324 +
 23.1325 +<para>A hook that involves the transfer of changesets between a local
 23.1326 +repository and another may be able to find out information about the
 23.1327 +<quote>far side</quote>.  Mercurial knows <emphasis>how</emphasis> changes are being
 23.1328 +transferred, and in many cases <emphasis>where</emphasis> they are being transferred
 23.1329 +to or from.
 23.1330 +</para>
 23.1331 +
 23.1332 +<sect3>
 23.1333 +<title>Sources of changesets</title>
 23.1334 +<para>\label{sec:hook:sources}
 23.1335 +</para>
 23.1336 +
 23.1337 +<para>Mercurial will tell a hook what means are, or were, used to transfer
 23.1338 +changesets between repositories.  This is provided by Mercurial in a
 23.1339 +Python parameter named <literal>source</literal>, or an environment variable named
 23.1340 +<envar>HG_SOURCE</envar>.
 23.1341 +</para>
 23.1342 +
 23.1343 +<itemizedlist>
 23.1344 +<listitem><para><literal>serve</literal>: Changesets are transferred to or from a remote
 23.1345 +  repository over http or ssh.
 23.1346 +</para>
 23.1347 +</listitem>
 23.1348 +<listitem><para><literal>pull</literal>: Changesets are being transferred via a pull from
 23.1349 +  one repository into another.
 23.1350 +</para>
 23.1351 +</listitem>
 23.1352 +<listitem><para><literal>push</literal>: Changesets are being transferred via a push from
 23.1353 +  one repository into another.
 23.1354 +</para>
 23.1355 +</listitem>
 23.1356 +<listitem><para><literal>bundle</literal>: Changesets are being transferred to or from a
 23.1357 +  bundle.
 23.1358 +</para>
 23.1359 +</listitem></itemizedlist>
 23.1360 +
 23.1361 +</sect3>
 23.1362 +<sect3>
 23.1363 +<title>Where changes are going&emdash;remote repository URLs</title>
 23.1364 +<para>\label{sec:hook:url}
 23.1365 +</para>
 23.1366 +
 23.1367 +<para>When possible, Mercurial will tell a hook the location of the <quote>far
 23.1368 +side</quote> of an activity that transfers changeset data between
 23.1369 +repositories.  This is provided by Mercurial in a Python parameter
 23.1370 +named <literal>url</literal>, or an environment variable named <envar>HG_URL</envar>.
 23.1371 +</para>
 23.1372 +
 23.1373 +<para>This information is not always known.  If a hook is invoked in a
 23.1374 +repository that is being served via http or ssh, Mercurial cannot tell
 23.1375 +where the remote repository is, but it may know where the client is
 23.1376 +connecting from.  In such cases, the URL will take one of the
 23.1377 +following forms:
 23.1378 +</para>
 23.1379 +<itemizedlist>
 23.1380 +<listitem><para><literal>remote:ssh:<emphasis>ip-address</emphasis></literal>&emdash;remote ssh client, at
 23.1381 +  the given IP address.
 23.1382 +</para>
 23.1383 +</listitem>
 23.1384 +<listitem><para><literal>remote:http:<emphasis>ip-address</emphasis></literal>&emdash;remote http client, at
 23.1385 +  the given IP address.  If the client is using SSL, this will be of
 23.1386 +  the form <literal>remote:https:<emphasis>ip-address</emphasis></literal>.
 23.1387 +</para>
 23.1388 +</listitem>
 23.1389 +<listitem><para>Empty&emdash;no information could be discovered about the remote
 23.1390 +  client.
 23.1391 +</para>
 23.1392 +</listitem></itemizedlist>
 23.1393 +
 23.1394 +</sect3>
 23.1395 +</sect2>
 23.1396 +</sect1>
 23.1397 +<sect1>
 23.1398 +<title>Hook reference</title>
 23.1399 +
 23.1400 +<sect2>
 23.1401 +<title><literal role="hook">changegroup</literal>&emdash;after remote changesets added</title>
 23.1402 +<para>\label{sec:hook:changegroup}
 23.1403 +</para>
 23.1404 +
 23.1405 +<para>This hook is run after a group of pre-existing changesets has been
 23.1406 +added to the repository, for example via a <command role="hg-cmd">hg pull</command> or
 23.1407 +<command role="hg-cmd">hg unbundle</command>.  This hook is run once per operation that added one
 23.1408 +or more changesets.  This is in contrast to the <literal role="hook">incoming</literal> hook,
 23.1409 +which is run once per changeset, regardless of whether the changesets
 23.1410 +arrive in a group.
 23.1411 +</para>
 23.1412 +
 23.1413 +<para>Some possible uses for this hook include kicking off an automated
 23.1414 +build or test of the added changesets, updating a bug database, or
 23.1415 +notifying subscribers that a repository contains new changes.
 23.1416 +</para>
 23.1417 +
 23.1418 +<para>Parameters to this hook:
 23.1419 +</para>
 23.1420 +<itemizedlist>
 23.1421 +<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the first
 23.1422 +  changeset in the group that was added.  All changesets between this
 23.1423 +  and \index{tags!<literal>tip</literal>}<literal>tip</literal>, inclusive, were added by
 23.1424 +  a single <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg push</command> or <command role="hg-cmd">hg unbundle</command>.
 23.1425 +</para>
 23.1426 +</listitem>
 23.1427 +<listitem><para><literal>source</literal>: A string.  The source of these changes.  See
 23.1428 +  section <xref linkend="sec:hook:sources"/> for details.
 23.1429 +</para>
 23.1430 +</listitem>
 23.1431 +<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
 23.1432 +  known.  See section <xref linkend="sec:hook:url"/> for more information.
 23.1433 +</para>
 23.1434 +</listitem></itemizedlist>
 23.1435 +
 23.1436 +<para>See also: <literal role="hook">incoming</literal> (section <xref linkend="sec:hook:incoming"/>),
 23.1437 +<literal role="hook">prechangegroup</literal> (section <xref linkend="sec:hook:prechangegroup"/>),
 23.1438 +<literal role="hook">pretxnchangegroup</literal> (section <xref linkend="sec:hook:pretxnchangegroup"/>)
 23.1439 +</para>
 23.1440 +
 23.1441 +</sect2>
 23.1442 +<sect2>
 23.1443 +<title><literal role="hook">commit</literal>&emdash;after a new changeset is created</title>
 23.1444 +<para>\label{sec:hook:commit}
 23.1445 +</para>
 23.1446 +
 23.1447 +<para>This hook is run after a new changeset has been created.
 23.1448 +</para>
 23.1449 +
 23.1450 +<para>Parameters to this hook:
 23.1451 +</para>
 23.1452 +<itemizedlist>
 23.1453 +<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the newly
 23.1454 +  committed changeset.
 23.1455 +</para>
 23.1456 +</listitem>
 23.1457 +<listitem><para><literal>parent1</literal>: A changeset ID.  The changeset ID of the first
 23.1458 +  parent of the newly committed changeset.
 23.1459 +</para>
 23.1460 +</listitem>
 23.1461 +<listitem><para><literal>parent2</literal>: A changeset ID.  The changeset ID of the second
 23.1462 +  parent of the newly committed changeset.
 23.1463 +</para>
 23.1464 +</listitem></itemizedlist>
 23.1465 +
 23.1466 +<para>See also: <literal role="hook">precommit</literal> (section <xref linkend="sec:hook:precommit"/>),
 23.1467 +<literal role="hook">pretxncommit</literal> (section <xref linkend="sec:hook:pretxncommit"/>)
 23.1468 +</para>
 23.1469 +
 23.1470 +</sect2>
 23.1471 +<sect2>
 23.1472 +<title><literal role="hook">incoming</literal>&emdash;after one remote changeset is added</title>
 23.1473 +<para>\label{sec:hook:incoming}
 23.1474 +</para>
 23.1475 +
 23.1476 +<para>This hook is run after a pre-existing changeset has been added to the
 23.1477 +repository, for example via a <command role="hg-cmd">hg push</command>.  If a group of changesets
 23.1478 +was added in a single operation, this hook is called once for each
 23.1479 +added changeset.
 23.1480 +</para>
 23.1481 +
 23.1482 +<para>You can use this hook for the same purposes as the <literal role="hook">changegroup</literal>
 23.1483 +hook (section <xref linkend="sec:hook:changegroup"/>); it's simply more convenient
 23.1484 +sometimes to run a hook once per group of changesets, while other
 23.1485 +times it's handier once per changeset.
 23.1486 +</para>
 23.1487 +
 23.1488 +<para>Parameters to this hook:
 23.1489 +</para>
 23.1490 +<itemizedlist>
 23.1491 +<listitem><para><literal>node</literal>: A changeset ID.  The ID of the newly added
 23.1492 +  changeset.
 23.1493 +</para>
 23.1494 +</listitem>
 23.1495 +<listitem><para><literal>source</literal>: A string.  The source of these changes.  See
 23.1496 +  section <xref linkend="sec:hook:sources"/> for details.
 23.1497 +</para>
 23.1498 +</listitem>
 23.1499 +<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
 23.1500 +  known.  See section <xref linkend="sec:hook:url"/> for more information.
 23.1501 +</para>
 23.1502 +</listitem></itemizedlist>
 23.1503 +
 23.1504 +<para>See also: <literal role="hook">changegroup</literal> (section <xref linkend="sec:hook:changegroup"/>) <literal role="hook">prechangegroup</literal> (section <xref linkend="sec:hook:prechangegroup"/>), <literal role="hook">pretxnchangegroup</literal> (section <xref linkend="sec:hook:pretxnchangegroup"/>)
 23.1505 +</para>
 23.1506 +
 23.1507 +</sect2>
 23.1508 +<sect2>
 23.1509 +<title><literal role="hook">outgoing</literal>&emdash;after changesets are propagated</title>
 23.1510 +<para>\label{sec:hook:outgoing}
 23.1511 +</para>
 23.1512 +
 23.1513 +<para>This hook is run after a group of changesets has been propagated out
 23.1514 +of this repository, for example by a <command role="hg-cmd">hg push</command> or <command role="hg-cmd">hg bundle</command>
 23.1515 +command.
 23.1516 +</para>
 23.1517 +
 23.1518 +<para>One possible use for this hook is to notify administrators that
 23.1519 +changes have been pulled.
 23.1520 +</para>
 23.1521 +
 23.1522 +<para>Parameters to this hook:
 23.1523 +</para>
 23.1524 +<itemizedlist>
 23.1525 +<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the first
 23.1526 +  changeset of the group that was sent.
 23.1527 +</para>
 23.1528 +</listitem>
 23.1529 +<listitem><para><literal>source</literal>: A string.  The source of the of the operation
 23.1530 +  (see section <xref linkend="sec:hook:sources"/>).  If a remote client pulled
 23.1531 +  changes from this repository, <literal>source</literal> will be
 23.1532 +  <literal>serve</literal>.  If the client that obtained changes from this
 23.1533 +  repository was local, <literal>source</literal> will be <literal>bundle</literal>,
 23.1534 +  <literal>pull</literal>, or <literal>push</literal>, depending on the operation the
 23.1535 +  client performed.
 23.1536 +</para>
 23.1537 +</listitem>
 23.1538 +<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
 23.1539 +  known.  See section <xref linkend="sec:hook:url"/> for more information.
 23.1540 +</para>
 23.1541 +</listitem></itemizedlist>
 23.1542 +
 23.1543 +<para>See also: <literal role="hook">preoutgoing</literal> (section <xref linkend="sec:hook:preoutgoing"/>)
 23.1544 +</para>
 23.1545 +
 23.1546 +</sect2>
 23.1547 +<sect2>
 23.1548 +<title><literal role="hook">prechangegroup</literal>&emdash;before starting to add remote changesets</title>
 23.1549 +<para>\label{sec:hook:prechangegroup}
 23.1550 +</para>
 23.1551 +
 23.1552 +<para>This controlling hook is run before Mercurial begins to add a group of
 23.1553 +changesets from another repository.
 23.1554 +</para>
 23.1555 +
 23.1556 +<para>This hook does not have any information about the changesets to be
 23.1557 +added, because it is run before transmission of those changesets is
 23.1558 +allowed to begin.  If this hook fails, the changesets will not be
 23.1559 +transmitted.
 23.1560 +</para>
 23.1561 +
 23.1562 +<para>One use for this hook is to prevent external changes from being added
 23.1563 +to a repository.  For example, you could use this to <quote>freeze</quote> a
 23.1564 +server-hosted branch temporarily or permanently so that users cannot
 23.1565 +push to it, while still allowing a local administrator to modify the
 23.1566 +repository.
 23.1567 +</para>
 23.1568 +
 23.1569 +<para>Parameters to this hook:
 23.1570 +</para>
 23.1571 +<itemizedlist>
 23.1572 +<listitem><para><literal>source</literal>: A string.  The source of these changes.  See
 23.1573 +  section <xref linkend="sec:hook:sources"/> for details.
 23.1574 +</para>
 23.1575 +</listitem>
 23.1576 +<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
 23.1577 +  known.  See section <xref linkend="sec:hook:url"/> for more information.
 23.1578 +</para>
 23.1579 +</listitem></itemizedlist>
 23.1580 +
 23.1581 +<para>See also: <literal role="hook">changegroup</literal> (section <xref linkend="sec:hook:changegroup"/>),
 23.1582 +<literal role="hook">incoming</literal> (section <xref linkend="sec:hook:incoming"/>), ,
 23.1583 +<literal role="hook">pretxnchangegroup</literal> (section <xref linkend="sec:hook:pretxnchangegroup"/>)
 23.1584 +</para>
 23.1585 +
 23.1586 +</sect2>
 23.1587 +<sect2>
 23.1588 +<title><literal role="hook">precommit</literal>&emdash;before starting to commit a changeset</title>
 23.1589 +<para>\label{sec:hook:precommit}
 23.1590 +</para>
 23.1591 +
 23.1592 +<para>This hook is run before Mercurial begins to commit a new changeset.
 23.1593 +It is run before Mercurial has any of the metadata for the commit,
 23.1594 +such as the files to be committed, the commit message, or the commit
 23.1595 +date.
 23.1596 +</para>
 23.1597 +
 23.1598 +<para>One use for this hook is to disable the ability to commit new
 23.1599 +changesets, while still allowing incoming changesets.  Another is to
 23.1600 +run a build or test, and only allow the commit to begin if the build
 23.1601 +or test succeeds.
 23.1602 +</para>
 23.1603 +
 23.1604 +<para>Parameters to this hook:
 23.1605 +</para>
 23.1606 +<itemizedlist>
 23.1607 +<listitem><para><literal>parent1</literal>: A changeset ID.  The changeset ID of the first
 23.1608 +  parent of the working directory.
 23.1609 +</para>
 23.1610 +</listitem>
 23.1611 +<listitem><para><literal>parent2</literal>: A changeset ID.  The changeset ID of the second
 23.1612 +  parent of the working directory.
 23.1613 +</para>
 23.1614 +</listitem></itemizedlist>
 23.1615 +<para>If the commit proceeds, the parents of the working directory will
 23.1616 +become the parents of the new changeset.
 23.1617 +</para>
 23.1618 +
 23.1619 +<para>See also: <literal role="hook">commit</literal> (section <xref linkend="sec:hook:commit"/>),
 23.1620 +<literal role="hook">pretxncommit</literal> (section <xref linkend="sec:hook:pretxncommit"/>)
 23.1621 +</para>
 23.1622 +
 23.1623 +</sect2>
 23.1624 +<sect2>
 23.1625 +<title><literal role="hook">preoutgoing</literal>&emdash;before starting to propagate changesets</title>
 23.1626 +<para>\label{sec:hook:preoutgoing}
 23.1627 +</para>
 23.1628 +
 23.1629 +<para>This hook is invoked before Mercurial knows the identities of the
 23.1630 +changesets to be transmitted.
 23.1631 +</para>
 23.1632 +
 23.1633 +<para>One use for this hook is to prevent changes from being transmitted to
 23.1634 +another repository.
 23.1635 +</para>
 23.1636 +
 23.1637 +<para>Parameters to this hook:
 23.1638 +</para>
 23.1639 +<itemizedlist>
 23.1640 +<listitem><para><literal>source</literal>: A string.  The source of the operation that is
 23.1641 +  attempting to obtain changes from this repository (see
 23.1642 +  section <xref linkend="sec:hook:sources"/>).  See the documentation for the
 23.1643 +  <literal>source</literal> parameter to the <literal role="hook">outgoing</literal> hook, in
 23.1644 +  section <xref linkend="sec:hook:outgoing"/>, for possible values of this
 23.1645 +  parameter.
 23.1646 +</para>
 23.1647 +</listitem>
 23.1648 +<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
 23.1649 +  known.  See section <xref linkend="sec:hook:url"/> for more information.
 23.1650 +</para>
 23.1651 +</listitem></itemizedlist>
 23.1652 +
 23.1653 +<para>See also: <literal role="hook">outgoing</literal> (section <xref linkend="sec:hook:outgoing"/>)
 23.1654 +</para>
 23.1655 +
 23.1656 +</sect2>
 23.1657 +<sect2>
 23.1658 +<title><literal role="hook">pretag</literal>&emdash;before tagging a changeset</title>
 23.1659 +<para>\label{sec:hook:pretag}
 23.1660 +</para>
 23.1661 +
 23.1662 +<para>This controlling hook is run before a tag is created.  If the hook
 23.1663 +succeeds, creation of the tag proceeds.  If the hook fails, the tag is
 23.1664 +not created.
 23.1665 +</para>
 23.1666 +
 23.1667 +<para>Parameters to this hook:
 23.1668 +</para>
 23.1669 +<itemizedlist>
 23.1670 +<listitem><para><literal>local</literal>: A boolean.  Whether the tag is local to this
 23.1671 +  repository instance (i.e. stored in <filename role="special">.hg/localtags</filename>) or
 23.1672 +  managed by Mercurial (stored in <filename role="special">.hgtags</filename>).
 23.1673 +</para>
 23.1674 +</listitem>
 23.1675 +<listitem><para><literal>node</literal>: A changeset ID.  The ID of the changeset to be tagged.
 23.1676 +</para>
 23.1677 +</listitem>
 23.1678 +<listitem><para><literal>tag</literal>: A string.  The name of the tag to be created.
 23.1679 +</para>
 23.1680 +</listitem></itemizedlist>
 23.1681 +
 23.1682 +<para>If the tag to be created is revision-controlled, the <literal role="hook">precommit</literal>
 23.1683 +and <literal role="hook">pretxncommit</literal> hooks (sections <xref linkend="sec:hook:commit"/>
 23.1684 +and <xref linkend="sec:hook:pretxncommit"/>) will also be run.
 23.1685 +</para>
 23.1686 +
 23.1687 +<para>See also: <literal role="hook">tag</literal> (section <xref linkend="sec:hook:tag"/>)
 23.1688 +</para>
 23.1689 +
 23.1690 +<para>\subsection{<literal role="hook">pretxnchangegroup</literal>&emdash;before completing addition of
 23.1691 +  remote changesets}
 23.1692 +\label{sec:hook:pretxnchangegroup}
 23.1693 +</para>
 23.1694 +
 23.1695 +<para>This controlling hook is run before a transaction&emdash;that manages the
 23.1696 +addition of a group of new changesets from outside the
 23.1697 +repository&emdash;completes.  If the hook succeeds, the transaction
 23.1698 +completes, and all of the changesets become permanent within this
 23.1699 +repository.  If the hook fails, the transaction is rolled back, and
 23.1700 +the data for the changesets is erased.
 23.1701 +</para>
 23.1702 +
 23.1703 +<para>This hook can access the metadata associated with the almost-added
 23.1704 +changesets, but it should not do anything permanent with this data.
 23.1705 +It must also not modify the working directory.
 23.1706 +</para>
 23.1707 +
 23.1708 +<para>While this hook is running, if other Mercurial processes access this
 23.1709 +repository, they will be able to see the almost-added changesets as if
 23.1710 +they are permanent.  This may lead to race conditions if you do not
 23.1711 +take steps to avoid them.
 23.1712 +</para>
 23.1713 +
 23.1714 +<para>This hook can be used to automatically vet a group of changesets.  If
 23.1715 +the hook fails, all of the changesets are <quote>rejected</quote> when the
 23.1716 +transaction rolls back.
 23.1717 +</para>
 23.1718 +
 23.1719 +<para>Parameters to this hook:
 23.1720 +</para>
 23.1721 +<itemizedlist>
 23.1722 +<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the first
 23.1723 +  changeset in the group that was added.  All changesets between this
 23.1724 +  and \index{tags!<literal>tip</literal>}<literal>tip</literal>, inclusive, were added by
 23.1725 +  a single <command role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg push</command> or <command role="hg-cmd">hg unbundle</command>.
 23.1726 +</para>
 23.1727 +</listitem>
 23.1728 +<listitem><para><literal>source</literal>: A string.  The source of these changes.  See
 23.1729 +  section <xref linkend="sec:hook:sources"/> for details.
 23.1730 +</para>
 23.1731 +</listitem>
 23.1732 +<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
 23.1733 +  known.  See section <xref linkend="sec:hook:url"/> for more information.
 23.1734 +</para>
 23.1735 +</listitem></itemizedlist>
 23.1736 +
 23.1737 +<para>See also: <literal role="hook">changegroup</literal> (section <xref linkend="sec:hook:changegroup"/>),
 23.1738 +<literal role="hook">incoming</literal> (section <xref linkend="sec:hook:incoming"/>),
 23.1739 +<literal role="hook">prechangegroup</literal> (section <xref linkend="sec:hook:prechangegroup"/>)
 23.1740 +</para>
 23.1741 +
 23.1742 +</sect2>
 23.1743 +<sect2>
 23.1744 +<title><literal role="hook">pretxncommit</literal>&emdash;before completing commit of new changeset</title>
 23.1745 +<para>\label{sec:hook:pretxncommit}
 23.1746 +</para>
 23.1747 +
 23.1748 +<para>This controlling hook is run before a transaction&emdash;that manages a new
 23.1749 +commit&emdash;completes.  If the hook succeeds, the transaction completes
 23.1750 +and the changeset becomes permanent within this repository.  If the
 23.1751 +hook fails, the transaction is rolled back, and the commit data is
 23.1752 +erased.
 23.1753 +</para>
 23.1754 +
 23.1755 +<para>This hook can access the metadata associated with the almost-new
 23.1756 +changeset, but it should not do anything permanent with this data.  It
 23.1757 +must also not modify the working directory.
 23.1758 +</para>
 23.1759 +
 23.1760 +<para>While this hook is running, if other Mercurial processes access this
 23.1761 +repository, they will be able to see the almost-new changeset as if it
 23.1762 +is permanent.  This may lead to race conditions if you do not take
 23.1763 +steps to avoid them.
 23.1764 +</para>
 23.1765 +
 23.1766 +<para>Parameters to this hook:
 23.1767 +</para>
 23.1768 +<itemizedlist>
 23.1769 +<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the newly
 23.1770 +  committed changeset.
 23.1771 +</para>
 23.1772 +</listitem>
 23.1773 +<listitem><para><literal>parent1</literal>: A changeset ID.  The changeset ID of the first
 23.1774 +  parent of the newly committed changeset.
 23.1775 +</para>
 23.1776 +</listitem>
 23.1777 +<listitem><para><literal>parent2</literal>: A changeset ID.  The changeset ID of the second
 23.1778 +  parent of the newly committed changeset.
 23.1779 +</para>
 23.1780 +</listitem></itemizedlist>
 23.1781 +
 23.1782 +<para>See also: <literal role="hook">precommit</literal> (section <xref linkend="sec:hook:precommit"/>)
 23.1783 +</para>
 23.1784 +
 23.1785 +</sect2>
 23.1786 +<sect2>
 23.1787 +<title><literal role="hook">preupdate</literal>&emdash;before updating or merging working directory</title>
 23.1788 +<para>\label{sec:hook:preupdate}
 23.1789 +</para>
 23.1790 +
 23.1791 +<para>This controlling hook is run before an update or merge of the working
 23.1792 +directory begins.  It is run only if Mercurial's normal pre-update
 23.1793 +checks determine that the update or merge can proceed.  If the hook
 23.1794 +succeeds, the update or merge may proceed; if it fails, the update or
 23.1795 +merge does not start.
 23.1796 +</para>
 23.1797 +
 23.1798 +<para>Parameters to this hook:
 23.1799 +</para>
 23.1800 +<itemizedlist>
 23.1801 +<listitem><para><literal>parent1</literal>: A changeset ID.  The ID of the parent that the
 23.1802 +  working directory is to be updated to.  If the working directory is
 23.1803 +  being merged, it will not change this parent.
 23.1804 +</para>
 23.1805 +</listitem>
 23.1806 +<listitem><para><literal>parent2</literal>: A changeset ID.  Only set if the working
 23.1807 +  directory is being merged.  The ID of the revision that the working
 23.1808 +  directory is being merged with.
 23.1809 +</para>
 23.1810 +</listitem></itemizedlist>
 23.1811 +
 23.1812 +<para>See also: <literal role="hook">update</literal> (section <xref linkend="sec:hook:update"/>)
 23.1813 +</para>
 23.1814 +
 23.1815 +</sect2>
 23.1816 +<sect2>
 23.1817 +<title><literal role="hook">tag</literal>&emdash;after tagging a changeset</title>
 23.1818 +<para>\label{sec:hook:tag}
 23.1819 +</para>
 23.1820 +
 23.1821 +<para>This hook is run after a tag has been created.
 23.1822 +</para>
 23.1823 +
 23.1824 +<para>Parameters to this hook:
 23.1825 +</para>
 23.1826 +<itemizedlist>
 23.1827 +<listitem><para><literal>local</literal>: A boolean.  Whether the new tag is local to this
 23.1828 +  repository instance (i.e. stored in <filename role="special">.hg/localtags</filename>) or
 23.1829 +  managed by Mercurial (stored in <filename role="special">.hgtags</filename>).
 23.1830 +</para>
 23.1831 +</listitem>
 23.1832 +<listitem><para><literal>node</literal>: A changeset ID.  The ID of the changeset that was
 23.1833 +  tagged.
 23.1834 +</para>
 23.1835 +</listitem>
 23.1836 +<listitem><para><literal>tag</literal>: A string.  The name of the tag that was created.
 23.1837 +</para>
 23.1838 +</listitem></itemizedlist>
 23.1839 +
 23.1840 +<para>If the created tag is revision-controlled, the <literal role="hook">commit</literal> hook
 23.1841 +(section <xref linkend="sec:hook:commit"/>) is run before this hook.
 23.1842 +</para>
 23.1843 +
 23.1844 +<para>See also: <literal role="hook">pretag</literal> (section <xref linkend="sec:hook:pretag"/>)
 23.1845 +</para>
 23.1846 +
 23.1847 +</sect2>
 23.1848 +<sect2>
 23.1849 +<title><literal role="hook">update</literal>&emdash;after updating or merging working directory</title>
 23.1850 +<para>\label{sec:hook:update}
 23.1851 +</para>
 23.1852 +
 23.1853 +<para>This hook is run after an update or merge of the working directory
 23.1854 +completes.  Since a merge can fail (if the external <command>hgmerge</command>
 23.1855 +command fails to resolve conflicts in a file), this hook communicates
 23.1856 +whether the update or merge completed cleanly.
 23.1857 +</para>
 23.1858 +
 23.1859 +<itemizedlist>
 23.1860 +<listitem><para><literal>error</literal>: A boolean.  Indicates whether the update or
 23.1861 +  merge completed successfully.
 23.1862 +</para>
 23.1863 +</listitem>
 23.1864 +<listitem><para><literal>parent1</literal>: A changeset ID.  The ID of the parent that the
 23.1865 +  working directory was updated to.  If the working directory was
 23.1866 +  merged, it will not have changed this parent.
 23.1867 +</para>
 23.1868 +</listitem>
 23.1869 +<listitem><para><literal>parent2</literal>: A changeset ID.  Only set if the working
 23.1870 +  directory was merged.  The ID of the revision that the working
 23.1871 +  directory was merged with.
 23.1872 +</para>
 23.1873 +</listitem></itemizedlist>
 23.1874 +
 23.1875 +<para>See also: <literal role="hook">preupdate</literal> (section <xref linkend="sec:hook:preupdate"/>)
 23.1876 +</para>
 23.1877 +
 23.1878 +</sect2>
 23.1879 +</sect1>
 23.1880 +</chapter>
 23.1881 +
 23.1882 +<!--
 23.1883 +local variables: 
 23.1884 +sgml-parent-document: ("00book.xml" "book" "chapter")
 23.1885 +end:
 23.1886 +-->
 23.1887 \ No newline at end of file
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/fr/ch11-template.xml	Sun Aug 16 04:58:01 2009 +0200
    24.3 @@ -0,0 +1,689 @@
    24.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    24.5 +
    24.6 +<chapter>
    24.7 +<title>Customising the output of Mercurial</title>
    24.8 +<para>\label{chap:template}</para>
    24.9 +
   24.10 +<para>Mercurial provides a powerful mechanism to let you control how it
   24.11 +displays information.  The mechanism is based on templates.  You can
   24.12 +use templates to generate specific output for a single command, or to
   24.13 +customise the entire appearance of the built-in web interface.</para>
   24.14 +
   24.15 +<sect1>
   24.16 +<title>Using precanned output styles</title>
   24.17 +<para>\label{sec:style}</para>
   24.18 +
   24.19 +<para>Packaged with Mercurial are some output styles that you can use
   24.20 +immediately.  A style is simply a precanned template that someone
   24.21 +wrote and installed somewhere that Mercurial can find.</para>
   24.22 +
   24.23 +<para>Before we take a look at Mercurial's bundled styles, let's review its
   24.24 +normal output.</para>
   24.25 +
   24.26 +<para><!-- &interaction.template.simple.normal; --></para>
   24.27 +
   24.28 +<para>This is somewhat informative, but it takes up a lot of space&emdash;five
   24.29 +lines of output per changeset.  The <literal>compact</literal> style reduces
   24.30 +this to three lines, presented in a sparse manner.</para>
   24.31 +
   24.32 +<para><!-- &interaction.template.simple.compact; --></para>
   24.33 +
   24.34 +<para>The <literal>changelog</literal> style hints at the expressive power of
   24.35 +Mercurial's templating engine.  This style attempts to follow the GNU
   24.36 +Project's changelog guidelines<citation>web:changelog</citation>.
   24.37 +</para>
   24.38 +
   24.39 +<para><!-- &interaction.template.simple.changelog; -->
   24.40 +</para>
   24.41 +
   24.42 +<para>You will not be shocked to learn that Mercurial's default output style
   24.43 +is named <literal>default</literal>.
   24.44 +</para>
   24.45 +
   24.46 +<sect2>
   24.47 +<title>Setting a default style</title>
   24.48 +
   24.49 +<para>You can modify the output style that Mercurial will use for every
   24.50 +command by editing your <filename role="special"> /.hgrc</filename>\ file, naming the style you would
   24.51 +prefer to use.
   24.52 +</para>
   24.53 +
   24.54 +<programlisting>
   24.55 +<para>  [ui]
   24.56 +  style = compact
   24.57 +</para>
   24.58 +</programlisting>
   24.59 +
   24.60 +<para>If you write a style of your own, you can use it by either providing
   24.61 +the path to your style file, or copying your style file into a
   24.62 +location where Mercurial can find it (typically the <literal>templates</literal>
   24.63 +subdirectory of your Mercurial install directory).
   24.64 +</para>
   24.65 +
   24.66 +</sect2>
   24.67 +</sect1>
   24.68 +<sect1>
   24.69 +<title>Commands that support styles and templates</title>
   24.70 +
   24.71 +<para>All of Mercurial's <quote><literal>log</literal>-like</quote> commands let you use styles
   24.72 +and templates: <command role="hg-cmd">hg incoming</command>, <command role="hg-cmd">hg log</command>, <command role="hg-cmd">hg outgoing</command>, and
   24.73 +<command role="hg-cmd">hg tip</command>.
   24.74 +</para>
   24.75 +
   24.76 +<para>As I write this manual, these are so far the only commands that
   24.77 +support styles and templates.  Since these are the most important
   24.78 +commands that need customisable output, there has been little pressure
   24.79 +from the Mercurial user community to add style and template support to
   24.80 +other commands.
   24.81 +</para>
   24.82 +
   24.83 +</sect1>
   24.84 +<sect1>
   24.85 +<title>The basics of templating</title>
   24.86 +
   24.87 +<para>At its simplest, a Mercurial template is a piece of text.  Some of the
   24.88 +text never changes, while other parts are <emphasis>expanded</emphasis>, or replaced
   24.89 +with new text, when necessary.
   24.90 +</para>
   24.91 +
   24.92 +<para>Before we continue, let's look again at a simple example of
   24.93 +Mercurial's normal output.
   24.94 +</para>
   24.95 +
   24.96 +<para><!-- &interaction.template.simple.normal; -->
   24.97 +</para>
   24.98 +
   24.99 +<para>Now, let's run the same command, but using a template to change its
  24.100 +output.
  24.101 +</para>
  24.102 +
  24.103 +<para><!-- &interaction.template.simple.simplest; -->
  24.104 +</para>
  24.105 +
  24.106 +<para>The example above illustrates the simplest possible template; it's
  24.107 +just a piece of static text, printed once for each changeset.  The
  24.108 +<option role="hg-opt-log">--template</option> option to the <command role="hg-cmd">hg log</command> command tells
  24.109 +Mercurial to use the given text as the template when printing each
  24.110 +changeset.
  24.111 +</para>
  24.112 +
  24.113 +<para>Notice that the template string above ends with the text
  24.114 +<quote><literal>\n</literal></quote>.  This is an <emphasis>escape sequence</emphasis>, telling Mercurial
  24.115 +to print a newline at the end of each template item.  If you omit this
  24.116 +newline, Mercurial will run each piece of output together.  See
  24.117 +section <xref linkend="sec:template:escape"/> for more details of escape sequences.
  24.118 +</para>
  24.119 +
  24.120 +<para>A template that prints a fixed string of text all the time isn't very
  24.121 +useful; let's try something a bit more complex.
  24.122 +</para>
  24.123 +
  24.124 +<para><!-- &interaction.template.simple.simplesub; -->
  24.125 +</para>
  24.126 +
  24.127 +<para>As you can see, the string <quote><literal>{desc}</literal></quote> in the template has been
  24.128 +replaced in the output with the description of each changeset.  Every
  24.129 +time Mercurial finds text enclosed in curly braces (<quote><literal>{</literal></quote>
  24.130 +and <quote>\texttt{}}</quote>), it will try to replace the braces and text with
  24.131 +the expansion of whatever is inside.  To print a literal curly brace,
  24.132 +you must escape it, as described in section <xref linkend="sec:template:escape"/>.
  24.133 +</para>
  24.134 +
  24.135 +</sect1>
  24.136 +<sect1>
  24.137 +<title>Common template keywords</title>
  24.138 +<para>\label{sec:template:keyword}
  24.139 +</para>
  24.140 +
  24.141 +<para>You can start writing simple templates immediately using the keywords
  24.142 +below.
  24.143 +</para>
  24.144 +
  24.145 +<itemizedlist>
  24.146 +<listitem><para><literal role="template-keyword">author</literal>: String.  The unmodified author of the changeset.
  24.147 +</para>
  24.148 +</listitem>
  24.149 +<listitem><para><literal role="template-keyword">branches</literal>: String.  The name of the branch on which
  24.150 +  the changeset was committed.  Will be empty if the branch name was
  24.151 +  <literal>default</literal>.
  24.152 +</para>
  24.153 +</listitem>
  24.154 +<listitem><para><literal role="template-keyword">date</literal>: Date information.  The date when the changeset
  24.155 +  was committed.  This is <emphasis>not</emphasis> human-readable; you must pass it
  24.156 +  through a filter that will render it appropriately.  See
  24.157 +  section <xref linkend="sec:template:filter"/> for more information on filters.
  24.158 +  The date is expressed as a pair of numbers.  The first number is a
  24.159 +  Unix UTC timestamp (seconds since January 1, 1970); the second is
  24.160 +  the offset of the committer's timezone from UTC, in seconds.
  24.161 +</para>
  24.162 +</listitem>
  24.163 +<listitem><para><literal role="template-keyword">desc</literal>: String.  The text of the changeset description.
  24.164 +</para>
  24.165 +</listitem>
  24.166 +<listitem><para><literal role="template-keyword">files</literal>: List of strings.  All files modified, added, or
  24.167 +  removed by this changeset.
  24.168 +</para>
  24.169 +</listitem>
  24.170 +<listitem><para><literal role="template-keyword">file_adds</literal>: List of strings.  Files added by this
  24.171 +  changeset.
  24.172 +</para>
  24.173 +</listitem>
  24.174 +<listitem><para><literal role="template-keyword">file_dels</literal>: List of strings.  Files removed by this
  24.175 +  changeset.
  24.176 +</para>
  24.177 +</listitem>
  24.178 +<listitem><para><literal role="template-keyword">node</literal>: String.  The changeset identification hash, as a
  24.179 +  40-character hexadecimal string.
  24.180 +</para>
  24.181 +</listitem>
  24.182 +<listitem><para><literal role="template-keyword">parents</literal>: List of strings.  The parents of the
  24.183 +  changeset.
  24.184 +</para>
  24.185 +</listitem>
  24.186 +<listitem><para><literal role="template-keyword">rev</literal>: Integer.  The repository-local changeset revision
  24.187 +  number.
  24.188 +</para>
  24.189 +</listitem>
  24.190 +<listitem><para><literal role="template-keyword">tags</literal>: List of strings.  Any tags associated with the
  24.191 +  changeset.
  24.192 +</para>
  24.193 +</listitem></itemizedlist>
  24.194 +
  24.195 +<para>A few simple experiments will show us what to expect when we use these
  24.196 +keywords; you can see the results in
  24.197 +figure <xref linkend="fig:template:keywords"/>.
  24.198 +</para>
  24.199 +
  24.200 +<informalfigure>
  24.201 +<para>  <!-- &interaction.template.simple.keywords; -->
  24.202 +  <caption><para>Template keywords in use</para></caption>
  24.203 +  \label{fig:template:keywords}
  24.204 +</para>
  24.205 +</informalfigure>
  24.206 +
  24.207 +<para>As we noted above, the date keyword does not produce human-readable
  24.208 +output, so we must treat it specially.  This involves using a
  24.209 +<emphasis>filter</emphasis>, about which more in section <xref linkend="sec:template:filter"/>.
  24.210 +</para>
  24.211 +
  24.212 +<para><!-- &interaction.template.simple.datekeyword; -->
  24.213 +</para>
  24.214 +
  24.215 +</sect1>
  24.216 +<sect1>
  24.217 +<title>Escape sequences</title>
  24.218 +<para>\label{sec:template:escape}
  24.219 +</para>
  24.220 +
  24.221 +<para>Mercurial's templating engine recognises the most commonly used escape
  24.222 +sequences in strings.  When it sees a backslash (<quote><literal>\</literal></quote>)
  24.223 +character, it looks at the following character and substitutes the two
  24.224 +characters with a single replacement, as described below.
  24.225 +</para>
  24.226 +
  24.227 +<itemizedlist>
  24.228 +<listitem><para><literal>\textbackslash\textbackslash</literal>: Backslash, <quote><literal>\</literal></quote>,
  24.229 +  ASCII 134.
  24.230 +</para>
  24.231 +</listitem>
  24.232 +<listitem><para><literal>\textbackslash n</literal>: Newline, ASCII 12.
  24.233 +</para>
  24.234 +</listitem>
  24.235 +<listitem><para><literal>\textbackslash r</literal>: Carriage return, ASCII 15.
  24.236 +</para>
  24.237 +</listitem>
  24.238 +<listitem><para><literal>\textbackslash t</literal>: Tab, ASCII 11.
  24.239 +</para>
  24.240 +</listitem>
  24.241 +<listitem><para><literal>\textbackslash v</literal>: Vertical tab, ASCII 13.
  24.242 +</para>
  24.243 +</listitem>
  24.244 +<listitem><para><literal>\textbackslash {</literal>: Open curly brace, <quote><literal>{</literal></quote>, ASCII 173.
  24.245 +</para>
  24.246 +</listitem>
  24.247 +<listitem><para><literal>\textbackslash }</literal>: Close curly brace, <quote><literal>}</literal></quote>, ASCII 175.
  24.248 +</para>
  24.249 +</listitem></itemizedlist>
  24.250 +
  24.251 +<para>As indicated above, if you want the expansion of a template to contain
  24.252 +a literal <quote><literal>\</literal></quote>, <quote><literal>{</literal></quote>, or <quote><literal>{</literal></quote> character, you
  24.253 +must escape it.
  24.254 +</para>
  24.255 +
  24.256 +</sect1>
  24.257 +<sect1>
  24.258 +<title>Filtering keywords to change their results</title>
  24.259 +<para>\label{sec:template:filter}
  24.260 +</para>
  24.261 +
  24.262 +<para>Some of the results of template expansion are not immediately easy to
  24.263 +use.  Mercurial lets you specify an optional chain of <emphasis>filters</emphasis>
  24.264 +to modify the result of expanding a keyword.  You have already seen a
  24.265 +common filter, <literal role="template-kw-filt-date">isodate</literal>, in action above, to make a
  24.266 +date readable.
  24.267 +</para>
  24.268 +
  24.269 +<para>Below is a list of the most commonly used filters that Mercurial
  24.270 +supports.  While some filters can be applied to any text, others can
  24.271 +only be used in specific circumstances.  The name of each filter is
  24.272 +followed first by an indication of where it can be used, then a
  24.273 +description of its effect.
  24.274 +</para>
  24.275 +
  24.276 +<itemizedlist>
  24.277 +<listitem><para><literal role="template-filter">addbreaks</literal>: Any text. Add an XHTML <quote><literal>&lt;br/&gt;</literal></quote>
  24.278 +  tag before the end of every line except the last.  For example,
  24.279 +  <quote><literal>foo\nbar</literal></quote> becomes <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.
  24.280 +</para>
  24.281 +</listitem>
  24.282 +<listitem><para><literal role="template-kw-filt-date">age</literal>: <literal role="template-keyword">date</literal> keyword.  Render the
  24.283 +  age of the date, relative to the current time.  Yields a string like
  24.284 +  <quote><literal>10 minutes</literal></quote>.
  24.285 +</para>
  24.286 +</listitem>
  24.287 +<listitem><para><literal role="template-filter">basename</literal>: Any text, but most useful for the
  24.288 +  <literal role="template-keyword">files</literal> keyword and its relatives.  Treat the text as a
  24.289 +  path, and return the basename. For example, <quote><literal>foo/bar/baz</literal></quote>
  24.290 +  becomes <quote><literal>baz</literal></quote>.
  24.291 +</para>
  24.292 +</listitem>
  24.293 +<listitem><para><literal role="template-kw-filt-date">date</literal>: <literal role="template-keyword">date</literal> keyword.  Render a date
  24.294 +  in a similar format to the Unix <literal role="template-keyword">date</literal> command, but with
  24.295 +  timezone included.  Yields a string like
  24.296 +  <quote><literal>Mon Sep 04 15:13:13 2006 -0700</literal></quote>.
  24.297 +</para>
  24.298 +</listitem>
  24.299 +<listitem><para><literal role="template-kw-filt-author">domain</literal>: Any text, but most useful for the
  24.300 +  <literal role="template-keyword">author</literal> keyword.  Finds the first string that looks like
  24.301 +  an email address, and extract just the domain component.  For
  24.302 +  example, <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes
  24.303 +  <quote><literal>serpentine.com</literal></quote>.
  24.304 +</para>
  24.305 +</listitem>
  24.306 +<listitem><para><literal role="template-kw-filt-author">email</literal>: Any text, but most useful for the
  24.307 +  <literal role="template-keyword">author</literal> keyword.  Extract the first string that looks like
  24.308 +  an email address.  For example,
  24.309 +  <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes
  24.310 +  <quote><literal>bos@serpentine.com</literal></quote>.
  24.311 +</para>
  24.312 +</listitem>
  24.313 +<listitem><para><literal role="template-filter">escape</literal>: Any text.  Replace the special XML/XHTML
  24.314 +  characters <quote><literal>&amp;</literal></quote>, <quote><literal>&lt;</literal></quote> and <quote><literal>&gt;</literal></quote> with
  24.315 +  XML entities.
  24.316 +</para>
  24.317 +</listitem>
  24.318 +<listitem><para><literal role="template-filter">fill68</literal>: Any text.  Wrap the text to fit in 68
  24.319 +  columns.  This is useful before you pass text through the
  24.320 +  <literal role="template-filter">tabindent</literal> filter, and still want it to fit in an
  24.321 +  80-column fixed-font window.
  24.322 +</para>
  24.323 +</listitem>
  24.324 +<listitem><para><literal role="template-filter">fill76</literal>: Any text.  Wrap the text to fit in 76
  24.325 +  columns.
  24.326 +</para>
  24.327 +</listitem>
  24.328 +<listitem><para><literal role="template-filter">firstline</literal>: Any text.  Yield the first line of text,
  24.329 +  without any trailing newlines.
  24.330 +</para>
  24.331 +</listitem>
  24.332 +<listitem><para><literal role="template-kw-filt-date">hgdate</literal>: <literal role="template-keyword">date</literal> keyword.  Render the
  24.333 +  date as a pair of readable numbers.  Yields a string like
  24.334 +  <quote><literal>1157407993 25200</literal></quote>.
  24.335 +</para>
  24.336 +</listitem>
  24.337 +<listitem><para><literal role="template-kw-filt-date">isodate</literal>: <literal role="template-keyword">date</literal> keyword.  Render the
  24.338 +  date as a text string in ISO 8601 format.  Yields a string like
  24.339 +  <quote><literal>2006-09-04 15:13:13 -0700</literal></quote>.
  24.340 +</para>
  24.341 +</listitem>
  24.342 +<listitem><para><literal role="template-filter">obfuscate</literal>: Any text, but most useful for the
  24.343 +  <literal role="template-keyword">author</literal> keyword.  Yield the input text rendered as a
  24.344 +  sequence of XML entities.  This helps to defeat some particularly
  24.345 +  stupid screen-scraping email harvesting spambots.
  24.346 +</para>
  24.347 +</listitem>
  24.348 +<listitem><para><literal role="template-kw-filt-author">person</literal>: Any text, but most useful for the
  24.349 +  <literal role="template-keyword">author</literal> keyword.  Yield the text before an email address.
  24.350 +  For example, <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote>
  24.351 +  becomes <quote><literal>Bryan O'Sullivan</literal></quote>.
  24.352 +</para>
  24.353 +</listitem>
  24.354 +<listitem><para><literal role="template-kw-filt-date">rfc822date</literal>: <literal role="template-keyword">date</literal> keyword.  Render a
  24.355 +  date using the same format used in email headers.  Yields a string
  24.356 +  like <quote><literal>Mon, 04 Sep 2006 15:13:13 -0700</literal></quote>.
  24.357 +</para>
  24.358 +</listitem>
  24.359 +<listitem><para><literal role="template-kw-filt-node">short</literal>: Changeset hash.  Yield the short form
  24.360 +  of a changeset hash, i.e. a 12-character hexadecimal string.
  24.361 +</para>
  24.362 +</listitem>
  24.363 +<listitem><para><literal role="template-kw-filt-date">shortdate</literal>: <literal role="template-keyword">date</literal> keyword.  Render
  24.364 +  the year, month, and day of the date.  Yields a string like
  24.365 +  <quote><literal>2006-09-04</literal></quote>.
  24.366 +</para>
  24.367 +</listitem>
  24.368 +<listitem><para><literal role="template-filter">strip</literal>: Any text.  Strip all leading and trailing
  24.369 +  whitespace from the string.
  24.370 +</para>
  24.371 +</listitem>
  24.372 +<listitem><para><literal role="template-filter">tabindent</literal>: Any text.  Yield the text, with every line
  24.373 +  except the first starting with a tab character.
  24.374 +</para>
  24.375 +</listitem>
  24.376 +<listitem><para><literal role="template-filter">urlescape</literal>: Any text.  Escape all characters that are
  24.377 +  considered <quote>special</quote> by URL parsers.  For example, <literal>foo bar</literal>
  24.378 +  becomes <literal>foo%20bar</literal>.
  24.379 +</para>
  24.380 +</listitem>
  24.381 +<listitem><para><literal role="template-kw-filt-author">user</literal>: Any text, but most useful for the
  24.382 +  <literal role="template-keyword">author</literal> keyword.  Return the <quote>user</quote> portion of an email
  24.383 +  address.  For example,
  24.384 +  <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes
  24.385 +  <quote><literal>bos</literal></quote>.
  24.386 +</para>
  24.387 +</listitem></itemizedlist>
  24.388 +
  24.389 +<informalfigure>
  24.390 +<para>  <!-- &interaction.template.simple.manyfilters; -->
  24.391 +  <caption><para>Template filters in action</para></caption>
  24.392 +  \label{fig:template:filters}
  24.393 +</para>
  24.394 +</informalfigure>
  24.395 +
  24.396 +<note>
  24.397 +<para>  If you try to apply a filter to a piece of data that it cannot
  24.398 +  process, Mercurial will fail and print a Python exception.  For
  24.399 +  example, trying to run the output of the <literal role="template-keyword">desc</literal> keyword
  24.400 +  into the <literal role="template-kw-filt-date">isodate</literal> filter is not a good idea.
  24.401 +</para>
  24.402 +</note>
  24.403 +
  24.404 +<sect2>
  24.405 +<title>Combining filters</title>
  24.406 +
  24.407 +<para>It is easy to combine filters to yield output in the form you would
  24.408 +like.  The following chain of filters tidies up a description, then
  24.409 +makes sure that it fits cleanly into 68 columns, then indents it by a
  24.410 +further 8 characters (at least on Unix-like systems, where a tab is
  24.411 +conventionally 8 characters wide).
  24.412 +</para>
  24.413 +
  24.414 +<para><!-- &interaction.template.simple.combine; -->
  24.415 +</para>
  24.416 +
  24.417 +<para>Note the use of <quote><literal>\t</literal></quote> (a tab character) in the template to
  24.418 +force the first line to be indented; this is necessary since
  24.419 +<literal role="template-keyword">tabindent</literal> indents all lines <emphasis>except</emphasis> the first.
  24.420 +</para>
  24.421 +
  24.422 +<para>Keep in mind that the order of filters in a chain is significant.  The
  24.423 +first filter is applied to the result of the keyword; the second to
  24.424 +the result of the first filter; and so on.  For example, using
  24.425 +<literal>fill68|tabindent</literal> gives very different results from
  24.426 +<literal>tabindent|fill68</literal>.
  24.427 +</para>
  24.428 +
  24.429 +
  24.430 +</sect2>
  24.431 +</sect1>
  24.432 +<sect1>
  24.433 +<title>From templates to styles</title>
  24.434 +
  24.435 +<para>A command line template provides a quick and simple way to format some
  24.436 +output.  Templates can become verbose, though, and it's useful to be
  24.437 +able to give a template a name.  A style file is a template with a
  24.438 +name, stored in a file.
  24.439 +</para>
  24.440 +
  24.441 +<para>More than that, using a style file unlocks the power of Mercurial's
  24.442 +templating engine in ways that are not possible using the command line
  24.443 +<option role="hg-opt-log">--template</option> option.
  24.444 +</para>
  24.445 +
  24.446 +<sect2>
  24.447 +<title>The simplest of style files</title>
  24.448 +
  24.449 +<para>Our simple style file contains just one line:
  24.450 +</para>
  24.451 +
  24.452 +<para><!-- &interaction.template.simple.rev; -->
  24.453 +</para>
  24.454 +
  24.455 +<para>This tells Mercurial, <quote>if you're printing a changeset, use the text
  24.456 +on the right as the template</quote>.
  24.457 +</para>
  24.458 +
  24.459 +</sect2>
  24.460 +<sect2>
  24.461 +<title>Style file syntax</title>
  24.462 +
  24.463 +<para>The syntax rules for a style file are simple.
  24.464 +</para>
  24.465 +
  24.466 +<itemizedlist>
  24.467 +<listitem><para>The file is processed one line at a time.
  24.468 +</para>
  24.469 +</listitem>
  24.470 +</para>
  24.471 +</listitem>
  24.472 +<listitem><para>Leading and trailing white space are ignored.
  24.473 +</para>
  24.474 +</listitem>
  24.475 +</para>
  24.476 +</listitem>
  24.477 +<listitem><para>Empty lines are skipped.
  24.478 +</para>
  24.479 +</listitem>
  24.480 +</para>
  24.481 +</listitem>
  24.482 +<listitem><para>If a line starts with either of the characters <quote><literal>#</literal></quote> or
  24.483 +  <quote><literal>;</literal></quote>, the entire line is treated as a comment, and skipped
  24.484 +  as if empty.
  24.485 +</para>
  24.486 +</listitem>
  24.487 +</para>
  24.488 +</listitem>
  24.489 +<listitem><para>A line starts with a keyword.  This must start with an
  24.490 +  alphabetic character or underscore, and can subsequently contain any
  24.491 +  alphanumeric character or underscore.  (In regexp notation, a
  24.492 +  keyword must match <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)
  24.493 +</para>
  24.494 +</listitem>
  24.495 +</para>
  24.496 +</listitem>
  24.497 +<listitem><para>The next element must be an <quote><literal>=</literal></quote> character, which can
  24.498 +  be preceded or followed by an arbitrary amount of white space.
  24.499 +</para>
  24.500 +</listitem>
  24.501 +</para>
  24.502 +</listitem>
  24.503 +<listitem><para>If the rest of the line starts and ends with matching quote
  24.504 +  characters (either single or double quote), it is treated as a
  24.505 +  template body.
  24.506 +</para>
  24.507 +</listitem>
  24.508 +</para>
  24.509 +</listitem>
  24.510 +<listitem><para>If the rest of the line <emphasis>does not</emphasis> start with a quote
  24.511 +  character, it is treated as the name of a file; the contents of this
  24.512 +  file will be read and used as a template body.
  24.513 +</para>
  24.514 +</listitem></itemizedlist>
  24.515 +
  24.516 +</sect2>
  24.517 +</sect1>
  24.518 +<sect1>
  24.519 +<title>Style files by example</title>
  24.520 +
  24.521 +<para>To illustrate how to write a style file, we will construct a few by
  24.522 +example.  Rather than provide a complete style file and walk through
  24.523 +it, we'll mirror the usual process of developing a style file by
  24.524 +starting with something very simple, and walking through a series of
  24.525 +successively more complete examples.
  24.526 +</para>
  24.527 +
  24.528 +<sect2>
  24.529 +<title>Identifying mistakes in style files</title>
  24.530 +
  24.531 +<para>If Mercurial encounters a problem in a style file you are working on,
  24.532 +it prints a terse error message that, once you figure out what it
  24.533 +means, is actually quite useful.
  24.534 +</para>
  24.535 +
  24.536 +<para><!-- &interaction.template.svnstyle.syntax.input; -->
  24.537 +</para>
  24.538 +
  24.539 +<para>Notice that <filename>broken.style</filename> attempts to define a
  24.540 +<literal>changeset</literal> keyword, but forgets to give any content for it.
  24.541 +When instructed to use this style file, Mercurial promptly complains.
  24.542 +</para>
  24.543 +
  24.544 +<para><!-- &interaction.template.svnstyle.syntax.error; -->
  24.545 +</para>
  24.546 +
  24.547 +<para>This error message looks intimidating, but it is not too hard to
  24.548 +follow.
  24.549 +</para>
  24.550 +
  24.551 +<itemizedlist>
  24.552 +<listitem><para>The first component is simply Mercurial's way of saying <quote>I am
  24.553 +  giving up</quote>.
  24.554 +</para>
  24.555 +</listitem><programlisting>
  24.556 +<listitem><para>    <emphasis role="bold">abort:</emphasis> broken.style:1: parse error
  24.557 +</para>
  24.558 +</listitem></programlisting>
  24.559 +
  24.560 +</para>
  24.561 +</listitem>
  24.562 +<listitem><para>Next comes the name of the style file that contains the error.
  24.563 +</para>
  24.564 +</listitem><programlisting>
  24.565 +<listitem><para>    abort: <emphasis role="bold">broken.style</emphasis>:1: parse error
  24.566 +</para>
  24.567 +</listitem></programlisting>
  24.568 +
  24.569 +</para>
  24.570 +</listitem>
  24.571 +<listitem><para>Following the file name is the line number where the error was
  24.572 +  encountered.
  24.573 +</para>
  24.574 +</listitem><programlisting>
  24.575 +<listitem><para>    abort: broken.style:<emphasis role="bold">1</emphasis>: parse error
  24.576 +</para>
  24.577 +</listitem></programlisting>
  24.578 +
  24.579 +</para>
  24.580 +</listitem>
  24.581 +<listitem><para>Finally, a description of what went wrong.
  24.582 +</para>
  24.583 +</listitem><programlisting>
  24.584 +<listitem><para>    abort: broken.style:1: <emphasis role="bold">parse error</emphasis>
  24.585 +</para>
  24.586 +</listitem></programlisting>
  24.587 +<listitem><para>  The description of the problem is not always clear (as in this
  24.588 +  case), but even when it is cryptic, it is almost always trivial to
  24.589 +  visually inspect the offending line in the style file and see what
  24.590 +  is wrong.
  24.591 +</para>
  24.592 +</listitem></itemizedlist>
  24.593 +
  24.594 +</sect2>
  24.595 +<sect2>
  24.596 +<title>Uniquely identifying a repository</title>
  24.597 +
  24.598 +<para>If you would like to be able to identify a Mercurial repository
  24.599 +<quote>fairly uniquely</quote> using a short string as an identifier, you can
  24.600 +use the first revision in the repository.
  24.601 +<!-- &interaction.template.svnstyle.id; -->
  24.602 +This is not guaranteed to be unique, but it is nevertheless useful in
  24.603 +many cases.
  24.604 +</para>
  24.605 +<itemizedlist>
  24.606 +<listitem><para>It will not work in a completely empty repository, because such
  24.607 +  a repository does not have a revision zero.
  24.608 +</para>
  24.609 +</listitem>
  24.610 +<listitem><para>Neither will it work in the (extremely rare) case where a
  24.611 +  repository is a merge of two or more formerly independent
  24.612 +  repositories, and you still have those repositories around.
  24.613 +</para>
  24.614 +</listitem></itemizedlist>
  24.615 +<para>Here are some uses to which you could put this identifier:
  24.616 +</para>
  24.617 +<itemizedlist>
  24.618 +<listitem><para>As a key into a table for a database that manages repositories
  24.619 +  on a server.
  24.620 +</para>
  24.621 +</listitem>
  24.622 +<listitem><para>As half of a {<emphasis>repository ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
  24.623 +  Save this information away when you run an automated build or other
  24.624 +  activity, so that you can <quote>replay</quote> the build later if necessary.
  24.625 +</para>
  24.626 +</listitem></itemizedlist>
  24.627 +
  24.628 +</sect2>
  24.629 +<sect2>
  24.630 +<title>Mimicking Subversion's output</title>
  24.631 +
  24.632 +<para>Let's try to emulate the default output format used by another
  24.633 +revision control tool, Subversion.
  24.634 +<!-- &interaction.template.svnstyle.short; -->
  24.635 +</para>
  24.636 +
  24.637 +<para>Since Subversion's output style is fairly simple, it is easy to
  24.638 +copy-and-paste a hunk of its output into a file, and replace the text
  24.639 +produced above by Subversion with the template values we'd like to see
  24.640 +expanded.
  24.641 +<!-- &interaction.template.svnstyle.template; -->
  24.642 +</para>
  24.643 +
  24.644 +<para>There are a few small ways in which this template deviates from the
  24.645 +output produced by Subversion.
  24.646 +</para>
  24.647 +<itemizedlist>
  24.648 +<listitem><para>Subversion prints a <quote>readable</quote> date (the <quote>\texttt{Wed, 27 Sep
  24.649 +    2006}</quote> in the example output above) in parentheses.  Mercurial's
  24.650 +  templating engine does not provide a way to display a date in this
  24.651 +  format without also printing the time and time zone.
  24.652 +</para>
  24.653 +</listitem>
  24.654 +<listitem><para>We emulate Subversion's printing of <quote>separator</quote> lines full of
  24.655 +  <quote><literal>-</literal></quote> characters by ending the template with such a line.
  24.656 +  We use the templating engine's <literal role="template-keyword">header</literal> keyword to print a
  24.657 +  separator line as the first line of output (see below), thus
  24.658 +  achieving similar output to Subversion.
  24.659 +</para>
  24.660 +</listitem>
  24.661 +<listitem><para>Subversion's output includes a count in the header of the number
  24.662 +  of lines in the commit message.  We cannot replicate this in
  24.663 +  Mercurial; the templating engine does not currently provide a filter
  24.664 +  that counts the number of lines the template generates.
  24.665 +</para>
  24.666 +</listitem></itemizedlist>
  24.667 +<para>It took me no more than a minute or two of work to replace literal
  24.668 +text from an example of Subversion's output with some keywords and
  24.669 +filters to give the template above.  The style file simply refers to
  24.670 +the template.
  24.671 +<!-- &interaction.template.svnstyle.style; -->
  24.672 +</para>
  24.673 +
  24.674 +<para>We could have included the text of the template file directly in the
  24.675 +style file by enclosing it in quotes and replacing the newlines with
  24.676 +<quote><literal>\n</literal></quote> sequences, but it would have made the style file too
  24.677 +difficult to read.  Readability is a good guide when you're trying to
  24.678 +decide whether some text belongs in a style file, or in a template
  24.679 +file that the style file points to.  If the style file will look too
  24.680 +big or cluttered if you insert a literal piece of text, drop it into a
  24.681 +template instead.
  24.682 +</para>
  24.683 +
  24.684 +</sect2>
  24.685 +</sect1>
  24.686 +</chapter>
  24.687 +
  24.688 +<!--
  24.689 +local variables: 
  24.690 +sgml-parent-document: ("00book.xml" "book" "chapter")
  24.691 +end:
  24.692 +-->
  24.693 \ No newline at end of file
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/fr/ch12-mq.xml	Sun Aug 16 04:58:01 2009 +0200
    25.3 @@ -0,0 +1,1309 @@
    25.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    25.5 +
    25.6 +<chapter>
    25.7 +<title>Managing change with Mercurial Queues</title>
    25.8 +<para>\label{chap:mq}</para>
    25.9 +
   25.10 +<sect1>
   25.11 +<title>The patch management problem</title>
   25.12 +<para>\label{sec:mq:patch-mgmt}</para>
   25.13 +
   25.14 +<para>Here is a common scenario: you need to install a software package from
   25.15 +source, but you find a bug that you must fix in the source before you
   25.16 +can start using the package.  You make your changes, forget about the
   25.17 +package for a while, and a few months later you need to upgrade to a
   25.18 +newer version of the package.  If the newer version of the package
   25.19 +still has the bug, you must extract your fix from the older source
   25.20 +tree and apply it against the newer version.  This is a tedious task,
   25.21 +and it's easy to make mistakes.</para>
   25.22 +
   25.23 +<para>This is a simple case of the <quote>patch management</quote> problem.  You have
   25.24 +an <quote>upstream</quote> source tree that you can't change; you need to make
   25.25 +some local changes on top of the upstream tree; and you'd like to be
   25.26 +able to keep those changes separate, so that you can apply them to
   25.27 +newer versions of the upstream source.</para>
   25.28 +
   25.29 +<para>The patch management problem arises in many situations.  Probably the
   25.30 +most visible is that a user of an open source software project will
   25.31 +contribute a bug fix or new feature to the project's maintainers in the
   25.32 +form of a patch.</para>
   25.33 +
   25.34 +<para>Distributors of operating systems that include open source software
   25.35 +often need to make changes to the packages they distribute so that
   25.36 +they will build properly in their environments.</para>
   25.37 +
   25.38 +<para>When you have few changes to maintain, it is easy to manage a single
   25.39 +patch using the standard <command>diff</command> and <command>patch</command> programs
   25.40 +(see section <xref linkend="sec:mq:patch"/> for a discussion of these tools).
   25.41 +Once the number of changes grows, it starts to make sense to maintain
   25.42 +patches as discrete <quote>chunks of work,</quote> so that for example a single
   25.43 +patch will contain only one bug fix (the patch might modify several
   25.44 +files, but it's doing <quote>only one thing</quote>), and you may have a number
   25.45 +of such patches for different bugs you need fixed and local changes
   25.46 +you require.  In this situation, if you submit a bug fix patch to the
   25.47 +upstream maintainers of a package and they include your fix in a
   25.48 +subsequent release, you can simply drop that single patch when you're
   25.49 +updating to the newer release.</para>
   25.50 +
   25.51 +<para>Maintaining a single patch against an upstream tree is a little
   25.52 +tedious and error-prone, but not difficult.  However, the complexity
   25.53 +of the problem grows rapidly as the number of patches you have to
   25.54 +maintain increases.  With more than a tiny number of patches in hand,
   25.55 +understanding which ones you have applied and maintaining them moves
   25.56 +from messy to overwhelming.</para>
   25.57 +
   25.58 +<para>Fortunately, Mercurial includes a powerful extension, Mercurial Queues
   25.59 +(or simply <quote>MQ</quote>), that massively simplifies the patch management
   25.60 +problem.
   25.61 +</para>
   25.62 +
   25.63 +</sect1>
   25.64 +<sect1>
   25.65 +<title>The prehistory of Mercurial Queues</title>
   25.66 +<para>\label{sec:mq:history}
   25.67 +</para>
   25.68 +
   25.69 +<para>During the late 1990s, several Linux kernel developers started to
   25.70 +maintain <quote>patch series</quote> that modified the behaviour of the Linux
   25.71 +kernel.  Some of these series were focused on stability, some on
   25.72 +feature coverage, and others were more speculative.
   25.73 +</para>
   25.74 +
   25.75 +<para>The sizes of these patch series grew rapidly.  In 2002, Andrew Morton
   25.76 +published some shell scripts he had been using to automate the task of
   25.77 +managing his patch queues.  Andrew was successfully using these
   25.78 +scripts to manage hundreds (sometimes thousands) of patches on top of
   25.79 +the Linux kernel.
   25.80 +</para>
   25.81 +
   25.82 +<sect2>
   25.83 +<title>A patchwork quilt</title>
   25.84 +<para>\label{sec:mq:quilt}
   25.85 +</para>
   25.86 +
   25.87 +<para>In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the
   25.88 +approach of Andrew's scripts and published a tool called <quote>patchwork
   25.89 +quilt</quote> <citation>web:quilt</citation>, or simply <quote>quilt</quote>
   25.90 +(see <citation>gruenbacher:2005</citation> for a paper describing it).  Because
   25.91 +quilt substantially automated patch management, it rapidly gained a
   25.92 +large following among open source software developers.
   25.93 +</para>
   25.94 +
   25.95 +<para>Quilt manages a <emphasis>stack of patches</emphasis> on top of a directory tree.
   25.96 +To begin, you tell quilt to manage a directory tree, and tell it which
   25.97 +files you want to manage; it stores away the names and contents of
   25.98 +those files.  To fix a bug, you create a new patch (using a single
   25.99 +command), edit the files you need to fix, then <quote>refresh</quote> the patch.
  25.100 +</para>
  25.101 +
  25.102 +<para>The refresh step causes quilt to scan the directory tree; it updates
  25.103 +the patch with all of the changes you have made.  You can create
  25.104 +another patch on top of the first, which will track the changes
  25.105 +required to modify the tree from <quote>tree with one patch applied</quote> to
  25.106 +<quote>tree with two patches applied</quote>.
  25.107 +</para>
  25.108 +
  25.109 +<para>You can <emphasis>change</emphasis> which patches are applied to the tree.  If you
  25.110 +<quote>pop</quote> a patch, the changes made by that patch will vanish from the
  25.111 +directory tree.  Quilt remembers which patches you have popped,
  25.112 +though, so you can <quote>push</quote> a popped patch again, and the directory
  25.113 +tree will be restored to contain the modifications in the patch.  Most
  25.114 +importantly, you can run the <quote>refresh</quote> command at any time, and the
  25.115 +topmost applied patch will be updated.  This means that you can, at
  25.116 +any time, change both which patches are applied and what
  25.117 +modifications those patches make.
  25.118 +</para>
  25.119 +
  25.120 +<para>Quilt knows nothing about revision control tools, so it works equally
  25.121 +well on top of an unpacked tarball or a Subversion working copy.
  25.122 +</para>
  25.123 +
  25.124 +</sect2>
  25.125 +<sect2>
  25.126 +<title>From patchwork quilt to Mercurial Queues</title>
  25.127 +<para>\label{sec:mq:quilt-mq}
  25.128 +</para>
  25.129 +
  25.130 +<para>In mid-2005, Chris Mason took the features of quilt and wrote an
  25.131 +extension that he called Mercurial Queues, which added quilt-like
  25.132 +behaviour to Mercurial.
  25.133 +</para>
  25.134 +
  25.135 +<para>The key difference between quilt and MQ is that quilt knows nothing
  25.136 +about revision control systems, while MQ is <emphasis>integrated</emphasis> into
  25.137 +Mercurial.  Each patch that you push is represented as a Mercurial
  25.138 +changeset.  Pop a patch, and the changeset goes away.
  25.139 +</para>
  25.140 +
  25.141 +<para>Because quilt does not care about revision control tools, it is still
  25.142 +a tremendously useful piece of software to know about for situations
  25.143 +where you cannot use Mercurial and MQ.
  25.144 +</para>
  25.145 +
  25.146 +</sect2>
  25.147 +</sect1>
  25.148 +<sect1>
  25.149 +<title>The huge advantage of MQ</title>
  25.150 +
  25.151 +<para>I cannot overstate the value that MQ offers through the unification of
  25.152 +patches and revision control.
  25.153 +</para>
  25.154 +
  25.155 +<para>A major reason that patches have persisted in the free software and
  25.156 +open source world&emdash;in spite of the availability of increasingly
  25.157 +capable revision control tools over the years&emdash;is the <emphasis>agility</emphasis>
  25.158 +they offer.
  25.159 +</para>
  25.160 +
  25.161 +<para>Traditional revision control tools make a permanent, irreversible
  25.162 +record of everything that you do.  While this has great value, it's
  25.163 +also somewhat stifling.  If you want to perform a wild-eyed
  25.164 +experiment, you have to be careful in how you go about it, or you risk
  25.165 +leaving unneeded&emdash;or worse, misleading or destabilising&emdash;traces of
  25.166 +your missteps and errors in the permanent revision record.
  25.167 +</para>
  25.168 +
  25.169 +<para>By contrast, MQ's marriage of distributed revision control with
  25.170 +patches makes it much easier to isolate your work.  Your patches live
  25.171 +on top of normal revision history, and you can make them disappear or
  25.172 +reappear at will.  If you don't like a patch, you can drop it.  If a
  25.173 +patch isn't quite as you want it to be, simply fix it&emdash;as many times
  25.174 +as you need to, until you have refined it into the form you desire.
  25.175 +</para>
  25.176 +
  25.177 +<para>As an example, the integration of patches with revision control makes
  25.178 +understanding patches and debugging their effects&emdash;and their
  25.179 +interplay with the code they're based on&emdash;<emphasis>enormously</emphasis> easier.
  25.180 +Since every applied patch has an associated changeset, you can use
  25.181 +<command role="hg-cmd">hg log <emphasis>filename</emphasis></command> to see which changesets and patches
  25.182 +affected a file.  You can use the <literal role="hg-ext">bisect</literal> command to
  25.183 +binary-search through all changesets and applied patches to see where
  25.184 +a bug got introduced or fixed.  You can use the <command role="hg-cmd">hg annotate</command>
  25.185 +command to see which changeset or patch modified a particular line of
  25.186 +a source file.  And so on.
  25.187 +</para>
  25.188 +
  25.189 +</sect1>
  25.190 +<sect1>
  25.191 +<title>Understanding patches</title>
  25.192 +<para>\label{sec:mq:patch}
  25.193 +</para>
  25.194 +
  25.195 +<para>Because MQ doesn't hide its patch-oriented nature, it is helpful to
  25.196 +understand what patches are, and a little about the tools that work
  25.197 +with them.
  25.198 +</para>
  25.199 +
  25.200 +<para>The traditional Unix <command>diff</command> command compares two files, and
  25.201 +prints a list of differences between them. The <command>patch</command> command
  25.202 +understands these differences as <emphasis>modifications</emphasis> to make to a
  25.203 +file.  Take a look at figure <xref linkend="ex:mq:diff"/> for a simple example of
  25.204 +these commands in action.
  25.205 +</para>
  25.206 +
  25.207 +<informalfigure>
  25.208 +<para>  <!-- &interaction.mq.dodiff.diff; -->
  25.209 +  <caption><para>Simple uses of the <command>diff</para></caption> and \command{patch</command> commands}
  25.210 +  \label{ex:mq:diff}
  25.211 +</para>
  25.212 +</informalfigure>
  25.213 +
  25.214 +<para>The type of file that <command>diff</command> generates (and <command>patch</command>
  25.215 +takes as input) is called a <quote>patch</quote> or a <quote>diff</quote>; there is no
  25.216 +difference between a patch and a diff.  (We'll use the term <quote>patch</quote>,
  25.217 +since it's more commonly used.)
  25.218 +</para>
  25.219 +
  25.220 +<para>A patch file can start with arbitrary text; the <command>patch</command>
  25.221 +command ignores this text, but MQ uses it as the commit message when
  25.222 +creating changesets.  To find the beginning of the patch content,
  25.223 +<command>patch</command> searches for the first line that starts with the
  25.224 +string <quote><literal>diff -</literal></quote>.
  25.225 +</para>
  25.226 +
  25.227 +<para>MQ works with <emphasis>unified</emphasis> diffs (<command>patch</command> can accept several
  25.228 +other diff formats, but MQ doesn't).  A unified diff contains two
  25.229 +kinds of header.  The <emphasis>file header</emphasis> describes the file being
  25.230 +modified; it contains the name of the file to modify.  When
  25.231 +<command>patch</command> sees a new file header, it looks for a file with that
  25.232 +name to start modifying.
  25.233 +</para>
  25.234 +
  25.235 +<para>After the file header comes a series of <emphasis>hunks</emphasis>.  Each hunk
  25.236 +starts with a header; this identifies the range of line numbers within
  25.237 +the file that the hunk should modify.  Following the header, a hunk
  25.238 +starts and ends with a few (usually three) lines of text from the
  25.239 +unmodified file; these are called the <emphasis>context</emphasis> for the hunk.  If
  25.240 +there's only a small amount of context between successive hunks,
  25.241 +<command>diff</command> doesn't print a new hunk header; it just runs the hunks
  25.242 +together, with a few lines of context between modifications.
  25.243 +</para>
  25.244 +
  25.245 +<para>Each line of context begins with a space character.  Within the hunk,
  25.246 +a line that begins with <quote><literal>-</literal></quote> means <quote>remove this line,</quote>
  25.247 +while a line that begins with <quote><literal>+</literal></quote> means <quote>insert this
  25.248 +line.</quote>  For example, a line that is modified is represented by one
  25.249 +deletion and one insertion.
  25.250 +</para>
  25.251 +
  25.252 +<para>We will return to some of the more subtle aspects of patches later (in
  25.253 +section <xref linkend="sec:mq:adv-patch"/>), but you should have enough information
  25.254 +now to use MQ.
  25.255 +</para>
  25.256 +
  25.257 +</sect1>
  25.258 +<sect1>
  25.259 +<title>Getting started with Mercurial Queues</title>
  25.260 +<para>\label{sec:mq:start}
  25.261 +</para>
  25.262 +
  25.263 +<para>Because MQ is implemented as an extension, you must explicitly enable
  25.264 +before you can use it.  (You don't need to download anything; MQ ships
  25.265 +with the standard Mercurial distribution.)  To enable MQ, edit your
  25.266 +<filename role="home">~/.hgrc</filename> file, and add the lines in figure <xref linkend="ex:mq:config"/>.
  25.267 +</para>
  25.268 +
  25.269 +<informalfigure>
  25.270 +<programlisting>
  25.271 +<para>    [extensions]
  25.272 +    hgext.mq =
  25.273 +</para>
  25.274 +</programlisting>
  25.275 +<para>  \label{ex:mq:config}
  25.276 +  <caption><para>Contents to add to <filename role="home">~/.hgrc</para></caption> to enable the MQ extension</filename>
  25.277 +</para>
  25.278 +</informalfigure>
  25.279 +
  25.280 +<para>Once the extension is enabled, it will make a number of new commands
  25.281 +available.  To verify that the extension is working, you can use
  25.282 +<command role="hg-cmd">hg help</command> to see if the <command role="hg-ext-mq">qinit</command> command is now available; see
  25.283 +the example in figure <xref linkend="ex:mq:enabled"/>.
  25.284 +</para>
  25.285 +
  25.286 +<informalfigure>
  25.287 +<para>  <!-- &interaction.mq.qinit-help.help; -->
  25.288 +  <caption><para>How to verify that MQ is enabled</para></caption>
  25.289 +  \label{ex:mq:enabled}
  25.290 +</para>
  25.291 +</informalfigure>
  25.292 +
  25.293 +<para>You can use MQ with <emphasis>any</emphasis> Mercurial repository, and its commands
  25.294 +only operate within that repository.  To get started, simply prepare
  25.295 +the repository using the <command role="hg-ext-mq">qinit</command> command (see
  25.296 +figure <xref linkend="ex:mq:qinit"/>).  This command creates an empty directory
  25.297 +called <filename role="special" class="directory">.hg/patches</filename>, where MQ will keep its metadata.  As
  25.298 +with many Mercurial commands, the <command role="hg-ext-mq">qinit</command> command prints nothing
  25.299 +if it succeeds.
  25.300 +</para>
  25.301 +
  25.302 +<informalfigure>
  25.303 +<para>  <!-- &interaction.mq.tutorial.qinit; -->
  25.304 +  <caption><para>Preparing a repository for use with MQ</para></caption>
  25.305 +  \label{ex:mq:qinit}
  25.306 +</para>
  25.307 +</informalfigure>
  25.308 +
  25.309 +<informalfigure>
  25.310 +<para>  <!-- &interaction.mq.tutorial.qnew; -->
  25.311 +  <caption><para>Creating a new patch</para></caption>
  25.312 +  \label{ex:mq:qnew}
  25.313 +</para>
  25.314 +</informalfigure>
  25.315 +
  25.316 +<sect2>
  25.317 +<title>Creating a new patch</title>
  25.318 +
  25.319 +<para>To begin work on a new patch, use the <command role="hg-ext-mq">qnew</command> command.  This
  25.320 +command takes one argument, the name of the patch to create.  MQ will
  25.321 +use this as the name of an actual file in the <filename role="special" class="directory">.hg/patches</filename>
  25.322 +directory, as you can see in figure <xref linkend="ex:mq:qnew"/>.
  25.323 +</para>
  25.324 +
  25.325 +<para>Also newly present in the <filename role="special" class="directory">.hg/patches</filename> directory are two
  25.326 +other files, <filename role="special">series</filename> and <filename role="special">status</filename>.  The
  25.327 +<filename role="special">series</filename> file lists all of the patches that MQ knows about
  25.328 +for this repository, with one patch per line.  Mercurial uses the
  25.329 +<filename role="special">status</filename> file for internal book-keeping; it tracks all of the
  25.330 +patches that MQ has <emphasis>applied</emphasis> in this repository.
  25.331 +</para>
  25.332 +
  25.333 +<note>
  25.334 +<para>  You may sometimes want to edit the <filename role="special">series</filename> file by hand;
  25.335 +  for example, to change the sequence in which some patches are
  25.336 +  applied.  However, manually editing the <filename role="special">status</filename> file is
  25.337 +  almost always a bad idea, as it's easy to corrupt MQ's idea of what
  25.338 +  is happening.
  25.339 +</para>
  25.340 +</note>
  25.341 +
  25.342 +<para>Once you have created your new patch, you can edit files in the
  25.343 +working directory as you usually would.  All of the normal Mercurial
  25.344 +commands, such as <command role="hg-cmd">hg diff</command> and <command role="hg-cmd">hg annotate</command>, work exactly as
  25.345 +they did before.
  25.346 +</para>
  25.347 +
  25.348 +</sect2>
  25.349 +<sect2>
  25.350 +<title>Refreshing a patch</title>
  25.351 +
  25.352 +<para>When you reach a point where you want to save your work, use the
  25.353 +<command role="hg-ext-mq">qrefresh</command> command (figure <xref linkend="ex:mq:qnew"/>) to update the patch
  25.354 +you are working on.  This command folds the changes you have made in
  25.355 +the working directory into your patch, and updates its corresponding
  25.356 +changeset to contain those changes.
  25.357 +</para>
  25.358 +
  25.359 +<informalfigure>
  25.360 +<para>  <!-- &interaction.mq.tutorial.qrefresh; -->
  25.361 +  <caption><para>Refreshing a patch</para></caption>
  25.362 +  \label{ex:mq:qrefresh}
  25.363 +</para>
  25.364 +</informalfigure>
  25.365 +
  25.366 +<para>You can run <command role="hg-ext-mq">qrefresh</command> as often as you like, so it's a good way
  25.367 +to <quote>checkpoint</quote> your work.  Refresh your patch at an opportune
  25.368 +time; try an experiment; and if the experiment doesn't work out,
  25.369 +<command role="hg-cmd">hg revert</command> your modifications back to the last time you refreshed.
  25.370 +</para>
  25.371 +
  25.372 +<informalfigure>
  25.373 +<para>  <!-- &interaction.mq.tutorial.qrefresh2; -->
  25.374 +  <caption><para>Refresh a patch many times to accumulate changes</para></caption>
  25.375 +  \label{ex:mq:qrefresh2}
  25.376 +</para>
  25.377 +</informalfigure>
  25.378 +
  25.379 +</sect2>
  25.380 +<sect2>
  25.381 +<title>Stacking and tracking patches</title>
  25.382 +
  25.383 +<para>Once you have finished working on a patch, or need to work on another,
  25.384 +you can use the <command role="hg-ext-mq">qnew</command> command again to create a new patch.
  25.385 +Mercurial will apply this patch on top of your existing patch.  See
  25.386 +figure <xref linkend="ex:mq:qnew2"/> for an example.  Notice that the patch
  25.387 +contains the changes in our prior patch as part of its context (you
  25.388 +can see this more clearly in the output of <command role="hg-cmd">hg annotate</command>).
  25.389 +</para>
  25.390 +
  25.391 +<informalfigure>
  25.392 +<para>  <!-- &interaction.mq.tutorial.qnew2; -->
  25.393 +  <caption><para>Stacking a second patch on top of the first</para></caption>
  25.394 +  \label{ex:mq:qnew2}
  25.395 +</para>
  25.396 +</informalfigure>
  25.397 +
  25.398 +<para>So far, with the exception of <command role="hg-ext-mq">qnew</command> and <command role="hg-ext-mq">qrefresh</command>, we've
  25.399 +been careful to only use regular Mercurial commands.  However, MQ
  25.400 +provides many commands that are easier to use when you are thinking
  25.401 +about patches, as illustrated in figure <xref linkend="ex:mq:qseries"/>:
  25.402 +</para>
  25.403 +
  25.404 +<itemizedlist>
  25.405 +<listitem><para>The <command role="hg-ext-mq">qseries</command> command lists every patch that MQ knows
  25.406 +  about in this repository, from oldest to newest (most recently
  25.407 +  <emphasis>created</emphasis>).
  25.408 +</para>
  25.409 +</listitem>
  25.410 +<listitem><para>The <command role="hg-ext-mq">qapplied</command> command lists every patch that MQ has
  25.411 +  <emphasis>applied</emphasis> in this repository, again from oldest to newest (most
  25.412 +  recently applied).
  25.413 +</para>
  25.414 +</listitem></itemizedlist>
  25.415 +
  25.416 +<informalfigure>
  25.417 +<para>  <!-- &interaction.mq.tutorial.qseries; -->
  25.418 +  \caption{Understanding the patch stack with <command role="hg-ext-mq">qseries</command> and
  25.419 +    <command role="hg-ext-mq">qapplied</command>}
  25.420 +  \label{ex:mq:qseries}
  25.421 +</para>
  25.422 +</informalfigure>
  25.423 +
  25.424 +</sect2>
  25.425 +<sect2>
  25.426 +<title>Manipulating the patch stack</title>
  25.427 +
  25.428 +<para>The previous discussion implied that there must be a difference
  25.429 +between <quote>known</quote> and <quote>applied</quote> patches, and there is.  MQ can
  25.430 +manage a patch without it being applied in the repository.
  25.431 +</para>
  25.432 +
  25.433 +<para>An <emphasis>applied</emphasis> patch has a corresponding changeset in the
  25.434 +repository, and the effects of the patch and changeset are visible in
  25.435 +the working directory.  You can undo the application of a patch using
  25.436 +the <command role="hg-ext-mq">qpop</command> command.  MQ still <emphasis>knows about</emphasis>, or manages, a
  25.437 +popped patch, but the patch no longer has a corresponding changeset in
  25.438 +the repository, and the working directory does not contain the changes
  25.439 +made by the patch.  Figure <xref linkend="fig:mq:stack"/> illustrates the
  25.440 +difference between applied and tracked patches.
  25.441 +</para>
  25.442 +
  25.443 +<informalfigure>
  25.444 +
  25.445 +<para>  <mediaobject><imageobject><imagedata fileref="mq-stack"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
  25.446 +  <caption><para>Applied and unapplied patches in the MQ patch stack</para></caption>
  25.447 +  \label{fig:mq:stack}
  25.448 +</para>
  25.449 +</informalfigure>
  25.450 +
  25.451 +<para>You can reapply an unapplied, or popped, patch using the <command role="hg-ext-mq">qpush</command>
  25.452 +command.  This creates a new changeset to correspond to the patch, and
  25.453 +the patch's changes once again become present in the working
  25.454 +directory.  See figure <xref linkend="ex:mq:qpop"/> for examples of <command role="hg-ext-mq">qpop</command>
  25.455 +and <command role="hg-ext-mq">qpush</command> in action.  Notice that once we have popped a patch
  25.456 +or two patches, the output of <command role="hg-ext-mq">qseries</command> remains the same, while
  25.457 +that of <command role="hg-ext-mq">qapplied</command> has changed.
  25.458 +</para>
  25.459 +
  25.460 +<informalfigure>
  25.461 +<para>  <!-- &interaction.mq.tutorial.qpop; -->
  25.462 +  <caption><para>Modifying the stack of applied patches</para></caption>
  25.463 +  \label{ex:mq:qpop}
  25.464 +</para>
  25.465 +</informalfigure>
  25.466 +
  25.467 +</sect2>
  25.468 +<sect2>
  25.469 +<title>Pushing and popping many patches</title>
  25.470 +
  25.471 +<para>While <command role="hg-ext-mq">qpush</command> and <command role="hg-ext-mq">qpop</command> each operate on a single patch at
  25.472 +a time by default, you can push and pop many patches in one go.  The
  25.473 +<option role="hg-ext-mq-cmd-qpush-opt">-a</option> option to <command role="hg-ext-mq">qpush</command> causes it to push all
  25.474 +unapplied patches, while the <option role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command role="hg-ext-mq">qpop</command>
  25.475 +causes it to pop all applied patches.  (For some more ways to push and
  25.476 +pop many patches, see section <xref linkend="sec:mq:perf"/> below.)
  25.477 +</para>
  25.478 +
  25.479 +<informalfigure>
  25.480 +<para>  <!-- &interaction.mq.tutorial.qpush-a; -->
  25.481 +  <caption><para>Pushing all unapplied patches</para></caption>
  25.482 +  \label{ex:mq:qpush-a}
  25.483 +</para>
  25.484 +</informalfigure>
  25.485 +
  25.486 +</sect2>
  25.487 +<sect2>
  25.488 +<title>Safety checks, and overriding them</title>
  25.489 +
  25.490 +<para>Several MQ commands check the working directory before they do
  25.491 +anything, and fail if they find any modifications.  They do this to
  25.492 +ensure that you won't lose any changes that you have made, but not yet
  25.493 +incorporated into a patch.  Figure <xref linkend="ex:mq:add"/> illustrates this;
  25.494 +the <command role="hg-ext-mq">qnew</command> command will not create a new patch if there are
  25.495 +outstanding changes, caused in this case by the <command role="hg-cmd">hg add</command> of
  25.496 +<filename>file3</filename>.
  25.497 +</para>
  25.498 +
  25.499 +<informalfigure>
  25.500 +<para>  <!-- &interaction.mq.tutorial.add; -->
  25.501 +  <caption><para>Forcibly creating a patch</para></caption>
  25.502 +  \label{ex:mq:add}
  25.503 +</para>
  25.504 +</informalfigure>
  25.505 +
  25.506 +<para>Commands that check the working directory all take an <quote>I know what
  25.507 +I'm doing</quote> option, which is always named <option>-f</option>.  The exact
  25.508 +meaning of <option>-f</option> depends on the command.  For example,
  25.509 +<command role="hg-cmd">hg qnew <option role="hg-ext-mq-cmd-qnew-opt">-f</option></command> will incorporate any outstanding
  25.510 +changes into the new patch it creates, but
  25.511 +<command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-f</option></command> will revert modifications to any
  25.512 +files affected by the patch that it is popping.  Be sure to read the
  25.513 +documentation for a command's <option>-f</option> option before you use it!
  25.514 +</para>
  25.515 +
  25.516 +</sect2>
  25.517 +<sect2>
  25.518 +<title>Working on several patches at once</title>
  25.519 +
  25.520 +<para>The <command role="hg-ext-mq">qrefresh</command> command always refreshes the <emphasis>topmost</emphasis>
  25.521 +applied patch.  This means that you can suspend work on one patch (by
  25.522 +refreshing it), pop or push to make a different patch the top, and
  25.523 +work on <emphasis>that</emphasis> patch for a while.
  25.524 +</para>
  25.525 +
  25.526 +<para>Here's an example that illustrates how you can use this ability.
  25.527 +Let's say you're developing a new feature as two patches.  The first
  25.528 +is a change to the core of your software, and the second&emdash;layered on
  25.529 +top of the first&emdash;changes the user interface to use the code you just
  25.530 +added to the core.  If you notice a bug in the core while you're
  25.531 +working on the UI patch, it's easy to fix the core.  Simply
  25.532 +<command role="hg-ext-mq">qrefresh</command> the UI patch to save your in-progress changes, and
  25.533 +<command role="hg-ext-mq">qpop</command> down to the core patch.  Fix the core bug,
  25.534 +<command role="hg-ext-mq">qrefresh</command> the core patch, and <command role="hg-ext-mq">qpush</command> back to the UI
  25.535 +patch to continue where you left off.
  25.536 +</para>
  25.537 +
  25.538 +</sect2>
  25.539 +</sect1>
  25.540 +<sect1>
  25.541 +<title>More about patches</title>
  25.542 +<para>\label{sec:mq:adv-patch}
  25.543 +</para>
  25.544 +
  25.545 +<para>MQ uses the GNU <command>patch</command> command to apply patches, so it's
  25.546 +helpful to know a few more detailed aspects of how <command>patch</command>
  25.547 +works, and about patches themselves.
  25.548 +</para>
  25.549 +
  25.550 +<sect2>
  25.551 +<title>The strip count</title>
  25.552 +
  25.553 +<para>If you look at the file headers in a patch, you will notice that the
  25.554 +pathnames usually have an extra component on the front that isn't
  25.555 +present in the actual path name.  This is a holdover from the way that
  25.556 +people used to generate patches (people still do this, but it's
  25.557 +somewhat rare with modern revision control tools).
  25.558 +</para>
  25.559 +
  25.560 +<para>Alice would unpack a tarball, edit her files, then decide that she
  25.561 +wanted to create a patch.  So she'd rename her working directory,
  25.562 +unpack the tarball again (hence the need for the rename), and use the
  25.563 +<option role="cmd-opt-diff">-r</option> and <option role="cmd-opt-diff">-N</option> options to <command>diff</command> to
  25.564 +recursively generate a patch between the unmodified directory and the
  25.565 +modified one.  The result would be that the name of the unmodified
  25.566 +directory would be at the front of the left-hand path in every file
  25.567 +header, and the name of the modified directory would be at the front
  25.568 +of the right-hand path.
  25.569 +</para>
  25.570 +
  25.571 +<para>Since someone receiving a patch from the Alices of the net would be
  25.572 +unlikely to have unmodified and modified directories with exactly the
  25.573 +same names, the <command>patch</command> command has a <option role="cmd-opt-patch">-p</option>
  25.574 +option that indicates the number of leading path name components to
  25.575 +strip when trying to apply a patch.  This number is called the
  25.576 +<emphasis>strip count</emphasis>.
  25.577 +</para>
  25.578 +
  25.579 +<para>An option of <quote><literal>-p1</literal></quote> means <quote>use a strip count of one</quote>.  If
  25.580 +<command>patch</command> sees a file name <filename>foo/bar/baz</filename> in a file
  25.581 +header, it will strip <filename>foo</filename> and try to patch a file named
  25.582 +<filename>bar/baz</filename>.  (Strictly speaking, the strip count refers to the
  25.583 +number of <emphasis>path separators</emphasis> (and the components that go with them
  25.584 +) to strip.  A strip count of one will turn <filename>foo/bar</filename> into
  25.585 +<filename>bar</filename>, but <filename>/foo/bar</filename> (notice the extra leading
  25.586 +slash) into <filename>foo/bar</filename>.)
  25.587 +</para>
  25.588 +
  25.589 +<para>The <quote>standard</quote> strip count for patches is one; almost all patches
  25.590 +contain one leading path name component that needs to be stripped.
  25.591 +Mercurial's <command role="hg-cmd">hg diff</command> command generates path names in this form,
  25.592 +and the <command role="hg-cmd">hg import</command> command and MQ expect patches to have a strip
  25.593 +count of one.
  25.594 +</para>
  25.595 +
  25.596 +<para>If you receive a patch from someone that you want to add to your patch
  25.597 +queue, and the patch needs a strip count other than one, you cannot
  25.598 +just <command role="hg-ext-mq">qimport</command> the patch, because <command role="hg-ext-mq">qimport</command> does not yet
  25.599 +have a <literal>-p</literal> option (see <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">issue 311</ulink>).  Your best bet is to
  25.600 +<command role="hg-ext-mq">qnew</command> a patch of your own, then use <command>patch -p<emphasis>N</emphasis></command>
  25.601 +to apply their patch, followed by <command role="hg-cmd">hg addremove</command> to pick up any
  25.602 +files added or removed by the patch, followed by <command role="hg-ext-mq">qrefresh</command>.
  25.603 +This complexity may become unnecessary; see <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue311">issue 311</ulink> for details.
  25.604 +</sect2>
  25.605 +<sect2>
  25.606 +<title>Strategies for applying a patch</title>
  25.607 +</para>
  25.608 +
  25.609 +<para>When <command>patch</command> applies a hunk, it tries a handful of
  25.610 +successively less accurate strategies to try to make the hunk apply.
  25.611 +This falling-back technique often makes it possible to take a patch
  25.612 +that was generated against an old version of a file, and apply it
  25.613 +against a newer version of that file.
  25.614 +</para>
  25.615 +
  25.616 +<para>First, <command>patch</command> tries an exact match, where the line numbers,
  25.617 +the context, and the text to be modified must apply exactly.  If it
  25.618 +cannot make an exact match, it tries to find an exact match for the
  25.619 +context, without honouring the line numbering information.  If this
  25.620 +succeeds, it prints a line of output saying that the hunk was applied,
  25.621 +but at some <emphasis>offset</emphasis> from the original line number.
  25.622 +</para>
  25.623 +
  25.624 +<para>If a context-only match fails, <command>patch</command> removes the first and
  25.625 +last lines of the context, and tries a <emphasis>reduced</emphasis> context-only
  25.626 +match.  If the hunk with reduced context succeeds, it prints a message
  25.627 +saying that it applied the hunk with a <emphasis>fuzz factor</emphasis> (the number
  25.628 +after the fuzz factor indicates how many lines of context
  25.629 +<command>patch</command> had to trim before the patch applied).
  25.630 +</para>
  25.631 +
  25.632 +<para>When neither of these techniques works, <command>patch</command> prints a
  25.633 +message saying that the hunk in question was rejected.  It saves
  25.634 +rejected hunks (also simply called <quote>rejects</quote>) to a file with the
  25.635 +same name, and an added <filename role="special">.rej</filename> extension.  It also saves an
  25.636 +unmodified copy of the file with a <filename role="special">.orig</filename> extension; the
  25.637 +copy of the file without any extensions will contain any changes made
  25.638 +by hunks that <emphasis>did</emphasis> apply cleanly.  If you have a patch that
  25.639 +modifies <filename>foo</filename> with six hunks, and one of them fails to
  25.640 +apply, you will have: an unmodified <filename>foo.orig</filename>, a
  25.641 +<filename>foo.rej</filename> containing one hunk, and <filename>foo</filename>, containing
  25.642 +the changes made by the five successful hunks.
  25.643 +</para>
  25.644 +
  25.645 +</sect2>
  25.646 +<sect2>
  25.647 +<title>Some quirks of patch representation</title>
  25.648 +
  25.649 +<para>There are a few useful things to know about how <command>patch</command> works
  25.650 +with files.
  25.651 +</para>
  25.652 +<itemizedlist>
  25.653 +<listitem><para>This should already be obvious, but <command>patch</command> cannot
  25.654 +  handle binary files.
  25.655 +</para>
  25.656 +</listitem>
  25.657 +<listitem><para>Neither does it care about the executable bit; it creates new
  25.658 +  files as readable, but not executable.
  25.659 +</para>
  25.660 +</listitem>
  25.661 +<listitem><para><command>patch</command> treats the removal of a file as a diff between
  25.662 +  the file to be removed and the empty file.  So your idea of <quote>I
  25.663 +  deleted this file</quote> looks like <quote>every line of this file was
  25.664 +  deleted</quote> in a patch.
  25.665 +</para>
  25.666 +</listitem>
  25.667 +<listitem><para>It treats the addition of a file as a diff between the empty
  25.668 +  file and the file to be added.  So in a patch, your idea of <quote>I
  25.669 +  added this file</quote> looks like <quote>every line of this file was added</quote>.
  25.670 +</para>
  25.671 +</listitem>
  25.672 +<listitem><para>It treats a renamed file as the removal of the old name, and the
  25.673 +  addition of the new name.  This means that renamed files have a big
  25.674 +  footprint in patches.  (Note also that Mercurial does not currently
  25.675 +  try to infer when files have been renamed or copied in a patch.)
  25.676 +</para>
  25.677 +</listitem>
  25.678 +<listitem><para><command>patch</command> cannot represent empty files, so you cannot use
  25.679 +  a patch to represent the notion <quote>I added this empty file to the
  25.680 +  tree</quote>.
  25.681 +</para>
  25.682 +</listitem></itemizedlist>
  25.683 +</sect2>
  25.684 +<sect2>
  25.685 +<title>Beware the fuzz</title>
  25.686 +
  25.687 +<para>While applying a hunk at an offset, or with a fuzz factor, will often
  25.688 +be completely successful, these inexact techniques naturally leave
  25.689 +open the possibility of corrupting the patched file.  The most common
  25.690 +cases typically involve applying a patch twice, or at an incorrect
  25.691 +location in the file.  If <command>patch</command> or <command role="hg-ext-mq">qpush</command> ever
  25.692 +mentions an offset or fuzz factor, you should make sure that the
  25.693 +modified files are correct afterwards.
  25.694 +</para>
  25.695 +
  25.696 +<para>It's often a good idea to refresh a patch that has applied with an
  25.697 +offset or fuzz factor; refreshing the patch generates new context
  25.698 +information that will make it apply cleanly.  I say <quote>often,</quote> not
  25.699 +<quote>always,</quote> because sometimes refreshing a patch will make it fail to
  25.700 +apply against a different revision of the underlying files.  In some
  25.701 +cases, such as when you're maintaining a patch that must sit on top of
  25.702 +multiple versions of a source tree, it's acceptable to have a patch
  25.703 +apply with some fuzz, provided you've verified the results of the
  25.704 +patching process in such cases.
  25.705 +</para>
  25.706 +
  25.707 +</sect2>
  25.708 +<sect2>
  25.709 +<title>Handling rejection</title>
  25.710 +
  25.711 +<para>If <command role="hg-ext-mq">qpush</command> fails to apply a patch, it will print an error
  25.712 +message and exit.  If it has left <filename role="special">.rej</filename> files behind, it is
  25.713 +usually best to fix up the rejected hunks before you push more patches
  25.714 +or do any further work.
  25.715 +</para>
  25.716 +
  25.717 +<para>If your patch <emphasis>used to</emphasis> apply cleanly, and no longer does because
  25.718 +you've changed the underlying code that your patches are based on,
  25.719 +Mercurial Queues can help; see section <xref linkend="sec:mq:merge"/> for details.
  25.720 +</para>
  25.721 +
  25.722 +<para>Unfortunately, there aren't any great techniques for dealing with
  25.723 +rejected hunks.  Most often, you'll need to view the <filename role="special">.rej</filename>
  25.724 +file and edit the target file, applying the rejected hunks by hand.
  25.725 +</para>
  25.726 +
  25.727 +<para>If you're feeling adventurous, Neil Brown, a Linux kernel hacker,
  25.728 +wrote a tool called <command>wiggle</command> <citation>web:wiggle</citation>, which is more
  25.729 +vigorous than <command>patch</command> in its attempts to make a patch apply.
  25.730 +</para>
  25.731 +
  25.732 +<para>Another Linux kernel hacker, Chris Mason (the author of Mercurial
  25.733 +Queues), wrote a similar tool called
  25.734 +<command>mpatch</command> <citation>web:mpatch</citation>, which takes a simple approach to
  25.735 +automating the application of hunks rejected by <command>patch</command>.  The
  25.736 +<command>mpatch</command> command can help with four common reasons that a hunk
  25.737 +may be rejected:
  25.738 +</para>
  25.739 +
  25.740 +<itemizedlist>
  25.741 +<listitem><para>The context in the middle of a hunk has changed.
  25.742 +</para>
  25.743 +</listitem>
  25.744 +<listitem><para>A hunk is missing some context at the beginning or end.
  25.745 +</para>
  25.746 +</listitem>
  25.747 +<listitem><para>A large hunk might apply better&emdash;either entirely or in
  25.748 +  part&emdash;if it was broken up into smaller hunks.
  25.749 +</para>
  25.750 +</listitem>
  25.751 +<listitem><para>A hunk removes lines with slightly different content than those
  25.752 +  currently present in the file.
  25.753 +</para>
  25.754 +</listitem></itemizedlist>
  25.755 +
  25.756 +<para>If you use <command>wiggle</command> or <command>mpatch</command>, you should be doubly
  25.757 +careful to check your results when you're done.  In fact,
  25.758 +<command>mpatch</command> enforces this method of double-checking the tool's
  25.759 +output, by automatically dropping you into a merge program when it has
  25.760 +done its job, so that you can verify its work and finish off any
  25.761 +remaining merges.
  25.762 +</para>
  25.763 +
  25.764 +</sect2>
  25.765 +</sect1>
  25.766 +<sect1>
  25.767 +<title>Getting the best performance out of MQ</title>
  25.768 +<para>\label{sec:mq:perf}
  25.769 +</para>
  25.770 +
  25.771 +<para>MQ is very efficient at handling a large number of patches.  I ran
  25.772 +some performance experiments in mid-2006 for a talk that I gave at the
  25.773 +2006 EuroPython conference <citation>web:europython</citation>.  I used as my data
  25.774 +set the Linux 2.6.17-mm1 patch series, which consists of 1,738
  25.775 +patches.  I applied these on top of a Linux kernel repository
  25.776 +containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux
  25.777 +2.6.17.
  25.778 +</para>
  25.779 +
  25.780 +<para>On my old, slow laptop, I was able to
  25.781 +<command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">-a</option></command> all 1,738 patches in 3.5 minutes,
  25.782 +and <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-a</option></command> them all in 30 seconds.  (On a
  25.783 +newer laptop, the time to push all patches dropped to two minutes.)  I
  25.784 +could <command role="hg-ext-mq">qrefresh</command> one of the biggest patches (which made 22,779
  25.785 +lines of changes to 287 files) in 6.6 seconds.
  25.786 +</para>
  25.787 +
  25.788 +<para>Clearly, MQ is well suited to working in large trees, but there are a
  25.789 +few tricks you can use to get the best performance of it.
  25.790 +</para>
  25.791 +
  25.792 +<para>First of all, try to <quote>batch</quote> operations together.  Every time you
  25.793 +run <command role="hg-ext-mq">qpush</command> or <command role="hg-ext-mq">qpop</command>, these commands scan the working
  25.794 +directory once to make sure you haven't made some changes and then
  25.795 +forgotten to run <command role="hg-ext-mq">qrefresh</command>.  On a small tree, the time that
  25.796 +this scan takes is unnoticeable.  However, on a medium-sized tree
  25.797 +(containing tens of thousands of files), it can take a second or more.
  25.798 +</para>
  25.799 +
  25.800 +<para>The <command role="hg-ext-mq">qpush</command> and <command role="hg-ext-mq">qpop</command> commands allow you to push and pop
  25.801 +multiple patches at a time.  You can identify the <quote>destination
  25.802 +patch</quote> that you want to end up at.  When you <command role="hg-ext-mq">qpush</command> with a
  25.803 +destination specified, it will push patches until that patch is at the
  25.804 +top of the applied stack.  When you <command role="hg-ext-mq">qpop</command> to a destination, MQ
  25.805 +will pop patches until the destination patch is at the top.
  25.806 +</para>
  25.807 +
  25.808 +<para>You can identify a destination patch using either the name of the
  25.809 +patch, or by number.  If you use numeric addressing, patches are
  25.810 +counted from zero; this means that the first patch is zero, the second
  25.811 +is one, and so on.
  25.812 +</para>
  25.813 +
  25.814 +</sect1>
  25.815 +<sect1>
  25.816 +<title>Updating your patches when the underlying code changes</title>
  25.817 +<para>\label{sec:mq:merge}
  25.818 +</para>
  25.819 +
  25.820 +<para>It's common to have a stack of patches on top of an underlying
  25.821 +repository that you don't modify directly.  If you're working on
  25.822 +changes to third-party code, or on a feature that is taking longer to
  25.823 +develop than the rate of change of the code beneath, you will often
  25.824 +need to sync up with the underlying code, and fix up any hunks in your
  25.825 +patches that no longer apply.  This is called <emphasis>rebasing</emphasis> your
  25.826 +patch series.
  25.827 +</para>
  25.828 +
  25.829 +<para>The simplest way to do this is to <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-a</option></command>
  25.830 +your patches, then <command role="hg-cmd">hg pull</command> changes into the underlying
  25.831 +repository, and finally <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpop-opt">-a</option></command> your
  25.832 +patches again.  MQ will stop pushing any time it runs across a patch
  25.833 +that fails to apply during conflicts, allowing you to fix your
  25.834 +conflicts, <command role="hg-ext-mq">qrefresh</command> the affected patch, and continue pushing
  25.835 +until you have fixed your entire stack.
  25.836 +</para>
  25.837 +
  25.838 +<para>This approach is easy to use and works well if you don't expect
  25.839 +changes to the underlying code to affect how well your patches apply.
  25.840 +If your patch stack touches code that is modified frequently or
  25.841 +invasively in the underlying repository, however, fixing up rejected
  25.842 +hunks by hand quickly becomes tiresome.
  25.843 +</para>
  25.844 +
  25.845 +<para>It's possible to partially automate the rebasing process.  If your
  25.846 +patches apply cleanly against some revision of the underlying repo, MQ
  25.847 +can use this information to help you to resolve conflicts between your
  25.848 +patches and a different revision.
  25.849 +</para>
  25.850 +
  25.851 +<para>The process is a little involved.
  25.852 +</para>
  25.853 +<orderedlist>
  25.854 +<listitem><para>To begin, <command role="hg-cmd">hg qpush -a</command> all of your patches on top of
  25.855 +  the revision where you know that they apply cleanly.
  25.856 +</para>
  25.857 +</listitem>
  25.858 +<listitem><para>Save a backup copy of your patch directory using
  25.859 +  <command role="hg-cmd">hg qsave <option role="hg-ext-mq-cmd-qsave-opt">-e</option> <option role="hg-ext-mq-cmd-qsave-opt">-c</option></command>.  This prints
  25.860 +  the name of the directory that it has saved the patches in.  It will
  25.861 +  save the patches to a directory called
  25.862 +  <filename role="special" class="directory">.hg/patches.<emphasis>N</filename></emphasis>, where <literal><emphasis>N</emphasis></literal> is a small
  25.863 +  integer.  It also commits a <quote>save changeset</quote> on top of your
  25.864 +  applied patches; this is for internal book-keeping, and records the
  25.865 +  states of the <filename role="special">series</filename> and <filename role="special">status</filename> files.
  25.866 +</para>
  25.867 +</listitem>
  25.868 +<listitem><para>Use <command role="hg-cmd">hg pull</command> to bring new changes into the underlying
  25.869 +  repository.  (Don't run <command role="hg-cmd">hg pull -u</command>; see below for why.)
  25.870 +</para>
  25.871 +</listitem>
  25.872 +<listitem><para>Update to the new tip revision, using
  25.873 +  <command role="hg-cmd">hg update <option role="hg-opt-update">-C</option></command> to override the patches you
  25.874 +  have pushed.
  25.875 +</para>
  25.876 +</listitem>
  25.877 +<listitem><para>Merge all patches using \hgcmdargs{qpush}{<option role="hg-ext-mq-cmd-qpush-opt">-m</option>
  25.878 +    <option role="hg-ext-mq-cmd-qpush-opt">-a</option>}.  The <option role="hg-ext-mq-cmd-qpush-opt">-m</option> option to <command role="hg-ext-mq">qpush</command>
  25.879 +  tells MQ to perform a three-way merge if the patch fails to apply.
  25.880 +</para>
  25.881 +</listitem></orderedlist>
  25.882 +
  25.883 +<para>During the <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">-m</option></command>, each patch in the
  25.884 +<filename role="special">series</filename> file is applied normally.  If a patch applies with
  25.885 +fuzz or rejects, MQ looks at the queue you <command role="hg-ext-mq">qsave</command>d, and
  25.886 +performs a three-way merge with the corresponding changeset.  This
  25.887 +merge uses Mercurial's normal merge machinery, so it may pop up a GUI
  25.888 +merge tool to help you to resolve problems.
  25.889 +</para>
  25.890 +
  25.891 +<para>When you finish resolving the effects of a patch, MQ refreshes your
  25.892 +patch based on the result of the merge.
  25.893 +</para>
  25.894 +
  25.895 +<para>At the end of this process, your repository will have one extra head
  25.896 +from the old patch queue, and a copy of the old patch queue will be in
  25.897 +<filename role="special" class="directory">.hg/patches.<emphasis>N</filename></emphasis>. You can remove the extra head using
  25.898 +<command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-a</option> <option role="hg-ext-mq-cmd-qpop-opt">-n</option> patches.<emphasis>N</emphasis></command>
  25.899 +or <command role="hg-cmd">hg strip</command>.  You can delete <filename role="special" class="directory">.hg/patches.<emphasis>N</filename></emphasis> once
  25.900 +you are sure that you no longer need it as a backup.
  25.901 +</para>
  25.902 +
  25.903 +</sect1>
  25.904 +<sect1>
  25.905 +<title>Identifying patches</title>
  25.906 +
  25.907 +<para>MQ commands that work with patches let you refer to a patch either by
  25.908 +using its name or by a number.  By name is obvious enough; pass the
  25.909 +name <filename>foo.patch</filename> to <command role="hg-ext-mq">qpush</command>, for example, and it will
  25.910 +push patches until <filename>foo.patch</filename> is applied.
  25.911 +</para>
  25.912 +
  25.913 +<para>As a shortcut, you can refer to a patch using both a name and a
  25.914 +numeric offset; <literal>foo.patch-2</literal> means <quote>two patches before
  25.915 +<literal>foo.patch</literal></quote>, while <literal>bar.patch+4</literal> means <quote>four patches
  25.916 +after <literal>bar.patch</literal></quote>.
  25.917 +</para>
  25.918 +
  25.919 +<para>Referring to a patch by index isn't much different.  The first patch
  25.920 +printed in the output of <command role="hg-ext-mq">qseries</command> is patch zero (yes, it's one
  25.921 +of those start-at-zero counting systems); the second is patch one; and
  25.922 +so on.
  25.923 +</para>
  25.924 +
  25.925 +<para>MQ also makes it easy to work with patches when you are using normal
  25.926 +Mercurial commands.  Every command that accepts a changeset ID will
  25.927 +also accept the name of an applied patch.  MQ augments the tags
  25.928 +normally in the repository with an eponymous one for each applied
  25.929 +patch.  In addition, the special tags \index{tags!special tag
  25.930 +  names!<literal>qbase</literal>}<literal>qbase</literal> and \index{tags!special tag
  25.931 +  names!<literal>qtip</literal>}<literal>qtip</literal> identify the <quote>bottom-most</quote> and
  25.932 +topmost applied patches, respectively.
  25.933 +</para>
  25.934 +
  25.935 +<para>These additions to Mercurial's normal tagging capabilities make
  25.936 +dealing with patches even more of a breeze.
  25.937 +</para>
  25.938 +<itemizedlist>
  25.939 +<listitem><para>Want to patchbomb a mailing list with your latest series of
  25.940 +  changes?
  25.941 +</para>
  25.942 +</listitem><programlisting>
  25.943 +<listitem><para>    hg email qbase:qtip
  25.944 +</para>
  25.945 +</listitem></programlisting>
  25.946 +<listitem><para>  (Don't know what <quote>patchbombing</quote> is?  See
  25.947 +  section <xref linkend="sec:hgext:patchbomb"/>.)
  25.948 +</para>
  25.949 +</listitem>
  25.950 +<listitem><para>Need to see all of the patches since <literal>foo.patch</literal> that
  25.951 +  have touched files in a subdirectory of your tree?
  25.952 +</para>
  25.953 +</listitem><programlisting>
  25.954 +<listitem><para>    hg log -r foo.patch:qtip <emphasis>subdir</emphasis>
  25.955 +</para>
  25.956 +</listitem></programlisting>
  25.957 +</itemizedlist>
  25.958 +
  25.959 +<para>Because MQ makes the names of patches available to the rest of
  25.960 +Mercurial through its normal internal tag machinery, you don't need to
  25.961 +type in the entire name of a patch when you want to identify it by
  25.962 +name.
  25.963 +</para>
  25.964 +
  25.965 +<informalfigure>
  25.966 +<para>  <!-- &interaction.mq.id.output; -->
  25.967 +  <caption><para>Using MQ's tag features to work with patches</para></caption>
  25.968 +  \label{ex:mq:id}
  25.969 +</para>
  25.970 +</informalfigure>
  25.971 +
  25.972 +<para>Another nice consequence of representing patch names as tags is that
  25.973 +when you run the <command role="hg-cmd">hg log</command> command, it will display a patch's name
  25.974 +as a tag, simply as part of its normal output.  This makes it easy to
  25.975 +visually distinguish applied patches from underlying <quote>normal</quote>
  25.976 +revisions.  Figure <xref linkend="ex:mq:id"/> shows a few normal Mercurial
  25.977 +commands in use with applied patches.
  25.978 +</para>
  25.979 +
  25.980 +</sect1>
  25.981 +<sect1>
  25.982 +<title>Useful things to know about</title>
  25.983 +
  25.984 +<para>There are a number of aspects of MQ usage that don't fit tidily into
  25.985 +sections of their own, but that are good to know.  Here they are, in
  25.986 +one place.
  25.987 +</para>
  25.988 +
  25.989 +<itemizedlist>
  25.990 +<listitem><para>Normally, when you <command role="hg-ext-mq">qpop</command> a patch and <command role="hg-ext-mq">qpush</command> it
  25.991 +  again, the changeset that represents the patch after the pop/push
  25.992 +  will have a <emphasis>different identity</emphasis> than the changeset that
  25.993 +  represented the hash beforehand.  See
  25.994 +  section <xref linkend="sec:mqref:cmd:qpush"/> for information as to why this is.
  25.995 +</para>
  25.996 +</listitem>
  25.997 +<listitem><para>It's not a good idea to <command role="hg-cmd">hg merge</command> changes from another
  25.998 +  branch with a patch changeset, at least if you want to maintain the
  25.999 +  <quote>patchiness</quote> of that changeset and changesets below it on the
 25.1000 +  patch stack.  If you try to do this, it will appear to succeed, but
 25.1001 +  MQ will become confused.
 25.1002 +</para>
 25.1003 +</listitem></itemizedlist>
 25.1004 +
 25.1005 +</sect1>
 25.1006 +<sect1>
 25.1007 +<title>Managing patches in a repository</title>
 25.1008 +<para>\label{sec:mq:repo}
 25.1009 +</para>
 25.1010 +
 25.1011 +<para>Because MQ's <filename role="special" class="directory">.hg/patches</filename> directory resides outside a
 25.1012 +Mercurial repository's working directory, the <quote>underlying</quote> Mercurial
 25.1013 +repository knows nothing about the management or presence of patches.
 25.1014 +</para>
 25.1015 +
 25.1016 +<para>This presents the interesting possibility of managing the contents of
 25.1017 +the patch directory as a Mercurial repository in its own right.  This
 25.1018 +can be a useful way to work.  For example, you can work on a patch for
 25.1019 +a while, <command role="hg-ext-mq">qrefresh</command> it, then <command role="hg-cmd">hg commit</command> the current state of
 25.1020 +the patch.  This lets you <quote>roll back</quote> to that version of the patch
 25.1021 +later on.
 25.1022 +</para>
 25.1023 +
 25.1024 +<para>You can then share different versions of the same patch stack among
 25.1025 +multiple underlying repositories.  I use this when I am developing a
 25.1026 +Linux kernel feature.  I have a pristine copy of my kernel sources for
 25.1027 +each of several CPU architectures, and a cloned repository under each
 25.1028 +that contains the patches I am working on.  When I want to test a
 25.1029 +change on a different architecture, I push my current patches to the
 25.1030 +patch repository associated with that kernel tree, pop and push all of
 25.1031 +my patches, and build and test that kernel.
 25.1032 +</para>
 25.1033 +
 25.1034 +<para>Managing patches in a repository makes it possible for multiple
 25.1035 +developers to work on the same patch series without colliding with
 25.1036 +each other, all on top of an underlying source base that they may or
 25.1037 +may not control.
 25.1038 +</para>
 25.1039 +
 25.1040 +<sect2>
 25.1041 +<title>MQ support for patch repositories</title>
 25.1042 +
 25.1043 +<para>MQ helps you to work with the <filename role="special" class="directory">.hg/patches</filename> directory as a
 25.1044 +repository; when you prepare a repository for working with patches
 25.1045 +using <command role="hg-ext-mq">qinit</command>, you can pass the <option role="hg-ext-mq-cmd-qinit-opt">-c</option> option to
 25.1046 +create the <filename role="special" class="directory">.hg/patches</filename> directory as a Mercurial repository.
 25.1047 +</para>
 25.1048 +
 25.1049 +<note>
 25.1050 +<para>  If you forget to use the <option role="hg-ext-mq-cmd-qinit-opt">-c</option> option, you can simply go
 25.1051 +  into the <filename role="special" class="directory">.hg/patches</filename> directory at any time and run
 25.1052 +  <command role="hg-cmd">hg init</command>.  Don't forget to add an entry for the
 25.1053 +  <filename role="special">status</filename> file to the <filename role="special">.hgignore</filename> file, though
 25.1054 +</para>
 25.1055 +
 25.1056 +<para>  (<command role="hg-cmd">hg qinit <option role="hg-ext-mq-cmd-qinit-opt">-c</option></command> does this for you
 25.1057 +  automatically); you <emphasis>really</emphasis> don't want to manage the
 25.1058 +  <filename role="special">status</filename> file.
 25.1059 +</para>
 25.1060 +</note>
 25.1061 +
 25.1062 +<para>As a convenience, if MQ notices that the <filename class="directory">.hg/patches</filename>
 25.1063 +directory is a repository, it will automatically <command role="hg-cmd">hg add</command> every
 25.1064 +patch that you create and import.
 25.1065 +</para>
 25.1066 +
 25.1067 +<para>MQ provides a shortcut command, <command role="hg-ext-mq">qcommit</command>, that runs
 25.1068 +<command role="hg-cmd">hg commit</command> in the <filename role="special" class="directory">.hg/patches</filename> directory.  This saves
 25.1069 +some bothersome typing.
 25.1070 +</para>
 25.1071 +
 25.1072 +<para>Finally, as a convenience to manage the patch directory, you can
 25.1073 +define the alias <command>mq</command> on Unix systems. For example, on Linux
 25.1074 +systems using the <command>bash</command> shell, you can include the following
 25.1075 +snippet in your <filename role="home">~/.bashrc</filename>.
 25.1076 +</para>
 25.1077 +
 25.1078 +<programlisting>
 25.1079 +<para>  alias mq=`hg -R $(hg root)/.hg/patches'
 25.1080 +</para>
 25.1081 +</programlisting>
 25.1082 +
 25.1083 +<para>You can then issue commands of the form <command>mq pull</command> from
 25.1084 +the main repository.
 25.1085 +</para>
 25.1086 +
 25.1087 +</sect2>
 25.1088 +<sect2>
 25.1089 +<title>A few things to watch out for</title>
 25.1090 +
 25.1091 +<para>MQ's support for working with a repository full of patches is limited
 25.1092 +in a few small respects.
 25.1093 +</para>
 25.1094 +
 25.1095 +<para>MQ cannot automatically detect changes that you make to the patch
 25.1096 +directory.  If you <command role="hg-cmd">hg pull</command>, manually edit, or <command role="hg-cmd">hg update</command>
 25.1097 +changes to patches or the <filename role="special">series</filename> file, you will have to
 25.1098 +<command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-a</option></command> and then
 25.1099 +<command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">-a</option></command> in the underlying repository to
 25.1100 +see those changes show up there.  If you forget to do this, you can
 25.1101 +confuse MQ's idea of which patches are applied.
 25.1102 +</para>
 25.1103 +
 25.1104 +</sect2>
 25.1105 +</sect1>
 25.1106 +<sect1>
 25.1107 +<title>Third party tools for working with patches</title>
 25.1108 +<para>\label{sec:mq:tools}
 25.1109 +</para>
 25.1110 +
 25.1111 +<para>Once you've been working with patches for a while, you'll find
 25.1112 +yourself hungry for tools that will help you to understand and
 25.1113 +manipulate the patches you're dealing with.
 25.1114 +</para>
 25.1115 +
 25.1116 +<para>The <command>diffstat</command> command <citation>web:diffstat</citation> generates a
 25.1117 +histogram of the modifications made to each file in a patch.  It
 25.1118 +provides a good way to <quote>get a sense of</quote> a patch&emdash;which files it
 25.1119 +affects, and how much change it introduces to each file and as a
 25.1120 +whole.  (I find that it's a good idea to use <command>diffstat</command>'s
 25.1121 +<option role="cmd-opt-diffstat">-p</option> option as a matter of course, as otherwise it
 25.1122 +will try to do clever things with prefixes of file names that
 25.1123 +inevitably confuse at least me.)
 25.1124 +</para>
 25.1125 +
 25.1126 +<informalfigure>
 25.1127 +<para>  <!-- &interaction.mq.tools.tools; -->
 25.1128 +  <caption><para>The <command>diffstat</para></caption>, \command{filterdiff</command>, and <command>lsdiff</command> commands}
 25.1129 +  \label{ex:mq:tools}
 25.1130 +</para>
 25.1131 +</informalfigure>
 25.1132 +
 25.1133 +<para>The <literal role="package">patchutils</literal> package <citation>web:patchutils</citation> is invaluable.
 25.1134 +It provides a set of small utilities that follow the <quote>Unix
 25.1135 +philosophy;</quote> each does one useful thing with a patch.  The
 25.1136 +<literal role="package">patchutils</literal> command I use most is <command>filterdiff</command>, which
 25.1137 +extracts subsets from a patch file.  For example, given a patch that
 25.1138 +modifies hundreds of files across dozens of directories, a single
 25.1139 +invocation of <command>filterdiff</command> can generate a smaller patch that
 25.1140 +only touches files whose names match a particular glob pattern.  See
 25.1141 +section <xref linkend="mq-collab:tips:interdiff"/> for another example.
 25.1142 +</para>
 25.1143 +
 25.1144 +</sect1>
 25.1145 +<sect1>
 25.1146 +<title>Good ways to work with patches</title>
 25.1147 +
 25.1148 +<para>Whether you are working on a patch series to submit to a free software
 25.1149 +or open source project, or a series that you intend to treat as a
 25.1150 +sequence of regular changesets when you're done, you can use some
 25.1151 +simple techniques to keep your work well organised.
 25.1152 +</para>
 25.1153 +
 25.1154 +<para>Give your patches descriptive names.  A good name for a patch might be
 25.1155 +<filename>rework-device-alloc.patch</filename>, because it will immediately give
 25.1156 +you a hint what the purpose of the patch is.  Long names shouldn't be
 25.1157 +a problem; you won't be typing the names often, but you <emphasis>will</emphasis> be
 25.1158 +running commands like <command role="hg-ext-mq">qapplied</command> and <command role="hg-ext-mq">qtop</command> over and over.
 25.1159 +Good naming becomes especially important when you have a number of
 25.1160 +patches to work with, or if you are juggling a number of different
 25.1161 +tasks and your patches only get a fraction of your attention.
 25.1162 +</para>
 25.1163 +
 25.1164 +<para>Be aware of what patch you're working on.  Use the <command role="hg-ext-mq">qtop</command>
 25.1165 +command and skim over the text of your patches frequently&emdash;for
 25.1166 +example, using <command role="hg-cmd">hg tip <option role="hg-opt-tip">-p</option></command>)&emdash;to be sure of where
 25.1167 +you stand.  I have several times worked on and <command role="hg-ext-mq">qrefresh</command>ed a
 25.1168 +patch other than the one I intended, and it's often tricky to migrate
 25.1169 +changes into the right patch after making them in the wrong one.
 25.1170 +</para>
 25.1171 +
 25.1172 +<para>For this reason, it is very much worth investing a little time to
 25.1173 +learn how to use some of the third-party tools I described in
 25.1174 +section <xref linkend="sec:mq:tools"/>, particularly <command>diffstat</command> and
 25.1175 +<command>filterdiff</command>.  The former will give you a quick idea of what
 25.1176 +changes your patch is making, while the latter makes it easy to splice
 25.1177 +hunks selectively out of one patch and into another.
 25.1178 +</para>
 25.1179 +
 25.1180 +</sect1>
 25.1181 +<sect1>
 25.1182 +<title>MQ cookbook</title>
 25.1183 +
 25.1184 +<sect2>
 25.1185 +<title>Manage <quote>trivial</quote> patches</title>
 25.1186 +
 25.1187 +<para>Because the overhead of dropping files into a new Mercurial repository
 25.1188 +is so low, it makes a lot of sense to manage patches this way even if
 25.1189 +you simply want to make a few changes to a source tarball that you
 25.1190 +downloaded.
 25.1191 +</para>
 25.1192 +
 25.1193 +<para>Begin by downloading and unpacking the source tarball,
 25.1194 +and turning it into a Mercurial repository.
 25.1195 +<!-- &interaction.mq.tarball.download; -->
 25.1196 +</para>
 25.1197 +
 25.1198 +<para>Continue by creating a patch stack and making your changes.
 25.1199 +<!-- &interaction.mq.tarball.qinit; -->
 25.1200 +</para>
 25.1201 +
 25.1202 +<para>Let's say a few weeks or months pass, and your package author releases
 25.1203 +a new version.  First, bring their changes into the repository.
 25.1204 +<!-- &interaction.mq.tarball.newsource; -->
 25.1205 +The pipeline starting with <command role="hg-cmd">hg locate</command> above deletes all files in
 25.1206 +the working directory, so that <command role="hg-cmd">hg commit</command>'s
 25.1207 +<option role="hg-opt-commit">--addremove</option> option can actually tell which files have
 25.1208 +really been removed in the newer version of the source.
 25.1209 +</para>
 25.1210 +
 25.1211 +<para>Finally, you can apply your patches on top of the new tree.
 25.1212 +<!-- &interaction.mq.tarball.repush; -->
 25.1213 +</para>
 25.1214 +
 25.1215 +</sect2>
 25.1216 +<sect2>
 25.1217 +<title>Combining entire patches</title>
 25.1218 +<para>\label{sec:mq:combine}
 25.1219 +</para>
 25.1220 +
 25.1221 +<para>MQ provides a command, <command role="hg-ext-mq">qfold</command> that lets you combine entire
 25.1222 +patches.  This <quote>folds</quote> the patches you name, in the order you name
 25.1223 +them, into the topmost applied patch, and concatenates their
 25.1224 +descriptions onto the end of its description.  The patches that you
 25.1225 +fold must be unapplied before you fold them.
 25.1226 +</para>
 25.1227 +
 25.1228 +<para>The order in which you fold patches matters.  If your topmost applied
 25.1229 +patch is <literal>foo</literal>, and you <command role="hg-ext-mq">qfold</command> <literal>bar</literal> and
 25.1230 +<literal>quux</literal> into it, you will end up with a patch that has the same
 25.1231 +effect as if you applied first <literal>foo</literal>, then <literal>bar</literal>,
 25.1232 +followed by <literal>quux</literal>.
 25.1233 +</para>
 25.1234 +
 25.1235 +</sect2>
 25.1236 +<sect2>
 25.1237 +<title>Merging part of one patch into another</title>
 25.1238 +
 25.1239 +<para>Merging <emphasis>part</emphasis> of one patch into another is more difficult than
 25.1240 +combining entire patches.
 25.1241 +</para>
 25.1242 +
 25.1243 +<para>If you want to move changes to entire files, you can use
 25.1244 +<command>filterdiff</command>'s <option role="cmd-opt-filterdiff">-i</option> and
 25.1245 +<option role="cmd-opt-filterdiff">-x</option> options to choose the modifications to snip
 25.1246 +out of one patch, concatenating its output onto the end of the patch
 25.1247 +you want to merge into.  You usually won't need to modify the patch
 25.1248 +you've merged the changes from.  Instead, MQ will report some rejected
 25.1249 +hunks when you <command role="hg-ext-mq">qpush</command> it (from the hunks you moved into the
 25.1250 +other patch), and you can simply <command role="hg-ext-mq">qrefresh</command> the patch to drop
 25.1251 +the duplicate hunks.
 25.1252 +</para>
 25.1253 +
 25.1254 +<para>If you have a patch that has multiple hunks modifying a file, and you
 25.1255 +only want to move a few of those hunks, the job becomes more messy,
 25.1256 +but you can still partly automate it.  Use <command>lsdiff -nvv</command> to
 25.1257 +print some metadata about the patch.
 25.1258 +<!-- &interaction.mq.tools.lsdiff; -->
 25.1259 +</para>
 25.1260 +
 25.1261 +<para>This command prints three different kinds of number:
 25.1262 +</para>
 25.1263 +<itemizedlist>
 25.1264 +<listitem><para>(in the first column) a <emphasis>file number</emphasis> to identify each file
 25.1265 +  modified in the patch;
 25.1266 +</para>
 25.1267 +</listitem>
 25.1268 +<listitem><para>(on the next line, indented) the line number within a modified
 25.1269 +  file where a hunk starts; and
 25.1270 +</para>
 25.1271 +</listitem>
 25.1272 +<listitem><para>(on the same line) a <emphasis>hunk number</emphasis> to identify that hunk.
 25.1273 +</para>
 25.1274 +</listitem></itemizedlist>
 25.1275 +
 25.1276 +<para>You'll have to use some visual inspection, and reading of the patch,
 25.1277 +to identify the file and hunk numbers you'll want, but you can then
 25.1278 +pass them to to <command>filterdiff</command>'s <option role="cmd-opt-filterdiff">--files</option>
 25.1279 +and <option role="cmd-opt-filterdiff">--hunks</option> options, to select exactly the file
 25.1280 +and hunk you want to extract.
 25.1281 +</para>
 25.1282 +
 25.1283 +<para>Once you have this hunk, you can concatenate it onto the end of your
 25.1284 +destination patch and continue with the remainder of
 25.1285 +section <xref linkend="sec:mq:combine"/>.
 25.1286 +</para>
 25.1287 +
 25.1288 +</sect2>
 25.1289 +</sect1>
 25.1290 +<sect1>
 25.1291 +<title>Differences between quilt and MQ</title>
 25.1292 +
 25.1293 +<para>If you are already familiar with quilt, MQ provides a similar command
 25.1294 +set.  There are a few differences in the way that it works.
 25.1295 +</para>
 25.1296 +
 25.1297 +<para>You will already have noticed that most quilt commands have MQ
 25.1298 +counterparts that simply begin with a <quote><literal>q</literal></quote>.  The exceptions
 25.1299 +are quilt's <literal>add</literal> and <literal>remove</literal> commands, the
 25.1300 +counterparts for which are the normal Mercurial <command role="hg-cmd">hg add</command> and
 25.1301 +<command role="hg-cmd">hg remove</command> commands.  There is no MQ equivalent of the quilt
 25.1302 +<literal>edit</literal> command.
 25.1303 +</para>
 25.1304 +
 25.1305 +</sect1>
 25.1306 +</chapter>
 25.1307 +
 25.1308 +<!--
 25.1309 +local variables: 
 25.1310 +sgml-parent-document: ("00book.xml" "book" "chapter")
 25.1311 +end:
 25.1312 +-->
 25.1313 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/fr/ch13-mq-collab.xml	Sun Aug 16 04:58:01 2009 +0200
    26.3 @@ -0,0 +1,499 @@
    26.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    26.5 +
    26.6 +<chapter>
    26.7 +<title>Advanced uses of Mercurial Queues</title>
    26.8 +<para>\label{chap:mq-collab}</para>
    26.9 +
   26.10 +<para>While it's easy to pick up straightforward uses of Mercurial Queues,
   26.11 +use of a little discipline and some of MQ's less frequently used
   26.12 +capabilities makes it possible to work in complicated development
   26.13 +environments.</para>
   26.14 +
   26.15 +<para>In this chapter, I will use as an example a technique I have used to
   26.16 +manage the development of an Infiniband device driver for the Linux
   26.17 +kernel.  The driver in question is large (at least as drivers go),
   26.18 +with 25,000 lines of code spread across 35 source files.  It is
   26.19 +maintained by a small team of developers.</para>
   26.20 +
   26.21 +<para>While much of the material in this chapter is specific to Linux, the
   26.22 +same principles apply to any code base for which you're not the
   26.23 +primary owner, and upon which you need to do a lot of development.</para>
   26.24 +
   26.25 +<sect1>
   26.26 +<title>The problem of many targets</title>
   26.27 +
   26.28 +<para>The Linux kernel changes rapidly, and has never been internally
   26.29 +stable; developers frequently make drastic changes between releases.
   26.30 +This means that a version of the driver that works well with a
   26.31 +particular released version of the kernel will not even <emphasis>compile</emphasis>
   26.32 +correctly against, typically, any other version.</para>
   26.33 +
   26.34 +<para>To maintain a driver, we have to keep a number of distinct versions of
   26.35 +Linux in mind.</para>
   26.36 +<itemizedlist>
   26.37 +<listitem><para>One target is the main Linux kernel development tree.
   26.38 +  Maintenance of the code is in this case partly shared by other
   26.39 +  developers in the kernel community, who make <quote>drive-by</quote>
   26.40 +  modifications to the driver as they develop and refine kernel
   26.41 +  subsystems.</para>
   26.42 +</listitem>
   26.43 +<listitem><para>We also maintain a number of <quote>backports</quote> to older versions of
   26.44 +  the Linux kernel, to support the needs of customers who are running
   26.45 +  older Linux distributions that do not incorporate our drivers.  (To
   26.46 +  <emphasis>backport</emphasis> a piece of code is to modify it to work in an older
   26.47 +  version of its target environment than the version it was developed
   26.48 +  for.)</para>
   26.49 +</listitem>
   26.50 +<listitem><para>Finally, we make software releases on a schedule that is
   26.51 +  necessarily not aligned with those used by Linux distributors and
   26.52 +  kernel developers, so that we can deliver new features to customers
   26.53 +  without forcing them to upgrade their entire kernels or
   26.54 +  distributions.
   26.55 +</para>
   26.56 +</listitem></itemizedlist>
   26.57 +
   26.58 +<sect2>
   26.59 +<title>Tempting approaches that don't work well</title>
   26.60 +
   26.61 +<para>There are two <quote>standard</quote> ways to maintain a piece of software that
   26.62 +has to target many different environments.
   26.63 +</para>
   26.64 +
   26.65 +<para>The first is to maintain a number of branches, each intended for a
   26.66 +single target.  The trouble with this approach is that you must
   26.67 +maintain iron discipline in the flow of changes between repositories.
   26.68 +A new feature or bug fix must start life in a <quote>pristine</quote> repository,
   26.69 +then percolate out to every backport repository.  Backport changes are
   26.70 +more limited in the branches they should propagate to; a backport
   26.71 +change that is applied to a branch where it doesn't belong will
   26.72 +probably stop the driver from compiling.
   26.73 +</para>
   26.74 +
   26.75 +<para>The second is to maintain a single source tree filled with conditional
   26.76 +statements that turn chunks of code on or off depending on the
   26.77 +intended target.  Because these <quote>ifdefs</quote> are not allowed in the
   26.78 +Linux kernel tree, a manual or automatic process must be followed to
   26.79 +strip them out and yield a clean tree.  A code base maintained in this
   26.80 +fashion rapidly becomes a rat's nest of conditional blocks that are
   26.81 +difficult to understand and maintain.
   26.82 +</para>
   26.83 +
   26.84 +<para>Neither of these approaches is well suited to a situation where you
   26.85 +don't <quote>own</quote> the canonical copy of a source tree.  In the case of a
   26.86 +Linux driver that is distributed with the standard kernel, Linus's
   26.87 +tree contains the copy of the code that will be treated by the world
   26.88 +as canonical.  The upstream version of <quote>my</quote> driver can be modified
   26.89 +by people I don't know, without me even finding out about it until
   26.90 +after the changes show up in Linus's tree.
   26.91 +</para>
   26.92 +
   26.93 +<para>These approaches have the added weakness of making it difficult to
   26.94 +generate well-formed patches to submit upstream.
   26.95 +</para>
   26.96 +
   26.97 +<para>In principle, Mercurial Queues seems like a good candidate to manage a
   26.98 +development scenario such as the above.  While this is indeed the
   26.99 +case, MQ contains a few added features that make the job more
  26.100 +pleasant.
  26.101 +</para>
  26.102 +
  26.103 +<para>\section{Conditionally applying patches with
  26.104 +  guards}
  26.105 +</para>
  26.106 +
  26.107 +<para>Perhaps the best way to maintain sanity with so many targets is to be
  26.108 +able to choose specific patches to apply for a given situation.  MQ
  26.109 +provides a feature called <quote>guards</quote> (which originates with quilt's
  26.110 +<literal>guards</literal> command) that does just this.  To start off, let's
  26.111 +create a simple repository for experimenting in.
  26.112 +<!-- &interaction.mq.guards.init; -->
  26.113 +This gives us a tiny repository that contains two patches that don't
  26.114 +have any dependencies on each other, because they touch different files.
  26.115 +</para>
  26.116 +
  26.117 +<para>The idea behind conditional application is that you can <quote>tag</quote> a
  26.118 +patch with a <emphasis>guard</emphasis>, which is simply a text string of your
  26.119 +choosing, then tell MQ to select specific guards to use when applying
  26.120 +patches.  MQ will then either apply, or skip over, a guarded patch,
  26.121 +depending on the guards that you have selected.
  26.122 +</para>
  26.123 +
  26.124 +<para>A patch can have an arbitrary number of guards;
  26.125 +each one is <emphasis>positive</emphasis> (<quote>apply this patch if this guard is
  26.126 +selected</quote>) or <emphasis>negative</emphasis> (<quote>skip this patch if this guard is
  26.127 +selected</quote>).  A patch with no guards is always applied.
  26.128 +</para>
  26.129 +
  26.130 +</sect2>
  26.131 +</sect1>
  26.132 +<sect1>
  26.133 +<title>Controlling the guards on a patch</title>
  26.134 +
  26.135 +<para>The <command role="hg-ext-mq">qguard</command> command lets you determine which guards should
  26.136 +apply to a patch, or display the guards that are already in effect.
  26.137 +Without any arguments, it displays the guards on the current topmost
  26.138 +patch.
  26.139 +<!-- &interaction.mq.guards.qguard; -->
  26.140 +To set a positive guard on a patch, prefix the name of the guard with
  26.141 +a <quote><literal>+</literal></quote>.
  26.142 +<!-- &interaction.mq.guards.qguard.pos; -->
  26.143 +To set a negative guard on a patch, prefix the name of the guard with
  26.144 +a <quote><literal>-</literal></quote>.
  26.145 +<!-- &interaction.mq.guards.qguard.neg; -->
  26.146 +</para>
  26.147 +
  26.148 +<note>
  26.149 +<para>  The <command role="hg-ext-mq">qguard</command> command <emphasis>sets</emphasis> the guards on a patch; it
  26.150 +  doesn't <emphasis>modify</emphasis> them.  What this means is that if you run
  26.151 +  <command role="hg-cmd">hg qguard +a +b</command> on a patch, then <command role="hg-cmd">hg qguard +c</command> on
  26.152 +  the same patch, the <emphasis>only</emphasis> guard that will be set on it
  26.153 +  afterwards is <literal>+c</literal>.
  26.154 +</para>
  26.155 +</note>
  26.156 +
  26.157 +<para>Mercurial stores guards in the <filename role="special">series</filename> file; the form in
  26.158 +which they are stored is easy both to understand and to edit by hand.
  26.159 +(In other words, you don't have to use the <command role="hg-ext-mq">qguard</command> command if
  26.160 +you don't want to; it's okay to simply edit the <filename role="special">series</filename>
  26.161 +file.)
  26.162 +<!-- &interaction.mq.guards.series; -->
  26.163 +</para>
  26.164 +
  26.165 +</sect1>
  26.166 +<sect1>
  26.167 +<title>Selecting the guards to use</title>
  26.168 +
  26.169 +<para>The <command role="hg-ext-mq">qselect</command> command determines which guards are active at a
  26.170 +given time.  The effect of this is to determine which patches MQ will
  26.171 +apply the next time you run <command role="hg-ext-mq">qpush</command>.  It has no other effect; in
  26.172 +particular, it doesn't do anything to patches that are already
  26.173 +applied.
  26.174 +</para>
  26.175 +
  26.176 +<para>With no arguments, the <command role="hg-ext-mq">qselect</command> command lists the guards
  26.177 +currently in effect, one per line of output.  Each argument is treated
  26.178 +as the name of a guard to apply.
  26.179 +<!-- &interaction.mq.guards.qselect.foo; -->
  26.180 +In case you're interested, the currently selected guards are stored in
  26.181 +the <filename role="special">guards</filename> file.
  26.182 +<!-- &interaction.mq.guards.qselect.cat; -->
  26.183 +We can see the effect the selected guards have when we run
  26.184 +<command role="hg-ext-mq">qpush</command>.
  26.185 +<!-- &interaction.mq.guards.qselect.qpush; -->
  26.186 +</para>
  26.187 +
  26.188 +<para>A guard cannot start with a <quote><literal>+</literal></quote> or <quote><literal>-</literal></quote>
  26.189 +character.  The name of a guard must not contain white space, but most
  26.190 +other characters are acceptable.  If you try to use a guard with an
  26.191 +invalid name, MQ will complain:
  26.192 +<!-- &interaction.mq.guards.qselect.error; -->
  26.193 +Changing the selected guards changes the patches that are applied.
  26.194 +<!-- &interaction.mq.guards.qselect.quux; -->
  26.195 +You can see in the example below that negative guards take precedence
  26.196 +over positive guards.
  26.197 +<!-- &interaction.mq.guards.qselect.foobar; -->
  26.198 +</para>
  26.199 +
  26.200 +</sect1>
  26.201 +<sect1>
  26.202 +<title>MQ's rules for applying patches</title>
  26.203 +
  26.204 +<para>The rules that MQ uses when deciding whether to apply a patch
  26.205 +are as follows.
  26.206 +</para>
  26.207 +<itemizedlist>
  26.208 +<listitem><para>A patch that has no guards is always applied.
  26.209 +</para>
  26.210 +</listitem>
  26.211 +<listitem><para>If the patch has any negative guard that matches any currently
  26.212 +  selected guard, the patch is skipped.
  26.213 +</para>
  26.214 +</listitem>
  26.215 +<listitem><para>If the patch has any positive guard that matches any currently
  26.216 +  selected guard, the patch is applied.
  26.217 +</para>
  26.218 +</listitem>
  26.219 +<listitem><para>If the patch has positive or negative guards, but none matches
  26.220 +  any currently selected guard, the patch is skipped.
  26.221 +</para>
  26.222 +</listitem></itemizedlist>
  26.223 +
  26.224 +</sect1>
  26.225 +<sect1>
  26.226 +<title>Trimming the work environment</title>
  26.227 +
  26.228 +<para>In working on the device driver I mentioned earlier, I don't apply the
  26.229 +patches to a normal Linux kernel tree.  Instead, I use a repository
  26.230 +that contains only a snapshot of the source files and headers that are
  26.231 +relevant to Infiniband development.  This repository is 1% the size
  26.232 +of a kernel repository, so it's easier to work with.
  26.233 +</para>
  26.234 +
  26.235 +<para>I then choose a <quote>base</quote> version on top of which the patches are
  26.236 +applied.  This is a snapshot of the Linux kernel tree as of a revision
  26.237 +of my choosing.  When I take the snapshot, I record the changeset ID
  26.238 +from the kernel repository in the commit message.  Since the snapshot
  26.239 +preserves the <quote>shape</quote> and content of the relevant parts of the
  26.240 +kernel tree, I can apply my patches on top of either my tiny
  26.241 +repository or a normal kernel tree.
  26.242 +</para>
  26.243 +
  26.244 +<para>Normally, the base tree atop which the patches apply should be a
  26.245 +snapshot of a very recent upstream tree.  This best facilitates the
  26.246 +development of patches that can easily be submitted upstream with few
  26.247 +or no modifications.
  26.248 +</para>
  26.249 +
  26.250 +</sect1>
  26.251 +<sect1>
  26.252 +<title>Dividing up the <filename role="special">series</filename> file</title>
  26.253 +
  26.254 +<para>I categorise the patches in the <filename role="special">series</filename> file into a number
  26.255 +of logical groups.  Each section of like patches begins with a block
  26.256 +of comments that describes the purpose of the patches that follow.
  26.257 +</para>
  26.258 +
  26.259 +<para>The sequence of patch groups that I maintain follows.  The ordering of
  26.260 +these groups is important; I'll describe why after I introduce the
  26.261 +groups.
  26.262 +</para>
  26.263 +<itemizedlist>
  26.264 +<listitem><para>The <quote>accepted</quote> group.  Patches that the development team has
  26.265 +  submitted to the maintainer of the Infiniband subsystem, and which
  26.266 +  he has accepted, but which are not present in the snapshot that the
  26.267 +  tiny repository is based on.  These are <quote>read only</quote> patches,
  26.268 +  present only to transform the tree into a similar state as it is in
  26.269 +  the upstream maintainer's repository.
  26.270 +</para>
  26.271 +</listitem>
  26.272 +<listitem><para>The <quote>rework</quote> group.  Patches that I have submitted, but that
  26.273 +  the upstream maintainer has requested modifications to before he
  26.274 +  will accept them.
  26.275 +</para>
  26.276 +</listitem>
  26.277 +<listitem><para>The <quote>pending</quote> group.  Patches that I have not yet submitted to
  26.278 +  the upstream maintainer, but which we have finished working on.
  26.279 +  These will be <quote>read only</quote> for a while.  If the upstream maintainer
  26.280 +  accepts them upon submission, I'll move them to the end of the
  26.281 +  <quote>accepted</quote> group.  If he requests that I modify any, I'll move
  26.282 +  them to the beginning of the <quote>rework</quote> group.
  26.283 +</para>
  26.284 +</listitem>
  26.285 +<listitem><para>The <quote>in progress</quote> group.  Patches that are actively being
  26.286 +  developed, and should not be submitted anywhere yet.
  26.287 +</para>
  26.288 +</listitem>
  26.289 +<listitem><para>The <quote>backport</quote> group.  Patches that adapt the source tree to
  26.290 +  older versions of the kernel tree.
  26.291 +</para>
  26.292 +</listitem>
  26.293 +<listitem><para>The <quote>do not ship</quote> group.  Patches that for some reason should
  26.294 +  never be submitted upstream.  For example, one such patch might
  26.295 +  change embedded driver identification strings to make it easier to
  26.296 +  distinguish, in the field, between an out-of-tree version of the
  26.297 +  driver and a version shipped by a distribution vendor.
  26.298 +</para>
  26.299 +</listitem></itemizedlist>
  26.300 +
  26.301 +<para>Now to return to the reasons for ordering groups of patches in this
  26.302 +way.  We would like the lowest patches in the stack to be as stable as
  26.303 +possible, so that we will not need to rework higher patches due to
  26.304 +changes in context.  Putting patches that will never be changed first
  26.305 +in the <filename role="special">series</filename> file serves this purpose.
  26.306 +</para>
  26.307 +
  26.308 +<para>We would also like the patches that we know we'll need to modify to be
  26.309 +applied on top of a source tree that resembles the upstream tree as
  26.310 +closely as possible.  This is why we keep accepted patches around for
  26.311 +a while.
  26.312 +</para>
  26.313 +
  26.314 +<para>The <quote>backport</quote> and <quote>do not ship</quote> patches float at the end of the
  26.315 +<filename role="special">series</filename> file.  The backport patches must be applied on top
  26.316 +of all other patches, and the <quote>do not ship</quote> patches might as well
  26.317 +stay out of harm's way.
  26.318 +</para>
  26.319 +
  26.320 +</sect1>
  26.321 +<sect1>
  26.322 +<title>Maintaining the patch series</title>
  26.323 +
  26.324 +<para>In my work, I use a number of guards to control which patches are to
  26.325 +be applied.
  26.326 +</para>
  26.327 +
  26.328 +<itemizedlist>
  26.329 +<listitem><para><quote>Accepted</quote> patches are guarded with <literal>accepted</literal>.  I
  26.330 +  enable this guard most of the time.  When I'm applying the patches
  26.331 +  on top of a tree where the patches are already present, I can turn
  26.332 +  this patch off, and the patches that follow it will apply cleanly.
  26.333 +</para>
  26.334 +</listitem>
  26.335 +<listitem><para>Patches that are <quote>finished</quote>, but not yet submitted, have no
  26.336 +  guards.  If I'm applying the patch stack to a copy of the upstream
  26.337 +  tree, I don't need to enable any guards in order to get a reasonably
  26.338 +  safe source tree.
  26.339 +</para>
  26.340 +</listitem>
  26.341 +<listitem><para>Those patches that need reworking before being resubmitted are
  26.342 +  guarded with <literal>rework</literal>.
  26.343 +</para>
  26.344 +</listitem>
  26.345 +<listitem><para>For those patches that are still under development, I use
  26.346 +  <literal>devel</literal>.
  26.347 +</para>
  26.348 +</listitem>
  26.349 +<listitem><para>A backport patch may have several guards, one for each version
  26.350 +  of the kernel to which it applies.  For example, a patch that
  26.351 +  backports a piece of code to 2.6.9 will have a <literal>2.6.9</literal> guard.
  26.352 +</para>
  26.353 +</listitem></itemizedlist>
  26.354 +<para>This variety of guards gives me considerable flexibility in
  26.355 +determining what kind of source tree I want to end up with.  For most
  26.356 +situations, the selection of appropriate guards is automated during
  26.357 +the build process, but I can manually tune the guards to use for less
  26.358 +common circumstances.
  26.359 +</para>
  26.360 +
  26.361 +<sect2>
  26.362 +<title>The art of writing backport patches</title>
  26.363 +
  26.364 +<para>Using MQ, writing a backport patch is a simple process.  All such a
  26.365 +patch has to do is modify a piece of code that uses a kernel feature
  26.366 +not present in the older version of the kernel, so that the driver
  26.367 +continues to work correctly under that older version.
  26.368 +</para>
  26.369 +
  26.370 +<para>A useful goal when writing a good backport patch is to make your code
  26.371 +look as if it was written for the older version of the kernel you're
  26.372 +targeting.  The less obtrusive the patch, the easier it will be to
  26.373 +understand and maintain.  If you're writing a collection of backport
  26.374 +patches to avoid the <quote>rat's nest</quote> effect of lots of
  26.375 +<literal>#ifdef</literal>s (hunks of source code that are only used
  26.376 +conditionally) in your code, don't introduce version-dependent
  26.377 +<literal>#ifdef</literal>s into the patches.  Instead, write several patches,
  26.378 +each of which makes unconditional changes, and control their
  26.379 +application using guards.
  26.380 +</para>
  26.381 +
  26.382 +<para>There are two reasons to divide backport patches into a distinct
  26.383 +group, away from the <quote>regular</quote> patches whose effects they modify.
  26.384 +The first is that intermingling the two makes it more difficult to use
  26.385 +a tool like the <literal role="hg-ext">patchbomb</literal> extension to automate the process of
  26.386 +submitting the patches to an upstream maintainer.  The second is that
  26.387 +a backport patch could perturb the context in which a subsequent
  26.388 +regular patch is applied, making it impossible to apply the regular
  26.389 +patch cleanly <emphasis>without</emphasis> the earlier backport patch already being
  26.390 +applied.
  26.391 +</para>
  26.392 +
  26.393 +</sect2>
  26.394 +</sect1>
  26.395 +<sect1>
  26.396 +<title>Useful tips for developing with MQ</title>
  26.397 +
  26.398 +<sect2>
  26.399 +<title>Organising patches in directories</title>
  26.400 +
  26.401 +<para>If you're working on a substantial project with MQ, it's not difficult
  26.402 +to accumulate a large number of patches.  For example, I have one
  26.403 +patch repository that contains over 250 patches.
  26.404 +</para>
  26.405 +
  26.406 +<para>If you can group these patches into separate logical categories, you
  26.407 +can if you like store them in different directories; MQ has no
  26.408 +problems with patch names that contain path separators.
  26.409 +</para>
  26.410 +
  26.411 +</sect2>
  26.412 +<sect2>
  26.413 +<title>Viewing the history of a patch</title>
  26.414 +<para>\label{mq-collab:tips:interdiff}
  26.415 +</para>
  26.416 +
  26.417 +<para>If you're developing a set of patches over a long time, it's a good
  26.418 +idea to maintain them in a repository, as discussed in
  26.419 +section <xref linkend="sec:mq:repo"/>.  If you do so, you'll quickly discover that
  26.420 +using the <command role="hg-cmd">hg diff</command> command to look at the history of changes to a
  26.421 +patch is unworkable.  This is in part because you're looking at the
  26.422 +second derivative of the real code (a diff of a diff), but also
  26.423 +because MQ adds noise to the process by modifying time stamps and
  26.424 +directory names when it updates a patch.
  26.425 +</para>
  26.426 +
  26.427 +<para>However, you can use the <literal role="hg-ext">extdiff</literal> extension, which is bundled
  26.428 +with Mercurial, to turn a diff of two versions of a patch into
  26.429 +something readable.  To do this, you will need a third-party package
  26.430 +called <literal role="package">patchutils</literal> <citation>web:patchutils</citation>.  This provides a
  26.431 +command named <command>interdiff</command>, which shows the differences between
  26.432 +two diffs as a diff.  Used on two versions of the same diff, it
  26.433 +generates a diff that represents the diff from the first to the second
  26.434 +version.
  26.435 +</para>
  26.436 +
  26.437 +<para>You can enable the <literal role="hg-ext">extdiff</literal> extension in the usual way, by
  26.438 +adding a line to the <literal role="rc-extensions">extensions</literal> section of your <filename role="special"> /.hgrc</filename>.
  26.439 +</para>
  26.440 +<programlisting>
  26.441 +<para>  [extensions]
  26.442 +  extdiff =
  26.443 +</para>
  26.444 +</programlisting>
  26.445 +<para>The <command>interdiff</command> command expects to be passed the names of two
  26.446 +files, but the <literal role="hg-ext">extdiff</literal> extension passes the program it runs a
  26.447 +pair of directories, each of which can contain an arbitrary number of
  26.448 +files.  We thus need a small program that will run <command>interdiff</command>
  26.449 +on each pair of files in these two directories.  This program is
  26.450 +available as <filename role="special">hg-interdiff</filename> in the <filename class="directory">examples</filename>
  26.451 +directory of the source code repository that accompanies this book.
  26.452 +<!-- &example.hg-interdiff; -->
  26.453 +</para>
  26.454 +
  26.455 +<para>With the <filename role="special">hg-interdiff</filename> program in your shell's search path,
  26.456 +you can run it as follows, from inside an MQ patch directory:
  26.457 +</para>
  26.458 +<programlisting>
  26.459 +<para>  hg extdiff -p hg-interdiff -r A:B my-change.patch
  26.460 +</para>
  26.461 +</programlisting>
  26.462 +<para>Since you'll probably want to use this long-winded command a lot, you
  26.463 +can get <literal role="hg-ext">hgext</literal> to make it available as a normal Mercurial
  26.464 +command, again by editing your <filename role="special"> /.hgrc</filename>.
  26.465 +</para>
  26.466 +<programlisting>
  26.467 +<para>  [extdiff]
  26.468 +  cmd.interdiff = hg-interdiff
  26.469 +</para>
  26.470 +</programlisting>
  26.471 +<para>This directs <literal role="hg-ext">hgext</literal> to make an <literal>interdiff</literal> command
  26.472 +available, so you can now shorten the previous invocation of
  26.473 +<command role="hg-ext-extdiff">extdiff</command> to something a little more wieldy.
  26.474 +</para>
  26.475 +<programlisting>
  26.476 +<para>  hg interdiff -r A:B my-change.patch
  26.477 +</para>
  26.478 +</programlisting>
  26.479 +
  26.480 +<note>
  26.481 +<para>  The <command>interdiff</command> command works well only if the underlying
  26.482 +  files against which versions of a patch are generated remain the
  26.483 +  same.  If you create a patch, modify the underlying files, and then
  26.484 +  regenerate the patch, <command>interdiff</command> may not produce useful
  26.485 +  output.
  26.486 +</para>
  26.487 +</note>
  26.488 +
  26.489 +<para>The <literal role="hg-ext">extdiff</literal> extension is useful for more than merely improving
  26.490 +the presentation of MQ patches.  To read more about it, go to
  26.491 +section <xref linkend="sec:hgext:extdiff"/>.
  26.492 +</para>
  26.493 +
  26.494 +</sect2>
  26.495 +</sect1>
  26.496 +</chapter>
  26.497 +
  26.498 +<!--
  26.499 +local variables: 
  26.500 +sgml-parent-document: ("00book.xml" "book" "chapter")
  26.501 +end:
  26.502 +-->
  26.503 \ No newline at end of file
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/fr/ch14-hgext.xml	Sun Aug 16 04:58:01 2009 +0200
    27.3 @@ -0,0 +1,539 @@
    27.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    27.5 +
    27.6 +<chapter>
    27.7 +<title>Adding functionality with extensions</title>
    27.8 +<para>\label{chap:hgext}</para>
    27.9 +
   27.10 +<para>While the core of Mercurial is quite complete from a functionality
   27.11 +standpoint, it's deliberately shorn of fancy features.  This approach
   27.12 +of preserving simplicity keeps the software easy to deal with for both
   27.13 +maintainers and users.</para>
   27.14 +
   27.15 +<para>However, Mercurial doesn't box you in with an inflexible command set:
   27.16 +you can add features to it as <emphasis>extensions</emphasis> (sometimes known as
   27.17 +<emphasis>plugins</emphasis>).  We've already discussed a few of these extensions in
   27.18 +earlier chapters.</para>
   27.19 +<itemizedlist>
   27.20 +<listitem><para>Section <xref linkend="sec:tour-merge:fetch"/> covers the <literal role="hg-ext">fetch</literal>
   27.21 +  extension; this combines pulling new changes and merging them with
   27.22 +  local changes into a single command, <command role="hg-ext-fetch">fetch</command>.</para>
   27.23 +</listitem>
   27.24 +<listitem><para>In chapter <xref linkend="chap:hook"/>, we covered several extensions that
   27.25 +  are useful for hook-related functionality: <literal role="hg-ext">acl</literal> adds access
   27.26 +  control lists; <literal role="hg-ext">bugzilla</literal> adds integration with the Bugzilla
   27.27 +  bug tracking system; and <literal role="hg-ext">notify</literal> sends notification emails on
   27.28 +  new changes.</para>
   27.29 +</listitem>
   27.30 +<listitem><para>The Mercurial Queues patch management extension is so invaluable
   27.31 +  that it merits two chapters and an appendix all to itself.
   27.32 +  Chapter <xref linkend="chap:mq"/> covers the basics;
   27.33 +  chapter <xref linkend="chap:mq-collab"/> discusses advanced topics; and
   27.34 +  appendix <xref linkend="chap:mqref"/> goes into detail on each command.</para>
   27.35 +</listitem></itemizedlist>
   27.36 +
   27.37 +<para>In this chapter, we'll cover some of the other extensions that are
   27.38 +available for Mercurial, and briefly touch on some of the machinery
   27.39 +you'll need to know about if you want to write an extension of your
   27.40 +own.</para>
   27.41 +<itemizedlist>
   27.42 +<listitem><para>In section <xref linkend="sec:hgext:inotify"/>, we'll discuss the
   27.43 +  possibility of <emphasis>huge</emphasis> performance improvements using the
   27.44 +  <literal role="hg-ext">inotify</literal> extension.</para>
   27.45 +</listitem></itemizedlist>
   27.46 +
   27.47 +<sect1>
   27.48 +<title>Improve performance with the <literal role="hg-ext">inotify</literal> extension</title>
   27.49 +<para>\label{sec:hgext:inotify}
   27.50 +</para>
   27.51 +
   27.52 +<para>Are you interested in having some of the most common Mercurial
   27.53 +operations run as much as a hundred times faster?  Read on!
   27.54 +</para>
   27.55 +
   27.56 +<para>Mercurial has great performance under normal circumstances.  For
   27.57 +example, when you run the <command role="hg-cmd">hg status</command> command, Mercurial has to
   27.58 +scan almost every directory and file in your repository so that it can
   27.59 +display file status.  Many other Mercurial commands need to do the
   27.60 +same work behind the scenes; for example, the <command role="hg-cmd">hg diff</command> command
   27.61 +uses the status machinery to avoid doing an expensive comparison
   27.62 +operation on files that obviously haven't changed.
   27.63 +</para>
   27.64 +
   27.65 +<para>Because obtaining file status is crucial to good performance, the
   27.66 +authors of Mercurial have optimised this code to within an inch of its
   27.67 +life.  However, there's no avoiding the fact that when you run
   27.68 +<command role="hg-cmd">hg status</command>, Mercurial is going to have to perform at least one
   27.69 +expensive system call for each managed file to determine whether it's
   27.70 +changed since the last time Mercurial checked.  For a sufficiently
   27.71 +large repository, this can take a long time.
   27.72 +</para>
   27.73 +
   27.74 +<para>To put a number on the magnitude of this effect, I created a
   27.75 +repository containing 150,000 managed files.  I timed <command role="hg-cmd">hg status</command>
   27.76 +as taking ten seconds to run, even when <emphasis>none</emphasis> of those files had
   27.77 +been modified.
   27.78 +</para>
   27.79 +
   27.80 +<para>Many modern operating systems contain a file notification facility.
   27.81 +If a program signs up to an appropriate service, the operating system
   27.82 +will notify it every time a file of interest is created, modified, or
   27.83 +deleted.  On Linux systems, the kernel component that does this is
   27.84 +called <literal>inotify</literal>.
   27.85 +</para>
   27.86 +
   27.87 +<para>Mercurial's <literal role="hg-ext">inotify</literal> extension talks to the kernel's
   27.88 +<literal>inotify</literal> component to optimise <command role="hg-cmd">hg status</command> commands.  The
   27.89 +extension has two components.  A daemon sits in the background and
   27.90 +receives notifications from the <literal>inotify</literal> subsystem.  It also
   27.91 +listens for connections from a regular Mercurial command.  The
   27.92 +extension modifies Mercurial's behaviour so that instead of scanning
   27.93 +the filesystem, it queries the daemon.  Since the daemon has perfect
   27.94 +information about the state of the repository, it can respond with a
   27.95 +result instantaneously, avoiding the need to scan every directory and
   27.96 +file in the repository.
   27.97 +</para>
   27.98 +
   27.99 +<para>Recall the ten seconds that I measured plain Mercurial as taking to
  27.100 +run <command role="hg-cmd">hg status</command> on a 150,000 file repository.  With the
  27.101 +<literal role="hg-ext">inotify</literal> extension enabled, the time dropped to 0.1 seconds, a
  27.102 +factor of <emphasis>one hundred</emphasis> faster.
  27.103 +</para>
  27.104 +
  27.105 +<para>Before we continue, please pay attention to some caveats.
  27.106 +</para>
  27.107 +<itemizedlist>
  27.108 +<listitem><para>The <literal role="hg-ext">inotify</literal> extension is Linux-specific.  Because it
  27.109 +  interfaces directly to the Linux kernel's <literal>inotify</literal>
  27.110 +  subsystem, it does not work on other operating systems.
  27.111 +</para>
  27.112 +</listitem>
  27.113 +<listitem><para>It should work on any Linux distribution that was released after
  27.114 +  early 2005.  Older distributions are likely to have a kernel that
  27.115 +  lacks <literal>inotify</literal>, or a version of <literal>glibc</literal> that does not
  27.116 +  have the necessary interfacing support.
  27.117 +</para>
  27.118 +</listitem>
  27.119 +<listitem><para>Not all filesystems are suitable for use with the
  27.120 +  <literal role="hg-ext">inotify</literal> extension.  Network filesystems such as NFS are a
  27.121 +  non-starter, for example, particularly if you're running Mercurial
  27.122 +  on several systems, all mounting the same network filesystem.  The
  27.123 +  kernel's <literal>inotify</literal> system has no way of knowing about changes
  27.124 +  made on another system.  Most local filesystems (e.g. ext3, XFS,
  27.125 +  ReiserFS) should work fine.
  27.126 +</para>
  27.127 +</listitem></itemizedlist>
  27.128 +
  27.129 +<para>The <literal role="hg-ext">inotify</literal> extension is not yet shipped with Mercurial as of
  27.130 +May 2007, so it's a little more involved to set up than other
  27.131 +extensions.  But the performance improvement is worth it!
  27.132 +</para>
  27.133 +
  27.134 +<para>The extension currently comes in two parts: a set of patches to the
  27.135 +Mercurial source code, and a library of Python bindings to the
  27.136 +<literal>inotify</literal> subsystem.
  27.137 +</para>
  27.138 +<note>
  27.139 +<para>  There are <emphasis>two</emphasis> Python <literal>inotify</literal> binding libraries.  One
  27.140 +  of them is called <literal>pyinotify</literal>, and is packaged by some Linux
  27.141 +  distributions as <literal>python-inotify</literal>.  This is <emphasis>not</emphasis> the
  27.142 +  one you'll need, as it is too buggy and inefficient to be practical.
  27.143 +</para>
  27.144 +</note>
  27.145 +<para>To get going, it's best to already have a functioning copy of
  27.146 +Mercurial installed.
  27.147 +</para>
  27.148 +<note>
  27.149 +<para>  If you follow the instructions below, you'll be <emphasis>replacing</emphasis> and
  27.150 +  overwriting any existing installation of Mercurial that you might
  27.151 +  already have, using the latest <quote>bleeding edge</quote> Mercurial code.
  27.152 +  Don't say you weren't warned!
  27.153 +</para>
  27.154 +</note>
  27.155 +<orderedlist>
  27.156 +<listitem><para>Clone the Python <literal>inotify</literal> binding repository.  Build and
  27.157 +  install it.
  27.158 +</para>
  27.159 +</listitem><programlisting>
  27.160 +<listitem><para>    hg clone http://hg.kublai.com/python/inotify
  27.161 +    cd inotify
  27.162 +    python setup.py build --force
  27.163 +    sudo python setup.py install --skip-build
  27.164 +</para>
  27.165 +</listitem></programlisting>
  27.166 +</para>
  27.167 +</listitem>
  27.168 +<listitem><para>Clone the <filename class="directory">crew</filename> Mercurial repository.  Clone the
  27.169 +  <literal role="hg-ext">inotify</literal> patch repository so that Mercurial Queues will be
  27.170 +  able to apply patches to your cope of the <filename class="directory">crew</filename> repository.
  27.171 +</para>
  27.172 +</listitem><programlisting>
  27.173 +<listitem><para>    hg clone http://hg.intevation.org/mercurial/crew
  27.174 +    hg clone crew inotify
  27.175 +    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
  27.176 +</para>
  27.177 +</listitem></programlisting>
  27.178 +</para>
  27.179 +</listitem>
  27.180 +<listitem><para>Make sure that you have the Mercurial Queues extension,
  27.181 +  <literal role="hg-ext">mq</literal>, enabled.  If you've never used MQ, read
  27.182 +  section <xref linkend="sec:mq:start"/> to get started quickly.
  27.183 +</para>
  27.184 +</listitem>
  27.185 +<listitem><para>Go into the <filename class="directory">inotify</filename> repo, and apply all of the
  27.186 +  <literal role="hg-ext">inotify</literal> patches using the <option role="hg-ext-mq-cmd-qpush-opt">-a</option> option to
  27.187 +  the <command role="hg-ext-mq">qpush</command> command.
  27.188 +</para>
  27.189 +</listitem><programlisting>
  27.190 +<listitem><para>    cd inotify
  27.191 +    hg qpush -a
  27.192 +</para>
  27.193 +</listitem></programlisting>
  27.194 +<listitem><para>  If you get an error message from <command role="hg-ext-mq">qpush</command>, you should not
  27.195 +  continue.  Instead, ask for help.
  27.196 +</para>
  27.197 +</listitem>
  27.198 +<listitem><para>Build and install the patched version of Mercurial.
  27.199 +</para>
  27.200 +</listitem><programlisting>
  27.201 +<listitem><para>    python setup.py build --force
  27.202 +    sudo python setup.py install --skip-build
  27.203 +</para>
  27.204 +</listitem></programlisting>
  27.205 +</orderedlist>
  27.206 +<para>Once you've build a suitably patched version of Mercurial, all you
  27.207 +need to do to enable the <literal role="hg-ext">inotify</literal> extension is add an entry to
  27.208 +your <filename role="special"> /.hgrc</filename>.
  27.209 +</para>
  27.210 +<programlisting>
  27.211 +<para>  [extensions]
  27.212 +  inotify =
  27.213 +</para>
  27.214 +</programlisting>
  27.215 +<para>When the <literal role="hg-ext">inotify</literal> extension is enabled, Mercurial will
  27.216 +automatically and transparently start the status daemon the first time
  27.217 +you run a command that needs status in a repository.  It runs one
  27.218 +status daemon per repository.
  27.219 +</para>
  27.220 +
  27.221 +<para>The status daemon is started silently, and runs in the background.  If
  27.222 +you look at a list of running processes after you've enabled the
  27.223 +<literal role="hg-ext">inotify</literal> extension and run a few commands in different
  27.224 +repositories, you'll thus see a few <literal>hg</literal> processes sitting
  27.225 +around, waiting for updates from the kernel and queries from
  27.226 +Mercurial.
  27.227 +</para>
  27.228 +
  27.229 +<para>The first time you run a Mercurial command in a repository when you
  27.230 +have the <literal role="hg-ext">inotify</literal> extension enabled, it will run with about the
  27.231 +same performance as a normal Mercurial command.  This is because the
  27.232 +status daemon needs to perform a normal status scan so that it has a
  27.233 +baseline against which to apply later updates from the kernel.
  27.234 +However, <emphasis>every</emphasis> subsequent command that does any kind of status
  27.235 +check should be noticeably faster on repositories of even fairly
  27.236 +modest size.  Better yet, the bigger your repository is, the greater a
  27.237 +performance advantage you'll see.  The <literal role="hg-ext">inotify</literal> daemon makes
  27.238 +status operations almost instantaneous on repositories of all sizes!
  27.239 +</para>
  27.240 +
  27.241 +<para>If you like, you can manually start a status daemon using the
  27.242 +<command role="hg-ext-inotify">inserve</command> command.  This gives you slightly finer
  27.243 +control over how the daemon ought to run.  This command will of course
  27.244 +only be available when the <literal role="hg-ext">inotify</literal> extension is enabled.
  27.245 +</para>
  27.246 +
  27.247 +<para>When you're using the <literal role="hg-ext">inotify</literal> extension, you should notice
  27.248 +<emphasis>no difference at all</emphasis> in Mercurial's behaviour, with the sole
  27.249 +exception of status-related commands running a whole lot faster than
  27.250 +they used to.  You should specifically expect that commands will not
  27.251 +print different output; neither should they give different results.
  27.252 +If either of these situations occurs, please report a bug.
  27.253 +</para>
  27.254 +
  27.255 +</sect1>
  27.256 +<sect1>
  27.257 +<title>Flexible diff support with the <literal role="hg-ext">extdiff</literal> extension</title>
  27.258 +<para>\label{sec:hgext:extdiff}
  27.259 +</para>
  27.260 +
  27.261 +<para>Mercurial's built-in <command role="hg-cmd">hg diff</command> command outputs plaintext unified
  27.262 +diffs.
  27.263 +<!-- &interaction.extdiff.diff; -->
  27.264 +If you would like to use an external tool to display modifications,
  27.265 +you'll want to use the <literal role="hg-ext">extdiff</literal> extension.  This will let you
  27.266 +use, for example, a graphical diff tool.
  27.267 +</para>
  27.268 +
  27.269 +<para>The <literal role="hg-ext">extdiff</literal> extension is bundled with Mercurial, so it's easy
  27.270 +to set up.  In the <literal role="rc-extensions">extensions</literal> section of your <filename role="special"> /.hgrc</filename>,
  27.271 +simply add a one-line entry to enable the extension.
  27.272 +</para>
  27.273 +<programlisting>
  27.274 +<para>  [extensions]
  27.275 +  extdiff =
  27.276 +</para>
  27.277 +</programlisting>
  27.278 +<para>This introduces a command named <command role="hg-ext-extdiff">extdiff</command>, which by
  27.279 +default uses your system's <command>diff</command> command to generate a
  27.280 +unified diff in the same form as the built-in <command role="hg-cmd">hg diff</command> command.
  27.281 +<!-- &interaction.extdiff.extdiff; -->
  27.282 +The result won't be exactly the same as with the built-in <command role="hg-cmd">hg diff</command>
  27.283 +variations, because the output of <command>diff</command> varies from one
  27.284 +system to another, even when passed the same options.
  27.285 +</para>
  27.286 +
  27.287 +<para>As the <quote><literal>making snapshot</literal></quote> lines of output above imply, the
  27.288 +<command role="hg-ext-extdiff">extdiff</command> command works by creating two snapshots of
  27.289 +your source tree.  The first snapshot is of the source revision; the
  27.290 +second, of the target revision or working directory.  The
  27.291 +<command role="hg-ext-extdiff">extdiff</command> command generates these snapshots in a
  27.292 +temporary directory, passes the name of each directory to an external
  27.293 +diff viewer, then deletes the temporary directory.  For efficiency, it
  27.294 +only snapshots the directories and files that have changed between the
  27.295 +two revisions.
  27.296 +</para>
  27.297 +
  27.298 +<para>Snapshot directory names have the same base name as your repository.
  27.299 +If your repository path is <filename class="directory">/quux/bar/foo</filename>, then <filename class="directory">foo</filename>
  27.300 +will be the name of each snapshot directory.  Each snapshot directory
  27.301 +name has its changeset ID appended, if appropriate.  If a snapshot is
  27.302 +of revision <literal>a631aca1083f</literal>, the directory will be named
  27.303 +<filename class="directory">foo.a631aca1083f</filename>.  A snapshot of the working directory won't
  27.304 +have a changeset ID appended, so it would just be <filename class="directory">foo</filename> in
  27.305 +this example.  To see what this looks like in practice, look again at
  27.306 +the <command role="hg-ext-extdiff">extdiff</command> example above.  Notice that the diff has
  27.307 +the snapshot directory names embedded in its header.
  27.308 +</para>
  27.309 +
  27.310 +<para>The <command role="hg-ext-extdiff">extdiff</command> command accepts two important options.
  27.311 +The <option role="hg-ext-extdiff-cmd-extdiff-opt">-p</option> option lets you choose a program to
  27.312 +view differences with, instead of <command>diff</command>.  With the
  27.313 +<option role="hg-ext-extdiff-cmd-extdiff-opt">-o</option> option, you can change the options that
  27.314 +<command role="hg-ext-extdiff">extdiff</command> passes to the program (by default, these
  27.315 +options are <quote><literal>-Npru</literal></quote>, which only make sense if you're
  27.316 +running <command>diff</command>).  In other respects, the
  27.317 +<command role="hg-ext-extdiff">extdiff</command> command acts similarly to the built-in
  27.318 +<command role="hg-cmd">hg diff</command> command: you use the same option names, syntax, and
  27.319 +arguments to specify the revisions you want, the files you want, and
  27.320 +so on.
  27.321 +</para>
  27.322 +
  27.323 +<para>As an example, here's how to run the normal system <command>diff</command>
  27.324 +command, getting it to generate context diffs (using the
  27.325 +<option role="cmd-opt-diff">-c</option> option) instead of unified diffs, and five lines of
  27.326 +context instead of the default three (passing <literal>5</literal> as the
  27.327 +argument to the <option role="cmd-opt-diff">-C</option> option).
  27.328 +<!-- &interaction.extdiff.extdiff-ctx; -->
  27.329 +</para>
  27.330 +
  27.331 +<para>Launching a visual diff tool is just as easy.  Here's how to launch
  27.332 +the <command>kdiff3</command> viewer.
  27.333 +</para>
  27.334 +<programlisting>
  27.335 +<para>  hg extdiff -p kdiff3 -o </quote>
  27.336 +</para>
  27.337 +</programlisting>
  27.338 +
  27.339 +<para>If your diff viewing command can't deal with directories, you can
  27.340 +easily work around this with a little scripting.  For an example of
  27.341 +such scripting in action with the <literal role="hg-ext">mq</literal> extension and the
  27.342 +<command>interdiff</command> command, see
  27.343 +section <xref linkend="mq-collab:tips:interdiff"/>.
  27.344 +</para>
  27.345 +
  27.346 +<sect2>
  27.347 +<title>Defining command aliases</title>
  27.348 +
  27.349 +<para>It can be cumbersome to remember the options to both the
  27.350 +<command role="hg-ext-extdiff">extdiff</command> command and the diff viewer you want to use,
  27.351 +so the <literal role="hg-ext">extdiff</literal> extension lets you define <emphasis>new</emphasis> commands
  27.352 +that will invoke your diff viewer with exactly the right options.
  27.353 +</para>
  27.354 +
  27.355 +<para>All you need to do is edit your <filename role="special"> /.hgrc</filename>, and add a section named
  27.356 +<literal role="rc-extdiff">extdiff</literal>.  Inside this section, you can define multiple
  27.357 +commands.  Here's how to add a <literal>kdiff3</literal> command.  Once you've
  27.358 +defined this, you can type <quote><literal>hg kdiff3</literal></quote> and the
  27.359 +<literal role="hg-ext">extdiff</literal> extension will run <command>kdiff3</command> for you.
  27.360 +</para>
  27.361 +<programlisting>
  27.362 +<para>  [extdiff]
  27.363 +  cmd.kdiff3 =
  27.364 +</para>
  27.365 +</programlisting>
  27.366 +<para>If you leave the right hand side of the definition empty, as above,
  27.367 +the <literal role="hg-ext">extdiff</literal> extension uses the name of the command you defined
  27.368 +as the name of the external program to run.  But these names don't
  27.369 +have to be the same.  Here, we define a command named <quote>\texttt{hg
  27.370 +  wibble}</quote>, which runs <command>kdiff3</command>.
  27.371 +</para>
  27.372 +<programlisting>
  27.373 +<para>  [extdiff]
  27.374 +  cmd.wibble = kdiff3
  27.375 +</para>
  27.376 +</programlisting>
  27.377 +
  27.378 +<para>You can also specify the default options that you want to invoke your
  27.379 +diff viewing program with.  The prefix to use is <quote><literal>opts.</literal></quote>,
  27.380 +followed by the name of the command to which the options apply.  This
  27.381 +example defines a <quote><literal>hg vimdiff</literal></quote> command that runs the
  27.382 +<command>vim</command> editor's <literal>DirDiff</literal> extension.
  27.383 +</para>
  27.384 +<programlisting>
  27.385 +<para>  [extdiff]
  27.386 +  cmd.vimdiff = vim
  27.387 +  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
  27.388 +</para>
  27.389 +</programlisting>
  27.390 +
  27.391 +</sect2>
  27.392 +</sect1>
  27.393 +<sect1>
  27.394 +<title>Cherrypicking changes with the <literal role="hg-ext">transplant</literal> extension</title>
  27.395 +<para>\label{sec:hgext:transplant}
  27.396 +</para>
  27.397 +
  27.398 +<para>Need to have a long chat with Brendan about this.
  27.399 +</para>
  27.400 +
  27.401 +</sect1>
  27.402 +<sect1>
  27.403 +<title>Send changes via email with the <literal role="hg-ext">patchbomb</literal> extension</title>
  27.404 +<para>\label{sec:hgext:patchbomb}
  27.405 +</para>
  27.406 +
  27.407 +<para>Many projects have a culture of <quote>change review</quote>, in which people
  27.408 +send their modifications to a mailing list for others to read and
  27.409 +comment on before they commit the final version to a shared
  27.410 +repository.  Some projects have people who act as gatekeepers; they
  27.411 +apply changes from other people to a repository to which those others
  27.412 +don't have access.
  27.413 +</para>
  27.414 +
  27.415 +<para>Mercurial makes it easy to send changes over email for review or
  27.416 +application, via its <literal role="hg-ext">patchbomb</literal> extension.  The extension is so
  27.417 +namd because changes are formatted as patches, and it's usual to send
  27.418 +one changeset per email message.  Sending a long series of changes by
  27.419 +email is thus much like <quote>bombing</quote> the recipient's inbox, hence
  27.420 +<quote>patchbomb</quote>.
  27.421 +</para>
  27.422 +
  27.423 +<para>As usual, the basic configuration of the <literal role="hg-ext">patchbomb</literal> extension
  27.424 +takes just one or two lines in your <filename role="special"> /.hgrc</filename>.
  27.425 +</para>
  27.426 +<programlisting>
  27.427 +<para>  [extensions]
  27.428 +  patchbomb =
  27.429 +</para>
  27.430 +</programlisting>
  27.431 +<para>Once you've enabled the extension, you will have a new command
  27.432 +available, named <command role="hg-ext-patchbomb">email</command>.
  27.433 +</para>
  27.434 +
  27.435 +<para>The safest and best way to invoke the <command role="hg-ext-patchbomb">email</command>
  27.436 +command is to <emphasis>always</emphasis> run it first with the
  27.437 +<option role="hg-ext-patchbomb-cmd-email-opt">-n</option> option.  This will show you what the
  27.438 +command <emphasis>would</emphasis> send, without actually sending anything.  Once
  27.439 +you've had a quick glance over the changes and verified that you are
  27.440 +sending the right ones, you can rerun the same command, with the
  27.441 +<option role="hg-ext-patchbomb-cmd-email-opt">-n</option> option removed.
  27.442 +</para>
  27.443 +
  27.444 +<para>The <command role="hg-ext-patchbomb">email</command> command accepts the same kind of
  27.445 +revision syntax as every other Mercurial command.  For example, this
  27.446 +command will send every revision between 7 and <literal>tip</literal>,
  27.447 +inclusive.
  27.448 +</para>
  27.449 +<programlisting>
  27.450 +<para>  hg email -n 7:tip
  27.451 +</para>
  27.452 +</programlisting>
  27.453 +<para>You can also specify a <emphasis>repository</emphasis> to compare with.  If you
  27.454 +provide a repository but no revisions, the <command role="hg-ext-patchbomb">email</command>
  27.455 +command will send all revisions in the local repository that are not
  27.456 +present in the remote repository.  If you additionally specify
  27.457 +revisions or a branch name (the latter using the
  27.458 +<option role="hg-ext-patchbomb-cmd-email-opt">-b</option> option), this will constrain the
  27.459 +revisions sent.
  27.460 +</para>
  27.461 +
  27.462 +<para>It's perfectly safe to run the <command role="hg-ext-patchbomb">email</command> command
  27.463 +without the names of the people you want to send to: if you do this,
  27.464 +it will just prompt you for those values interactively.  (If you're
  27.465 +using a Linux or Unix-like system, you should have enhanced
  27.466 +<literal>readline</literal>-style editing capabilities when entering those
  27.467 +headers, too, which is useful.)
  27.468 +</para>
  27.469 +
  27.470 +<para>When you are sending just one revision, the <command role="hg-ext-patchbomb">email</command>
  27.471 +command will by default use the first line of the changeset
  27.472 +description as the subject of the single email message it sends.
  27.473 +</para>
  27.474 +
  27.475 +<para>If you send multiple revisions, the <command role="hg-ext-patchbomb">email</command> command
  27.476 +will usually send one message per changeset.  It will preface the
  27.477 +series with an introductory message, in which you should describe the
  27.478 +purpose of the series of changes you're sending.
  27.479 +</para>
  27.480 +
  27.481 +<sect2>
  27.482 +<title>Changing the behaviour of patchbombs</title>
  27.483 +
  27.484 +<para>Not every project has exactly the same conventions for sending changes
  27.485 +in email; the <literal role="hg-ext">patchbomb</literal> extension tries to accommodate a
  27.486 +number of variations through command line options.
  27.487 +</para>
  27.488 +<itemizedlist>
  27.489 +<listitem><para>You can write a subject for the introductory message on the
  27.490 +  command line using the <option role="hg-ext-patchbomb-cmd-email-opt">-s</option> option.  This
  27.491 +  takes one argument, the text of the subject to use.
  27.492 +</para>
  27.493 +</listitem>
  27.494 +<listitem><para>To change the email address from which the messages originate,
  27.495 +  use the <option role="hg-ext-patchbomb-cmd-email-opt">-f</option> option.  This takes one
  27.496 +  argument, the email address to use.
  27.497 +</para>
  27.498 +</listitem>
  27.499 +<listitem><para>The default behaviour is to send unified diffs (see
  27.500 +  section <xref linkend="sec:mq:patch"/> for a description of the format), one per
  27.501 +  message.  You can send a binary bundle instead with the
  27.502 +  <option role="hg-ext-patchbomb-cmd-email-opt">-b</option> option.
  27.503 +</para>
  27.504 +</listitem>
  27.505 +<listitem><para>Unified diffs are normally prefaced with a metadata header.  You
  27.506 +  can omit this, and send unadorned diffs, with the
  27.507 +  <option role="hg-ext-patchbomb-cmd-email-opt">--plain</option> option.
  27.508 +</para>
  27.509 +</listitem>
  27.510 +<listitem><para>Diffs are normally sent <quote>inline</quote>, in the same body part as the
  27.511 +  description of a patch.  This makes it easiest for the largest
  27.512 +  number of readers to quote and respond to parts of a diff, as some
  27.513 +  mail clients will only quote the first MIME body part in a message.
  27.514 +  If you'd prefer to send the description and the diff in separate
  27.515 +  body parts, use the <option role="hg-ext-patchbomb-cmd-email-opt">-a</option> option.
  27.516 +</para>
  27.517 +</listitem>
  27.518 +<listitem><para>Instead of sending mail messages, you can write them to an
  27.519 +  <literal>mbox</literal>-format mail folder using the
  27.520 +  <option role="hg-ext-patchbomb-cmd-email-opt">-m</option> option.  That option takes one
  27.521 +  argument, the name of the file to write to.
  27.522 +</para>
  27.523 +</listitem>
  27.524 +<listitem><para>If you would like to add a <command>diffstat</command>-format summary to
  27.525 +  each patch, and one to the introductory message, use the
  27.526 +  <option role="hg-ext-patchbomb-cmd-email-opt">-d</option> option.  The <command>diffstat</command>
  27.527 +  command displays a table containing the name of each file patched,
  27.528 +  the number of lines affected, and a histogram showing how much each
  27.529 +  file is modified.  This gives readers a qualitative glance at how
  27.530 +  complex a patch is.
  27.531 +</para>
  27.532 +</listitem></itemizedlist>
  27.533 +
  27.534 +</sect2>
  27.535 +</sect1>
  27.536 +</chapter>
  27.537 +
  27.538 +<!--
  27.539 +local variables: 
  27.540 +sgml-parent-document: ("00book.xml" "book" "chapter")
  27.541 +end:
  27.542 +-->
  27.543 \ No newline at end of file
    28.1 --- a/fr/cmdref.tex	Sun Aug 16 03:41:39 2009 +0200
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,176 +0,0 @@
    28.4 -\chapter{Command reference}
    28.5 -\label{cmdref}
    28.6 -
    28.7 -\cmdref{add}{add files at the next commit}
    28.8 -\optref{add}{I}{include}
    28.9 -\optref{add}{X}{exclude}
   28.10 -\optref{add}{n}{dry-run}
   28.11 -
   28.12 -\cmdref{diff}{print changes in history or working directory}
   28.13 -
   28.14 -Show differences between revisions for the specified files or
   28.15 -directories, using the unified diff format.  For a description of the
   28.16 -unified diff format, see section~\ref{sec:mq:patch}.
   28.17 -
   28.18 -By default, this command does not print diffs for files that Mercurial
   28.19 -considers to contain binary data.  To control this behaviour, see the
   28.20 -\hgopt{diff}{-a} and \hgopt{diff}{--git} options.
   28.21 -
   28.22 -\subsection{Options}
   28.23 -
   28.24 -\loptref{diff}{nodates}
   28.25 -
   28.26 -Omit date and time information when printing diff headers.
   28.27 -
   28.28 -\optref{diff}{B}{ignore-blank-lines}
   28.29 -
   28.30 -Do not print changes that only insert or delete blank lines.  A line
   28.31 -that contains only whitespace is not considered blank.
   28.32 -
   28.33 -\optref{diff}{I}{include}
   28.34 -
   28.35 -Include files and directories whose names match the given patterns.
   28.36 -
   28.37 -\optref{diff}{X}{exclude}
   28.38 -
   28.39 -Exclude files and directories whose names match the given patterns.
   28.40 -
   28.41 -\optref{diff}{a}{text}
   28.42 -
   28.43 -If this option is not specified, \hgcmd{diff} will refuse to print
   28.44 -diffs for files that it detects as binary. Specifying \hgopt{diff}{-a}
   28.45 -forces \hgcmd{diff} to treat all files as text, and generate diffs for
   28.46 -all of them.
   28.47 -
   28.48 -This option is useful for files that are ``mostly text'' but have a
   28.49 -few embedded NUL characters.  If you use it on files that contain a
   28.50 -lot of binary data, its output will be incomprehensible.
   28.51 -
   28.52 -\optref{diff}{b}{ignore-space-change}
   28.53 -
   28.54 -Do not print a line if the only change to that line is in the amount
   28.55 -of white space it contains.
   28.56 -
   28.57 -\optref{diff}{g}{git}
   28.58 -
   28.59 -Print \command{git}-compatible diffs.  XXX reference a format
   28.60 -description.
   28.61 -
   28.62 -\optref{diff}{p}{show-function}
   28.63 -
   28.64 -Display the name of the enclosing function in a hunk header, using a
   28.65 -simple heuristic.  This functionality is enabled by default, so the
   28.66 -\hgopt{diff}{-p} option has no effect unless you change the value of
   28.67 -the \rcitem{diff}{showfunc} config item, as in the following example.
   28.68 -\interaction{cmdref.diff-p}
   28.69 -
   28.70 -\optref{diff}{r}{rev}
   28.71 -
   28.72 -Specify one or more revisions to compare.  The \hgcmd{diff} command
   28.73 -accepts up to two \hgopt{diff}{-r} options to specify the revisions to
   28.74 -compare.
   28.75 -
   28.76 -\begin{enumerate}
   28.77 -\setcounter{enumi}{0}
   28.78 -\item Display the differences between the parent revision of the
   28.79 -  working directory and the working directory.
   28.80 -\item Display the differences between the specified changeset and the
   28.81 -  working directory.
   28.82 -\item Display the differences between the two specified changesets.
   28.83 -\end{enumerate}
   28.84 -
   28.85 -You can specify two revisions using either two \hgopt{diff}{-r}
   28.86 -options or revision range notation.  For example, the two revision
   28.87 -specifications below are equivalent.
   28.88 -\begin{codesample2}
   28.89 -  hg diff -r 10 -r 20
   28.90 -  hg diff -r10:20
   28.91 -\end{codesample2}
   28.92 -
   28.93 -When you provide two revisions, Mercurial treats the order of those
   28.94 -revisions as significant.  Thus, \hgcmdargs{diff}{-r10:20} will
   28.95 -produce a diff that will transform files from their contents as of
   28.96 -revision~10 to their contents as of revision~20, while
   28.97 -\hgcmdargs{diff}{-r20:10} means the opposite: the diff that will
   28.98 -transform files from their revision~20 contents to their revision~10
   28.99 -contents.  You cannot reverse the ordering in this way if you are
  28.100 -diffing against the working directory.
  28.101 -
  28.102 -\optref{diff}{w}{ignore-all-space}
  28.103 -
  28.104 -\cmdref{version}{print version and copyright information}
  28.105 -
  28.106 -This command displays the version of Mercurial you are running, and
  28.107 -its copyright license.  There are four kinds of version string that
  28.108 -you may see.
  28.109 -\begin{itemize}
  28.110 -\item The string ``\texttt{unknown}''. This version of Mercurial was
  28.111 -  not built in a Mercurial repository, and cannot determine its own
  28.112 -  version.
  28.113 -\item A short numeric string, such as ``\texttt{1.1}''. This is a
  28.114 -  build of a revision of Mercurial that was identified by a specific
  28.115 -  tag in the repository where it was built.  (This doesn't necessarily
  28.116 -  mean that you're running an official release; someone else could
  28.117 -  have added that tag to any revision in the repository where they
  28.118 -  built Mercurial.)
  28.119 -\item A hexadecimal string, such as ``\texttt{875489e31abe}''.  This
  28.120 -  is a build of the given revision of Mercurial.
  28.121 -\item A hexadecimal string followed by a date, such as
  28.122 -  ``\texttt{875489e31abe+20070205}''.  This is a build of the given
  28.123 -  revision of Mercurial, where the build repository contained some
  28.124 -  local changes that had not been committed.
  28.125 -\end{itemize}
  28.126 -
  28.127 -\subsection{Tips and tricks}
  28.128 -
  28.129 -\subsubsection{Why do the results of \hgcmd{diff} and \hgcmd{status}
  28.130 -  differ?}
  28.131 -\label{cmdref:diff-vs-status}
  28.132 -
  28.133 -When you run the \hgcmd{status} command, you'll see a list of files
  28.134 -that Mercurial will record changes for the next time you perform a
  28.135 -commit.  If you run the \hgcmd{diff} command, you may notice that it
  28.136 -prints diffs for only a \emph{subset} of the files that \hgcmd{status}
  28.137 -listed.  There are two possible reasons for this.
  28.138 -
  28.139 -The first is that \hgcmd{status} prints some kinds of modifications
  28.140 -that \hgcmd{diff} doesn't normally display.  The \hgcmd{diff} command
  28.141 -normally outputs unified diffs, which don't have the ability to
  28.142 -represent some changes that Mercurial can track.  Most notably,
  28.143 -traditional diffs can't represent a change in whether or not a file is
  28.144 -executable, but Mercurial records this information.
  28.145 -
  28.146 -If you use the \hgopt{diff}{--git} option to \hgcmd{diff}, it will
  28.147 -display \command{git}-compatible diffs that \emph{can} display this
  28.148 -extra information.
  28.149 -
  28.150 -The second possible reason that \hgcmd{diff} might be printing diffs
  28.151 -for a subset of the files displayed by \hgcmd{status} is that if you
  28.152 -invoke it without any arguments, \hgcmd{diff} prints diffs against the
  28.153 -first parent of the working directory.  If you have run \hgcmd{merge}
  28.154 -to merge two changesets, but you haven't yet committed the results of
  28.155 -the merge, your working directory has two parents (use \hgcmd{parents}
  28.156 -to see them).  While \hgcmd{status} prints modifications relative to
  28.157 -\emph{both} parents after an uncommitted merge, \hgcmd{diff} still
  28.158 -operates relative only to the first parent.  You can get it to print
  28.159 -diffs relative to the second parent by specifying that parent with the
  28.160 -\hgopt{diff}{-r} option.  There is no way to print diffs relative to
  28.161 -both parents.
  28.162 -
  28.163 -\subsubsection{Generating safe binary diffs}
  28.164 -
  28.165 -If you use the \hgopt{diff}{-a} option to force Mercurial to print
  28.166 -diffs of files that are either ``mostly text'' or contain lots of
  28.167 -binary data, those diffs cannot subsequently be applied by either
  28.168 -Mercurial's \hgcmd{import} command or the system's \command{patch}
  28.169 -command.  
  28.170 -
  28.171 -If you want to generate a diff of a binary file that is safe to use as
  28.172 -input for \hgcmd{import}, use the \hgcmd{diff}{--git} option when you
  28.173 -generate the patch.  The system \command{patch} command cannot handle
  28.174 -binary patches at all.
  28.175 -
  28.176 -%%% Local Variables: 
  28.177 -%%% mode: latex
  28.178 -%%% TeX-master: "00book"
  28.179 -%%% End: 
    29.1 --- a/fr/collab.tex	Sun Aug 16 03:41:39 2009 +0200
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,1118 +0,0 @@
    29.4 -\chapter{Collaborating with other people}
    29.5 -\label{cha:collab}
    29.6 -
    29.7 -As a completely decentralised tool, Mercurial doesn't impose any
    29.8 -policy on how people ought to work with each other.  However, if
    29.9 -you're new to distributed revision control, it helps to have some
   29.10 -tools and examples in mind when you're thinking about possible
   29.11 -workflow models.
   29.12 -
   29.13 -\section{Mercurial's web interface}
   29.14 -
   29.15 -Mercurial has a powerful web interface that provides several 
   29.16 -useful capabilities.
   29.17 -
   29.18 -For interactive use, the web interface lets you browse a single
   29.19 -repository or a collection of repositories.  You can view the history
   29.20 -of a repository, examine each change (comments and diffs), and view
   29.21 -the contents of each directory and file.
   29.22 -
   29.23 -Also for human consumption, the web interface provides an RSS feed of
   29.24 -the changes in a repository.  This lets you ``subscribe'' to a
   29.25 -repository using your favourite feed reader, and be automatically
   29.26 -notified of activity in that repository as soon as it happens.  I find
   29.27 -this capability much more convenient than the model of subscribing to
   29.28 -a mailing list to which notifications are sent, as it requires no
   29.29 -additional configuration on the part of whoever is serving the
   29.30 -repository.
   29.31 -
   29.32 -The web interface also lets remote users clone a repository, pull
   29.33 -changes from it, and (when the server is configured to permit it) push
   29.34 -changes back to it.  Mercurial's HTTP tunneling protocol aggressively
   29.35 -compresses data, so that it works efficiently even over low-bandwidth
   29.36 -network connections.
   29.37 -
   29.38 -The easiest way to get started with the web interface is to use your
   29.39 -web browser to visit an existing repository, such as the master
   29.40 -Mercurial repository at
   29.41 -\url{http://www.selenic.com/repo/hg?style=gitweb}.
   29.42 -
   29.43 -If you're interested in providing a web interface to your own
   29.44 -repositories, Mercurial provides two ways to do this.  The first is
   29.45 -using the \hgcmd{serve} command, which is best suited to short-term
   29.46 -``lightweight'' serving.  See section~\ref{sec:collab:serve} below for
   29.47 -details of how to use this command.  If you have a long-lived
   29.48 -repository that you'd like to make permanently available, Mercurial
   29.49 -has built-in support for the CGI (Common Gateway Interface) standard,
   29.50 -which all common web servers support.  See
   29.51 -section~\ref{sec:collab:cgi} for details of CGI configuration.
   29.52 -
   29.53 -\section{Collaboration models}
   29.54 -
   29.55 -With a suitably flexible tool, making decisions about workflow is much
   29.56 -more of a social engineering challenge than a technical one.
   29.57 -Mercurial imposes few limitations on how you can structure the flow of
   29.58 -work in a project, so it's up to you and your group to set up and live
   29.59 -with a model that matches your own particular needs.
   29.60 -
   29.61 -\subsection{Factors to keep in mind}
   29.62 -
   29.63 -The most important aspect of any model that you must keep in mind is
   29.64 -how well it matches the needs and capabilities of the people who will
   29.65 -be using it.  This might seem self-evident; even so, you still can't
   29.66 -afford to forget it for a moment.
   29.67 -
   29.68 -I once put together a workflow model that seemed to make perfect sense
   29.69 -to me, but that caused a considerable amount of consternation and
   29.70 -strife within my development team.  In spite of my attempts to explain
   29.71 -why we needed a complex set of branches, and how changes ought to flow
   29.72 -between them, a few team members revolted.  Even though they were
   29.73 -smart people, they didn't want to pay attention to the constraints we
   29.74 -were operating under, or face the consequences of those constraints in
   29.75 -the details of the model that I was advocating.
   29.76 -
   29.77 -Don't sweep foreseeable social or technical problems under the rug.
   29.78 -Whatever scheme you put into effect, you should plan for mistakes and
   29.79 -problem scenarios.  Consider adding automated machinery to prevent, or
   29.80 -quickly recover from, trouble that you can anticipate.  As an example,
   29.81 -if you intend to have a branch with not-for-release changes in it,
   29.82 -you'd do well to think early about the possibility that someone might
   29.83 -accidentally merge those changes into a release branch.  You could
   29.84 -avoid this particular problem by writing a hook that prevents changes
   29.85 -from being merged from an inappropriate branch.
   29.86 -
   29.87 -\subsection{Informal anarchy}
   29.88 -
   29.89 -I wouldn't suggest an ``anything goes'' approach as something
   29.90 -sustainable, but it's a model that's easy to grasp, and it works
   29.91 -perfectly well in a few unusual situations.
   29.92 -
   29.93 -As one example, many projects have a loose-knit group of collaborators
   29.94 -who rarely physically meet each other.  Some groups like to overcome
   29.95 -the isolation of working at a distance by organising occasional
   29.96 -``sprints''.  In a sprint, a number of people get together in a single
   29.97 -location (a company's conference room, a hotel meeting room, that kind
   29.98 -of place) and spend several days more or less locked in there, hacking
   29.99 -intensely on a handful of projects.
  29.100 -
  29.101 -A sprint is the perfect place to use the \hgcmd{serve} command, since
  29.102 -\hgcmd{serve} does not requires any fancy server infrastructure.  You
  29.103 -can get started with \hgcmd{serve} in moments, by reading
  29.104 -section~\ref{sec:collab:serve} below.  Then simply tell the person
  29.105 -next to you that you're running a server, send the URL to them in an
  29.106 -instant message, and you immediately have a quick-turnaround way to
  29.107 -work together.  They can type your URL into their web browser and
  29.108 -quickly review your changes; or they can pull a bugfix from you and
  29.109 -verify it; or they can clone a branch containing a new feature and try
  29.110 -it out.
  29.111 -
  29.112 -The charm, and the problem, with doing things in an ad hoc fashion
  29.113 -like this is that only people who know about your changes, and where
  29.114 -they are, can see them.  Such an informal approach simply doesn't
  29.115 -scale beyond a handful people, because each individual needs to know
  29.116 -about $n$ different repositories to pull from.
  29.117 -
  29.118 -\subsection{A single central repository}
  29.119 -
  29.120 -For smaller projects migrating from a centralised revision control
  29.121 -tool, perhaps the easiest way to get started is to have changes flow
  29.122 -through a single shared central repository.  This is also the
  29.123 -most common ``building block'' for more ambitious workflow schemes.
  29.124 -
  29.125 -Contributors start by cloning a copy of this repository.  They can
  29.126 -pull changes from it whenever they need to, and some (perhaps all)
  29.127 -developers have permission to push a change back when they're ready
  29.128 -for other people to see it.
  29.129 -
  29.130 -Under this model, it can still often make sense for people to pull
  29.131 -changes directly from each other, without going through the central
  29.132 -repository.  Consider a case in which I have a tentative bug fix, but
  29.133 -I am worried that if I were to publish it to the central repository,
  29.134 -it might subsequently break everyone else's trees as they pull it.  To
  29.135 -reduce the potential for damage, I can ask you to clone my repository
  29.136 -into a temporary repository of your own and test it.  This lets us put
  29.137 -off publishing the potentially unsafe change until it has had a little
  29.138 -testing.
  29.139 -
  29.140 -In this kind of scenario, people usually use the \command{ssh}
  29.141 -protocol to securely push changes to the central repository, as
  29.142 -documented in section~\ref{sec:collab:ssh}.  It's also usual to
  29.143 -publish a read-only copy of the repository over HTTP using CGI, as in
  29.144 -section~\ref{sec:collab:cgi}.  Publishing over HTTP satisfies the
  29.145 -needs of people who don't have push access, and those who want to use
  29.146 -web browsers to browse the repository's history.
  29.147 -
  29.148 -\subsection{Working with multiple branches}
  29.149 -
  29.150 -Projects of any significant size naturally tend to make progress on
  29.151 -several fronts simultaneously.  In the case of software, it's common
  29.152 -for a project to go through periodic official releases.  A release
  29.153 -might then go into ``maintenance mode'' for a while after its first
  29.154 -publication; maintenance releases tend to contain only bug fixes, not
  29.155 -new features.  In parallel with these maintenance releases, one or
  29.156 -more future releases may be under development.  People normally use
  29.157 -the word ``branch'' to refer to one of these many slightly different
  29.158 -directions in which development is proceeding.
  29.159 -
  29.160 -Mercurial is particularly well suited to managing a number of
  29.161 -simultaneous, but not identical, branches.  Each ``development
  29.162 -direction'' can live in its own central repository, and you can merge
  29.163 -changes from one to another as the need arises.  Because repositories
  29.164 -are independent of each other, unstable changes in a development
  29.165 -branch will never affect a stable branch unless someone explicitly
  29.166 -merges those changes in.
  29.167 -
  29.168 -Here's an example of how this can work in practice.  Let's say you
  29.169 -have one ``main branch'' on a central server.
  29.170 -\interaction{branching.init}
  29.171 -People clone it, make changes locally, test them, and push them back.
  29.172 -
  29.173 -Once the main branch reaches a release milestone, you can use the
  29.174 -\hgcmd{tag} command to give a permanent name to the milestone
  29.175 -revision.
  29.176 -\interaction{branching.tag}
  29.177 -Let's say some ongoing development occurs on the main branch.
  29.178 -\interaction{branching.main}
  29.179 -Using the tag that was recorded at the milestone, people who clone
  29.180 -that repository at any time in the future can use \hgcmd{update} to
  29.181 -get a copy of the working directory exactly as it was when that tagged
  29.182 -revision was committed.  
  29.183 -\interaction{branching.update}
  29.184 -
  29.185 -In addition, immediately after the main branch is tagged, someone can
  29.186 -then clone the main branch on the server to a new ``stable'' branch,
  29.187 -also on the server.
  29.188 -\interaction{branching.clone}
  29.189 -
  29.190 -Someone who needs to make a change to the stable branch can then clone
  29.191 -\emph{that} repository, make their changes, commit, and push their
  29.192 -changes back there.
  29.193 -\interaction{branching.stable}
  29.194 -Because Mercurial repositories are independent, and Mercurial doesn't
  29.195 -move changes around automatically, the stable and main branches are
  29.196 -\emph{isolated} from each other.  The changes that you made on the
  29.197 -main branch don't ``leak'' to the stable branch, and vice versa.
  29.198 -
  29.199 -You'll often want all of your bugfixes on the stable branch to show up
  29.200 -on the main branch, too.  Rather than rewrite a bugfix on the main
  29.201 -branch, you can simply pull and merge changes from the stable to the
  29.202 -main branch, and Mercurial will bring those bugfixes in for you.
  29.203 -\interaction{branching.merge}
  29.204 -The main branch will still contain changes that are not on the stable
  29.205 -branch, but it will also contain all of the bugfixes from the stable
  29.206 -branch.  The stable branch remains unaffected by these changes.
  29.207 -
  29.208 -\subsection{Feature branches}
  29.209 -
  29.210 -For larger projects, an effective way to manage change is to break up
  29.211 -a team into smaller groups.  Each group has a shared branch of its
  29.212 -own, cloned from a single ``master'' branch used by the entire
  29.213 -project.  People working on an individual branch are typically quite
  29.214 -isolated from developments on other branches.
  29.215 -
  29.216 -\begin{figure}[ht]
  29.217 -  \centering
  29.218 -  \grafix{feature-branches}
  29.219 -  \caption{Feature branches}
  29.220 -  \label{fig:collab:feature-branches}
  29.221 -\end{figure}
  29.222 -
  29.223 -When a particular feature is deemed to be in suitable shape, someone
  29.224 -on that feature team pulls and merges from the master branch into the
  29.225 -feature branch, then pushes back up to the master branch.
  29.226 -
  29.227 -\subsection{The release train}
  29.228 -
  29.229 -Some projects are organised on a ``train'' basis: a release is
  29.230 -scheduled to happen every few months, and whatever features are ready
  29.231 -when the ``train'' is ready to leave are allowed in.
  29.232 -
  29.233 -This model resembles working with feature branches.  The difference is
  29.234 -that when a feature branch misses a train, someone on the feature team
  29.235 -pulls and merges the changes that went out on that train release into
  29.236 -the feature branch, and the team continues its work on top of that
  29.237 -release so that their feature can make the next release.
  29.238 -
  29.239 -\subsection{The Linux kernel model}
  29.240 -
  29.241 -The development of the Linux kernel has a shallow hierarchical
  29.242 -structure, surrounded by a cloud of apparent chaos.  Because most
  29.243 -Linux developers use \command{git}, a distributed revision control
  29.244 -tool with capabilities similar to Mercurial, it's useful to describe
  29.245 -the way work flows in that environment; if you like the ideas, the
  29.246 -approach translates well across tools.
  29.247 -
  29.248 -At the center of the community sits Linus Torvalds, the creator of
  29.249 -Linux.  He publishes a single source repository that is considered the
  29.250 -``authoritative'' current tree by the entire developer community.
  29.251 -Anyone can clone Linus's tree, but he is very choosy about whose trees
  29.252 -he pulls from.
  29.253 -
  29.254 -Linus has a number of ``trusted lieutenants''.  As a general rule, he
  29.255 -pulls whatever changes they publish, in most cases without even
  29.256 -reviewing those changes.  Some of those lieutenants are generally
  29.257 -agreed to be ``maintainers'', responsible for specific subsystems
  29.258 -within the kernel.  If a random kernel hacker wants to make a change
  29.259 -to a subsystem that they want to end up in Linus's tree, they must
  29.260 -find out who the subsystem's maintainer is, and ask that maintainer to
  29.261 -take their change.  If the maintainer reviews their changes and agrees
  29.262 -to take them, they'll pass them along to Linus in due course.
  29.263 -
  29.264 -Individual lieutenants have their own approaches to reviewing,
  29.265 -accepting, and publishing changes; and for deciding when to feed them
  29.266 -to Linus.  In addition, there are several well known branches that
  29.267 -people use for different purposes.  For example, a few people maintain
  29.268 -``stable'' repositories of older versions of the kernel, to which they
  29.269 -apply critical fixes as needed.  Some maintainers publish multiple
  29.270 -trees: one for experimental changes; one for changes that they are
  29.271 -about to feed upstream; and so on.  Others just publish a single
  29.272 -tree.
  29.273 -
  29.274 -This model has two notable features.  The first is that it's ``pull
  29.275 -only''.  You have to ask, convince, or beg another developer to take a
  29.276 -change from you, because there are almost no trees to which more than
  29.277 -one person can push, and there's no way to push changes into a tree
  29.278 -that someone else controls.
  29.279 -
  29.280 -The second is that it's based on reputation and acclaim.  If you're an
  29.281 -unknown, Linus will probably ignore changes from you without even
  29.282 -responding.  But a subsystem maintainer will probably review them, and
  29.283 -will likely take them if they pass their criteria for suitability.
  29.284 -The more ``good'' changes you contribute to a maintainer, the more
  29.285 -likely they are to trust your judgment and accept your changes.  If
  29.286 -you're well-known and maintain a long-lived branch for something Linus
  29.287 -hasn't yet accepted, people with similar interests may pull your
  29.288 -changes regularly to keep up with your work.
  29.289 -
  29.290 -Reputation and acclaim don't necessarily cross subsystem or ``people''
  29.291 -boundaries.  If you're a respected but specialised storage hacker, and
  29.292 -you try to fix a networking bug, that change will receive a level of
  29.293 -scrutiny from a network maintainer comparable to a change from a
  29.294 -complete stranger.
  29.295 -
  29.296 -To people who come from more orderly project backgrounds, the
  29.297 -comparatively chaotic Linux kernel development process often seems
  29.298 -completely insane.  It's subject to the whims of individuals; people
  29.299 -make sweeping changes whenever they deem it appropriate; and the pace
  29.300 -of development is astounding.  And yet Linux is a highly successful,
  29.301 -well-regarded piece of software.
  29.302 -
  29.303 -\subsection{Pull-only versus shared-push collaboration}
  29.304 -
  29.305 -A perpetual source of heat in the open source community is whether a
  29.306 -development model in which people only ever pull changes from others
  29.307 -is ``better than'' one in which multiple people can push changes to a
  29.308 -shared repository.
  29.309 -
  29.310 -Typically, the backers of the shared-push model use tools that
  29.311 -actively enforce this approach.  If you're using a centralised
  29.312 -revision control tool such as Subversion, there's no way to make a
  29.313 -choice over which model you'll use: the tool gives you shared-push,
  29.314 -and if you want to do anything else, you'll have to roll your own
  29.315 -approach on top (such as applying a patch by hand).
  29.316 -
  29.317 -A good distributed revision control tool, such as Mercurial, will
  29.318 -support both models.  You and your collaborators can then structure
  29.319 -how you work together based on your own needs and preferences, not on
  29.320 -what contortions your tools force you into.
  29.321 -
  29.322 -\subsection{Where collaboration meets branch management}
  29.323 -
  29.324 -Once you and your team set up some shared repositories and start
  29.325 -propagating changes back and forth between local and shared repos, you
  29.326 -begin to face a related, but slightly different challenge: that of
  29.327 -managing the multiple directions in which your team may be moving at
  29.328 -once.  Even though this subject is intimately related to how your team
  29.329 -collaborates, it's dense enough to merit treatment of its own, in
  29.330 -chapter~\ref{chap:branch}.
  29.331 -
  29.332 -\section{The technical side of sharing}
  29.333 -
  29.334 -The remainder of this chapter is devoted to the question of serving
  29.335 -data to your collaborators.
  29.336 -
  29.337 -\section{Informal sharing with \hgcmd{serve}}
  29.338 -\label{sec:collab:serve}
  29.339 -
  29.340 -Mercurial's \hgcmd{serve} command is wonderfully suited to small,
  29.341 -tight-knit, and fast-paced group environments.  It also provides a
  29.342 -great way to get a feel for using Mercurial commands over a network.
  29.343 -
  29.344 -Run \hgcmd{serve} inside a repository, and in under a second it will
  29.345 -bring up a specialised HTTP server; this will accept connections from
  29.346 -any client, and serve up data for that repository until you terminate
  29.347 -it.  Anyone who knows the URL of the server you just started, and can
  29.348 -talk to your computer over the network, can then use a web browser or
  29.349 -Mercurial to read data from that repository.  A URL for a
  29.350 -\hgcmd{serve} instance running on a laptop is likely to look something
  29.351 -like \Verb|http://my-laptop.local:8000/|.
  29.352 -
  29.353 -The \hgcmd{serve} command is \emph{not} a general-purpose web server.
  29.354 -It can do only two things:
  29.355 -\begin{itemize}
  29.356 -\item Allow people to browse the history of the repository it's
  29.357 -  serving, from their normal web browsers.
  29.358 -\item Speak Mercurial's wire protocol, so that people can
  29.359 -  \hgcmd{clone} or \hgcmd{pull} changes from that repository.
  29.360 -\end{itemize}
  29.361 -In particular, \hgcmd{serve} won't allow remote users to \emph{modify}
  29.362 -your repository.  It's intended for read-only use.
  29.363 -
  29.364 -If you're getting started with Mercurial, there's nothing to prevent
  29.365 -you from using \hgcmd{serve} to serve up a repository on your own
  29.366 -computer, then use commands like \hgcmd{clone}, \hgcmd{incoming}, and
  29.367 -so on to talk to that server as if the repository was hosted remotely.
  29.368 -This can help you to quickly get acquainted with using commands on
  29.369 -network-hosted repositories.
  29.370 -
  29.371 -\subsection{A few things to keep in mind}
  29.372 -
  29.373 -Because it provides unauthenticated read access to all clients, you
  29.374 -should only use \hgcmd{serve} in an environment where you either don't
  29.375 -care, or have complete control over, who can access your network and
  29.376 -pull data from your repository.
  29.377 -
  29.378 -The \hgcmd{serve} command knows nothing about any firewall software
  29.379 -you might have installed on your system or network.  It cannot detect
  29.380 -or control your firewall software.  If other people are unable to talk
  29.381 -to a running \hgcmd{serve} instance, the second thing you should do
  29.382 -(\emph{after} you make sure that they're using the correct URL) is
  29.383 -check your firewall configuration.
  29.384 -
  29.385 -By default, \hgcmd{serve} listens for incoming connections on
  29.386 -port~8000.  If another process is already listening on the port you
  29.387 -want to use, you can specify a different port to listen on using the
  29.388 -\hgopt{serve}{-p} option.
  29.389 -
  29.390 -Normally, when \hgcmd{serve} starts, it prints no output, which can be
  29.391 -a bit unnerving.  If you'd like to confirm that it is indeed running
  29.392 -correctly, and find out what URL you should send to your
  29.393 -collaborators, start it with the \hggopt{-v} option.
  29.394 -
  29.395 -\section{Using the Secure Shell (ssh) protocol}
  29.396 -\label{sec:collab:ssh}
  29.397 -
  29.398 -You can pull and push changes securely over a network connection using
  29.399 -the Secure Shell (\texttt{ssh}) protocol.  To use this successfully,
  29.400 -you may have to do a little bit of configuration on the client or
  29.401 -server sides.
  29.402 -
  29.403 -If you're not familiar with ssh, it's a network protocol that lets you
  29.404 -securely communicate with another computer.  To use it with Mercurial,
  29.405 -you'll be setting up one or more user accounts on a server so that
  29.406 -remote users can log in and execute commands.
  29.407 -
  29.408 -(If you \emph{are} familiar with ssh, you'll probably find some of the
  29.409 -material that follows to be elementary in nature.)
  29.410 -
  29.411 -\subsection{How to read and write ssh URLs}
  29.412 -
  29.413 -An ssh URL tends to look like this:
  29.414 -\begin{codesample2}
  29.415 -  ssh://bos@hg.serpentine.com:22/hg/hgbook
  29.416 -\end{codesample2}
  29.417 -\begin{enumerate}
  29.418 -\item The ``\texttt{ssh://}'' part tells Mercurial to use the ssh
  29.419 -  protocol.
  29.420 -\item The ``\texttt{bos@}'' component indicates what username to log
  29.421 -  into the server as.  You can leave this out if the remote username
  29.422 -  is the same as your local username.
  29.423 -\item The ``\texttt{hg.serpentine.com}'' gives the hostname of the
  29.424 -  server to log into.
  29.425 -\item The ``:22'' identifies the port number to connect to the server
  29.426 -  on.  The default port is~22, so you only need to specify this part
  29.427 -  if you're \emph{not} using port~22.
  29.428 -\item The remainder of the URL is the local path to the repository on
  29.429 -  the server.
  29.430 -\end{enumerate}
  29.431 -
  29.432 -There's plenty of scope for confusion with the path component of ssh
  29.433 -URLs, as there is no standard way for tools to interpret it.  Some
  29.434 -programs behave differently than others when dealing with these paths.
  29.435 -This isn't an ideal situation, but it's unlikely to change.  Please
  29.436 -read the following paragraphs carefully.
  29.437 -
  29.438 -Mercurial treats the path to a repository on the server as relative to
  29.439 -the remote user's home directory.  For example, if user \texttt{foo}
  29.440 -on the server has a home directory of \dirname{/home/foo}, then an ssh
  29.441 -URL that contains a path component of \dirname{bar}
  29.442 -\emph{really} refers to the directory \dirname{/home/foo/bar}.
  29.443 -
  29.444 -If you want to specify a path relative to another user's home
  29.445 -directory, you can use a path that starts with a tilde character
  29.446 -followed by the user's name (let's call them \texttt{otheruser}), like
  29.447 -this.
  29.448 -\begin{codesample2}
  29.449 -  ssh://server/~otheruser/hg/repo
  29.450 -\end{codesample2}
  29.451 -
  29.452 -And if you really want to specify an \emph{absolute} path on the
  29.453 -server, begin the path component with two slashes, as in this example.
  29.454 -\begin{codesample2}
  29.455 -  ssh://server//absolute/path
  29.456 -\end{codesample2}
  29.457 -
  29.458 -\subsection{Finding an ssh client for your system}
  29.459 -
  29.460 -Almost every Unix-like system comes with OpenSSH preinstalled.  If
  29.461 -you're using such a system, run \Verb|which ssh| to find out if
  29.462 -the \command{ssh} command is installed (it's usually in
  29.463 -\dirname{/usr/bin}).  In the unlikely event that it isn't present,
  29.464 -take a look at your system documentation to figure out how to install
  29.465 -it.
  29.466 -
  29.467 -On Windows, you'll first need to download a suitable ssh
  29.468 -client.  There are two alternatives.
  29.469 -\begin{itemize}
  29.470 -\item Simon Tatham's excellent PuTTY package~\cite{web:putty} provides
  29.471 -  a complete suite of ssh client commands.
  29.472 -\item If you have a high tolerance for pain, you can use the Cygwin
  29.473 -  port of OpenSSH.
  29.474 -\end{itemize}
  29.475 -In either case, you'll need to edit your \hgini\ file to tell
  29.476 -Mercurial where to find the actual client command.  For example, if
  29.477 -you're using PuTTY, you'll need to use the \command{plink} command as
  29.478 -a command-line ssh client.
  29.479 -\begin{codesample2}
  29.480 -  [ui]
  29.481 -  ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"
  29.482 -\end{codesample2}
  29.483 -
  29.484 -\begin{note}
  29.485 -  The path to \command{plink} shouldn't contain any whitespace
  29.486 -  characters, or Mercurial may not be able to run it correctly (so
  29.487 -  putting it in \dirname{C:\\Program Files} is probably not a good
  29.488 -  idea).
  29.489 -\end{note}
  29.490 -
  29.491 -\subsection{Generating a key pair}
  29.492 -
  29.493 -To avoid the need to repetitively type a password every time you need
  29.494 -to use your ssh client, I recommend generating a key pair.  On a
  29.495 -Unix-like system, the \command{ssh-keygen} command will do the trick.
  29.496 -On Windows, if you're using PuTTY, the \command{puttygen} command is
  29.497 -what you'll need.
  29.498 -
  29.499 -When you generate a key pair, it's usually \emph{highly} advisable to
  29.500 -protect it with a passphrase.  (The only time that you might not want
  29.501 -to do this is when you're using the ssh protocol for automated tasks
  29.502 -on a secure network.)
  29.503 -
  29.504 -Simply generating a key pair isn't enough, however.  You'll need to
  29.505 -add the public key to the set of authorised keys for whatever user
  29.506 -you're logging in remotely as.  For servers using OpenSSH (the vast
  29.507 -majority), this will mean adding the public key to a list in a file
  29.508 -called \sfilename{authorized\_keys} in their \sdirname{.ssh}
  29.509 -directory.
  29.510 -
  29.511 -On a Unix-like system, your public key will have a \filename{.pub}
  29.512 -extension.  If you're using \command{puttygen} on Windows, you can
  29.513 -save the public key to a file of your choosing, or paste it from the
  29.514 -window it's displayed in straight into the
  29.515 -\sfilename{authorized\_keys} file.
  29.516 -
  29.517 -\subsection{Using an authentication agent}
  29.518 -
  29.519 -An authentication agent is a daemon that stores passphrases in memory
  29.520 -(so it will forget passphrases if you log out and log back in again).
  29.521 -An ssh client will notice if it's running, and query it for a
  29.522 -passphrase.  If there's no authentication agent running, or the agent
  29.523 -doesn't store the necessary passphrase, you'll have to type your
  29.524 -passphrase every time Mercurial tries to communicate with a server on
  29.525 -your behalf (e.g.~whenever you pull or push changes).
  29.526 -
  29.527 -The downside of storing passphrases in an agent is that it's possible
  29.528 -for a well-prepared attacker to recover the plain text of your
  29.529 -passphrases, in some cases even if your system has been power-cycled.
  29.530 -You should make your own judgment as to whether this is an acceptable
  29.531 -risk.  It certainly saves a lot of repeated typing.
  29.532 -
  29.533 -On Unix-like systems, the agent is called \command{ssh-agent}, and
  29.534 -it's often run automatically for you when you log in.  You'll need to
  29.535 -use the \command{ssh-add} command to add passphrases to the agent's
  29.536 -store.  On Windows, if you're using PuTTY, the \command{pageant}
  29.537 -command acts as the agent.  It adds an icon to your system tray that
  29.538 -will let you manage stored passphrases.
  29.539 -
  29.540 -\subsection{Configuring the server side properly}
  29.541 -
  29.542 -Because ssh can be fiddly to set up if you're new to it, there's a
  29.543 -variety of things that can go wrong.  Add Mercurial on top, and
  29.544 -there's plenty more scope for head-scratching.  Most of these
  29.545 -potential problems occur on the server side, not the client side.  The
  29.546 -good news is that once you've gotten a configuration working, it will
  29.547 -usually continue to work indefinitely.
  29.548 -
  29.549 -Before you try using Mercurial to talk to an ssh server, it's best to
  29.550 -make sure that you can use the normal \command{ssh} or \command{putty}
  29.551 -command to talk to the server first.  If you run into problems with
  29.552 -using these commands directly, Mercurial surely won't work.  Worse, it
  29.553 -will obscure the underlying problem.  Any time you want to debug
  29.554 -ssh-related Mercurial problems, you should drop back to making sure
  29.555 -that plain ssh client commands work first, \emph{before} you worry
  29.556 -about whether there's a problem with Mercurial.
  29.557 -
  29.558 -The first thing to be sure of on the server side is that you can
  29.559 -actually log in from another machine at all.  If you can't use
  29.560 -\command{ssh} or \command{putty} to log in, the error message you get
  29.561 -may give you a few hints as to what's wrong.  The most common problems
  29.562 -are as follows.
  29.563 -\begin{itemize}
  29.564 -\item If you get a ``connection refused'' error, either there isn't an
  29.565 -  SSH daemon running on the server at all, or it's inaccessible due to
  29.566 -  firewall configuration.
  29.567 -\item If you get a ``no route to host'' error, you either have an
  29.568 -  incorrect address for the server or a seriously locked down firewall
  29.569 -  that won't admit its existence at all.
  29.570 -\item If you get a ``permission denied'' error, you may have mistyped
  29.571 -  the username on the server, or you could have mistyped your key's
  29.572 -  passphrase or the remote user's password.
  29.573 -\end{itemize}
  29.574 -In summary, if you're having trouble talking to the server's ssh
  29.575 -daemon, first make sure that one is running at all.  On many systems
  29.576 -it will be installed, but disabled, by default.  Once you're done with
  29.577 -this step, you should then check that the server's firewall is
  29.578 -configured to allow incoming connections on the port the ssh daemon is
  29.579 -listening on (usually~22).  Don't worry about more exotic
  29.580 -possibilities for misconfiguration until you've checked these two
  29.581 -first.
  29.582 -
  29.583 -If you're using an authentication agent on the client side to store
  29.584 -passphrases for your keys, you ought to be able to log into the server
  29.585 -without being prompted for a passphrase or a password.  If you're
  29.586 -prompted for a passphrase, there are a few possible culprits.
  29.587 -\begin{itemize}
  29.588 -\item You might have forgotten to use \command{ssh-add} or
  29.589 -  \command{pageant} to store the passphrase.
  29.590 -\item You might have stored the passphrase for the wrong key.
  29.591 -\end{itemize}
  29.592 -If you're being prompted for the remote user's password, there are
  29.593 -another few possible problems to check.
  29.594 -\begin{itemize}
  29.595 -\item Either the user's home directory or their \sdirname{.ssh}
  29.596 -  directory might have excessively liberal permissions.  As a result,
  29.597 -  the ssh daemon will not trust or read their
  29.598 -  \sfilename{authorized\_keys} file.  For example, a group-writable
  29.599 -  home or \sdirname{.ssh} directory will often cause this symptom.
  29.600 -\item The user's \sfilename{authorized\_keys} file may have a problem.
  29.601 -  If anyone other than the user owns or can write to that file, the
  29.602 -  ssh daemon will not trust or read it.
  29.603 -\end{itemize}
  29.604 -
  29.605 -In the ideal world, you should be able to run the following command
  29.606 -successfully, and it should print exactly one line of output, the
  29.607 -current date and time.
  29.608 -\begin{codesample2}
  29.609 -  ssh myserver date
  29.610 -\end{codesample2}
  29.611 -
  29.612 -If, on your server, you have login scripts that print banners or other
  29.613 -junk even when running non-interactive commands like this, you should
  29.614 -fix them before you continue, so that they only print output if
  29.615 -they're run interactively.  Otherwise these banners will at least
  29.616 -clutter up Mercurial's output.  Worse, they could potentially cause
  29.617 -problems with running Mercurial commands remotely.  Mercurial makes
  29.618 -tries to detect and ignore banners in non-interactive \command{ssh}
  29.619 -sessions, but it is not foolproof.  (If you're editing your login
  29.620 -scripts on your server, the usual way to see if a login script is
  29.621 -running in an interactive shell is to check the return code from the
  29.622 -command \Verb|tty -s|.)
  29.623 -
  29.624 -Once you've verified that plain old ssh is working with your server,
  29.625 -the next step is to ensure that Mercurial runs on the server.  The
  29.626 -following command should run successfully:
  29.627 -\begin{codesample2}
  29.628 -  ssh myserver hg version
  29.629 -\end{codesample2}
  29.630 -If you see an error message instead of normal \hgcmd{version} output,
  29.631 -this is usually because you haven't installed Mercurial to
  29.632 -\dirname{/usr/bin}.  Don't worry if this is the case; you don't need
  29.633 -to do that.  But you should check for a few possible problems.
  29.634 -\begin{itemize}
  29.635 -\item Is Mercurial really installed on the server at all?  I know this
  29.636 -  sounds trivial, but it's worth checking!
  29.637 -\item Maybe your shell's search path (usually set via the \envar{PATH}
  29.638 -  environment variable) is simply misconfigured.
  29.639 -\item Perhaps your \envar{PATH} environment variable is only being set
  29.640 -  to point to the location of the \command{hg} executable if the login
  29.641 -  session is interactive.  This can happen if you're setting the path
  29.642 -  in the wrong shell login script.  See your shell's documentation for
  29.643 -  details.
  29.644 -\item The \envar{PYTHONPATH} environment variable may need to contain
  29.645 -  the path to the Mercurial Python modules.  It might not be set at
  29.646 -  all; it could be incorrect; or it may be set only if the login is
  29.647 -  interactive.
  29.648 -\end{itemize}
  29.649 -
  29.650 -If you can run \hgcmd{version} over an ssh connection, well done!
  29.651 -You've got the server and client sorted out.  You should now be able
  29.652 -to use Mercurial to access repositories hosted by that username on
  29.653 -that server.  If you run into problems with Mercurial and ssh at this
  29.654 -point, try using the \hggopt{--debug} option to get a clearer picture
  29.655 -of what's going on.
  29.656 -
  29.657 -\subsection{Using compression with ssh}
  29.658 -
  29.659 -Mercurial does not compress data when it uses the ssh protocol,
  29.660 -because the ssh protocol can transparently compress data.  However,
  29.661 -the default behaviour of ssh clients is \emph{not} to request
  29.662 -compression.
  29.663 -
  29.664 -Over any network other than a fast LAN (even a wireless network),
  29.665 -using compression is likely to significantly speed up Mercurial's
  29.666 -network operations.  For example, over a WAN, someone measured
  29.667 -compression as reducing the amount of time required to clone a
  29.668 -particularly large repository from~51 minutes to~17 minutes.
  29.669 -
  29.670 -Both \command{ssh} and \command{plink} accept a \cmdopt{ssh}{-C}
  29.671 -option which turns on compression.  You can easily edit your \hgrc\ to
  29.672 -enable compression for all of Mercurial's uses of the ssh protocol.
  29.673 -\begin{codesample2}
  29.674 -  [ui]
  29.675 -  ssh = ssh -C
  29.676 -\end{codesample2}
  29.677 -
  29.678 -If you use \command{ssh}, you can configure it to always use
  29.679 -compression when talking to your server.  To do this, edit your
  29.680 -\sfilename{.ssh/config} file (which may not yet exist), as follows.
  29.681 -\begin{codesample2}
  29.682 -  Host hg
  29.683 -    Compression yes
  29.684 -    HostName hg.example.com
  29.685 -\end{codesample2}
  29.686 -This defines an alias, \texttt{hg}.  When you use it on the
  29.687 -\command{ssh} command line or in a Mercurial \texttt{ssh}-protocol
  29.688 -URL, it will cause \command{ssh} to connect to \texttt{hg.example.com}
  29.689 -and use compression.  This gives you both a shorter name to type and
  29.690 -compression, each of which is a good thing in its own right.
  29.691 -
  29.692 -\section{Serving over HTTP using CGI}
  29.693 -\label{sec:collab:cgi}
  29.694 -
  29.695 -Depending on how ambitious you are, configuring Mercurial's CGI
  29.696 -interface can take anything from a few moments to several hours.
  29.697 -
  29.698 -We'll begin with the simplest of examples, and work our way towards a
  29.699 -more complex configuration.  Even for the most basic case, you're
  29.700 -almost certainly going to need to read and modify your web server's
  29.701 -configuration.
  29.702 -
  29.703 -\begin{note}
  29.704 -  Configuring a web server is a complex, fiddly, and highly
  29.705 -  system-dependent activity.  I can't possibly give you instructions
  29.706 -  that will cover anything like all of the cases you will encounter.
  29.707 -  Please use your discretion and judgment in following the sections
  29.708 -  below.  Be prepared to make plenty of mistakes, and to spend a lot
  29.709 -  of time reading your server's error logs.
  29.710 -\end{note}
  29.711 -
  29.712 -\subsection{Web server configuration checklist}
  29.713 -
  29.714 -Before you continue, do take a few moments to check a few aspects of
  29.715 -your system's setup.
  29.716 -
  29.717 -\begin{enumerate}
  29.718 -\item Do you have a web server installed at all?  Mac OS X ships with
  29.719 -  Apache, but many other systems may not have a web server installed.
  29.720 -\item If you have a web server installed, is it actually running?  On
  29.721 -  most systems, even if one is present, it will be disabled by
  29.722 -  default.
  29.723 -\item Is your server configured to allow you to run CGI programs in
  29.724 -  the directory where you plan to do so?  Most servers default to
  29.725 -  explicitly disabling the ability to run CGI programs.
  29.726 -\end{enumerate}
  29.727 -
  29.728 -If you don't have a web server installed, and don't have substantial
  29.729 -experience configuring Apache, you should consider using the
  29.730 -\texttt{lighttpd} web server instead of Apache.  Apache has a
  29.731 -well-deserved reputation for baroque and confusing configuration.
  29.732 -While \texttt{lighttpd} is less capable in some ways than Apache, most
  29.733 -of these capabilities are not relevant to serving Mercurial
  29.734 -repositories.  And \texttt{lighttpd} is undeniably \emph{much} easier
  29.735 -to get started with than Apache.
  29.736 -
  29.737 -\subsection{Basic CGI configuration}
  29.738 -
  29.739 -On Unix-like systems, it's common for users to have a subdirectory
  29.740 -named something like \dirname{public\_html} in their home directory,
  29.741 -from which they can serve up web pages.  A file named \filename{foo}
  29.742 -in this directory will be accessible at a URL of the form
  29.743 -\texttt{http://www.example.com/\~{}username/foo}.
  29.744 -
  29.745 -To get started, find the \sfilename{hgweb.cgi} script that should be
  29.746 -present in your Mercurial installation.  If you can't quickly find a
  29.747 -local copy on your system, simply download one from the master
  29.748 -Mercurial repository at
  29.749 -\url{http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi}.
  29.750 -
  29.751 -You'll need to copy this script into your \dirname{public\_html}
  29.752 -directory, and ensure that it's executable.
  29.753 -\begin{codesample2}
  29.754 -  cp .../hgweb.cgi ~/public_html
  29.755 -  chmod 755 ~/public_html/hgweb.cgi
  29.756 -\end{codesample2}
  29.757 -The \texttt{755} argument to \command{chmod} is a little more general
  29.758 -than just making the script executable: it ensures that the script is
  29.759 -executable by anyone, and that ``group'' and ``other'' write
  29.760 -permissions are \emph{not} set.  If you were to leave those write
  29.761 -permissions enabled, Apache's \texttt{suexec} subsystem would likely
  29.762 -refuse to execute the script.  In fact, \texttt{suexec} also insists
  29.763 -that the \emph{directory} in which the script resides must not be
  29.764 -writable by others.
  29.765 -\begin{codesample2}
  29.766 -  chmod 755 ~/public_html
  29.767 -\end{codesample2}
  29.768 -
  29.769 -\subsubsection{What could \emph{possibly} go wrong?}
  29.770 -\label{sec:collab:wtf}
  29.771 -
  29.772 -Once you've copied the CGI script into place, go into a web browser,
  29.773 -and try to open the URL \url{http://myhostname/~myuser/hgweb.cgi},
  29.774 -\emph{but} brace yourself for instant failure.  There's a high
  29.775 -probability that trying to visit this URL will fail, and there are
  29.776 -many possible reasons for this.  In fact, you're likely to stumble
  29.777 -over almost every one of the possible errors below, so please read
  29.778 -carefully.  The following are all of the problems I ran into on a
  29.779 -system running Fedora~7, with a fresh installation of Apache, and a
  29.780 -user account that I created specially to perform this exercise.
  29.781 -
  29.782 -Your web server may have per-user directories disabled.  If you're
  29.783 -using Apache, search your config file for a \texttt{UserDir}
  29.784 -directive.  If there's none present, per-user directories will be
  29.785 -disabled.  If one exists, but its value is \texttt{disabled}, then
  29.786 -per-user directories will be disabled.  Otherwise, the string after
  29.787 -\texttt{UserDir} gives the name of the subdirectory that Apache will
  29.788 -look in under your home directory, for example \dirname{public\_html}.
  29.789 -
  29.790 -Your file access permissions may be too restrictive.  The web server
  29.791 -must be able to traverse your home directory and directories under
  29.792 -your \dirname{public\_html} directory, and read files under the latter
  29.793 -too.  Here's a quick recipe to help you to make your permissions more
  29.794 -appropriate.
  29.795 -\begin{codesample2}
  29.796 -  chmod 755 ~
  29.797 -  find ~/public_html -type d -print0 | xargs -0r chmod 755
  29.798 -  find ~/public_html -type f -print0 | xargs -0r chmod 644
  29.799 -\end{codesample2}
  29.800 -
  29.801 -The other possibility with permissions is that you might get a
  29.802 -completely empty window when you try to load the script.  In this
  29.803 -case, it's likely that your access permissions are \emph{too
  29.804 -  permissive}.  Apache's \texttt{suexec} subsystem won't execute a
  29.805 -script that's group-~or world-writable, for example.
  29.806 -
  29.807 -Your web server may be configured to disallow execution of CGI
  29.808 -programs in your per-user web directory.  Here's Apache's
  29.809 -default per-user configuration from my Fedora system.
  29.810 -\begin{codesample2}
  29.811 -  <Directory /home/*/public_html>
  29.812 -      AllowOverride FileInfo AuthConfig Limit
  29.813 -      Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  29.814 -      <Limit GET POST OPTIONS>
  29.815 -          Order allow,deny
  29.816 -          Allow from all
  29.817 -      </Limit>
  29.818 -      <LimitExcept GET POST OPTIONS>
  29.819 -          Order deny,allow
  29.820 -          Deny from all
  29.821 -      </LimitExcept>
  29.822 -  </Directory>
  29.823 -\end{codesample2}
  29.824 -If you find a similar-looking \texttt{Directory} group in your Apache
  29.825 -configuration, the directive to look at inside it is \texttt{Options}.
  29.826 -Add \texttt{ExecCGI} to the end of this list if it's missing, and
  29.827 -restart the web server.
  29.828 -
  29.829 -If you find that Apache serves you the text of the CGI script instead
  29.830 -of executing it, you may need to either uncomment (if already present)
  29.831 -or add a directive like this.
  29.832 -\begin{codesample2}
  29.833 -  AddHandler cgi-script .cgi
  29.834 -\end{codesample2}
  29.835 -
  29.836 -The next possibility is that you might be served with a colourful
  29.837 -Python backtrace claiming that it can't import a
  29.838 -\texttt{mercurial}-related module.  This is actually progress!  The
  29.839 -server is now capable of executing your CGI script.  This error is
  29.840 -only likely to occur if you're running a private installation of
  29.841 -Mercurial, instead of a system-wide version.  Remember that the web
  29.842 -server runs the CGI program without any of the environment variables
  29.843 -that you take for granted in an interactive session.  If this error
  29.844 -happens to you, edit your copy of \sfilename{hgweb.cgi} and follow the
  29.845 -directions inside it to correctly set your \envar{PYTHONPATH}
  29.846 -environment variable.
  29.847 -
  29.848 -Finally, you are \emph{certain} to by served with another colourful
  29.849 -Python backtrace: this one will complain that it can't find
  29.850 -\dirname{/path/to/repository}.  Edit your \sfilename{hgweb.cgi} script
  29.851 -and replace the \dirname{/path/to/repository} string with the complete
  29.852 -path to the repository you want to serve up.
  29.853 -
  29.854 -At this point, when you try to reload the page, you should be
  29.855 -presented with a nice HTML view of your repository's history.  Whew!
  29.856 -
  29.857 -\subsubsection{Configuring lighttpd}
  29.858 -
  29.859 -To be exhaustive in my experiments, I tried configuring the
  29.860 -increasingly popular \texttt{lighttpd} web server to serve the same
  29.861 -repository as I described with Apache above.  I had already overcome
  29.862 -all of the problems I outlined with Apache, many of which are not
  29.863 -server-specific.  As a result, I was fairly sure that my file and
  29.864 -directory permissions were good, and that my \sfilename{hgweb.cgi}
  29.865 -script was properly edited.
  29.866 -
  29.867 -Once I had Apache running, getting \texttt{lighttpd} to serve the
  29.868 -repository was a snap (in other words, even if you're trying to use
  29.869 -\texttt{lighttpd}, you should read the Apache section).  I first had
  29.870 -to edit the \texttt{mod\_access} section of its config file to enable
  29.871 -\texttt{mod\_cgi} and \texttt{mod\_userdir}, both of which were
  29.872 -disabled by default on my system.  I then added a few lines to the end
  29.873 -of the config file, to configure these modules.
  29.874 -\begin{codesample2}
  29.875 -  userdir.path = "public_html"
  29.876 -  cgi.assign = ( ".cgi" => "" )
  29.877 -\end{codesample2}
  29.878 -With this done, \texttt{lighttpd} ran immediately for me.  If I had
  29.879 -configured \texttt{lighttpd} before Apache, I'd almost certainly have
  29.880 -run into many of the same system-level configuration problems as I did
  29.881 -with Apache.  However, I found \texttt{lighttpd} to be noticeably
  29.882 -easier to configure than Apache, even though I've used Apache for over
  29.883 -a decade, and this was my first exposure to \texttt{lighttpd}.
  29.884 -
  29.885 -\subsection{Sharing multiple repositories with one CGI script}
  29.886 -
  29.887 -The \sfilename{hgweb.cgi} script only lets you publish a single
  29.888 -repository, which is an annoying restriction.  If you want to publish
  29.889 -more than one without wracking yourself with multiple copies of the
  29.890 -same script, each with different names, a better choice is to use the
  29.891 -\sfilename{hgwebdir.cgi} script.
  29.892 -
  29.893 -The procedure to configure \sfilename{hgwebdir.cgi} is only a little
  29.894 -more involved than for \sfilename{hgweb.cgi}.  First, you must obtain
  29.895 -a copy of the script.  If you don't have one handy, you can download a
  29.896 -copy from the master Mercurial repository at
  29.897 -\url{http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi}.
  29.898 -
  29.899 -You'll need to copy this script into your \dirname{public\_html}
  29.900 -directory, and ensure that it's executable.
  29.901 -\begin{codesample2}
  29.902 -  cp .../hgwebdir.cgi ~/public_html
  29.903 -  chmod 755 ~/public_html ~/public_html/hgwebdir.cgi
  29.904 -\end{codesample2}
  29.905 -With basic configuration out of the way, try to visit
  29.906 -\url{http://myhostname/~myuser/hgwebdir.cgi} in your browser.  It
  29.907 -should display an empty list of repositories.  If you get a blank
  29.908 -window or error message, try walking through the list of potential
  29.909 -problems in section~\ref{sec:collab:wtf}.
  29.910 -
  29.911 -The \sfilename{hgwebdir.cgi} script relies on an external
  29.912 -configuration file.  By default, it searches for a file named
  29.913 -\sfilename{hgweb.config} in the same directory as itself.  You'll need
  29.914 -to create this file, and make it world-readable.  The format of the
  29.915 -file is similar to a Windows ``ini'' file, as understood by Python's
  29.916 -\texttt{ConfigParser}~\cite{web:configparser} module.
  29.917 -
  29.918 -The easiest way to configure \sfilename{hgwebdir.cgi} is with a
  29.919 -section named \texttt{collections}.  This will automatically publish
  29.920 -\emph{every} repository under the directories you name.  The section
  29.921 -should look like this:
  29.922 -\begin{codesample2}
  29.923 -  [collections]
  29.924 -  /my/root = /my/root
  29.925 -\end{codesample2}
  29.926 -Mercurial interprets this by looking at the directory name on the
  29.927 -\emph{right} hand side of the ``\texttt{=}'' sign; finding
  29.928 -repositories in that directory hierarchy; and using the text on the
  29.929 -\emph{left} to strip off matching text from the names it will actually
  29.930 -list in the web interface.  The remaining component of a path after
  29.931 -this stripping has occurred is called a ``virtual path''.
  29.932 -
  29.933 -Given the example above, if we have a repository whose local path is
  29.934 -\dirname{/my/root/this/repo}, the CGI script will strip the leading
  29.935 -\dirname{/my/root} from the name, and publish the repository with a
  29.936 -virtual path of \dirname{this/repo}.  If the base URL for our CGI
  29.937 -script is \url{http://myhostname/~myuser/hgwebdir.cgi}, the complete
  29.938 -URL for that repository will be
  29.939 -\url{http://myhostname/~myuser/hgwebdir.cgi/this/repo}.
  29.940 -
  29.941 -If we replace \dirname{/my/root} on the left hand side of this example
  29.942 -with \dirname{/my}, then \sfilename{hgwebdir.cgi} will only strip off
  29.943 -\dirname{/my} from the repository name, and will give us a virtual
  29.944 -path of \dirname{root/this/repo} instead of \dirname{this/repo}.
  29.945 -
  29.946 -The \sfilename{hgwebdir.cgi} script will recursively search each
  29.947 -directory listed in the \texttt{collections} section of its
  29.948 -configuration file, but it will \texttt{not} recurse into the
  29.949 -repositories it finds.
  29.950 -
  29.951 -The \texttt{collections} mechanism makes it easy to publish many
  29.952 -repositories in a ``fire and forget'' manner.  You only need to set up
  29.953 -the CGI script and configuration file one time.  Afterwards, you can
  29.954 -publish or unpublish a repository at any time by simply moving it
  29.955 -into, or out of, the directory hierarchy in which you've configured
  29.956 -\sfilename{hgwebdir.cgi} to look.
  29.957 -
  29.958 -\subsubsection{Explicitly specifying which repositories to publish}
  29.959 -
  29.960 -In addition to the \texttt{collections} mechanism, the
  29.961 -\sfilename{hgwebdir.cgi} script allows you to publish a specific list
  29.962 -of repositories.  To do so, create a \texttt{paths} section, with
  29.963 -contents of the following form.
  29.964 -\begin{codesample2}
  29.965 -  [paths]
  29.966 -  repo1 = /my/path/to/some/repo
  29.967 -  repo2 = /some/path/to/another
  29.968 -\end{codesample2}
  29.969 -In this case, the virtual path (the component that will appear in a
  29.970 -URL) is on the left hand side of each definition, while the path to
  29.971 -the repository is on the right.  Notice that there does not need to be
  29.972 -any relationship between the virtual path you choose and the location
  29.973 -of a repository in your filesystem.
  29.974 -
  29.975 -If you wish, you can use both the \texttt{collections} and
  29.976 -\texttt{paths} mechanisms simultaneously in a single configuration
  29.977 -file.
  29.978 -
  29.979 -\begin{note}
  29.980 -  If multiple repositories have the same virtual path,
  29.981 -  \sfilename{hgwebdir.cgi} will not report an error.  Instead, it will
  29.982 -  behave unpredictably.
  29.983 -\end{note}
  29.984 -
  29.985 -\subsection{Downloading source archives}
  29.986 -
  29.987 -Mercurial's web interface lets users download an archive of any
  29.988 -revision.  This archive will contain a snapshot of the working
  29.989 -directory as of that revision, but it will not contain a copy of the
  29.990 -repository data.
  29.991 -
  29.992 -By default, this feature is not enabled.  To enable it, you'll need to
  29.993 -add an \rcitem{web}{allow\_archive} item to the \rcsection{web}
  29.994 -section of your \hgrc.
  29.995 -
  29.996 -\subsection{Web configuration options}
  29.997 -
  29.998 -Mercurial's web interfaces (the \hgcmd{serve} command, and the
  29.999 -\sfilename{hgweb.cgi} and \sfilename{hgwebdir.cgi} scripts) have a
 29.1000 -number of configuration options that you can set.  These belong in a
 29.1001 -section named \rcsection{web}.
 29.1002 -\begin{itemize}
 29.1003 -\item[\rcitem{web}{allow\_archive}] Determines which (if any) archive
 29.1004 -  download mechanisms Mercurial supports.  If you enable this
 29.1005 -  feature, users of the web interface will be able to download an
 29.1006 -  archive of whatever revision of a repository they are viewing.
 29.1007 -  To enable the archive feature, this item must take the form of a
 29.1008 -  sequence of words drawn from the list below.
 29.1009 -  \begin{itemize}
 29.1010 -  \item[\texttt{bz2}] A \command{tar} archive, compressed using
 29.1011 -    \texttt{bzip2} compression.  This has the best compression ratio,
 29.1012 -    but uses the most CPU time on the server.
 29.1013 -  \item[\texttt{gz}] A \command{tar} archive, compressed using
 29.1014 -    \texttt{gzip} compression.
 29.1015 -  \item[\texttt{zip}] A \command{zip} archive, compressed using LZW
 29.1016 -    compression.  This format has the worst compression ratio, but is
 29.1017 -    widely used in the Windows world.
 29.1018 -  \end{itemize}
 29.1019 -  If you provide an empty list, or don't have an
 29.1020 -  \rcitem{web}{allow\_archive} entry at all, this feature will be
 29.1021 -  disabled.  Here is an example of how to enable all three supported
 29.1022 -  formats.
 29.1023 -  \begin{codesample4}
 29.1024 -    [web]
 29.1025 -    allow_archive = bz2 gz zip
 29.1026 -  \end{codesample4}
 29.1027 -\item[\rcitem{web}{allowpull}] Boolean.  Determines whether the web
 29.1028 -  interface allows remote users to \hgcmd{pull} and \hgcmd{clone} this
 29.1029 -  repository over~HTTP.  If set to \texttt{no} or \texttt{false}, only
 29.1030 -  the ``human-oriented'' portion of the web interface is available.
 29.1031 -\item[\rcitem{web}{contact}] String.  A free-form (but preferably
 29.1032 -  brief) string identifying the person or group in charge of the
 29.1033 -  repository.  This often contains the name and email address of a
 29.1034 -  person or mailing list.  It often makes sense to place this entry in
 29.1035 -  a repository's own \sfilename{.hg/hgrc} file, but it can make sense
 29.1036 -  to use in a global \hgrc\ if every repository has a single
 29.1037 -  maintainer.
 29.1038 -\item[\rcitem{web}{maxchanges}] Integer.  The default maximum number
 29.1039 -  of changesets to display in a single page of output.
 29.1040 -\item[\rcitem{web}{maxfiles}] Integer.  The default maximum number
 29.1041 -  of modified files to display in a single page of output.
 29.1042 -\item[\rcitem{web}{stripes}] Integer.  If the web interface displays
 29.1043 -  alternating ``stripes'' to make it easier to visually align rows
 29.1044 -  when you are looking at a table, this number controls the number of
 29.1045 -  rows in each stripe.
 29.1046 -\item[\rcitem{web}{style}] Controls the template Mercurial uses to
 29.1047 -  display the web interface.  Mercurial ships with two web templates,
 29.1048 -  named \texttt{default} and \texttt{gitweb} (the latter is much more
 29.1049 -  visually attractive).  You can also specify a custom template of
 29.1050 -  your own; see chapter~\ref{chap:template} for details.  Here, you
 29.1051 -  can see how to enable the \texttt{gitweb} style.
 29.1052 -  \begin{codesample4}
 29.1053 -    [web]
 29.1054 -    style = gitweb
 29.1055 -  \end{codesample4}
 29.1056 -\item[\rcitem{web}{templates}] Path.  The directory in which to search
 29.1057 -  for template files.  By default, Mercurial searches in the directory
 29.1058 -  in which it was installed.
 29.1059 -\end{itemize}
 29.1060 -If you are using \sfilename{hgwebdir.cgi}, you can place a few
 29.1061 -configuration items in a \rcsection{web} section of the
 29.1062 -\sfilename{hgweb.config} file instead of a \hgrc\ file, for
 29.1063 -convenience.  These items are \rcitem{web}{motd} and
 29.1064 -\rcitem{web}{style}.
 29.1065 -
 29.1066 -\subsubsection{Options specific to an individual repository}
 29.1067 -
 29.1068 -A few \rcsection{web} configuration items ought to be placed in a
 29.1069 -repository's local \sfilename{.hg/hgrc}, rather than a user's or
 29.1070 -global \hgrc.
 29.1071 -\begin{itemize}
 29.1072 -\item[\rcitem{web}{description}] String.  A free-form (but preferably
 29.1073 -  brief) string that describes the contents or purpose of the
 29.1074 -  repository.
 29.1075 -\item[\rcitem{web}{name}] String.  The name to use for the repository
 29.1076 -  in the web interface.  This overrides the default name, which is the
 29.1077 -  last component of the repository's path.
 29.1078 -\end{itemize}
 29.1079 -
 29.1080 -\subsubsection{Options specific to the \hgcmd{serve} command}
 29.1081 -
 29.1082 -Some of the items in the \rcsection{web} section of a \hgrc\ file are
 29.1083 -only for use with the \hgcmd{serve} command.
 29.1084 -\begin{itemize}
 29.1085 -\item[\rcitem{web}{accesslog}] Path.  The name of a file into which to
 29.1086 -  write an access log.  By default, the \hgcmd{serve} command writes
 29.1087 -  this information to standard output, not to a file.  Log entries are
 29.1088 -  written in the standard ``combined'' file format used by almost all
 29.1089 -  web servers.
 29.1090 -\item[\rcitem{web}{address}] String.  The local address on which the
 29.1091 -  server should listen for incoming connections.  By default, the
 29.1092 -  server listens on all addresses.
 29.1093 -\item[\rcitem{web}{errorlog}] Path.  The name of a file into which to
 29.1094 -  write an error log.  By default, the \hgcmd{serve} command writes this
 29.1095 -  information to standard error, not to a file.
 29.1096 -\item[\rcitem{web}{ipv6}] Boolean.  Whether to use the IPv6 protocol.
 29.1097 -  By default, IPv6 is not used. 
 29.1098 -\item[\rcitem{web}{port}] Integer.  The TCP~port number on which the
 29.1099 -  server should listen.  The default port number used is~8000.
 29.1100 -\end{itemize}
 29.1101 -
 29.1102 -\subsubsection{Choosing the right \hgrc\ file to add \rcsection{web}
 29.1103 -  items to}
 29.1104 -
 29.1105 -It is important to remember that a web server like Apache or
 29.1106 -\texttt{lighttpd} will run under a user~ID that is different to yours.
 29.1107 -CGI scripts run by your server, such as \sfilename{hgweb.cgi}, will
 29.1108 -usually also run under that user~ID.
 29.1109 -
 29.1110 -If you add \rcsection{web} items to your own personal \hgrc\ file, CGI
 29.1111 -scripts won't read that \hgrc\ file.  Those settings will thus only
 29.1112 -affect the behaviour of the \hgcmd{serve} command when you run it.  To
 29.1113 -cause CGI scripts to see your settings, either create a \hgrc\ file in
 29.1114 -the home directory of the user ID that runs your web server, or add
 29.1115 -those settings to a system-wide \hgrc\ file.
 29.1116 -
 29.1117 -
 29.1118 -%%% Local Variables: 
 29.1119 -%%% mode: latex
 29.1120 -%%% TeX-master: "00book"
 29.1121 -%%% End: 
    30.1 --- a/fr/concepts.tex	Sun Aug 16 03:41:39 2009 +0200
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,577 +0,0 @@
    30.4 -\chapter{Behind the scenes}
    30.5 -\label{chap:concepts}
    30.6 -
    30.7 -Unlike many revision control systems, the concepts upon which
    30.8 -Mercurial is built are simple enough that it's easy to understand how
    30.9 -the software really works.  Knowing this certainly isn't necessary,
   30.10 -but I find it useful to have a ``mental model'' of what's going on.
   30.11 -
   30.12 -This understanding gives me confidence that Mercurial has been
   30.13 -carefully designed to be both \emph{safe} and \emph{efficient}.  And
   30.14 -just as importantly, if it's easy for me to retain a good idea of what
   30.15 -the software is doing when I perform a revision control task, I'm less
   30.16 -likely to be surprised by its behaviour.
   30.17 -
   30.18 -In this chapter, we'll initially cover the core concepts behind
   30.19 -Mercurial's design, then continue to discuss some of the interesting
   30.20 -details of its implementation.
   30.21 -
   30.22 -\section{Mercurial's historical record}
   30.23 -
   30.24 -\subsection{Tracking the history of a single file}
   30.25 -
   30.26 -When Mercurial tracks modifications to a file, it stores the history
   30.27 -of that file in a metadata object called a \emph{filelog}.  Each entry
   30.28 -in the filelog contains enough information to reconstruct one revision
   30.29 -of the file that is being tracked.  Filelogs are stored as files in
   30.30 -the \sdirname{.hg/store/data} directory.  A filelog contains two kinds
   30.31 -of information: revision data, and an index to help Mercurial to find
   30.32 -a revision efficiently.
   30.33 -
   30.34 -A file that is large, or has a lot of history, has its filelog stored
   30.35 -in separate data (``\texttt{.d}'' suffix) and index (``\texttt{.i}''
   30.36 -suffix) files.  For small files without much history, the revision
   30.37 -data and index are combined in a single ``\texttt{.i}'' file.  The
   30.38 -correspondence between a file in the working directory and the filelog
   30.39 -that tracks its history in the repository is illustrated in
   30.40 -figure~\ref{fig:concepts:filelog}.
   30.41 -
   30.42 -\begin{figure}[ht]
   30.43 -  \centering
   30.44 -  \grafix{filelog}
   30.45 -  \caption{Relationships between files in working directory and
   30.46 -    filelogs in repository}
   30.47 -  \label{fig:concepts:filelog}
   30.48 -\end{figure}
   30.49 -
   30.50 -\subsection{Managing tracked files}
   30.51 -
   30.52 -Mercurial uses a structure called a \emph{manifest} to collect
   30.53 -together information about the files that it tracks.  Each entry in
   30.54 -the manifest contains information about the files present in a single
   30.55 -changeset.  An entry records which files are present in the changeset,
   30.56 -the revision of each file, and a few other pieces of file metadata.
   30.57 -
   30.58 -\subsection{Recording changeset information}
   30.59 -
   30.60 -The \emph{changelog} contains information about each changeset.  Each
   30.61 -revision records who committed a change, the changeset comment, other
   30.62 -pieces of changeset-related information, and the revision of the
   30.63 -manifest to use.
   30.64 -
   30.65 -\subsection{Relationships between revisions}
   30.66 -
   30.67 -Within a changelog, a manifest, or a filelog, each revision stores a
   30.68 -pointer to its immediate parent (or to its two parents, if it's a
   30.69 -merge revision).  As I mentioned above, there are also relationships
   30.70 -between revisions \emph{across} these structures, and they are
   30.71 -hierarchical in nature.
   30.72 -
   30.73 -For every changeset in a repository, there is exactly one revision
   30.74 -stored in the changelog.  Each revision of the changelog contains a
   30.75 -pointer to a single revision of the manifest.  A revision of the
   30.76 -manifest stores a pointer to a single revision of each filelog tracked
   30.77 -when that changeset was created.  These relationships are illustrated
   30.78 -in figure~\ref{fig:concepts:metadata}.
   30.79 -
   30.80 -\begin{figure}[ht]
   30.81 -  \centering
   30.82 -  \grafix{metadata}
   30.83 -  \caption{Metadata relationships}
   30.84 -  \label{fig:concepts:metadata}
   30.85 -\end{figure}
   30.86 -
   30.87 -As the illustration shows, there is \emph{not} a ``one to one''
   30.88 -relationship between revisions in the changelog, manifest, or filelog.
   30.89 -If the manifest hasn't changed between two changesets, the changelog
   30.90 -entries for those changesets will point to the same revision of the
   30.91 -manifest.  If a file that Mercurial tracks hasn't changed between two
   30.92 -changesets, the entry for that file in the two revisions of the
   30.93 -manifest will point to the same revision of its filelog.
   30.94 -
   30.95 -\section{Safe, efficient storage}
   30.96 -
   30.97 -The underpinnings of changelogs, manifests, and filelogs are provided
   30.98 -by a single structure called the \emph{revlog}.
   30.99 -
  30.100 -\subsection{Efficient storage}
  30.101 -
  30.102 -The revlog provides efficient storage of revisions using a
  30.103 -\emph{delta} mechanism.  Instead of storing a complete copy of a file
  30.104 -for each revision, it stores the changes needed to transform an older
  30.105 -revision into the new revision.  For many kinds of file data, these
  30.106 -deltas are typically a fraction of a percent of the size of a full
  30.107 -copy of a file.
  30.108 -
  30.109 -Some obsolete revision control systems can only work with deltas of
  30.110 -text files.  They must either store binary files as complete snapshots
  30.111 -or encoded into a text representation, both of which are wasteful
  30.112 -approaches.  Mercurial can efficiently handle deltas of files with
  30.113 -arbitrary binary contents; it doesn't need to treat text as special.
  30.114 -
  30.115 -\subsection{Safe operation}
  30.116 -\label{sec:concepts:txn}
  30.117 -
  30.118 -Mercurial only ever \emph{appends} data to the end of a revlog file.
  30.119 -It never modifies a section of a file after it has written it.  This
  30.120 -is both more robust and efficient than schemes that need to modify or
  30.121 -rewrite data.
  30.122 -
  30.123 -In addition, Mercurial treats every write as part of a
  30.124 -\emph{transaction} that can span a number of files.  A transaction is
  30.125 -\emph{atomic}: either the entire transaction succeeds and its effects
  30.126 -are all visible to readers in one go, or the whole thing is undone.
  30.127 -This guarantee of atomicity means that if you're running two copies of
  30.128 -Mercurial, where one is reading data and one is writing it, the reader
  30.129 -will never see a partially written result that might confuse it.
  30.130 -
  30.131 -The fact that Mercurial only appends to files makes it easier to
  30.132 -provide this transactional guarantee.  The easier it is to do stuff
  30.133 -like this, the more confident you should be that it's done correctly.
  30.134 -
  30.135 -\subsection{Fast retrieval}
  30.136 -
  30.137 -Mercurial cleverly avoids a pitfall common to all earlier
  30.138 -revision control systems: the problem of \emph{inefficient retrieval}.
  30.139 -Most revision control systems store the contents of a revision as an
  30.140 -incremental series of modifications against a ``snapshot''.  To
  30.141 -reconstruct a specific revision, you must first read the snapshot, and
  30.142 -then every one of the revisions between the snapshot and your target
  30.143 -revision.  The more history that a file accumulates, the more
  30.144 -revisions you must read, hence the longer it takes to reconstruct a
  30.145 -particular revision.
  30.146 -
  30.147 -\begin{figure}[ht]
  30.148 -  \centering
  30.149 -  \grafix{snapshot}
  30.150 -  \caption{Snapshot of a revlog, with incremental deltas}
  30.151 -  \label{fig:concepts:snapshot}
  30.152 -\end{figure}
  30.153 -
  30.154 -The innovation that Mercurial applies to this problem is simple but
  30.155 -effective.  Once the cumulative amount of delta information stored
  30.156 -since the last snapshot exceeds a fixed threshold, it stores a new
  30.157 -snapshot (compressed, of course), instead of another delta.  This
  30.158 -makes it possible to reconstruct \emph{any} revision of a file
  30.159 -quickly.  This approach works so well that it has since been copied by
  30.160 -several other revision control systems.
  30.161 -
  30.162 -Figure~\ref{fig:concepts:snapshot} illustrates the idea.  In an entry
  30.163 -in a revlog's index file, Mercurial stores the range of entries from
  30.164 -the data file that it must read to reconstruct a particular revision.
  30.165 -
  30.166 -\subsubsection{Aside: the influence of video compression}
  30.167 -
  30.168 -If you're familiar with video compression or have ever watched a TV
  30.169 -feed through a digital cable or satellite service, you may know that
  30.170 -most video compression schemes store each frame of video as a delta
  30.171 -against its predecessor frame.  In addition, these schemes use
  30.172 -``lossy'' compression techniques to increase the compression ratio, so
  30.173 -visual errors accumulate over the course of a number of inter-frame
  30.174 -deltas.
  30.175 -
  30.176 -Because it's possible for a video stream to ``drop out'' occasionally
  30.177 -due to signal glitches, and to limit the accumulation of artefacts
  30.178 -introduced by the lossy compression process, video encoders
  30.179 -periodically insert a complete frame (called a ``key frame'') into the
  30.180 -video stream; the next delta is generated against that frame.  This
  30.181 -means that if the video signal gets interrupted, it will resume once
  30.182 -the next key frame is received.  Also, the accumulation of encoding
  30.183 -errors restarts anew with each key frame.
  30.184 -
  30.185 -\subsection{Identification and strong integrity}
  30.186 -
  30.187 -Along with delta or snapshot information, a revlog entry contains a
  30.188 -cryptographic hash of the data that it represents.  This makes it
  30.189 -difficult to forge the contents of a revision, and easy to detect
  30.190 -accidental corruption.  
  30.191 -
  30.192 -Hashes provide more than a mere check against corruption; they are
  30.193 -used as the identifiers for revisions.  The changeset identification
  30.194 -hashes that you see as an end user are from revisions of the
  30.195 -changelog.  Although filelogs and the manifest also use hashes,
  30.196 -Mercurial only uses these behind the scenes.
  30.197 -
  30.198 -Mercurial verifies that hashes are correct when it retrieves file
  30.199 -revisions and when it pulls changes from another repository.  If it
  30.200 -encounters an integrity problem, it will complain and stop whatever
  30.201 -it's doing.
  30.202 -
  30.203 -In addition to the effect it has on retrieval efficiency, Mercurial's
  30.204 -use of periodic snapshots makes it more robust against partial data
  30.205 -corruption.  If a revlog becomes partly corrupted due to a hardware
  30.206 -error or system bug, it's often possible to reconstruct some or most
  30.207 -revisions from the uncorrupted sections of the revlog, both before and
  30.208 -after the corrupted section.  This would not be possible with a
  30.209 -delta-only storage model.
  30.210 -
  30.211 -\section{Revision history, branching,
  30.212 -  and merging}
  30.213 -
  30.214 -Every entry in a Mercurial revlog knows the identity of its immediate
  30.215 -ancestor revision, usually referred to as its \emph{parent}.  In fact,
  30.216 -a revision contains room for not one parent, but two.  Mercurial uses
  30.217 -a special hash, called the ``null ID'', to represent the idea ``there
  30.218 -is no parent here''.  This hash is simply a string of zeroes.
  30.219 -
  30.220 -In figure~\ref{fig:concepts:revlog}, you can see an example of the
  30.221 -conceptual structure of a revlog.  Filelogs, manifests, and changelogs
  30.222 -all have this same structure; they differ only in the kind of data
  30.223 -stored in each delta or snapshot.
  30.224 -
  30.225 -The first revision in a revlog (at the bottom of the image) has the
  30.226 -null ID in both of its parent slots.  For a ``normal'' revision, its
  30.227 -first parent slot contains the ID of its parent revision, and its
  30.228 -second contains the null ID, indicating that the revision has only one
  30.229 -real parent.  Any two revisions that have the same parent ID are
  30.230 -branches.  A revision that represents a merge between branches has two
  30.231 -normal revision IDs in its parent slots.
  30.232 -
  30.233 -\begin{figure}[ht]
  30.234 -  \centering
  30.235 -  \grafix{revlog}
  30.236 -  \caption{}
  30.237 -  \label{fig:concepts:revlog}
  30.238 -\end{figure}
  30.239 -
  30.240 -\section{The working directory}
  30.241 -
  30.242 -In the working directory, Mercurial stores a snapshot of the files
  30.243 -from the repository as of a particular changeset.
  30.244 -
  30.245 -The working directory ``knows'' which changeset it contains.  When you
  30.246 -update the working directory to contain a particular changeset,
  30.247 -Mercurial looks up the appropriate revision of the manifest to find
  30.248 -out which files it was tracking at the time that changeset was
  30.249 -committed, and which revision of each file was then current.  It then
  30.250 -recreates a copy of each of those files, with the same contents it had
  30.251 -when the changeset was committed.
  30.252 -
  30.253 -The \emph{dirstate} contains Mercurial's knowledge of the working
  30.254 -directory.  This details which changeset the working directory is
  30.255 -updated to, and all of the files that Mercurial is tracking in the
  30.256 -working directory.
  30.257 -
  30.258 -Just as a revision of a revlog has room for two parents, so that it
  30.259 -can represent either a normal revision (with one parent) or a merge of
  30.260 -two earlier revisions, the dirstate has slots for two parents.  When
  30.261 -you use the \hgcmd{update} command, the changeset that you update to
  30.262 -is stored in the ``first parent'' slot, and the null ID in the second.
  30.263 -When you \hgcmd{merge} with another changeset, the first parent
  30.264 -remains unchanged, and the second parent is filled in with the
  30.265 -changeset you're merging with.  The \hgcmd{parents} command tells you
  30.266 -what the parents of the dirstate are.
  30.267 -
  30.268 -\subsection{What happens when you commit}
  30.269 -
  30.270 -The dirstate stores parent information for more than just book-keeping
  30.271 -purposes.  Mercurial uses the parents of the dirstate as \emph{the
  30.272 -  parents of a new changeset} when you perform a commit.
  30.273 -
  30.274 -\begin{figure}[ht]
  30.275 -  \centering
  30.276 -  \grafix{wdir}
  30.277 -  \caption{The working directory can have two parents}
  30.278 -  \label{fig:concepts:wdir}
  30.279 -\end{figure}
  30.280 -
  30.281 -Figure~\ref{fig:concepts:wdir} shows the normal state of the working
  30.282 -directory, where it has a single changeset as parent.  That changeset
  30.283 -is the \emph{tip}, the newest changeset in the repository that has no
  30.284 -children.
  30.285 -
  30.286 -\begin{figure}[ht]
  30.287 -  \centering
  30.288 -  \grafix{wdir-after-commit}
  30.289 -  \caption{The working directory gains new parents after a commit}
  30.290 -  \label{fig:concepts:wdir-after-commit}
  30.291 -\end{figure}
  30.292 -
  30.293 -It's useful to think of the working directory as ``the changeset I'm
  30.294 -about to commit''.  Any files that you tell Mercurial that you've
  30.295 -added, removed, renamed, or copied will be reflected in that
  30.296 -changeset, as will modifications to any files that Mercurial is
  30.297 -already tracking; the new changeset will have the parents of the
  30.298 -working directory as its parents.
  30.299 -
  30.300 -After a commit, Mercurial will update the parents of the working
  30.301 -directory, so that the first parent is the ID of the new changeset,
  30.302 -and the second is the null ID.  This is shown in
  30.303 -figure~\ref{fig:concepts:wdir-after-commit}.  Mercurial doesn't touch
  30.304 -any of the files in the working directory when you commit; it just
  30.305 -modifies the dirstate to note its new parents.
  30.306 -
  30.307 -\subsection{Creating a new head}
  30.308 -
  30.309 -It's perfectly normal to update the working directory to a changeset
  30.310 -other than the current tip.  For example, you might want to know what
  30.311 -your project looked like last Tuesday, or you could be looking through
  30.312 -changesets to see which one introduced a bug.  In cases like this, the
  30.313 -natural thing to do is update the working directory to the changeset
  30.314 -you're interested in, and then examine the files in the working
  30.315 -directory directly to see their contents as they were when you
  30.316 -committed that changeset.  The effect of this is shown in
  30.317 -figure~\ref{fig:concepts:wdir-pre-branch}.
  30.318 -
  30.319 -\begin{figure}[ht]
  30.320 -  \centering
  30.321 -  \grafix{wdir-pre-branch}
  30.322 -  \caption{The working directory, updated to an older changeset}
  30.323 -  \label{fig:concepts:wdir-pre-branch}
  30.324 -\end{figure}
  30.325 -
  30.326 -Having updated the working directory to an older changeset, what
  30.327 -happens if you make some changes, and then commit?  Mercurial behaves
  30.328 -in the same way as I outlined above.  The parents of the working
  30.329 -directory become the parents of the new changeset.  This new changeset
  30.330 -has no children, so it becomes the new tip.  And the repository now
  30.331 -contains two changesets that have no children; we call these
  30.332 -\emph{heads}.  You can see the structure that this creates in
  30.333 -figure~\ref{fig:concepts:wdir-branch}.
  30.334 -
  30.335 -\begin{figure}[ht]
  30.336 -  \centering
  30.337 -  \grafix{wdir-branch}
  30.338 -  \caption{After a commit made while synced to an older changeset}
  30.339 -  \label{fig:concepts:wdir-branch}
  30.340 -\end{figure}
  30.341 -
  30.342 -\begin{note}
  30.343 -  If you're new to Mercurial, you should keep in mind a common
  30.344 -  ``error'', which is to use the \hgcmd{pull} command without any
  30.345 -  options.  By default, the \hgcmd{pull} command \emph{does not}
  30.346 -  update the working directory, so you'll bring new changesets into
  30.347 -  your repository, but the working directory will stay synced at the
  30.348 -  same changeset as before the pull.  If you make some changes and
  30.349 -  commit afterwards, you'll thus create a new head, because your
  30.350 -  working directory isn't synced to whatever the current tip is.
  30.351 -
  30.352 -  I put the word ``error'' in quotes because all that you need to do
  30.353 -  to rectify this situation is \hgcmd{merge}, then \hgcmd{commit}.  In
  30.354 -  other words, this almost never has negative consequences; it just
  30.355 -  surprises people.  I'll discuss other ways to avoid this behaviour,
  30.356 -  and why Mercurial behaves in this initially surprising way, later
  30.357 -  on.
  30.358 -\end{note}
  30.359 -
  30.360 -\subsection{Merging heads}
  30.361 -
  30.362 -When you run the \hgcmd{merge} command, Mercurial leaves the first
  30.363 -parent of the working directory unchanged, and sets the second parent
  30.364 -to the changeset you're merging with, as shown in
  30.365 -figure~\ref{fig:concepts:wdir-merge}.
  30.366 -
  30.367 -\begin{figure}[ht]
  30.368 -  \centering
  30.369 -  \grafix{wdir-merge}
  30.370 -  \caption{Merging two heads}
  30.371 -  \label{fig:concepts:wdir-merge}
  30.372 -\end{figure}
  30.373 -
  30.374 -Mercurial also has to modify the working directory, to merge the files
  30.375 -managed in the two changesets.  Simplified a little, the merging
  30.376 -process goes like this, for every file in the manifests of both
  30.377 -changesets.
  30.378 -\begin{itemize}
  30.379 -\item If neither changeset has modified a file, do nothing with that
  30.380 -  file.
  30.381 -\item If one changeset has modified a file, and the other hasn't,
  30.382 -  create the modified copy of the file in the working directory.
  30.383 -\item If one changeset has removed a file, and the other hasn't (or
  30.384 -  has also deleted it), delete the file from the working directory.
  30.385 -\item If one changeset has removed a file, but the other has modified
  30.386 -  the file, ask the user what to do: keep the modified file, or remove
  30.387 -  it?
  30.388 -\item If both changesets have modified a file, invoke an external
  30.389 -  merge program to choose the new contents for the merged file.  This
  30.390 -  may require input from the user.
  30.391 -\item If one changeset has modified a file, and the other has renamed
  30.392 -  or copied the file, make sure that the changes follow the new name
  30.393 -  of the file.
  30.394 -\end{itemize}
  30.395 -There are more details---merging has plenty of corner cases---but
  30.396 -these are the most common choices that are involved in a merge.  As
  30.397 -you can see, most cases are completely automatic, and indeed most
  30.398 -merges finish automatically, without requiring your input to resolve
  30.399 -any conflicts.
  30.400 -
  30.401 -When you're thinking about what happens when you commit after a merge,
  30.402 -once again the working directory is ``the changeset I'm about to
  30.403 -commit''.  After the \hgcmd{merge} command completes, the working
  30.404 -directory has two parents; these will become the parents of the new
  30.405 -changeset.
  30.406 -
  30.407 -Mercurial lets you perform multiple merges, but you must commit the
  30.408 -results of each individual merge as you go.  This is necessary because
  30.409 -Mercurial only tracks two parents for both revisions and the working
  30.410 -directory.  While it would be technically possible to merge multiple
  30.411 -changesets at once, the prospect of user confusion and making a
  30.412 -terrible mess of a merge immediately becomes overwhelming.
  30.413 -
  30.414 -\section{Other interesting design features}
  30.415 -
  30.416 -In the sections above, I've tried to highlight some of the most
  30.417 -important aspects of Mercurial's design, to illustrate that it pays
  30.418 -careful attention to reliability and performance.  However, the
  30.419 -attention to detail doesn't stop there.  There are a number of other
  30.420 -aspects of Mercurial's construction that I personally find
  30.421 -interesting.  I'll detail a few of them here, separate from the ``big
  30.422 -ticket'' items above, so that if you're interested, you can gain a
  30.423 -better idea of the amount of thinking that goes into a well-designed
  30.424 -system.
  30.425 -
  30.426 -\subsection{Clever compression}
  30.427 -
  30.428 -When appropriate, Mercurial will store both snapshots and deltas in
  30.429 -compressed form.  It does this by always \emph{trying to} compress a
  30.430 -snapshot or delta, but only storing the compressed version if it's
  30.431 -smaller than the uncompressed version.
  30.432 -
  30.433 -This means that Mercurial does ``the right thing'' when storing a file
  30.434 -whose native form is compressed, such as a \texttt{zip} archive or a
  30.435 -JPEG image.  When these types of files are compressed a second time,
  30.436 -the resulting file is usually bigger than the once-compressed form,
  30.437 -and so Mercurial will store the plain \texttt{zip} or JPEG.
  30.438 -
  30.439 -Deltas between revisions of a compressed file are usually larger than
  30.440 -snapshots of the file, and Mercurial again does ``the right thing'' in
  30.441 -these cases.  It finds that such a delta exceeds the threshold at
  30.442 -which it should store a complete snapshot of the file, so it stores
  30.443 -the snapshot, again saving space compared to a naive delta-only
  30.444 -approach.
  30.445 -
  30.446 -\subsubsection{Network recompression}
  30.447 -
  30.448 -When storing revisions on disk, Mercurial uses the ``deflate''
  30.449 -compression algorithm (the same one used by the popular \texttt{zip}
  30.450 -archive format), which balances good speed with a respectable
  30.451 -compression ratio.  However, when transmitting revision data over a
  30.452 -network connection, Mercurial uncompresses the compressed revision
  30.453 -data.
  30.454 -
  30.455 -If the connection is over HTTP, Mercurial recompresses the entire
  30.456 -stream of data using a compression algorithm that gives a better
  30.457 -compression ratio (the Burrows-Wheeler algorithm from the widely used
  30.458 -\texttt{bzip2} compression package).  This combination of algorithm
  30.459 -and compression of the entire stream (instead of a revision at a time)
  30.460 -substantially reduces the number of bytes to be transferred, yielding
  30.461 -better network performance over almost all kinds of network.
  30.462 -
  30.463 -(If the connection is over \command{ssh}, Mercurial \emph{doesn't}
  30.464 -recompress the stream, because \command{ssh} can already do this
  30.465 -itself.)
  30.466 -
  30.467 -\subsection{Read/write ordering and atomicity}
  30.468 -
  30.469 -Appending to files isn't the whole story when it comes to guaranteeing
  30.470 -that a reader won't see a partial write.  If you recall
  30.471 -figure~\ref{fig:concepts:metadata}, revisions in the changelog point to
  30.472 -revisions in the manifest, and revisions in the manifest point to
  30.473 -revisions in filelogs.  This hierarchy is deliberate.
  30.474 -
  30.475 -A writer starts a transaction by writing filelog and manifest data,
  30.476 -and doesn't write any changelog data until those are finished.  A
  30.477 -reader starts by reading changelog data, then manifest data, followed
  30.478 -by filelog data.
  30.479 -
  30.480 -Since the writer has always finished writing filelog and manifest data
  30.481 -before it writes to the changelog, a reader will never read a pointer
  30.482 -to a partially written manifest revision from the changelog, and it will
  30.483 -never read a pointer to a partially written filelog revision from the
  30.484 -manifest.
  30.485 -
  30.486 -\subsection{Concurrent access}
  30.487 -
  30.488 -The read/write ordering and atomicity guarantees mean that Mercurial
  30.489 -never needs to \emph{lock} a repository when it's reading data, even
  30.490 -if the repository is being written to while the read is occurring.
  30.491 -This has a big effect on scalability; you can have an arbitrary number
  30.492 -of Mercurial processes safely reading data from a repository safely
  30.493 -all at once, no matter whether it's being written to or not.
  30.494 -
  30.495 -The lockless nature of reading means that if you're sharing a
  30.496 -repository on a multi-user system, you don't need to grant other local
  30.497 -users permission to \emph{write} to your repository in order for them
  30.498 -to be able to clone it or pull changes from it; they only need
  30.499 -\emph{read} permission.  (This is \emph{not} a common feature among
  30.500 -revision control systems, so don't take it for granted!  Most require
  30.501 -readers to be able to lock a repository to access it safely, and this
  30.502 -requires write permission on at least one directory, which of course
  30.503 -makes for all kinds of nasty and annoying security and administrative
  30.504 -problems.)
  30.505 -
  30.506 -Mercurial uses locks to ensure that only one process can write to a
  30.507 -repository at a time (the locking mechanism is safe even over
  30.508 -filesystems that are notoriously hostile to locking, such as NFS).  If
  30.509 -a repository is locked, a writer will wait for a while to retry if the
  30.510 -repository becomes unlocked, but if the repository remains locked for
  30.511 -too long, the process attempting to write will time out after a while.
  30.512 -This means that your daily automated scripts won't get stuck forever
  30.513 -and pile up if a system crashes unnoticed, for example.  (Yes, the
  30.514 -timeout is configurable, from zero to infinity.)
  30.515 -
  30.516 -\subsubsection{Safe dirstate access}
  30.517 -
  30.518 -As with revision data, Mercurial doesn't take a lock to read the
  30.519 -dirstate file; it does acquire a lock to write it.  To avoid the
  30.520 -possibility of reading a partially written copy of the dirstate file,
  30.521 -Mercurial writes to a file with a unique name in the same directory as
  30.522 -the dirstate file, then renames the temporary file atomically to
  30.523 -\filename{dirstate}.  The file named \filename{dirstate} is thus
  30.524 -guaranteed to be complete, not partially written.
  30.525 -
  30.526 -\subsection{Avoiding seeks}
  30.527 -
  30.528 -Critical to Mercurial's performance is the avoidance of seeks of the
  30.529 -disk head, since any seek is far more expensive than even a
  30.530 -comparatively large read operation.
  30.531 -
  30.532 -This is why, for example, the dirstate is stored in a single file.  If
  30.533 -there were a dirstate file per directory that Mercurial tracked, the
  30.534 -disk would seek once per directory.  Instead, Mercurial reads the
  30.535 -entire single dirstate file in one step.
  30.536 -
  30.537 -Mercurial also uses a ``copy on write'' scheme when cloning a
  30.538 -repository on local storage.  Instead of copying every revlog file
  30.539 -from the old repository into the new repository, it makes a ``hard
  30.540 -link'', which is a shorthand way to say ``these two names point to the
  30.541 -same file''.  When Mercurial is about to write to one of a revlog's
  30.542 -files, it checks to see if the number of names pointing at the file is
  30.543 -greater than one.  If it is, more than one repository is using the
  30.544 -file, so Mercurial makes a new copy of the file that is private to
  30.545 -this repository.
  30.546 -
  30.547 -A few revision control developers have pointed out that this idea of
  30.548 -making a complete private copy of a file is not very efficient in its
  30.549 -use of storage.  While this is true, storage is cheap, and this method
  30.550 -gives the highest performance while deferring most book-keeping to the
  30.551 -operating system.  An alternative scheme would most likely reduce
  30.552 -performance and increase the complexity of the software, each of which
  30.553 -is much more important to the ``feel'' of day-to-day use.
  30.554 -
  30.555 -\subsection{Other contents of the dirstate}
  30.556 -
  30.557 -Because Mercurial doesn't force you to tell it when you're modifying a
  30.558 -file, it uses the dirstate to store some extra information so it can
  30.559 -determine efficiently whether you have modified a file.  For each file
  30.560 -in the working directory, it stores the time that it last modified the
  30.561 -file itself, and the size of the file at that time.  
  30.562 -
  30.563 -When you explicitly \hgcmd{add}, \hgcmd{remove}, \hgcmd{rename} or
  30.564 -\hgcmd{copy} files, Mercurial updates the dirstate so that it knows
  30.565 -what to do with those files when you commit.
  30.566 -
  30.567 -When Mercurial is checking the states of files in the working
  30.568 -directory, it first checks a file's modification time.  If that has
  30.569 -not changed, the file must not have been modified.  If the file's size
  30.570 -has changed, the file must have been modified.  If the modification
  30.571 -time has changed, but the size has not, only then does Mercurial need
  30.572 -to read the actual contents of the file to see if they've changed.
  30.573 -Storing these few extra pieces of information dramatically reduces the
  30.574 -amount of data that Mercurial needs to read, which yields large
  30.575 -performance improvements compared to other revision control systems.
  30.576 -
  30.577 -%%% Local Variables: 
  30.578 -%%% mode: latex
  30.579 -%%% TeX-master: "00book"
  30.580 -%%% End:
    31.1 --- a/fr/daily.tex	Sun Aug 16 03:41:39 2009 +0200
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,381 +0,0 @@
    31.4 -\chapter{Mercurial in daily use}
    31.5 -\label{chap:daily}
    31.6 -
    31.7 -\section{Telling Mercurial which files to track}
    31.8 -
    31.9 -Mercurial does not work with files in your repository unless you tell
   31.10 -it to manage them.  The \hgcmd{status} command will tell you which
   31.11 -files Mercurial doesn't know about; it uses a ``\texttt{?}'' to
   31.12 -display such files.
   31.13 -
   31.14 -To tell Mercurial to track a file, use the \hgcmd{add} command.  Once
   31.15 -you have added a file, the entry in the output of \hgcmd{status} for
   31.16 -that file changes from ``\texttt{?}'' to ``\texttt{A}''.
   31.17 -\interaction{daily.files.add}
   31.18 -
   31.19 -After you run a \hgcmd{commit}, the files that you added before the
   31.20 -commit will no longer be listed in the output of \hgcmd{status}.  The
   31.21 -reason for this is that \hgcmd{status} only tells you about
   31.22 -``interesting'' files---those that you have modified or told Mercurial
   31.23 -to do something with---by default.  If you have a repository that
   31.24 -contains thousands of files, you will rarely want to know about files
   31.25 -that Mercurial is tracking, but that have not changed.  (You can still
   31.26 -get this information; we'll return to this later.)
   31.27 -
   31.28 -Once you add a file, Mercurial doesn't do anything with it
   31.29 -immediately.  Instead, it will take a snapshot of the file's state the
   31.30 -next time you perform a commit.  It will then continue to track the
   31.31 -changes you make to the file every time you commit, until you remove
   31.32 -the file.
   31.33 -
   31.34 -\subsection{Explicit versus implicit file naming}
   31.35 -
   31.36 -A useful behaviour that Mercurial has is that if you pass the name of
   31.37 -a directory to a command, every Mercurial command will treat this as
   31.38 -``I want to operate on every file in this directory and its
   31.39 -subdirectories''.
   31.40 -\interaction{daily.files.add-dir}
   31.41 -Notice in this example that Mercurial printed the names of the files
   31.42 -it added, whereas it didn't do so when we added the file named
   31.43 -\filename{a} in the earlier example.
   31.44 -
   31.45 -What's going on is that in the former case, we explicitly named the
   31.46 -file to add on the command line, so the assumption that Mercurial
   31.47 -makes in such cases is that you know what you were doing, and it
   31.48 -doesn't print any output.
   31.49 -
   31.50 -However, when we \emph{imply} the names of files by giving the name of
   31.51 -a directory, Mercurial takes the extra step of printing the name of
   31.52 -each file that it does something with.  This makes it more clear what
   31.53 -is happening, and reduces the likelihood of a silent and nasty
   31.54 -surprise.  This behaviour is common to most Mercurial commands.
   31.55 -
   31.56 -\subsection{Aside: Mercurial tracks files, not directories}
   31.57 -
   31.58 -Mercurial does not track directory information.  Instead, it tracks
   31.59 -the path to a file.  Before creating a file, it first creates any
   31.60 -missing directory components of the path.  After it deletes a file, it
   31.61 -then deletes any empty directories that were in the deleted file's
   31.62 -path.  This sounds like a trivial distinction, but it has one minor
   31.63 -practical consequence: it is not possible to represent a completely
   31.64 -empty directory in Mercurial.
   31.65 -
   31.66 -Empty directories are rarely useful, and there are unintrusive
   31.67 -workarounds that you can use to achieve an appropriate effect.  The
   31.68 -developers of Mercurial thus felt that the complexity that would be
   31.69 -required to manage empty directories was not worth the limited benefit
   31.70 -this feature would bring.
   31.71 -
   31.72 -If you need an empty directory in your repository, there are a few
   31.73 -ways to achieve this. One is to create a directory, then \hgcmd{add} a
   31.74 -``hidden'' file to that directory.  On Unix-like systems, any file
   31.75 -name that begins with a period (``\texttt{.}'') is treated as hidden
   31.76 -by most commands and GUI tools.  This approach is illustrated in
   31.77 -figure~\ref{ex:daily:hidden}.
   31.78 -
   31.79 -\begin{figure}[ht]
   31.80 -  \interaction{daily.files.hidden}
   31.81 -  \caption{Simulating an empty directory using a hidden file}
   31.82 -  \label{ex:daily:hidden}
   31.83 -\end{figure}
   31.84 -
   31.85 -Another way to tackle a need for an empty directory is to simply
   31.86 -create one in your automated build scripts before they will need it.
   31.87 -
   31.88 -\section{How to stop tracking a file}
   31.89 -
   31.90 -Once you decide that a file no longer belongs in your repository, use
   31.91 -the \hgcmd{remove} command; this deletes the file, and tells Mercurial
   31.92 -to stop tracking it.  A removed file is represented in the output of
   31.93 -\hgcmd{status} with a ``\texttt{R}''.
   31.94 -\interaction{daily.files.remove}
   31.95 -
   31.96 -After you \hgcmd{remove} a file, Mercurial will no longer track
   31.97 -changes to that file, even if you recreate a file with the same name
   31.98 -in your working directory.  If you do recreate a file with the same
   31.99 -name and want Mercurial to track the new file, simply \hgcmd{add} it.
  31.100 -Mercurial will know that the newly added file is not related to the
  31.101 -old file of the same name.
  31.102 -
  31.103 -\subsection{Removing a file does not affect its history}
  31.104 -
  31.105 -It is important to understand that removing a file has only two
  31.106 -effects.
  31.107 -\begin{itemize}
  31.108 -\item It removes the current version of the file from the working
  31.109 -  directory.
  31.110 -\item It stops Mercurial from tracking changes to the file, from the
  31.111 -  time of the next commit.
  31.112 -\end{itemize}
  31.113 -Removing a file \emph{does not} in any way alter the \emph{history} of
  31.114 -the file.
  31.115 -
  31.116 -If you update the working directory to a changeset in which a file
  31.117 -that you have removed was still tracked, it will reappear in the
  31.118 -working directory, with the contents it had when you committed that
  31.119 -changeset.  If you then update the working directory to a later
  31.120 -changeset, in which the file had been removed, Mercurial will once
  31.121 -again remove the file from the working directory.
  31.122 -
  31.123 -\subsection{Missing files}
  31.124 -
  31.125 -Mercurial considers a file that you have deleted, but not used
  31.126 -\hgcmd{remove} to delete, to be \emph{missing}.  A missing file is
  31.127 -represented with ``\texttt{!}'' in the output of \hgcmd{status}.
  31.128 -Mercurial commands will not generally do anything with missing files.
  31.129 -\interaction{daily.files.missing}
  31.130 -
  31.131 -If your repository contains a file that \hgcmd{status} reports as
  31.132 -missing, and you want the file to stay gone, you can run
  31.133 -\hgcmdargs{remove}{\hgopt{remove}{--after}} at any time later on, to
  31.134 -tell Mercurial that you really did mean to remove the file.
  31.135 -\interaction{daily.files.remove-after}
  31.136 -
  31.137 -On the other hand, if you deleted the missing file by accident, use
  31.138 -\hgcmdargs{revert}{\emph{filename}} to recover the file.  It will
  31.139 -reappear, in unmodified form.
  31.140 -\interaction{daily.files.recover-missing}
  31.141 -
  31.142 -\subsection{Aside: why tell Mercurial explicitly to 
  31.143 -  remove a file?}
  31.144 -
  31.145 -You might wonder why Mercurial requires you to explicitly tell it that
  31.146 -you are deleting a file.  Early during the development of Mercurial,
  31.147 -it let you delete a file however you pleased; Mercurial would notice
  31.148 -the absence of the file automatically when you next ran a
  31.149 -\hgcmd{commit}, and stop tracking the file.  In practice, this made it
  31.150 -too easy to accidentally remove a file without noticing.
  31.151 -
  31.152 -\subsection{Useful shorthand---adding and removing files
  31.153 -  in one step}
  31.154 -
  31.155 -Mercurial offers a combination command, \hgcmd{addremove}, that adds
  31.156 -untracked files and marks missing files as removed.  
  31.157 -\interaction{daily.files.addremove}
  31.158 -The \hgcmd{commit} command also provides a \hgopt{commit}{-A} option
  31.159 -that performs this same add-and-remove, immediately followed by a
  31.160 -commit.
  31.161 -\interaction{daily.files.commit-addremove}
  31.162 -
  31.163 -\section{Copying files}
  31.164 -
  31.165 -Mercurial provides a \hgcmd{copy} command that lets you make a new
  31.166 -copy of a file.  When you copy a file using this command, Mercurial
  31.167 -makes a record of the fact that the new file is a copy of the original
  31.168 -file.  It treats these copied files specially when you merge your work
  31.169 -with someone else's.
  31.170 -
  31.171 -\subsection{The results of copying during a merge}
  31.172 -
  31.173 -What happens during a merge is that changes ``follow'' a copy.  To
  31.174 -best illustrate what this means, let's create an example.  We'll start
  31.175 -with the usual tiny repository that contains a single file.
  31.176 -\interaction{daily.copy.init}
  31.177 -We need to do some work in parallel, so that we'll have something to
  31.178 -merge.  So let's clone our repository.
  31.179 -\interaction{daily.copy.clone}
  31.180 -Back in our initial repository, let's use the \hgcmd{copy} command to
  31.181 -make a copy of the first file we created.
  31.182 -\interaction{daily.copy.copy}
  31.183 -
  31.184 -If we look at the output of the \hgcmd{status} command afterwards, the
  31.185 -copied file looks just like a normal added file.
  31.186 -\interaction{daily.copy.status}
  31.187 -But if we pass the \hgopt{status}{-C} option to \hgcmd{status}, it
  31.188 -prints another line of output: this is the file that our newly-added
  31.189 -file was copied \emph{from}.
  31.190 -\interaction{daily.copy.status-copy}
  31.191 -
  31.192 -Now, back in the repository we cloned, let's make a change in
  31.193 -parallel.  We'll add a line of content to the original file that we
  31.194 -created.
  31.195 -\interaction{daily.copy.other}
  31.196 -Now we have a modified \filename{file} in this repository.  When we
  31.197 -pull the changes from the first repository, and merge the two heads,
  31.198 -Mercurial will propagate the changes that we made locally to
  31.199 -\filename{file} into its copy, \filename{new-file}.
  31.200 -\interaction{daily.copy.merge}
  31.201 -
  31.202 -\subsection{Why should changes follow copies?}
  31.203 -\label{sec:daily:why-copy}
  31.204 -
  31.205 -This behaviour, of changes to a file propagating out to copies of the
  31.206 -file, might seem esoteric, but in most cases it's highly desirable.
  31.207 -
  31.208 -First of all, remember that this propagation \emph{only} happens when
  31.209 -you merge.  So if you \hgcmd{copy} a file, and subsequently modify the
  31.210 -original file during the normal course of your work, nothing will
  31.211 -happen.
  31.212 -
  31.213 -The second thing to know is that modifications will only propagate
  31.214 -across a copy as long as the repository that you're pulling changes
  31.215 -from \emph{doesn't know} about the copy.
  31.216 -
  31.217 -The reason that Mercurial does this is as follows.  Let's say I make
  31.218 -an important bug fix in a source file, and commit my changes.
  31.219 -Meanwhile, you've decided to \hgcmd{copy} the file in your repository,
  31.220 -without knowing about the bug or having seen the fix, and you have
  31.221 -started hacking on your copy of the file.
  31.222 -
  31.223 -If you pulled and merged my changes, and Mercurial \emph{didn't}
  31.224 -propagate changes across copies, your source file would now contain
  31.225 -the bug, and unless you remembered to propagate the bug fix by hand,
  31.226 -the bug would \emph{remain} in your copy of the file.
  31.227 -
  31.228 -By automatically propagating the change that fixed the bug from the
  31.229 -original file to the copy, Mercurial prevents this class of problem.
  31.230 -To my knowledge, Mercurial is the \emph{only} revision control system
  31.231 -that propagates changes across copies like this.
  31.232 -
  31.233 -Once your change history has a record that the copy and subsequent
  31.234 -merge occurred, there's usually no further need to propagate changes
  31.235 -from the original file to the copied file, and that's why Mercurial
  31.236 -only propagates changes across copies until this point, and no
  31.237 -further.
  31.238 -
  31.239 -\subsection{How to make changes \emph{not} follow a copy}
  31.240 -
  31.241 -If, for some reason, you decide that this business of automatically
  31.242 -propagating changes across copies is not for you, simply use your
  31.243 -system's normal file copy command (on Unix-like systems, that's
  31.244 -\command{cp}) to make a copy of a file, then \hgcmd{add} the new copy
  31.245 -by hand.  Before you do so, though, please do reread
  31.246 -section~\ref{sec:daily:why-copy}, and make an informed decision that
  31.247 -this behaviour is not appropriate to your specific case.
  31.248 -
  31.249 -\subsection{Behaviour of the \hgcmd{copy} command}
  31.250 -
  31.251 -When you use the \hgcmd{copy} command, Mercurial makes a copy of each
  31.252 -source file as it currently stands in the working directory.  This
  31.253 -means that if you make some modifications to a file, then \hgcmd{copy}
  31.254 -it without first having committed those changes, the new copy will
  31.255 -also contain the modifications you have made up until that point.  (I
  31.256 -find this behaviour a little counterintuitive, which is why I mention
  31.257 -it here.)
  31.258 -
  31.259 -The \hgcmd{copy} command acts similarly to the Unix \command{cp}
  31.260 -command (you can use the \hgcmd{cp} alias if you prefer).  The last
  31.261 -argument is the \emph{destination}, and all prior arguments are
  31.262 -\emph{sources}.  If you pass it a single file as the source, and the
  31.263 -destination does not exist, it creates a new file with that name.
  31.264 -\interaction{daily.copy.simple}
  31.265 -If the destination is a directory, Mercurial copies its sources into
  31.266 -that directory.
  31.267 -\interaction{daily.copy.dir-dest}
  31.268 -Copying a directory is recursive, and preserves the directory
  31.269 -structure of the source.
  31.270 -\interaction{daily.copy.dir-src}
  31.271 -If the source and destination are both directories, the source tree is
  31.272 -recreated in the destination directory.
  31.273 -\interaction{daily.copy.dir-src-dest}
  31.274 -
  31.275 -As with the \hgcmd{rename} command, if you copy a file manually and
  31.276 -then want Mercurial to know that you've copied the file, simply use
  31.277 -the \hgopt{copy}{--after} option to \hgcmd{copy}.
  31.278 -\interaction{daily.copy.after}
  31.279 -
  31.280 -\section{Renaming files}
  31.281 -
  31.282 -It's rather more common to need to rename a file than to make a copy
  31.283 -of it.  The reason I discussed the \hgcmd{copy} command before talking
  31.284 -about renaming files is that Mercurial treats a rename in essentially
  31.285 -the same way as a copy.  Therefore, knowing what Mercurial does when
  31.286 -you copy a file tells you what to expect when you rename a file.
  31.287 -
  31.288 -When you use the \hgcmd{rename} command, Mercurial makes a copy of
  31.289 -each source file, then deletes it and marks the file as removed.
  31.290 -\interaction{daily.rename.rename}
  31.291 -The \hgcmd{status} command shows the newly copied file as added, and
  31.292 -the copied-from file as removed.
  31.293 -\interaction{daily.rename.status}
  31.294 -As with the results of a \hgcmd{copy}, we must use the
  31.295 -\hgopt{status}{-C} option to \hgcmd{status} to see that the added file
  31.296 -is really being tracked by Mercurial as a copy of the original, now
  31.297 -removed, file.
  31.298 -\interaction{daily.rename.status-copy}
  31.299 -
  31.300 -As with \hgcmd{remove} and \hgcmd{copy}, you can tell Mercurial about
  31.301 -a rename after the fact using the \hgopt{rename}{--after} option.  In
  31.302 -most other respects, the behaviour of the \hgcmd{rename} command, and
  31.303 -the options it accepts, are similar to the \hgcmd{copy} command.
  31.304 -
  31.305 -\subsection{Renaming files and merging changes}
  31.306 -
  31.307 -Since Mercurial's rename is implemented as copy-and-remove, the same
  31.308 -propagation of changes happens when you merge after a rename as after
  31.309 -a copy.
  31.310 -
  31.311 -If I modify a file, and you rename it to a new name, and then we merge
  31.312 -our respective changes, my modifications to the file under its
  31.313 -original name will be propagated into the file under its new name.
  31.314 -(This is something you might expect to ``simply work,'' but not all
  31.315 -revision control systems actually do this.)
  31.316 -
  31.317 -Whereas having changes follow a copy is a feature where you can
  31.318 -perhaps nod and say ``yes, that might be useful,'' it should be clear
  31.319 -that having them follow a rename is definitely important.  Without
  31.320 -this facility, it would simply be too easy for changes to become
  31.321 -orphaned when files are renamed.
  31.322 -
  31.323 -\subsection{Divergent renames and merging}
  31.324 -
  31.325 -The case of diverging names occurs when two developers start with a
  31.326 -file---let's call it \filename{foo}---in their respective
  31.327 -repositories.
  31.328 -
  31.329 -\interaction{rename.divergent.clone}
  31.330 -Anne renames the file to \filename{bar}.
  31.331 -\interaction{rename.divergent.rename.anne}
  31.332 -Meanwhile, Bob renames it to \filename{quux}.
  31.333 -\interaction{rename.divergent.rename.bob}
  31.334 -
  31.335 -I like to think of this as a conflict because each developer has
  31.336 -expressed different intentions about what the file ought to be named.
  31.337 -
  31.338 -What do you think should happen when they merge their work?
  31.339 -Mercurial's actual behaviour is that it always preserves \emph{both}
  31.340 -names when it merges changesets that contain divergent renames.
  31.341 -\interaction{rename.divergent.merge}
  31.342 -
  31.343 -Notice that Mercurial does warn about the divergent renames, but it
  31.344 -leaves it up to you to do something about the divergence after the merge.
  31.345 -
  31.346 -\subsection{Convergent renames and merging}
  31.347 -
  31.348 -Another kind of rename conflict occurs when two people choose to
  31.349 -rename different \emph{source} files to the same \emph{destination}.
  31.350 -In this case, Mercurial runs its normal merge machinery, and lets you
  31.351 -guide it to a suitable resolution.
  31.352 -
  31.353 -\subsection{Other name-related corner cases}
  31.354 -
  31.355 -Mercurial has a longstanding bug in which it fails to handle a merge
  31.356 -where one side has a file with a given name, while another has a
  31.357 -directory with the same name.  This is documented as~\bug{29}.
  31.358 -\interaction{issue29.go}
  31.359 -
  31.360 -\section{Recovering from mistakes}
  31.361 -
  31.362 -Mercurial has some useful commands that will help you to recover from
  31.363 -some common mistakes.
  31.364 -
  31.365 -The \hgcmd{revert} command lets you undo changes that you have made to
  31.366 -your working directory.  For example, if you \hgcmd{add} a file by
  31.367 -accident, just run \hgcmd{revert} with the name of the file you added,
  31.368 -and while the file won't be touched in any way, it won't be tracked
  31.369 -for adding by Mercurial any longer, either.  You can also use
  31.370 -\hgcmd{revert} to get rid of erroneous changes to a file.
  31.371 -
  31.372 -It's useful to remember that the \hgcmd{revert} command is useful for
  31.373 -changes that you have not yet committed.  Once you've committed a
  31.374 -change, if you decide it was a mistake, you can still do something
  31.375 -about it, though your options may be more limited.
  31.376 -
  31.377 -For more information about the \hgcmd{revert} command, and details
  31.378 -about how to deal with changes you have already committed, see
  31.379 -chapter~\ref{chap:undo}.
  31.380 -
  31.381 -%%% Local Variables: 
  31.382 -%%% mode: latex
  31.383 -%%% TeX-master: "00book"
  31.384 -%%% End: 
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/fr/examples/auto-snippets.xml	Sun Aug 16 04:58:01 2009 +0200
    32.3 @@ -0,0 +1,276 @@
    32.4 +<!ENTITY ch06-apache-config.lst SYSTEM "results/ch06-apache-config.lst.lxo">
    32.5 +<!ENTITY ch09-check_whitespace.py.lst SYSTEM "results/ch09-check_whitespace.py.lst.lxo">
    32.6 +<!ENTITY ch10-bugzilla-config.lst SYSTEM "results/ch10-bugzilla-config.lst.lxo">
    32.7 +<!ENTITY ch10-notify-config-mail.lst SYSTEM "results/ch10-notify-config-mail.lst.lxo">
    32.8 +<!ENTITY ch10-notify-config.lst SYSTEM "results/ch10-notify-config.lst.lxo">
    32.9 +<!ENTITY interaction.backout.init SYSTEM "results/backout.init.lxo">
   32.10 +<!ENTITY interaction.backout.manual.backout SYSTEM "results/backout.manual.backout.lxo">
   32.11 +<!ENTITY interaction.backout.manual.cat SYSTEM "results/backout.manual.cat.lxo">
   32.12 +<!ENTITY interaction.backout.manual.clone SYSTEM "results/backout.manual.clone.lxo">
   32.13 +<!ENTITY interaction.backout.manual.heads SYSTEM "results/backout.manual.heads.lxo">
   32.14 +<!ENTITY interaction.backout.manual.log SYSTEM "results/backout.manual.log.lxo">
   32.15 +<!ENTITY interaction.backout.manual.merge SYSTEM "results/backout.manual.merge.lxo">
   32.16 +<!ENTITY interaction.backout.manual.parents SYSTEM "results/backout.manual.parents.lxo">
   32.17 +<!ENTITY interaction.backout.non-tip.backout SYSTEM "results/backout.non-tip.backout.lxo">
   32.18 +<!ENTITY interaction.backout.non-tip.cat SYSTEM "results/backout.non-tip.cat.lxo">
   32.19 +<!ENTITY interaction.backout.non-tip.clone SYSTEM "results/backout.non-tip.clone.lxo">
   32.20 +<!ENTITY interaction.backout.simple SYSTEM "results/backout.simple.lxo">
   32.21 +<!ENTITY interaction.backout.simple.log SYSTEM "results/backout.simple.log.lxo">
   32.22 +<!ENTITY interaction.bisect.commits SYSTEM "results/bisect.commits.lxo">
   32.23 +<!ENTITY interaction.bisect.help SYSTEM "results/bisect.help.lxo">
   32.24 +<!ENTITY interaction.bisect.init SYSTEM "results/bisect.init.lxo">
   32.25 +<!ENTITY interaction.bisect.search.bad-init SYSTEM "results/bisect.search.bad-init.lxo">
   32.26 +<!ENTITY interaction.bisect.search.good-init SYSTEM "results/bisect.search.good-init.lxo">
   32.27 +<!ENTITY interaction.bisect.search.init SYSTEM "results/bisect.search.init.lxo">
   32.28 +<!ENTITY interaction.bisect.search.mytest SYSTEM "results/bisect.search.mytest.lxo">
   32.29 +<!ENTITY interaction.bisect.search.reset SYSTEM "results/bisect.search.reset.lxo">
   32.30 +<!ENTITY interaction.bisect.search.rest SYSTEM "results/bisect.search.rest.lxo">
   32.31 +<!ENTITY interaction.bisect.search.step1 SYSTEM "results/bisect.search.step1.lxo">
   32.32 +<!ENTITY interaction.bisect.search.step2 SYSTEM "results/bisect.search.step2.lxo">
   32.33 +<!ENTITY interaction.branch-named.branch SYSTEM "results/branch-named.branch.lxo">
   32.34 +<!ENTITY interaction.branch-named.branches SYSTEM "results/branch-named.branches.lxo">
   32.35 +<!ENTITY interaction.branch-named.commit SYSTEM "results/branch-named.commit.lxo">
   32.36 +<!ENTITY interaction.branch-named.create SYSTEM "results/branch-named.create.lxo">
   32.37 +<!ENTITY interaction.branch-named.foo-commit SYSTEM "results/branch-named.foo-commit.lxo">
   32.38 +<!ENTITY interaction.branch-named.merge SYSTEM "results/branch-named.merge.lxo">
   32.39 +<!ENTITY interaction.branch-named.parents SYSTEM "results/branch-named.parents.lxo">
   32.40 +<!ENTITY interaction.branch-named.rebranch SYSTEM "results/branch-named.rebranch.lxo">
   32.41 +<!ENTITY interaction.branch-named.status SYSTEM "results/branch-named.status.lxo">
   32.42 +<!ENTITY interaction.branch-named.update-bar SYSTEM "results/branch-named.update-bar.lxo">
   32.43 +<!ENTITY interaction.branch-named.update-nothing SYSTEM "results/branch-named.update-nothing.lxo">
   32.44 +<!ENTITY interaction.branch-named.update-switchy SYSTEM "results/branch-named.update-switchy.lxo">
   32.45 +<!ENTITY interaction.branch-repo.bugfix SYSTEM "results/branch-repo.bugfix.lxo">
   32.46 +<!ENTITY interaction.branch-repo.clone SYSTEM "results/branch-repo.clone.lxo">
   32.47 +<!ENTITY interaction.branch-repo.merge SYSTEM "results/branch-repo.merge.lxo">
   32.48 +<!ENTITY interaction.branch-repo.new SYSTEM "results/branch-repo.new.lxo">
   32.49 +<!ENTITY interaction.branch-repo.pull SYSTEM "results/branch-repo.pull.lxo">
   32.50 +<!ENTITY interaction.branch-repo.tag SYSTEM "results/branch-repo.tag.lxo">
   32.51 +<!ENTITY interaction.branching.clone SYSTEM "results/branching.clone.lxo">
   32.52 +<!ENTITY interaction.branching.init SYSTEM "results/branching.init.lxo">
   32.53 +<!ENTITY interaction.branching.main SYSTEM "results/branching.main.lxo">
   32.54 +<!ENTITY interaction.branching.merge SYSTEM "results/branching.merge.lxo">
   32.55 +<!ENTITY interaction.branching.stable SYSTEM "results/branching.stable.lxo">
   32.56 +<!ENTITY interaction.branching.tag SYSTEM "results/branching.tag.lxo">
   32.57 +<!ENTITY interaction.branching.update SYSTEM "results/branching.update.lxo">
   32.58 +<!ENTITY interaction.ch01-new.add SYSTEM "results/ch01-new.add.lxo">
   32.59 +<!ENTITY interaction.ch01-new.commit SYSTEM "results/ch01-new.commit.lxo">
   32.60 +<!ENTITY interaction.ch01-new.init SYSTEM "results/ch01-new.init.lxo">
   32.61 +<!ENTITY interaction.ch01-new.ls SYSTEM "results/ch01-new.ls.lxo">
   32.62 +<!ENTITY interaction.ch01-new.ls2 SYSTEM "results/ch01-new.ls2.lxo">
   32.63 +<!ENTITY interaction.ch02-rename.alice SYSTEM "results/ch02-rename.alice.lxo">
   32.64 +<!ENTITY interaction.ch02-rename.bob SYSTEM "results/ch02-rename.bob.lxo">
   32.65 +<!ENTITY interaction.ch02-rename.clone SYSTEM "results/ch02-rename.clone.lxo">
   32.66 +<!ENTITY interaction.ch02-rename.clone2 SYSTEM "results/ch02-rename.clone2.lxo">
   32.67 +<!ENTITY interaction.ch02-rename.init SYSTEM "results/ch02-rename.init.lxo">
   32.68 +<!ENTITY interaction.ch02-rename.merge SYSTEM "results/ch02-rename.merge.lxo">
   32.69 +<!ENTITY interaction.ch02-rename.merge2 SYSTEM "results/ch02-rename.merge2.lxo">
   32.70 +<!ENTITY interaction.ch02-rename.status SYSTEM "results/ch02-rename.status.lxo">
   32.71 +<!ENTITY interaction.ch02-rename.status2 SYSTEM "results/ch02-rename.status2.lxo">
   32.72 +<!ENTITY interaction.ch04-diff.chmod SYSTEM "results/ch04-diff.chmod.lxo">
   32.73 +<!ENTITY interaction.ch04-diff.chmod.git SYSTEM "results/ch04-diff.chmod.git.lxo">
   32.74 +<!ENTITY interaction.ch04-diff.rename.basic SYSTEM "results/ch04-diff.rename.basic.lxo">
   32.75 +<!ENTITY interaction.ch04-diff.rename.git SYSTEM "results/ch04-diff.rename.git.lxo">
   32.76 +<!ENTITY interaction.ch04-rename.basic SYSTEM "results/ch04-rename.basic.lxo">
   32.77 +<!ENTITY interaction.ch04-resolve.cifail SYSTEM "results/ch04-resolve.cifail.lxo">
   32.78 +<!ENTITY interaction.ch04-resolve.export SYSTEM "results/ch04-resolve.export.lxo">
   32.79 +<!ENTITY interaction.ch04-resolve.heads SYSTEM "results/ch04-resolve.heads.lxo">
   32.80 +<!ENTITY interaction.ch04-resolve.init SYSTEM "results/ch04-resolve.init.lxo">
   32.81 +<!ENTITY interaction.ch04-resolve.left SYSTEM "results/ch04-resolve.left.lxo">
   32.82 +<!ENTITY interaction.ch04-resolve.list SYSTEM "results/ch04-resolve.list.lxo">
   32.83 +<!ENTITY interaction.ch04-resolve.merge SYSTEM "results/ch04-resolve.merge.lxo">
   32.84 +<!ENTITY interaction.ch04-resolve.pull SYSTEM "results/ch04-resolve.pull.lxo">
   32.85 +<!ENTITY interaction.ch04-resolve.right SYSTEM "results/ch04-resolve.right.lxo">
   32.86 +<!ENTITY interaction.ch09-hook.ws.better SYSTEM "results/ch09-hook.ws.better.lxo">
   32.87 +<!ENTITY interaction.ch09-hook.ws.simple SYSTEM "results/ch09-hook.ws.simple.lxo">
   32.88 +<!ENTITY interaction.ch10-multiline.go SYSTEM "results/ch10-multiline.go.lxo">
   32.89 +<!ENTITY interaction.ch10-multiline.orig.go SYSTEM "results/ch10-multiline.orig.go.lxo">
   32.90 +<!ENTITY interaction.ch11-qdelete.convert SYSTEM "results/ch11-qdelete.convert.lxo">
   32.91 +<!ENTITY interaction.ch11-qdelete.go SYSTEM "results/ch11-qdelete.go.lxo">
   32.92 +<!ENTITY interaction.ch11-qdelete.import SYSTEM "results/ch11-qdelete.import.lxo">
   32.93 +<!ENTITY interaction.cmdref.diff-p SYSTEM "results/cmdref.diff-p.lxo">
   32.94 +<!ENTITY interaction.daily.copy.after SYSTEM "results/daily.copy.after.lxo">
   32.95 +<!ENTITY interaction.daily.copy.cat SYSTEM "results/daily.copy.cat.lxo">
   32.96 +<!ENTITY interaction.daily.copy.clone SYSTEM "results/daily.copy.clone.lxo">
   32.97 +<!ENTITY interaction.daily.copy.copy SYSTEM "results/daily.copy.copy.lxo">
   32.98 +<!ENTITY interaction.daily.copy.dir-dest SYSTEM "results/daily.copy.dir-dest.lxo">
   32.99 +<!ENTITY interaction.daily.copy.dir-src SYSTEM "results/daily.copy.dir-src.lxo">
  32.100 +<!ENTITY interaction.daily.copy.dir-src-dest SYSTEM "results/daily.copy.dir-src-dest.lxo">
  32.101 +<!ENTITY interaction.daily.copy.init SYSTEM "results/daily.copy.init.lxo">
  32.102 +<!ENTITY interaction.daily.copy.merge SYSTEM "results/daily.copy.merge.lxo">
  32.103 +<!ENTITY interaction.daily.copy.orig.after SYSTEM "results/daily.copy.orig.after.lxo">
  32.104 +<!ENTITY interaction.daily.copy.orig.cat SYSTEM "results/daily.copy.orig.cat.lxo">
  32.105 +<!ENTITY interaction.daily.copy.orig.clone SYSTEM "results/daily.copy.orig.clone.lxo">
  32.106 +<!ENTITY interaction.daily.copy.orig.copy SYSTEM "results/daily.copy.orig.copy.lxo">
  32.107 +<!ENTITY interaction.daily.copy.orig.dir-dest SYSTEM "results/daily.copy.orig.dir-dest.lxo">
  32.108 +<!ENTITY interaction.daily.copy.orig.dir-src SYSTEM "results/daily.copy.orig.dir-src.lxo">
  32.109 +<!ENTITY interaction.daily.copy.orig.dir-src-dest SYSTEM "results/daily.copy.orig.dir-src-dest.lxo">
  32.110 +<!ENTITY interaction.daily.copy.orig.init SYSTEM "results/daily.copy.orig.init.lxo">
  32.111 +<!ENTITY interaction.daily.copy.orig.merge SYSTEM "results/daily.copy.orig.merge.lxo">
  32.112 +<!ENTITY interaction.daily.copy.orig.other SYSTEM "results/daily.copy.orig.other.lxo">
  32.113 +<!ENTITY interaction.daily.copy.orig.simple SYSTEM "results/daily.copy.orig.simple.lxo">
  32.114 +<!ENTITY interaction.daily.copy.orig.status SYSTEM "results/daily.copy.orig.status.lxo">
  32.115 +<!ENTITY interaction.daily.copy.orig.status-copy SYSTEM "results/daily.copy.orig.status-copy.lxo">
  32.116 +<!ENTITY interaction.daily.copy.other SYSTEM "results/daily.copy.other.lxo">
  32.117 +<!ENTITY interaction.daily.copy.simple SYSTEM "results/daily.copy.simple.lxo">
  32.118 +<!ENTITY interaction.daily.copy.status SYSTEM "results/daily.copy.status.lxo">
  32.119 +<!ENTITY interaction.daily.copy.status-copy SYSTEM "results/daily.copy.status-copy.lxo">
  32.120 +<!ENTITY interaction.daily.files.add SYSTEM "results/daily.files.add.lxo">
  32.121 +<!ENTITY interaction.daily.files.add-dir SYSTEM "results/daily.files.add-dir.lxo">
  32.122 +<!ENTITY interaction.daily.files.addremove SYSTEM "results/daily.files.addremove.lxo">
  32.123 +<!ENTITY interaction.daily.files.commit-addremove SYSTEM "results/daily.files.commit-addremove.lxo">
  32.124 +<!ENTITY interaction.daily.files.hidden SYSTEM "results/daily.files.hidden.lxo">
  32.125 +<!ENTITY interaction.daily.files.missing SYSTEM "results/daily.files.missing.lxo">
  32.126 +<!ENTITY interaction.daily.files.recover-missing SYSTEM "results/daily.files.recover-missing.lxo">
  32.127 +<!ENTITY interaction.daily.files.remove SYSTEM "results/daily.files.remove.lxo">
  32.128 +<!ENTITY interaction.daily.files.remove-after SYSTEM "results/daily.files.remove-after.lxo">
  32.129 +<!ENTITY interaction.daily.rename.rename SYSTEM "results/daily.rename.rename.lxo">
  32.130 +<!ENTITY interaction.daily.rename.status SYSTEM "results/daily.rename.status.lxo">
  32.131 +<!ENTITY interaction.daily.rename.status-copy SYSTEM "results/daily.rename.status-copy.lxo">
  32.132 +<!ENTITY interaction.daily.revert.add SYSTEM "results/daily.revert.add.lxo">
  32.133 +<!ENTITY interaction.daily.revert.copy SYSTEM "results/daily.revert.copy.lxo">
  32.134 +<!ENTITY interaction.daily.revert.missing SYSTEM "results/daily.revert.missing.lxo">
  32.135 +<!ENTITY interaction.daily.revert.modify SYSTEM "results/daily.revert.modify.lxo">
  32.136 +<!ENTITY interaction.daily.revert.remove SYSTEM "results/daily.revert.remove.lxo">
  32.137 +<!ENTITY interaction.daily.revert.rename SYSTEM "results/daily.revert.rename.lxo">
  32.138 +<!ENTITY interaction.daily.revert.rename-orig SYSTEM "results/daily.revert.rename-orig.lxo">
  32.139 +<!ENTITY interaction.daily.revert.status SYSTEM "results/daily.revert.status.lxo">
  32.140 +<!ENTITY interaction.daily.revert.unmodify SYSTEM "results/daily.revert.unmodify.lxo">
  32.141 +<!ENTITY interaction.extdiff.diff SYSTEM "results/extdiff.diff.lxo">
  32.142 +<!ENTITY interaction.extdiff.extdiff SYSTEM "results/extdiff.extdiff.lxo">
  32.143 +<!ENTITY interaction.extdiff.extdiff-ctx SYSTEM "results/extdiff.extdiff-ctx.lxo">
  32.144 +<!ENTITY interaction.filenames.dirs SYSTEM "results/filenames.dirs.lxo">
  32.145 +<!ENTITY interaction.filenames.files SYSTEM "results/filenames.files.lxo">
  32.146 +<!ENTITY interaction.filenames.filter.exclude SYSTEM "results/filenames.filter.exclude.lxo">
  32.147 +<!ENTITY interaction.filenames.filter.include SYSTEM "results/filenames.filter.include.lxo">
  32.148 +<!ENTITY interaction.filenames.glob.group SYSTEM "results/filenames.glob.group.lxo">
  32.149 +<!ENTITY interaction.filenames.glob.question SYSTEM "results/filenames.glob.question.lxo">
  32.150 +<!ENTITY interaction.filenames.glob.range SYSTEM "results/filenames.glob.range.lxo">
  32.151 +<!ENTITY interaction.filenames.glob.star SYSTEM "results/filenames.glob.star.lxo">
  32.152 +<!ENTITY interaction.filenames.glob.star-starstar SYSTEM "results/filenames.glob.star-starstar.lxo">
  32.153 +<!ENTITY interaction.filenames.glob.starstar SYSTEM "results/filenames.glob.starstar.lxo">
  32.154 +<!ENTITY interaction.filenames.wdir-relname SYSTEM "results/filenames.wdir-relname.lxo">
  32.155 +<!ENTITY interaction.filenames.wdir-subdir SYSTEM "results/filenames.wdir-subdir.lxo">
  32.156 +<!ENTITY interaction.hook.msglen.go SYSTEM "results/hook.msglen.go.lxo">
  32.157 +<!ENTITY interaction.hook.simple.ext SYSTEM "results/hook.simple.ext.lxo">
  32.158 +<!ENTITY interaction.hook.simple.init SYSTEM "results/hook.simple.init.lxo">
  32.159 +<!ENTITY interaction.hook.simple.pretxncommit SYSTEM "results/hook.simple.pretxncommit.lxo">
  32.160 +<!ENTITY interaction.issue29.go SYSTEM "results/issue29.go.lxo">
  32.161 +<!ENTITY interaction.mq.dodiff.diff SYSTEM "results/mq.dodiff.diff.lxo">
  32.162 +<!ENTITY interaction.mq.guards.init SYSTEM "results/mq.guards.init.lxo">
  32.163 +<!ENTITY interaction.mq.guards.qguard SYSTEM "results/mq.guards.qguard.lxo">
  32.164 +<!ENTITY interaction.mq.guards.qguard.neg SYSTEM "results/mq.guards.qguard.neg.lxo">
  32.165 +<!ENTITY interaction.mq.guards.qguard.pos SYSTEM "results/mq.guards.qguard.pos.lxo">
  32.166 +<!ENTITY interaction.mq.guards.qselect.cat SYSTEM "results/mq.guards.qselect.cat.lxo">
  32.167 +<!ENTITY interaction.mq.guards.qselect.error SYSTEM "results/mq.guards.qselect.error.lxo">
  32.168 +<!ENTITY interaction.mq.guards.qselect.foo SYSTEM "results/mq.guards.qselect.foo.lxo">
  32.169 +<!ENTITY interaction.mq.guards.qselect.foobar SYSTEM "results/mq.guards.qselect.foobar.lxo">
  32.170 +<!ENTITY interaction.mq.guards.qselect.qpush SYSTEM "results/mq.guards.qselect.qpush.lxo">
  32.171 +<!ENTITY interaction.mq.guards.qselect.quux SYSTEM "results/mq.guards.qselect.quux.lxo">
  32.172 +<!ENTITY interaction.mq.guards.series SYSTEM "results/mq.guards.series.lxo">
  32.173 +<!ENTITY interaction.mq.id.lxoput SYSTEM "results/mq.id.lxoput.lxo">
  32.174 +<!ENTITY interaction.mq.id.output SYSTEM "results/mq.id.output.lxo">
  32.175 +<!ENTITY interaction.mq.qinit-help.help SYSTEM "results/mq.qinit-help.help.lxo">
  32.176 +<!ENTITY interaction.mq.tarball.download SYSTEM "results/mq.tarball.download.lxo">
  32.177 +<!ENTITY interaction.mq.tarball.newsource SYSTEM "results/mq.tarball.newsource.lxo">
  32.178 +<!ENTITY interaction.mq.tarball.qinit SYSTEM "results/mq.tarball.qinit.lxo">
  32.179 +<!ENTITY interaction.mq.tarball.repush SYSTEM "results/mq.tarball.repush.lxo">
  32.180 +<!ENTITY interaction.mq.tools.lsdiff SYSTEM "results/mq.tools.lsdiff.lxo">
  32.181 +<!ENTITY interaction.mq.tools.tools SYSTEM "results/mq.tools.tools.lxo">
  32.182 +<!ENTITY interaction.mq.tutorial.add SYSTEM "results/mq.tutorial.add.lxo">
  32.183 +<!ENTITY interaction.mq.tutorial.qinit SYSTEM "results/mq.tutorial.qinit.lxo">
  32.184 +<!ENTITY interaction.mq.tutorial.qnew SYSTEM "results/mq.tutorial.qnew.lxo">
  32.185 +<!ENTITY interaction.mq.tutorial.qnew2 SYSTEM "results/mq.tutorial.qnew2.lxo">
  32.186 +<!ENTITY interaction.mq.tutorial.qpop SYSTEM "results/mq.tutorial.qpop.lxo">
  32.187 +<!ENTITY interaction.mq.tutorial.qpush-a SYSTEM "results/mq.tutorial.qpush-a.lxo">
  32.188 +<!ENTITY interaction.mq.tutorial.qrefresh SYSTEM "results/mq.tutorial.qrefresh.lxo">
  32.189 +<!ENTITY interaction.mq.tutorial.qrefresh2 SYSTEM "results/mq.tutorial.qrefresh2.lxo">
  32.190 +<!ENTITY interaction.mq.tutorial.qseries SYSTEM "results/mq.tutorial.qseries.lxo">
  32.191 +<!ENTITY interaction.rename.divergent.clone SYSTEM "results/rename.divergent.clone.lxo">
  32.192 +<!ENTITY interaction.rename.divergent.merge SYSTEM "results/rename.divergent.merge.lxo">
  32.193 +<!ENTITY interaction.rename.divergent.rename.anne SYSTEM "results/rename.divergent.rename.anne.lxo">
  32.194 +<!ENTITY interaction.rename.divergent.rename.bob SYSTEM "results/rename.divergent.rename.bob.lxo">
  32.195 +<!ENTITY interaction.rollback.add SYSTEM "results/rollback.add.lxo">
  32.196 +<!ENTITY interaction.rollback.commit SYSTEM "results/rollback.commit.lxo">
  32.197 +<!ENTITY interaction.rollback.rollback SYSTEM "results/rollback.rollback.lxo">
  32.198 +<!ENTITY interaction.rollback.status SYSTEM "results/rollback.status.lxo">
  32.199 +<!ENTITY interaction.rollback.tip SYSTEM "results/rollback.tip.lxo">
  32.200 +<!ENTITY interaction.rollback.twice SYSTEM "results/rollback.twice.lxo">
  32.201 +<!ENTITY interaction.tag.init SYSTEM "results/tag.init.lxo">
  32.202 +<!ENTITY interaction.tag.log SYSTEM "results/tag.log.lxo">
  32.203 +<!ENTITY interaction.tag.log.v1.0 SYSTEM "results/tag.log.v1.0.lxo">
  32.204 +<!ENTITY interaction.tag.remove SYSTEM "results/tag.remove.lxo">
  32.205 +<!ENTITY interaction.tag.replace SYSTEM "results/tag.replace.lxo">
  32.206 +<!ENTITY interaction.tag.tag SYSTEM "results/tag.tag.lxo">
  32.207 +<!ENTITY interaction.tag.tags SYSTEM "results/tag.tags.lxo">
  32.208 +<!ENTITY interaction.tag.tip SYSTEM "results/tag.tip.lxo">
  32.209 +<!ENTITY interaction.template.simple.changelog SYSTEM "results/template.simple.changelog.lxo">
  32.210 +<!ENTITY interaction.template.simple.combine SYSTEM "results/template.simple.combine.lxo">
  32.211 +<!ENTITY interaction.template.simple.compact SYSTEM "results/template.simple.compact.lxo">
  32.212 +<!ENTITY interaction.template.simple.datekeyword SYSTEM "results/template.simple.datekeyword.lxo">
  32.213 +<!ENTITY interaction.template.simple.keywords SYSTEM "results/template.simple.keywords.lxo">
  32.214 +<!ENTITY interaction.template.simple.manyfilters SYSTEM "results/template.simple.manyfilters.lxo">
  32.215 +<!ENTITY interaction.template.simple.normal SYSTEM "results/template.simple.normal.lxo">
  32.216 +<!ENTITY interaction.template.simple.rev SYSTEM "results/template.simple.rev.lxo">
  32.217 +<!ENTITY interaction.template.simple.simplest SYSTEM "results/template.simple.simplest.lxo">
  32.218 +<!ENTITY interaction.template.simple.simplesub SYSTEM "results/template.simple.simplesub.lxo">
  32.219 +<!ENTITY interaction.template.svnstyle.id SYSTEM "results/template.svnstyle.id.lxo">
  32.220 +<!ENTITY interaction.template.svnstyle.result SYSTEM "results/template.svnstyle.result.lxo">
  32.221 +<!ENTITY interaction.template.svnstyle.short SYSTEM "results/template.svnstyle.short.lxo">
  32.222 +<!ENTITY interaction.template.svnstyle.simplest SYSTEM "results/template.svnstyle.simplest.lxo">
  32.223 +<!ENTITY interaction.template.svnstyle.style SYSTEM "results/template.svnstyle.style.lxo">
  32.224 +<!ENTITY interaction.template.svnstyle.syntax.error SYSTEM "results/template.svnstyle.syntax.error.lxo">
  32.225 +<!ENTITY interaction.template.svnstyle.syntax.input SYSTEM "results/template.svnstyle.syntax.input.lxo">
  32.226 +<!ENTITY interaction.template.svnstyle.template SYSTEM "results/template.svnstyle.template.lxo">
  32.227 +<!ENTITY interaction.tour-merge-conflict.commit SYSTEM "results/tour-merge-conflict.commit.lxo">
  32.228 +<!ENTITY interaction.tour-merge-conflict.cousin SYSTEM "results/tour-merge-conflict.cousin.lxo">
  32.229 +<!ENTITY interaction.tour-merge-conflict.merge SYSTEM "results/tour-merge-conflict.merge.lxo">
  32.230 +<!ENTITY interaction.tour-merge-conflict.pull SYSTEM "results/tour-merge-conflict.pull.lxo">
  32.231 +<!ENTITY interaction.tour-merge-conflict.son SYSTEM "results/tour-merge-conflict.son.lxo">
  32.232 +<!ENTITY interaction.tour-merge-conflict.wife SYSTEM "results/tour-merge-conflict.wife.lxo">
  32.233 +<!ENTITY interaction.tour.cat1 SYSTEM "results/tour.cat1.lxo">
  32.234 +<!ENTITY interaction.tour.cat2 SYSTEM "results/tour.cat2.lxo">
  32.235 +<!ENTITY interaction.tour.clone SYSTEM "results/tour.clone.lxo">
  32.236 +<!ENTITY interaction.tour.clone-pull SYSTEM "results/tour.clone-pull.lxo">
  32.237 +<!ENTITY interaction.tour.clone-push SYSTEM "results/tour.clone-push.lxo">
  32.238 +<!ENTITY interaction.tour.commit SYSTEM "results/tour.commit.lxo">
  32.239 +<!ENTITY interaction.tour.diff SYSTEM "results/tour.diff.lxo">
  32.240 +<!ENTITY interaction.tour.help SYSTEM "results/tour.help.lxo">
  32.241 +<!ENTITY interaction.tour.incoming SYSTEM "results/tour.incoming.lxo">
  32.242 +<!ENTITY interaction.tour.log SYSTEM "results/tour.log.lxo">
  32.243 +<!ENTITY interaction.tour.log-r SYSTEM "results/tour.log-r.lxo">
  32.244 +<!ENTITY interaction.tour.log-v SYSTEM "results/tour.log-v.lxo">
  32.245 +<!ENTITY interaction.tour.log-vp SYSTEM "results/tour.log-vp.lxo">
  32.246 +<!ENTITY interaction.tour.log.range SYSTEM "results/tour.log.range.lxo">
  32.247 +<!ENTITY interaction.tour.ls SYSTEM "results/tour.ls.lxo">
  32.248 +<!ENTITY interaction.tour.ls-a SYSTEM "results/tour.ls-a.lxo">
  32.249 +<!ENTITY interaction.tour.lxogoing SYSTEM "results/tour.lxogoing.lxo">
  32.250 +<!ENTITY interaction.tour.lxogoing.net SYSTEM "results/tour.lxogoing.net.lxo">
  32.251 +<!ENTITY interaction.tour.merge.cat SYSTEM "results/tour.merge.cat.lxo">
  32.252 +<!ENTITY interaction.tour.merge.cat1 SYSTEM "results/tour.merge.cat1.lxo">
  32.253 +<!ENTITY interaction.tour.merge.cat2 SYSTEM "results/tour.merge.cat2.lxo">
  32.254 +<!ENTITY interaction.tour.merge.clone SYSTEM "results/tour.merge.clone.lxo">
  32.255 +<!ENTITY interaction.tour.merge.commit SYSTEM "results/tour.merge.commit.lxo">
  32.256 +<!ENTITY interaction.tour.merge.dummy1 SYSTEM "results/tour.merge.dummy1.lxo">
  32.257 +<!ENTITY interaction.tour.merge.dummy2 SYSTEM "results/tour.merge.dummy2.lxo">
  32.258 +<!ENTITY interaction.tour.merge.dummy3 SYSTEM "results/tour.merge.dummy3.lxo">
  32.259 +<!ENTITY interaction.tour.merge.dummy4 SYSTEM "results/tour.merge.dummy4.lxo">
  32.260 +<!ENTITY interaction.tour.merge.heads SYSTEM "results/tour.merge.heads.lxo">
  32.261 +<!ENTITY interaction.tour.merge.merge SYSTEM "results/tour.merge.merge.lxo">
  32.262 +<!ENTITY interaction.tour.merge.parents SYSTEM "results/tour.merge.parents.lxo">
  32.263 +<!ENTITY interaction.tour.merge.pull SYSTEM "results/tour.merge.pull.lxo">
  32.264 +<!ENTITY interaction.tour.merge.tip SYSTEM "results/tour.merge.tip.lxo">
  32.265 +<!ENTITY interaction.tour.merge.update SYSTEM "results/tour.merge.update.lxo">
  32.266 +<!ENTITY interaction.tour.older SYSTEM "results/tour.older.lxo">
  32.267 +<!ENTITY interaction.tour.outgoing SYSTEM "results/tour.outgoing.lxo">
  32.268 +<!ENTITY interaction.tour.outgoing.net SYSTEM "results/tour.outgoing.net.lxo">
  32.269 +<!ENTITY interaction.tour.parents SYSTEM "results/tour.parents.lxo">
  32.270 +<!ENTITY interaction.tour.pull SYSTEM "results/tour.pull.lxo">
  32.271 +<!ENTITY interaction.tour.push SYSTEM "results/tour.push.lxo">
  32.272 +<!ENTITY interaction.tour.push.net SYSTEM "results/tour.push.net.lxo">
  32.273 +<!ENTITY interaction.tour.push.nothing SYSTEM "results/tour.push.nothing.lxo">
  32.274 +<!ENTITY interaction.tour.reclone SYSTEM "results/tour.reclone.lxo">
  32.275 +<!ENTITY interaction.tour.sed SYSTEM "results/tour.sed.lxo">
  32.276 +<!ENTITY interaction.tour.status SYSTEM "results/tour.status.lxo">
  32.277 +<!ENTITY interaction.tour.tip SYSTEM "results/tour.tip.lxo">
  32.278 +<!ENTITY interaction.tour.update SYSTEM "results/tour.update.lxo">
  32.279 +<!ENTITY interaction.tour.version SYSTEM "results/tour.version.lxo">
    33.1 --- a/fr/examples/data/check_whitespace.py	Sun Aug 16 03:41:39 2009 +0200
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,44 +0,0 @@
    33.4 -#!/usr/bin/python
    33.5 -
    33.6 -import re
    33.7 -
    33.8 -def trailing_whitespace(difflines):
    33.9 -    added, linenum, header = [], 0, False
   33.10 -
   33.11 -    for line in difflines:
   33.12 -        if header:
   33.13 -            # remember the name of the file that this diff affects
   33.14 -            m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)
   33.15 -            if m and m.group(1) != '/dev/null':
   33.16 -                filename = m.group(1).split('/', 1)[-1]
   33.17 -            if line.startswith('+++ '):
   33.18 -                header = False
   33.19 -            continue
   33.20 -        if line.startswith('diff '):
   33.21 -            header = True
   33.22 -            continue
   33.23 -        # hunk header - save the line number
   33.24 -        m = re.match(r'@@ -\d+,\d+ \+(\d+),', line)
   33.25 -        if m:
   33.26 -            linenum = int(m.group(1))
   33.27 -            continue
   33.28 -        # hunk body - check for an added line with trailing whitespace
   33.29 -        m = re.match(r'\+.*\s$', line)
   33.30 -        if m:
   33.31 -            added.append((filename, linenum))
   33.32 -        if line and line[0] in ' +':
   33.33 -            linenum += 1
   33.34 -    return added
   33.35 -
   33.36 -if __name__ == '__main__':
   33.37 -    import os, sys
   33.38 -    
   33.39 -    added = trailing_whitespace(os.popen('hg export tip'))
   33.40 -    if added:
   33.41 -        for filename, linenum in added:
   33.42 -            print >> sys.stderr, ('%s, line %d: trailing whitespace added' %
   33.43 -                                  (filename, linenum))
   33.44 -        # save the commit message so we don't need to retype it
   33.45 -        os.system('hg tip --template "{desc}" > .hg/commit.save')
   33.46 -        print >> sys.stderr, 'commit message saved to .hg/commit.save'
   33.47 -        sys.exit(1)
    34.1 --- a/fr/examples/hook.ws	Sun Aug 16 03:41:39 2009 +0200
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,31 +0,0 @@
    34.4 -#!/bin/bash
    34.5 -
    34.6 -hg init a
    34.7 -cd a
    34.8 -echo '[hooks]' > .hg/hgrc
    34.9 -echo "pretxncommit.whitespace = hg export tip | (! egrep -q '^\\+.*[ \\t]$')" >> .hg/hgrc
   34.10 -
   34.11 -#$ name: simple
   34.12 -
   34.13 -cat .hg/hgrc
   34.14 -echo 'a ' > a
   34.15 -hg commit -A -m 'test with trailing whitespace'
   34.16 -echo 'a' > a
   34.17 -hg commit -A -m 'drop trailing whitespace and try again'
   34.18 -
   34.19 -#$ name:
   34.20 -
   34.21 -echo '[hooks]' > .hg/hgrc
   34.22 -echo "pretxncommit.whitespace = .hg/check_whitespace.py" >> .hg/hgrc
   34.23 -cp $EXAMPLE_DIR/data/check_whitespace.py .hg
   34.24 -
   34.25 -#$ name: better
   34.26 -
   34.27 -cat .hg/hgrc
   34.28 -echo 'a ' >> a
   34.29 -hg commit -A -m 'add new line with trailing whitespace'
   34.30 -sed -i 's, *$,,' a
   34.31 -hg commit -A -m 'trimmed trailing whitespace'
   34.32 -
   34.33 -#$ name:
   34.34 -exit 0
    35.1 --- a/fr/feature-branches.dot	Sun Aug 16 03:41:39 2009 +0200
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,8 +0,0 @@
    35.4 -digraph feature_branches {
    35.5 -	master -> crypto;
    35.6 -	master -> filesystems;
    35.7 -	master -> ipc;
    35.8 -	master -> memory;
    35.9 -	master -> network;
   35.10 -	master -> security;
   35.11 -}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/fr/figs/bad-merge-1.dot	Sun Aug 16 04:58:01 2009 +0200
    36.3 @@ -0,0 +1,13 @@
    36.4 +digraph bad_merge_1 {
    36.5 +	ancestor [label="1: ancestor"];
    36.6 +	left [label="2: my change"];
    36.7 +	right [label="3: your change"];
    36.8 +	bad [label="4: bad merge"];
    36.9 +	new [label="5: new change"];
   36.10 +
   36.11 +	ancestor -> left;
   36.12 +	ancestor -> right;
   36.13 +	left -> bad;
   36.14 +	right -> bad;
   36.15 +	bad -> new;
   36.16 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/fr/figs/bad-merge-2.dot	Sun Aug 16 04:58:01 2009 +0200
    37.3 @@ -0,0 +1,18 @@
    37.4 +digraph bad_merge_2 {
    37.5 +	ancestor [label="1: ancestor",color=grey,fontcolor=grey];
    37.6 +	left [label="2: my change",color=grey,fontcolor=grey];
    37.7 +	right [label="3: your change",color=grey,fontcolor=grey];
    37.8 +	bad [label="4: bad merge",color=grey,fontcolor=grey];
    37.9 +	new [label="5: new change",color=grey,fontcolor=grey];
   37.10 +
   37.11 +	bak_left [label="6: backout 1 of\nbad merge",shape=box];
   37.12 +
   37.13 +	ancestor -> left [color=grey];
   37.14 +	ancestor -> right [color=grey];
   37.15 +	left -> bad [color=grey];
   37.16 +	right -> bad [color=grey];
   37.17 +	bad -> new [color=grey];
   37.18 +
   37.19 +	bad -> bak_left;
   37.20 +	left -> bak_left [style=dotted,label="--parent=2"];
   37.21 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/fr/figs/bad-merge-3.dot	Sun Aug 16 04:58:01 2009 +0200
    38.3 @@ -0,0 +1,22 @@
    38.4 +digraph bad_merge_3 {
    38.5 +	ancestor [label="1: ancestor",color="#bbbbbb",fontcolor="#bbbbbb"];
    38.6 +	left [label="2: my change",color="#bbbbbb",fontcolor="#bbbbbb"];
    38.7 +	right [label="3: your change",color="#bbbbbb",fontcolor="#bbbbbb"];
    38.8 +	bad [label="4: bad merge",color="#bbbbbb",fontcolor="#bbbbbb"];
    38.9 +	new [label="5: new change",color="#bbbbbb",fontcolor="#bbbbbb"];
   38.10 +
   38.11 +	bak_left [label="6: backout 1 of\nbad merge",color=grey,shape=box];
   38.12 +	bak_right [label="8: backout 2 of\nbad merge",shape=box];
   38.13 +
   38.14 +	ancestor -> left [color="#bbbbbb"];
   38.15 +	ancestor -> right [color="#bbbbbb"];
   38.16 +	left -> bad [color="#bbbbbb"];
   38.17 +	right -> bad [color="#bbbbbb"];
   38.18 +	bad -> new [color="#bbbbbb"];
   38.19 +
   38.20 +	bad -> bak_left [color=grey];
   38.21 +	left -> bak_left [style=dotted,label="--parent=2",color=grey,fontcolor=grey];
   38.22 +
   38.23 +	bad -> bak_right;
   38.24 +	right -> bak_right [style=dotted,label="--parent=3"];
   38.25 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/fr/figs/bad-merge-4.dot	Sun Aug 16 04:58:01 2009 +0200
    39.3 @@ -0,0 +1,26 @@
    39.4 +digraph bad_merge_4 {
    39.5 +	ancestor [label="1: ancestor",color="#bbbbbb",fontcolor="#bbbbbb"];
    39.6 +	left [label="2: my change",color="#bbbbbb",fontcolor="#bbbbbb"];
    39.7 +	right [label="3: your change",color="#bbbbbb",fontcolor="#bbbbbb"];
    39.8 +	bad [label="4: bad merge",color="#bbbbbb",fontcolor="#bbbbbb"];
    39.9 +	new [label="5: new change",color="#bbbbbb",fontcolor="#bbbbbb"];
   39.10 +
   39.11 +	bak_left [label="6: backout 1 of\nbad merge",color=grey,fontcolor=grey,shape=box];
   39.12 +	bak_right [label="7: backout 2 of\nbad merge",color=grey,fontcolor=grey,shape=box];
   39.13 +	good [label="8: merge\nof backouts",shape=box];
   39.14 +
   39.15 +	ancestor -> left [color="#bbbbbb"];
   39.16 +	ancestor -> right [color="#bbbbbb"];
   39.17 +	left -> bad [color="#bbbbbb"];
   39.18 +	right -> bad [color="#bbbbbb"];
   39.19 +	bad -> new [color="#bbbbbb"];
   39.20 +
   39.21 +	bad -> bak_left [color=grey];
   39.22 +	left -> bak_left [style=dotted,label="--parent=2",color=grey,fontcolor=grey];
   39.23 +
   39.24 +	bad -> bak_right [color=grey];
   39.25 +	right -> bak_right [style=dotted,label="--parent=3",color=grey,fontcolor=grey];
   39.26 +
   39.27 +	bak_left -> good;
   39.28 +	bak_right -> good;
   39.29 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/fr/figs/bad-merge-5.dot	Sun Aug 16 04:58:01 2009 +0200
    40.3 @@ -0,0 +1,30 @@
    40.4 +digraph bad_merge_5 {
    40.5 +	ancestor [label="1: ancestor",color="#bbbbbb",fontcolor="#bbbbbb"];
    40.6 +	left [label="2: my change",color="#bbbbbb",fontcolor="#bbbbbb"];
    40.7 +	right [label="3: your change",color="#bbbbbb",fontcolor="#bbbbbb"];
    40.8 +	bad [label="4: bad merge",color="#bbbbbb",fontcolor="#bbbbbb"];
    40.9 +	new [label="5: new change",color=grey,fontcolor=grey];
   40.10 +
   40.11 +	bak_left [label="6: backout 1 of\nbad merge",color="#bbbbbb",fontcolor="#bbbbbb",shape=box];
   40.12 +	bak_right [label="7: backout 2 of\nbad merge",color="#bbbbbb",fontcolor="#bbbbbb",shape=box];
   40.13 +	good [label="8: merge\nof backouts",color=grey,fontcolor=grey,shape=box];
   40.14 +	last [label="9: merge with\nnew change",shape=box];
   40.15 +
   40.16 +	ancestor -> left [color="#bbbbbb"];
   40.17 +	ancestor -> right [color="#bbbbbb"];
   40.18 +	left -> bad [color="#bbbbbb"];
   40.19 +	right -> bad [color="#bbbbbb"];
   40.20 +	bad -> new [color="#bbbbbb"];
   40.21 +
   40.22 +	bad -> bak_left [color="#bbbbbb"];
   40.23 +	left -> bak_left [style=dotted,label="--parent=2",color="#bbbbbb",fontcolor="#bbbbbb"];
   40.24 +
   40.25 +	bad -> bak_right [color="#bbbbbb"];
   40.26 +	right -> bak_right [style=dotted,label="--parent=3",color="#bbbbbb",fontcolor="#bbbbbb"];
   40.27 +
   40.28 +	bak_left -> good [color=grey];
   40.29 +	bak_right -> good [color=grey];
   40.30 +
   40.31 +	good -> last;
   40.32 +	new -> last;
   40.33 +}
    41.1 Binary file fr/figs/caution.png has changed
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/fr/figs/feature-branches.dot	Sun Aug 16 04:58:01 2009 +0200
    42.3 @@ -0,0 +1,8 @@
    42.4 +digraph feature_branches {
    42.5 +	master -> crypto;
    42.6 +	master -> filesystems;
    42.7 +	master -> ipc;
    42.8 +	master -> memory;
    42.9 +	master -> network;
   42.10 +	master -> security;
   42.11 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/fr/figs/filelog.svg	Sun Aug 16 04:58:01 2009 +0200
    43.3 @@ -0,0 +1,381 @@
    43.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    43.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    43.6 +<svg
    43.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    43.8 +   xmlns:cc="http://creativecommons.org/ns#"
    43.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   43.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   43.11 +   xmlns="http://www.w3.org/2000/svg"
   43.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   43.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   43.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   43.15 +   width="744.09448819"
   43.16 +   height="1052.3622047"
   43.17 +   id="svg2"
   43.18 +   sodipodi:version="0.32"
   43.19 +   inkscape:version="0.46"
   43.20 +   sodipodi:docname="filelog.svg"
   43.21 +   sodipodi:docbase="/home/arun/hgbook/en"
   43.22 +   inkscape:output_extension="org.inkscape.output.svg.inkscape">
   43.23 +  <defs
   43.24 +     id="defs4">
   43.25 +    <inkscape:perspective
   43.26 +       sodipodi:type="inkscape:persp3d"
   43.27 +       inkscape:vp_x="0 : 526.18109 : 1"
   43.28 +       inkscape:vp_y="0 : 1000 : 0"
   43.29 +       inkscape:vp_z="744.09448 : 526.18109 : 1"
   43.30 +       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
   43.31 +       id="perspective57" />
   43.32 +    <marker
   43.33 +       inkscape:stockid="Arrow1Mend"
   43.34 +       orient="auto"
   43.35 +       refY="0.0"
   43.36 +       refX="0.0"
   43.37 +       id="Arrow1Mend"
   43.38 +       style="overflow:visible;">
   43.39 +      <path
   43.40 +         id="path3128"
   43.41 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   43.42 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   43.43 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   43.44 +    </marker>
   43.45 +    <linearGradient
   43.46 +       id="linearGradient2887">
   43.47 +      <stop
   43.48 +         style="stop-color:#91cfcf;stop-opacity:1;"
   43.49 +         offset="0"
   43.50 +         id="stop2889" />
   43.51 +      <stop
   43.52 +         style="stop-color:aqua;stop-opacity:0;"
   43.53 +         offset="1"
   43.54 +         id="stop2891" />
   43.55 +    </linearGradient>
   43.56 +    <linearGradient
   43.57 +       id="linearGradient2795">
   43.58 +      <stop
   43.59 +         style="stop-color:#ccc;stop-opacity:1;"
   43.60 +         offset="0"
   43.61 +         id="stop2797" />
   43.62 +      <stop
   43.63 +         style="stop-color:#ccc;stop-opacity:0;"
   43.64 +         offset="1"
   43.65 +         id="stop2799" />
   43.66 +    </linearGradient>
   43.67 +    <linearGradient
   43.68 +       inkscape:collect="always"
   43.69 +       xlink:href="#linearGradient2795"
   43.70 +       id="linearGradient3170"
   43.71 +       gradientUnits="userSpaceOnUse"
   43.72 +       gradientTransform="translate(121.2183,94.95434)"
   43.73 +       x1="81.322357"
   43.74 +       y1="404.34424"
   43.75 +       x2="201.52036"
   43.76 +       y2="373.03967" />
   43.77 +    <linearGradient
   43.78 +       inkscape:collect="always"
   43.79 +       xlink:href="#linearGradient2887"
   43.80 +       id="linearGradient3172"
   43.81 +       gradientUnits="userSpaceOnUse"
   43.82 +       gradientTransform="translate(0,12)"
   43.83 +       x1="62.634491"
   43.84 +       y1="503.3392"
   43.85 +       x2="248.49242"
   43.86 +       y2="462.94327" />
   43.87 +    <linearGradient
   43.88 +       inkscape:collect="always"
   43.89 +       xlink:href="#linearGradient2795"
   43.90 +       id="linearGradient3174"
   43.91 +       gradientUnits="userSpaceOnUse"
   43.92 +       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
   43.93 +       x1="81.322357"
   43.94 +       y1="404.34424"
   43.95 +       x2="201.52036"
   43.96 +       y2="373.03967" />
   43.97 +    <linearGradient
   43.98 +       inkscape:collect="always"
   43.99 +       xlink:href="#linearGradient2887"
  43.100 +       id="linearGradient3176"
  43.101 +       gradientUnits="userSpaceOnUse"
  43.102 +       gradientTransform="translate(0,12)"
  43.103 +       x1="62.634491"
  43.104 +       y1="503.3392"
  43.105 +       x2="248.49242"
  43.106 +       y2="462.94327" />
  43.107 +    <linearGradient
  43.108 +       inkscape:collect="always"
  43.109 +       xlink:href="#linearGradient2795"
  43.110 +       id="linearGradient3208"
  43.111 +       gradientUnits="userSpaceOnUse"
  43.112 +       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
  43.113 +       x1="81.322357"
  43.114 +       y1="404.34424"
  43.115 +       x2="201.52036"
  43.116 +       y2="373.03967" />
  43.117 +    <linearGradient
  43.118 +       inkscape:collect="always"
  43.119 +       xlink:href="#linearGradient2887"
  43.120 +       id="linearGradient3210"
  43.121 +       gradientUnits="userSpaceOnUse"
  43.122 +       gradientTransform="translate(0,12)"
  43.123 +       x1="62.634491"
  43.124 +       y1="503.3392"
  43.125 +       x2="248.49242"
  43.126 +       y2="462.94327" />
  43.127 +    <linearGradient
  43.128 +       inkscape:collect="always"
  43.129 +       xlink:href="#linearGradient2795"
  43.130 +       id="linearGradient3212"
  43.131 +       gradientUnits="userSpaceOnUse"
  43.132 +       gradientTransform="translate(121.2183,94.95434)"
  43.133 +       x1="81.322357"
  43.134 +       y1="404.34424"
  43.135 +       x2="201.52036"
  43.136 +       y2="373.03967" />
  43.137 +    <linearGradient
  43.138 +       inkscape:collect="always"
  43.139 +       xlink:href="#linearGradient2887"
  43.140 +       id="linearGradient3214"
  43.141 +       gradientUnits="userSpaceOnUse"
  43.142 +       gradientTransform="translate(0,12)"
  43.143 +       x1="62.634491"
  43.144 +       y1="503.3392"
  43.145 +       x2="248.49242"
  43.146 +       y2="462.94327" />
  43.147 +    <linearGradient
  43.148 +       inkscape:collect="always"
  43.149 +       xlink:href="#linearGradient2795"
  43.150 +       id="linearGradient3256"
  43.151 +       gradientUnits="userSpaceOnUse"
  43.152 +       gradientTransform="matrix(1.2343775,0,0,0.9981848,103.25588,95.681888)"
  43.153 +       x1="74.301666"
  43.154 +       y1="431.67441"
  43.155 +       x2="260.05884"
  43.156 +       y2="369.95322" />
  43.157 +    <linearGradient
  43.158 +       inkscape:collect="always"
  43.159 +       xlink:href="#linearGradient2887"
  43.160 +       id="linearGradient3258"
  43.161 +       gradientUnits="userSpaceOnUse"
  43.162 +       gradientTransform="matrix(1.228929,0,0,0.9972824,-62.037003,13.312997)"
  43.163 +       x1="62.634491"
  43.164 +       y1="503.3392"
  43.165 +       x2="248.49242"
  43.166 +       y2="462.94327" />
  43.167 +    <linearGradient
  43.168 +       inkscape:collect="always"
  43.169 +       xlink:href="#linearGradient2795"
  43.170 +       id="linearGradient3260"
  43.171 +       gradientUnits="userSpaceOnUse"
  43.172 +       gradientTransform="matrix(1.2300738,0,0,0.6517275,219.97511,153.61527)"
  43.173 +       x1="74.387527"
  43.174 +       y1="431.80576"
  43.175 +       x2="259.97339"
  43.176 +       y2="369.82224" />
  43.177 +    <linearGradient
  43.178 +       inkscape:collect="always"
  43.179 +       xlink:href="#linearGradient2887"
  43.180 +       id="linearGradient3262"
  43.181 +       gradientUnits="userSpaceOnUse"
  43.182 +       gradientTransform="matrix(1.2289272,0,0,0.9972824,-62.036756,13.312985)"
  43.183 +       x1="62.634491"
  43.184 +       y1="503.3392"
  43.185 +       x2="248.49242"
  43.186 +       y2="462.94327" />
  43.187 +  </defs>
  43.188 +  <sodipodi:namedview
  43.189 +     id="base"
  43.190 +     pagecolor="#ffffff"
  43.191 +     bordercolor="#666666"
  43.192 +     borderopacity="1.0"
  43.193 +     gridtolerance="10000"
  43.194 +     guidetolerance="10"
  43.195 +     objecttolerance="10"
  43.196 +     inkscape:pageopacity="0.0"
  43.197 +     inkscape:pageshadow="2"
  43.198 +     inkscape:zoom="1.4"
  43.199 +     inkscape:cx="455.8122"
  43.200 +     inkscape:cy="520"
  43.201 +     inkscape:document-units="px"
  43.202 +     inkscape:current-layer="g2940"
  43.203 +     inkscape:window-width="1680"
  43.204 +     inkscape:window-height="970"
  43.205 +     inkscape:window-x="3"
  43.206 +     inkscape:window-y="46"
  43.207 +     showgrid="false" />
  43.208 +  <metadata
  43.209 +     id="metadata7">
  43.210 +    <rdf:RDF>
  43.211 +      <cc:Work
  43.212 +         rdf:about="">
  43.213 +        <dc:format>image/svg+xml</dc:format>
  43.214 +        <dc:type
  43.215 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  43.216 +      </cc:Work>
  43.217 +    </rdf:RDF>
  43.218 +  </metadata>
  43.219 +  <g
  43.220 +     inkscape:label="Layer 1"
  43.221 +     inkscape:groupmode="layer"
  43.222 +     id="layer1">
  43.223 +    <rect
  43.224 +       style="opacity:1;fill:#abadf8;fill-opacity:1;stroke:#595959;stroke-width:0.93760371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  43.225 +       id="rect3180"
  43.226 +       width="273.81375"
  43.227 +       height="199.06245"
  43.228 +       x="369.1796"
  43.229 +       y="351.79019" />
  43.230 +    <rect
  43.231 +       style="opacity:1;fill:#a2f69c;fill-opacity:1;stroke:#595959;stroke-width:0.93760341;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  43.232 +       id="rect3178"
  43.233 +       width="273.81339"
  43.234 +       height="199.06233"
  43.235 +       x="72.699799"
  43.236 +       y="351.78983" />
  43.237 +    <g
  43.238 +       id="g3144"
  43.239 +       transform="translate(80.467048,0.71578)">
  43.240 +      <g
  43.241 +         id="g2940">
  43.242 +        <rect
  43.243 +           style="fill:url(#linearGradient3260);fill-opacity:1;stroke:#000000;stroke-width:0.89536202;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  43.244 +           id="rect2914"
  43.245 +           width="227.38896"
  43.246 +           height="39.500999"
  43.247 +           x="311.92496"
  43.248 +           y="395.08627" />
  43.249 +        <text
  43.250 +           xml:space="preserve"
  43.251 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.252 +           x="323.72824"
  43.253 +           y="416.7626"
  43.254 +           id="text2918"><tspan
  43.255 +             sodipodi:role="line"
  43.256 +             id="tspan2920"
  43.257 +             x="323.72824"
  43.258 +             y="416.7626"
  43.259 +             style="font-family:Courier">.hg/store/data/_r_e_a_d_m_e.i</tspan></text>
  43.260 +      </g>
  43.261 +      <g
  43.262 +         transform="translate(3.79093e-5,-80.1853)"
  43.263 +         id="g2945">
  43.264 +        <g
  43.265 +           id="g2955">
  43.266 +          <rect
  43.267 +             y="475.4968"
  43.268 +             x="15.550935"
  43.269 +             height="39.500999"
  43.270 +             width="227.17694"
  43.271 +             id="rect2947"
  43.272 +             style="fill:url(#linearGradient3262);fill-opacity:1;stroke:#000000;stroke-width:1.10706258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  43.273 +          <text
  43.274 +             id="text2949"
  43.275 +             y="498.35123"
  43.276 +             x="31.230644"
  43.277 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.278 +             xml:space="preserve"><tspan
  43.279 +               style="font-family:Courier"
  43.280 +               y="498.35123"
  43.281 +               x="31.230644"
  43.282 +               id="tspan2951"
  43.283 +               sodipodi:role="line">README</tspan></text>
  43.284 +        </g>
  43.285 +      </g>
  43.286 +      <path
  43.287 +         inkscape:connector-type="polyline"
  43.288 +         id="path2960"
  43.289 +         d="M 242.94685,414.91115 C 242.94685,414.91115 293.61127,415.26754 310.16269,415.38633"
  43.290 +         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.02046943px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  43.291 +         sodipodi:nodetypes="cz" />
  43.292 +    </g>
  43.293 +    <g
  43.294 +       id="g3156"
  43.295 +       transform="translate(80.467048,0.71578)">
  43.296 +      <g
  43.297 +         transform="translate(116,0)"
  43.298 +         id="g2831">
  43.299 +        <rect
  43.300 +           style="fill:url(#linearGradient3256);fill-opacity:1;stroke:#000000;stroke-width:1.11001658;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  43.301 +           id="rect1906"
  43.302 +           width="228.18446"
  43.303 +           height="60.499123"
  43.304 +           x="195.52719"
  43.305 +           y="465.51859" />
  43.306 +        <g
  43.307 +           id="g2803"
  43.308 +           transform="translate(-0.893671,1.833581)">
  43.309 +          <text
  43.310 +             id="text1884"
  43.311 +             y="483.92801"
  43.312 +             x="208.95944"
  43.313 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.314 +             xml:space="preserve"><tspan
  43.315 +               style="font-family:Courier"
  43.316 +               y="483.92801"
  43.317 +               x="208.95944"
  43.318 +               id="tspan1886"
  43.319 +               sodipodi:role="line">.hg/store/data/src/hello.c.d</tspan></text>
  43.320 +          <text
  43.321 +             id="text1888"
  43.322 +             y="507.79309"
  43.323 +             x="208.95944"
  43.324 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.325 +             xml:space="preserve"><tspan
  43.326 +               style="font-family:Courier"
  43.327 +               y="507.79309"
  43.328 +               x="208.95944"
  43.329 +               id="tspan1890"
  43.330 +               sodipodi:role="line">.hg/store/data/src/hello.c.i</tspan></text>
  43.331 +        </g>
  43.332 +      </g>
  43.333 +      <g
  43.334 +         id="g2907">
  43.335 +        <rect
  43.336 +           style="fill:url(#linearGradient3258);fill-opacity:1;stroke:#000000;stroke-width:1.10706329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  43.337 +           id="rect2843"
  43.338 +           width="227.17728"
  43.339 +           height="39.500999"
  43.340 +           x="15.550805"
  43.341 +           y="475.4968" />
  43.342 +        <text
  43.343 +           xml:space="preserve"
  43.344 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.345 +           x="31.230644"
  43.346 +           y="498.35123"
  43.347 +           id="text2847"><tspan
  43.348 +             sodipodi:role="line"
  43.349 +             id="tspan2849"
  43.350 +             x="31.230644"
  43.351 +             y="498.35123"
  43.352 +             style="font-family:Courier">src/hello.c</tspan></text>
  43.353 +      </g>
  43.354 +      <path
  43.355 +         inkscape:connection-end="#g2831"
  43.356 +         inkscape:connection-start="#g2907"
  43.357 +         inkscape:connector-type="polyline"
  43.358 +         id="path2962"
  43.359 +         d="M 242.4315,495.88043 C 242.4315,495.88043 292.8861,495.99942 310.04102,496.03909"
  43.360 +         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  43.361 +         sodipodi:nodetypes="cs" />
  43.362 +    </g>
  43.363 +    <text
  43.364 +       xml:space="preserve"
  43.365 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.366 +       x="98.496666"
  43.367 +       y="373.96353"
  43.368 +       id="text3216"><tspan
  43.369 +         sodipodi:role="line"
  43.370 +         id="tspan3218"
  43.371 +         x="98.496666"
  43.372 +         y="373.96353">Working directory</tspan></text>
  43.373 +    <text
  43.374 +       xml:space="preserve"
  43.375 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  43.376 +       x="391.39197"
  43.377 +       y="373.96353"
  43.378 +       id="text3228"><tspan
  43.379 +         sodipodi:role="line"
  43.380 +         id="tspan3230"
  43.381 +         x="391.39197"
  43.382 +         y="373.96353">Repository</tspan></text>
  43.383 +  </g>
  43.384 +</svg>
    44.1 Binary file fr/figs/kdiff3.png has changed
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/fr/figs/metadata.svg	Sun Aug 16 04:58:01 2009 +0200
    45.3 @@ -0,0 +1,328 @@
    45.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    45.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    45.6 +<svg
    45.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    45.8 +   xmlns:cc="http://web.resource.org/cc/"
    45.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   45.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   45.11 +   xmlns="http://www.w3.org/2000/svg"
   45.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   45.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   45.14 +   width="744.09448819"
   45.15 +   height="1052.3622047"
   45.16 +   id="svg2"
   45.17 +   sodipodi:version="0.32"
   45.18 +   inkscape:version="0.44.1"
   45.19 +   sodipodi:docname="metadata.svg"
   45.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en">
   45.21 +  <defs
   45.22 +     id="defs4">
   45.23 +    <marker
   45.24 +       inkscape:stockid="Arrow1Mend"
   45.25 +       orient="auto"
   45.26 +       refY="0.0"
   45.27 +       refX="0.0"
   45.28 +       id="Arrow1Mend"
   45.29 +       style="overflow:visible;">
   45.30 +      <path
   45.31 +         id="path2944"
   45.32 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   45.33 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   45.34 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   45.35 +    </marker>
   45.36 +  </defs>
   45.37 +  <sodipodi:namedview
   45.38 +     id="base"
   45.39 +     pagecolor="#ffffff"
   45.40 +     bordercolor="#666666"
   45.41 +     borderopacity="1.0"
   45.42 +     gridtolerance="10000"
   45.43 +     guidetolerance="10"
   45.44 +     objecttolerance="10"
   45.45 +     inkscape:pageopacity="0.0"
   45.46 +     inkscape:pageshadow="2"
   45.47 +     inkscape:zoom="1.4"
   45.48 +     inkscape:cx="232.14286"
   45.49 +     inkscape:cy="490.68696"
   45.50 +     inkscape:document-units="px"
   45.51 +     inkscape:current-layer="layer1"
   45.52 +     inkscape:window-width="906"
   45.53 +     inkscape:window-height="620"
   45.54 +     inkscape:window-x="181"
   45.55 +     inkscape:window-y="58" />
   45.56 +  <metadata
   45.57 +     id="metadata7">
   45.58 +    <rdf:RDF>
   45.59 +      <cc:Work
   45.60 +         rdf:about="">
   45.61 +        <dc:format>image/svg+xml</dc:format>
   45.62 +        <dc:type
   45.63 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   45.64 +      </cc:Work>
   45.65 +    </rdf:RDF>
   45.66 +  </metadata>
   45.67 +  <g
   45.68 +     inkscape:label="Layer 1"
   45.69 +     inkscape:groupmode="layer"
   45.70 +     id="layer1">
   45.71 +    <path
   45.72 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
   45.73 +       d="M 326.94646,467.18359 L 326.94646,510.98123"
   45.74 +       id="path1910"
   45.75 +       inkscape:connector-type="polyline"
   45.76 +       inkscape:connection-end="#rect2962"
   45.77 +       inkscape:connection-start="#rect2764" />
   45.78 +    <path
   45.79 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
   45.80 +       d="M 326.94646,531.98123 L 326.94646,591.77887"
   45.81 +       id="path1912"
   45.82 +       inkscape:connector-type="polyline"
   45.83 +       inkscape:connection-start="#rect2962"
   45.84 +       inkscape:connection-end="#rect3000" />
   45.85 +    <path
   45.86 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
   45.87 +       d="M 316.1622,531.98123 L 192.30212,652.57648"
   45.88 +       id="path1916"
   45.89 +       inkscape:connector-type="polyline"
   45.90 +       inkscape:connection-end="#rect3038"
   45.91 +       inkscape:connection-start="#rect2962" />
   45.92 +    <path
   45.93 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
   45.94 +       d="M 254.23217,467.18359 L 254.23216,510.98123"
   45.95 +       id="path3088"
   45.96 +       inkscape:connector-type="polyline"
   45.97 +       inkscape:connection-start="#rect1872"
   45.98 +       inkscape:connection-end="#rect2960" />
   45.99 +    <path
  45.100 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
  45.101 +       d="M 254.23215,531.98123 L 254.23215,591.77887"
  45.102 +       id="path3090"
  45.103 +       inkscape:connector-type="polyline"
  45.104 +       inkscape:connection-start="#rect2960"
  45.105 +       inkscape:connection-end="#rect2998" />
  45.106 +    <path
  45.107 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
  45.108 +       d="M 248.84002,531.98123 L 186.90999,652.57648"
  45.109 +       id="path3092"
  45.110 +       inkscape:connector-type="polyline"
  45.111 +       inkscape:connection-start="#rect2960"
  45.112 +       inkscape:connection-end="#rect3038" />
  45.113 +    <rect
  45.114 +       style="fill:#7b7df5;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.115 +       id="rect1872"
  45.116 +       width="51.42857"
  45.117 +       height="20"
  45.118 +       x="228.51788"
  45.119 +       y="446.68359" />
  45.120 +    <rect
  45.121 +       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.122 +       id="rect2764"
  45.123 +       width="51.42857"
  45.124 +       height="20"
  45.125 +       x="301.23218"
  45.126 +       y="446.68359" />
  45.127 +    <rect
  45.128 +       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.129 +       id="rect2766"
  45.130 +       width="51.42857"
  45.131 +       height="20"
  45.132 +       x="155.80359"
  45.133 +       y="446.68359" />
  45.134 +    <rect
  45.135 +       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.136 +       id="rect2768"
  45.137 +       width="51.42857"
  45.138 +       height="20"
  45.139 +       x="83.089294"
  45.140 +       y="446.68359" />
  45.141 +    <path
  45.142 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.143 +       d="M 135.01786,456.68359 L 155.30359,456.68359"
  45.144 +       id="path2770"
  45.145 +       inkscape:connector-type="polyline"
  45.146 +       inkscape:connection-start="#rect2768"
  45.147 +       inkscape:connection-end="#rect2766" />
  45.148 +    <path
  45.149 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.150 +       d="M 207.73216,456.68359 L 228.01788,456.68359"
  45.151 +       id="path2772"
  45.152 +       inkscape:connector-type="polyline"
  45.153 +       inkscape:connection-start="#rect2766"
  45.154 +       inkscape:connection-end="#rect1872" />
  45.155 +    <path
  45.156 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.157 +       d="M 280.44645,456.68359 L 300.73218,456.68359"
  45.158 +       id="path2774"
  45.159 +       inkscape:connector-type="polyline"
  45.160 +       inkscape:connection-start="#rect1872"
  45.161 +       inkscape:connection-end="#rect2764" />
  45.162 +    <path
  45.163 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  45.164 +       d="M 62.303571,456.68359 L 82.589294,456.68359"
  45.165 +       id="path2778"
  45.166 +       inkscape:connector-type="polyline"
  45.167 +       inkscape:connection-end="#rect2768" />
  45.168 +    <rect
  45.169 +       style="fill:#84f57b;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.170 +       id="rect2960"
  45.171 +       width="51.42857"
  45.172 +       height="20"
  45.173 +       x="228.51787"
  45.174 +       y="511.48123" />
  45.175 +    <rect
  45.176 +       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.177 +       id="rect2962"
  45.178 +       width="51.42857"
  45.179 +       height="20"
  45.180 +       x="301.23218"
  45.181 +       y="511.48123" />
  45.182 +    <rect
  45.183 +       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.184 +       id="rect2964"
  45.185 +       width="51.42857"
  45.186 +       height="20"
  45.187 +       x="155.80357"
  45.188 +       y="511.48123" />
  45.189 +    <rect
  45.190 +       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.191 +       id="rect2966"
  45.192 +       width="51.42857"
  45.193 +       height="20"
  45.194 +       x="83.089287"
  45.195 +       y="511.48123" />
  45.196 +    <path
  45.197 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.198 +       d="M 135.01786,521.48121 L 155.30359,521.48121"
  45.199 +       id="path2968"
  45.200 +       inkscape:connector-type="polyline" />
  45.201 +    <path
  45.202 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.203 +       d="M 207.73216,521.48121 L 228.01788,521.48121"
  45.204 +       id="path2970"
  45.205 +       inkscape:connector-type="polyline" />
  45.206 +    <path
  45.207 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.208 +       d="M 280.44645,521.48121 L 300.73218,521.48121"
  45.209 +       id="path2972"
  45.210 +       inkscape:connector-type="polyline" />
  45.211 +    <path
  45.212 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  45.213 +       d="M 62.30358,521.48121 L 82.5893,521.48121"
  45.214 +       id="path2974"
  45.215 +       inkscape:connector-type="polyline" />
  45.216 +    <rect
  45.217 +       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.218 +       id="rect2998"
  45.219 +       width="51.42857"
  45.220 +       height="20"
  45.221 +       x="228.51787"
  45.222 +       y="592.27887" />
  45.223 +    <rect
  45.224 +       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.225 +       id="rect3000"
  45.226 +       width="51.42857"
  45.227 +       height="20"
  45.228 +       x="301.23218"
  45.229 +       y="592.27887" />
  45.230 +    <rect
  45.231 +       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.232 +       id="rect3002"
  45.233 +       width="51.42857"
  45.234 +       height="20"
  45.235 +       x="155.80357"
  45.236 +       y="592.27887" />
  45.237 +    <rect
  45.238 +       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.239 +       id="rect3004"
  45.240 +       width="51.42857"
  45.241 +       height="20"
  45.242 +       x="83.089287"
  45.243 +       y="592.27887" />
  45.244 +    <path
  45.245 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.246 +       d="M 135.01786,602.27884 L 155.30359,602.27884"
  45.247 +       id="path3006"
  45.248 +       inkscape:connector-type="polyline" />
  45.249 +    <path
  45.250 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.251 +       d="M 207.73216,602.27884 L 228.01788,602.27884"
  45.252 +       id="path3008"
  45.253 +       inkscape:connector-type="polyline" />
  45.254 +    <path
  45.255 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.256 +       d="M 280.44645,602.27884 L 300.73218,602.27884"
  45.257 +       id="path3010"
  45.258 +       inkscape:connector-type="polyline" />
  45.259 +    <path
  45.260 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  45.261 +       d="M 62.30358,602.27884 L 82.5893,602.27884"
  45.262 +       id="path3012"
  45.263 +       inkscape:connector-type="polyline" />
  45.264 +    <rect
  45.265 +       style="fill:#ffced6;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.266 +       id="rect3034"
  45.267 +       width="51.42857"
  45.268 +       height="20"
  45.269 +       x="228.51787"
  45.270 +       y="653.07648" />
  45.271 +    <rect
  45.272 +       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.273 +       id="rect3038"
  45.274 +       width="51.42857"
  45.275 +       height="20"
  45.276 +       x="155.80357"
  45.277 +       y="653.07648" />
  45.278 +    <rect
  45.279 +       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  45.280 +       id="rect3040"
  45.281 +       width="51.42857"
  45.282 +       height="20"
  45.283 +       x="83.089287"
  45.284 +       y="653.07648" />
  45.285 +    <path
  45.286 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.287 +       d="M 135.01786,663.07646 L 155.30359,663.07646"
  45.288 +       id="path3042"
  45.289 +       inkscape:connector-type="polyline" />
  45.290 +    <path
  45.291 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  45.292 +       d="M 207.73216,663.07646 L 228.01788,663.07646"
  45.293 +       id="path3044"
  45.294 +       inkscape:connector-type="polyline" />
  45.295 +    <path
  45.296 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  45.297 +       d="M 62.30358,663.07646 L 82.5893,663.07646"
  45.298 +       id="path3048"
  45.299 +       inkscape:connector-type="polyline" />
  45.300 +    <text
  45.301 +       xml:space="preserve"
  45.302 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  45.303 +       x="82.072548"
  45.304 +       y="432.64789"
  45.305 +       id="text3094"><tspan
  45.306 +         sodipodi:role="line"
  45.307 +         id="tspan3096"
  45.308 +         x="82.072548"
  45.309 +         y="432.64789">Changelog</tspan></text>
  45.310 +    <text
  45.311 +       xml:space="preserve"
  45.312 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  45.313 +       x="82.306923"
  45.314 +       y="498.97327"
  45.315 +       id="text3098"><tspan
  45.316 +         sodipodi:role="line"
  45.317 +         id="tspan3100"
  45.318 +         x="82.306923"
  45.319 +         y="498.97327">Manifest</tspan></text>
  45.320 +    <text
  45.321 +       xml:space="preserve"
  45.322 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  45.323 +       x="82.14286"
  45.324 +       y="580.08569"
  45.325 +       id="text3102"><tspan
  45.326 +         sodipodi:role="line"
  45.327 +         id="tspan3104"
  45.328 +         x="82.14286"
  45.329 +         y="580.08569">Filelogs</tspan></text>
  45.330 +  </g>
  45.331 +</svg>
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/fr/figs/mq-stack.svg	Sun Aug 16 04:58:01 2009 +0200
    46.3 @@ -0,0 +1,270 @@
    46.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    46.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    46.6 +<svg
    46.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    46.8 +   xmlns:cc="http://web.resource.org/cc/"
    46.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   46.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   46.11 +   xmlns="http://www.w3.org/2000/svg"
   46.12 +   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
   46.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   46.14 +   width="744.09448819"
   46.15 +   height="1052.3622047"
   46.16 +   id="svg2"
   46.17 +   sodipodi:version="0.32"
   46.18 +   inkscape:version="0.43"
   46.19 +   sodipodi:docname="mq-stack.svg"
   46.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en">
   46.21 +  <defs
   46.22 +     id="defs4" />
   46.23 +  <sodipodi:namedview
   46.24 +     id="base"
   46.25 +     pagecolor="#ffffff"
   46.26 +     bordercolor="#666666"
   46.27 +     borderopacity="1.0"
   46.28 +     inkscape:pageopacity="0.0"
   46.29 +     inkscape:pageshadow="2"
   46.30 +     inkscape:zoom="1.4142136"
   46.31 +     inkscape:cx="299.33323"
   46.32 +     inkscape:cy="815.646"
   46.33 +     inkscape:document-units="px"
   46.34 +     inkscape:current-layer="layer1"
   46.35 +     inkscape:window-width="1014"
   46.36 +     inkscape:window-height="689"
   46.37 +     inkscape:window-x="0"
   46.38 +     inkscape:window-y="25" />
   46.39 +  <metadata
   46.40 +     id="metadata7">
   46.41 +    <rdf:RDF>
   46.42 +      <cc:Work
   46.43 +         rdf:about="">
   46.44 +        <dc:format>image/svg+xml</dc:format>
   46.45 +        <dc:type
   46.46 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   46.47 +      </cc:Work>
   46.48 +    </rdf:RDF>
   46.49 +  </metadata>
   46.50 +  <g
   46.51 +     inkscape:label="Layer 1"
   46.52 +     inkscape:groupmode="layer"
   46.53 +     id="layer1">
   46.54 +    <rect
   46.55 +       style="fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   46.56 +       id="rect1307"
   46.57 +       width="202.93683"
   46.58 +       height="24.243662"
   46.59 +       x="230.01944"
   46.60 +       y="221.70146" />
   46.61 +    <text
   46.62 +       xml:space="preserve"
   46.63 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   46.64 +       x="237.89606"
   46.65 +       y="237.13383"
   46.66 +       id="text1309"><tspan
   46.67 +         sodipodi:role="line"
   46.68 +         id="tspan1311"
   46.69 +         x="237.89606"
   46.70 +         y="237.13383">prevent-compiler-reorder.patch</tspan></text>
   46.71 +    <rect
   46.72 +       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   46.73 +       id="rect1320"
   46.74 +       width="202.93683"
   46.75 +       height="24.243662"
   46.76 +       x="230.01936"
   46.77 +       y="251.34325" />
   46.78 +    <text
   46.79 +       xml:space="preserve"
   46.80 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   46.81 +       x="237.89598"
   46.82 +       y="266.77563"
   46.83 +       id="text1322"><tspan
   46.84 +         sodipodi:role="line"
   46.85 +         id="tspan1324"
   46.86 +         x="237.89598"
   46.87 +         y="266.77563">namespace-cleanup.patch</tspan></text>
   46.88 +    <rect
   46.89 +       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   46.90 +       id="rect2217"
   46.91 +       width="202.93683"
   46.92 +       height="24.243662"
   46.93 +       x="230.01936"
   46.94 +       y="280.98505" />
   46.95 +    <text
   46.96 +       xml:space="preserve"
   46.97 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   46.98 +       x="237.89598"
   46.99 +       y="296.41742"
  46.100 +       id="text2219"><tspan
  46.101 +         sodipodi:role="line"
  46.102 +         id="tspan2221"
  46.103 +         x="237.89598"
  46.104 +         y="296.41742">powerpc-port-fixes.patch</tspan></text>
  46.105 +    <rect
  46.106 +       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  46.107 +       id="rect3114"
  46.108 +       width="202.93683"
  46.109 +       height="24.243662"
  46.110 +       x="230.01936"
  46.111 +       y="310.6268" />
  46.112 +    <text
  46.113 +       xml:space="preserve"
  46.114 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.115 +       x="237.89598"
  46.116 +       y="326.05917"
  46.117 +       id="text3116"><tspan
  46.118 +         sodipodi:role="line"
  46.119 +         id="tspan3118"
  46.120 +         x="237.89598"
  46.121 +         y="326.05917">report-devinfo-correctly.patch</tspan></text>
  46.122 +    <text
  46.123 +       xml:space="preserve"
  46.124 +       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.125 +       x="200.01021"
  46.126 +       y="191.68094"
  46.127 +       id="text3170"
  46.128 +       sodipodi:linespacing="125%"><tspan
  46.129 +         sodipodi:role="line"
  46.130 +         id="tspan3172"
  46.131 +         x="200.01021"
  46.132 +         y="191.68094"
  46.133 +         style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
  46.134 +    <text
  46.135 +       xml:space="preserve"
  46.136 +       style="font-size:15.25329685px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.137 +       x="255.26627"
  46.138 +       y="248.79449"
  46.139 +       id="text3190"
  46.140 +       sodipodi:linespacing="125%"
  46.141 +       transform="scale(0.786716,1.271107)"><tspan
  46.142 +         sodipodi:role="line"
  46.143 +         id="tspan3192"
  46.144 +         x="255.26627"
  46.145 +         y="248.79449"
  46.146 +         style="font-size:61.01318741px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
  46.147 +    <text
  46.148 +       xml:space="preserve"
  46.149 +       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.150 +       x="195.86807"
  46.151 +       y="173.17117"
  46.152 +       id="text4085"
  46.153 +       sodipodi:linespacing="125%"><tspan
  46.154 +         sodipodi:role="line"
  46.155 +         id="tspan4087"
  46.156 +         x="195.86807"
  46.157 +         y="173.17117"
  46.158 +         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">present in series,</tspan><tspan
  46.159 +         sodipodi:role="line"
  46.160 +         x="195.86807"
  46.161 +         y="188.17117"
  46.162 +         id="tspan4089"
  46.163 +         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">but not applied</tspan></text>
  46.164 +    <text
  46.165 +       xml:space="preserve"
  46.166 +       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.167 +       x="195.0712"
  46.168 +       y="288.91745"
  46.169 +       id="text4091"
  46.170 +       sodipodi:linespacing="125%"><tspan
  46.171 +         sodipodi:role="line"
  46.172 +         id="tspan4093"
  46.173 +         x="195.0712"
  46.174 +         y="288.91745"
  46.175 +         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">patches applied,</tspan><tspan
  46.176 +         sodipodi:role="line"
  46.177 +         x="195.0712"
  46.178 +         y="303.91745"
  46.179 +         id="tspan4111"
  46.180 +         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">changesets present</tspan></text>
  46.181 +    <text
  46.182 +       xml:space="preserve"
  46.183 +       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.184 +       x="195.0712"
  46.185 +       y="229.28813"
  46.186 +       id="text4095"
  46.187 +       sodipodi:linespacing="125%"><tspan
  46.188 +         sodipodi:role="line"
  46.189 +         id="tspan4097"
  46.190 +         x="195.0712"
  46.191 +         y="229.28813"
  46.192 +         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">topmost</tspan><tspan
  46.193 +         sodipodi:role="line"
  46.194 +         x="195.0712"
  46.195 +         y="244.28813"
  46.196 +         id="tspan4109"
  46.197 +         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">applied patch</tspan></text>
  46.198 +    <text
  46.199 +       xml:space="preserve"
  46.200 +       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.201 +       x="450.4975"
  46.202 +       y="238.29692"
  46.203 +       id="text4137"><tspan
  46.204 +         sodipodi:role="line"
  46.205 +         id="tspan4139"
  46.206 +         x="450.4975"
  46.207 +         y="238.29692">201ad3209902</tspan></text>
  46.208 +    <text
  46.209 +       xml:space="preserve"
  46.210 +       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.211 +       x="450.05804"
  46.212 +       y="267.93872"
  46.213 +       id="text4141"><tspan
  46.214 +         sodipodi:role="line"
  46.215 +         id="tspan4143"
  46.216 +         x="450.05804"
  46.217 +         y="267.93872">126b84e593ae</tspan></text>
  46.218 +    <text
  46.219 +       xml:space="preserve"
  46.220 +       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.221 +       x="450.6557"
  46.222 +       y="297.58051"
  46.223 +       id="text4145"><tspan
  46.224 +         sodipodi:role="line"
  46.225 +         id="tspan4147"
  46.226 +         x="450.6557"
  46.227 +         y="297.58051">a655daf15409</tspan></text>
  46.228 +    <text
  46.229 +       xml:space="preserve"
  46.230 +       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.231 +       x="450.71429"
  46.232 +       y="327.22226"
  46.233 +       id="text4149"><tspan
  46.234 +         sodipodi:role="line"
  46.235 +         id="tspan4151"
  46.236 +         x="450.71429"
  46.237 +         y="327.22226">e50d59aaea3a</tspan></text>
  46.238 +    <rect
  46.239 +       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  46.240 +       id="rect3106"
  46.241 +       width="202.93683"
  46.242 +       height="24.243662"
  46.243 +       x="230.01936"
  46.244 +       y="150.41792" />
  46.245 +    <text
  46.246 +       xml:space="preserve"
  46.247 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.248 +       x="237.89598"
  46.249 +       y="165.8503"
  46.250 +       id="text3108"><tspan
  46.251 +         sodipodi:role="line"
  46.252 +         id="tspan3110"
  46.253 +         x="237.89598"
  46.254 +         y="165.8503">forbid-illegal-params.patch</tspan></text>
  46.255 +    <rect
  46.256 +       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  46.257 +       id="rect2241"
  46.258 +       width="202.93683"
  46.259 +       height="24.243662"
  46.260 +       x="230.16466"
  46.261 +       y="180.05968" />
  46.262 +    <text
  46.263 +       xml:space="preserve"
  46.264 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  46.265 +       x="238.04128"
  46.266 +       y="195.49205"
  46.267 +       id="text2243"><tspan
  46.268 +         sodipodi:role="line"
  46.269 +         id="tspan2245"
  46.270 +         x="238.04128"
  46.271 +         y="195.49205">fix-memory-leak.patch</tspan></text>
  46.272 +  </g>
  46.273 +</svg>
    47.1 Binary file fr/figs/note.png has changed
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/fr/figs/revlog.svg	Sun Aug 16 04:58:01 2009 +0200
    48.3 @@ -0,0 +1,1155 @@
    48.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    48.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    48.6 +<svg
    48.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    48.8 +   xmlns:cc="http://web.resource.org/cc/"
    48.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   48.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   48.11 +   xmlns="http://www.w3.org/2000/svg"
   48.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   48.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   48.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   48.15 +   width="744.09448819"
   48.16 +   height="1052.3622047"
   48.17 +   id="svg2"
   48.18 +   sodipodi:version="0.32"
   48.19 +   inkscape:version="0.44.1"
   48.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   48.21 +   sodipodi:docname="revlog.svg">
   48.22 +  <defs
   48.23 +     id="defs4">
   48.24 +    <marker
   48.25 +       inkscape:stockid="Arrow1Mend"
   48.26 +       orient="auto"
   48.27 +       refY="0.0"
   48.28 +       refX="0.0"
   48.29 +       id="Arrow1Mend"
   48.30 +       style="overflow:visible;">
   48.31 +      <path
   48.32 +         id="path4852"
   48.33 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   48.34 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   48.35 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   48.36 +    </marker>
   48.37 +    <linearGradient
   48.38 +       id="linearGradient3092">
   48.39 +      <stop
   48.40 +         style="stop-color:#44436f;stop-opacity:1;"
   48.41 +         offset="0"
   48.42 +         id="stop3094" />
   48.43 +      <stop
   48.44 +         style="stop-color:#abade5;stop-opacity:1;"
   48.45 +         offset="1"
   48.46 +         id="stop3096" />
   48.47 +    </linearGradient>
   48.48 +    <linearGradient
   48.49 +       inkscape:collect="always"
   48.50 +       xlink:href="#linearGradient3092"
   48.51 +       id="linearGradient3118"
   48.52 +       gradientUnits="userSpaceOnUse"
   48.53 +       x1="176.16635"
   48.54 +       y1="405.21934"
   48.55 +       x2="417.11935"
   48.56 +       y2="405.21934" />
   48.57 +    <linearGradient
   48.58 +       inkscape:collect="always"
   48.59 +       xlink:href="#linearGradient3092"
   48.60 +       id="linearGradient3120"
   48.61 +       gradientUnits="userSpaceOnUse"
   48.62 +       x1="176.16635"
   48.63 +       y1="405.21934"
   48.64 +       x2="417.11935"
   48.65 +       y2="405.21934" />
   48.66 +    <linearGradient
   48.67 +       inkscape:collect="always"
   48.68 +       xlink:href="#linearGradient3092"
   48.69 +       id="linearGradient3129"
   48.70 +       gradientUnits="userSpaceOnUse"
   48.71 +       x1="176.16635"
   48.72 +       y1="405.21934"
   48.73 +       x2="417.11935"
   48.74 +       y2="405.21934"
   48.75 +       gradientTransform="translate(-0.928574,-1.428574)" />
   48.76 +    <linearGradient
   48.77 +       inkscape:collect="always"
   48.78 +       xlink:href="#linearGradient3092"
   48.79 +       id="linearGradient3133"
   48.80 +       gradientUnits="userSpaceOnUse"
   48.81 +       x1="176.16635"
   48.82 +       y1="405.21934"
   48.83 +       x2="417.11935"
   48.84 +       y2="405.21934"
   48.85 +       gradientTransform="translate(-0.928574,-1.428574)" />
   48.86 +    <linearGradient
   48.87 +       inkscape:collect="always"
   48.88 +       xlink:href="#linearGradient3092"
   48.89 +       id="linearGradient3708"
   48.90 +       gradientUnits="userSpaceOnUse"
   48.91 +       gradientTransform="matrix(0.423343,0,0,0.423343,138.874,-67.01732)"
   48.92 +       x1="175.23776"
   48.93 +       y1="509.98154"
   48.94 +       x2="416.29077"
   48.95 +       y2="297.49997" />
   48.96 +    <linearGradient
   48.97 +       inkscape:collect="always"
   48.98 +       xlink:href="#linearGradient3092"
   48.99 +       id="linearGradient5164"
  48.100 +       gradientUnits="userSpaceOnUse"
  48.101 +       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,247.4358)"
  48.102 +       x1="175.23776"
  48.103 +       y1="509.98154"
  48.104 +       x2="416.29077"
  48.105 +       y2="297.49997" />
  48.106 +    <linearGradient
  48.107 +       inkscape:collect="always"
  48.108 +       xlink:href="#linearGradient3092"
  48.109 +       id="linearGradient5584"
  48.110 +       gradientUnits="userSpaceOnUse"
  48.111 +       gradientTransform="matrix(0.423343,0,0,0.423343,143.9081,371.2915)"
  48.112 +       x1="175.23776"
  48.113 +       y1="509.98154"
  48.114 +       x2="416.29077"
  48.115 +       y2="297.49997" />
  48.116 +    <linearGradient
  48.117 +       inkscape:collect="always"
  48.118 +       xlink:href="#linearGradient3092"
  48.119 +       id="linearGradient5784"
  48.120 +       gradientUnits="userSpaceOnUse"
  48.121 +       gradientTransform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  48.122 +       x1="175.23776"
  48.123 +       y1="509.98154"
  48.124 +       x2="416.29077"
  48.125 +       y2="297.49997" />
  48.126 +    <linearGradient
  48.127 +       inkscape:collect="always"
  48.128 +       xlink:href="#linearGradient3092"
  48.129 +       id="linearGradient5786"
  48.130 +       gradientUnits="userSpaceOnUse"
  48.131 +       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,152.137)"
  48.132 +       x1="175.23776"
  48.133 +       y1="509.98154"
  48.134 +       x2="416.29077"
  48.135 +       y2="297.49997" />
  48.136 +    <linearGradient
  48.137 +       inkscape:collect="always"
  48.138 +       xlink:href="#linearGradient3092"
  48.139 +       id="linearGradient5895"
  48.140 +       gradientUnits="userSpaceOnUse"
  48.141 +       gradientTransform="matrix(0.423343,0,0,0.423343,198.0215,261.7142)"
  48.142 +       x1="175.23776"
  48.143 +       y1="509.98154"
  48.144 +       x2="416.29077"
  48.145 +       y2="297.49997" />
  48.146 +    <linearGradient
  48.147 +       inkscape:collect="always"
  48.148 +       xlink:href="#linearGradient3092"
  48.149 +       id="linearGradient5958"
  48.150 +       gradientUnits="userSpaceOnUse"
  48.151 +       gradientTransform="matrix(0.423343,0,0,0.423343,137.1978,42.55987)"
  48.152 +       x1="175.23776"
  48.153 +       y1="509.98154"
  48.154 +       x2="416.29077"
  48.155 +       y2="297.49997" />
  48.156 +  </defs>
  48.157 +  <sodipodi:namedview
  48.158 +     id="base"
  48.159 +     pagecolor="#ffffff"
  48.160 +     bordercolor="#666666"
  48.161 +     borderopacity="1.0"
  48.162 +     gridtolerance="10000"
  48.163 +     guidetolerance="10"
  48.164 +     objecttolerance="10"
  48.165 +     inkscape:pageopacity="0.0"
  48.166 +     inkscape:pageshadow="2"
  48.167 +     inkscape:zoom="0.64"
  48.168 +     inkscape:cx="566.02368"
  48.169 +     inkscape:cy="688.16826"
  48.170 +     inkscape:document-units="px"
  48.171 +     inkscape:current-layer="layer1"
  48.172 +     inkscape:window-width="906"
  48.173 +     inkscape:window-height="620"
  48.174 +     inkscape:window-x="29"
  48.175 +     inkscape:window-y="79"
  48.176 +     inkscape:connector-spacing="11" />
  48.177 +  <metadata
  48.178 +     id="metadata7">
  48.179 +    <rdf:RDF>
  48.180 +      <cc:Work
  48.181 +         rdf:about="">
  48.182 +        <dc:format>image/svg+xml</dc:format>
  48.183 +        <dc:type
  48.184 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  48.185 +      </cc:Work>
  48.186 +    </rdf:RDF>
  48.187 +  </metadata>
  48.188 +  <g
  48.189 +     inkscape:label="Layer 1"
  48.190 +     inkscape:groupmode="layer"
  48.191 +     id="layer1">
  48.192 +    <rect
  48.193 +       y="168.74846"
  48.194 +       x="211.58516"
  48.195 +       height="89.506805"
  48.196 +       width="101.60232"
  48.197 +       id="rect3068"
  48.198 +       style="fill:url(#linearGradient5958);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.199 +    <g
  48.200 +       id="g3215"
  48.201 +       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55985)">
  48.202 +      <rect
  48.203 +         y="447.71451"
  48.204 +         x="299.67859"
  48.205 +         height="48.571426"
  48.206 +         width="103.14286"
  48.207 +         id="rect2899"
  48.208 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.209 +      <text
  48.210 +         id="text2903"
  48.211 +         y="464.8139"
  48.212 +         x="308.89639"
  48.213 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.214 +         xml:space="preserve"><tspan
  48.215 +           y="464.8139"
  48.216 +           x="308.89639"
  48.217 +           sodipodi:role="line"
  48.218 +           id="tspan2905">Second parent</tspan></text>
  48.219 +      <text
  48.220 +         id="text2907"
  48.221 +         y="485.50256"
  48.222 +         x="308.20175"
  48.223 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.224 +         xml:space="preserve"><tspan
  48.225 +           style="font-family:Courier"
  48.226 +           y="485.50256"
  48.227 +           x="308.20175"
  48.228 +           id="tspan2909"
  48.229 +           sodipodi:role="line">32bf9a5f22c0</tspan></text>
  48.230 +    </g>
  48.231 +    <g
  48.232 +       id="g3250"
  48.233 +       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55986)">
  48.234 +      <rect
  48.235 +         y="311.28598"
  48.236 +         x="188.6071"
  48.237 +         height="48.571426"
  48.238 +         width="103.14286"
  48.239 +         id="rect2936"
  48.240 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.241 +      <text
  48.242 +         id="text2940"
  48.243 +         y="328.38538"
  48.244 +         x="197.82495"
  48.245 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.246 +         xml:space="preserve"><tspan
  48.247 +           y="328.38538"
  48.248 +           x="197.82495"
  48.249 +           sodipodi:role="line"
  48.250 +           id="tspan2942">Revision hash</tspan></text>
  48.251 +      <text
  48.252 +         id="text2944"
  48.253 +         y="349.07404"
  48.254 +         x="197.13031"
  48.255 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.256 +         xml:space="preserve"><tspan
  48.257 +           style="font-family:Courier"
  48.258 +           y="349.07404"
  48.259 +           x="197.13031"
  48.260 +           id="tspan2946"
  48.261 +           sodipodi:role="line">34b8b7a15ea1</tspan></text>
  48.262 +    </g>
  48.263 +    <g
  48.264 +       id="g3243"
  48.265 +       transform="matrix(0.423343,0,0,0.423343,137.6664,43.91853)">
  48.266 +      <rect
  48.267 +         y="363.07654"
  48.268 +         x="187.5"
  48.269 +         height="75"
  48.270 +         width="213.85715"
  48.271 +         id="rect2950"
  48.272 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.273 +      <text
  48.274 +         id="text2958"
  48.275 +         y="400.86459"
  48.276 +         x="196.02321"
  48.277 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.278 +         xml:space="preserve"><tspan
  48.279 +           style="fill:black;fill-opacity:1;font-family:Courier"
  48.280 +           y="400.86459"
  48.281 +           x="196.02321"
  48.282 +           id="tspan2960"
  48.283 +           sodipodi:role="line">...</tspan></text>
  48.284 +      <text
  48.285 +         id="text2954"
  48.286 +         y="380.17593"
  48.287 +         x="196.71785"
  48.288 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.289 +         xml:space="preserve"><tspan
  48.290 +           y="380.17593"
  48.291 +           x="196.71785"
  48.292 +           sodipodi:role="line"
  48.293 +           id="tspan2956"
  48.294 +           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
  48.295 +    </g>
  48.296 +    <g
  48.297 +       id="g5529"
  48.298 +       transform="translate(-6.710312,-8.165836e-6)">
  48.299 +      <rect
  48.300 +         style="fill:url(#linearGradient5584);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.301 +         id="rect3509"
  48.302 +         width="101.60232"
  48.303 +         height="89.506805"
  48.304 +         x="218.29547"
  48.305 +         y="497.4801" />
  48.306 +      <g
  48.307 +         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
  48.308 +         id="g3513">
  48.309 +        <g
  48.310 +           id="g3515">
  48.311 +          <rect
  48.312 +             y="447.72418"
  48.313 +             x="188.6071"
  48.314 +             height="48.571426"
  48.315 +             width="103.14286"
  48.316 +             id="rect3517"
  48.317 +             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.318 +          <text
  48.319 +             id="text3519"
  48.320 +             y="464.82358"
  48.321 +             x="197.82495"
  48.322 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.323 +             xml:space="preserve"><tspan
  48.324 +               y="464.82358"
  48.325 +               x="197.82495"
  48.326 +               sodipodi:role="line"
  48.327 +               id="tspan3521">First parent</tspan></text>
  48.328 +          <text
  48.329 +             id="text3523"
  48.330 +             y="485.51224"
  48.331 +             x="197.13031"
  48.332 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.333 +             xml:space="preserve"><tspan
  48.334 +               style="font-family:Courier"
  48.335 +               y="485.51224"
  48.336 +               x="197.13031"
  48.337 +               id="tspan3525"
  48.338 +               sodipodi:role="line">000000000000</tspan></text>
  48.339 +        </g>
  48.340 +        <g
  48.341 +           id="g3527">
  48.342 +          <rect
  48.343 +             y="447.71451"
  48.344 +             x="299.67859"
  48.345 +             height="48.571426"
  48.346 +             width="103.14286"
  48.347 +             id="rect3529"
  48.348 +             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.349 +          <text
  48.350 +             id="text3531"
  48.351 +             y="464.8139"
  48.352 +             x="308.89639"
  48.353 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.354 +             xml:space="preserve"><tspan
  48.355 +               y="464.8139"
  48.356 +               x="308.89639"
  48.357 +               sodipodi:role="line"
  48.358 +               id="tspan3533">Second parent</tspan></text>
  48.359 +          <text
  48.360 +             id="text3535"
  48.361 +             y="485.50256"
  48.362 +             x="308.20175"
  48.363 +             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.364 +             xml:space="preserve"><tspan
  48.365 +               style="font-family:Courier"
  48.366 +               y="485.50256"
  48.367 +               x="308.20175"
  48.368 +               id="tspan3537"
  48.369 +               sodipodi:role="line">000000000000</tspan></text>
  48.370 +        </g>
  48.371 +      </g>
  48.372 +      <g
  48.373 +         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
  48.374 +         id="g3539">
  48.375 +        <rect
  48.376 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.377 +           id="rect3541"
  48.378 +           width="103.14286"
  48.379 +           height="48.571426"
  48.380 +           x="188.6071"
  48.381 +           y="311.28598" />
  48.382 +        <text
  48.383 +           xml:space="preserve"
  48.384 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.385 +           x="197.82495"
  48.386 +           y="328.38538"
  48.387 +           id="text3543"><tspan
  48.388 +             id="tspan3545"
  48.389 +             sodipodi:role="line"
  48.390 +             x="197.82495"
  48.391 +             y="328.38538">Revision hash</tspan></text>
  48.392 +        <text
  48.393 +           xml:space="preserve"
  48.394 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.395 +           x="197.13031"
  48.396 +           y="349.07404"
  48.397 +           id="text3547"><tspan
  48.398 +             sodipodi:role="line"
  48.399 +             id="tspan3549"
  48.400 +             x="197.13031"
  48.401 +             y="349.07404"
  48.402 +             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
  48.403 +      </g>
  48.404 +      <g
  48.405 +         transform="matrix(0.423343,0,0,0.423343,144.3767,372.6502)"
  48.406 +         id="g3551">
  48.407 +        <rect
  48.408 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.409 +           id="rect3553"
  48.410 +           width="213.85715"
  48.411 +           height="75"
  48.412 +           x="187.5"
  48.413 +           y="363.07654" />
  48.414 +        <text
  48.415 +           xml:space="preserve"
  48.416 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.417 +           x="196.02321"
  48.418 +           y="400.86459"
  48.419 +           id="text3555"><tspan
  48.420 +             sodipodi:role="line"
  48.421 +             id="tspan3557"
  48.422 +             x="196.02321"
  48.423 +             y="400.86459"
  48.424 +             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  48.425 +        <text
  48.426 +           xml:space="preserve"
  48.427 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.428 +           x="196.71785"
  48.429 +           y="380.17593"
  48.430 +           id="text3559"><tspan
  48.431 +             style="fill:black;fill-opacity:1"
  48.432 +             id="tspan3561"
  48.433 +             sodipodi:role="line"
  48.434 +             x="196.71785"
  48.435 +             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  48.436 +      </g>
  48.437 +    </g>
  48.438 +    <g
  48.439 +       id="g4868"
  48.440 +       transform="translate(-1.676208,-2.342463e-5)">
  48.441 +      <rect
  48.442 +         style="fill:url(#linearGradient3708);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.443 +         id="rect3567"
  48.444 +         width="101.60232"
  48.445 +         height="89.506805"
  48.446 +         x="213.26137"
  48.447 +         y="59.171272" />
  48.448 +      <g
  48.449 +         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
  48.450 +         id="g3573">
  48.451 +        <rect
  48.452 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.453 +           id="rect3575"
  48.454 +           width="103.14286"
  48.455 +           height="48.571426"
  48.456 +           x="188.6071"
  48.457 +           y="447.72418" />
  48.458 +        <text
  48.459 +           xml:space="preserve"
  48.460 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.461 +           x="197.82495"
  48.462 +           y="464.82358"
  48.463 +           id="text3577"><tspan
  48.464 +             id="tspan3579"
  48.465 +             sodipodi:role="line"
  48.466 +             x="197.82495"
  48.467 +             y="464.82358">First parent</tspan></text>
  48.468 +        <text
  48.469 +           xml:space="preserve"
  48.470 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.471 +           x="197.13031"
  48.472 +           y="485.51224"
  48.473 +           id="text3581"><tspan
  48.474 +             sodipodi:role="line"
  48.475 +             id="tspan3583"
  48.476 +             x="197.13031"
  48.477 +             y="485.51224"
  48.478 +             style="font-family:Courier">34b8b7a15ea1</tspan></text>
  48.479 +      </g>
  48.480 +      <g
  48.481 +         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
  48.482 +         id="g3585">
  48.483 +        <rect
  48.484 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.485 +           id="rect3587"
  48.486 +           width="103.14286"
  48.487 +           height="48.571426"
  48.488 +           x="299.67859"
  48.489 +           y="447.71451" />
  48.490 +        <text
  48.491 +           xml:space="preserve"
  48.492 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.493 +           x="308.89639"
  48.494 +           y="464.8139"
  48.495 +           id="text3589"><tspan
  48.496 +             id="tspan3591"
  48.497 +             sodipodi:role="line"
  48.498 +             x="308.89639"
  48.499 +             y="464.8139">Second parent</tspan></text>
  48.500 +        <text
  48.501 +           xml:space="preserve"
  48.502 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.503 +           x="308.20175"
  48.504 +           y="485.50256"
  48.505 +           id="text3593"><tspan
  48.506 +             sodipodi:role="line"
  48.507 +             id="tspan3595"
  48.508 +             x="308.20175"
  48.509 +             y="485.50256"
  48.510 +             style="font-family:Courier">000000000000</tspan></text>
  48.511 +      </g>
  48.512 +      <g
  48.513 +         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01733)"
  48.514 +         id="g3597">
  48.515 +        <rect
  48.516 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.517 +           id="rect3599"
  48.518 +           width="103.14286"
  48.519 +           height="48.571426"
  48.520 +           x="188.6071"
  48.521 +           y="311.28598" />
  48.522 +        <text
  48.523 +           xml:space="preserve"
  48.524 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.525 +           x="197.82495"
  48.526 +           y="328.38538"
  48.527 +           id="text3601"><tspan
  48.528 +             id="tspan3603"
  48.529 +             sodipodi:role="line"
  48.530 +             x="197.82495"
  48.531 +             y="328.38538">Revision hash</tspan></text>
  48.532 +        <text
  48.533 +           xml:space="preserve"
  48.534 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.535 +           x="197.13031"
  48.536 +           y="349.07404"
  48.537 +           id="text3605"><tspan
  48.538 +             sodipodi:role="line"
  48.539 +             id="tspan3607"
  48.540 +             x="197.13031"
  48.541 +             y="349.07404"
  48.542 +             style="font-family:Courier">1b67dc96f27a</tspan></text>
  48.543 +      </g>
  48.544 +      <g
  48.545 +         transform="matrix(0.423343,0,0,0.423343,139.3426,-65.65866)"
  48.546 +         id="g3609">
  48.547 +        <rect
  48.548 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.549 +           id="rect3611"
  48.550 +           width="213.85715"
  48.551 +           height="75"
  48.552 +           x="187.5"
  48.553 +           y="363.07654" />
  48.554 +        <text
  48.555 +           xml:space="preserve"
  48.556 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.557 +           x="196.02321"
  48.558 +           y="400.86459"
  48.559 +           id="text3613"><tspan
  48.560 +             sodipodi:role="line"
  48.561 +             id="tspan3615"
  48.562 +             x="196.02321"
  48.563 +             y="400.86459"
  48.564 +             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  48.565 +        <text
  48.566 +           xml:space="preserve"
  48.567 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.568 +           x="196.71785"
  48.569 +           y="380.17593"
  48.570 +           id="text3617"><tspan
  48.571 +             style="fill:black;fill-opacity:1"
  48.572 +             id="tspan3619"
  48.573 +             sodipodi:role="line"
  48.574 +             x="196.71785"
  48.575 +             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  48.576 +      </g>
  48.577 +    </g>
  48.578 +    <path
  48.579 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Mend)"
  48.580 +       d="M 240.78255,143.08593 L 241.42595,171.75349"
  48.581 +       id="path3801"
  48.582 +       inkscape:connector-type="polyline"
  48.583 +       inkscape:connection-start="#g3573"
  48.584 +       inkscape:connection-end="#g3250" />
  48.585 +    <g
  48.586 +       id="g5677">
  48.587 +      <rect
  48.588 +         style="fill:url(#linearGradient5784);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.589 +         id="rect3393"
  48.590 +         width="101.60232"
  48.591 +         height="89.506805"
  48.592 +         x="150.76137"
  48.593 +         y="278.32565" />
  48.594 +      <g
  48.595 +         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  48.596 +         id="g3399">
  48.597 +        <rect
  48.598 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.599 +           id="rect3401"
  48.600 +           width="103.14286"
  48.601 +           height="48.571426"
  48.602 +           x="188.6071"
  48.603 +           y="447.72418" />
  48.604 +        <text
  48.605 +           xml:space="preserve"
  48.606 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.607 +           x="197.82495"
  48.608 +           y="464.82358"
  48.609 +           id="text3403"><tspan
  48.610 +             id="tspan3405"
  48.611 +             sodipodi:role="line"
  48.612 +             x="197.82495"
  48.613 +             y="464.82358">First parent</tspan></text>
  48.614 +        <text
  48.615 +           xml:space="preserve"
  48.616 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.617 +           x="197.13031"
  48.618 +           y="485.51224"
  48.619 +           id="text3407"><tspan
  48.620 +             sodipodi:role="line"
  48.621 +             id="tspan3409"
  48.622 +             x="197.13031"
  48.623 +             y="485.51224"
  48.624 +             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
  48.625 +      </g>
  48.626 +      <g
  48.627 +         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  48.628 +         id="g3411">
  48.629 +        <rect
  48.630 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.631 +           id="rect3413"
  48.632 +           width="103.14286"
  48.633 +           height="48.571426"
  48.634 +           x="299.67859"
  48.635 +           y="447.71451" />
  48.636 +        <text
  48.637 +           xml:space="preserve"
  48.638 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.639 +           x="308.89639"
  48.640 +           y="464.8139"
  48.641 +           id="text3415"><tspan
  48.642 +             id="tspan3417"
  48.643 +             sodipodi:role="line"
  48.644 +             x="308.89639"
  48.645 +             y="464.8139">Second parent</tspan></text>
  48.646 +        <text
  48.647 +           xml:space="preserve"
  48.648 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.649 +           x="308.20175"
  48.650 +           y="485.50256"
  48.651 +           id="text3419"><tspan
  48.652 +             sodipodi:role="line"
  48.653 +             id="tspan3421"
  48.654 +             x="308.20175"
  48.655 +             y="485.50256"
  48.656 +             style="font-family:Courier">000000000000</tspan></text>
  48.657 +      </g>
  48.658 +      <g
  48.659 +         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  48.660 +         id="g3423">
  48.661 +        <rect
  48.662 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.663 +           id="rect3425"
  48.664 +           width="103.14286"
  48.665 +           height="48.571426"
  48.666 +           x="188.6071"
  48.667 +           y="311.28598" />
  48.668 +        <text
  48.669 +           xml:space="preserve"
  48.670 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.671 +           x="197.82495"
  48.672 +           y="328.38538"
  48.673 +           id="text3427"><tspan
  48.674 +             id="tspan3429"
  48.675 +             sodipodi:role="line"
  48.676 +             x="197.82495"
  48.677 +             y="328.38538">Revision hash</tspan></text>
  48.678 +        <text
  48.679 +           xml:space="preserve"
  48.680 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.681 +           x="197.13031"
  48.682 +           y="349.07404"
  48.683 +           id="text3431"><tspan
  48.684 +             sodipodi:role="line"
  48.685 +             id="tspan3433"
  48.686 +             x="197.13031"
  48.687 +             y="349.07404"
  48.688 +             style="font-family:Courier">5b80c922ebdd</tspan></text>
  48.689 +      </g>
  48.690 +      <g
  48.691 +         transform="matrix(0.423343,0,0,0.423343,76.84265,153.4957)"
  48.692 +         id="g3435">
  48.693 +        <rect
  48.694 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.695 +           id="rect3437"
  48.696 +           width="213.85715"
  48.697 +           height="75"
  48.698 +           x="187.5"
  48.699 +           y="363.07654" />
  48.700 +        <text
  48.701 +           xml:space="preserve"
  48.702 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.703 +           x="196.02321"
  48.704 +           y="400.86459"
  48.705 +           id="text3439"><tspan
  48.706 +             sodipodi:role="line"
  48.707 +             id="tspan3441"
  48.708 +             x="196.02321"
  48.709 +             y="400.86459"
  48.710 +             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  48.711 +        <text
  48.712 +           xml:space="preserve"
  48.713 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.714 +           x="196.71785"
  48.715 +           y="380.17593"
  48.716 +           id="text3443"><tspan
  48.717 +             style="fill:black;fill-opacity:1"
  48.718 +             id="tspan3445"
  48.719 +             sodipodi:role="line"
  48.720 +             x="196.71785"
  48.721 +             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  48.722 +      </g>
  48.723 +    </g>
  48.724 +    <g
  48.725 +       id="g5646"
  48.726 +       transform="translate(-0.227432,0)">
  48.727 +      <rect
  48.728 +         style="fill:url(#linearGradient5786);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.729 +         id="rect3451"
  48.730 +         width="101.60232"
  48.731 +         height="89.506805"
  48.732 +         x="272.63638"
  48.733 +         y="278.32565" />
  48.734 +      <g
  48.735 +         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
  48.736 +         id="g3457">
  48.737 +        <rect
  48.738 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.739 +           id="rect3459"
  48.740 +           width="103.14286"
  48.741 +           height="48.571426"
  48.742 +           x="188.6071"
  48.743 +           y="447.72418" />
  48.744 +        <text
  48.745 +           xml:space="preserve"
  48.746 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.747 +           x="197.82495"
  48.748 +           y="464.82358"
  48.749 +           id="text3461"><tspan
  48.750 +             id="tspan3463"
  48.751 +             sodipodi:role="line"
  48.752 +             x="197.82495"
  48.753 +             y="464.82358">First parent</tspan></text>
  48.754 +        <text
  48.755 +           xml:space="preserve"
  48.756 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.757 +           x="197.13031"
  48.758 +           y="485.51224"
  48.759 +           id="text3465"><tspan
  48.760 +             sodipodi:role="line"
  48.761 +             id="tspan3467"
  48.762 +             x="197.13031"
  48.763 +             y="485.51224"
  48.764 +             style="font-family:Courier">ecacb6b4c9fd</tspan></text>
  48.765 +      </g>
  48.766 +      <g
  48.767 +         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
  48.768 +         id="g3469">
  48.769 +        <rect
  48.770 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.771 +           id="rect3471"
  48.772 +           width="103.14286"
  48.773 +           height="48.571426"
  48.774 +           x="299.67859"
  48.775 +           y="447.71451" />
  48.776 +        <text
  48.777 +           xml:space="preserve"
  48.778 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.779 +           x="308.89639"
  48.780 +           y="464.8139"
  48.781 +           id="text3473"><tspan
  48.782 +             id="tspan3475"
  48.783 +             sodipodi:role="line"
  48.784 +             x="308.89639"
  48.785 +             y="464.8139">Second parent</tspan></text>
  48.786 +        <text
  48.787 +           xml:space="preserve"
  48.788 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.789 +           x="308.20175"
  48.790 +           y="485.50256"
  48.791 +           id="text3477"><tspan
  48.792 +             sodipodi:role="line"
  48.793 +             id="tspan3479"
  48.794 +             x="308.20175"
  48.795 +             y="485.50256"
  48.796 +             style="font-family:Courier">000000000000</tspan></text>
  48.797 +      </g>
  48.798 +      <g
  48.799 +         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
  48.800 +         id="g3481">
  48.801 +        <rect
  48.802 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.803 +           id="rect3483"
  48.804 +           width="103.14286"
  48.805 +           height="48.571426"
  48.806 +           x="188.6071"
  48.807 +           y="311.28598" />
  48.808 +        <text
  48.809 +           xml:space="preserve"
  48.810 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.811 +           x="197.82495"
  48.812 +           y="328.38538"
  48.813 +           id="text3485"><tspan
  48.814 +             id="tspan3487"
  48.815 +             sodipodi:role="line"
  48.816 +             x="197.82495"
  48.817 +             y="328.38538">Revision hash</tspan></text>
  48.818 +        <text
  48.819 +           xml:space="preserve"
  48.820 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.821 +           x="197.13031"
  48.822 +           y="349.07404"
  48.823 +           id="text3489"><tspan
  48.824 +             sodipodi:role="line"
  48.825 +             id="tspan3491"
  48.826 +             x="197.13031"
  48.827 +             y="349.07404"
  48.828 +             style="font-family:Courier">32bf9a5f22c0</tspan></text>
  48.829 +      </g>
  48.830 +      <g
  48.831 +         transform="matrix(0.423343,0,0,0.423343,198.7176,153.4957)"
  48.832 +         id="g3493">
  48.833 +        <rect
  48.834 +           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  48.835 +           id="rect3495"
  48.836 +           width="213.85715"
  48.837 +           height="75"
  48.838 +           x="187.5"
  48.839 +           y="363.07654" />
  48.840 +        <text
  48.841 +           xml:space="preserve"
  48.842 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.843 +           x="196.02321"
  48.844 +           y="400.86459"
  48.845 +           id="text3497"><tspan
  48.846 +             sodipodi:role="line"
  48.847 +             id="tspan3499"
  48.848 +             x="196.02321"
  48.849 +             y="400.86459"
  48.850 +             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  48.851 +        <text
  48.852 +           xml:space="preserve"
  48.853 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.854 +           x="196.71785"
  48.855 +           y="380.17593"
  48.856 +           id="text3501"><tspan
  48.857 +             style="fill:black;fill-opacity:1"
  48.858 +             id="tspan3503"
  48.859 +             sodipodi:role="line"
  48.860 +             x="196.71785"
  48.861 +             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  48.862 +      </g>
  48.863 +    </g>
  48.864 +    <rect
  48.865 +       y="387.90286"
  48.866 +       x="272.40894"
  48.867 +       height="89.506805"
  48.868 +       width="101.60232"
  48.869 +       id="rect5081"
  48.870 +       style="fill:url(#linearGradient5895);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.871 +    <g
  48.872 +       id="g5087"
  48.873 +       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
  48.874 +      <rect
  48.875 +         y="447.72418"
  48.876 +         x="188.6071"
  48.877 +         height="48.571426"
  48.878 +         width="103.14286"
  48.879 +         id="rect5089"
  48.880 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.881 +      <text
  48.882 +         id="text5091"
  48.883 +         y="464.82358"
  48.884 +         x="197.82495"
  48.885 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.886 +         xml:space="preserve"><tspan
  48.887 +           y="464.82358"
  48.888 +           x="197.82495"
  48.889 +           sodipodi:role="line"
  48.890 +           id="tspan5093">First parent</tspan></text>
  48.891 +      <text
  48.892 +         id="text5095"
  48.893 +         y="485.51224"
  48.894 +         x="197.13031"
  48.895 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.896 +         xml:space="preserve"><tspan
  48.897 +           style="font-family:Courier"
  48.898 +           y="485.51224"
  48.899 +           x="197.13031"
  48.900 +           id="tspan5097"
  48.901 +           sodipodi:role="line">ff9dc8bc2a8b</tspan></text>
  48.902 +    </g>
  48.903 +    <g
  48.904 +       id="g5099"
  48.905 +       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
  48.906 +      <rect
  48.907 +         y="447.71451"
  48.908 +         x="299.67859"
  48.909 +         height="48.571426"
  48.910 +         width="103.14286"
  48.911 +         id="rect5101"
  48.912 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.913 +      <text
  48.914 +         id="text5103"
  48.915 +         y="464.8139"
  48.916 +         x="308.89639"
  48.917 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.918 +         xml:space="preserve"><tspan
  48.919 +           y="464.8139"
  48.920 +           x="308.89639"
  48.921 +           sodipodi:role="line"
  48.922 +           id="tspan5105">Second parent</tspan></text>
  48.923 +      <text
  48.924 +         id="text5107"
  48.925 +         y="485.50256"
  48.926 +         x="308.20175"
  48.927 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.928 +         xml:space="preserve"><tspan
  48.929 +           style="font-family:Courier"
  48.930 +           y="485.50256"
  48.931 +           x="308.20175"
  48.932 +           id="tspan5109"
  48.933 +           sodipodi:role="line">000000000000</tspan></text>
  48.934 +    </g>
  48.935 +    <g
  48.936 +       id="g5111"
  48.937 +       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
  48.938 +      <rect
  48.939 +         y="311.28598"
  48.940 +         x="188.6071"
  48.941 +         height="48.571426"
  48.942 +         width="103.14286"
  48.943 +         id="rect5113"
  48.944 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.945 +      <text
  48.946 +         id="text5115"
  48.947 +         y="328.38538"
  48.948 +         x="197.82495"
  48.949 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.950 +         xml:space="preserve"><tspan
  48.951 +           y="328.38538"
  48.952 +           x="197.82495"
  48.953 +           sodipodi:role="line"
  48.954 +           id="tspan5117">Revision hash</tspan></text>
  48.955 +      <text
  48.956 +         id="text5119"
  48.957 +         y="349.07404"
  48.958 +         x="197.13031"
  48.959 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.960 +         xml:space="preserve"><tspan
  48.961 +           style="font-family:Courier"
  48.962 +           y="349.07404"
  48.963 +           x="197.13031"
  48.964 +           id="tspan5121"
  48.965 +           sodipodi:role="line">ecacb6b4c9fd</tspan></text>
  48.966 +    </g>
  48.967 +    <g
  48.968 +       id="g5123"
  48.969 +       transform="matrix(0.423343,0,0,0.423343,198.4901,263.0729)">
  48.970 +      <rect
  48.971 +         y="363.07654"
  48.972 +         x="187.5"
  48.973 +         height="75"
  48.974 +         width="213.85715"
  48.975 +         id="rect5125"
  48.976 +         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  48.977 +      <text
  48.978 +         id="text5127"
  48.979 +         y="400.86459"
  48.980 +         x="196.02321"
  48.981 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.982 +         xml:space="preserve"><tspan
  48.983 +           style="fill:black;fill-opacity:1;font-family:Courier"
  48.984 +           y="400.86459"
  48.985 +           x="196.02321"
  48.986 +           id="tspan5129"
  48.987 +           sodipodi:role="line">...</tspan></text>
  48.988 +      <text
  48.989 +         id="text5131"
  48.990 +         y="380.17593"
  48.991 +         x="196.71785"
  48.992 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  48.993 +         xml:space="preserve"><tspan
  48.994 +           y="380.17593"
  48.995 +           x="196.71785"
  48.996 +           sodipodi:role="line"
  48.997 +           id="tspan5133"
  48.998 +           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
  48.999 +    </g>
 48.1000 +    <path
 48.1001 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 48.1002 +       d="M 299.69935,362.24027 L 299.69931,393.49494"
 48.1003 +       id="path5203"
 48.1004 +       inkscape:connector-type="polyline"
 48.1005 +       inkscape:connection-start="#g3457"
 48.1006 +       inkscape:connection-end="#g5111" />
 48.1007 +    <path
 48.1008 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
 48.1009 +       d="M 182.35357,362.22647 L 241.2842,503.07224"
 48.1010 +       id="path5271"
 48.1011 +       inkscape:connector-type="polyline"
 48.1012 +       inkscape:connection-start="#g3399"
 48.1013 +       inkscape:connection-end="#g3539" />
 48.1014 +    <path
 48.1015 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 48.1016 +       d="M 287.63109,471.81747 L 250.9438,503.07223"
 48.1017 +       id="path5285"
 48.1018 +       inkscape:connector-type="polyline"
 48.1019 +       inkscape:connection-start="#g5087"
 48.1020 +       inkscape:connection-end="#g3539" />
 48.1021 +    <path
 48.1022 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 48.1023 +       d="M 290.80419,250.07192 L 297.80065,283.90394"
 48.1024 +       id="path5077"
 48.1025 +       inkscape:connector-type="polyline"
 48.1026 +       inkscape:connection-start="#g3215"
 48.1027 +       inkscape:connection-end="#g3481" />
 48.1028 +    <path
 48.1029 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 48.1030 +       d="M 229.63373,250.07601 L 190.07484,283.90394"
 48.1031 +       id="path5075"
 48.1032 +       inkscape:connector-type="polyline"
 48.1033 +       inkscape:connection-end="#g3423" />
 48.1034 +    <text
 48.1035 +       xml:space="preserve"
 48.1036 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 48.1037 +       x="131.5625"
 48.1038 +       y="100.79968"
 48.1039 +       id="text5897"><tspan
 48.1040 +         sodipodi:role="line"
 48.1041 +         id="tspan5899"
 48.1042 +         x="131.5625"
 48.1043 +         y="100.79968"
 48.1044 +         style="text-align:end;text-anchor:end">Head revision</tspan><tspan
 48.1045 +         sodipodi:role="line"
 48.1046 +         x="131.5625"
 48.1047 +         y="115.79968"
 48.1048 +         id="tspan5901"
 48.1049 +         style="text-align:end;text-anchor:end">(no children)</tspan></text>
 48.1050 +    <text
 48.1051 +       xml:space="preserve"
 48.1052 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 48.1053 +       x="131.5625"
 48.1054 +       y="207.04968"
 48.1055 +       id="text5903"><tspan
 48.1056 +         sodipodi:role="line"
 48.1057 +         id="tspan5905"
 48.1058 +         x="131.5625"
 48.1059 +         y="207.04968"
 48.1060 +         style="text-align:end;text-anchor:end">Merge revision</tspan><tspan
 48.1061 +         sodipodi:role="line"
 48.1062 +         x="131.5625"
 48.1063 +         y="222.04968"
 48.1064 +         id="tspan5907"
 48.1065 +         style="text-align:end;text-anchor:end">(two parents)</tspan></text>
 48.1066 +    <text
 48.1067 +       xml:space="preserve"
 48.1068 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 48.1069 +       x="131.92578"
 48.1070 +       y="451.58093"
 48.1071 +       id="text5909"><tspan
 48.1072 +         sodipodi:role="line"
 48.1073 +         id="tspan5911"
 48.1074 +         x="131.92578"
 48.1075 +         y="451.58093"
 48.1076 +         style="text-align:end;text-anchor:end">Branches</tspan><tspan
 48.1077 +         sodipodi:role="line"
 48.1078 +         x="131.92578"
 48.1079 +         y="466.58093"
 48.1080 +         id="tspan5913"
 48.1081 +         style="text-align:end;text-anchor:end">(two revisions,</tspan><tspan
 48.1082 +         sodipodi:role="line"
 48.1083 +         x="131.92578"
 48.1084 +         y="481.58093"
 48.1085 +         id="tspan5915"
 48.1086 +         style="text-align:end;text-anchor:end">same parent)</tspan></text>
 48.1087 +    <path
 48.1088 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 48.1089 +       d="M 111.71875,433.61218 L 154.7268,368.52294"
 48.1090 +       id="path5917"
 48.1091 +       inkscape:connector-type="polyline" />
 48.1092 +    <path
 48.1093 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 48.1094 +       d="M 134.375,464.86218 L 277.86691,440.37816"
 48.1095 +       id="path5919"
 48.1096 +       inkscape:connector-type="polyline"
 48.1097 +       inkscape:connection-end="#g5123" />
 48.1098 +    <text
 48.1099 +       xml:space="preserve"
 48.1100 +       style="font-size:12px;font-style:normal;font-weight:normal;text-align:end;text-anchor:end;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 48.1101 +       x="131.5625"
 48.1102 +       y="536.73718"
 48.1103 +       id="text5927"><tspan
 48.1104 +         sodipodi:role="line"
 48.1105 +         id="tspan5929"
 48.1106 +         x="131.5625"
 48.1107 +         y="536.73718">First revision</tspan><tspan
 48.1108 +         sodipodi:role="line"
 48.1109 +         x="131.5625"
 48.1110 +         y="551.73718"
 48.1111 +         id="tspan5931">(both parents null)</tspan></text>
 48.1112 +    <rect
 48.1113 +       style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 48.1114 +       id="rect2830"
 48.1115 +       width="43.664806"
 48.1116 +       height="20.562374"
 48.1117 +       x="217.0432"
 48.1118 +       y="232.10075" />
 48.1119 +    <text
 48.1120 +       xml:space="preserve"
 48.1121 +       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 48.1122 +       x="220.94551"
 48.1123 +       y="239.33966"
 48.1124 +       id="text2832"><tspan
 48.1125 +         id="tspan2836"
 48.1126 +         sodipodi:role="line"
 48.1127 +         x="220.94551"
 48.1128 +         y="239.33966">First parent</tspan></text>
 48.1129 +    <text
 48.1130 +       xml:space="preserve"
 48.1131 +       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 48.1132 +       x="220.65144"
 48.1133 +       y="248.09805"
 48.1134 +       id="text2879"><tspan
 48.1135 +         sodipodi:role="line"
 48.1136 +         id="tspan2881"
 48.1137 +         x="220.65144"
 48.1138 +         y="248.09805"
 48.1139 +         style="font-family:Courier">5b80c922ebdd</tspan></text>
 48.1140 +    <path
 48.1141 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 48.1142 +       d="M 139.84375,107.83093 L 210.15625,107.83093"
 48.1143 +       id="path5965"
 48.1144 +       inkscape:connector-type="polyline" />
 48.1145 +    <path
 48.1146 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 48.1147 +       d="M 137.5,213.29968 L 210.49036,214.09055"
 48.1148 +       id="path5967"
 48.1149 +       inkscape:connector-type="polyline" />
 48.1150 +    <path
 48.1151 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 48.1152 +       d="M 136.34375,544.54968 L 206.65625,544.54968"
 48.1153 +       id="path5969"
 48.1154 +       inkscape:connector-type="polyline"
 48.1155 +       inkscape:transform-center-y="-171.09375"
 48.1156 +       inkscape:transform-center-x="53.90625" />
 48.1157 +  </g>
 48.1158 +</svg>
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/fr/figs/snapshot.svg	Sun Aug 16 04:58:01 2009 +0200
    49.3 @@ -0,0 +1,202 @@
    49.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    49.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    49.6 +<svg
    49.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    49.8 +   xmlns:cc="http://web.resource.org/cc/"
    49.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   49.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   49.11 +   xmlns="http://www.w3.org/2000/svg"
   49.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   49.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   49.14 +   width="744.09448819"
   49.15 +   height="1052.3622047"
   49.16 +   id="svg2807"
   49.17 +   sodipodi:version="0.32"
   49.18 +   inkscape:version="0.44.1"
   49.19 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   49.20 +   sodipodi:docname="snapshots.svg">
   49.21 +  <defs
   49.22 +     id="defs2809" />
   49.23 +  <sodipodi:namedview
   49.24 +     id="base"
   49.25 +     pagecolor="#ffffff"
   49.26 +     bordercolor="#666666"
   49.27 +     borderopacity="1.0"
   49.28 +     gridtolerance="10000"
   49.29 +     guidetolerance="10"
   49.30 +     objecttolerance="10"
   49.31 +     inkscape:pageopacity="0.0"
   49.32 +     inkscape:pageshadow="2"
   49.33 +     inkscape:zoom="1.4"
   49.34 +     inkscape:cx="252.04111"
   49.35 +     inkscape:cy="605.75448"
   49.36 +     inkscape:document-units="px"
   49.37 +     inkscape:current-layer="layer1"
   49.38 +     inkscape:window-width="906"
   49.39 +     inkscape:window-height="721"
   49.40 +     inkscape:window-x="0"
   49.41 +     inkscape:window-y="25" />
   49.42 +  <metadata
   49.43 +     id="metadata2812">
   49.44 +    <rdf:RDF>
   49.45 +      <cc:Work
   49.46 +         rdf:about="">
   49.47 +        <dc:format>image/svg+xml</dc:format>
   49.48 +        <dc:type
   49.49 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   49.50 +      </cc:Work>
   49.51 +    </rdf:RDF>
   49.52 +  </metadata>
   49.53 +  <g
   49.54 +     inkscape:label="Layer 1"
   49.55 +     inkscape:groupmode="layer"
   49.56 +     id="layer1">
   49.57 +    <rect
   49.58 +       style="opacity:1;fill:#d3ceff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.88795626;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
   49.59 +       id="rect2817"
   49.60 +       width="118.18347"
   49.61 +       height="245.32632"
   49.62 +       x="243.05112"
   49.63 +       y="315.4133"
   49.64 +       inkscape:transform-center-x="136.84403"
   49.65 +       inkscape:transform-center-y="-66.529183" />
   49.66 +    <rect
   49.67 +       y="315.04153"
   49.68 +       x="46.965065"
   49.69 +       height="97.803009"
   49.70 +       width="108.92702"
   49.71 +       id="rect2815"
   49.72 +       style="fill:#ffced6;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.14441991;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
   49.73 +    <g
   49.74 +       id="g3814">
   49.75 +      <rect
   49.76 +         y="348.94302"
   49.77 +         x="59.285713"
   49.78 +         height="30"
   49.79 +         width="84.285713"
   49.80 +         id="rect2819"
   49.81 +         style="fill:#ff6e86;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
   49.82 +         ry="0" />
   49.83 +      <text
   49.84 +         id="text2821"
   49.85 +         y="368.02701"
   49.86 +         x="72.717636"
   49.87 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
   49.88 +         xml:space="preserve"><tspan
   49.89 +           y="368.02701"
   49.90 +           x="72.717636"
   49.91 +           id="tspan2823"
   49.92 +           sodipodi:role="line">Index, rev 7</tspan></text>
   49.93 +    </g>
   49.94 +    <text
   49.95 +       id="text3722"
   49.96 +       y="301.29074"
   49.97 +       x="46.187778"
   49.98 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
   49.99 +       xml:space="preserve"><tspan
  49.100 +         y="301.29074"
  49.101 +         x="46.187778"
  49.102 +         id="tspan3724"
  49.103 +         sodipodi:role="line">Revlog index (.i file)</tspan></text>
  49.104 +    <text
  49.105 +       id="text3726"
  49.106 +       y="301.29074"
  49.107 +       x="241.90207"
  49.108 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  49.109 +       xml:space="preserve"><tspan
  49.110 +         y="301.29074"
  49.111 +         x="241.90207"
  49.112 +         id="tspan3728"
  49.113 +         sodipodi:role="line">Revlog data (.d file)</tspan></text>
  49.114 +    <path
  49.115 +       style="fill:#c695ff;fill-opacity:0.60109288;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  49.116 +       d="M 143.57143,348.07647 L 255,368.07646 L 255.71429,544.50504 L 142.85714,379.50504 L 143.57143,348.07647 z "
  49.117 +       id="path3839"
  49.118 +       sodipodi:nodetypes="ccccc" />
  49.119 +    <rect
  49.120 +       style="fill:#4733ff;fill-opacity:1;stroke:#a7a7a7;stroke-width:2.35124183;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  49.121 +       id="rect3752"
  49.122 +       width="92.720184"
  49.123 +       height="67.005905"
  49.124 +       x="255.42564"
  49.125 +       y="368.64264" />
  49.126 +    <text
  49.127 +       xml:space="preserve"
  49.128 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  49.129 +       x="264.45859"
  49.130 +       y="387.30099"
  49.131 +       id="text3754"><tspan
  49.132 +         sodipodi:role="line"
  49.133 +         id="tspan3756"
  49.134 +         x="264.45859"
  49.135 +         y="387.30099">Snapshot, rev 4</tspan></text>
  49.136 +    <rect
  49.137 +       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  49.138 +       id="rect3761"
  49.139 +       width="93.49366"
  49.140 +       height="29.922237"
  49.141 +       x="255.03891"
  49.142 +       y="442.04395" />
  49.143 +    <text
  49.144 +       xml:space="preserve"
  49.145 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  49.146 +       x="263.2662"
  49.147 +       y="460.17206"
  49.148 +       id="text3763"><tspan
  49.149 +         sodipodi:role="line"
  49.150 +         id="tspan3765"
  49.151 +         x="263.2662"
  49.152 +         y="460.17206">Delta, rev 4 to 5</tspan></text>
  49.153 +    <rect
  49.154 +       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  49.155 +       id="rect3774"
  49.156 +       width="93.49366"
  49.157 +       height="29.922237"
  49.158 +       x="255.03891"
  49.159 +       y="477.97485" />
  49.160 +    <text
  49.161 +       xml:space="preserve"
  49.162 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  49.163 +       x="263.2662"
  49.164 +       y="496.10297"
  49.165 +       id="text3776"><tspan
  49.166 +         sodipodi:role="line"
  49.167 +         id="tspan3778"
  49.168 +         x="263.2662"
  49.169 +         y="496.10297">Delta, rev 5 to 6</tspan></text>
  49.170 +    <rect
  49.171 +       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  49.172 +       id="rect3782"
  49.173 +       width="93.49366"
  49.174 +       height="29.922237"
  49.175 +       x="255.03891"
  49.176 +       y="513.90576" />
  49.177 +    <text
  49.178 +       xml:space="preserve"
  49.179 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  49.180 +       x="263.2662"
  49.181 +       y="532.03387"
  49.182 +       id="text3784"><tspan
  49.183 +         sodipodi:role="line"
  49.184 +         id="tspan3786"
  49.185 +         x="263.2662"
  49.186 +         y="532.03387">Delta, rev 6 to 7</tspan></text>
  49.187 +    <rect
  49.188 +       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  49.189 +       id="rect3889"
  49.190 +       width="93.49366"
  49.191 +       height="29.922237"
  49.192 +       x="255.03891"
  49.193 +       y="332.32489" />
  49.194 +    <text
  49.195 +       xml:space="preserve"
  49.196 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  49.197 +       x="263.2662"
  49.198 +       y="350.453"
  49.199 +       id="text3891"><tspan
  49.200 +         sodipodi:role="line"
  49.201 +         id="tspan3893"
  49.202 +         x="263.2662"
  49.203 +         y="350.453">Delta, rev 2 to 3</tspan></text>
  49.204 +  </g>
  49.205 +</svg>
    50.1 Binary file fr/figs/throbber.gif has changed
    51.1 Binary file fr/figs/tip.png has changed
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/fr/figs/tour-history.svg	Sun Aug 16 04:58:01 2009 +0200
    52.3 @@ -0,0 +1,289 @@
    52.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    52.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    52.6 +<svg
    52.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    52.8 +   xmlns:cc="http://web.resource.org/cc/"
    52.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   52.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   52.11 +   xmlns="http://www.w3.org/2000/svg"
   52.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   52.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   52.14 +   width="744.09448819"
   52.15 +   height="1052.3622047"
   52.16 +   id="svg2"
   52.17 +   sodipodi:version="0.32"
   52.18 +   inkscape:version="0.44.1"
   52.19 +   sodipodi:docname="tour-history.svg">
   52.20 +  <defs
   52.21 +     id="defs4">
   52.22 +    <marker
   52.23 +       inkscape:stockid="Arrow1Mstart"
   52.24 +       orient="auto"
   52.25 +       refY="0.0"
   52.26 +       refX="0.0"
   52.27 +       id="Arrow1Mstart"
   52.28 +       style="overflow:visible">
   52.29 +      <path
   52.30 +         id="path2973"
   52.31 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   52.32 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   52.33 +         transform="scale(0.4) translate(10,0)" />
   52.34 +    </marker>
   52.35 +    <marker
   52.36 +       inkscape:stockid="Arrow1Mend"
   52.37 +       orient="auto"
   52.38 +       refY="0.0"
   52.39 +       refX="0.0"
   52.40 +       id="Arrow1Mend"
   52.41 +       style="overflow:visible;">
   52.42 +      <path
   52.43 +         id="path3066"
   52.44 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   52.45 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   52.46 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   52.47 +    </marker>
   52.48 +  </defs>
   52.49 +  <sodipodi:namedview
   52.50 +     id="base"
   52.51 +     pagecolor="#ffffff"
   52.52 +     bordercolor="#666666"
   52.53 +     borderopacity="1.0"
   52.54 +     gridtolerance="10000"
   52.55 +     guidetolerance="10"
   52.56 +     objecttolerance="10"
   52.57 +     inkscape:pageopacity="0.0"
   52.58 +     inkscape:pageshadow="2"
   52.59 +     inkscape:zoom="1.4"
   52.60 +     inkscape:cx="232.14286"
   52.61 +     inkscape:cy="672.75296"
   52.62 +     inkscape:document-units="px"
   52.63 +     inkscape:current-layer="layer1"
   52.64 +     inkscape:window-width="906"
   52.65 +     inkscape:window-height="620"
   52.66 +     inkscape:window-x="5"
   52.67 +     inkscape:window-y="49" />
   52.68 +  <metadata
   52.69 +     id="metadata7">
   52.70 +    <rdf:RDF>
   52.71 +      <cc:Work
   52.72 +         rdf:about="">
   52.73 +        <dc:format>image/svg+xml</dc:format>
   52.74 +        <dc:type
   52.75 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   52.76 +      </cc:Work>
   52.77 +    </rdf:RDF>
   52.78 +  </metadata>
   52.79 +  <g
   52.80 +     inkscape:label="Layer 1"
   52.81 +     inkscape:groupmode="layer"
   52.82 +     id="layer1">
   52.83 +    <rect
   52.84 +       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   52.85 +       id="rect1878"
   52.86 +       width="94.285713"
   52.87 +       height="20.714285"
   52.88 +       x="138"
   52.89 +       y="479.50504" />
   52.90 +    <text
   52.91 +       xml:space="preserve"
   52.92 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   52.93 +       x="162.09892"
   52.94 +       y="493.12619"
   52.95 +       id="text1872"><tspan
   52.96 +         sodipodi:role="line"
   52.97 +         id="tspan1874"
   52.98 +         x="162.09892"
   52.99 +         y="493.12619"
  52.100 +         style="font-family:Courier"><tspan
  52.101 +   style="font-weight:bold"
  52.102 +   id="tspan1876">0</tspan>: REV0</tspan></text>
  52.103 +    <rect
  52.104 +       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  52.105 +       id="rect2800"
  52.106 +       width="94.285713"
  52.107 +       height="20.714285"
  52.108 +       x="138"
  52.109 +       y="432.63004" />
  52.110 +    <text
  52.111 +       xml:space="preserve"
  52.112 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  52.113 +       x="162.09892"
  52.114 +       y="446.25119"
  52.115 +       id="text2794"><tspan
  52.116 +         sodipodi:role="line"
  52.117 +         id="tspan2796"
  52.118 +         x="162.09892"
  52.119 +         y="446.25119"
  52.120 +         style="font-family:Courier"><tspan
  52.121 +   id="tspan2868"
  52.122 +   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  52.123 +    <rect
  52.124 +       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  52.125 +       id="rect2810"
  52.126 +       width="94.285713"
  52.127 +       height="20.714285"
  52.128 +       x="138"
  52.129 +       y="385.75504" />
  52.130 +    <text
  52.131 +       xml:space="preserve"
  52.132 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  52.133 +       x="162.09892"
  52.134 +       y="399.37619"
  52.135 +       id="text2804"><tspan
  52.136 +         sodipodi:role="line"
  52.137 +         id="tspan2806"
  52.138 +         x="162.09892"
  52.139 +         y="399.37619"
  52.140 +         style="font-family:Courier"><tspan
  52.141 +   style="font-weight:bold"
  52.142 +   id="tspan2866">2</tspan>: REV2</tspan></text>
  52.143 +    <rect
  52.144 +       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  52.145 +       id="rect2820"
  52.146 +       width="94.285713"
  52.147 +       height="20.714285"
  52.148 +       x="138"
  52.149 +       y="338.88007" />
  52.150 +    <text
  52.151 +       xml:space="preserve"
  52.152 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  52.153 +       x="162.09892"
  52.154 +       y="352.50122"
  52.155 +       id="text2814"><tspan
  52.156 +         sodipodi:role="line"
  52.157 +         id="tspan2816"
  52.158 +         x="162.09892"
  52.159 +         y="352.50122"
  52.160 +         style="font-family:Courier"><tspan
  52.161 +   style="font-weight:bold"
  52.162 +   id="tspan2864">3</tspan>: REV3</tspan></text>
  52.163 +    <rect
  52.164 +       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  52.165 +       id="rect2830"
  52.166 +       width="94.285713"
  52.167 +       height="20.714285"
  52.168 +       x="138"
  52.169 +       y="292.00504" />
  52.170 +    <text
  52.171 +       xml:space="preserve"
  52.172 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  52.173 +       x="162.09892"
  52.174 +       y="305.62619"
  52.175 +       id="text2824"><tspan
  52.176 +         sodipodi:role="line"
  52.177 +         id="tspan2826"
  52.178 +         x="162.09892"
  52.179 +         y="305.62619"
  52.180 +         style="font-family:Courier"><tspan
  52.181 +   style="font-weight:bold"
  52.182 +   id="tspan2862">4</tspan>: REV4</tspan></text>
  52.183 +    <text
  52.184 +       xml:space="preserve"
  52.185 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  52.186 +       x="173.57143"
  52.187 +       y="443.79074"
  52.188 +       id="text2832"><tspan
  52.189 +         sodipodi:role="line"
  52.190 +         id="tspan2834"
  52.191 +         x="173.57143"
  52.192 +         y="443.79074" /></text>
  52.193 +    <path
  52.194 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  52.195 +       d="M 185.14286,478.50504 L 185.14286,454.34432"
  52.196 +       id="path2894"
  52.197 +       inkscape:connector-type="polyline" />
  52.198 +    <path
  52.199 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  52.200 +       d="M 185.14286,431.63004 L 185.14286,407.46932"
  52.201 +       id="path2896"
  52.202 +       inkscape:connector-type="polyline" />
  52.203 +    <path
  52.204 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  52.205 +       d="M 185.14286,384.75504 L 185.14286,360.59435"
  52.206 +       id="path2898"
  52.207 +       inkscape:connector-type="polyline" />
  52.208 +    <path
  52.209 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  52.210 +       d="M 185.14286,337.88007 L 185.14286,313.71932"
  52.211 +       id="path2900"
  52.212 +       inkscape:connector-type="polyline" />
  52.213 +    <text
  52.214 +       xml:space="preserve"
  52.215 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  52.216 +       x="244.60992"
  52.217 +       y="305.245"
  52.218 +       id="text1902"><tspan
  52.219 +         sodipodi:role="line"
  52.220 +         id="tspan1904"
  52.221 +         x="244.60992"
  52.222 +         y="305.245">(newest)</tspan></text>
  52.223 +    <text
  52.224 +       xml:space="preserve"
  52.225 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  52.226 +       x="244.60992"
  52.227 +       y="492.745"
  52.228 +       id="text1906"><tspan
  52.229 +         sodipodi:role="line"
  52.230 +         id="tspan1908"
  52.231 +         x="244.60992"
  52.232 +         y="492.745">(oldest)</tspan></text>
  52.233 +    <rect
  52.234 +       style="opacity:1;fill:#d2e1e4;fill-opacity:1;stroke:#b1cbd0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  52.235 +       id="rect1907"
  52.236 +       width="94.285713"
  52.237 +       height="20.714285"
  52.238 +       x="309.28571"
  52.239 +       y="324.86218" />
  52.240 +    <text
  52.241 +       xml:space="preserve"
  52.242 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  52.243 +       x="333.38464"
  52.244 +       y="338.48334"
  52.245 +       id="text1909"><tspan
  52.246 +         sodipodi:role="line"
  52.247 +         id="tspan1911"
  52.248 +         x="333.38464"
  52.249 +         y="338.48334"
  52.250 +         style="font-family:Courier"><tspan
  52.251 +   style="font-weight:bold"
  52.252 +   id="tspan1913">4</tspan>: REV4</tspan></text>
  52.253 +    <path
  52.254 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  52.255 +       d="M 332.14286,375.21932 L 335.71429,347.36218"
  52.256 +       id="path2802" />
  52.257 +    <path
  52.258 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  52.259 +       d="M 372.69968,375.21932 L 369.12825,347.36218"
  52.260 +       id="path2986" />
  52.261 +    <text
  52.262 +       xml:space="preserve"
  52.263 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  52.264 +       x="335.14285"
  52.265 +       y="387.21933"
  52.266 +       id="text2988"><tspan
  52.267 +         sodipodi:role="line"
  52.268 +         x="335.14285"
  52.269 +         y="387.21933"
  52.270 +         id="tspan3020"
  52.271 +         style="text-align:end;text-anchor:end">revision</tspan><tspan
  52.272 +         sodipodi:role="line"
  52.273 +         x="335.14285"
  52.274 +         y="402.21933"
  52.275 +         id="tspan3014"
  52.276 +         style="text-align:end;text-anchor:end">number</tspan></text>
  52.277 +    <text
  52.278 +       xml:space="preserve"
  52.279 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  52.280 +       x="368.71429"
  52.281 +       y="387.21933"
  52.282 +       id="text2994"><tspan
  52.283 +         sodipodi:role="line"
  52.284 +         id="tspan2996"
  52.285 +         x="368.71429"
  52.286 +         y="387.21933">changeset</tspan><tspan
  52.287 +         sodipodi:role="line"
  52.288 +         x="368.71429"
  52.289 +         y="402.21933"
  52.290 +         id="tspan2998">identifier</tspan></text>
  52.291 +  </g>
  52.292 +</svg>
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/fr/figs/tour-merge-conflict.svg	Sun Aug 16 04:58:01 2009 +0200
    53.3 @@ -0,0 +1,210 @@
    53.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    53.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    53.6 +<svg
    53.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    53.8 +   xmlns:cc="http://web.resource.org/cc/"
    53.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   53.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   53.11 +   xmlns="http://www.w3.org/2000/svg"
   53.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   53.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   53.14 +   width="744.09448819"
   53.15 +   height="1052.3622047"
   53.16 +   id="svg2"
   53.17 +   sodipodi:version="0.32"
   53.18 +   inkscape:version="0.44.1"
   53.19 +   sodipodi:docname="tour-merge-conflict.svg">
   53.20 +  <defs
   53.21 +     id="defs4">
   53.22 +    <marker
   53.23 +       inkscape:stockid="Arrow1Mend"
   53.24 +       orient="auto"
   53.25 +       refY="0.0"
   53.26 +       refX="0.0"
   53.27 +       id="Arrow1Mend"
   53.28 +       style="overflow:visible;">
   53.29 +      <path
   53.30 +         id="path3053"
   53.31 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   53.32 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   53.33 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   53.34 +    </marker>
   53.35 +  </defs>
   53.36 +  <sodipodi:namedview
   53.37 +     id="base"
   53.38 +     pagecolor="#ffffff"
   53.39 +     bordercolor="#666666"
   53.40 +     borderopacity="1.0"
   53.41 +     gridtolerance="10000"
   53.42 +     guidetolerance="10"
   53.43 +     objecttolerance="10"
   53.44 +     inkscape:pageopacity="0.0"
   53.45 +     inkscape:pageshadow="2"
   53.46 +     inkscape:zoom="1.4"
   53.47 +     inkscape:cx="164.78349"
   53.48 +     inkscape:cy="590.07679"
   53.49 +     inkscape:document-units="px"
   53.50 +     inkscape:current-layer="layer1"
   53.51 +     inkscape:window-width="906"
   53.52 +     inkscape:window-height="620"
   53.53 +     inkscape:window-x="5"
   53.54 +     inkscape:window-y="49" />
   53.55 +  <metadata
   53.56 +     id="metadata7">
   53.57 +    <rdf:RDF>
   53.58 +      <cc:Work
   53.59 +         rdf:about="">
   53.60 +        <dc:format>image/svg+xml</dc:format>
   53.61 +        <dc:type
   53.62 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   53.63 +      </cc:Work>
   53.64 +    </rdf:RDF>
   53.65 +  </metadata>
   53.66 +  <g
   53.67 +     inkscape:label="Layer 1"
   53.68 +     inkscape:groupmode="layer"
   53.69 +     id="layer1">
   53.70 +    <g
   53.71 +       id="g1988"
   53.72 +       transform="translate(84.85711,0)">
   53.73 +      <g
   53.74 +         id="g1876">
   53.75 +        <path
   53.76 +           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   53.77 +           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
   53.78 +           id="path1872"
   53.79 +           sodipodi:nodetypes="cccccc" />
   53.80 +        <path
   53.81 +           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   53.82 +           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
   53.83 +           id="path1874"
   53.84 +           sodipodi:nodetypes="cccc" />
   53.85 +      </g>
   53.86 +      <flowRoot
   53.87 +         style="font-size:8px;font-family:Times New Roman"
   53.88 +         id="flowRoot1898"
   53.89 +         xml:space="preserve"><flowRegion
   53.90 +           id="flowRegion1900"><rect
   53.91 +             style="font-size:8px;font-family:Times New Roman"
   53.92 +             y="464.50504"
   53.93 +             x="122.85714"
   53.94 +             height="93.571426"
   53.95 +             width="76.428574"
   53.96 +             id="rect1902" /></flowRegion><flowPara
   53.97 +           id="flowPara1904">Greetings!</flowPara><flowPara
   53.98 +           id="flowPara1906" /><flowPara
   53.99 +           id="flowPara1908">I am Mariam Abacha, the wife of former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
  53.100 +    <g
  53.101 +       id="g1966"
  53.102 +       transform="translate(82,0.35715)">
  53.103 +      <g
  53.104 +         transform="translate(-77.85718,-140.0714)"
  53.105 +         id="g1910">
  53.106 +        <path
  53.107 +           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  53.108 +           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
  53.109 +           id="path1912"
  53.110 +           sodipodi:nodetypes="cccccc" />
  53.111 +        <path
  53.112 +           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  53.113 +           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
  53.114 +           id="path1914"
  53.115 +           sodipodi:nodetypes="cccc" />
  53.116 +      </g>
  53.117 +      <flowRoot
  53.118 +         transform="translate(-77.85718,-140.0714)"
  53.119 +         style="font-size:8px;font-family:Times New Roman"
  53.120 +         id="flowRoot1916"
  53.121 +         xml:space="preserve"><flowRegion
  53.122 +           id="flowRegion1918"><rect
  53.123 +             style="font-size:8px;font-family:Times New Roman"
  53.124 +             y="464.50504"
  53.125 +             x="122.85714"
  53.126 +             height="93.571426"
  53.127 +             width="76.428574"
  53.128 +             id="rect1920" /></flowRegion><flowPara
  53.129 +           id="flowPara1922">Greetings!</flowPara><flowPara
  53.130 +           id="flowPara1924" /><flowPara
  53.131 +           id="flowPara1926">I am <flowSpan
  53.132 +   style="font-style:italic;fill:red"
  53.133 +   id="flowSpan3094">Shehu Musa Abacha, cousin to</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
  53.134 +    <g
  53.135 +       id="g1977"
  53.136 +       transform="translate(81.99999,-0.35715)">
  53.137 +      <g
  53.138 +         transform="translate(83.57141,-139.3571)"
  53.139 +         id="g1932">
  53.140 +        <path
  53.141 +           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  53.142 +           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
  53.143 +           id="path1934"
  53.144 +           sodipodi:nodetypes="cccccc" />
  53.145 +        <path
  53.146 +           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  53.147 +           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
  53.148 +           id="path1936"
  53.149 +           sodipodi:nodetypes="cccc" />
  53.150 +      </g>
  53.151 +      <flowRoot
  53.152 +         transform="translate(83.57141,-139.3571)"
  53.153 +         style="font-size:8px;font-family:Times New Roman"
  53.154 +         id="flowRoot1938"
  53.155 +         xml:space="preserve"><flowRegion
  53.156 +           id="flowRegion1940"><rect
  53.157 +             style="font-size:8px;font-family:Times New Roman"
  53.158 +             y="464.50504"
  53.159 +             x="122.85714"
  53.160 +             height="93.571426"
  53.161 +             width="76.428574"
  53.162 +             id="rect1942" /></flowRegion><flowPara
  53.163 +           id="flowPara1944">Greetings!</flowPara><flowPara
  53.164 +           id="flowPara1946" /><flowPara
  53.165 +           id="flowPara1948">I am <flowSpan
  53.166 +   style="font-style:italic;fill:red"
  53.167 +   id="flowSpan3096">Alhaji Abba Abacha, son of</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
  53.168 +    <path
  53.169 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  53.170 +       d="M 215.502,457.71933 L 196.35507,424.5765"
  53.171 +       id="path1999"
  53.172 +       inkscape:connector-type="polyline"
  53.173 +       inkscape:connection-start="#g1988"
  53.174 +       inkscape:connection-end="#g1966" />
  53.175 +    <path
  53.176 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  53.177 +       d="M 277.06936,457.71933 L 296.21629,424.5765"
  53.178 +       id="path2001"
  53.179 +       inkscape:connector-type="polyline"
  53.180 +       inkscape:connection-start="#g1988"
  53.181 +       inkscape:connection-end="#g1977" />
  53.182 +    <text
  53.183 +       xml:space="preserve"
  53.184 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  53.185 +       x="302.42859"
  53.186 +       y="515.08905"
  53.187 +       id="text1905"><tspan
  53.188 +         sodipodi:role="line"
  53.189 +         id="tspan1907"
  53.190 +         x="302.42859"
  53.191 +         y="515.08905">Base version</tspan></text>
  53.192 +    <text
  53.193 +       xml:space="preserve"
  53.194 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  53.195 +       x="45.57143"
  53.196 +       y="374.1619"
  53.197 +       id="text1917"><tspan
  53.198 +         sodipodi:role="line"
  53.199 +         id="tspan1919"
  53.200 +         x="45.57143"
  53.201 +         y="374.1619">Our changes</tspan></text>
  53.202 +    <text
  53.203 +       xml:space="preserve"
  53.204 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  53.205 +       x="385.71429"
  53.206 +       y="374.1619"
  53.207 +       id="text1921"><tspan
  53.208 +         sodipodi:role="line"
  53.209 +         id="tspan1923"
  53.210 +         x="385.71429"
  53.211 +         y="374.1619">Their changes</tspan></text>
  53.212 +  </g>
  53.213 +</svg>
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/fr/figs/tour-merge-merge.svg	Sun Aug 16 04:58:01 2009 +0200
    54.3 @@ -0,0 +1,380 @@
    54.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    54.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    54.6 +<svg
    54.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    54.8 +   xmlns:cc="http://web.resource.org/cc/"
    54.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   54.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   54.11 +   xmlns="http://www.w3.org/2000/svg"
   54.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   54.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   54.14 +   width="744.09448819"
   54.15 +   height="1052.3622047"
   54.16 +   id="svg2"
   54.17 +   sodipodi:version="0.32"
   54.18 +   inkscape:version="0.44.1"
   54.19 +   sodipodi:docname="tour-merge-merge.svg">
   54.20 +  <defs
   54.21 +     id="defs4">
   54.22 +    <marker
   54.23 +       inkscape:stockid="Arrow1Mstart"
   54.24 +       orient="auto"
   54.25 +       refY="0.0"
   54.26 +       refX="0.0"
   54.27 +       id="Arrow1Mstart"
   54.28 +       style="overflow:visible">
   54.29 +      <path
   54.30 +         id="path2973"
   54.31 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   54.32 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   54.33 +         transform="scale(0.4) translate(10,0)" />
   54.34 +    </marker>
   54.35 +    <marker
   54.36 +       inkscape:stockid="Arrow1Mend"
   54.37 +       orient="auto"
   54.38 +       refY="0.0"
   54.39 +       refX="0.0"
   54.40 +       id="Arrow1Mend"
   54.41 +       style="overflow:visible;">
   54.42 +      <path
   54.43 +         id="path3066"
   54.44 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   54.45 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   54.46 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   54.47 +    </marker>
   54.48 +  </defs>
   54.49 +  <sodipodi:namedview
   54.50 +     id="base"
   54.51 +     pagecolor="#ffffff"
   54.52 +     bordercolor="#666666"
   54.53 +     borderopacity="1.0"
   54.54 +     gridtolerance="10000"
   54.55 +     guidetolerance="10"
   54.56 +     objecttolerance="10"
   54.57 +     inkscape:pageopacity="0.0"
   54.58 +     inkscape:pageshadow="2"
   54.59 +     inkscape:zoom="1.4"
   54.60 +     inkscape:cx="247.53795"
   54.61 +     inkscape:cy="871.05738"
   54.62 +     inkscape:document-units="px"
   54.63 +     inkscape:current-layer="layer1"
   54.64 +     inkscape:window-width="906"
   54.65 +     inkscape:window-height="620"
   54.66 +     inkscape:window-x="38"
   54.67 +     inkscape:window-y="95" />
   54.68 +  <metadata
   54.69 +     id="metadata7">
   54.70 +    <rdf:RDF>
   54.71 +      <cc:Work
   54.72 +         rdf:about="">
   54.73 +        <dc:format>image/svg+xml</dc:format>
   54.74 +        <dc:type
   54.75 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   54.76 +      </cc:Work>
   54.77 +    </rdf:RDF>
   54.78 +  </metadata>
   54.79 +  <g
   54.80 +     inkscape:label="Layer 1"
   54.81 +     inkscape:groupmode="layer"
   54.82 +     id="layer1">
   54.83 +    <rect
   54.84 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   54.85 +       id="rect2995"
   54.86 +       width="94.285713"
   54.87 +       height="20.714285"
   54.88 +       x="532.85718"
   54.89 +       y="203.0479" />
   54.90 +    <text
   54.91 +       xml:space="preserve"
   54.92 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   54.93 +       x="173.57143"
   54.94 +       y="443.79074"
   54.95 +       id="text2832"><tspan
   54.96 +         sodipodi:role="line"
   54.97 +         id="tspan2834"
   54.98 +         x="173.57143"
   54.99 +         y="443.79074" /></text>
  54.100 +    <rect
  54.101 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  54.102 +       id="rect2830"
  54.103 +       width="94.285713"
  54.104 +       height="20.714285"
  54.105 +       x="138"
  54.106 +       y="297.76227" />
  54.107 +    <text
  54.108 +       xml:space="preserve"
  54.109 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  54.110 +       x="162.09892"
  54.111 +       y="311.38342"
  54.112 +       id="text2824"><tspan
  54.113 +         sodipodi:role="line"
  54.114 +         id="tspan2826"
  54.115 +         x="162.09892"
  54.116 +         y="311.38342"
  54.117 +         style="font-family:Courier"><tspan
  54.118 +   style="font-weight:bold"
  54.119 +   id="tspan2862">4</tspan>: REV4</tspan></text>
  54.120 +    <path
  54.121 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  54.122 +       d="M 185.14286,343.63731 L 185.14286,319.47656"
  54.123 +       id="path2900"
  54.124 +       inkscape:connector-type="polyline" />
  54.125 +    <rect
  54.126 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  54.127 +       id="rect2863"
  54.128 +       width="94.285713"
  54.129 +       height="20.714285"
  54.130 +       x="91.428574"
  54.131 +       y="250.47656" />
  54.132 +    <text
  54.133 +       xml:space="preserve"
  54.134 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  54.135 +       x="116.09886"
  54.136 +       y="264.56592"
  54.137 +       id="text1965"
  54.138 +       transform="scale(1.000002,0.999998)"><tspan
  54.139 +         sodipodi:role="line"
  54.140 +         id="tspan1967"
  54.141 +         x="116.09886"
  54.142 +         y="264.56592"
  54.143 +         style="font-family:Courier"><tspan
  54.144 +   style="font-weight:bold"
  54.145 +   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
  54.146 +    <path
  54.147 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  54.148 +       d="M 173.95727,296.76228 L 149.75702,272.19085"
  54.149 +       id="path1971"
  54.150 +       inkscape:connector-type="polyline"
  54.151 +       inkscape:connection-end="#rect2863"
  54.152 +       inkscape:connection-start="#rect2830" />
  54.153 +    <rect
  54.154 +       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  54.155 +       id="rect2911"
  54.156 +       width="94.285995"
  54.157 +       height="20.714283"
  54.158 +       x="186.71414"
  54.159 +       y="204.40514" />
  54.160 +    <text
  54.161 +       xml:space="preserve"
  54.162 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  54.163 +       x="210.81311"
  54.164 +       y="218.02673"
  54.165 +       id="text2913"
  54.166 +       transform="scale(1.000002,0.999998)"><tspan
  54.167 +         sodipodi:role="line"
  54.168 +         id="tspan2915"
  54.169 +         x="210.81311"
  54.170 +         y="218.02673"
  54.171 +         style="font-family:Courier"><tspan
  54.172 +   id="tspan1966"
  54.173 +   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
  54.174 +    <path
  54.175 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  54.176 +       d="M 191.06908,296.76228 L 227.93092,226.11942"
  54.177 +       id="path2919"
  54.178 +       inkscape:connector-type="polyline"
  54.179 +       inkscape:connection-start="#rect2830" />
  54.180 +    <text
  54.181 +       xml:space="preserve"
  54.182 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.183 +       x="295.28571"
  54.184 +       y="217.56711"
  54.185 +       id="text2871"><tspan
  54.186 +         sodipodi:role="line"
  54.187 +         id="tspan2873"
  54.188 +         x="295.28571"
  54.189 +         y="217.56711">tip (and head)</tspan></text>
  54.190 +    <text
  54.191 +       xml:space="preserve"
  54.192 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.193 +       x="76"
  54.194 +       y="264.91769"
  54.195 +       id="text2875"><tspan
  54.196 +         sodipodi:role="line"
  54.197 +         id="tspan2877"
  54.198 +         x="76"
  54.199 +         y="264.91769"
  54.200 +         style="text-align:end;text-anchor:end">head</tspan></text>
  54.201 +    <rect
  54.202 +       style="fill:#c8aaa5;fill-opacity:1;stroke:#a07163;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2, 4;stroke-dashoffset:0;stroke-opacity:1"
  54.203 +       id="rect1913"
  54.204 +       width="94.285713"
  54.205 +       height="20.714285"
  54.206 +       x="138"
  54.207 +       y="156.90514" />
  54.208 +    <path
  54.209 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
  54.210 +       d="M 144.22399,249.47657 L 179.49029,178.61943"
  54.211 +       id="path1915"
  54.212 +       inkscape:connector-type="polyline"
  54.213 +       inkscape:connection-start="#rect2863"
  54.214 +       inkscape:connection-end="#rect1913" />
  54.215 +    <path
  54.216 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
  54.217 +       d="M 222.20966,203.40514 L 196.79033,178.61943"
  54.218 +       id="path1917"
  54.219 +       inkscape:connector-type="polyline"
  54.220 +       inkscape:connection-start="#rect2911"
  54.221 +       inkscape:connection-end="#rect1913" />
  54.222 +    <text
  54.223 +       xml:space="preserve"
  54.224 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.225 +       x="166.16823"
  54.226 +       y="168.52228"
  54.227 +       id="text2806"><tspan
  54.228 +         sodipodi:role="line"
  54.229 +         id="tspan2808"
  54.230 +         x="166.16823"
  54.231 +         y="168.52228"
  54.232 +         style="font-family:Courier">merge</tspan></text>
  54.233 +    <text
  54.234 +       xml:space="preserve"
  54.235 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.236 +       x="246"
  54.237 +       y="162.63338"
  54.238 +       id="text2810"><tspan
  54.239 +         sodipodi:role="line"
  54.240 +         id="tspan2812"
  54.241 +         x="246"
  54.242 +         y="162.63338">working directory</tspan><tspan
  54.243 +         sodipodi:role="line"
  54.244 +         x="246"
  54.245 +         y="177.63338"
  54.246 +         id="tspan2814">during merge</tspan></text>
  54.247 +    <rect
  54.248 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  54.249 +       id="rect2816"
  54.250 +       width="94.285713"
  54.251 +       height="20.714285"
  54.252 +       x="483.14636"
  54.253 +       y="297.76227" />
  54.254 +    <text
  54.255 +       xml:space="preserve"
  54.256 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  54.257 +       x="507.24527"
  54.258 +       y="311.38342"
  54.259 +       id="text2818"><tspan
  54.260 +         sodipodi:role="line"
  54.261 +         id="tspan2820"
  54.262 +         x="507.24527"
  54.263 +         y="311.38342"
  54.264 +         style="font-family:Courier"><tspan
  54.265 +   style="font-weight:bold"
  54.266 +   id="tspan2822">4</tspan>: REV4</tspan></text>
  54.267 +    <path
  54.268 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  54.269 +       d="M 530.28921,343.6373 L 530.28921,319.47655"
  54.270 +       id="path2824"
  54.271 +       inkscape:connector-type="polyline" />
  54.272 +    <rect
  54.273 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  54.274 +       id="rect2826"
  54.275 +       width="94.285713"
  54.276 +       height="20.714285"
  54.277 +       x="436.57492"
  54.278 +       y="250.47656" />
  54.279 +    <text
  54.280 +       xml:space="preserve"
  54.281 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  54.282 +       x="461.24484"
  54.283 +       y="264.56613"
  54.284 +       id="text2828"
  54.285 +       transform="scale(1.000002,0.999998)"><tspan
  54.286 +         sodipodi:role="line"
  54.287 +         id="tspan2830"
  54.288 +         x="461.24484"
  54.289 +         y="264.56613"
  54.290 +         style="font-family:Courier"><tspan
  54.291 +   style="font-weight:bold"
  54.292 +   id="tspan2832">5</tspan>: REV_my_new_hello</tspan></text>
  54.293 +    <path
  54.294 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  54.295 +       d="M 519.10362,296.76227 L 494.90337,272.19084"
  54.296 +       id="path2834"
  54.297 +       inkscape:connector-type="polyline" />
  54.298 +    <rect
  54.299 +       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  54.300 +       id="rect2836"
  54.301 +       width="94.285995"
  54.302 +       height="20.714283"
  54.303 +       x="483.14001"
  54.304 +       y="156.548" />
  54.305 +    <text
  54.306 +       xml:space="preserve"
  54.307 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  54.308 +       x="555.95911"
  54.309 +       y="218.02698"
  54.310 +       id="text2838"
  54.311 +       transform="scale(1.000002,0.999998)"><tspan
  54.312 +         sodipodi:role="line"
  54.313 +         id="tspan2840"
  54.314 +         x="555.95911"
  54.315 +         y="218.02698"
  54.316 +         style="font-family:Courier"><tspan
  54.317 +   id="tspan2842"
  54.318 +   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
  54.319 +    <path
  54.320 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  54.321 +       d="M 536.21543,296.76227 L 574.03453,224.76218"
  54.322 +       id="path2844"
  54.323 +       inkscape:connector-type="polyline" />
  54.324 +    <text
  54.325 +       xml:space="preserve"
  54.326 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.327 +       x="594.43207"
  54.328 +       y="169.78796"
  54.329 +       id="text2846"><tspan
  54.330 +         sodipodi:role="line"
  54.331 +         id="tspan2848"
  54.332 +         x="594.43207"
  54.333 +         y="169.78796">tip</tspan></text>
  54.334 +    <path
  54.335 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
  54.336 +       d="M 489.37034,249.47656 L 524.65575,178.26229"
  54.337 +       id="path2856"
  54.338 +       inkscape:connector-type="polyline"
  54.339 +       inkscape:connection-end="#rect2836" />
  54.340 +    <path
  54.341 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
  54.342 +       d="M 567.85714,202.0479 L 542.42591,178.26229"
  54.343 +       id="path2858"
  54.344 +       inkscape:connector-type="polyline"
  54.345 +       inkscape:connection-end="#rect2836"
  54.346 +       inkscape:connection-start="#rect2995" />
  54.347 +    <text
  54.348 +       xml:space="preserve"
  54.349 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.350 +       x="504.54507"
  54.351 +       y="170.39714"
  54.352 +       id="text2860"><tspan
  54.353 +         sodipodi:role="line"
  54.354 +         id="tspan2863"
  54.355 +         x="504.54507"
  54.356 +         y="170.39714"
  54.357 +         style="font-family:Courier"><tspan
  54.358 +   style="font-weight:bold"
  54.359 +   id="tspan2997">7</tspan>: REV7_my_new_hello</tspan></text>
  54.360 +    <text
  54.361 +       xml:space="preserve"
  54.362 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.363 +       x="90.323105"
  54.364 +       y="120.21933"
  54.365 +       id="text2929"><tspan
  54.366 +         sodipodi:role="line"
  54.367 +         id="tspan2931"
  54.368 +         x="90.323105"
  54.369 +         y="120.21933"
  54.370 +         style="font-weight:bold">Working directory during merge</tspan></text>
  54.371 +    <text
  54.372 +       xml:space="preserve"
  54.373 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  54.374 +       x="435.35226"
  54.375 +       y="120.21933"
  54.376 +       id="text2937"><tspan
  54.377 +         sodipodi:role="line"
  54.378 +         id="tspan2939"
  54.379 +         x="435.35226"
  54.380 +         y="120.21933"
  54.381 +         style="font-weight:bold">Repository after merge committed</tspan></text>
  54.382 +  </g>
  54.383 +</svg>
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/fr/figs/tour-merge-pull.svg	Sun Aug 16 04:58:01 2009 +0200
    55.3 @@ -0,0 +1,288 @@
    55.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    55.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    55.6 +<svg
    55.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    55.8 +   xmlns:cc="http://web.resource.org/cc/"
    55.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   55.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   55.11 +   xmlns="http://www.w3.org/2000/svg"
   55.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   55.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   55.14 +   width="744.09448819"
   55.15 +   height="1052.3622047"
   55.16 +   id="svg2"
   55.17 +   sodipodi:version="0.32"
   55.18 +   inkscape:version="0.44.1"
   55.19 +   sodipodi:docname="tour-merge-pull.svg"
   55.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en">
   55.21 +  <defs
   55.22 +     id="defs4">
   55.23 +    <marker
   55.24 +       inkscape:stockid="Arrow1Mstart"
   55.25 +       orient="auto"
   55.26 +       refY="0.0"
   55.27 +       refX="0.0"
   55.28 +       id="Arrow1Mstart"
   55.29 +       style="overflow:visible">
   55.30 +      <path
   55.31 +         id="path2973"
   55.32 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   55.33 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   55.34 +         transform="scale(0.4) translate(10,0)" />
   55.35 +    </marker>
   55.36 +    <marker
   55.37 +       inkscape:stockid="Arrow1Mend"
   55.38 +       orient="auto"
   55.39 +       refY="0.0"
   55.40 +       refX="0.0"
   55.41 +       id="Arrow1Mend"
   55.42 +       style="overflow:visible;">
   55.43 +      <path
   55.44 +         id="path3066"
   55.45 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   55.46 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   55.47 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   55.48 +    </marker>
   55.49 +  </defs>
   55.50 +  <sodipodi:namedview
   55.51 +     id="base"
   55.52 +     pagecolor="#ffffff"
   55.53 +     bordercolor="#666666"
   55.54 +     borderopacity="1.0"
   55.55 +     gridtolerance="10000"
   55.56 +     guidetolerance="10"
   55.57 +     objecttolerance="10"
   55.58 +     inkscape:pageopacity="0.0"
   55.59 +     inkscape:pageshadow="2"
   55.60 +     inkscape:zoom="1.4"
   55.61 +     inkscape:cx="233.63208"
   55.62 +     inkscape:cy="832.54381"
   55.63 +     inkscape:document-units="px"
   55.64 +     inkscape:current-layer="layer1"
   55.65 +     inkscape:window-width="906"
   55.66 +     inkscape:window-height="620"
   55.67 +     inkscape:window-x="237"
   55.68 +     inkscape:window-y="103" />
   55.69 +  <metadata
   55.70 +     id="metadata7">
   55.71 +    <rdf:RDF>
   55.72 +      <cc:Work
   55.73 +         rdf:about="">
   55.74 +        <dc:format>image/svg+xml</dc:format>
   55.75 +        <dc:type
   55.76 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   55.77 +      </cc:Work>
   55.78 +    </rdf:RDF>
   55.79 +  </metadata>
   55.80 +  <g
   55.81 +     inkscape:label="Layer 1"
   55.82 +     inkscape:groupmode="layer"
   55.83 +     id="layer1">
   55.84 +    <text
   55.85 +       xml:space="preserve"
   55.86 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   55.87 +       x="173.57143"
   55.88 +       y="443.79074"
   55.89 +       id="text2832"><tspan
   55.90 +         sodipodi:role="line"
   55.91 +         id="tspan2834"
   55.92 +         x="173.57143"
   55.93 +         y="443.79074" /></text>
   55.94 +    <rect
   55.95 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   55.96 +       id="rect1878"
   55.97 +       width="94.285713"
   55.98 +       height="20.714285"
   55.99 +       x="138"
  55.100 +       y="479.50504" />
  55.101 +    <text
  55.102 +       xml:space="preserve"
  55.103 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.104 +       x="162.09892"
  55.105 +       y="493.12619"
  55.106 +       id="text1872"><tspan
  55.107 +         sodipodi:role="line"
  55.108 +         id="tspan1874"
  55.109 +         x="162.09892"
  55.110 +         y="493.12619"
  55.111 +         style="font-family:Courier"><tspan
  55.112 +   style="font-weight:bold"
  55.113 +   id="tspan1876">0</tspan>: REV0</tspan></text>
  55.114 +    <rect
  55.115 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  55.116 +       id="rect2800"
  55.117 +       width="94.285713"
  55.118 +       height="20.714285"
  55.119 +       x="138"
  55.120 +       y="432.63004" />
  55.121 +    <text
  55.122 +       xml:space="preserve"
  55.123 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.124 +       x="162.09892"
  55.125 +       y="446.25119"
  55.126 +       id="text2794"><tspan
  55.127 +         sodipodi:role="line"
  55.128 +         id="tspan2796"
  55.129 +         x="162.09892"
  55.130 +         y="446.25119"
  55.131 +         style="font-family:Courier"><tspan
  55.132 +   id="tspan2868"
  55.133 +   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  55.134 +    <rect
  55.135 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  55.136 +       id="rect2810"
  55.137 +       width="94.285713"
  55.138 +       height="20.714285"
  55.139 +       x="138"
  55.140 +       y="385.75504" />
  55.141 +    <text
  55.142 +       xml:space="preserve"
  55.143 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.144 +       x="162.09892"
  55.145 +       y="399.37619"
  55.146 +       id="text2804"><tspan
  55.147 +         sodipodi:role="line"
  55.148 +         id="tspan2806"
  55.149 +         x="162.09892"
  55.150 +         y="399.37619"
  55.151 +         style="font-family:Courier"><tspan
  55.152 +   style="font-weight:bold"
  55.153 +   id="tspan2866">2</tspan>: REV2</tspan></text>
  55.154 +    <rect
  55.155 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  55.156 +       id="rect2820"
  55.157 +       width="94.285713"
  55.158 +       height="20.714285"
  55.159 +       x="138"
  55.160 +       y="338.88007" />
  55.161 +    <text
  55.162 +       xml:space="preserve"
  55.163 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.164 +       x="162.09892"
  55.165 +       y="352.50122"
  55.166 +       id="text2814"><tspan
  55.167 +         sodipodi:role="line"
  55.168 +         id="tspan2816"
  55.169 +         x="162.09892"
  55.170 +         y="352.50122"
  55.171 +         style="font-family:Courier"><tspan
  55.172 +   style="font-weight:bold"
  55.173 +   id="tspan2864">3</tspan>: REV3</tspan></text>
  55.174 +    <rect
  55.175 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  55.176 +       id="rect2830"
  55.177 +       width="94.285713"
  55.178 +       height="20.714285"
  55.179 +       x="138"
  55.180 +       y="292.00504" />
  55.181 +    <text
  55.182 +       xml:space="preserve"
  55.183 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.184 +       x="162.09892"
  55.185 +       y="305.62619"
  55.186 +       id="text2824"><tspan
  55.187 +         sodipodi:role="line"
  55.188 +         id="tspan2826"
  55.189 +         x="162.09892"
  55.190 +         y="305.62619"
  55.191 +         style="font-family:Courier"><tspan
  55.192 +   style="font-weight:bold"
  55.193 +   id="tspan2862">4</tspan>: REV4</tspan></text>
  55.194 +    <path
  55.195 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  55.196 +       d="M 185.14286,478.50504 L 185.14286,454.34432"
  55.197 +       id="path2894"
  55.198 +       inkscape:connector-type="polyline" />
  55.199 +    <path
  55.200 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  55.201 +       d="M 185.14286,431.63004 L 185.14286,407.46932"
  55.202 +       id="path2896"
  55.203 +       inkscape:connector-type="polyline" />
  55.204 +    <path
  55.205 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  55.206 +       d="M 185.14286,384.75504 L 185.14286,360.59435"
  55.207 +       id="path2898"
  55.208 +       inkscape:connector-type="polyline" />
  55.209 +    <path
  55.210 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  55.211 +       d="M 185.14286,337.88007 L 185.14286,313.71932"
  55.212 +       id="path2900"
  55.213 +       inkscape:connector-type="polyline" />
  55.214 +    <rect
  55.215 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  55.216 +       id="rect2863"
  55.217 +       width="94.285713"
  55.218 +       height="20.714285"
  55.219 +       x="91.428574"
  55.220 +       y="244.71933" />
  55.221 +    <text
  55.222 +       xml:space="preserve"
  55.223 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.224 +       x="116.09886"
  55.225 +       y="258.80865"
  55.226 +       id="text1965"
  55.227 +       transform="scale(1.000002,0.999998)"><tspan
  55.228 +         sodipodi:role="line"
  55.229 +         id="tspan1967"
  55.230 +         x="116.09886"
  55.231 +         y="258.80865"
  55.232 +         style="font-family:Courier"><tspan
  55.233 +   style="font-weight:bold"
  55.234 +   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
  55.235 +    <path
  55.236 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  55.237 +       d="M 173.95727,291.00504 L 149.75702,266.43361"
  55.238 +       id="path1971"
  55.239 +       inkscape:connector-type="polyline"
  55.240 +       inkscape:connection-end="#rect2863"
  55.241 +       inkscape:connection-start="#rect2830" />
  55.242 +    <rect
  55.243 +       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  55.244 +       id="rect2911"
  55.245 +       width="94.285995"
  55.246 +       height="20.714283"
  55.247 +       x="186.71414"
  55.248 +       y="198.6479" />
  55.249 +    <text
  55.250 +       xml:space="preserve"
  55.251 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  55.252 +       x="210.81311"
  55.253 +       y="212.26949"
  55.254 +       id="text2913"
  55.255 +       transform="scale(1.000002,0.999998)"><tspan
  55.256 +         sodipodi:role="line"
  55.257 +         id="tspan2915"
  55.258 +         x="210.81311"
  55.259 +         y="212.26949"
  55.260 +         style="font-family:Courier"><tspan
  55.261 +   id="tspan1966"
  55.262 +   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
  55.263 +    <path
  55.264 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  55.265 +       d="M 191.06908,291.00504 L 227.93092,220.36218"
  55.266 +       id="path2919"
  55.267 +       inkscape:connector-type="polyline"
  55.268 +       inkscape:connection-start="#rect2830" />
  55.269 +    <text
  55.270 +       xml:space="preserve"
  55.271 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  55.272 +       x="295.28571"
  55.273 +       y="211.80988"
  55.274 +       id="text2871"><tspan
  55.275 +         sodipodi:role="line"
  55.276 +         id="tspan2873"
  55.277 +         x="295.28571"
  55.278 +         y="211.80988">tip (and head)</tspan></text>
  55.279 +    <text
  55.280 +       xml:space="preserve"
  55.281 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  55.282 +       x="76"
  55.283 +       y="259.16046"
  55.284 +       id="text2875"><tspan
  55.285 +         sodipodi:role="line"
  55.286 +         id="tspan2877"
  55.287 +         x="76"
  55.288 +         y="259.16046"
  55.289 +         style="text-align:end;text-anchor:end">head</tspan></text>
  55.290 +  </g>
  55.291 +</svg>
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/fr/figs/tour-merge-sep-repos.svg	Sun Aug 16 04:58:01 2009 +0200
    56.3 @@ -0,0 +1,466 @@
    56.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    56.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    56.6 +<svg
    56.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    56.8 +   xmlns:cc="http://web.resource.org/cc/"
    56.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   56.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   56.11 +   xmlns="http://www.w3.org/2000/svg"
   56.12 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   56.13 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   56.14 +   width="744.09448819"
   56.15 +   height="1052.3622047"
   56.16 +   id="svg2"
   56.17 +   sodipodi:version="0.32"
   56.18 +   inkscape:version="0.44.1"
   56.19 +   sodipodi:docname="tour-merge-sep-repos.svg">
   56.20 +  <defs
   56.21 +     id="defs4">
   56.22 +    <marker
   56.23 +       inkscape:stockid="Arrow1Mstart"
   56.24 +       orient="auto"
   56.25 +       refY="0.0"
   56.26 +       refX="0.0"
   56.27 +       id="Arrow1Mstart"
   56.28 +       style="overflow:visible">
   56.29 +      <path
   56.30 +         id="path2973"
   56.31 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   56.32 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   56.33 +         transform="scale(0.4) translate(10,0)" />
   56.34 +    </marker>
   56.35 +    <marker
   56.36 +       inkscape:stockid="Arrow1Mend"
   56.37 +       orient="auto"
   56.38 +       refY="0.0"
   56.39 +       refX="0.0"
   56.40 +       id="Arrow1Mend"
   56.41 +       style="overflow:visible;">
   56.42 +      <path
   56.43 +         id="path3066"
   56.44 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   56.45 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   56.46 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   56.47 +    </marker>
   56.48 +  </defs>
   56.49 +  <sodipodi:namedview
   56.50 +     id="base"
   56.51 +     pagecolor="#ffffff"
   56.52 +     bordercolor="#666666"
   56.53 +     borderopacity="1.0"
   56.54 +     gridtolerance="10000"
   56.55 +     guidetolerance="10"
   56.56 +     objecttolerance="10"
   56.57 +     inkscape:pageopacity="0.0"
   56.58 +     inkscape:pageshadow="2"
   56.59 +     inkscape:zoom="1.4"
   56.60 +     inkscape:cx="307.20351"
   56.61 +     inkscape:cy="716.87911"
   56.62 +     inkscape:document-units="px"
   56.63 +     inkscape:current-layer="layer1"
   56.64 +     inkscape:window-width="906"
   56.65 +     inkscape:window-height="620"
   56.66 +     inkscape:window-x="5"
   56.67 +     inkscape:window-y="49" />
   56.68 +  <metadata
   56.69 +     id="metadata7">
   56.70 +    <rdf:RDF>
   56.71 +      <cc:Work
   56.72 +         rdf:about="">
   56.73 +        <dc:format>image/svg+xml</dc:format>
   56.74 +        <dc:type
   56.75 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   56.76 +      </cc:Work>
   56.77 +    </rdf:RDF>
   56.78 +  </metadata>
   56.79 +  <g
   56.80 +     inkscape:label="Layer 1"
   56.81 +     inkscape:groupmode="layer"
   56.82 +     id="layer1">
   56.83 +    <text
   56.84 +       xml:space="preserve"
   56.85 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   56.86 +       x="173.57143"
   56.87 +       y="443.79074"
   56.88 +       id="text2832"><tspan
   56.89 +         sodipodi:role="line"
   56.90 +         id="tspan2834"
   56.91 +         x="173.57143"
   56.92 +         y="443.79074" /></text>
   56.93 +    <rect
   56.94 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   56.95 +       id="rect1878"
   56.96 +       width="94.285713"
   56.97 +       height="20.714285"
   56.98 +       x="138"
   56.99 +       y="479.50504" />
  56.100 +    <text
  56.101 +       xml:space="preserve"
  56.102 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.103 +       x="162.09892"
  56.104 +       y="493.12619"
  56.105 +       id="text1872"><tspan
  56.106 +         sodipodi:role="line"
  56.107 +         id="tspan1874"
  56.108 +         x="162.09892"
  56.109 +         y="493.12619"
  56.110 +         style="font-family:Courier"><tspan
  56.111 +   style="font-weight:bold"
  56.112 +   id="tspan1876">0</tspan>: REV0</tspan></text>
  56.113 +    <rect
  56.114 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.115 +       id="rect2800"
  56.116 +       width="94.285713"
  56.117 +       height="20.714285"
  56.118 +       x="138"
  56.119 +       y="432.63004" />
  56.120 +    <text
  56.121 +       xml:space="preserve"
  56.122 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.123 +       x="162.09892"
  56.124 +       y="446.25119"
  56.125 +       id="text2794"><tspan
  56.126 +         sodipodi:role="line"
  56.127 +         id="tspan2796"
  56.128 +         x="162.09892"
  56.129 +         y="446.25119"
  56.130 +         style="font-family:Courier"><tspan
  56.131 +   id="tspan2868"
  56.132 +   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  56.133 +    <rect
  56.134 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.135 +       id="rect2810"
  56.136 +       width="94.285713"
  56.137 +       height="20.714285"
  56.138 +       x="138"
  56.139 +       y="385.75504" />
  56.140 +    <text
  56.141 +       xml:space="preserve"
  56.142 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.143 +       x="162.09892"
  56.144 +       y="399.37619"
  56.145 +       id="text2804"><tspan
  56.146 +         sodipodi:role="line"
  56.147 +         id="tspan2806"
  56.148 +         x="162.09892"
  56.149 +         y="399.37619"
  56.150 +         style="font-family:Courier"><tspan
  56.151 +   style="font-weight:bold"
  56.152 +   id="tspan2866">2</tspan>: REV2</tspan></text>
  56.153 +    <rect
  56.154 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.155 +       id="rect2820"
  56.156 +       width="94.285713"
  56.157 +       height="20.714285"
  56.158 +       x="138"
  56.159 +       y="338.88007" />
  56.160 +    <text
  56.161 +       xml:space="preserve"
  56.162 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.163 +       x="162.09892"
  56.164 +       y="352.50122"
  56.165 +       id="text2814"><tspan
  56.166 +         sodipodi:role="line"
  56.167 +         id="tspan2816"
  56.168 +         x="162.09892"
  56.169 +         y="352.50122"
  56.170 +         style="font-family:Courier"><tspan
  56.171 +   style="font-weight:bold"
  56.172 +   id="tspan2864">3</tspan>: REV3</tspan></text>
  56.173 +    <rect
  56.174 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.175 +       id="rect2830"
  56.176 +       width="94.285713"
  56.177 +       height="20.714285"
  56.178 +       x="138"
  56.179 +       y="292.00504" />
  56.180 +    <text
  56.181 +       xml:space="preserve"
  56.182 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.183 +       x="162.09892"
  56.184 +       y="305.62619"
  56.185 +       id="text2824"><tspan
  56.186 +         sodipodi:role="line"
  56.187 +         id="tspan2826"
  56.188 +         x="162.09892"
  56.189 +         y="305.62619"
  56.190 +         style="font-family:Courier"><tspan
  56.191 +   style="font-weight:bold"
  56.192 +   id="tspan2862">4</tspan>: REV4</tspan></text>
  56.193 +    <path
  56.194 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.195 +       d="M 185.14286,478.50504 L 185.14286,454.34432"
  56.196 +       id="path2894"
  56.197 +       inkscape:connector-type="polyline" />
  56.198 +    <path
  56.199 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.200 +       d="M 185.14286,431.63004 L 185.14286,407.46932"
  56.201 +       id="path2896"
  56.202 +       inkscape:connector-type="polyline" />
  56.203 +    <path
  56.204 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.205 +       d="M 185.14286,384.75504 L 185.14286,360.59435"
  56.206 +       id="path2898"
  56.207 +       inkscape:connector-type="polyline" />
  56.208 +    <path
  56.209 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.210 +       d="M 185.14286,337.88007 L 185.14286,313.71932"
  56.211 +       id="path2900"
  56.212 +       inkscape:connector-type="polyline" />
  56.213 +    <rect
  56.214 +       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.215 +       id="rect1963"
  56.216 +       width="94.285995"
  56.217 +       height="20.714283"
  56.218 +       x="138"
  56.219 +       y="245.18723" />
  56.220 +    <text
  56.221 +       xml:space="preserve"
  56.222 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.223 +       x="162.09877"
  56.224 +       y="258.80865"
  56.225 +       id="text1965"
  56.226 +       transform="scale(1.000002,0.999998)"><tspan
  56.227 +         sodipodi:role="line"
  56.228 +         id="tspan1967"
  56.229 +         x="162.09877"
  56.230 +         y="258.80865"
  56.231 +         style="font-family:Courier"><tspan
  56.232 +   style="font-weight:bold"
  56.233 +   id="tspan1973">5</tspan>: REV_my_hello</tspan></text>
  56.234 +    <path
  56.235 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.236 +       d="M 185.143,291.06218 L 185.143,266.90143"
  56.237 +       id="path1971"
  56.238 +       inkscape:connector-type="polyline" />
  56.239 +    <text
  56.240 +       xml:space="preserve"
  56.241 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  56.242 +       x="136.90039"
  56.243 +       y="232.25546"
  56.244 +       id="text2921"><tspan
  56.245 +         sodipodi:role="line"
  56.246 +         id="tspan2923"
  56.247 +         x="136.90039"
  56.248 +         y="232.25546">my-hello</tspan></text>
  56.249 +    <rect
  56.250 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.251 +       id="rect2863"
  56.252 +       width="94.285713"
  56.253 +       height="20.714285"
  56.254 +       x="370.71414"
  56.255 +       y="479.49289" />
  56.256 +    <text
  56.257 +       xml:space="preserve"
  56.258 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.259 +       x="394.81305"
  56.260 +       y="493.11404"
  56.261 +       id="text2865"><tspan
  56.262 +         sodipodi:role="line"
  56.263 +         id="tspan2867"
  56.264 +         x="394.81305"
  56.265 +         y="493.11404"
  56.266 +         style="font-family:Courier"><tspan
  56.267 +   style="font-weight:bold"
  56.268 +   id="tspan2869">0</tspan>: REV0</tspan></text>
  56.269 +    <rect
  56.270 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.271 +       id="rect2871"
  56.272 +       width="94.285713"
  56.273 +       height="20.714285"
  56.274 +       x="370.71414"
  56.275 +       y="432.61789" />
  56.276 +    <text
  56.277 +       xml:space="preserve"
  56.278 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.279 +       x="394.81305"
  56.280 +       y="446.23904"
  56.281 +       id="text2873"><tspan
  56.282 +         sodipodi:role="line"
  56.283 +         id="tspan2875"
  56.284 +         x="394.81305"
  56.285 +         y="446.23904"
  56.286 +         style="font-family:Courier"><tspan
  56.287 +   id="tspan2877"
  56.288 +   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  56.289 +    <rect
  56.290 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.291 +       id="rect2879"
  56.292 +       width="94.285713"
  56.293 +       height="20.714285"
  56.294 +       x="370.71414"
  56.295 +       y="385.74289" />
  56.296 +    <text
  56.297 +       xml:space="preserve"
  56.298 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.299 +       x="394.81305"
  56.300 +       y="399.36404"
  56.301 +       id="text2881"><tspan
  56.302 +         sodipodi:role="line"
  56.303 +         id="tspan2883"
  56.304 +         x="394.81305"
  56.305 +         y="399.36404"
  56.306 +         style="font-family:Courier"><tspan
  56.307 +   style="font-weight:bold"
  56.308 +   id="tspan2885">2</tspan>: REV2</tspan></text>
  56.309 +    <rect
  56.310 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.311 +       id="rect2887"
  56.312 +       width="94.285713"
  56.313 +       height="20.714285"
  56.314 +       x="370.71414"
  56.315 +       y="338.86792" />
  56.316 +    <text
  56.317 +       xml:space="preserve"
  56.318 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.319 +       x="394.81305"
  56.320 +       y="352.48907"
  56.321 +       id="text2889"><tspan
  56.322 +         sodipodi:role="line"
  56.323 +         id="tspan2891"
  56.324 +         x="394.81305"
  56.325 +         y="352.48907"
  56.326 +         style="font-family:Courier"><tspan
  56.327 +   style="font-weight:bold"
  56.328 +   id="tspan2893">3</tspan>: REV3</tspan></text>
  56.329 +    <rect
  56.330 +       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.331 +       id="rect2895"
  56.332 +       width="94.285713"
  56.333 +       height="20.714285"
  56.334 +       x="370.71414"
  56.335 +       y="291.99289" />
  56.336 +    <text
  56.337 +       xml:space="preserve"
  56.338 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.339 +       x="394.81305"
  56.340 +       y="305.61404"
  56.341 +       id="text2897"><tspan
  56.342 +         sodipodi:role="line"
  56.343 +         id="tspan2899"
  56.344 +         x="394.81305"
  56.345 +         y="305.61404"
  56.346 +         style="font-family:Courier"><tspan
  56.347 +   style="font-weight:bold"
  56.348 +   id="tspan2901">4</tspan>: REV4</tspan></text>
  56.349 +    <path
  56.350 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.351 +       d="M 417.85701,478.4929 L 417.85701,454.33218"
  56.352 +       id="path2903"
  56.353 +       inkscape:connector-type="polyline" />
  56.354 +    <path
  56.355 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.356 +       d="M 417.85701,431.6179 L 417.85701,407.45718"
  56.357 +       id="path2905"
  56.358 +       inkscape:connector-type="polyline" />
  56.359 +    <path
  56.360 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.361 +       d="M 417.85701,384.7429 L 417.85701,360.58221"
  56.362 +       id="path2907"
  56.363 +       inkscape:connector-type="polyline" />
  56.364 +    <path
  56.365 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.366 +       d="M 417.85701,337.86793 L 417.85701,313.70718"
  56.367 +       id="path2909"
  56.368 +       inkscape:connector-type="polyline" />
  56.369 +    <rect
  56.370 +       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.371 +       id="rect2911"
  56.372 +       width="94.285995"
  56.373 +       height="20.714283"
  56.374 +       x="370.71414"
  56.375 +       y="245.17511" />
  56.376 +    <text
  56.377 +       xml:space="preserve"
  56.378 +       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  56.379 +       x="394.81274"
  56.380 +       y="258.79678"
  56.381 +       id="text2913"
  56.382 +       transform="scale(1.000002,0.999998)"><tspan
  56.383 +         sodipodi:role="line"
  56.384 +         id="tspan2915"
  56.385 +         x="394.81274"
  56.386 +         y="258.79678"
  56.387 +         style="font-family:Courier"><tspan
  56.388 +   style="font-weight:bold"
  56.389 +   id="tspan2917">5</tspan>: REV_my_new_hello</tspan></text>
  56.390 +    <path
  56.391 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  56.392 +       d="M 417.85715,291.05004 L 417.85715,266.88929"
  56.393 +       id="path2919"
  56.394 +       inkscape:connector-type="polyline" />
  56.395 +    <text
  56.396 +       xml:space="preserve"
  56.397 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  56.398 +       x="369.61453"
  56.399 +       y="232.25546"
  56.400 +       id="text2925"><tspan
  56.401 +         sodipodi:role="line"
  56.402 +         id="tspan2927"
  56.403 +         x="369.61453"
  56.404 +         y="232.25546">my-new-hello</tspan></text>
  56.405 +    <text
  56.406 +       xml:space="preserve"
  56.407 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  56.408 +       x="300.54352"
  56.409 +       y="252.12723"
  56.410 +       id="text2933"><tspan
  56.411 +         sodipodi:role="line"
  56.412 +         id="tspan2935"
  56.413 +         x="300.54352"
  56.414 +         y="252.12723"
  56.415 +         style="text-align:center;text-anchor:middle">newest changes</tspan><tspan
  56.416 +         sodipodi:role="line"
  56.417 +         x="300.54352"
  56.418 +         y="267.12723"
  56.419 +         style="text-align:center;text-anchor:middle"
  56.420 +         id="tspan3132">differ</tspan></text>
  56.421 +    <text
  56.422 +       xml:space="preserve"
  56.423 +       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  56.424 +       x="262.15436"
  56.425 +       y="398.37112"
  56.426 +       id="text2929"><tspan
  56.427 +         sodipodi:role="line"
  56.428 +         x="262.15436"
  56.429 +         y="398.37112"
  56.430 +         id="tspan3013"
  56.431 +         style="text-align:start;text-anchor:start">common history</tspan></text>
  56.432 +    <g
  56.433 +       id="g3107"
  56.434 +       transform="translate(0,0.855744)">
  56.435 +      <path
  56.436 +         id="path3101"
  56.437 +         d="M 300.35713,381.29075 L 300.35713,304.50504"
  56.438 +         style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" />
  56.439 +      <path
  56.440 +         id="path3105"
  56.441 +         d="M 291.07142,301.64789 L 309.28571,301.64789"
  56.442 +         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
  56.443 +    </g>
  56.444 +    <path
  56.445 +       style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1"
  56.446 +       d="M 300.53571,486.38926 L 300.53571,409.60355"
  56.447 +       id="path3113" />
  56.448 +    <path
  56.449 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  56.450 +       d="M 291.25,488.49641 L 309.46429,488.49641"
  56.451 +       id="path3115" />
  56.452 +    <text
  56.453 +       xml:space="preserve"
  56.454 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  56.455 +       x="480.71429"
  56.456 +       y="250.91507"
  56.457 +       id="text1949"><tspan
  56.458 +         sodipodi:role="line"
  56.459 +         id="tspan1951"
  56.460 +         x="480.71429"
  56.461 +         y="250.91507"
  56.462 +         style="text-align:start;text-anchor:start">head revision</tspan><tspan
  56.463 +         sodipodi:role="line"
  56.464 +         x="480.71429"
  56.465 +         y="265.91507"
  56.466 +         id="tspan1953"
  56.467 +         style="text-align:start;text-anchor:start">(has no children)</tspan></text>
  56.468 +  </g>
  56.469 +</svg>
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/fr/figs/undo-manual-merge.dot	Sun Aug 16 04:58:01 2009 +0200
    57.3 @@ -0,0 +1,8 @@
    57.4 +digraph undo_manual {
    57.5 +	"first change" -> "second change";
    57.6 +	"second change" -> "third change";
    57.7 +	backout [label="back out\nsecond change", shape=box];
    57.8 +	"second change" -> backout;
    57.9 +	"third change" -> "manual\nmerge";
   57.10 +	backout -> "manual\nmerge";
   57.11 +}
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/fr/figs/undo-manual.dot	Sun Aug 16 04:58:01 2009 +0200
    58.3 @@ -0,0 +1,6 @@
    58.4 +digraph undo_manual {
    58.5 +	"first change" -> "second change";
    58.6 +	"second change" -> "third change";
    58.7 +	backout [label="back out\nsecond change", shape=box];
    58.8 +	"second change" -> backout;
    58.9 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/fr/figs/undo-non-tip.dot	Sun Aug 16 04:58:01 2009 +0200
    59.3 @@ -0,0 +1,9 @@
    59.4 +digraph undo_non_tip {
    59.5 +	"first change" -> "second change";
    59.6 +	"second change" -> "third change";
    59.7 +	backout [label="back out\nsecond change", shape=box];
    59.8 +	"second change" -> backout;
    59.9 +	merge [label="automated\nmerge", shape=box];
   59.10 +	"third change" -> merge;
   59.11 +	backout -> merge;
   59.12 +}
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/fr/figs/undo-simple.dot	Sun Aug 16 04:58:01 2009 +0200
    60.3 @@ -0,0 +1,4 @@
    60.4 +digraph undo_simple {
    60.5 +	"first change" -> "second change";
    60.6 +	"second change" -> "back out\nsecond change";
    60.7 +}
    61.1 Binary file fr/figs/warning.png has changed
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/fr/figs/wdir-after-commit.svg	Sun Aug 16 04:58:01 2009 +0200
    62.3 @@ -0,0 +1,394 @@
    62.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    62.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    62.6 +<svg
    62.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    62.8 +   xmlns:cc="http://web.resource.org/cc/"
    62.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   62.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   62.11 +   xmlns="http://www.w3.org/2000/svg"
   62.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   62.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   62.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   62.15 +   width="744.09448819"
   62.16 +   height="1052.3622047"
   62.17 +   id="svg5971"
   62.18 +   sodipodi:version="0.32"
   62.19 +   inkscape:version="0.44.1"
   62.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   62.21 +   sodipodi:docname="wdir-after-commit.svg">
   62.22 +  <defs
   62.23 +     id="defs5973">
   62.24 +    <linearGradient
   62.25 +       inkscape:collect="always"
   62.26 +       xlink:href="#linearGradient6049"
   62.27 +       id="linearGradient6445"
   62.28 +       gradientUnits="userSpaceOnUse"
   62.29 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
   62.30 +       x1="333.91171"
   62.31 +       y1="488.79077"
   62.32 +       x2="508.94543"
   62.33 +       y2="263.79077" />
   62.34 +    <marker
   62.35 +       inkscape:stockid="Arrow1Mstart"
   62.36 +       orient="auto"
   62.37 +       refY="0.0"
   62.38 +       refX="0.0"
   62.39 +       id="Arrow1Mstart"
   62.40 +       style="overflow:visible">
   62.41 +      <path
   62.42 +         id="path4855"
   62.43 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   62.44 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   62.45 +         transform="scale(0.4) translate(10,0)" />
   62.46 +    </marker>
   62.47 +    <linearGradient
   62.48 +       id="linearGradient6049">
   62.49 +      <stop
   62.50 +         style="stop-color:#686868;stop-opacity:1;"
   62.51 +         offset="0"
   62.52 +         id="stop6051" />
   62.53 +      <stop
   62.54 +         style="stop-color:#f0f0f0;stop-opacity:1;"
   62.55 +         offset="1"
   62.56 +         id="stop6053" />
   62.57 +    </linearGradient>
   62.58 +    <marker
   62.59 +       inkscape:stockid="Arrow1Mend"
   62.60 +       orient="auto"
   62.61 +       refY="0.0"
   62.62 +       refX="0.0"
   62.63 +       id="Arrow1Mend"
   62.64 +       style="overflow:visible;">
   62.65 +      <path
   62.66 +         id="path4852"
   62.67 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   62.68 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   62.69 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   62.70 +    </marker>
   62.71 +    <linearGradient
   62.72 +       inkscape:collect="always"
   62.73 +       xlink:href="#linearGradient6049"
   62.74 +       id="linearGradient6083"
   62.75 +       gradientUnits="userSpaceOnUse"
   62.76 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   62.77 +       x1="333.91171"
   62.78 +       y1="488.79077"
   62.79 +       x2="508.94543"
   62.80 +       y2="263.79077" />
   62.81 +    <linearGradient
   62.82 +       inkscape:collect="always"
   62.83 +       xlink:href="#linearGradient6049"
   62.84 +       id="linearGradient6142"
   62.85 +       gradientUnits="userSpaceOnUse"
   62.86 +       gradientTransform="translate(-42.00893,-30.49544)"
   62.87 +       x1="333.91171"
   62.88 +       y1="488.79077"
   62.89 +       x2="508.94543"
   62.90 +       y2="263.79077" />
   62.91 +    <linearGradient
   62.92 +       inkscape:collect="always"
   62.93 +       xlink:href="#linearGradient6049"
   62.94 +       id="linearGradient6193"
   62.95 +       gradientUnits="userSpaceOnUse"
   62.96 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   62.97 +       x1="333.91171"
   62.98 +       y1="488.79077"
   62.99 +       x2="508.94543"
  62.100 +       y2="263.79077" />
  62.101 +    <linearGradient
  62.102 +       inkscape:collect="always"
  62.103 +       xlink:href="#linearGradient6049"
  62.104 +       id="linearGradient6216"
  62.105 +       gradientUnits="userSpaceOnUse"
  62.106 +       gradientTransform="translate(-6.0462,-0.664361)"
  62.107 +       x1="333.91171"
  62.108 +       y1="488.79077"
  62.109 +       x2="508.94543"
  62.110 +       y2="263.79077" />
  62.111 +    <linearGradient
  62.112 +       inkscape:collect="always"
  62.113 +       xlink:href="#linearGradient6049"
  62.114 +       id="linearGradient6232"
  62.115 +       gradientUnits="userSpaceOnUse"
  62.116 +       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
  62.117 +       x1="333.91171"
  62.118 +       y1="488.79077"
  62.119 +       x2="508.94543"
  62.120 +       y2="263.79077" />
  62.121 +    <linearGradient
  62.122 +       inkscape:collect="always"
  62.123 +       xlink:href="#linearGradient6049"
  62.124 +       id="linearGradient6772"
  62.125 +       gradientUnits="userSpaceOnUse"
  62.126 +       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
  62.127 +       x1="333.91171"
  62.128 +       y1="488.79077"
  62.129 +       x2="508.94543"
  62.130 +       y2="263.79077" />
  62.131 +  </defs>
  62.132 +  <sodipodi:namedview
  62.133 +     id="base"
  62.134 +     pagecolor="#ffffff"
  62.135 +     bordercolor="#666666"
  62.136 +     borderopacity="1.0"
  62.137 +     gridtolerance="10000"
  62.138 +     guidetolerance="10"
  62.139 +     objecttolerance="10"
  62.140 +     inkscape:pageopacity="0.0"
  62.141 +     inkscape:pageshadow="2"
  62.142 +     inkscape:zoom="0.90509668"
  62.143 +     inkscape:cx="390.0539"
  62.144 +     inkscape:cy="690.49342"
  62.145 +     inkscape:document-units="px"
  62.146 +     inkscape:current-layer="layer1"
  62.147 +     showguides="true"
  62.148 +     inkscape:guide-bbox="true"
  62.149 +     inkscape:window-width="906"
  62.150 +     inkscape:window-height="620"
  62.151 +     inkscape:window-x="0"
  62.152 +     inkscape:window-y="25">
  62.153 +    <sodipodi:guide
  62.154 +       orientation="vertical"
  62.155 +       position="-1.4285714"
  62.156 +       id="guide6022" />
  62.157 +  </sodipodi:namedview>
  62.158 +  <metadata
  62.159 +     id="metadata5976">
  62.160 +    <rdf:RDF>
  62.161 +      <cc:Work
  62.162 +         rdf:about="">
  62.163 +        <dc:format>image/svg+xml</dc:format>
  62.164 +        <dc:type
  62.165 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  62.166 +      </cc:Work>
  62.167 +    </rdf:RDF>
  62.168 +  </metadata>
  62.169 +  <g
  62.170 +     inkscape:label="Layer 1"
  62.171 +     inkscape:groupmode="layer"
  62.172 +     id="layer1">
  62.173 +    <rect
  62.174 +       y="245.98355"
  62.175 +       x="328.23956"
  62.176 +       height="258.57144"
  62.177 +       width="174.28572"
  62.178 +       id="rect6047"
  62.179 +       style="fill:url(#linearGradient6216);fill-opacity:1;stroke:#686868;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  62.180 +    <g
  62.181 +       id="g6261"
  62.182 +       transform="translate(234,0)">
  62.183 +      <rect
  62.184 +         y="258.7149"
  62.185 +         x="114.11369"
  62.186 +         height="44.537449"
  62.187 +         width="134.53746"
  62.188 +         id="rect5983"
  62.189 +         style="fill:#b1b1b1;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  62.190 +      <text
  62.191 +         id="text5985"
  62.192 +         y="284.47562"
  62.193 +         x="138.7962"
  62.194 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.195 +         xml:space="preserve"><tspan
  62.196 +           style="font-family:Courier"
  62.197 +           y="284.47562"
  62.198 +           x="138.7962"
  62.199 +           id="tspan5987"
  62.200 +           sodipodi:role="line">dfbbb33f3fa3</tspan></text>
  62.201 +    </g>
  62.202 +    <rect
  62.203 +       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  62.204 +       id="rect5996"
  62.205 +       width="134.53746"
  62.206 +       height="44.537449"
  62.207 +       x="348.11371"
  62.208 +       y="320.38159" />
  62.209 +    <text
  62.210 +       xml:space="preserve"
  62.211 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.212 +       x="372.7962"
  62.213 +       y="346.1423"
  62.214 +       id="text5998"><tspan
  62.215 +         sodipodi:role="line"
  62.216 +         id="tspan6000"
  62.217 +         x="372.7962"
  62.218 +         y="346.1423"
  62.219 +         style="font-family:Courier">e7639888bb2f</tspan></text>
  62.220 +    <rect
  62.221 +       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  62.222 +       id="rect6004"
  62.223 +       width="134.53746"
  62.224 +       height="44.537449"
  62.225 +       x="348.11371"
  62.226 +       y="382.04825" />
  62.227 +    <text
  62.228 +       xml:space="preserve"
  62.229 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.230 +       x="370.65421"
  62.231 +       y="407.80896"
  62.232 +       id="text6006"><tspan
  62.233 +         sodipodi:role="line"
  62.234 +         id="tspan6008"
  62.235 +         x="370.65421"
  62.236 +         y="407.80896"
  62.237 +         style="font-family:Courier">7b064d8bac5e</tspan></text>
  62.238 +    <path
  62.239 +       inkscape:connector-type="polyline"
  62.240 +       id="path6018"
  62.241 +       d="M 415.38242,303.62646 L 415.38242,320.00744"
  62.242 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  62.243 +    <path
  62.244 +       inkscape:connection-end="#rect6004"
  62.245 +       inkscape:connector-type="polyline"
  62.246 +       id="path6020"
  62.247 +       d="M 415.38242,365.29315 L 415.38243,381.67412"
  62.248 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  62.249 +    <rect
  62.250 +       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  62.251 +       id="rect6039"
  62.252 +       width="134.53746"
  62.253 +       height="44.537449"
  62.254 +       x="348.11359"
  62.255 +       y="443.71487" />
  62.256 +    <text
  62.257 +       xml:space="preserve"
  62.258 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.259 +       x="372.79706"
  62.260 +       y="469.47556"
  62.261 +       id="text6041"><tspan
  62.262 +         sodipodi:role="line"
  62.263 +         id="tspan6043"
  62.264 +         x="372.79706"
  62.265 +         y="469.47556"
  62.266 +         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  62.267 +    <path
  62.268 +       inkscape:connection-end="#rect6039"
  62.269 +       inkscape:connector-type="polyline"
  62.270 +       id="path6045"
  62.271 +       d="M 415.38238,426.95981 L 415.38235,443.34087"
  62.272 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  62.273 +    <text
  62.274 +       xml:space="preserve"
  62.275 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.276 +       x="327.66046"
  62.277 +       y="231.36218"
  62.278 +       id="text6102"><tspan
  62.279 +         sodipodi:role="line"
  62.280 +         id="tspan6104"
  62.281 +         x="327.66046"
  62.282 +         y="231.36218">History in repository</tspan></text>
  62.283 +    <rect
  62.284 +       y="245.94225"
  62.285 +       x="557.28418"
  62.286 +       height="204.51619"
  62.287 +       width="174.36833"
  62.288 +       id="rect6140"
  62.289 +       style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  62.290 +    <g
  62.291 +       id="g6130"
  62.292 +       transform="translate(262.3254,24.38544)">
  62.293 +      <rect
  62.294 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  62.295 +         id="rect6106"
  62.296 +         width="134.53746"
  62.297 +         height="44.537449"
  62.298 +         x="314.87415"
  62.299 +         y="257.95059" />
  62.300 +      <text
  62.301 +         xml:space="preserve"
  62.302 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.303 +         x="339.55664"
  62.304 +         y="283.7113"
  62.305 +         id="text6108"><tspan
  62.306 +           sodipodi:role="line"
  62.307 +           id="tspan6110"
  62.308 +           x="339.55664"
  62.309 +           y="283.7113"
  62.310 +           style="font-family:Courier">dfbbb33f3fa3</tspan></text>
  62.311 +    </g>
  62.312 +    <g
  62.313 +       id="g6135"
  62.314 +       transform="translate(263.0396,49.83106)">
  62.315 +      <rect
  62.316 +         inkscape:transform-center-y="102.85714"
  62.317 +         inkscape:transform-center-x="129.28571"
  62.318 +         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  62.319 +         id="rect6112"
  62.320 +         width="134.53746"
  62.321 +         height="44.537449"
  62.322 +         x="314.15985"
  62.323 +         y="326.52203" />
  62.324 +      <text
  62.325 +         inkscape:transform-center-y="102.7311"
  62.326 +         inkscape:transform-center-x="128.69672"
  62.327 +         xml:space="preserve"
  62.328 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.329 +         x="338.84335"
  62.330 +         y="352.28271"
  62.331 +         id="text6114"><tspan
  62.332 +           sodipodi:role="line"
  62.333 +           id="tspan6116"
  62.334 +           x="338.84335"
  62.335 +           y="352.28271"
  62.336 +           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  62.337 +    </g>
  62.338 +    <text
  62.339 +       xml:space="preserve"
  62.340 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.341 +       x="576.63208"
  62.342 +       y="270.479"
  62.343 +       id="text6118"><tspan
  62.344 +         sodipodi:role="line"
  62.345 +         id="tspan6120"
  62.346 +         x="576.63208"
  62.347 +         y="270.479">First parent</tspan></text>
  62.348 +    <text
  62.349 +       xml:space="preserve"
  62.350 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.351 +       x="576.07544"
  62.352 +       y="364.49615"
  62.353 +       id="text6122"><tspan
  62.354 +         sodipodi:role="line"
  62.355 +         id="tspan6124"
  62.356 +         x="576.07544"
  62.357 +         y="364.49615">Second parent</tspan></text>
  62.358 +    <text
  62.359 +       xml:space="preserve"
  62.360 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.361 +       x="556.61743"
  62.362 +       y="231.36218"
  62.363 +       id="text6195"><tspan
  62.364 +         sodipodi:role="line"
  62.365 +         id="tspan6197"
  62.366 +         x="556.61743"
  62.367 +         y="231.36218">Parents of working directory</tspan></text>
  62.368 +    <path
  62.369 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  62.370 +       d="M 576.82542,297.63008 L 483.02528,287.95831"
  62.371 +       id="path6266"
  62.372 +       inkscape:connector-type="polyline"
  62.373 +       inkscape:connection-start="#g6130"
  62.374 +       inkscape:connection-end="#g6261" />
  62.375 +    <path
  62.376 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  62.377 +       d="M 665.12232,418.17579 L 665.12232,418.17579"
  62.378 +       id="path6270"
  62.379 +       inkscape:connector-type="polyline" />
  62.380 +    <text
  62.381 +       xml:space="preserve"
  62.382 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  62.383 +       x="316.86407"
  62.384 +       y="275.6496"
  62.385 +       id="text6573"><tspan
  62.386 +         sodipodi:role="line"
  62.387 +         id="tspan6575"
  62.388 +         x="316.86407"
  62.389 +         y="275.6496"
  62.390 +         style="text-align:end;text-anchor:end">New</tspan><tspan
  62.391 +         sodipodi:role="line"
  62.392 +         x="316.86407"
  62.393 +         y="290.6496"
  62.394 +         id="tspan6577"
  62.395 +         style="text-align:end;text-anchor:end">changeset</tspan></text>
  62.396 +  </g>
  62.397 +</svg>
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/fr/figs/wdir-branch.svg	Sun Aug 16 04:58:01 2009 +0200
    63.3 @@ -0,0 +1,418 @@
    63.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    63.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    63.6 +<svg
    63.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    63.8 +   xmlns:cc="http://web.resource.org/cc/"
    63.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   63.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   63.11 +   xmlns="http://www.w3.org/2000/svg"
   63.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   63.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   63.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   63.15 +   width="744.09448819"
   63.16 +   height="1052.3622047"
   63.17 +   id="svg5971"
   63.18 +   sodipodi:version="0.32"
   63.19 +   inkscape:version="0.44.1"
   63.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   63.21 +   sodipodi:docname="wdir-branch.svg">
   63.22 +  <defs
   63.23 +     id="defs5973">
   63.24 +    <marker
   63.25 +       inkscape:stockid="Arrow1Mstart"
   63.26 +       orient="auto"
   63.27 +       refY="0.0"
   63.28 +       refX="0.0"
   63.29 +       id="Arrow1Mstart"
   63.30 +       style="overflow:visible">
   63.31 +      <path
   63.32 +         id="path4855"
   63.33 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   63.34 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   63.35 +         transform="scale(0.4) translate(10,0)" />
   63.36 +    </marker>
   63.37 +    <linearGradient
   63.38 +       id="linearGradient6049">
   63.39 +      <stop
   63.40 +         style="stop-color:#686868;stop-opacity:1;"
   63.41 +         offset="0"
   63.42 +         id="stop6051" />
   63.43 +      <stop
   63.44 +         style="stop-color:#f0f0f0;stop-opacity:1;"
   63.45 +         offset="1"
   63.46 +         id="stop6053" />
   63.47 +    </linearGradient>
   63.48 +    <marker
   63.49 +       inkscape:stockid="Arrow1Mend"
   63.50 +       orient="auto"
   63.51 +       refY="0.0"
   63.52 +       refX="0.0"
   63.53 +       id="Arrow1Mend"
   63.54 +       style="overflow:visible;">
   63.55 +      <path
   63.56 +         id="path4852"
   63.57 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   63.58 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   63.59 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   63.60 +    </marker>
   63.61 +    <linearGradient
   63.62 +       inkscape:collect="always"
   63.63 +       xlink:href="#linearGradient6049"
   63.64 +       id="linearGradient6083"
   63.65 +       gradientUnits="userSpaceOnUse"
   63.66 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   63.67 +       x1="333.91171"
   63.68 +       y1="488.79077"
   63.69 +       x2="508.94543"
   63.70 +       y2="263.79077" />
   63.71 +    <linearGradient
   63.72 +       inkscape:collect="always"
   63.73 +       xlink:href="#linearGradient6049"
   63.74 +       id="linearGradient6142"
   63.75 +       gradientUnits="userSpaceOnUse"
   63.76 +       gradientTransform="translate(-42.00893,-30.49544)"
   63.77 +       x1="333.91171"
   63.78 +       y1="488.79077"
   63.79 +       x2="508.94543"
   63.80 +       y2="263.79077" />
   63.81 +    <linearGradient
   63.82 +       inkscape:collect="always"
   63.83 +       xlink:href="#linearGradient6049"
   63.84 +       id="linearGradient6193"
   63.85 +       gradientUnits="userSpaceOnUse"
   63.86 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   63.87 +       x1="333.91171"
   63.88 +       y1="488.79077"
   63.89 +       x2="508.94543"
   63.90 +       y2="263.79077" />
   63.91 +    <linearGradient
   63.92 +       inkscape:collect="always"
   63.93 +       xlink:href="#linearGradient6049"
   63.94 +       id="linearGradient6216"
   63.95 +       gradientUnits="userSpaceOnUse"
   63.96 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
   63.97 +       x1="333.91171"
   63.98 +       y1="488.79077"
   63.99 +       x2="508.94543"
  63.100 +       y2="263.79077" />
  63.101 +    <linearGradient
  63.102 +       inkscape:collect="always"
  63.103 +       xlink:href="#linearGradient6049"
  63.104 +       id="linearGradient6232"
  63.105 +       gradientUnits="userSpaceOnUse"
  63.106 +       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
  63.107 +       x1="333.91171"
  63.108 +       y1="488.79077"
  63.109 +       x2="508.94543"
  63.110 +       y2="263.79077" />
  63.111 +    <linearGradient
  63.112 +       inkscape:collect="always"
  63.113 +       xlink:href="#linearGradient6049"
  63.114 +       id="linearGradient6445"
  63.115 +       gradientUnits="userSpaceOnUse"
  63.116 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  63.117 +       x1="333.91171"
  63.118 +       y1="488.79077"
  63.119 +       x2="508.94543"
  63.120 +       y2="263.79077" />
  63.121 +    <linearGradient
  63.122 +       inkscape:collect="always"
  63.123 +       xlink:href="#linearGradient6049"
  63.124 +       id="linearGradient6974"
  63.125 +       gradientUnits="userSpaceOnUse"
  63.126 +       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
  63.127 +       x1="333.91171"
  63.128 +       y1="488.79077"
  63.129 +       x2="508.94543"
  63.130 +       y2="263.79077" />
  63.131 +    <linearGradient
  63.132 +       inkscape:collect="always"
  63.133 +       xlink:href="#linearGradient6049"
  63.134 +       id="linearGradient6996"
  63.135 +       gradientUnits="userSpaceOnUse"
  63.136 +       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
  63.137 +       x1="333.91171"
  63.138 +       y1="488.79077"
  63.139 +       x2="508.94543"
  63.140 +       y2="263.79077" />
  63.141 +  </defs>
  63.142 +  <sodipodi:namedview
  63.143 +     id="base"
  63.144 +     pagecolor="#ffffff"
  63.145 +     bordercolor="#666666"
  63.146 +     borderopacity="1.0"
  63.147 +     gridtolerance="10000"
  63.148 +     guidetolerance="10"
  63.149 +     objecttolerance="10"
  63.150 +     inkscape:pageopacity="0.0"
  63.151 +     inkscape:pageshadow="2"
  63.152 +     inkscape:zoom="0.90509668"
  63.153 +     inkscape:cx="345.85973"
  63.154 +     inkscape:cy="690.49342"
  63.155 +     inkscape:document-units="px"
  63.156 +     inkscape:current-layer="layer1"
  63.157 +     showguides="true"
  63.158 +     inkscape:guide-bbox="true"
  63.159 +     inkscape:window-width="906"
  63.160 +     inkscape:window-height="620"
  63.161 +     inkscape:window-x="0"
  63.162 +     inkscape:window-y="25">
  63.163 +    <sodipodi:guide
  63.164 +       orientation="vertical"
  63.165 +       position="-1.4285714"
  63.166 +       id="guide6022" />
  63.167 +  </sodipodi:namedview>
  63.168 +  <metadata
  63.169 +     id="metadata5976">
  63.170 +    <rdf:RDF>
  63.171 +      <cc:Work
  63.172 +         rdf:about="">
  63.173 +        <dc:format>image/svg+xml</dc:format>
  63.174 +        <dc:type
  63.175 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  63.176 +      </cc:Work>
  63.177 +    </rdf:RDF>
  63.178 +  </metadata>
  63.179 +  <g
  63.180 +     inkscape:label="Layer 1"
  63.181 +     inkscape:groupmode="layer"
  63.182 +     id="layer1">
  63.183 +    <rect
  63.184 +       y="246.06918"
  63.185 +       x="64.325172"
  63.186 +       height="204.26233"
  63.187 +       width="333.2135"
  63.188 +       id="rect6047"
  63.189 +       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  63.190 +    <g
  63.191 +       id="g1935">
  63.192 +      <rect
  63.193 +         y="266.24374"
  63.194 +         x="84.113708"
  63.195 +         height="44.537449"
  63.196 +         width="134.53746"
  63.197 +         id="rect5996"
  63.198 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  63.199 +      <text
  63.200 +         id="text5998"
  63.201 +         y="292.00446"
  63.202 +         x="108.7962"
  63.203 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.204 +         xml:space="preserve"><tspan
  63.205 +           style="font-family:Courier"
  63.206 +           y="292.00446"
  63.207 +           x="108.7962"
  63.208 +           id="tspan6000"
  63.209 +           sodipodi:role="line">e7639888bb2f</tspan></text>
  63.210 +    </g>
  63.211 +    <g
  63.212 +       id="g6976"
  63.213 +       transform="translate(70,0)">
  63.214 +      <rect
  63.215 +         y="327.9104"
  63.216 +         x="40.113693"
  63.217 +         height="44.537449"
  63.218 +         width="134.53746"
  63.219 +         id="rect6004"
  63.220 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  63.221 +      <text
  63.222 +         id="text6006"
  63.223 +         y="353.67111"
  63.224 +         x="62.654205"
  63.225 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.226 +         xml:space="preserve"><tspan
  63.227 +           style="font-family:Courier"
  63.228 +           y="353.67111"
  63.229 +           x="62.654205"
  63.230 +           id="tspan6008"
  63.231 +           sodipodi:role="line">7b064d8bac5e</tspan></text>
  63.232 +    </g>
  63.233 +    <path
  63.234 +       inkscape:connector-type="polyline"
  63.235 +       id="path6020"
  63.236 +       d="M 160.92915,311.15532 L 167.83571,327.53627"
  63.237 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  63.238 +       inkscape:connection-end="#g6976"
  63.239 +       inkscape:connection-start="#g1935" />
  63.240 +    <rect
  63.241 +       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  63.242 +       id="rect6039"
  63.243 +       width="134.53746"
  63.244 +       height="44.537449"
  63.245 +       x="110.11359"
  63.246 +       y="389.57703" />
  63.247 +    <text
  63.248 +       xml:space="preserve"
  63.249 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.250 +       x="134.79706"
  63.251 +       y="415.33771"
  63.252 +       id="text6041"><tspan
  63.253 +         sodipodi:role="line"
  63.254 +         id="tspan6043"
  63.255 +         x="134.79706"
  63.256 +         y="415.33771"
  63.257 +         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  63.258 +    <path
  63.259 +       inkscape:connection-end="#rect6039"
  63.260 +       inkscape:connector-type="polyline"
  63.261 +       id="path6045"
  63.262 +       d="M 177.38238,372.82195 L 177.38235,389.20303"
  63.263 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  63.264 +    <rect
  63.265 +       y="245.94225"
  63.266 +       x="447.28412"
  63.267 +       height="204.51619"
  63.268 +       width="174.36833"
  63.269 +       id="rect6140"
  63.270 +       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  63.271 +    <g
  63.272 +       id="g6130"
  63.273 +       transform="translate(152.3254,24.38544)">
  63.274 +      <rect
  63.275 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  63.276 +         id="rect6106"
  63.277 +         width="134.53746"
  63.278 +         height="44.537449"
  63.279 +         x="314.87415"
  63.280 +         y="257.95059" />
  63.281 +      <text
  63.282 +         xml:space="preserve"
  63.283 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.284 +         x="339.55664"
  63.285 +         y="283.7113"
  63.286 +         id="text6108"><tspan
  63.287 +           sodipodi:role="line"
  63.288 +           id="tspan6110"
  63.289 +           x="339.55664"
  63.290 +           y="283.7113"
  63.291 +           style="font-family:Courier">ffb20e1701ea</tspan></text>
  63.292 +    </g>
  63.293 +    <g
  63.294 +       id="g6135"
  63.295 +       transform="translate(153.0396,49.83106)">
  63.296 +      <rect
  63.297 +         inkscape:transform-center-y="102.85714"
  63.298 +         inkscape:transform-center-x="129.28571"
  63.299 +         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  63.300 +         id="rect6112"
  63.301 +         width="134.53746"
  63.302 +         height="44.537449"
  63.303 +         x="314.15985"
  63.304 +         y="326.52203" />
  63.305 +      <text
  63.306 +         inkscape:transform-center-y="102.7311"
  63.307 +         inkscape:transform-center-x="128.69672"
  63.308 +         xml:space="preserve"
  63.309 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.310 +         x="338.84335"
  63.311 +         y="352.28271"
  63.312 +         id="text6114"><tspan
  63.313 +           sodipodi:role="line"
  63.314 +           id="tspan6116"
  63.315 +           x="338.84335"
  63.316 +           y="352.28271"
  63.317 +           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  63.318 +    </g>
  63.319 +    <text
  63.320 +       xml:space="preserve"
  63.321 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.322 +       x="466.63208"
  63.323 +       y="270.479"
  63.324 +       id="text6118"><tspan
  63.325 +         sodipodi:role="line"
  63.326 +         id="tspan6120"
  63.327 +         x="466.63208"
  63.328 +         y="270.479">First parent</tspan></text>
  63.329 +    <text
  63.330 +       xml:space="preserve"
  63.331 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.332 +       x="466.07544"
  63.333 +       y="364.49615"
  63.334 +       id="text6122"><tspan
  63.335 +         sodipodi:role="line"
  63.336 +         id="tspan6124"
  63.337 +         x="466.07544"
  63.338 +         y="364.49615">Second parent</tspan></text>
  63.339 +    <text
  63.340 +       xml:space="preserve"
  63.341 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.342 +       x="446.61743"
  63.343 +       y="231.36218"
  63.344 +       id="text6195"><tspan
  63.345 +         sodipodi:role="line"
  63.346 +         id="tspan6197"
  63.347 +         x="446.61743"
  63.348 +         y="231.36218">Parents of working directory</tspan></text>
  63.349 +    <path
  63.350 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
  63.351 +       d="M 466.82542,300.21999 L 377.00207,294.39744"
  63.352 +       id="path6266"
  63.353 +       inkscape:connector-type="polyline"
  63.354 +       inkscape:connection-start="#g6130"
  63.355 +       inkscape:connection-end="#rect1925" />
  63.356 +    <path
  63.357 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  63.358 +       d="M 665.12232,418.17579 L 665.12232,418.17579"
  63.359 +       id="path6270"
  63.360 +       inkscape:connector-type="polyline" />
  63.361 +    <g
  63.362 +       id="g2845">
  63.363 +      <rect
  63.364 +         y="266.24374"
  63.365 +         x="242.09048"
  63.366 +         height="44.537449"
  63.367 +         width="134.53746"
  63.368 +         id="rect1925"
  63.369 +         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  63.370 +      <text
  63.371 +         id="text1927"
  63.372 +         y="292.00446"
  63.373 +         x="266.77298"
  63.374 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.375 +         xml:space="preserve"><tspan
  63.376 +           style="font-family:Courier"
  63.377 +           y="292.00446"
  63.378 +           x="266.77298"
  63.379 +           id="tspan1929"
  63.380 +           sodipodi:role="line">ffb20e1701ea</tspan></text>
  63.381 +    </g>
  63.382 +    <path
  63.383 +       inkscape:connector-type="polyline"
  63.384 +       id="path1933"
  63.385 +       d="M 260.89978,311.15532 L 225.84185,327.53627"
  63.386 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  63.387 +       inkscape:connection-end="#g6976" />
  63.388 +    <text
  63.389 +       xml:space="preserve"
  63.390 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.391 +       x="109.45568"
  63.392 +       y="231.4554"
  63.393 +       id="text2837"><tspan
  63.394 +         sodipodi:role="line"
  63.395 +         id="tspan2839"
  63.396 +         x="109.45568"
  63.397 +         y="231.4554">Pre-existing head</tspan></text>
  63.398 +    <text
  63.399 +       xml:space="preserve"
  63.400 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  63.401 +       x="237.54184"
  63.402 +       y="231.4554"
  63.403 +       id="text2841"><tspan
  63.404 +         sodipodi:role="line"
  63.405 +         id="tspan2843"
  63.406 +         x="237.54184"
  63.407 +         y="231.4554">Newly created head (and tip)</tspan></text>
  63.408 +    <path
  63.409 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  63.410 +       d="M 148.05048,235.87482 L 149.94915,265.86962"
  63.411 +       id="path2850"
  63.412 +       inkscape:connector-type="polyline"
  63.413 +       inkscape:connection-end="#g1935" />
  63.414 +    <path
  63.415 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  63.416 +       d="M 303.83495,238.08453 L 306.87874,265.86962"
  63.417 +       id="path2852"
  63.418 +       inkscape:connector-type="polyline"
  63.419 +       inkscape:connection-end="#g2845" />
  63.420 +  </g>
  63.421 +</svg>
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/fr/figs/wdir-merge.svg	Sun Aug 16 04:58:01 2009 +0200
    64.3 @@ -0,0 +1,425 @@
    64.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    64.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    64.6 +<svg
    64.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    64.8 +   xmlns:cc="http://web.resource.org/cc/"
    64.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   64.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   64.11 +   xmlns="http://www.w3.org/2000/svg"
   64.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   64.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   64.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   64.15 +   width="744.09448819"
   64.16 +   height="1052.3622047"
   64.17 +   id="svg5971"
   64.18 +   sodipodi:version="0.32"
   64.19 +   inkscape:version="0.44.1"
   64.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   64.21 +   sodipodi:docname="wdir-merge.svg">
   64.22 +  <defs
   64.23 +     id="defs5973">
   64.24 +    <marker
   64.25 +       inkscape:stockid="Arrow1Mstart"
   64.26 +       orient="auto"
   64.27 +       refY="0.0"
   64.28 +       refX="0.0"
   64.29 +       id="Arrow1Mstart"
   64.30 +       style="overflow:visible">
   64.31 +      <path
   64.32 +         id="path4855"
   64.33 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   64.34 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   64.35 +         transform="scale(0.4) translate(10,0)" />
   64.36 +    </marker>
   64.37 +    <linearGradient
   64.38 +       id="linearGradient6049">
   64.39 +      <stop
   64.40 +         style="stop-color:#686868;stop-opacity:1;"
   64.41 +         offset="0"
   64.42 +         id="stop6051" />
   64.43 +      <stop
   64.44 +         style="stop-color:#f0f0f0;stop-opacity:1;"
   64.45 +         offset="1"
   64.46 +         id="stop6053" />
   64.47 +    </linearGradient>
   64.48 +    <marker
   64.49 +       inkscape:stockid="Arrow1Mend"
   64.50 +       orient="auto"
   64.51 +       refY="0.0"
   64.52 +       refX="0.0"
   64.53 +       id="Arrow1Mend"
   64.54 +       style="overflow:visible;">
   64.55 +      <path
   64.56 +         id="path4852"
   64.57 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   64.58 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   64.59 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   64.60 +    </marker>
   64.61 +    <linearGradient
   64.62 +       inkscape:collect="always"
   64.63 +       xlink:href="#linearGradient6049"
   64.64 +       id="linearGradient6083"
   64.65 +       gradientUnits="userSpaceOnUse"
   64.66 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   64.67 +       x1="333.91171"
   64.68 +       y1="488.79077"
   64.69 +       x2="508.94543"
   64.70 +       y2="263.79077" />
   64.71 +    <linearGradient
   64.72 +       inkscape:collect="always"
   64.73 +       xlink:href="#linearGradient6049"
   64.74 +       id="linearGradient6142"
   64.75 +       gradientUnits="userSpaceOnUse"
   64.76 +       gradientTransform="translate(-42.00893,-30.49544)"
   64.77 +       x1="333.91171"
   64.78 +       y1="488.79077"
   64.79 +       x2="508.94543"
   64.80 +       y2="263.79077" />
   64.81 +    <linearGradient
   64.82 +       inkscape:collect="always"
   64.83 +       xlink:href="#linearGradient6049"
   64.84 +       id="linearGradient6193"
   64.85 +       gradientUnits="userSpaceOnUse"
   64.86 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   64.87 +       x1="333.91171"
   64.88 +       y1="488.79077"
   64.89 +       x2="508.94543"
   64.90 +       y2="263.79077" />
   64.91 +    <linearGradient
   64.92 +       inkscape:collect="always"
   64.93 +       xlink:href="#linearGradient6049"
   64.94 +       id="linearGradient6216"
   64.95 +       gradientUnits="userSpaceOnUse"
   64.96 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
   64.97 +       x1="333.91171"
   64.98 +       y1="488.79077"
   64.99 +       x2="508.94543"
  64.100 +       y2="263.79077" />
  64.101 +    <linearGradient
  64.102 +       inkscape:collect="always"
  64.103 +       xlink:href="#linearGradient6049"
  64.104 +       id="linearGradient6232"
  64.105 +       gradientUnits="userSpaceOnUse"
  64.106 +       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
  64.107 +       x1="333.91171"
  64.108 +       y1="488.79077"
  64.109 +       x2="508.94543"
  64.110 +       y2="263.79077" />
  64.111 +    <linearGradient
  64.112 +       inkscape:collect="always"
  64.113 +       xlink:href="#linearGradient6049"
  64.114 +       id="linearGradient6445"
  64.115 +       gradientUnits="userSpaceOnUse"
  64.116 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  64.117 +       x1="333.91171"
  64.118 +       y1="488.79077"
  64.119 +       x2="508.94543"
  64.120 +       y2="263.79077" />
  64.121 +    <linearGradient
  64.122 +       inkscape:collect="always"
  64.123 +       xlink:href="#linearGradient6049"
  64.124 +       id="linearGradient6974"
  64.125 +       gradientUnits="userSpaceOnUse"
  64.126 +       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
  64.127 +       x1="333.91171"
  64.128 +       y1="488.79077"
  64.129 +       x2="508.94543"
  64.130 +       y2="263.79077" />
  64.131 +    <linearGradient
  64.132 +       inkscape:collect="always"
  64.133 +       xlink:href="#linearGradient6049"
  64.134 +       id="linearGradient6996"
  64.135 +       gradientUnits="userSpaceOnUse"
  64.136 +       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
  64.137 +       x1="333.91171"
  64.138 +       y1="488.79077"
  64.139 +       x2="508.94543"
  64.140 +       y2="263.79077" />
  64.141 +  </defs>
  64.142 +  <sodipodi:namedview
  64.143 +     id="base"
  64.144 +     pagecolor="#ffffff"
  64.145 +     bordercolor="#666666"
  64.146 +     borderopacity="1.0"
  64.147 +     gridtolerance="10000"
  64.148 +     guidetolerance="10"
  64.149 +     objecttolerance="10"
  64.150 +     inkscape:pageopacity="0.0"
  64.151 +     inkscape:pageshadow="2"
  64.152 +     inkscape:zoom="1.28"
  64.153 +     inkscape:cx="345.85973"
  64.154 +     inkscape:cy="690.49342"
  64.155 +     inkscape:document-units="px"
  64.156 +     inkscape:current-layer="layer1"
  64.157 +     showguides="true"
  64.158 +     inkscape:guide-bbox="true"
  64.159 +     inkscape:window-width="906"
  64.160 +     inkscape:window-height="620"
  64.161 +     inkscape:window-x="0"
  64.162 +     inkscape:window-y="25">
  64.163 +    <sodipodi:guide
  64.164 +       orientation="vertical"
  64.165 +       position="-1.4285714"
  64.166 +       id="guide6022" />
  64.167 +  </sodipodi:namedview>
  64.168 +  <metadata
  64.169 +     id="metadata5976">
  64.170 +    <rdf:RDF>
  64.171 +      <cc:Work
  64.172 +         rdf:about="">
  64.173 +        <dc:format>image/svg+xml</dc:format>
  64.174 +        <dc:type
  64.175 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  64.176 +      </cc:Work>
  64.177 +    </rdf:RDF>
  64.178 +  </metadata>
  64.179 +  <g
  64.180 +     inkscape:label="Layer 1"
  64.181 +     inkscape:groupmode="layer"
  64.182 +     id="layer1">
  64.183 +    <rect
  64.184 +       y="246.06918"
  64.185 +       x="64.325172"
  64.186 +       height="204.26233"
  64.187 +       width="333.2135"
  64.188 +       id="rect6047"
  64.189 +       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  64.190 +    <g
  64.191 +       id="g6976"
  64.192 +       transform="translate(70,0)">
  64.193 +      <rect
  64.194 +         y="327.9104"
  64.195 +         x="40.113693"
  64.196 +         height="44.537449"
  64.197 +         width="134.53746"
  64.198 +         id="rect6004"
  64.199 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  64.200 +      <text
  64.201 +         id="text6006"
  64.202 +         y="353.67111"
  64.203 +         x="62.654205"
  64.204 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.205 +         xml:space="preserve"><tspan
  64.206 +           style="font-family:Courier"
  64.207 +           y="353.67111"
  64.208 +           x="62.654205"
  64.209 +           id="tspan6008"
  64.210 +           sodipodi:role="line">7b064d8bac5e</tspan></text>
  64.211 +    </g>
  64.212 +    <path
  64.213 +       inkscape:connector-type="polyline"
  64.214 +       id="path6020"
  64.215 +       d="M 160.92915,311.15532 L 167.83571,327.53627"
  64.216 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  64.217 +       inkscape:connection-end="#g6976"
  64.218 +       inkscape:connection-start="#g1935" />
  64.219 +    <rect
  64.220 +       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  64.221 +       id="rect6039"
  64.222 +       width="134.53746"
  64.223 +       height="44.537449"
  64.224 +       x="110.11359"
  64.225 +       y="389.57703" />
  64.226 +    <text
  64.227 +       xml:space="preserve"
  64.228 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.229 +       x="134.79706"
  64.230 +       y="415.33771"
  64.231 +       id="text6041"><tspan
  64.232 +         sodipodi:role="line"
  64.233 +         id="tspan6043"
  64.234 +         x="134.79706"
  64.235 +         y="415.33771"
  64.236 +         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  64.237 +    <path
  64.238 +       inkscape:connection-end="#rect6039"
  64.239 +       inkscape:connector-type="polyline"
  64.240 +       id="path6045"
  64.241 +       d="M 177.38238,372.82195 L 177.38235,389.20303"
  64.242 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  64.243 +    <rect
  64.244 +       y="245.94225"
  64.245 +       x="447.28412"
  64.246 +       height="204.51619"
  64.247 +       width="174.36833"
  64.248 +       id="rect6140"
  64.249 +       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  64.250 +    <g
  64.251 +       id="g6130"
  64.252 +       transform="translate(152.3254,24.38544)">
  64.253 +      <rect
  64.254 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  64.255 +         id="rect6106"
  64.256 +         width="134.53746"
  64.257 +         height="44.537449"
  64.258 +         x="314.87415"
  64.259 +         y="257.95059" />
  64.260 +      <text
  64.261 +         xml:space="preserve"
  64.262 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.263 +         x="339.55664"
  64.264 +         y="283.7113"
  64.265 +         id="text6108"><tspan
  64.266 +           sodipodi:role="line"
  64.267 +           id="tspan6110"
  64.268 +           x="339.55664"
  64.269 +           y="283.7113"
  64.270 +           style="font-family:Courier">ffb20e1701ea</tspan></text>
  64.271 +    </g>
  64.272 +    <g
  64.273 +       id="g6135"
  64.274 +       transform="translate(153.0396,49.83106)">
  64.275 +      <rect
  64.276 +         inkscape:transform-center-y="102.85714"
  64.277 +         inkscape:transform-center-x="129.28571"
  64.278 +         style="fill:#d4d4d4;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  64.279 +         id="rect6112"
  64.280 +         width="134.53746"
  64.281 +         height="44.537449"
  64.282 +         x="314.15985"
  64.283 +         y="326.52203" />
  64.284 +      <text
  64.285 +         inkscape:transform-center-y="102.7311"
  64.286 +         inkscape:transform-center-x="128.69672"
  64.287 +         xml:space="preserve"
  64.288 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.289 +         x="338.84335"
  64.290 +         y="352.28271"
  64.291 +         id="text6114"><tspan
  64.292 +           sodipodi:role="line"
  64.293 +           id="tspan6116"
  64.294 +           x="338.84335"
  64.295 +           y="352.28271"
  64.296 +           style="fill:black;fill-opacity:1;font-family:Courier">e7639888bb2f</tspan></text>
  64.297 +    </g>
  64.298 +    <text
  64.299 +       xml:space="preserve"
  64.300 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.301 +       x="466.63208"
  64.302 +       y="270.479"
  64.303 +       id="text6118"><tspan
  64.304 +         sodipodi:role="line"
  64.305 +         id="tspan6120"
  64.306 +         x="466.63208"
  64.307 +         y="270.479">First parent (unchanged)</tspan></text>
  64.308 +    <text
  64.309 +       xml:space="preserve"
  64.310 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.311 +       x="466.07544"
  64.312 +       y="364.49615"
  64.313 +       id="text6122"><tspan
  64.314 +         sodipodi:role="line"
  64.315 +         id="tspan6124"
  64.316 +         x="466.07544"
  64.317 +         y="364.49615">Second parent</tspan></text>
  64.318 +    <text
  64.319 +       xml:space="preserve"
  64.320 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.321 +       x="446.61743"
  64.322 +       y="231.36218"
  64.323 +       id="text6195"><tspan
  64.324 +         sodipodi:role="line"
  64.325 +         id="tspan6197"
  64.326 +         x="446.61743"
  64.327 +         y="231.36218">Parents of working directory</tspan></text>
  64.328 +    <path
  64.329 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
  64.330 +       d="M 466.82542,300.21999 L 377.00207,294.39744"
  64.331 +       id="path6266"
  64.332 +       inkscape:connector-type="polyline"
  64.333 +       inkscape:connection-start="#g6130"
  64.334 +       inkscape:connection-end="#rect1925" />
  64.335 +    <path
  64.336 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  64.337 +       d="M 665.12232,418.17579 L 665.12232,418.17579"
  64.338 +       id="path6270"
  64.339 +       inkscape:connector-type="polyline" />
  64.340 +    <g
  64.341 +       id="g2845">
  64.342 +      <rect
  64.343 +         y="266.24374"
  64.344 +         x="242.09048"
  64.345 +         height="44.537449"
  64.346 +         width="134.53746"
  64.347 +         id="rect1925"
  64.348 +         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  64.349 +      <text
  64.350 +         id="text1927"
  64.351 +         y="292.00446"
  64.352 +         x="266.77298"
  64.353 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.354 +         xml:space="preserve"><tspan
  64.355 +           style="font-family:Courier"
  64.356 +           y="292.00446"
  64.357 +           x="266.77298"
  64.358 +           id="tspan1929"
  64.359 +           sodipodi:role="line">ffb20e1701ea</tspan></text>
  64.360 +    </g>
  64.361 +    <path
  64.362 +       inkscape:connector-type="polyline"
  64.363 +       id="path1933"
  64.364 +       d="M 260.89978,311.15532 L 225.84185,327.53627"
  64.365 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  64.366 +       inkscape:connection-end="#g6976" />
  64.367 +    <text
  64.368 +       xml:space="preserve"
  64.369 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.370 +       x="109.45568"
  64.371 +       y="231.4554"
  64.372 +       id="text2837"><tspan
  64.373 +         sodipodi:role="line"
  64.374 +         id="tspan2839"
  64.375 +         x="109.45568"
  64.376 +         y="231.4554">Pre-existing head</tspan></text>
  64.377 +    <text
  64.378 +       xml:space="preserve"
  64.379 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.380 +       x="237.54184"
  64.381 +       y="231.4554"
  64.382 +       id="text2841"><tspan
  64.383 +         sodipodi:role="line"
  64.384 +         id="tspan2843"
  64.385 +         x="237.54184"
  64.386 +         y="231.4554">Newly created head (and tip)</tspan></text>
  64.387 +    <path
  64.388 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  64.389 +       d="M 148.05048,235.87482 L 149.94915,265.86962"
  64.390 +       id="path2850"
  64.391 +       inkscape:connector-type="polyline"
  64.392 +       inkscape:connection-end="#g1935" />
  64.393 +    <path
  64.394 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  64.395 +       d="M 303.83495,238.08453 L 306.87874,265.86962"
  64.396 +       id="path2852"
  64.397 +       inkscape:connector-type="polyline"
  64.398 +       inkscape:connection-end="#g2845" />
  64.399 +    <path
  64.400 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
  64.401 +       d="M 466.82545,379.17944 L 219.0253,307.95488"
  64.402 +       id="path3016"
  64.403 +       inkscape:connector-type="polyline"
  64.404 +       inkscape:connection-start="#g6135"
  64.405 +       inkscape:connection-end="#g1935" />
  64.406 +    <g
  64.407 +       id="g1935">
  64.408 +      <rect
  64.409 +         y="266.24374"
  64.410 +         x="84.113708"
  64.411 +         height="44.537449"
  64.412 +         width="134.53746"
  64.413 +         id="rect5996"
  64.414 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  64.415 +      <text
  64.416 +         id="text5998"
  64.417 +         y="292.00446"
  64.418 +         x="108.7962"
  64.419 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  64.420 +         xml:space="preserve"><tspan
  64.421 +           style="font-family:Courier"
  64.422 +           y="292.00446"
  64.423 +           x="108.7962"
  64.424 +           id="tspan6000"
  64.425 +           sodipodi:role="line">e7639888bb2f</tspan></text>
  64.426 +    </g>
  64.427 +  </g>
  64.428 +</svg>
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/fr/figs/wdir-pre-branch.svg	Sun Aug 16 04:58:01 2009 +0200
    65.3 @@ -0,0 +1,364 @@
    65.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    65.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    65.6 +<svg
    65.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    65.8 +   xmlns:cc="http://web.resource.org/cc/"
    65.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   65.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   65.11 +   xmlns="http://www.w3.org/2000/svg"
   65.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   65.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   65.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   65.15 +   width="744.09448819"
   65.16 +   height="1052.3622047"
   65.17 +   id="svg5971"
   65.18 +   sodipodi:version="0.32"
   65.19 +   inkscape:version="0.44.1"
   65.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   65.21 +   sodipodi:docname="wdir-branch.svg">
   65.22 +  <defs
   65.23 +     id="defs5973">
   65.24 +    <marker
   65.25 +       inkscape:stockid="Arrow1Mstart"
   65.26 +       orient="auto"
   65.27 +       refY="0.0"
   65.28 +       refX="0.0"
   65.29 +       id="Arrow1Mstart"
   65.30 +       style="overflow:visible">
   65.31 +      <path
   65.32 +         id="path4855"
   65.33 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   65.34 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   65.35 +         transform="scale(0.4) translate(10,0)" />
   65.36 +    </marker>
   65.37 +    <linearGradient
   65.38 +       id="linearGradient6049">
   65.39 +      <stop
   65.40 +         style="stop-color:#686868;stop-opacity:1;"
   65.41 +         offset="0"
   65.42 +         id="stop6051" />
   65.43 +      <stop
   65.44 +         style="stop-color:#f0f0f0;stop-opacity:1;"
   65.45 +         offset="1"
   65.46 +         id="stop6053" />
   65.47 +    </linearGradient>
   65.48 +    <marker
   65.49 +       inkscape:stockid="Arrow1Mend"
   65.50 +       orient="auto"
   65.51 +       refY="0.0"
   65.52 +       refX="0.0"
   65.53 +       id="Arrow1Mend"
   65.54 +       style="overflow:visible;">
   65.55 +      <path
   65.56 +         id="path4852"
   65.57 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   65.58 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   65.59 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   65.60 +    </marker>
   65.61 +    <linearGradient
   65.62 +       inkscape:collect="always"
   65.63 +       xlink:href="#linearGradient6049"
   65.64 +       id="linearGradient6083"
   65.65 +       gradientUnits="userSpaceOnUse"
   65.66 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   65.67 +       x1="333.91171"
   65.68 +       y1="488.79077"
   65.69 +       x2="508.94543"
   65.70 +       y2="263.79077" />
   65.71 +    <linearGradient
   65.72 +       inkscape:collect="always"
   65.73 +       xlink:href="#linearGradient6049"
   65.74 +       id="linearGradient6142"
   65.75 +       gradientUnits="userSpaceOnUse"
   65.76 +       gradientTransform="translate(-42.00893,-30.49544)"
   65.77 +       x1="333.91171"
   65.78 +       y1="488.79077"
   65.79 +       x2="508.94543"
   65.80 +       y2="263.79077" />
   65.81 +    <linearGradient
   65.82 +       inkscape:collect="always"
   65.83 +       xlink:href="#linearGradient6049"
   65.84 +       id="linearGradient6193"
   65.85 +       gradientUnits="userSpaceOnUse"
   65.86 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   65.87 +       x1="333.91171"
   65.88 +       y1="488.79077"
   65.89 +       x2="508.94543"
   65.90 +       y2="263.79077" />
   65.91 +    <linearGradient
   65.92 +       inkscape:collect="always"
   65.93 +       xlink:href="#linearGradient6049"
   65.94 +       id="linearGradient6216"
   65.95 +       gradientUnits="userSpaceOnUse"
   65.96 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
   65.97 +       x1="333.91171"
   65.98 +       y1="488.79077"
   65.99 +       x2="508.94543"
  65.100 +       y2="263.79077" />
  65.101 +    <linearGradient
  65.102 +       inkscape:collect="always"
  65.103 +       xlink:href="#linearGradient6049"
  65.104 +       id="linearGradient6232"
  65.105 +       gradientUnits="userSpaceOnUse"
  65.106 +       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
  65.107 +       x1="333.91171"
  65.108 +       y1="488.79077"
  65.109 +       x2="508.94543"
  65.110 +       y2="263.79077" />
  65.111 +    <linearGradient
  65.112 +       inkscape:collect="always"
  65.113 +       xlink:href="#linearGradient6049"
  65.114 +       id="linearGradient6445"
  65.115 +       gradientUnits="userSpaceOnUse"
  65.116 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  65.117 +       x1="333.91171"
  65.118 +       y1="488.79077"
  65.119 +       x2="508.94543"
  65.120 +       y2="263.79077" />
  65.121 +    <linearGradient
  65.122 +       inkscape:collect="always"
  65.123 +       xlink:href="#linearGradient6049"
  65.124 +       id="linearGradient6974"
  65.125 +       gradientUnits="userSpaceOnUse"
  65.126 +       gradientTransform="matrix(1.000474,0,0,0.790947,-314.246,50.85694)"
  65.127 +       x1="333.91171"
  65.128 +       y1="488.79077"
  65.129 +       x2="508.94543"
  65.130 +       y2="263.79077" />
  65.131 +    <linearGradient
  65.132 +       inkscape:collect="always"
  65.133 +       xlink:href="#linearGradient6049"
  65.134 +       id="linearGradient6996"
  65.135 +       gradientUnits="userSpaceOnUse"
  65.136 +       gradientTransform="matrix(1.000473,0,0,0.790947,-85.16012,50.85693)"
  65.137 +       x1="333.91171"
  65.138 +       y1="488.79077"
  65.139 +       x2="508.94543"
  65.140 +       y2="263.79077" />
  65.141 +  </defs>
  65.142 +  <sodipodi:namedview
  65.143 +     id="base"
  65.144 +     pagecolor="#ffffff"
  65.145 +     bordercolor="#666666"
  65.146 +     borderopacity="1.0"
  65.147 +     gridtolerance="10000"
  65.148 +     guidetolerance="10"
  65.149 +     objecttolerance="10"
  65.150 +     inkscape:pageopacity="0.0"
  65.151 +     inkscape:pageshadow="2"
  65.152 +     inkscape:zoom="0.90509668"
  65.153 +     inkscape:cx="390.0539"
  65.154 +     inkscape:cy="690.49342"
  65.155 +     inkscape:document-units="px"
  65.156 +     inkscape:current-layer="layer1"
  65.157 +     showguides="true"
  65.158 +     inkscape:guide-bbox="true"
  65.159 +     inkscape:window-width="906"
  65.160 +     inkscape:window-height="620"
  65.161 +     inkscape:window-x="0"
  65.162 +     inkscape:window-y="25">
  65.163 +    <sodipodi:guide
  65.164 +       orientation="vertical"
  65.165 +       position="-1.4285714"
  65.166 +       id="guide6022" />
  65.167 +  </sodipodi:namedview>
  65.168 +  <metadata
  65.169 +     id="metadata5976">
  65.170 +    <rdf:RDF>
  65.171 +      <cc:Work
  65.172 +         rdf:about="">
  65.173 +        <dc:format>image/svg+xml</dc:format>
  65.174 +        <dc:type
  65.175 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  65.176 +      </cc:Work>
  65.177 +    </rdf:RDF>
  65.178 +  </metadata>
  65.179 +  <g
  65.180 +     inkscape:label="Layer 1"
  65.181 +     inkscape:groupmode="layer"
  65.182 +     id="layer1">
  65.183 +    <rect
  65.184 +       y="245.94225"
  65.185 +       x="20.198257"
  65.186 +       height="204.51619"
  65.187 +       width="174.36833"
  65.188 +       id="rect6047"
  65.189 +       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  65.190 +    <rect
  65.191 +       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  65.192 +       id="rect5996"
  65.193 +       width="134.53746"
  65.194 +       height="44.537449"
  65.195 +       x="40.113693"
  65.196 +       y="266.24374" />
  65.197 +    <text
  65.198 +       xml:space="preserve"
  65.199 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.200 +       x="64.796204"
  65.201 +       y="292.00446"
  65.202 +       id="text5998"><tspan
  65.203 +         sodipodi:role="line"
  65.204 +         id="tspan6000"
  65.205 +         x="64.796204"
  65.206 +         y="292.00446"
  65.207 +         style="font-family:Courier">e7639888bb2f</tspan></text>
  65.208 +    <g
  65.209 +       id="g6976">
  65.210 +      <rect
  65.211 +         y="327.9104"
  65.212 +         x="40.113693"
  65.213 +         height="44.537449"
  65.214 +         width="134.53746"
  65.215 +         id="rect6004"
  65.216 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  65.217 +      <text
  65.218 +         id="text6006"
  65.219 +         y="353.67111"
  65.220 +         x="62.654205"
  65.221 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.222 +         xml:space="preserve"><tspan
  65.223 +           style="font-family:Courier"
  65.224 +           y="353.67111"
  65.225 +           x="62.654205"
  65.226 +           id="tspan6008"
  65.227 +           sodipodi:role="line">7b064d8bac5e</tspan></text>
  65.228 +    </g>
  65.229 +    <path
  65.230 +       inkscape:connection-end="#rect6004"
  65.231 +       inkscape:connector-type="polyline"
  65.232 +       id="path6020"
  65.233 +       d="M 107.38242,311.15529 L 107.38242,327.53626"
  65.234 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  65.235 +    <rect
  65.236 +       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  65.237 +       id="rect6039"
  65.238 +       width="134.53746"
  65.239 +       height="44.537449"
  65.240 +       x="40.113571"
  65.241 +       y="389.57703" />
  65.242 +    <text
  65.243 +       xml:space="preserve"
  65.244 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.245 +       x="64.797073"
  65.246 +       y="415.33771"
  65.247 +       id="text6041"><tspan
  65.248 +         sodipodi:role="line"
  65.249 +         id="tspan6043"
  65.250 +         x="64.797073"
  65.251 +         y="415.33771"
  65.252 +         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  65.253 +    <path
  65.254 +       inkscape:connection-end="#rect6039"
  65.255 +       inkscape:connector-type="polyline"
  65.256 +       id="path6045"
  65.257 +       d="M 107.38238,372.82195 L 107.38235,389.20301"
  65.258 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
  65.259 +    <text
  65.260 +       xml:space="preserve"
  65.261 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.262 +       x="19.660461"
  65.263 +       y="231.36218"
  65.264 +       id="text6102"><tspan
  65.265 +         sodipodi:role="line"
  65.266 +         id="tspan6104"
  65.267 +         x="19.660461"
  65.268 +         y="231.36218">History in repository</tspan></text>
  65.269 +    <rect
  65.270 +       y="245.94225"
  65.271 +       x="249.28412"
  65.272 +       height="204.51619"
  65.273 +       width="174.36833"
  65.274 +       id="rect6140"
  65.275 +       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  65.276 +    <g
  65.277 +       id="g6130"
  65.278 +       transform="translate(-45.67459,24.38544)">
  65.279 +      <rect
  65.280 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
  65.281 +         id="rect6106"
  65.282 +         width="134.53746"
  65.283 +         height="44.537449"
  65.284 +         x="314.87415"
  65.285 +         y="257.95059" />
  65.286 +      <text
  65.287 +         xml:space="preserve"
  65.288 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.289 +         x="339.55664"
  65.290 +         y="283.7113"
  65.291 +         id="text6108"><tspan
  65.292 +           sodipodi:role="line"
  65.293 +           id="tspan6110"
  65.294 +           x="339.55664"
  65.295 +           y="283.7113"
  65.296 +           style="font-family:Courier">7b064d8bac5e</tspan></text>
  65.297 +    </g>
  65.298 +    <g
  65.299 +       id="g6135"
  65.300 +       transform="translate(-44.96042,49.83106)">
  65.301 +      <rect
  65.302 +         inkscape:transform-center-y="102.85714"
  65.303 +         inkscape:transform-center-x="129.28571"
  65.304 +         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  65.305 +         id="rect6112"
  65.306 +         width="134.53746"
  65.307 +         height="44.537449"
  65.308 +         x="314.15985"
  65.309 +         y="326.52203" />
  65.310 +      <text
  65.311 +         inkscape:transform-center-y="102.7311"
  65.312 +         inkscape:transform-center-x="128.69672"
  65.313 +         xml:space="preserve"
  65.314 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.315 +         x="338.84335"
  65.316 +         y="352.28271"
  65.317 +         id="text6114"><tspan
  65.318 +           sodipodi:role="line"
  65.319 +           id="tspan6116"
  65.320 +           x="338.84335"
  65.321 +           y="352.28271"
  65.322 +           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
  65.323 +    </g>
  65.324 +    <text
  65.325 +       xml:space="preserve"
  65.326 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.327 +       x="268.63208"
  65.328 +       y="270.479"
  65.329 +       id="text6118"><tspan
  65.330 +         sodipodi:role="line"
  65.331 +         id="tspan6120"
  65.332 +         x="268.63208"
  65.333 +         y="270.479">First parent</tspan></text>
  65.334 +    <text
  65.335 +       xml:space="preserve"
  65.336 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.337 +       x="268.07544"
  65.338 +       y="364.49615"
  65.339 +       id="text6122"><tspan
  65.340 +         sodipodi:role="line"
  65.341 +         id="tspan6124"
  65.342 +         x="268.07544"
  65.343 +         y="364.49615">Second parent</tspan></text>
  65.344 +    <text
  65.345 +       xml:space="preserve"
  65.346 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  65.347 +       x="248.61746"
  65.348 +       y="231.36218"
  65.349 +       id="text6195"><tspan
  65.350 +         sodipodi:role="line"
  65.351 +         id="tspan6197"
  65.352 +         x="248.61746"
  65.353 +         y="231.36218">Parents of working directory</tspan></text>
  65.354 +    <path
  65.355 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
  65.356 +       d="M 268.82543,318.06163 L 175.02528,336.72225"
  65.357 +       id="path6266"
  65.358 +       inkscape:connector-type="polyline"
  65.359 +       inkscape:connection-end="#g6976"
  65.360 +       inkscape:connection-start="#g6130" />
  65.361 +    <path
  65.362 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  65.363 +       d="M 665.12232,418.17579 L 665.12232,418.17579"
  65.364 +       id="path6270"
  65.365 +       inkscape:connector-type="polyline" />
  65.366 +  </g>
  65.367 +</svg>
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/fr/figs/wdir.svg	Sun Aug 16 04:58:01 2009 +0200
    66.3 @@ -0,0 +1,348 @@
    66.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    66.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    66.6 +<svg
    66.7 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    66.8 +   xmlns:cc="http://web.resource.org/cc/"
    66.9 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   66.10 +   xmlns:svg="http://www.w3.org/2000/svg"
   66.11 +   xmlns="http://www.w3.org/2000/svg"
   66.12 +   xmlns:xlink="http://www.w3.org/1999/xlink"
   66.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   66.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   66.15 +   width="744.09448819"
   66.16 +   height="1052.3622047"
   66.17 +   id="svg5971"
   66.18 +   sodipodi:version="0.32"
   66.19 +   inkscape:version="0.44.1"
   66.20 +   sodipodi:docbase="/home/bos/hg/hgbook/en"
   66.21 +   sodipodi:docname="wdir.svg">
   66.22 +  <defs
   66.23 +     id="defs5973">
   66.24 +    <marker
   66.25 +       inkscape:stockid="Arrow1Mstart"
   66.26 +       orient="auto"
   66.27 +       refY="0.0"
   66.28 +       refX="0.0"
   66.29 +       id="Arrow1Mstart"
   66.30 +       style="overflow:visible">
   66.31 +      <path
   66.32 +         id="path4855"
   66.33 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   66.34 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   66.35 +         transform="scale(0.4) translate(10,0)" />
   66.36 +    </marker>
   66.37 +    <linearGradient
   66.38 +       id="linearGradient6049">
   66.39 +      <stop
   66.40 +         style="stop-color:#686868;stop-opacity:1;"
   66.41 +         offset="0"
   66.42 +         id="stop6051" />
   66.43 +      <stop
   66.44 +         style="stop-color:#f0f0f0;stop-opacity:1;"
   66.45 +         offset="1"
   66.46 +         id="stop6053" />
   66.47 +    </linearGradient>
   66.48 +    <marker
   66.49 +       inkscape:stockid="Arrow1Mend"
   66.50 +       orient="auto"
   66.51 +       refY="0.0"
   66.52 +       refX="0.0"
   66.53 +       id="Arrow1Mend"
   66.54 +       style="overflow:visible;">
   66.55 +      <path
   66.56 +         id="path4852"
   66.57 +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   66.58 +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   66.59 +         transform="scale(0.4) rotate(180) translate(10,0)" />
   66.60 +    </marker>
   66.61 +    <linearGradient
   66.62 +       inkscape:collect="always"
   66.63 +       xlink:href="#linearGradient6049"
   66.64 +       id="linearGradient6083"
   66.65 +       gradientUnits="userSpaceOnUse"
   66.66 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   66.67 +       x1="333.91171"
   66.68 +       y1="488.79077"
   66.69 +       x2="508.94543"
   66.70 +       y2="263.79077" />
   66.71 +    <linearGradient
   66.72 +       inkscape:collect="always"
   66.73 +       xlink:href="#linearGradient6049"
   66.74 +       id="linearGradient6142"
   66.75 +       gradientUnits="userSpaceOnUse"
   66.76 +       gradientTransform="translate(-42.00893,-30.49544)"
   66.77 +       x1="333.91171"
   66.78 +       y1="488.79077"
   66.79 +       x2="508.94543"
   66.80 +       y2="263.79077" />
   66.81 +    <linearGradient
   66.82 +       inkscape:collect="always"
   66.83 +       xlink:href="#linearGradient6049"
   66.84 +       id="linearGradient6193"
   66.85 +       gradientUnits="userSpaceOnUse"
   66.86 +       gradientTransform="translate(-240.0462,-8.633237e-6)"
   66.87 +       x1="333.91171"
   66.88 +       y1="488.79077"
   66.89 +       x2="508.94543"
   66.90 +       y2="263.79077" />
   66.91 +    <linearGradient
   66.92 +       inkscape:collect="always"
   66.93 +       xlink:href="#linearGradient6049"
   66.94 +       id="linearGradient6216"
   66.95 +       gradientUnits="userSpaceOnUse"
   66.96 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
   66.97 +       x1="333.91171"
   66.98 +       y1="488.79077"
   66.99 +       x2="508.94543"
  66.100 +       y2="263.79077" />
  66.101 +    <linearGradient
  66.102 +       inkscape:collect="always"
  66.103 +       xlink:href="#linearGradient6049"
  66.104 +       id="linearGradient6232"
  66.105 +       gradientUnits="userSpaceOnUse"
  66.106 +       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
  66.107 +       x1="333.91171"
  66.108 +       y1="488.79077"
  66.109 +       x2="508.94543"
  66.110 +       y2="263.79077" />
  66.111 +    <linearGradient
  66.112 +       inkscape:collect="always"
  66.113 +       xlink:href="#linearGradient6049"
  66.114 +       id="linearGradient6445"
  66.115 +       gradientUnits="userSpaceOnUse"
  66.116 +       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  66.117 +       x1="333.91171"
  66.118 +       y1="488.79077"
  66.119 +       x2="508.94543"
  66.120 +       y2="263.79077" />
  66.121 +  </defs>
  66.122 +  <sodipodi:namedview
  66.123 +     id="base"
  66.124 +     pagecolor="#ffffff"
  66.125 +     bordercolor="#666666"
  66.126 +     borderopacity="1.0"
  66.127 +     gridtolerance="10000"
  66.128 +     guidetolerance="10"
  66.129 +     objecttolerance="10"
  66.130 +     inkscape:pageopacity="0.0"
  66.131 +     inkscape:pageshadow="2"
  66.132 +     inkscape:zoom="0.90509668"
  66.133 +     inkscape:cx="390.0539"
  66.134 +     inkscape:cy="690.49342"
  66.135 +     inkscape:document-units="px"
  66.136 +     inkscape:current-layer="layer1"
  66.137 +     showguides="true"
  66.138 +     inkscape:guide-bbox="true"
  66.139 +     inkscape:window-width="906"
  66.140 +     inkscape:window-height="620"
  66.141 +     inkscape:window-x="0"
  66.142 +     inkscape:window-y="25">
  66.143 +    <sodipodi:guide
  66.144 +       orientation="vertical"
  66.145 +       position="-1.4285714"
  66.146 +       id="guide6022" />
  66.147 +  </sodipodi:namedview>
  66.148 +  <metadata
  66.149 +     id="metadata5976">
  66.150 +    <rdf:RDF>
  66.151 +      <cc:Work
  66.152 +         rdf:about="">
  66.153 +        <dc:format>image/svg+xml</dc:format>
  66.154 +        <dc:type
  66.155 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  66.156 +      </cc:Work>
  66.157 +    </rdf:RDF>
  66.158 +  </metadata>
  66.159 +  <g
  66.160 +     inkscape:label="Layer 1"
  66.161 +     inkscape:groupmode="layer"
  66.162 +     id="layer1">
  66.163 +    <g
  66.164 +       id="g6431"
  66.165 +       transform="translate(0,-0.137863)">
  66.166 +      <rect
  66.167 +         style="fill:url(#linearGradient6445);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  66.168 +         id="rect6047"
  66.169 +         width="174.36833"
  66.170 +         height="204.51619"
  66.171 +         x="94.198257"
  66.172 +         y="246.08011" />
  66.173 +      <rect
  66.174 +         y="266.38159"
  66.175 +         x="114.11369"
  66.176 +         height="44.537449"
  66.177 +         width="134.53746"
  66.178 +         id="rect5996"
  66.179 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  66.180 +      <text
  66.181 +         id="text5998"
  66.182 +         y="292.1423"
  66.183 +         x="138.7962"
  66.184 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.185 +         xml:space="preserve"><tspan
  66.186 +           style="font-family:Courier"
  66.187 +           y="292.1423"
  66.188 +           x="138.7962"
  66.189 +           id="tspan6000"
  66.190 +           sodipodi:role="line">e7639888bb2f</tspan></text>
  66.191 +      <rect
  66.192 +         y="328.04825"
  66.193 +         x="114.11369"
  66.194 +         height="44.537449"
  66.195 +         width="134.53746"
  66.196 +         id="rect6004"
  66.197 +         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  66.198 +      <text
  66.199 +         id="text6006"
  66.200 +         y="353.80896"
  66.201 +         x="136.65421"
  66.202 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.203 +         xml:space="preserve"><tspan
  66.204 +           style="font-family:Courier"
  66.205 +           y="353.80896"
  66.206 +           x="136.65421"
  66.207 +           id="tspan6008"
  66.208 +           sodipodi:role="line">7b064d8bac5e</tspan></text>
  66.209 +      <path
  66.210 +         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  66.211 +         d="M 181.38242,311.29315 L 181.38242,327.67412"
  66.212 +         id="path6020"
  66.213 +         inkscape:connector-type="polyline"
  66.214 +         inkscape:connection-end="#rect6004" />
  66.215 +      <rect
  66.216 +         y="389.71487"
  66.217 +         x="114.11357"
  66.218 +         height="44.537449"
  66.219 +         width="134.53746"
  66.220 +         id="rect6039"
  66.221 +         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  66.222 +      <text
  66.223 +         id="text6041"
  66.224 +         y="415.47556"
  66.225 +         x="138.79707"
  66.226 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.227 +         xml:space="preserve"><tspan
  66.228 +           style="fill:#979797;fill-opacity:1;font-family:Courier"
  66.229 +           y="415.47556"
  66.230 +           x="138.79707"
  66.231 +           id="tspan6043"
  66.232 +           sodipodi:role="line">000000000000</tspan></text>
  66.233 +      <path
  66.234 +         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  66.235 +         d="M 181.38238,372.95981 L 181.38235,389.34087"
  66.236 +         id="path6045"
  66.237 +         inkscape:connector-type="polyline"
  66.238 +         inkscape:connection-end="#rect6039" />
  66.239 +    </g>
  66.240 +    <text
  66.241 +       xml:space="preserve"
  66.242 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.243 +       x="93.660484"
  66.244 +       y="231.36218"
  66.245 +       id="text6102"><tspan
  66.246 +         sodipodi:role="line"
  66.247 +         id="tspan6104"
  66.248 +         x="93.660484"
  66.249 +         y="231.36218">History in repository</tspan></text>
  66.250 +    <g
  66.251 +       id="g6416">
  66.252 +      <rect
  66.253 +         style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  66.254 +         id="rect6140"
  66.255 +         width="174.36833"
  66.256 +         height="204.51619"
  66.257 +         x="323.28412"
  66.258 +         y="245.94225" />
  66.259 +      <g
  66.260 +         transform="translate(28.32541,24.38544)"
  66.261 +         id="g6130">
  66.262 +        <rect
  66.263 +           y="257.95059"
  66.264 +           x="314.87415"
  66.265 +           height="44.537449"
  66.266 +           width="134.53746"
  66.267 +           id="rect6106"
  66.268 +           style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
  66.269 +        <text
  66.270 +           id="text6108"
  66.271 +           y="283.7113"
  66.272 +           x="339.55664"
  66.273 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.274 +           xml:space="preserve"><tspan
  66.275 +             style="font-family:Courier"
  66.276 +             y="283.7113"
  66.277 +             x="339.55664"
  66.278 +             id="tspan6110"
  66.279 +             sodipodi:role="line">e7639888bb2f</tspan></text>
  66.280 +      </g>
  66.281 +      <g
  66.282 +         transform="translate(29.03958,49.83106)"
  66.283 +         id="g6135">
  66.284 +        <rect
  66.285 +           y="326.52203"
  66.286 +           x="314.15985"
  66.287 +           height="44.537449"
  66.288 +           width="134.53746"
  66.289 +           id="rect6112"
  66.290 +           style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  66.291 +           inkscape:transform-center-x="129.28571"
  66.292 +           inkscape:transform-center-y="102.85714" />
  66.293 +        <text
  66.294 +           id="text6114"
  66.295 +           y="352.28271"
  66.296 +           x="338.84335"
  66.297 +           style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.298 +           xml:space="preserve"
  66.299 +           inkscape:transform-center-x="128.69672"
  66.300 +           inkscape:transform-center-y="102.7311"><tspan
  66.301 +             style="fill:#979797;fill-opacity:1;font-family:Courier"
  66.302 +             y="352.28271"
  66.303 +             x="338.84335"
  66.304 +             id="tspan6116"
  66.305 +             sodipodi:role="line">000000000000</tspan></text>
  66.306 +      </g>
  66.307 +      <text
  66.308 +         id="text6118"
  66.309 +         y="270.479"
  66.310 +         x="342.63208"
  66.311 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.312 +         xml:space="preserve"><tspan
  66.313 +           y="270.479"
  66.314 +           x="342.63208"
  66.315 +           id="tspan6120"
  66.316 +           sodipodi:role="line">First parent</tspan></text>
  66.317 +      <text
  66.318 +         id="text6122"
  66.319 +         y="364.49615"
  66.320 +         x="342.07544"
  66.321 +         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.322 +         xml:space="preserve"><tspan
  66.323 +           y="364.49615"
  66.324 +           x="342.07544"
  66.325 +           id="tspan6124"
  66.326 +           sodipodi:role="line">Second parent</tspan></text>
  66.327 +    </g>
  66.328 +    <text
  66.329 +       xml:space="preserve"
  66.330 +       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  66.331 +       x="322.61746"
  66.332 +       y="231.36218"
  66.333 +       id="text6195"><tspan
  66.334 +         sodipodi:role="line"
  66.335 +         id="tspan6197"
  66.336 +         x="322.61746"
  66.337 +         y="231.36218">Parents of working directory</tspan></text>
  66.338 +    <path
  66.339 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
  66.340 +       d="M 342.82543,299.89384 L 249.02528,293.36123"
  66.341 +       id="path6266"
  66.342 +       inkscape:connector-type="polyline"
  66.343 +       inkscape:connection-start="#g6130"
  66.344 +       inkscape:connection-end="#rect5996" />
  66.345 +    <path
  66.346 +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  66.347 +       d="M 665.12232,418.17579 L 665.12232,418.17579"
  66.348 +       id="path6270"
  66.349 +       inkscape:connector-type="polyline" />
  66.350 +  </g>
  66.351 +</svg>
    67.1 --- a/fr/filelog.svg	Sun Aug 16 03:41:39 2009 +0200
    67.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.3 @@ -1,373 +0,0 @@
    67.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    67.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    67.6 -<svg
    67.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    67.8 -   xmlns:cc="http://web.resource.org/cc/"
    67.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   67.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   67.11 -   xmlns="http://www.w3.org/2000/svg"
   67.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
   67.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   67.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   67.15 -   width="744.09448819"
   67.16 -   height="1052.3622047"
   67.17 -   id="svg2"
   67.18 -   sodipodi:version="0.32"
   67.19 -   inkscape:version="0.45.1"
   67.20 -   sodipodi:docname="filelog.svg"
   67.21 -   sodipodi:docbase="/home/arun/hgbook/en"
   67.22 -   inkscape:output_extension="org.inkscape.output.svg.inkscape">
   67.23 -  <defs
   67.24 -     id="defs4">
   67.25 -    <marker
   67.26 -       inkscape:stockid="Arrow1Mend"
   67.27 -       orient="auto"
   67.28 -       refY="0.0"
   67.29 -       refX="0.0"
   67.30 -       id="Arrow1Mend"
   67.31 -       style="overflow:visible;">
   67.32 -      <path
   67.33 -         id="path3128"
   67.34 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   67.35 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   67.36 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   67.37 -    </marker>
   67.38 -    <linearGradient
   67.39 -       id="linearGradient2887">
   67.40 -      <stop
   67.41 -         style="stop-color:#91cfcf;stop-opacity:1;"
   67.42 -         offset="0"
   67.43 -         id="stop2889" />
   67.44 -      <stop
   67.45 -         style="stop-color:aqua;stop-opacity:0;"
   67.46 -         offset="1"
   67.47 -         id="stop2891" />
   67.48 -    </linearGradient>
   67.49 -    <linearGradient
   67.50 -       id="linearGradient2795">
   67.51 -      <stop
   67.52 -         style="stop-color:#ccc;stop-opacity:1;"
   67.53 -         offset="0"
   67.54 -         id="stop2797" />
   67.55 -      <stop
   67.56 -         style="stop-color:#ccc;stop-opacity:0;"
   67.57 -         offset="1"
   67.58 -         id="stop2799" />
   67.59 -    </linearGradient>
   67.60 -    <linearGradient
   67.61 -       inkscape:collect="always"
   67.62 -       xlink:href="#linearGradient2795"
   67.63 -       id="linearGradient3170"
   67.64 -       gradientUnits="userSpaceOnUse"
   67.65 -       gradientTransform="translate(121.2183,94.95434)"
   67.66 -       x1="81.322357"
   67.67 -       y1="404.34424"
   67.68 -       x2="201.52036"
   67.69 -       y2="373.03967" />
   67.70 -    <linearGradient
   67.71 -       inkscape:collect="always"
   67.72 -       xlink:href="#linearGradient2887"
   67.73 -       id="linearGradient3172"
   67.74 -       gradientUnits="userSpaceOnUse"
   67.75 -       gradientTransform="translate(0,12)"
   67.76 -       x1="62.634491"
   67.77 -       y1="503.3392"
   67.78 -       x2="248.49242"
   67.79 -       y2="462.94327" />
   67.80 -    <linearGradient
   67.81 -       inkscape:collect="always"
   67.82 -       xlink:href="#linearGradient2795"
   67.83 -       id="linearGradient3174"
   67.84 -       gradientUnits="userSpaceOnUse"
   67.85 -       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
   67.86 -       x1="81.322357"
   67.87 -       y1="404.34424"
   67.88 -       x2="201.52036"
   67.89 -       y2="373.03967" />
   67.90 -    <linearGradient
   67.91 -       inkscape:collect="always"
   67.92 -       xlink:href="#linearGradient2887"
   67.93 -       id="linearGradient3176"
   67.94 -       gradientUnits="userSpaceOnUse"
   67.95 -       gradientTransform="translate(0,12)"
   67.96 -       x1="62.634491"
   67.97 -       y1="503.3392"
   67.98 -       x2="248.49242"
   67.99 -       y2="462.94327" />
  67.100 -    <linearGradient
  67.101 -       inkscape:collect="always"
  67.102 -       xlink:href="#linearGradient2795"
  67.103 -       id="linearGradient3208"
  67.104 -       gradientUnits="userSpaceOnUse"
  67.105 -       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
  67.106 -       x1="81.322357"
  67.107 -       y1="404.34424"
  67.108 -       x2="201.52036"
  67.109 -       y2="373.03967" />
  67.110 -    <linearGradient
  67.111 -       inkscape:collect="always"
  67.112 -       xlink:href="#linearGradient2887"
  67.113 -       id="linearGradient3210"
  67.114 -       gradientUnits="userSpaceOnUse"
  67.115 -       gradientTransform="translate(0,12)"
  67.116 -       x1="62.634491"
  67.117 -       y1="503.3392"
  67.118 -       x2="248.49242"
  67.119 -       y2="462.94327" />
  67.120 -    <linearGradient
  67.121 -       inkscape:collect="always"
  67.122 -       xlink:href="#linearGradient2795"
  67.123 -       id="linearGradient3212"
  67.124 -       gradientUnits="userSpaceOnUse"
  67.125 -       gradientTransform="translate(121.2183,94.95434)"
  67.126 -       x1="81.322357"
  67.127 -       y1="404.34424"
  67.128 -       x2="201.52036"
  67.129 -       y2="373.03967" />
  67.130 -    <linearGradient
  67.131 -       inkscape:collect="always"
  67.132 -       xlink:href="#linearGradient2887"
  67.133 -       id="linearGradient3214"
  67.134 -       gradientUnits="userSpaceOnUse"
  67.135 -       gradientTransform="translate(0,12)"
  67.136 -       x1="62.634491"
  67.137 -       y1="503.3392"
  67.138 -       x2="248.49242"
  67.139 -       y2="462.94327" />
  67.140 -    <linearGradient
  67.141 -       inkscape:collect="always"
  67.142 -       xlink:href="#linearGradient2795"
  67.143 -       id="linearGradient3256"
  67.144 -       gradientUnits="userSpaceOnUse"
  67.145 -       gradientTransform="matrix(1.2343775,0,0,0.9981848,103.25588,95.681888)"
  67.146 -       x1="74.301666"
  67.147 -       y1="431.67441"
  67.148 -       x2="260.05884"
  67.149 -       y2="369.95322" />
  67.150 -    <linearGradient
  67.151 -       inkscape:collect="always"
  67.152 -       xlink:href="#linearGradient2887"
  67.153 -       id="linearGradient3258"
  67.154 -       gradientUnits="userSpaceOnUse"
  67.155 -       gradientTransform="matrix(1.228929,0,0,0.9972824,-62.037003,13.312997)"
  67.156 -       x1="62.634491"
  67.157 -       y1="503.3392"
  67.158 -       x2="248.49242"
  67.159 -       y2="462.94327" />
  67.160 -    <linearGradient
  67.161 -       inkscape:collect="always"
  67.162 -       xlink:href="#linearGradient2795"
  67.163 -       id="linearGradient3260"
  67.164 -       gradientUnits="userSpaceOnUse"
  67.165 -       gradientTransform="matrix(1.2300738,0,0,0.6517275,219.97511,153.61527)"
  67.166 -       x1="74.387527"
  67.167 -       y1="431.80576"
  67.168 -       x2="259.97339"
  67.169 -       y2="369.82224" />
  67.170 -    <linearGradient
  67.171 -       inkscape:collect="always"
  67.172 -       xlink:href="#linearGradient2887"
  67.173 -       id="linearGradient3262"
  67.174 -       gradientUnits="userSpaceOnUse"
  67.175 -       gradientTransform="matrix(1.2289272,0,0,0.9972824,-62.036756,13.312985)"
  67.176 -       x1="62.634491"
  67.177 -       y1="503.3392"
  67.178 -       x2="248.49242"
  67.179 -       y2="462.94327" />
  67.180 -  </defs>
  67.181 -  <sodipodi:namedview
  67.182 -     id="base"
  67.183 -     pagecolor="#ffffff"
  67.184 -     bordercolor="#666666"
  67.185 -     borderopacity="1.0"
  67.186 -     gridtolerance="10000"
  67.187 -     guidetolerance="10"
  67.188 -     objecttolerance="10"
  67.189 -     inkscape:pageopacity="0.0"
  67.190 -     inkscape:pageshadow="2"
  67.191 -     inkscape:zoom="1.4"
  67.192 -     inkscape:cx="455.8122"
  67.193 -     inkscape:cy="520"
  67.194 -     inkscape:document-units="px"
  67.195 -     inkscape:current-layer="layer1"
  67.196 -     inkscape:window-width="1680"
  67.197 -     inkscape:window-height="970"
  67.198 -     inkscape:window-x="0"
  67.199 -     inkscape:window-y="54" />
  67.200 -  <metadata
  67.201 -     id="metadata7">
  67.202 -    <rdf:RDF>
  67.203 -      <cc:Work
  67.204 -         rdf:about="">
  67.205 -        <dc:format>image/svg+xml</dc:format>
  67.206 -        <dc:type
  67.207 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  67.208 -      </cc:Work>
  67.209 -    </rdf:RDF>
  67.210 -  </metadata>
  67.211 -  <g
  67.212 -     inkscape:label="Layer 1"
  67.213 -     inkscape:groupmode="layer"
  67.214 -     id="layer1">
  67.215 -    <rect
  67.216 -       style="opacity:1;fill:#abadf8;fill-opacity:1;stroke:#595959;stroke-width:0.93760371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  67.217 -       id="rect3180"
  67.218 -       width="273.81375"
  67.219 -       height="199.06245"
  67.220 -       x="369.1796"
  67.221 -       y="351.79019" />
  67.222 -    <rect
  67.223 -       style="opacity:1;fill:#a2f69c;fill-opacity:1;stroke:#595959;stroke-width:0.93760341;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  67.224 -       id="rect3178"
  67.225 -       width="273.81339"
  67.226 -       height="199.06233"
  67.227 -       x="72.699799"
  67.228 -       y="351.78983" />
  67.229 -    <g
  67.230 -       id="g3144"
  67.231 -       transform="translate(80.467048,0.71578)">
  67.232 -      <g
  67.233 -         id="g2940">
  67.234 -        <rect
  67.235 -           style="fill:url(#linearGradient3260);fill-opacity:1;stroke:#000000;stroke-width:0.89536202;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  67.236 -           id="rect2914"
  67.237 -           width="227.38896"
  67.238 -           height="39.500999"
  67.239 -           x="311.92496"
  67.240 -           y="395.08627" />
  67.241 -        <text
  67.242 -           xml:space="preserve"
  67.243 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.244 -           x="323.72824"
  67.245 -           y="416.7626"
  67.246 -           id="text2918"><tspan
  67.247 -             sodipodi:role="line"
  67.248 -             id="tspan2920"
  67.249 -             x="323.72824"
  67.250 -             y="416.7626"
  67.251 -             style="font-family:Courier">.hg/store/data/README.i</tspan></text>
  67.252 -      </g>
  67.253 -      <g
  67.254 -         transform="translate(3.79093e-5,-80.1853)"
  67.255 -         id="g2945">
  67.256 -        <g
  67.257 -           id="g2955">
  67.258 -          <rect
  67.259 -             y="475.4968"
  67.260 -             x="15.550935"
  67.261 -             height="39.500999"
  67.262 -             width="227.17694"
  67.263 -             id="rect2947"
  67.264 -             style="fill:url(#linearGradient3262);fill-opacity:1;stroke:#000000;stroke-width:1.10706258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  67.265 -          <text
  67.266 -             id="text2949"
  67.267 -             y="498.35123"
  67.268 -             x="31.230644"
  67.269 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.270 -             xml:space="preserve"><tspan
  67.271 -               style="font-family:Courier"
  67.272 -               y="498.35123"
  67.273 -               x="31.230644"
  67.274 -               id="tspan2951"
  67.275 -               sodipodi:role="line">README</tspan></text>
  67.276 -        </g>
  67.277 -      </g>
  67.278 -      <path
  67.279 -         inkscape:connector-type="polyline"
  67.280 -         id="path2960"
  67.281 -         d="M 242.94685,414.91115 C 242.94685,414.91115 293.61127,415.26754 310.16269,415.38633"
  67.282 -         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.02046943px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  67.283 -         sodipodi:nodetypes="cz" />
  67.284 -    </g>
  67.285 -    <g
  67.286 -       id="g3156"
  67.287 -       transform="translate(80.467048,0.71578)">
  67.288 -      <g
  67.289 -         transform="translate(116,0)"
  67.290 -         id="g2831">
  67.291 -        <rect
  67.292 -           style="fill:url(#linearGradient3256);fill-opacity:1;stroke:#000000;stroke-width:1.11001658;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  67.293 -           id="rect1906"
  67.294 -           width="228.18446"
  67.295 -           height="60.499123"
  67.296 -           x="195.52719"
  67.297 -           y="465.51859" />
  67.298 -        <g
  67.299 -           id="g2803"
  67.300 -           transform="translate(-0.893671,1.833581)">
  67.301 -          <text
  67.302 -             id="text1884"
  67.303 -             y="483.92801"
  67.304 -             x="208.95944"
  67.305 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.306 -             xml:space="preserve"><tspan
  67.307 -               style="font-family:Courier"
  67.308 -               y="483.92801"
  67.309 -               x="208.95944"
  67.310 -               id="tspan1886"
  67.311 -               sodipodi:role="line">.hg/store/data/src/hello.c.d</tspan></text>
  67.312 -          <text
  67.313 -             id="text1888"
  67.314 -             y="507.79309"
  67.315 -             x="208.95944"
  67.316 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.317 -             xml:space="preserve"><tspan
  67.318 -               style="font-family:Courier"
  67.319 -               y="507.79309"
  67.320 -               x="208.95944"
  67.321 -               id="tspan1890"
  67.322 -               sodipodi:role="line">.hg/store/data/src/hello.c.i</tspan></text>
  67.323 -        </g>
  67.324 -      </g>
  67.325 -      <g
  67.326 -         id="g2907">
  67.327 -        <rect
  67.328 -           style="fill:url(#linearGradient3258);fill-opacity:1;stroke:#000000;stroke-width:1.10706329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  67.329 -           id="rect2843"
  67.330 -           width="227.17728"
  67.331 -           height="39.500999"
  67.332 -           x="15.550805"
  67.333 -           y="475.4968" />
  67.334 -        <text
  67.335 -           xml:space="preserve"
  67.336 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.337 -           x="31.230644"
  67.338 -           y="498.35123"
  67.339 -           id="text2847"><tspan
  67.340 -             sodipodi:role="line"
  67.341 -             id="tspan2849"
  67.342 -             x="31.230644"
  67.343 -             y="498.35123"
  67.344 -             style="font-family:Courier">src/hello.c</tspan></text>
  67.345 -      </g>
  67.346 -      <path
  67.347 -         inkscape:connection-end="#g2831"
  67.348 -         inkscape:connection-start="#g2907"
  67.349 -         inkscape:connector-type="polyline"
  67.350 -         id="path2962"
  67.351 -         d="M 242.4315,495.88043 C 242.4315,495.88043 292.8861,495.99942 310.04102,496.03909"
  67.352 -         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  67.353 -         sodipodi:nodetypes="cs" />
  67.354 -    </g>
  67.355 -    <text
  67.356 -       xml:space="preserve"
  67.357 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.358 -       x="98.496666"
  67.359 -       y="373.96353"
  67.360 -       id="text3216"><tspan
  67.361 -         sodipodi:role="line"
  67.362 -         id="tspan3218"
  67.363 -         x="98.496666"
  67.364 -         y="373.96353">Working directory</tspan></text>
  67.365 -    <text
  67.366 -       xml:space="preserve"
  67.367 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  67.368 -       x="391.39197"
  67.369 -       y="373.96353"
  67.370 -       id="text3228"><tspan
  67.371 -         sodipodi:role="line"
  67.372 -         id="tspan3230"
  67.373 -         x="391.39197"
  67.374 -         y="373.96353">Repository</tspan></text>
  67.375 -  </g>
  67.376 -</svg>
    68.1 --- a/fr/filenames.tex	Sun Aug 16 03:41:39 2009 +0200
    68.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.3 @@ -1,306 +0,0 @@
    68.4 -\chapter{File names and pattern matching}
    68.5 -\label{chap:names}
    68.6 -
    68.7 -Mercurial provides mechanisms that let you work with file names in a
    68.8 -consistent and expressive way.
    68.9 -
   68.10 -\section{Simple file naming}
   68.11 -
   68.12 -Mercurial uses a unified piece of machinery ``under the hood'' to
   68.13 -handle file names.  Every command behaves uniformly with respect to
   68.14 -file names.  The way in which commands work with file names is as
   68.15 -follows.
   68.16 -
   68.17 -If you explicitly name real files on the command line, Mercurial works
   68.18 -with exactly those files, as you would expect.
   68.19 -\interaction{filenames.files}
   68.20 -
   68.21 -When you provide a directory name, Mercurial will interpret this as
   68.22 -``operate on every file in this directory and its subdirectories''.
   68.23 -Mercurial traverses the files and subdirectories in a directory in
   68.24 -alphabetical order.  When it encounters a subdirectory, it will
   68.25 -traverse that subdirectory before continuing with the current
   68.26 -directory.
   68.27 -\interaction{filenames.dirs}
   68.28 -
   68.29 -\section{Running commands without any file names}
   68.30 -
   68.31 -Mercurial's commands that work with file names have useful default
   68.32 -behaviours when you invoke them without providing any file names or
   68.33 -patterns.  What kind of behaviour you should expect depends on what
   68.34 -the command does.  Here are a few rules of thumb you can use to
   68.35 -predict what a command is likely to do if you don't give it any names
   68.36 -to work with.
   68.37 -\begin{itemize}
   68.38 -\item Most commands will operate on the entire working directory.
   68.39 -  This is what the \hgcmd{add} command does, for example.
   68.40 -\item If the command has effects that are difficult or impossible to
   68.41 -  reverse, it will force you to explicitly provide at least one name
   68.42 -  or pattern (see below).  This protects you from accidentally
   68.43 -  deleting files by running \hgcmd{remove} with no arguments, for
   68.44 -  example.
   68.45 -\end{itemize}
   68.46 -
   68.47 -It's easy to work around these default behaviours if they don't suit
   68.48 -you.  If a command normally operates on the whole working directory,
   68.49 -you can invoke it on just the current directory and its subdirectories
   68.50 -by giving it the name ``\dirname{.}''.
   68.51 -\interaction{filenames.wdir-subdir}
   68.52 -
   68.53 -Along the same lines, some commands normally print file names relative
   68.54 -to the root of the repository, even if you're invoking them from a
   68.55 -subdirectory.  Such a command will print file names relative to your
   68.56 -subdirectory if you give it explicit names.  Here, we're going to run
   68.57 -\hgcmd{status} from a subdirectory, and get it to operate on the
   68.58 -entire working directory while printing file names relative to our
   68.59 -subdirectory, by passing it the output of the \hgcmd{root} command.
   68.60 -\interaction{filenames.wdir-relname}
   68.61 -
   68.62 -\section{Telling you what's going on}
   68.63 -
   68.64 -The \hgcmd{add} example in the preceding section illustrates something
   68.65 -else that's helpful about Mercurial commands.  If a command operates
   68.66 -on a file that you didn't name explicitly on the command line, it will
   68.67 -usually print the name of the file, so that you will not be surprised
   68.68 -what's going on.
   68.69 -
   68.70 -The principle here is of \emph{least surprise}.  If you've exactly
   68.71 -named a file on the command line, there's no point in repeating it
   68.72 -back at you.  If Mercurial is acting on a file \emph{implicitly},
   68.73 -because you provided no names, or a directory, or a pattern (see
   68.74 -below), it's safest to tell you what it's doing.
   68.75 -
   68.76 -For commands that behave this way, you can silence them using the
   68.77 -\hggopt{-q} option.  You can also get them to print the name of every
   68.78 -file, even those you've named explicitly, using the \hggopt{-v}
   68.79 -option.
   68.80 -
   68.81 -\section{Using patterns to identify files}
   68.82 -
   68.83 -In addition to working with file and directory names, Mercurial lets
   68.84 -you use \emph{patterns} to identify files.  Mercurial's pattern
   68.85 -handling is expressive.
   68.86 -
   68.87 -On Unix-like systems (Linux, MacOS, etc.), the job of matching file
   68.88 -names to patterns normally falls to the shell.  On these systems, you
   68.89 -must explicitly tell Mercurial that a name is a pattern.  On Windows,
   68.90 -the shell does not expand patterns, so Mercurial will automatically
   68.91 -identify names that are patterns, and expand them for you.
   68.92 -
   68.93 -To provide a pattern in place of a regular name on the command line,
   68.94 -the mechanism is simple:
   68.95 -\begin{codesample2}
   68.96 -  syntax:patternbody
   68.97 -\end{codesample2}
   68.98 -That is, a pattern is identified by a short text string that says what
   68.99 -kind of pattern this is, followed by a colon, followed by the actual
  68.100 -pattern.
  68.101 -
  68.102 -Mercurial supports two kinds of pattern syntax.  The most frequently
  68.103 -used is called \texttt{glob}; this is the same kind of pattern
  68.104 -matching used by the Unix shell, and should be familiar to Windows
  68.105 -command prompt users, too.  
  68.106 -
  68.107 -When Mercurial does automatic pattern matching on Windows, it uses
  68.108 -\texttt{glob} syntax.  You can thus omit the ``\texttt{glob:}'' prefix
  68.109 -on Windows, but it's safe to use it, too.
  68.110 -
  68.111 -The \texttt{re} syntax is more powerful; it lets you specify patterns
  68.112 -using regular expressions, also known as regexps.
  68.113 -
  68.114 -By the way, in the examples that follow, notice that I'm careful to
  68.115 -wrap all of my patterns in quote characters, so that they won't get
  68.116 -expanded by the shell before Mercurial sees them.
  68.117 -
  68.118 -\subsection{Shell-style \texttt{glob} patterns}
  68.119 -
  68.120 -This is an overview of the kinds of patterns you can use when you're
  68.121 -matching on glob patterns.
  68.122 -
  68.123 -The ``\texttt{*}'' character matches any string, within a single
  68.124 -directory.
  68.125 -\interaction{filenames.glob.star}
  68.126 -
  68.127 -The ``\texttt{**}'' pattern matches any string, and crosses directory
  68.128 -boundaries.  It's not a standard Unix glob token, but it's accepted by
  68.129 -several popular Unix shells, and is very useful.
  68.130 -\interaction{filenames.glob.starstar}
  68.131 -
  68.132 -The ``\texttt{?}'' pattern matches any single character.
  68.133 -\interaction{filenames.glob.question}
  68.134 -
  68.135 -The ``\texttt{[}'' character begins a \emph{character class}.  This
  68.136 -matches any single character within the class.  The class ends with a
  68.137 -``\texttt{]}'' character.  A class may contain multiple \emph{range}s
  68.138 -of the form ``\texttt{a-f}'', which is shorthand for
  68.139 -``\texttt{abcdef}''.
  68.140 -\interaction{filenames.glob.range}
  68.141 -If the first character after the ``\texttt{[}'' in a character class
  68.142 -is a ``\texttt{!}'', it \emph{negates} the class, making it match any
  68.143 -single character not in the class.
  68.144 -
  68.145 -A ``\texttt{\{}'' begins a group of subpatterns, where the whole group
  68.146 -matches if any subpattern in the group matches.  The ``\texttt{,}''
  68.147 -character separates subpatterns, and ``\texttt{\}}'' ends the group.
  68.148 -\interaction{filenames.glob.group}
  68.149 -
  68.150 -\subsubsection{Watch out!}
  68.151 -
  68.152 -Don't forget that if you want to match a pattern in any directory, you
  68.153 -should not be using the ``\texttt{*}'' match-any token, as this will
  68.154 -only match within one directory.  Instead, use the ``\texttt{**}''
  68.155 -token.  This small example illustrates the difference between the two.
  68.156 -\interaction{filenames.glob.star-starstar}
  68.157 -
  68.158 -\subsection{Regular expression matching with \texttt{re} patterns}
  68.159 -
  68.160 -Mercurial accepts the same regular expression syntax as the Python
  68.161 -programming language (it uses Python's regexp engine internally).
  68.162 -This is based on the Perl language's regexp syntax, which is the most
  68.163 -popular dialect in use (it's also used in Java, for example).
  68.164 -
  68.165 -I won't discuss Mercurial's regexp dialect in any detail here, as
  68.166 -regexps are not often used.  Perl-style regexps are in any case
  68.167 -already exhaustively documented on a multitude of web sites, and in
  68.168 -many books.  Instead, I will focus here on a few things you should
  68.169 -know if you find yourself needing to use regexps with Mercurial.
  68.170 -
  68.171 -A regexp is matched against an entire file name, relative to the root
  68.172 -of the repository.  In other words, even if you're already in
  68.173 -subbdirectory \dirname{foo}, if you want to match files under this
  68.174 -directory, your pattern must start with ``\texttt{foo/}''.
  68.175 -
  68.176 -One thing to note, if you're familiar with Perl-style regexps, is that
  68.177 -Mercurial's are \emph{rooted}.  That is, a regexp starts matching
  68.178 -against the beginning of a string; it doesn't look for a match
  68.179 -anywhere within the string.  To match anywhere in a string, start
  68.180 -your pattern with ``\texttt{.*}''.
  68.181 -
  68.182 -\section{Filtering files}
  68.183 -
  68.184 -Not only does Mercurial give you a variety of ways to specify files;
  68.185 -it lets you further winnow those files using \emph{filters}.  Commands
  68.186 -that work with file names accept two filtering options.
  68.187 -\begin{itemize}
  68.188 -\item \hggopt{-I}, or \hggopt{--include}, lets you specify a pattern
  68.189 -  that file names must match in order to be processed.
  68.190 -\item \hggopt{-X}, or \hggopt{--exclude}, gives you a way to
  68.191 -  \emph{avoid} processing files, if they match this pattern.
  68.192 -\end{itemize}
  68.193 -You can provide multiple \hggopt{-I} and \hggopt{-X} options on the
  68.194 -command line, and intermix them as you please.  Mercurial interprets
  68.195 -the patterns you provide using glob syntax by default (but you can use
  68.196 -regexps if you need to).
  68.197 -
  68.198 -You can read a \hggopt{-I} filter as ``process only the files that
  68.199 -match this filter''.
  68.200 -\interaction{filenames.filter.include}
  68.201 -The \hggopt{-X} filter is best read as ``process only the files that
  68.202 -don't match this pattern''.
  68.203 -\interaction{filenames.filter.exclude}
  68.204 -
  68.205 -\section{Ignoring unwanted files and directories}
  68.206 -
  68.207 -XXX.
  68.208 -
  68.209 -\section{Case sensitivity}
  68.210 -\label{sec:names:case}
  68.211 -
  68.212 -If you're working in a mixed development environment that contains
  68.213 -both Linux (or other Unix) systems and Macs or Windows systems, you
  68.214 -should keep in the back of your mind the knowledge that they treat the
  68.215 -case (``N'' versus ``n'') of file names in incompatible ways.  This is
  68.216 -not very likely to affect you, and it's easy to deal with if it does,
  68.217 -but it could surprise you if you don't know about it.
  68.218 -
  68.219 -Operating systems and filesystems differ in the way they handle the
  68.220 -\emph{case} of characters in file and directory names.  There are
  68.221 -three common ways to handle case in names.
  68.222 -\begin{itemize}
  68.223 -\item Completely case insensitive.  Uppercase and lowercase versions
  68.224 -  of a letter are treated as identical, both when creating a file and
  68.225 -  during subsequent accesses.  This is common on older DOS-based
  68.226 -  systems.
  68.227 -\item Case preserving, but insensitive.  When a file or directory is
  68.228 -  created, the case of its name is stored, and can be retrieved and
  68.229 -  displayed by the operating system.  When an existing file is being
  68.230 -  looked up, its case is ignored.  This is the standard arrangement on
  68.231 -  Windows and MacOS.  The names \filename{foo} and \filename{FoO}
  68.232 -  identify the same file.  This treatment of uppercase and lowercase
  68.233 -  letters as interchangeable is also referred to as \emph{case
  68.234 -    folding}.
  68.235 -\item Case sensitive.  The case of a name is significant at all times.
  68.236 -  The names \filename{foo} and {FoO} identify different files.  This
  68.237 -  is the way Linux and Unix systems normally work.
  68.238 -\end{itemize}
  68.239 -
  68.240 -On Unix-like systems, it is possible to have any or all of the above
  68.241 -ways of handling case in action at once.  For example, if you use a
  68.242 -USB thumb drive formatted with a FAT32 filesystem on a Linux system,
  68.243 -Linux will handle names on that filesystem in a case preserving, but
  68.244 -insensitive, way.
  68.245 -
  68.246 -\subsection{Safe, portable repository storage}
  68.247 -
  68.248 -Mercurial's repository storage mechanism is \emph{case safe}.  It
  68.249 -translates file names so that they can be safely stored on both case
  68.250 -sensitive and case insensitive filesystems.  This means that you can
  68.251 -use normal file copying tools to transfer a Mercurial repository onto,
  68.252 -for example, a USB thumb drive, and safely move that drive and
  68.253 -repository back and forth between a Mac, a PC running Windows, and a
  68.254 -Linux box.
  68.255 -
  68.256 -\subsection{Detecting case conflicts}
  68.257 -
  68.258 -When operating in the working directory, Mercurial honours the naming
  68.259 -policy of the filesystem where the working directory is located.  If
  68.260 -the filesystem is case preserving, but insensitive, Mercurial will
  68.261 -treat names that differ only in case as the same.
  68.262 -
  68.263 -An important aspect of this approach is that it is possible to commit
  68.264 -a changeset on a case sensitive (typically Linux or Unix) filesystem
  68.265 -that will cause trouble for users on case insensitive (usually Windows
  68.266 -and MacOS) users.  If a Linux user commits changes to two files, one
  68.267 -named \filename{myfile.c} and the other named \filename{MyFile.C},
  68.268 -they will be stored correctly in the repository.  And in the working
  68.269 -directories of other Linux users, they will be correctly represented
  68.270 -as separate files.
  68.271 -
  68.272 -If a Windows or Mac user pulls this change, they will not initially
  68.273 -have a problem, because Mercurial's repository storage mechanism is
  68.274 -case safe.  However, once they try to \hgcmd{update} the working
  68.275 -directory to that changeset, or \hgcmd{merge} with that changeset,
  68.276 -Mercurial will spot the conflict between the two file names that the
  68.277 -filesystem would treat as the same, and forbid the update or merge
  68.278 -from occurring.
  68.279 -
  68.280 -\subsection{Fixing a case conflict}
  68.281 -
  68.282 -If you are using Windows or a Mac in a mixed environment where some of
  68.283 -your collaborators are using Linux or Unix, and Mercurial reports a
  68.284 -case folding conflict when you try to \hgcmd{update} or \hgcmd{merge},
  68.285 -the procedure to fix the problem is simple.
  68.286 -
  68.287 -Just find a nearby Linux or Unix box, clone the problem repository
  68.288 -onto it, and use Mercurial's \hgcmd{rename} command to change the
  68.289 -names of any offending files or directories so that they will no
  68.290 -longer cause case folding conflicts.  Commit this change, \hgcmd{pull}
  68.291 -or \hgcmd{push} it across to your Windows or MacOS system, and
  68.292 -\hgcmd{update} to the revision with the non-conflicting names.
  68.293 -
  68.294 -The changeset with case-conflicting names will remain in your
  68.295 -project's history, and you still won't be able to \hgcmd{update} your
  68.296 -working directory to that changeset on a Windows or MacOS system, but
  68.297 -you can continue development unimpeded.
  68.298 -
  68.299 -\begin{note}
  68.300 -  Prior to version~0.9.3, Mercurial did not use a case safe repository
  68.301 -  storage mechanism, and did not detect case folding conflicts.  If
  68.302 -  you are using an older version of Mercurial on Windows or MacOS, I
  68.303 -  strongly recommend that you upgrade.
  68.304 -\end{note}
  68.305 -
  68.306 -%%% Local Variables: 
  68.307 -%%% mode: latex
  68.308 -%%% TeX-master: "00book"
  68.309 -%%% End: 
    69.1 --- a/fr/fixhtml.py	Sun Aug 16 03:41:39 2009 +0200
    69.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.3 @@ -1,50 +0,0 @@
    69.4 -#!/usr/bin/env python
    69.5 -#
    69.6 -# This script attempts to work around some of the more bizarre and
    69.7 -# quirky behaviours of htlatex.
    69.8 -#
    69.9 -# - We've persuaded htlatex to produce UTF-8, which unfortunately
   69.10 -#   causes it to use huge character sequences to represent even the
   69.11 -#   safe 7-bit ASCII subset of UTF-8.  We fix that up.
   69.12 -#
   69.13 -# - BUT we have to treat angle brackets (for example, redirections in
   69.14 -#   shell script snippets) specially, otherwise they'll break the
   69.15 -#   generated HTML.  (Reported by Johannes Hoff.)
   69.16 -#
   69.17 -# - For some reason, htlatex gives a unique ID to each fancyvrb
   69.18 -#   environment, which makes writing a sane, small CSS stylesheet
   69.19 -#   impossible.  We squish all those IDs down to nothing.
   69.20 -
   69.21 -import os
   69.22 -import sys
   69.23 -import re
   69.24 -
   69.25 -angle_re = re.compile(r'(&#x003[CE];)')
   69.26 -unicode_re = re.compile(r'&#x00([0-7][0-9A-F]);')
   69.27 -fancyvrb_re = re.compile(r'id="fancyvrb\d+"', re.I)
   69.28 -ligature_re = re.compile(r'&#xFB0([0-4]);')
   69.29 -
   69.30 -tmpsuffix = '.tmp.' + str(os.getpid())
   69.31 -
   69.32 -def hide_angle(m):
   69.33 -    return m.group(1).lower()
   69.34 -
   69.35 -def fix_ascii(m):
   69.36 -    return chr(int(m.group(1), 16))
   69.37 -
   69.38 -ligatures = ['ff', 'fi', 'fl', 'ffi', 'ffl']
   69.39 -
   69.40 -def expand_ligature(m):
   69.41 -    return ligatures[int(m.group(1))]
   69.42 -
   69.43 -for name in sys.argv[1:]:
   69.44 -    tmpname = name + tmpsuffix
   69.45 -    ofp = file(tmpname, 'w')
   69.46 -    for line in file(name):
   69.47 -        line = angle_re.sub(hide_angle, line)
   69.48 -        line = unicode_re.sub(fix_ascii, line)
   69.49 -        line = ligature_re.sub(expand_ligature, line)
   69.50 -        line = fancyvrb_re.sub('id="fancyvrb"', line)
   69.51 -        ofp.write(line)
   69.52 -    ofp.close()
   69.53 -    os.rename(tmpname, name)
    70.1 --- a/fr/hgbook.css	Sun Aug 16 03:41:39 2009 +0200
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,441 +0,0 @@
    70.4 -body {
    70.5 -  font: 12px/1.5 Verdana, sans-serif;
    70.6 -  padding-top: 50px;
    70.7 -  padding-left: 80px;
    70.8 -  padding-right: 80px;
    70.9 -  padding-bottom: 90px;
   70.10 -}
   70.11 -.ptmr7t- {
   70.12 -  font-family: monospace;
   70.13 -}
   70.14 -.ptmr7t-x-x-172 {
   70.15 -  font-size: 172%;
   70.16 -  font-family: monospace;
   70.17 -}
   70.18 -.ptmr7t-x-x-120 {
   70.19 -  font-size: 120%;
   70.20 -}
   70.21 -.zpzccmry-x-x-120 {
   70.22 -  font-size: 120%;
   70.23 -  font-weight: bold;
   70.24 -  font-style: italic;
   70.25 -}
   70.26 -.zpzccmry-x-x-120 {
   70.27 -  font-weight: bold;
   70.28 -  font-style: italic;
   70.29 -}
   70.30 -.pcrr7tn- {
   70.31 -  font-family: monospace;
   70.32 -}
   70.33 -.ptmri7t- {
   70.34 -  font-style: italic;
   70.35 -}
   70.36 -.ptmr7t-x-x-50 {
   70.37 -  font-size: 50%;
   70.38 -  font-family: monospace;
   70.39 -}
   70.40 -.ptmb7t- {
   70.41 -  font-weight: bold;
   70.42 -}
   70.43 -.zptmcmr- {
   70.44 -  font-style: italic;
   70.45 -}
   70.46 -.zptmcmrm- {
   70.47 -  font-style: italic;
   70.48 -}
   70.49 -.zpzccmry- {
   70.50 -  font-weight: bold;
   70.51 -  font-style: italic;
   70.52 -}
   70.53 -.pcrb7t- {
   70.54 -  font-family: monospace;
   70.55 -  font-weight: bold;
   70.56 -}
   70.57 -.pcrro7t- {
   70.58 -  font-family: monospace;
   70.59 -  font-style: oblique;
   70.60 -}
   70.61 -p.noindent {
   70.62 -  text-indent: 0em;
   70.63 -  margin: 0em;
   70.64 -}
   70.65 -p.nopar {
   70.66 -  text-indent: 0em;
   70.67 -}
   70.68 -p.indent {
   70.69 -  text-indent: 1.5em;
   70.70 -  margin: 0em;
   70.71 -}
   70.72 -a img {
   70.73 -  border-top: 0;
   70.74 -  border-left: 0;
   70.75 -  border-right: 0;
   70.76 -}
   70.77 -center {
   70.78 -  margin-top: 1em;
   70.79 -  margin-bottom: 1em;
   70.80 -}
   70.81 -td center {
   70.82 -  margin-top: 0em;
   70.83 -  margin-bottom: 0em;
   70.84 -}
   70.85 -.Canvas {
   70.86 -  position: relative;
   70.87 -}
   70.88 -img.math {
   70.89 -  vertical-align: middle;
   70.90 -}
   70.91 -li p.indent {
   70.92 -  text-indent: 0em;
   70.93 -}
   70.94 -.enumerate1 {
   70.95 -  list-style-type: decimal;
   70.96 -}
   70.97 -.enumerate2 {
   70.98 -  list-style-type: lower-alpha;
   70.99 -}
  70.100 -.enumerate3 {
  70.101 -  list-style-type: lower-roman;
  70.102 -}
  70.103 -.enumerate4 {
  70.104 -  list-style-type: upper-alpha;
  70.105 -}
  70.106 -div.newtheorem {
  70.107 -  margin-bottom: 2em;
  70.108 -  margin-top: 2em;
  70.109 -}
  70.110 -.obeylines-h,.obeylines-v {
  70.111 -  white-space: nowrap;
  70.112 -}
  70.113 -div.obeylines-v p {
  70.114 -  margin-top: 0;
  70.115 -  margin-bottom: 0;
  70.116 -}
  70.117 -.overline {
  70.118 -  text-decoration: overline;
  70.119 -}
  70.120 -.overline img {
  70.121 -  border-top: 1px solid black;
  70.122 -}
  70.123 -td.displaylines {
  70.124 -  text-align: center;
  70.125 -  white-space: nowrap;
  70.126 -}
  70.127 -.centerline {
  70.128 -  text-align: center;
  70.129 -}
  70.130 -.rightline {
  70.131 -  text-align: right;
  70.132 -}
  70.133 -div.verbatim {
  70.134 -  font-family: monospace;
  70.135 -  white-space: nowrap;
  70.136 -}
  70.137 -table.verbatim {
  70.138 -  width: 100%;
  70.139 -}
  70.140 -.fbox {
  70.141 -  background: url(note.png) no-repeat #cec;
  70.142 -  padding-left: 65px;
  70.143 -  padding-top: 1em;
  70.144 -  padding-bottom: 1em;
  70.145 -  padding-right: 1em;
  70.146 -  text-indent: 0pt;
  70.147 -  border: dotted black 1px;
  70.148 -}
  70.149 -div.center div.fbox {
  70.150 -  text-align: center;
  70.151 -  clear: both;
  70.152 -  padding-left: 3.0pt;
  70.153 -  padding-right: 3.0pt;
  70.154 -  text-indent: 0pt;
  70.155 -  border: solid black 0.4pt;
  70.156 -}
  70.157 -table.minipage {
  70.158 -  width: 100%;
  70.159 -}
  70.160 -div.center, div.center div.center {
  70.161 -  text-align: center;
  70.162 -  margin-left: 1em;
  70.163 -  margin-right: 1em;
  70.164 -}
  70.165 -div.center div {
  70.166 -  text-align: left;
  70.167 -}
  70.168 -div.flushright, div.flushright div.flushright {
  70.169 -  text-align: right;
  70.170 -}
  70.171 -div.flushright div {
  70.172 -  text-align: left;
  70.173 -}
  70.174 -div.flushleft {
  70.175 -  text-align: left;
  70.176 -}
  70.177 -.underline {
  70.178 -  text-decoration: underline;
  70.179 -}
  70.180 -.underline img {
  70.181 -  border-bottom: 1px solid black;
  70.182 -  margin-bottom: 1pt;
  70.183 -}
  70.184 -.framebox-c, .framebox-l, .framebox-r {
  70.185 -  padding-left: 3.0pt;
  70.186 -  padding-right: 3.0pt;
  70.187 -  text-indent: 0pt;
  70.188 -  border: solid black 0.4pt;
  70.189 -}
  70.190 -.framebox-c {
  70.191 -  text-align: center;
  70.192 -}
  70.193 -.framebox-l {
  70.194 -  text-align: left;
  70.195 -}
  70.196 -.framebox-r {
  70.197 -  text-align: right;
  70.198 -}
  70.199 -span.thank-mark {
  70.200 -  vertical-align: super
  70.201 -}
  70.202 -span.footnote-mark sup.textsuperscript, span.footnote-mark a sup.textsuperscript {
  70.203 -  font-size: 80%;
  70.204 -}
  70.205 -div.tabular, div.center div.tabular {
  70.206 -  text-align: center;
  70.207 -  margin-top: 0.5em;
  70.208 -  margin-bottom: 0.5em;
  70.209 -}
  70.210 -table.tabular td p {
  70.211 -  margin-top: 0em;
  70.212 -}
  70.213 -table.tabular {
  70.214 -  margin-left: auto;
  70.215 -  margin-right: auto;
  70.216 -}
  70.217 -div.td00 {
  70.218 -  margin-left: 0pt;
  70.219 -  margin-right: 0pt;
  70.220 -}
  70.221 -div.td01 {
  70.222 -  margin-left: 0pt;
  70.223 -  margin-right: 5pt;
  70.224 -}
  70.225 -div.td10 {
  70.226 -  margin-left: 5pt;
  70.227 -  margin-right: 0pt;
  70.228 -}
  70.229 -div.td11 {
  70.230 -  margin-left: 5pt;
  70.231 -  margin-right: 5pt;
  70.232 -}
  70.233 -table[rules] {
  70.234 -  border-left: solid black 0.4pt;
  70.235 -  border-right: solid black 0.4pt;
  70.236 -}
  70.237 -td.td00 {
  70.238 -  padding-left: 0pt;
  70.239 -  padding-right: 0pt;
  70.240 -}
  70.241 -td.td01 {
  70.242 -  padding-left: 0pt;
  70.243 -  padding-right: 5pt;
  70.244 -}
  70.245 -td.td10 {
  70.246 -  padding-left: 5pt;
  70.247 -  padding-right: 0pt;
  70.248 -}
  70.249 -td.td11 {
  70.250 -  padding-left: 5pt;
  70.251 -  padding-right: 5pt;
  70.252 -}
  70.253 -table[rules] {
  70.254 -  border-left: solid black 0.4pt;
  70.255 -  border-right: solid black 0.4pt;
  70.256 -}
  70.257 -.hline hr, .cline hr {
  70.258 -  height : 1px;
  70.259 -  margin: 0px;
  70.260 -}
  70.261 -.tabbing-right {
  70.262 -  text-align: right;
  70.263 -}
  70.264 -span.TEX {
  70.265 -  letter-spacing: -0.125em;
  70.266 -}
  70.267 -span.TEX span.E {
  70.268 -  position: relative;top: 0.5ex;left: -0.0417em;
  70.269 -}
  70.270 -a span.TEX span.E {
  70.271 -  text-decoration: none;
  70.272 -}
  70.273 -span.LATEX span.A {
  70.274 -  position: relative;
  70.275 -  top: -0.5ex;
  70.276 -  left: -0.4em;
  70.277 -  font-size: 85%;
  70.278 -}
  70.279 -span.LATEX span.TEX {
  70.280 -  position: relative;
  70.281 -  left: -0.4em;
  70.282 -}
  70.283 -div.float img, div.float .caption {
  70.284 -  text-align: center;
  70.285 -}
  70.286 -div.figure img, div.figure .caption {
  70.287 -  text-align: center;
  70.288 -}
  70.289 -.marginpar {
  70.290 -  width: 20%;
  70.291 -  float: right;
  70.292 -  text-align: left;
  70.293 -  margin-left: auto;
  70.294 -  margin-top: 0.5em;
  70.295 -  font-size: 85%;
  70.296 -  text-decoration: underline;
  70.297 -}
  70.298 -.marginpar p {
  70.299 -  margin-top: 0.4em;
  70.300 -  margin-bottom: 0.4em;
  70.301 -}
  70.302 -table.equation {
  70.303 -  width: 100%;
  70.304 -}
  70.305 -.equation td {
  70.306 -  text-align: center;
  70.307 -}
  70.308 -td.equation {
  70.309 -  margin-top: 1em;
  70.310 -  margin-bottom: 1em;
  70.311 -} 
  70.312 -td.equation-label {
  70.313 -  width: 5%;
  70.314 -  text-align: center;
  70.315 -}
  70.316 -td.eqnarray4 {
  70.317 -  width: 5%;
  70.318 -  white-space: normal;
  70.319 -}
  70.320 -td.eqnarray2 {
  70.321 -  width: 5%;
  70.322 -}
  70.323 -table.eqnarray-star, table.eqnarray {
  70.324 -  width: 100%;
  70.325 -}
  70.326 -div.eqnarray {
  70.327 -  text-align: center;
  70.328 -}
  70.329 -div.array {
  70.330 -  text-align: center;
  70.331 -}
  70.332 -div.pmatrix {
  70.333 -  text-align: center;
  70.334 -}
  70.335 -table.pmatrix {
  70.336 -  width: 100%;
  70.337 -}
  70.338 -span.pmatrix img {
  70.339 -  vertical-align: middle;
  70.340 -}
  70.341 -div.pmatrix {
  70.342 -  text-align: center;
  70.343 -}
  70.344 -table.pmatrix {
  70.345 -  width: 100%;
  70.346 -}
  70.347 -img.cdots {
  70.348 -  vertical-align: middle;
  70.349 -}
  70.350 -.partToc a, .partToc, .likepartToc a, .likepartToc {
  70.351 -  line-height: 200%;
  70.352 -  font-weight: bold;
  70.353 -  font-size: 110%;
  70.354 -}
  70.355 -.chapterToc a, .chapterToc, .likechapterToc a, .likechapterToc, .appendixToc a, .appendixToc {
  70.356 -  line-height: 200%;
  70.357 -  font-weight: bold;
  70.358 -}
  70.359 -.caption td.id {
  70.360 -  font-weight: bold;
  70.361 -  white-space: nowrap;
  70.362 -}
  70.363 -table.caption {
  70.364 -  text-align: center;
  70.365 -}
  70.366 -h1.partHead {
  70.367 -  text-align: center;
  70.368 -}
  70.369 -p.bibitem {
  70.370 -  text-indent: -2em;
  70.371 -  margin-left: 2em;
  70.372 -  margin-top: 0.6em;
  70.373 -  margin-bottom: 0.6em;
  70.374 -}
  70.375 -p.bibitem-p {
  70.376 -  text-indent: 0em;
  70.377 -  margin-left: 2em;
  70.378 -  margin-top: 0.6em;
  70.379 -  margin-bottom: 0.6em;
  70.380 -}
  70.381 -.paragraphHead, .likeparagraphHead {
  70.382 -  margin-top: 2em;
  70.383 -  font-weight: bold;
  70.384 -}
  70.385 -.subparagraphHead, .likesubparagraphHead {
  70.386 -  font-weight: bold;
  70.387 -}
  70.388 -.quote {
  70.389 -  margin-bottom: 0.25em;
  70.390 -  margin-top: 0.25em;
  70.391 -  margin-left: 1em;
  70.392 -  margin-right: 1em;
  70.393 -  text-align: justify;
  70.394 -}
  70.395 -.verse {
  70.396 -  white-space: nowrap;
  70.397 -  margin-left: 2em}
  70.398 -div.maketitle {
  70.399 -  text-align: center;
  70.400 -}
  70.401 -h2.titleHead {
  70.402 -  text-align: center;
  70.403 -}
  70.404 -div.maketitle {
  70.405 -  margin-bottom: 2em;
  70.406 -}
  70.407 -div.author, div.date {
  70.408 -  text-align: center;
  70.409 -}
  70.410 -div.thanks {
  70.411 -  text-align: left;
  70.412 -  margin-left: 10%;
  70.413 -  font-size: 85%;
  70.414 -  font-style: italic;
  70.415 -}
  70.416 -div.author {
  70.417 -  white-space: nowrap;
  70.418 -}
  70.419 -.quotation {
  70.420 -  margin-bottom: 0.25em;
  70.421 -  margin-top: 0.25em;
  70.422 -  margin-left: 1em;
  70.423 -}
  70.424 -h1.partHead {
  70.425 -  text-align: center;
  70.426 -}
  70.427 -img.graphics {
  70.428 -  margin-left: 10%;
  70.429 -}
  70.430 -.figure {
  70.431 -  width: 100%;
  70.432 -}
  70.433 -P.fancyvrb {
  70.434 -  white-space: nowrap;
  70.435 -}
  70.436 -hr {
  70.437 -  border: 0;
  70.438 -  height: 1px;
  70.439 -}
  70.440 -div#fancyvrb {
  70.441 -  white-space: nowrap;
  70.442 -  background: #eee;
  70.443 -  padding: 1em;
  70.444 -}
    71.1 --- a/fr/hgext.tex	Sun Aug 16 03:41:39 2009 +0200
    71.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.3 @@ -1,429 +0,0 @@
    71.4 -\chapter{Adding functionality with extensions}
    71.5 -\label{chap:hgext}
    71.6 -
    71.7 -While the core of Mercurial is quite complete from a functionality
    71.8 -standpoint, it's deliberately shorn of fancy features.  This approach
    71.9 -of preserving simplicity keeps the software easy to deal with for both
   71.10 -maintainers and users.
   71.11 -
   71.12 -However, Mercurial doesn't box you in with an inflexible command set:
   71.13 -you can add features to it as \emph{extensions} (sometimes known as
   71.14 -\emph{plugins}).  We've already discussed a few of these extensions in
   71.15 -earlier chapters.
   71.16 -\begin{itemize}
   71.17 -\item Section~\ref{sec:tour-merge:fetch} covers the \hgext{fetch}
   71.18 -  extension; this combines pulling new changes and merging them with
   71.19 -  local changes into a single command, \hgxcmd{fetch}{fetch}.
   71.20 -\item In chapter~\ref{chap:hook}, we covered several extensions that
   71.21 -  are useful for hook-related functionality: \hgext{acl} adds access
   71.22 -  control lists; \hgext{bugzilla} adds integration with the Bugzilla
   71.23 -  bug tracking system; and \hgext{notify} sends notification emails on
   71.24 -  new changes.
   71.25 -\item The Mercurial Queues patch management extension is so invaluable
   71.26 -  that it merits two chapters and an appendix all to itself.
   71.27 -  Chapter~\ref{chap:mq} covers the basics;
   71.28 -  chapter~\ref{chap:mq-collab} discusses advanced topics; and
   71.29 -  appendix~\ref{chap:mqref} goes into detail on each command.
   71.30 -\end{itemize}
   71.31 -
   71.32 -In this chapter, we'll cover some of the other extensions that are
   71.33 -available for Mercurial, and briefly touch on some of the machinery
   71.34 -you'll need to know about if you want to write an extension of your
   71.35 -own.
   71.36 -\begin{itemize}
   71.37 -\item In section~\ref{sec:hgext:inotify}, we'll discuss the
   71.38 -  possibility of \emph{huge} performance improvements using the
   71.39 -  \hgext{inotify} extension.
   71.40 -\end{itemize}
   71.41 -
   71.42 -\section{Improve performance with the \hgext{inotify} extension}
   71.43 -\label{sec:hgext:inotify}
   71.44 -
   71.45 -Are you interested in having some of the most common Mercurial
   71.46 -operations run as much as a hundred times faster?  Read on!
   71.47 -
   71.48 -Mercurial has great performance under normal circumstances.  For
   71.49 -example, when you run the \hgcmd{status} command, Mercurial has to
   71.50 -scan almost every directory and file in your repository so that it can
   71.51 -display file status.  Many other Mercurial commands need to do the
   71.52 -same work behind the scenes; for example, the \hgcmd{diff} command
   71.53 -uses the status machinery to avoid doing an expensive comparison
   71.54 -operation on files that obviously haven't changed.
   71.55 -
   71.56 -Because obtaining file status is crucial to good performance, the
   71.57 -authors of Mercurial have optimised this code to within an inch of its
   71.58 -life.  However, there's no avoiding the fact that when you run
   71.59 -\hgcmd{status}, Mercurial is going to have to perform at least one
   71.60 -expensive system call for each managed file to determine whether it's
   71.61 -changed since the last time Mercurial checked.  For a sufficiently
   71.62 -large repository, this can take a long time.
   71.63 -
   71.64 -To put a number on the magnitude of this effect, I created a
   71.65 -repository containing 150,000 managed files.  I timed \hgcmd{status}
   71.66 -as taking ten seconds to run, even when \emph{none} of those files had
   71.67 -been modified.
   71.68 -
   71.69 -Many modern operating systems contain a file notification facility.
   71.70 -If a program signs up to an appropriate service, the operating system
   71.71 -will notify it every time a file of interest is created, modified, or
   71.72 -deleted.  On Linux systems, the kernel component that does this is
   71.73 -called \texttt{inotify}.
   71.74 -
   71.75 -Mercurial's \hgext{inotify} extension talks to the kernel's
   71.76 -\texttt{inotify} component to optimise \hgcmd{status} commands.  The
   71.77 -extension has two components.  A daemon sits in the background and
   71.78 -receives notifications from the \texttt{inotify} subsystem.  It also
   71.79 -listens for connections from a regular Mercurial command.  The
   71.80 -extension modifies Mercurial's behaviour so that instead of scanning
   71.81 -the filesystem, it queries the daemon.  Since the daemon has perfect
   71.82 -information about the state of the repository, it can respond with a
   71.83 -result instantaneously, avoiding the need to scan every directory and
   71.84 -file in the repository.
   71.85 -
   71.86 -Recall the ten seconds that I measured plain Mercurial as taking to
   71.87 -run \hgcmd{status} on a 150,000 file repository.  With the
   71.88 -\hgext{inotify} extension enabled, the time dropped to 0.1~seconds, a
   71.89 -factor of \emph{one hundred} faster.
   71.90 -
   71.91 -Before we continue, please pay attention to some caveats.
   71.92 -\begin{itemize}
   71.93 -\item The \hgext{inotify} extension is Linux-specific.  Because it
   71.94 -  interfaces directly to the Linux kernel's \texttt{inotify}
   71.95 -  subsystem, it does not work on other operating systems.
   71.96 -\item It should work on any Linux distribution that was released after
   71.97 -  early~2005.  Older distributions are likely to have a kernel that
   71.98 -  lacks \texttt{inotify}, or a version of \texttt{glibc} that does not
   71.99 -  have the necessary interfacing support.
  71.100 -\item Not all filesystems are suitable for use with the
  71.101 -  \hgext{inotify} extension.  Network filesystems such as NFS are a
  71.102 -  non-starter, for example, particularly if you're running Mercurial
  71.103 -  on several systems, all mounting the same network filesystem.  The
  71.104 -  kernel's \texttt{inotify} system has no way of knowing about changes
  71.105 -  made on another system.  Most local filesystems (e.g.~ext3, XFS,
  71.106 -  ReiserFS) should work fine.
  71.107 -\end{itemize}
  71.108 -
  71.109 -The \hgext{inotify} extension is not yet shipped with Mercurial as of
  71.110 -May~2007, so it's a little more involved to set up than other
  71.111 -extensions.  But the performance improvement is worth it!
  71.112 -
  71.113 -The extension currently comes in two parts: a set of patches to the
  71.114 -Mercurial source code, and a library of Python bindings to the
  71.115 -\texttt{inotify} subsystem.
  71.116 -\begin{note}
  71.117 -  There are \emph{two} Python \texttt{inotify} binding libraries.  One
  71.118 -  of them is called \texttt{pyinotify}, and is packaged by some Linux
  71.119 -  distributions as \texttt{python-inotify}.  This is \emph{not} the
  71.120 -  one you'll need, as it is too buggy and inefficient to be practical.
  71.121 -\end{note}
  71.122 -To get going, it's best to already have a functioning copy of
  71.123 -Mercurial installed.
  71.124 -\begin{note}
  71.125 -  If you follow the instructions below, you'll be \emph{replacing} and
  71.126 -  overwriting any existing installation of Mercurial that you might
  71.127 -  already have, using the latest ``bleeding edge'' Mercurial code.
  71.128 -  Don't say you weren't warned!
  71.129 -\end{note}
  71.130 -\begin{enumerate}
  71.131 -\item Clone the Python \texttt{inotify} binding repository.  Build and
  71.132 -  install it.
  71.133 -  \begin{codesample4}
  71.134 -    hg clone http://hg.kublai.com/python/inotify
  71.135 -    cd inotify
  71.136 -    python setup.py build --force
  71.137 -    sudo python setup.py install --skip-build
  71.138 -  \end{codesample4}
  71.139 -\item Clone the \dirname{crew} Mercurial repository.  Clone the
  71.140 -  \hgext{inotify} patch repository so that Mercurial Queues will be
  71.141 -  able to apply patches to your cope of the \dirname{crew} repository.
  71.142 -  \begin{codesample4}
  71.143 -    hg clone http://hg.intevation.org/mercurial/crew
  71.144 -    hg clone crew inotify
  71.145 -    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
  71.146 -  \end{codesample4}
  71.147 -\item Make sure that you have the Mercurial Queues extension,
  71.148 -  \hgext{mq}, enabled.  If you've never used MQ, read
  71.149 -  section~\ref{sec:mq:start} to get started quickly.
  71.150 -\item Go into the \dirname{inotify} repo, and apply all of the
  71.151 -  \hgext{inotify} patches using the \hgxopt{mq}{qpush}{-a} option to
  71.152 -  the \hgxcmd{mq}{qpush} command.
  71.153 -  \begin{codesample4}
  71.154 -    cd inotify
  71.155 -    hg qpush -a
  71.156 -  \end{codesample4}
  71.157 -  If you get an error message from \hgxcmd{mq}{qpush}, you should not
  71.158 -  continue.  Instead, ask for help.
  71.159 -\item Build and install the patched version of Mercurial.
  71.160 -  \begin{codesample4}
  71.161 -    python setup.py build --force
  71.162 -    sudo python setup.py install --skip-build
  71.163 -  \end{codesample4}
  71.164 -\end{enumerate}
  71.165 -Once you've build a suitably patched version of Mercurial, all you
  71.166 -need to do to enable the \hgext{inotify} extension is add an entry to
  71.167 -your \hgrc.
  71.168 -\begin{codesample2}
  71.169 -  [extensions]
  71.170 -  inotify =
  71.171 -\end{codesample2}
  71.172 -When the \hgext{inotify} extension is enabled, Mercurial will
  71.173 -automatically and transparently start the status daemon the first time
  71.174 -you run a command that needs status in a repository.  It runs one
  71.175 -status daemon per repository.
  71.176 -
  71.177 -The status daemon is started silently, and runs in the background.  If
  71.178 -you look at a list of running processes after you've enabled the
  71.179 -\hgext{inotify} extension and run a few commands in different
  71.180 -repositories, you'll thus see a few \texttt{hg} processes sitting
  71.181 -around, waiting for updates from the kernel and queries from
  71.182 -Mercurial.
  71.183 -
  71.184 -The first time you run a Mercurial command in a repository when you
  71.185 -have the \hgext{inotify} extension enabled, it will run with about the
  71.186 -same performance as a normal Mercurial command.  This is because the
  71.187 -status daemon needs to perform a normal status scan so that it has a
  71.188 -baseline against which to apply later updates from the kernel.
  71.189 -However, \emph{every} subsequent command that does any kind of status
  71.190 -check should be noticeably faster on repositories of even fairly
  71.191 -modest size.  Better yet, the bigger your repository is, the greater a
  71.192 -performance advantage you'll see.  The \hgext{inotify} daemon makes
  71.193 -status operations almost instantaneous on repositories of all sizes!
  71.194 -
  71.195 -If you like, you can manually start a status daemon using the
  71.196 -\hgxcmd{inotify}{inserve} command.  This gives you slightly finer
  71.197 -control over how the daemon ought to run.  This command will of course
  71.198 -only be available when the \hgext{inotify} extension is enabled.
  71.199 -
  71.200 -When you're using the \hgext{inotify} extension, you should notice
  71.201 -\emph{no difference at all} in Mercurial's behaviour, with the sole
  71.202 -exception of status-related commands running a whole lot faster than
  71.203 -they used to.  You should specifically expect that commands will not
  71.204 -print different output; neither should they give different results.
  71.205 -If either of these situations occurs, please report a bug.
  71.206 -
  71.207 -\section{Flexible diff support with the \hgext{extdiff} extension}
  71.208 -\label{sec:hgext:extdiff}
  71.209 -
  71.210 -Mercurial's built-in \hgcmd{diff} command outputs plaintext unified
  71.211 -diffs.
  71.212 -\interaction{extdiff.diff}
  71.213 -If you would like to use an external tool to display modifications,
  71.214 -you'll want to use the \hgext{extdiff} extension.  This will let you
  71.215 -use, for example, a graphical diff tool.
  71.216 -
  71.217 -The \hgext{extdiff} extension is bundled with Mercurial, so it's easy
  71.218 -to set up.  In the \rcsection{extensions} section of your \hgrc,
  71.219 -simply add a one-line entry to enable the extension.
  71.220 -\begin{codesample2}
  71.221 -  [extensions]
  71.222 -  extdiff =
  71.223 -\end{codesample2}
  71.224 -This introduces a command named \hgxcmd{extdiff}{extdiff}, which by
  71.225 -default uses your system's \command{diff} command to generate a
  71.226 -unified diff in the same form as the built-in \hgcmd{diff} command.
  71.227 -\interaction{extdiff.extdiff}
  71.228 -The result won't be exactly the same as with the built-in \hgcmd{diff}
  71.229 -variations, because the output of \command{diff} varies from one
  71.230 -system to another, even when passed the same options.
  71.231 -
  71.232 -As the ``\texttt{making snapshot}'' lines of output above imply, the
  71.233 -\hgxcmd{extdiff}{extdiff} command works by creating two snapshots of
  71.234 -your source tree.  The first snapshot is of the source revision; the
  71.235 -second, of the target revision or working directory.  The
  71.236 -\hgxcmd{extdiff}{extdiff} command generates these snapshots in a
  71.237 -temporary directory, passes the name of each directory to an external
  71.238 -diff viewer, then deletes the temporary directory.  For efficiency, it
  71.239 -only snapshots the directories and files that have changed between the
  71.240 -two revisions.
  71.241 -
  71.242 -Snapshot directory names have the same base name as your repository.
  71.243 -If your repository path is \dirname{/quux/bar/foo}, then \dirname{foo}
  71.244 -will be the name of each snapshot directory.  Each snapshot directory
  71.245 -name has its changeset ID appended, if appropriate.  If a snapshot is
  71.246 -of revision \texttt{a631aca1083f}, the directory will be named
  71.247 -\dirname{foo.a631aca1083f}.  A snapshot of the working directory won't
  71.248 -have a changeset ID appended, so it would just be \dirname{foo} in
  71.249 -this example.  To see what this looks like in practice, look again at
  71.250 -the \hgxcmd{extdiff}{extdiff} example above.  Notice that the diff has
  71.251 -the snapshot directory names embedded in its header.
  71.252 -
  71.253 -The \hgxcmd{extdiff}{extdiff} command accepts two important options.
  71.254 -The \hgxopt{extdiff}{extdiff}{-p} option lets you choose a program to
  71.255 -view differences with, instead of \command{diff}.  With the
  71.256 -\hgxopt{extdiff}{extdiff}{-o} option, you can change the options that
  71.257 -\hgxcmd{extdiff}{extdiff} passes to the program (by default, these
  71.258 -options are ``\texttt{-Npru}'', which only make sense if you're
  71.259 -running \command{diff}).  In other respects, the
  71.260 -\hgxcmd{extdiff}{extdiff} command acts similarly to the built-in
  71.261 -\hgcmd{diff} command: you use the same option names, syntax, and
  71.262 -arguments to specify the revisions you want, the files you want, and
  71.263 -so on.
  71.264 -
  71.265 -As an example, here's how to run the normal system \command{diff}
  71.266 -command, getting it to generate context diffs (using the
  71.267 -\cmdopt{diff}{-c} option) instead of unified diffs, and five lines of
  71.268 -context instead of the default three (passing \texttt{5} as the
  71.269 -argument to the \cmdopt{diff}{-C} option).
  71.270 -\interaction{extdiff.extdiff-ctx}
  71.271 -
  71.272 -Launching a visual diff tool is just as easy.  Here's how to launch
  71.273 -the \command{kdiff3} viewer.
  71.274 -\begin{codesample2}
  71.275 -  hg extdiff -p kdiff3 -o ''
  71.276 -\end{codesample2}
  71.277 -
  71.278 -If your diff viewing command can't deal with directories, you can
  71.279 -easily work around this with a little scripting.  For an example of
  71.280 -such scripting in action with the \hgext{mq} extension and the
  71.281 -\command{interdiff} command, see
  71.282 -section~\ref{mq-collab:tips:interdiff}.
  71.283 -
  71.284 -\subsection{Defining command aliases}
  71.285 -
  71.286 -It can be cumbersome to remember the options to both the
  71.287 -\hgxcmd{extdiff}{extdiff} command and the diff viewer you want to use,
  71.288 -so the \hgext{extdiff} extension lets you define \emph{new} commands
  71.289 -that will invoke your diff viewer with exactly the right options.
  71.290 -
  71.291 -All you need to do is edit your \hgrc, and add a section named
  71.292 -\rcsection{extdiff}.  Inside this section, you can define multiple
  71.293 -commands.  Here's how to add a \texttt{kdiff3} command.  Once you've
  71.294 -defined this, you can type ``\texttt{hg kdiff3}'' and the
  71.295 -\hgext{extdiff} extension will run \command{kdiff3} for you.
  71.296 -\begin{codesample2}
  71.297 -  [extdiff]
  71.298 -  cmd.kdiff3 =
  71.299 -\end{codesample2}
  71.300 -If you leave the right hand side of the definition empty, as above,
  71.301 -the \hgext{extdiff} extension uses the name of the command you defined
  71.302 -as the name of the external program to run.  But these names don't
  71.303 -have to be the same.  Here, we define a command named ``\texttt{hg
  71.304 -  wibble}'', which runs \command{kdiff3}.
  71.305 -\begin{codesample2}
  71.306 -  [extdiff]
  71.307 -  cmd.wibble = kdiff3
  71.308 -\end{codesample2}
  71.309 -
  71.310 -You can also specify the default options that you want to invoke your
  71.311 -diff viewing program with.  The prefix to use is ``\texttt{opts.}'',
  71.312 -followed by the name of the command to which the options apply.  This
  71.313 -example defines a ``\texttt{hg vimdiff}'' command that runs the
  71.314 -\command{vim} editor's \texttt{DirDiff} extension.
  71.315 -\begin{codesample2}
  71.316 -  [extdiff]  
  71.317 -  cmd.vimdiff = vim
  71.318 -  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
  71.319 -\end{codesample2}
  71.320 -
  71.321 -\section{Cherrypicking changes with the \hgext{transplant} extension}
  71.322 -\label{sec:hgext:transplant}
  71.323 -
  71.324 -Need to have a long chat with Brendan about this.
  71.325 -
  71.326 -\section{Send changes via email with the \hgext{patchbomb} extension}
  71.327 -\label{sec:hgext:patchbomb}
  71.328 -
  71.329 -Many projects have a culture of ``change review'', in which people
  71.330 -send their modifications to a mailing list for others to read and
  71.331 -comment on before they commit the final version to a shared
  71.332 -repository.  Some projects have people who act as gatekeepers; they
  71.333 -apply changes from other people to a repository to which those others
  71.334 -don't have access.
  71.335 -
  71.336 -Mercurial makes it easy to send changes over email for review or
  71.337 -application, via its \hgext{patchbomb} extension.  The extension is so
  71.338 -namd because changes are formatted as patches, and it's usual to send
  71.339 -one changeset per email message.  Sending a long series of changes by
  71.340 -email is thus much like ``bombing'' the recipient's inbox, hence
  71.341 -``patchbomb''.
  71.342 -
  71.343 -As usual, the basic configuration of the \hgext{patchbomb} extension
  71.344 -takes just one or two lines in your \hgrc.
  71.345 -\begin{codesample2}
  71.346 -  [extensions]
  71.347 -  patchbomb =
  71.348 -\end{codesample2}
  71.349 -Once you've enabled the extension, you will have a new command
  71.350 -available, named \hgxcmd{patchbomb}{email}.
  71.351 -
  71.352 -The safest and best way to invoke the \hgxcmd{patchbomb}{email}
  71.353 -command is to \emph{always} run it first with the
  71.354 -\hgxopt{patchbomb}{email}{-n} option.  This will show you what the
  71.355 -command \emph{would} send, without actually sending anything.  Once
  71.356 -you've had a quick glance over the changes and verified that you are
  71.357 -sending the right ones, you can rerun the same command, with the
  71.358 -\hgxopt{patchbomb}{email}{-n} option removed.
  71.359 -
  71.360 -The \hgxcmd{patchbomb}{email} command accepts the same kind of
  71.361 -revision syntax as every other Mercurial command.  For example, this
  71.362 -command will send every revision between 7 and \texttt{tip},
  71.363 -inclusive.
  71.364 -\begin{codesample2}
  71.365 -  hg email -n 7:tip
  71.366 -\end{codesample2}
  71.367 -You can also specify a \emph{repository} to compare with.  If you
  71.368 -provide a repository but no revisions, the \hgxcmd{patchbomb}{email}
  71.369 -command will send all revisions in the local repository that are not
  71.370 -present in the remote repository.  If you additionally specify
  71.371 -revisions or a branch name (the latter using the
  71.372 -\hgxopt{patchbomb}{email}{-b} option), this will constrain the
  71.373 -revisions sent.
  71.374 -
  71.375 -It's perfectly safe to run the \hgxcmd{patchbomb}{email} command
  71.376 -without the names of the people you want to send to: if you do this,
  71.377 -it will just prompt you for those values interactively.  (If you're
  71.378 -using a Linux or Unix-like system, you should have enhanced
  71.379 -\texttt{readline}-style editing capabilities when entering those
  71.380 -headers, too, which is useful.)
  71.381 -
  71.382 -When you are sending just one revision, the \hgxcmd{patchbomb}{email}
  71.383 -command will by default use the first line of the changeset
  71.384 -description as the subject of the single email message it sends.
  71.385 -
  71.386 -If you send multiple revisions, the \hgxcmd{patchbomb}{email} command
  71.387 -will usually send one message per changeset.  It will preface the
  71.388 -series with an introductory message, in which you should describe the
  71.389 -purpose of the series of changes you're sending.
  71.390 -
  71.391 -\subsection{Changing the behaviour of patchbombs}
  71.392 -
  71.393 -Not every project has exactly the same conventions for sending changes
  71.394 -in email; the \hgext{patchbomb} extension tries to accommodate a
  71.395 -number of variations through command line options.
  71.396 -\begin{itemize}
  71.397 -\item You can write a subject for the introductory message on the
  71.398 -  command line using the \hgxopt{patchbomb}{email}{-s} option.  This
  71.399 -  takes one argument, the text of the subject to use.
  71.400 -\item To change the email address from which the messages originate,
  71.401 -  use the \hgxopt{patchbomb}{email}{-f} option.  This takes one
  71.402 -  argument, the email address to use.
  71.403 -\item The default behaviour is to send unified diffs (see
  71.404 -  section~\ref{sec:mq:patch} for a description of the format), one per
  71.405 -  message.  You can send a binary bundle instead with the
  71.406 -  \hgxopt{patchbomb}{email}{-b} option.  
  71.407 -\item Unified diffs are normally prefaced with a metadata header.  You
  71.408 -  can omit this, and send unadorned diffs, with the
  71.409 -  \hgxopt{patchbomb}{email}{--plain} option.
  71.410 -\item Diffs are normally sent ``inline'', in the same body part as the
  71.411 -  description of a patch.  This makes it easiest for the largest
  71.412 -  number of readers to quote and respond to parts of a diff, as some
  71.413 -  mail clients will only quote the first MIME body part in a message.
  71.414 -  If you'd prefer to send the description and the diff in separate
  71.415 -  body parts, use the \hgxopt{patchbomb}{email}{-a} option.
  71.416 -\item Instead of sending mail messages, you can write them to an
  71.417 -  \texttt{mbox}-format mail folder using the
  71.418 -  \hgxopt{patchbomb}{email}{-m} option.  That option takes one
  71.419 -  argument, the name of the file to write to.
  71.420 -\item If you would like to add a \command{diffstat}-format summary to
  71.421 -  each patch, and one to the introductory message, use the
  71.422 -  \hgxopt{patchbomb}{email}{-d} option.  The \command{diffstat}
  71.423 -  command displays a table containing the name of each file patched,
  71.424 -  the number of lines affected, and a histogram showing how much each
  71.425 -  file is modified.  This gives readers a qualitative glance at how
  71.426 -  complex a patch is.
  71.427 -\end{itemize}
  71.428 -
  71.429 -%%% Local Variables: 
  71.430 -%%% mode: latex
  71.431 -%%% TeX-master: "00book"
  71.432 -%%% End: 
    72.1 --- a/fr/hook.tex	Sun Aug 16 03:41:39 2009 +0200
    72.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.3 @@ -1,1413 +0,0 @@
    72.4 -\chapter{Handling repository events with hooks}
    72.5 -\label{chap:hook}
    72.6 -
    72.7 -Mercurial offers a powerful mechanism to let you perform automated
    72.8 -actions in response to events that occur in a repository.  In some
    72.9 -cases, you can even control Mercurial's response to those events.
   72.10 -
   72.11 -The name Mercurial uses for one of these actions is a \emph{hook}.
   72.12 -Hooks are called ``triggers'' in some revision control systems, but
   72.13 -the two names refer to the same idea.
   72.14 -
   72.15 -\section{An overview of hooks in Mercurial}
   72.16 -
   72.17 -Here is a brief list of the hooks that Mercurial supports.  We will
   72.18 -revisit each of these hooks in more detail later, in
   72.19 -section~\ref{sec:hook:ref}.
   72.20 -
   72.21 -\begin{itemize}
   72.22 -\item[\small\hook{changegroup}] This is run after a group of
   72.23 -  changesets has been brought into the repository from elsewhere.
   72.24 -\item[\small\hook{commit}] This is run after a new changeset has been
   72.25 -  created in the local repository.
   72.26 -\item[\small\hook{incoming}] This is run once for each new changeset
   72.27 -  that is brought into the repository from elsewhere.  Notice the
   72.28 -  difference from \hook{changegroup}, which is run once per
   72.29 -  \emph{group} of changesets brought in.
   72.30 -\item[\small\hook{outgoing}] This is run after a group of changesets
   72.31 -  has been transmitted from this repository.
   72.32 -\item[\small\hook{prechangegroup}] This is run before starting to
   72.33 -  bring a group of changesets into the repository.
   72.34 -\item[\small\hook{precommit}] Controlling. This is run before starting
   72.35 -  a commit.
   72.36 -\item[\small\hook{preoutgoing}] Controlling. This is run before
   72.37 -  starting to transmit a group of changesets from this repository.
   72.38 -\item[\small\hook{pretag}] Controlling. This is run before creating a tag.
   72.39 -\item[\small\hook{pretxnchangegroup}] Controlling. This is run after a
   72.40 -  group of changesets has been brought into the local repository from
   72.41 -  another, but before the transaction completes that will make the
   72.42 -  changes permanent in the repository.
   72.43 -\item[\small\hook{pretxncommit}] Controlling. This is run after a new
   72.44 -  changeset has been created in the local repository, but before the
   72.45 -  transaction completes that will make it permanent.
   72.46 -\item[\small\hook{preupdate}] Controlling. This is run before starting
   72.47 -  an update or merge of the working directory.
   72.48 -\item[\small\hook{tag}] This is run after a tag is created.
   72.49 -\item[\small\hook{update}] This is run after an update or merge of the
   72.50 -  working directory has finished.
   72.51 -\end{itemize}
   72.52 -Each of the hooks whose description begins with the word
   72.53 -``Controlling'' has the ability to determine whether an activity can
   72.54 -proceed.  If the hook succeeds, the activity may proceed; if it fails,
   72.55 -the activity is either not permitted or undone, depending on the hook.
   72.56 -
   72.57 -\section{Hooks and security}
   72.58 -
   72.59 -\subsection{Hooks are run with your privileges}
   72.60 -
   72.61 -When you run a Mercurial command in a repository, and the command
   72.62 -causes a hook to run, that hook runs on \emph{your} system, under
   72.63 -\emph{your} user account, with \emph{your} privilege level.  Since
   72.64 -hooks are arbitrary pieces of executable code, you should treat them
   72.65 -with an appropriate level of suspicion.  Do not install a hook unless
   72.66 -you are confident that you know who created it and what it does.
   72.67 -
   72.68 -In some cases, you may be exposed to hooks that you did not install
   72.69 -yourself.  If you work with Mercurial on an unfamiliar system,
   72.70 -Mercurial will run hooks defined in that system's global \hgrc\ file.
   72.71 -
   72.72 -If you are working with a repository owned by another user, Mercurial
   72.73 -can run hooks defined in that user's repository, but it will still run
   72.74 -them as ``you''.  For example, if you \hgcmd{pull} from that
   72.75 -repository, and its \sfilename{.hg/hgrc} defines a local
   72.76 -\hook{outgoing} hook, that hook will run under your user account, even
   72.77 -though you don't own that repository.
   72.78 -
   72.79 -\begin{note}
   72.80 -  This only applies if you are pulling from a repository on a local or
   72.81 -  network filesystem.  If you're pulling over http or ssh, any
   72.82 -  \hook{outgoing} hook will run under whatever account is executing
   72.83 -  the server process, on the server.
   72.84 -\end{note}
   72.85 -
   72.86 -XXX To see what hooks are defined in a repository, use the
   72.87 -\hgcmdargs{config}{hooks} command.  If you are working in one
   72.88 -repository, but talking to another that you do not own (e.g.~using
   72.89 -\hgcmd{pull} or \hgcmd{incoming}), remember that it is the other
   72.90 -repository's hooks you should be checking, not your own.
   72.91 -
   72.92 -\subsection{Hooks do not propagate}
   72.93 -
   72.94 -In Mercurial, hooks are not revision controlled, and do not propagate
   72.95 -when you clone, or pull from, a repository.  The reason for this is
   72.96 -simple: a hook is a completely arbitrary piece of executable code.  It
   72.97 -runs under your user identity, with your privilege level, on your
   72.98 -machine.
   72.99 -
  72.100 -It would be extremely reckless for any distributed revision control
  72.101 -system to implement revision-controlled hooks, as this would offer an
  72.102 -easily exploitable way to subvert the accounts of users of the
  72.103 -revision control system.
  72.104 -
  72.105 -Since Mercurial does not propagate hooks, if you are collaborating
  72.106 -with other people on a common project, you should not assume that they
  72.107 -are using the same Mercurial hooks as you are, or that theirs are
  72.108 -correctly configured.  You should document the hooks you expect people
  72.109 -to use.
  72.110 -
  72.111 -In a corporate intranet, this is somewhat easier to control, as you
  72.112 -can for example provide a ``standard'' installation of Mercurial on an
  72.113 -NFS filesystem, and use a site-wide \hgrc\ file to define hooks that
  72.114 -all users will see.  However, this too has its limits; see below.
  72.115 -
  72.116 -\subsection{Hooks can be overridden}
  72.117 -
  72.118 -Mercurial allows you to override a hook definition by redefining the
  72.119 -hook.  You can disable it by setting its value to the empty string, or
  72.120 -change its behaviour as you wish.
  72.121 -
  72.122 -If you deploy a system-~or site-wide \hgrc\ file that defines some
  72.123 -hooks, you should thus understand that your users can disable or
  72.124 -override those hooks.
  72.125 -
  72.126 -\subsection{Ensuring that critical hooks are run}
  72.127 -
  72.128 -Sometimes you may want to enforce a policy that you do not want others
  72.129 -to be able to work around.  For example, you may have a requirement
  72.130 -that every changeset must pass a rigorous set of tests.  Defining this
  72.131 -requirement via a hook in a site-wide \hgrc\ won't work for remote
  72.132 -users on laptops, and of course local users can subvert it at will by
  72.133 -overriding the hook.
  72.134 -
  72.135 -Instead, you can set up your policies for use of Mercurial so that
  72.136 -people are expected to propagate changes through a well-known
  72.137 -``canonical'' server that you have locked down and configured
  72.138 -appropriately.
  72.139 -
  72.140 -One way to do this is via a combination of social engineering and
  72.141 -technology.  Set up a restricted-access account; users can push
  72.142 -changes over the network to repositories managed by this account, but
  72.143 -they cannot log into the account and run normal shell commands.  In
  72.144 -this scenario, a user can commit a changeset that contains any old
  72.145 -garbage they want.
  72.146 -
  72.147 -When someone pushes a changeset to the server that everyone pulls
  72.148 -from, the server will test the changeset before it accepts it as
  72.149 -permanent, and reject it if it fails to pass the test suite.  If
  72.150 -people only pull changes from this filtering server, it will serve to
  72.151 -ensure that all changes that people pull have been automatically
  72.152 -vetted.
  72.153 -
  72.154 -\section{Care with \texttt{pretxn} hooks in a shared-access repository}
  72.155 -
  72.156 -If you want to use hooks to do some automated work in a repository
  72.157 -that a number of people have shared access to, you need to be careful
  72.158 -in how you do this.
  72.159 -
  72.160 -Mercurial only locks a repository when it is writing to the
  72.161 -repository, and only the parts of Mercurial that write to the
  72.162 -repository pay attention to locks.  Write locks are necessary to
  72.163 -prevent multiple simultaneous writers from scribbling on each other's
  72.164 -work, corrupting the repository.
  72.165 -
  72.166 -Because Mercurial is careful with the order in which it reads and
  72.167 -writes data, it does not need to acquire a lock when it wants to read
  72.168 -data from the repository.  The parts of Mercurial that read from the
  72.169 -repository never pay attention to locks.  This lockless reading scheme
  72.170 -greatly increases performance and concurrency.
  72.171 -
  72.172 -With great performance comes a trade-off, though, one which has the
  72.173 -potential to cause you trouble unless you're aware of it.  To describe
  72.174 -this requires a little detail about how Mercurial adds changesets to a
  72.175 -repository and reads those changes.
  72.176 -
  72.177 -When Mercurial \emph{writes} metadata, it writes it straight into the
  72.178 -destination file.  It writes file data first, then manifest data
  72.179 -(which contains pointers to the new file data), then changelog data
  72.180 -(which contains pointers to the new manifest data).  Before the first
  72.181 -write to each file, it stores a record of where the end of the file
  72.182 -was in its transaction log.  If the transaction must be rolled back,
  72.183 -Mercurial simply truncates each file back to the size it was before the
  72.184 -transaction began.
  72.185 -
  72.186 -When Mercurial \emph{reads} metadata, it reads the changelog first,
  72.187 -then everything else.  Since a reader will only access parts of the
  72.188 -manifest or file metadata that it can see in the changelog, it can
  72.189 -never see partially written data.
  72.190 -
  72.191 -Some controlling hooks (\hook{pretxncommit} and
  72.192 -\hook{pretxnchangegroup}) run when a transaction is almost complete.
  72.193 -All of the metadata has been written, but Mercurial can still roll the
  72.194 -transaction back and cause the newly-written data to disappear.
  72.195 -
  72.196 -If one of these hooks runs for long, it opens a window of time during
  72.197 -which a reader can see the metadata for changesets that are not yet
  72.198 -permanent, and should not be thought of as ``really there''.  The
  72.199 -longer the hook runs, the longer that window is open.
  72.200 -
  72.201 -\subsection{The problem illustrated}
  72.202 -
  72.203 -In principle, a good use for the \hook{pretxnchangegroup} hook would
  72.204 -be to automatically build and test incoming changes before they are
  72.205 -accepted into a central repository.  This could let you guarantee that
  72.206 -nobody can push changes to this repository that ``break the build''.
  72.207 -But if a client can pull changes while they're being tested, the
  72.208 -usefulness of the test is zero; an unsuspecting someone can pull
  72.209 -untested changes, potentially breaking their build.
  72.210 -
  72.211 -The safest technological answer to this challenge is to set up such a
  72.212 -``gatekeeper'' repository as \emph{unidirectional}.  Let it take
  72.213 -changes pushed in from the outside, but do not allow anyone to pull
  72.214 -changes from it (use the \hook{preoutgoing} hook to lock it down).
  72.215 -Configure a \hook{changegroup} hook so that if a build or test
  72.216 -succeeds, the hook will push the new changes out to another repository
  72.217 -that people \emph{can} pull from.
  72.218 -
  72.219 -In practice, putting a centralised bottleneck like this in place is
  72.220 -not often a good idea, and transaction visibility has nothing to do
  72.221 -with the problem.  As the size of a project---and the time it takes to
  72.222 -build and test---grows, you rapidly run into a wall with this ``try
  72.223 -before you buy'' approach, where you have more changesets to test than
  72.224 -time in which to deal with them.  The inevitable result is frustration
  72.225 -on the part of all involved.
  72.226 -
  72.227 -An approach that scales better is to get people to build and test
  72.228 -before they push, then run automated builds and tests centrally
  72.229 -\emph{after} a push, to be sure all is well.  The advantage of this
  72.230 -approach is that it does not impose a limit on the rate at which the
  72.231 -repository can accept changes.
  72.232 -
  72.233 -\section{A short tutorial on using hooks}
  72.234 -\label{sec:hook:simple}
  72.235 -
  72.236 -It is easy to write a Mercurial hook.  Let's start with a hook that
  72.237 -runs when you finish a \hgcmd{commit}, and simply prints the hash of
  72.238 -the changeset you just created.  The hook is called \hook{commit}.
  72.239 -
  72.240 -\begin{figure}[ht]
  72.241 -  \interaction{hook.simple.init}
  72.242 -  \caption{A simple hook that runs when a changeset is committed}
  72.243 -  \label{ex:hook:init}
  72.244 -\end{figure}
  72.245 -
  72.246 -All hooks follow the pattern in example~\ref{ex:hook:init}.  You add
  72.247 -an entry to the \rcsection{hooks} section of your \hgrc.  On the left
  72.248 -is the name of the event to trigger on; on the right is the action to
  72.249 -take.  As you can see, you can run an arbitrary shell command in a
  72.250 -hook.  Mercurial passes extra information to the hook using
  72.251 -environment variables (look for \envar{HG\_NODE} in the example).
  72.252 -
  72.253 -\subsection{Performing multiple actions per event}
  72.254 -
  72.255 -Quite often, you will want to define more than one hook for a
  72.256 -particular kind of event, as shown in example~\ref{ex:hook:ext}.
  72.257 -Mercurial lets you do this by adding an \emph{extension} to the end of
  72.258 -a hook's name.  You extend a hook's name by giving the name of the
  72.259 -hook, followed by a full stop (the ``\texttt{.}'' character), followed
  72.260 -by some more text of your choosing.  For example, Mercurial will run
  72.261 -both \texttt{commit.foo} and \texttt{commit.bar} when the
  72.262 -\texttt{commit} event occurs.
  72.263 -
  72.264 -\begin{figure}[ht]
  72.265 -  \interaction{hook.simple.ext}
  72.266 -  \caption{Defining a second \hook{commit} hook}
  72.267 -  \label{ex:hook:ext}
  72.268 -\end{figure}
  72.269 -
  72.270 -To give a well-defined order of execution when there are multiple
  72.271 -hooks defined for an event, Mercurial sorts hooks by extension, and
  72.272 -executes the hook commands in this sorted order.  In the above
  72.273 -example, it will execute \texttt{commit.bar} before
  72.274 -\texttt{commit.foo}, and \texttt{commit} before both.
  72.275 -
  72.276 -It is a good idea to use a somewhat descriptive extension when you
  72.277 -define a new hook.  This will help you to remember what the hook was
  72.278 -for.  If the hook fails, you'll get an error message that contains the
  72.279 -hook name and extension, so using a descriptive extension could give
  72.280 -you an immediate hint as to why the hook failed (see
  72.281 -section~\ref{sec:hook:perm} for an example).
  72.282 -
  72.283 -\subsection{Controlling whether an activity can proceed}
  72.284 -\label{sec:hook:perm}
  72.285 -
  72.286 -In our earlier examples, we used the \hook{commit} hook, which is
  72.287 -run after a commit has completed.  This is one of several Mercurial
  72.288 -hooks that run after an activity finishes.  Such hooks have no way of
  72.289 -influencing the activity itself.
  72.290 -
  72.291 -Mercurial defines a number of events that occur before an activity
  72.292 -starts; or after it starts, but before it finishes.  Hooks that
  72.293 -trigger on these events have the added ability to choose whether the
  72.294 -activity can continue, or will abort.  
  72.295 -
  72.296 -The \hook{pretxncommit} hook runs after a commit has all but
  72.297 -completed.  In other words, the metadata representing the changeset
  72.298 -has been written out to disk, but the transaction has not yet been
  72.299 -allowed to complete.  The \hook{pretxncommit} hook has the ability to
  72.300 -decide whether the transaction can complete, or must be rolled back.
  72.301 -
  72.302 -If the \hook{pretxncommit} hook exits with a status code of zero, the
  72.303 -transaction is allowed to complete; the commit finishes; and the
  72.304 -\hook{commit} hook is run.  If the \hook{pretxncommit} hook exits with
  72.305 -a non-zero status code, the transaction is rolled back; the metadata
  72.306 -representing the changeset is erased; and the \hook{commit} hook is
  72.307 -not run.
  72.308 -
  72.309 -\begin{figure}[ht]
  72.310 -  \interaction{hook.simple.pretxncommit}
  72.311 -  \caption{Using the \hook{pretxncommit} hook to control commits}
  72.312 -  \label{ex:hook:pretxncommit}
  72.313 -\end{figure}
  72.314 -
  72.315 -The hook in example~\ref{ex:hook:pretxncommit} checks that a commit
  72.316 -comment contains a bug ID.  If it does, the commit can complete.  If
  72.317 -not, the commit is rolled back.
  72.318 -
  72.319 -\section{Writing your own hooks}
  72.320 -
  72.321 -When you are writing a hook, you might find it useful to run Mercurial
  72.322 -either with the \hggopt{-v} option, or the \rcitem{ui}{verbose} config
  72.323 -item set to ``true''.  When you do so, Mercurial will print a message
  72.324 -before it calls each hook.
  72.325 -
  72.326 -\subsection{Choosing how your hook should run}
  72.327 -\label{sec:hook:lang}
  72.328 -
  72.329 -You can write a hook either as a normal program---typically a shell
  72.330 -script---or as a Python function that is executed within the Mercurial
  72.331 -process.
  72.332 -
  72.333 -Writing a hook as an external program has the advantage that it
  72.334 -requires no knowledge of Mercurial's internals.  You can call normal
  72.335 -Mercurial commands to get any added information you need.  The
  72.336 -trade-off is that external hooks are slower than in-process hooks.
  72.337 -
  72.338 -An in-process Python hook has complete access to the Mercurial API,
  72.339 -and does not ``shell out'' to another process, so it is inherently
  72.340 -faster than an external hook.  It is also easier to obtain much of the
  72.341 -information that a hook requires by using the Mercurial API than by
  72.342 -running Mercurial commands.
  72.343 -
  72.344 -If you are comfortable with Python, or require high performance,
  72.345 -writing your hooks in Python may be a good choice.  However, when you
  72.346 -have a straightforward hook to write and you don't need to care about
  72.347 -performance (probably the majority of hooks), a shell script is
  72.348 -perfectly fine.
  72.349 -
  72.350 -\subsection{Hook parameters}
  72.351 -\label{sec:hook:param}
  72.352 -
  72.353 -Mercurial calls each hook with a set of well-defined parameters.  In
  72.354 -Python, a parameter is passed as a keyword argument to your hook
  72.355 -function.  For an external program, a parameter is passed as an
  72.356 -environment variable.
  72.357 -
  72.358 -Whether your hook is written in Python or as a shell script, the
  72.359 -hook-specific parameter names and values will be the same.  A boolean
  72.360 -parameter will be represented as a boolean value in Python, but as the
  72.361 -number 1 (for ``true'') or 0 (for ``false'') as an environment
  72.362 -variable for an external hook.  If a hook parameter is named
  72.363 -\texttt{foo}, the keyword argument for a Python hook will also be
  72.364 -named \texttt{foo}, while the environment variable for an external
  72.365 -hook will be named \texttt{HG\_FOO}.
  72.366 -
  72.367 -\subsection{Hook return values and activity control}
  72.368 -
  72.369 -A hook that executes successfully must exit with a status of zero if
  72.370 -external, or return boolean ``false'' if in-process.  Failure is
  72.371 -indicated with a non-zero exit status from an external hook, or an
  72.372 -in-process hook returning boolean ``true''.  If an in-process hook
  72.373 -raises an exception, the hook is considered to have failed.
  72.374 -
  72.375 -For a hook that controls whether an activity can proceed, zero/false
  72.376 -means ``allow'', while non-zero/true/exception means ``deny''.
  72.377 -
  72.378 -\subsection{Writing an external hook}
  72.379 -
  72.380 -When you define an external hook in your \hgrc\ and the hook is run,
  72.381 -its value is passed to your shell, which interprets it.  This means
  72.382 -that you can use normal shell constructs in the body of the hook.
  72.383 -
  72.384 -An executable hook is always run with its current directory set to a
  72.385 -repository's root directory.
  72.386 -
  72.387 -Each hook parameter is passed in as an environment variable; the name
  72.388 -is upper-cased, and prefixed with the string ``\texttt{HG\_}''.
  72.389 -
  72.390 -With the exception of hook parameters, Mercurial does not set or
  72.391 -modify any environment variables when running a hook.  This is useful
  72.392 -to remember if you are writing a site-wide hook that may be run by a
  72.393 -number of different users with differing environment variables set.
  72.394 -In multi-user situations, you should not rely on environment variables
  72.395 -being set to the values you have in your environment when testing the
  72.396 -hook.
  72.397 -
  72.398 -\subsection{Telling Mercurial to use an in-process hook}
  72.399 -
  72.400 -The \hgrc\ syntax for defining an in-process hook is slightly
  72.401 -different than for an executable hook.  The value of the hook must
  72.402 -start with the text ``\texttt{python:}'', and continue with the
  72.403 -fully-qualified name of a callable object to use as the hook's value.
  72.404 -
  72.405 -The module in which a hook lives is automatically imported when a hook
  72.406 -is run.  So long as you have the module name and \envar{PYTHONPATH}
  72.407 -right, it should ``just work''.
  72.408 -
  72.409 -The following \hgrc\ example snippet illustrates the syntax and
  72.410 -meaning of the notions we just described.
  72.411 -\begin{codesample2}
  72.412 -  [hooks]
  72.413 -  commit.example = python:mymodule.submodule.myhook
  72.414 -\end{codesample2}
  72.415 -When Mercurial runs the \texttt{commit.example} hook, it imports
  72.416 -\texttt{mymodule.submodule}, looks for the callable object named
  72.417 -\texttt{myhook}, and calls it.
  72.418 -
  72.419 -\subsection{Writing an in-process hook}
  72.420 -
  72.421 -The simplest in-process hook does nothing, but illustrates the basic
  72.422 -shape of the hook API:
  72.423 -\begin{codesample2}
  72.424 -  def myhook(ui, repo, **kwargs):
  72.425 -      pass
  72.426 -\end{codesample2}
  72.427 -The first argument to a Python hook is always a
  72.428 -\pymodclass{mercurial.ui}{ui} object.  The second is a repository object;
  72.429 -at the moment, it is always an instance of
  72.430 -\pymodclass{mercurial.localrepo}{localrepository}.  Following these two
  72.431 -arguments are other keyword arguments.  Which ones are passed in
  72.432 -depends on the hook being called, but a hook can ignore arguments it
  72.433 -doesn't care about by dropping them into a keyword argument dict, as
  72.434 -with \texttt{**kwargs} above.
  72.435 -
  72.436 -\section{Some hook examples}
  72.437 -
  72.438 -\subsection{Writing meaningful commit messages}
  72.439 -
  72.440 -It's hard to imagine a useful commit message being very short.  The
  72.441 -simple \hook{pretxncommit} hook of figure~\ref{ex:hook:msglen.go}
  72.442 -will prevent you from committing a changeset with a message that is
  72.443 -less than ten bytes long.
  72.444 -
  72.445 -\begin{figure}[ht]
  72.446 -  \interaction{hook.msglen.go}
  72.447 -  \caption{A hook that forbids overly short commit messages}
  72.448 -  \label{ex:hook:msglen.go}
  72.449 -\end{figure}
  72.450 -
  72.451 -\subsection{Checking for trailing whitespace}
  72.452 -
  72.453 -An interesting use of a commit-related hook is to help you to write
  72.454 -cleaner code.  A simple example of ``cleaner code'' is the dictum that
  72.455 -a change should not add any new lines of text that contain ``trailing
  72.456 -whitespace''.  Trailing whitespace is a series of space and tab
  72.457 -characters at the end of a line of text.  In most cases, trailing
  72.458 -whitespace is unnecessary, invisible noise, but it is occasionally
  72.459 -problematic, and people often prefer to get rid of it.
  72.460 -
  72.461 -You can use either the \hook{precommit} or \hook{pretxncommit} hook to
  72.462 -tell whether you have a trailing whitespace problem.  If you use the
  72.463 -\hook{precommit} hook, the hook will not know which files you are
  72.464 -committing, so it will have to check every modified file in the
  72.465 -repository for trailing white space.  If you want to commit a change
  72.466 -to just the file \filename{foo}, but the file \filename{bar} contains
  72.467 -trailing whitespace, doing a check in the \hook{precommit} hook will
  72.468 -prevent you from committing \filename{foo} due to the problem with
  72.469 -\filename{bar}.  This doesn't seem right.
  72.470 -
  72.471 -Should you choose the \hook{pretxncommit} hook, the check won't occur
  72.472 -until just before the transaction for the commit completes.  This will
  72.473 -allow you to check for problems only the exact files that are being
  72.474 -committed.  However, if you entered the commit message interactively
  72.475 -and the hook fails, the transaction will roll back; you'll have to
  72.476 -re-enter the commit message after you fix the trailing whitespace and
  72.477 -run \hgcmd{commit} again.
  72.478 -
  72.479 -\begin{figure}[ht]
  72.480 -  \interaction{hook.ws.simple}
  72.481 -  \caption{A simple hook that checks for trailing whitespace}
  72.482 -  \label{ex:hook:ws.simple}
  72.483 -\end{figure}
  72.484 -
  72.485 -Figure~\ref{ex:hook:ws.simple} introduces a simple \hook{pretxncommit}
  72.486 -hook that checks for trailing whitespace.  This hook is short, but not
  72.487 -very helpful.  It exits with an error status if a change adds a line
  72.488 -with trailing whitespace to any file, but does not print any
  72.489 -information that might help us to identify the offending file or
  72.490 -line.  It also has the nice property of not paying attention to
  72.491 -unmodified lines; only lines that introduce new trailing whitespace
  72.492 -cause problems.
  72.493 -
  72.494 -\begin{figure}[ht]
  72.495 -  \interaction{hook.ws.better}
  72.496 -  \caption{A better trailing whitespace hook}
  72.497 -  \label{ex:hook:ws.better}
  72.498 -\end{figure}
  72.499 -
  72.500 -The example of figure~\ref{ex:hook:ws.better} is much more complex,
  72.501 -but also more useful.  It parses a unified diff to see if any lines
  72.502 -add trailing whitespace, and prints the name of the file and the line
  72.503 -number of each such occurrence.  Even better, if the change adds
  72.504 -trailing whitespace, this hook saves the commit comment and prints the
  72.505 -name of the save file before exiting and telling Mercurial to roll the
  72.506 -transaction back, so you can use
  72.507 -\hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{filename}} to reuse the
  72.508 -saved commit message once you've corrected the problem.
  72.509 -
  72.510 -As a final aside, note in figure~\ref{ex:hook:ws.better} the use of
  72.511 -\command{perl}'s in-place editing feature to get rid of trailing
  72.512 -whitespace from a file.  This is concise and useful enough that I will
  72.513 -reproduce it here.
  72.514 -\begin{codesample2}
  72.515 -  perl -pi -e 's,\textbackslash{}s+\$,,' filename
  72.516 -\end{codesample2}
  72.517 -
  72.518 -\section{Bundled hooks}
  72.519 -
  72.520 -Mercurial ships with several bundled hooks.  You can find them in the
  72.521 -\dirname{hgext} directory of a Mercurial source tree.  If you are
  72.522 -using a Mercurial binary package, the hooks will be located in the
  72.523 -\dirname{hgext} directory of wherever your package installer put
  72.524 -Mercurial.
  72.525 -
  72.526 -\subsection{\hgext{acl}---access control for parts of a repository}
  72.527 -
  72.528 -The \hgext{acl} extension lets you control which remote users are
  72.529 -allowed to push changesets to a networked server.  You can protect any
  72.530 -portion of a repository (including the entire repo), so that a
  72.531 -specific remote user can push changes that do not affect the protected
  72.532 -portion.
  72.533 -
  72.534 -This extension implements access control based on the identity of the
  72.535 -user performing a push, \emph{not} on who committed the changesets
  72.536 -they're pushing.  It makes sense to use this hook only if you have a
  72.537 -locked-down server environment that authenticates remote users, and
  72.538 -you want to be sure that only specific users are allowed to push
  72.539 -changes to that server.
  72.540 -
  72.541 -\subsubsection{Configuring the \hook{acl} hook}
  72.542 -
  72.543 -In order to manage incoming changesets, the \hgext{acl} hook must be
  72.544 -used as a \hook{pretxnchangegroup} hook.  This lets it see which files
  72.545 -are modified by each incoming changeset, and roll back a group of
  72.546 -changesets if they modify ``forbidden'' files.  Example:
  72.547 -\begin{codesample2}
  72.548 -  [hooks]
  72.549 -  pretxnchangegroup.acl = python:hgext.acl.hook
  72.550 -\end{codesample2}
  72.551 -
  72.552 -The \hgext{acl} extension is configured using three sections.  
  72.553 -
  72.554 -The \rcsection{acl} section has only one entry, \rcitem{acl}{sources},
  72.555 -which lists the sources of incoming changesets that the hook should
  72.556 -pay attention to.  You don't normally need to configure this section.
  72.557 -\begin{itemize}
  72.558 -\item[\rcitem{acl}{serve}] Control incoming changesets that are arriving
  72.559 -  from a remote repository over http or ssh.  This is the default
  72.560 -  value of \rcitem{acl}{sources}, and usually the only setting you'll
  72.561 -  need for this configuration item.
  72.562 -\item[\rcitem{acl}{pull}] Control incoming changesets that are
  72.563 -  arriving via a pull from a local repository.
  72.564 -\item[\rcitem{acl}{push}] Control incoming changesets that are
  72.565 -  arriving via a push from a local repository.
  72.566 -\item[\rcitem{acl}{bundle}] Control incoming changesets that are
  72.567 -  arriving from another repository via a bundle.
  72.568 -\end{itemize}
  72.569 -
  72.570 -The \rcsection{acl.allow} section controls the users that are allowed to
  72.571 -add changesets to the repository.  If this section is not present, all
  72.572 -users that are not explicitly denied are allowed.  If this section is
  72.573 -present, all users that are not explicitly allowed are denied (so an
  72.574 -empty section means that all users are denied).
  72.575 -
  72.576 -The \rcsection{acl.deny} section determines which users are denied
  72.577 -from adding changesets to the repository.  If this section is not
  72.578 -present or is empty, no users are denied.
  72.579 -
  72.580 -The syntaxes for the \rcsection{acl.allow} and \rcsection{acl.deny}
  72.581 -sections are identical.  On the left of each entry is a glob pattern
  72.582 -that matches files or directories, relative to the root of the
  72.583 -repository; on the right, a user name.
  72.584 -
  72.585 -In the following example, the user \texttt{docwriter} can only push
  72.586 -changes to the \dirname{docs} subtree of the repository, while
  72.587 -\texttt{intern} can push changes to any file or directory except
  72.588 -\dirname{source/sensitive}.
  72.589 -\begin{codesample2}
  72.590 -  [acl.allow]
  72.591 -  docs/** = docwriter
  72.592 -
  72.593 -  [acl.deny]
  72.594 -  source/sensitive/** = intern
  72.595 -\end{codesample2}
  72.596 -
  72.597 -\subsubsection{Testing and troubleshooting}
  72.598 -
  72.599 -If you want to test the \hgext{acl} hook, run it with Mercurial's
  72.600 -debugging output enabled.  Since you'll probably be running it on a
  72.601 -server where it's not convenient (or sometimes possible) to pass in
  72.602 -the \hggopt{--debug} option, don't forget that you can enable
  72.603 -debugging output in your \hgrc:
  72.604 -\begin{codesample2}
  72.605 -  [ui]
  72.606 -  debug = true
  72.607 -\end{codesample2}
  72.608 -With this enabled, the \hgext{acl} hook will print enough information
  72.609 -to let you figure out why it is allowing or forbidding pushes from
  72.610 -specific users.
  72.611 -
  72.612 -\subsection{\hgext{bugzilla}---integration with Bugzilla}
  72.613 -
  72.614 -The \hgext{bugzilla} extension adds a comment to a Bugzilla bug
  72.615 -whenever it finds a reference to that bug ID in a commit comment.  You
  72.616 -can install this hook on a shared server, so that any time a remote
  72.617 -user pushes changes to this server, the hook gets run.  
  72.618 -
  72.619 -It adds a comment to the bug that looks like this (you can configure
  72.620 -the contents of the comment---see below):
  72.621 -\begin{codesample2}
  72.622 -  Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in
  72.623 -  the frobnitz repository, refers to this bug.
  72.624 -
  72.625 -  For complete details, see
  72.626 -  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
  72.627 -
  72.628 -  Changeset description:
  72.629 -        Fix bug 10483 by guarding against some NULL pointers
  72.630 -\end{codesample2}
  72.631 -The value of this hook is that it automates the process of updating a
  72.632 -bug any time a changeset refers to it.  If you configure the hook
  72.633 -properly, it makes it easy for people to browse straight from a
  72.634 -Bugzilla bug to a changeset that refers to that bug.
  72.635 -
  72.636 -You can use the code in this hook as a starting point for some more
  72.637 -exotic Bugzilla integration recipes.  Here are a few possibilities:
  72.638 -\begin{itemize}
  72.639 -\item Require that every changeset pushed to the server have a valid
  72.640 -  bug~ID in its commit comment.  In this case, you'd want to configure
  72.641 -  the hook as a \hook{pretxncommit} hook.  This would allow the hook
  72.642 -  to reject changes that didn't contain bug IDs.
  72.643 -\item Allow incoming changesets to automatically modify the
  72.644 -  \emph{state} of a bug, as well as simply adding a comment.  For
  72.645 -  example, the hook could recognise the string ``fixed bug 31337'' as
  72.646 -  indicating that it should update the state of bug 31337 to
  72.647 -  ``requires testing''.
  72.648 -\end{itemize}
  72.649 -
  72.650 -\subsubsection{Configuring the \hook{bugzilla} hook}
  72.651 -\label{sec:hook:bugzilla:config}
  72.652 -
  72.653 -You should configure this hook in your server's \hgrc\ as an
  72.654 -\hook{incoming} hook, for example as follows:
  72.655 -\begin{codesample2}
  72.656 -  [hooks]
  72.657 -  incoming.bugzilla = python:hgext.bugzilla.hook
  72.658 -\end{codesample2}
  72.659 -
  72.660 -Because of the specialised nature of this hook, and because Bugzilla
  72.661 -was not written with this kind of integration in mind, configuring
  72.662 -this hook is a somewhat involved process.
  72.663 -
  72.664 -Before you begin, you must install the MySQL bindings for Python on
  72.665 -the host(s) where you'll be running the hook.  If this is not
  72.666 -available as a binary package for your system, you can download it
  72.667 -from~\cite{web:mysql-python}.
  72.668 -
  72.669 -Configuration information for this hook lives in the
  72.670 -\rcsection{bugzilla} section of your \hgrc.
  72.671 -\begin{itemize}
  72.672 -\item[\rcitem{bugzilla}{version}] The version of Bugzilla installed on
  72.673 -  the server.  The database schema that Bugzilla uses changes
  72.674 -  occasionally, so this hook has to know exactly which schema to use.
  72.675 -  At the moment, the only version supported is \texttt{2.16}.
  72.676 -\item[\rcitem{bugzilla}{host}] The hostname of the MySQL server that
  72.677 -  stores your Bugzilla data.  The database must be configured to allow
  72.678 -  connections from whatever host you are running the \hook{bugzilla}
  72.679 -  hook on.
  72.680 -\item[\rcitem{bugzilla}{user}] The username with which to connect to
  72.681 -  the MySQL server.  The database must be configured to allow this
  72.682 -  user to connect from whatever host you are running the
  72.683 -  \hook{bugzilla} hook on.  This user must be able to access and
  72.684 -  modify Bugzilla tables.  The default value of this item is
  72.685 -  \texttt{bugs}, which is the standard name of the Bugzilla user in a
  72.686 -  MySQL database.
  72.687 -\item[\rcitem{bugzilla}{password}] The MySQL password for the user you
  72.688 -  configured above.  This is stored as plain text, so you should make
  72.689 -  sure that unauthorised users cannot read the \hgrc\ file where you
  72.690 -  store this information.
  72.691 -\item[\rcitem{bugzilla}{db}] The name of the Bugzilla database on the
  72.692 -  MySQL server.  The default value of this item is \texttt{bugs},
  72.693 -  which is the standard name of the MySQL database where Bugzilla
  72.694 -  stores its data.
  72.695 -\item[\rcitem{bugzilla}{notify}] If you want Bugzilla to send out a
  72.696 -  notification email to subscribers after this hook has added a
  72.697 -  comment to a bug, you will need this hook to run a command whenever
  72.698 -  it updates the database.  The command to run depends on where you
  72.699 -  have installed Bugzilla, but it will typically look something like
  72.700 -  this, if you have Bugzilla installed in
  72.701 -  \dirname{/var/www/html/bugzilla}:
  72.702 -  \begin{codesample4}
  72.703 -    cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com
  72.704 -  \end{codesample4}
  72.705 -  The Bugzilla \texttt{processmail} program expects to be given a
  72.706 -  bug~ID (the hook replaces ``\texttt{\%s}'' with the bug~ID) and an
  72.707 -  email address.  It also expects to be able to write to some files in
  72.708 -  the directory that it runs in.  If Bugzilla and this hook are not
  72.709 -  installed on the same machine, you will need to find a way to run
  72.710 -  \texttt{processmail} on the server where Bugzilla is installed.
  72.711 -\end{itemize}
  72.712 -
  72.713 -\subsubsection{Mapping committer names to Bugzilla user names}
  72.714 -
  72.715 -By default, the \hgext{bugzilla} hook tries to use the email address
  72.716 -of a changeset's committer as the Bugzilla user name with which to
  72.717 -update a bug.  If this does not suit your needs, you can map committer
  72.718 -email addresses to Bugzilla user names using a \rcsection{usermap}
  72.719 -section.
  72.720 -
  72.721 -Each item in the \rcsection{usermap} section contains an email address
  72.722 -on the left, and a Bugzilla user name on the right.
  72.723 -\begin{codesample2}
  72.724 -  [usermap]
  72.725 -  jane.user@example.com = jane
  72.726 -\end{codesample2}
  72.727 -You can either keep the \rcsection{usermap} data in a normal \hgrc, or
  72.728 -tell the \hgext{bugzilla} hook to read the information from an
  72.729 -external \filename{usermap} file.  In the latter case, you can store
  72.730 -\filename{usermap} data by itself in (for example) a user-modifiable
  72.731 -repository.  This makes it possible to let your users maintain their
  72.732 -own \rcitem{bugzilla}{usermap} entries.  The main \hgrc\ file might
  72.733 -look like this:
  72.734 -\begin{codesample2}
  72.735 -  # regular hgrc file refers to external usermap file
  72.736 -  [bugzilla]
  72.737 -  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
  72.738 -\end{codesample2}
  72.739 -While the \filename{usermap} file that it refers to might look like
  72.740 -this:
  72.741 -\begin{codesample2}
  72.742 -  # bugzilla-usermap.conf - inside a hg repository
  72.743 -  [usermap]
  72.744 -  stephanie@example.com = steph
  72.745 -\end{codesample2}
  72.746 -
  72.747 -\subsubsection{Configuring the text that gets added to a bug}
  72.748 -
  72.749 -You can configure the text that this hook adds as a comment; you
  72.750 -specify it in the form of a Mercurial template.  Several \hgrc\
  72.751 -entries (still in the \rcsection{bugzilla} section) control this
  72.752 -behaviour.
  72.753 -\begin{itemize}
  72.754 -\item[\texttt{strip}] The number of leading path elements to strip
  72.755 -  from a repository's path name to construct a partial path for a URL.
  72.756 -  For example, if the repositories on your server live under
  72.757 -  \dirname{/home/hg/repos}, and you have a repository whose path is
  72.758 -  \dirname{/home/hg/repos/app/tests}, then setting \texttt{strip} to
  72.759 -  \texttt{4} will give a partial path of \dirname{app/tests}.  The
  72.760 -  hook will make this partial path available when expanding a
  72.761 -  template, as \texttt{webroot}.
  72.762 -\item[\texttt{template}] The text of the template to use.  In addition
  72.763 -  to the usual changeset-related variables, this template can use
  72.764 -  \texttt{hgweb} (the value of the \texttt{hgweb} configuration item
  72.765 -  above) and \texttt{webroot} (the path constructed using
  72.766 -  \texttt{strip} above).
  72.767 -\end{itemize}
  72.768 -
  72.769 -In addition, you can add a \rcitem{web}{baseurl} item to the
  72.770 -\rcsection{web} section of your \hgrc.  The \hgext{bugzilla} hook will
  72.771 -make this available when expanding a template, as the base string to
  72.772 -use when constructing a URL that will let users browse from a Bugzilla
  72.773 -comment to view a changeset.  Example:
  72.774 -\begin{codesample2}
  72.775 -  [web]
  72.776 -  baseurl = http://hg.domain.com/
  72.777 -\end{codesample2}
  72.778 -
  72.779 -Here is an example set of \hgext{bugzilla} hook config information.
  72.780 -\begin{codesample2}
  72.781 -  [bugzilla]
  72.782 -  host = bugzilla.example.com
  72.783 -  password = mypassword
  72.784 -  version = 2.16
  72.785 -  # server-side repos live in /home/hg/repos, so strip 4 leading
  72.786 -  # separators
  72.787 -  strip = 4
  72.788 -  hgweb = http://hg.example.com/
  72.789 -  usermap = /home/hg/repos/notify/bugzilla.conf
  72.790 -  template = Changeset \{node|short\}, made by \{author\} in the \{webroot\}
  72.791 -    repo, refers to this bug.\\nFor complete details, see 
  72.792 -    \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset
  72.793 -    description:\\n\\t\{desc|tabindent\}
  72.794 -\end{codesample2}
  72.795 -
  72.796 -\subsubsection{Testing and troubleshooting}
  72.797 -
  72.798 -The most common problems with configuring the \hgext{bugzilla} hook
  72.799 -relate to running Bugzilla's \filename{processmail} script and mapping
  72.800 -committer names to user names.
  72.801 -
  72.802 -Recall from section~\ref{sec:hook:bugzilla:config} above that the user
  72.803 -that runs the Mercurial process on the server is also the one that
  72.804 -will run the \filename{processmail} script.  The
  72.805 -\filename{processmail} script sometimes causes Bugzilla to write to
  72.806 -files in its configuration directory, and Bugzilla's configuration
  72.807 -files are usually owned by the user that your web server runs under.
  72.808 -
  72.809 -You can cause \filename{processmail} to be run with the suitable
  72.810 -user's identity using the \command{sudo} command.  Here is an example
  72.811 -entry for a \filename{sudoers} file.
  72.812 -\begin{codesample2}
  72.813 -  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
  72.814 -\end{codesample2}
  72.815 -This allows the \texttt{hg\_user} user to run a
  72.816 -\filename{processmail-wrapper} program under the identity of
  72.817 -\texttt{httpd\_user}.
  72.818 -
  72.819 -This indirection through a wrapper script is necessary, because
  72.820 -\filename{processmail} expects to be run with its current directory
  72.821 -set to wherever you installed Bugzilla; you can't specify that kind of
  72.822 -constraint in a \filename{sudoers} file.  The contents of the wrapper
  72.823 -script are simple:
  72.824 -\begin{codesample2}
  72.825 -  #!/bin/sh
  72.826 -  cd `dirname $0` && ./processmail "$1" nobody@example.com
  72.827 -\end{codesample2}
  72.828 -It doesn't seem to matter what email address you pass to
  72.829 -\filename{processmail}.
  72.830 -
  72.831 -If your \rcsection{usermap} is not set up correctly, users will see an
  72.832 -error message from the \hgext{bugzilla} hook when they push changes
  72.833 -to the server.  The error message will look like this:
  72.834 -\begin{codesample2}
  72.835 -  cannot find bugzilla user id for john.q.public@example.com
  72.836 -\end{codesample2}
  72.837 -What this means is that the committer's address,
  72.838 -\texttt{john.q.public@example.com}, is not a valid Bugzilla user name,
  72.839 -nor does it have an entry in your \rcsection{usermap} that maps it to
  72.840 -a valid Bugzilla user name.
  72.841 -
  72.842 -\subsection{\hgext{notify}---send email notifications}
  72.843 -
  72.844 -Although Mercurial's built-in web server provides RSS feeds of changes
  72.845 -in every repository, many people prefer to receive change
  72.846 -notifications via email.  The \hgext{notify} hook lets you send out
  72.847 -notifications to a set of email addresses whenever changesets arrive
  72.848 -that those subscribers are interested in.
  72.849 -
  72.850 -As with the \hgext{bugzilla} hook, the \hgext{notify} hook is
  72.851 -template-driven, so you can customise the contents of the notification
  72.852 -messages that it sends.
  72.853 -
  72.854 -By default, the \hgext{notify} hook includes a diff of every changeset
  72.855 -that it sends out; you can limit the size of the diff, or turn this
  72.856 -feature off entirely.  It is useful for letting subscribers review
  72.857 -changes immediately, rather than clicking to follow a URL.
  72.858 -
  72.859 -\subsubsection{Configuring the \hgext{notify} hook}
  72.860 -
  72.861 -You can set up the \hgext{notify} hook to send one email message per
  72.862 -incoming changeset, or one per incoming group of changesets (all those
  72.863 -that arrived in a single pull or push).
  72.864 -\begin{codesample2}
  72.865 -  [hooks]
  72.866 -  # send one email per group of changes
  72.867 -  changegroup.notify = python:hgext.notify.hook
  72.868 -  # send one email per change
  72.869 -  incoming.notify = python:hgext.notify.hook
  72.870 -\end{codesample2}
  72.871 -
  72.872 -Configuration information for this hook lives in the
  72.873 -\rcsection{notify} section of a \hgrc\ file.
  72.874 -\begin{itemize}
  72.875 -\item[\rcitem{notify}{test}] By default, this hook does not send out
  72.876 -  email at all; instead, it prints the message that it \emph{would}
  72.877 -  send.  Set this item to \texttt{false} to allow email to be sent.
  72.878 -  The reason that sending of email is turned off by default is that it
  72.879 -  takes several tries to configure this extension exactly as you would
  72.880 -  like, and it would be bad form to spam subscribers with a number of
  72.881 -  ``broken'' notifications while you debug your configuration.
  72.882 -\item[\rcitem{notify}{config}] The path to a configuration file that
  72.883 -  contains subscription information.  This is kept separate from the
  72.884 -  main \hgrc\ so that you can maintain it in a repository of its own.
  72.885 -  People can then clone that repository, update their subscriptions,
  72.886 -  and push the changes back to your server.
  72.887 -\item[\rcitem{notify}{strip}] The number of leading path separator
  72.888 -  characters to strip from a repository's path, when deciding whether
  72.889 -  a repository has subscribers.  For example, if the repositories on
  72.890 -  your server live in \dirname{/home/hg/repos}, and \hgext{notify} is
  72.891 -  considering a repository named \dirname{/home/hg/repos/shared/test},
  72.892 -  setting \rcitem{notify}{strip} to \texttt{4} will cause
  72.893 -  \hgext{notify} to trim the path it considers down to
  72.894 -  \dirname{shared/test}, and it will match subscribers against that.
  72.895 -\item[\rcitem{notify}{template}] The template text to use when sending
  72.896 -  messages.  This specifies both the contents of the message header
  72.897 -  and its body.
  72.898 -\item[\rcitem{notify}{maxdiff}] The maximum number of lines of diff
  72.899 -  data to append to the end of a message.  If a diff is longer than
  72.900 -  this, it is truncated.  By default, this is set to 300.  Set this to
  72.901 -  \texttt{0} to omit diffs from notification emails.
  72.902 -\item[\rcitem{notify}{sources}] A list of sources of changesets to
  72.903 -  consider.  This lets you limit \hgext{notify} to only sending out
  72.904 -  email about changes that remote users pushed into this repository
  72.905 -  via a server, for example.  See section~\ref{sec:hook:sources} for
  72.906 -  the sources you can specify here.
  72.907 -\end{itemize}
  72.908 -
  72.909 -If you set the \rcitem{web}{baseurl} item in the \rcsection{web}
  72.910 -section, you can use it in a template; it will be available as
  72.911 -\texttt{webroot}.
  72.912 -
  72.913 -Here is an example set of \hgext{notify} configuration information.
  72.914 -\begin{codesample2}
  72.915 -  [notify]
  72.916 -  # really send email
  72.917 -  test = false
  72.918 -  # subscriber data lives in the notify repo
  72.919 -  config = /home/hg/repos/notify/notify.conf
  72.920 -  # repos live in /home/hg/repos on server, so strip 4 "/" chars
  72.921 -  strip = 4
  72.922 -  template = X-Hg-Repo: \{webroot\}
  72.923 -    Subject: \{webroot\}: \{desc|firstline|strip\}
  72.924 -    From: \{author\}
  72.925 -
  72.926 -    changeset \{node|short\} in \{root\}
  72.927 -    details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}
  72.928 -    description:
  72.929 -      \{desc|tabindent|strip\}
  72.930 -
  72.931 -  [web]
  72.932 -  baseurl = http://hg.example.com/
  72.933 -\end{codesample2}
  72.934 -
  72.935 -This will produce a message that looks like the following:
  72.936 -\begin{codesample2}
  72.937 -  X-Hg-Repo: tests/slave
  72.938 -  Subject: tests/slave: Handle error case when slave has no buffers
  72.939 -  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
  72.940 -
  72.941 -  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
  72.942 -  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
  72.943 -  description:
  72.944 -          Handle error case when slave has no buffers
  72.945 -  diffs (54 lines):
  72.946 -
  72.947 -  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
  72.948 -  --- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
  72.949 -  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
  72.950 -  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
  72.951 -  [...snip...]
  72.952 -\end{codesample2}
  72.953 -
  72.954 -\subsubsection{Testing and troubleshooting}
  72.955 -
  72.956 -Do not forget that by default, the \hgext{notify} extension \emph{will
  72.957 -  not send any mail} until you explicitly configure it to do so, by
  72.958 -setting \rcitem{notify}{test} to \texttt{false}.  Until you do that,
  72.959 -it simply prints the message it \emph{would} send.
  72.960 -
  72.961 -\section{Information for writers of hooks}
  72.962 -\label{sec:hook:ref}
  72.963 -
  72.964 -\subsection{In-process hook execution}
  72.965 -
  72.966 -An in-process hook is called with arguments of the following form:
  72.967 -\begin{codesample2}
  72.968 -  def myhook(ui, repo, **kwargs):
  72.969 -      pass
  72.970 -\end{codesample2}
  72.971 -The \texttt{ui} parameter is a \pymodclass{mercurial.ui}{ui} object.
  72.972 -The \texttt{repo} parameter is a
  72.973 -\pymodclass{mercurial.localrepo}{localrepository} object.  The
  72.974 -names and values of the \texttt{**kwargs} parameters depend on the
  72.975 -hook being invoked, with the following common features:
  72.976 -\begin{itemize}
  72.977 -\item If a parameter is named \texttt{node} or
  72.978 -  \texttt{parent\emph{N}}, it will contain a hexadecimal changeset ID.
  72.979 -  The empty string is used to represent ``null changeset ID'' instead
  72.980 -  of a string of zeroes.
  72.981 -\item If a parameter is named \texttt{url}, it will contain the URL of
  72.982 -  a remote repository, if that can be determined.
  72.983 -\item Boolean-valued parameters are represented as Python
  72.984 -  \texttt{bool} objects.
  72.985 -\end{itemize}
  72.986 -
  72.987 -An in-process hook is called without a change to the process's working
  72.988 -directory (unlike external hooks, which are run in the root of the
  72.989 -repository).  It must not change the process's working directory, or
  72.990 -it will cause any calls it makes into the Mercurial API to fail.
  72.991 -
  72.992 -If a hook returns a boolean ``false'' value, it is considered to have
  72.993 -succeeded.  If it returns a boolean ``true'' value or raises an
  72.994 -exception, it is considered to have failed.  A useful way to think of
  72.995 -the calling convention is ``tell me if you fail''.
  72.996 -
  72.997 -Note that changeset IDs are passed into Python hooks as hexadecimal
  72.998 -strings, not the binary hashes that Mercurial's APIs normally use.  To
  72.999 -convert a hash from hex to binary, use the
 72.1000 -\pymodfunc{mercurial.node}{bin} function.
 72.1001 -
 72.1002 -\subsection{External hook execution}
 72.1003 -
 72.1004 -An external hook is passed to the shell of the user running Mercurial.
 72.1005 -Features of that shell, such as variable substitution and command
 72.1006 -redirection, are available.  The hook is run in the root directory of
 72.1007 -the repository (unlike in-process hooks, which are run in the same
 72.1008 -directory that Mercurial was run in).
 72.1009 -
 72.1010 -Hook parameters are passed to the hook as environment variables.  Each
 72.1011 -environment variable's name is converted in upper case and prefixed
 72.1012 -with the string ``\texttt{HG\_}''.  For example, if the name of a
 72.1013 -parameter is ``\texttt{node}'', the name of the environment variable
 72.1014 -representing that parameter will be ``\texttt{HG\_NODE}''.
 72.1015 -
 72.1016 -A boolean parameter is represented as the string ``\texttt{1}'' for
 72.1017 -``true'', ``\texttt{0}'' for ``false''.  If an environment variable is
 72.1018 -named \envar{HG\_NODE}, \envar{HG\_PARENT1} or \envar{HG\_PARENT2}, it
 72.1019 -contains a changeset ID represented as a hexadecimal string.  The
 72.1020 -empty string is used to represent ``null changeset ID'' instead of a
 72.1021 -string of zeroes.  If an environment variable is named
 72.1022 -\envar{HG\_URL}, it will contain the URL of a remote repository, if
 72.1023 -that can be determined.
 72.1024 -
 72.1025 -If a hook exits with a status of zero, it is considered to have
 72.1026 -succeeded.  If it exits with a non-zero status, it is considered to
 72.1027 -have failed.
 72.1028 -
 72.1029 -\subsection{Finding out where changesets come from}
 72.1030 -
 72.1031 -A hook that involves the transfer of changesets between a local
 72.1032 -repository and another may be able to find out information about the
 72.1033 -``far side''.  Mercurial knows \emph{how} changes are being
 72.1034 -transferred, and in many cases \emph{where} they are being transferred
 72.1035 -to or from.
 72.1036 -
 72.1037 -\subsubsection{Sources of changesets}
 72.1038 -\label{sec:hook:sources}
 72.1039 -
 72.1040 -Mercurial will tell a hook what means are, or were, used to transfer
 72.1041 -changesets between repositories.  This is provided by Mercurial in a
 72.1042 -Python parameter named \texttt{source}, or an environment variable named
 72.1043 -\envar{HG\_SOURCE}.
 72.1044 -
 72.1045 -\begin{itemize}
 72.1046 -\item[\texttt{serve}] Changesets are transferred to or from a remote
 72.1047 -  repository over http or ssh.
 72.1048 -\item[\texttt{pull}] Changesets are being transferred via a pull from
 72.1049 -  one repository into another.
 72.1050 -\item[\texttt{push}] Changesets are being transferred via a push from
 72.1051 -  one repository into another.
 72.1052 -\item[\texttt{bundle}] Changesets are being transferred to or from a
 72.1053 -  bundle.
 72.1054 -\end{itemize}
 72.1055 -
 72.1056 -\subsubsection{Where changes are going---remote repository URLs}
 72.1057 -\label{sec:hook:url}
 72.1058 -
 72.1059 -When possible, Mercurial will tell a hook the location of the ``far
 72.1060 -side'' of an activity that transfers changeset data between
 72.1061 -repositories.  This is provided by Mercurial in a Python parameter
 72.1062 -named \texttt{url}, or an environment variable named \envar{HG\_URL}.
 72.1063 -
 72.1064 -This information is not always known.  If a hook is invoked in a
 72.1065 -repository that is being served via http or ssh, Mercurial cannot tell
 72.1066 -where the remote repository is, but it may know where the client is
 72.1067 -connecting from.  In such cases, the URL will take one of the
 72.1068 -following forms:
 72.1069 -\begin{itemize}
 72.1070 -\item \texttt{remote:ssh:\emph{ip-address}}---remote ssh client, at
 72.1071 -  the given IP address.
 72.1072 -\item \texttt{remote:http:\emph{ip-address}}---remote http client, at
 72.1073 -  the given IP address.  If the client is using SSL, this will be of
 72.1074 -  the form \texttt{remote:https:\emph{ip-address}}.
 72.1075 -\item Empty---no information could be discovered about the remote
 72.1076 -  client.
 72.1077 -\end{itemize}
 72.1078 -
 72.1079 -\section{Hook reference}
 72.1080 -
 72.1081 -\subsection{\hook{changegroup}---after remote changesets added}
 72.1082 -\label{sec:hook:changegroup}
 72.1083 -
 72.1084 -This hook is run after a group of pre-existing changesets has been
 72.1085 -added to the repository, for example via a \hgcmd{pull} or
 72.1086 -\hgcmd{unbundle}.  This hook is run once per operation that added one
 72.1087 -or more changesets.  This is in contrast to the \hook{incoming} hook,
 72.1088 -which is run once per changeset, regardless of whether the changesets
 72.1089 -arrive in a group.
 72.1090 -
 72.1091 -Some possible uses for this hook include kicking off an automated
 72.1092 -build or test of the added changesets, updating a bug database, or
 72.1093 -notifying subscribers that a repository contains new changes.
 72.1094 -
 72.1095 -Parameters to this hook:
 72.1096 -\begin{itemize}
 72.1097 -\item[\texttt{node}] A changeset ID.  The changeset ID of the first
 72.1098 -  changeset in the group that was added.  All changesets between this
 72.1099 -  and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
 72.1100 -  a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
 72.1101 -\item[\texttt{source}] A string.  The source of these changes.  See
 72.1102 -  section~\ref{sec:hook:sources} for details.
 72.1103 -\item[\texttt{url}] A URL.  The location of the remote repository, if
 72.1104 -  known.  See section~\ref{sec:hook:url} for more information.
 72.1105 -\end{itemize}
 72.1106 -
 72.1107 -See also: \hook{incoming} (section~\ref{sec:hook:incoming}),
 72.1108 -\hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}),
 72.1109 -\hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
 72.1110 -
 72.1111 -\subsection{\hook{commit}---after a new changeset is created}
 72.1112 -\label{sec:hook:commit}
 72.1113 -
 72.1114 -This hook is run after a new changeset has been created.
 72.1115 -
 72.1116 -Parameters to this hook:
 72.1117 -\begin{itemize}
 72.1118 -\item[\texttt{node}] A changeset ID.  The changeset ID of the newly
 72.1119 -  committed changeset.
 72.1120 -\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
 72.1121 -  parent of the newly committed changeset.
 72.1122 -\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
 72.1123 -  parent of the newly committed changeset.
 72.1124 -\end{itemize}
 72.1125 -
 72.1126 -See also: \hook{precommit} (section~\ref{sec:hook:precommit}),
 72.1127 -\hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
 72.1128 -
 72.1129 -\subsection{\hook{incoming}---after one remote changeset is added}
 72.1130 -\label{sec:hook:incoming}
 72.1131 -
 72.1132 -This hook is run after a pre-existing changeset has been added to the
 72.1133 -repository, for example via a \hgcmd{push}.  If a group of changesets
 72.1134 -was added in a single operation, this hook is called once for each
 72.1135 -added changeset.
 72.1136 -
 72.1137 -You can use this hook for the same purposes as the \hook{changegroup}
 72.1138 -hook (section~\ref{sec:hook:changegroup}); it's simply more convenient
 72.1139 -sometimes to run a hook once per group of changesets, while other
 72.1140 -times it's handier once per changeset.
 72.1141 -
 72.1142 -Parameters to this hook:
 72.1143 -\begin{itemize}
 72.1144 -\item[\texttt{node}] A changeset ID.  The ID of the newly added
 72.1145 -  changeset.
 72.1146 -\item[\texttt{source}] A string.  The source of these changes.  See
 72.1147 -  section~\ref{sec:hook:sources} for details.
 72.1148 -\item[\texttt{url}] A URL.  The location of the remote repository, if
 72.1149 -  known.  See section~\ref{sec:hook:url} for more information.
 72.1150 -\end{itemize}
 72.1151 -
 72.1152 -See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}) \hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}), \hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
 72.1153 -
 72.1154 -\subsection{\hook{outgoing}---after changesets are propagated}
 72.1155 -\label{sec:hook:outgoing}
 72.1156 -
 72.1157 -This hook is run after a group of changesets has been propagated out
 72.1158 -of this repository, for example by a \hgcmd{push} or \hgcmd{bundle}
 72.1159 -command.
 72.1160 -
 72.1161 -One possible use for this hook is to notify administrators that
 72.1162 -changes have been pulled.
 72.1163 -
 72.1164 -Parameters to this hook:
 72.1165 -\begin{itemize}
 72.1166 -\item[\texttt{node}] A changeset ID.  The changeset ID of the first
 72.1167 -  changeset of the group that was sent.
 72.1168 -\item[\texttt{source}] A string.  The source of the of the operation
 72.1169 -  (see section~\ref{sec:hook:sources}).  If a remote client pulled
 72.1170 -  changes from this repository, \texttt{source} will be
 72.1171 -  \texttt{serve}.  If the client that obtained changes from this
 72.1172 -  repository was local, \texttt{source} will be \texttt{bundle},
 72.1173 -  \texttt{pull}, or \texttt{push}, depending on the operation the
 72.1174 -  client performed.
 72.1175 -\item[\texttt{url}] A URL.  The location of the remote repository, if
 72.1176 -  known.  See section~\ref{sec:hook:url} for more information.
 72.1177 -\end{itemize}
 72.1178 -
 72.1179 -See also: \hook{preoutgoing} (section~\ref{sec:hook:preoutgoing})
 72.1180 -
 72.1181 -\subsection{\hook{prechangegroup}---before starting to add remote changesets}
 72.1182 -\label{sec:hook:prechangegroup}
 72.1183 -
 72.1184 -This controlling hook is run before Mercurial begins to add a group of
 72.1185 -changesets from another repository.
 72.1186 -
 72.1187 -This hook does not have any information about the changesets to be
 72.1188 -added, because it is run before transmission of those changesets is
 72.1189 -allowed to begin.  If this hook fails, the changesets will not be
 72.1190 -transmitted.
 72.1191 -
 72.1192 -One use for this hook is to prevent external changes from being added
 72.1193 -to a repository.  For example, you could use this to ``freeze'' a
 72.1194 -server-hosted branch temporarily or permanently so that users cannot
 72.1195 -push to it, while still allowing a local administrator to modify the
 72.1196 -repository.
 72.1197 -
 72.1198 -Parameters to this hook:
 72.1199 -\begin{itemize}
 72.1200 -\item[\texttt{source}] A string.  The source of these changes.  See
 72.1201 -  section~\ref{sec:hook:sources} for details.
 72.1202 -\item[\texttt{url}] A URL.  The location of the remote repository, if
 72.1203 -  known.  See section~\ref{sec:hook:url} for more information.
 72.1204 -\end{itemize}
 72.1205 -
 72.1206 -See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
 72.1207 -\hook{incoming} (section~\ref{sec:hook:incoming}), ,
 72.1208 -\hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
 72.1209 -
 72.1210 -\subsection{\hook{precommit}---before starting to commit a changeset}
 72.1211 -\label{sec:hook:precommit}
 72.1212 -
 72.1213 -This hook is run before Mercurial begins to commit a new changeset.
 72.1214 -It is run before Mercurial has any of the metadata for the commit,
 72.1215 -such as the files to be committed, the commit message, or the commit
 72.1216 -date.
 72.1217 -
 72.1218 -One use for this hook is to disable the ability to commit new
 72.1219 -changesets, while still allowing incoming changesets.  Another is to
 72.1220 -run a build or test, and only allow the commit to begin if the build
 72.1221 -or test succeeds.
 72.1222 -
 72.1223 -Parameters to this hook:
 72.1224 -\begin{itemize}
 72.1225 -\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
 72.1226 -  parent of the working directory.
 72.1227 -\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
 72.1228 -  parent of the working directory.
 72.1229 -\end{itemize}
 72.1230 -If the commit proceeds, the parents of the working directory will
 72.1231 -become the parents of the new changeset.
 72.1232 -
 72.1233 -See also: \hook{commit} (section~\ref{sec:hook:commit}),
 72.1234 -\hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
 72.1235 -
 72.1236 -\subsection{\hook{preoutgoing}---before starting to propagate changesets}
 72.1237 -\label{sec:hook:preoutgoing}
 72.1238 -
 72.1239 -This hook is invoked before Mercurial knows the identities of the
 72.1240 -changesets to be transmitted.
 72.1241 -
 72.1242 -One use for this hook is to prevent changes from being transmitted to
 72.1243 -another repository.
 72.1244 -
 72.1245 -Parameters to this hook:
 72.1246 -\begin{itemize}
 72.1247 -\item[\texttt{source}] A string.  The source of the operation that is
 72.1248 -  attempting to obtain changes from this repository (see
 72.1249 -  section~\ref{sec:hook:sources}).  See the documentation for the
 72.1250 -  \texttt{source} parameter to the \hook{outgoing} hook, in
 72.1251 -  section~\ref{sec:hook:outgoing}, for possible values of this
 72.1252 -  parameter.
 72.1253 -\item[\texttt{url}] A URL.  The location of the remote repository, if
 72.1254 -  known.  See section~\ref{sec:hook:url} for more information.
 72.1255 -\end{itemize}
 72.1256 -
 72.1257 -See also: \hook{outgoing} (section~\ref{sec:hook:outgoing})
 72.1258 -
 72.1259 -\subsection{\hook{pretag}---before tagging a changeset}
 72.1260 -\label{sec:hook:pretag}
 72.1261 -
 72.1262 -This controlling hook is run before a tag is created.  If the hook
 72.1263 -succeeds, creation of the tag proceeds.  If the hook fails, the tag is
 72.1264 -not created.
 72.1265 -
 72.1266 -Parameters to this hook:
 72.1267 -\begin{itemize}
 72.1268 -\item[\texttt{local}] A boolean.  Whether the tag is local to this
 72.1269 -  repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
 72.1270 -  managed by Mercurial (stored in \sfilename{.hgtags}).
 72.1271 -\item[\texttt{node}] A changeset ID.  The ID of the changeset to be tagged.
 72.1272 -\item[\texttt{tag}] A string.  The name of the tag to be created.
 72.1273 -\end{itemize}
 72.1274 -
 72.1275 -If the tag to be created is revision-controlled, the \hook{precommit}
 72.1276 -and \hook{pretxncommit} hooks (sections~\ref{sec:hook:commit}
 72.1277 -and~\ref{sec:hook:pretxncommit}) will also be run.
 72.1278 -
 72.1279 -See also: \hook{tag} (section~\ref{sec:hook:tag})
 72.1280 -
 72.1281 -\subsection{\hook{pretxnchangegroup}---before completing addition of
 72.1282 -  remote changesets}
 72.1283 -\label{sec:hook:pretxnchangegroup}
 72.1284 -
 72.1285 -This controlling hook is run before a transaction---that manages the
 72.1286 -addition of a group of new changesets from outside the
 72.1287 -repository---completes.  If the hook succeeds, the transaction
 72.1288 -completes, and all of the changesets become permanent within this
 72.1289 -repository.  If the hook fails, the transaction is rolled back, and
 72.1290 -the data for the changesets is erased.
 72.1291 -
 72.1292 -This hook can access the metadata associated with the almost-added
 72.1293 -changesets, but it should not do anything permanent with this data.
 72.1294 -It must also not modify the working directory.
 72.1295 -
 72.1296 -While this hook is running, if other Mercurial processes access this
 72.1297 -repository, they will be able to see the almost-added changesets as if
 72.1298 -they are permanent.  This may lead to race conditions if you do not
 72.1299 -take steps to avoid them.
 72.1300 -
 72.1301 -This hook can be used to automatically vet a group of changesets.  If
 72.1302 -the hook fails, all of the changesets are ``rejected'' when the
 72.1303 -transaction rolls back.
 72.1304 -
 72.1305 -Parameters to this hook:
 72.1306 -\begin{itemize}
 72.1307 -\item[\texttt{node}] A changeset ID.  The changeset ID of the first
 72.1308 -  changeset in the group that was added.  All changesets between this
 72.1309 -  and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
 72.1310 -  a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
 72.1311 -\item[\texttt{source}] A string.  The source of these changes.  See
 72.1312 -  section~\ref{sec:hook:sources} for details.
 72.1313 -\item[\texttt{url}] A URL.  The location of the remote repository, if
 72.1314 -  known.  See section~\ref{sec:hook:url} for more information.
 72.1315 -\end{itemize}
 72.1316 -
 72.1317 -See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
 72.1318 -\hook{incoming} (section~\ref{sec:hook:incoming}),
 72.1319 -\hook{prechangegroup} (section~\ref{sec:hook:prechangegroup})
 72.1320 -
 72.1321 -\subsection{\hook{pretxncommit}---before completing commit of new changeset}
 72.1322 -\label{sec:hook:pretxncommit}
 72.1323 -
 72.1324 -This controlling hook is run before a transaction---that manages a new
 72.1325 -commit---completes.  If the hook succeeds, the transaction completes
 72.1326 -and the changeset becomes permanent within this repository.  If the
 72.1327 -hook fails, the transaction is rolled back, and the commit data is
 72.1328 -erased.
 72.1329 -
 72.1330 -This hook can access the metadata associated with the almost-new
 72.1331 -changeset, but it should not do anything permanent with this data.  It
 72.1332 -must also not modify the working directory.
 72.1333 -
 72.1334 -While this hook is running, if other Mercurial processes access this
 72.1335 -repository, they will be able to see the almost-new changeset as if it
 72.1336 -is permanent.  This may lead to race conditions if you do not take
 72.1337 -steps to avoid them.
 72.1338 -
 72.1339 -Parameters to this hook:
 72.1340 -\begin{itemize}
 72.1341 -\item[\texttt{node}] A changeset ID.  The changeset ID of the newly
 72.1342 -  committed changeset.
 72.1343 -\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
 72.1344 -  parent of the newly committed changeset.
 72.1345 -\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
 72.1346 -  parent of the newly committed changeset.
 72.1347 -\end{itemize}
 72.1348 -
 72.1349 -See also: \hook{precommit} (section~\ref{sec:hook:precommit})
 72.1350 -
 72.1351 -\subsection{\hook{preupdate}---before updating or merging working directory}
 72.1352 -\label{sec:hook:preupdate}
 72.1353 -
 72.1354 -This controlling hook is run before an update or merge of the working
 72.1355 -directory begins.  It is run only if Mercurial's normal pre-update
 72.1356 -checks determine that the update or merge can proceed.  If the hook
 72.1357 -succeeds, the update or merge may proceed; if it fails, the update or
 72.1358 -merge does not start.
 72.1359 -
 72.1360 -Parameters to this hook:
 72.1361 -\begin{itemize}
 72.1362 -\item[\texttt{parent1}] A changeset ID.  The ID of the parent that the
 72.1363 -  working directory is to be updated to.  If the working directory is
 72.1364 -  being merged, it will not change this parent.
 72.1365 -\item[\texttt{parent2}] A changeset ID.  Only set if the working
 72.1366 -  directory is being merged.  The ID of the revision that the working
 72.1367 -  directory is being merged with.
 72.1368 -\end{itemize}
 72.1369 -
 72.1370 -See also: \hook{update} (section~\ref{sec:hook:update})
 72.1371 -
 72.1372 -\subsection{\hook{tag}---after tagging a changeset}
 72.1373 -\label{sec:hook:tag}
 72.1374 -
 72.1375 -This hook is run after a tag has been created.
 72.1376 -
 72.1377 -Parameters to this hook:
 72.1378 -\begin{itemize}
 72.1379 -\item[\texttt{local}] A boolean.  Whether the new tag is local to this
 72.1380 -  repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
 72.1381 -  managed by Mercurial (stored in \sfilename{.hgtags}).
 72.1382 -\item[\texttt{node}] A changeset ID.  The ID of the changeset that was
 72.1383 -  tagged.
 72.1384 -\item[\texttt{tag}] A string.  The name of the tag that was created.
 72.1385 -\end{itemize}
 72.1386 -
 72.1387 -If the created tag is revision-controlled, the \hook{commit} hook
 72.1388 -(section~\ref{sec:hook:commit}) is run before this hook.
 72.1389 -
 72.1390 -See also: \hook{pretag} (section~\ref{sec:hook:pretag})
 72.1391 -
 72.1392 -\subsection{\hook{update}---after updating or merging working directory}
 72.1393 -\label{sec:hook:update}
 72.1394 -
 72.1395 -This hook is run after an update or merge of the working directory
 72.1396 -completes.  Since a merge can fail (if the external \command{hgmerge}
 72.1397 -command fails to resolve conflicts in a file), this hook communicates
 72.1398 -whether the update or merge completed cleanly.
 72.1399 -
 72.1400 -\begin{itemize}
 72.1401 -\item[\texttt{error}] A boolean.  Indicates whether the update or
 72.1402 -  merge completed successfully.
 72.1403 -\item[\texttt{parent1}] A changeset ID.  The ID of the parent that the
 72.1404 -  working directory was updated to.  If the working directory was
 72.1405 -  merged, it will not have changed this parent.
 72.1406 -\item[\texttt{parent2}] A changeset ID.  Only set if the working
 72.1407 -  directory was merged.  The ID of the revision that the working
 72.1408 -  directory was merged with.
 72.1409 -\end{itemize}
 72.1410 -
 72.1411 -See also: \hook{preupdate} (section~\ref{sec:hook:preupdate})
 72.1412 -
 72.1413 -%%% Local Variables: 
 72.1414 -%%% mode: latex
 72.1415 -%%% TeX-master: "00book"
 72.1416 -%%% End: 
    73.1 --- a/fr/htlatex.book	Sun Aug 16 03:41:39 2009 +0200
    73.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.3 @@ -1,12 +0,0 @@
    73.4 -#!/bin/bash
    73.5 -#
    73.6 -# This script is horrible.  It's essentially a hacked copy of
    73.7 -# /usr/bin/htlatex from Fedora Core 6.  I apologise for any lasting
    73.8 -# pain reading it causes.
    73.9 -
   73.10 -latex $5 '\makeatletter\def\HCode{\futurelet\HCode\HChar}\def\HChar{\ifx"\HCode\def\HCode"##1"{\Link##1}\expandafter\HCode\else\expandafter\Link\fi}\def\Link#1.a.b.c.{\g@addto@macro\@documentclasshook{\RequirePackage[#1,html]{tex4ht}}\let\HCode\documentstyle\def\documentstyle{\let\documentstyle\HCode\expandafter\def\csname tex4ht\endcsname{#1,html}\def\HCode####1{\documentstyle[tex4ht,}\@ifnextchar[{\HCode}{\documentstyle[tex4ht]}}}\makeatother\HCode '$2'.a.b.c.\input ' $1
   73.11 -(cd $4 && bibtex hgbook)
   73.12 -(cd $4 && makeindex hgbook)
   73.13 -latex $5 '\makeatletter\def\HCode{\futurelet\HCode\HChar}\def\HChar{\ifx"\HCode\def\HCode"##1"{\Link##1}\expandafter\HCode\else\expandafter\Link\fi}\def\Link#1.a.b.c.{\g@addto@macro\@documentclasshook{\RequirePackage[#1,html]{tex4ht}}\let\HCode\documentstyle\def\documentstyle{\let\documentstyle\HCode\expandafter\def\csname tex4ht\endcsname{#1,html}\def\HCode####1{\documentstyle[tex4ht,}\@ifnextchar[{\HCode}{\documentstyle[tex4ht]}}}\makeatother\HCode '$2'.a.b.c.\input ' $1
   73.14 -latex $5 '\makeatletter\def\HCode{\futurelet\HCode\HChar}\def\HChar{\ifx"\HCode\def\HCode"##1"{\Link##1}\expandafter\HCode\else\expandafter\Link\fi}\def\Link#1.a.b.c.{\g@addto@macro\@documentclasshook{\RequirePackage[#1,html]{tex4ht}}\let\HCode\documentstyle\def\documentstyle{\let\documentstyle\HCode\expandafter\def\csname tex4ht\endcsname{#1,html}\def\HCode####1{\documentstyle[tex4ht,}\@ifnextchar[{\HCode}{\documentstyle[tex4ht]}}}\makeatother\HCode '$2'.a.b.c.\input ' $1
   73.15 -echo status $$
    74.1 --- a/fr/intro.tex	Sun Aug 16 03:41:39 2009 +0200
    74.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.3 @@ -1,617 +0,0 @@
    74.4 -\chapter{Introduction}
    74.5 -\label{chap:intro}
    74.6 -
    74.7 -\section{À propos de la gestion source}
    74.8 -
    74.9 -La gestion de sources est un processus permettant de gérer différentes
   74.10 -versions de la même information. Dans sa forme la plus simple, c'est
   74.11 -ce que tout le monde fait manuellement : quand vous modifiez
   74.12 -un fichier, vous le sauvegardez sous un nouveau nom contenant un numéro,
   74.13 -à chaque fois plus grand que celui de la version précédente.
   74.14 -
   74.15 -Ce genre de gestion de version manuelle est cependant facilement sujette 
   74.16 -à des erreurs, ainsi, depuis longtemps, des logiciels existent pour
   74.17 -résoudre cette problématique. Les premiers outils de gestion de sources
   74.18 -étaient destinés à aider un seul utilisateur, à automatiser la gestion
   74.19 -des versions d'un seul fichier. Dans les dernières décades, cette cible 
   74.20 -s'est largement agrandie, ils gèrent désormais de multiples fichiers, et
   74.21 -aident un grand nombre de personnes à travailler ensemble. Les outils les
   74.22 -plus modernes n'ont aucune difficulté à gérer plusieurs milliers de 
   74.23 -personnes travaillant ensemble sur des projets regroupant plusieurs 
   74.24 -centaines de milliers de fichiers.
   74.25 -
   74.26 -\subsection{Pourquoi utiliser un gestionnaire de source ?}
   74.27 -
   74.28 -Il y a de nombreuses raisons pour que vous ou votre équipe souhaitiez
   74.29 -utiliser un outil automatisant la gestion de version pour votre projet.
   74.30 -\begin{itemize}
   74.31 -\item L'outil se chargera de suivre l'évolution de votre projet, sans
   74.32 -que vous n'ayez à le faire. Pour chaque modification, vous aurez à votre
   74.33 -disposition un journal indiquant \emph{qui} a fait quoi, \emph{pourquoi}
   74.34 -ils l'ont fait, \emph{quand} ils l'ont fait, et \emph{ce} qu'ils ont
   74.35 -modifiés.
   74.36 -\item Quand vous travaillez avec d'autres personnes, les logiciels de 
   74.37 -gestion de source facilitent le travail collaboratif. Par exemple, quand
   74.38 -plusieurs personnes font, plus ou moins simultanément, des modifications
   74.39 -incompatibles, le logiciel vous aidera à identifier et à résoudre les conflits.
   74.40 -\item L'outil vous aidera à réparer vos erreurs. Si vous effectuez un changement
   74.41 -qui se révèle être une erreur, vous pourrez revenir à une version
   74.42 -antérieure d'un fichier ou même d'un ensemble de fichiers. En fait, un outil de
   74.43 -gestion de source \emph{vraiment} efficace vous permettra d'identifier à quel
   74.44 -moment le problème est apparu (voir la section~\ref{sec:undo:bisect} pour plus
   74.45 -de détails).
   74.46 -\item L'outil vous permettra aussi de travailler sur plusieurs versions différentes
   74.47 -de votre projet et à gérer l'écart entre chacune.
   74.48 -\end{itemize}
   74.49 -La plupart de ces raisons ont autant d'importances ---du moins en théorie--- que
   74.50 -vous travailliez sur un projet pour vous, ou avec une centaine d'autres
   74.51 -personnes.
   74.52 -
   74.53 -Une question fondamentale à propos des outils de gestion de source, qu'il s'agisse
   74.54 -du projet d'une personne ou d'une grande équipe, est quels sont ses  
   74.55 -\emph{avantages} par rapport à ses \emph{coûts}. Un outil qui est difficile à 
   74.56 -utiliser ou à comprendre exigera un lourd effort d'adaptation.
   74.57 -
   74.58 -Un projet de cinq milles personnes s'effondrera très certainement de lui même
   74.59 -sans aucun processus et outil de gestion de source. Dans ce cas, le coût 
   74.60 -d'utilisation d'un logiciel de gestion de source est dérisoire puisque 
   74.61 -\emph{sans}, l'échec est presque garanti.
   74.62 -
   74.63 -D'un autre coté, un ``rapide hack'' d'une personne peut sembler un contexte
   74.64 -bien pauvre pour utiliser un outil de gestion de source, car, bien évidement
   74.65 -le coût d'utilisation dépasse le coût total du projet. N'est ce pas ?
   74.66 -
   74.67 -Mercurial supporte ces \emph{deux} échelles de travail. Vous pouvez apprendre
   74.68 -les bases en quelques minutes seulement, et, grâce à sa performance, vous pouvez
   74.69 -l'utiliser avec facilité sur le plus petit des projets. Cette simplicité 
   74.70 -signifie que vous n'avez pas de concept obscurs ou de séquence de commandes
   74.71 -défiant l'imagination, sans aucune corrélation avec \emph{ce que vous êtes 
   74.72 -vraiment en train de faire}. En même temps, ces mêmes performances et sa 
   74.73 -nature ``peer-to-peer'' vous permettent d'augmenter, sans difficulté, son 
   74.74 -utilisation à de très grands projets.
   74.75 -
   74.76 -Aucun outil de gestion de source ne peut sauver un projet mal mené, mais un
   74.77 -bon outil peut rendre beaucoup plus fluide votre travail.
   74.78 -
   74.79 -\subsection{Les multiples noms de la gestion de source}
   74.80 -
   74.81 -La gestion de source\footnote{NdT: J'ai utilisé systématiquement le terme
   74.82 -``gestion de source'' à travers tout l'ouvrage. Ce n'est pas forcement la
   74.83 -meilleure traduction, et ceci peut rendre la lecture un peu lourde, mais je
   74.84 -pense que le document y gagne en clarté et en précision.} est un domaine
   74.85 -divers, tellement qu'il n'existe pas une seul nom ou acronyme pour le désigner.
   74.86 -Voilà quelqu'uns des noms ou 
   74.87 -acronymes que vous rencontrerez le plus souvent\footnote{NdT: J'ai conservé la
   74.88 -liste des noms en anglais pour des raisons de commodité (ils sont plus
   74.89 -``googelable''). En outre, j'ai opté  pour conserver l'ensemble des opérations de
   74.90 -Mercurial (\textit{commit},\textit{push}, \textit{pull},...) en anglais, là
   74.91 -aussi pour faciliter la lecture d'autres documents en anglais, ainsi que
   74.92 -l'utilisation de Mercurial}.
   74.93 -
   74.94 -:
   74.95 -\begin{itemize}
   74.96 -\item \textit{Revision control (RCS)} ;
   74.97 -\item Software configuration management (SCM), ou \textit{configuration management} ;
   74.98 -\item \textit{Source code management} ;
   74.99 -\item \textit{Source code control}, ou \textit{source control} ;
  74.100 -\item \textit{Version control (VCS)}.
  74.101 -\end{itemize}
  74.102 -
  74.103 -Certaines personnes prétendent que ces termes ont en fait des sens
  74.104 -différents mais en pratique ils se recouvrent tellement qu'il n'y a pas
  74.105 -réellement de manière pertinente de les distinguer.
  74.106 -
  74.107 -\section{Une courte histoire de la gestion de source}
  74.108 -
  74.109 -Le plus célèbre des anciens outils de gestion de source est \textit{SCCS
  74.110 -(Source Code Control System)}, que Marc Rochkind conçu dans les laboratoires de
  74.111 -recherche de Bell (\textit{Bell Labs}), dans le début des années 70.
  74.112 -\textit{SCCS} ne fonctionnait que sur des fichiers individuels, et obligeait chaque 
  74.113 -personne travaillant sur le projet d'avoir un accès à un répertoire de
  74.114 -travail commun, sur le même système. Seulement une seule personne pouvait
  74.115 -modifier un fichier au même moment, ce fonctionnement était assuré par
  74.116 -l'utilisation de verrou (``lock''). Il était courant que des personnes
  74.117 -verrouillent des fichiers, et plus tard, oublient de le déverrouiller;
  74.118 -empêchant n'importe qui d'autre de travailler sur ces fichiers sans l'aide de
  74.119 -l'administrateur...
  74.120 -
  74.121 -Walter Tichy a développé une alternative libre à \textit{SCCS} au début des
  74.122 -années 80, qu'il nomma \textit{RSC (Revison Control System)}.  Comme
  74.123 -\textit{SCCS}, \textit{RCS} demandait aux développeurs de travailler sur le même
  74.124 -répertoire partagé, et de verrouiller les
  74.125 -fichiers pour se prémunir de tout conflit issu de modifications concurrentes.
  74.126 -
  74.127 -Un peu plus tard dans les années 1980, Dick Grune utilisa \textit{RCS} comme
  74.128 -une brique de base pour un ensemble de scripts \textit{shell} qu'il intitula
  74.129 -cmt, avant de la renommer en \textit{CVS (Concurrent Versions System)}.  La
  74.130 -grande innovation de CVS était que les développeurs pouvaient travailler
  74.131 -simultanément et indépendamment dans leur propre espace de travail. Ces espaces
  74.132 -de travail privés assuraient que les développeurs ne se marchent pas
  74.133 -mutuellement sur les pieds, comme c'était souvent le cas avec RCS et SCCS.
  74.134 -Chaque développeur disposait donc de sa copie de tous les fichiers du projet,
  74.135 -et ils pouvaient donc librement les modifier. Ils devaient néanmoins effectuer
  74.136 -la ``fusion'' (\textit{``merge''}) de leurs fichiers, avant d'effectuer le
  74.137 -``commit'' de leur modifications sur le dépôt central.
  74.138 -
  74.139 -Brian Berliner reprit les scripts de Grune's et les réécrit en~C, qu'il publia
  74.140 -en 1989. Depuis, ce code a été modifié jusqu'à devenir la version moderne de
  74.141 -CVS. CVS a acquis ainsi la capacité de fonctionner en réseau, transformant son
  74.142 -architecture en client/serveur. L'architecture de CVS est centralisée, seul le
  74.143 -serveur a une copie de l'historique du projet. L'espace de travail client ne
  74.144 -contient qu'une copie de la dernière version du projet, et quelques métadonnées
  74.145 -pour indiquer où le serveur se trouve. CVS a été un grand succès, aujourd'hui
  74.146 -il est probablement l'outil de gestion de contrôle le plus utilisé au monde. 
  74.147 -
  74.148 -Au début des années 1990, Sun Microsystmes développa un premier outil de
  74.149 -gestion de source distribué, nommé TeamWare. Un espace de travail TeamWare
  74.150 -contient une copie complète de l'historique du projet. TeamWare n'a pas de
  74.151 -notion de dépôt central. (CVS utilisait RCS pour le stockage de l'historique,
  74.152 -TeamWare utilisait SCCS).
  74.153 -
  74.154 -Alors que les années 1990 avançaient, les utilisateurs ont pris conscience d'un
  74.155 -certain nombre de problèmes avec CVS. Il enregistrait simultanément des
  74.156 -modifications sur différents fichiers individuellement, au lieu de les
  74.157 -regrouper dans une seule opération cohérente et atomique. Il ne gère pas bien
  74.158 -sa hiérarchie de fichier, il est donc assez aisé de créer le chaos en renommant
  74.159 -les fichiers et les répertoires. Pire encore, son code source est difficile à
  74.160 -lire et à maintenir, ce qui agrandit largement le ``niveau de souffrance''
  74.161 -associé à la réparation de ces problèmes d'architecture de manière prohibitive. 
  74.162 -
  74.163 -En 2001, Jim Blandy et Karl Fogel, deux développeurs qui avaient travaillé sur
  74.164 -CVS, initièrent un projet pour le remplacer par un outil qui aurait une
  74.165 -meilleure architecture et un code plus propre. Le résultat, Subversion, ne
  74.166 -quitte pas le modèle centralisé et client/server de CVS, mais ajoute les
  74.167 -opérations de ``commit'' atomique sur de multiples fichiers, une meilleure
  74.168 -gestion des espaces de noms, et d'autres fonctionnalités qui en font un
  74.169 -meilleur outil que CVS. Depuis sa première publication, il est rapidement
  74.170 -devenu très populaire.
  74.171 -
  74.172 -Plus ou moins simultanément, Graydon Hoare a commencé sur l'ambitieux
  74.173 -système de gestion distribué Monotone. Bien que Monotone corrige plusieurs
  74.174 -défauts de CVS's tout en offrant une architecture ``peer-to-peer'', il va aussi
  74.175 -plus loin que la plupart des outils de révision de manière assez innovante. Il
  74.176 -utilise des ``hash'' cryptographiques comme identifiants, et il a une notion
  74.177 -complète de ``confiance'' du code issu des différentes sources.
  74.178 -
  74.179 -Mercurial est né en 2005. Bien que très influencé par Monotone, Mercurial se
  74.180 -concentre sur la facilité d'utilisation, les performances et la capacité à
  74.181 -monter en charge pour de très gros projets.
  74.182 -
  74.183 -\section{Tendances de la gestion de source}
  74.184 -
  74.185 -Il y a eu une tendance évidente dans le développement et l'utilisation d'outils
  74.186 -de gestion de source depuis les quatre dernières décades, au fur et à mesure
  74.187 -que les utilisateurs se sont habitués à leur outils et se sont sentis contraints
  74.188 -par leurs limitations.
  74.189 -
  74.190 -La première génération commença simplement par gérer un fichier unique sur un
  74.191 -ordinateur individuel. Cependant, même si ces outils présentaient une grande
  74.192 -avancée par rapport à la gestion manuelle des versions, leur modèle de
  74.193 -verrouillage et leur utilisation limitée à un seul ordinateur rendaient leur
  74.194 -utilisation possible uniquement dans une très petite équipe. 
  74.195 -
  74.196 -La seconde génération a assoupli ces contraintes en adoptant une architecture
  74.197 -réseau et centralisée, permettant de gérer plusieurs projets entiers en même
  74.198 -temps. Alors que les projets grandirent en taille, ils rencontrèrent de nouveaux
  74.199 -problèmes. Avec les clients discutant régulièrement avec le serveurs, la montée
  74.200 -en charge devint un réel problème sur les gros projets. Une connexion réseau
  74.201 -peu fiable pouvait complètement empêcher les utilisateurs distants de dialoguer
  74.202 -avec le serveur. Alors que les projets \textit{Open Source} commencèrent à
  74.203 -mettre en place des accès en lecture seule disponible anonymement, les
  74.204 -utilisateurs sans les privilèges de ``commit'' réalisèrent qu'ils ne pouvaient
  74.205 -pas utiliser les outils pour collaborer naturellement avec le projet, comme ils
  74.206 -ne pouvaient pas non plus enregistrer leurs modifications.
  74.207 -
  74.208 -La génération actuelle des outils de gestion de source est ``peer-to-peer'' par
  74.209 -nature. Tout ces systèmes ont abandonné la dépendance à un serveur central, et
  74.210 -ont permis à leur utilisateur de distribuer les données de leur gestion de
  74.211 -source à qui en a besoin. La collaboration à travers Internet a transformé la
  74.212 -contrainte technologique en une simple question de choix et de consencus. Les
  74.213 -outils modernes peuvent maintenant fonctionner en mode déconnecté sans limite et
  74.214 -de manière autonome, la connexion au réseau n'étant nécessaire que pour
  74.215 -synchroniser les modifications avec les autres dépôts.
  74.216 -
  74.217 -\section{Quelques avantages des gestionnaires de source distribués}
  74.218 -
  74.219 -Même si les gestionnaire de source distribués sont depuis plusieurs années
  74.220 -assez robustes et aussi utilisables que leurs prédécesseurs, les utilisateurs
  74.221 -d'autres outils n'y ont pas encore été sensibilisés. Les gestionnaires
  74.222 -de source distribués se distinguent particulièrement de leurs équivalents
  74.223 -centralisés de nombreuses manières.
  74.224 -
  74.225 -Pour un développeur individuel, ils restent beaucoup plus rapides que les
  74.226 -outils centralisés. Cela pour une raison simple : un outil centralisé doit
  74.227 -toujours dialoguer à travers le réseau pour la plupart des opérations, car
  74.228 -presque toutes les métadonnées sont stockées sur la seule copie du serveur
  74.229 -central. Un outil distribué stocke toute ses métadonnées localement. À tâche
  74.230 -égale, effectuer un échange avec le réseau ajoute un délai aux outils 
  74.231 -centralisés. Ne sous-estimez pas la valeur d'un outil rapide : vous allez
  74.232 -passer beaucoup de temps à interagir avec un logiciel de gestion de source.
  74.233 -
  74.234 -Les outils distribués sont complètement indépendants des aléas de votre serveur,
  74.235 -d'autant plus qu'ils répliquent les métadonnées à beaucoup d'endroits. Si
  74.236 -votre serveur central prend feu, vous avez intérêt à ce que les médias de 
  74.237 -sauvegardes soient fiables, et que votre dernier ``backup'' soit récent et
  74.238 -fonctionne sans problème. Avec un outil distribué, vous avez autant de 
  74.239 -``backup'' que de contributeurs.
  74.240 -
  74.241 -En outre, la fiabilité de votre réseau affectera beaucoup moins les
  74.242 -outils distribués. Vous ne pouvez même pas utiliser un outil centralisé
  74.243 -sans connexion réseau, à l'exception de quelques commandes, très limitées. 
  74.244 -Avec un outil distribué, si votre connexion réseau tombe pendant que vous
  74.245 -travaillez, vous pouvez ne même pas vous en rendre compte. La seule chose
  74.246 -que vous ne serez pas capable de faire sera de communiquer avec des dépôts
  74.247 -distants, opération somme toute assez rare en comparaison aux opérations
  74.248 -locales. Si vous avez une équipe de collaborateurs très dispersée ceci peut
  74.249 -être significatif.
  74.250 -
  74.251 -\subsection{Avantages pour les projets \textit{Open Source}}
  74.252 -
  74.253 -Si vous prenez goût à un projet \textit{Open Source} et que vous
  74.254 -décidez de commencer à toucher à son code, et que le projet utilise
  74.255 -un gestionnaire de source distribué, vous êtes immédiatement un "pair"
  74.256 -avec les personnes formant le ``cœur'' du projet. Si ils publient
  74.257 -leurs dépôts, vous pouvez immédiatement copier leurs historiques de
  74.258 -projet, faire des modifications, enregistrer votre travail en utilisant
  74.259 -les même outils qu'eux. Par comparaison, avec un outil centralisé, vous
  74.260 -devez utiliser un logiciel en mode ``lecture seule'' à moins que 
  74.261 -quelqu'un ne vous donne les privilèges de ``commit'' sur le serveur
  74.262 -central. Avant ça, vous ne serez pas capable d'enregistrer vos 
  74.263 -modifications, et vos propres modifications risqueront de se 
  74.264 -corrompre chaque fois que vous essayerez de mettre à jour à votre
  74.265 -espace de travail avec le serveur central.
  74.266 -
  74.267 -\subsubsection{Le non-problème du \textit{fork}}
  74.268 -
  74.269 -Il a été souvent suggéré que les gestionnaires de source distribués
  74.270 -posent un risque pour les projets \textit{Open Source} car ils 
  74.271 -facilitent grandement la création de ``fork''\footnote{NdT:Création 
  74.272 -d'une 
  74.273 -\url{version alternative du logiciel}{http://fr.wikipedia.org/wiki/Fork\#Embranchement\_d.27un\_projet\_informatique}.}
  74.274 -Un ``fork'' apparait quand il y des divergences d'opinion ou d'attitude
  74.275 -au sein d'un groupe de développeurs qui aboutissent à la décision de ne 
  74.276 -plus travailler ensemble. Chaque parti s'empare d'une copie plus ou moins
  74.277 -complète du code source du projet et continue dans sa propre direction.
  74.278 -
  74.279 -Parfois ces différents partis décident de se réconcilier. Avec un 
  74.280 -serveur central, l'aspect \emph{technique} de cette réconciliation
  74.281 -est un processus douloureux, et essentiellement manuel. Vous devez
  74.282 -décider quelle modification est ``la gagnante'', et replacer, par un
  74.283 -moyen ou un autre, les modifications de l'autre équipe dans l'arborescence
  74.284 -du projet. Ceci implique généralement la perte d'une partie de l'historique 
  74.285 -d'un des partis, ou même des deux.
  74.286 -
  74.287 -Ce que les outils distribués permettent à ce sujet est probablement
  74.288 -la \emph{meilleure} façon de développer un projet. Chaque modification
  74.289 -que vous effectuez est potentiellement un ``fork''. La grande force de 
  74.290 -cette approche est que les gestionnaires de source distribués doivent être
  74.291 -vraiment très efficaces pour \emph{fusionner}\footnote{NdT:j'ai choisi de
  74.292 -traduire ici \textit{merging} par ``fusionner'' pour des raisons de clarté}
  74.293 -des ``forks'', car les ``forks'', dans ce contexte, arrivent tout le
  74.294 -temps.
  74.295 -
  74.296 -Si chaque altération que n'importe qui effectue, à tout moment, est vue
  74.297 -comme un ``fork'' à fusionner, alors ce que le monde de l'\textit{Open 
  74.298 -Source} voit comme un ``fork'' devient \emph{uniquement} une problématique 
  74.299 -sociale. En fait, les outils de gestions de source distribués \emph{réduisent} 
  74.300 -les chances de ``fork'':
  74.301 -\begin{itemize}
  74.302 -\item Ils éliminent la distinction sociale qu'imposent les outils centralisés
  74.303 -    entre les membres du projets (ceux qui ont accès au ``commit'') et ceux de
  74.304 -    l'extérieur (ce qui ne l'ont pas).  \item Ils rendent plus facile la
  74.305 -    réconciliation après un ``fork'' social, car
  74.306 -	tout ce qu'elle implique est une simple fusion.
  74.307 -\end{itemize}
  74.308 -
  74.309 -Certaines personnes font de la résistance envers les gestionnaires de source
  74.310 -distribués parce qu'ils veulent garder un contrôle ferme sur leur projet, et
  74.311 -ils pensent que les outils centralisés leur fournissent ce contrôle. Néanmoins,
  74.312 -si c'est votre cas, sachez que si vous publiez votre dépôt CVS ou Subversion
  74.313 -de manière publique, il existe une quantité d'outils disponibles pour récupérer
  74.314 -entièrement votre projet et son historique (quoique lentement) et le récréer 
  74.315 -ailleurs, sans votre contrôle. En fait, votre contrôle sur votre projet est 
  74.316 -illusoire, vous ne faites qu'interdire à vos collaborateurs de travailler
  74.317 -de manière fluide, en disposant d'un miroir ou d'un ``fork'' de votre
  74.318 -historique.
  74.319 -%%%TODO: Fussy, those last sentences are not really well translated:
  74.320 -%%%no problem for me (wilk)
  74.321 -%However, if you're of this belief, and you publish your CVS or Subversion 
  74.322 -%repositories publically, there are plenty of tools available that can pull 
  74.323 -%out your entire project's history (albeit slowly) and recreate it somewhere 
  74.324 -%that you don't control.  So while your control in this case is illusory, you are
  74.325 -%forgoing the ability to fluidly collaborate with whatever people feel
  74.326 -%compelled to mirror and fork your history.
  74.327 -
  74.328 -\subsection{Avantages pour les projets commerciaux}
  74.329 -
  74.330 -Beaucoup de projets commerciaux sont réalisés par des équipes éparpillées
  74.331 -à travers le globe. Les contributeurs qui sont loin du serveur central
  74.332 -devront subir des commandes lentes et même parfois peu fiables. Les 
  74.333 -solutions propriétaires de gestion de source tentent de palier ce problème 
  74.334 -avec des réplications de sites distants qui sont à la fois coûteuses à mettre
  74.335 -en place et lourdes à administrer. Un système distribué ne souffre pas
  74.336 -de ce genre de problèmes. En outre, il est très aisé de mettre en place
  74.337 -plusieurs serveurs de références, disons un par site, de manière à ce qu'il
  74.338 -n'y ait pas de communication redondante entre les dépôts, sur une connexion
  74.339 -longue distance souvent onéreuse.
  74.340 -
  74.341 -Les systèmes de gestion de source supportent généralement assez mal la 
  74.342 -montée en charge. Ce n'est pas rare pour un gestionnaire de source centralisé 
  74.343 -pourtant onéreux de s'effondrer sous la charge combinée d'une douzaine 
  74.344 -d'utilisateurs concurrents seulement. Une fois encore, la réponse à cette problématique 
  74.345 -est généralement encore la mise en place d'un ensemble complexe de serveurs
  74.346 -synchronisés par un mécanisme de réplication. Dans le cas d'un gestionnaire
  74.347 -de source distribué, la charge du serveur central --- si vous avez un--- est
  74.348 -plusieurs fois inférieure (car toutes les données sont déjà répliquées ailleurs),
  74.349 -un simple serveur, pas très cher, peut gérer les besoins d'une plus grande
  74.350 -équipe, et la réplication pour balancer la charge devient le
  74.351 -travail d'un simple script.
  74.352 -
  74.353 -Si vous avez des employés sur le terrain, en train de chercher à résoudre un souci sur
  74.354 -le site d'un client, ils bénéficieront aussi d'un gestionnaire de source
  74.355 -distribué. Cet outil leur permettra de générer des versions personnalisées,
  74.356 -d'essayer différentes solutions, en les isolant aisément les unes des autres,
  74.357 -et de rechercher efficacement à travers l'historique des sources, la cause
  74.358 -des bugs ou des régressions, tout ceci sans avoir besoin de la moindre 
  74.359 -connexion au réseau de votre compagnie.
  74.360 -
  74.361 -\section{Pourquoi choisir Mercurial?}
  74.362 -
  74.363 -Mercurial a plusieurs caractéristiques qui en font un choix particulièrement
  74.364 -pertinent pour la gestion de source:
  74.365 -\begin{itemize}
  74.366 -	\item Il est facile à apprendre et à utiliser ;
  74.367 -	\item Il est léger et performant ;
  74.368 -	\item Il monte facilement en charge ; 
  74.369 -	\item Il est facile à personnaliser ;
  74.370 -\end{itemize}
  74.371 -
  74.372 -Si vous êtes déjà familier d'un outil de gestion de source, vous serez
  74.373 -capable de l'utiliser en moins de 5 minutes. Sinon, ça ne sera pas beaucoup
  74.374 -plus long\footnote{NdT: Pour appuyer le propos de l'auteur, je signale que 
  74.375 -j'utilise Mercurial comme outil d'initiation à la gestion de contrôle dans
  74.376 -des travaux pratiques à l'ESME Sudria (\url{http://www.esme.fr}) et que les
  74.377 -élèves le prennent en main sans difficulté majeure malgré l'approche distribuée.}. 
  74.378 -Les commandes utilisées par Mercurial, comme ses fonctionnalités, sont 
  74.379 -généralement uniformes et cohérentes, et vous pouvez donc ainsi garder en tête 
  74.380 -simplement quelques règles générales, plutôt qu'un lot complexe d'exceptions.
  74.381 -
  74.382 -Sur un petit projet, vous pouvez commencer à travailler avec Mercurial en
  74.383 -quelques instants. Ajouter des modifications ou des branches, transférer 
  74.384 -ces modifications (localement ou via le réseau), et les opérations 
  74.385 -d'historique ou de statut sont aussi très rapides. Mercurial reste hors de 
  74.386 -votre chemin grâce à sa simplicité d'utilisation et sa rapidité d'exécution.
  74.387 -
  74.388 -L'utilité de Mercurial ne se limite pas à de petits projets: il est 
  74.389 -aussi utilisé par des projets ayant des centaines ou même des milliers
  74.390 -de contributeurs, avec plusieurs dizaines de milliers de fichiers, et des
  74.391 -centaines de méga de code source.
  74.392 -
  74.393 -Voici une liste non exhaustive des projets complexes ou critiques utilisant 
  74.394 -Mercurial :
  74.395 -%TODO
  74.396 -% For both spanish and english version, add the following examples:
  74.397 -\begin{itemize}
  74.398 -	\item \url{Firefox}{https://developer.mozilla.org/en/Mozilla\_Source\_Code\_(Mercurial)} ;
  74.399 -	\item \url{OpenSolaris}{http://opensolaris.org/os/community/tools/scm/hg\_help/} ;
  74.400 -	\item \url{OpenJDK}{http://hg.openjdk.java.net/} (utilisant en outre l'extension 
  74.401 -	``forest'' pour gérer ses sous modules);
  74.402 -\end{itemize}
  74.403 -
  74.404 -Si les fonctionnalités cœur de Mercurial ne sont pas suffisantes pour vous, 
  74.405 -il est très aisé d'en construire d'autres. Mercurial est adapté à l'utilisation
  74.406 -de scripts, et son implémentation interne en Python, propre et claire,
  74.407 -rend encore plus facile l'ajout de fonctionnalités sous forme d'extensions. Il
  74.408 -en existe déjà un certain nombre de très populaires et très utiles, 
  74.409 -dont le périmètre va de la recherche de bugs à l'amélioration des performances.
  74.410 -
  74.411 -\section{Mercurial comparé aux autres outils}
  74.412 -
  74.413 -Avant que vous n'alliez plus loin, comprenez bien que cette section
  74.414 -reflète mes propres expériences, et elle est donc (j'ose le dire)
  74.415 -peu objective. Néanmoins, j'ai utilisé les outils de gestion de source
  74.416 -listés ci dessous, dans la plupart des cas, pendant plusieurs années.
  74.417 -%% TODO: Fussy translation.
  74.418 -
  74.419 -\subsection{Subversion}
  74.420 -
  74.421 -Subversion est un des outils de gestion de source les plus populaire, il fût 
  74.422 -développé pour remplacer CVS. Il a une architecture client/server centralisée.
  74.423 -
  74.424 -Subversion et Mercurial ont des noms de commandes très similaires pour 
  74.425 -les mêmes opérations, ainsi si vous êtes familier avec l'un, c'est facile
  74.426 -d'apprendre l'autre. Ces deux outils sont portables sur les systèmes 
  74.427 -d'exploitation les plus populaires\footnote{NdT:Mercurial fonctionne sans problème
  74.428 -sur OpenVMS à l'ESME Sudria \url{http://www.esme.fr}, compte tenu que Subversion a été 
  74.429 -développé en C, je ne suis pas sûr que son portage aurait été aussi aisé.}.
  74.430 -%TODO: Backport this statement in english and spanish 
  74.431 -
  74.432 -Avant la version 1.5, Subversion n'offrait aucune forme de support pour les fusions. Lors 
  74.433 -de l'écriture de ce livre, ses capacités de fusion étaient nouvelles, et réputées pour être
  74.434 -\href{http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword}{complexes
  74.435 -et bugguées}.
  74.436 -
  74.437 -Mercurial dispose d'un avantage substantiel en terme de performance par rapport à 
  74.438 -Subversion sur la plupart des opérations que j'ai pu tester. J'ai mesuré
  74.439 -une différence de performance allant de deux à six fois plus rapide avec
  74.440 -le système de stockage de fichier local de Subversion~1.4.3 
  74.441 -(\emph{ra\_local}), qui est la méthode d'accès la plus rapide disponible. Dans
  74.442 -un déploiement plus réaliste, impliquant un stockage réseau, Subversion 
  74.443 -serait encore plus désavantagé. Parce que la plupart des commandes Subversion
  74.444 -doivent communiquer avec le serveur et que Subversion n'a pas de mécanisme
  74.445 -de réplication, la capacité du serveur et la bande passante sont devenues des
  74.446 -goulots d'étranglement pour les projets de taille moyenne ou grande.
  74.447 -
  74.448 -En outre, Subversion implique une surcharge substantielle dans le stockage local
  74.449 -de certaines données, pour éviter des transactions avec le serveur, pour 
  74.450 -certaines opérations communes, telles que la recherche des fichiers modifiés
  74.451 -(\texttt{status}) et l'affichage des modifications par rapport à la révision 
  74.452 -courante (\texttt{diff}). En conséquence, un répertoire de travail Subversion
  74.453 -a souvent la même taille, ou est plus grand, qu'un dépôt Mercurial et son
  74.454 -espace de travail, et ceci bien que le dépôt Mercurial contienne l'intégralité 
  74.455 -de l'historique.
  74.456 -
  74.457 -Subversion est largement supporté par les outils tierces. Mercurial est
  74.458 -actuellement encore en retrait de ce point de vue. L'écart se réduit, néanmoins,
  74.459 -et en effet certains des outils graphiques sont maintenant supérieurs à leurs
  74.460 -équivalents Subversion. Comme Mercurial, Subversion dispose d'un excellent
  74.461 -manuel utilisateur.
  74.462 -
  74.463 -Parce que Subversion ne stocke pas l'historique chez ses clients, il est 
  74.464 -parfaitement adapté à la gestion de projets qui doivent suivre un ensemble
  74.465 -de larges fichiers binaires et opaques. Si vous suivez une cinquantaine de
  74.466 -versions d'un fichier incompressible de 10MB, l'occupation disque coté client
  74.467 -d'un projet sous Subversion restera à peu près constante. A l'inverse, 
  74.468 -l'occupation disque du même projet sous n'importe lequel des gestionnaires
  74.469 -de source distribués grandira rapidement, proportionnellement aux nombres
  74.470 -de versions, car les différences entre chaque révisions seront très grandes.
  74.471 -
  74.472 -En outre, c'est souvent difficile ou, généralement, impossible de fusionner
  74.473 -des différences dans un fichier binaire. La capacité de Subversion de 
  74.474 -verrouiller des fichiers, pour permettre à l'utilisateur d'être le seul
  74.475 -à le mettre à jour (``commit'') temporairement, est un avantage significatif
  74.476 -dans un projet doté de beaucoup de fichiers binaires.
  74.477 -
  74.478 -Mercurial peut importer l'historique depuis un dépôt Subversion. Il peut
  74.479 -aussi exporter l'ensemble des révisions d'un projet vers un dépôt Subversion.
  74.480 -Ceci rend très facile de ``prendre la température'' et d'utiliser Mercurial et Subversion
  74.481 -en parallèle, avant de décider de migrer vers Mercurial. La conversion de 
  74.482 -l'historique est incrémentale, donc vous pouvez effectuer une conversion 
  74.483 -initiale, puis de petites additions par la suite pour ajouter les nouvelles
  74.484 -modifications.
  74.485 -
  74.486 -\subsection{Git}
  74.487 -
  74.488 -Git est un outil de gestion de source distribué qui fût développé pour gérer
  74.489 -le code source de noyau de Linux. Comme Mercurial, sa conception initiale a 
  74.490 -été inspirée par Monotone.
  74.491 -
  74.492 -Git dispose d'un ensemble conséquent de commandes, avec plus de~139 commandes
  74.493 -individuelles pour la version~1.5.0. Il a aussi la réputation d'être difficile
  74.494 -à apprendre. Comparé à Git, le point fort de Mercurial est clairement sa 
  74.495 -simplicité.
  74.496 -
  74.497 -En terme de performance, Git est extrêmement rapide. Dans la plupart des
  74.498 -cas, il est plus rapide que Mercurial, tout du moins sur Linux, alors que 
  74.499 -Mercurial peut être plus performant sur d'autres opérations. Néanmoins, sur
  74.500 -Windows, les performances et le niveau de support général fourni par Git, 
  74.501 -au moment de l'écriture de cet ouvrage, est bien derrière celui de Mercurial.
  74.502 -
  74.503 -Alors que le dépôt Mercurial ne demande aucune maintenance, un dépôt Git
  74.504 -exige d'exécuter manuellement et régulièrement la commande ``repacks'' sur
  74.505 -ces métadonnées. Sans ceci, les performances de git se dégradent et la 
  74.506 -consommation de l'espace disque augmente rapidement. Un serveur qui contient
  74.507 -plusieurs dépôts Git qui ne sont pas régulièrement et fréquemment ``repacked''
  74.508 -deviendra un vrai problème lors des ``backups'' du disque, et il y eu des
  74.509 -cas, où un ``backup'' journalier pouvait durer plus de~24 heures. Un dépôt
  74.510 -fraichement ``repacked'' sera légèrement plus petit qu'un dépôt Mercurial,
  74.511 -mais un dépôt non ``repacked'' est beaucoup plus grand.
  74.512 -
  74.513 -Le cœur de Git est écrit en C. La plupart des commandes Git sont implémentées
  74.514 -sous forme de scripts Shell ou Perl, et la qualité de ces scripts varie
  74.515 -grandement. J'ai plusieurs fois constaté que certains de ces scripts étaient
  74.516 -chargés en mémoire aveuglément et que la présence d'erreurs pouvait s'avérer
  74.517 -fatal.
  74.518 -
  74.519 -Mercurial peut importer l'historique d'un dépôt Git.
  74.520 -
  74.521 -\subsection{CVS}
  74.522 -
  74.523 -CVS est probablement l'outil de gestion de source le plus utilisé aujourd'hui
  74.524 -dans le monde. À cause de son manque de clarté interne, il n'est plus 
  74.525 -maintenu depuis plusieurs années.
  74.526 -
  74.527 -Il a une architecture client/serveur centralisée. Il ne regroupe pas les
  74.528 -modifications de fichiers dans une opération de ``commit'' atomique, ce
  74.529 -qui permet à ses utilisateurs de ``casser le \textit{build}'' assez
  74.530 -facilement : une personne peut effectuer une opération de ``commit'' 
  74.531 -sans problème puis être bloquée par besoin de fusion, avec comme conséquence
  74.532 -néfaste, que les autres utilisateurs ne récupèreront qu'une partie de ses
  74.533 -modifications. Ce problème affecte aussi la manière de travailler avec 
  74.534 -l'historique du projet. Si vous voulez voir toutes les modifications d'une
  74.535 -personne du projet, vous devrez injecter manuellement les descriptions et les
  74.536 -\textit{timestamps} des modifications de chacun des fichiers impliqués (si
  74.537 -vous savez au moins quels sont ces fichiers).
  74.538 -
  74.539 -CVS a une notion étrange des \textit{tags} et des branches que je n'essayerai
  74.540 -même pas de décrire ici. Il ne supporte pas bien les opérations de renommage d'un 
  74.541 -fichier ou d'un répertoire, ce qui facilite la corruption de son dépôt. Il n'a
  74.542 -presque pas pour ainsi dire de contrôle de cohérence interne, il est donc 
  74.543 -pratiquement impossible de dire si un dépôt est corrompu ni à quel point. Je
  74.544 -ne recommanderai pas CVS pour un projet existant ou nouveau.
  74.545 -
  74.546 -Mercurial peut importer l'historique d'un projet CVS. Néanmoins, il y a 
  74.547 -quelques principes à respecter; ce qui est vrai aussi pour les autres
  74.548 -outils d'import de projet CVS. À cause de l'absence de ``commit'' atomique
  74.549 -et gestion de version de l'arborescence, il n'est pas possible de reconstruire
  74.550 -de manière précise l'ensemble de l'historique. Un travail de ``devinette''
  74.551 -est donc nécessaire, et les fichiers renommés ne sont pas détectés. Parce 
  74.552 -qu'une bonne part de l'administration d'un dépôt CVS est effectuée manuellement, 
  74.553 -et est donc, sujette à erreur, il est courant que les imports CVS rencontrent 
  74.554 -de nombreux problèmes avec les dépôt corrompus (des \textit{timestamps} 
  74.555 -de révision complètement buggés et des fichiers verrouillés depuis des années 
  74.556 -sont deux des problèmes les moins intéressants dont je me souvienne).
  74.557 -
  74.558 -Mercurial peut importer l'historique depuis un dépôt CVS.
  74.559 -
  74.560 -\subsection{Outils propriétaires} 
  74.561 -
  74.562 -Perforce a une architecture client/serveur centralisée, sans aucun
  74.563 -mécanisme de mise en cache de données coté client. Contrairement à la plupart
  74.564 -des outils modernes de gestion de source, Perforce exige de ses 
  74.565 -utilisateurs d'exécuter une commande pour informer le serveur
  74.566 -central de tout fichier qu'ils souhaitent modifier.
  74.567 -
  74.568 -Les performances de Perforce sont plutôt bonnes pour des petites
  74.569 -équipes, mais elles s'effondrent rapidement lorsque le nombre 
  74.570 -d'utilisateurs augmente au delà de la douzaine. Des installations 
  74.571 -de Perforce assez larges nécessitent le déploiement de proxies pour 
  74.572 -supporter la montée en charge associée.
  74.573 -
  74.574 -\subsection{Choisir un outil de gestion de source}
  74.575 -
  74.576 -A l'exception de CVS, tous les outils listés ci-dessus ont des 
  74.577 -forces qui leur sont propres et qui correspondent à certaines
  74.578 -formes de projet. Il n'y a pas un seul meilleur outil de gestion
  74.579 -de source qui correspondrait le mieux à toutes les situations.
  74.580 -
  74.581 -Par exemple, Subversion est un très bon choix lorsqu'on travaille
  74.582 -avec beaucoup de fichiers binaires, qui évoluent régulièrement, grâce
  74.583 -à sa nature centralisée et sa capacité à verrouiller des fichiers.
  74.584 -
  74.585 -Personnellement, je préfère Mercurial pour sa simplicité, ses 
  74.586 -performances et sa bonne capacité de fusion, et il m'a très bien rendu service
  74.587 -de plusieurs années maintenant.
  74.588 -
  74.589 -\section{Migrer depuis un outil à Mercurial}
  74.590 -
  74.591 -Mercurial est livré avec une extension nommée \hgext{convert}, qui
  74.592 -peut de manière incrémentale importer des révisions depuis différents
  74.593 -autres outils de gestion de source. Par ``incrémental'', j'entends que
  74.594 -vous pouvez convertir l'historique entier du projet en une seule fois,
  74.595 -puis relancer l'outil d'import plus tard pour obtenir les modifications
  74.596 -effectuées depuis votre import initial.
  74.597 -
  74.598 -Les outils de gestion de source supportés par \hgext{convert} sont :
  74.599 -\begin{itemize}
  74.600 -	\item Subversion
  74.601 -	\item CVS
  74.602 -	\item Git
  74.603 -	\item Darcs
  74.604 -\end{itemize}
  74.605 -
  74.606 -En outre, \hgext{convert} peut exporter les modifications depuis Mercurial
  74.607 -vers Subversion. Ceci rend possible d'essayer Subversion en parallèle 
  74.608 -avant de choisir une solution définitive, sans aucun risque de perte de
  74.609 -données.
  74.610 -
  74.611 -La commande \hgxcmd{conver}{convert} est très simple à utiliser. Simplement,
  74.612 -indiquez le chemin ou l'URL du dépôt de source, en lui indiquant éventuellement
  74.613 -le nom du chemin de destination, et la conversion se met en route. Après cet
  74.614 -import initial, il suffit de relancer la commande encore une fois pour 
  74.615 -importer les modifications effectuées depuis.
  74.616 -
  74.617 -%%% Local Variables: 
  74.618 -%%% mode: latex
  74.619 -%%% TeX-master: "00book"
  74.620 -%%% End: 
    75.1 Binary file fr/kdiff3.png has changed
    76.1 --- a/fr/license.tex	Sun Aug 16 03:41:39 2009 +0200
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,138 +0,0 @@
    76.4 -\chapter{Open Publication License}
    76.5 -\label{cha:opl}
    76.6 -
    76.7 -Version 1.0, 8 June 1999
    76.8 -
    76.9 -\section{Requirements on both unmodified and modified versions}
   76.10 -
   76.11 -The Open Publication works may be reproduced and distributed in whole
   76.12 -or in part, in any medium physical or electronic, provided that the
   76.13 -terms of this license are adhered to, and that this license or an
   76.14 -incorporation of it by reference (with any options elected by the
   76.15 -author(s) and/or publisher) is displayed in the reproduction.
   76.16 -
   76.17 -Proper form for an incorporation by reference is as follows:
   76.18 -
   76.19 -\begin{quote}
   76.20 -  Copyright (c) \emph{year} by \emph{author's name or designee}. This
   76.21 -  material may be distributed only subject to the terms and conditions
   76.22 -  set forth in the Open Publication License, v\emph{x.y} or later (the
   76.23 -  latest version is presently available at
   76.24 -  \url{http://www.opencontent.org/openpub/}).
   76.25 -\end{quote}
   76.26 -
   76.27 -The reference must be immediately followed with any options elected by
   76.28 -the author(s) and/or publisher of the document (see
   76.29 -section~\ref{sec:opl:options}).
   76.30 -
   76.31 -Commercial redistribution of Open Publication-licensed material is
   76.32 -permitted.
   76.33 -
   76.34 -Any publication in standard (paper) book form shall require the
   76.35 -citation of the original publisher and author. The publisher and
   76.36 -author's names shall appear on all outer surfaces of the book. On all
   76.37 -outer surfaces of the book the original publisher's name shall be as
   76.38 -large as the title of the work and cited as possessive with respect to
   76.39 -the title.
   76.40 -
   76.41 -\section{Copyright}
   76.42 -
   76.43 -The copyright to each Open Publication is owned by its author(s) or
   76.44 -designee.
   76.45 -
   76.46 -\section{Scope of license}
   76.47 -
   76.48 -The following license terms apply to all Open Publication works,
   76.49 -unless otherwise explicitly stated in the document.
   76.50 -
   76.51 -Mere aggregation of Open Publication works or a portion of an Open
   76.52 -Publication work with other works or programs on the same media shall
   76.53 -not cause this license to apply to those other works. The aggregate
   76.54 -work shall contain a notice specifying the inclusion of the Open
   76.55 -Publication material and appropriate copyright notice.
   76.56 -
   76.57 -\textbf{Severability}. If any part of this license is found to be
   76.58 -unenforceable in any jurisdiction, the remaining portions of the
   76.59 -license remain in force.
   76.60 -
   76.61 -\textbf{No warranty}. Open Publication works are licensed and provided
   76.62 -``as is'' without warranty of any kind, express or implied, including,
   76.63 -but not limited to, the implied warranties of merchantability and
   76.64 -fitness for a particular purpose or a warranty of non-infringement.
   76.65 -
   76.66 -\section{Requirements on modified works}
   76.67 -
   76.68 -All modified versions of documents covered by this license, including
   76.69 -translations, anthologies, compilations and partial documents, must
   76.70 -meet the following requirements:
   76.71 -
   76.72 -\begin{enumerate}
   76.73 -\item The modified version must be labeled as such.
   76.74 -\item The person making the modifications must be identified and the
   76.75 -  modifications dated.
   76.76 -\item Acknowledgement of the original author and publisher if
   76.77 -  applicable must be retained according to normal academic citation
   76.78 -  practices.
   76.79 -\item The location of the original unmodified document must be
   76.80 -  identified.
   76.81 -\item The original author's (or authors') name(s) may not be used to
   76.82 -  assert or imply endorsement of the resulting document without the
   76.83 -  original author's (or authors') permission.
   76.84 -\end{enumerate}
   76.85 -
   76.86 -\section{Good-practice recommendations}
   76.87 -
   76.88 -In addition to the requirements of this license, it is requested from
   76.89 -and strongly recommended of redistributors that:
   76.90 -
   76.91 -\begin{enumerate}
   76.92 -\item If you are distributing Open Publication works on hardcopy or
   76.93 -  CD-ROM, you provide email notification to the authors of your intent
   76.94 -  to redistribute at least thirty days before your manuscript or media
   76.95 -  freeze, to give the authors time to provide updated documents. This
   76.96 -  notification should describe modifications, if any, made to the
   76.97 -  document.
   76.98 -\item All substantive modifications (including deletions) be either
   76.99 -  clearly marked up in the document or else described in an attachment
  76.100 -  to the document.
  76.101 -\item Finally, while it is not mandatory under this license, it is
  76.102 -  considered good form to offer a free copy of any hardcopy and CD-ROM
  76.103 -  expression of an Open Publication-licensed work to its author(s).
  76.104 -\end{enumerate}
  76.105 -
  76.106 -\section{License options}
  76.107 -\label{sec:opl:options}
  76.108 -
  76.109 -The author(s) and/or publisher of an Open Publication-licensed
  76.110 -document may elect certain options by appending language to the
  76.111 -reference to or copy of the license. These options are considered part
  76.112 -of the license instance and must be included with the license (or its
  76.113 -incorporation by reference) in derived works.
  76.114 -
  76.115 -\begin{enumerate}[A]
  76.116 -\item To prohibit distribution of substantively modified versions
  76.117 -  without the explicit permission of the author(s). ``Substantive
  76.118 -  modification'' is defined as a change to the semantic content of the
  76.119 -  document, and excludes mere changes in format or typographical
  76.120 -  corrections.
  76.121 -
  76.122 -  To accomplish this, add the phrase ``Distribution of substantively
  76.123 -  modified versions of this document is prohibited without the
  76.124 -  explicit permission of the copyright holder.'' to the license
  76.125 -  reference or copy.
  76.126 -
  76.127 -\item To prohibit any publication of this work or derivative works in
  76.128 -  whole or in part in standard (paper) book form for commercial
  76.129 -  purposes is prohibited unless prior permission is obtained from the
  76.130 -  copyright holder.
  76.131 -
  76.132 -  To accomplish this, add the phrase ``Distribution of the work or
  76.133 -  derivative of the work in any standard (paper) book form is
  76.134 -  prohibited unless prior permission is obtained from the copyright
  76.135 -  holder.'' to the license reference or copy.
  76.136 -\end{enumerate}
  76.137 -
  76.138 -%%% Local Variables: 
  76.139 -%%% mode: latex
  76.140 -%%% TeX-master: "00book"
  76.141 -%%% End: 
    77.1 --- a/fr/metadata.svg	Sun Aug 16 03:41:39 2009 +0200
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,328 +0,0 @@
    77.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    77.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    77.6 -<svg
    77.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    77.8 -   xmlns:cc="http://web.resource.org/cc/"
    77.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   77.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   77.11 -   xmlns="http://www.w3.org/2000/svg"
   77.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   77.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   77.14 -   width="744.09448819"
   77.15 -   height="1052.3622047"
   77.16 -   id="svg2"
   77.17 -   sodipodi:version="0.32"
   77.18 -   inkscape:version="0.44.1"
   77.19 -   sodipodi:docname="metadata.svg"
   77.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en">
   77.21 -  <defs
   77.22 -     id="defs4">
   77.23 -    <marker
   77.24 -       inkscape:stockid="Arrow1Mend"
   77.25 -       orient="auto"
   77.26 -       refY="0.0"
   77.27 -       refX="0.0"
   77.28 -       id="Arrow1Mend"
   77.29 -       style="overflow:visible;">
   77.30 -      <path
   77.31 -         id="path2944"
   77.32 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   77.33 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   77.34 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   77.35 -    </marker>
   77.36 -  </defs>
   77.37 -  <sodipodi:namedview
   77.38 -     id="base"
   77.39 -     pagecolor="#ffffff"
   77.40 -     bordercolor="#666666"
   77.41 -     borderopacity="1.0"
   77.42 -     gridtolerance="10000"
   77.43 -     guidetolerance="10"
   77.44 -     objecttolerance="10"
   77.45 -     inkscape:pageopacity="0.0"
   77.46 -     inkscape:pageshadow="2"
   77.47 -     inkscape:zoom="1.4"
   77.48 -     inkscape:cx="232.14286"
   77.49 -     inkscape:cy="490.68696"
   77.50 -     inkscape:document-units="px"
   77.51 -     inkscape:current-layer="layer1"
   77.52 -     inkscape:window-width="906"
   77.53 -     inkscape:window-height="620"
   77.54 -     inkscape:window-x="181"
   77.55 -     inkscape:window-y="58" />
   77.56 -  <metadata
   77.57 -     id="metadata7">
   77.58 -    <rdf:RDF>
   77.59 -      <cc:Work
   77.60 -         rdf:about="">
   77.61 -        <dc:format>image/svg+xml</dc:format>
   77.62 -        <dc:type
   77.63 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   77.64 -      </cc:Work>
   77.65 -    </rdf:RDF>
   77.66 -  </metadata>
   77.67 -  <g
   77.68 -     inkscape:label="Layer 1"
   77.69 -     inkscape:groupmode="layer"
   77.70 -     id="layer1">
   77.71 -    <path
   77.72 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
   77.73 -       d="M 326.94646,467.18359 L 326.94646,510.98123"
   77.74 -       id="path1910"
   77.75 -       inkscape:connector-type="polyline"
   77.76 -       inkscape:connection-end="#rect2962"
   77.77 -       inkscape:connection-start="#rect2764" />
   77.78 -    <path
   77.79 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
   77.80 -       d="M 326.94646,531.98123 L 326.94646,591.77887"
   77.81 -       id="path1912"
   77.82 -       inkscape:connector-type="polyline"
   77.83 -       inkscape:connection-start="#rect2962"
   77.84 -       inkscape:connection-end="#rect3000" />
   77.85 -    <path
   77.86 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
   77.87 -       d="M 316.1622,531.98123 L 192.30212,652.57648"
   77.88 -       id="path1916"
   77.89 -       inkscape:connector-type="polyline"
   77.90 -       inkscape:connection-end="#rect3038"
   77.91 -       inkscape:connection-start="#rect2962" />
   77.92 -    <path
   77.93 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
   77.94 -       d="M 254.23217,467.18359 L 254.23216,510.98123"
   77.95 -       id="path3088"
   77.96 -       inkscape:connector-type="polyline"
   77.97 -       inkscape:connection-start="#rect1872"
   77.98 -       inkscape:connection-end="#rect2960" />
   77.99 -    <path
  77.100 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
  77.101 -       d="M 254.23215,531.98123 L 254.23215,591.77887"
  77.102 -       id="path3090"
  77.103 -       inkscape:connector-type="polyline"
  77.104 -       inkscape:connection-start="#rect2960"
  77.105 -       inkscape:connection-end="#rect2998" />
  77.106 -    <path
  77.107 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
  77.108 -       d="M 248.84002,531.98123 L 186.90999,652.57648"
  77.109 -       id="path3092"
  77.110 -       inkscape:connector-type="polyline"
  77.111 -       inkscape:connection-start="#rect2960"
  77.112 -       inkscape:connection-end="#rect3038" />
  77.113 -    <rect
  77.114 -       style="fill:#7b7df5;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.115 -       id="rect1872"
  77.116 -       width="51.42857"
  77.117 -       height="20"
  77.118 -       x="228.51788"
  77.119 -       y="446.68359" />
  77.120 -    <rect
  77.121 -       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.122 -       id="rect2764"
  77.123 -       width="51.42857"
  77.124 -       height="20"
  77.125 -       x="301.23218"
  77.126 -       y="446.68359" />
  77.127 -    <rect
  77.128 -       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.129 -       id="rect2766"
  77.130 -       width="51.42857"
  77.131 -       height="20"
  77.132 -       x="155.80359"
  77.133 -       y="446.68359" />
  77.134 -    <rect
  77.135 -       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.136 -       id="rect2768"
  77.137 -       width="51.42857"
  77.138 -       height="20"
  77.139 -       x="83.089294"
  77.140 -       y="446.68359" />
  77.141 -    <path
  77.142 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.143 -       d="M 135.01786,456.68359 L 155.30359,456.68359"
  77.144 -       id="path2770"
  77.145 -       inkscape:connector-type="polyline"
  77.146 -       inkscape:connection-start="#rect2768"
  77.147 -       inkscape:connection-end="#rect2766" />
  77.148 -    <path
  77.149 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.150 -       d="M 207.73216,456.68359 L 228.01788,456.68359"
  77.151 -       id="path2772"
  77.152 -       inkscape:connector-type="polyline"
  77.153 -       inkscape:connection-start="#rect2766"
  77.154 -       inkscape:connection-end="#rect1872" />
  77.155 -    <path
  77.156 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.157 -       d="M 280.44645,456.68359 L 300.73218,456.68359"
  77.158 -       id="path2774"
  77.159 -       inkscape:connector-type="polyline"
  77.160 -       inkscape:connection-start="#rect1872"
  77.161 -       inkscape:connection-end="#rect2764" />
  77.162 -    <path
  77.163 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  77.164 -       d="M 62.303571,456.68359 L 82.589294,456.68359"
  77.165 -       id="path2778"
  77.166 -       inkscape:connector-type="polyline"
  77.167 -       inkscape:connection-end="#rect2768" />
  77.168 -    <rect
  77.169 -       style="fill:#84f57b;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.170 -       id="rect2960"
  77.171 -       width="51.42857"
  77.172 -       height="20"
  77.173 -       x="228.51787"
  77.174 -       y="511.48123" />
  77.175 -    <rect
  77.176 -       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.177 -       id="rect2962"
  77.178 -       width="51.42857"
  77.179 -       height="20"
  77.180 -       x="301.23218"
  77.181 -       y="511.48123" />
  77.182 -    <rect
  77.183 -       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.184 -       id="rect2964"
  77.185 -       width="51.42857"
  77.186 -       height="20"
  77.187 -       x="155.80357"
  77.188 -       y="511.48123" />
  77.189 -    <rect
  77.190 -       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.191 -       id="rect2966"
  77.192 -       width="51.42857"
  77.193 -       height="20"
  77.194 -       x="83.089287"
  77.195 -       y="511.48123" />
  77.196 -    <path
  77.197 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.198 -       d="M 135.01786,521.48121 L 155.30359,521.48121"
  77.199 -       id="path2968"
  77.200 -       inkscape:connector-type="polyline" />
  77.201 -    <path
  77.202 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.203 -       d="M 207.73216,521.48121 L 228.01788,521.48121"
  77.204 -       id="path2970"
  77.205 -       inkscape:connector-type="polyline" />
  77.206 -    <path
  77.207 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.208 -       d="M 280.44645,521.48121 L 300.73218,521.48121"
  77.209 -       id="path2972"
  77.210 -       inkscape:connector-type="polyline" />
  77.211 -    <path
  77.212 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  77.213 -       d="M 62.30358,521.48121 L 82.5893,521.48121"
  77.214 -       id="path2974"
  77.215 -       inkscape:connector-type="polyline" />
  77.216 -    <rect
  77.217 -       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.218 -       id="rect2998"
  77.219 -       width="51.42857"
  77.220 -       height="20"
  77.221 -       x="228.51787"
  77.222 -       y="592.27887" />
  77.223 -    <rect
  77.224 -       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.225 -       id="rect3000"
  77.226 -       width="51.42857"
  77.227 -       height="20"
  77.228 -       x="301.23218"
  77.229 -       y="592.27887" />
  77.230 -    <rect
  77.231 -       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.232 -       id="rect3002"
  77.233 -       width="51.42857"
  77.234 -       height="20"
  77.235 -       x="155.80357"
  77.236 -       y="592.27887" />
  77.237 -    <rect
  77.238 -       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.239 -       id="rect3004"
  77.240 -       width="51.42857"
  77.241 -       height="20"
  77.242 -       x="83.089287"
  77.243 -       y="592.27887" />
  77.244 -    <path
  77.245 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.246 -       d="M 135.01786,602.27884 L 155.30359,602.27884"
  77.247 -       id="path3006"
  77.248 -       inkscape:connector-type="polyline" />
  77.249 -    <path
  77.250 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.251 -       d="M 207.73216,602.27884 L 228.01788,602.27884"
  77.252 -       id="path3008"
  77.253 -       inkscape:connector-type="polyline" />
  77.254 -    <path
  77.255 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.256 -       d="M 280.44645,602.27884 L 300.73218,602.27884"
  77.257 -       id="path3010"
  77.258 -       inkscape:connector-type="polyline" />
  77.259 -    <path
  77.260 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  77.261 -       d="M 62.30358,602.27884 L 82.5893,602.27884"
  77.262 -       id="path3012"
  77.263 -       inkscape:connector-type="polyline" />
  77.264 -    <rect
  77.265 -       style="fill:#ffced6;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.266 -       id="rect3034"
  77.267 -       width="51.42857"
  77.268 -       height="20"
  77.269 -       x="228.51787"
  77.270 -       y="653.07648" />
  77.271 -    <rect
  77.272 -       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.273 -       id="rect3038"
  77.274 -       width="51.42857"
  77.275 -       height="20"
  77.276 -       x="155.80357"
  77.277 -       y="653.07648" />
  77.278 -    <rect
  77.279 -       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  77.280 -       id="rect3040"
  77.281 -       width="51.42857"
  77.282 -       height="20"
  77.283 -       x="83.089287"
  77.284 -       y="653.07648" />
  77.285 -    <path
  77.286 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.287 -       d="M 135.01786,663.07646 L 155.30359,663.07646"
  77.288 -       id="path3042"
  77.289 -       inkscape:connector-type="polyline" />
  77.290 -    <path
  77.291 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  77.292 -       d="M 207.73216,663.07646 L 228.01788,663.07646"
  77.293 -       id="path3044"
  77.294 -       inkscape:connector-type="polyline" />
  77.295 -    <path
  77.296 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
  77.297 -       d="M 62.30358,663.07646 L 82.5893,663.07646"
  77.298 -       id="path3048"
  77.299 -       inkscape:connector-type="polyline" />
  77.300 -    <text
  77.301 -       xml:space="preserve"
  77.302 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  77.303 -       x="82.072548"
  77.304 -       y="432.64789"
  77.305 -       id="text3094"><tspan
  77.306 -         sodipodi:role="line"
  77.307 -         id="tspan3096"
  77.308 -         x="82.072548"
  77.309 -         y="432.64789">Changelog</tspan></text>
  77.310 -    <text
  77.311 -       xml:space="preserve"
  77.312 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  77.313 -       x="82.306923"
  77.314 -       y="498.97327"
  77.315 -       id="text3098"><tspan
  77.316 -         sodipodi:role="line"
  77.317 -         id="tspan3100"
  77.318 -         x="82.306923"
  77.319 -         y="498.97327">Manifest</tspan></text>
  77.320 -    <text
  77.321 -       xml:space="preserve"
  77.322 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  77.323 -       x="82.14286"
  77.324 -       y="580.08569"
  77.325 -       id="text3102"><tspan
  77.326 -         sodipodi:role="line"
  77.327 -         id="tspan3104"
  77.328 -         x="82.14286"
  77.329 -         y="580.08569">Filelogs</tspan></text>
  77.330 -  </g>
  77.331 -</svg>
    78.1 --- a/fr/mq-collab.tex	Sun Aug 16 03:41:39 2009 +0200
    78.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.3 @@ -1,393 +0,0 @@
    78.4 -\chapter{Advanced uses of Mercurial Queues}
    78.5 -\label{chap:mq-collab}
    78.6 -
    78.7 -While it's easy to pick up straightforward uses of Mercurial Queues,
    78.8 -use of a little discipline and some of MQ's less frequently used
    78.9 -capabilities makes it possible to work in complicated development
   78.10 -environments.
   78.11 -
   78.12 -In this chapter, I will use as an example a technique I have used to
   78.13 -manage the development of an Infiniband device driver for the Linux
   78.14 -kernel.  The driver in question is large (at least as drivers go),
   78.15 -with 25,000 lines of code spread across 35 source files.  It is
   78.16 -maintained by a small team of developers.
   78.17 -
   78.18 -While much of the material in this chapter is specific to Linux, the
   78.19 -same principles apply to any code base for which you're not the
   78.20 -primary owner, and upon which you need to do a lot of development.
   78.21 -
   78.22 -\section{The problem of many targets}
   78.23 -
   78.24 -The Linux kernel changes rapidly, and has never been internally
   78.25 -stable; developers frequently make drastic changes between releases.
   78.26 -This means that a version of the driver that works well with a
   78.27 -particular released version of the kernel will not even \emph{compile}
   78.28 -correctly against, typically, any other version.
   78.29 -
   78.30 -To maintain a driver, we have to keep a number of distinct versions of
   78.31 -Linux in mind.
   78.32 -\begin{itemize}
   78.33 -\item One target is the main Linux kernel development tree.
   78.34 -  Maintenance of the code is in this case partly shared by other
   78.35 -  developers in the kernel community, who make ``drive-by''
   78.36 -  modifications to the driver as they develop and refine kernel
   78.37 -  subsystems.
   78.38 -\item We also maintain a number of ``backports'' to older versions of
   78.39 -  the Linux kernel, to support the needs of customers who are running
   78.40 -  older Linux distributions that do not incorporate our drivers.  (To
   78.41 -  \emph{backport} a piece of code is to modify it to work in an older
   78.42 -  version of its target environment than the version it was developed
   78.43 -  for.)
   78.44 -\item Finally, we make software releases on a schedule that is
   78.45 -  necessarily not aligned with those used by Linux distributors and
   78.46 -  kernel developers, so that we can deliver new features to customers
   78.47 -  without forcing them to upgrade their entire kernels or
   78.48 -  distributions.
   78.49 -\end{itemize}
   78.50 -
   78.51 -\subsection{Tempting approaches that don't work well}
   78.52 -
   78.53 -There are two ``standard'' ways to maintain a piece of software that
   78.54 -has to target many different environments.
   78.55 -
   78.56 -The first is to maintain a number of branches, each intended for a
   78.57 -single target.  The trouble with this approach is that you must
   78.58 -maintain iron discipline in the flow of changes between repositories.
   78.59 -A new feature or bug fix must start life in a ``pristine'' repository,
   78.60 -then percolate out to every backport repository.  Backport changes are
   78.61 -more limited in the branches they should propagate to; a backport
   78.62 -change that is applied to a branch where it doesn't belong will
   78.63 -probably stop the driver from compiling.
   78.64 -
   78.65 -The second is to maintain a single source tree filled with conditional
   78.66 -statements that turn chunks of code on or off depending on the
   78.67 -intended target.  Because these ``ifdefs'' are not allowed in the
   78.68 -Linux kernel tree, a manual or automatic process must be followed to
   78.69 -strip them out and yield a clean tree.  A code base maintained in this
   78.70 -fashion rapidly becomes a rat's nest of conditional blocks that are
   78.71 -difficult to understand and maintain.
   78.72 -
   78.73 -Neither of these approaches is well suited to a situation where you
   78.74 -don't ``own'' the canonical copy of a source tree.  In the case of a
   78.75 -Linux driver that is distributed with the standard kernel, Linus's
   78.76 -tree contains the copy of the code that will be treated by the world
   78.77 -as canonical.  The upstream version of ``my'' driver can be modified
   78.78 -by people I don't know, without me even finding out about it until
   78.79 -after the changes show up in Linus's tree.  
   78.80 -
   78.81 -These approaches have the added weakness of making it difficult to
   78.82 -generate well-formed patches to submit upstream.
   78.83 -
   78.84 -In principle, Mercurial Queues seems like a good candidate to manage a
   78.85 -development scenario such as the above.  While this is indeed the
   78.86 -case, MQ contains a few added features that make the job more
   78.87 -pleasant.
   78.88 -
   78.89 -\section{Conditionally applying patches with 
   78.90 -  guards}
   78.91 -
   78.92 -Perhaps the best way to maintain sanity with so many targets is to be
   78.93 -able to choose specific patches to apply for a given situation.  MQ
   78.94 -provides a feature called ``guards'' (which originates with quilt's
   78.95 -\texttt{guards} command) that does just this.  To start off, let's
   78.96 -create a simple repository for experimenting in.
   78.97 -\interaction{mq.guards.init}
   78.98 -This gives us a tiny repository that contains two patches that don't
   78.99 -have any dependencies on each other, because they touch different files.
  78.100 -
  78.101 -The idea behind conditional application is that you can ``tag'' a
  78.102 -patch with a \emph{guard}, which is simply a text string of your
  78.103 -choosing, then tell MQ to select specific guards to use when applying
  78.104 -patches.  MQ will then either apply, or skip over, a guarded patch,
  78.105 -depending on the guards that you have selected.
  78.106 -
  78.107 -A patch can have an arbitrary number of guards;
  78.108 -each one is \emph{positive} (``apply this patch if this guard is
  78.109 -selected'') or \emph{negative} (``skip this patch if this guard is
  78.110 -selected'').  A patch with no guards is always applied.
  78.111 -
  78.112 -\section{Controlling the guards on a patch}
  78.113 -
  78.114 -The \hgxcmd{mq}{qguard} command lets you determine which guards should
  78.115 -apply to a patch, or display the guards that are already in effect.
  78.116 -Without any arguments, it displays the guards on the current topmost
  78.117 -patch.
  78.118 -\interaction{mq.guards.qguard}
  78.119 -To set a positive guard on a patch, prefix the name of the guard with
  78.120 -a ``\texttt{+}''.
  78.121 -\interaction{mq.guards.qguard.pos}
  78.122 -To set a negative guard on a patch, prefix the name of the guard with
  78.123 -a ``\texttt{-}''.
  78.124 -\interaction{mq.guards.qguard.neg}
  78.125 -
  78.126 -\begin{note}
  78.127 -  The \hgxcmd{mq}{qguard} command \emph{sets} the guards on a patch; it
  78.128 -  doesn't \emph{modify} them.  What this means is that if you run
  78.129 -  \hgcmdargs{qguard}{+a +b} on a patch, then \hgcmdargs{qguard}{+c} on
  78.130 -  the same patch, the \emph{only} guard that will be set on it
  78.131 -  afterwards is \texttt{+c}.
  78.132 -\end{note}
  78.133 -
  78.134 -Mercurial stores guards in the \sfilename{series} file; the form in
  78.135 -which they are stored is easy both to understand and to edit by hand.
  78.136 -(In other words, you don't have to use the \hgxcmd{mq}{qguard} command if
  78.137 -you don't want to; it's okay to simply edit the \sfilename{series}
  78.138 -file.)
  78.139 -\interaction{mq.guards.series}
  78.140 -
  78.141 -\section{Selecting the guards to use}
  78.142 -
  78.143 -The \hgxcmd{mq}{qselect} command determines which guards are active at a
  78.144 -given time.  The effect of this is to determine which patches MQ will
  78.145 -apply the next time you run \hgxcmd{mq}{qpush}.  It has no other effect; in
  78.146 -particular, it doesn't do anything to patches that are already
  78.147 -applied.
  78.148 -
  78.149 -With no arguments, the \hgxcmd{mq}{qselect} command lists the guards
  78.150 -currently in effect, one per line of output.  Each argument is treated
  78.151 -as the name of a guard to apply.
  78.152 -\interaction{mq.guards.qselect.foo}
  78.153 -In case you're interested, the currently selected guards are stored in
  78.154 -the \sfilename{guards} file.
  78.155 -\interaction{mq.guards.qselect.cat}
  78.156 -We can see the effect the selected guards have when we run
  78.157 -\hgxcmd{mq}{qpush}.
  78.158 -\interaction{mq.guards.qselect.qpush}
  78.159 -
  78.160 -A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}''
  78.161 -character.  The name of a guard must not contain white space, but most
  78.162 -other characters are acceptable.  If you try to use a guard with an
  78.163 -invalid name, MQ will complain:
  78.164 -\interaction{mq.guards.qselect.error} 
  78.165 -Changing the selected guards changes the patches that are applied.
  78.166 -\interaction{mq.guards.qselect.quux} 
  78.167 -You can see in the example below that negative guards take precedence
  78.168 -over positive guards.
  78.169 -\interaction{mq.guards.qselect.foobar}
  78.170 -
  78.171 -\section{MQ's rules for applying patches}
  78.172 -
  78.173 -The rules that MQ uses when deciding whether to apply a patch
  78.174 -are as follows.
  78.175 -\begin{itemize}
  78.176 -\item A patch that has no guards is always applied.
  78.177 -\item If the patch has any negative guard that matches any currently
  78.178 -  selected guard, the patch is skipped.
  78.179 -\item If the patch has any positive guard that matches any currently
  78.180 -  selected guard, the patch is applied.
  78.181 -\item If the patch has positive or negative guards, but none matches
  78.182 -  any currently selected guard, the patch is skipped.
  78.183 -\end{itemize}
  78.184 -
  78.185 -\section{Trimming the work environment}
  78.186 -
  78.187 -In working on the device driver I mentioned earlier, I don't apply the
  78.188 -patches to a normal Linux kernel tree.  Instead, I use a repository
  78.189 -that contains only a snapshot of the source files and headers that are
  78.190 -relevant to Infiniband development.  This repository is~1\% the size
  78.191 -of a kernel repository, so it's easier to work with.
  78.192 -
  78.193 -I then choose a ``base'' version on top of which the patches are
  78.194 -applied.  This is a snapshot of the Linux kernel tree as of a revision
  78.195 -of my choosing.  When I take the snapshot, I record the changeset ID
  78.196 -from the kernel repository in the commit message.  Since the snapshot
  78.197 -preserves the ``shape'' and content of the relevant parts of the
  78.198 -kernel tree, I can apply my patches on top of either my tiny
  78.199 -repository or a normal kernel tree.
  78.200 -
  78.201 -Normally, the base tree atop which the patches apply should be a
  78.202 -snapshot of a very recent upstream tree.  This best facilitates the
  78.203 -development of patches that can easily be submitted upstream with few
  78.204 -or no modifications.
  78.205 -
  78.206 -\section{Dividing up the \sfilename{series} file}
  78.207 -
  78.208 -I categorise the patches in the \sfilename{series} file into a number
  78.209 -of logical groups.  Each section of like patches begins with a block
  78.210 -of comments that describes the purpose of the patches that follow.
  78.211 -
  78.212 -The sequence of patch groups that I maintain follows.  The ordering of
  78.213 -these groups is important; I'll describe why after I introduce the
  78.214 -groups.
  78.215 -\begin{itemize}
  78.216 -\item The ``accepted'' group.  Patches that the development team has
  78.217 -  submitted to the maintainer of the Infiniband subsystem, and which
  78.218 -  he has accepted, but which are not present in the snapshot that the
  78.219 -  tiny repository is based on.  These are ``read only'' patches,
  78.220 -  present only to transform the tree into a similar state as it is in
  78.221 -  the upstream maintainer's repository.
  78.222 -\item The ``rework'' group.  Patches that I have submitted, but that
  78.223 -  the upstream maintainer has requested modifications to before he
  78.224 -  will accept them.
  78.225 -\item The ``pending'' group.  Patches that I have not yet submitted to
  78.226 -  the upstream maintainer, but which we have finished working on.
  78.227 -  These will be ``read only'' for a while.  If the upstream maintainer
  78.228 -  accepts them upon submission, I'll move them to the end of the
  78.229 -  ``accepted'' group.  If he requests that I modify any, I'll move
  78.230 -  them to the beginning of the ``rework'' group.
  78.231 -\item The ``in progress'' group.  Patches that are actively being
  78.232 -  developed, and should not be submitted anywhere yet.
  78.233 -\item The ``backport'' group.  Patches that adapt the source tree to
  78.234 -  older versions of the kernel tree.
  78.235 -\item The ``do not ship'' group.  Patches that for some reason should
  78.236 -  never be submitted upstream.  For example, one such patch might
  78.237 -  change embedded driver identification strings to make it easier to
  78.238 -  distinguish, in the field, between an out-of-tree version of the
  78.239 -  driver and a version shipped by a distribution vendor.
  78.240 -\end{itemize}
  78.241 -
  78.242 -Now to return to the reasons for ordering groups of patches in this
  78.243 -way.  We would like the lowest patches in the stack to be as stable as
  78.244 -possible, so that we will not need to rework higher patches due to
  78.245 -changes in context.  Putting patches that will never be changed first
  78.246 -in the \sfilename{series} file serves this purpose.
  78.247 -
  78.248 -We would also like the patches that we know we'll need to modify to be
  78.249 -applied on top of a source tree that resembles the upstream tree as
  78.250 -closely as possible.  This is why we keep accepted patches around for
  78.251 -a while.
  78.252 -
  78.253 -The ``backport'' and ``do not ship'' patches float at the end of the
  78.254 -\sfilename{series} file.  The backport patches must be applied on top
  78.255 -of all other patches, and the ``do not ship'' patches might as well
  78.256 -stay out of harm's way.
  78.257 -
  78.258 -\section{Maintaining the patch series}
  78.259 -
  78.260 -In my work, I use a number of guards to control which patches are to
  78.261 -be applied.
  78.262 -
  78.263 -\begin{itemize}
  78.264 -\item ``Accepted'' patches are guarded with \texttt{accepted}.  I
  78.265 -  enable this guard most of the time.  When I'm applying the patches
  78.266 -  on top of a tree where the patches are already present, I can turn
  78.267 -  this patch off, and the patches that follow it will apply cleanly.
  78.268 -\item Patches that are ``finished'', but not yet submitted, have no
  78.269 -  guards.  If I'm applying the patch stack to a copy of the upstream
  78.270 -  tree, I don't need to enable any guards in order to get a reasonably
  78.271 -  safe source tree.
  78.272 -\item Those patches that need reworking before being resubmitted are
  78.273 -  guarded with \texttt{rework}.
  78.274 -\item For those patches that are still under development, I use
  78.275 -  \texttt{devel}.
  78.276 -\item A backport patch may have several guards, one for each version
  78.277 -  of the kernel to which it applies.  For example, a patch that
  78.278 -  backports a piece of code to~2.6.9 will have a~\texttt{2.6.9} guard.
  78.279 -\end{itemize}
  78.280 -This variety of guards gives me considerable flexibility in
  78.281 -determining what kind of source tree I want to end up with.  For most
  78.282 -situations, the selection of appropriate guards is automated during
  78.283 -the build process, but I can manually tune the guards to use for less
  78.284 -common circumstances.
  78.285 -
  78.286 -\subsection{The art of writing backport patches}
  78.287 -
  78.288 -Using MQ, writing a backport patch is a simple process.  All such a
  78.289 -patch has to do is modify a piece of code that uses a kernel feature
  78.290 -not present in the older version of the kernel, so that the driver
  78.291 -continues to work correctly under that older version.
  78.292 -
  78.293 -A useful goal when writing a good backport patch is to make your code
  78.294 -look as if it was written for the older version of the kernel you're
  78.295 -targeting.  The less obtrusive the patch, the easier it will be to
  78.296 -understand and maintain.  If you're writing a collection of backport
  78.297 -patches to avoid the ``rat's nest'' effect of lots of
  78.298 -\texttt{\#ifdef}s (hunks of source code that are only used
  78.299 -conditionally) in your code, don't introduce version-dependent
  78.300 -\texttt{\#ifdef}s into the patches.  Instead, write several patches,
  78.301 -each of which makes unconditional changes, and control their
  78.302 -application using guards.
  78.303 -
  78.304 -There are two reasons to divide backport patches into a distinct
  78.305 -group, away from the ``regular'' patches whose effects they modify.
  78.306 -The first is that intermingling the two makes it more difficult to use
  78.307 -a tool like the \hgext{patchbomb} extension to automate the process of
  78.308 -submitting the patches to an upstream maintainer.  The second is that
  78.309 -a backport patch could perturb the context in which a subsequent
  78.310 -regular patch is applied, making it impossible to apply the regular
  78.311 -patch cleanly \emph{without} the earlier backport patch already being
  78.312 -applied.
  78.313 -
  78.314 -\section{Useful tips for developing with MQ}
  78.315 -
  78.316 -\subsection{Organising patches in directories}
  78.317 -
  78.318 -If you're working on a substantial project with MQ, it's not difficult
  78.319 -to accumulate a large number of patches.  For example, I have one
  78.320 -patch repository that contains over 250 patches.
  78.321 -
  78.322 -If you can group these patches into separate logical categories, you
  78.323 -can if you like store them in different directories; MQ has no
  78.324 -problems with patch names that contain path separators.
  78.325 -
  78.326 -\subsection{Viewing the history of a patch}
  78.327 -\label{mq-collab:tips:interdiff}
  78.328 -
  78.329 -If you're developing a set of patches over a long time, it's a good
  78.330 -idea to maintain them in a repository, as discussed in
  78.331 -section~\ref{sec:mq:repo}.  If you do so, you'll quickly discover that
  78.332 -using the \hgcmd{diff} command to look at the history of changes to a
  78.333 -patch is unworkable.  This is in part because you're looking at the
  78.334 -second derivative of the real code (a diff of a diff), but also
  78.335 -because MQ adds noise to the process by modifying time stamps and
  78.336 -directory names when it updates a patch.
  78.337 -
  78.338 -However, you can use the \hgext{extdiff} extension, which is bundled
  78.339 -with Mercurial, to turn a diff of two versions of a patch into
  78.340 -something readable.  To do this, you will need a third-party package
  78.341 -called \package{patchutils}~\cite{web:patchutils}.  This provides a
  78.342 -command named \command{interdiff}, which shows the differences between
  78.343 -two diffs as a diff.  Used on two versions of the same diff, it
  78.344 -generates a diff that represents the diff from the first to the second
  78.345 -version.
  78.346 -
  78.347 -You can enable the \hgext{extdiff} extension in the usual way, by
  78.348 -adding a line to the \rcsection{extensions} section of your \hgrc.
  78.349 -\begin{codesample2}
  78.350 -  [extensions]
  78.351 -  extdiff =
  78.352 -\end{codesample2}
  78.353 -The \command{interdiff} command expects to be passed the names of two
  78.354 -files, but the \hgext{extdiff} extension passes the program it runs a
  78.355 -pair of directories, each of which can contain an arbitrary number of
  78.356 -files.  We thus need a small program that will run \command{interdiff}
  78.357 -on each pair of files in these two directories.  This program is
  78.358 -available as \sfilename{hg-interdiff} in the \dirname{examples}
  78.359 -directory of the source code repository that accompanies this book.
  78.360 -\excode{hg-interdiff}
  78.361 -
  78.362 -With the \sfilename{hg-interdiff} program in your shell's search path,
  78.363 -you can run it as follows, from inside an MQ patch directory:
  78.364 -\begin{codesample2}
  78.365 -  hg extdiff -p hg-interdiff -r A:B my-change.patch
  78.366 -\end{codesample2}
  78.367 -Since you'll probably want to use this long-winded command a lot, you
  78.368 -can get \hgext{hgext} to make it available as a normal Mercurial
  78.369 -command, again by editing your \hgrc.
  78.370 -\begin{codesample2}
  78.371 -  [extdiff]
  78.372 -  cmd.interdiff = hg-interdiff
  78.373 -\end{codesample2}
  78.374 -This directs \hgext{hgext} to make an \texttt{interdiff} command
  78.375 -available, so you can now shorten the previous invocation of
  78.376 -\hgxcmd{extdiff}{extdiff} to something a little more wieldy.
  78.377 -\begin{codesample2}
  78.378 -  hg interdiff -r A:B my-change.patch
  78.379 -\end{codesample2}
  78.380 -
  78.381 -\begin{note}
  78.382 -  The \command{interdiff} command works well only if the underlying
  78.383 -  files against which versions of a patch are generated remain the
  78.384 -  same.  If you create a patch, modify the underlying files, and then
  78.385 -  regenerate the patch, \command{interdiff} may not produce useful
  78.386 -  output.
  78.387 -\end{note}
  78.388 -
  78.389 -The \hgext{extdiff} extension is useful for more than merely improving
  78.390 -the presentation of MQ~patches.  To read more about it, go to
  78.391 -section~\ref{sec:hgext:extdiff}.
  78.392 -
  78.393 -%%% Local Variables: 
  78.394 -%%% mode: latex
  78.395 -%%% TeX-master: "00book"
  78.396 -%%% End: 
    79.1 --- a/fr/mq-ref.tex	Sun Aug 16 03:41:39 2009 +0200
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,349 +0,0 @@
    79.4 -\chapter{Mercurial Queues reference}
    79.5 -\label{chap:mqref}
    79.6 -
    79.7 -\section{MQ command reference}
    79.8 -\label{sec:mqref:cmdref}
    79.9 -
   79.10 -For an overview of the commands provided by MQ, use the command
   79.11 -\hgcmdargs{help}{mq}.
   79.12 -
   79.13 -\subsection{\hgxcmd{mq}{qapplied}---print applied patches}
   79.14 -
   79.15 -The \hgxcmd{mq}{qapplied} command prints the current stack of applied
   79.16 -patches.  Patches are printed in oldest-to-newest order, so the last
   79.17 -patch in the list is the ``top'' patch.
   79.18 -
   79.19 -\subsection{\hgxcmd{mq}{qcommit}---commit changes in the queue repository}
   79.20 -
   79.21 -The \hgxcmd{mq}{qcommit} command commits any outstanding changes in the
   79.22 -\sdirname{.hg/patches} repository.  This command only works if the
   79.23 -\sdirname{.hg/patches} directory is a repository, i.e.~you created the
   79.24 -directory using \hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} or ran
   79.25 -\hgcmd{init} in the directory after running \hgxcmd{mq}{qinit}.
   79.26 -
   79.27 -This command is shorthand for \hgcmdargs{commit}{--cwd .hg/patches}.
   79.28 -
   79.29 -\subsection{\hgxcmd{mq}{qdelete}---delete a patch from the
   79.30 -  \sfilename{series} file}
   79.31 -
   79.32 -The \hgxcmd{mq}{qdelete} command removes the entry for a patch from the
   79.33 -\sfilename{series} file in the \sdirname{.hg/patches} directory.  It
   79.34 -does not pop the patch if the patch is already applied.  By default,
   79.35 -it does not delete the patch file; use the \hgxopt{mq}{qdel}{-f} option to
   79.36 -do that.
   79.37 -
   79.38 -Options:
   79.39 -\begin{itemize}
   79.40 -\item[\hgxopt{mq}{qdel}{-f}] Delete the patch file.
   79.41 -\end{itemize}
   79.42 -
   79.43 -\subsection{\hgxcmd{mq}{qdiff}---print a diff of the topmost applied patch}
   79.44 -
   79.45 -The \hgxcmd{mq}{qdiff} command prints a diff of the topmost applied patch.
   79.46 -It is equivalent to \hgcmdargs{diff}{-r-2:-1}.
   79.47 -
   79.48 -\subsection{\hgxcmd{mq}{qfold}---merge (``fold'') several patches into one}
   79.49 -
   79.50 -The \hgxcmd{mq}{qfold} command merges multiple patches into the topmost
   79.51 -applied patch, so that the topmost applied patch makes the union of
   79.52 -all of the changes in the patches in question.
   79.53 -
   79.54 -The patches to fold must not be applied; \hgxcmd{mq}{qfold} will exit with
   79.55 -an error if any is.  The order in which patches are folded is
   79.56 -significant; \hgcmdargs{qfold}{a b} means ``apply the current topmost
   79.57 -patch, followed by \texttt{a}, followed by \texttt{b}''.
   79.58 -
   79.59 -The comments from the folded patches are appended to the comments of
   79.60 -the destination patch, with each block of comments separated by three
   79.61 -asterisk (``\texttt{*}'') characters.  Use the \hgxopt{mq}{qfold}{-e}
   79.62 -option to edit the commit message for the combined patch/changeset
   79.63 -after the folding has completed.
   79.64 -
   79.65 -Options:
   79.66 -\begin{itemize}
   79.67 -\item[\hgxopt{mq}{qfold}{-e}] Edit the commit message and patch description
   79.68 -  for the newly folded patch.
   79.69 -\item[\hgxopt{mq}{qfold}{-l}] Use the contents of the given file as the new
   79.70 -  commit message and patch description for the folded patch.
   79.71 -\item[\hgxopt{mq}{qfold}{-m}] Use the given text as the new commit message
   79.72 -  and patch description for the folded patch.
   79.73 -\end{itemize}
   79.74 -
   79.75 -\subsection{\hgxcmd{mq}{qheader}---display the header/description of a patch}
   79.76 -
   79.77 -The \hgxcmd{mq}{qheader} command prints the header, or description, of a
   79.78 -patch.  By default, it prints the header of the topmost applied patch.
   79.79 -Given an argument, it prints the header of the named patch.
   79.80 -
   79.81 -\subsection{\hgxcmd{mq}{qimport}---import a third-party patch into the queue}
   79.82 -
   79.83 -The \hgxcmd{mq}{qimport} command adds an entry for an external patch to the
   79.84 -\sfilename{series} file, and copies the patch into the
   79.85 -\sdirname{.hg/patches} directory.  It adds the entry immediately after
   79.86 -the topmost applied patch, but does not push the patch.
   79.87 -
   79.88 -If the \sdirname{.hg/patches} directory is a repository,
   79.89 -\hgxcmd{mq}{qimport} automatically does an \hgcmd{add} of the imported
   79.90 -patch.
   79.91 -
   79.92 -\subsection{\hgxcmd{mq}{qinit}---prepare a repository to work with MQ}
   79.93 -
   79.94 -The \hgxcmd{mq}{qinit} command prepares a repository to work with MQ.  It
   79.95 -creates a directory called \sdirname{.hg/patches}.
   79.96 -
   79.97 -Options:
   79.98 -\begin{itemize}
   79.99 -\item[\hgxopt{mq}{qinit}{-c}] Create \sdirname{.hg/patches} as a repository
  79.100 -  in its own right.  Also creates a \sfilename{.hgignore} file that
  79.101 -  will ignore the \sfilename{status} file.
  79.102 -\end{itemize}
  79.103 -
  79.104 -When the \sdirname{.hg/patches} directory is a repository, the
  79.105 -\hgxcmd{mq}{qimport} and \hgxcmd{mq}{qnew} commands automatically \hgcmd{add}
  79.106 -new patches.
  79.107 -
  79.108 -\subsection{\hgxcmd{mq}{qnew}---create a new patch}
  79.109 -
  79.110 -The \hgxcmd{mq}{qnew} command creates a new patch.  It takes one mandatory
  79.111 -argument, the name to use for the patch file.  The newly created patch
  79.112 -is created empty by default.  It is added to the \sfilename{series}
  79.113 -file after the current topmost applied patch, and is immediately
  79.114 -pushed on top of that patch.
  79.115 -
  79.116 -If \hgxcmd{mq}{qnew} finds modified files in the working directory, it will
  79.117 -refuse to create a new patch unless the \hgxopt{mq}{qnew}{-f} option is
  79.118 -used (see below).  This behaviour allows you to \hgxcmd{mq}{qrefresh} your
  79.119 -topmost applied patch before you apply a new patch on top of it.
  79.120 -
  79.121 -Options:
  79.122 -\begin{itemize}
  79.123 -\item[\hgxopt{mq}{qnew}{-f}] Create a new patch if the contents of the
  79.124 -  working directory are modified.  Any outstanding modifications are
  79.125 -  added to the newly created patch, so after this command completes,
  79.126 -  the working directory will no longer be modified.
  79.127 -\item[\hgxopt{mq}{qnew}{-m}] Use the given text as the commit message.
  79.128 -  This text will be stored at the beginning of the patch file, before
  79.129 -  the patch data.
  79.130 -\end{itemize}
  79.131 -
  79.132 -\subsection{\hgxcmd{mq}{qnext}---print the name of the next patch}
  79.133 -
  79.134 -The \hgxcmd{mq}{qnext} command prints the name name of the next patch in
  79.135 -the \sfilename{series} file after the topmost applied patch.  This
  79.136 -patch will become the topmost applied patch if you run \hgxcmd{mq}{qpush}.
  79.137 -
  79.138 -\subsection{\hgxcmd{mq}{qpop}---pop patches off the stack}
  79.139 -
  79.140 -The \hgxcmd{mq}{qpop} command removes applied patches from the top of the
  79.141 -stack of applied patches.  By default, it removes only one patch.
  79.142 -
  79.143 -This command removes the changesets that represent the popped patches
  79.144 -from the repository, and updates the working directory to undo the
  79.145 -effects of the patches.
  79.146 -
  79.147 -This command takes an optional argument, which it uses as the name or
  79.148 -index of the patch to pop to.  If given a name, it will pop patches
  79.149 -until the named patch is the topmost applied patch.  If given a
  79.150 -number, \hgxcmd{mq}{qpop} treats the number as an index into the entries in
  79.151 -the series file, counting from zero (empty lines and lines containing
  79.152 -only comments do not count).  It pops patches until the patch
  79.153 -identified by the given index is the topmost applied patch.
  79.154 -
  79.155 -The \hgxcmd{mq}{qpop} command does not read or write patches or the
  79.156 -\sfilename{series} file.  It is thus safe to \hgxcmd{mq}{qpop} a patch that
  79.157 -you have removed from the \sfilename{series} file, or a patch that you
  79.158 -have renamed or deleted entirely.  In the latter two cases, use the
  79.159 -name of the patch as it was when you applied it.
  79.160 -
  79.161 -By default, the \hgxcmd{mq}{qpop} command will not pop any patches if the
  79.162 -working directory has been modified.  You can override this behaviour
  79.163 -using the \hgxopt{mq}{qpop}{-f} option, which reverts all modifications in
  79.164 -the working directory.
  79.165 -
  79.166 -Options:
  79.167 -\begin{itemize}
  79.168 -\item[\hgxopt{mq}{qpop}{-a}] Pop all applied patches.  This returns the
  79.169 -  repository to its state before you applied any patches.
  79.170 -\item[\hgxopt{mq}{qpop}{-f}] Forcibly revert any modifications to the
  79.171 -  working directory when popping.
  79.172 -\item[\hgxopt{mq}{qpop}{-n}] Pop a patch from the named queue.
  79.173 -\end{itemize}
  79.174 -
  79.175 -The \hgxcmd{mq}{qpop} command removes one line from the end of the
  79.176 -\sfilename{status} file for each patch that it pops.
  79.177 -
  79.178 -\subsection{\hgxcmd{mq}{qprev}---print the name of the previous patch}
  79.179 -
  79.180 -The \hgxcmd{mq}{qprev} command prints the name of the patch in the
  79.181 -\sfilename{series} file that comes before the topmost applied patch.
  79.182 -This will become the topmost applied patch if you run \hgxcmd{mq}{qpop}.
  79.183 -
  79.184 -\subsection{\hgxcmd{mq}{qpush}---push patches onto the stack}
  79.185 -\label{sec:mqref:cmd:qpush}
  79.186 -
  79.187 -The \hgxcmd{mq}{qpush} command adds patches onto the applied stack.  By
  79.188 -default, it adds only one patch.
  79.189 -
  79.190 -This command creates a new changeset to represent each applied patch,
  79.191 -and updates the working directory to apply the effects of the patches.
  79.192 -
  79.193 -The default data used when creating a changeset are as follows:
  79.194 -\begin{itemize}
  79.195 -\item The commit date and time zone are the current date and time
  79.196 -  zone.  Because these data are used to compute the identity of a
  79.197 -  changeset, this means that if you \hgxcmd{mq}{qpop} a patch and
  79.198 -  \hgxcmd{mq}{qpush} it again, the changeset that you push will have a
  79.199 -  different identity than the changeset you popped.
  79.200 -\item The author is the same as the default used by the \hgcmd{commit}
  79.201 -  command.
  79.202 -\item The commit message is any text from the patch file that comes
  79.203 -  before the first diff header.  If there is no such text, a default
  79.204 -  commit message is used that identifies the name of the patch.
  79.205 -\end{itemize}
  79.206 -If a patch contains a Mercurial patch header (XXX add link), the
  79.207 -information in the patch header overrides these defaults.
  79.208 -
  79.209 -Options:
  79.210 -\begin{itemize}
  79.211 -\item[\hgxopt{mq}{qpush}{-a}] Push all unapplied patches from the
  79.212 -  \sfilename{series} file until there are none left to push.
  79.213 -\item[\hgxopt{mq}{qpush}{-l}] Add the name of the patch to the end
  79.214 -  of the commit message.
  79.215 -\item[\hgxopt{mq}{qpush}{-m}] If a patch fails to apply cleanly, use the
  79.216 -  entry for the patch in another saved queue to compute the parameters
  79.217 -  for a three-way merge, and perform a three-way merge using the
  79.218 -  normal Mercurial merge machinery.  Use the resolution of the merge
  79.219 -  as the new patch content.
  79.220 -\item[\hgxopt{mq}{qpush}{-n}] Use the named queue if merging while pushing.
  79.221 -\end{itemize}
  79.222 -
  79.223 -The \hgxcmd{mq}{qpush} command reads, but does not modify, the
  79.224 -\sfilename{series} file.  It appends one line to the \hgcmd{status}
  79.225 -file for each patch that it pushes.
  79.226 -
  79.227 -\subsection{\hgxcmd{mq}{qrefresh}---update the topmost applied patch}
  79.228 -
  79.229 -The \hgxcmd{mq}{qrefresh} command updates the topmost applied patch.  It
  79.230 -modifies the patch, removes the old changeset that represented the
  79.231 -patch, and creates a new changeset to represent the modified patch.
  79.232 -
  79.233 -The \hgxcmd{mq}{qrefresh} command looks for the following modifications:
  79.234 -\begin{itemize}
  79.235 -\item Changes to the commit message, i.e.~the text before the first
  79.236 -  diff header in the patch file, are reflected in the new changeset
  79.237 -  that represents the patch.
  79.238 -\item Modifications to tracked files in the working directory are
  79.239 -  added to the patch.
  79.240 -\item Changes to the files tracked using \hgcmd{add}, \hgcmd{copy},
  79.241 -  \hgcmd{remove}, or \hgcmd{rename}.  Added files and copy and rename
  79.242 -  destinations are added to the patch, while removed files and rename
  79.243 -  sources are removed.
  79.244 -\end{itemize}
  79.245 -
  79.246 -Even if \hgxcmd{mq}{qrefresh} detects no changes, it still recreates the
  79.247 -changeset that represents the patch.  This causes the identity of the
  79.248 -changeset to differ from the previous changeset that identified the
  79.249 -patch.
  79.250 -
  79.251 -Options:
  79.252 -\begin{itemize}
  79.253 -\item[\hgxopt{mq}{qrefresh}{-e}] Modify the commit and patch description,
  79.254 -  using the preferred text editor.
  79.255 -\item[\hgxopt{mq}{qrefresh}{-m}] Modify the commit message and patch
  79.256 -  description, using the given text.
  79.257 -\item[\hgxopt{mq}{qrefresh}{-l}] Modify the commit message and patch
  79.258 -  description, using text from the given file.
  79.259 -\end{itemize}
  79.260 -
  79.261 -\subsection{\hgxcmd{mq}{qrename}---rename a patch}
  79.262 -
  79.263 -The \hgxcmd{mq}{qrename} command renames a patch, and changes the entry for
  79.264 -the patch in the \sfilename{series} file.
  79.265 -
  79.266 -With a single argument, \hgxcmd{mq}{qrename} renames the topmost applied
  79.267 -patch.  With two arguments, it renames its first argument to its
  79.268 -second.
  79.269 -
  79.270 -\subsection{\hgxcmd{mq}{qrestore}---restore saved queue state}
  79.271 -
  79.272 -XXX No idea what this does.
  79.273 -
  79.274 -\subsection{\hgxcmd{mq}{qsave}---save current queue state}
  79.275 -
  79.276 -XXX Likewise.
  79.277 -
  79.278 -\subsection{\hgxcmd{mq}{qseries}---print the entire patch series}
  79.279 -
  79.280 -The \hgxcmd{mq}{qseries} command prints the entire patch series from the
  79.281 -\sfilename{series} file.  It prints only patch names, not empty lines
  79.282 -or comments.  It prints in order from first to be applied to last.
  79.283 -
  79.284 -\subsection{\hgxcmd{mq}{qtop}---print the name of the current patch}
  79.285 -
  79.286 -The \hgxcmd{mq}{qtop} prints the name of the topmost currently applied
  79.287 -patch.
  79.288 -
  79.289 -\subsection{\hgxcmd{mq}{qunapplied}---print patches not yet applied}
  79.290 -
  79.291 -The \hgxcmd{mq}{qunapplied} command prints the names of patches from the
  79.292 -\sfilename{series} file that are not yet applied.  It prints them in
  79.293 -order from the next patch that will be pushed to the last.
  79.294 -
  79.295 -\subsection{\hgcmd{strip}---remove a revision and descendants}
  79.296 -
  79.297 -The \hgcmd{strip} command removes a revision, and all of its
  79.298 -descendants, from the repository.  It undoes the effects of the
  79.299 -removed revisions from the repository, and updates the working
  79.300 -directory to the first parent of the removed revision.
  79.301 -
  79.302 -The \hgcmd{strip} command saves a backup of the removed changesets in
  79.303 -a bundle, so that they can be reapplied if removed in error.
  79.304 -
  79.305 -Options:
  79.306 -\begin{itemize}
  79.307 -\item[\hgopt{strip}{-b}] Save unrelated changesets that are intermixed
  79.308 -  with the stripped changesets in the backup bundle.
  79.309 -\item[\hgopt{strip}{-f}] If a branch has multiple heads, remove all
  79.310 -  heads. XXX This should be renamed, and use \texttt{-f} to strip revs
  79.311 -  when there are pending changes.
  79.312 -\item[\hgopt{strip}{-n}] Do not save a backup bundle.
  79.313 -\end{itemize}
  79.314 -
  79.315 -\section{MQ file reference}
  79.316 -
  79.317 -\subsection{The \sfilename{series} file}
  79.318 -
  79.319 -The \sfilename{series} file contains a list of the names of all
  79.320 -patches that MQ can apply.  It is represented as a list of names, with
  79.321 -one name saved per line.  Leading and trailing white space in each
  79.322 -line are ignored.
  79.323 -
  79.324 -Lines may contain comments.  A comment begins with the ``\texttt{\#}''
  79.325 -character, and extends to the end of the line.  Empty lines, and lines
  79.326 -that contain only comments, are ignored.
  79.327 -
  79.328 -You will often need to edit the \sfilename{series} file by hand, hence
  79.329 -the support for comments and empty lines noted above.  For example,
  79.330 -you can comment out a patch temporarily, and \hgxcmd{mq}{qpush} will skip
  79.331 -over that patch when applying patches.  You can also change the order
  79.332 -in which patches are applied by reordering their entries in the
  79.333 -\sfilename{series} file.
  79.334 -
  79.335 -Placing the \sfilename{series} file under revision control is also
  79.336 -supported; it is a good idea to place all of the patches that it
  79.337 -refers to under revision control, as well.  If you create a patch
  79.338 -directory using the \hgxopt{mq}{qinit}{-c} option to \hgxcmd{mq}{qinit}, this
  79.339 -will be done for you automatically.
  79.340 -
  79.341 -\subsection{The \sfilename{status} file}
  79.342 -
  79.343 -The \sfilename{status} file contains the names and changeset hashes of
  79.344 -all patches that MQ currently has applied.  Unlike the
  79.345 -\sfilename{series} file, this file is not intended for editing.  You
  79.346 -should not place this file under revision control, or modify it in any
  79.347 -way.  It is used by MQ strictly for internal book-keeping.
  79.348 -
  79.349 -%%% Local Variables: 
  79.350 -%%% mode: latex
  79.351 -%%% TeX-master: "00book"
  79.352 -%%% End: 
    80.1 --- a/fr/mq-stack.svg	Sun Aug 16 03:41:39 2009 +0200
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,270 +0,0 @@
    80.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    80.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    80.6 -<svg
    80.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    80.8 -   xmlns:cc="http://web.resource.org/cc/"
    80.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   80.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   80.11 -   xmlns="http://www.w3.org/2000/svg"
   80.12 -   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
   80.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   80.14 -   width="744.09448819"
   80.15 -   height="1052.3622047"
   80.16 -   id="svg2"
   80.17 -   sodipodi:version="0.32"
   80.18 -   inkscape:version="0.43"
   80.19 -   sodipodi:docname="mq-stack.svg"
   80.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en">
   80.21 -  <defs
   80.22 -     id="defs4" />
   80.23 -  <sodipodi:namedview
   80.24 -     id="base"
   80.25 -     pagecolor="#ffffff"
   80.26 -     bordercolor="#666666"
   80.27 -     borderopacity="1.0"
   80.28 -     inkscape:pageopacity="0.0"
   80.29 -     inkscape:pageshadow="2"
   80.30 -     inkscape:zoom="1.4142136"
   80.31 -     inkscape:cx="299.33323"
   80.32 -     inkscape:cy="815.646"
   80.33 -     inkscape:document-units="px"
   80.34 -     inkscape:current-layer="layer1"
   80.35 -     inkscape:window-width="1014"
   80.36 -     inkscape:window-height="689"
   80.37 -     inkscape:window-x="0"
   80.38 -     inkscape:window-y="25" />
   80.39 -  <metadata
   80.40 -     id="metadata7">
   80.41 -    <rdf:RDF>
   80.42 -      <cc:Work
   80.43 -         rdf:about="">
   80.44 -        <dc:format>image/svg+xml</dc:format>
   80.45 -        <dc:type
   80.46 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   80.47 -      </cc:Work>
   80.48 -    </rdf:RDF>
   80.49 -  </metadata>
   80.50 -  <g
   80.51 -     inkscape:label="Layer 1"
   80.52 -     inkscape:groupmode="layer"
   80.53 -     id="layer1">
   80.54 -    <rect
   80.55 -       style="fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   80.56 -       id="rect1307"
   80.57 -       width="202.93683"
   80.58 -       height="24.243662"
   80.59 -       x="230.01944"
   80.60 -       y="221.70146" />
   80.61 -    <text
   80.62 -       xml:space="preserve"
   80.63 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   80.64 -       x="237.89606"
   80.65 -       y="237.13383"
   80.66 -       id="text1309"><tspan
   80.67 -         sodipodi:role="line"
   80.68 -         id="tspan1311"
   80.69 -         x="237.89606"
   80.70 -         y="237.13383">prevent-compiler-reorder.patch</tspan></text>
   80.71 -    <rect
   80.72 -       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   80.73 -       id="rect1320"
   80.74 -       width="202.93683"
   80.75 -       height="24.243662"
   80.76 -       x="230.01936"
   80.77 -       y="251.34325" />
   80.78 -    <text
   80.79 -       xml:space="preserve"
   80.80 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   80.81 -       x="237.89598"
   80.82 -       y="266.77563"
   80.83 -       id="text1322"><tspan
   80.84 -         sodipodi:role="line"
   80.85 -         id="tspan1324"
   80.86 -         x="237.89598"
   80.87 -         y="266.77563">namespace-cleanup.patch</tspan></text>
   80.88 -    <rect
   80.89 -       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   80.90 -       id="rect2217"
   80.91 -       width="202.93683"
   80.92 -       height="24.243662"
   80.93 -       x="230.01936"
   80.94 -       y="280.98505" />
   80.95 -    <text
   80.96 -       xml:space="preserve"
   80.97 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   80.98 -       x="237.89598"
   80.99 -       y="296.41742"
  80.100 -       id="text2219"><tspan
  80.101 -         sodipodi:role="line"
  80.102 -         id="tspan2221"
  80.103 -         x="237.89598"
  80.104 -         y="296.41742">powerpc-port-fixes.patch</tspan></text>
  80.105 -    <rect
  80.106 -       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  80.107 -       id="rect3114"
  80.108 -       width="202.93683"
  80.109 -       height="24.243662"
  80.110 -       x="230.01936"
  80.111 -       y="310.6268" />
  80.112 -    <text
  80.113 -       xml:space="preserve"
  80.114 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.115 -       x="237.89598"
  80.116 -       y="326.05917"
  80.117 -       id="text3116"><tspan
  80.118 -         sodipodi:role="line"
  80.119 -         id="tspan3118"
  80.120 -         x="237.89598"
  80.121 -         y="326.05917">report-devinfo-correctly.patch</tspan></text>
  80.122 -    <text
  80.123 -       xml:space="preserve"
  80.124 -       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.125 -       x="200.01021"
  80.126 -       y="191.68094"
  80.127 -       id="text3170"
  80.128 -       sodipodi:linespacing="125%"><tspan
  80.129 -         sodipodi:role="line"
  80.130 -         id="tspan3172"
  80.131 -         x="200.01021"
  80.132 -         y="191.68094"
  80.133 -         style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
  80.134 -    <text
  80.135 -       xml:space="preserve"
  80.136 -       style="font-size:15.25329685px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.137 -       x="255.26627"
  80.138 -       y="248.79449"
  80.139 -       id="text3190"
  80.140 -       sodipodi:linespacing="125%"
  80.141 -       transform="scale(0.786716,1.271107)"><tspan
  80.142 -         sodipodi:role="line"
  80.143 -         id="tspan3192"
  80.144 -         x="255.26627"
  80.145 -         y="248.79449"
  80.146 -         style="font-size:61.01318741px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
  80.147 -    <text
  80.148 -       xml:space="preserve"
  80.149 -       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.150 -       x="195.86807"
  80.151 -       y="173.17117"
  80.152 -       id="text4085"
  80.153 -       sodipodi:linespacing="125%"><tspan
  80.154 -         sodipodi:role="line"
  80.155 -         id="tspan4087"
  80.156 -         x="195.86807"
  80.157 -         y="173.17117"
  80.158 -         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">present in series,</tspan><tspan
  80.159 -         sodipodi:role="line"
  80.160 -         x="195.86807"
  80.161 -         y="188.17117"
  80.162 -         id="tspan4089"
  80.163 -         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">but not applied</tspan></text>
  80.164 -    <text
  80.165 -       xml:space="preserve"
  80.166 -       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.167 -       x="195.0712"
  80.168 -       y="288.91745"
  80.169 -       id="text4091"
  80.170 -       sodipodi:linespacing="125%"><tspan
  80.171 -         sodipodi:role="line"
  80.172 -         id="tspan4093"
  80.173 -         x="195.0712"
  80.174 -         y="288.91745"
  80.175 -         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">patches applied,</tspan><tspan
  80.176 -         sodipodi:role="line"
  80.177 -         x="195.0712"
  80.178 -         y="303.91745"
  80.179 -         id="tspan4111"
  80.180 -         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">changesets present</tspan></text>
  80.181 -    <text
  80.182 -       xml:space="preserve"
  80.183 -       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.184 -       x="195.0712"
  80.185 -       y="229.28813"
  80.186 -       id="text4095"
  80.187 -       sodipodi:linespacing="125%"><tspan
  80.188 -         sodipodi:role="line"
  80.189 -         id="tspan4097"
  80.190 -         x="195.0712"
  80.191 -         y="229.28813"
  80.192 -         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">topmost</tspan><tspan
  80.193 -         sodipodi:role="line"
  80.194 -         x="195.0712"
  80.195 -         y="244.28813"
  80.196 -         id="tspan4109"
  80.197 -         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">applied patch</tspan></text>
  80.198 -    <text
  80.199 -       xml:space="preserve"
  80.200 -       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.201 -       x="450.4975"
  80.202 -       y="238.29692"
  80.203 -       id="text4137"><tspan
  80.204 -         sodipodi:role="line"
  80.205 -         id="tspan4139"
  80.206 -         x="450.4975"
  80.207 -         y="238.29692">201ad3209902</tspan></text>
  80.208 -    <text
  80.209 -       xml:space="preserve"
  80.210 -       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.211 -       x="450.05804"
  80.212 -       y="267.93872"
  80.213 -       id="text4141"><tspan
  80.214 -         sodipodi:role="line"
  80.215 -         id="tspan4143"
  80.216 -         x="450.05804"
  80.217 -         y="267.93872">126b84e593ae</tspan></text>
  80.218 -    <text
  80.219 -       xml:space="preserve"
  80.220 -       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.221 -       x="450.6557"
  80.222 -       y="297.58051"
  80.223 -       id="text4145"><tspan
  80.224 -         sodipodi:role="line"
  80.225 -         id="tspan4147"
  80.226 -         x="450.6557"
  80.227 -         y="297.58051">a655daf15409</tspan></text>
  80.228 -    <text
  80.229 -       xml:space="preserve"
  80.230 -       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.231 -       x="450.71429"
  80.232 -       y="327.22226"
  80.233 -       id="text4149"><tspan
  80.234 -         sodipodi:role="line"
  80.235 -         id="tspan4151"
  80.236 -         x="450.71429"
  80.237 -         y="327.22226">e50d59aaea3a</tspan></text>
  80.238 -    <rect
  80.239 -       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  80.240 -       id="rect3106"
  80.241 -       width="202.93683"
  80.242 -       height="24.243662"
  80.243 -       x="230.01936"
  80.244 -       y="150.41792" />
  80.245 -    <text
  80.246 -       xml:space="preserve"
  80.247 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.248 -       x="237.89598"
  80.249 -       y="165.8503"
  80.250 -       id="text3108"><tspan
  80.251 -         sodipodi:role="line"
  80.252 -         id="tspan3110"
  80.253 -         x="237.89598"
  80.254 -         y="165.8503">forbid-illegal-params.patch</tspan></text>
  80.255 -    <rect
  80.256 -       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  80.257 -       id="rect2241"
  80.258 -       width="202.93683"
  80.259 -       height="24.243662"
  80.260 -       x="230.16466"
  80.261 -       y="180.05968" />
  80.262 -    <text
  80.263 -       xml:space="preserve"
  80.264 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
  80.265 -       x="238.04128"
  80.266 -       y="195.49205"
  80.267 -       id="text2243"><tspan
  80.268 -         sodipodi:role="line"
  80.269 -         id="tspan2245"
  80.270 -         x="238.04128"
  80.271 -         y="195.49205">fix-memory-leak.patch</tspan></text>
  80.272 -  </g>
  80.273 -</svg>
    81.1 --- a/fr/mq.tex	Sun Aug 16 03:41:39 2009 +0200
    81.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.3 @@ -1,1043 +0,0 @@
    81.4 -\chapter{Managing change with Mercurial Queues}
    81.5 -\label{chap:mq}
    81.6 -
    81.7 -\section{The patch management problem}
    81.8 -\label{sec:mq:patch-mgmt}
    81.9 -
   81.10 -Here is a common scenario: you need to install a software package from
   81.11 -source, but you find a bug that you must fix in the source before you
   81.12 -can start using the package.  You make your changes, forget about the
   81.13 -package for a while, and a few months later you need to upgrade to a
   81.14 -newer version of the package.  If the newer version of the package
   81.15 -still has the bug, you must extract your fix from the older source
   81.16 -tree and apply it against the newer version.  This is a tedious task,
   81.17 -and it's easy to make mistakes.
   81.18 -
   81.19 -This is a simple case of the ``patch management'' problem.  You have
   81.20 -an ``upstream'' source tree that you can't change; you need to make
   81.21 -some local changes on top of the upstream tree; and you'd like to be
   81.22 -able to keep those changes separate, so that you can apply them to
   81.23 -newer versions of the upstream source.
   81.24 -
   81.25 -The patch management problem arises in many situations.  Probably the
   81.26 -most visible is that a user of an open source software project will
   81.27 -contribute a bug fix or new feature to the project's maintainers in the
   81.28 -form of a patch.
   81.29 -
   81.30 -Distributors of operating systems that include open source software
   81.31 -often need to make changes to the packages they distribute so that
   81.32 -they will build properly in their environments.
   81.33 -
   81.34 -When you have few changes to maintain, it is easy to manage a single
   81.35 -patch using the standard \command{diff} and \command{patch} programs
   81.36 -(see section~\ref{sec:mq:patch} for a discussion of these tools).
   81.37 -Once the number of changes grows, it starts to make sense to maintain
   81.38 -patches as discrete ``chunks of work,'' so that for example a single
   81.39 -patch will contain only one bug fix (the patch might modify several
   81.40 -files, but it's doing ``only one thing''), and you may have a number
   81.41 -of such patches for different bugs you need fixed and local changes
   81.42 -you require.  In this situation, if you submit a bug fix patch to the
   81.43 -upstream maintainers of a package and they include your fix in a
   81.44 -subsequent release, you can simply drop that single patch when you're
   81.45 -updating to the newer release.
   81.46 -
   81.47 -Maintaining a single patch against an upstream tree is a little
   81.48 -tedious and error-prone, but not difficult.  However, the complexity
   81.49 -of the problem grows rapidly as the number of patches you have to
   81.50 -maintain increases.  With more than a tiny number of patches in hand,
   81.51 -understanding which ones you have applied and maintaining them moves
   81.52 -from messy to overwhelming.
   81.53 -
   81.54 -Fortunately, Mercurial includes a powerful extension, Mercurial Queues
   81.55 -(or simply ``MQ''), that massively simplifies the patch management
   81.56 -problem.
   81.57 -
   81.58 -\section{The prehistory of Mercurial Queues}
   81.59 -\label{sec:mq:history}
   81.60 -
   81.61 -During the late 1990s, several Linux kernel developers started to
   81.62 -maintain ``patch series'' that modified the behaviour of the Linux
   81.63 -kernel.  Some of these series were focused on stability, some on
   81.64 -feature coverage, and others were more speculative.
   81.65 -
   81.66 -The sizes of these patch series grew rapidly.  In 2002, Andrew Morton
   81.67 -published some shell scripts he had been using to automate the task of
   81.68 -managing his patch queues.  Andrew was successfully using these
   81.69 -scripts to manage hundreds (sometimes thousands) of patches on top of
   81.70 -the Linux kernel.
   81.71 -
   81.72 -\subsection{A patchwork quilt}
   81.73 -\label{sec:mq:quilt}
   81.74 -
   81.75 -In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the
   81.76 -approach of Andrew's scripts and published a tool called ``patchwork
   81.77 -quilt''~\cite{web:quilt}, or simply ``quilt''
   81.78 -(see~\cite{gruenbacher:2005} for a paper describing it).  Because
   81.79 -quilt substantially automated patch management, it rapidly gained a
   81.80 -large following among open source software developers.
   81.81 -
   81.82 -Quilt manages a \emph{stack of patches} on top of a directory tree.
   81.83 -To begin, you tell quilt to manage a directory tree, and tell it which
   81.84 -files you want to manage; it stores away the names and contents of
   81.85 -those files.  To fix a bug, you create a new patch (using a single
   81.86 -command), edit the files you need to fix, then ``refresh'' the patch.
   81.87 -
   81.88 -The refresh step causes quilt to scan the directory tree; it updates
   81.89 -the patch with all of the changes you have made.  You can create
   81.90 -another patch on top of the first, which will track the changes
   81.91 -required to modify the tree from ``tree with one patch applied'' to
   81.92 -``tree with two patches applied''.
   81.93 -
   81.94 -You can \emph{change} which patches are applied to the tree.  If you
   81.95 -``pop'' a patch, the changes made by that patch will vanish from the
   81.96 -directory tree.  Quilt remembers which patches you have popped,
   81.97 -though, so you can ``push'' a popped patch again, and the directory
   81.98 -tree will be restored to contain the modifications in the patch.  Most
   81.99 -importantly, you can run the ``refresh'' command at any time, and the
  81.100 -topmost applied patch will be updated.  This means that you can, at
  81.101 -any time, change both which patches are applied and what
  81.102 -modifications those patches make.
  81.103 -
  81.104 -Quilt knows nothing about revision control tools, so it works equally
  81.105 -well on top of an unpacked tarball or a Subversion working copy.
  81.106 -
  81.107 -\subsection{From patchwork quilt to Mercurial Queues}
  81.108 -\label{sec:mq:quilt-mq}
  81.109 -
  81.110 -In mid-2005, Chris Mason took the features of quilt and wrote an
  81.111 -extension that he called Mercurial Queues, which added quilt-like
  81.112 -behaviour to Mercurial.
  81.113 -
  81.114 -The key difference between quilt and MQ is that quilt knows nothing
  81.115 -about revision control systems, while MQ is \emph{integrated} into
  81.116 -Mercurial.  Each patch that you push is represented as a Mercurial
  81.117 -changeset.  Pop a patch, and the changeset goes away.
  81.118 -
  81.119 -Because quilt does not care about revision control tools, it is still
  81.120 -a tremendously useful piece of software to know about for situations
  81.121 -where you cannot use Mercurial and MQ.
  81.122 -
  81.123 -\section{The huge advantage of MQ}
  81.124 -
  81.125 -I cannot overstate the value that MQ offers through the unification of
  81.126 -patches and revision control.
  81.127 -
  81.128 -A major reason that patches have persisted in the free software and
  81.129 -open source world---in spite of the availability of increasingly
  81.130 -capable revision control tools over the years---is the \emph{agility}
  81.131 -they offer.  
  81.132 -
  81.133 -Traditional revision control tools make a permanent, irreversible
  81.134 -record of everything that you do.  While this has great value, it's
  81.135 -also somewhat stifling.  If you want to perform a wild-eyed
  81.136 -experiment, you have to be careful in how you go about it, or you risk
  81.137 -leaving unneeded---or worse, misleading or destabilising---traces of
  81.138 -your missteps and errors in the permanent revision record.
  81.139 -
  81.140 -By contrast, MQ's marriage of distributed revision control with
  81.141 -patches makes it much easier to isolate your work.  Your patches live
  81.142 -on top of normal revision history, and you can make them disappear or
  81.143 -reappear at will.  If you don't like a patch, you can drop it.  If a
  81.144 -patch isn't quite as you want it to be, simply fix it---as many times
  81.145 -as you need to, until you have refined it into the form you desire.
  81.146 -
  81.147 -As an example, the integration of patches with revision control makes
  81.148 -understanding patches and debugging their effects---and their
  81.149 -interplay with the code they're based on---\emph{enormously} easier.
  81.150 -Since every applied patch has an associated changeset, you can use
  81.151 -\hgcmdargs{log}{\emph{filename}} to see which changesets and patches
  81.152 -affected a file.  You can use the \hgext{bisect} command to
  81.153 -binary-search through all changesets and applied patches to see where
  81.154 -a bug got introduced or fixed.  You can use the \hgcmd{annotate}
  81.155 -command to see which changeset or patch modified a particular line of
  81.156 -a source file.  And so on.
  81.157 -
  81.158 -\section{Understanding patches}
  81.159 -\label{sec:mq:patch}
  81.160 -
  81.161 -Because MQ doesn't hide its patch-oriented nature, it is helpful to
  81.162 -understand what patches are, and a little about the tools that work
  81.163 -with them.
  81.164 -
  81.165 -The traditional Unix \command{diff} command compares two files, and
  81.166 -prints a list of differences between them. The \command{patch} command
  81.167 -understands these differences as \emph{modifications} to make to a
  81.168 -file.  Take a look at figure~\ref{ex:mq:diff} for a simple example of
  81.169 -these commands in action.
  81.170 -
  81.171 -\begin{figure}[ht]
  81.172 -  \interaction{mq.dodiff.diff}
  81.173 -  \caption{Simple uses of the \command{diff} and \command{patch} commands}
  81.174 -  \label{ex:mq:diff}
  81.175 -\end{figure}
  81.176 -
  81.177 -The type of file that \command{diff} generates (and \command{patch}
  81.178 -takes as input) is called a ``patch'' or a ``diff''; there is no
  81.179 -difference between a patch and a diff.  (We'll use the term ``patch'',
  81.180 -since it's more commonly used.)
  81.181 -
  81.182 -A patch file can start with arbitrary text; the \command{patch}
  81.183 -command ignores this text, but MQ uses it as the commit message when
  81.184 -creating changesets.  To find the beginning of the patch content,
  81.185 -\command{patch} searches for the first line that starts with the
  81.186 -string ``\texttt{diff~-}''.
  81.187 -
  81.188 -MQ works with \emph{unified} diffs (\command{patch} can accept several
  81.189 -other diff formats, but MQ doesn't).  A unified diff contains two
  81.190 -kinds of header.  The \emph{file header} describes the file being
  81.191 -modified; it contains the name of the file to modify.  When
  81.192 -\command{patch} sees a new file header, it looks for a file with that
  81.193 -name to start modifying.
  81.194 -
  81.195 -After the file header comes a series of \emph{hunks}.  Each hunk
  81.196 -starts with a header; this identifies the range of line numbers within
  81.197 -the file that the hunk should modify.  Following the header, a hunk
  81.198 -starts and ends with a few (usually three) lines of text from the
  81.199 -unmodified file; these are called the \emph{context} for the hunk.  If
  81.200 -there's only a small amount of context between successive hunks,
  81.201 -\command{diff} doesn't print a new hunk header; it just runs the hunks
  81.202 -together, with a few lines of context between modifications.
  81.203 -
  81.204 -Each line of context begins with a space character.  Within the hunk,
  81.205 -a line that begins with ``\texttt{-}'' means ``remove this line,''
  81.206 -while a line that begins with ``\texttt{+}'' means ``insert this
  81.207 -line.''  For example, a line that is modified is represented by one
  81.208 -deletion and one insertion.
  81.209 -
  81.210 -We will return to some of the more subtle aspects of patches later (in
  81.211 -section~\ref{sec:mq:adv-patch}), but you should have enough information
  81.212 -now to use MQ.
  81.213 -
  81.214 -\section{Getting started with Mercurial Queues}
  81.215 -\label{sec:mq:start}
  81.216 -
  81.217 -Because MQ is implemented as an extension, you must explicitly enable
  81.218 -before you can use it.  (You don't need to download anything; MQ ships
  81.219 -with the standard Mercurial distribution.)  To enable MQ, edit your
  81.220 -\tildefile{.hgrc} file, and add the lines in figure~\ref{ex:mq:config}.
  81.221 -
  81.222 -\begin{figure}[ht]
  81.223 -  \begin{codesample4}
  81.224 -    [extensions]
  81.225 -    hgext.mq =
  81.226 -  \end{codesample4}
  81.227 -  \label{ex:mq:config}
  81.228 -  \caption{Contents to add to \tildefile{.hgrc} to enable the MQ extension}
  81.229 -\end{figure}
  81.230 -
  81.231 -Once the extension is enabled, it will make a number of new commands
  81.232 -available.  To verify that the extension is working, you can use
  81.233 -\hgcmd{help} to see if the \hgxcmd{mq}{qinit} command is now available; see
  81.234 -the example in figure~\ref{ex:mq:enabled}.
  81.235 -
  81.236 -\begin{figure}[ht]
  81.237 -  \interaction{mq.qinit-help.help}
  81.238 -  \caption{How to verify that MQ is enabled}
  81.239 -  \label{ex:mq:enabled}
  81.240 -\end{figure}
  81.241 -
  81.242 -You can use MQ with \emph{any} Mercurial repository, and its commands
  81.243 -only operate within that repository.  To get started, simply prepare
  81.244 -the repository using the \hgxcmd{mq}{qinit} command (see
  81.245 -figure~\ref{ex:mq:qinit}).  This command creates an empty directory
  81.246 -called \sdirname{.hg/patches}, where MQ will keep its metadata.  As
  81.247 -with many Mercurial commands, the \hgxcmd{mq}{qinit} command prints nothing
  81.248 -if it succeeds.
  81.249 -
  81.250 -\begin{figure}[ht]
  81.251 -  \interaction{mq.tutorial.qinit}
  81.252 -  \caption{Preparing a repository for use with MQ}
  81.253 -  \label{ex:mq:qinit}
  81.254 -\end{figure}
  81.255 -
  81.256 -\begin{figure}[ht]
  81.257 -  \interaction{mq.tutorial.qnew}
  81.258 -  \caption{Creating a new patch}
  81.259 -  \label{ex:mq:qnew}
  81.260 -\end{figure}
  81.261 -
  81.262 -\subsection{Creating a new patch}
  81.263 -
  81.264 -To begin work on a new patch, use the \hgxcmd{mq}{qnew} command.  This
  81.265 -command takes one argument, the name of the patch to create.  MQ will
  81.266 -use this as the name of an actual file in the \sdirname{.hg/patches}
  81.267 -directory, as you can see in figure~\ref{ex:mq:qnew}.
  81.268 -
  81.269 -Also newly present in the \sdirname{.hg/patches} directory are two
  81.270 -other files, \sfilename{series} and \sfilename{status}.  The
  81.271 -\sfilename{series} file lists all of the patches that MQ knows about
  81.272 -for this repository, with one patch per line.  Mercurial uses the
  81.273 -\sfilename{status} file for internal book-keeping; it tracks all of the
  81.274 -patches that MQ has \emph{applied} in this repository.
  81.275 -
  81.276 -\begin{note}
  81.277 -  You may sometimes want to edit the \sfilename{series} file by hand;
  81.278 -  for example, to change the sequence in which some patches are
  81.279 -  applied.  However, manually editing the \sfilename{status} file is
  81.280 -  almost always a bad idea, as it's easy to corrupt MQ's idea of what
  81.281 -  is happening.
  81.282 -\end{note}
  81.283 -
  81.284 -Once you have created your new patch, you can edit files in the
  81.285 -working directory as you usually would.  All of the normal Mercurial
  81.286 -commands, such as \hgcmd{diff} and \hgcmd{annotate}, work exactly as
  81.287 -they did before.
  81.288 -
  81.289 -\subsection{Refreshing a patch}
  81.290 -
  81.291 -When you reach a point where you want to save your work, use the
  81.292 -\hgxcmd{mq}{qrefresh} command (figure~\ref{ex:mq:qnew}) to update the patch
  81.293 -you are working on.  This command folds the changes you have made in
  81.294 -the working directory into your patch, and updates its corresponding
  81.295 -changeset to contain those changes.
  81.296 -
  81.297 -\begin{figure}[ht]
  81.298 -  \interaction{mq.tutorial.qrefresh}
  81.299 -  \caption{Refreshing a patch}
  81.300 -  \label{ex:mq:qrefresh}
  81.301 -\end{figure}
  81.302 -
  81.303 -You can run \hgxcmd{mq}{qrefresh} as often as you like, so it's a good way
  81.304 -to ``checkpoint'' your work.  Refresh your patch at an opportune
  81.305 -time; try an experiment; and if the experiment doesn't work out,
  81.306 -\hgcmd{revert} your modifications back to the last time you refreshed.
  81.307 -
  81.308 -\begin{figure}[ht]
  81.309 -  \interaction{mq.tutorial.qrefresh2}
  81.310 -  \caption{Refresh a patch many times to accumulate changes}
  81.311 -  \label{ex:mq:qrefresh2}
  81.312 -\end{figure}
  81.313 -
  81.314 -\subsection{Stacking and tracking patches}
  81.315 -
  81.316 -Once you have finished working on a patch, or need to work on another,
  81.317 -you can use the \hgxcmd{mq}{qnew} command again to create a new patch.
  81.318 -Mercurial will apply this patch on top of your existing patch.  See
  81.319 -figure~\ref{ex:mq:qnew2} for an example.  Notice that the patch
  81.320 -contains the changes in our prior patch as part of its context (you
  81.321 -can see this more clearly in the output of \hgcmd{annotate}).
  81.322 -
  81.323 -\begin{figure}[ht]
  81.324 -  \interaction{mq.tutorial.qnew2}
  81.325 -  \caption{Stacking a second patch on top of the first}
  81.326 -  \label{ex:mq:qnew2}
  81.327 -\end{figure}
  81.328 -
  81.329 -So far, with the exception of \hgxcmd{mq}{qnew} and \hgxcmd{mq}{qrefresh}, we've
  81.330 -been careful to only use regular Mercurial commands.  However, MQ
  81.331 -provides many commands that are easier to use when you are thinking
  81.332 -about patches, as illustrated in figure~\ref{ex:mq:qseries}:
  81.333 -
  81.334 -\begin{itemize}
  81.335 -\item The \hgxcmd{mq}{qseries} command lists every patch that MQ knows
  81.336 -  about in this repository, from oldest to newest (most recently
  81.337 -  \emph{created}).
  81.338 -\item The \hgxcmd{mq}{qapplied} command lists every patch that MQ has
  81.339 -  \emph{applied} in this repository, again from oldest to newest (most
  81.340 -  recently applied).
  81.341 -\end{itemize}
  81.342 -
  81.343 -\begin{figure}[ht]
  81.344 -  \interaction{mq.tutorial.qseries}
  81.345 -  \caption{Understanding the patch stack with \hgxcmd{mq}{qseries} and
  81.346 -    \hgxcmd{mq}{qapplied}}
  81.347 -  \label{ex:mq:qseries}
  81.348 -\end{figure}
  81.349 -
  81.350 -\subsection{Manipulating the patch stack}
  81.351 -
  81.352 -The previous discussion implied that there must be a difference
  81.353 -between ``known'' and ``applied'' patches, and there is.  MQ can
  81.354 -manage a patch without it being applied in the repository.
  81.355 -
  81.356 -An \emph{applied} patch has a corresponding changeset in the
  81.357 -repository, and the effects of the patch and changeset are visible in
  81.358 -the working directory.  You can undo the application of a patch using
  81.359 -the \hgxcmd{mq}{qpop} command.  MQ still \emph{knows about}, or manages, a
  81.360 -popped patch, but the patch no longer has a corresponding changeset in
  81.361 -the repository, and the working directory does not contain the changes
  81.362 -made by the patch.  Figure~\ref{fig:mq:stack} illustrates the
  81.363 -difference between applied and tracked patches.
  81.364 -
  81.365 -\begin{figure}[ht]
  81.366 -  \centering
  81.367 -  \grafix{mq-stack}
  81.368 -  \caption{Applied and unapplied patches in the MQ patch stack}
  81.369 -  \label{fig:mq:stack}
  81.370 -\end{figure}
  81.371 -
  81.372 -You can reapply an unapplied, or popped, patch using the \hgxcmd{mq}{qpush}
  81.373 -command.  This creates a new changeset to correspond to the patch, and
  81.374 -the patch's changes once again become present in the working
  81.375 -directory.  See figure~\ref{ex:mq:qpop} for examples of \hgxcmd{mq}{qpop}
  81.376 -and \hgxcmd{mq}{qpush} in action.  Notice that once we have popped a patch
  81.377 -or two patches, the output of \hgxcmd{mq}{qseries} remains the same, while
  81.378 -that of \hgxcmd{mq}{qapplied} has changed.
  81.379 -
  81.380 -\begin{figure}[ht]
  81.381 -  \interaction{mq.tutorial.qpop}
  81.382 -  \caption{Modifying the stack of applied patches}
  81.383 -  \label{ex:mq:qpop}
  81.384 -\end{figure}
  81.385 -
  81.386 -\subsection{Pushing and popping many patches}
  81.387 -
  81.388 -While \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} each operate on a single patch at
  81.389 -a time by default, you can push and pop many patches in one go.  The
  81.390 -\hgxopt{mq}{qpush}{-a} option to \hgxcmd{mq}{qpush} causes it to push all
  81.391 -unapplied patches, while the \hgxopt{mq}{qpop}{-a} option to \hgxcmd{mq}{qpop}
  81.392 -causes it to pop all applied patches.  (For some more ways to push and
  81.393 -pop many patches, see section~\ref{sec:mq:perf} below.)
  81.394 -
  81.395 -\begin{figure}[ht]
  81.396 -  \interaction{mq.tutorial.qpush-a}
  81.397 -  \caption{Pushing all unapplied patches}
  81.398 -  \label{ex:mq:qpush-a}
  81.399 -\end{figure}
  81.400 -
  81.401 -\subsection{Safety checks, and overriding them}
  81.402 -
  81.403 -Several MQ commands check the working directory before they do
  81.404 -anything, and fail if they find any modifications.  They do this to
  81.405 -ensure that you won't lose any changes that you have made, but not yet
  81.406 -incorporated into a patch.  Figure~\ref{ex:mq:add} illustrates this;
  81.407 -the \hgxcmd{mq}{qnew} command will not create a new patch if there are
  81.408 -outstanding changes, caused in this case by the \hgcmd{add} of
  81.409 -\filename{file3}.
  81.410 -
  81.411 -\begin{figure}[ht]
  81.412 -  \interaction{mq.tutorial.add}
  81.413 -  \caption{Forcibly creating a patch}
  81.414 -  \label{ex:mq:add}
  81.415 -\end{figure}
  81.416 -
  81.417 -Commands that check the working directory all take an ``I know what
  81.418 -I'm doing'' option, which is always named \option{-f}.  The exact
  81.419 -meaning of \option{-f} depends on the command.  For example,
  81.420 -\hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}} will incorporate any outstanding
  81.421 -changes into the new patch it creates, but
  81.422 -\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} will revert modifications to any
  81.423 -files affected by the patch that it is popping.  Be sure to read the
  81.424 -documentation for a command's \option{-f} option before you use it!
  81.425 -
  81.426 -\subsection{Working on several patches at once}
  81.427 -
  81.428 -The \hgxcmd{mq}{qrefresh} command always refreshes the \emph{topmost}
  81.429 -applied patch.  This means that you can suspend work on one patch (by
  81.430 -refreshing it), pop or push to make a different patch the top, and
  81.431 -work on \emph{that} patch for a while.
  81.432 -
  81.433 -Here's an example that illustrates how you can use this ability.
  81.434 -Let's say you're developing a new feature as two patches.  The first
  81.435 -is a change to the core of your software, and the second---layered on
  81.436 -top of the first---changes the user interface to use the code you just
  81.437 -added to the core.  If you notice a bug in the core while you're
  81.438 -working on the UI patch, it's easy to fix the core.  Simply
  81.439 -\hgxcmd{mq}{qrefresh} the UI patch to save your in-progress changes, and
  81.440 -\hgxcmd{mq}{qpop} down to the core patch.  Fix the core bug,
  81.441 -\hgxcmd{mq}{qrefresh} the core patch, and \hgxcmd{mq}{qpush} back to the UI
  81.442 -patch to continue where you left off.
  81.443 -
  81.444 -\section{More about patches}
  81.445 -\label{sec:mq:adv-patch}
  81.446 -
  81.447 -MQ uses the GNU \command{patch} command to apply patches, so it's
  81.448 -helpful to know a few more detailed aspects of how \command{patch}
  81.449 -works, and about patches themselves.
  81.450 -
  81.451 -\subsection{The strip count}
  81.452 -
  81.453 -If you look at the file headers in a patch, you will notice that the
  81.454 -pathnames usually have an extra component on the front that isn't
  81.455 -present in the actual path name.  This is a holdover from the way that
  81.456 -people used to generate patches (people still do this, but it's
  81.457 -somewhat rare with modern revision control tools).  
  81.458 -
  81.459 -Alice would unpack a tarball, edit her files, then decide that she
  81.460 -wanted to create a patch.  So she'd rename her working directory,
  81.461 -unpack the tarball again (hence the need for the rename), and use the
  81.462 -\cmdopt{diff}{-r} and \cmdopt{diff}{-N} options to \command{diff} to
  81.463 -recursively generate a patch between the unmodified directory and the
  81.464 -modified one.  The result would be that the name of the unmodified
  81.465 -directory would be at the front of the left-hand path in every file
  81.466 -header, and the name of the modified directory would be at the front
  81.467 -of the right-hand path.
  81.468 -
  81.469 -Since someone receiving a patch from the Alices of the net would be
  81.470 -unlikely to have unmodified and modified directories with exactly the
  81.471 -same names, the \command{patch} command has a \cmdopt{patch}{-p}
  81.472 -option that indicates the number of leading path name components to
  81.473 -strip when trying to apply a patch.  This number is called the
  81.474 -\emph{strip count}.
  81.475 -
  81.476 -An option of ``\texttt{-p1}'' means ``use a strip count of one''.  If
  81.477 -\command{patch} sees a file name \filename{foo/bar/baz} in a file
  81.478 -header, it will strip \filename{foo} and try to patch a file named
  81.479 -\filename{bar/baz}.  (Strictly speaking, the strip count refers to the
  81.480 -number of \emph{path separators} (and the components that go with them
  81.481 -) to strip.  A strip count of one will turn \filename{foo/bar} into
  81.482 -\filename{bar}, but \filename{/foo/bar} (notice the extra leading
  81.483 -slash) into \filename{foo/bar}.)
  81.484 -
  81.485 -The ``standard'' strip count for patches is one; almost all patches
  81.486 -contain one leading path name component that needs to be stripped.
  81.487 -Mercurial's \hgcmd{diff} command generates path names in this form,
  81.488 -and the \hgcmd{import} command and MQ expect patches to have a strip
  81.489 -count of one.
  81.490 -
  81.491 -If you receive a patch from someone that you want to add to your patch
  81.492 -queue, and the patch needs a strip count other than one, you cannot
  81.493 -just \hgxcmd{mq}{qimport} the patch, because \hgxcmd{mq}{qimport} does not yet
  81.494 -have a \texttt{-p} option (see~\bug{311}).  Your best bet is to
  81.495 -\hgxcmd{mq}{qnew} a patch of your own, then use \cmdargs{patch}{-p\emph{N}}
  81.496 -to apply their patch, followed by \hgcmd{addremove} to pick up any
  81.497 -files added or removed by the patch, followed by \hgxcmd{mq}{qrefresh}.
  81.498 -This complexity may become unnecessary; see~\bug{311} for details.
  81.499 -\subsection{Strategies for applying a patch}
  81.500 -
  81.501 -When \command{patch} applies a hunk, it tries a handful of
  81.502 -successively less accurate strategies to try to make the hunk apply.
  81.503 -This falling-back technique often makes it possible to take a patch
  81.504 -that was generated against an old version of a file, and apply it
  81.505 -against a newer version of that file.
  81.506 -
  81.507 -First, \command{patch} tries an exact match, where the line numbers,
  81.508 -the context, and the text to be modified must apply exactly.  If it
  81.509 -cannot make an exact match, it tries to find an exact match for the
  81.510 -context, without honouring the line numbering information.  If this
  81.511 -succeeds, it prints a line of output saying that the hunk was applied,
  81.512 -but at some \emph{offset} from the original line number.
  81.513 -
  81.514 -If a context-only match fails, \command{patch} removes the first and
  81.515 -last lines of the context, and tries a \emph{reduced} context-only
  81.516 -match.  If the hunk with reduced context succeeds, it prints a message
  81.517 -saying that it applied the hunk with a \emph{fuzz factor} (the number
  81.518 -after the fuzz factor indicates how many lines of context
  81.519 -\command{patch} had to trim before the patch applied).
  81.520 -
  81.521 -When neither of these techniques works, \command{patch} prints a
  81.522 -message saying that the hunk in question was rejected.  It saves
  81.523 -rejected hunks (also simply called ``rejects'') to a file with the
  81.524 -same name, and an added \sfilename{.rej} extension.  It also saves an
  81.525 -unmodified copy of the file with a \sfilename{.orig} extension; the
  81.526 -copy of the file without any extensions will contain any changes made
  81.527 -by hunks that \emph{did} apply cleanly.  If you have a patch that
  81.528 -modifies \filename{foo} with six hunks, and one of them fails to
  81.529 -apply, you will have: an unmodified \filename{foo.orig}, a
  81.530 -\filename{foo.rej} containing one hunk, and \filename{foo}, containing
  81.531 -the changes made by the five successful hunks.
  81.532 -
  81.533 -\subsection{Some quirks of patch representation}
  81.534 -
  81.535 -There are a few useful things to know about how \command{patch} works
  81.536 -with files.
  81.537 -\begin{itemize}
  81.538 -\item This should already be obvious, but \command{patch} cannot
  81.539 -  handle binary files.
  81.540 -\item Neither does it care about the executable bit; it creates new
  81.541 -  files as readable, but not executable.
  81.542 -\item \command{patch} treats the removal of a file as a diff between
  81.543 -  the file to be removed and the empty file.  So your idea of ``I
  81.544 -  deleted this file'' looks like ``every line of this file was
  81.545 -  deleted'' in a patch.
  81.546 -\item It treats the addition of a file as a diff between the empty
  81.547 -  file and the file to be added.  So in a patch, your idea of ``I
  81.548 -  added this file'' looks like ``every line of this file was added''.
  81.549 -\item It treats a renamed file as the removal of the old name, and the
  81.550 -  addition of the new name.  This means that renamed files have a big
  81.551 -  footprint in patches.  (Note also that Mercurial does not currently
  81.552 -  try to infer when files have been renamed or copied in a patch.)
  81.553 -\item \command{patch} cannot represent empty files, so you cannot use
  81.554 -  a patch to represent the notion ``I added this empty file to the
  81.555 -  tree''.
  81.556 -\end{itemize}
  81.557 -\subsection{Beware the fuzz}
  81.558 -
  81.559 -While applying a hunk at an offset, or with a fuzz factor, will often
  81.560 -be completely successful, these inexact techniques naturally leave
  81.561 -open the possibility of corrupting the patched file.  The most common
  81.562 -cases typically involve applying a patch twice, or at an incorrect
  81.563 -location in the file.  If \command{patch} or \hgxcmd{mq}{qpush} ever
  81.564 -mentions an offset or fuzz factor, you should make sure that the
  81.565 -modified files are correct afterwards.  
  81.566 -
  81.567 -It's often a good idea to refresh a patch that has applied with an
  81.568 -offset or fuzz factor; refreshing the patch generates new context
  81.569 -information that will make it apply cleanly.  I say ``often,'' not
  81.570 -``always,'' because sometimes refreshing a patch will make it fail to
  81.571 -apply against a different revision of the underlying files.  In some
  81.572 -cases, such as when you're maintaining a patch that must sit on top of
  81.573 -multiple versions of a source tree, it's acceptable to have a patch
  81.574 -apply with some fuzz, provided you've verified the results of the
  81.575 -patching process in such cases.
  81.576 -
  81.577 -\subsection{Handling rejection}
  81.578 -
  81.579 -If \hgxcmd{mq}{qpush} fails to apply a patch, it will print an error
  81.580 -message and exit.  If it has left \sfilename{.rej} files behind, it is
  81.581 -usually best to fix up the rejected hunks before you push more patches
  81.582 -or do any further work.
  81.583 -
  81.584 -If your patch \emph{used to} apply cleanly, and no longer does because
  81.585 -you've changed the underlying code that your patches are based on,
  81.586 -Mercurial Queues can help; see section~\ref{sec:mq:merge} for details.
  81.587 -
  81.588 -Unfortunately, there aren't any great techniques for dealing with
  81.589 -rejected hunks.  Most often, you'll need to view the \sfilename{.rej}
  81.590 -file and edit the target file, applying the rejected hunks by hand.
  81.591 -
  81.592 -If you're feeling adventurous, Neil Brown, a Linux kernel hacker,
  81.593 -wrote a tool called \command{wiggle}~\cite{web:wiggle}, which is more
  81.594 -vigorous than \command{patch} in its attempts to make a patch apply.
  81.595 -
  81.596 -Another Linux kernel hacker, Chris Mason (the author of Mercurial
  81.597 -Queues), wrote a similar tool called
  81.598 -\command{mpatch}~\cite{web:mpatch}, which takes a simple approach to
  81.599 -automating the application of hunks rejected by \command{patch}.  The
  81.600 -\command{mpatch} command can help with four common reasons that a hunk
  81.601 -may be rejected:
  81.602 -
  81.603 -\begin{itemize}
  81.604 -\item The context in the middle of a hunk has changed.
  81.605 -\item A hunk is missing some context at the beginning or end.
  81.606 -\item A large hunk might apply better---either entirely or in
  81.607 -  part---if it was broken up into smaller hunks.
  81.608 -\item A hunk removes lines with slightly different content than those
  81.609 -  currently present in the file.
  81.610 -\end{itemize}
  81.611 -
  81.612 -If you use \command{wiggle} or \command{mpatch}, you should be doubly
  81.613 -careful to check your results when you're done.  In fact,
  81.614 -\command{mpatch} enforces this method of double-checking the tool's
  81.615 -output, by automatically dropping you into a merge program when it has
  81.616 -done its job, so that you can verify its work and finish off any
  81.617 -remaining merges.
  81.618 -
  81.619 -\section{Getting the best performance out of MQ}
  81.620 -\label{sec:mq:perf}
  81.621 -
  81.622 -MQ is very efficient at handling a large number of patches.  I ran
  81.623 -some performance experiments in mid-2006 for a talk that I gave at the
  81.624 -2006 EuroPython conference~\cite{web:europython}.  I used as my data
  81.625 -set the Linux 2.6.17-mm1 patch series, which consists of 1,738
  81.626 -patches.  I applied these on top of a Linux kernel repository
  81.627 -containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux
  81.628 -2.6.17.
  81.629 -
  81.630 -On my old, slow laptop, I was able to
  81.631 -\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} all 1,738 patches in 3.5 minutes,
  81.632 -and \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} them all in 30 seconds.  (On a
  81.633 -newer laptop, the time to push all patches dropped to two minutes.)  I
  81.634 -could \hgxcmd{mq}{qrefresh} one of the biggest patches (which made 22,779
  81.635 -lines of changes to 287 files) in 6.6 seconds.
  81.636 -
  81.637 -Clearly, MQ is well suited to working in large trees, but there are a
  81.638 -few tricks you can use to get the best performance of it.
  81.639 -
  81.640 -First of all, try to ``batch'' operations together.  Every time you
  81.641 -run \hgxcmd{mq}{qpush} or \hgxcmd{mq}{qpop}, these commands scan the working
  81.642 -directory once to make sure you haven't made some changes and then
  81.643 -forgotten to run \hgxcmd{mq}{qrefresh}.  On a small tree, the time that
  81.644 -this scan takes is unnoticeable.  However, on a medium-sized tree
  81.645 -(containing tens of thousands of files), it can take a second or more.
  81.646 -
  81.647 -The \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} commands allow you to push and pop
  81.648 -multiple patches at a time.  You can identify the ``destination
  81.649 -patch'' that you want to end up at.  When you \hgxcmd{mq}{qpush} with a
  81.650 -destination specified, it will push patches until that patch is at the
  81.651 -top of the applied stack.  When you \hgxcmd{mq}{qpop} to a destination, MQ
  81.652 -will pop patches until the destination patch is at the top.
  81.653 -
  81.654 -You can identify a destination patch using either the name of the
  81.655 -patch, or by number.  If you use numeric addressing, patches are
  81.656 -counted from zero; this means that the first patch is zero, the second
  81.657 -is one, and so on.
  81.658 -
  81.659 -\section{Updating your patches when the underlying code changes}
  81.660 -\label{sec:mq:merge}
  81.661 -
  81.662 -It's common to have a stack of patches on top of an underlying
  81.663 -repository that you don't modify directly.  If you're working on
  81.664 -changes to third-party code, or on a feature that is taking longer to
  81.665 -develop than the rate of change of the code beneath, you will often
  81.666 -need to sync up with the underlying code, and fix up any hunks in your
  81.667 -patches that no longer apply.  This is called \emph{rebasing} your
  81.668 -patch series.
  81.669 -
  81.670 -The simplest way to do this is to \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}}
  81.671 -your patches, then \hgcmd{pull} changes into the underlying
  81.672 -repository, and finally \hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} your
  81.673 -patches again.  MQ will stop pushing any time it runs across a patch
  81.674 -that fails to apply during conflicts, allowing you to fix your
  81.675 -conflicts, \hgxcmd{mq}{qrefresh} the affected patch, and continue pushing
  81.676 -until you have fixed your entire stack.
  81.677 -
  81.678 -This approach is easy to use and works well if you don't expect
  81.679 -changes to the underlying code to affect how well your patches apply.
  81.680 -If your patch stack touches code that is modified frequently or
  81.681 -invasively in the underlying repository, however, fixing up rejected
  81.682 -hunks by hand quickly becomes tiresome.
  81.683 -
  81.684 -It's possible to partially automate the rebasing process.  If your
  81.685 -patches apply cleanly against some revision of the underlying repo, MQ
  81.686 -can use this information to help you to resolve conflicts between your
  81.687 -patches and a different revision.
  81.688 -
  81.689 -The process is a little involved.
  81.690 -\begin{enumerate}
  81.691 -\item To begin, \hgcmdargs{qpush}{-a} all of your patches on top of
  81.692 -  the revision where you know that they apply cleanly.
  81.693 -\item Save a backup copy of your patch directory using
  81.694 -  \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}.  This prints
  81.695 -  the name of the directory that it has saved the patches in.  It will
  81.696 -  save the patches to a directory called
  81.697 -  \sdirname{.hg/patches.\emph{N}}, where \texttt{\emph{N}} is a small
  81.698 -  integer.  It also commits a ``save changeset'' on top of your
  81.699 -  applied patches; this is for internal book-keeping, and records the
  81.700 -  states of the \sfilename{series} and \sfilename{status} files.
  81.701 -\item Use \hgcmd{pull} to bring new changes into the underlying
  81.702 -  repository.  (Don't run \hgcmdargs{pull}{-u}; see below for why.)
  81.703 -\item Update to the new tip revision, using
  81.704 -  \hgcmdargs{update}{\hgopt{update}{-C}} to override the patches you
  81.705 -  have pushed.
  81.706 -\item Merge all patches using \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}
  81.707 -    \hgxopt{mq}{qpush}{-a}}.  The \hgxopt{mq}{qpush}{-m} option to \hgxcmd{mq}{qpush}
  81.708 -  tells MQ to perform a three-way merge if the patch fails to apply.
  81.709 -\end{enumerate}
  81.710 -
  81.711 -During the \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, each patch in the
  81.712 -\sfilename{series} file is applied normally.  If a patch applies with
  81.713 -fuzz or rejects, MQ looks at the queue you \hgxcmd{mq}{qsave}d, and
  81.714 -performs a three-way merge with the corresponding changeset.  This
  81.715 -merge uses Mercurial's normal merge machinery, so it may pop up a GUI
  81.716 -merge tool to help you to resolve problems.
  81.717 -
  81.718 -When you finish resolving the effects of a patch, MQ refreshes your
  81.719 -patch based on the result of the merge.
  81.720 -
  81.721 -At the end of this process, your repository will have one extra head
  81.722 -from the old patch queue, and a copy of the old patch queue will be in
  81.723 -\sdirname{.hg/patches.\emph{N}}. You can remove the extra head using
  81.724 -\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}}
  81.725 -or \hgcmd{strip}.  You can delete \sdirname{.hg/patches.\emph{N}} once
  81.726 -you are sure that you no longer need it as a backup.
  81.727 -
  81.728 -\section{Identifying patches}
  81.729 -
  81.730 -MQ commands that work with patches let you refer to a patch either by
  81.731 -using its name or by a number.  By name is obvious enough; pass the
  81.732 -name \filename{foo.patch} to \hgxcmd{mq}{qpush}, for example, and it will
  81.733 -push patches until \filename{foo.patch} is applied.  
  81.734 -
  81.735 -As a shortcut, you can refer to a patch using both a name and a
  81.736 -numeric offset; \texttt{foo.patch-2} means ``two patches before
  81.737 -\texttt{foo.patch}'', while \texttt{bar.patch+4} means ``four patches
  81.738 -after \texttt{bar.patch}''.
  81.739 -
  81.740 -Referring to a patch by index isn't much different.  The first patch
  81.741 -printed in the output of \hgxcmd{mq}{qseries} is patch zero (yes, it's one
  81.742 -of those start-at-zero counting systems); the second is patch one; and
  81.743 -so on.
  81.744 -
  81.745 -MQ also makes it easy to work with patches when you are using normal
  81.746 -Mercurial commands.  Every command that accepts a changeset ID will
  81.747 -also accept the name of an applied patch.  MQ augments the tags
  81.748 -normally in the repository with an eponymous one for each applied
  81.749 -patch.  In addition, the special tags \index{tags!special tag
  81.750 -  names!\texttt{qbase}}\texttt{qbase} and \index{tags!special tag
  81.751 -  names!\texttt{qtip}}\texttt{qtip} identify the ``bottom-most'' and
  81.752 -topmost applied patches, respectively.
  81.753 -
  81.754 -These additions to Mercurial's normal tagging capabilities make
  81.755 -dealing with patches even more of a breeze.
  81.756 -\begin{itemize}
  81.757 -\item Want to patchbomb a mailing list with your latest series of
  81.758 -  changes?
  81.759 -  \begin{codesample4}
  81.760 -    hg email qbase:qtip
  81.761 -  \end{codesample4}
  81.762 -  (Don't know what ``patchbombing'' is?  See
  81.763 -  section~\ref{sec:hgext:patchbomb}.)
  81.764 -\item Need to see all of the patches since \texttt{foo.patch} that
  81.765 -  have touched files in a subdirectory of your tree?
  81.766 -  \begin{codesample4}
  81.767 -    hg log -r foo.patch:qtip \emph{subdir}
  81.768 -  \end{codesample4}
  81.769 -\end{itemize}
  81.770 -
  81.771 -Because MQ makes the names of patches available to the rest of
  81.772 -Mercurial through its normal internal tag machinery, you don't need to
  81.773 -type in the entire name of a patch when you want to identify it by
  81.774 -name.
  81.775 -
  81.776 -\begin{figure}[ht]
  81.777 -  \interaction{mq.id.output}
  81.778 -  \caption{Using MQ's tag features to work with patches}
  81.779 -  \label{ex:mq:id}
  81.780 -\end{figure}
  81.781 -
  81.782 -Another nice consequence of representing patch names as tags is that
  81.783 -when you run the \hgcmd{log} command, it will display a patch's name
  81.784 -as a tag, simply as part of its normal output.  This makes it easy to
  81.785 -visually distinguish applied patches from underlying ``normal''
  81.786 -revisions.  Figure~\ref{ex:mq:id} shows a few normal Mercurial
  81.787 -commands in use with applied patches.
  81.788 -
  81.789 -\section{Useful things to know about}
  81.790 -
  81.791 -There are a number of aspects of MQ usage that don't fit tidily into
  81.792 -sections of their own, but that are good to know.  Here they are, in
  81.793 -one place.
  81.794 -
  81.795 -\begin{itemize}
  81.796 -\item Normally, when you \hgxcmd{mq}{qpop} a patch and \hgxcmd{mq}{qpush} it
  81.797 -  again, the changeset that represents the patch after the pop/push
  81.798 -  will have a \emph{different identity} than the changeset that
  81.799 -  represented the hash beforehand.  See
  81.800 -  section~\ref{sec:mqref:cmd:qpush} for information as to why this is.
  81.801 -\item It's not a good idea to \hgcmd{merge} changes from another
  81.802 -  branch with a patch changeset, at least if you want to maintain the
  81.803 -  ``patchiness'' of that changeset and changesets below it on the
  81.804 -  patch stack.  If you try to do this, it will appear to succeed, but
  81.805 -  MQ will become confused.
  81.806 -\end{itemize}
  81.807 -
  81.808 -\section{Managing patches in a repository}
  81.809 -\label{sec:mq:repo}
  81.810 -
  81.811 -Because MQ's \sdirname{.hg/patches} directory resides outside a
  81.812 -Mercurial repository's working directory, the ``underlying'' Mercurial
  81.813 -repository knows nothing about the management or presence of patches.
  81.814 -
  81.815 -This presents the interesting possibility of managing the contents of
  81.816 -the patch directory as a Mercurial repository in its own right.  This
  81.817 -can be a useful way to work.  For example, you can work on a patch for
  81.818 -a while, \hgxcmd{mq}{qrefresh} it, then \hgcmd{commit} the current state of
  81.819 -the patch.  This lets you ``roll back'' to that version of the patch
  81.820 -later on.
  81.821 -
  81.822 -You can then share different versions of the same patch stack among
  81.823 -multiple underlying repositories.  I use this when I am developing a
  81.824 -Linux kernel feature.  I have a pristine copy of my kernel sources for
  81.825 -each of several CPU architectures, and a cloned repository under each
  81.826 -that contains the patches I am working on.  When I want to test a
  81.827 -change on a different architecture, I push my current patches to the
  81.828 -patch repository associated with that kernel tree, pop and push all of
  81.829 -my patches, and build and test that kernel.
  81.830 -
  81.831 -Managing patches in a repository makes it possible for multiple
  81.832 -developers to work on the same patch series without colliding with
  81.833 -each other, all on top of an underlying source base that they may or
  81.834 -may not control.
  81.835 -
  81.836 -\subsection{MQ support for patch repositories}
  81.837 -
  81.838 -MQ helps you to work with the \sdirname{.hg/patches} directory as a
  81.839 -repository; when you prepare a repository for working with patches
  81.840 -using \hgxcmd{mq}{qinit}, you can pass the \hgxopt{mq}{qinit}{-c} option to
  81.841 -create the \sdirname{.hg/patches} directory as a Mercurial repository.
  81.842 -
  81.843 -\begin{note}
  81.844 -  If you forget to use the \hgxopt{mq}{qinit}{-c} option, you can simply go
  81.845 -  into the \sdirname{.hg/patches} directory at any time and run
  81.846 -  \hgcmd{init}.  Don't forget to add an entry for the
  81.847 -  \sfilename{status} file to the \sfilename{.hgignore} file, though
  81.848 -
  81.849 -  (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} does this for you
  81.850 -  automatically); you \emph{really} don't want to manage the
  81.851 -  \sfilename{status} file.
  81.852 -\end{note}
  81.853 -
  81.854 -As a convenience, if MQ notices that the \dirname{.hg/patches}
  81.855 -directory is a repository, it will automatically \hgcmd{add} every
  81.856 -patch that you create and import.
  81.857 -
  81.858 -MQ provides a shortcut command, \hgxcmd{mq}{qcommit}, that runs
  81.859 -\hgcmd{commit} in the \sdirname{.hg/patches} directory.  This saves
  81.860 -some bothersome typing.
  81.861 -
  81.862 -Finally, as a convenience to manage the patch directory, you can
  81.863 -define the alias \command{mq} on Unix systems. For example, on Linux
  81.864 -systems using the \command{bash} shell, you can include the following
  81.865 -snippet in your \tildefile{.bashrc}.
  81.866 -
  81.867 -\begin{codesample2}
  81.868 -  alias mq=`hg -R \$(hg root)/.hg/patches'
  81.869 -\end{codesample2}
  81.870 -
  81.871 -You can then issue commands of the form \cmdargs{mq}{pull} from
  81.872 -the main repository.
  81.873 -
  81.874 -\subsection{A few things to watch out for}
  81.875 -
  81.876 -MQ's support for working with a repository full of patches is limited
  81.877 -in a few small respects.
  81.878 -
  81.879 -MQ cannot automatically detect changes that you make to the patch
  81.880 -directory.  If you \hgcmd{pull}, manually edit, or \hgcmd{update}
  81.881 -changes to patches or the \sfilename{series} file, you will have to
  81.882 -\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} and then
  81.883 -\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} in the underlying repository to
  81.884 -see those changes show up there.  If you forget to do this, you can
  81.885 -confuse MQ's idea of which patches are applied.
  81.886 -
  81.887 -\section{Third party tools for working with patches}
  81.888 -\label{sec:mq:tools}
  81.889 -
  81.890 -Once you've been working with patches for a while, you'll find
  81.891 -yourself hungry for tools that will help you to understand and
  81.892 -manipulate the patches you're dealing with.
  81.893 -
  81.894 -The \command{diffstat} command~\cite{web:diffstat} generates a
  81.895 -histogram of the modifications made to each file in a patch.  It
  81.896 -provides a good way to ``get a sense of'' a patch---which files it
  81.897 -affects, and how much change it introduces to each file and as a
  81.898 -whole.  (I find that it's a good idea to use \command{diffstat}'s
  81.899 -\cmdopt{diffstat}{-p} option as a matter of course, as otherwise it
  81.900 -will try to do clever things with prefixes of file names that
  81.901 -inevitably confuse at least me.)
  81.902 -
  81.903 -\begin{figure}[ht]
  81.904 -  \interaction{mq.tools.tools}
  81.905 -  \caption{The \command{diffstat}, \command{filterdiff}, and \command{lsdiff} commands}
  81.906 -  \label{ex:mq:tools}
  81.907 -\end{figure}
  81.908 -
  81.909 -The \package{patchutils} package~\cite{web:patchutils} is invaluable.
  81.910 -It provides a set of small utilities that follow the ``Unix
  81.911 -philosophy;'' each does one useful thing with a patch.  The
  81.912 -\package{patchutils} command I use most is \command{filterdiff}, which
  81.913 -extracts subsets from a patch file.  For example, given a patch that
  81.914 -modifies hundreds of files across dozens of directories, a single
  81.915 -invocation of \command{filterdiff} can generate a smaller patch that
  81.916 -only touches files whose names match a particular glob pattern.  See
  81.917 -section~\ref{mq-collab:tips:interdiff} for another example.
  81.918 -
  81.919 -\section{Good ways to work with patches}
  81.920 -
  81.921 -Whether you are working on a patch series to submit to a free software
  81.922 -or open source project, or a series that you intend to treat as a
  81.923 -sequence of regular changesets when you're done, you can use some
  81.924 -simple techniques to keep your work well organised.
  81.925 -
  81.926 -Give your patches descriptive names.  A good name for a patch might be
  81.927 -\filename{rework-device-alloc.patch}, because it will immediately give
  81.928 -you a hint what the purpose of the patch is.  Long names shouldn't be
  81.929 -a problem; you won't be typing the names often, but you \emph{will} be
  81.930 -running commands like \hgxcmd{mq}{qapplied} and \hgxcmd{mq}{qtop} over and over.
  81.931 -Good naming becomes especially important when you have a number of
  81.932 -patches to work with, or if you are juggling a number of different
  81.933 -tasks and your patches only get a fraction of your attention.
  81.934 -
  81.935 -Be aware of what patch you're working on.  Use the \hgxcmd{mq}{qtop}
  81.936 -command and skim over the text of your patches frequently---for
  81.937 -example, using \hgcmdargs{tip}{\hgopt{tip}{-p}})---to be sure of where
  81.938 -you stand.  I have several times worked on and \hgxcmd{mq}{qrefresh}ed a
  81.939 -patch other than the one I intended, and it's often tricky to migrate
  81.940 -changes into the right patch after making them in the wrong one.
  81.941 -
  81.942 -For this reason, it is very much worth investing a little time to
  81.943 -learn how to use some of the third-party tools I described in
  81.944 -section~\ref{sec:mq:tools}, particularly \command{diffstat} and
  81.945 -\command{filterdiff}.  The former will give you a quick idea of what
  81.946 -changes your patch is making, while the latter makes it easy to splice
  81.947 -hunks selectively out of one patch and into another.
  81.948 -
  81.949 -\section{MQ cookbook}
  81.950 -
  81.951 -\subsection{Manage ``trivial'' patches}
  81.952 -
  81.953 -Because the overhead of dropping files into a new Mercurial repository
  81.954 -is so low, it makes a lot of sense to manage patches this way even if
  81.955 -you simply want to make a few changes to a source tarball that you
  81.956 -downloaded.
  81.957 -
  81.958 -Begin by downloading and unpacking the source tarball,
  81.959 -and turning it into a Mercurial repository.
  81.960 -\interaction{mq.tarball.download}
  81.961 -
  81.962 -Continue by creating a patch stack and making your changes.
  81.963 -\interaction{mq.tarball.qinit}
  81.964 -
  81.965 -Let's say a few weeks or months pass, and your package author releases
  81.966 -a new version.  First, bring their changes into the repository.
  81.967 -\interaction{mq.tarball.newsource}
  81.968 -The pipeline starting with \hgcmd{locate} above deletes all files in
  81.969 -the working directory, so that \hgcmd{commit}'s
  81.970 -\hgopt{commit}{--addremove} option can actually tell which files have
  81.971 -really been removed in the newer version of the source.
  81.972 -
  81.973 -Finally, you can apply your patches on top of the new tree.
  81.974 -\interaction{mq.tarball.repush}
  81.975 -
  81.976 -\subsection{Combining entire patches}
  81.977 -\label{sec:mq:combine}
  81.978 -
  81.979 -MQ provides a command, \hgxcmd{mq}{qfold} that lets you combine entire
  81.980 -patches.  This ``folds'' the patches you name, in the order you name
  81.981 -them, into the topmost applied patch, and concatenates their
  81.982 -descriptions onto the end of its description.  The patches that you
  81.983 -fold must be unapplied before you fold them.
  81.984 -
  81.985 -The order in which you fold patches matters.  If your topmost applied
  81.986 -patch is \texttt{foo}, and you \hgxcmd{mq}{qfold} \texttt{bar} and
  81.987 -\texttt{quux} into it, you will end up with a patch that has the same
  81.988 -effect as if you applied first \texttt{foo}, then \texttt{bar},
  81.989 -followed by \texttt{quux}.
  81.990 -
  81.991 -\subsection{Merging part of one patch into another}
  81.992 -
  81.993 -Merging \emph{part} of one patch into another is more difficult than
  81.994 -combining entire patches.
  81.995 -
  81.996 -If you want to move changes to entire files, you can use
  81.997 -\command{filterdiff}'s \cmdopt{filterdiff}{-i} and
  81.998 -\cmdopt{filterdiff}{-x} options to choose the modifications to snip
  81.999 -out of one patch, concatenating its output onto the end of the patch
 81.1000 -you want to merge into.  You usually won't need to modify the patch
 81.1001 -you've merged the changes from.  Instead, MQ will report some rejected
 81.1002 -hunks when you \hgxcmd{mq}{qpush} it (from the hunks you moved into the
 81.1003 -other patch), and you can simply \hgxcmd{mq}{qrefresh} the patch to drop
 81.1004 -the duplicate hunks.
 81.1005 -
 81.1006 -If you have a patch that has multiple hunks modifying a file, and you
 81.1007 -only want to move a few of those hunks, the job becomes more messy,
 81.1008 -but you can still partly automate it.  Use \cmdargs{lsdiff}{-nvv} to
 81.1009 -print some metadata about the patch.
 81.1010 -\interaction{mq.tools.lsdiff}
 81.1011 -
 81.1012 -This command prints three different kinds of number:
 81.1013 -\begin{itemize}
 81.1014 -\item (in the first column) a \emph{file number} to identify each file
 81.1015 -  modified in the patch;
 81.1016 -\item (on the next line, indented) the line number within a modified
 81.1017 -  file where a hunk starts; and
 81.1018 -\item (on the same line) a \emph{hunk number} to identify that hunk.
 81.1019 -\end{itemize}
 81.1020 -
 81.1021 -You'll have to use some visual inspection, and reading of the patch,
 81.1022 -to identify the file and hunk numbers you'll want, but you can then
 81.1023 -pass them to to \command{filterdiff}'s \cmdopt{filterdiff}{--files}
 81.1024 -and \cmdopt{filterdiff}{--hunks} options, to select exactly the file
 81.1025 -and hunk you want to extract.
 81.1026 -
 81.1027 -Once you have this hunk, you can concatenate it onto the end of your
 81.1028 -destination patch and continue with the remainder of
 81.1029 -section~\ref{sec:mq:combine}.
 81.1030 -
 81.1031 -\section{Differences between quilt and MQ}
 81.1032 -
 81.1033 -If you are already familiar with quilt, MQ provides a similar command
 81.1034 -set.  There are a few differences in the way that it works.
 81.1035 -
 81.1036 -You will already have noticed that most quilt commands have MQ
 81.1037 -counterparts that simply begin with a ``\texttt{q}''.  The exceptions
 81.1038 -are quilt's \texttt{add} and \texttt{remove} commands, the
 81.1039 -counterparts for which are the normal Mercurial \hgcmd{add} and
 81.1040 -\hgcmd{remove} commands.  There is no MQ equivalent of the quilt
 81.1041 -\texttt{edit} command.
 81.1042 -
 81.1043 -%%% Local Variables: 
 81.1044 -%%% mode: latex
 81.1045 -%%% TeX-master: "00book"
 81.1046 -%%% End: 
    82.1 Binary file fr/note.png has changed
    83.1 --- a/fr/preface.tex	Sun Aug 16 03:41:39 2009 +0200
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,65 +0,0 @@
    83.4 -\chapter*{Préface}
    83.5 -\addcontentsline{toc}{chapter}{Préface}
    83.6 -\label{chap:preface}
    83.7 -
    83.8 -La gestion de source distribuée est encore un territoire peu exploré
    83.9 -et qui, par conséquent, a grandi très rapidement grâce à la seule 
   83.10 -volonté de ses explorateurs.
   83.11 -
   83.12 -Je rédige un livre sur ce sujet car je crois que c'est un sujet 
   83.13 -important qui mérite bien un guide du ``terrain''. J'ai choisi d'écrire
   83.14 -ce livre sur Mercurial car c'est l'outil le plus simple pour découvrir
   83.15 -ce nouveau monde et qu'en outre, il répond très bien au besoin de
   83.16 -réels environnements, là où d'autres outils de gestion de source n'y
   83.17 -parviennent pas.
   83.18 -
   83.19 -\section{Cet ouvrage est un travail en cours}
   83.20 -
   83.21 -Je publie ce livre tout en continuant à l'écrire, dans l'espoir qu'il
   83.22 -vous sera utile. J'espère aussi que les lecteurs pourront ainsi y contribuer
   83.23 -si ils le souhaitent.
   83.24 -
   83.25 -\section{À propros des exemples de ce livre}
   83.26 -
   83.27 -Ce livre a une approche particulière des exemples d'exécution. Ils sont 
   83.28 -toujours ``dynamiques''---chacun est le résultat d'un script shell qui
   83.29 -exécute les commandes Mercurial que vous voyez. Chaque fois qu'une 
   83.30 -image du livre est construite à partir des sources, tous les scripts d'exemple
   83.31 -sont exécutés automatiquement, et les résultats comparés à ceux attendus.
   83.32 -
   83.33 -Cette approche a l'avantage de garantir que les exemples sont toujours
   83.34 -justes ; ils montrent \emph{exactement} le comportement de la version de
   83.35 -Mercurial spécifiée dans la couverture de ce livre. Si je mets à jour cette
   83.36 -version, et que les commandes changent, la génération du livre échouera.
   83.37 -
   83.38 -Il y a un petit désavantage à cette approche, les dates et les
   83.39 -durées que vous verrez dans ces exemples ont tendances à être
   83.40 -``réduits'' de manière très différente d'une exécution manuelle. Un être humain
   83.41 -ne peut exécuter qu'une commande toutes les secondes, alors que mes scripts
   83.42 -automatisés en exécutent plusieurs en une seule seconde.
   83.43 -
   83.44 -Ainsi, en une seule seconde, plusieurs ``commits'' peuvent avoir lieu
   83.45 -au sein d'un exemple. Vous le constatez, entre autres, dans les 
   83.46 -exemples sur \hgext{bisect}, dans la section~\ref{sec:undo:bisect}.
   83.47 -
   83.48 -En conséquence, quand vous lisez les exemples, n'accordez pas trop
   83.49 -d'importance aux dates et aux durées d'exécution des commandes. Mais
   83.50 -\emph{soyez sûr} que le comportement que vous voyez est cohérent et
   83.51 -reproductible.
   83.52 -
   83.53 -\section{Colophon---Cet ouvrage est libre}
   83.54 -
   83.55 -Ce livre est publié sous la licence ``Open Publication License''
   83.56 -\footnote{Pour plus de renseignements : 
   83.57 -\url{http://opencontent.org/openpub/}{Open Publication License} }, 
   83.58 -et est construit uniquement à l'aide de logiciels libres. Il est mis
   83.59 -en forme avec \LaTex{}; et les illustrations sont réalisées avec 
   83.60 -\href{http://www.inkscape.org/}{Inkscape}.
   83.61 -
   83.62 -L'ensemble des fichiers sources de cet ouvrage est publié dans un
   83.63 -dépot mercurial  \url{http://hg.serpentine.com/mercurial/book}.
   83.64 -
   83.65 -%%% Local Variables: 
   83.66 -%%% mode: latex
   83.67 -%%% TeX-master: "00book"
   83.68 -%%% End: 
    84.1 --- a/fr/revlog.svg	Sun Aug 16 03:41:39 2009 +0200
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,1155 +0,0 @@
    84.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    84.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    84.6 -<svg
    84.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    84.8 -   xmlns:cc="http://web.resource.org/cc/"
    84.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   84.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   84.11 -   xmlns="http://www.w3.org/2000/svg"
   84.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
   84.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   84.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   84.15 -   width="744.09448819"
   84.16 -   height="1052.3622047"
   84.17 -   id="svg2"
   84.18 -   sodipodi:version="0.32"
   84.19 -   inkscape:version="0.44.1"
   84.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
   84.21 -   sodipodi:docname="revlog.svg">
   84.22 -  <defs
   84.23 -     id="defs4">
   84.24 -    <marker
   84.25 -       inkscape:stockid="Arrow1Mend"
   84.26 -       orient="auto"
   84.27 -       refY="0.0"
   84.28 -       refX="0.0"
   84.29 -       id="Arrow1Mend"
   84.30 -       style="overflow:visible;">
   84.31 -      <path
   84.32 -         id="path4852"
   84.33 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   84.34 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   84.35 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   84.36 -    </marker>
   84.37 -    <linearGradient
   84.38 -       id="linearGradient3092">
   84.39 -      <stop
   84.40 -         style="stop-color:#44436f;stop-opacity:1;"
   84.41 -         offset="0"
   84.42 -         id="stop3094" />
   84.43 -      <stop
   84.44 -         style="stop-color:#abade5;stop-opacity:1;"
   84.45 -         offset="1"
   84.46 -         id="stop3096" />
   84.47 -    </linearGradient>
   84.48 -    <linearGradient
   84.49 -       inkscape:collect="always"
   84.50 -       xlink:href="#linearGradient3092"
   84.51 -       id="linearGradient3118"
   84.52 -       gradientUnits="userSpaceOnUse"
   84.53 -       x1="176.16635"
   84.54 -       y1="405.21934"
   84.55 -       x2="417.11935"
   84.56 -       y2="405.21934" />
   84.57 -    <linearGradient
   84.58 -       inkscape:collect="always"
   84.59 -       xlink:href="#linearGradient3092"
   84.60 -       id="linearGradient3120"
   84.61 -       gradientUnits="userSpaceOnUse"
   84.62 -       x1="176.16635"
   84.63 -       y1="405.21934"
   84.64 -       x2="417.11935"
   84.65 -       y2="405.21934" />
   84.66 -    <linearGradient
   84.67 -       inkscape:collect="always"
   84.68 -       xlink:href="#linearGradient3092"
   84.69 -       id="linearGradient3129"
   84.70 -       gradientUnits="userSpaceOnUse"
   84.71 -       x1="176.16635"
   84.72 -       y1="405.21934"
   84.73 -       x2="417.11935"
   84.74 -       y2="405.21934"
   84.75 -       gradientTransform="translate(-0.928574,-1.428574)" />
   84.76 -    <linearGradient
   84.77 -       inkscape:collect="always"
   84.78 -       xlink:href="#linearGradient3092"
   84.79 -       id="linearGradient3133"
   84.80 -       gradientUnits="userSpaceOnUse"
   84.81 -       x1="176.16635"
   84.82 -       y1="405.21934"
   84.83 -       x2="417.11935"
   84.84 -       y2="405.21934"
   84.85 -       gradientTransform="translate(-0.928574,-1.428574)" />
   84.86 -    <linearGradient
   84.87 -       inkscape:collect="always"
   84.88 -       xlink:href="#linearGradient3092"
   84.89 -       id="linearGradient3708"
   84.90 -       gradientUnits="userSpaceOnUse"
   84.91 -       gradientTransform="matrix(0.423343,0,0,0.423343,138.874,-67.01732)"
   84.92 -       x1="175.23776"
   84.93 -       y1="509.98154"
   84.94 -       x2="416.29077"
   84.95 -       y2="297.49997" />
   84.96 -    <linearGradient
   84.97 -       inkscape:collect="always"
   84.98 -       xlink:href="#linearGradient3092"
   84.99 -       id="linearGradient5164"
  84.100 -       gradientUnits="userSpaceOnUse"
  84.101 -       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,247.4358)"
  84.102 -       x1="175.23776"
  84.103 -       y1="509.98154"
  84.104 -       x2="416.29077"
  84.105 -       y2="297.49997" />
  84.106 -    <linearGradient
  84.107 -       inkscape:collect="always"
  84.108 -       xlink:href="#linearGradient3092"
  84.109 -       id="linearGradient5584"
  84.110 -       gradientUnits="userSpaceOnUse"
  84.111 -       gradientTransform="matrix(0.423343,0,0,0.423343,143.9081,371.2915)"
  84.112 -       x1="175.23776"
  84.113 -       y1="509.98154"
  84.114 -       x2="416.29077"
  84.115 -       y2="297.49997" />
  84.116 -    <linearGradient
  84.117 -       inkscape:collect="always"
  84.118 -       xlink:href="#linearGradient3092"
  84.119 -       id="linearGradient5784"
  84.120 -       gradientUnits="userSpaceOnUse"
  84.121 -       gradientTransform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  84.122 -       x1="175.23776"
  84.123 -       y1="509.98154"
  84.124 -       x2="416.29077"
  84.125 -       y2="297.49997" />
  84.126 -    <linearGradient
  84.127 -       inkscape:collect="always"
  84.128 -       xlink:href="#linearGradient3092"
  84.129 -       id="linearGradient5786"
  84.130 -       gradientUnits="userSpaceOnUse"
  84.131 -       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,152.137)"
  84.132 -       x1="175.23776"
  84.133 -       y1="509.98154"
  84.134 -       x2="416.29077"
  84.135 -       y2="297.49997" />
  84.136 -    <linearGradient
  84.137 -       inkscape:collect="always"
  84.138 -       xlink:href="#linearGradient3092"
  84.139 -       id="linearGradient5895"
  84.140 -       gradientUnits="userSpaceOnUse"
  84.141 -       gradientTransform="matrix(0.423343,0,0,0.423343,198.0215,261.7142)"
  84.142 -       x1="175.23776"
  84.143 -       y1="509.98154"
  84.144 -       x2="416.29077"
  84.145 -       y2="297.49997" />
  84.146 -    <linearGradient
  84.147 -       inkscape:collect="always"
  84.148 -       xlink:href="#linearGradient3092"
  84.149 -       id="linearGradient5958"
  84.150 -       gradientUnits="userSpaceOnUse"
  84.151 -       gradientTransform="matrix(0.423343,0,0,0.423343,137.1978,42.55987)"
  84.152 -       x1="175.23776"
  84.153 -       y1="509.98154"
  84.154 -       x2="416.29077"
  84.155 -       y2="297.49997" />
  84.156 -  </defs>
  84.157 -  <sodipodi:namedview
  84.158 -     id="base"
  84.159 -     pagecolor="#ffffff"
  84.160 -     bordercolor="#666666"
  84.161 -     borderopacity="1.0"
  84.162 -     gridtolerance="10000"
  84.163 -     guidetolerance="10"
  84.164 -     objecttolerance="10"
  84.165 -     inkscape:pageopacity="0.0"
  84.166 -     inkscape:pageshadow="2"
  84.167 -     inkscape:zoom="0.64"
  84.168 -     inkscape:cx="566.02368"
  84.169 -     inkscape:cy="688.16826"
  84.170 -     inkscape:document-units="px"
  84.171 -     inkscape:current-layer="layer1"
  84.172 -     inkscape:window-width="906"
  84.173 -     inkscape:window-height="620"
  84.174 -     inkscape:window-x="29"
  84.175 -     inkscape:window-y="79"
  84.176 -     inkscape:connector-spacing="11" />
  84.177 -  <metadata
  84.178 -     id="metadata7">
  84.179 -    <rdf:RDF>
  84.180 -      <cc:Work
  84.181 -         rdf:about="">
  84.182 -        <dc:format>image/svg+xml</dc:format>
  84.183 -        <dc:type
  84.184 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  84.185 -      </cc:Work>
  84.186 -    </rdf:RDF>
  84.187 -  </metadata>
  84.188 -  <g
  84.189 -     inkscape:label="Layer 1"
  84.190 -     inkscape:groupmode="layer"
  84.191 -     id="layer1">
  84.192 -    <rect
  84.193 -       y="168.74846"
  84.194 -       x="211.58516"
  84.195 -       height="89.506805"
  84.196 -       width="101.60232"
  84.197 -       id="rect3068"
  84.198 -       style="fill:url(#linearGradient5958);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.199 -    <g
  84.200 -       id="g3215"
  84.201 -       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55985)">
  84.202 -      <rect
  84.203 -         y="447.71451"
  84.204 -         x="299.67859"
  84.205 -         height="48.571426"
  84.206 -         width="103.14286"
  84.207 -         id="rect2899"
  84.208 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.209 -      <text
  84.210 -         id="text2903"
  84.211 -         y="464.8139"
  84.212 -         x="308.89639"
  84.213 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.214 -         xml:space="preserve"><tspan
  84.215 -           y="464.8139"
  84.216 -           x="308.89639"
  84.217 -           sodipodi:role="line"
  84.218 -           id="tspan2905">Second parent</tspan></text>
  84.219 -      <text
  84.220 -         id="text2907"
  84.221 -         y="485.50256"
  84.222 -         x="308.20175"
  84.223 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.224 -         xml:space="preserve"><tspan
  84.225 -           style="font-family:Courier"
  84.226 -           y="485.50256"
  84.227 -           x="308.20175"
  84.228 -           id="tspan2909"
  84.229 -           sodipodi:role="line">32bf9a5f22c0</tspan></text>
  84.230 -    </g>
  84.231 -    <g
  84.232 -       id="g3250"
  84.233 -       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55986)">
  84.234 -      <rect
  84.235 -         y="311.28598"
  84.236 -         x="188.6071"
  84.237 -         height="48.571426"
  84.238 -         width="103.14286"
  84.239 -         id="rect2936"
  84.240 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.241 -      <text
  84.242 -         id="text2940"
  84.243 -         y="328.38538"
  84.244 -         x="197.82495"
  84.245 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.246 -         xml:space="preserve"><tspan
  84.247 -           y="328.38538"
  84.248 -           x="197.82495"
  84.249 -           sodipodi:role="line"
  84.250 -           id="tspan2942">Revision hash</tspan></text>
  84.251 -      <text
  84.252 -         id="text2944"
  84.253 -         y="349.07404"
  84.254 -         x="197.13031"
  84.255 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.256 -         xml:space="preserve"><tspan
  84.257 -           style="font-family:Courier"
  84.258 -           y="349.07404"
  84.259 -           x="197.13031"
  84.260 -           id="tspan2946"
  84.261 -           sodipodi:role="line">34b8b7a15ea1</tspan></text>
  84.262 -    </g>
  84.263 -    <g
  84.264 -       id="g3243"
  84.265 -       transform="matrix(0.423343,0,0,0.423343,137.6664,43.91853)">
  84.266 -      <rect
  84.267 -         y="363.07654"
  84.268 -         x="187.5"
  84.269 -         height="75"
  84.270 -         width="213.85715"
  84.271 -         id="rect2950"
  84.272 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.273 -      <text
  84.274 -         id="text2958"
  84.275 -         y="400.86459"
  84.276 -         x="196.02321"
  84.277 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.278 -         xml:space="preserve"><tspan
  84.279 -           style="fill:black;fill-opacity:1;font-family:Courier"
  84.280 -           y="400.86459"
  84.281 -           x="196.02321"
  84.282 -           id="tspan2960"
  84.283 -           sodipodi:role="line">...</tspan></text>
  84.284 -      <text
  84.285 -         id="text2954"
  84.286 -         y="380.17593"
  84.287 -         x="196.71785"
  84.288 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.289 -         xml:space="preserve"><tspan
  84.290 -           y="380.17593"
  84.291 -           x="196.71785"
  84.292 -           sodipodi:role="line"
  84.293 -           id="tspan2956"
  84.294 -           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
  84.295 -    </g>
  84.296 -    <g
  84.297 -       id="g5529"
  84.298 -       transform="translate(-6.710312,-8.165836e-6)">
  84.299 -      <rect
  84.300 -         style="fill:url(#linearGradient5584);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.301 -         id="rect3509"
  84.302 -         width="101.60232"
  84.303 -         height="89.506805"
  84.304 -         x="218.29547"
  84.305 -         y="497.4801" />
  84.306 -      <g
  84.307 -         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
  84.308 -         id="g3513">
  84.309 -        <g
  84.310 -           id="g3515">
  84.311 -          <rect
  84.312 -             y="447.72418"
  84.313 -             x="188.6071"
  84.314 -             height="48.571426"
  84.315 -             width="103.14286"
  84.316 -             id="rect3517"
  84.317 -             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.318 -          <text
  84.319 -             id="text3519"
  84.320 -             y="464.82358"
  84.321 -             x="197.82495"
  84.322 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.323 -             xml:space="preserve"><tspan
  84.324 -               y="464.82358"
  84.325 -               x="197.82495"
  84.326 -               sodipodi:role="line"
  84.327 -               id="tspan3521">First parent</tspan></text>
  84.328 -          <text
  84.329 -             id="text3523"
  84.330 -             y="485.51224"
  84.331 -             x="197.13031"
  84.332 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.333 -             xml:space="preserve"><tspan
  84.334 -               style="font-family:Courier"
  84.335 -               y="485.51224"
  84.336 -               x="197.13031"
  84.337 -               id="tspan3525"
  84.338 -               sodipodi:role="line">000000000000</tspan></text>
  84.339 -        </g>
  84.340 -        <g
  84.341 -           id="g3527">
  84.342 -          <rect
  84.343 -             y="447.71451"
  84.344 -             x="299.67859"
  84.345 -             height="48.571426"
  84.346 -             width="103.14286"
  84.347 -             id="rect3529"
  84.348 -             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.349 -          <text
  84.350 -             id="text3531"
  84.351 -             y="464.8139"
  84.352 -             x="308.89639"
  84.353 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.354 -             xml:space="preserve"><tspan
  84.355 -               y="464.8139"
  84.356 -               x="308.89639"
  84.357 -               sodipodi:role="line"
  84.358 -               id="tspan3533">Second parent</tspan></text>
  84.359 -          <text
  84.360 -             id="text3535"
  84.361 -             y="485.50256"
  84.362 -             x="308.20175"
  84.363 -             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.364 -             xml:space="preserve"><tspan
  84.365 -               style="font-family:Courier"
  84.366 -               y="485.50256"
  84.367 -               x="308.20175"
  84.368 -               id="tspan3537"
  84.369 -               sodipodi:role="line">000000000000</tspan></text>
  84.370 -        </g>
  84.371 -      </g>
  84.372 -      <g
  84.373 -         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
  84.374 -         id="g3539">
  84.375 -        <rect
  84.376 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.377 -           id="rect3541"
  84.378 -           width="103.14286"
  84.379 -           height="48.571426"
  84.380 -           x="188.6071"
  84.381 -           y="311.28598" />
  84.382 -        <text
  84.383 -           xml:space="preserve"
  84.384 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.385 -           x="197.82495"
  84.386 -           y="328.38538"
  84.387 -           id="text3543"><tspan
  84.388 -             id="tspan3545"
  84.389 -             sodipodi:role="line"
  84.390 -             x="197.82495"
  84.391 -             y="328.38538">Revision hash</tspan></text>
  84.392 -        <text
  84.393 -           xml:space="preserve"
  84.394 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.395 -           x="197.13031"
  84.396 -           y="349.07404"
  84.397 -           id="text3547"><tspan
  84.398 -             sodipodi:role="line"
  84.399 -             id="tspan3549"
  84.400 -             x="197.13031"
  84.401 -             y="349.07404"
  84.402 -             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
  84.403 -      </g>
  84.404 -      <g
  84.405 -         transform="matrix(0.423343,0,0,0.423343,144.3767,372.6502)"
  84.406 -         id="g3551">
  84.407 -        <rect
  84.408 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.409 -           id="rect3553"
  84.410 -           width="213.85715"
  84.411 -           height="75"
  84.412 -           x="187.5"
  84.413 -           y="363.07654" />
  84.414 -        <text
  84.415 -           xml:space="preserve"
  84.416 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.417 -           x="196.02321"
  84.418 -           y="400.86459"
  84.419 -           id="text3555"><tspan
  84.420 -             sodipodi:role="line"
  84.421 -             id="tspan3557"
  84.422 -             x="196.02321"
  84.423 -             y="400.86459"
  84.424 -             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  84.425 -        <text
  84.426 -           xml:space="preserve"
  84.427 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.428 -           x="196.71785"
  84.429 -           y="380.17593"
  84.430 -           id="text3559"><tspan
  84.431 -             style="fill:black;fill-opacity:1"
  84.432 -             id="tspan3561"
  84.433 -             sodipodi:role="line"
  84.434 -             x="196.71785"
  84.435 -             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  84.436 -      </g>
  84.437 -    </g>
  84.438 -    <g
  84.439 -       id="g4868"
  84.440 -       transform="translate(-1.676208,-2.342463e-5)">
  84.441 -      <rect
  84.442 -         style="fill:url(#linearGradient3708);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.443 -         id="rect3567"
  84.444 -         width="101.60232"
  84.445 -         height="89.506805"
  84.446 -         x="213.26137"
  84.447 -         y="59.171272" />
  84.448 -      <g
  84.449 -         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
  84.450 -         id="g3573">
  84.451 -        <rect
  84.452 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.453 -           id="rect3575"
  84.454 -           width="103.14286"
  84.455 -           height="48.571426"
  84.456 -           x="188.6071"
  84.457 -           y="447.72418" />
  84.458 -        <text
  84.459 -           xml:space="preserve"
  84.460 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.461 -           x="197.82495"
  84.462 -           y="464.82358"
  84.463 -           id="text3577"><tspan
  84.464 -             id="tspan3579"
  84.465 -             sodipodi:role="line"
  84.466 -             x="197.82495"
  84.467 -             y="464.82358">First parent</tspan></text>
  84.468 -        <text
  84.469 -           xml:space="preserve"
  84.470 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.471 -           x="197.13031"
  84.472 -           y="485.51224"
  84.473 -           id="text3581"><tspan
  84.474 -             sodipodi:role="line"
  84.475 -             id="tspan3583"
  84.476 -             x="197.13031"
  84.477 -             y="485.51224"
  84.478 -             style="font-family:Courier">34b8b7a15ea1</tspan></text>
  84.479 -      </g>
  84.480 -      <g
  84.481 -         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
  84.482 -         id="g3585">
  84.483 -        <rect
  84.484 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.485 -           id="rect3587"
  84.486 -           width="103.14286"
  84.487 -           height="48.571426"
  84.488 -           x="299.67859"
  84.489 -           y="447.71451" />
  84.490 -        <text
  84.491 -           xml:space="preserve"
  84.492 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.493 -           x="308.89639"
  84.494 -           y="464.8139"
  84.495 -           id="text3589"><tspan
  84.496 -             id="tspan3591"
  84.497 -             sodipodi:role="line"
  84.498 -             x="308.89639"
  84.499 -             y="464.8139">Second parent</tspan></text>
  84.500 -        <text
  84.501 -           xml:space="preserve"
  84.502 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.503 -           x="308.20175"
  84.504 -           y="485.50256"
  84.505 -           id="text3593"><tspan
  84.506 -             sodipodi:role="line"
  84.507 -             id="tspan3595"
  84.508 -             x="308.20175"
  84.509 -             y="485.50256"
  84.510 -             style="font-family:Courier">000000000000</tspan></text>
  84.511 -      </g>
  84.512 -      <g
  84.513 -         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01733)"
  84.514 -         id="g3597">
  84.515 -        <rect
  84.516 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.517 -           id="rect3599"
  84.518 -           width="103.14286"
  84.519 -           height="48.571426"
  84.520 -           x="188.6071"
  84.521 -           y="311.28598" />
  84.522 -        <text
  84.523 -           xml:space="preserve"
  84.524 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.525 -           x="197.82495"
  84.526 -           y="328.38538"
  84.527 -           id="text3601"><tspan
  84.528 -             id="tspan3603"
  84.529 -             sodipodi:role="line"
  84.530 -             x="197.82495"
  84.531 -             y="328.38538">Revision hash</tspan></text>
  84.532 -        <text
  84.533 -           xml:space="preserve"
  84.534 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.535 -           x="197.13031"
  84.536 -           y="349.07404"
  84.537 -           id="text3605"><tspan
  84.538 -             sodipodi:role="line"
  84.539 -             id="tspan3607"
  84.540 -             x="197.13031"
  84.541 -             y="349.07404"
  84.542 -             style="font-family:Courier">1b67dc96f27a</tspan></text>
  84.543 -      </g>
  84.544 -      <g
  84.545 -         transform="matrix(0.423343,0,0,0.423343,139.3426,-65.65866)"
  84.546 -         id="g3609">
  84.547 -        <rect
  84.548 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.549 -           id="rect3611"
  84.550 -           width="213.85715"
  84.551 -           height="75"
  84.552 -           x="187.5"
  84.553 -           y="363.07654" />
  84.554 -        <text
  84.555 -           xml:space="preserve"
  84.556 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.557 -           x="196.02321"
  84.558 -           y="400.86459"
  84.559 -           id="text3613"><tspan
  84.560 -             sodipodi:role="line"
  84.561 -             id="tspan3615"
  84.562 -             x="196.02321"
  84.563 -             y="400.86459"
  84.564 -             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  84.565 -        <text
  84.566 -           xml:space="preserve"
  84.567 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.568 -           x="196.71785"
  84.569 -           y="380.17593"
  84.570 -           id="text3617"><tspan
  84.571 -             style="fill:black;fill-opacity:1"
  84.572 -             id="tspan3619"
  84.573 -             sodipodi:role="line"
  84.574 -             x="196.71785"
  84.575 -             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  84.576 -      </g>
  84.577 -    </g>
  84.578 -    <path
  84.579 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Mend)"
  84.580 -       d="M 240.78255,143.08593 L 241.42595,171.75349"
  84.581 -       id="path3801"
  84.582 -       inkscape:connector-type="polyline"
  84.583 -       inkscape:connection-start="#g3573"
  84.584 -       inkscape:connection-end="#g3250" />
  84.585 -    <g
  84.586 -       id="g5677">
  84.587 -      <rect
  84.588 -         style="fill:url(#linearGradient5784);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.589 -         id="rect3393"
  84.590 -         width="101.60232"
  84.591 -         height="89.506805"
  84.592 -         x="150.76137"
  84.593 -         y="278.32565" />
  84.594 -      <g
  84.595 -         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  84.596 -         id="g3399">
  84.597 -        <rect
  84.598 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.599 -           id="rect3401"
  84.600 -           width="103.14286"
  84.601 -           height="48.571426"
  84.602 -           x="188.6071"
  84.603 -           y="447.72418" />
  84.604 -        <text
  84.605 -           xml:space="preserve"
  84.606 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.607 -           x="197.82495"
  84.608 -           y="464.82358"
  84.609 -           id="text3403"><tspan
  84.610 -             id="tspan3405"
  84.611 -             sodipodi:role="line"
  84.612 -             x="197.82495"
  84.613 -             y="464.82358">First parent</tspan></text>
  84.614 -        <text
  84.615 -           xml:space="preserve"
  84.616 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.617 -           x="197.13031"
  84.618 -           y="485.51224"
  84.619 -           id="text3407"><tspan
  84.620 -             sodipodi:role="line"
  84.621 -             id="tspan3409"
  84.622 -             x="197.13031"
  84.623 -             y="485.51224"
  84.624 -             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
  84.625 -      </g>
  84.626 -      <g
  84.627 -         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  84.628 -         id="g3411">
  84.629 -        <rect
  84.630 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.631 -           id="rect3413"
  84.632 -           width="103.14286"
  84.633 -           height="48.571426"
  84.634 -           x="299.67859"
  84.635 -           y="447.71451" />
  84.636 -        <text
  84.637 -           xml:space="preserve"
  84.638 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.639 -           x="308.89639"
  84.640 -           y="464.8139"
  84.641 -           id="text3415"><tspan
  84.642 -             id="tspan3417"
  84.643 -             sodipodi:role="line"
  84.644 -             x="308.89639"
  84.645 -             y="464.8139">Second parent</tspan></text>
  84.646 -        <text
  84.647 -           xml:space="preserve"
  84.648 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.649 -           x="308.20175"
  84.650 -           y="485.50256"
  84.651 -           id="text3419"><tspan
  84.652 -             sodipodi:role="line"
  84.653 -             id="tspan3421"
  84.654 -             x="308.20175"
  84.655 -             y="485.50256"
  84.656 -             style="font-family:Courier">000000000000</tspan></text>
  84.657 -      </g>
  84.658 -      <g
  84.659 -         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
  84.660 -         id="g3423">
  84.661 -        <rect
  84.662 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.663 -           id="rect3425"
  84.664 -           width="103.14286"
  84.665 -           height="48.571426"
  84.666 -           x="188.6071"
  84.667 -           y="311.28598" />
  84.668 -        <text
  84.669 -           xml:space="preserve"
  84.670 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.671 -           x="197.82495"
  84.672 -           y="328.38538"
  84.673 -           id="text3427"><tspan
  84.674 -             id="tspan3429"
  84.675 -             sodipodi:role="line"
  84.676 -             x="197.82495"
  84.677 -             y="328.38538">Revision hash</tspan></text>
  84.678 -        <text
  84.679 -           xml:space="preserve"
  84.680 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.681 -           x="197.13031"
  84.682 -           y="349.07404"
  84.683 -           id="text3431"><tspan
  84.684 -             sodipodi:role="line"
  84.685 -             id="tspan3433"
  84.686 -             x="197.13031"
  84.687 -             y="349.07404"
  84.688 -             style="font-family:Courier">5b80c922ebdd</tspan></text>
  84.689 -      </g>
  84.690 -      <g
  84.691 -         transform="matrix(0.423343,0,0,0.423343,76.84265,153.4957)"
  84.692 -         id="g3435">
  84.693 -        <rect
  84.694 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.695 -           id="rect3437"
  84.696 -           width="213.85715"
  84.697 -           height="75"
  84.698 -           x="187.5"
  84.699 -           y="363.07654" />
  84.700 -        <text
  84.701 -           xml:space="preserve"
  84.702 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.703 -           x="196.02321"
  84.704 -           y="400.86459"
  84.705 -           id="text3439"><tspan
  84.706 -             sodipodi:role="line"
  84.707 -             id="tspan3441"
  84.708 -             x="196.02321"
  84.709 -             y="400.86459"
  84.710 -             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  84.711 -        <text
  84.712 -           xml:space="preserve"
  84.713 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.714 -           x="196.71785"
  84.715 -           y="380.17593"
  84.716 -           id="text3443"><tspan
  84.717 -             style="fill:black;fill-opacity:1"
  84.718 -             id="tspan3445"
  84.719 -             sodipodi:role="line"
  84.720 -             x="196.71785"
  84.721 -             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  84.722 -      </g>
  84.723 -    </g>
  84.724 -    <g
  84.725 -       id="g5646"
  84.726 -       transform="translate(-0.227432,0)">
  84.727 -      <rect
  84.728 -         style="fill:url(#linearGradient5786);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.729 -         id="rect3451"
  84.730 -         width="101.60232"
  84.731 -         height="89.506805"
  84.732 -         x="272.63638"
  84.733 -         y="278.32565" />
  84.734 -      <g
  84.735 -         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
  84.736 -         id="g3457">
  84.737 -        <rect
  84.738 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.739 -           id="rect3459"
  84.740 -           width="103.14286"
  84.741 -           height="48.571426"
  84.742 -           x="188.6071"
  84.743 -           y="447.72418" />
  84.744 -        <text
  84.745 -           xml:space="preserve"
  84.746 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.747 -           x="197.82495"
  84.748 -           y="464.82358"
  84.749 -           id="text3461"><tspan
  84.750 -             id="tspan3463"
  84.751 -             sodipodi:role="line"
  84.752 -             x="197.82495"
  84.753 -             y="464.82358">First parent</tspan></text>
  84.754 -        <text
  84.755 -           xml:space="preserve"
  84.756 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.757 -           x="197.13031"
  84.758 -           y="485.51224"
  84.759 -           id="text3465"><tspan
  84.760 -             sodipodi:role="line"
  84.761 -             id="tspan3467"
  84.762 -             x="197.13031"
  84.763 -             y="485.51224"
  84.764 -             style="font-family:Courier">ecacb6b4c9fd</tspan></text>
  84.765 -      </g>
  84.766 -      <g
  84.767 -         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
  84.768 -         id="g3469">
  84.769 -        <rect
  84.770 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.771 -           id="rect3471"
  84.772 -           width="103.14286"
  84.773 -           height="48.571426"
  84.774 -           x="299.67859"
  84.775 -           y="447.71451" />
  84.776 -        <text
  84.777 -           xml:space="preserve"
  84.778 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.779 -           x="308.89639"
  84.780 -           y="464.8139"
  84.781 -           id="text3473"><tspan
  84.782 -             id="tspan3475"
  84.783 -             sodipodi:role="line"
  84.784 -             x="308.89639"
  84.785 -             y="464.8139">Second parent</tspan></text>
  84.786 -        <text
  84.787 -           xml:space="preserve"
  84.788 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.789 -           x="308.20175"
  84.790 -           y="485.50256"
  84.791 -           id="text3477"><tspan
  84.792 -             sodipodi:role="line"
  84.793 -             id="tspan3479"
  84.794 -             x="308.20175"
  84.795 -             y="485.50256"
  84.796 -             style="font-family:Courier">000000000000</tspan></text>
  84.797 -      </g>
  84.798 -      <g
  84.799 -         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
  84.800 -         id="g3481">
  84.801 -        <rect
  84.802 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.803 -           id="rect3483"
  84.804 -           width="103.14286"
  84.805 -           height="48.571426"
  84.806 -           x="188.6071"
  84.807 -           y="311.28598" />
  84.808 -        <text
  84.809 -           xml:space="preserve"
  84.810 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.811 -           x="197.82495"
  84.812 -           y="328.38538"
  84.813 -           id="text3485"><tspan
  84.814 -             id="tspan3487"
  84.815 -             sodipodi:role="line"
  84.816 -             x="197.82495"
  84.817 -             y="328.38538">Revision hash</tspan></text>
  84.818 -        <text
  84.819 -           xml:space="preserve"
  84.820 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.821 -           x="197.13031"
  84.822 -           y="349.07404"
  84.823 -           id="text3489"><tspan
  84.824 -             sodipodi:role="line"
  84.825 -             id="tspan3491"
  84.826 -             x="197.13031"
  84.827 -             y="349.07404"
  84.828 -             style="font-family:Courier">32bf9a5f22c0</tspan></text>
  84.829 -      </g>
  84.830 -      <g
  84.831 -         transform="matrix(0.423343,0,0,0.423343,198.7176,153.4957)"
  84.832 -         id="g3493">
  84.833 -        <rect
  84.834 -           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  84.835 -           id="rect3495"
  84.836 -           width="213.85715"
  84.837 -           height="75"
  84.838 -           x="187.5"
  84.839 -           y="363.07654" />
  84.840 -        <text
  84.841 -           xml:space="preserve"
  84.842 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.843 -           x="196.02321"
  84.844 -           y="400.86459"
  84.845 -           id="text3497"><tspan
  84.846 -             sodipodi:role="line"
  84.847 -             id="tspan3499"
  84.848 -             x="196.02321"
  84.849 -             y="400.86459"
  84.850 -             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
  84.851 -        <text
  84.852 -           xml:space="preserve"
  84.853 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.854 -           x="196.71785"
  84.855 -           y="380.17593"
  84.856 -           id="text3501"><tspan
  84.857 -             style="fill:black;fill-opacity:1"
  84.858 -             id="tspan3503"
  84.859 -             sodipodi:role="line"
  84.860 -             x="196.71785"
  84.861 -             y="380.17593">Revision data (delta or snapshot)</tspan></text>
  84.862 -      </g>
  84.863 -    </g>
  84.864 -    <rect
  84.865 -       y="387.90286"
  84.866 -       x="272.40894"
  84.867 -       height="89.506805"
  84.868 -       width="101.60232"
  84.869 -       id="rect5081"
  84.870 -       style="fill:url(#linearGradient5895);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.871 -    <g
  84.872 -       id="g5087"
  84.873 -       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
  84.874 -      <rect
  84.875 -         y="447.72418"
  84.876 -         x="188.6071"
  84.877 -         height="48.571426"
  84.878 -         width="103.14286"
  84.879 -         id="rect5089"
  84.880 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.881 -      <text
  84.882 -         id="text5091"
  84.883 -         y="464.82358"
  84.884 -         x="197.82495"
  84.885 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.886 -         xml:space="preserve"><tspan
  84.887 -           y="464.82358"
  84.888 -           x="197.82495"
  84.889 -           sodipodi:role="line"
  84.890 -           id="tspan5093">First parent</tspan></text>
  84.891 -      <text
  84.892 -         id="text5095"
  84.893 -         y="485.51224"
  84.894 -         x="197.13031"
  84.895 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.896 -         xml:space="preserve"><tspan
  84.897 -           style="font-family:Courier"
  84.898 -           y="485.51224"
  84.899 -           x="197.13031"
  84.900 -           id="tspan5097"
  84.901 -           sodipodi:role="line">ff9dc8bc2a8b</tspan></text>
  84.902 -    </g>
  84.903 -    <g
  84.904 -       id="g5099"
  84.905 -       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
  84.906 -      <rect
  84.907 -         y="447.71451"
  84.908 -         x="299.67859"
  84.909 -         height="48.571426"
  84.910 -         width="103.14286"
  84.911 -         id="rect5101"
  84.912 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.913 -      <text
  84.914 -         id="text5103"
  84.915 -         y="464.8139"
  84.916 -         x="308.89639"
  84.917 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.918 -         xml:space="preserve"><tspan
  84.919 -           y="464.8139"
  84.920 -           x="308.89639"
  84.921 -           sodipodi:role="line"
  84.922 -           id="tspan5105">Second parent</tspan></text>
  84.923 -      <text
  84.924 -         id="text5107"
  84.925 -         y="485.50256"
  84.926 -         x="308.20175"
  84.927 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.928 -         xml:space="preserve"><tspan
  84.929 -           style="font-family:Courier"
  84.930 -           y="485.50256"
  84.931 -           x="308.20175"
  84.932 -           id="tspan5109"
  84.933 -           sodipodi:role="line">000000000000</tspan></text>
  84.934 -    </g>
  84.935 -    <g
  84.936 -       id="g5111"
  84.937 -       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
  84.938 -      <rect
  84.939 -         y="311.28598"
  84.940 -         x="188.6071"
  84.941 -         height="48.571426"
  84.942 -         width="103.14286"
  84.943 -         id="rect5113"
  84.944 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.945 -      <text
  84.946 -         id="text5115"
  84.947 -         y="328.38538"
  84.948 -         x="197.82495"
  84.949 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.950 -         xml:space="preserve"><tspan
  84.951 -           y="328.38538"
  84.952 -           x="197.82495"
  84.953 -           sodipodi:role="line"
  84.954 -           id="tspan5117">Revision hash</tspan></text>
  84.955 -      <text
  84.956 -         id="text5119"
  84.957 -         y="349.07404"
  84.958 -         x="197.13031"
  84.959 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.960 -         xml:space="preserve"><tspan
  84.961 -           style="font-family:Courier"
  84.962 -           y="349.07404"
  84.963 -           x="197.13031"
  84.964 -           id="tspan5121"
  84.965 -           sodipodi:role="line">ecacb6b4c9fd</tspan></text>
  84.966 -    </g>
  84.967 -    <g
  84.968 -       id="g5123"
  84.969 -       transform="matrix(0.423343,0,0,0.423343,198.4901,263.0729)">
  84.970 -      <rect
  84.971 -         y="363.07654"
  84.972 -         x="187.5"
  84.973 -         height="75"
  84.974 -         width="213.85715"
  84.975 -         id="rect5125"
  84.976 -         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
  84.977 -      <text
  84.978 -         id="text5127"
  84.979 -         y="400.86459"
  84.980 -         x="196.02321"
  84.981 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.982 -         xml:space="preserve"><tspan
  84.983 -           style="fill:black;fill-opacity:1;font-family:Courier"
  84.984 -           y="400.86459"
  84.985 -           x="196.02321"
  84.986 -           id="tspan5129"
  84.987 -           sodipodi:role="line">...</tspan></text>
  84.988 -      <text
  84.989 -         id="text5131"
  84.990 -         y="380.17593"
  84.991 -         x="196.71785"
  84.992 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  84.993 -         xml:space="preserve"><tspan
  84.994 -           y="380.17593"
  84.995 -           x="196.71785"
  84.996 -           sodipodi:role="line"
  84.997 -           id="tspan5133"
  84.998 -           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
  84.999 -    </g>
 84.1000 -    <path
 84.1001 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 84.1002 -       d="M 299.69935,362.24027 L 299.69931,393.49494"
 84.1003 -       id="path5203"
 84.1004 -       inkscape:connector-type="polyline"
 84.1005 -       inkscape:connection-start="#g3457"
 84.1006 -       inkscape:connection-end="#g5111" />
 84.1007 -    <path
 84.1008 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
 84.1009 -       d="M 182.35357,362.22647 L 241.2842,503.07224"
 84.1010 -       id="path5271"
 84.1011 -       inkscape:connector-type="polyline"
 84.1012 -       inkscape:connection-start="#g3399"
 84.1013 -       inkscape:connection-end="#g3539" />
 84.1014 -    <path
 84.1015 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 84.1016 -       d="M 287.63109,471.81747 L 250.9438,503.07223"
 84.1017 -       id="path5285"
 84.1018 -       inkscape:connector-type="polyline"
 84.1019 -       inkscape:connection-start="#g5087"
 84.1020 -       inkscape:connection-end="#g3539" />
 84.1021 -    <path
 84.1022 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 84.1023 -       d="M 290.80419,250.07192 L 297.80065,283.90394"
 84.1024 -       id="path5077"
 84.1025 -       inkscape:connector-type="polyline"
 84.1026 -       inkscape:connection-start="#g3215"
 84.1027 -       inkscape:connection-end="#g3481" />
 84.1028 -    <path
 84.1029 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 84.1030 -       d="M 229.63373,250.07601 L 190.07484,283.90394"
 84.1031 -       id="path5075"
 84.1032 -       inkscape:connector-type="polyline"
 84.1033 -       inkscape:connection-end="#g3423" />
 84.1034 -    <text
 84.1035 -       xml:space="preserve"
 84.1036 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 84.1037 -       x="131.5625"
 84.1038 -       y="100.79968"
 84.1039 -       id="text5897"><tspan
 84.1040 -         sodipodi:role="line"
 84.1041 -         id="tspan5899"
 84.1042 -         x="131.5625"
 84.1043 -         y="100.79968"
 84.1044 -         style="text-align:end;text-anchor:end">Head revision</tspan><tspan
 84.1045 -         sodipodi:role="line"
 84.1046 -         x="131.5625"
 84.1047 -         y="115.79968"
 84.1048 -         id="tspan5901"
 84.1049 -         style="text-align:end;text-anchor:end">(no children)</tspan></text>
 84.1050 -    <text
 84.1051 -       xml:space="preserve"
 84.1052 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 84.1053 -       x="131.5625"
 84.1054 -       y="207.04968"
 84.1055 -       id="text5903"><tspan
 84.1056 -         sodipodi:role="line"
 84.1057 -         id="tspan5905"
 84.1058 -         x="131.5625"
 84.1059 -         y="207.04968"
 84.1060 -         style="text-align:end;text-anchor:end">Merge revision</tspan><tspan
 84.1061 -         sodipodi:role="line"
 84.1062 -         x="131.5625"
 84.1063 -         y="222.04968"
 84.1064 -         id="tspan5907"
 84.1065 -         style="text-align:end;text-anchor:end">(two parents)</tspan></text>
 84.1066 -    <text
 84.1067 -       xml:space="preserve"
 84.1068 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 84.1069 -       x="131.92578"
 84.1070 -       y="451.58093"
 84.1071 -       id="text5909"><tspan
 84.1072 -         sodipodi:role="line"
 84.1073 -         id="tspan5911"
 84.1074 -         x="131.92578"
 84.1075 -         y="451.58093"
 84.1076 -         style="text-align:end;text-anchor:end">Branches</tspan><tspan
 84.1077 -         sodipodi:role="line"
 84.1078 -         x="131.92578"
 84.1079 -         y="466.58093"
 84.1080 -         id="tspan5913"
 84.1081 -         style="text-align:end;text-anchor:end">(two revisions,</tspan><tspan
 84.1082 -         sodipodi:role="line"
 84.1083 -         x="131.92578"
 84.1084 -         y="481.58093"
 84.1085 -         id="tspan5915"
 84.1086 -         style="text-align:end;text-anchor:end">same parent)</tspan></text>
 84.1087 -    <path
 84.1088 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 84.1089 -       d="M 111.71875,433.61218 L 154.7268,368.52294"
 84.1090 -       id="path5917"
 84.1091 -       inkscape:connector-type="polyline" />
 84.1092 -    <path
 84.1093 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 84.1094 -       d="M 134.375,464.86218 L 277.86691,440.37816"
 84.1095 -       id="path5919"
 84.1096 -       inkscape:connector-type="polyline"
 84.1097 -       inkscape:connection-end="#g5123" />
 84.1098 -    <text
 84.1099 -       xml:space="preserve"
 84.1100 -       style="font-size:12px;font-style:normal;font-weight:normal;text-align:end;text-anchor:end;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 84.1101 -       x="131.5625"
 84.1102 -       y="536.73718"
 84.1103 -       id="text5927"><tspan
 84.1104 -         sodipodi:role="line"
 84.1105 -         id="tspan5929"
 84.1106 -         x="131.5625"
 84.1107 -         y="536.73718">First revision</tspan><tspan
 84.1108 -         sodipodi:role="line"
 84.1109 -         x="131.5625"
 84.1110 -         y="551.73718"
 84.1111 -         id="tspan5931">(both parents null)</tspan></text>
 84.1112 -    <rect
 84.1113 -       style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 84.1114 -       id="rect2830"
 84.1115 -       width="43.664806"
 84.1116 -       height="20.562374"
 84.1117 -       x="217.0432"
 84.1118 -       y="232.10075" />
 84.1119 -    <text
 84.1120 -       xml:space="preserve"
 84.1121 -       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 84.1122 -       x="220.94551"
 84.1123 -       y="239.33966"
 84.1124 -       id="text2832"><tspan
 84.1125 -         id="tspan2836"
 84.1126 -         sodipodi:role="line"
 84.1127 -         x="220.94551"
 84.1128 -         y="239.33966">First parent</tspan></text>
 84.1129 -    <text
 84.1130 -       xml:space="preserve"
 84.1131 -       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 84.1132 -       x="220.65144"
 84.1133 -       y="248.09805"
 84.1134 -       id="text2879"><tspan
 84.1135 -         sodipodi:role="line"
 84.1136 -         id="tspan2881"
 84.1137 -         x="220.65144"
 84.1138 -         y="248.09805"
 84.1139 -         style="font-family:Courier">5b80c922ebdd</tspan></text>
 84.1140 -    <path
 84.1141 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 84.1142 -       d="M 139.84375,107.83093 L 210.15625,107.83093"
 84.1143 -       id="path5965"
 84.1144 -       inkscape:connector-type="polyline" />
 84.1145 -    <path
 84.1146 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 84.1147 -       d="M 137.5,213.29968 L 210.49036,214.09055"
 84.1148 -       id="path5967"
 84.1149 -       inkscape:connector-type="polyline" />
 84.1150 -    <path
 84.1151 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
 84.1152 -       d="M 136.34375,544.54968 L 206.65625,544.54968"
 84.1153 -       id="path5969"
 84.1154 -       inkscape:connector-type="polyline"
 84.1155 -       inkscape:transform-center-y="-171.09375"
 84.1156 -       inkscape:transform-center-x="53.90625" />
 84.1157 -  </g>
 84.1158 -</svg>
    85.1 --- a/fr/snapshot.svg	Sun Aug 16 03:41:39 2009 +0200
    85.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.3 @@ -1,202 +0,0 @@
    85.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    85.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    85.6 -<svg
    85.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    85.8 -   xmlns:cc="http://web.resource.org/cc/"
    85.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   85.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   85.11 -   xmlns="http://www.w3.org/2000/svg"
   85.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   85.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   85.14 -   width="744.09448819"
   85.15 -   height="1052.3622047"
   85.16 -   id="svg2807"
   85.17 -   sodipodi:version="0.32"
   85.18 -   inkscape:version="0.44.1"
   85.19 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
   85.20 -   sodipodi:docname="snapshots.svg">
   85.21 -  <defs
   85.22 -     id="defs2809" />
   85.23 -  <sodipodi:namedview
   85.24 -     id="base"
   85.25 -     pagecolor="#ffffff"
   85.26 -     bordercolor="#666666"
   85.27 -     borderopacity="1.0"
   85.28 -     gridtolerance="10000"
   85.29 -     guidetolerance="10"
   85.30 -     objecttolerance="10"
   85.31 -     inkscape:pageopacity="0.0"
   85.32 -     inkscape:pageshadow="2"
   85.33 -     inkscape:zoom="1.4"
   85.34 -     inkscape:cx="252.04111"
   85.35 -     inkscape:cy="605.75448"
   85.36 -     inkscape:document-units="px"
   85.37 -     inkscape:current-layer="layer1"
   85.38 -     inkscape:window-width="906"
   85.39 -     inkscape:window-height="721"
   85.40 -     inkscape:window-x="0"
   85.41 -     inkscape:window-y="25" />
   85.42 -  <metadata
   85.43 -     id="metadata2812">
   85.44 -    <rdf:RDF>
   85.45 -      <cc:Work
   85.46 -         rdf:about="">
   85.47 -        <dc:format>image/svg+xml</dc:format>
   85.48 -        <dc:type
   85.49 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   85.50 -      </cc:Work>
   85.51 -    </rdf:RDF>
   85.52 -  </metadata>
   85.53 -  <g
   85.54 -     inkscape:label="Layer 1"
   85.55 -     inkscape:groupmode="layer"
   85.56 -     id="layer1">
   85.57 -    <rect
   85.58 -       style="opacity:1;fill:#d3ceff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.88795626;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
   85.59 -       id="rect2817"
   85.60 -       width="118.18347"
   85.61 -       height="245.32632"
   85.62 -       x="243.05112"
   85.63 -       y="315.4133"
   85.64 -       inkscape:transform-center-x="136.84403"
   85.65 -       inkscape:transform-center-y="-66.529183" />
   85.66 -    <rect
   85.67 -       y="315.04153"
   85.68 -       x="46.965065"
   85.69 -       height="97.803009"
   85.70 -       width="108.92702"
   85.71 -       id="rect2815"
   85.72 -       style="fill:#ffced6;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.14441991;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
   85.73 -    <g
   85.74 -       id="g3814">
   85.75 -      <rect
   85.76 -         y="348.94302"
   85.77 -         x="59.285713"
   85.78 -         height="30"
   85.79 -         width="84.285713"
   85.80 -         id="rect2819"
   85.81 -         style="fill:#ff6e86;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
   85.82 -         ry="0" />
   85.83 -      <text
   85.84 -         id="text2821"
   85.85 -         y="368.02701"
   85.86 -         x="72.717636"
   85.87 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
   85.88 -         xml:space="preserve"><tspan
   85.89 -           y="368.02701"
   85.90 -           x="72.717636"
   85.91 -           id="tspan2823"
   85.92 -           sodipodi:role="line">Index, rev 7</tspan></text>
   85.93 -    </g>
   85.94 -    <text
   85.95 -       id="text3722"
   85.96 -       y="301.29074"
   85.97 -       x="46.187778"
   85.98 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
   85.99 -       xml:space="preserve"><tspan
  85.100 -         y="301.29074"
  85.101 -         x="46.187778"
  85.102 -         id="tspan3724"
  85.103 -         sodipodi:role="line">Revlog index (.i file)</tspan></text>
  85.104 -    <text
  85.105 -       id="text3726"
  85.106 -       y="301.29074"
  85.107 -       x="241.90207"
  85.108 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  85.109 -       xml:space="preserve"><tspan
  85.110 -         y="301.29074"
  85.111 -         x="241.90207"
  85.112 -         id="tspan3728"
  85.113 -         sodipodi:role="line">Revlog data (.d file)</tspan></text>
  85.114 -    <path
  85.115 -       style="fill:#c695ff;fill-opacity:0.60109288;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  85.116 -       d="M 143.57143,348.07647 L 255,368.07646 L 255.71429,544.50504 L 142.85714,379.50504 L 143.57143,348.07647 z "
  85.117 -       id="path3839"
  85.118 -       sodipodi:nodetypes="ccccc" />
  85.119 -    <rect
  85.120 -       style="fill:#4733ff;fill-opacity:1;stroke:#a7a7a7;stroke-width:2.35124183;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  85.121 -       id="rect3752"
  85.122 -       width="92.720184"
  85.123 -       height="67.005905"
  85.124 -       x="255.42564"
  85.125 -       y="368.64264" />
  85.126 -    <text
  85.127 -       xml:space="preserve"
  85.128 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  85.129 -       x="264.45859"
  85.130 -       y="387.30099"
  85.131 -       id="text3754"><tspan
  85.132 -         sodipodi:role="line"
  85.133 -         id="tspan3756"
  85.134 -         x="264.45859"
  85.135 -         y="387.30099">Snapshot, rev 4</tspan></text>
  85.136 -    <rect
  85.137 -       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  85.138 -       id="rect3761"
  85.139 -       width="93.49366"
  85.140 -       height="29.922237"
  85.141 -       x="255.03891"
  85.142 -       y="442.04395" />
  85.143 -    <text
  85.144 -       xml:space="preserve"
  85.145 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  85.146 -       x="263.2662"
  85.147 -       y="460.17206"
  85.148 -       id="text3763"><tspan
  85.149 -         sodipodi:role="line"
  85.150 -         id="tspan3765"
  85.151 -         x="263.2662"
  85.152 -         y="460.17206">Delta, rev 4 to 5</tspan></text>
  85.153 -    <rect
  85.154 -       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  85.155 -       id="rect3774"
  85.156 -       width="93.49366"
  85.157 -       height="29.922237"
  85.158 -       x="255.03891"
  85.159 -       y="477.97485" />
  85.160 -    <text
  85.161 -       xml:space="preserve"
  85.162 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  85.163 -       x="263.2662"
  85.164 -       y="496.10297"
  85.165 -       id="text3776"><tspan
  85.166 -         sodipodi:role="line"
  85.167 -         id="tspan3778"
  85.168 -         x="263.2662"
  85.169 -         y="496.10297">Delta, rev 5 to 6</tspan></text>
  85.170 -    <rect
  85.171 -       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  85.172 -       id="rect3782"
  85.173 -       width="93.49366"
  85.174 -       height="29.922237"
  85.175 -       x="255.03891"
  85.176 -       y="513.90576" />
  85.177 -    <text
  85.178 -       xml:space="preserve"
  85.179 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  85.180 -       x="263.2662"
  85.181 -       y="532.03387"
  85.182 -       id="text3784"><tspan
  85.183 -         sodipodi:role="line"
  85.184 -         id="tspan3786"
  85.185 -         x="263.2662"
  85.186 -         y="532.03387">Delta, rev 6 to 7</tspan></text>
  85.187 -    <rect
  85.188 -       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
  85.189 -       id="rect3889"
  85.190 -       width="93.49366"
  85.191 -       height="29.922237"
  85.192 -       x="255.03891"
  85.193 -       y="332.32489" />
  85.194 -    <text
  85.195 -       xml:space="preserve"
  85.196 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  85.197 -       x="263.2662"
  85.198 -       y="350.453"
  85.199 -       id="text3891"><tspan
  85.200 -         sodipodi:role="line"
  85.201 -         id="tspan3893"
  85.202 -         x="263.2662"
  85.203 -         y="350.453">Delta, rev 2 to 3</tspan></text>
  85.204 -  </g>
  85.205 -</svg>
    86.1 --- a/fr/srcinstall.tex	Sun Aug 16 03:41:39 2009 +0200
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,53 +0,0 @@
    86.4 -\chapter{Installing Mercurial from source}
    86.5 -\label{chap:srcinstall}
    86.6 -
    86.7 -\section{On a Unix-like system}
    86.8 -\label{sec:srcinstall:unixlike}
    86.9 -
   86.10 -If you are using a Unix-like system that has a sufficiently recent
   86.11 -version of Python (2.3~or newer) available, it is easy to install
   86.12 -Mercurial from source.
   86.13 -\begin{enumerate}
   86.14 -\item Download a recent source tarball from
   86.15 -  \url{http://www.selenic.com/mercurial/download}.
   86.16 -\item Unpack the tarball:
   86.17 -  \begin{codesample4}
   86.18 -    gzip -dc mercurial-\emph{version}.tar.gz | tar xf -
   86.19 -  \end{codesample4}
   86.20 -\item Go into the source directory and run the installer script.  This
   86.21 -  will build Mercurial and install it in your home directory.
   86.22 -  \begin{codesample4}
   86.23 -    cd mercurial-\emph{version}
   86.24 -    python setup.py install --force --home=\$HOME
   86.25 -  \end{codesample4}
   86.26 -\end{enumerate}
   86.27 -Once the install finishes, Mercurial will be in the \texttt{bin}
   86.28 -subdirectory of your home directory.  Don't forget to make sure that
   86.29 -this directory is present in your shell's search path.
   86.30 -
   86.31 -You will probably need to set the \envar{PYTHONPATH} environment
   86.32 -variable so that the Mercurial executable can find the rest of the
   86.33 -Mercurial packages.  For example, on my laptop, I have set it to
   86.34 -\texttt{/home/bos/lib/python}.  The exact path that you will need to
   86.35 -use depends on how Python was built for your system, but should be
   86.36 -easy to figure out.  If you're uncertain, look through the output of
   86.37 -the installer script above, and see where the contents of the
   86.38 -\texttt{mercurial} directory were installed to.
   86.39 -
   86.40 -\section{On Windows}
   86.41 -
   86.42 -Building and installing Mercurial on Windows requires a variety of
   86.43 -tools, a fair amount of technical knowledge, and considerable
   86.44 -patience.  I very much \emph{do not recommend} this route if you are a
   86.45 -``casual user''.  Unless you intend to hack on Mercurial, I strongly
   86.46 -suggest that you use a binary package instead.
   86.47 -
   86.48 -If you are intent on building Mercurial from source on Windows, follow
   86.49 -the ``hard way'' directions on the Mercurial wiki at
   86.50 -\url{http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall},
   86.51 -and expect the process to involve a lot of fiddly work.
   86.52 -
   86.53 -%%% Local Variables: 
   86.54 -%%% mode: latex
   86.55 -%%% TeX-master: "00book"
   86.56 -%%% End: 
    87.1 --- a/fr/template.tex	Sun Aug 16 03:41:39 2009 +0200
    87.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.3 @@ -1,475 +0,0 @@
    87.4 -\chapter{Customising the output of Mercurial}
    87.5 -\label{chap:template}
    87.6 -
    87.7 -Mercurial provides a powerful mechanism to let you control how it
    87.8 -displays information.  The mechanism is based on templates.  You can
    87.9 -use templates to generate specific output for a single command, or to
   87.10 -customise the entire appearance of the built-in web interface.
   87.11 -
   87.12 -\section{Using precanned output styles}
   87.13 -\label{sec:style}
   87.14 -
   87.15 -Packaged with Mercurial are some output styles that you can use
   87.16 -immediately.  A style is simply a precanned template that someone
   87.17 -wrote and installed somewhere that Mercurial can find.
   87.18 -
   87.19 -Before we take a look at Mercurial's bundled styles, let's review its
   87.20 -normal output.
   87.21 -
   87.22 -\interaction{template.simple.normal}
   87.23 -
   87.24 -This is somewhat informative, but it takes up a lot of space---five
   87.25 -lines of output per changeset.  The \texttt{compact} style reduces
   87.26 -this to three lines, presented in a sparse manner.
   87.27 -
   87.28 -\interaction{template.simple.compact}
   87.29 -
   87.30 -The \texttt{changelog} style hints at the expressive power of
   87.31 -Mercurial's templating engine.  This style attempts to follow the GNU
   87.32 -Project's changelog guidelines\cite{web:changelog}.
   87.33 -
   87.34 -\interaction{template.simple.changelog}
   87.35 -
   87.36 -You will not be shocked to learn that Mercurial's default output style
   87.37 -is named \texttt{default}.
   87.38 -
   87.39 -\subsection{Setting a default style}
   87.40 -
   87.41 -You can modify the output style that Mercurial will use for every
   87.42 -command by editing your \hgrc\ file, naming the style you would
   87.43 -prefer to use.
   87.44 -
   87.45 -\begin{codesample2}
   87.46 -  [ui]
   87.47 -  style = compact
   87.48 -\end{codesample2}
   87.49 -
   87.50 -If you write a style of your own, you can use it by either providing
   87.51 -the path to your style file, or copying your style file into a
   87.52 -location where Mercurial can find it (typically the \texttt{templates}
   87.53 -subdirectory of your Mercurial install directory).
   87.54 -
   87.55 -\section{Commands that support styles and templates}
   87.56 -
   87.57 -All of Mercurial's ``\texttt{log}-like'' commands let you use styles
   87.58 -and templates: \hgcmd{incoming}, \hgcmd{log}, \hgcmd{outgoing}, and
   87.59 -\hgcmd{tip}.
   87.60 -
   87.61 -As I write this manual, these are so far the only commands that
   87.62 -support styles and templates.  Since these are the most important
   87.63 -commands that need customisable output, there has been little pressure
   87.64 -from the Mercurial user community to add style and template support to
   87.65 -other commands.
   87.66 -
   87.67 -\section{The basics of templating}
   87.68 -
   87.69 -At its simplest, a Mercurial template is a piece of text.  Some of the
   87.70 -text never changes, while other parts are \emph{expanded}, or replaced
   87.71 -with new text, when necessary.
   87.72 -
   87.73 -Before we continue, let's look again at a simple example of
   87.74 -Mercurial's normal output.
   87.75 -
   87.76 -\interaction{template.simple.normal}
   87.77 -
   87.78 -Now, let's run the same command, but using a template to change its
   87.79 -output.
   87.80 -
   87.81 -\interaction{template.simple.simplest}
   87.82 -
   87.83 -The example above illustrates the simplest possible template; it's
   87.84 -just a piece of static text, printed once for each changeset.  The
   87.85 -\hgopt{log}{--template} option to the \hgcmd{log} command tells
   87.86 -Mercurial to use the given text as the template when printing each
   87.87 -changeset.
   87.88 -
   87.89 -Notice that the template string above ends with the text
   87.90 -``\Verb+\n+''.  This is an \emph{escape sequence}, telling Mercurial
   87.91 -to print a newline at the end of each template item.  If you omit this
   87.92 -newline, Mercurial will run each piece of output together.  See
   87.93 -section~\ref{sec:template:escape} for more details of escape sequences.
   87.94 -
   87.95 -A template that prints a fixed string of text all the time isn't very
   87.96 -useful; let's try something a bit more complex.
   87.97 -
   87.98 -\interaction{template.simple.simplesub}
   87.99 -
  87.100 -As you can see, the string ``\Verb+{desc}+'' in the template has been
  87.101 -replaced in the output with the description of each changeset.  Every
  87.102 -time Mercurial finds text enclosed in curly braces (``\texttt{\{}''
  87.103 -and ``\texttt{\}}''), it will try to replace the braces and text with
  87.104 -the expansion of whatever is inside.  To print a literal curly brace,
  87.105 -you must escape it, as described in section~\ref{sec:template:escape}.
  87.106 -
  87.107 -\section{Common template keywords}
  87.108 -\label{sec:template:keyword}
  87.109 -
  87.110 -You can start writing simple templates immediately using the keywords
  87.111 -below.
  87.112 -
  87.113 -\begin{itemize}
  87.114 -\item[\tplkword{author}] String.  The unmodified author of the changeset.
  87.115 -\item[\tplkword{branches}] String.  The name of the branch on which
  87.116 -  the changeset was committed.  Will be empty if the branch name was
  87.117 -  \texttt{default}.
  87.118 -\item[\tplkword{date}] Date information.  The date when the changeset
  87.119 -  was committed.  This is \emph{not} human-readable; you must pass it
  87.120 -  through a filter that will render it appropriately.  See
  87.121 -  section~\ref{sec:template:filter} for more information on filters.
  87.122 -  The date is expressed as a pair of numbers.  The first number is a
  87.123 -  Unix UTC timestamp (seconds since January 1, 1970); the second is
  87.124 -  the offset of the committer's timezone from UTC, in seconds.
  87.125 -\item[\tplkword{desc}] String.  The text of the changeset description.
  87.126 -\item[\tplkword{files}] List of strings.  All files modified, added, or
  87.127 -  removed by this changeset.
  87.128 -\item[\tplkword{file\_adds}] List of strings.  Files added by this
  87.129 -  changeset.
  87.130 -\item[\tplkword{file\_dels}] List of strings.  Files removed by this
  87.131 -  changeset.
  87.132 -\item[\tplkword{node}] String.  The changeset identification hash, as a
  87.133 -  40-character hexadecimal string.
  87.134 -\item[\tplkword{parents}] List of strings.  The parents of the
  87.135 -  changeset.
  87.136 -\item[\tplkword{rev}] Integer.  The repository-local changeset revision
  87.137 -  number.
  87.138 -\item[\tplkword{tags}] List of strings.  Any tags associated with the
  87.139 -  changeset.
  87.140 -\end{itemize}
  87.141 -
  87.142 -A few simple experiments will show us what to expect when we use these
  87.143 -keywords; you can see the results in
  87.144 -figure~\ref{fig:template:keywords}.
  87.145 -
  87.146 -\begin{figure}
  87.147 -  \interaction{template.simple.keywords}
  87.148 -  \caption{Template keywords in use}
  87.149 -  \label{fig:template:keywords}
  87.150 -\end{figure}
  87.151 -
  87.152 -As we noted above, the date keyword does not produce human-readable
  87.153 -output, so we must treat it specially.  This involves using a
  87.154 -\emph{filter}, about which more in section~\ref{sec:template:filter}.
  87.155 -
  87.156 -\interaction{template.simple.datekeyword}
  87.157 -
  87.158 -\section{Escape sequences}
  87.159 -\label{sec:template:escape}
  87.160 -
  87.161 -Mercurial's templating engine recognises the most commonly used escape
  87.162 -sequences in strings.  When it sees a backslash (``\Verb+\+'')
  87.163 -character, it looks at the following character and substitutes the two
  87.164 -characters with a single replacement, as described below.
  87.165 -
  87.166 -\begin{itemize}
  87.167 -\item[\Verb+\textbackslash\textbackslash+] Backslash, ``\Verb+\+'',
  87.168 -  ASCII~134.
  87.169 -\item[\Verb+\textbackslash n+] Newline, ASCII~12.
  87.170 -\item[\Verb+\textbackslash r+] Carriage return, ASCII~15.
  87.171 -\item[\Verb+\textbackslash t+] Tab, ASCII~11.
  87.172 -\item[\Verb+\textbackslash v+] Vertical tab, ASCII~13.
  87.173 -\item[\Verb+\textbackslash \{+] Open curly brace, ``\Verb+{+'', ASCII~173.
  87.174 -\item[\Verb+\textbackslash \}+] Close curly brace, ``\Verb+}+'', ASCII~175.
  87.175 -\end{itemize}
  87.176 -
  87.177 -As indicated above, if you want the expansion of a template to contain
  87.178 -a literal ``\Verb+\+'', ``\Verb+{+'', or ``\Verb+{+'' character, you
  87.179 -must escape it.
  87.180 -
  87.181 -\section{Filtering keywords to change their results}
  87.182 -\label{sec:template:filter}
  87.183 -
  87.184 -Some of the results of template expansion are not immediately easy to
  87.185 -use.  Mercurial lets you specify an optional chain of \emph{filters}
  87.186 -to modify the result of expanding a keyword.  You have already seen a
  87.187 -common filter, \tplkwfilt{date}{isodate}, in action above, to make a
  87.188 -date readable.
  87.189 -
  87.190 -Below is a list of the most commonly used filters that Mercurial
  87.191 -supports.  While some filters can be applied to any text, others can
  87.192 -only be used in specific circumstances.  The name of each filter is
  87.193 -followed first by an indication of where it can be used, then a
  87.194 -description of its effect.
  87.195 -
  87.196 -\begin{itemize}
  87.197 -\item[\tplfilter{addbreaks}] Any text. Add an XHTML ``\Verb+<br/>+''
  87.198 -  tag before the end of every line except the last.  For example,
  87.199 -  ``\Verb+foo\nbar+'' becomes ``\Verb+foo<br/>\nbar+''.
  87.200 -\item[\tplkwfilt{date}{age}] \tplkword{date} keyword.  Render the
  87.201 -  age of the date, relative to the current time.  Yields a string like
  87.202 -  ``\Verb+10 minutes+''.
  87.203 -\item[\tplfilter{basename}] Any text, but most useful for the
  87.204 -  \tplkword{files} keyword and its relatives.  Treat the text as a
  87.205 -  path, and return the basename. For example, ``\Verb+foo/bar/baz+''
  87.206 -  becomes ``\Verb+baz+''.
  87.207 -\item[\tplkwfilt{date}{date}] \tplkword{date} keyword.  Render a date
  87.208 -  in a similar format to the Unix \tplkword{date} command, but with
  87.209 -  timezone included.  Yields a string like
  87.210 -  ``\Verb+Mon Sep 04 15:13:13 2006 -0700+''.
  87.211 -\item[\tplkwfilt{author}{domain}] Any text, but most useful for the
  87.212 -  \tplkword{author} keyword.  Finds the first string that looks like
  87.213 -  an email address, and extract just the domain component.  For
  87.214 -  example, ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' becomes
  87.215 -  ``\Verb+serpentine.com+''.
  87.216 -\item[\tplkwfilt{author}{email}] Any text, but most useful for the
  87.217 -  \tplkword{author} keyword.  Extract the first string that looks like
  87.218 -  an email address.  For example,
  87.219 -  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' becomes
  87.220 -  ``\Verb+bos@serpentine.com+''.
  87.221 -\item[\tplfilter{escape}] Any text.  Replace the special XML/XHTML
  87.222 -  characters ``\Verb+&+'', ``\Verb+<+'' and ``\Verb+>+'' with
  87.223 -  XML entities.
  87.224 -\item[\tplfilter{fill68}] Any text.  Wrap the text to fit in 68
  87.225 -  columns.  This is useful before you pass text through the
  87.226 -  \tplfilter{tabindent} filter, and still want it to fit in an
  87.227 -  80-column fixed-font window.
  87.228 -\item[\tplfilter{fill76}] Any text.  Wrap the text to fit in 76
  87.229 -  columns.
  87.230 -\item[\tplfilter{firstline}] Any text.  Yield the first line of text,
  87.231 -  without any trailing newlines.
  87.232 -\item[\tplkwfilt{date}{hgdate}] \tplkword{date} keyword.  Render the
  87.233 -  date as a pair of readable numbers.  Yields a string like
  87.234 -  ``\Verb+1157407993 25200+''.
  87.235 -\item[\tplkwfilt{date}{isodate}] \tplkword{date} keyword.  Render the
  87.236 -  date as a text string in ISO~8601 format.  Yields a string like
  87.237 -  ``\Verb+2006-09-04 15:13:13 -0700+''.
  87.238 -\item[\tplfilter{obfuscate}] Any text, but most useful for the
  87.239 -  \tplkword{author} keyword.  Yield the input text rendered as a
  87.240 -  sequence of XML entities.  This helps to defeat some particularly
  87.241 -  stupid screen-scraping email harvesting spambots.
  87.242 -\item[\tplkwfilt{author}{person}] Any text, but most useful for the
  87.243 -  \tplkword{author} keyword.  Yield the text before an email address.
  87.244 -  For example, ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+''
  87.245 -  becomes ``\Verb+Bryan O'Sullivan+''.
  87.246 -\item[\tplkwfilt{date}{rfc822date}] \tplkword{date} keyword.  Render a
  87.247 -  date using the same format used in email headers.  Yields a string
  87.248 -  like ``\Verb+Mon, 04 Sep 2006 15:13:13 -0700+''.
  87.249 -\item[\tplkwfilt{node}{short}] Changeset hash.  Yield the short form
  87.250 -  of a changeset hash, i.e.~a 12-character hexadecimal string.
  87.251 -\item[\tplkwfilt{date}{shortdate}] \tplkword{date} keyword.  Render
  87.252 -  the year, month, and day of the date.  Yields a string like
  87.253 -  ``\Verb+2006-09-04+''.
  87.254 -\item[\tplfilter{strip}] Any text.  Strip all leading and trailing
  87.255 -  whitespace from the string.
  87.256 -\item[\tplfilter{tabindent}] Any text.  Yield the text, with every line
  87.257 -  except the first starting with a tab character.
  87.258 -\item[\tplfilter{urlescape}] Any text.  Escape all characters that are
  87.259 -  considered ``special'' by URL parsers.  For example, \Verb+foo bar+
  87.260 -  becomes \Verb+foo%20bar+.
  87.261 -\item[\tplkwfilt{author}{user}] Any text, but most useful for the
  87.262 -  \tplkword{author} keyword.  Return the ``user'' portion of an email
  87.263 -  address.  For example,
  87.264 -  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' becomes
  87.265 -  ``\Verb+bos+''.
  87.266 -\end{itemize}
  87.267 -
  87.268 -\begin{figure}
  87.269 -  \interaction{template.simple.manyfilters}
  87.270 -  \caption{Template filters in action}
  87.271 -  \label{fig:template:filters}
  87.272 -\end{figure}
  87.273 -
  87.274 -\begin{note}
  87.275 -  If you try to apply a filter to a piece of data that it cannot
  87.276 -  process, Mercurial will fail and print a Python exception.  For
  87.277 -  example, trying to run the output of the \tplkword{desc} keyword
  87.278 -  into the \tplkwfilt{date}{isodate} filter is not a good idea.
  87.279 -\end{note}
  87.280 -
  87.281 -\subsection{Combining filters}
  87.282 -
  87.283 -It is easy to combine filters to yield output in the form you would
  87.284 -like.  The following chain of filters tidies up a description, then
  87.285 -makes sure that it fits cleanly into 68 columns, then indents it by a
  87.286 -further 8~characters (at least on Unix-like systems, where a tab is
  87.287 -conventionally 8~characters wide).
  87.288 -
  87.289 -\interaction{template.simple.combine}
  87.290 -
  87.291 -Note the use of ``\Verb+\t+'' (a tab character) in the template to
  87.292 -force the first line to be indented; this is necessary since
  87.293 -\tplkword{tabindent} indents all lines \emph{except} the first.
  87.294 -
  87.295 -Keep in mind that the order of filters in a chain is significant.  The
  87.296 -first filter is applied to the result of the keyword; the second to
  87.297 -the result of the first filter; and so on.  For example, using
  87.298 -\Verb+fill68|tabindent+ gives very different results from
  87.299 -\Verb+tabindent|fill68+.
  87.300 -
  87.301 -
  87.302 -\section{From templates to styles}
  87.303 -
  87.304 -A command line template provides a quick and simple way to format some
  87.305 -output.  Templates can become verbose, though, and it's useful to be
  87.306 -able to give a template a name.  A style file is a template with a
  87.307 -name, stored in a file.
  87.308 -
  87.309 -More than that, using a style file unlocks the power of Mercurial's
  87.310 -templating engine in ways that are not possible using the command line
  87.311 -\hgopt{log}{--template} option.
  87.312 -
  87.313 -\subsection{The simplest of style files}
  87.314 -
  87.315 -Our simple style file contains just one line:
  87.316 -
  87.317 -\interaction{template.simple.rev}
  87.318 -
  87.319 -This tells Mercurial, ``if you're printing a changeset, use the text
  87.320 -on the right as the template''.
  87.321 -
  87.322 -\subsection{Style file syntax}
  87.323 -
  87.324 -The syntax rules for a style file are simple.
  87.325 -
  87.326 -\begin{itemize}
  87.327 -\item The file is processed one line at a time.
  87.328 -
  87.329 -\item Leading and trailing white space are ignored.
  87.330 -
  87.331 -\item Empty lines are skipped.
  87.332 -
  87.333 -\item If a line starts with either of the characters ``\texttt{\#}'' or
  87.334 -  ``\texttt{;}'', the entire line is treated as a comment, and skipped
  87.335 -  as if empty.
  87.336 -
  87.337 -\item A line starts with a keyword.  This must start with an
  87.338 -  alphabetic character or underscore, and can subsequently contain any
  87.339 -  alphanumeric character or underscore.  (In regexp notation, a
  87.340 -  keyword must match \Verb+[A-Za-z_][A-Za-z0-9_]*+.)
  87.341 -
  87.342 -\item The next element must be an ``\texttt{=}'' character, which can
  87.343 -  be preceded or followed by an arbitrary amount of white space.
  87.344 -
  87.345 -\item If the rest of the line starts and ends with matching quote
  87.346 -  characters (either single or double quote), it is treated as a
  87.347 -  template body.
  87.348 -
  87.349 -\item If the rest of the line \emph{does not} start with a quote
  87.350 -  character, it is treated as the name of a file; the contents of this
  87.351 -  file will be read and used as a template body.
  87.352 -\end{itemize}
  87.353 -
  87.354 -\section{Style files by example}
  87.355 -
  87.356 -To illustrate how to write a style file, we will construct a few by
  87.357 -example.  Rather than provide a complete style file and walk through
  87.358 -it, we'll mirror the usual process of developing a style file by
  87.359 -starting with something very simple, and walking through a series of
  87.360 -successively more complete examples.
  87.361 -
  87.362 -\subsection{Identifying mistakes in style files}
  87.363 -
  87.364 -If Mercurial encounters a problem in a style file you are working on,
  87.365 -it prints a terse error message that, once you figure out what it
  87.366 -means, is actually quite useful.
  87.367 -
  87.368 -\interaction{template.svnstyle.syntax.input}
  87.369 -
  87.370 -Notice that \filename{broken.style} attempts to define a
  87.371 -\texttt{changeset} keyword, but forgets to give any content for it.
  87.372 -When instructed to use this style file, Mercurial promptly complains.
  87.373 -
  87.374 -\interaction{template.svnstyle.syntax.error}
  87.375 -
  87.376 -This error message looks intimidating, but it is not too hard to
  87.377 -follow.
  87.378 -
  87.379 -\begin{itemize}
  87.380 -\item The first component is simply Mercurial's way of saying ``I am
  87.381 -  giving up''.
  87.382 -  \begin{codesample4}
  87.383 -    \textbf{abort:} broken.style:1: parse error
  87.384 -  \end{codesample4}
  87.385 -
  87.386 -\item Next comes the name of the style file that contains the error.
  87.387 -  \begin{codesample4}
  87.388 -    abort: \textbf{broken.style}:1: parse error
  87.389 -  \end{codesample4}
  87.390 -
  87.391 -\item Following the file name is the line number where the error was
  87.392 -  encountered.
  87.393 -  \begin{codesample4}
  87.394 -    abort: broken.style:\textbf{1}: parse error
  87.395 -  \end{codesample4}
  87.396 -
  87.397 -\item Finally, a description of what went wrong.
  87.398 -  \begin{codesample4}
  87.399 -    abort: broken.style:1: \textbf{parse error}
  87.400 -  \end{codesample4}
  87.401 -  The description of the problem is not always clear (as in this
  87.402 -  case), but even when it is cryptic, it is almost always trivial to
  87.403 -  visually inspect the offending line in the style file and see what
  87.404 -  is wrong.
  87.405 -\end{itemize}
  87.406 -
  87.407 -\subsection{Uniquely identifying a repository}
  87.408 -
  87.409 -If you would like to be able to identify a Mercurial repository
  87.410 -``fairly uniquely'' using a short string as an identifier, you can
  87.411 -use the first revision in the repository.
  87.412 -\interaction{template.svnstyle.id} 
  87.413 -This is not guaranteed to be unique, but it is nevertheless useful in
  87.414 -many cases.
  87.415 -\begin{itemize}
  87.416 -\item It will not work in a completely empty repository, because such
  87.417 -  a repository does not have a revision~zero.
  87.418 -\item Neither will it work in the (extremely rare) case where a
  87.419 -  repository is a merge of two or more formerly independent
  87.420 -  repositories, and you still have those repositories around.
  87.421 -\end{itemize}
  87.422 -Here are some uses to which you could put this identifier:
  87.423 -\begin{itemize}
  87.424 -\item As a key into a table for a database that manages repositories
  87.425 -  on a server.
  87.426 -\item As half of a \{\emph{repository~ID}, \emph{revision~ID}\} tuple.
  87.427 -  Save this information away when you run an automated build or other
  87.428 -  activity, so that you can ``replay'' the build later if necessary.
  87.429 -\end{itemize}
  87.430 -
  87.431 -\subsection{Mimicking Subversion's output}
  87.432 -
  87.433 -Let's try to emulate the default output format used by another
  87.434 -revision control tool, Subversion.
  87.435 -\interaction{template.svnstyle.short}
  87.436 -
  87.437 -Since Subversion's output style is fairly simple, it is easy to
  87.438 -copy-and-paste a hunk of its output into a file, and replace the text
  87.439 -produced above by Subversion with the template values we'd like to see
  87.440 -expanded.
  87.441 -\interaction{template.svnstyle.template}
  87.442 -
  87.443 -There are a few small ways in which this template deviates from the
  87.444 -output produced by Subversion.
  87.445 -\begin{itemize}
  87.446 -\item Subversion prints a ``readable'' date (the ``\texttt{Wed, 27 Sep
  87.447 -    2006}'' in the example output above) in parentheses.  Mercurial's
  87.448 -  templating engine does not provide a way to display a date in this
  87.449 -  format without also printing the time and time zone.
  87.450 -\item We emulate Subversion's printing of ``separator'' lines full of
  87.451 -  ``\texttt{-}'' characters by ending the template with such a line.
  87.452 -  We use the templating engine's \tplkword{header} keyword to print a
  87.453 -  separator line as the first line of output (see below), thus
  87.454 -  achieving similar output to Subversion.
  87.455 -\item Subversion's output includes a count in the header of the number
  87.456 -  of lines in the commit message.  We cannot replicate this in
  87.457 -  Mercurial; the templating engine does not currently provide a filter
  87.458 -  that counts the number of lines the template generates.
  87.459 -\end{itemize}
  87.460 -It took me no more than a minute or two of work to replace literal
  87.461 -text from an example of Subversion's output with some keywords and
  87.462 -filters to give the template above.  The style file simply refers to
  87.463 -the template.
  87.464 -\interaction{template.svnstyle.style}
  87.465 -
  87.466 -We could have included the text of the template file directly in the
  87.467 -style file by enclosing it in quotes and replacing the newlines with
  87.468 -``\verb!\n!'' sequences, but it would have made the style file too
  87.469 -difficult to read.  Readability is a good guide when you're trying to
  87.470 -decide whether some text belongs in a style file, or in a template
  87.471 -file that the style file points to.  If the style file will look too
  87.472 -big or cluttered if you insert a literal piece of text, drop it into a
  87.473 -template instead.
  87.474 -
  87.475 -%%% Local Variables: 
  87.476 -%%% mode: latex
  87.477 -%%% TeX-master: "00book"
  87.478 -%%% End: 
    88.1 --- a/fr/tour-basic.tex	Sun Aug 16 03:41:39 2009 +0200
    88.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.3 @@ -1,696 +0,0 @@
    88.4 -\chapter{Un rapide tour de Mercurial}
    88.5 -\label{chap:tour-basic}
    88.6 -
    88.7 -\section{Installer Mercurial sur votre système}
    88.8 -\label{sec:tour:install}
    88.9 -
   88.10 -Des paquetages binaires de Mercurial sont disponibles pour la plupart
   88.11 -des systèmes d'exploitation, ce qui rend facile l'utilisation immédiate
   88.12 -de Mercurial sur votre ordinateur.
   88.13 -
   88.14 -\subsection{Linux}
   88.15 -
   88.16 -Parce que chaque distribution de Linux a ses propres outils de gestion
   88.17 -de paquets, politiques et rythmes de développements, il est difficile de
   88.18 -donner un ensemble d'instructions uniques pour installer les binaires de
   88.19 -Mercurial. La version de Mercurial avec laquelle vous vous retrouverez
   88.20 -dépendra grandement de l'activité de la personne en charge du paquetage
   88.21 -pour la distribution.
   88.22 -
   88.23 -Pour rester simple, je me concentrerai sur l'installation de Mercurial
   88.24 -en ligne de commande, sous les distributions les plus courantes. La 
   88.25 -plupart des distributions fournissent des gestionnaires graphiques de
   88.26 -paquetage qui vous permettront d'installer Mercurial en quelques clicks.
   88.27 -Le paquetage devrait se nommer \textit{mercurial}.
   88.28 -
   88.29 -\begin{itemize}
   88.30 -\item[Debian]
   88.31 -  \begin{codesample4}
   88.32 -    apt-get install mercurial
   88.33 -  \end{codesample4}
   88.34 -
   88.35 -\item[Fedora Core]
   88.36 -  \begin{codesample4}
   88.37 -    yum install mercurial
   88.38 -  \end{codesample4}
   88.39 -
   88.40 -\item[Gentoo]
   88.41 -  \begin{codesample4}
   88.42 -    emerge mercurial
   88.43 -  \end{codesample4}
   88.44 -
   88.45 -\item[OpenSUSE]
   88.46 -  \begin{codesample4}
   88.47 -    yum install mercurial
   88.48 -  \end{codesample4}
   88.49 -
   88.50 -\item[Ubuntu] Le paquetage de Mercurial d'Ubuntu est construit sur celui de Debian. 
   88.51 -              Pour l'installer, exécutez simplement les commandes suivantes:
   88.52 -  \begin{codesample4}
   88.53 -    apt-get install mercurial
   88.54 -  \end{codesample4}
   88.55 -  Les paquetages Ubuntu pour Mercurial ont tendance à être un peu en retard
   88.56 -  par rapport au paquetage Debian (au moment de l'écriture de ce livre, il
   88.57 -  faut compter à peu près un retard de 7 mois), ce qui signifie que parfois 
   88.58 -  sur Ubuntu, vous risquez de rencontrer des problèmes qui ont été corrigés 
   88.59 -  depuis longtemps dans les paquetages Debian.
   88.60 -\end{itemize}
   88.61 -
   88.62 -\subsection{Solaris}
   88.63 -
   88.64 -SunFreeWare, à \url{http://www.saufreeware.com}, est une bonne source 
   88.65 -pour trouver un vaste nombre de paquets précompilés pour 32 ou 64 bits
   88.66 -Intel et les architecture Sparc, dont les versions courantes de Mercurial.
   88.67 -
   88.68 -\subsection{Mac OS X}
   88.69 -
   88.70 -Lee Cantey publie un installateur de Mercurial pour Mac OS~X sur le site 
   88.71 -\url{http://mercurial.berkwood.com}.  Ce paquetage fonctionne sur les 
   88.72 -architectures Intel-~et PowerPC. Avant de vous en servir, vous devez
   88.73 -installer une version Universelle MacPython~\cite{web:macpython}. C'est
   88.74 -assez facile à faire : suivez simplement les instructions sur le site
   88.75 -de Lee.
   88.76 -
   88.77 -Il est aussi possible d'installer Mercurial en utilisant Fink ou MacPorts,
   88.78 -deux outils de gestion de paquetage libres pour Mac OS X. Si vous avez 
   88.79 -Fink, utilisez \command{sudo fink install mercurial-py25}. Si vous avez 
   88.80 -MacPorts, \command{sudo port install mercurial}.
   88.81 -
   88.82 -\subsection{Windows}
   88.83 -
   88.84 -Lee Cantey publie aussi un installateur de Mercurial pour Windows sur le site
   88.85 -\url{http://mercurial.berkwood.com}. Ce paquetage n'a aucune dépendance 
   88.86 -externe, il fonctionne ``tout court''.
   88.87 -
   88.88 -\begin{note}
   88.89 -  La version de Windows de Mercurial ne convertie pas automatiquement
   88.90 -  les retours chariot Windows et Unix. Si vous désirez partager votre
   88.91 -  travail avec des utilisateurs Unix, vous devez faire un peu de configuration
   88.92 -  supplémentaire. XXX En dire plus.
   88.93 -\end{note}
   88.94 -
   88.95 -\section{Commencer à utiliser Mercurial}
   88.96 -
   88.97 -Pour commencer, nous utiliserons la commande \hgcmd{version} pour vérifier
   88.98 -si Mercurial est installé proprement. Les informations affichées sur la 
   88.99 -version ne sont pas réellement importantes en soit, c'est surtout de savoir
  88.100 -si elles s'affichent qui nous intéresse.
  88.101 -\interaction{tour.version}
  88.102 -
  88.103 -\subsection{L'aide intégrée}
  88.104 -
  88.105 -Mercurial fournit un système d'aide intégré, ce qui est inestimable quand
  88.106 -vous vous retrouvez coincé à essayer de vous rappeler comment lancer telle
  88.107 -ou telle commande. 
  88.108 -Si c'est le cas, exécutez simplement \hgcmd{help}; il vous aidera à imprimer
  88.109 -une brève liste de commandes, avec une description de ce qu'elles font. Si vous
  88.110 -demandez de l'aide sur une commande spécifique (voir ci-dessous), il affichera
  88.111 -des informations plus détaillées.
  88.112 -\interaction{tour.help}
  88.113 -Pour un niveau d'informations encore plus détaillées (ce dont vous aurez rarement
  88.114 -besoin), exécuter \hgcmdargs{help}{\hggopt{-v}}.  L'option \hggopt{-v} est 
  88.115 -l'abréviation de \hggopt{--verbose}, et indique à Mercurial d'afficher plus 
  88.116 -d'informations que d'habitude.
  88.117 -
  88.118 -\section{Travailler avec un dépôt}
  88.119 -
  88.120 -Avec Mercurial, tout se déroule au sein du \emph{dépôt}\footnote{NdT: Dépôt est
  88.121 -la traduction que j'ai retenue pour tout l'ouvrage du terme anglais \textit{repository}}.
  88.122 -Le dépôt d'un projet contient tous les fichiers qui ``appartiennent'' au projet.
  88.123 -
  88.124 -Il n'y a rien de particulièrement magique au sujet de ce dépôt, c'est
  88.125 -simplement une arborescence sur votre système de fichiers que Mercurial
  88.126 -traite de manière spéciale. Vous pouvez renommer ou effacer ce répertoire
  88.127 -à n'importe quel moment, en utilisant la ligne de commande ou votre
  88.128 -explorateur de fichiers.
  88.129 -
  88.130 -\subsection{Faire une copie locale de votre dépôt}
  88.131 -
  88.132 -\emph{Copier} un dépôt est juste un peu spécial. Bien que vous 
  88.133 -puissiez utiliser une commande habituelle de copie pour copier
  88.134 -votre dépôt, il vaut mieux utiliser une commande fournie par
  88.135 -Mercurial. Cette commande est appelée \hgcmd{clone}, car elle
  88.136 -crée une copie identique à un dépôt existant.
  88.137 -\interaction{tour.clone}
  88.138 -Si votre opération de clonage réussit, vous devriez maintenant
  88.139 -avoir un répertoire local appelé \dirname{hello}. Ce répertoire
  88.140 -contiendra quelques fichiers.
  88.141 -\interaction{tour.ls}
  88.142 -Ces fichiers ont le même contenu et historique dans votre dépôt
  88.143 -qu'ils ont dans le dépôt que vous avez cloné.
  88.144 -
  88.145 -Chaque dépôt Mercurial est complet, autonome et indépendant. Il
  88.146 -contient sa propre copie privée des fichiers du projet et de leur
  88.147 -historique. Le clone d'un dépôt se souvient de la localisation du
  88.148 -dépôt à partir duquel il a été clôné, mais il ne communique pas avec
  88.149 -ce dernier, ou un autre, à moins que vous ne lui demandiez.
  88.150 -
  88.151 -Ce que tout ceci signifie pour le moment est que nous sommes libres
  88.152 -d'expérimenter avec ce dépôt, confiants dans le fait qu'il s'agit d'un
  88.153 -``bac à sable'' qui n'affectera personne d'autre.
  88.154 -
  88.155 -\subsection{Quel est le contenu d'un dépôt ?}
  88.156 -
  88.157 -Prêtons plus attention un instant au contenu d'un dépôt. Nous voyons 
  88.158 -qu'il contient un répertoire nommé \dirname{.hg}. C'est ici que Mercurial
  88.159 -conserve toutes ses métadonnées.
  88.160 -\interaction{tour.ls-a}
  88.161 -
  88.162 -Le contenu du répertoire \dirname{.hg} et ses sous répertoires sont les
  88.163 -seuls propres à Mercurial. Tous les autres fichiers et répertoires dans 
  88.164 -le dépôt sont à vous, et vous pouvez en faire ce que vous voulez.
  88.165 -
  88.166 -Pour introduire un peu de terminologie, le répertoire \dirname{.hg} est
  88.167 -un ``vrai'' dépôt, et tous les fichiers et les répertoires qui coexistent
  88.168 -avec lui, sont désignés sous le nom \emph{espace de travail}\footnote{NdT: 
  88.169 -\textit{working directory}}. Une manière facile de se rappeler cette 
  88.170 -distinction est de retenir que le \emph{dépôt} contient l'\emph{historique}
  88.171 -de votre projet, alors que l'\emph{espace de travail} contient une \emph{copie
  88.172 -ponctuelle}\footnote{NdT: Ce terme est une traduction du terme anglais 
  88.173 -\textit{snapshot}. Il est traduit ici pour faciliter la lecture, mais ne sera
  88.174 -plus traduit par la suite.} de votre projet à un certain point de son
  88.175 -historique.
  88.176 -
  88.177 -\section{Une ballade dans l'historique}
  88.178 -
  88.179 -Une des premières choses que vous aurez envie de faire avec un nouveau
  88.180 -dépôt, sera de comprendre son historique. La commande \hgcmd{log} vous
  88.181 -donne une vue de l'historique.
  88.182 -\interaction{tour.log}
  88.183 -Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque
  88.184 -révision enregistrée pour ce projet. Dans la terminologie de Mercurial, nous
  88.185 -appelons chacun de ces évènements enregistrés un \emph{changeset}, parce 
  88.186 -qu'il contient un ensemble de modifications sur plusieurs fichiers.
  88.187 -
  88.188 -La commande \hgcmd{log} affiche ainsi ces informations:
  88.189 -\begin{itemize}
  88.190 -\item[\texttt{changeset}] Ce champ contient un nombre, séparé par deux points
  88.191 -  (:), d'une chaine hexadécimale. Il s'agit en fait d'\emph{identifiants}
  88.192 -  d'un \textit{changeset}. Il y a deux identifiants car le numéro de
  88.193 -  la révision est plus court et plus à facile à saisir qu'une séquence
  88.194 -  hexadécimale.
  88.195 -\item[\texttt{user}] L'identité de la personne qui a créée ce  %%% laisser le terme anglais car il sera affiché
  88.196 -  \textit{changeset}. C'est un champ libre de forme, mais la plupart du
  88.197 -  temps il contient le nom et l'email de la personne.
  88.198 -\item[\texttt{date}] La date et l'heure à laquelle le \textit{changeset}
  88.199 -  a été créé, ainsi que le \textit{fuseau horaire} dans laquelle il a été créé. %%%TODO: Translate 'timezone' properly : FUSEAU
  88.200 -  (La date et l'heure sont locales à ce \textit{fuseau}, elles indiquent
  88.201 -  donc quelle date et heure il était pour la personne qui a créé ce %%%TODO: je suppose (quelle "heure")  OUI
  88.202 -  \textit{changeset}.)
  88.203 -\item[\texttt{résumé}] La première du message que le créateur a associé à
  88.204 -  son \textit{changeset} pour le décrire.
  88.205 -\end{itemize}
  88.206 -
  88.207 -Par défaut, la commande \hgcmd{log} n'affiche qu'un résumé, il manque 
  88.208 -beaucoup de détails.
  88.209 -
  88.210 -La figure~\ref{fig:tour-basic:history} fournit une représentation graphique
  88.211 -de l'historique du dépôt \dirname{hello}, pour rendre plus facile de voir
  88.212 -dans quelle direction l'historique se ``déroule''\footnote{NdT: \textit{flowing in}.}.
  88.213 -Nous reviendrons régulièrement sur cette représentation dans ce chapitre et
  88.214 -ceux qui suivent.
  88.215 -
  88.216 -\begin{figure}[ht]
  88.217 -  \centering
  88.218 -  \grafix{tour-history}
  88.219 -  \caption{Représentation graphique du dépôt \dirname{hello} }
  88.220 -  \label{fig:tour-basic:history}
  88.221 -\end{figure}
  88.222 -
  88.223 -\subsection{Changesets, révisions, et discuter avec les autres}%%%TODO: je propose : "discussion" (3 noms communs)
  88.224 -%%% je propose "colaboration"
  88.225 -
  88.226 -Comme l'anglais est réputé pour être un langage maladroit, et que l'informatique
  88.227 -est la source de bien des erreurs de terminologies (pourquoi utiliser un
  88.228 -seul terme quand quatre feront l'affaire ?), la gestion de version a une
  88.229 -variété de mots et de phrases qui veulent dire la même chose. Si vous 
  88.230 -discutez d'historique de Mercurial avec d'autres personnes, 
  88.231 -%%%TODO: ça ne veut rien dire: il faut supprimer une des personnes : soit "quelqu'un", 
  88.232 -% soit "à d'autres personnes"
  88.233 -vous constaterez que souvent le mot ``\textit{changeset}'' est contracté simplement
  88.234 -en ``change'' ou (à l'écrit) ``cset'', et même parfois un 
  88.235 -\textit{changeset} simplement ``révision'', abrégé en ``rev''.
  88.236 -
  88.237 -Bien que le \emph{mot} que vous utilisez pour désigner le concept de
  88.238 -\textit{changeset} importe peu, l'\emph{identifiant} que vous utilisez
  88.239 -pour désigner un \emph{changeset} \textit{spécifique} a une grande
  88.240 -importance. Rappelez vous que le champ \textit{changeset} affiché par la 
  88.241 -commande \hgcmd{log} identifie un \textit{changeset} à la fois avec
  88.242 -un numéro de révision et une séquence hexadécimale.
  88.243 -
  88.244 -\begin{itemize}
  88.245 -\item Le numéro de révision est \emph{seulement valable dans ce dépôt},
  88.246 -\item alors que la séquence hexadécimale est un \emph{identifiant 
  88.247 -	permanent, et invariant } qui pourra toujours être associé au 
  88.248 -	\textit{changeset} exact de \emph{chaque} copie de votre dépôt.
  88.249 -\end{itemize}
  88.250 -
  88.251 -La distinction est importante. Si vous envoyez un email à quelqu'un en
  88.252 -parlant de la ``révision 33'', il est très probable que sa révision~33
  88.253 -\emph{ne sera pas la même} que la votre. La raison de ceci est que le
  88.254 -numéro de révision dépend de l'ordre dans lequel les modifications sont
  88.255 -arrivées dans le dépôt, et il n'y a aucune garantie que les mêmes changements
  88.256 -soient arrivés dans le même ordre dans différents dépôts. Trois modifications
  88.257 -$a,b,c$ peuvent aisément apparaitre dans un dépôt comme $0,1,2$, et dans
  88.258 -un autre comme $1,0,2$.
  88.259 -
  88.260 -Mercurial utilise les numéros de révision uniquement comme des raccourcis
  88.261 -pratiques. Si vous devez discuter d'un \textit{changeset} avec quelqu'un, 
  88.262 -ou identifer un \textit{changeset} pour une quelquonque %%%TODO: our : "pour" ou "ou"
  88.263 -raison (par exemple, un rapport de \textit{bug}), utilisez la séquence
  88.264 -hexadécimale.
  88.265 -
  88.266 -\subsection{Afficher une révision spécifique}
  88.267 -
  88.268 -Pour réduire la sortie de \hgcmd{log} à une seule révision, utilisez
  88.269 -l'option \hgopt{log}{-r} (ou \hgopt{log}{--rev}). Vous pouvez utiliser
  88.270 -le numéro de révision ou la séquence hexadécimale comme identifiant, et 
  88.271 -demander autant de révisions que vous le souhaitez. 
  88.272 -\interaction{tour.log-r}
  88.273 -
  88.274 -Si vous voulez voir l'historique de plusieurs révisions sans avoir à 
  88.275 -les énumérer, vous pouvez utiliser la \emph{\textit{range notation}}
  88.276 -\footnote{NdT: Il n'est pas aisé de traduire ce terme, donc je le  %%%TODO : intervalle de numérotation ?
  88.277 -laisse en anglais} qui vous permet d'exprimer l'idée ``je veux toutes
  88.278 -les révisions entre $a$ et $b$, inclus''.
  88.279 -\interaction{tour.log.range}
  88.280 -Mercurial respecte aussi l'ordre dans lequel vous spécifiez les 
  88.281 -révisions, ainsi \hgcmdargs{log}{-r 2:4} affichera $2,3,4$ alors que 
  88.282 -\hgcmdargs{log}{-r 4:2} affichera $4,3,2$.
  88.283 -
  88.284 -\subsection{Informations détaillées}
  88.285 -
  88.286 -
  88.287 -Le résumé affiché par \hgcmd{log} est suffisant si vous savez déjà ce %%%TODO: je pense que le premier "si" est de trop : exact
  88.288 -que vous cherchez. En revanche, vous aurez probablement besoin de voir une description
  88.289 -complète du changement, ou une liste des fichiers modifiés si vous 
  88.290 -cherchez à déterminer qu'un \textit{changeset} est bien celui que vous%%%TODO: les propositions sont mal construites : après un "si...." il faut une proposition sans "si... donc ici : "si ... recherchez", ben quoi ?
  88.291 -recherchez. L'option \hgopt{-v} de la commande \hgcmd{log} (ou 
  88.292 -\hgopt{--verbose}) vous donne ces informations supplémentaires.
  88.293 -\interaction{tour.log-v}
  88.294 -
  88.295 -Si vous voulez voir à la fois la description et le contenu d'une 
  88.296 -modification, ajouter l'option \hgopt{log}{-p} (ou \hgopt{log}{--patch}).
  88.297 -Ceci affiche le contenu d'une modification comme un \emph{diff unifié}
  88.298 -\footnote{NdT: \textit{unified diff}} (si vous n'avez jamais vu de diff 
  88.299 -unifié avant, consultez la section~\ref{sec:mq:patch} pour un rapide 
  88.300 -survol).
  88.301 -
  88.302 -\interaction{tour.log-vp}
  88.303 -
  88.304 -\section{Tout sur les options de commandes}
  88.305 -
  88.306 -
  88.307 -Avant d'aller plus loin sur le fonctionnement des commandes de Mercurial,
  88.308 -étudions un moment comment elles fonctionnent de manière générale. Vous
  88.309 -trouverez ça probablement utile pour la suite de notre parcours.
  88.310 -
  88.311 -Mercurial utilise une approche directe et cohérente pour interpréter %%%TODO: une manière d'approche ?
  88.312 -les options que vous passez aux commandes. Il suit une convention commune
  88.313 -à la plupart des systèmes Unix et Linux modernes.
  88.314 -
  88.315 -\begin{itemize}
  88.316 -\item Chaque option a un nom complet. Par exemple, comme nous l'avons déjà
  88.317 -      vu, la commande \hgcmd{log} accepte l'option \hgopt{log}{--rev}.%%%TODO: commande ou command e\hgcmd...?
  88.318 -\item La plupart des options disposent de noms abrégés. Aussi, au lieu d'utiliser
  88.319 -  \hgopt{log}{--rev}, vous pouvez utiliser \hgopt{log}{-r}. (Les options qui
  88.320 -  n'ont pas de noms abrégés sont généralement rarement utilisées, pour cette raison).
  88.321 -\item Les noms complets commencent par deux tirets (i.e.~\hgopt{log}{--rev}),
  88.322 -  alors que les options courtes commencent avec un seul (i.e.~\hgopt{log}{-r}).
  88.323 -\item Les noms des options sont cohérents entre les commandes. Par exemple, 
  88.324 -  chaque commande qui accepte un \textit{changeset~ID} ou un numéro de révision
  88.325 -  accepte aussi \hgopt{log}{-r} et \hgopt{log}{--rev} comme arguments.
  88.326 -  %TODO: Small mistake here, shouldn't have log here... shouldn't it ?
  88.327 -\end{itemize}
  88.328 -
  88.329 -Dans les exemples de ce livre, j'utilise les noms abrégés plutôt que les noms
  88.330 -complets. Ceci est une préférence personnelle, pas une recommandation.
  88.331 -
  88.332 -La plupart des commandes qui affichent une quelconque sortie à l'écran,
  88.333 -afficheront davantage avec l'option \hggopt{-v} (ou \hggopt{--verbose}), et
  88.334 -moins avec l'option \hggopt{-q} (ou \hggopt{--quiet}).
  88.335 -
  88.336 -\section{Faire et vérifier des modifications}
  88.337 -
  88.338 -Maintenant que nous avons une bonne idée des commandes pour consulter 
  88.339 -l'historique de Mercurial, regardons comment faire des modifications et 
  88.340 -les examiner.
  88.341 -
  88.342 -
  88.343 -La première chose que nous allons faire c'est isoler notre expérience dans
  88.344 -un dépôt à part. Nous allons utiliser la commande \hgcmd{clone}, mais nous
  88.345 -n'avons pas besoin de faire une copie de dépôt distant. Comme nous avons 
  88.346 -déjà une copie locale, nous pouvons juste faire un clone de celle-ci à la 
  88.347 -place. C'est beaucoup plus rapide que de faire une copie à travers le 
  88.348 -réseau, et un dépôt cloné localement prend également moins d'espace disque.
  88.349 -
  88.350 -\interaction{tour.reclone}
  88.351 -
  88.352 -On notera au passage qu'il est souvent considéré comme une bonne pratique
  88.353 -de conserver une copie ``immaculée'' du dépôt distant, à partir de laquelle
  88.354 -vous pourrez faire des copies locales temporaires pour créer des ``bacs à 
  88.355 -sable'' pour chaque tâche sur laquelle vous souhaitez travailler. Ceci vous
  88.356 -permet de travailler sur plusieurs choses en parallèle, chacune isolée les 
  88.357 -unes des autres en attendant que ces tâches soient finies et que vous soyez
  88.358 -prêt à les réintégrer. Parce que les copies locales sont peu coûteuses, il
  88.359 -est très rapide de créer ou détruire des dépôts dès que vous en avez besoin.
  88.360 -
  88.361 -%% Note: la dernière phrase n'est pas une traduction littérale, mais je
  88.362 -%% pense qu'elle exprime plus clairement en français ce que veut dire son 
  88.363 -%% équivalent anglais. : OUI
  88.364 -
  88.365 -Dans notre dépôt \dirname{my-hello}, nous avons un fichier \filename{hello.c}
  88.366 -qui contient le classique programme ``hello, world''. Nous allons utiliser 
  88.367 -l'ancienne et vénérable commande \command{sed} pour l'éditer afin qu'il 
  88.368 -affiche une seconde ligne à l'écran. (J'utilise \command{sed} seulement parce
  88.369 -qu'il est ainsi facile d'écrire des exemples sous forme de script. Comme 
  88.370 -vous n'avez pas ces contraintes, vous n'utiliserez probablement pas \command{sed}
  88.371 -mais plutôt votre éditeur de texte favori). 
  88.372 -
  88.373 -\interaction{tour.sed}
  88.374 -
  88.375 -La commande \hgcmd{status} de Mercurial nous dira de quels fichiers Mercurial
  88.376 -s'occupe au sein de ce dépôt.
  88.377 -\interaction{tour.status}
  88.378 -La commande \hgcmd{status} n'affiche rien sur la sortie pour quelques fichiers
  88.379 -mais une ligne commence par ``\texttt{M}'' for \filename{hello.c}. À moins que
  88.380 -vous ne lui indiquiez de le faire, \hgcmd{status} n'affichera aucune sortie 
  88.381 -pour les fichiers qui n'ont pas été modifiés.
  88.382 -
  88.383 -Le caractère ``\texttt{M}'' indique que Mercurial a remarqué que nous avions
  88.384 -modifié le fichier \filename{hello.c}. Nous n'avons pas besoin d'\emph{informer}
  88.385 -Mercurial que nous allons modifier un fichier avant de le faire, ou que nous 
  88.386 -venons de le modifier, il est capable de s'en rendre compte tout seul.
  88.387 -
  88.388 -C'est pratique de savoir que nous avons modifié \filename{hello.c}, mais il
  88.389 -serait encore plus pratique de savoir ce que nous avons modifié exactement. Pour
  88.390 -cela, nous avons la commande  \hgcmd{diff}.
  88.391 -
  88.392 -\interaction{tour.diff}
  88.393 -
  88.394 -\section{Enregister les modifications dans un nouveau \textit{changeset}}
  88.395 -
  88.396 -Nous pouvons modifier des fichiers, compiler et tester nos modifications,
  88.397 -et utiliser les commandes \hgcmd{status} et \hgcmd{diff} pour voir les
  88.398 -modifications effectuées, jusqu'au moment où nous serons assez satisfaits
  88.399 -pour décider d'enregistrer notre travail dans un \textit{changeset}.
  88.400 -
  88.401 -La commande \hgcmd{commit} vous laisse créer un nouveau \textit{changeset},
  88.402 -nous désignerons généralement cette opération par ``faire un commit'' ou
  88.403 -``commiter''\footnote{NdT: De mon expérience, la plupart des francophones 
  88.404 -utilisent  régulièrement, à l'oral, cette expression, mais bien évidement
  88.405 -il ne s'agit pas d'un terme de terminologie correcte, ni même français.}
  88.406 -
  88.407 -\subsection{Définir le nom d'utilisateur}
  88.408 -
  88.409 -Quand vous exécutez la commande \hgcmd{commit} pour la première fois, elle
  88.410 -n'est pas garantie de réussir. Mercurial enregistre votre nom et votre 
  88.411 -adresse avec chaque modification que vous effectuez, de manière à ce que
  88.412 -vous soyez capable (ou d'autres le soient) de savoir qui a fait quelle
  88.413 -modification. Mercurial essaye automatiquement de découvrir un nom 
  88.414 -d'utilisateur qui ait un minimum de sens pour effectuer l'opération
  88.415 -de \textit{commit} avec. Il va essayer chacune des méthodes suivantes,
  88.416 -dans l'ordre:
  88.417 -\begin{enumerate}
  88.418 -\item Si vous spécifiez l'option \hgopt{commit}{-u} avec la commande 
  88.419 -  \hgcmd{commit}, suivi d'un nom d'utilisateur, ceci aura toujours la 
  88.420 -  priorité sur les autres méthodes ci dessous.
  88.421 -\item Si vous avez défini une variable d'environnement \envar{HGUSER}, 
  88.422 -  c'est cette valeur qui est alors utilisée.
  88.423 -\item Si vous créez un fichier nommé \sfilename{.hgrc} dans votre 
  88.424 -   répertoire \textit{home}, avec une entrée \rcitem{ui}{username}, 
  88.425 -   c'est la valeur associée qui sera utilisée. Pour voir à quoi 
  88.426 -   ressemble le contenu de ce fichier regardez la 
  88.427 -   section~\ref{sec:tour-basic:username} ci-dessous.
  88.428 -\item Si vous avez défini une variable d'environnement \envar{EMAIL}
  88.429 -  celle ci sera utilisée ensuite.
  88.430 -\item Enfin, Mercurial interrogera votre système pour trouver votre
  88.431 -  nom d'utilisateur local ainsi que le nom de la machine hôte, et il 
  88.432 -  fabriquera un nom d'utilisateur à partir de ces données. Comme il arrive
  88.433 -  souvent que ce genre de noms soit totalement inutile, il vous 
  88.434 -  préviendra en affichant un message d'avertissement.
  88.435 -\end{enumerate}
  88.436 -
  88.437 -Si tous ces mécanismes échouent, Mercurial n'exécutera pas la commande,
  88.438 -affichant un message d'erreur. Dans ce cas, il ne vous laissera pas 
  88.439 -effectuer de \textit{commit} tant que vous n'aurez pas défini un nom
  88.440 -d'utilisateur.
  88.441 -
  88.442 -Vous devriez penser à utiliser la variable d'environement \envar{HGUSER} 
  88.443 -et l'option \hgopt{commit}{-u} comme moyen pour \emph{changer le nom
  88.444 -d'utilisateur} par défaut. Pour une utilisation normale, la manière la plus
  88.445 -simple et robuste d'opérer est de créer un fichier \sfilename{.hgrc},
  88.446 -voir ci-dessous pour les détails à ce sujet.
  88.447 -
  88.448 -\subsubsection{Créer un fichier de configuration pour Mercurial}
  88.449 -\label{sec:tour-basic:username}
  88.450 -
  88.451 -Pour définir un nom d'utilisateur, utilisez votre éditeur de texte favori
  88.452 -pour créer un fichier \sfilename{.hgrc} dans votre répertoire \textit{home}.
  88.453 -Mercurial va utiliser ce fichier pour retrouver votre configuration personnelle.
  88.454 -Le contenu initial devrait ressembler à ceci:
  88.455 -\begin{codesample2}
  88.456 -  # This is a Mercurial configuration file.
  88.457 -  [ui]
  88.458 -  username = Firstname Lastname <email.address@domain.net>
  88.459 -\end{codesample2}
  88.460 -La ligne avec \texttt{[ui]} commence une \emph{section} du fichier de
  88.461 -configuration, ainsi la ligne ``\texttt{username = ...}'' signifie ``
  88.462 -définir la valeur de l'élément \texttt{username} dans la section 
  88.463 -\texttt{ui}''. Une section continue jusqu'à ce qu'une nouvelle 
  88.464 -commence, ou que la fin du fichier soit atteinte. Mercurial ignore
  88.465 -les lignes vides et traite tout texte situé à la suite d'un  
  88.466 -``\texttt{\#}'' jusqu'à la fin de la ligne comme un commentaire.
  88.467 -
  88.468 -\subsubsection{Choisir un nom d'utilisateur}
  88.469 -
  88.470 -Vous pouvez utiliser n'importe quelle valeur pour votre \texttt{username},
  88.471 -car cette information est destinée à d'autres personnes et non à être
  88.472 -interprétée par Mercurial. La convention que la plupart des personnes
  88.473 -<<<<<<< local
  88.474 -suivent est d'utiliser leurs noms suivies de leurs adresses emails,
  88.475 -comme montrée ci-dessus:
  88.476 -
  88.477 -\begin{note}
  88.478 -  Le mécanisme interne du serveur \textit{web} intégré à Mercurial,
  88.479 -  masque les adresses emails, pour rendre plus difficile leurs
  88.480 -  récupérations par les outils utilisés par les \textit{spammmers}.
  88.481 -  Ceci réduit la probabilité que de recevoir encore plus de 
  88.482 -  \textit{spam} si vous vous publiez un dépôt sur internet.
  88.483 -\end{note}
  88.484 -
  88.485 -\subsection{Rédiger un message de \textit{commit}}
  88.486 -
  88.487 -Lorsqu'on effectue une opération de \textit{commit}, Mercurial 
  88.488 -lance automatiquement un éditeur de texte pour permettre de saisir
  88.489 -un message qui décrira les modifications effectuées dans ce 
  88.490 -\textit{changeset}. Ce message est nommé le \emph{message de 
  88.491 -\textit{commit}}. Ce sera un enregistrement pour tout lecteur 
  88.492 -expliquant le pourquoi et le comment de vos modifications, et il sera
  88.493 -affiché par la commande \hgcmd{log}.
  88.494 -\interaction{tour.commit}
  88.495 -
  88.496 -L'éditeur que la commande \hgcmd{commit} déclenche ne contiendra
  88.497 -qu'une ligne vide suivi d'un certain nombre de lignes commençant
  88.498 -par ``\texttt{HG:}''.
  88.499 -\begin{codesample2}
  88.500 -  \emph{empty line}
  88.501 -  HG: changed hello.c
  88.502 -\end{codesample2}
  88.503 -Mercurial ignore les lignes qui commencent avec ``\texttt{HG:}'', il 
  88.504 -ne les utilise que pour nous indiquer quels fichiers modifiés il se 
  88.505 -prépare à \textit{commiter}. Modifier ou effacer ces lignes n'a 
  88.506 -aucune conséquence sur l'opération de \textit{commit}.
  88.507 -
  88.508 -\subsection{Rédiger un message \textit{approprié}}
  88.509 -
  88.510 -Comme \hgcmd{log} n'affiche que la première ligne du message de
  88.511 -\textit{commit} par défaut, il est souvent considéré comme une bonne
  88.512 -pratique de rédiger des messages de \textit{commit} qui tiennent
  88.513 -sur une seule ligne. Voilà un exemple concret de message de 
  88.514 -\textit{commit} qui \emph{ne suit pas} cette directive, et qui a donc
  88.515 -un résumé peu lisible.
  88.516 -
  88.517 -\begin{codesample2}
  88.518 -  changeset:   73:584af0e231be
  88.519 -  user:        Censored Person <censored.person@example.org>
  88.520 -  date:        Tue Sep 26 21:37:07 2006 -0700
  88.521 -  summary:     include buildmeister/commondefs.   Add an exports and install
  88.522 -\end{codesample2}
  88.523 -
  88.524 -A ce sujet, il faut noter qu'il n'existe pas de règle absolue dans ce 
  88.525 -domaine. Mercurial lui-même n'interprète pas les contenus des messages
  88.526 -de \textit{commit}, ainsi votre projet est libre de concevoir différentes
  88.527 -politiques de mise en page des messages.
  88.528 -
  88.529 -Ma préférence personnelle va au message court, mais informatif, qui offre
  88.530 -des précisions supplémentaires par rapport à ce que pourrait m'apprendre une commande
  88.531 -\hgcmdargs{log}{--patch}.
  88.532 -
  88.533 -\subsection{Annuler un \textit{commit}}
  88.534 -
  88.535 -Si, en rédigeant le message, vous décidez que finalement vous ne 
  88.536 -voulez pas effectuer ce \textit{commit}, il suffit de quitter simplement
  88.537 -l'éditeur sans sauver. Ceci n'aura aucune conséquence sur le dépôt ou
  88.538 -les fichiers de l'espace de travail.
  88.539 -
  88.540 -Si vous exécuter la commande \hgcmd{commit} sans aucun argument, elle
  88.541 -enregistre toutes les modifications que vous avez faites, comme le montre
  88.542 -les commandes \hgcmd{status} et \hgcmd{diff}.
  88.543 -
  88.544 -\subsection{Admirer votre travail}
  88.545 -
  88.546 -Une fois que votre \textit{commit} est terminé, vous pouvez utiliser
  88.547 -la commande \hgcmd{tip} pour afficher le \textit{changeset} que nous
  88.548 -venons de créer. Cette commande produit une sortie à l'écran qui est
  88.549 -identique à celle du \hgcmd{log}, mais qui n'affiche que la dernière
  88.550 -révision du dépôt.
  88.551 -\interaction{tour.tip}
  88.552 -On fait couramment référence à la dernière révision du dépôt comme
  88.553 -étant la révision \textit{tip}, ou plus simplement le \textit{tip}.
  88.554 -
  88.555 -\section{Partager ses modifications}
  88.556 -
  88.557 -Nous avons mentionné plus haut que les dépôts de Mercurial 
  88.558 -sont autosuffisants. Ce qui signifie que le \textit{changeset} 
  88.559 -que vous venez de créer existe seulement dans votre répertoire 
  88.560 -\dirname{my-hello}. Étudions comment propager cette modification
  88.561 -dans d'autres dépôts.
  88.562 -
  88.563 -\subsection{Récupérer les modifications d'autres dépôts}
  88.564 -\label{sec:tour:pull}
  88.565 -
  88.566 -Pour commencer, construisons un clone de notre dépôt \dirname{hello} 
  88.567 -qui ne contiendra pas le changement que nous venons d'effectuer. Nous
  88.568 -l'appellerons notre dépôt temporaire \dirname{hello-pull}.
  88.569 -
  88.570 -\interaction{tour.clone-pull}
  88.571 -
  88.572 -Nous allons utiliser la commande \hgcmd{pull} pour apporter les 
  88.573 -modifications depuis \dirname{my-hello} dans \dirname{hello-pull}.
  88.574 -Néanmoins, récupérer aveuglement des modifications depuis un dépôt
  88.575 -a quelque chose d'un peu effrayant. Mercurial propose donc une 
  88.576 -commande \hgcmd{incoming} qui permet de savoir quelles modifications
  88.577 -la commande \hgcmd{pull} \emph{pourrait} entraîner dans notre dépôt,
  88.578 -et ceci sans effectuer réellement de modification dessus.
  88.579 -\interaction{tour.incoming}
  88.580 -(Bien évidement, quelqu'un pourrait ajouter des modifications
  88.581 -supplémentaires sur le dépôt que nous étudions avec \hgcmd{incoming},
  88.582 -avant que nous ayons effectué notre \hgcmd{pull}, avec comme 
  88.583 -triste conséquence que nous aurons récupéré des modifications que 
  88.584 -nous n'attendions pas.)
  88.585 -
  88.586 -Apporter les modifications rapatriées dans un dépôt se résume donc
  88.587 -à exécuter la commande \hgcmd{pull}, et préciser depuis quel dépôt 
  88.588 -effectuer le \hgcmd{pull}.
  88.589 -\interaction{tour.pull}
  88.590 -
  88.591 -Comme vous le voyez avec une sortie avant et après de la commande
  88.592 -\hgcmd{tip}, nous avons réussi à récupérer aisément les modifications
  88.593 -dans notre dépôt. Il reste néanmoins quelque chose à faire avant de
  88.594 -placer ces modifications dans l'espace de travail.
  88.595 -
  88.596 -\subsection{Mise à jour de l'espace de travail}
  88.597 -
  88.598 -Nous avons jusqu'à maintenant grossièrement définie la relation 
  88.599 -entre un dépôt et un espace de travail. La commande \hgcmd{pull} que
  88.600 -nous avons exécutée dans la section~\ref{sec:tour:pull} a apporté
  88.601 -des modifications, que nous avons vérifiées, dans notre dépôt, mais
  88.602 -il n'y a aucune trace de ces modifications dans notre espace de travail.
  88.603 -En effet, \hgcmd{pull} ne touche pas (par défaut) à l'espace de 
  88.604 -travail. C'est la commande \hgcmd{update} qui s'en charge.
  88.605 -\interaction{tour.update}
  88.606 -
  88.607 -Il peut sembler un peu étrange que la commande \hgcmd{pull} ne mette
  88.608 -pas à jour l'espace de travail automatiquement. Il y a en fait une
  88.609 -très bonne raison à cela : vous pouvez utilisez la commande 
  88.610 -
  88.611 -\hgcmd{update} pour mettre à jour votre espace de travail à l'état
  88.612 -dans lequel il était à \emph{n'importe quelle révision} de l'historique
  88.613 -du dépôt. Si vous aviez un espace de travail contenant une ancienne
  88.614 -révision---pour chercher l'origine d'un \textit{bug}, par exemple---et
  88.615 -que vous effectuiez un \hgcmd{pull} qui mettrait à jour automatiquement
  88.616 -votre espace de travail, vous ne seriez probablement pas très satisfait.
  88.617 -
  88.618 -Néanmoins, comme les opérations de \textit{pull} sont très souvent
  88.619 -suivies d'un \textit{update}, Mercurial vous permet de combiner les
  88.620 -deux aisément en passant l'option \hgopt{pull}{-u} à la commande
  88.621 -\hgcmd{pull}
  88.622 -\begin{codesample2}
  88.623 -  hg pull -u
  88.624 -\end{codesample2}
  88.625 -
  88.626 -Si vous étudiez de nouveau la sortie de la commande \hgcmd{pull} dans
  88.627 -la section~\ref{sec:tour:pull} quand nous l'avons exécutée sans l'option
  88.628 -\hgopt{pull}{-u}, vous pouvez constater qu'elle a affiché un rappel assez
  88.629 -utile : vous devez encore effectuer une opération pour mettre à jour
  88.630 -votre espace de travail:
  88.631 -
  88.632 -\begin{codesample2}
  88.633 -  (run 'hg update' to get a working copy)
  88.634 -\end{codesample2}
  88.635 -
  88.636 -Pour découvrir sur quelle révision de l'espace de travail on est, utilisez
  88.637 -la commande \hgcmd{parents}. 
  88.638 -\interaction{tour.parents}
  88.639 -Si vous regardez de nouveau le dessin~\ref{fig:tour-basic:history}, vous
  88.640 -<<<<<<< local
  88.641 -verrez les flèches reliant entre eux les \textit{changeset}. Le nœud 
  88.642 -d'où la flèche \emph{part} est dans chaque cas un parent, 
  88.643 -et le nœud où la flèche \emph{arrive} est un enfant. 
  88.644 -
  88.645 -L'espace de travail a un parent de la même manière, c'est ce \textit{changeset} 
  88.646 -que l'espace de travail contient à ce moment.
  88.647 -%%%TODO : difficile à comprendre : l'espace de travail a un parent, de la même manière, c'est ce changeset que l'espace...
  88.648 -
  88.649 -Pour mettre à jour l'espace de travail d'une révision particulière, 
  88.650 -indiquez un numéro de révision ou un \textit{changeset~ID} à la commande 
  88.651 -\hgcmd{update}.
  88.652 -\interaction{tour.older}
  88.653 -Si vous ne précisez pas de manière explicite de numéro de révision
  88.654 -la commande \hgcmd{update} mettra à jour votre espace de travail avec
  88.655 -le contenu de la révsion \textit{tip}, comme montré dans l'exemple 
  88.656 -ci dessus lors du second appel à \hgcmd{update}.
  88.657 -
  88.658 -\subsection{Transférer les modifications à un autre dépôt}
  88.659 -
  88.660 -Mercurial vous laisse transférer les modifications à un autre
  88.661 -dépôt, depuis votre dépôt actuel. Comme dans l'exemple du 
  88.662 -\hgcmd{pull} ci-dessus, nous allons créer un dépôt temporaire
  88.663 -vers lequel transférer\footnote{NdT: Les francophones disent souvent 
  88.664 -``pousser'' tout simplement} nos modifications.
  88.665 -\interaction{tour.clone-push}
  88.666 -La commande \hgcmd{outgoing} nous indique quels changements nous
  88.667 -allons transférer vers l'autre serveur ?
  88.668 -\interaction{tour.outgoing}
  88.669 -Et la commande \hgcmd{push} effectue réellement le transfert.
  88.670 -\interaction{tour.push}
  88.671 -Comme avec \hgcmd{pull}, la commande \hgcmd{push} ne met pas à jour
  88.672 -le répertoire de travail du dépôt dans lequel il transfère les 
  88.673 -modifications. (À l'inverse de \hgcmd{pull}, \hgcmd{push} ne fournit
  88.674 -pas d'option \texttt{-u} pour forcer la mise à jour de l'espace
  88.675 -de travail cible).
  88.676 -
  88.677 -Qu'est ce qui se passe lorsque vous essayez de récupérer ou de transférer
  88.678 -vos modifications et que le dépôt cible a déjà reçu ces modifications ? 
  88.679 -Rien de bien excitant.
  88.680 -\interaction{tour.push.nothing}
  88.681 -
  88.682 -\subsection{Partager ses modifications à travers le réseau}
  88.683 -
  88.684 -Les commandes que nous avons étudiées dans les sections précédentes
  88.685 -ne sont pas limitées aux dépôt locaux. Chacune fonctionne de la même
  88.686 -manière à travers une connexion réseau, il suffit de lui passer une 
  88.687 -URL à la place d'un chemin de fichier local.
  88.688 -
  88.689 -\interaction{tour.outgoing.net}
  88.690 -Dans cet exemple, nous allons voir quels changements nous pourrions
  88.691 -transférer vers le dépôt distant, mais le dépôt est, de manière tout
  88.692 -à fait compréhensible, pas configuré pour accepter des modifications
  88.693 -d'utilisateurs anonymes.
  88.694 -\interaction{tour.push.net}
  88.695 -
  88.696 -%%% Local Variables: 
  88.697 -%%% mode: latex
  88.698 -%%% TeX-master: "00book"
  88.699 -%%% End: 
    89.1 --- a/fr/tour-history.svg	Sun Aug 16 03:41:39 2009 +0200
    89.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.3 @@ -1,289 +0,0 @@
    89.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    89.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    89.6 -<svg
    89.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    89.8 -   xmlns:cc="http://web.resource.org/cc/"
    89.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   89.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   89.11 -   xmlns="http://www.w3.org/2000/svg"
   89.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   89.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   89.14 -   width="744.09448819"
   89.15 -   height="1052.3622047"
   89.16 -   id="svg2"
   89.17 -   sodipodi:version="0.32"
   89.18 -   inkscape:version="0.44.1"
   89.19 -   sodipodi:docname="tour-history.svg">
   89.20 -  <defs
   89.21 -     id="defs4">
   89.22 -    <marker
   89.23 -       inkscape:stockid="Arrow1Mstart"
   89.24 -       orient="auto"
   89.25 -       refY="0.0"
   89.26 -       refX="0.0"
   89.27 -       id="Arrow1Mstart"
   89.28 -       style="overflow:visible">
   89.29 -      <path
   89.30 -         id="path2973"
   89.31 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   89.32 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   89.33 -         transform="scale(0.4) translate(10,0)" />
   89.34 -    </marker>
   89.35 -    <marker
   89.36 -       inkscape:stockid="Arrow1Mend"
   89.37 -       orient="auto"
   89.38 -       refY="0.0"
   89.39 -       refX="0.0"
   89.40 -       id="Arrow1Mend"
   89.41 -       style="overflow:visible;">
   89.42 -      <path
   89.43 -         id="path3066"
   89.44 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   89.45 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   89.46 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   89.47 -    </marker>
   89.48 -  </defs>
   89.49 -  <sodipodi:namedview
   89.50 -     id="base"
   89.51 -     pagecolor="#ffffff"
   89.52 -     bordercolor="#666666"
   89.53 -     borderopacity="1.0"
   89.54 -     gridtolerance="10000"
   89.55 -     guidetolerance="10"
   89.56 -     objecttolerance="10"
   89.57 -     inkscape:pageopacity="0.0"
   89.58 -     inkscape:pageshadow="2"
   89.59 -     inkscape:zoom="1.4"
   89.60 -     inkscape:cx="232.14286"
   89.61 -     inkscape:cy="672.75296"
   89.62 -     inkscape:document-units="px"
   89.63 -     inkscape:current-layer="layer1"
   89.64 -     inkscape:window-width="906"
   89.65 -     inkscape:window-height="620"
   89.66 -     inkscape:window-x="5"
   89.67 -     inkscape:window-y="49" />
   89.68 -  <metadata
   89.69 -     id="metadata7">
   89.70 -    <rdf:RDF>
   89.71 -      <cc:Work
   89.72 -         rdf:about="">
   89.73 -        <dc:format>image/svg+xml</dc:format>
   89.74 -        <dc:type
   89.75 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   89.76 -      </cc:Work>
   89.77 -    </rdf:RDF>
   89.78 -  </metadata>
   89.79 -  <g
   89.80 -     inkscape:label="Layer 1"
   89.81 -     inkscape:groupmode="layer"
   89.82 -     id="layer1">
   89.83 -    <rect
   89.84 -       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   89.85 -       id="rect1878"
   89.86 -       width="94.285713"
   89.87 -       height="20.714285"
   89.88 -       x="138"
   89.89 -       y="479.50504" />
   89.90 -    <text
   89.91 -       xml:space="preserve"
   89.92 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   89.93 -       x="162.09892"
   89.94 -       y="493.12619"
   89.95 -       id="text1872"><tspan
   89.96 -         sodipodi:role="line"
   89.97 -         id="tspan1874"
   89.98 -         x="162.09892"
   89.99 -         y="493.12619"
  89.100 -         style="font-family:Courier"><tspan
  89.101 -   style="font-weight:bold"
  89.102 -   id="tspan1876">0</tspan>: REV0</tspan></text>
  89.103 -    <rect
  89.104 -       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  89.105 -       id="rect2800"
  89.106 -       width="94.285713"
  89.107 -       height="20.714285"
  89.108 -       x="138"
  89.109 -       y="432.63004" />
  89.110 -    <text
  89.111 -       xml:space="preserve"
  89.112 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  89.113 -       x="162.09892"
  89.114 -       y="446.25119"
  89.115 -       id="text2794"><tspan
  89.116 -         sodipodi:role="line"
  89.117 -         id="tspan2796"
  89.118 -         x="162.09892"
  89.119 -         y="446.25119"
  89.120 -         style="font-family:Courier"><tspan
  89.121 -   id="tspan2868"
  89.122 -   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  89.123 -    <rect
  89.124 -       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  89.125 -       id="rect2810"
  89.126 -       width="94.285713"
  89.127 -       height="20.714285"
  89.128 -       x="138"
  89.129 -       y="385.75504" />
  89.130 -    <text
  89.131 -       xml:space="preserve"
  89.132 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  89.133 -       x="162.09892"
  89.134 -       y="399.37619"
  89.135 -       id="text2804"><tspan
  89.136 -         sodipodi:role="line"
  89.137 -         id="tspan2806"
  89.138 -         x="162.09892"
  89.139 -         y="399.37619"
  89.140 -         style="font-family:Courier"><tspan
  89.141 -   style="font-weight:bold"
  89.142 -   id="tspan2866">2</tspan>: REV2</tspan></text>
  89.143 -    <rect
  89.144 -       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  89.145 -       id="rect2820"
  89.146 -       width="94.285713"
  89.147 -       height="20.714285"
  89.148 -       x="138"
  89.149 -       y="338.88007" />
  89.150 -    <text
  89.151 -       xml:space="preserve"
  89.152 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  89.153 -       x="162.09892"
  89.154 -       y="352.50122"
  89.155 -       id="text2814"><tspan
  89.156 -         sodipodi:role="line"
  89.157 -         id="tspan2816"
  89.158 -         x="162.09892"
  89.159 -         y="352.50122"
  89.160 -         style="font-family:Courier"><tspan
  89.161 -   style="font-weight:bold"
  89.162 -   id="tspan2864">3</tspan>: REV3</tspan></text>
  89.163 -    <rect
  89.164 -       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  89.165 -       id="rect2830"
  89.166 -       width="94.285713"
  89.167 -       height="20.714285"
  89.168 -       x="138"
  89.169 -       y="292.00504" />
  89.170 -    <text
  89.171 -       xml:space="preserve"
  89.172 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  89.173 -       x="162.09892"
  89.174 -       y="305.62619"
  89.175 -       id="text2824"><tspan
  89.176 -         sodipodi:role="line"
  89.177 -         id="tspan2826"
  89.178 -         x="162.09892"
  89.179 -         y="305.62619"
  89.180 -         style="font-family:Courier"><tspan
  89.181 -   style="font-weight:bold"
  89.182 -   id="tspan2862">4</tspan>: REV4</tspan></text>
  89.183 -    <text
  89.184 -       xml:space="preserve"
  89.185 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  89.186 -       x="173.57143"
  89.187 -       y="443.79074"
  89.188 -       id="text2832"><tspan
  89.189 -         sodipodi:role="line"
  89.190 -         id="tspan2834"
  89.191 -         x="173.57143"
  89.192 -         y="443.79074" /></text>
  89.193 -    <path
  89.194 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  89.195 -       d="M 185.14286,478.50504 L 185.14286,454.34432"
  89.196 -       id="path2894"
  89.197 -       inkscape:connector-type="polyline" />
  89.198 -    <path
  89.199 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  89.200 -       d="M 185.14286,431.63004 L 185.14286,407.46932"
  89.201 -       id="path2896"
  89.202 -       inkscape:connector-type="polyline" />
  89.203 -    <path
  89.204 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  89.205 -       d="M 185.14286,384.75504 L 185.14286,360.59435"
  89.206 -       id="path2898"
  89.207 -       inkscape:connector-type="polyline" />
  89.208 -    <path
  89.209 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
  89.210 -       d="M 185.14286,337.88007 L 185.14286,313.71932"
  89.211 -       id="path2900"
  89.212 -       inkscape:connector-type="polyline" />
  89.213 -    <text
  89.214 -       xml:space="preserve"
  89.215 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  89.216 -       x="244.60992"
  89.217 -       y="305.245"
  89.218 -       id="text1902"><tspan
  89.219 -         sodipodi:role="line"
  89.220 -         id="tspan1904"
  89.221 -         x="244.60992"
  89.222 -         y="305.245">(newest)</tspan></text>
  89.223 -    <text
  89.224 -       xml:space="preserve"
  89.225 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  89.226 -       x="244.60992"
  89.227 -       y="492.745"
  89.228 -       id="text1906"><tspan
  89.229 -         sodipodi:role="line"
  89.230 -         id="tspan1908"
  89.231 -         x="244.60992"
  89.232 -         y="492.745">(oldest)</tspan></text>
  89.233 -    <rect
  89.234 -       style="opacity:1;fill:#d2e1e4;fill-opacity:1;stroke:#b1cbd0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  89.235 -       id="rect1907"
  89.236 -       width="94.285713"
  89.237 -       height="20.714285"
  89.238 -       x="309.28571"
  89.239 -       y="324.86218" />
  89.240 -    <text
  89.241 -       xml:space="preserve"
  89.242 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  89.243 -       x="333.38464"
  89.244 -       y="338.48334"
  89.245 -       id="text1909"><tspan
  89.246 -         sodipodi:role="line"
  89.247 -         id="tspan1911"
  89.248 -         x="333.38464"
  89.249 -         y="338.48334"
  89.250 -         style="font-family:Courier"><tspan
  89.251 -   style="font-weight:bold"
  89.252 -   id="tspan1913">4</tspan>: REV4</tspan></text>
  89.253 -    <path
  89.254 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  89.255 -       d="M 332.14286,375.21932 L 335.71429,347.36218"
  89.256 -       id="path2802" />
  89.257 -    <path
  89.258 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  89.259 -       d="M 372.69968,375.21932 L 369.12825,347.36218"
  89.260 -       id="path2986" />
  89.261 -    <text
  89.262 -       xml:space="preserve"
  89.263 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  89.264 -       x="335.14285"
  89.265 -       y="387.21933"
  89.266 -       id="text2988"><tspan
  89.267 -         sodipodi:role="line"
  89.268 -         x="335.14285"
  89.269 -         y="387.21933"
  89.270 -         id="tspan3020"
  89.271 -         style="text-align:end;text-anchor:end">revision</tspan><tspan
  89.272 -         sodipodi:role="line"
  89.273 -         x="335.14285"
  89.274 -         y="402.21933"
  89.275 -         id="tspan3014"
  89.276 -         style="text-align:end;text-anchor:end">number</tspan></text>
  89.277 -    <text
  89.278 -       xml:space="preserve"
  89.279 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
  89.280 -       x="368.71429"
  89.281 -       y="387.21933"
  89.282 -       id="text2994"><tspan
  89.283 -         sodipodi:role="line"
  89.284 -         id="tspan2996"
  89.285 -         x="368.71429"
  89.286 -         y="387.21933">changeset</tspan><tspan
  89.287 -         sodipodi:role="line"
  89.288 -         x="368.71429"
  89.289 -         y="402.21933"
  89.290 -         id="tspan2998">identifier</tspan></text>
  89.291 -  </g>
  89.292 -</svg>
    90.1 --- a/fr/tour-merge-conflict.svg	Sun Aug 16 03:41:39 2009 +0200
    90.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.3 @@ -1,210 +0,0 @@
    90.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    90.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    90.6 -<svg
    90.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    90.8 -   xmlns:cc="http://web.resource.org/cc/"
    90.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   90.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   90.11 -   xmlns="http://www.w3.org/2000/svg"
   90.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   90.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   90.14 -   width="744.09448819"
   90.15 -   height="1052.3622047"
   90.16 -   id="svg2"
   90.17 -   sodipodi:version="0.32"
   90.18 -   inkscape:version="0.44.1"
   90.19 -   sodipodi:docname="tour-merge-conflict.svg">
   90.20 -  <defs
   90.21 -     id="defs4">
   90.22 -    <marker
   90.23 -       inkscape:stockid="Arrow1Mend"
   90.24 -       orient="auto"
   90.25 -       refY="0.0"
   90.26 -       refX="0.0"
   90.27 -       id="Arrow1Mend"
   90.28 -       style="overflow:visible;">
   90.29 -      <path
   90.30 -         id="path3053"
   90.31 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   90.32 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   90.33 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   90.34 -    </marker>
   90.35 -  </defs>
   90.36 -  <sodipodi:namedview
   90.37 -     id="base"
   90.38 -     pagecolor="#ffffff"
   90.39 -     bordercolor="#666666"
   90.40 -     borderopacity="1.0"
   90.41 -     gridtolerance="10000"
   90.42 -     guidetolerance="10"
   90.43 -     objecttolerance="10"
   90.44 -     inkscape:pageopacity="0.0"
   90.45 -     inkscape:pageshadow="2"
   90.46 -     inkscape:zoom="1.4"
   90.47 -     inkscape:cx="164.78349"
   90.48 -     inkscape:cy="590.07679"
   90.49 -     inkscape:document-units="px"
   90.50 -     inkscape:current-layer="layer1"
   90.51 -     inkscape:window-width="906"
   90.52 -     inkscape:window-height="620"
   90.53 -     inkscape:window-x="5"
   90.54 -     inkscape:window-y="49" />
   90.55 -  <metadata
   90.56 -     id="metadata7">
   90.57 -    <rdf:RDF>
   90.58 -      <cc:Work
   90.59 -         rdf:about="">
   90.60 -        <dc:format>image/svg+xml</dc:format>
   90.61 -        <dc:type
   90.62 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   90.63 -      </cc:Work>
   90.64 -    </rdf:RDF>
   90.65 -  </metadata>
   90.66 -  <g
   90.67 -     inkscape:label="Layer 1"
   90.68 -     inkscape:groupmode="layer"
   90.69 -     id="layer1">
   90.70 -    <g
   90.71 -       id="g1988"
   90.72 -       transform="translate(84.85711,0)">
   90.73 -      <g
   90.74 -         id="g1876">
   90.75 -        <path
   90.76 -           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   90.77 -           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
   90.78 -           id="path1872"
   90.79 -           sodipodi:nodetypes="cccccc" />
   90.80 -        <path
   90.81 -           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
   90.82 -           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
   90.83 -           id="path1874"
   90.84 -           sodipodi:nodetypes="cccc" />
   90.85 -      </g>
   90.86 -      <flowRoot
   90.87 -         style="font-size:8px;font-family:Times New Roman"
   90.88 -         id="flowRoot1898"
   90.89 -         xml:space="preserve"><flowRegion
   90.90 -           id="flowRegion1900"><rect
   90.91 -             style="font-size:8px;font-family:Times New Roman"
   90.92 -             y="464.50504"
   90.93 -             x="122.85714"
   90.94 -             height="93.571426"
   90.95 -             width="76.428574"
   90.96 -             id="rect1902" /></flowRegion><flowPara
   90.97 -           id="flowPara1904">Greetings!</flowPara><flowPara
   90.98 -           id="flowPara1906" /><flowPara
   90.99 -           id="flowPara1908">I am Mariam Abacha, the wife of former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
  90.100 -    <g
  90.101 -       id="g1966"
  90.102 -       transform="translate(82,0.35715)">
  90.103 -      <g
  90.104 -         transform="translate(-77.85718,-140.0714)"
  90.105 -         id="g1910">
  90.106 -        <path
  90.107 -           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  90.108 -           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
  90.109 -           id="path1912"
  90.110 -           sodipodi:nodetypes="cccccc" />
  90.111 -        <path
  90.112 -           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  90.113 -           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
  90.114 -           id="path1914"
  90.115 -           sodipodi:nodetypes="cccc" />
  90.116 -      </g>
  90.117 -      <flowRoot
  90.118 -         transform="translate(-77.85718,-140.0714)"
  90.119 -         style="font-size:8px;font-family:Times New Roman"
  90.120 -         id="flowRoot1916"
  90.121 -         xml:space="preserve"><flowRegion
  90.122 -           id="flowRegion1918"><rect
  90.123 -             style="font-size:8px;font-family:Times New Roman"
  90.124 -             y="464.50504"
  90.125 -             x="122.85714"
  90.126 -             height="93.571426"
  90.127 -             width="76.428574"
  90.128 -             id="rect1920" /></flowRegion><flowPara
  90.129 -           id="flowPara1922">Greetings!</flowPara><flowPara
  90.130 -           id="flowPara1924" /><flowPara
  90.131 -           id="flowPara1926">I am <flowSpan
  90.132 -   style="font-style:italic;fill:red"
  90.133 -   id="flowSpan3094">Shehu Musa Abacha, cousin to</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
  90.134 -    <g
  90.135 -       id="g1977"
  90.136 -       transform="translate(81.99999,-0.35715)">
  90.137 -      <g
  90.138 -         transform="translate(83.57141,-139.3571)"
  90.139 -         id="g1932">
  90.140 -        <path
  90.141 -           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  90.142 -           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
  90.143 -           id="path1934"
  90.144 -           sodipodi:nodetypes="cccccc" />
  90.145 -        <path
  90.146 -           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  90.147 -           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
  90.148 -           id="path1936"
  90.149 -           sodipodi:nodetypes="cccc" />
  90.150 -      </g>
  90.151 -      <flowRoot
  90.152 -         transform="translate(83.57141,-139.3571)"
  90.153 -         style="font-size:8px;font-family:Times New Roman"
  90.154 -         id="flowRoot1938"
  90.155 -         xml:space="preserve"><flowRegion
  90.156 -           id="flowRegion1940"><rect
  90.157 -             style="font-size:8px;font-family:Times New Roman"
  90.158 -             y="464.50504"
  90.159 -             x="122.85714"
  90.160 -             height="93.571426"
  90.161 -             width="76.428574"
  90.162 -             id="rect1942" /></flowRegion><flowPara
  90.163 -           id="flowPara1944">Greetings!</flowPara><flowPara
  90.164 -           id="flowPara1946" /><flowPara
  90.165 -           id="flowPara1948">I am <flowSpan
  90.166 -   style="font-style:italic;fill:red"
  90.167 -   id="flowSpan3096">Alhaji Abba Abacha, son of</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
  90.168 -    <path
  90.169 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  90.170 -       d="M 215.502,457.71933 L 196.35507,424.5765"
  90.171 -       id="path1999"
  90.172 -       inkscape:connector-type="polyline"
  90.173 -       inkscape:connection-start="#g1988"
  90.174 -       inkscape:connection-end="#g1966" />
  90.175 -    <path
  90.176 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  90.177 -       d="M 277.06936,457.71933 L 296.21629,424.5765"
  90.178 -       id="path2001"
  90.179 -       inkscape:connector-type="polyline"
  90.180 -       inkscape:connection-start="#g1988"
  90.181 -       inkscape:connection-end="#g1977" />
  90.182 -    <text
  90.183 -       xml:space="preserve"
  90.184 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  90.185 -       x="302.42859"
  90.186 -       y="515.08905"
  90.187 -       id="text1905"><tspan
  90.188 -         sodipodi:role="line"
  90.189 -         id="tspan1907"
  90.190 -         x="302.42859"
  90.191 -         y="515.08905">Base version</tspan></text>
  90.192 -    <text
  90.193 -       xml:space="preserve"
  90.194 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  90.195 -       x="45.57143"
  90.196 -       y="374.1619"
  90.197 -       id="text1917"><tspan
  90.198 -         sodipodi:role="line"
  90.199 -         id="tspan1919"
  90.200 -         x="45.57143"
  90.201 -         y="374.1619">Our changes</tspan></text>
  90.202 -    <text
  90.203 -       xml:space="preserve"
  90.204 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  90.205 -       x="385.71429"
  90.206 -       y="374.1619"
  90.207 -       id="text1921"><tspan
  90.208 -         sodipodi:role="line"
  90.209 -         id="tspan1923"
  90.210 -         x="385.71429"
  90.211 -         y="374.1619">Their changes</tspan></text>
  90.212 -  </g>
  90.213 -</svg>
    91.1 --- a/fr/tour-merge-merge.svg	Sun Aug 16 03:41:39 2009 +0200
    91.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.3 @@ -1,380 +0,0 @@
    91.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    91.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    91.6 -<svg
    91.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    91.8 -   xmlns:cc="http://web.resource.org/cc/"
    91.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   91.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   91.11 -   xmlns="http://www.w3.org/2000/svg"
   91.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   91.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   91.14 -   width="744.09448819"
   91.15 -   height="1052.3622047"
   91.16 -   id="svg2"
   91.17 -   sodipodi:version="0.32"
   91.18 -   inkscape:version="0.44.1"
   91.19 -   sodipodi:docname="tour-merge-merge.svg">
   91.20 -  <defs
   91.21 -     id="defs4">
   91.22 -    <marker
   91.23 -       inkscape:stockid="Arrow1Mstart"
   91.24 -       orient="auto"
   91.25 -       refY="0.0"
   91.26 -       refX="0.0"
   91.27 -       id="Arrow1Mstart"
   91.28 -       style="overflow:visible">
   91.29 -      <path
   91.30 -         id="path2973"
   91.31 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   91.32 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   91.33 -         transform="scale(0.4) translate(10,0)" />
   91.34 -    </marker>
   91.35 -    <marker
   91.36 -       inkscape:stockid="Arrow1Mend"
   91.37 -       orient="auto"
   91.38 -       refY="0.0"
   91.39 -       refX="0.0"
   91.40 -       id="Arrow1Mend"
   91.41 -       style="overflow:visible;">
   91.42 -      <path
   91.43 -         id="path3066"
   91.44 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   91.45 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   91.46 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   91.47 -    </marker>
   91.48 -  </defs>
   91.49 -  <sodipodi:namedview
   91.50 -     id="base"
   91.51 -     pagecolor="#ffffff"
   91.52 -     bordercolor="#666666"
   91.53 -     borderopacity="1.0"
   91.54 -     gridtolerance="10000"
   91.55 -     guidetolerance="10"
   91.56 -     objecttolerance="10"
   91.57 -     inkscape:pageopacity="0.0"
   91.58 -     inkscape:pageshadow="2"
   91.59 -     inkscape:zoom="1.4"
   91.60 -     inkscape:cx="247.53795"
   91.61 -     inkscape:cy="871.05738"
   91.62 -     inkscape:document-units="px"
   91.63 -     inkscape:current-layer="layer1"
   91.64 -     inkscape:window-width="906"
   91.65 -     inkscape:window-height="620"
   91.66 -     inkscape:window-x="38"
   91.67 -     inkscape:window-y="95" />
   91.68 -  <metadata
   91.69 -     id="metadata7">
   91.70 -    <rdf:RDF>
   91.71 -      <cc:Work
   91.72 -         rdf:about="">
   91.73 -        <dc:format>image/svg+xml</dc:format>
   91.74 -        <dc:type
   91.75 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   91.76 -      </cc:Work>
   91.77 -    </rdf:RDF>
   91.78 -  </metadata>
   91.79 -  <g
   91.80 -     inkscape:label="Layer 1"
   91.81 -     inkscape:groupmode="layer"
   91.82 -     id="layer1">
   91.83 -    <rect
   91.84 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   91.85 -       id="rect2995"
   91.86 -       width="94.285713"
   91.87 -       height="20.714285"
   91.88 -       x="532.85718"
   91.89 -       y="203.0479" />
   91.90 -    <text
   91.91 -       xml:space="preserve"
   91.92 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   91.93 -       x="173.57143"
   91.94 -       y="443.79074"
   91.95 -       id="text2832"><tspan
   91.96 -         sodipodi:role="line"
   91.97 -         id="tspan2834"
   91.98 -         x="173.57143"
   91.99 -         y="443.79074" /></text>
  91.100 -    <rect
  91.101 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  91.102 -       id="rect2830"
  91.103 -       width="94.285713"
  91.104 -       height="20.714285"
  91.105 -       x="138"
  91.106 -       y="297.76227" />
  91.107 -    <text
  91.108 -       xml:space="preserve"
  91.109 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  91.110 -       x="162.09892"
  91.111 -       y="311.38342"
  91.112 -       id="text2824"><tspan
  91.113 -         sodipodi:role="line"
  91.114 -         id="tspan2826"
  91.115 -         x="162.09892"
  91.116 -         y="311.38342"
  91.117 -         style="font-family:Courier"><tspan
  91.118 -   style="font-weight:bold"
  91.119 -   id="tspan2862">4</tspan>: REV4</tspan></text>
  91.120 -    <path
  91.121 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  91.122 -       d="M 185.14286,343.63731 L 185.14286,319.47656"
  91.123 -       id="path2900"
  91.124 -       inkscape:connector-type="polyline" />
  91.125 -    <rect
  91.126 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  91.127 -       id="rect2863"
  91.128 -       width="94.285713"
  91.129 -       height="20.714285"
  91.130 -       x="91.428574"
  91.131 -       y="250.47656" />
  91.132 -    <text
  91.133 -       xml:space="preserve"
  91.134 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  91.135 -       x="116.09886"
  91.136 -       y="264.56592"
  91.137 -       id="text1965"
  91.138 -       transform="scale(1.000002,0.999998)"><tspan
  91.139 -         sodipodi:role="line"
  91.140 -         id="tspan1967"
  91.141 -         x="116.09886"
  91.142 -         y="264.56592"
  91.143 -         style="font-family:Courier"><tspan
  91.144 -   style="font-weight:bold"
  91.145 -   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
  91.146 -    <path
  91.147 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  91.148 -       d="M 173.95727,296.76228 L 149.75702,272.19085"
  91.149 -       id="path1971"
  91.150 -       inkscape:connector-type="polyline"
  91.151 -       inkscape:connection-end="#rect2863"
  91.152 -       inkscape:connection-start="#rect2830" />
  91.153 -    <rect
  91.154 -       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  91.155 -       id="rect2911"
  91.156 -       width="94.285995"
  91.157 -       height="20.714283"
  91.158 -       x="186.71414"
  91.159 -       y="204.40514" />
  91.160 -    <text
  91.161 -       xml:space="preserve"
  91.162 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  91.163 -       x="210.81311"
  91.164 -       y="218.02673"
  91.165 -       id="text2913"
  91.166 -       transform="scale(1.000002,0.999998)"><tspan
  91.167 -         sodipodi:role="line"
  91.168 -         id="tspan2915"
  91.169 -         x="210.81311"
  91.170 -         y="218.02673"
  91.171 -         style="font-family:Courier"><tspan
  91.172 -   id="tspan1966"
  91.173 -   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
  91.174 -    <path
  91.175 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  91.176 -       d="M 191.06908,296.76228 L 227.93092,226.11942"
  91.177 -       id="path2919"
  91.178 -       inkscape:connector-type="polyline"
  91.179 -       inkscape:connection-start="#rect2830" />
  91.180 -    <text
  91.181 -       xml:space="preserve"
  91.182 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.183 -       x="295.28571"
  91.184 -       y="217.56711"
  91.185 -       id="text2871"><tspan
  91.186 -         sodipodi:role="line"
  91.187 -         id="tspan2873"
  91.188 -         x="295.28571"
  91.189 -         y="217.56711">tip (and head)</tspan></text>
  91.190 -    <text
  91.191 -       xml:space="preserve"
  91.192 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.193 -       x="76"
  91.194 -       y="264.91769"
  91.195 -       id="text2875"><tspan
  91.196 -         sodipodi:role="line"
  91.197 -         id="tspan2877"
  91.198 -         x="76"
  91.199 -         y="264.91769"
  91.200 -         style="text-align:end;text-anchor:end">head</tspan></text>
  91.201 -    <rect
  91.202 -       style="fill:#c8aaa5;fill-opacity:1;stroke:#a07163;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2, 4;stroke-dashoffset:0;stroke-opacity:1"
  91.203 -       id="rect1913"
  91.204 -       width="94.285713"
  91.205 -       height="20.714285"
  91.206 -       x="138"
  91.207 -       y="156.90514" />
  91.208 -    <path
  91.209 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
  91.210 -       d="M 144.22399,249.47657 L 179.49029,178.61943"
  91.211 -       id="path1915"
  91.212 -       inkscape:connector-type="polyline"
  91.213 -       inkscape:connection-start="#rect2863"
  91.214 -       inkscape:connection-end="#rect1913" />
  91.215 -    <path
  91.216 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
  91.217 -       d="M 222.20966,203.40514 L 196.79033,178.61943"
  91.218 -       id="path1917"
  91.219 -       inkscape:connector-type="polyline"
  91.220 -       inkscape:connection-start="#rect2911"
  91.221 -       inkscape:connection-end="#rect1913" />
  91.222 -    <text
  91.223 -       xml:space="preserve"
  91.224 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.225 -       x="166.16823"
  91.226 -       y="168.52228"
  91.227 -       id="text2806"><tspan
  91.228 -         sodipodi:role="line"
  91.229 -         id="tspan2808"
  91.230 -         x="166.16823"
  91.231 -         y="168.52228"
  91.232 -         style="font-family:Courier">merge</tspan></text>
  91.233 -    <text
  91.234 -       xml:space="preserve"
  91.235 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.236 -       x="246"
  91.237 -       y="162.63338"
  91.238 -       id="text2810"><tspan
  91.239 -         sodipodi:role="line"
  91.240 -         id="tspan2812"
  91.241 -         x="246"
  91.242 -         y="162.63338">working directory</tspan><tspan
  91.243 -         sodipodi:role="line"
  91.244 -         x="246"
  91.245 -         y="177.63338"
  91.246 -         id="tspan2814">during merge</tspan></text>
  91.247 -    <rect
  91.248 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  91.249 -       id="rect2816"
  91.250 -       width="94.285713"
  91.251 -       height="20.714285"
  91.252 -       x="483.14636"
  91.253 -       y="297.76227" />
  91.254 -    <text
  91.255 -       xml:space="preserve"
  91.256 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  91.257 -       x="507.24527"
  91.258 -       y="311.38342"
  91.259 -       id="text2818"><tspan
  91.260 -         sodipodi:role="line"
  91.261 -         id="tspan2820"
  91.262 -         x="507.24527"
  91.263 -         y="311.38342"
  91.264 -         style="font-family:Courier"><tspan
  91.265 -   style="font-weight:bold"
  91.266 -   id="tspan2822">4</tspan>: REV4</tspan></text>
  91.267 -    <path
  91.268 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  91.269 -       d="M 530.28921,343.6373 L 530.28921,319.47655"
  91.270 -       id="path2824"
  91.271 -       inkscape:connector-type="polyline" />
  91.272 -    <rect
  91.273 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  91.274 -       id="rect2826"
  91.275 -       width="94.285713"
  91.276 -       height="20.714285"
  91.277 -       x="436.57492"
  91.278 -       y="250.47656" />
  91.279 -    <text
  91.280 -       xml:space="preserve"
  91.281 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  91.282 -       x="461.24484"
  91.283 -       y="264.56613"
  91.284 -       id="text2828"
  91.285 -       transform="scale(1.000002,0.999998)"><tspan
  91.286 -         sodipodi:role="line"
  91.287 -         id="tspan2830"
  91.288 -         x="461.24484"
  91.289 -         y="264.56613"
  91.290 -         style="font-family:Courier"><tspan
  91.291 -   style="font-weight:bold"
  91.292 -   id="tspan2832">5</tspan>: REV_my_new_hello</tspan></text>
  91.293 -    <path
  91.294 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  91.295 -       d="M 519.10362,296.76227 L 494.90337,272.19084"
  91.296 -       id="path2834"
  91.297 -       inkscape:connector-type="polyline" />
  91.298 -    <rect
  91.299 -       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  91.300 -       id="rect2836"
  91.301 -       width="94.285995"
  91.302 -       height="20.714283"
  91.303 -       x="483.14001"
  91.304 -       y="156.548" />
  91.305 -    <text
  91.306 -       xml:space="preserve"
  91.307 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  91.308 -       x="555.95911"
  91.309 -       y="218.02698"
  91.310 -       id="text2838"
  91.311 -       transform="scale(1.000002,0.999998)"><tspan
  91.312 -         sodipodi:role="line"
  91.313 -         id="tspan2840"
  91.314 -         x="555.95911"
  91.315 -         y="218.02698"
  91.316 -         style="font-family:Courier"><tspan
  91.317 -   id="tspan2842"
  91.318 -   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
  91.319 -    <path
  91.320 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  91.321 -       d="M 536.21543,296.76227 L 574.03453,224.76218"
  91.322 -       id="path2844"
  91.323 -       inkscape:connector-type="polyline" />
  91.324 -    <text
  91.325 -       xml:space="preserve"
  91.326 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.327 -       x="594.43207"
  91.328 -       y="169.78796"
  91.329 -       id="text2846"><tspan
  91.330 -         sodipodi:role="line"
  91.331 -         id="tspan2848"
  91.332 -         x="594.43207"
  91.333 -         y="169.78796">tip</tspan></text>
  91.334 -    <path
  91.335 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
  91.336 -       d="M 489.37034,249.47656 L 524.65575,178.26229"
  91.337 -       id="path2856"
  91.338 -       inkscape:connector-type="polyline"
  91.339 -       inkscape:connection-end="#rect2836" />
  91.340 -    <path
  91.341 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
  91.342 -       d="M 567.85714,202.0479 L 542.42591,178.26229"
  91.343 -       id="path2858"
  91.344 -       inkscape:connector-type="polyline"
  91.345 -       inkscape:connection-end="#rect2836"
  91.346 -       inkscape:connection-start="#rect2995" />
  91.347 -    <text
  91.348 -       xml:space="preserve"
  91.349 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.350 -       x="504.54507"
  91.351 -       y="170.39714"
  91.352 -       id="text2860"><tspan
  91.353 -         sodipodi:role="line"
  91.354 -         id="tspan2863"
  91.355 -         x="504.54507"
  91.356 -         y="170.39714"
  91.357 -         style="font-family:Courier"><tspan
  91.358 -   style="font-weight:bold"
  91.359 -   id="tspan2997">7</tspan>: REV7_my_new_hello</tspan></text>
  91.360 -    <text
  91.361 -       xml:space="preserve"
  91.362 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.363 -       x="90.323105"
  91.364 -       y="120.21933"
  91.365 -       id="text2929"><tspan
  91.366 -         sodipodi:role="line"
  91.367 -         id="tspan2931"
  91.368 -         x="90.323105"
  91.369 -         y="120.21933"
  91.370 -         style="font-weight:bold">Working directory during merge</tspan></text>
  91.371 -    <text
  91.372 -       xml:space="preserve"
  91.373 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  91.374 -       x="435.35226"
  91.375 -       y="120.21933"
  91.376 -       id="text2937"><tspan
  91.377 -         sodipodi:role="line"
  91.378 -         id="tspan2939"
  91.379 -         x="435.35226"
  91.380 -         y="120.21933"
  91.381 -         style="font-weight:bold">Repository after merge committed</tspan></text>
  91.382 -  </g>
  91.383 -</svg>
    92.1 --- a/fr/tour-merge-pull.svg	Sun Aug 16 03:41:39 2009 +0200
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,288 +0,0 @@
    92.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    92.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    92.6 -<svg
    92.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    92.8 -   xmlns:cc="http://web.resource.org/cc/"
    92.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   92.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   92.11 -   xmlns="http://www.w3.org/2000/svg"
   92.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   92.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   92.14 -   width="744.09448819"
   92.15 -   height="1052.3622047"
   92.16 -   id="svg2"
   92.17 -   sodipodi:version="0.32"
   92.18 -   inkscape:version="0.44.1"
   92.19 -   sodipodi:docname="tour-merge-pull.svg"
   92.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en">
   92.21 -  <defs
   92.22 -     id="defs4">
   92.23 -    <marker
   92.24 -       inkscape:stockid="Arrow1Mstart"
   92.25 -       orient="auto"
   92.26 -       refY="0.0"
   92.27 -       refX="0.0"
   92.28 -       id="Arrow1Mstart"
   92.29 -       style="overflow:visible">
   92.30 -      <path
   92.31 -         id="path2973"
   92.32 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   92.33 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   92.34 -         transform="scale(0.4) translate(10,0)" />
   92.35 -    </marker>
   92.36 -    <marker
   92.37 -       inkscape:stockid="Arrow1Mend"
   92.38 -       orient="auto"
   92.39 -       refY="0.0"
   92.40 -       refX="0.0"
   92.41 -       id="Arrow1Mend"
   92.42 -       style="overflow:visible;">
   92.43 -      <path
   92.44 -         id="path3066"
   92.45 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   92.46 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   92.47 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   92.48 -    </marker>
   92.49 -  </defs>
   92.50 -  <sodipodi:namedview
   92.51 -     id="base"
   92.52 -     pagecolor="#ffffff"
   92.53 -     bordercolor="#666666"
   92.54 -     borderopacity="1.0"
   92.55 -     gridtolerance="10000"
   92.56 -     guidetolerance="10"
   92.57 -     objecttolerance="10"
   92.58 -     inkscape:pageopacity="0.0"
   92.59 -     inkscape:pageshadow="2"
   92.60 -     inkscape:zoom="1.4"
   92.61 -     inkscape:cx="233.63208"
   92.62 -     inkscape:cy="832.54381"
   92.63 -     inkscape:document-units="px"
   92.64 -     inkscape:current-layer="layer1"
   92.65 -     inkscape:window-width="906"
   92.66 -     inkscape:window-height="620"
   92.67 -     inkscape:window-x="237"
   92.68 -     inkscape:window-y="103" />
   92.69 -  <metadata
   92.70 -     id="metadata7">
   92.71 -    <rdf:RDF>
   92.72 -      <cc:Work
   92.73 -         rdf:about="">
   92.74 -        <dc:format>image/svg+xml</dc:format>
   92.75 -        <dc:type
   92.76 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   92.77 -      </cc:Work>
   92.78 -    </rdf:RDF>
   92.79 -  </metadata>
   92.80 -  <g
   92.81 -     inkscape:label="Layer 1"
   92.82 -     inkscape:groupmode="layer"
   92.83 -     id="layer1">
   92.84 -    <text
   92.85 -       xml:space="preserve"
   92.86 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   92.87 -       x="173.57143"
   92.88 -       y="443.79074"
   92.89 -       id="text2832"><tspan
   92.90 -         sodipodi:role="line"
   92.91 -         id="tspan2834"
   92.92 -         x="173.57143"
   92.93 -         y="443.79074" /></text>
   92.94 -    <rect
   92.95 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   92.96 -       id="rect1878"
   92.97 -       width="94.285713"
   92.98 -       height="20.714285"
   92.99 -       x="138"
  92.100 -       y="479.50504" />
  92.101 -    <text
  92.102 -       xml:space="preserve"
  92.103 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.104 -       x="162.09892"
  92.105 -       y="493.12619"
  92.106 -       id="text1872"><tspan
  92.107 -         sodipodi:role="line"
  92.108 -         id="tspan1874"
  92.109 -         x="162.09892"
  92.110 -         y="493.12619"
  92.111 -         style="font-family:Courier"><tspan
  92.112 -   style="font-weight:bold"
  92.113 -   id="tspan1876">0</tspan>: REV0</tspan></text>
  92.114 -    <rect
  92.115 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  92.116 -       id="rect2800"
  92.117 -       width="94.285713"
  92.118 -       height="20.714285"
  92.119 -       x="138"
  92.120 -       y="432.63004" />
  92.121 -    <text
  92.122 -       xml:space="preserve"
  92.123 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.124 -       x="162.09892"
  92.125 -       y="446.25119"
  92.126 -       id="text2794"><tspan
  92.127 -         sodipodi:role="line"
  92.128 -         id="tspan2796"
  92.129 -         x="162.09892"
  92.130 -         y="446.25119"
  92.131 -         style="font-family:Courier"><tspan
  92.132 -   id="tspan2868"
  92.133 -   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  92.134 -    <rect
  92.135 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  92.136 -       id="rect2810"
  92.137 -       width="94.285713"
  92.138 -       height="20.714285"
  92.139 -       x="138"
  92.140 -       y="385.75504" />
  92.141 -    <text
  92.142 -       xml:space="preserve"
  92.143 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.144 -       x="162.09892"
  92.145 -       y="399.37619"
  92.146 -       id="text2804"><tspan
  92.147 -         sodipodi:role="line"
  92.148 -         id="tspan2806"
  92.149 -         x="162.09892"
  92.150 -         y="399.37619"
  92.151 -         style="font-family:Courier"><tspan
  92.152 -   style="font-weight:bold"
  92.153 -   id="tspan2866">2</tspan>: REV2</tspan></text>
  92.154 -    <rect
  92.155 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  92.156 -       id="rect2820"
  92.157 -       width="94.285713"
  92.158 -       height="20.714285"
  92.159 -       x="138"
  92.160 -       y="338.88007" />
  92.161 -    <text
  92.162 -       xml:space="preserve"
  92.163 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.164 -       x="162.09892"
  92.165 -       y="352.50122"
  92.166 -       id="text2814"><tspan
  92.167 -         sodipodi:role="line"
  92.168 -         id="tspan2816"
  92.169 -         x="162.09892"
  92.170 -         y="352.50122"
  92.171 -         style="font-family:Courier"><tspan
  92.172 -   style="font-weight:bold"
  92.173 -   id="tspan2864">3</tspan>: REV3</tspan></text>
  92.174 -    <rect
  92.175 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  92.176 -       id="rect2830"
  92.177 -       width="94.285713"
  92.178 -       height="20.714285"
  92.179 -       x="138"
  92.180 -       y="292.00504" />
  92.181 -    <text
  92.182 -       xml:space="preserve"
  92.183 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.184 -       x="162.09892"
  92.185 -       y="305.62619"
  92.186 -       id="text2824"><tspan
  92.187 -         sodipodi:role="line"
  92.188 -         id="tspan2826"
  92.189 -         x="162.09892"
  92.190 -         y="305.62619"
  92.191 -         style="font-family:Courier"><tspan
  92.192 -   style="font-weight:bold"
  92.193 -   id="tspan2862">4</tspan>: REV4</tspan></text>
  92.194 -    <path
  92.195 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  92.196 -       d="M 185.14286,478.50504 L 185.14286,454.34432"
  92.197 -       id="path2894"
  92.198 -       inkscape:connector-type="polyline" />
  92.199 -    <path
  92.200 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  92.201 -       d="M 185.14286,431.63004 L 185.14286,407.46932"
  92.202 -       id="path2896"
  92.203 -       inkscape:connector-type="polyline" />
  92.204 -    <path
  92.205 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  92.206 -       d="M 185.14286,384.75504 L 185.14286,360.59435"
  92.207 -       id="path2898"
  92.208 -       inkscape:connector-type="polyline" />
  92.209 -    <path
  92.210 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  92.211 -       d="M 185.14286,337.88007 L 185.14286,313.71932"
  92.212 -       id="path2900"
  92.213 -       inkscape:connector-type="polyline" />
  92.214 -    <rect
  92.215 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  92.216 -       id="rect2863"
  92.217 -       width="94.285713"
  92.218 -       height="20.714285"
  92.219 -       x="91.428574"
  92.220 -       y="244.71933" />
  92.221 -    <text
  92.222 -       xml:space="preserve"
  92.223 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.224 -       x="116.09886"
  92.225 -       y="258.80865"
  92.226 -       id="text1965"
  92.227 -       transform="scale(1.000002,0.999998)"><tspan
  92.228 -         sodipodi:role="line"
  92.229 -         id="tspan1967"
  92.230 -         x="116.09886"
  92.231 -         y="258.80865"
  92.232 -         style="font-family:Courier"><tspan
  92.233 -   style="font-weight:bold"
  92.234 -   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
  92.235 -    <path
  92.236 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  92.237 -       d="M 173.95727,291.00504 L 149.75702,266.43361"
  92.238 -       id="path1971"
  92.239 -       inkscape:connector-type="polyline"
  92.240 -       inkscape:connection-end="#rect2863"
  92.241 -       inkscape:connection-start="#rect2830" />
  92.242 -    <rect
  92.243 -       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  92.244 -       id="rect2911"
  92.245 -       width="94.285995"
  92.246 -       height="20.714283"
  92.247 -       x="186.71414"
  92.248 -       y="198.6479" />
  92.249 -    <text
  92.250 -       xml:space="preserve"
  92.251 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  92.252 -       x="210.81311"
  92.253 -       y="212.26949"
  92.254 -       id="text2913"
  92.255 -       transform="scale(1.000002,0.999998)"><tspan
  92.256 -         sodipodi:role="line"
  92.257 -         id="tspan2915"
  92.258 -         x="210.81311"
  92.259 -         y="212.26949"
  92.260 -         style="font-family:Courier"><tspan
  92.261 -   id="tspan1966"
  92.262 -   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
  92.263 -    <path
  92.264 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
  92.265 -       d="M 191.06908,291.00504 L 227.93092,220.36218"
  92.266 -       id="path2919"
  92.267 -       inkscape:connector-type="polyline"
  92.268 -       inkscape:connection-start="#rect2830" />
  92.269 -    <text
  92.270 -       xml:space="preserve"
  92.271 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  92.272 -       x="295.28571"
  92.273 -       y="211.80988"
  92.274 -       id="text2871"><tspan
  92.275 -         sodipodi:role="line"
  92.276 -         id="tspan2873"
  92.277 -         x="295.28571"
  92.278 -         y="211.80988">tip (and head)</tspan></text>
  92.279 -    <text
  92.280 -       xml:space="preserve"
  92.281 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  92.282 -       x="76"
  92.283 -       y="259.16046"
  92.284 -       id="text2875"><tspan
  92.285 -         sodipodi:role="line"
  92.286 -         id="tspan2877"
  92.287 -         x="76"
  92.288 -         y="259.16046"
  92.289 -         style="text-align:end;text-anchor:end">head</tspan></text>
  92.290 -  </g>
  92.291 -</svg>
    93.1 --- a/fr/tour-merge-sep-repos.svg	Sun Aug 16 03:41:39 2009 +0200
    93.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.3 @@ -1,466 +0,0 @@
    93.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    93.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
    93.6 -<svg
    93.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
    93.8 -   xmlns:cc="http://web.resource.org/cc/"
    93.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   93.10 -   xmlns:svg="http://www.w3.org/2000/svg"
   93.11 -   xmlns="http://www.w3.org/2000/svg"
   93.12 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   93.13 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   93.14 -   width="744.09448819"
   93.15 -   height="1052.3622047"
   93.16 -   id="svg2"
   93.17 -   sodipodi:version="0.32"
   93.18 -   inkscape:version="0.44.1"
   93.19 -   sodipodi:docname="tour-merge-sep-repos.svg">
   93.20 -  <defs
   93.21 -     id="defs4">
   93.22 -    <marker
   93.23 -       inkscape:stockid="Arrow1Mstart"
   93.24 -       orient="auto"
   93.25 -       refY="0.0"
   93.26 -       refX="0.0"
   93.27 -       id="Arrow1Mstart"
   93.28 -       style="overflow:visible">
   93.29 -      <path
   93.30 -         id="path2973"
   93.31 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   93.32 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
   93.33 -         transform="scale(0.4) translate(10,0)" />
   93.34 -    </marker>
   93.35 -    <marker
   93.36 -       inkscape:stockid="Arrow1Mend"
   93.37 -       orient="auto"
   93.38 -       refY="0.0"
   93.39 -       refX="0.0"
   93.40 -       id="Arrow1Mend"
   93.41 -       style="overflow:visible;">
   93.42 -      <path
   93.43 -         id="path3066"
   93.44 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
   93.45 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
   93.46 -         transform="scale(0.4) rotate(180) translate(10,0)" />
   93.47 -    </marker>
   93.48 -  </defs>
   93.49 -  <sodipodi:namedview
   93.50 -     id="base"
   93.51 -     pagecolor="#ffffff"
   93.52 -     bordercolor="#666666"
   93.53 -     borderopacity="1.0"
   93.54 -     gridtolerance="10000"
   93.55 -     guidetolerance="10"
   93.56 -     objecttolerance="10"
   93.57 -     inkscape:pageopacity="0.0"
   93.58 -     inkscape:pageshadow="2"
   93.59 -     inkscape:zoom="1.4"
   93.60 -     inkscape:cx="307.20351"
   93.61 -     inkscape:cy="716.87911"
   93.62 -     inkscape:document-units="px"
   93.63 -     inkscape:current-layer="layer1"
   93.64 -     inkscape:window-width="906"
   93.65 -     inkscape:window-height="620"
   93.66 -     inkscape:window-x="5"
   93.67 -     inkscape:window-y="49" />
   93.68 -  <metadata
   93.69 -     id="metadata7">
   93.70 -    <rdf:RDF>
   93.71 -      <cc:Work
   93.72 -         rdf:about="">
   93.73 -        <dc:format>image/svg+xml</dc:format>
   93.74 -        <dc:type
   93.75 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   93.76 -      </cc:Work>
   93.77 -    </rdf:RDF>
   93.78 -  </metadata>
   93.79 -  <g
   93.80 -     inkscape:label="Layer 1"
   93.81 -     inkscape:groupmode="layer"
   93.82 -     id="layer1">
   93.83 -    <text
   93.84 -       xml:space="preserve"
   93.85 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
   93.86 -       x="173.57143"
   93.87 -       y="443.79074"
   93.88 -       id="text2832"><tspan
   93.89 -         sodipodi:role="line"
   93.90 -         id="tspan2834"
   93.91 -         x="173.57143"
   93.92 -         y="443.79074" /></text>
   93.93 -    <rect
   93.94 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   93.95 -       id="rect1878"
   93.96 -       width="94.285713"
   93.97 -       height="20.714285"
   93.98 -       x="138"
   93.99 -       y="479.50504" />
  93.100 -    <text
  93.101 -       xml:space="preserve"
  93.102 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.103 -       x="162.09892"
  93.104 -       y="493.12619"
  93.105 -       id="text1872"><tspan
  93.106 -         sodipodi:role="line"
  93.107 -         id="tspan1874"
  93.108 -         x="162.09892"
  93.109 -         y="493.12619"
  93.110 -         style="font-family:Courier"><tspan
  93.111 -   style="font-weight:bold"
  93.112 -   id="tspan1876">0</tspan>: REV0</tspan></text>
  93.113 -    <rect
  93.114 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.115 -       id="rect2800"
  93.116 -       width="94.285713"
  93.117 -       height="20.714285"
  93.118 -       x="138"
  93.119 -       y="432.63004" />
  93.120 -    <text
  93.121 -       xml:space="preserve"
  93.122 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.123 -       x="162.09892"
  93.124 -       y="446.25119"
  93.125 -       id="text2794"><tspan
  93.126 -         sodipodi:role="line"
  93.127 -         id="tspan2796"
  93.128 -         x="162.09892"
  93.129 -         y="446.25119"
  93.130 -         style="font-family:Courier"><tspan
  93.131 -   id="tspan2868"
  93.132 -   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  93.133 -    <rect
  93.134 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.135 -       id="rect2810"
  93.136 -       width="94.285713"
  93.137 -       height="20.714285"
  93.138 -       x="138"
  93.139 -       y="385.75504" />
  93.140 -    <text
  93.141 -       xml:space="preserve"
  93.142 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.143 -       x="162.09892"
  93.144 -       y="399.37619"
  93.145 -       id="text2804"><tspan
  93.146 -         sodipodi:role="line"
  93.147 -         id="tspan2806"
  93.148 -         x="162.09892"
  93.149 -         y="399.37619"
  93.150 -         style="font-family:Courier"><tspan
  93.151 -   style="font-weight:bold"
  93.152 -   id="tspan2866">2</tspan>: REV2</tspan></text>
  93.153 -    <rect
  93.154 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.155 -       id="rect2820"
  93.156 -       width="94.285713"
  93.157 -       height="20.714285"
  93.158 -       x="138"
  93.159 -       y="338.88007" />
  93.160 -    <text
  93.161 -       xml:space="preserve"
  93.162 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.163 -       x="162.09892"
  93.164 -       y="352.50122"
  93.165 -       id="text2814"><tspan
  93.166 -         sodipodi:role="line"
  93.167 -         id="tspan2816"
  93.168 -         x="162.09892"
  93.169 -         y="352.50122"
  93.170 -         style="font-family:Courier"><tspan
  93.171 -   style="font-weight:bold"
  93.172 -   id="tspan2864">3</tspan>: REV3</tspan></text>
  93.173 -    <rect
  93.174 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.175 -       id="rect2830"
  93.176 -       width="94.285713"
  93.177 -       height="20.714285"
  93.178 -       x="138"
  93.179 -       y="292.00504" />
  93.180 -    <text
  93.181 -       xml:space="preserve"
  93.182 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.183 -       x="162.09892"
  93.184 -       y="305.62619"
  93.185 -       id="text2824"><tspan
  93.186 -         sodipodi:role="line"
  93.187 -         id="tspan2826"
  93.188 -         x="162.09892"
  93.189 -         y="305.62619"
  93.190 -         style="font-family:Courier"><tspan
  93.191 -   style="font-weight:bold"
  93.192 -   id="tspan2862">4</tspan>: REV4</tspan></text>
  93.193 -    <path
  93.194 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.195 -       d="M 185.14286,478.50504 L 185.14286,454.34432"
  93.196 -       id="path2894"
  93.197 -       inkscape:connector-type="polyline" />
  93.198 -    <path
  93.199 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.200 -       d="M 185.14286,431.63004 L 185.14286,407.46932"
  93.201 -       id="path2896"
  93.202 -       inkscape:connector-type="polyline" />
  93.203 -    <path
  93.204 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.205 -       d="M 185.14286,384.75504 L 185.14286,360.59435"
  93.206 -       id="path2898"
  93.207 -       inkscape:connector-type="polyline" />
  93.208 -    <path
  93.209 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.210 -       d="M 185.14286,337.88007 L 185.14286,313.71932"
  93.211 -       id="path2900"
  93.212 -       inkscape:connector-type="polyline" />
  93.213 -    <rect
  93.214 -       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.215 -       id="rect1963"
  93.216 -       width="94.285995"
  93.217 -       height="20.714283"
  93.218 -       x="138"
  93.219 -       y="245.18723" />
  93.220 -    <text
  93.221 -       xml:space="preserve"
  93.222 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.223 -       x="162.09877"
  93.224 -       y="258.80865"
  93.225 -       id="text1965"
  93.226 -       transform="scale(1.000002,0.999998)"><tspan
  93.227 -         sodipodi:role="line"
  93.228 -         id="tspan1967"
  93.229 -         x="162.09877"
  93.230 -         y="258.80865"
  93.231 -         style="font-family:Courier"><tspan
  93.232 -   style="font-weight:bold"
  93.233 -   id="tspan1973">5</tspan>: REV_my_hello</tspan></text>
  93.234 -    <path
  93.235 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.236 -       d="M 185.143,291.06218 L 185.143,266.90143"
  93.237 -       id="path1971"
  93.238 -       inkscape:connector-type="polyline" />
  93.239 -    <text
  93.240 -       xml:space="preserve"
  93.241 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  93.242 -       x="136.90039"
  93.243 -       y="232.25546"
  93.244 -       id="text2921"><tspan
  93.245 -         sodipodi:role="line"
  93.246 -         id="tspan2923"
  93.247 -         x="136.90039"
  93.248 -         y="232.25546">my-hello</tspan></text>
  93.249 -    <rect
  93.250 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.251 -       id="rect2863"
  93.252 -       width="94.285713"
  93.253 -       height="20.714285"
  93.254 -       x="370.71414"
  93.255 -       y="479.49289" />
  93.256 -    <text
  93.257 -       xml:space="preserve"
  93.258 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.259 -       x="394.81305"
  93.260 -       y="493.11404"
  93.261 -       id="text2865"><tspan
  93.262 -         sodipodi:role="line"
  93.263 -         id="tspan2867"
  93.264 -         x="394.81305"
  93.265 -         y="493.11404"
  93.266 -         style="font-family:Courier"><tspan
  93.267 -   style="font-weight:bold"
  93.268 -   id="tspan2869">0</tspan>: REV0</tspan></text>
  93.269 -    <rect
  93.270 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.271 -       id="rect2871"
  93.272 -       width="94.285713"
  93.273 -       height="20.714285"
  93.274 -       x="370.71414"
  93.275 -       y="432.61789" />
  93.276 -    <text
  93.277 -       xml:space="preserve"
  93.278 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.279 -       x="394.81305"
  93.280 -       y="446.23904"
  93.281 -       id="text2873"><tspan
  93.282 -         sodipodi:role="line"
  93.283 -         id="tspan2875"
  93.284 -         x="394.81305"
  93.285 -         y="446.23904"
  93.286 -         style="font-family:Courier"><tspan
  93.287 -   id="tspan2877"
  93.288 -   style="font-weight:bold">1</tspan>: REV1</tspan></text>
  93.289 -    <rect
  93.290 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.291 -       id="rect2879"
  93.292 -       width="94.285713"
  93.293 -       height="20.714285"
  93.294 -       x="370.71414"
  93.295 -       y="385.74289" />
  93.296 -    <text
  93.297 -       xml:space="preserve"
  93.298 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.299 -       x="394.81305"
  93.300 -       y="399.36404"
  93.301 -       id="text2881"><tspan
  93.302 -         sodipodi:role="line"
  93.303 -         id="tspan2883"
  93.304 -         x="394.81305"
  93.305 -         y="399.36404"
  93.306 -         style="font-family:Courier"><tspan
  93.307 -   style="font-weight:bold"
  93.308 -   id="tspan2885">2</tspan>: REV2</tspan></text>
  93.309 -    <rect
  93.310 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.311 -       id="rect2887"
  93.312 -       width="94.285713"
  93.313 -       height="20.714285"
  93.314 -       x="370.71414"
  93.315 -       y="338.86792" />
  93.316 -    <text
  93.317 -       xml:space="preserve"
  93.318 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.319 -       x="394.81305"
  93.320 -       y="352.48907"
  93.321 -       id="text2889"><tspan
  93.322 -         sodipodi:role="line"
  93.323 -         id="tspan2891"
  93.324 -         x="394.81305"
  93.325 -         y="352.48907"
  93.326 -         style="font-family:Courier"><tspan
  93.327 -   style="font-weight:bold"
  93.328 -   id="tspan2893">3</tspan>: REV3</tspan></text>
  93.329 -    <rect
  93.330 -       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.331 -       id="rect2895"
  93.332 -       width="94.285713"
  93.333 -       height="20.714285"
  93.334 -       x="370.71414"
  93.335 -       y="291.99289" />
  93.336 -    <text
  93.337 -       xml:space="preserve"
  93.338 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.339 -       x="394.81305"
  93.340 -       y="305.61404"
  93.341 -       id="text2897"><tspan
  93.342 -         sodipodi:role="line"
  93.343 -         id="tspan2899"
  93.344 -         x="394.81305"
  93.345 -         y="305.61404"
  93.346 -         style="font-family:Courier"><tspan
  93.347 -   style="font-weight:bold"
  93.348 -   id="tspan2901">4</tspan>: REV4</tspan></text>
  93.349 -    <path
  93.350 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.351 -       d="M 417.85701,478.4929 L 417.85701,454.33218"
  93.352 -       id="path2903"
  93.353 -       inkscape:connector-type="polyline" />
  93.354 -    <path
  93.355 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.356 -       d="M 417.85701,431.6179 L 417.85701,407.45718"
  93.357 -       id="path2905"
  93.358 -       inkscape:connector-type="polyline" />
  93.359 -    <path
  93.360 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.361 -       d="M 417.85701,384.7429 L 417.85701,360.58221"
  93.362 -       id="path2907"
  93.363 -       inkscape:connector-type="polyline" />
  93.364 -    <path
  93.365 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.366 -       d="M 417.85701,337.86793 L 417.85701,313.70718"
  93.367 -       id="path2909"
  93.368 -       inkscape:connector-type="polyline" />
  93.369 -    <rect
  93.370 -       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.371 -       id="rect2911"
  93.372 -       width="94.285995"
  93.373 -       height="20.714283"
  93.374 -       x="370.71414"
  93.375 -       y="245.17511" />
  93.376 -    <text
  93.377 -       xml:space="preserve"
  93.378 -       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
  93.379 -       x="394.81274"
  93.380 -       y="258.79678"
  93.381 -       id="text2913"
  93.382 -       transform="scale(1.000002,0.999998)"><tspan
  93.383 -         sodipodi:role="line"
  93.384 -         id="tspan2915"
  93.385 -         x="394.81274"
  93.386 -         y="258.79678"
  93.387 -         style="font-family:Courier"><tspan
  93.388 -   style="font-weight:bold"
  93.389 -   id="tspan2917">5</tspan>: REV_my_new_hello</tspan></text>
  93.390 -    <path
  93.391 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
  93.392 -       d="M 417.85715,291.05004 L 417.85715,266.88929"
  93.393 -       id="path2919"
  93.394 -       inkscape:connector-type="polyline" />
  93.395 -    <text
  93.396 -       xml:space="preserve"
  93.397 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  93.398 -       x="369.61453"
  93.399 -       y="232.25546"
  93.400 -       id="text2925"><tspan
  93.401 -         sodipodi:role="line"
  93.402 -         id="tspan2927"
  93.403 -         x="369.61453"
  93.404 -         y="232.25546">my-new-hello</tspan></text>
  93.405 -    <text
  93.406 -       xml:space="preserve"
  93.407 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  93.408 -       x="300.54352"
  93.409 -       y="252.12723"
  93.410 -       id="text2933"><tspan
  93.411 -         sodipodi:role="line"
  93.412 -         id="tspan2935"
  93.413 -         x="300.54352"
  93.414 -         y="252.12723"
  93.415 -         style="text-align:center;text-anchor:middle">newest changes</tspan><tspan
  93.416 -         sodipodi:role="line"
  93.417 -         x="300.54352"
  93.418 -         y="267.12723"
  93.419 -         style="text-align:center;text-anchor:middle"
  93.420 -         id="tspan3132">differ</tspan></text>
  93.421 -    <text
  93.422 -       xml:space="preserve"
  93.423 -       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  93.424 -       x="262.15436"
  93.425 -       y="398.37112"
  93.426 -       id="text2929"><tspan
  93.427 -         sodipodi:role="line"
  93.428 -         x="262.15436"
  93.429 -         y="398.37112"
  93.430 -         id="tspan3013"
  93.431 -         style="text-align:start;text-anchor:start">common history</tspan></text>
  93.432 -    <g
  93.433 -       id="g3107"
  93.434 -       transform="translate(0,0.855744)">
  93.435 -      <path
  93.436 -         id="path3101"
  93.437 -         d="M 300.35713,381.29075 L 300.35713,304.50504"
  93.438 -         style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" />
  93.439 -      <path
  93.440 -         id="path3105"
  93.441 -         d="M 291.07142,301.64789 L 309.28571,301.64789"
  93.442 -         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
  93.443 -    </g>
  93.444 -    <path
  93.445 -       style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1"
  93.446 -       d="M 300.53571,486.38926 L 300.53571,409.60355"
  93.447 -       id="path3113" />
  93.448 -    <path
  93.449 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  93.450 -       d="M 291.25,488.49641 L 309.46429,488.49641"
  93.451 -       id="path3115" />
  93.452 -    <text
  93.453 -       xml:space="preserve"
  93.454 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
  93.455 -       x="480.71429"
  93.456 -       y="250.91507"
  93.457 -       id="text1949"><tspan
  93.458 -         sodipodi:role="line"
  93.459 -         id="tspan1951"
  93.460 -         x="480.71429"
  93.461 -         y="250.91507"
  93.462 -         style="text-align:start;text-anchor:start">head revision</tspan><tspan
  93.463 -         sodipodi:role="line"
  93.464 -         x="480.71429"
  93.465 -         y="265.91507"
  93.466 -         id="tspan1953"
  93.467 -         style="text-align:start;text-anchor:start">(has no children)</tspan></text>
  93.468 -  </g>
  93.469 -</svg>
    94.1 --- a/fr/tour-merge.tex	Sun Aug 16 03:41:39 2009 +0200
    94.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.3 @@ -1,319 +0,0 @@
    94.4 -\chapter{Un rapide tour de Mercurial: fusionner les travaux}
    94.5 -\label{chap:tour-merge}
    94.6 -
    94.7 -Nous avons maintenant étudié comment cloner un dépôt, effectuer
    94.8 -des changements dedans, et récupérer ou transférer depuis un 
    94.9 -autre dépôt. La prochaine étape est donc de \emph{fusionner} les
   94.10 -modifications de différents dépôts.
   94.11 -
   94.12 -\section{Fusionner différents travaux} %%%TODO: better translation
   94.13 -				       %%% for 'Merging streams of work' ?
   94.14 -La fusion\footnote{NdT: Je garde fusion mais le jargon professionnel 
   94.15 -emploiera généralement le terme \textit{merge}.} est un aspect 
   94.16 -fondamental lorsqu'on travaille avec un gestionnaire de source 
   94.17 -distribué.
   94.18 -\begin{itemize}
   94.19 -\item Alice et Bob ont chacun une copie personnelle du dépôt d'un
   94.20 -  projet sur lequel ils collaborent. Alice corrige un \textit{bug} 
   94.21 -  dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
   94.22 -  sien. Ils veulent un dépôt partagé avec à la fois le correctif du
   94.23 -  \textit{bug} et la nouvelle fonctionnalité.
   94.24 -\item Je travaille régulièrement sur plusieurs tâches différentes sur
   94.25 -  un seul projet en même temps, chacun isolé dans son propre dépôt.
   94.26 -  Travailler ainsi signifie que je dois régulièrement fusionner une 
   94.27 -  partie de mon code avec celui des autres.
   94.28 -\end{itemize}
   94.29 -
   94.30 -Parce que la fusion est une opération si commune à réaliser,
   94.31 -Mercurial la rend facile. Étudions ensemble le déroulement des opérations.
   94.32 -Nous commencerons encore par faire un clone d'un autre dépôt (vous voyez
   94.33 -que l'on fait ça tout le temps ?) puis nous ferons quelques modifications
   94.34 -dessus.
   94.35 -\interaction{tour.merge.clone}
   94.36 -Nous devrions avoir maintenant deux copies de \filename{hello.c} avec 
   94.37 -des contenus différents. Les historiques de ces deux dépôts ont aussi 
   94.38 -divergés, comme illustré dans la figure~\ref{fig:tour-merge:sep-repos}.
   94.39 -
   94.40 -\interaction{tour.merge.cat}
   94.41 -
   94.42 -\begin{figure}[ht]
   94.43 -  \centering
   94.44 -  \grafix{tour-merge-sep-repos}
   94.45 -  \caption{Historiques récent divergents des dépôts \dirname{my-hello} 
   94.46 -  et \dirname{my-new-hello}}
   94.47 -  \label{fig:tour-merge:sep-repos}
   94.48 -\end{figure}
   94.49 -
   94.50 -Nous savons déjà que récupérer les modifications depuis notre dépôt 
   94.51 -\dirname{my-hello} n'aura aucun effet sur l'espace de travail.
   94.52 -
   94.53 -\interaction{tour.merge.pull}
   94.54 -
   94.55 -Néanmoins, la commande \hgcmd{pull} nous indique quelque chose au 
   94.56 -sujet des ``heads''.
   94.57 -
   94.58 -\subsection{\textit{Head changesets}} %%%TODO: Hard (too?) to translate
   94.59 -
   94.60 -Une \textit{head}\footnote{NdT: Je garde \textit{head} que j'accorde 
   94.61 -au féminin comme la coutume orale l'a imposé.} est un \textit{changeset} 
   94.62 -sans descendants, ou enfants, comme on les désigne parfois. La révision 
   94.63 -\textit{tip} est une \textit{head}, car la dernière révision dans un dépôt 
   94.64 -n'a aucun enfant, mais il est important de noter qu'un dépôt peut contenir 
   94.65 -plus d'une \textit{head}.
   94.66 -
   94.67 -\begin{figure}[ht]
   94.68 -  \centering
   94.69 -  \grafix{tour-merge-pull}
   94.70 -  \caption{Contenu d'un dépôt après avoir transféré le contenu du dépôt 
   94.71 -    \dirname{my-hello} dans le dépôt \dirname{my-new-hello}}
   94.72 -  \label{fig:tour-merge:pull}
   94.73 -\end{figure}
   94.74 -
   94.75 -Dans la figure~\ref{fig:tour-merge:pull}, vous pouvez constater l'effet
   94.76 -d'un \textit{pull} depuis le dépôt \dirname{my-hello} dans le dépôt 
   94.77 -\dirname{my-new-hello}. L'historique qui était déjà présent dans le dépôt
   94.78 -\dirname{my-new-hello} reste intact, mais une nouvelle révision a été 
   94.79 -ajoutée. En vous reportant à la figure~\ref{fig:tour-merge:sep-repos},
   94.80 -vous pouvez voir que le \textit{\emph{changeset ID}} reste le même dans
   94.81 -le nouveau dépôt, mais que le \emph{numéro de révision} reste le même.
   94.82 -(Ceci est un parfait exemple de pourquoi il n'est fiable d'utiliser les
   94.83 -numéros de révision lorsque l'on discute d'un \textit{changeset}.) Vous
   94.84 -pouvez voir les \texit{heads} présentes dans le dépôt en utilisant la 
   94.85 -commande \hgcmd{heads}.
   94.86 -\interaction{tour.merge.heads}
   94.87 -
   94.88 -\subsection{Effectuer la fusion}
   94.89 -
   94.90 -Que se passe-t-il quand vous essayez d'utiliser la commande \hgcmd{update} 
   94.91 -pour mettre à jour votre espace de travail au nouveau \textit{tip}.
   94.92 -\interaction{tour.merge.update}
   94.93 -Mercurial nous prévient que la commande \hgcmd{update} n'effectuera pas
   94.94 -la fusion, il ne veut pas mettre à jour l'espace de travail quand il 
   94.95 -estime que nous pourrions avoir besoin d'une fusion, à moins de lui
   94.96 -forcer la main. À la place, il faut utiliser la commande \hgcmd{merge}
   94.97 -pour fusionner les deux \textit{heads}.
   94.98 -\interaction{tour.merge.merge}
   94.99 -
  94.100 -\begin{figure}[ht]
  94.101 -  \centering
  94.102 -  \grafix{tour-merge-merge}
  94.103 -  \caption{Espace de travail et dépôt lors d'une fusion, et dans le
  94.104 -    \textit{commit} qui suit.}
  94.105 -  \label{fig:tour-merge:merge}
  94.106 -\end{figure}
  94.107 -
  94.108 -Ceci met à jour l'espace de travail de manière à ce qu'il contienne
  94.109 -les modifications des \emph{deux} \textit{heads}, ce qui apparaît dans
  94.110 -les sorties de la commande \hgcmd{parents} et le contenu de 
  94.111 -\filename{hello.c}. 
  94.112 -\interaction{tour.merge.parents}
  94.113 -
  94.114 -\subsection{Effectuer le \textit{commit} du résultat de la fusion}
  94.115 -
  94.116 -Dès l'instant où vous avez effectué une fusion, \hgcmd{parents} vous
  94.117 -affichera deux parents, avant que vous n'exécutiez la commande 
  94.118 -\hgcmd{commit} sur le résultat de la fusion.
  94.119 -\interaction{tour.merge.commit}
  94.120 -Nous avons maintenant un nouveau \textit{tip}, remarquer qu'il contient
  94.121 -\emph{à la fois} nos anciennes \textit{heads} et leurs parents. Ce sont
  94.122 -les mêmes révisions que nous avions affichées avec la commande 
  94.123 -\hgcmd{parents}.
  94.124 -
  94.125 -\interaction{tour.merge.tip}
  94.126 -Dans la figure~\ref{fig:tour-merge:merge}, vous pouvez voir une représentation
  94.127 -de ce qui se passe dans l'espace de travail pendant la fusion, et comment ceci
  94.128 -affecte le dépôt lors du \textit{commit}. Pendant la fusion, l'espace de travail,
  94.129 -qui a deux \texit{changesets} comme parents, voit ces derniers devenir le parent
  94.130 -%%% TODO: le parent ou "les parents" : plus logique mais si il reste seulement 
  94.131 -%%% un changeset, alors c'est effectivement un parent (le changeset est hermaphrodite)
  94.132 -d'un nouveau \textit{changeset}.
  94.133 -
  94.134 -\section{Fusionner les modifications en conflit}
  94.135 -
  94.136 -La plupart des fusions sont assez simple à réaliser, mais parfois 
  94.137 -vous vous retrouverez à fusionner des fichiers où la modification touche
  94.138 -la même portion de code, au sein d'un même fichier. À moins que ces
  94.139 -modification ne soient identiques, ceci aboutira à un \emph{conflit},
  94.140 -et vous devrez décider comment réconcilier les différentes modifications
  94.141 -dans un tout cohérent. 
  94.142 -
  94.143 -\begin{figure}[ht]
  94.144 -  \centering
  94.145 -  \grafix{tour-merge-conflict}
  94.146 -  \caption{Modifications conflictuelles dans un document}
  94.147 -  \label{fig:tour-merge:conflict}
  94.148 -\end{figure}
  94.149 -
  94.150 -La figure~\ref{fig:tour-merge:conflict} illustre un cas de modifications
  94.151 -conflictuelles dans un document. Nous avons commencé avec une version simple
  94.152 -de ce fichier, puis nous avons ajouté des modifications, pendant que 
  94.153 -quelqu'un d'autre modifiait le même texte. Notre tâche dans la résolution
  94.154 -du conflit est de décider à quoi le fichier devrait ressembler.
  94.155 -
  94.156 -Mercurial n'a pas de mécanisme interne pour gérer les conflits. 
  94.157 -À la place, il exécute un programme externe appelé \command{hgmerge}.
  94.158 -Il s'agit d'un script shell qui est embarqué par Mercurial, vous
  94.159 -pouvez le modifier si vous le voulez. Ce qu'il fait par défaut est
  94.160 -d'essayer de trouver un des différents outils de fusion qui seront
  94.161 -probablement installés sur le système. Il commence par les outils
  94.162 -totalement automatiques, et si ils échouent (parce que la résolution
  94.163 -du conflit nécessite une intervention humaine) ou si ils sont absents,
  94.164 -le script tente d'exécuter certains outils graphiques de fusion.
  94.165 -
  94.166 -Il est aussi possible de demander à Mercurial d'exécuter un autre
  94.167 -programme ou un autre script au lieu de la commande \command{hgmerge},
  94.168 -en définissant la variable d'environnement \envar{HGMERGE} avec le nom
  94.169 -du programme de votre choix.
  94.170 -
  94.171 -\subsection{Utiliser un outil graphique de fusion}
  94.172 -
  94.173 -Mon outil de fusion préféré est \command{kdiff3}, que j'utilise ici
  94.174 -pour illustrer les fonctionnalités classiques des outils graphiques 
  94.175 -de fusion. Vous pouvez voir une capture d'écran de l'utilisation de 
  94.176 -\command{kdiff3} dans la figure~\ref{fig:tour-merge:kdiff3}. Cet outil
  94.177 -effectue une \emph{fusion \textit{three-way}}, car il y a trois différentes
  94.178 -versions du fichier qui nous intéresse. Le fichier découpe la partie
  94.179 -supérieure de la fenêtre en trois panneaux:
  94.180 -
  94.181 -\begin{itemize}
  94.182 -\item A gauche on la version de \emph{base} du fichier, soit la plus 
  94.183 -  récente version des deux versions qu'on souhaite fusionner.
  94.184 -\item Au centre, il y a ``notre'' version du fichier, avec le contenu 
  94.185 -  que nous avons modifié.
  94.186 -\item Sur la droite, on trouve ``leur'' version du fichier, celui qui
  94.187 -  contient le \textit{changeset} que nous souhaitons intégré. 
  94.188 -\end{itemize}
  94.189 -
  94.190 -Dans le panneau en dessous, on trouve le \emph{résultat} actuel de notre
  94.191 -fusion. Notre tâche consiste donc à remplacement tous les textes en rouges,
  94.192 -qui indiquent des conflits non résolus, avec une fusion manuelle et pertinente
  94.193 -de ``notre'' version et de la ``leur''. 
  94.194 -
  94.195 -Tous les quatre panneaux sont \emph{accrochés ensemble}, si nous déroulons
  94.196 -les ascenseurs verticalement ou horizontalement dans chacun d'entre eux, les
  94.197 -autres sont mis à jour avec la section correspondante dans leurs fichiers
  94.198 -respectifs.
  94.199 -
  94.200 -\begin{figure}[ht]
  94.201 -  \centering
  94.202 -  \grafix{kdiff3}
  94.203 -  \caption{Utilisation de \command{kdiff3} pour fusionner différentes versions
  94.204 -  d'un fichier.}
  94.205 -  \label{fig:tour-merge:kdiff3}
  94.206 -\end{figure}
  94.207 -
  94.208 -Pour chaque portion de fichier posant problème, nous pouvons choisir 
  94.209 -de résoudre le conflit en utilisant une combinaison 
  94.210 -de texte depuis la version de base, la notre, ou la leur. Nous pouvons 
  94.211 -aussi éditer manuellement les fichiers à tout moment, si c'est
  94.212 -nécessaire.
  94.213 -
  94.214 -Il y a \emph{beaucoup} d'outils de fusion disponibles, bien trop pour
  94.215 -en parler de tous ici. Leurs disponibilités varient selon les plate formes
  94.216 -ainsi que leurs avantages et inconvénients. La plupart sont optimisé pour
  94.217 -la fusion de fichier contenant un texte plat, certains sont spécialisé
  94.218 -dans un format de fichier précis (généralement XML).
  94.219 -
  94.220 -\subsection{Un exemple concret}
  94.221 -
  94.222 -Dans cet exemple, nous allons reproduire la modification de l'historique
  94.223 -du fichier de la figure~\ref{fig:tour-merge:conflict} ci dessus. Commençons
  94.224 -par créer un dépôt avec une version de base de notre document.
  94.225 -
  94.226 -\interaction{tour-merge-conflict.wife}
  94.227 -Créons un clone de ce dépôt et faisons une modification dans le fichier.
  94.228 -\interaction{tour-merge-conflict.cousin}
  94.229 -Et un autre clone, pour simuler que quelqu'un d'autre effectue une
  94.230 -modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
  94.231 -de devoir effectuer des \textit{merge} avec vos propres travaux quand 
  94.232 -vous isolez les tâches dans des dépôts distincts. En effet, vous 
  94.233 -aurez alors à trouver et résoudre certains conflits).
  94.234 -\interaction{tour-merge-conflict.son}
  94.235 -Maintenant que ces deux versions différentes du même fichier sont 
  94.236 -créées, nous allons configurer l'environnement de manière appropriée pour
  94.237 -exécuter notre \textit{merge}.
  94.238 -\interaction{tour-merge-conflict.pull}
  94.239 -
  94.240 -Dans cette exemple, je n'utiliserais pas la commande Mercurial
  94.241 -habituelle \command{hgmerge} pour effectuer le \textit{merge},
  94.242 -car il me faudrait abandonner ce joli petit exemple automatisé
  94.243 -pour utiliser un outil graphique. À la place, je vais définir
  94.244 -la variable d'environnement \envar{HGMERGE} pour indiquer à 
  94.245 -Mercurial d'utiliser la commande non-interactive \command{merge}.
  94.246 -Cette dernière est embarquée par de nombreux systèmes ``à la Unix''.
  94.247 -Si vous exécutez cet exemple depuis votre ordinateur, ne vous
  94.248 -occupez pas de définir \envar{HGMERGE}.
  94.249 -\interaction{tour-merge-conflict.merge}
  94.250 -Parce que \command{merge} ne peut pas résoudre les modifications
  94.251 -conflictuelles, il laisse des \emph{marqueurs de différences}
  94.252 -\footnote{NdT: Oui, je traduis \textit{merge markers} par un sens
  94.253 -inverse en Français, mais je pense vraiment que c'est plus clair 
  94.254 -comme ça...} à l'intérieur du fichier qui a des conflits, indiquant
  94.255 -clairement quelles lignes sont en conflits, et si elles viennent de
  94.256 -notre fichier ou du fichier externe.
  94.257 -
  94.258 -Mercurial peut distinguer, à la manière dont la commande \command{merge}
  94.259 -se termine, qu'elle n'a pas été capable d'effectuer le \textit{merge},
  94.260 -alors il nous indique que nous devons effectuer de nouveau cette
  94.261 -opération. Ceci peut être très utile si, par exemple, nous exécutons un
  94.262 -outil graphique de fusion et que nous le quittons sans nous rendre compte
  94.263 -qu'il reste des conflits ou simplement par erreur.
  94.264 -
  94.265 -Si le \textit{merge} automatique ou manuel échoue, il n'y a rien pour
  94.266 -nous empêcher de ``corriger le tir'' en modifiant nous même les fichiers,
  94.267 -et enfin effectuer le \textit{commit} du fichier:
  94.268 -\interaction{tour-merge-conflict.commit}
  94.269 -
  94.270 -\section{Simplification de la séquence pull-merge-commit}
  94.271 -\label{sec:tour-merge:fetch}
  94.272 -
  94.273 -La procédure pour effectuer la fusion indiquée ci-dessus est simple,
  94.274 -mais requiert le lancement de trois commandes à la suite.
  94.275 -\begin{codesample2}
  94.276 -  hg pull
  94.277 -  hg merge
  94.278 -  hg commit -m 'Merged remote changes'
  94.279 -\end{codesample2}
  94.280 -
  94.281 -Lors du \textit{commit} final, vous devez également saisir un message,
  94.282 -qui aura vraisemblablement assez peu d'intérêt.
  94.283 -
  94.284 -Il serait assez sympathique de pouvoir réduire le nombre d'opérations
  94.285 -nécessaire, si possible. De fait Mercurial est fourni avec une
  94.286 -extension appelé \hgext{fetch} qui fait justement cela.
  94.287 -
  94.288 -Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
  94.289 -d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
  94.290 -léger et facile à utiliser. Certains extensions ajoutent de nouvelles
  94.291 -commandes que vous pouvez utiliser en ligne de commande, alors que
  94.292 -d'autres travaillent ``en coulisse,'' par exemple en ajoutant des
  94.293 -possibilités au serveur.
  94.294 -
  94.295 -L'extension \hgext{fetch} ajoute une nouvelle commande nommée, sans
  94.296 -surprise, \hgcmd{fetch}. Cette extension résulte en une combinaison
  94.297 -de \hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}. Elle commence par
  94.298 -récupérer les modifications d'un autre dépôt dans le dépôt courant.
  94.299 -Si elle trouve que les modifications ajoutent une nouvelle \textit{head},
  94.300 -elle effectue un \textit{merge}, et ensuite \texit{commit} le résultat
  94.301 -du \textit{merge} avec un message généré automatiquement. Si aucune
  94.302 -\textit{head} n'ont été ajouté, elle met à jour le répertoire de travail
  94.303 -au niveau du nouveau \textit{changeset} \textit{tip}.
  94.304 -
  94.305 -
  94.306 -Activer l'extension \hgext{fetch} est facile. Modifiez votre \sfilename{.hgrc},
  94.307 -et soit allez à la section \rcsection{extensions} soit créer une 
  94.308 -section \rcsection{extensions}. Ensuite ajoutez une ligne qui consiste
  94.309 -simplement en ``\Verb+fetch =''.
  94.310 -
  94.311 -\begin{codesample2}
  94.312 -  [extensions]
  94.313 -  fetch =
  94.314 -\end{codesample2}
  94.315 -(Normalement, sur la partie droite de ``\texttt{=}'' devrait apparaître
  94.316 -le chemin de l'extension, mais étant donné que l'extension \hgext{fetch}
  94.317 -fait partie de la distribution standard, Mercurial sait où la trouver.)
  94.318 -
  94.319 -%%% Local Variables: 
  94.320 -%%% mode: latex
  94.321 -%%% TeX-master: "00book"
  94.322 -%%% End: 
    95.1 --- a/fr/undo-manual-merge.dot	Sun Aug 16 03:41:39 2009 +0200
    95.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.3 @@ -1,8 +0,0 @@
    95.4 -digraph undo_manual {
    95.5 -	"first change" -> "second change";
    95.6 -	"second change" -> "third change";
    95.7 -	backout [label="back out\nsecond change", shape=box];
    95.8 -	"second change" -> backout;
    95.9 -	"third change" -> "manual\nmerge";
   95.10 -	backout -> "manual\nmerge";
   95.11 -}
    96.1 --- a/fr/undo-manual.dot	Sun Aug 16 03:41:39 2009 +0200
    96.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.3 @@ -1,6 +0,0 @@
    96.4 -digraph undo_manual {
    96.5 -	"first change" -> "second change";
    96.6 -	"second change" -> "third change";
    96.7 -	backout [label="back out\nsecond change", shape=box];
    96.8 -	"second change" -> backout;
    96.9 -}
    97.1 --- a/fr/undo-non-tip.dot	Sun Aug 16 03:41:39 2009 +0200
    97.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.3 @@ -1,9 +0,0 @@
    97.4 -digraph undo_non_tip {
    97.5 -	"first change" -> "second change";
    97.6 -	"second change" -> "third change";
    97.7 -	backout [label="back out\nsecond change", shape=box];
    97.8 -	"second change" -> backout;
    97.9 -	merge [label="automated\nmerge", shape=box];
   97.10 -	"third change" -> merge;
   97.11 -	backout -> merge;
   97.12 -}
    98.1 --- a/fr/undo-simple.dot	Sun Aug 16 03:41:39 2009 +0200
    98.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.3 @@ -1,4 +0,0 @@
    98.4 -digraph undo_simple {
    98.5 -	"first change" -> "second change";
    98.6 -	"second change" -> "back out\nsecond change";
    98.7 -}
    99.1 --- a/fr/undo.tex	Sun Aug 16 03:41:39 2009 +0200
    99.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.3 @@ -1,767 +0,0 @@
    99.4 -\chapter{Finding and fixing your mistakes}
    99.5 -\label{chap:undo}
    99.6 -
    99.7 -To err might be human, but to really handle the consequences well
    99.8 -takes a top-notch revision control system.  In this chapter, we'll
    99.9 -discuss some of the techniques you can use when you find that a
   99.10 -problem has crept into your project.  Mercurial has some highly
   99.11 -capable features that will help you to isolate the sources of
   99.12 -problems, and to handle them appropriately.
   99.13 -
   99.14 -\section{Erasing local history}
   99.15 -
   99.16 -\subsection{The accidental commit}
   99.17 -
   99.18 -I have the occasional but persistent problem of typing rather more
   99.19 -quickly than I can think, which sometimes results in me committing a
   99.20 -changeset that is either incomplete or plain wrong.  In my case, the
   99.21 -usual kind of incomplete changeset is one in which I've created a new
   99.22 -source file, but forgotten to \hgcmd{add} it.  A ``plain wrong''
   99.23 -changeset is not as common, but no less annoying.
   99.24 -
   99.25 -\subsection{Rolling back a transaction}
   99.26 -\label{sec:undo:rollback}
   99.27 -
   99.28 -In section~\ref{sec:concepts:txn}, I mentioned that Mercurial treats
   99.29 -each modification of a repository as a \emph{transaction}.  Every time
   99.30 -you commit a changeset or pull changes from another repository,
   99.31 -Mercurial remembers what you did.  You can undo, or \emph{roll back},
   99.32 -exactly one of these actions using the \hgcmd{rollback} command.  (See
   99.33 -section~\ref{sec:undo:rollback-after-push} for an important caveat
   99.34 -about the use of this command.)
   99.35 -
   99.36 -Here's a mistake that I often find myself making: committing a change
   99.37 -in which I've created a new file, but forgotten to \hgcmd{add} it.
   99.38 -\interaction{rollback.commit}
   99.39 -Looking at the output of \hgcmd{status} after the commit immediately
   99.40 -confirms the error.
   99.41 -\interaction{rollback.status}
   99.42 -The commit captured the changes to the file \filename{a}, but not the
   99.43 -new file \filename{b}.  If I were to push this changeset to a
   99.44 -repository that I shared with a colleague, the chances are high that
   99.45 -something in \filename{a} would refer to \filename{b}, which would not
   99.46 -be present in their repository when they pulled my changes.  I would
   99.47 -thus become the object of some indignation.
   99.48 -
   99.49 -However, luck is with me---I've caught my error before I pushed the
   99.50 -changeset.  I use the \hgcmd{rollback} command, and Mercurial makes
   99.51 -that last changeset vanish.
   99.52 -\interaction{rollback.rollback}
   99.53 -Notice that the changeset is no longer present in the repository's
   99.54 -history, and the working directory once again thinks that the file
   99.55 -\filename{a} is modified.  The commit and rollback have left the
   99.56 -working directory exactly as it was prior to the commit; the changeset
   99.57 -has been completely erased.  I can now safely \hgcmd{add} the file
   99.58 -\filename{b}, and rerun my commit.
   99.59 -\interaction{rollback.add}
   99.60 -
   99.61 -\subsection{The erroneous pull}
   99.62 -
   99.63 -It's common practice with Mercurial to maintain separate development
   99.64 -branches of a project in different repositories.  Your development
   99.65 -team might have one shared repository for your project's ``0.9''
   99.66 -release, and another, containing different changes, for the ``1.0''
   99.67 -release.
   99.68 -
   99.69 -Given this, you can imagine that the consequences could be messy if
   99.70 -you had a local ``0.9'' repository, and accidentally pulled changes
   99.71 -from the shared ``1.0'' repository into it.  At worst, you could be
   99.72 -paying insufficient attention, and push those changes into the shared
   99.73 -``0.9'' tree, confusing your entire team (but don't worry, we'll
   99.74 -return to this horror scenario later).  However, it's more likely that
   99.75 -you'll notice immediately, because Mercurial will display the URL it's
   99.76 -pulling from, or you will see it pull a suspiciously large number of
   99.77 -changes into the repository.
   99.78 -
   99.79 -The \hgcmd{rollback} command will work nicely to expunge all of the
   99.80 -changesets that you just pulled.  Mercurial groups all changes from
   99.81 -one \hgcmd{pull} into a single transaction, so one \hgcmd{rollback} is
   99.82 -all you need to undo this mistake.
   99.83 -
   99.84 -\subsection{Rolling back is useless once you've pushed}
   99.85 -\label{sec:undo:rollback-after-push}
   99.86 -
   99.87 -The value of the \hgcmd{rollback} command drops to zero once you've
   99.88 -pushed your changes to another repository.  Rolling back a change
   99.89 -makes it disappear entirely, but \emph{only} in the repository in
   99.90 -which you perform the \hgcmd{rollback}.  Because a rollback eliminates
   99.91 -history, there's no way for the disappearance of a change to propagate
   99.92 -between repositories.
   99.93 -
   99.94 -If you've pushed a change to another repository---particularly if it's
   99.95 -a shared repository---it has essentially ``escaped into the wild,''
   99.96 -and you'll have to recover from your mistake in a different way.  What
   99.97 -will happen if you push a changeset somewhere, then roll it back, then
   99.98 -pull from the repository you pushed to, is that the changeset will
   99.99 -reappear in your repository.
  99.100 -
  99.101 -(If you absolutely know for sure that the change you want to roll back
  99.102 -is the most recent change in the repository that you pushed to,
  99.103 -\emph{and} you know that nobody else could have pulled it from that
  99.104 -repository, you can roll back the changeset there, too, but you really
  99.105 -should really not rely on this working reliably.  If you do this,
  99.106 -sooner or later a change really will make it into a repository that
  99.107 -you don't directly control (or have forgotten about), and come back to
  99.108 -bite you.)
  99.109 -
  99.110 -\subsection{You can only roll back once}
  99.111 -
  99.112 -Mercurial stores exactly one transaction in its transaction log; that
  99.113 -transaction is the most recent one that occurred in the repository.
  99.114 -This means that you can only roll back one transaction.  If you expect
  99.115 -to be able to roll back one transaction, then its predecessor, this is
  99.116 -not the behaviour you will get.
  99.117 -\interaction{rollback.twice}
  99.118 -Once you've rolled back one transaction in a repository, you can't
  99.119 -roll back again in that repository until you perform another commit or
  99.120 -pull.
  99.121 -
  99.122 -\section{Reverting the mistaken change}
  99.123 -
  99.124 -If you make a modification to a file, and decide that you really
  99.125 -didn't want to change the file at all, and you haven't yet committed
  99.126 -your changes, the \hgcmd{revert} command is the one you'll need.  It
  99.127 -looks at the changeset that's the parent of the working directory, and
  99.128 -restores the contents of the file to their state as of that changeset.
  99.129 -(That's a long-winded way of saying that, in the normal case, it
  99.130 -undoes your modifications.)
  99.131 -
  99.132 -Let's illustrate how the \hgcmd{revert} command works with yet another
  99.133 -small example.  We'll begin by modifying a file that Mercurial is
  99.134 -already tracking.
  99.135 -\interaction{daily.revert.modify}
  99.136 -If we don't want that change, we can simply \hgcmd{revert} the file.
  99.137 -\interaction{daily.revert.unmodify}
  99.138 -The \hgcmd{revert} command provides us with an extra degree of safety
  99.139 -by saving our modified file with a \filename{.orig} extension.
  99.140 -\interaction{daily.revert.status}
  99.141 -
  99.142 -Here is a summary of the cases that the \hgcmd{revert} command can
  99.143 -deal with.  We will describe each of these in more detail in the
  99.144 -section that follows.
  99.145 -\begin{itemize}
  99.146 -\item If you modify a file, it will restore the file to its unmodified
  99.147 -  state.
  99.148 -\item If you \hgcmd{add} a file, it will undo the ``added'' state of
  99.149 -  the file, but leave the file itself untouched.
  99.150 -\item If you delete a file without telling Mercurial, it will restore
  99.151 -  the file to its unmodified contents.
  99.152 -\item If you use the \hgcmd{remove} command to remove a file, it will
  99.153 -  undo the ``removed'' state of the file, and restore the file to its
  99.154 -  unmodified contents.
  99.155 -\end{itemize}
  99.156 -
  99.157 -\subsection{File management errors}
  99.158 -\label{sec:undo:mgmt}
  99.159 -
  99.160 -The \hgcmd{revert} command is useful for more than just modified
  99.161 -files.  It lets you reverse the results of all of Mercurial's file
  99.162 -management commands---\hgcmd{add}, \hgcmd{remove}, and so on.
  99.163 -
  99.164 -If you \hgcmd{add} a file, then decide that in fact you don't want
  99.165 -Mercurial to track it, use \hgcmd{revert} to undo the add.  Don't
  99.166 -worry; Mercurial will not modify the file in any way.  It will just
  99.167 -``unmark'' the file.
  99.168 -\interaction{daily.revert.add}
  99.169 -
  99.170 -Similarly, if you ask Mercurial to \hgcmd{remove} a file, you can use
  99.171 -\hgcmd{revert} to restore it to the contents it had as of the parent
  99.172 -of the working directory.
  99.173 -\interaction{daily.revert.remove}
  99.174 -This works just as well for a file that you deleted by hand, without
  99.175 -telling Mercurial (recall that in Mercurial terminology, this kind of
  99.176 -file is called ``missing'').
  99.177 -\interaction{daily.revert.missing}
  99.178 -
  99.179 -If you revert a \hgcmd{copy}, the copied-to file remains in your
  99.180 -working directory afterwards, untracked.  Since a copy doesn't affect
  99.181 -the copied-from file in any way, Mercurial doesn't do anything with
  99.182 -the copied-from file.
  99.183 -\interaction{daily.revert.copy}
  99.184 -
  99.185 -\subsubsection{A slightly special case: reverting a rename}
  99.186 -
  99.187 -If you \hgcmd{rename} a file, there is one small detail that
  99.188 -you should remember.  When you \hgcmd{revert} a rename, it's not
  99.189 -enough to provide the name of the renamed-to file, as you can see
  99.190 -here.
  99.191 -\interaction{daily.revert.rename}
  99.192 -As you can see from the output of \hgcmd{status}, the renamed-to file
  99.193 -is no longer identified as added, but the renamed-\emph{from} file is
  99.194 -still removed!  This is counter-intuitive (at least to me), but at
  99.195 -least it's easy to deal with.
  99.196 -\interaction{daily.revert.rename-orig}
  99.197 -So remember, to revert a \hgcmd{rename}, you must provide \emph{both}
  99.198 -the source and destination names.  
  99.199 -
  99.200 -% TODO: the output doesn't look like it will be removed!
  99.201 -
  99.202 -(By the way, if you rename a file, then modify the renamed-to file,
  99.203 -then revert both components of the rename, when Mercurial restores the
  99.204 -file that was removed as part of the rename, it will be unmodified.
  99.205 -If you need the modifications in the renamed-to file to show up in the
  99.206 -renamed-from file, don't forget to copy them over.)
  99.207 -
  99.208 -These fiddly aspects of reverting a rename arguably constitute a small
  99.209 -bug in Mercurial.
  99.210 -
  99.211 -\section{Dealing with committed changes}
  99.212 -
  99.213 -Consider a case where you have committed a change $a$, and another
  99.214 -change $b$ on top of it; you then realise that change $a$ was
  99.215 -incorrect.  Mercurial lets you ``back out'' an entire changeset
  99.216 -automatically, and building blocks that let you reverse part of a
  99.217 -changeset by hand.
  99.218 -
  99.219 -Before you read this section, here's something to keep in mind: the
  99.220 -\hgcmd{backout} command undoes changes by \emph{adding} history, not
  99.221 -by modifying or erasing it.  It's the right tool to use if you're
  99.222 -fixing bugs, but not if you're trying to undo some change that has
  99.223 -catastrophic consequences.  To deal with those, see
  99.224 -section~\ref{sec:undo:aaaiiieee}.
  99.225 -
  99.226 -\subsection{Backing out a changeset}
  99.227 -
  99.228 -The \hgcmd{backout} command lets you ``undo'' the effects of an entire
  99.229 -changeset in an automated fashion.  Because Mercurial's history is
  99.230 -immutable, this command \emph{does not} get rid of the changeset you
  99.231 -want to undo.  Instead, it creates a new changeset that
  99.232 -\emph{reverses} the effect of the to-be-undone changeset.
  99.233 -
  99.234 -The operation of the \hgcmd{backout} command is a little intricate, so
  99.235 -let's illustrate it with some examples.  First, we'll create a
  99.236 -repository with some simple changes.
  99.237 -\interaction{backout.init}
  99.238 -
  99.239 -The \hgcmd{backout} command takes a single changeset ID as its
  99.240 -argument; this is the changeset to back out.  Normally,
  99.241 -\hgcmd{backout} will drop you into a text editor to write a commit
  99.242 -message, so you can record why you're backing the change out.  In this
  99.243 -example, we provide a commit message on the command line using the
  99.244 -\hgopt{backout}{-m} option.
  99.245 -
  99.246 -\subsection{Backing out the tip changeset}
  99.247 -
  99.248 -We're going to start by backing out the last changeset we committed.
  99.249 -\interaction{backout.simple}
  99.250 -You can see that the second line from \filename{myfile} is no longer
  99.251 -present.  Taking a look at the output of \hgcmd{log} gives us an idea
  99.252 -of what the \hgcmd{backout} command has done.
  99.253 -\interaction{backout.simple.log}
  99.254 -Notice that the new changeset that \hgcmd{backout} has created is a
  99.255 -child of the changeset we backed out.  It's easier to see this in
  99.256 -figure~\ref{fig:undo:backout}, which presents a graphical view of the
  99.257 -change history.  As you can see, the history is nice and linear.
  99.258 -
  99.259 -\begin{figure}[htb]
  99.260 -  \centering
  99.261 -  \grafix{undo-simple}
  99.262 -  \caption{Backing out a change using the \hgcmd{backout} command}
  99.263 -  \label{fig:undo:backout}
  99.264 -\end{figure}
  99.265 -
  99.266 -\subsection{Backing out a non-tip change}
  99.267 -
  99.268 -If you want to back out a change other than the last one you
  99.269 -committed, pass the \hgopt{backout}{--merge} option to the
  99.270 -\hgcmd{backout} command.
  99.271 -\interaction{backout.non-tip.clone}
  99.272 -This makes backing out any changeset a ``one-shot'' operation that's
  99.273 -usually simple and fast.
  99.274 -\interaction{backout.non-tip.backout}
  99.275 -
  99.276 -If you take a look at the contents of \filename{myfile} after the
  99.277 -backout finishes, you'll see that the first and third changes are
  99.278 -present, but not the second.
  99.279 -\interaction{backout.non-tip.cat}
  99.280 -
  99.281 -As the graphical history in figure~\ref{fig:undo:backout-non-tip}
  99.282 -illustrates, Mercurial actually commits \emph{two} changes in this
  99.283 -kind of situation (the box-shaped nodes are the ones that Mercurial
  99.284 -commits automatically).  Before Mercurial begins the backout process,
  99.285 -it first remembers what the current parent of the working directory
  99.286 -is.  It then backs out the target changeset, and commits that as a
  99.287 -changeset.  Finally, it merges back to the previous parent of the
  99.288 -working directory, and commits the result of the merge.
  99.289 -
  99.290 -% TODO: to me it looks like mercurial doesn't commit the second merge automatically!
  99.291 -
  99.292 -\begin{figure}[htb]
  99.293 -  \centering
  99.294 -  \grafix{undo-non-tip}
  99.295 -  \caption{Automated backout of a non-tip change using the \hgcmd{backout} command}
  99.296 -  \label{fig:undo:backout-non-tip}
  99.297 -\end{figure}
  99.298 -
  99.299 -The result is that you end up ``back where you were'', only with some
  99.300 -extra history that undoes the effect of the changeset you wanted to
  99.301 -back out.
  99.302 -
  99.303 -\subsubsection{Always use the \hgopt{backout}{--merge} option}
  99.304 -
  99.305 -In fact, since the \hgopt{backout}{--merge} option will do the ``right
  99.306 -thing'' whether or not the changeset you're backing out is the tip
  99.307 -(i.e.~it won't try to merge if it's backing out the tip, since there's
  99.308 -no need), you should \emph{always} use this option when you run the
  99.309 -\hgcmd{backout} command.
  99.310 -
  99.311 -\subsection{Gaining more control of the backout process}
  99.312 -
  99.313 -While I've recommended that you always use the
  99.314 -\hgopt{backout}{--merge} option when backing out a change, the
  99.315 -\hgcmd{backout} command lets you decide how to merge a backout
  99.316 -changeset.  Taking control of the backout process by hand is something
  99.317 -you will rarely need to do, but it can be useful to understand what
  99.318 -the \hgcmd{backout} command is doing for you automatically.  To
  99.319 -illustrate this, let's clone our first repository, but omit the
  99.320 -backout change that it contains.
  99.321 -
  99.322 -\interaction{backout.manual.clone}
  99.323 -As with our earlier example, We'll commit a third changeset, then back
  99.324 -out its parent, and see what happens.
  99.325 -\interaction{backout.manual.backout} 
  99.326 -Our new changeset is again a descendant of the changeset we backout
  99.327 -out; it's thus a new head, \emph{not} a descendant of the changeset
  99.328 -that was the tip.  The \hgcmd{backout} command was quite explicit in
  99.329 -telling us this.
  99.330 -\interaction{backout.manual.log}
  99.331 -
  99.332 -Again, it's easier to see what has happened by looking at a graph of
  99.333 -the revision history, in figure~\ref{fig:undo:backout-manual}.  This
  99.334 -makes it clear that when we use \hgcmd{backout} to back out a change
  99.335 -other than the tip, Mercurial adds a new head to the repository (the
  99.336 -change it committed is box-shaped).
  99.337 -
  99.338 -\begin{figure}[htb]
  99.339 -  \centering
  99.340 -  \grafix{undo-manual}
  99.341 -  \caption{Backing out a change using the \hgcmd{backout} command}
  99.342 -  \label{fig:undo:backout-manual}
  99.343 -\end{figure}
  99.344 -
  99.345 -After the \hgcmd{backout} command has completed, it leaves the new
  99.346 -``backout'' changeset as the parent of the working directory.
  99.347 -\interaction{backout.manual.parents}
  99.348 -Now we have two isolated sets of changes.
  99.349 -\interaction{backout.manual.heads}
  99.350 -
  99.351 -Let's think about what we expect to see as the contents of
  99.352 -\filename{myfile} now.  The first change should be present, because
  99.353 -we've never backed it out.  The second change should be missing, as
  99.354 -that's the change we backed out.  Since the history graph shows the
  99.355 -third change as a separate head, we \emph{don't} expect to see the
  99.356 -third change present in \filename{myfile}.
  99.357 -\interaction{backout.manual.cat}
  99.358 -To get the third change back into the file, we just do a normal merge
  99.359 -of our two heads.
  99.360 -\interaction{backout.manual.merge}
  99.361 -Afterwards, the graphical history of our repository looks like
  99.362 -figure~\ref{fig:undo:backout-manual-merge}.
  99.363 -
  99.364 -\begin{figure}[htb]
  99.365 -  \centering
  99.366 -  \grafix{undo-manual-merge}
  99.367 -  \caption{Manually merging a backout change}
  99.368 -  \label{fig:undo:backout-manual-merge}
  99.369 -\end{figure}
  99.370 -
  99.371 -\subsection{Why \hgcmd{backout} works as it does}
  99.372 -
  99.373 -Here's a brief description of how the \hgcmd{backout} command works.
  99.374 -\begin{enumerate}
  99.375 -\item It ensures that the working directory is ``clean'', i.e.~that
  99.376 -  the output of \hgcmd{status} would be empty.
  99.377 -\item It remembers the current parent of the working directory.  Let's
  99.378 -  call this changeset \texttt{orig}
  99.379 -\item It does the equivalent of a \hgcmd{update} to sync the working
  99.380 -  directory to the changeset you want to back out.  Let's call this
  99.381 -  changeset \texttt{backout}
  99.382 -\item It finds the parent of that changeset.  Let's call that
  99.383 -  changeset \texttt{parent}.
  99.384 -\item For each file that the \texttt{backout} changeset affected, it
  99.385 -  does the equivalent of a \hgcmdargs{revert}{-r parent} on that file,
  99.386 -  to restore it to the contents it had before that changeset was
  99.387 -  committed.
  99.388 -\item It commits the result as a new changeset.  This changeset has
  99.389 -  \texttt{backout} as its parent.
  99.390 -\item If you specify \hgopt{backout}{--merge} on the command line, it
  99.391 -  merges with \texttt{orig}, and commits the result of the merge.
  99.392 -\end{enumerate}
  99.393 -
  99.394 -An alternative way to implement the \hgcmd{backout} command would be
  99.395 -to \hgcmd{export} the to-be-backed-out changeset as a diff, then use
  99.396 -the \cmdopt{patch}{--reverse} option to the \command{patch} command to
  99.397 -reverse the effect of the change without fiddling with the working
  99.398 -directory.  This sounds much simpler, but it would not work nearly as
  99.399 -well.
  99.400 -
  99.401 -The reason that \hgcmd{backout} does an update, a commit, a merge, and
  99.402 -another commit is to give the merge machinery the best chance to do a
  99.403 -good job when dealing with all the changes \emph{between} the change
  99.404 -you're backing out and the current tip.  
  99.405 -
  99.406 -If you're backing out a changeset that's~100 revisions back in your
  99.407 -project's history, the chances that the \command{patch} command will
  99.408 -be able to apply a reverse diff cleanly are not good, because
  99.409 -intervening changes are likely to have ``broken the context'' that
  99.410 -\command{patch} uses to determine whether it can apply a patch (if
  99.411 -this sounds like gibberish, see \ref{sec:mq:patch} for a
  99.412 -discussion of the \command{patch} command).  Also, Mercurial's merge
  99.413 -machinery will handle files and directories being renamed, permission
  99.414 -changes, and modifications to binary files, none of which
  99.415 -\command{patch} can deal with.
  99.416 -
  99.417 -\section{Changes that should never have been}
  99.418 -\label{sec:undo:aaaiiieee}
  99.419 -
  99.420 -Most of the time, the \hgcmd{backout} command is exactly what you need
  99.421 -if you want to undo the effects of a change.  It leaves a permanent
  99.422 -record of exactly what you did, both when committing the original
  99.423 -changeset and when you cleaned up after it.
  99.424 -
  99.425 -On rare occasions, though, you may find that you've committed a change
  99.426 -that really should not be present in the repository at all.  For
  99.427 -example, it would be very unusual, and usually considered a mistake,
  99.428 -to commit a software project's object files as well as its source
  99.429 -files.  Object files have almost no intrinsic value, and they're
  99.430 -\emph{big}, so they increase the size of the repository and the amount
  99.431 -of time it takes to clone or pull changes.
  99.432 -
  99.433 -Before I discuss the options that you have if you commit a ``brown
  99.434 -paper bag'' change (the kind that's so bad that you want to pull a
  99.435 -brown paper bag over your head), let me first discuss some approaches
  99.436 -that probably won't work.
  99.437 -
  99.438 -Since Mercurial treats history as accumulative---every change builds
  99.439 -on top of all changes that preceded it---you generally can't just make
  99.440 -disastrous changes disappear.  The one exception is when you've just
  99.441 -committed a change, and it hasn't been pushed or pulled into another
  99.442 -repository.  That's when you can safely use the \hgcmd{rollback}
  99.443 -command, as I detailed in section~\ref{sec:undo:rollback}.
  99.444 -
  99.445 -After you've pushed a bad change to another repository, you
  99.446 -\emph{could} still use \hgcmd{rollback} to make your local copy of the
  99.447 -change disappear, but it won't have the consequences you want.  The
  99.448 -change will still be present in the remote repository, so it will
  99.449 -reappear in your local repository the next time you pull.
  99.450 -
  99.451 -If a situation like this arises, and you know which repositories your
  99.452 -bad change has propagated into, you can \emph{try} to get rid of the
  99.453 -changeefrom \emph{every} one of those repositories.  This is, of
  99.454 -course, not a satisfactory solution: if you miss even a single
  99.455 -repository while you're expunging, the change is still ``in the
  99.456 -wild'', and could propagate further.
  99.457 -
  99.458 -If you've committed one or more changes \emph{after} the change that
  99.459 -you'd like to see disappear, your options are further reduced.
  99.460 -Mercurial doesn't provide a way to ``punch a hole'' in history,
  99.461 -leaving changesets intact.
  99.462 -
  99.463 -XXX This needs filling out.  The \texttt{hg-replay} script in the
  99.464 -\texttt{examples} directory works, but doesn't handle merge
  99.465 -changesets.  Kind of an important omission.
  99.466 -
  99.467 -\subsection{Protect yourself from ``escaped'' changes}
  99.468 -
  99.469 -If you've committed some changes to your local repository and they've
  99.470 -been pushed or pulled somewhere else, this isn't necessarily a
  99.471 -disaster.  You can protect yourself ahead of time against some classes
  99.472 -of bad changeset.  This is particularly easy if your team usually
  99.473 -pulls changes from a central repository.
  99.474 -
  99.475 -By configuring some hooks on that repository to validate incoming
  99.476 -changesets (see chapter~\ref{chap:hook}), you can automatically
  99.477 -prevent some kinds of bad changeset from being pushed to the central
  99.478 -repository at all.  With such a configuration in place, some kinds of
  99.479 -bad changeset will naturally tend to ``die out'' because they can't
  99.480 -propagate into the central repository.  Better yet, this happens
  99.481 -without any need for explicit intervention.
  99.482 -
  99.483 -For instance, an incoming change hook that verifies that a changeset
  99.484 -will actually compile can prevent people from inadvertantly ``breaking
  99.485 -the build''.
  99.486 -
  99.487 -\section{Finding the source of a bug}
  99.488 -\label{sec:undo:bisect}
  99.489 -
  99.490 -While it's all very well to be able to back out a changeset that
  99.491 -introduced a bug, this requires that you know which changeset to back
  99.492 -out.  Mercurial provides an invaluable command, called
  99.493 -\hgcmd{bisect}, that helps you to automate this process and accomplish
  99.494 -it very efficiently.
  99.495 -
  99.496 -The idea behind the \hgcmd{bisect} command is that a changeset has
  99.497 -introduced some change of behaviour that you can identify with a
  99.498 -simple binary test.  You don't know which piece of code introduced the
  99.499 -change, but you know how to test for the presence of the bug.  The
  99.500 -\hgcmd{bisect} command uses your test to direct its search for the
  99.501 -changeset that introduced the code that caused the bug.
  99.502 -
  99.503 -Here are a few scenarios to help you understand how you might apply
  99.504 -this command.
  99.505 -\begin{itemize}
  99.506 -\item The most recent version of your software has a bug that you
  99.507 -  remember wasn't present a few weeks ago, but you don't know when it
  99.508 -  was introduced.  Here, your binary test checks for the presence of
  99.509 -  that bug.
  99.510 -\item You fixed a bug in a rush, and now it's time to close the entry
  99.511 -  in your team's bug database.  The bug database requires a changeset
  99.512 -  ID when you close an entry, but you don't remember which changeset
  99.513 -  you fixed the bug in.  Once again, your binary test checks for the
  99.514 -  presence of the bug.
  99.515 -\item Your software works correctly, but runs~15\% slower than the
  99.516 -  last time you measured it.  You want to know which changeset
  99.517 -  introduced the performance regression.  In this case, your binary
  99.518 -  test measures the performance of your software, to see whether it's
  99.519 -  ``fast'' or ``slow''.
  99.520 -\item The sizes of the components of your project that you ship
  99.521 -  exploded recently, and you suspect that something changed in the way
  99.522 -  you build your project.
  99.523 -\end{itemize}
  99.524 -
  99.525 -From these examples, it should be clear that the \hgcmd{bisect}
  99.526 -command is not useful only for finding the sources of bugs.  You can
  99.527 -use it to find any ``emergent property'' of a repository (anything
  99.528 -that you can't find from a simple text search of the files in the
  99.529 -tree) for which you can write a binary test.
  99.530 -
  99.531 -We'll introduce a little bit of terminology here, just to make it
  99.532 -clear which parts of the search process are your responsibility, and
  99.533 -which are Mercurial's.  A \emph{test} is something that \emph{you} run
  99.534 -when \hgcmd{bisect} chooses a changeset.  A \emph{probe} is what
  99.535 -\hgcmd{bisect} runs to tell whether a revision is good.  Finally,
  99.536 -we'll use the word ``bisect'', as both a noun and a verb, to stand in
  99.537 -for the phrase ``search using the \hgcmd{bisect} command.
  99.538 -
  99.539 -One simple way to automate the searching process would be simply to
  99.540 -probe every changeset.  However, this scales poorly.  If it took ten
  99.541 -minutes to test a single changeset, and you had 10,000 changesets in
  99.542 -your repository, the exhaustive approach would take on average~35
  99.543 -\emph{days} to find the changeset that introduced a bug.  Even if you
  99.544 -knew that the bug was introduced by one of the last 500 changesets,
  99.545 -and limited your search to those, you'd still be looking at over 40
  99.546 -hours to find the changeset that introduced your bug.
  99.547 -
  99.548 -What the \hgcmd{bisect} command does is use its knowledge of the
  99.549 -``shape'' of your project's revision history to perform a search in
  99.550 -time proportional to the \emph{logarithm} of the number of changesets
  99.551 -to check (the kind of search it performs is called a dichotomic
  99.552 -search).  With this approach, searching through 10,000 changesets will
  99.553 -take less than three hours, even at ten minutes per test (the search
  99.554 -will require about 14 tests).  Limit your search to the last hundred
  99.555 -changesets, and it will take only about an hour (roughly seven tests).
  99.556 -
  99.557 -The \hgcmd{bisect} command is aware of the ``branchy'' nature of a
  99.558 -Mercurial project's revision history, so it has no problems dealing
  99.559 -with branches, merges, or multiple heads in a repository.  It can
  99.560 -prune entire branches of history with a single probe, which is how it
  99.561 -operates so efficiently.
  99.562 -
  99.563 -\subsection{Using the \hgcmd{bisect} command}
  99.564 -
  99.565 -Here's an example of \hgcmd{bisect} in action.
  99.566 -
  99.567 -\begin{note}
  99.568 -  In versions 0.9.5 and earlier of Mercurial, \hgcmd{bisect} was not a
  99.569 -  core command: it was distributed with Mercurial as an extension.
  99.570 -  This section describes the built-in command, not the old extension.
  99.571 -\end{note}
  99.572 -
  99.573 -Now let's create a repository, so that we can try out the
  99.574 -\hgcmd{bisect} command in isolation.
  99.575 -\interaction{bisect.init}
  99.576 -We'll simulate a project that has a bug in it in a simple-minded way:
  99.577 -create trivial changes in a loop, and nominate one specific change
  99.578 -that will have the ``bug''.  This loop creates 35 changesets, each
  99.579 -adding a single file to the repository.  We'll represent our ``bug''
  99.580 -with a file that contains the text ``i have a gub''.
  99.581 -\interaction{bisect.commits}
  99.582 -
  99.583 -The next thing that we'd like to do is figure out how to use the
  99.584 -\hgcmd{bisect} command.  We can use Mercurial's normal built-in help
  99.585 -mechanism for this.
  99.586 -\interaction{bisect.help}
  99.587 -
  99.588 -The \hgcmd{bisect} command works in steps.  Each step proceeds as follows.
  99.589 -\begin{enumerate}
  99.590 -\item You run your binary test.
  99.591 -  \begin{itemize}
  99.592 -  \item If the test succeeded, you tell \hgcmd{bisect} by running the
  99.593 -    \hgcmdargs{bisect}{good} command.
  99.594 -  \item If it failed, run the \hgcmdargs{bisect}{--bad} command.
  99.595 -  \end{itemize}
  99.596 -\item The command uses your information to decide which changeset to
  99.597 -  test next.
  99.598 -\item It updates the working directory to that changeset, and the
  99.599 -  process begins again.
  99.600 -\end{enumerate}
  99.601 -The process ends when \hgcmd{bisect} identifies a unique changeset
  99.602 -that marks the point where your test transitioned from ``succeeding''
  99.603 -to ``failing''.
  99.604 -
  99.605 -To start the search, we must run the \hgcmdargs{bisect}{--reset} command.
  99.606 -\interaction{bisect.search.init}
  99.607 -
  99.608 -In our case, the binary test we use is simple: we check to see if any
  99.609 -file in the repository contains the string ``i have a gub''.  If it
  99.610 -does, this changeset contains the change that ``caused the bug''.  By
  99.611 -convention, a changeset that has the property we're searching for is
  99.612 -``bad'', while one that doesn't is ``good''.
  99.613 -
  99.614 -Most of the time, the revision to which the working directory is
  99.615 -synced (usually the tip) already exhibits the problem introduced by
  99.616 -the buggy change, so we'll mark it as ``bad''.
  99.617 -\interaction{bisect.search.bad-init}
  99.618 -
  99.619 -Our next task is to nominate a changeset that we know \emph{doesn't}
  99.620 -have the bug; the \hgcmd{bisect} command will ``bracket'' its search
  99.621 -between the first pair of good and bad changesets.  In our case, we
  99.622 -know that revision~10 didn't have the bug.  (I'll have more words
  99.623 -about choosing the first ``good'' changeset later.)
  99.624 -\interaction{bisect.search.good-init}
  99.625 -
  99.626 -Notice that this command printed some output.
  99.627 -\begin{itemize}
  99.628 -\item It told us how many changesets it must consider before it can
  99.629 -  identify the one that introduced the bug, and how many tests that
  99.630 -  will require.
  99.631 -\item It updated the working directory to the next changeset to test,
  99.632 -  and told us which changeset it's testing.
  99.633 -\end{itemize}
  99.634 -
  99.635 -We now run our test in the working directory.  We use the
  99.636 -\command{grep} command to see if our ``bad'' file is present in the
  99.637 -working directory.  If it is, this revision is bad; if not, this
  99.638 -revision is good.
  99.639 -\interaction{bisect.search.step1}
  99.640 -
  99.641 -This test looks like a perfect candidate for automation, so let's turn
  99.642 -it into a shell function.
  99.643 -\interaction{bisect.search.mytest}
  99.644 -We can now run an entire test step with a single command,
  99.645 -\texttt{mytest}.
  99.646 -\interaction{bisect.search.step2}
  99.647 -A few more invocations of our canned test step command, and we're
  99.648 -done.
  99.649 -\interaction{bisect.search.rest}
  99.650 -
  99.651 -Even though we had~40 changesets to search through, the \hgcmd{bisect}
  99.652 -command let us find the changeset that introduced our ``bug'' with
  99.653 -only five tests.  Because the number of tests that the \hgcmd{bisect}
  99.654 -command performs grows logarithmically with the number of changesets to
  99.655 -search, the advantage that it has over the ``brute force'' search
  99.656 -approach increases with every changeset you add.
  99.657 -
  99.658 -\subsection{Cleaning up after your search}
  99.659 -
  99.660 -When you're finished using the \hgcmd{bisect} command in a
  99.661 -repository, you can use the \hgcmdargs{bisect}{reset} command to drop
  99.662 -the information it was using to drive your search.  The command
  99.663 -doesn't use much space, so it doesn't matter if you forget to run this
  99.664 -command.  However, \hgcmd{bisect} won't let you start a new search in
  99.665 -that repository until you do a \hgcmdargs{bisect}{reset}.
  99.666 -\interaction{bisect.search.reset}
  99.667 -
  99.668 -\section{Tips for finding bugs effectively}
  99.669 -
  99.670 -\subsection{Give consistent input}
  99.671 -
  99.672 -The \hgcmd{bisect} command requires that you correctly report the
  99.673 -result of every test you perform.  If you tell it that a test failed
  99.674 -when it really succeeded, it \emph{might} be able to detect the
  99.675 -inconsistency.  If it can identify an inconsistency in your reports,
  99.676 -it will tell you that a particular changeset is both good and bad.
  99.677 -However, it can't do this perfectly; it's about as likely to report
  99.678 -the wrong changeset as the source of the bug.
  99.679 -
  99.680 -\subsection{Automate as much as possible}
  99.681 -
  99.682 -When I started using the \hgcmd{bisect} command, I tried a few times
  99.683 -to run my tests by hand, on the command line.  This is an approach
  99.684 -that I, at least, am not suited to.  After a few tries, I found that I
  99.685 -was making enough mistakes that I was having to restart my searches
  99.686 -several times before finally getting correct results.
  99.687 -
  99.688 -My initial problems with driving the \hgcmd{bisect} command by hand
  99.689 -occurred even with simple searches on small repositories; if the
  99.690 -problem you're looking for is more subtle, or the number of tests that
  99.691 -\hgcmd{bisect} must perform increases, the likelihood of operator
  99.692 -error ruining the search is much higher.  Once I started automating my
  99.693 -tests, I had much better results.
  99.694 -
  99.695 -The key to automated testing is twofold:
  99.696 -\begin{itemize}
  99.697 -\item always test for the same symptom, and
  99.698 -\item always feed consistent input to the \hgcmd{bisect} command.
  99.699 -\end{itemize}
  99.700 -In my tutorial example above, the \command{grep} command tests for the
  99.701 -symptom, and the \texttt{if} statement takes the result of this check
  99.702 -and ensures that we always feed the same input to the \hgcmd{bisect}
  99.703 -command.  The \texttt{mytest} function marries these together in a
  99.704 -reproducible way, so that every test is uniform and consistent.
  99.705 -
  99.706 -\subsection{Check your results}
  99.707 -
  99.708 -Because the output of a \hgcmd{bisect} search is only as good as the
  99.709 -input you give it, don't take the changeset it reports as the
  99.710 -absolute truth.  A simple way to cross-check its report is to manually
  99.711 -run your test at each of the following changesets:
  99.712 -\begin{itemize}
  99.713 -\item The changeset that it reports as the first bad revision.  Your
  99.714 -  test should still report this as bad.
  99.715 -\item The parent of that changeset (either parent, if it's a merge).
  99.716 -  Your test should report this changeset as good.
  99.717 -\item A child of that changeset.  Your test should report this
  99.718 -  changeset as bad.
  99.719 -\end{itemize}
  99.720 -
  99.721 -\subsection{Beware interference between bugs}
  99.722 -
  99.723 -It's possible that your search for one bug could be disrupted by the
  99.724 -presence of another.  For example, let's say your software crashes at
  99.725 -revision 100, and worked correctly at revision 50.  Unknown to you,
  99.726 -someone else introduced a different crashing bug at revision 60, and
  99.727 -fixed it at revision 80.  This could distort your results in one of
  99.728 -several ways.
  99.729 -
  99.730 -It is possible that this other bug completely ``masks'' yours, which
  99.731 -is to say that it occurs before your bug has a chance to manifest
  99.732 -itself.  If you can't avoid that other bug (for example, it prevents
  99.733 -your project from building), and so can't tell whether your bug is
  99.734 -present in a particular changeset, the \hgcmd{bisect} command cannot
  99.735 -help you directly.  Instead, you can mark a changeset as untested by
  99.736 -running \hgcmdargs{bisect}{--skip}.
  99.737 -
  99.738 -A different problem could arise if your test for a bug's presence is
  99.739 -not specific enough.  If you check for ``my program crashes'', then
  99.740 -both your crashing bug and an unrelated crashing bug that masks it
  99.741 -will look like the same thing, and mislead \hgcmd{bisect}.
  99.742 -
  99.743 -Another useful situation in which to use \hgcmdargs{bisect}{--skip} is
  99.744 -if you can't test a revision because your project was in a broken and
  99.745 -hence untestable state at that revision, perhaps because someone
  99.746 -checked in a change that prevented the project from building.
  99.747 -
  99.748 -\subsection{Bracket your search lazily}
  99.749 -
  99.750 -Choosing the first ``good'' and ``bad'' changesets that will mark the
  99.751 -end points of your search is often easy, but it bears a little
  99.752 -discussion nevertheless.  From the perspective of \hgcmd{bisect}, the
  99.753 -``newest'' changeset is conventionally ``bad'', and the older
  99.754 -changeset is ``good''.
  99.755 -
  99.756 -If you're having trouble remembering when a suitable ``good'' change
  99.757 -was, so that you can tell \hgcmd{bisect}, you could do worse than
  99.758 -testing changesets at random.  Just remember to eliminate contenders
  99.759 -that can't possibly exhibit the bug (perhaps because the feature with
  99.760 -the bug isn't present yet) and those where another problem masks the
  99.761 -bug (as I discussed above).
  99.762 -
  99.763 -Even if you end up ``early'' by thousands of changesets or months of
  99.764 -history, you will only add a handful of tests to the total number that
  99.765 -\hgcmd{bisect} must perform, thanks to its logarithmic behaviour.
  99.766 -
  99.767 -%%% Local Variables: 
  99.768 -%%% mode: latex
  99.769 -%%% TeX-master: "00book"
  99.770 -%%% End: 
   100.1 --- a/fr/wdir-after-commit.svg	Sun Aug 16 03:41:39 2009 +0200
   100.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.3 @@ -1,394 +0,0 @@
   100.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
   100.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
   100.6 -<svg
   100.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
   100.8 -   xmlns:cc="http://web.resource.org/cc/"
   100.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  100.10 -   xmlns:svg="http://www.w3.org/2000/svg"
  100.11 -   xmlns="http://www.w3.org/2000/svg"
  100.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
  100.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  100.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  100.15 -   width="744.09448819"
  100.16 -   height="1052.3622047"
  100.17 -   id="svg5971"
  100.18 -   sodipodi:version="0.32"
  100.19 -   inkscape:version="0.44.1"
  100.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
  100.21 -   sodipodi:docname="wdir-after-commit.svg">
  100.22 -  <defs
  100.23 -     id="defs5973">
  100.24 -    <linearGradient
  100.25 -       inkscape:collect="always"
  100.26 -       xlink:href="#linearGradient6049"
  100.27 -       id="linearGradient6445"
  100.28 -       gradientUnits="userSpaceOnUse"
  100.29 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  100.30 -       x1="333.91171"
  100.31 -       y1="488.79077"
  100.32 -       x2="508.94543"
  100.33 -       y2="263.79077" />
  100.34 -    <marker
  100.35 -       inkscape:stockid="Arrow1Mstart"
  100.36 -       orient="auto"
  100.37 -       refY="0.0"
  100.38 -       refX="0.0"
  100.39 -       id="Arrow1Mstart"
  100.40 -       style="overflow:visible">
  100.41 -      <path
  100.42 -         id="path4855"
  100.43 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  100.44 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
  100.45 -         transform="scale(0.4) translate(10,0)" />
  100.46 -    </marker>
  100.47 -    <linearGradient
  100.48 -       id="linearGradient6049">
  100.49 -      <stop
  100.50 -         style="stop-color:#686868;stop-opacity:1;"
  100.51 -         offset="0"
  100.52 -         id="stop6051" />
  100.53 -      <stop
  100.54 -         style="stop-color:#f0f0f0;stop-opacity:1;"
  100.55 -         offset="1"
  100.56 -         id="stop6053" />
  100.57 -    </linearGradient>
  100.58 -    <marker
  100.59 -       inkscape:stockid="Arrow1Mend"
  100.60 -       orient="auto"
  100.61 -       refY="0.0"
  100.62 -       refX="0.0"
  100.63 -       id="Arrow1Mend"
  100.64 -       style="overflow:visible;">
  100.65 -      <path
  100.66 -         id="path4852"
  100.67 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  100.68 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
  100.69 -         transform="scale(0.4) rotate(180) translate(10,0)" />
  100.70 -    </marker>
  100.71 -    <linearGradient
  100.72 -       inkscape:collect="always"
  100.73 -       xlink:href="#linearGradient6049"
  100.74 -       id="linearGradient6083"
  100.75 -       gradientUnits="userSpaceOnUse"
  100.76 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  100.77 -       x1="333.91171"
  100.78 -       y1="488.79077"
  100.79 -       x2="508.94543"
  100.80 -       y2="263.79077" />
  100.81 -    <linearGradient
  100.82 -       inkscape:collect="always"
  100.83 -       xlink:href="#linearGradient6049"
  100.84 -       id="linearGradient6142"
  100.85 -       gradientUnits="userSpaceOnUse"
  100.86 -       gradientTransform="translate(-42.00893,-30.49544)"
  100.87 -       x1="333.91171"
  100.88 -       y1="488.79077"
  100.89 -       x2="508.94543"
  100.90 -       y2="263.79077" />
  100.91 -    <linearGradient
  100.92 -       inkscape:collect="always"
  100.93 -       xlink:href="#linearGradient6049"
  100.94 -       id="linearGradient6193"
  100.95 -       gradientUnits="userSpaceOnUse"
  100.96 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  100.97 -       x1="333.91171"
  100.98 -       y1="488.79077"
  100.99 -       x2="508.94543"
 100.100 -       y2="263.79077" />
 100.101 -    <linearGradient
 100.102 -       inkscape:collect="always"
 100.103 -       xlink:href="#linearGradient6049"
 100.104 -       id="linearGradient6216"
 100.105 -       gradientUnits="userSpaceOnUse"
 100.106 -       gradientTransform="translate(-6.0462,-0.664361)"
 100.107 -       x1="333.91171"
 100.108 -       y1="488.79077"
 100.109 -       x2="508.94543"
 100.110 -       y2="263.79077" />
 100.111 -    <linearGradient
 100.112 -       inkscape:collect="always"
 100.113 -       xlink:href="#linearGradient6049"
 100.114 -       id="linearGradient6232"
 100.115 -       gradientUnits="userSpaceOnUse"
 100.116 -       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
 100.117 -       x1="333.91171"
 100.118 -       y1="488.79077"
 100.119 -       x2="508.94543"
 100.120 -       y2="263.79077" />
 100.121 -    <linearGradient
 100.122 -       inkscape:collect="always"
 100.123 -       xlink:href="#linearGradient6049"
 100.124 -       id="linearGradient6772"
 100.125 -       gradientUnits="userSpaceOnUse"
 100.126 -       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
 100.127 -       x1="333.91171"
 100.128 -       y1="488.79077"
 100.129 -       x2="508.94543"
 100.130 -       y2="263.79077" />
 100.131 -  </defs>
 100.132 -  <sodipodi:namedview
 100.133 -     id="base"
 100.134 -     pagecolor="#ffffff"
 100.135 -     bordercolor="#666666"
 100.136 -     borderopacity="1.0"
 100.137 -     gridtolerance="10000"
 100.138 -     guidetolerance="10"
 100.139 -     objecttolerance="10"
 100.140 -     inkscape:pageopacity="0.0"
 100.141 -     inkscape:pageshadow="2"
 100.142 -     inkscape:zoom="0.90509668"
 100.143 -     inkscape:cx="390.0539"
 100.144 -     inkscape:cy="690.49342"
 100.145 -     inkscape:document-units="px"
 100.146 -     inkscape:current-layer="layer1"
 100.147 -     showguides="true"
 100.148 -     inkscape:guide-bbox="true"
 100.149 -     inkscape:window-width="906"
 100.150 -     inkscape:window-height="620"
 100.151 -     inkscape:window-x="0"
 100.152 -     inkscape:window-y="25">
 100.153 -    <sodipodi:guide
 100.154 -       orientation="vertical"
 100.155 -       position="-1.4285714"
 100.156 -       id="guide6022" />
 100.157 -  </sodipodi:namedview>
 100.158 -  <metadata
 100.159 -     id="metadata5976">
 100.160 -    <rdf:RDF>
 100.161 -      <cc:Work
 100.162 -         rdf:about="">
 100.163 -        <dc:format>image/svg+xml</dc:format>
 100.164 -        <dc:type
 100.165 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 100.166 -      </cc:Work>
 100.167 -    </rdf:RDF>
 100.168 -  </metadata>
 100.169 -  <g
 100.170 -     inkscape:label="Layer 1"
 100.171 -     inkscape:groupmode="layer"
 100.172 -     id="layer1">
 100.173 -    <rect
 100.174 -       y="245.98355"
 100.175 -       x="328.23956"
 100.176 -       height="258.57144"
 100.177 -       width="174.28572"
 100.178 -       id="rect6047"
 100.179 -       style="fill:url(#linearGradient6216);fill-opacity:1;stroke:#686868;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 100.180 -    <g
 100.181 -       id="g6261"
 100.182 -       transform="translate(234,0)">
 100.183 -      <rect
 100.184 -         y="258.7149"
 100.185 -         x="114.11369"
 100.186 -         height="44.537449"
 100.187 -         width="134.53746"
 100.188 -         id="rect5983"
 100.189 -         style="fill:#b1b1b1;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 100.190 -      <text
 100.191 -         id="text5985"
 100.192 -         y="284.47562"
 100.193 -         x="138.7962"
 100.194 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.195 -         xml:space="preserve"><tspan
 100.196 -           style="font-family:Courier"
 100.197 -           y="284.47562"
 100.198 -           x="138.7962"
 100.199 -           id="tspan5987"
 100.200 -           sodipodi:role="line">dfbbb33f3fa3</tspan></text>
 100.201 -    </g>
 100.202 -    <rect
 100.203 -       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 100.204 -       id="rect5996"
 100.205 -       width="134.53746"
 100.206 -       height="44.537449"
 100.207 -       x="348.11371"
 100.208 -       y="320.38159" />
 100.209 -    <text
 100.210 -       xml:space="preserve"
 100.211 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.212 -       x="372.7962"
 100.213 -       y="346.1423"
 100.214 -       id="text5998"><tspan
 100.215 -         sodipodi:role="line"
 100.216 -         id="tspan6000"
 100.217 -         x="372.7962"
 100.218 -         y="346.1423"
 100.219 -         style="font-family:Courier">e7639888bb2f</tspan></text>
 100.220 -    <rect
 100.221 -       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 100.222 -       id="rect6004"
 100.223 -       width="134.53746"
 100.224 -       height="44.537449"
 100.225 -       x="348.11371"
 100.226 -       y="382.04825" />
 100.227 -    <text
 100.228 -       xml:space="preserve"
 100.229 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.230 -       x="370.65421"
 100.231 -       y="407.80896"
 100.232 -       id="text6006"><tspan
 100.233 -         sodipodi:role="line"
 100.234 -         id="tspan6008"
 100.235 -         x="370.65421"
 100.236 -         y="407.80896"
 100.237 -         style="font-family:Courier">7b064d8bac5e</tspan></text>
 100.238 -    <path
 100.239 -       inkscape:connector-type="polyline"
 100.240 -       id="path6018"
 100.241 -       d="M 415.38242,303.62646 L 415.38242,320.00744"
 100.242 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 100.243 -    <path
 100.244 -       inkscape:connection-end="#rect6004"
 100.245 -       inkscape:connector-type="polyline"
 100.246 -       id="path6020"
 100.247 -       d="M 415.38242,365.29315 L 415.38243,381.67412"
 100.248 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 100.249 -    <rect
 100.250 -       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 100.251 -       id="rect6039"
 100.252 -       width="134.53746"
 100.253 -       height="44.537449"
 100.254 -       x="348.11359"
 100.255 -       y="443.71487" />
 100.256 -    <text
 100.257 -       xml:space="preserve"
 100.258 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.259 -       x="372.79706"
 100.260 -       y="469.47556"
 100.261 -       id="text6041"><tspan
 100.262 -         sodipodi:role="line"
 100.263 -         id="tspan6043"
 100.264 -         x="372.79706"
 100.265 -         y="469.47556"
 100.266 -         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 100.267 -    <path
 100.268 -       inkscape:connection-end="#rect6039"
 100.269 -       inkscape:connector-type="polyline"
 100.270 -       id="path6045"
 100.271 -       d="M 415.38238,426.95981 L 415.38235,443.34087"
 100.272 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 100.273 -    <text
 100.274 -       xml:space="preserve"
 100.275 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.276 -       x="327.66046"
 100.277 -       y="231.36218"
 100.278 -       id="text6102"><tspan
 100.279 -         sodipodi:role="line"
 100.280 -         id="tspan6104"
 100.281 -         x="327.66046"
 100.282 -         y="231.36218">History in repository</tspan></text>
 100.283 -    <rect
 100.284 -       y="245.94225"
 100.285 -       x="557.28418"
 100.286 -       height="204.51619"
 100.287 -       width="174.36833"
 100.288 -       id="rect6140"
 100.289 -       style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 100.290 -    <g
 100.291 -       id="g6130"
 100.292 -       transform="translate(262.3254,24.38544)">
 100.293 -      <rect
 100.294 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 100.295 -         id="rect6106"
 100.296 -         width="134.53746"
 100.297 -         height="44.537449"
 100.298 -         x="314.87415"
 100.299 -         y="257.95059" />
 100.300 -      <text
 100.301 -         xml:space="preserve"
 100.302 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.303 -         x="339.55664"
 100.304 -         y="283.7113"
 100.305 -         id="text6108"><tspan
 100.306 -           sodipodi:role="line"
 100.307 -           id="tspan6110"
 100.308 -           x="339.55664"
 100.309 -           y="283.7113"
 100.310 -           style="font-family:Courier">dfbbb33f3fa3</tspan></text>
 100.311 -    </g>
 100.312 -    <g
 100.313 -       id="g6135"
 100.314 -       transform="translate(263.0396,49.83106)">
 100.315 -      <rect
 100.316 -         inkscape:transform-center-y="102.85714"
 100.317 -         inkscape:transform-center-x="129.28571"
 100.318 -         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 100.319 -         id="rect6112"
 100.320 -         width="134.53746"
 100.321 -         height="44.537449"
 100.322 -         x="314.15985"
 100.323 -         y="326.52203" />
 100.324 -      <text
 100.325 -         inkscape:transform-center-y="102.7311"
 100.326 -         inkscape:transform-center-x="128.69672"
 100.327 -         xml:space="preserve"
 100.328 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.329 -         x="338.84335"
 100.330 -         y="352.28271"
 100.331 -         id="text6114"><tspan
 100.332 -           sodipodi:role="line"
 100.333 -           id="tspan6116"
 100.334 -           x="338.84335"
 100.335 -           y="352.28271"
 100.336 -           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 100.337 -    </g>
 100.338 -    <text
 100.339 -       xml:space="preserve"
 100.340 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.341 -       x="576.63208"
 100.342 -       y="270.479"
 100.343 -       id="text6118"><tspan
 100.344 -         sodipodi:role="line"
 100.345 -         id="tspan6120"
 100.346 -         x="576.63208"
 100.347 -         y="270.479">First parent</tspan></text>
 100.348 -    <text
 100.349 -       xml:space="preserve"
 100.350 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.351 -       x="576.07544"
 100.352 -       y="364.49615"
 100.353 -       id="text6122"><tspan
 100.354 -         sodipodi:role="line"
 100.355 -         id="tspan6124"
 100.356 -         x="576.07544"
 100.357 -         y="364.49615">Second parent</tspan></text>
 100.358 -    <text
 100.359 -       xml:space="preserve"
 100.360 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.361 -       x="556.61743"
 100.362 -       y="231.36218"
 100.363 -       id="text6195"><tspan
 100.364 -         sodipodi:role="line"
 100.365 -         id="tspan6197"
 100.366 -         x="556.61743"
 100.367 -         y="231.36218">Parents of working directory</tspan></text>
 100.368 -    <path
 100.369 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 100.370 -       d="M 576.82542,297.63008 L 483.02528,287.95831"
 100.371 -       id="path6266"
 100.372 -       inkscape:connector-type="polyline"
 100.373 -       inkscape:connection-start="#g6130"
 100.374 -       inkscape:connection-end="#g6261" />
 100.375 -    <path
 100.376 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 100.377 -       d="M 665.12232,418.17579 L 665.12232,418.17579"
 100.378 -       id="path6270"
 100.379 -       inkscape:connector-type="polyline" />
 100.380 -    <text
 100.381 -       xml:space="preserve"
 100.382 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 100.383 -       x="316.86407"
 100.384 -       y="275.6496"
 100.385 -       id="text6573"><tspan
 100.386 -         sodipodi:role="line"
 100.387 -         id="tspan6575"
 100.388 -         x="316.86407"
 100.389 -         y="275.6496"
 100.390 -         style="text-align:end;text-anchor:end">New</tspan><tspan
 100.391 -         sodipodi:role="line"
 100.392 -         x="316.86407"
 100.393 -         y="290.6496"
 100.394 -         id="tspan6577"
 100.395 -         style="text-align:end;text-anchor:end">changeset</tspan></text>
 100.396 -  </g>
 100.397 -</svg>
   101.1 --- a/fr/wdir-branch.svg	Sun Aug 16 03:41:39 2009 +0200
   101.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.3 @@ -1,418 +0,0 @@
   101.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
   101.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
   101.6 -<svg
   101.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
   101.8 -   xmlns:cc="http://web.resource.org/cc/"
   101.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  101.10 -   xmlns:svg="http://www.w3.org/2000/svg"
  101.11 -   xmlns="http://www.w3.org/2000/svg"
  101.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
  101.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  101.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  101.15 -   width="744.09448819"
  101.16 -   height="1052.3622047"
  101.17 -   id="svg5971"
  101.18 -   sodipodi:version="0.32"
  101.19 -   inkscape:version="0.44.1"
  101.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
  101.21 -   sodipodi:docname="wdir-branch.svg">
  101.22 -  <defs
  101.23 -     id="defs5973">
  101.24 -    <marker
  101.25 -       inkscape:stockid="Arrow1Mstart"
  101.26 -       orient="auto"
  101.27 -       refY="0.0"
  101.28 -       refX="0.0"
  101.29 -       id="Arrow1Mstart"
  101.30 -       style="overflow:visible">
  101.31 -      <path
  101.32 -         id="path4855"
  101.33 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  101.34 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
  101.35 -         transform="scale(0.4) translate(10,0)" />
  101.36 -    </marker>
  101.37 -    <linearGradient
  101.38 -       id="linearGradient6049">
  101.39 -      <stop
  101.40 -         style="stop-color:#686868;stop-opacity:1;"
  101.41 -         offset="0"
  101.42 -         id="stop6051" />
  101.43 -      <stop
  101.44 -         style="stop-color:#f0f0f0;stop-opacity:1;"
  101.45 -         offset="1"
  101.46 -         id="stop6053" />
  101.47 -    </linearGradient>
  101.48 -    <marker
  101.49 -       inkscape:stockid="Arrow1Mend"
  101.50 -       orient="auto"
  101.51 -       refY="0.0"
  101.52 -       refX="0.0"
  101.53 -       id="Arrow1Mend"
  101.54 -       style="overflow:visible;">
  101.55 -      <path
  101.56 -         id="path4852"
  101.57 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  101.58 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
  101.59 -         transform="scale(0.4) rotate(180) translate(10,0)" />
  101.60 -    </marker>
  101.61 -    <linearGradient
  101.62 -       inkscape:collect="always"
  101.63 -       xlink:href="#linearGradient6049"
  101.64 -       id="linearGradient6083"
  101.65 -       gradientUnits="userSpaceOnUse"
  101.66 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  101.67 -       x1="333.91171"
  101.68 -       y1="488.79077"
  101.69 -       x2="508.94543"
  101.70 -       y2="263.79077" />
  101.71 -    <linearGradient
  101.72 -       inkscape:collect="always"
  101.73 -       xlink:href="#linearGradient6049"
  101.74 -       id="linearGradient6142"
  101.75 -       gradientUnits="userSpaceOnUse"
  101.76 -       gradientTransform="translate(-42.00893,-30.49544)"
  101.77 -       x1="333.91171"
  101.78 -       y1="488.79077"
  101.79 -       x2="508.94543"
  101.80 -       y2="263.79077" />
  101.81 -    <linearGradient
  101.82 -       inkscape:collect="always"
  101.83 -       xlink:href="#linearGradient6049"
  101.84 -       id="linearGradient6193"
  101.85 -       gradientUnits="userSpaceOnUse"
  101.86 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  101.87 -       x1="333.91171"
  101.88 -       y1="488.79077"
  101.89 -       x2="508.94543"
  101.90 -       y2="263.79077" />
  101.91 -    <linearGradient
  101.92 -       inkscape:collect="always"
  101.93 -       xlink:href="#linearGradient6049"
  101.94 -       id="linearGradient6216"
  101.95 -       gradientUnits="userSpaceOnUse"
  101.96 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  101.97 -       x1="333.91171"
  101.98 -       y1="488.79077"
  101.99 -       x2="508.94543"
 101.100 -       y2="263.79077" />
 101.101 -    <linearGradient
 101.102 -       inkscape:collect="always"
 101.103 -       xlink:href="#linearGradient6049"
 101.104 -       id="linearGradient6232"
 101.105 -       gradientUnits="userSpaceOnUse"
 101.106 -       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
 101.107 -       x1="333.91171"
 101.108 -       y1="488.79077"
 101.109 -       x2="508.94543"
 101.110 -       y2="263.79077" />
 101.111 -    <linearGradient
 101.112 -       inkscape:collect="always"
 101.113 -       xlink:href="#linearGradient6049"
 101.114 -       id="linearGradient6445"
 101.115 -       gradientUnits="userSpaceOnUse"
 101.116 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
 101.117 -       x1="333.91171"
 101.118 -       y1="488.79077"
 101.119 -       x2="508.94543"
 101.120 -       y2="263.79077" />
 101.121 -    <linearGradient
 101.122 -       inkscape:collect="always"
 101.123 -       xlink:href="#linearGradient6049"
 101.124 -       id="linearGradient6974"
 101.125 -       gradientUnits="userSpaceOnUse"
 101.126 -       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
 101.127 -       x1="333.91171"
 101.128 -       y1="488.79077"
 101.129 -       x2="508.94543"
 101.130 -       y2="263.79077" />
 101.131 -    <linearGradient
 101.132 -       inkscape:collect="always"
 101.133 -       xlink:href="#linearGradient6049"
 101.134 -       id="linearGradient6996"
 101.135 -       gradientUnits="userSpaceOnUse"
 101.136 -       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
 101.137 -       x1="333.91171"
 101.138 -       y1="488.79077"
 101.139 -       x2="508.94543"
 101.140 -       y2="263.79077" />
 101.141 -  </defs>
 101.142 -  <sodipodi:namedview
 101.143 -     id="base"
 101.144 -     pagecolor="#ffffff"
 101.145 -     bordercolor="#666666"
 101.146 -     borderopacity="1.0"
 101.147 -     gridtolerance="10000"
 101.148 -     guidetolerance="10"
 101.149 -     objecttolerance="10"
 101.150 -     inkscape:pageopacity="0.0"
 101.151 -     inkscape:pageshadow="2"
 101.152 -     inkscape:zoom="0.90509668"
 101.153 -     inkscape:cx="345.85973"
 101.154 -     inkscape:cy="690.49342"
 101.155 -     inkscape:document-units="px"
 101.156 -     inkscape:current-layer="layer1"
 101.157 -     showguides="true"
 101.158 -     inkscape:guide-bbox="true"
 101.159 -     inkscape:window-width="906"
 101.160 -     inkscape:window-height="620"
 101.161 -     inkscape:window-x="0"
 101.162 -     inkscape:window-y="25">
 101.163 -    <sodipodi:guide
 101.164 -       orientation="vertical"
 101.165 -       position="-1.4285714"
 101.166 -       id="guide6022" />
 101.167 -  </sodipodi:namedview>
 101.168 -  <metadata
 101.169 -     id="metadata5976">
 101.170 -    <rdf:RDF>
 101.171 -      <cc:Work
 101.172 -         rdf:about="">
 101.173 -        <dc:format>image/svg+xml</dc:format>
 101.174 -        <dc:type
 101.175 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 101.176 -      </cc:Work>
 101.177 -    </rdf:RDF>
 101.178 -  </metadata>
 101.179 -  <g
 101.180 -     inkscape:label="Layer 1"
 101.181 -     inkscape:groupmode="layer"
 101.182 -     id="layer1">
 101.183 -    <rect
 101.184 -       y="246.06918"
 101.185 -       x="64.325172"
 101.186 -       height="204.26233"
 101.187 -       width="333.2135"
 101.188 -       id="rect6047"
 101.189 -       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 101.190 -    <g
 101.191 -       id="g1935">
 101.192 -      <rect
 101.193 -         y="266.24374"
 101.194 -         x="84.113708"
 101.195 -         height="44.537449"
 101.196 -         width="134.53746"
 101.197 -         id="rect5996"
 101.198 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 101.199 -      <text
 101.200 -         id="text5998"
 101.201 -         y="292.00446"
 101.202 -         x="108.7962"
 101.203 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.204 -         xml:space="preserve"><tspan
 101.205 -           style="font-family:Courier"
 101.206 -           y="292.00446"
 101.207 -           x="108.7962"
 101.208 -           id="tspan6000"
 101.209 -           sodipodi:role="line">e7639888bb2f</tspan></text>
 101.210 -    </g>
 101.211 -    <g
 101.212 -       id="g6976"
 101.213 -       transform="translate(70,0)">
 101.214 -      <rect
 101.215 -         y="327.9104"
 101.216 -         x="40.113693"
 101.217 -         height="44.537449"
 101.218 -         width="134.53746"
 101.219 -         id="rect6004"
 101.220 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 101.221 -      <text
 101.222 -         id="text6006"
 101.223 -         y="353.67111"
 101.224 -         x="62.654205"
 101.225 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.226 -         xml:space="preserve"><tspan
 101.227 -           style="font-family:Courier"
 101.228 -           y="353.67111"
 101.229 -           x="62.654205"
 101.230 -           id="tspan6008"
 101.231 -           sodipodi:role="line">7b064d8bac5e</tspan></text>
 101.232 -    </g>
 101.233 -    <path
 101.234 -       inkscape:connector-type="polyline"
 101.235 -       id="path6020"
 101.236 -       d="M 160.92915,311.15532 L 167.83571,327.53627"
 101.237 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 101.238 -       inkscape:connection-end="#g6976"
 101.239 -       inkscape:connection-start="#g1935" />
 101.240 -    <rect
 101.241 -       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 101.242 -       id="rect6039"
 101.243 -       width="134.53746"
 101.244 -       height="44.537449"
 101.245 -       x="110.11359"
 101.246 -       y="389.57703" />
 101.247 -    <text
 101.248 -       xml:space="preserve"
 101.249 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.250 -       x="134.79706"
 101.251 -       y="415.33771"
 101.252 -       id="text6041"><tspan
 101.253 -         sodipodi:role="line"
 101.254 -         id="tspan6043"
 101.255 -         x="134.79706"
 101.256 -         y="415.33771"
 101.257 -         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 101.258 -    <path
 101.259 -       inkscape:connection-end="#rect6039"
 101.260 -       inkscape:connector-type="polyline"
 101.261 -       id="path6045"
 101.262 -       d="M 177.38238,372.82195 L 177.38235,389.20303"
 101.263 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 101.264 -    <rect
 101.265 -       y="245.94225"
 101.266 -       x="447.28412"
 101.267 -       height="204.51619"
 101.268 -       width="174.36833"
 101.269 -       id="rect6140"
 101.270 -       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 101.271 -    <g
 101.272 -       id="g6130"
 101.273 -       transform="translate(152.3254,24.38544)">
 101.274 -      <rect
 101.275 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 101.276 -         id="rect6106"
 101.277 -         width="134.53746"
 101.278 -         height="44.537449"
 101.279 -         x="314.87415"
 101.280 -         y="257.95059" />
 101.281 -      <text
 101.282 -         xml:space="preserve"
 101.283 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.284 -         x="339.55664"
 101.285 -         y="283.7113"
 101.286 -         id="text6108"><tspan
 101.287 -           sodipodi:role="line"
 101.288 -           id="tspan6110"
 101.289 -           x="339.55664"
 101.290 -           y="283.7113"
 101.291 -           style="font-family:Courier">ffb20e1701ea</tspan></text>
 101.292 -    </g>
 101.293 -    <g
 101.294 -       id="g6135"
 101.295 -       transform="translate(153.0396,49.83106)">
 101.296 -      <rect
 101.297 -         inkscape:transform-center-y="102.85714"
 101.298 -         inkscape:transform-center-x="129.28571"
 101.299 -         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 101.300 -         id="rect6112"
 101.301 -         width="134.53746"
 101.302 -         height="44.537449"
 101.303 -         x="314.15985"
 101.304 -         y="326.52203" />
 101.305 -      <text
 101.306 -         inkscape:transform-center-y="102.7311"
 101.307 -         inkscape:transform-center-x="128.69672"
 101.308 -         xml:space="preserve"
 101.309 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.310 -         x="338.84335"
 101.311 -         y="352.28271"
 101.312 -         id="text6114"><tspan
 101.313 -           sodipodi:role="line"
 101.314 -           id="tspan6116"
 101.315 -           x="338.84335"
 101.316 -           y="352.28271"
 101.317 -           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 101.318 -    </g>
 101.319 -    <text
 101.320 -       xml:space="preserve"
 101.321 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.322 -       x="466.63208"
 101.323 -       y="270.479"
 101.324 -       id="text6118"><tspan
 101.325 -         sodipodi:role="line"
 101.326 -         id="tspan6120"
 101.327 -         x="466.63208"
 101.328 -         y="270.479">First parent</tspan></text>
 101.329 -    <text
 101.330 -       xml:space="preserve"
 101.331 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.332 -       x="466.07544"
 101.333 -       y="364.49615"
 101.334 -       id="text6122"><tspan
 101.335 -         sodipodi:role="line"
 101.336 -         id="tspan6124"
 101.337 -         x="466.07544"
 101.338 -         y="364.49615">Second parent</tspan></text>
 101.339 -    <text
 101.340 -       xml:space="preserve"
 101.341 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.342 -       x="446.61743"
 101.343 -       y="231.36218"
 101.344 -       id="text6195"><tspan
 101.345 -         sodipodi:role="line"
 101.346 -         id="tspan6197"
 101.347 -         x="446.61743"
 101.348 -         y="231.36218">Parents of working directory</tspan></text>
 101.349 -    <path
 101.350 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
 101.351 -       d="M 466.82542,300.21999 L 377.00207,294.39744"
 101.352 -       id="path6266"
 101.353 -       inkscape:connector-type="polyline"
 101.354 -       inkscape:connection-start="#g6130"
 101.355 -       inkscape:connection-end="#rect1925" />
 101.356 -    <path
 101.357 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 101.358 -       d="M 665.12232,418.17579 L 665.12232,418.17579"
 101.359 -       id="path6270"
 101.360 -       inkscape:connector-type="polyline" />
 101.361 -    <g
 101.362 -       id="g2845">
 101.363 -      <rect
 101.364 -         y="266.24374"
 101.365 -         x="242.09048"
 101.366 -         height="44.537449"
 101.367 -         width="134.53746"
 101.368 -         id="rect1925"
 101.369 -         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 101.370 -      <text
 101.371 -         id="text1927"
 101.372 -         y="292.00446"
 101.373 -         x="266.77298"
 101.374 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.375 -         xml:space="preserve"><tspan
 101.376 -           style="font-family:Courier"
 101.377 -           y="292.00446"
 101.378 -           x="266.77298"
 101.379 -           id="tspan1929"
 101.380 -           sodipodi:role="line">ffb20e1701ea</tspan></text>
 101.381 -    </g>
 101.382 -    <path
 101.383 -       inkscape:connector-type="polyline"
 101.384 -       id="path1933"
 101.385 -       d="M 260.89978,311.15532 L 225.84185,327.53627"
 101.386 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 101.387 -       inkscape:connection-end="#g6976" />
 101.388 -    <text
 101.389 -       xml:space="preserve"
 101.390 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.391 -       x="109.45568"
 101.392 -       y="231.4554"
 101.393 -       id="text2837"><tspan
 101.394 -         sodipodi:role="line"
 101.395 -         id="tspan2839"
 101.396 -         x="109.45568"
 101.397 -         y="231.4554">Pre-existing head</tspan></text>
 101.398 -    <text
 101.399 -       xml:space="preserve"
 101.400 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 101.401 -       x="237.54184"
 101.402 -       y="231.4554"
 101.403 -       id="text2841"><tspan
 101.404 -         sodipodi:role="line"
 101.405 -         id="tspan2843"
 101.406 -         x="237.54184"
 101.407 -         y="231.4554">Newly created head (and tip)</tspan></text>
 101.408 -    <path
 101.409 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 101.410 -       d="M 148.05048,235.87482 L 149.94915,265.86962"
 101.411 -       id="path2850"
 101.412 -       inkscape:connector-type="polyline"
 101.413 -       inkscape:connection-end="#g1935" />
 101.414 -    <path
 101.415 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 101.416 -       d="M 303.83495,238.08453 L 306.87874,265.86962"
 101.417 -       id="path2852"
 101.418 -       inkscape:connector-type="polyline"
 101.419 -       inkscape:connection-end="#g2845" />
 101.420 -  </g>
 101.421 -</svg>
   102.1 --- a/fr/wdir-merge.svg	Sun Aug 16 03:41:39 2009 +0200
   102.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.3 @@ -1,425 +0,0 @@
   102.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
   102.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
   102.6 -<svg
   102.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
   102.8 -   xmlns:cc="http://web.resource.org/cc/"
   102.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  102.10 -   xmlns:svg="http://www.w3.org/2000/svg"
  102.11 -   xmlns="http://www.w3.org/2000/svg"
  102.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
  102.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  102.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  102.15 -   width="744.09448819"
  102.16 -   height="1052.3622047"
  102.17 -   id="svg5971"
  102.18 -   sodipodi:version="0.32"
  102.19 -   inkscape:version="0.44.1"
  102.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
  102.21 -   sodipodi:docname="wdir-merge.svg">
  102.22 -  <defs
  102.23 -     id="defs5973">
  102.24 -    <marker
  102.25 -       inkscape:stockid="Arrow1Mstart"
  102.26 -       orient="auto"
  102.27 -       refY="0.0"
  102.28 -       refX="0.0"
  102.29 -       id="Arrow1Mstart"
  102.30 -       style="overflow:visible">
  102.31 -      <path
  102.32 -         id="path4855"
  102.33 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  102.34 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
  102.35 -         transform="scale(0.4) translate(10,0)" />
  102.36 -    </marker>
  102.37 -    <linearGradient
  102.38 -       id="linearGradient6049">
  102.39 -      <stop
  102.40 -         style="stop-color:#686868;stop-opacity:1;"
  102.41 -         offset="0"
  102.42 -         id="stop6051" />
  102.43 -      <stop
  102.44 -         style="stop-color:#f0f0f0;stop-opacity:1;"
  102.45 -         offset="1"
  102.46 -         id="stop6053" />
  102.47 -    </linearGradient>
  102.48 -    <marker
  102.49 -       inkscape:stockid="Arrow1Mend"
  102.50 -       orient="auto"
  102.51 -       refY="0.0"
  102.52 -       refX="0.0"
  102.53 -       id="Arrow1Mend"
  102.54 -       style="overflow:visible;">
  102.55 -      <path
  102.56 -         id="path4852"
  102.57 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  102.58 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
  102.59 -         transform="scale(0.4) rotate(180) translate(10,0)" />
  102.60 -    </marker>
  102.61 -    <linearGradient
  102.62 -       inkscape:collect="always"
  102.63 -       xlink:href="#linearGradient6049"
  102.64 -       id="linearGradient6083"
  102.65 -       gradientUnits="userSpaceOnUse"
  102.66 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  102.67 -       x1="333.91171"
  102.68 -       y1="488.79077"
  102.69 -       x2="508.94543"
  102.70 -       y2="263.79077" />
  102.71 -    <linearGradient
  102.72 -       inkscape:collect="always"
  102.73 -       xlink:href="#linearGradient6049"
  102.74 -       id="linearGradient6142"
  102.75 -       gradientUnits="userSpaceOnUse"
  102.76 -       gradientTransform="translate(-42.00893,-30.49544)"
  102.77 -       x1="333.91171"
  102.78 -       y1="488.79077"
  102.79 -       x2="508.94543"
  102.80 -       y2="263.79077" />
  102.81 -    <linearGradient
  102.82 -       inkscape:collect="always"
  102.83 -       xlink:href="#linearGradient6049"
  102.84 -       id="linearGradient6193"
  102.85 -       gradientUnits="userSpaceOnUse"
  102.86 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  102.87 -       x1="333.91171"
  102.88 -       y1="488.79077"
  102.89 -       x2="508.94543"
  102.90 -       y2="263.79077" />
  102.91 -    <linearGradient
  102.92 -       inkscape:collect="always"
  102.93 -       xlink:href="#linearGradient6049"
  102.94 -       id="linearGradient6216"
  102.95 -       gradientUnits="userSpaceOnUse"
  102.96 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  102.97 -       x1="333.91171"
  102.98 -       y1="488.79077"
  102.99 -       x2="508.94543"
 102.100 -       y2="263.79077" />
 102.101 -    <linearGradient
 102.102 -       inkscape:collect="always"
 102.103 -       xlink:href="#linearGradient6049"
 102.104 -       id="linearGradient6232"
 102.105 -       gradientUnits="userSpaceOnUse"
 102.106 -       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
 102.107 -       x1="333.91171"
 102.108 -       y1="488.79077"
 102.109 -       x2="508.94543"
 102.110 -       y2="263.79077" />
 102.111 -    <linearGradient
 102.112 -       inkscape:collect="always"
 102.113 -       xlink:href="#linearGradient6049"
 102.114 -       id="linearGradient6445"
 102.115 -       gradientUnits="userSpaceOnUse"
 102.116 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
 102.117 -       x1="333.91171"
 102.118 -       y1="488.79077"
 102.119 -       x2="508.94543"
 102.120 -       y2="263.79077" />
 102.121 -    <linearGradient
 102.122 -       inkscape:collect="always"
 102.123 -       xlink:href="#linearGradient6049"
 102.124 -       id="linearGradient6974"
 102.125 -       gradientUnits="userSpaceOnUse"
 102.126 -       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
 102.127 -       x1="333.91171"
 102.128 -       y1="488.79077"
 102.129 -       x2="508.94543"
 102.130 -       y2="263.79077" />
 102.131 -    <linearGradient
 102.132 -       inkscape:collect="always"
 102.133 -       xlink:href="#linearGradient6049"
 102.134 -       id="linearGradient6996"
 102.135 -       gradientUnits="userSpaceOnUse"
 102.136 -       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
 102.137 -       x1="333.91171"
 102.138 -       y1="488.79077"
 102.139 -       x2="508.94543"
 102.140 -       y2="263.79077" />
 102.141 -  </defs>
 102.142 -  <sodipodi:namedview
 102.143 -     id="base"
 102.144 -     pagecolor="#ffffff"
 102.145 -     bordercolor="#666666"
 102.146 -     borderopacity="1.0"
 102.147 -     gridtolerance="10000"
 102.148 -     guidetolerance="10"
 102.149 -     objecttolerance="10"
 102.150 -     inkscape:pageopacity="0.0"
 102.151 -     inkscape:pageshadow="2"
 102.152 -     inkscape:zoom="1.28"
 102.153 -     inkscape:cx="345.85973"
 102.154 -     inkscape:cy="690.49342"
 102.155 -     inkscape:document-units="px"
 102.156 -     inkscape:current-layer="layer1"
 102.157 -     showguides="true"
 102.158 -     inkscape:guide-bbox="true"
 102.159 -     inkscape:window-width="906"
 102.160 -     inkscape:window-height="620"
 102.161 -     inkscape:window-x="0"
 102.162 -     inkscape:window-y="25">
 102.163 -    <sodipodi:guide
 102.164 -       orientation="vertical"
 102.165 -       position="-1.4285714"
 102.166 -       id="guide6022" />
 102.167 -  </sodipodi:namedview>
 102.168 -  <metadata
 102.169 -     id="metadata5976">
 102.170 -    <rdf:RDF>
 102.171 -      <cc:Work
 102.172 -         rdf:about="">
 102.173 -        <dc:format>image/svg+xml</dc:format>
 102.174 -        <dc:type
 102.175 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 102.176 -      </cc:Work>
 102.177 -    </rdf:RDF>
 102.178 -  </metadata>
 102.179 -  <g
 102.180 -     inkscape:label="Layer 1"
 102.181 -     inkscape:groupmode="layer"
 102.182 -     id="layer1">
 102.183 -    <rect
 102.184 -       y="246.06918"
 102.185 -       x="64.325172"
 102.186 -       height="204.26233"
 102.187 -       width="333.2135"
 102.188 -       id="rect6047"
 102.189 -       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 102.190 -    <g
 102.191 -       id="g6976"
 102.192 -       transform="translate(70,0)">
 102.193 -      <rect
 102.194 -         y="327.9104"
 102.195 -         x="40.113693"
 102.196 -         height="44.537449"
 102.197 -         width="134.53746"
 102.198 -         id="rect6004"
 102.199 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 102.200 -      <text
 102.201 -         id="text6006"
 102.202 -         y="353.67111"
 102.203 -         x="62.654205"
 102.204 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.205 -         xml:space="preserve"><tspan
 102.206 -           style="font-family:Courier"
 102.207 -           y="353.67111"
 102.208 -           x="62.654205"
 102.209 -           id="tspan6008"
 102.210 -           sodipodi:role="line">7b064d8bac5e</tspan></text>
 102.211 -    </g>
 102.212 -    <path
 102.213 -       inkscape:connector-type="polyline"
 102.214 -       id="path6020"
 102.215 -       d="M 160.92915,311.15532 L 167.83571,327.53627"
 102.216 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 102.217 -       inkscape:connection-end="#g6976"
 102.218 -       inkscape:connection-start="#g1935" />
 102.219 -    <rect
 102.220 -       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 102.221 -       id="rect6039"
 102.222 -       width="134.53746"
 102.223 -       height="44.537449"
 102.224 -       x="110.11359"
 102.225 -       y="389.57703" />
 102.226 -    <text
 102.227 -       xml:space="preserve"
 102.228 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.229 -       x="134.79706"
 102.230 -       y="415.33771"
 102.231 -       id="text6041"><tspan
 102.232 -         sodipodi:role="line"
 102.233 -         id="tspan6043"
 102.234 -         x="134.79706"
 102.235 -         y="415.33771"
 102.236 -         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 102.237 -    <path
 102.238 -       inkscape:connection-end="#rect6039"
 102.239 -       inkscape:connector-type="polyline"
 102.240 -       id="path6045"
 102.241 -       d="M 177.38238,372.82195 L 177.38235,389.20303"
 102.242 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 102.243 -    <rect
 102.244 -       y="245.94225"
 102.245 -       x="447.28412"
 102.246 -       height="204.51619"
 102.247 -       width="174.36833"
 102.248 -       id="rect6140"
 102.249 -       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 102.250 -    <g
 102.251 -       id="g6130"
 102.252 -       transform="translate(152.3254,24.38544)">
 102.253 -      <rect
 102.254 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 102.255 -         id="rect6106"
 102.256 -         width="134.53746"
 102.257 -         height="44.537449"
 102.258 -         x="314.87415"
 102.259 -         y="257.95059" />
 102.260 -      <text
 102.261 -         xml:space="preserve"
 102.262 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.263 -         x="339.55664"
 102.264 -         y="283.7113"
 102.265 -         id="text6108"><tspan
 102.266 -           sodipodi:role="line"
 102.267 -           id="tspan6110"
 102.268 -           x="339.55664"
 102.269 -           y="283.7113"
 102.270 -           style="font-family:Courier">ffb20e1701ea</tspan></text>
 102.271 -    </g>
 102.272 -    <g
 102.273 -       id="g6135"
 102.274 -       transform="translate(153.0396,49.83106)">
 102.275 -      <rect
 102.276 -         inkscape:transform-center-y="102.85714"
 102.277 -         inkscape:transform-center-x="129.28571"
 102.278 -         style="fill:#d4d4d4;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 102.279 -         id="rect6112"
 102.280 -         width="134.53746"
 102.281 -         height="44.537449"
 102.282 -         x="314.15985"
 102.283 -         y="326.52203" />
 102.284 -      <text
 102.285 -         inkscape:transform-center-y="102.7311"
 102.286 -         inkscape:transform-center-x="128.69672"
 102.287 -         xml:space="preserve"
 102.288 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.289 -         x="338.84335"
 102.290 -         y="352.28271"
 102.291 -         id="text6114"><tspan
 102.292 -           sodipodi:role="line"
 102.293 -           id="tspan6116"
 102.294 -           x="338.84335"
 102.295 -           y="352.28271"
 102.296 -           style="fill:black;fill-opacity:1;font-family:Courier">e7639888bb2f</tspan></text>
 102.297 -    </g>
 102.298 -    <text
 102.299 -       xml:space="preserve"
 102.300 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.301 -       x="466.63208"
 102.302 -       y="270.479"
 102.303 -       id="text6118"><tspan
 102.304 -         sodipodi:role="line"
 102.305 -         id="tspan6120"
 102.306 -         x="466.63208"
 102.307 -         y="270.479">First parent (unchanged)</tspan></text>
 102.308 -    <text
 102.309 -       xml:space="preserve"
 102.310 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.311 -       x="466.07544"
 102.312 -       y="364.49615"
 102.313 -       id="text6122"><tspan
 102.314 -         sodipodi:role="line"
 102.315 -         id="tspan6124"
 102.316 -         x="466.07544"
 102.317 -         y="364.49615">Second parent</tspan></text>
 102.318 -    <text
 102.319 -       xml:space="preserve"
 102.320 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.321 -       x="446.61743"
 102.322 -       y="231.36218"
 102.323 -       id="text6195"><tspan
 102.324 -         sodipodi:role="line"
 102.325 -         id="tspan6197"
 102.326 -         x="446.61743"
 102.327 -         y="231.36218">Parents of working directory</tspan></text>
 102.328 -    <path
 102.329 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
 102.330 -       d="M 466.82542,300.21999 L 377.00207,294.39744"
 102.331 -       id="path6266"
 102.332 -       inkscape:connector-type="polyline"
 102.333 -       inkscape:connection-start="#g6130"
 102.334 -       inkscape:connection-end="#rect1925" />
 102.335 -    <path
 102.336 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 102.337 -       d="M 665.12232,418.17579 L 665.12232,418.17579"
 102.338 -       id="path6270"
 102.339 -       inkscape:connector-type="polyline" />
 102.340 -    <g
 102.341 -       id="g2845">
 102.342 -      <rect
 102.343 -         y="266.24374"
 102.344 -         x="242.09048"
 102.345 -         height="44.537449"
 102.346 -         width="134.53746"
 102.347 -         id="rect1925"
 102.348 -         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 102.349 -      <text
 102.350 -         id="text1927"
 102.351 -         y="292.00446"
 102.352 -         x="266.77298"
 102.353 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.354 -         xml:space="preserve"><tspan
 102.355 -           style="font-family:Courier"
 102.356 -           y="292.00446"
 102.357 -           x="266.77298"
 102.358 -           id="tspan1929"
 102.359 -           sodipodi:role="line">ffb20e1701ea</tspan></text>
 102.360 -    </g>
 102.361 -    <path
 102.362 -       inkscape:connector-type="polyline"
 102.363 -       id="path1933"
 102.364 -       d="M 260.89978,311.15532 L 225.84185,327.53627"
 102.365 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
 102.366 -       inkscape:connection-end="#g6976" />
 102.367 -    <text
 102.368 -       xml:space="preserve"
 102.369 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.370 -       x="109.45568"
 102.371 -       y="231.4554"
 102.372 -       id="text2837"><tspan
 102.373 -         sodipodi:role="line"
 102.374 -         id="tspan2839"
 102.375 -         x="109.45568"
 102.376 -         y="231.4554">Pre-existing head</tspan></text>
 102.377 -    <text
 102.378 -       xml:space="preserve"
 102.379 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.380 -       x="237.54184"
 102.381 -       y="231.4554"
 102.382 -       id="text2841"><tspan
 102.383 -         sodipodi:role="line"
 102.384 -         id="tspan2843"
 102.385 -         x="237.54184"
 102.386 -         y="231.4554">Newly created head (and tip)</tspan></text>
 102.387 -    <path
 102.388 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 102.389 -       d="M 148.05048,235.87482 L 149.94915,265.86962"
 102.390 -       id="path2850"
 102.391 -       inkscape:connector-type="polyline"
 102.392 -       inkscape:connection-end="#g1935" />
 102.393 -    <path
 102.394 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
 102.395 -       d="M 303.83495,238.08453 L 306.87874,265.86962"
 102.396 -       id="path2852"
 102.397 -       inkscape:connector-type="polyline"
 102.398 -       inkscape:connection-end="#g2845" />
 102.399 -    <path
 102.400 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
 102.401 -       d="M 466.82545,379.17944 L 219.0253,307.95488"
 102.402 -       id="path3016"
 102.403 -       inkscape:connector-type="polyline"
 102.404 -       inkscape:connection-start="#g6135"
 102.405 -       inkscape:connection-end="#g1935" />
 102.406 -    <g
 102.407 -       id="g1935">
 102.408 -      <rect
 102.409 -         y="266.24374"
 102.410 -         x="84.113708"
 102.411 -         height="44.537449"
 102.412 -         width="134.53746"
 102.413 -         id="rect5996"
 102.414 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 102.415 -      <text
 102.416 -         id="text5998"
 102.417 -         y="292.00446"
 102.418 -         x="108.7962"
 102.419 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 102.420 -         xml:space="preserve"><tspan
 102.421 -           style="font-family:Courier"
 102.422 -           y="292.00446"
 102.423 -           x="108.7962"
 102.424 -           id="tspan6000"
 102.425 -           sodipodi:role="line">e7639888bb2f</tspan></text>
 102.426 -    </g>
 102.427 -  </g>
 102.428 -</svg>
   103.1 --- a/fr/wdir-pre-branch.svg	Sun Aug 16 03:41:39 2009 +0200
   103.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.3 @@ -1,364 +0,0 @@
   103.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
   103.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
   103.6 -<svg
   103.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
   103.8 -   xmlns:cc="http://web.resource.org/cc/"
   103.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  103.10 -   xmlns:svg="http://www.w3.org/2000/svg"
  103.11 -   xmlns="http://www.w3.org/2000/svg"
  103.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
  103.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  103.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  103.15 -   width="744.09448819"
  103.16 -   height="1052.3622047"
  103.17 -   id="svg5971"
  103.18 -   sodipodi:version="0.32"
  103.19 -   inkscape:version="0.44.1"
  103.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
  103.21 -   sodipodi:docname="wdir-branch.svg">
  103.22 -  <defs
  103.23 -     id="defs5973">
  103.24 -    <marker
  103.25 -       inkscape:stockid="Arrow1Mstart"
  103.26 -       orient="auto"
  103.27 -       refY="0.0"
  103.28 -       refX="0.0"
  103.29 -       id="Arrow1Mstart"
  103.30 -       style="overflow:visible">
  103.31 -      <path
  103.32 -         id="path4855"
  103.33 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  103.34 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
  103.35 -         transform="scale(0.4) translate(10,0)" />
  103.36 -    </marker>
  103.37 -    <linearGradient
  103.38 -       id="linearGradient6049">
  103.39 -      <stop
  103.40 -         style="stop-color:#686868;stop-opacity:1;"
  103.41 -         offset="0"
  103.42 -         id="stop6051" />
  103.43 -      <stop
  103.44 -         style="stop-color:#f0f0f0;stop-opacity:1;"
  103.45 -         offset="1"
  103.46 -         id="stop6053" />
  103.47 -    </linearGradient>
  103.48 -    <marker
  103.49 -       inkscape:stockid="Arrow1Mend"
  103.50 -       orient="auto"
  103.51 -       refY="0.0"
  103.52 -       refX="0.0"
  103.53 -       id="Arrow1Mend"
  103.54 -       style="overflow:visible;">
  103.55 -      <path
  103.56 -         id="path4852"
  103.57 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  103.58 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
  103.59 -         transform="scale(0.4) rotate(180) translate(10,0)" />
  103.60 -    </marker>
  103.61 -    <linearGradient
  103.62 -       inkscape:collect="always"
  103.63 -       xlink:href="#linearGradient6049"
  103.64 -       id="linearGradient6083"
  103.65 -       gradientUnits="userSpaceOnUse"
  103.66 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  103.67 -       x1="333.91171"
  103.68 -       y1="488.79077"
  103.69 -       x2="508.94543"
  103.70 -       y2="263.79077" />
  103.71 -    <linearGradient
  103.72 -       inkscape:collect="always"
  103.73 -       xlink:href="#linearGradient6049"
  103.74 -       id="linearGradient6142"
  103.75 -       gradientUnits="userSpaceOnUse"
  103.76 -       gradientTransform="translate(-42.00893,-30.49544)"
  103.77 -       x1="333.91171"
  103.78 -       y1="488.79077"
  103.79 -       x2="508.94543"
  103.80 -       y2="263.79077" />
  103.81 -    <linearGradient
  103.82 -       inkscape:collect="always"
  103.83 -       xlink:href="#linearGradient6049"
  103.84 -       id="linearGradient6193"
  103.85 -       gradientUnits="userSpaceOnUse"
  103.86 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  103.87 -       x1="333.91171"
  103.88 -       y1="488.79077"
  103.89 -       x2="508.94543"
  103.90 -       y2="263.79077" />
  103.91 -    <linearGradient
  103.92 -       inkscape:collect="always"
  103.93 -       xlink:href="#linearGradient6049"
  103.94 -       id="linearGradient6216"
  103.95 -       gradientUnits="userSpaceOnUse"
  103.96 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  103.97 -       x1="333.91171"
  103.98 -       y1="488.79077"
  103.99 -       x2="508.94543"
 103.100 -       y2="263.79077" />
 103.101 -    <linearGradient
 103.102 -       inkscape:collect="always"
 103.103 -       xlink:href="#linearGradient6049"
 103.104 -       id="linearGradient6232"
 103.105 -       gradientUnits="userSpaceOnUse"
 103.106 -       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
 103.107 -       x1="333.91171"
 103.108 -       y1="488.79077"
 103.109 -       x2="508.94543"
 103.110 -       y2="263.79077" />
 103.111 -    <linearGradient
 103.112 -       inkscape:collect="always"
 103.113 -       xlink:href="#linearGradient6049"
 103.114 -       id="linearGradient6445"
 103.115 -       gradientUnits="userSpaceOnUse"
 103.116 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
 103.117 -       x1="333.91171"
 103.118 -       y1="488.79077"
 103.119 -       x2="508.94543"
 103.120 -       y2="263.79077" />
 103.121 -    <linearGradient
 103.122 -       inkscape:collect="always"
 103.123 -       xlink:href="#linearGradient6049"
 103.124 -       id="linearGradient6974"
 103.125 -       gradientUnits="userSpaceOnUse"
 103.126 -       gradientTransform="matrix(1.000474,0,0,0.790947,-314.246,50.85694)"
 103.127 -       x1="333.91171"
 103.128 -       y1="488.79077"
 103.129 -       x2="508.94543"
 103.130 -       y2="263.79077" />
 103.131 -    <linearGradient
 103.132 -       inkscape:collect="always"
 103.133 -       xlink:href="#linearGradient6049"
 103.134 -       id="linearGradient6996"
 103.135 -       gradientUnits="userSpaceOnUse"
 103.136 -       gradientTransform="matrix(1.000473,0,0,0.790947,-85.16012,50.85693)"
 103.137 -       x1="333.91171"
 103.138 -       y1="488.79077"
 103.139 -       x2="508.94543"
 103.140 -       y2="263.79077" />
 103.141 -  </defs>
 103.142 -  <sodipodi:namedview
 103.143 -     id="base"
 103.144 -     pagecolor="#ffffff"
 103.145 -     bordercolor="#666666"
 103.146 -     borderopacity="1.0"
 103.147 -     gridtolerance="10000"
 103.148 -     guidetolerance="10"
 103.149 -     objecttolerance="10"
 103.150 -     inkscape:pageopacity="0.0"
 103.151 -     inkscape:pageshadow="2"
 103.152 -     inkscape:zoom="0.90509668"
 103.153 -     inkscape:cx="390.0539"
 103.154 -     inkscape:cy="690.49342"
 103.155 -     inkscape:document-units="px"
 103.156 -     inkscape:current-layer="layer1"
 103.157 -     showguides="true"
 103.158 -     inkscape:guide-bbox="true"
 103.159 -     inkscape:window-width="906"
 103.160 -     inkscape:window-height="620"
 103.161 -     inkscape:window-x="0"
 103.162 -     inkscape:window-y="25">
 103.163 -    <sodipodi:guide
 103.164 -       orientation="vertical"
 103.165 -       position="-1.4285714"
 103.166 -       id="guide6022" />
 103.167 -  </sodipodi:namedview>
 103.168 -  <metadata
 103.169 -     id="metadata5976">
 103.170 -    <rdf:RDF>
 103.171 -      <cc:Work
 103.172 -         rdf:about="">
 103.173 -        <dc:format>image/svg+xml</dc:format>
 103.174 -        <dc:type
 103.175 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 103.176 -      </cc:Work>
 103.177 -    </rdf:RDF>
 103.178 -  </metadata>
 103.179 -  <g
 103.180 -     inkscape:label="Layer 1"
 103.181 -     inkscape:groupmode="layer"
 103.182 -     id="layer1">
 103.183 -    <rect
 103.184 -       y="245.94225"
 103.185 -       x="20.198257"
 103.186 -       height="204.51619"
 103.187 -       width="174.36833"
 103.188 -       id="rect6047"
 103.189 -       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 103.190 -    <rect
 103.191 -       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 103.192 -       id="rect5996"
 103.193 -       width="134.53746"
 103.194 -       height="44.537449"
 103.195 -       x="40.113693"
 103.196 -       y="266.24374" />
 103.197 -    <text
 103.198 -       xml:space="preserve"
 103.199 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.200 -       x="64.796204"
 103.201 -       y="292.00446"
 103.202 -       id="text5998"><tspan
 103.203 -         sodipodi:role="line"
 103.204 -         id="tspan6000"
 103.205 -         x="64.796204"
 103.206 -         y="292.00446"
 103.207 -         style="font-family:Courier">e7639888bb2f</tspan></text>
 103.208 -    <g
 103.209 -       id="g6976">
 103.210 -      <rect
 103.211 -         y="327.9104"
 103.212 -         x="40.113693"
 103.213 -         height="44.537449"
 103.214 -         width="134.53746"
 103.215 -         id="rect6004"
 103.216 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 103.217 -      <text
 103.218 -         id="text6006"
 103.219 -         y="353.67111"
 103.220 -         x="62.654205"
 103.221 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.222 -         xml:space="preserve"><tspan
 103.223 -           style="font-family:Courier"
 103.224 -           y="353.67111"
 103.225 -           x="62.654205"
 103.226 -           id="tspan6008"
 103.227 -           sodipodi:role="line">7b064d8bac5e</tspan></text>
 103.228 -    </g>
 103.229 -    <path
 103.230 -       inkscape:connection-end="#rect6004"
 103.231 -       inkscape:connector-type="polyline"
 103.232 -       id="path6020"
 103.233 -       d="M 107.38242,311.15529 L 107.38242,327.53626"
 103.234 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 103.235 -    <rect
 103.236 -       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 103.237 -       id="rect6039"
 103.238 -       width="134.53746"
 103.239 -       height="44.537449"
 103.240 -       x="40.113571"
 103.241 -       y="389.57703" />
 103.242 -    <text
 103.243 -       xml:space="preserve"
 103.244 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.245 -       x="64.797073"
 103.246 -       y="415.33771"
 103.247 -       id="text6041"><tspan
 103.248 -         sodipodi:role="line"
 103.249 -         id="tspan6043"
 103.250 -         x="64.797073"
 103.251 -         y="415.33771"
 103.252 -         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 103.253 -    <path
 103.254 -       inkscape:connection-end="#rect6039"
 103.255 -       inkscape:connector-type="polyline"
 103.256 -       id="path6045"
 103.257 -       d="M 107.38238,372.82195 L 107.38235,389.20301"
 103.258 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
 103.259 -    <text
 103.260 -       xml:space="preserve"
 103.261 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.262 -       x="19.660461"
 103.263 -       y="231.36218"
 103.264 -       id="text6102"><tspan
 103.265 -         sodipodi:role="line"
 103.266 -         id="tspan6104"
 103.267 -         x="19.660461"
 103.268 -         y="231.36218">History in repository</tspan></text>
 103.269 -    <rect
 103.270 -       y="245.94225"
 103.271 -       x="249.28412"
 103.272 -       height="204.51619"
 103.273 -       width="174.36833"
 103.274 -       id="rect6140"
 103.275 -       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 103.276 -    <g
 103.277 -       id="g6130"
 103.278 -       transform="translate(-45.67459,24.38544)">
 103.279 -      <rect
 103.280 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
 103.281 -         id="rect6106"
 103.282 -         width="134.53746"
 103.283 -         height="44.537449"
 103.284 -         x="314.87415"
 103.285 -         y="257.95059" />
 103.286 -      <text
 103.287 -         xml:space="preserve"
 103.288 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.289 -         x="339.55664"
 103.290 -         y="283.7113"
 103.291 -         id="text6108"><tspan
 103.292 -           sodipodi:role="line"
 103.293 -           id="tspan6110"
 103.294 -           x="339.55664"
 103.295 -           y="283.7113"
 103.296 -           style="font-family:Courier">7b064d8bac5e</tspan></text>
 103.297 -    </g>
 103.298 -    <g
 103.299 -       id="g6135"
 103.300 -       transform="translate(-44.96042,49.83106)">
 103.301 -      <rect
 103.302 -         inkscape:transform-center-y="102.85714"
 103.303 -         inkscape:transform-center-x="129.28571"
 103.304 -         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 103.305 -         id="rect6112"
 103.306 -         width="134.53746"
 103.307 -         height="44.537449"
 103.308 -         x="314.15985"
 103.309 -         y="326.52203" />
 103.310 -      <text
 103.311 -         inkscape:transform-center-y="102.7311"
 103.312 -         inkscape:transform-center-x="128.69672"
 103.313 -         xml:space="preserve"
 103.314 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.315 -         x="338.84335"
 103.316 -         y="352.28271"
 103.317 -         id="text6114"><tspan
 103.318 -           sodipodi:role="line"
 103.319 -           id="tspan6116"
 103.320 -           x="338.84335"
 103.321 -           y="352.28271"
 103.322 -           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
 103.323 -    </g>
 103.324 -    <text
 103.325 -       xml:space="preserve"
 103.326 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.327 -       x="268.63208"
 103.328 -       y="270.479"
 103.329 -       id="text6118"><tspan
 103.330 -         sodipodi:role="line"
 103.331 -         id="tspan6120"
 103.332 -         x="268.63208"
 103.333 -         y="270.479">First parent</tspan></text>
 103.334 -    <text
 103.335 -       xml:space="preserve"
 103.336 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.337 -       x="268.07544"
 103.338 -       y="364.49615"
 103.339 -       id="text6122"><tspan
 103.340 -         sodipodi:role="line"
 103.341 -         id="tspan6124"
 103.342 -         x="268.07544"
 103.343 -         y="364.49615">Second parent</tspan></text>
 103.344 -    <text
 103.345 -       xml:space="preserve"
 103.346 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 103.347 -       x="248.61746"
 103.348 -       y="231.36218"
 103.349 -       id="text6195"><tspan
 103.350 -         sodipodi:role="line"
 103.351 -         id="tspan6197"
 103.352 -         x="248.61746"
 103.353 -         y="231.36218">Parents of working directory</tspan></text>
 103.354 -    <path
 103.355 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
 103.356 -       d="M 268.82543,318.06163 L 175.02528,336.72225"
 103.357 -       id="path6266"
 103.358 -       inkscape:connector-type="polyline"
 103.359 -       inkscape:connection-end="#g6976"
 103.360 -       inkscape:connection-start="#g6130" />
 103.361 -    <path
 103.362 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 103.363 -       d="M 665.12232,418.17579 L 665.12232,418.17579"
 103.364 -       id="path6270"
 103.365 -       inkscape:connector-type="polyline" />
 103.366 -  </g>
 103.367 -</svg>
   104.1 --- a/fr/wdir.svg	Sun Aug 16 03:41:39 2009 +0200
   104.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.3 @@ -1,348 +0,0 @@
   104.4 -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
   104.5 -<!-- Created with Inkscape (http://www.inkscape.org/) -->
   104.6 -<svg
   104.7 -   xmlns:dc="http://purl.org/dc/elements/1.1/"
   104.8 -   xmlns:cc="http://web.resource.org/cc/"
   104.9 -   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  104.10 -   xmlns:svg="http://www.w3.org/2000/svg"
  104.11 -   xmlns="http://www.w3.org/2000/svg"
  104.12 -   xmlns:xlink="http://www.w3.org/1999/xlink"
  104.13 -   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  104.14 -   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  104.15 -   width="744.09448819"
  104.16 -   height="1052.3622047"
  104.17 -   id="svg5971"
  104.18 -   sodipodi:version="0.32"
  104.19 -   inkscape:version="0.44.1"
  104.20 -   sodipodi:docbase="/home/bos/hg/hgbook/en"
  104.21 -   sodipodi:docname="wdir.svg">
  104.22 -  <defs
  104.23 -     id="defs5973">
  104.24 -    <marker
  104.25 -       inkscape:stockid="Arrow1Mstart"
  104.26 -       orient="auto"
  104.27 -       refY="0.0"
  104.28 -       refX="0.0"
  104.29 -       id="Arrow1Mstart"
  104.30 -       style="overflow:visible">
  104.31 -      <path
  104.32 -         id="path4855"
  104.33 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  104.34 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
  104.35 -         transform="scale(0.4) translate(10,0)" />
  104.36 -    </marker>
  104.37 -    <linearGradient
  104.38 -       id="linearGradient6049">
  104.39 -      <stop
  104.40 -         style="stop-color:#686868;stop-opacity:1;"
  104.41 -         offset="0"
  104.42 -         id="stop6051" />
  104.43 -      <stop
  104.44 -         style="stop-color:#f0f0f0;stop-opacity:1;"
  104.45 -         offset="1"
  104.46 -         id="stop6053" />
  104.47 -    </linearGradient>
  104.48 -    <marker
  104.49 -       inkscape:stockid="Arrow1Mend"
  104.50 -       orient="auto"
  104.51 -       refY="0.0"
  104.52 -       refX="0.0"
  104.53 -       id="Arrow1Mend"
  104.54 -       style="overflow:visible;">
  104.55 -      <path
  104.56 -         id="path4852"
  104.57 -         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  104.58 -         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
  104.59 -         transform="scale(0.4) rotate(180) translate(10,0)" />
  104.60 -    </marker>
  104.61 -    <linearGradient
  104.62 -       inkscape:collect="always"
  104.63 -       xlink:href="#linearGradient6049"
  104.64 -       id="linearGradient6083"
  104.65 -       gradientUnits="userSpaceOnUse"
  104.66 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  104.67 -       x1="333.91171"
  104.68 -       y1="488.79077"
  104.69 -       x2="508.94543"
  104.70 -       y2="263.79077" />
  104.71 -    <linearGradient
  104.72 -       inkscape:collect="always"
  104.73 -       xlink:href="#linearGradient6049"
  104.74 -       id="linearGradient6142"
  104.75 -       gradientUnits="userSpaceOnUse"
  104.76 -       gradientTransform="translate(-42.00893,-30.49544)"
  104.77 -       x1="333.91171"
  104.78 -       y1="488.79077"
  104.79 -       x2="508.94543"
  104.80 -       y2="263.79077" />
  104.81 -    <linearGradient
  104.82 -       inkscape:collect="always"
  104.83 -       xlink:href="#linearGradient6049"
  104.84 -       id="linearGradient6193"
  104.85 -       gradientUnits="userSpaceOnUse"
  104.86 -       gradientTransform="translate(-240.0462,-8.633237e-6)"
  104.87 -       x1="333.91171"
  104.88 -       y1="488.79077"
  104.89 -       x2="508.94543"
  104.90 -       y2="263.79077" />
  104.91 -    <linearGradient
  104.92 -       inkscape:collect="always"
  104.93 -       xlink:href="#linearGradient6049"
  104.94 -       id="linearGradient6216"
  104.95 -       gradientUnits="userSpaceOnUse"
  104.96 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
  104.97 -       x1="333.91171"
  104.98 -       y1="488.79077"
  104.99 -       x2="508.94543"
 104.100 -       y2="263.79077" />
 104.101 -    <linearGradient
 104.102 -       inkscape:collect="always"
 104.103 -       xlink:href="#linearGradient6049"
 104.104 -       id="linearGradient6232"
 104.105 -       gradientUnits="userSpaceOnUse"
 104.106 -       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
 104.107 -       x1="333.91171"
 104.108 -       y1="488.79077"
 104.109 -       x2="508.94543"
 104.110 -       y2="263.79077" />
 104.111 -    <linearGradient
 104.112 -       inkscape:collect="always"
 104.113 -       xlink:href="#linearGradient6049"
 104.114 -       id="linearGradient6445"
 104.115 -       gradientUnits="userSpaceOnUse"
 104.116 -       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
 104.117 -       x1="333.91171"
 104.118 -       y1="488.79077"
 104.119 -       x2="508.94543"
 104.120 -       y2="263.79077" />
 104.121 -  </defs>
 104.122 -  <sodipodi:namedview
 104.123 -     id="base"
 104.124 -     pagecolor="#ffffff"
 104.125 -     bordercolor="#666666"
 104.126 -     borderopacity="1.0"
 104.127 -     gridtolerance="10000"
 104.128 -     guidetolerance="10"
 104.129 -     objecttolerance="10"
 104.130 -     inkscape:pageopacity="0.0"
 104.131 -     inkscape:pageshadow="2"
 104.132 -     inkscape:zoom="0.90509668"
 104.133 -     inkscape:cx="390.0539"
 104.134 -     inkscape:cy="690.49342"
 104.135 -     inkscape:document-units="px"
 104.136 -     inkscape:current-layer="layer1"
 104.137 -     showguides="true"
 104.138 -     inkscape:guide-bbox="true"
 104.139 -     inkscape:window-width="906"
 104.140 -     inkscape:window-height="620"
 104.141 -     inkscape:window-x="0"
 104.142 -     inkscape:window-y="25">
 104.143 -    <sodipodi:guide
 104.144 -       orientation="vertical"
 104.145 -       position="-1.4285714"
 104.146 -       id="guide6022" />
 104.147 -  </sodipodi:namedview>
 104.148 -  <metadata
 104.149 -     id="metadata5976">
 104.150 -    <rdf:RDF>
 104.151 -      <cc:Work
 104.152 -         rdf:about="">
 104.153 -        <dc:format>image/svg+xml</dc:format>
 104.154 -        <dc:type
 104.155 -           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 104.156 -      </cc:Work>
 104.157 -    </rdf:RDF>
 104.158 -  </metadata>
 104.159 -  <g
 104.160 -     inkscape:label="Layer 1"
 104.161 -     inkscape:groupmode="layer"
 104.162 -     id="layer1">
 104.163 -    <g
 104.164 -       id="g6431"
 104.165 -       transform="translate(0,-0.137863)">
 104.166 -      <rect
 104.167 -         style="fill:url(#linearGradient6445);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 104.168 -         id="rect6047"
 104.169 -         width="174.36833"
 104.170 -         height="204.51619"
 104.171 -         x="94.198257"
 104.172 -         y="246.08011" />
 104.173 -      <rect
 104.174 -         y="266.38159"
 104.175 -         x="114.11369"
 104.176 -         height="44.537449"
 104.177 -         width="134.53746"
 104.178 -         id="rect5996"
 104.179 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 104.180 -      <text
 104.181 -         id="text5998"
 104.182 -         y="292.1423"
 104.183 -         x="138.7962"
 104.184 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.185 -         xml:space="preserve"><tspan
 104.186 -           style="font-family:Courier"
 104.187 -           y="292.1423"
 104.188 -           x="138.7962"
 104.189 -           id="tspan6000"
 104.190 -           sodipodi:role="line">e7639888bb2f</tspan></text>
 104.191 -      <rect
 104.192 -         y="328.04825"
 104.193 -         x="114.11369"
 104.194 -         height="44.537449"
 104.195 -         width="134.53746"
 104.196 -         id="rect6004"
 104.197 -         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 104.198 -      <text
 104.199 -         id="text6006"
 104.200 -         y="353.80896"
 104.201 -         x="136.65421"
 104.202 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.203 -         xml:space="preserve"><tspan
 104.204 -           style="font-family:Courier"
 104.205 -           y="353.80896"
 104.206 -           x="136.65421"
 104.207 -           id="tspan6008"
 104.208 -           sodipodi:role="line">7b064d8bac5e</tspan></text>
 104.209 -      <path
 104.210 -         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
 104.211 -         d="M 181.38242,311.29315 L 181.38242,327.67412"
 104.212 -         id="path6020"
 104.213 -         inkscape:connector-type="polyline"
 104.214 -         inkscape:connection-end="#rect6004" />
 104.215 -      <rect
 104.216 -         y="389.71487"
 104.217 -         x="114.11357"
 104.218 -         height="44.537449"
 104.219 -         width="134.53746"
 104.220 -         id="rect6039"
 104.221 -         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 104.222 -      <text
 104.223 -         id="text6041"
 104.224 -         y="415.47556"
 104.225 -         x="138.79707"
 104.226 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.227 -         xml:space="preserve"><tspan
 104.228 -           style="fill:#979797;fill-opacity:1;font-family:Courier"
 104.229 -           y="415.47556"
 104.230 -           x="138.79707"
 104.231 -           id="tspan6043"
 104.232 -           sodipodi:role="line">000000000000</tspan></text>
 104.233 -      <path
 104.234 -         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
 104.235 -         d="M 181.38238,372.95981 L 181.38235,389.34087"
 104.236 -         id="path6045"
 104.237 -         inkscape:connector-type="polyline"
 104.238 -         inkscape:connection-end="#rect6039" />
 104.239 -    </g>
 104.240 -    <text
 104.241 -       xml:space="preserve"
 104.242 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.243 -       x="93.660484"
 104.244 -       y="231.36218"
 104.245 -       id="text6102"><tspan
 104.246 -         sodipodi:role="line"
 104.247 -         id="tspan6104"
 104.248 -         x="93.660484"
 104.249 -         y="231.36218">History in repository</tspan></text>
 104.250 -    <g
 104.251 -       id="g6416">
 104.252 -      <rect
 104.253 -         style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 104.254 -         id="rect6140"
 104.255 -         width="174.36833"
 104.256 -         height="204.51619"
 104.257 -         x="323.28412"
 104.258 -         y="245.94225" />
 104.259 -      <g
 104.260 -         transform="translate(28.32541,24.38544)"
 104.261 -         id="g6130">
 104.262 -        <rect
 104.263 -           y="257.95059"
 104.264 -           x="314.87415"
 104.265 -           height="44.537449"
 104.266 -           width="134.53746"
 104.267 -           id="rect6106"
 104.268 -           style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
 104.269 -        <text
 104.270 -           id="text6108"
 104.271 -           y="283.7113"
 104.272 -           x="339.55664"
 104.273 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.274 -           xml:space="preserve"><tspan
 104.275 -             style="font-family:Courier"
 104.276 -             y="283.7113"
 104.277 -             x="339.55664"
 104.278 -             id="tspan6110"
 104.279 -             sodipodi:role="line">e7639888bb2f</tspan></text>
 104.280 -      </g>
 104.281 -      <g
 104.282 -         transform="translate(29.03958,49.83106)"
 104.283 -         id="g6135">
 104.284 -        <rect
 104.285 -           y="326.52203"
 104.286 -           x="314.15985"
 104.287 -           height="44.537449"
 104.288 -           width="134.53746"
 104.289 -           id="rect6112"
 104.290 -           style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 104.291 -           inkscape:transform-center-x="129.28571"
 104.292 -           inkscape:transform-center-y="102.85714" />
 104.293 -        <text
 104.294 -           id="text6114"
 104.295 -           y="352.28271"
 104.296 -           x="338.84335"
 104.297 -           style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.298 -           xml:space="preserve"
 104.299 -           inkscape:transform-center-x="128.69672"
 104.300 -           inkscape:transform-center-y="102.7311"><tspan
 104.301 -             style="fill:#979797;fill-opacity:1;font-family:Courier"
 104.302 -             y="352.28271"
 104.303 -             x="338.84335"
 104.304 -             id="tspan6116"
 104.305 -             sodipodi:role="line">000000000000</tspan></text>
 104.306 -      </g>
 104.307 -      <text
 104.308 -         id="text6118"
 104.309 -         y="270.479"
 104.310 -         x="342.63208"
 104.311 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.312 -         xml:space="preserve"><tspan
 104.313 -           y="270.479"
 104.314 -           x="342.63208"
 104.315 -           id="tspan6120"
 104.316 -           sodipodi:role="line">First parent</tspan></text>
 104.317 -      <text
 104.318 -         id="text6122"
 104.319 -         y="364.49615"
 104.320 -         x="342.07544"
 104.321 -         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.322 -         xml:space="preserve"><tspan
 104.323 -           y="364.49615"
 104.324 -           x="342.07544"
 104.325 -           id="tspan6124"
 104.326 -           sodipodi:role="line">Second parent</tspan></text>
 104.327 -    </g>
 104.328 -    <text
 104.329 -       xml:space="preserve"
 104.330 -       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
 104.331 -       x="322.61746"
 104.332 -       y="231.36218"
 104.333 -       id="text6195"><tspan
 104.334 -         sodipodi:role="line"
 104.335 -         id="tspan6197"
 104.336 -         x="322.61746"
 104.337 -         y="231.36218">Parents of working directory</tspan></text>
 104.338 -    <path
 104.339 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
 104.340 -       d="M 342.82543,299.89384 L 249.02528,293.36123"
 104.341 -       id="path6266"
 104.342 -       inkscape:connector-type="polyline"
 104.343 -       inkscape:connection-start="#g6130"
 104.344 -       inkscape:connection-end="#rect5996" />
 104.345 -    <path
 104.346 -       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 104.347 -       d="M 665.12232,418.17579 L 665.12232,418.17579"
 104.348 -       id="path6270"
 104.349 -       inkscape:connector-type="polyline" />
 104.350 -  </g>
 104.351 -</svg>