%% Mercurial French Cookbook - Adrien Herubel - 2007
%% This documentation is free as in free speech. It comes without any warranty, to
%% the extent permitted by applicable law. You can redistribute it
%% and/or modify it under the terms of the Do What The Fuck You Want
%% To Public License, Version 2, as published by Sam Hocevar. See
%% http://sam.zoy.org/wtfpl/COPYING for more details.


%Article : Utiliser Mercurial et la libRT in a Nutshell.
\documentclass[a4paper,11pt]{article}

%Fichier unicode
\usepackage[utf8]{inputenc}

%Police standard
\usepackage[T1]{fontenc}
\usepackage{lmodern}

%Francisation
\usepackage[francais]{babel}

% Package d'inclusion de code.
\usepackage{listings}
\lstset{tabsize=2,basicstyle=\scriptsize,frame=single,extendedchars=true,inputencoding=utf8} %Petite taille + cadre

\usepackage{makeidx}

%Configuration des marges
\usepackage{anysize}
\marginsize{1cm}{1cm}{1cm}{1cm}



\usepackage{hyperref}
\hypersetup{colorlinks, linkcolor=black, urlcolor=blue,%
 pdfcreator={LaTeX},%
 } 


%Définition des commandes
\newcommand{\librt}{ {\bf libMISSTK} }

%Header 
\title{Utiliser Mercurial \\ in a Nutshell}
\author{Adrien Herubel}
\date{\today}

%Document
\begin{document}

%Couverture
\pagestyle{empty}
\maketitle
%%\newpage


%Table des Matières
\pagestyle{headings}
\tableofcontents
%%\newpage

%Partie 1
\part{Pour commencer}
\section{Conventions de nommage}
Les notions et mots clés propres à Mercurial seront notés en {\bf gras} tandis que les noms de commandes seront notés en {\it italique}.
Les résultats de commande seront présenté sous la forme:
\begin{lstlisting}[]
$ commande
resultat
\end{lstlisting}

\section{Installer Mercurial}
 
\subsection{Sur Linux}
Il existe un paquet Mercurial pour la plupart des distributions donc sur Debian et Ubuntu un simple:
\begin{lstlisting}[]
$ apt-get install mercurial
\end{lstlisting}
devrait suffire.\\
Les sources sont disponibles ici : \url{http://www.selenic.com/mercurial/download}.

\subsection {sur MacOSX}
Un paquet est disponible pour les macs PowerPC et Intel à l'adresse suivante : 
\url{http://mercurial.berkwood.com}. Il est nécessaire de disposer d'une installation de Python valide.

\subsection {sur Windows}
Un installeur indépendant est disponible à l'adresse suivante : \url{http://mercurial.berkwood.com}.

\section{Premières commandes}
Il n'existe qu'une seule commande pour gérer l'ensemble des fonctions de Mercurial : {\it hg}  (symbole du mercure)

\subsection{Tester l'installation}
Si l'installation s'est bien passée la commande suivante devrait fonctionner :
\begin{lstlisting}[]
$ hg version
Mercurial Distributed SCM (version 0.9.3)

Copyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\end{lstlisting}

\subsection{L'aide intégrée}
Mercurial possède un système d'aide intégrée. {\it hg help} fournit une liste de commande 
et une rapide description tandis que {\it hg help  \textless commande\textgreater } fournit le manuel de la commande.
\begin{lstlisting}[]
$ hg help init
hg init [-e CMD] [--remotecmd CMD] [DEST]

create a new repository in the given directory

    Initialize a new repository in the given directory.  If the given
    directory does not exist, it is created.

    If no directory is given, the current directory is used.

    It is possible to specify an ssh:// URL as the destination.
    Look at the help text for the pull command for important details
    about ssh:// URLs.

options:

 -e --ssh        specify ssh command to use
    --remotecmd  specify hg command to run on the remote side
\end{lstlisting}

\subsection{Syntaxe des commandes}
Toutes les commandes mercurial sont préfixées par {\it hg}, dans ce manuel on se référera le plus souvent au suffixe, 
par exemple la commande {\it log} est en réalité la commande {\it hg log}. 
La plupart des commandes peuvent s'appliquer à un fichier en particulier s'il est précisé ou à l'ensemble du repository s'il est omis.
De plus la majorité des commandes supportent les expressions régulières.

\section{Notions}
\subsection{Repository}
Un repository Mercurial contient deux éléments, le {\bf répertoire de travail} 
dans lequel les fichiers sont modifiés et le {\bf store} ou se trouve l'historique 
complet du projet. Contrairement systèmes de gestion de version centralisés type CVS/Subversion,
il n'existe pas de Repository central. Chaque développeur possède un clone du repository 
et donc de l'historique du projet. Cette approche permet le développement en parallèle.

\subsection{Changesets, Révisions}
Un {\bf changeset} est un lot de modifications dans le répertoire de travail, enregistré par une opération de {\bf commit}. 
Le changeset intégré s'appelle une {\bf révision}. Chaque révision possède un numéro de révision. 
En cas de développement parallèle les numéros de révision peuvent entrer en conflit, 
Mercurial assigne donc à chaque révision un identifiant de changeset unique
long de 40 chiffres qui peut s'abréger sous la forme ``e38487''.

\subsection{Branches, Heads et Tip}
Une {\bf branche} est une révision fille d'une autre révision.
Une révision parente peut avoir plusieurs révisions filles en cas de développement parallèle. 
Les dernières révisions de chaque branche sont appelées des {\bf heads}. 
Le {\bf tip} est la head avec le plus haut numéro de révision. 
Une révision possédant deux révisions parentes s'appelle un {\bf merge}.

\subsection{Clone}
Un {\bf clone} est une copie complète d'un repository comprenant le repertoire de travail et le store.
Le clone est l'opération qui permet à plusieurs développeurs de travailler sur le même projet 
ou au même développeur de travailler sur deux versions du projet (private/public, stable/unstable). 
L'opération de clone est aussi une façon simple de tester l'incidence d'un changement sur le projet en toute sécurité.

Plus de details :
\begin{lstlisting}
$ hg help clone
\end{lstlisting}

\subsection{Commit}
Lors d'une opération de {\bf commit} l'état du répertoire de travail 
est enregistré en tant que nouvelle révision. Chaque commit enregistre un changeset et crée une nouvelle révision. 
Un commit donne lieu à un rapport de commit.

Plus de details :
\begin{lstlisting}
$ hg help commit
\end{lstlisting}

\subsection{Pull, Push et Merge}
L'opération {\bf pull} permet de synchroniser un repository local avec un autre repository. 
Cette opération fonctionne aussi bien en local que par ssh, http ou https. Le {\bf push} est l'opération inverse, on synchronise 
un repository distant avec son repository local.
Si les deux repository on subit des développements en parallèle, le pull/push créera une branche divergente à partir de la dernière révision commune.
Il existera alors plusieurs heads dans le projet. Ces heads peuvent être mergées grâce à l'opération {\bf merge}. 

Plus de details :
\begin{lstlisting}
$ hg help pull
$ hg help push
$ hg help merge
\end{lstlisting}

% Partie 2 
\part{Recettes}
\section{Configurer son {\it .hgrc}}
Le fichier de configuration .hgrc influe sur le comportement général de Mercurial 
et permet de configurer certaines fonctionnalités et extensions.
Un fichier .hrgc doit se trouver dans \~/ et comporter au minimum :
\begin{lstlisting}
[ui]
username = "Adrien Herubel <herubel@gmail.com>"
\end{lstlisting}

Pour plus d'informations sur les options, consulter le man {\it hgrc } 
et le fichier /usr/share/doc/mercurial/examples/sample.hgrc installé par le paquet debian/ubuntu.


\section{Commencer un nouveau projet avec Mercurial.}
Il suffit d'une seule commande pour transformer un répertoire en repository Mercurial. La création d'un nouveau projet 
utilisant Mercurial est particulièrement aisée :
\begin{lstlisting}
$ mkdir myHelloWorld && cd myHelloWorld
$ hg init
\end{lstlisting}
La commande hg init permet d'initialiser le repository mercurial (voir {\it hg help init} pour les options). 
Elle construit le store :
\begin{lstlisting}
$ls -la 
drwxr-xr-x  3 ----- ----- 4096 8888-88-88 88:88 .hg
\end{lstlisting}
La réciproque est aussi vraie, pour supprimer le support de Mercurial dans un repository il suffit d'effacer le store {\it .hg}.
On peut ensuite créer ses premiers fichiers.
\begin{lstlisting}
$ echo '
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
	printf("Hello, World\n!");
	return (EXIT_SUCCESS);
}
' > main.c
\end{lstlisting}
On ajoute en suite les fichiers crées grâce à la commande hg add. 
On peut contrôler le résultat grâce à la commande hg status qui montre 
les changements du répertoire de travail par rapport à la dernière révision.
\begin{lstlisting}
$ hg add main.c 
$ hg status 
A main.c
\end{lstlisting}
hg status nous indique que main.c  a été ajouté.
On utilise ensuite hg commit pour valider les changements et créer la première révision du projet.
\begin{lstlisting}
$ hg commit -m 'Creation du projet'
\end{lstlisting}


\section{Développer un projet avec Mercurial}
Cette recette explique les commandes et les procédures d'usage quotidiennes de Mercurial~:
la gestion des fichiers du repository, la sauvegarde des modifications, l'utilisation de l'historique 
et la correction des erreurs.
\subsection{Gérer le tracking des fichiers}
Mercurial ne travaille pas avec les fichiers du repository tant qu'on ne lui a pas explicitement demandé de le faire.
La commande hg status informe des fichiers du repository non traités en les marquant avec un {\it ?}
\begin{lstlisting}
$hg status
? main.c
\end{lstlisting}
Afin de spécifier à Mercurial de gérer un fichier il faut utiliser la commande {\it add} comme vu dans la recette précédente.
\begin{lstlisting}
$hg add main.c
$hg status
A main.c
\end{lstlisting}
On remarque que {\it status} signale maintenant le fichier {\it main.c } comme ayant été ajouté. 

Il est important de noter que Mercurial traite des fichiers et non des répertoires. 
Si l'on passe des répertoires et non des fichiers à la commande add, celle-ci traitera récursivement 
les fichiers inclus dans les répertoires. Si l'on veut que Mercurial traite un répertoire vide la seule méthode est
d'ajouter un fichier invisible et de l'ajouter.

Si l'on veut que Mercurial arrête de gérer un fichier il faut utiliser la commande {\it remove}.
\begin{lstlisting}
$hg remove main.c
$hg status
R main.c
\end{lstlisting}
Le fichier est alors marqué R par {\it status}. Les modifications du fichiers ne seront plus suivies par Mercurial, 
le fichier peut être effacé et recréé puis ajouté à nouveau il ne sera pas lié à l'ancienne version.
%% Si un fichier géré par Mercurial est effacé.
Si un fichier toujours géré par Mercurial est effacé, il est marqué comme manquant.
\begin{lstlisting}
$rm main.c
$hg status
! main.c
\end{lstlisting}
Ces commandes n'ont aucune incidence sur l'historique du fichier. En cas de retour en arrière 
dans les versions du projet, le fichier sera présent.
\subsection{Renommer les fichiers}
L'opération de renommage de Mercurial s'appuie sur deux autres opérations, la suppression et la copie.
\begin{lstlisting}
$ls
main.c
$hg rename main.c myHelloWorld.c
$ls
myHelloWorld.c
$hg status
A myHelloWorld.c
R main.c
$hg status -C
A myHelloWorld.c
  main.c
R main.c
\end{lstlisting}
Lors de l'utilisation de l'opération {\it rename} Mercurial a fait une copie du fichier {\it main.c} et l'a appelé {\it myHelloWorld.c}.
Il a ensuite marqué {\it main.c} comme effacé et {\it myHelloWorld.c} comme ajouté. Mercurial garde une trace de la source d'une copie. 
L'option -C de la commande {\it status} permet de trouver la source d'un fichier copié. 
Ainsi {\it myHelloWorld.c} possède son historique propre et celui de sa source.
\subsection{Commiter ses modifications}
La commande {\it status} permet de lister tous les fichiers modifiés depuis la dernière révision~:
elle permet de voir les fichiers ajoutés, supprimés, manquants et modifiés. Le groupe de modifications consultable par la commande {\it status} 
est un changeset. Ce changeset doit être commité pour devenir une nouvelle révision.
La commande { \it commit} permet d'enregistrer le changeset. Cette commande s'accompagne par la rédaction d'un message de commit.
Seule la première ligne d'un message de commit est affichée par défaut, 
le message rédigé doit dont comprendre une première ligne de résumé indépendante du reste du message.
Le message est rédigé avec l'éditeur décrit dans le fichier {\it .hgrc} ou bien dans la variable d'environnement {\it EDITOR} ou dans vi par défaut.
Enfin l'option {\it -m } permet de passer directement le message de commit en ligne de commande.
\begin{lstlisting}
$ hg commit -m 'Creation du projet'
\end{lstlisting}
\subsection{Consulter l'historique}
La commande {\it status} permet de consulter l'état des fichiers du répertoire de travail. 
Après un commit le répertoire de travail est identique à la dernière révision et la commande {\it status} ne montre plus rien. 
C'est la commande {\it log } qui va permettre de consulter l'historique du projet. Par défaut elle se contente d'afficher 
l'ensemble des révisions et pour chaque révision, l'id de changeset, l'utilisateur, la date du commit ainsi que la première ligne du message de commit.
\begin{lstlisting}
$ hg log
changeset:   1:1e9ce0993cc1
tag:         tip
user:        "Adrien Herubel <herubel@gmail.com>"
date:        Wed Jul 25 11:54:16 2007 +0200
summary:     Correction syntaxique

changeset:   0:a42bff8275ac
user:        "Adrien Herubel <herubel@gmail.com>"
date:        Tue Jul 24 18:37:25 2007 +0200
summary:     Ajout du fichier
\end{lstlisting}
La commande {\it log } accepte de nombreuses options, l'option {\it -r <revision number>} 
permet de consulter une ou plusieurs révisions précises. L'option {\it -v ou --verbose} 
donne plus d'informations sur le commit et l'option {\it -p ou --patch} affiche le diff unifié entre les deux dernières révisions.
\begin{lstlisting}
$ hg log -v -r1 -p
changeset:   1:1e9ce0993cc1
tag:         tip
user:        "Adrien Herubel <herubel@gmail.com>"
date:        Wed Jul 25 11:54:16 2007 +0200
files:       main.c
description:
Correction syntaxique


diff -r a42bff8275ac -r 1e9ce0993cc1 main.c
--- a/main.c	Tue Jul 24 18:37:25 2007 +0200
+++ b/main.c	Wed Jul 25 11:54:16 2007 +0200
@@ -1,8 +1,8 @@
 
-#include <stdio . h>
-#include <stdlib . h>
+#include <stdio.h>
+#include <stdlib.h>
 int main( int argc , char **argv ) {
-printf ( Hello , World\n !  ) ;
-return (EXIT SUCCESS) ;
+printf ( "Hello, World!\n");
+return (EXIT_SUCCESS);
 }
\end{lstlisting} 
La commande {\it hg diff} permet d'afficher un fichier diff en réglant plus finement les paramètres d'affichage et de révision.
La commande {\it tip} fonctionne de la même manière que log sauf qu'elle ne s'applique qu'au {\it tip } 
c'est à dire la dernière révision, cette commande est particulièrement utile après un commit.

\subsection{Revenir en arrière et corriger ses erreurs}
\subsubsection{Annuler un changement pas encore commité}
Si un changement dans le répertoire de travail doit être annulé et que celui-ci n'a pas encore été commité ,
il est possible de faire revenir le repository, ou un seul fichier, à l'état de la dernière révision grâce à la commande {\it revert}.
Par exemple si un fichier a été ajouté avec {\it add}, modifié ou effacé par mégarde~: 
\begin{lstlisting}
$ ls
myHelloWorld.c
$ rm myHelloWorld.c 
$ hg revert myHelloWorld.c 
$ ls
myHelloWorld.c
\end{lstlisting}
L'option {\it --all} permet de replacer l'ensemble du répertoire de travail dans l'état de la dernière révision. 
Attention il est impossible d'annuler un {\it revert}.
\subsubsection{Annuler un changement déjà commité}
Mercurial fournit une commande simple permettant d'annuler un commit accidentel. Par exemple, s'il l'on crée un fichier 
et qu'on commit les changements en ayant oublier d'utiliser {\it add} sur le fichier, il est possible d'annuler le commit 
grâce à la commande {\it rollback}. Cette commande peut annuler un et un seul {\it commit}, {\it pull} ou {\it import}. 
Attention il est impossible d'annuler un {\it rollback}.
Mercurial fournit de nombreuses commandes de retour et d'annulation de changements. La commande {\it revert} précédemment vue 
permet aussi de remonter dans l'historique des révision grâce à l'option {\it -r}. 
La commande {\it backout} est extrêmement efficace. Soient trois changements a, b et c. La commande backout va permettre d'annuler le changement b sans annuler les changements a et c. Elle va en fait créer un autre changement inverse à b qui va annuler ses effets.
\subsubsection{Voyager dans le temps}
Il est souvent utile de faire revenir le répertoire de travail à l'état ou il était à telle ou telle version, notamment pour la recherche d'anciens bugs. Mercurial fournit la commande {\it update} qui permet de faire revenir le répertoire de travail à la révision souhaitée. Cette opération est non destructrice, elle ne modifie à aucun moment l'historique.
\begin{lstlisting}
$ ls
myHelloWorld.c
$ hg update -r 0
$ ls
main.c
$ hg update -r tip 
$ ls
myHelloWorld.c
\end{lstlisting}
A noter qu'il est possible de modifier les fichiers alors qu'on est en update dans une ancienne révision. Le commit d'un tel changeset créera une nouvelle head 
sur laquelle pourront se greffer d'autres développement. Les deux heads pourront bien sur être mergées.


\section{Participer à un projet avec mainteneur central}
L'avantage des systèmes de gestion de versions distribués, c'est qu'ils laissent au développeur le soin de décider eux-même de l'architecture du développement. On s'intéressera dans cette recette au projet avec mainteneur central. Un développeur met à disposition la version officielle du projet, quelques développeurs ont accès au repository, les autres envoient des patchs au mainteneur central.
\subsection{Récupérer le projet}
La récupération d'un repository existant s'effectue à travers la commande {\it clone}. Les clones peuvent se faire en local, auquel cas Mercurial utilisera des liens en durs pour effectuer un clonage rapide et peu coûteux en espace disque (équivalent à {\it cp -al }), au travers d'ssh, par le mini-serveur http {\it hg serve} ou encore par cgi avec Apache et hgweb.cgi.
\begin{lstlisting}
$ hg clone myHelloWorld myHelloWorld-dev
$ hg clone ssh://login@myhelloworld.org:22/repository/myhelloworld
$ hg clone http://hg.myhelloworld.com/myhelloworld
\end{lstlisting}
\subsection{Mettre à jour son repository}
Lorsque d'un développeur travaille sur son propre clone du repository central, il est nécessaire d'effectuer régulièrement des {\it pull} 
du repository central afin d'inclure les mises à jour dans sa propre version. Cela facilite grandement le travail de mainteneur central, car la 
plupart des conflits lors des merge sont ainsi résolus par les développeurs. %% qui soumettent les modification donnant lieu à un conflit.
La commande {\it pull} est semblable par la syntaxe à la commande clone et fonctionne sur les mêmes supports.
\begin{lstlisting}
$ hg pull ../myHelloWorld-dev 
pulling from ../myHelloWorld-dev
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
(run 'hg update' to get a working copy)
\end{lstlisting}
À noter que la commande {\it pull} ne modifie pas elle même le répertoire de travail, notamment pour éviter des problèmes liés à un répertoire se trouvant 
dans un état antérieur suite à une commande {\it update}. Afin d'appliquer les changements au répertoire de travail, il faut utiliser la commande {\it hg update} 
qui replacera le répertoire dans l'état du tip.
Si des développements ont eu lieu en parallèle, le {\it pull} créera une nouvelle head. 
Les deux heads pourront être mergées et les conflits résolus grâce à la commande {\it hg merge}. La commande {\it pull} peut être annulée grâce à {\it rollback}.
\subsection{Partager ses modifications}
\subsubsection{La méthode push}
La commande {\it push} est la réciproque de {\it pull}~: elle permet d'envoyer ses changements vers un repository distant. 
Dans notre exemple d'architecture de développement, quelques développeurs privilégiés 
ont les droits d'accès en ssh sur le repository central et effectuent des {\it push}s directement. 
Par défaut, la commande {\it push} interdit la création de nouvelles head dans le repository distant (ce qui est plutôt une bonne chose), car Mercurial préconise une 
approche où le développeur résout les conflits locaux avant d'envoyer ses modifications. Attention la commande {\it push} ne peut pas être annulée par un {\it rollback}.
\subsubsection{Envoyer des patchs}
Pour le reste du monde, l'accès ssh n'est pas disponible. Seule reste la possibilité d'envoyer des patchs 
par mail au mainteneur ou à l'un des développeurs privilégiés. La commande {\it export} est utilisée pour produire des patchs. 
Elle prend en argument la ou les révisions qui vont constituer le patch. 
\begin{lstlisting}
$ hg export 17 18 19 > mypatch.patch 
\end{lstlisting}
La même règle s'applique que pour les push~: un patch ne doit pas créer de nouvelles head sur le repository du mainteneur.
Le développeur qui fournit le patch résout les conflits locaux avant la soumission.

\section{Maintenir un projet multi-développeurs}
\subsection{Publier le projet en ssh}
La publication par ssh permet de publier le projet en lecture et écriture pour les développeurs et mainteneurs principaux du projet.
Chaque développeur doit bénéficier d'un compte sur la machine hébergeant le serveur ssh, ainsi qu'un accès en lecture et écriture sur le repository.
Il est conseillé de générer une paire de clé d'identification afin d'éviter de devoir retaper un mot de passe à chaque {\it pull}.
La syntaxe des URL ssh est la suivante~:
\begin{lstlisting}
ssh://login@server:port/path
\end{lstlisting}

\subsection{Publier le projet en http}
La publication par http permet de fournir rapidement sur un protocole standard 
un accès en lecture au repository et une interface web de consultation.
Mercurial fournit un petit serveur http basique pour publier un repository :
\begin{lstlisting}
$ hg serve -p 8000
\end{lstlisting}
Pour un usage plus soutenu, il est conseillé d'utiliser {\it hgweb.cgi }  ({\it /usr/share/doc/mercurial/examples/hgweb.cgi }) un script
CGI qui s'utilise avec Apache. Il est pour cela nécessaire de disposer d'un serveur web type Apache ou lighttpd supportant le CGI python.

Une troisième méthode basée sur le protocole static-http permet de publier le repository sans disposer d'un serveur supportant les CGI, 
il suffit de placer le repository en accès sur le serveur web. Les commandes de {\it clone}, {\it push} et {\it pull} utiliseront alors la syntaxe suivante
\begin{lstlisting}
$ hg clone static-http://server/repository
\end{lstlisting}
Cette méthode est cependant assez lente.

Enfin une dernière méthode, la plus simple, mais qui ne permettra pas les opérations de  {\it clone}, {\it push} et {\it pull} est de diffuser une archive du repository.
Attention, la commande {\it hg archive} ne convient pas pour cette méthode car elle crée une archive sans le store.



\subsection{Appliquer et tester un patch}
Les patchs proviennent d'utilisateurs n'ayant pas d'accès ssh au repository. 
Les patchs peuvent potentiellement être nocifs et doivent être étudiés avant application.
Il existe de nombreux programmes pour lire les patchs de façon graphique. 
La manière la plus sure d'appliquer un patch est de cloner le repository en local et d'appliquer le patch sur le clone. 
On peut ensuite tester le patch puis en cas de validation faire un push dans le repository officiel.
\begin{lstlisting}
$ hg clone myHelloWorld myHelloWorld-experimental
$ cd myHelloWorld-experimental
$ hg import ../patchexperimental.patch
**faire les tests**
$ hg push ../myHelloWorld
$ cd ../myHelloWorld
$ hg update
\end{lstlisting}
\subsection{Définir des numéros de version}
Il peut parfois être utile de marquer une révision de façon plus spécifique, par exemple pour la 
réalisation d'une branche stable ou d'une publication particulière. 
Mercurial fournit le mécanisme des tags conjointement aux numéros de révisions. Les tags s'utilisent de façon transparente dans les commandes
Mercurial au même titre que les numéros de version. La commande {\it tag} permet de donner une étiquette à la révision courante et la commande {\it tags}
permet de lister les tags du repository. 
\begin{lstlisting}
$hg tag v0.22
$ hg tags 
tip                               20:cc37a4823319
v0.22                             19:4d4c066c7aae
v0.2                              13:640a581737cd
v0.11                             11:b7b9a085b543
v0.1                               6:572f1e9be549
$ cd ../myHelloWorld-stable/
$ hg pull -rv0.22 ../myHelloWorld/
pulling from ../myHelloWorld/
searching for changes
adding changesets
adding manifests
adding file changes
added 5 changesets with 5 changes to 3 files
(run 'hg update' to get a working copy)
$ hg update
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
\end{lstlisting}
Dans cette exemple la version de travail myHelloWorld est étiquetée v0.22, et la version stable 
récupère les modifications effectuée jusqu'à cette version.
\subsection{Maintenir deux versions d'un projet}
Il est parfois nécessaire de maintenir deux versions concurrentes d'un même projet, par exemple une version publique et une version privée 
contenant le code de la version publique ainsi que du code sensible. Une des approches possible est de créer un clone du repository public qui deviendra
le repository privé et d'y ajouter le code sensible. Le repository public sera accessible en http tandis que l'accès ssh permettra d'accéder à la fois
au repository public et au repository privé. Les patchs concernant le code sensible sont uniquement appliqués au repository privé, 
et le mainteneur effectue régulièrement des pulls du repository public vers le privé pour récupérer les modifications concernant le code. Attention à ne pas 
réaliser l'opération inverse, qui ajouterait l'ensemble du code sensible au repository public.


\begin{thebibliography}{widest-label}
\bibitem[1]{1} Bryan O'Sullivan, {\it Distributed revision control with Mercurial} \url{http://hgbook.red-bean.com/}.
\end{thebibliography}

%Fin du document
\end{document}
