Auteurs: | Alain Leufroy, Pierre-Yves David. |
---|
Table des Matières
Un DVCS, est un "Distributed Version Control System" !
La gestion de versions consiste à maintenir l'ensemble des versions d'un ou plusieurs fichiers […] Cette activité étant fastidieuse et relativement complexe, un appui logiciel est presque indispensable.
—Wikipedia
C'est donc l'outil qui permet de gérer intelligemment les sauvegardes de vos travaux. C'est le compagnon indispensable du programmeur, scientifique, auteur, etc…
Mercurial est un outil :
- Simple
- Sûr
- Décentralisé
- Multiplateforme (même sur plan9 !)
- Activement maintenu
- Rapide
- Puissant
- Extensible
Vous aurez évidemment besoin de Mercurial. (disponible sur http://mercurial.selenic.com/)
Pour visualiser l'historique, nous conseillons Hgview:
Prenons le temps de configurer un minimum les choses en éditant le fichier de configuration utilisateur de mercurial.
C'est un simple fichier INI. Vous le trouverez à ~/.hgrc sur systèmes UNIX et plan9, et à %USERPROFILE%/Mercurial.ini (par default C:\Documents and Settings\XXX\Mercurial.ini) sur Windows
A minima, renseignez votre nom :
$ cat >> $HGRCPATH << EOF > [ui] > username = test <testeur@mondomaine.org> > EOF
Nous utilisons pour ce tutoriel l'interface officielle en ligne de commandes : hg [options globales] COMMANDE [options spécifiques] [ARGS]
Il existe d'autres interfaces (TortoiseHg, mode Emacs, EclipseHg, Hgview,...).
Vous pouvez obtenir de l'aide et/ou accéder à la documentation avec la commande help.
$ hg help showconfig
Astuces
Exercices
Regardez l'aide sur la "config" et ajoutez un raccourci quisuisje pour "showconfig ui.username" (section alias). Puism observez la sortie de $ hg quisuisje
$ cat >> $HGRCPATH << EOF > [alias] > quisuisje=showconfig ui.username > EOF
La première étape consiste à créer un dépôt vierge de changeset (ou revision) :
$ hg init pyconfr $ cd pyconfr
Créons un script python :
$ cat >> babar.py << EOF > # -*- coding: utf-8 -*- > #! /usr/bin/env python > > """Mon beau petit script""" > > print "Mon script python est cool !" > > EOF
Il faut explicitement demander à Mercurial de surveiller le fichier babar.py. Nous le mettons alors sous contrôle de version puis juste après nous figeons son état dans une révision (ou changeset)
$ hg add babar.py $ hg commit --message 'version initiale'
Pensez à regarder l'aide des commandes pour plus d'informations (hg help add et hg help commit).
--message omis, Mercurial démarre votre éditeur de texte car la description est obligatoire. On mettra donc hg commit pour renseigner une description plus complète.
Astuces
Les "révisions" sont des états figés et sauvegardés de vos fichiers : "Commitez" rapidement, et souvent !
Nous avons une révision datée, revendiquée, et commentée :
$ hg log changeset: 0:ac45076e2510 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: version initiale $ hg -v log changeset: 0:ac45076e2510 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 files: babar.py description: version initiale
Astuces
Vous pouvez utiliser des logiciels graphiques comme HgView qui pourront rester ouverts en permanence pendant que vous travaillez sur votre dépôt.
Exercices
Créez un dossier avec deux fichiers à l'intérieur. Ajoutez-les à votre dépôt et faites une nouvelle révision. Puis observez la sortie de hg log -G:
$ mkdir dossier $ echo 'le contenu de fichier 1' > dossier/fichier_1 $ echo 'le contenu de fichier 2' > dossier/fichier_2 $ hg add dossier adding dossier/fichier_1 adding dossier/fichier_2 $ hg commit --message "ajout d'un dossier" $ hg log -G @ changeset: 1:996158b51bfe | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: ajout d'un dossier | o changeset: 0:ac45076e2510 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: version initiale
Nous allons maintenant modifier notre fichier pour qu'il affiche le contenu d'un fichier passé en argument :
$ cat > babar.py << EOF > # -*- coding: utf-8 -*- > #! /usr/bin/env python > > """Mon beau petit script""" > > import sys > > print sys.argv[-1] > > EOF
Vous pouvez avoir différentes informations sur l'état actuel de votre dépôt (dir state) avec :
$ hg summary parent: 1:996158b51bfe tip ajout d'un dossier branch: default commit: 1 modified update: (current) $ hg status M babar.py $ hg diff -g babar.py diff --git a/babar.py b/babar.py --- a/babar.py +++ b/babar.py @@ -3,5 +3,7 @@ """Mon beau petit script""" -print "Mon script python est cool !" +import sys +print sys.argv[-1] +
Astuces
hg summary donne une très bonne vue générale de l'état de votre dépôt. Pensez à l'utiliser avant toute opération sur votre dépôt. Il vous dira si vous avez oublié un hg add ou si des modifications parasites sont présentes.
Si vous avez plus de fichiers modifiés que vous ne l'espériez, utilisez hg status pour les trouver.
Pensez à relire vos modifications avec hg diff. Les meilleures modifications sont les plus simples et sont faciles à relire !
On fait une nouvelle révision :
$ hg ci --message "Permet d'afficher le contenu du fichier en argument" $ hg log changeset: 2:339b3e5f3521 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: Permet d'afficher le contenu du fichier en argument changeset: 1:996158b51bfe user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: ajout d'un dossier changeset: 0:ac45076e2510 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: version initiale
Astuces
Il existe des alias spécifiques pour les commandes les plus courantes permettant de réduire le nombre de caratères à taper.
Vous pouvez même ne taper que le début du nom de la commande. Mercurial doit touefois disposer de suffisamment de caractères pour retrouver la commande sans ambigüité.
Astuces
Vous pouvez activer l'extension color pour ajouter des couleurs à la plupart des commandes. Ajoutez les lignes suivantes à votre hgrc
| [extensions] | color=
Vous voici devant votre premier défi : remonter dans le temps !
Le premier avantage d'un gestionnaire de contrôle de versions est de pouvoir revenir dans un état figé antérieur.
$ tree . |-- babar.py `-- dossier |-- fichier_1 `-- fichier_2 1 directory, 3 files $ hg update ac45076e2510 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ ls babar.py $ cat babar.py # -*- coding: utf-8 -*- #! /usr/bin/env python """Mon beau petit script""" print "Mon script python est cool !" $ hg log --template "{rev}) {desc}\n" 2) Permet d'afficher le contenu du fichier en argument 1) ajout d'un dossier 0) version initiale
Astuces
La commande log qui vous permet d'observer le contenu de votre dépôt (pas celui des fichiers), comporte de nombreuses options pour filtrer et personnaliser sa sortie. Vous pourrez prendre un peu de temps pour lire hg -v help log et hg help template.
On peut remarquer que l'on a oublié le texte de la licence dans la version initiale :-/ Ajoutons-la !
$ hg summary parent: 0:ac45076e2510 version initiale branch: default commit: (clean) update: 2 new changesets (update) $ cat > babar.py << EOF > # -*- coding: utf-8 -*- > #! /usr/bin/env python > # License: WTFPL v. 2 > > """Mon beau petit script""" > > print "Mon script python est cool !" > > EOF $ hg summary parent: 0:ac45076e2510 version initiale branch: default commit: 1 modified (new branch head) update: 2 new changesets (update) $ hg diff -g diff --git a/babar.py b/babar.py --- a/babar.py +++ b/babar.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- #! /usr/bin/env python +# License: WTFPL v. 2 """Mon beau petit script""" $ hg ci -m '[license] oOPps: Ajoute la license au script python' created new head
Mais qu'est-ce donc que cette nouvelle tête ?
$ hg log --graph --template="\t{rev}) {desc}\n" @ 3) [license] oOPps: Ajoute la license au script python | | o 2) Permet d'afficher le contenu du fichier en argument | | | o 1) ajout d'un dossier |/ o 0) version initiale
La modification (ajout de la licence) à été versionnée alors que nous étions sur la révision 0) version initiale. Le lien de parenté est conservé. Nous avons alors l'arbre "généalogique" des révisions. Celui-ci comporte 2 branches et deux têtes.
Astuces
L'option --graph de la commande log est très souvent utilisée. Vous pouvez créer un alias glog dans votre configuration Mercurial
| [aliases] | glog = log -G
Notre fichier contient :
$ cat babar.py # -*- coding: utf-8 -*- #! /usr/bin/env python # License: WTFPL v. 2 """Mon beau petit script""" print "Mon script python est cool !"
Mais nous souhaiterions aussi "ajouter un dossier" et "permettre d'afficher le contenu du fichier en argument". Nous allons donc rassembler les deux branches [1] :
[1] | Cette situation est plutôt artificielle. Elle sert surtout de prétexte pour introduire le concept de branche. |
$ hg merge merging babar.py 2 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m 'Fusion !' $ hg log -v -G @ changeset: 4:3b60711b69f9 |\ tag: tip | | parent: 3:831e8464b77f | | parent: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | files: babar.py | | description: | | Fusion ! | | | | | o changeset: 3:831e8464b77f | | parent: 0:ac45076e2510 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | files: babar.py | | description: | | [license] oOPps: Ajoute la license au script python | | | | o | changeset: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | files: babar.py | | description: | | Permet d'afficher le contenu du fichier en argument | | | | o | changeset: 1:996158b51bfe |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | files: dossier/fichier_1 dossier/fichier_2 | description: | ajout d'un dossier | | o changeset: 0:ac45076e2510 user: test date: Thu Jan 01 00:00:00 1970 +0000 files: babar.py description: version initiale $ hg summary parent: 4:3b60711b69f9 tip Fusion ! branch: default commit: (clean) update: (current) $ tree . |-- babar.py `-- dossier |-- fichier_1 `-- fichier_2 1 directory, 3 files $ cat babar.py # -*- coding: utf-8 -*- #! /usr/bin/env python # License: WTFPL v. 2 """Mon beau petit script""" import sys print sys.argv[-1]
L'arbre de révisions est à votre disposition, vous pouvez vous y balader, mais faisons-le à la manière de Tarzan.
Pour y parvenir, nous allons voir différentes façons d'identifier des révisions grâce aux différentes formes du revid. Pour avoir les identifiants de la révision courante :
$ hg identify
3b60711b69f9 tip
Les différentes façons d'identifier une révision sont :
numéro: | [4], est local et dépend de l'historique de votre arbre ; nous aurions pu faire "Une autre variante" avant "Interactif maintenant". |
---|---|
identifiant: | [12d134c4d432]: est un hash unique et sans ambigüité. Il est construit à partir du contenu des fichiers, des metadonnées et de la parenté. |
tag: | est un identifiant unique pour humain, c'est le pseudo de la révision. |
bookmark: | est une marque dans votre dépôt qui vous permet de suivre une thématique de modifications. |
Vous pouvez les déclarer avec la commande tag :
$ hg tag -r ac45076e2510 init $ hg tag -r 3b60711b69f9 fusion $ hg log -G @ changeset: 6:2850220e4952 | tag: tip | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Added tag fusion for changeset 3b60711b69f9 | o changeset: 5:4935bb98f72a | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: Added tag init for changeset ac45076e2510 | o changeset: 4:3b60711b69f9 |\ tag: fusion | | parent: 3:831e8464b77f | | parent: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Fusion ! | | | o changeset: 3:831e8464b77f | | parent: 0:ac45076e2510 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: [license] oOPps: Ajoute la license au script python | | o | changeset: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Permet d'afficher le contenu du fichier en argument | | o | changeset: 1:996158b51bfe |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: ajout d'un dossier | o changeset: 0:ac45076e2510 tag: init user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: version initiale
On voit que les tags ont été déposés sur les révisions. Ils n'en bougeront plus (à moins de les enlever à la main). C'est une marque pérenne.
Astuces
Les tags sont souvent utilisés pour marquer une version particulière de votre projet.
S'il n'y a pas de restriction particulière pour les tags, il est largement préférable de n'utiliser que des caratères alphanumériques, le point . et le underscore _.
Vous pouvez alors utiliser les tags pour identifier des revisions :
$ hg up fusion 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg summary parent: 4:3b60711b69f9 fusion Fusion ! branch: default commit: (clean) update: 2 new changesets (update) $ hg up init 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ python babar.py Mon script python est cool !
Exercices
Remontez en haut de votre arbre d'historique. De là, ajouter un tag license à la révision qui intègre la licence. Déplacez-vous sur cette révision et ajouter le texte de votre licence et figez les modifications dans une nouvelle révision.
Revenez sur la révision 6:2850220e4952 puis "fusionnez" (merge) les modifications précédentes.
$ hg update 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg tag -r 831e8464b77f license $ hg update license 1 files updated, 0 files merged, 3 files removed, 0 files unresolved $ cat > babar.py << EOF > # -*- coding: utf-8 -*- > #! /usr/bin/env python > # License: WTFPL v. 2 > > # WTFPL v. 2: You just DO WHAT THE FUCK YOU WANT TO. > """Mon beau petit script""" > > print "Mon script python est cool !" > > EOF $ hg summary parent: 3:831e8464b77f license [license] oOPps: Ajoute la license au script python branch: default commit: 1 modified (new branch head) update: 6 new changesets (update) $ hg ci -m 'ajoute le contenu de la license' created new head $ hg merge 53538fc8b983 merging babar.py 3 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg commit --message 'Fusion !' $ hg log -G @ changeset: 9:700db0dd081c |\ tag: tip | | parent: 8:9f31cfa47c9a | | parent: 7:53538fc8b983 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Fusion ! | | | o changeset: 8:9f31cfa47c9a | | parent: 3:831e8464b77f | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: ajoute le contenu de la license | | o | changeset: 7:53538fc8b983 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Added tag license for changeset 831e8464b77f | | o | changeset: 6:2850220e4952 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Added tag fusion for changeset 3b60711b69f9 | | o | changeset: 5:4935bb98f72a | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Added tag init for changeset ac45076e2510 | | o | changeset: 4:3b60711b69f9 |\| tag: fusion | | parent: 3:831e8464b77f | | parent: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Fusion ! | | | o changeset: 3:831e8464b77f | | tag: license | | parent: 0:ac45076e2510 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: [license] oOPps: Ajoute la license au script python | | o | changeset: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Permet d'afficher le contenu du fichier en argument | | o | changeset: 1:996158b51bfe |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: ajout d'un dossier | o changeset: 0:ac45076e2510 tag: init user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: version initiale $ cd ..
Vous pouvez aisément partager votre travail entre vos machines, avec des collaborateurs, voire même avec le monde entier...
Un des principes de base d'un DVCS, tient au fait que toutes les informations du dépôt sont disponibles localement. Il est donc possible d'effectuer l'ensemble des opérations sur le dépôt, depuis une machine tierce. Mercurial permet donc de travailler en mode "hors-ligne".
Dès lors, il est nécessaire de disposer de commandes de synchronisation avec d'autres dépôts, qui seront explicitement appelées.
La première opèration naturelle, quand on entre dans un projet, consiste à récupérer ses sources et leurs historiques. Cela permet de comprendre en partie les différents choix retenus (d'où l'importance des messages liés aux révisions).
On commencera donc par dupliquer le dépôt du projet avant de pouvoir y appliquer des modifications.
Il faut utiliser pour cela la commande hg clone source, où la source peut être :
$ hg clone https://bitbucket.org/aleufroy/pyconfr warning: bitbucket.org certificate with fingerprint 24:9c:45:8b:9c:aa:ba:55:4e:01:6d:58:ff:e4:28:7d:2a:14:ae:3b not verified (check hostfingerprints or web.cacerts config setting) destination directory: pyconfr requesting all changes adding changesets adding manifests adding file changes added 10 changesets with 11 changes to 4 files updating to branch default 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd pyconfr $ hg log -G @ changeset: 9:700db0dd081c |\ tag: tip | | parent: 8:9f31cfa47c9a | | parent: 7:53538fc8b983 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Fusion ! | | | o changeset: 8:9f31cfa47c9a | | parent: 3:831e8464b77f | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: ajoute le contenu de la license | | o | changeset: 7:53538fc8b983 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Added tag license for changeset 831e8464b77f | | o | changeset: 6:2850220e4952 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Added tag fusion for changeset 3b60711b69f9 | | o | changeset: 5:4935bb98f72a | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Added tag init for changeset ac45076e2510 | | o | changeset: 4:3b60711b69f9 |\| tag: fusion | | parent: 3:831e8464b77f | | parent: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Fusion ! | | | o changeset: 3:831e8464b77f | | tag: license | | parent: 0:ac45076e2510 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: [license] oOPps: Ajoute la license au script python | | o | changeset: 2:339b3e5f3521 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: Permet d'afficher le contenu du fichier en argument | | o | changeset: 1:996158b51bfe |/ user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: ajout d'un dossier | o changeset: 0:ac45076e2510 $ cd ..
$ cd .. $ hg clone ssh://hg@bitbucket.org/aleufroy/pyconfr2012 $ cd hgview $ hg qv -l 5 $ cd ..
$ cd .. $ hg clone /tmp/pyconfr pyconde updating to branch default 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd pyconde $ hg summary parent: 9:700db0dd081c tip branch: default commit: (clean) update: (current)
Astuces
Vous pouvez renseigner un identifiant de révision pour ne dupliquer que partiellement un dépôt. En général, dans ces cas on renseigne un numéro de version du projet, utilisé comme tag.
Vous pouvez échanger votre historique avec les autres dépôts (aux permissions près). Il existe deux commandes pour la synchronisation : push et pull.
hg pull source: | rapatrie l'historique d'un autre dépôt source en local. |
---|---|
hg push cible: | transmet l'historique vers un autre dépôt cible |
Astuces
Ici aussi vous pouvez renseigner l'identifiant pour limiter la partie de l'historique échangée.
Exercices
Dupliquez le dépôt pyconfr en pyconbe jusqu'à la révision license. Modifiez la licence puis figez une nouvelle révision.
Rapatriez le reste de l'historique de pyconfr et observez le contenu de votre dossier et celui de votre dépôt.
Fusionnez vos modifications aux changements rapatriés.
$ hg clone -r license https://bitbucket.org/aleufroy/pyconfr pyconbe adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd pyconbe $ tree . `-- babar.py 0 directories, 1 file $ hg log -G --template='{rev}:{node|short} | {desc}' @ 1:831e8464b77f | [license] oOPps: Ajoute la license au script python | o 0:ac45076e2510 | version initiale $ cat > babar.py << EOF > # -*- coding: utf-8 -*- > #! /usr/bin/env python > # WTFPL v. 2: You just DO WHAT THE FUCK YOU WANT TO. > > """Mon beau petit script""" > > print "Mon script python est cool !" > > EOF $ hg ci -m 'met a jour la license' $ hg pull pulling from /tmp/pyconfr searching for changes adding changesets adding manifests adding file changes added 8 changesets with 9 changes to 4 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) $ tree . `-- babar.py 0 directories, 1 file $ hg log -G --template='{rev}:{node|short} | {desc}' o 10:700db0dd081c | Fusion ! |\ | o 9:9f31cfa47c9a | ajoute le contenu de la license | | o | 8:53538fc8b983 | Added tag license for changeset 831e8464b77f | | o | 7:2850220e4952 | Added tag fusion for changeset 3b60711b69f9 | | o | 6:4935bb98f72a | Added tag init for changeset ac45076e2510 | | o | 5:3b60711b69f9 | Fusion ! |\| o | 4:339b3e5f3521 | Permet d'afficher le contenu du fichier en argument | | o | 3:996158b51bfe | ajout d'un dossier | | | | @ 2:9205c8a8c3c7 | met a jour la license | |/ | o 1:831e8464b77f | [license] oOPps: Ajoute la license au script python |/ o 0:ac45076e2510 | version initiale $ hg merge merging babar.py 3 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)
Si deux branches modifient le même fichier, Mercurial a besoin de fusionner ces modifications lorsque ces branches sont fusionnées.
En cas de difficultés, Mercurial va faire appel à un outil externe. Si aucun outil n'est configuré des marqueurs de conflit seront utilisés (comme dans CVS).
La section merge-tools de l'aide explique comment configurer un tel outil. Vous pouvez aussi vous référer au fichier d'exemple fourni par Mercurial [2] .
[2] | Attention, votre distribution linux l'a peut-être déjà activé par défaut. |
Astuces
Mercurial implémente un certain nombre d'outils en interne, jetez y un œil :
Exercices
Créez deux branches du projet réalisant des modifications conflictuelles au même endroit d'un même fichier. Puis lancez-vous dans une fusion avec hg merge.
Il arrive que l'on récupère des révisions vérolées - car c'est connu, c'est toutjours de la faute des autres ...
Il est donc nécessaire de rechercher la révision problématique.
Astuces
Vous pouvez modifier de manière permanante la sortie de log en fixant un "template" personnalisé (hg help template):
$ cat >> $HGRCPATH << EOF > [ui] > logtemplate="{rev}:{node|short}> {desc}" > EOF
Nous pouvons utilisez la commande log pour suivre l'évolution d'un fichier particulier:
$ hg log babar.py
La méthode la plus simple pour partager son propre dépôt avec d'autres personnes consiste à avoir une machine connectée à Internet et... la commande serve.
$ hg serve -p 41705 & $ hgpid=$! $ cd .. $ hg clone http://localhost:41705 pyconuk $ cd pyconuk $ hg log -G --template="{rev}:{node|short} | {desc}" $ kill -15 $hgpid
Exercices
Une fois vos serveurs Mercurial lancés, vous pouvez essayer de récupérer les dépôts de vos voisins.
Astuces
Il y a une version wsgi/cgi pour des utilisation en production: hg help hgweb.
Il est possible de transporter des révisions d'un dépôt à l'autre sans connexion directe avec l'utilisattion des bundles. La commande bundle permet de générer les fichiers de synchronisation.
$ hg bundle pyconfr.tar.gz searching for changes 1 changesets found $ ls -lah pyconfr.tar.gz -rw-r--r-- 1 alain users 463 Sep 16 01:54 pyconfr.tar.gz
Les commandes export et import sont pratiques car elles permettent le partage de fichiers ".patch".
$ hg export --git -r license
L'option --git permet d'utiliser un format de patch plus complet que le vieux format UNIX. Activez dans la section diff de votre fichier de configuration le format git:
[diff] git = true
On s'échangera donc des patches avec:
.. sourcecode:: ini
$ hg export --git -r license > license.patch $ sendmail license.patch $ readmail license.patch $ hg import --exact license.patch
L'option --exact applique le patch à l'endroit où il a été généré.
Astuces
L'extension patchbomb ajoute la command email simplifie grandement l'envoie de patch par mail. Il peut être un outil pratique pour permettre à des contributeurs externes de participer à un projet.
Mercurial propose une langage de requête sur l'arbre de révisions: revset
Ce langage supporte un nombre de prédicats joints grâce à des opérateurs.
Les prédicats permettent de filter selon le nom de l'auteur author(str), la date(interval), le contenu de la description desc(str), disponible qu'en local outgoing(path), la parenté parants(set), etc ...
Les opérateurs permettent de joindre en combinant x and y, en rejetant x - y, en parcourant l'arbre des révisions x :: yy, en énumérant les numéros de révisions `` x : y``, en se déplacant sur le parent ^...
La liste complète des prédicats et des opérateurs est disponible dans l'aide hg help revset.
$ hg log -G --template='{rev}:{node|short} | {desc}' @ 10:700db0dd081c | Fusion ! |\ | o 9:9f31cfa47c9a | ajoute le contenu de la license | | o | 8:53538fc8b983 | Added tag license for changeset 831e8464b77f | | o | 7:2850220e4952 | Added tag fusion for changeset 3b60711b69f9 | | o | 6:4935bb98f72a | Added tag init for changeset ac45076e2510 | | o | 5:3b60711b69f9 | Fusion ! |\| o | 4:339b3e5f3521 | Permet d'afficher le contenu du fichier en argument | | o | 3:996158b51bfe | ajout d'un dossier | | | | @ 2:9205c8a8c3c7 | met a jour la license | |/ | o 1:831e8464b77f | [license] oOPps: Ajoute la license au script python |/ o 0:ac45076e2510 | version initiale
Il est possible d'utiliser un revset partout où une ou plusieurs révisions sont requises.
$ hg log -G --template='{rev}:{node|short} | {desc}' -r . @ 2:9205c8a8c3c7 | met a jour la license | $ hg log -G --template='{rev}:{node|short} | {desc}' -r .^ o 1:831e8464b77f | [license] oOPps: Ajoute la license au script python | $ hg log -G --template='{rev}:{node|short} | {desc}' -r 'desc("Fusion")' @ 10:700db0dd081c | Fusion ! |\ | o 7:2850220e4952 | Added tag fusion for changeset 3b60711b69f9 | | | o 5:3b60711b69f9 | Fusion ! | |\ $ hg log -G --template='{rev}:{node|short} | {desc}' -r 'merge()::'
Il existe aussi un langage équivalent pour les requêtes sur les fichiers.