Chapter 2. Une rapide présentation de Mercurial : les bases

Table of Contents

2.1. Installer Mercurial sur votre système
2.1.1. Windows
2.1.2. Mac OS X
2.1.3. Linux
2.1.4. Solaris
2.2. Commencer à utiliser Mercurial
2.2.1. L'aide intégrée
2.3. Travailler avec un dépôt
2.3.1. Faire une copie locale de votre dépôt
2.3.2. Quel est le contenu d'un dépôt ?
2.4. Une promenade dans l'historique
2.4.1. Changesets, révisions, et collaboration
2.4.2. Afficher une révision spécifique
2.4.3. Informations détaillées
2.5. Tout sur les options de commandes
2.6. Faire et vérifier des modifications
2.7. Enregistrer vos modifications dans une nouvelle révision
2.7.1. Définir le nom d'utilisateur
2.7.2. Rédiger un message de commit
2.7.3. Rédiger un message approprié
2.7.4. Annuler un commit
2.7.5. Admirer votre travail
2.8. Partager ses modifications
2.8.1. Récupérer les modifications d'autres dépôts
2.8.2. Mise à jour de l'espace de travail
2.8.3. Transférer les modifications vers un autre dépôt
2.8.4. Emplacements par défaut
2.8.5. Partager ses modifications à travers le réseau
2.9. Commencer un nouveau projet

2.1. Installer Mercurial sur votre système

Des paquetages binaires de Mercurial sont disponibles pour la plupart des systèmes d'exploitation, ce qui rend facile l'utilisation immédiate de Mercurial sur votre ordinateur.

2.1.1. Windows

La meilleure version de Mercurial pour Windows est TortoiseHg, qui peut être téléchargée ici : http://bitbucket.org/tortoisehg/stable/wiki/Home. Ce logiciel n'a aucune dépendance exterieure ; il fonctionne et c'est tout. Il fournit aussi bien les outils en ligne de commmande qu'une interface graphique.

2.1.2. Mac OS X

Lee Cantey publie un installeur de Mercurial pour Mac OS X sur http://mercurial.berkwood.com.

2.1.3. Linux

Parce que chaque distribution de Linux a ses propres outils de gestion de paquets, politiques et rythmes de développements, il est difficile de donner un ensemble d'instructions unique pour installer les binaires de Mercurial. La version de Mercurial avec laquelle vous vous retrouverez dépendra grandement de l'activité de la personne en charge du paquetage pour la distribution.

Pour rester simple, je me concentrerai sur l'installation de Mercurial en ligne de commande, sous les distributions les plus courantes. La plupart des distributions fournissent des gestionnaires graphiques de paquetage qui vous permettront d'installer Mercurial en quelques clicks. Le paquetage devrait se nommer mercurial.

  • Ubuntu et Debian :

    apt-get install mercurial
  • Fedora :

    yum install mercurial
  • Gentoo :

    emerge mercurial
  • OpenSUSE :

    zypper install
              mercurial

2.1.4. Solaris

SunFreeWare, à http://www.sunfreeware.com, fournit des paquets précompilés pour Mercurial.

2.2. Commencer à utiliser Mercurial

Pour commencer, nous utiliserons la commande hg version pour vérifier si Mercurial est installé proprement. L'information de version affichée n'est pas réellement importante en soi, c'est surtout de savoir si elles s'affichent qui nous intéresse.

$ hg version
Mercurial Distributed SCM (version 1.6.4)

Copyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2.2.1. L'aide intégrée

Mercurial fournit un système d'aide intégré, ce qui est inestimable quand vous vous retrouvez coincé à essayer de vous rappeler comment lancer une commande. Si vous êtes bloqué, exécutez simplement hg help ; elle affichera une brève liste des commandes, avec une description pour chacune. Si vous demandez de l'aide sur une commande spécifique (voir ci-dessous), elle affichera des informations plus détaillées.

$ 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 will be created.

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

    It is possible to specify an "ssh://" URL as the destination. See "hg help
    urls" for more information.

    Returns 0 on success.

options:

 -e --ssh CMD        specify ssh command to use
    --remotecmd CMD  specify hg command to run on the remote side

use "hg -v help init" to show global options

Pour un niveau d'informations encore plus détaillé (ce dont vous aurez rarement besoin), exécutez hg help -v. L'option -v est l'abréviation de --verbose, et indique à Mercurial d'afficher plus d'informations que d'habitude.

2.3. Travailler avec un dépôt

Avec Mercurial, tout se déroule au sein d'un dépôt. Le dépôt d'un projet contient tous les fichiers qui appartiennent au projet.

Il n'y a rien de particulièrement magique au sujet de ce dépôt, c'est simplement une arborescence sur votre système de fichiers que Mercurial traite de manière spéciale. Vous pouvez renommer ou effacer ce répertoire à n'importe quel moment, en utilisant la ligne de commande ou votre explorateur de fichiers.

2.3.1. Faire une copie locale de votre dépôt

Copier un dépôt est juste un peu spécial. Bien que vous puissiez utiliser une commande habituelle de copie pour copier votre dépôt, il vaut mieux utiliser une commande fournie par Mercurial. Cette commande est appelée hg clone, car elle crée une copie identique à un dépôt existant.

$ hg clone http://hg.serpentine.com/tutorial/hello
destination directory: hello
requesting all changes
adding changesets
adding manifests
adding file changes
added 5 changesets with 5 changes to 2 files
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

Un avantage de la commande hg clone est que, comme nous l'avons vu ci dessus, elle nous permet de cloner les dépôts à travers le réseau. Un autre est qu'elle se rappelle d'où a été cloné un dépôt, ce qui est utile quand on veut mettre à jour le clone.

Si votre opération de clonage réussit, vous devriez maintenant avoir un répertoire local appelé hello. Ce répertoire contiendra quelques fichiers.

$ ls -l
total 0
drwxr-xr-x 3 oracle dba 120 Mar 17 05:09 hello
$ ls hello
Makefile  hello.c

Ces fichiers ont le même contenu et historique dans votre dépôt qu'ils ont dans le dépôt que vous avez cloné.

Chaque dépôt Mercurial est complet, autonome et indépendant. Il contient sa propre copie privée des fichiers du projet et de leur historique. Le clone d'un dépôt se souvient de la localisation du dépôt à partir duquel il a été cloné, mais il ne communique pas avec ce dernier, ou un autre, à moins que vous ne lui demandiez.

Tout ceci signifie pour le moment que nous sommes libres d'expérimenter avec ce dépôt, confiants dans le fait qu'il s'agit d'un bac à sable qui n'affectera personne d'autre.

2.3.2. Quel est le contenu d'un dépôt ?

Prêtons plus attention un instant au contenu d'un dépôt. Nous voyons qu'il contient un répertoire nommé .hg . C'est ici que Mercurial conserve toutes ses métadonnées.

$ cd hello
$ ls -a
.  ..  .hg  Makefile  hello.c

Le contenu du répertoire .hg et ses sous-répertoires sont les seuls propres à Mercurial. Tous les autres fichiers et répertoires dans le dépôt sont à vous, et vous pouvez en faire ce que vous voulez.

Pour introduire un peu de terminologie, le répertoire .hg est un vrai dépôt, et tous les fichiers et les répertoires qui coexistent avec lui, sont désignés sous le nom espace de travail. Une manière facile de se rappeler cette distinction est de retenir que le dépôt contient l'historique de votre projet, alors que l'espace de travail contient un "snapshot" de votre projet à un certain point de son historique.

2.4. Une promenade dans l'historique

Une des premières choses que vous aurez envie de faire avec un nouveau dépôt, sera de comprendre son historique. La commande hg log vous donne une vue de l'historique.

$ hg log
changeset:   4:2278160e78d4
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:16:53 2008 +0200
summary:     Trim comments.

changeset:   3:0272e0d5a517
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:08:02 2008 +0200
summary:     Get make to generate the final binary from a .o file.

changeset:   2:fef857204a0c
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:05:04 2008 +0200
summary:     Introduce a typo into hello.c.

changeset:   1:82e55d328c8c
user:        mpm@selenic.com
date:        Fri Aug 26 01:21:28 2005 -0700
summary:     Create a makefile

changeset:   0:0a04b987be5a
user:        mpm@selenic.com
date:        Fri Aug 26 01:20:50 2005 -0700
summary:     Create a standard "hello, world" program

Par défaut, cette commande affiche à l'écran un bref paragraphe pour chaque révision enregistrée pour ce projet. Dans la terminologie de Mercurial, nous appelons chacun de ces évènements enregistrés un changeset, parce qu'il contient un ensemble de modifications sur plusieurs fichiers.

La commande hg log affiche ainsi ces informations :

  • changeset : Ce champ contient un nombre, séparé par deux points (:), d'une chaine hexadécimale. Il s'agit en fait d'identifiants d'un changeset. Il y a deux identifiants car le numéro de la révision est plus court et plus facile à saisir qu'une séquence hexadécimale.

  • user : L'identité de la personne qui a créé ce changeset. C'est un champ libre de forme, mais la plupart du temps il contient le nom et l'email de la personne.

  • date : La date et l'heure à laquelle le changeset a été créé, ainsi que le fuseau horaire dans lequelle il a été créé. (La date et l'heure sont locales à ce fuseau, elles indiquent donc quelle date et heure il était pour la personne qui a créé ce changeset.)

  • summary: La première ligne du message que le créateur a associé à son changeset pour le décrire.

  • Certains changesets, comme le premier de la liste ci-dessus ont un champ tag. Le tag est une autre façon d'identifier un changeset en lui donnant un nom simple à retenir. (Le tag nommé tip est spécial : il fait toujours référence au dernier changement dans le dépôt.)

Par défaut, la commande hg log n'affiche qu'un résumé, il manque beaucoup de détails.

La figure Figure 2.1, “Historique graphique du dépôt hello fournit une représentation graphique de l'historique du dépôt hello , pour voir plus facilement dans quelle direction l'historique se déroule. Nous reviendrons régulièrement sur cette représentation dans ce chapitre et ceux qui suivent.

Figure 2.1. Historique graphique du dépôt hello

XXX add text

2.4.1. Changesets, révisions, et collaboration

Comme l'anglais est réputé pour être un langage maladroit, et que l'informatique est la source de bien des erreurs de terminologie (pourquoi utiliser un seul terme quand quatre feront l'affaire ?), la gestion de révisions a une variété de mots et de phrases qui veulent dire la même chose. Si vous discutez d'historique de Mercurial avec d'autres personnes, vous constaterez que souvent, le mot changeset est contracté simplement en change ou (à l'écrit) cset, et même parfois révision, abrégé en rev.

Bien que le mot que vous utilisez pour désigner le concept de changeset importe peu, l'identifiant que vous utilisez pour désigner un changeset spécifique a une grande importance. Rappelez vous que le champ changeset affiché par la commande hg log identifie un changeset à la fois avec un numéro de révision et une séquence hexadécimale.

  • Le numéro de révision est seulement valable dans ce dépôt,

  • La séquence hexadécimale est un identifiant permanent, et invariant qui pourra toujours être associé au changeset exact de chaque copie de votre dépôt.

La distinction est importante. Si vous envoyez un email à quelqu'un en parlant de la révision 33, il est très probable que sa révision 33 ne sera pas la même que la votre. La raison de ceci est que le numéro de révision dépend de l'ordre dans lequel les modifications sont arrivées dans le dépôt, et il n'y a aucune garantie que les mêmes changements soient arrivés dans le même ordre dans différents dépôts. Trois modifications a, b, c peuvent aisément apparaitre dans un dépôt comme 0, 1, 2, et dans un autre comme 0, 2, 1 .

Mercurial utilise les numéros de révision uniquement comme des raccourcis pratiques. Si vous devez discuter d'un changeset avec quelqu'un, ou identifer un changeset pour une quelconque raison (par exemple, un rapport de bug), utilisez la séquence hexadécimale.

2.4.2. Afficher une révision spécifique

Pour réduire la sortie de hg log à une seule révision, utilisez l'option -r (ou --rev). Vous pouvez utiliser le numéro de révision ou la séquence hexadécimale comme identifiant, et demander autant de révisions que vous le souhaitez.

$ hg log -r 3
changeset:   3:0272e0d5a517
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:08:02 2008 +0200
summary:     Get make to generate the final binary from a .o file.

$ hg log -r 0272e0d5a517
changeset:   3:0272e0d5a517
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:08:02 2008 +0200
summary:     Get make to generate the final binary from a .o file.

$ hg log -r 1 -r 4
changeset:   1:82e55d328c8c
user:        mpm@selenic.com
date:        Fri Aug 26 01:21:28 2005 -0700
summary:     Create a makefile

changeset:   4:2278160e78d4
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:16:53 2008 +0200
summary:     Trim comments.

Si vous voulez voir l'historique de plusieurs révisions sans avoir à les énumérer, vous pouvez utiliser un intervalle de numérotation qui vous permet d'exprimer l'idée je veux toutes les révisions entre abc et def inclus.

$ hg log -r 2:4
changeset:   2:fef857204a0c
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:05:04 2008 +0200
summary:     Introduce a typo into hello.c.

changeset:   3:0272e0d5a517
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:08:02 2008 +0200
summary:     Get make to generate the final binary from a .o file.

changeset:   4:2278160e78d4
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:16:53 2008 +0200
summary:     Trim comments.

Mercurial respecte aussi l'ordre dans lequel vous spécifiez les révisions, ainsi hg log -r 2:4 affichera 2, 3, 4 alors que hg log -r 4:2 affichera 4, 3, 2.

2.4.3. Informations détaillées

Le résumé affiché par hg log est suffisant si vous savez déjà ce que vous cherchez. En revanche, vous aurez probablement besoin de voir une description complète du changement, ou une liste des fichiers modifiés si vous cherchez à déterminer qu'un changeset est bien celui que vous recherchez. L'option -v de la commande hg log (ou --verbose) vous donne ces informations supplémentaires.

$ hg log -v -r 3
changeset:   3:0272e0d5a517
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:08:02 2008 +0200
files:       Makefile
description:
Get make to generate the final binary from a .o file.


Si vous voulez voir à la fois la description et le contenu d'une modification, ajoutez l'option -p (ou --patch). Ceci affiche le contenu d'une modification comme un diff unifié (si vous n'avez jamais vu de diff unifié avant, consultez la section Section 12.4, “Understanding patches” pour un rapide survol).

$ hg log -v -p -r 2
changeset:   2:fef857204a0c
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:05:04 2008 +0200
files:       hello.c
description:
Introduce a typo into hello.c.


diff -r 82e55d328c8c -r fef857204a0c hello.c
--- a/hello.c	Fri Aug 26 01:21:28 2005 -0700
+++ b/hello.c	Sat Aug 16 22:05:04 2008 +0200
@@ -11,6 +11,6 @@
 
 int main(int argc, char **argv)
 {
-	printf("hello, world!\n");
+	printf("hello, world!\");
 	return 0;
 }

L'option -p est incroyablement utile, il est donc important dans s'en rappeler.

2.5. Tout sur les options de commandes

Avant d'aller plus loin sur le fonctionnement des commandes de Mercurial, étudions un moment comment elles fonctionnent de manière générale. Vous trouverez ça probablement utile pour la suite de notre parcours.

Mercurial utilise une approche directe et cohérente pour interpréter les options que vous passez aux commandes. Il suit une convention commune à la plupart des systèmes Unix et Linux modernes.

  • Chaque option a un nom complet. Par exemple, comme nous l'avons déjà vu, la commande hg log accepte l'option --rev .

  • La plupart des options disposent de noms abrégés. Aussi, au lieu d'utiliser --rev , vous pouvez utiliser -r. (Les options qui n'ont pas de nom abrégé sont généralement rarement utilisées).

  • Les noms complets commencent par deux tirets (par exemple --rev), alors que les options courtes commencent avec un seul (par exemple -r).

  • Les noms des options sont cohérents entre les commandes. Par exemple, chaque commande qui accepte un changeset ID ou un numéro de révision accepte aussi -r et --rev comme arguments.

Dans les exemples de ce livre, j'utilise les noms abrégés plutôt que les noms complets. Ceci est une préférence personnelle, pas une recommandation.

La plupart des commandes qui affichent une quelconque sortie à l'écran, afficheront davantage avec l'option -v (ou --verbose), et moins avec l'option -q (ou --quiet).

[Note] Cohérence dans le nom des options

Presque toujours, les commandes de Mercurial utilisent des noms d'options cohérentes pour se référer à des concepts identiques. Par exemple, si une commande concerne les changesets, vous les identifierez toujours avec l'option -r. Cette utilisation cohérente des noms d'options permet de mémoriser plus facilement quelles options acceptent une commande.

2.6. Faire et vérifier des modifications

Maintenant que nous avons une bonne idée des commandes pour consulter l'historique de Mercurial, regardons comment faire des modifications et les examiner.

La première chose que nous allons faire est d'isoler notre exercice dans un dépôt à part. Nous allons utiliser la commande hg clone, mais nous n'avons pas besoin de faire une copie de dépôt distant. Comme nous avons déjà une copie locale, nous pouvons juste faire un clone de celle-ci à la place. C'est beaucoup plus rapide que de faire une copie à travers le réseau, et un dépôt cloné localement prend également moins d'espace disque[1].

$ cd ..
$ hg clone hello my-hello
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd my-hello

On notera au passage qu'il est souvent considéré comme une bonne pratique de conserver une copie immaculée du dépôt distant, à partir de laquelle vous pourrez faire des copies locales temporaires pour créer des bacs à sable pour chaque tâche sur laquelle vous souhaitez travailler. Ceci vous permet de travailler sur plusieurs choses en parallèle, chacunes isolées les unes des autres en attendant que ces tâches soient finies et que vous soyez prêt à les réintégrer. Parce que les copies locales sont peu coûteuses, il est très rapide de créer ou détruire des dépôts dès que vous n'en avez plus besoin.

Dans notre dépôt my-hello, nous avons un fichier hello.c qui contient le classique hello, world.

$ cat hello.c
/*
 * Placed in the public domain by Bryan O'Sullivan.  This program is
 * not covered by patents in the United States or other countries.
 */

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("hello, world!\");
	return 0;
}

Éditons ce fichier pour qu'il affiche une autre ligne sur la sortie standard.

# ... edit edit edit ...
$ cat hello.c
/*
 * Placed in the public domain by Bryan O'Sullivan.  This program is
 * not covered by patents in the United States or other countries.
 */

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("hello, world!\");
	printf("hello again!\n");
	return 0;
}

La commande Mercurial hg status nous dira ce que Mercurial sait des fichiers du dépôts.

$ ls
Makefile  hello.c
$ hg status
M hello.c

La commande hg status n'affichera pas le contenu des fichiers, mais une ligne commençant par M pour hello.c. À moins que vous lui demandiez, la commande hg status n'affichera aucune information sur les fichiers que vous n'avez pas modifiés.

Le M indique que Mercurial a remarqué que nous avons modifié le fichier hello.c. Nous n'avons pas besoin d'informer Mercurial que nous allons modifier un fichier avant de commencer à le faire, ou que nous avons modifié un fichier après avoir commencé à le faire, il est capable de le découvrir tout seul.

C'est déjà pratique de savoir que nous avons modifié le fichier hello.c, mais nous préférerions savoir exactement ce que nous avons changé. Pour ceci, nous utilisons la commande hg diff.

$ hg diff
diff -r 2278160e78d4 hello.c
--- a/hello.c	Sat Aug 16 22:16:53 2008 +0200
+++ b/hello.c	Thu Mar 17 05:09:25 2011 +0000
@@ -8,5 +8,6 @@
 int main(int argc, char **argv)
 {
 	printf("hello, world!\");
+	printf("hello again!\n");
 	return 0;
 }
[Tip] Comprendre les patches

Penser à jeter un oeil à Section 12.4, “Understanding patches” si vous n'arrivez pas à lire la sortie ci-dessus.

2.7. Enregistrer vos modifications dans une nouvelle révision

Nous pouvons modifier des fichiers, compiler et tester nos modifications, et utiliser les commandes hg status et hg diff pour voir les modifications effectuées, jusqu'à ce que nous soyons assez satisfaits pour décider d'enregistrer notre travail dans un changeset.

La commande hg commit vous laisse créer une nouvelle révision, nous désignerons généralement cette opération par faire un commit ou commiter.

2.7.1. Définir le nom d'utilisateur

Quand vous exécutez la commande hg commit pour la première fois, il n'est pas garanti qu'elle réussisse du premier coup. En effet, Mercurial enregistre votre nom et votre adresse avec chaque modification que vous effectuez, de manière à ce que vous soyez capable (ou d'autres le soient) de savoir qui a fait telle modification. Mercurial essaye automatiquement de découvrir un nom d'utilisateur qui ait un minimum de sens pour effectuer l'opération de commit avec. Il va essayer chacune des méthodes suivantes, dans l'ordre :

  1. Si vous spécifiez l'option -u avec la commande hg commit, suivi d'un nom d'utilisateur, ceci aura toujours la priorité sur les autres méthodes ci dessous.

  2. Si vous avez défini une variable d'environnement HGUSER, c'est cette valeur qui est alors utilisée.

  3. Si vous créez un fichier nommé .hgrc dans votre répertoire \textit{home}, avec une entrée username, c'est la valeur associée qui sera utilisée. Pour voir à quoi ressemble le contenu de ce fichier regardez la section Section 2.7.1.1, “Créer un fichier de configuration pour Mercurial” ci-dessous.

  4. Si vous avez défini une variable d'environnement EMAIL celle ci sera utilisée ensuite.

  5. Enfin, Mercurial interrogera votre système pour trouver votre nom d'utilisateur local ainsi que le nom de la machine hôte, et il fabriquera un nom d'utilisateur à partir de ces données. Comme il arrive souvent que ce genre de nom soit totalement inutile, il vous préviendra en affichant un message d'avertissement.

Si tous ces mécanismes échouent, Mercurial n'exécutera pas la commande, affichant un message d'erreur. Dans ce cas, il ne vous laissera pas effectuer de commit tant que vous n'aurez pas défini un nom d'utilisateur.

Vous devriez penser à utiliser la variable d'environement HGUSER et l'option -u comme moyen pour changer le nom d'utilisateur par défaut. Pour une utilisation normale, la manière la plus simple et robuste d'opérer est de créer un fichier .hgrc, voir ci-dessous pour les détails à ce sujet.

2.7.1.1. Créer un fichier de configuration pour Mercurial

Pour définir un nom d'utilisateur, utilisez votre éditeur de texte favori pour créer un fichier .hgrc dans votre répertoire home. Mercurial va utiliser ce fichier pour retrouver votre configuration personnelle. Le contenu initial devrait ressembler à ceci :

[Tip] Home directory sous Windows

Quand on parle de répertoire home, sur une version anglaise d'une installation de Windows, il s'agira habituellement d'un répertoire nommée comme votre nom dans C:\Documents and Settings. Vous pouvez trouver de quel répertoire il s'agit en lançant une fenêtre d'interpréteur de commande et en exécutant la commande suivante :

C:\ echo
              %UserProfile
# This is a Mercurial configuration file.
[ui]
username = Firstname Lastname <email.address@domain.net>

La ligne avec [ui] commence une section du fichier de configuration, ainsi la ligne username = ... signifie définir la valeur de l'élément username dans la section ui. Une section continue jusqu'à ce qu'une nouvelle commence, ou que la fin du fichier soit atteinte. Mercurial ignore les lignes vides et traite tout texte situé à la suite d'un # jusqu'à la fin de la ligne comme un commentaire.

2.7.1.2. Choisir un nom d'utilisateur

Vous pouvez utiliser n'importe quelle valeur pour votre username, car cette information est destinée à d'autres personnes et non à être interprétée par Mercurial. La convention que la plupart des personnes suivent est d'utiliser leur nom suivie de leur adresse email, comme montré ci-dessus :

[Note] Note

Le mécanisme interne du serveur web intégré à Mercurial, masque les adresses emails, pour rendre plus difficile leurs récupérations par les outils utilisés par les spammmers. Ceci réduit la probabilité que de recevoir encore plus de spam si vous vous publiez un dépôt sur internet.

2.7.2. Rédiger un message de commit

Lorsqu'on effectue une opération de commit, Mercurial lance automatiquement un éditeur de texte pour permettre de saisir un message qui décrira les modifications effectuées dans cette révision. Ce message est nommé le message de commit. Ce sera un enregistrement pour tout lecteur expliquant le pourquoi et le comment de vos modifications, et il sera affiché par la commande hg log.

$ hg commit

L'éditeur que la commande hg commit déclenche ne contiendra qu'une ligne vide suivi d'un certain nombre de lignes commençant par HG: .

    This is where I type my commit comment.
    
    HG: Enter commit message.  Lines beginning with 'HG:' are removed.
    HG: --
    HG: user: Bryan O'Sullivan <bos@serpentine.com>
    HG: branch 'default'
    HG: changed hello.c

Mercurial ignore les lignes qui commencent avec HG:, il ne les utilise que pour nous indiquer quels fichiers modifiés il se prépare à commiter. Modifier ou effacer ces lignes n'a aucune conséquence sur l'opération de commit.

2.7.3. Rédiger un message approprié

Comme hg log n'affiche que la première ligne du message de commit par défaut, il est souvent considéré comme une bonne pratique de rédiger des messages de commit qui tiennent sur une seule ligne. Voilà un exemple concret de message de commit qui ne suit pas cette directive, et qui a donc un résumé peu lisible.

changeset:   73:584af0e231be
user:        Censored Person <censored.person@example.org>
date:        Tue Sep 26 21:37:07 2006 -0700
summary:     include buildmeister/commondefs.   Add an exports and install
      

À ce sujet, il faut noter qu'il n'existe pas de règle absolue dans ce domaine. Mercurial lui-même n'interprète pas les contenus des messages de commit, ainsi votre projet est libre de concevoir différentes politiques de mise en page des messages.

Ma préférence personnelle va au message court, mais informatif, qui offre des précisions supplémentaires par rapport à ce que pourrait m'apprendre une commande hg log --patch.

Si vous exécutez la commande hg commit sans aucun argument, elle enregistre tous les changements qui ont été fait, et qui sont indiqué par les commandes hg status et hg diff.

[Note] Une surprise pour les utilisateurs habitués à Subversion

Comme n'importe quel autre commande de Mercurial, si vous ne soumettez pas de manière explicite les noms des fichiers à commiter à la commande hg commit, elle va travailler sur l'ensemble du répertoire de travail. Soyez conscient de ceci si vous venez du monde Subversion ou CVS, car vous pourriez vous attendre à ce qu'elle opère uniquement sur le répertoire courant et ses sous-répertoires.

2.7.4. Annuler un commit

Si, en rédigeant le message, vous décidez que finalement vous ne voulez pas effectuer ce commit, il suffit de quitter simplement l'éditeur sans sauvegarder. Ceci n'aura aucune conséquence sur le dépôt ou les fichiers du répertoire de travail.

2.7.5. Admirer votre travail

Une fois que votre commit est terminé, vous pouvez utiliser la commande hg tip pour afficher le changeset que vous venez de créer. Cette commande produit une sortie à l'écran qui est identique à celle du hg log, mais qui n'affiche que la dernière révision du dépôt.

$ hg tip -vp
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
files:       hello.c
description:
Added an extra line of output


diff -r 2278160e78d4 -r ec142fc290c8 hello.c
--- a/hello.c	Sat Aug 16 22:16:53 2008 +0200
+++ b/hello.c	Thu Mar 17 05:09:25 2011 +0000
@@ -8,5 +8,6 @@
 int main(int argc, char **argv)
 {
 	printf("hello, world!\");
+	printf("hello again!\n");
 	return 0;
 }

On fait couramment référence à la dernière révision du dépôt comme étant la révision tip, ou plus simplement le tip.

Au passage, la commande hg tip accepte la plupart des options qu'accepte hg log. Ainsi -v ci-dessus implique soit verbeux, -p veut dire affiche le patch. L'utilisation de l'option -p pour afficher un patch est un autre exemple de la cohérence des commandes évoquée plus tôt.

2.8. Partager ses modifications

Nous avons mentionné plus haut que les dépôts de Mercurial sont autosuffisants. Ce qui signifie que la nouvelle révision que vous venez de créer existe seulement dans votre répertoire my-hello. Étudions comment propager cette modification dans d'autres dépôts.

2.8.1. Récupérer les modifications d'autres dépôts

Pour commencer, construisons un clone de notre dépôt hello qui ne contiendra pas le changement que nous venons d'effectuer. Nous l'appellerons notre dépôt temporaire hello-pull.

$ cd ..
$ hg clone hello hello-pull
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

Nous allons utiliser la commande hg pull pour envoyer les modifications depuis my-hello dans hello-pull. Néanmoins, récupérer aveuglement des modifications depuis un dépôt a quelque chose d'un peu effrayant. Mercurial propose donc une commande hg incoming qui permet de savoir quelles modifications la commande hg pull pourrait entraîner dans notre dépôt, et ceci sans effectuer réellement de modification dessus.

$ cd hello-pull
$ hg incoming ../my-hello
comparing with ../my-hello
searching for changes
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
summary:     Added an extra line of output

Apporter les modifications rapatriées dans un dépôt se résume donc à exécuter la commande hg pull, et préciser depuis quel dépôt effectuer le hg pull.

$ hg tip
changeset:   4:2278160e78d4
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:16:53 2008 +0200
summary:     Trim comments.

$ hg pull ../my-hello
pulling from ../my-hello
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)
$ hg tip
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
summary:     Added an extra line of output

Comme vous le voyez avec une sortie avant et après de la commande hg tip, nous avons réussi à récupérer aisément les modifications dans notre dépôt. Il reste néanmoins quelque chose à faire avant de retrouver ces modifications dans l'espace de travail.

[Tip] Récupérer des changements précis

Il est possible à cause du délai entre l'exécution de la commande hg incoming et l'exécution de la commande hg pull, que vous ne puissiez pas voir toutes les modifications que vous rapporterez d'un autre dépôt. Supposons que vous récupériez les modifications d'un dépôt situé quelque part sur le réseau. Alors que vous regardez le résultat de la commande hg incoming, et avant que vous ne décidiez de récupérer ces modifications, quelqu'un peut ajouter de nouvelles révisions dans le dépôt distant. Ce qui signifie que vous récupérez plus de révisions que ce que vous aviez regardées en utilisant la commande hg incoming.

Si vous voulez seulement récupérer ce que vous aviez vérifié à l'aide de la commande hg incoming, ou que pour d'autres raisons vous ne souhaitiez récupérer qu'un sous ensemble des révisions supplémentaires disponibles, indiquez simplement les modifications que vous souhaitez récupérer par leurs ID de révision, soit hg pull -r7e95bb.

2.8.2. Mise à jour de l'espace de travail

Nous avons jusqu'à maintenant grossièrement défini la relation entre un dépôt et un espace de travail. La commande hg pull que nous avons exécutée dans la section Section 2.8.1, “Récupérer les modifications d'autres dépôts” a apporté des modifications, que nous avons vérifiées, dans notre dépôt, mais il n'y a aucune trace de ces modifications dans notre espace de travail. En effet, hg pull ne touche pas (par défaut) à l'espace de travail. C'est la commande hg update qui s'en charge.

$ grep printf hello.c
	printf("hello, world!\");
$ hg update tip
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ grep printf hello.c
	printf("hello, world!\");
	printf("hello again!\n");

Il peut sembler un peu étrange que la commande hg pull ne mette pas à jour l'espace de travail automatiquement. Il y a en fait une très bonne raison à cela : vous pouvez utiliser la commande hg update pour mettre à jour votre espace de travail à l'état dans lequel il était à n'importe quelle révision de l'historique du dépôt. Si vous aviez un espace de travail contenant une ancienne révision—pour chercher l'origine d'un bug, par exemple—et que vous effectuiez un hg pull qui mettrait à jour automatiquement votre espace de travail, vous ne seriez probablement pas très satisfait.

Néanmoins, comme les opérations de pull sont très souvent suivies d'un update, Mercurial vous permet de combiner les deux aisément en passant l'option -u à la commande hg pull.

Si vous étudiez de nouveau la sortie de la commande hg pull dans la section Section 2.8.1, “Récupérer les modifications d'autres dépôts” quand nous l'avons exécutée sans l'option -u, vous pouvez constater qu'elle a affiché un rappel assez utile : vous devez encore effectuer une opération pour mettre à jour votre espace de travail.

Pour découvrir sur quelle révision de l'espace de travail on se trouve, utilisez la commande hg parents.

$ hg parents
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
summary:     Added an extra line of output

Si vous regardez de nouveau le dessin Figure 2.1, “Historique graphique du dépôt hello, vous verrez les flèches reliant entre elles les révisions. Le nœud d'où la flèche part est dans chaque cas un parent, et le nœud où la flèche arrive est un enfant.

Pour mettre à jour l'espace de travail d'une révision particulière, indiquez un numéro de révision ou un changeset ID à la commande hg update.

$ hg update 2
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg parents
changeset:   2:fef857204a0c
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Sat Aug 16 22:05:04 2008 +0200
summary:     Introduce a typo into hello.c.

$ hg update
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg parents
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
summary:     Added an extra line of output

Si vous ne précisez pas de manière explicite de numéro de révision la commande hg update mettra à jour votre espace de travail avec le contenu de la révison tip, comme montré dans l'exemple ci-dessus lors du second appel à hg update.

2.8.3. Transférer les modifications vers un autre dépôt

Mercurial vous laisse transférer les modifications vers un autre dépôt, depuis votre dépôt actuel. Comme dans l'exemple du hg pull ci-dessus, nous allons créer un dépôt temporaire vers lequel transférer nos modifications.

$ cd ..
$ hg clone hello hello-push
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

La commande hg outgoing nous indique quels changements nous allons transférer vers l'autre serveur.

$ cd my-hello
$ hg outgoing ../hello-push
comparing with ../hello-push
searching for changes
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
summary:     Added an extra line of output

Et la commande hg push effectue réellement le transfert.

$ hg push ../hello-push
pushing to ../hello-push
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

Comme avec hg pull, la commande hg push ne met pas à jour le répertoire de travail du dépôt dans lequel il transfère les modifications. À l'inverse de hg pull, hg push ne fournit pas d'option -u pour forcer la mise à jour de l'espace de travail cible. Cette asymétrie est délibéré : le dépot vers lequel nous transférons peut très bien être un serveur distant et partagé par plusieurs personnes. Si nous devions mettre à jour son répertoire de travail alors que quelqu'un d'autre travaille dessus, nous risquerions de perturber son travail.

Que se passe-t-il lorsque vous essayez de récupérer ou de transférer vos modifications et que le dépôt cible a déjà reçu ces modifications ? Rien de bien excitant.

$ hg push ../hello-push
pushing to ../hello-push
searching for changes
no changes found

2.8.4. Emplacements par défaut

Quand nous faisons un clone d'un dépôt, Mercurial enregistre l'emplacement du dépôt d'origine dans le fichier .hg/hgrc de notre nouveau dépôt. Si nous ne fournissons pas d'emplacement à la commande hg pull ou à la commande hg push, ces commandes utiliseront alors cet emplacement comme valeur par défaut. Les commandes hg incoming et hg outgoing feront de même.

Si vous regardez le fichier .hg/hgrc, vous constaterez que son contenu ressemble à ce qui suit.

[paths]
default = http://www.selenic.com/repo/hg

Il est possible—et souvent pratique—d'avoir un emplacement par défaut pour les commandes hg push et hg outgoing différent de celui des commandes hg pull et hg incoming. C'est faisable en ajoutant une entrée default-push à la section [paths] du .hg/hgrc, comme suit.

[paths]
default = http://www.selenic.com/repo/hg
default-push = http://hg.example.com/hg

2.8.5. Partager ses modifications à travers le réseau

Les commandes que nous avons étudiées dans les sections précédentes ne sont pas limitées aux dépôts locaux. Chacune fonctionne de la même manière à travers une connexion réseau, il suffit de lui passer une URL à la place d'un chemin de fichier local.

$ hg outgoing http://hg.serpentine.com/tutorial/hello
comparing with http://hg.serpentine.com/tutorial/hello
searching for changes
changeset:   5:ec142fc290c8
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:09:25 2011 +0000
summary:     Added an extra line of output

Dans cet exemple, nous allons voir quels changements nous pourrions transférer vers le dépôt distant, mais le dépôt n'est, de manière tout à fait compréhensible, pas configuré pour accepter des modifications d'utilisateurs anonymes.

$ hg push http://hg.serpentine.com/tutorial/hello
pushing to http://hg.serpentine.com/tutorial/hello
searching for changes
remote: ssl required

2.9. Commencer un nouveau projet

Il est tout aussi aisé de commencer un nouveau projet que de travailler sur un qui existe déjà. La commande hg init crée un nouveau dépôt Mercurial vide.

$ hg init myproject

Ceci crée simplement un répertoire nommé myproject dans le répertoire courant.

$ ls -l
total 8
-rw-r--r-- 1 oracle dba 47 Mar 17 05:08 goodbye.c
-rw-r--r-- 1 oracle dba 45 Mar 17 05:08 hello.c
drwxr-xr-x 3 oracle dba 72 Mar 17 05:08 myproject

Nous pouvons dire que myproject est un dépôt Mercurial car il contient un répertoire .hg.

$ ls -al myproject
total 0
drwxr-xr-x 3 oracle dba  72 Mar 17 05:08 .
drwx------ 3 oracle dba 184 Mar 17 05:08 ..
drwxr-xr-x 3 oracle dba 128 Mar 17 05:08 .hg

Si vous voulons ajouter quelques fichiers préexistants dans ce dépôt, il suffit de les recopier dans le répertoire de travail, et demander à Mercurial de commencer à les suivre en utilisant la commande hg add.

$ cd myproject
$ cp ../hello.c .
$ cp ../goodbye.c .
$ hg add
adding goodbye.c
adding hello.c
$ hg status
A goodbye.c
A hello.c

Une fois que nous sommes satisfaits de notre projet, nous pouvons commencer à ajouter nos révisions.

$ hg commit -m 'Initial commit'

Il ne prend que quelques instants pour commencer à utiliser Mercurial sur un nouveau projet, ce qui fait aussi de ses points forts. Travailler avec une gestion de révision devient très facile, nous pouvons même l'utiliser pour les plus petits projets où nous aurions probablement jamais pensé utiliser un outil aussi complexe.



[1] L'économie d'espace disque apparait clairement quand les dépôts source et destination sont sur le même système de fichier, où, dans ce cas, Mercurial utilisera des liens physiques pour effectuer des partages copie-lors-des-écritures de ses métadonnées internes. Si cette explication ne signifie rien pour vous, ne vous inquiétez pas : tout ceci se passe de manière transparente et automatique. Vous n'avez pas du tout besoin de comprendre ceci.