~~NOTOC~~ ====== 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 date: Wed Oct 18 22:05:41 2006 +0200 summary: Accord incertain ... Pour limiter l'historique aux N derniers //commits//, utiliser ''hg log -l '' ===== Ajout, suppression, déplacement de fichiers ===== ''hg add '', ''hg remove '' ''hg rename '' 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 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 [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 : * dans le fichier .hg/hgrc de son dépôt elle rajoute allow_push = * push_ssl = false * dans un fichier .htaccess de son dépôt elle rajoute AuthType Digest AuthName "committers" AuthUserFile /home/alice/www/projet/.digestpw require valid-user * elle crée enfin le fichier .digestpw nécessaire avec un login et un mot de passe pour Robert. 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''