Crash course mercurial


Création du dépôt

[bug@tux]$ cd projet
[bug@tux:~projet/ ]$ hg init

À partir de ce moment là, mercurial dispose du nécessaire pour consigner les changements apportés aux sources.

Consignation des modifications dans le dépôt

[bug@tux]$ hg commit

Permet d'enregistrer les modifications des fichiers sous contrôle de mercurial, dans le dépôt. La variante hg commit -m “commit message” permet de passer directement le commentaire à enregistrer (s'il est court) dans l'historique des modifications du dépôt pour ce commit. Exemple :

[bug@tux:~projet/ ]$ hg ci -m "Correction bug #23"

Historique du dépôt

hg log

Affiche l'historique des consignations (commits) dans le dépôt. Par exemple :

[bug@tux:~projet/ ]$ hg log
changeset:   35:14844509ed21
tag:         tip
user:        bug
date:        Thu Oct 19 22:44:18 2006 +0200
summary:     Correction bug #23
 
changeset:   34:25845386fc92
user:        autre@tux.u-strasbg.fr
date:        Thu Oct 19 21:02:24 2006 +0200
summary:     Ajout blablabla
 
changeset:   33:248fd23b2247
user:        Dave Nul <devnull@tux>
date:        Wed Oct 18 22:05:41 2006 +0200
summary:     Accord incertain
...

Pour limiter l'historique aux N derniers commits, utiliser hg log -l <N>

Ajout, suppression, déplacement de fichiers

hg add <fichier>, hg remove <fichier> hg rename <ancien-nom> <nouveau-nom> permettent respectivement d'ajouter, de supprimer et de renommer un fichier du dépôt. Comme dans tout SCM/VCS, l'action est enregistrée mais sera effectuée au prochain commit. Exemple

[bug@tux:~projet/ ]$ hg st
? style.css
[bug@tux:~projet/ ]$ hg add style.css
[bug@tux:~projet/ ]$ hg ci -m "Ajout du CSS"
[bug@tux:~projet/ ]$ hg remove file.old
[bug@tux:~projet/ ]$ hg ci -m "Suppression fichier inutilisé"
[bug@tux:~projet/ ]$ hg rename afile thefile
[bug@tux:~projet/ ]$ hg ci -m "afile devait s'appeler thefile"

Etat du dépôt

hg status

Permet de voir dans quel état sont les sources du point de vue de mercurial. Exemple :

[bug@tux:~projet/ ]$ hg status
M index.html
? search.patch

Le fichier index.html est sous contrôle de mercurial et son état est M(odified), donc il a été modifié depuis la dernière consignation dans le dépôt (commit). Le fichier search.patch est inconnu (d'où le ?) de mercurial. Pour indiquer à mercurial qu'il doit aussi contrôler les modifications faites sur le fichier search.patch, il faut l'ajouter au dépôt mercurial (et consigner cet ajout) :

[bug@tux:~projet/ ]$ hg add search.patch
[bug@tux:~projet/ ]$ hg status
M index.html
A search.patch
[bug@tux:~projet/ ]$ hg ci -m "Ajout du patch" search.patch

Différences avec le dépôt

hg diff permet d'afficher les modifications qui n'ont pas encore été consignées dans le dépôt. Par exemple :

[bug@tux:~projet/ ]$ hg diff
diff -r a0a00f7ed15a index.html
--- a/index.html      Wed Oct 18 23:44:54 2006 +0200
+++ b/index.html      Thu Oct 19 22:01:22 2006 +0200
@@ -10,10 +10,10 @@ Morbi et dui. Sed tellus elit, volutpat 
 Morbi et dui. Sed tellus elit, volutpat a, dignissim nec,
 sapien. Donec aliquam. Nullam magna. Donec dictum, urna at
 lacinia, risus libero vestibulum tortor, vel sodales dolor dui
-erat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+erat. Lorem ipsum dilor sit amet, consectetuer adipiscing elit.
 enim.
 
-Nulla viverra sem nec erat. Fusce laoreet libero vel ante. Mauris
+Nulla viverra sem nic erot. Fusce laoreet libero vel ante. Mauris
 adipiscing suscipit risus. Etiam est. Nunc quis purus. Morbi non
 vitae nisi convallis faucibus. Nunc molestie molestie. Quisque
 facilisis. Quisque eu risus a libero commodo pellentesque.

Restauration de l'état du projet

Pour restaurer le répertoire de travail dans le dernier état consigné dans le dépôt (tip), il existe la commande hg revert. Celle-ci efface toutes les modifications qui ont été faites dans les fichiers sources et qui n'ont pas été consignées dans le dépôt.

Il peut aussi être nécessaire de restaurer le répertoire de travail dans un état antérieur. Par exemple :

[bug@tux:~projet/ ]$ hg id
14844509ed21
[bug@tux:~projet/ ]$ hg log
changeset:   35:14844509ed21
tag:         tip
user:        bug
date:        Thu Oct 19 22:44:18 2006 +0200
summary:     Correction bug #23
 
changeset:   34:25845386fc92
user:        autre@tux.u-strasbg.fr
date:        Thu Oct 19 21:02:24 2006 +0200
summary:     Ajout blablabla
 
changeset:   33:248fd23b2247
user:        Dave Nul <devnull@tux>
date:        Wed Oct 18 22:05:41 2006 +0200
summary:     Accord incertain
...

Pour restaurer le répertoire de travail dans l'état dans lequel il se trouvait au moment du changeset 33, une seule commande est nécessaire :

[bug@tux:~projet/ ]$ hg update -C 33
248fd23b2247

Branche et mainline

Mercurial étant un SCM/VCS distribué, tout dépôt est une branche. La méthode la plus simple pour créer une nouvelle branche consiste à copier (cloner) un dépôt existant. Par exemple :

[bug@tux:~projet/ ]$ cd ..
[bug@tux]$ hg clone projet projet-test-branch

Par la suite, pour synchroniser la “branche” projet-test-branch avec sa source, il suffit de lancer hg pull pour récupérer les modifications de la source, suivi d'un hg update pour appliquer aux données dans la branche les modifications récupérées par pull.

Dans un dépôt la commande hg tip permet de connaître le changeset le plus récent, hg id indique à quel changeset se situe le répertoire de travail et hg parents montre le changeset parent du répertoire de travail. Si le répertoire de travail courant (et donc le dépôt qu'il contient) a été cloné depuis un autre dépôt, les commandes hg in et hg out montrent respectivement les modifications du dépôt source qui n'ont pas été incluses dans le dépôt local et les modifications du dépôt local qui n'ont pas été envoyées vers le dépôt source.

Fichier de configuration

Le fichier $HOME/.hgrc est le fichier personnel des options et paramètres de Mercurial. Il est formé de sections et de couples variable = valeur. Ce fichier permet de contrôler des variables de l'utilisateur (adresse mail par exemple), de déterminer quelles extensions sont chargées ou encore de modifier la manière dont un dépôt est accessible ou présenté en HTTP. Ce fichier peut ressembler à ceci :

[ui]
username = Alice <alice@tux>

[web]
contact = Alice
allowgz = true
allowbz2 = true
allowzip = true
style = gitweb

[extensions]
hgext.mq=
hgext.hbisect=
hgext.hgk=
hgext.patchbomb=

Dans chaque dépôt, les valeurs de ces variables peuvent être surchargées via un fichier local .hg/hgrc spécifique au dépôt. Voir la page manuel de hgrc pour plus d'information.

Communiquer les changements

Alice et Robert souhaitent coordonner leur travail sur un projet commun placé sous contrôle de Mercurial. Alice dispose du dépôt primaire (localisé dans /home/alice/www/projet/).

Accès local

Robert travaillant sur la même machine qu'Alice, il récupère une copie (un clône du dépôt) par :

[robert@tux:~/ ]$ hg clone /home/alice/www/projet
[robert@tux:~projet/ ]$ hg tip
changeset:   35:f066ae784d95
tag:         tip
user:        alice
date:        Thu Oct 19 22:44:18 2006 +0200
summary:     Ajout Makefile

Il peut maintenant modifier le projet puis envoyer ses changesets à Alice par un push dans le dépôt d'Alice (si les autorisations le permettent) :

[robert@tux:~projet/ ]$ hg -m "Correction Makefile"
[robert@tux:~projet/ ]$ hg push
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

Si Robert ne peut écrire dans le dépôt d'Alice, il peut générer un bundle qui contient les modifications de son dépôt à inclure dans celui d'Alice par hg bundle changeset, puis il expédie le fichier changeset à Alice (par mail par exemple). Robert peut aussi utiliser l'extension patchbomb de Mercurial, pour expédier par mail ses modifications (patch) à Alice, via la commande hg email.

Accès réseaux en lecture seule

Le dépôt d'Alice (dans /home/alice/www/projet/) peut être servi par le serveur Web interne de Mercurial. Dans l'exemple qui suit Alice démarre ce serveur Web, et Robert prend une copie du dépôt d'Alice :

[alice@tux:~www/projet/ ]$ hg serve
...
[robert@tux:~/ ]$ hg clone http://serveur-alice:8000 projet
[robert@tux:~projet/ ]$ hg tip
changeset:   35:f066ae784d95
tag:         tip
user:        alice
date:        Thu Oct 19 22:44:18 2006 +0200
summary:     Ajout Makefile

Robert transmettra ensuite ses modifications par bundle ou email comme précédemment.

Alice peut aussi opter pour offrir un accès HTTP permanent à son dépôt (sans avoir à lancer la commande hg serve). Pour cela, elle copie dans son dépôt le CGI hgweb.cgi livré avec Mercurial et après modification de deux paramètres dans ce fichier son dépôt est désormais accessible via HTTP.

[alice@tux:~www/projet/ ]$ cp /usr/local/www/hgweb.cgi index.cgi
[alice@tux:~www/projet/ ]$ vi index.cgi
[alice@tux:~www/projet/ ]$ chmod a+x index.cgi
...
[robert@tux:~/ ]$ hg clone http://serveur-alice/~alice/projet
[robert@tux:~projet/ ]$ hg tip
changeset:   35:f066ae784d95
tag:         tip
user:        alice
date:        Thu Oct 19 22:44:18 2006 +0200
summary:     Ajout Makefile

Accès réseaux en écriture

Alice décide que Robert peut écrire dans son dépôt Mercurial. Si Robert a un accès SSH sur la machine d'Alice, une session de travail de Robert pourrait ressembler à ceci :

[robert@tux:~/ ]$ hg clone ssh://robert@serveur-alice//projet
[robert@tux:~projet/ ]$ hg tip
changeset:   35:f066ae784d95
tag:         tip
user:        alice
date:        Thu Oct 19 22:44:18 2006 +0200
summary:     Ajout Makefile
[robert@tux:~projet/ ]$ vi Makefile
[robert@tux:~projet/ ]$ hg -m "Correction Makefile"
[robert@tux:~projet/ ]$ hg push
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
[robert@tux:~/ ]$ hg push

La commande push se souvient de la source depuis laquelle le dépôt de Robert a été cloné, ainsi que du protocole (SSH ici) d'accès.

La même chose est réalisable via HTTP. Alice met en place un accès HTTP à son dépôt comme précédemment (en utilisant le CGI), puis :

allow_push = *
push_ssl = false
<Limit POST>
AuthType Digest
AuthName "committers"
AuthUserFile /home/alice/www/projet/.digestpw
require valid-user
</Limit>

Robert peut désormais récupérer le dépôt d'Alice (hg clone et hg pull par la suite pour le mettre à jour) et y injecter ses modifications (hg push).

Annulation d'un commit

Dans mercurial, l'historique d'un projet est inviolable (le format des fichiers du dépôt est « append-only »). Seul le dernier commit qui a été effectué peut-être annulé, via la commande hg rollback.

Exportation d'une archive

La distribution des sources d'un projet sous contrôle de mercurial peut être réalisée sous la forme d'un fichier archive (tar, tgz, tbz, zip) qui est fabriqué via une commande analogue à hg archive -t tgz src.tgz.

Nommer une revision

Dans mercurial, chaque révision d'un dépôt est identifié par un compteur incrémenté à chaque commit et par un HASH :

[robert@tux:~projet/ ]$ hg tip -q
changeset:   35:f066ae784d95

Ce HASH est en réalité une version courte du HASH (SHA) réel utilisé pour identifié la révision dans le dépôt :

[robert@tux:~projet/ ]$ hg tip --template '{node}'
f066ae784d95f9730992036faa9cbb53a422b494

Il est aussi possible de donner un nom symbolique à une révision quelconque. Par exemple :

[robert@tux:~projet/ ]$ hg tip -q
changeset:   35:f066ae784d95
[robert@tux:~projet/ ]$ hg tag RELEASE-1.1

va associer à la révision 35 ou au changeset f066ae784d95 le nom symbolique RELEASE-1.1. Pour restaurer le répertoire de travail dans l'état où il se trouvait à la révision 35, il est aussi possible d'utiliser le nom associé à cette révision :

[robert@tux:~projet/ ]$ hg update RELEASE-1.1

Autres commandes utiles

hg branch : crée ou montre la branche courante du dépôt
hg annotate : affiche quel changeset a modifié quelle ligne
hg help : les autres commandes de mercurial man hg et man hgrc