aragost Trifork: Mercurial Kick Start Exercises


Signets Mercurial

There are two main ways to organize branches in Mercurial: named branches and bookmarks. Bookmarks are used for short-term feature or topic branches whereas named branches are used for long-term branches.

Les branches nommées sont plus adaptées lorsque vous voulez suivre le contexte dans lequel chaque révision a été faite ; le nom de la branche est intégré dans la révision et vous pouvez ainsi vous y référer des années plus tard. Comme le nom des branches est intégré dans l’historique, les branches nommées sont parfaitement adaptées lorsque vous avez besoin d’un audit et que vous voulez savoir qui a fait quoi et quand.

Il y a des cas où les branches nommées sont moins adaptées : si vous n’avez pas besoin ou si vous ne devez pas suivre la branche nommée après le développement d’une fonctionnalité alors les branches nommées ne sont pas faites pour vous. Peut-être voudrez-vous faire quelques expériences sans vous attacher à une branche nommée, ou peut-être voudrez-vous changer le nom de la branche ultérieurement.

Si tel est votre cas, alors les signets de Mercurial vous aideront.

Note

Vous devez utiliser au moins la version 2.1 de Mercurial pour les exemples de cette partie.

Sommaire

Introduction

Nous allons explorer les signets en détail ci-dessous, mais brièvement nous pouvons dire que les signets de Mercurial vous permettent d’associer un nouveau nom à une révision. C’est pratique si vous travaillez sur plusieurs choses en même temps comme deux branches différentes.

Les étiquettes permettent aussi d’ajouter un nom à une révision, mais contrairement aux étiquettes, les signets sont mutables et éphémères : vous pouvez les déplacer, les renommer ou les supprimer et ils ne sont pas enregistrés dans l’historique. Cela signifie qu’il n’y a pas de traces des signets lors d’un audit.

L’essentiel des signets

Imaginez que Alice, Bob et Carla écrivent ensemble un livre de phrases. Dans le projet, ils travailleront sur des phrases dans différentes catégories, et ils devront de temps en temps travailler sur des catégories différentes en même temps. Ils auront donc des développements en cours dans plusieurs branches au même moment. Les signets leur permettent de garder une trace de ces branches d’une manière simple.

Carla est la chef, donc elle commence par créer le dépôt qui sera utilisé pour le projet :

carla$ hg init phrases
carla$ cd phrases
carla$ echo "The Phrase Book Project" > README.txt
carla$ hg add
adding README.txt
carla$ hg commit -m "Added a README" 

Alice et Bob vont chacun avoir leur propre copie de travail et pousseront/tireront vers/depuis le dépôt de Carla, qui fonctionnera comme un dépôt central. Généralement le dépôt central est hébergé sur un serveur de la société et les copies de travail sont sur les postes de chaque développeur. Pour la simplicité, les trois dépôts seront sur la même machine.

Alice et Bob peuvent maintenant faire une copie de travail du dépôt que Carla vient de créer. Pour Alice, cela ressemble à cela :

alice$ hg clone ../carla/phrases
destination directory: phrases
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
alice$ cd phrases

Ils travailleront sur des phrases dans différentes catégories et commenceront par rassembler seulement des phrases anglaises. Carla demande à Alice d’ajouter des phrases de salutations (greetings en anglais) :

alice$ echo "Hello!" > greetings.txt
alice$ hg add
adding greetings.txt
alice$ hg commit -m "First greeting" 

Ajouter un signet

Carla demande soudain à Alice de commencer à chercher des phrases pour les voyages. Alice est déjà en train de travailler sur les salutations, et elle voudrait séparer les deux tâches — mélanger les changements liés aux salutations avec les changements liés aux voyages les rendront plus difficile à suivre ultérieurement. Alice va donc revenir à la révision 0 avec la commande hg update et commencer une nouvelle branche à partir de cette révision. Mais pour se souvenir de là ou elle en était, elle va d’abord créer un signet. À ce moment son dépôt ressemblera à :

alice-pre-bookmark.png

Ses changements pour les salutations sont seulement identifiés car ils sont sur la branche default et par la révision tip. Ces deux identifications vont changer dès qu’elle travaillera sur une nouvelle branche, elle a donc besoin de quelque chose de plus stable — un signet. Elle crée donc un signet :

alice$ hg bookmark greetings

La révision est maintenant associée à un signet :

alice-greetings-bookmark.png

Elle peut voir le signet avec la commande hg bookmarks :

alice$ hg bookmarks
 * greetings                 1:0b89bcda3dcf

L’étoile (*) indique que le signet est actif, ce qui signifie qu’il se déplacera lorsqu’elle fera une nouvelle révision. Comme le signet se déplace à chaque nouvelle révision, il pointera donc toujours sur la tête de la branche sur laquelle elle travaille.

Alice veut créer une nouvelle branche pour les phrases sur les voyages. La branche doit commencer à la révision 0, elle effectue donc d’abord la mise à jour vers cette révision. Cela rend le signet des greetings (salutations en français) inactif puisqu’elle travaille maintenant sur une autre branche de développement :

alice$ hg update 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf

Le signet est resté à sa place :

alice-inactive-greetings.png

Cela signifie qu’Alice peut toujours exécuter la commande hg update greetings pour revenir aux salutations. Maintenant elle est astucieuse et elle crée donc tout de suite un signet appelé traveling (voyages en français) pour la nouvelle branche que lui a demandée Carla. Le nouveau signet est automatiquement actif :

alice$ hg bookmark traveling
alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf
 * traveling                 0:4326a390b9b6

Le signet actif peut aussi être visualisé dans TortoiseHg :

alice-active-traveling.png

Maintenant lorsqu’Alice crée une nouvelle révision, le signet traveling fera, eh bien … le voyage avec la révision !

alice$ echo "When does the bus arrive?" > traveling.txt
alice$ hg add traveling.txt
alice$ hg commit -m "Started on traveling phrases" 
created new head
alice-traveling-moved.png

Mise à jour vers un signet

Maintenant que Alice a des signets vers les révisions 1 et 2, elle peut utiliser le nom des signets dans toutes les commandes qui nécessitent un numéro de révision. C’est à dire qu’elle peut maintenant utiliser soit 1 (le numéro de révision local), soit 0b89bcda3dcf (l’id de révision global), soit greetings (le nom du signet) :

alice$ hg log -r 1
changeset:   1:0b89bcda3dcf
bookmark:    greetings
user:        Alice <alice@example.net>
date:        Tue May 01 10:20:35 2012 +0000
summary:     First greeting
alice$ hg log -r 0b89bcda3dcf
changeset:   1:0b89bcda3dcf
bookmark:    greetings
user:        Alice <alice@example.net>
date:        Tue May 01 10:20:35 2012 +0000
summary:     First greeting
alice$ hg log -r greetings
changeset:   1:0b89bcda3dcf
bookmark:    greetings
user:        Alice <alice@example.net>
date:        Tue May 01 10:20:35 2012 +0000
summary:     First greeting

Commes les étiquettes et les noms des branches, les noms de signets fonctionnent avec toutes les commandes — hg diff, hg merge, etc. Voici la commande pour mettre à jour :

alice$ hg update greetings
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
alice$ hg bookmarks
 * greetings                 1:0b89bcda3dcf
   traveling                 2:f1cd0e213eec
alice$ hg update traveling
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf
 * traveling                 2:f1cd0e213eec

Remarquez que la mise à jour avec le signet rend ce dernier actif. De plus, une nouvelle révision avancera le signet actif, donc hg update traveling sera suffisant pour préparer le répertoire d’Alice pour travailler sur les voyages (branche traveling) :

Renommer et supprimer un signet

The distinguishing feature of bookmarks compared to named branches is that they exist outside of the history. Here, “history” means the immutable changesets that cannot be changed without changing their changeset IDs. Bookmarks are not stored in the changesets and they are not part of the computation of changeset IDs. They can therefore be deleted and renamed at will.

Imaginez qu’Alice ajoute un nouveau signet :

alice$ hg bookmark some-name
alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf
 * some-name                 2:f1cd0e213eec
   traveling                 2:f1cd0e213eec

Elle peut maintenant renommer le signet :

alice$ hg bookmark --rename some-name new-name
alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf
 * new-name                  2:f1cd0e213eec
   traveling                 2:f1cd0e213eec

Elle peut aussi le supprimer :

alice$ hg bookmark --delete new-name
alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf
   traveling                 2:f1cd0e213eec

Il n’y a maintenant plus aucune trace du signet supprimé ; personne ne peut savoir qu’il a existé. Cela rend le signet parfaitement adapté pour tracer des branches, pour de petits développements, qui n’ont pas besoin d’être enregistrées dans l’historique comme peuvent l’être les branches nommées.

Après la suppression du signet new-name, il n’y a plus de signet actif. Nous allons continuer avec la branche traveling, donc nous rendons à nouveau ce signet actif :

alice$ hg update traveling
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

Pousser une branche

Quand Alice travaillait, Carla était occupée aussi. Elle mettait à jour le fichier README avec le nom des auteurs :

carla$ echo "by Alice, Bob, and Carla" >> README.txt
carla$ hg commit -m "Added authors" 

Cela signifie que la branche traveling d’Alice deviendra une seconde tête lorsqu’elle la poussera. Avec le fonctionnement par défaut de Mercurial, cette action échouera :

alice$ hg push -r traveling
pushing to /home/carla/phrases
searching for changes
abort: push creates new remote head f1cd0e213eec!
(you should pull and merge or use push -f to force)

Pour résoudre ce problème Alice va tirer les révisions et regarder le dépôt dans TortoiseHg :

alice$ hg pull
pulling from /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads .' to see heads, 'hg merge' to merge)
alice-two-heads.png

Il n’y a pas moins de 3 têtes ! Pousser la tête traveling créera deux têtes dans le dépôt distant et comme cela peut prêter à confusion d’avoir plusieurs têtes sans nom, Mercurial va l’empêcher : un utilisateur qui créerait une copie de travail du dépôt ne saurait pas qu’elle tête utiliser. Quand il n’y a qu’une seule tête, il n’y a plus de question — vous avez juste à créer votre copie de travail et commencer à travailler.

Ci-dessus, Mercurial a suggéré de fusionner les têtes ou d’utiliser le paramètre -f pour forcer la poussée. Forcer les choses est généralement le signe que vous n’utilisez pas l’outil comme il a été conçu, mais ici c’est un des cas où vous devrez utiliser le paramètre -f. La raison est simple, Alice n’a pas encore fini de travailler sur la branche traveling, et elle ne veut donc pas mélanger les changements de sa branche avec ceux de la branche principale. Si il y avait eu une correction importante dans la branche principale, alors elle aurait pu la fusionner dans sa branche, mais ici ce n’est pas nécessaire.

Alice va donc pousser en force sa branche dans le dépôt distant :

alice$ hg push -f -r traveling
pushing to /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)

Il est très important qu’Alice limite sa poussée seulement à une seule branche ! Elle a dans son dépôt deux branches qui n’existent pas dans le dépôt de Carla, et le paramètre -f indique à Mercurial de pousser aveuglément toutes les révisions sortantes. Un peu d’attention est donc nécessaire pour ne publier qu’une seule des branche privées. Ici le texte +1 heads (une tête supplémentaire) indique à Alice qu’elle a bien fait — elle n’a poussé qu’une nouvelle branche dans le dépôt.

À quoi ressemble le dépôt, du point de vue de Carla ? Elle a maintenant 2 têtes anonymes dans son dépôt :

carla$ hg heads
changeset:   2:f1cd0e213eec
tag:         tip
parent:      0:4326a390b9b6
user:        Alice <alice@example.net>
date:        Tue May 01 10:20:40 2012 +0000
summary:     Started on traveling phrases

changeset:   1:4b18431b805d
user:        Carla <carla@example.net>
date:        Tue May 01 10:20:45 2012 +0000
summary:     Added authors

On les appelle anonymes car elles n’ont pas de nom associé — elles sont sur la même branche nommée et n’ont pas de signet :

carla$ hg bookmarks
no bookmarks set

Comme Alice entend continuer à travailler sur sa branche, il aurait été plus pratique si son signet avait été poussé aussi. Au début (avant Mercurial 1.6), les signets étaient strictement locaux mais il est maintenant possible de les pousser et de les tirer.

Partage de signets

Les signets peuvent être poussés et tirés entre les dépôts. Cela fonctionne avec tous les protocoles utilisés par Mercurial : SSH, HTTP et les fichiers locaux. La possibilité de pousser un signet est régie par les mêmes règles d’accès que les poussées normales. Si vous pouvez pousser une révision vers un dépôt alors vous pouvez aussi y pousser un signet.

Signets entrants et sortants

Alice peut facilement corriger son erreur précédente. D’abord elle utilise hg outgoing -B pour voir s’il manque dans le dépôt du serveur un des signets de son dépôt local (de même hg incoming -B vous indiquera les signets présents dans le dépôt du serveur et qui n’existent pas dans votre dépôt local) :

alice$ hg outgoing -B
comparing with /home/carla/phrases
searching for changed bookmarks
   greetings                 0b89bcda3dcf
   traveling                 f1cd0e213eec

Elle a deux signets dans son dépôt local qui n’existent pas sur le serveur. Pour pousser un signet elle a juste besoin d’utiliser l’option -B à la place de l’option -r lors de la poussée :

alice$ hg push -B traveling
pushing to /home/carla/phrases
searching for changes
no changes found
exporting bookmark traveling

Mercurial va ainsi pousser la révision pointée par traveling et exporter le signet vers le serveur. Ici, comme elle a déjà poussé la révision, seul le signet sera poussé. Maintenant le dépôt de Carla est beaucoup plus ordonné qu’auparavant :

carla-with-bookmark.png

Alice va aussi publier sa branche greetings de la même manière et mais du premier coup correctement cette fois :

alice$ hg push -f -B greetings
pushing to /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
exporting bookmark greetings

Travailler avec un signet publié

Maintenant qu’Alice a publié son signet traveling, elle peut continuer à travailler et régulièrement pousser des révisions vers Carla. Cela avancera automatiquement les signets sur le serveur — plus besoin d’utiliser le paramètre -B :

alice$ echo "Two tickets, please!" >> traveling.txt
alice$ hg commit -m "A ticket phrase" 
alice$ hg push
pushing to /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating bookmark traveling

Remarquez le message updating bookmark traveling (mise à jour du signet traveling en français) en bas. C’est ce qui indique à Alice que le signet est synchronisé dans les deux dépôts.

Alice et Bob vont maintenant travailler ensemble sur la branche. Bob va d’abord tirer la branche depuis le dépôt de Carla. La première fois qu’il tire la branche, Bob doit préciser le paramètre -B :

bob$ hg pull -B traveling
pulling from /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
(run 'hg update' to get a working copy)
importing bookmark traveling
bob$ hg bookmarks
   traveling                 2:0098cff6f6d8

Note

Ce fonctionnement va changer avec la version 2.3 de Mercurial. À partir de cette version, Mercurial importera automatiquement les signets distants des révisions que vous tirez. Cela signifie que Bob pourra juste exécuter la commande hg pull pour récupérer toutes les révisions entrantes et les signets du dépôt de Carla.

Bob va maintenant mettre à jour la révision, faire une modification et pousser le résultat :

bob$ hg update traveling
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
bob$ echo "Where is the train station?" >> traveling.txt
bob$ hg commit -m "Asking for a train station" 
bob$ hg push
pushing to /home/carla/phrases
searching for changes
note: unsynced remote changes!
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating bookmark traveling

Remarquez comme le signet traveling a été automatiquement mis à jour sur le serveur. En général, Mercurial synchronisera automatiquement un signet dès qu’il est présent à la fois dans le dépôt local et dans le dépôt distant. Il y a une contrainte additionnelle : hg push ne mettra à jour le signet distant que si c’est un parent du signet local. Si les signets ont divergé, cela signifie qu’une autre personne a travaillé sur la branche et les deux têtes devraient donc être fusionnées avant d’être poussées. Nous allons voir cette situation ensuite.

Signets divergents

Bob vient juste de pousser une révision dans la branche traveling, mais Alice ne l’a pas encore tirée. Avant de la tirer, elle fait sa propre révision dans la branche :

alice$ echo "How much for a ticket?" >> traveling.txt
alice$ hg commit -m "Asking for the ticket price" 

Comme d’habitude dans Mercurial, elle va remarquer la nouvelle révision de Bob quand elle essaiera de pousser vers le serveur.

alice$ hg push
pushing to /home/carla/phrases
searching for changes
abort: push creates new remote head e0c765eadfc4!
(you should pull and merge or use push -f to force)

Ici, elle veut tirer et fusionner — elle n’est pas en train de publier une nouvelle branche, ce serait donc une erreur d’utiliser le paramètre -f.

Renommage automatique d’un signet

Quand Alice tire, elle va recevoir le révisions de Bob :

alice$ hg pull
pulling from /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
divergent bookmark traveling stored as traveling@default
(run 'hg heads .' to see heads, 'hg merge' to merge)

En plus de la sortie normale de hg pull, Mercurial affiche aussi un message à propos de l’enregistrement du signet divergent traveling@default. Voici la situation dans TortoiseHg :

alice-divergent-bookmarks.png

Ce qui s’est passé, c’est que Mercurial a détecté que le signet traveling sur le serveur a divergé du signet traveling local. Comme expliqué ci-dessus, la divergence signifie que les signets sont frères — aucun n’est le parent de l’autre. Le signet distant a donc été renommé traveling@default. La partie @default vient du chemin par défaut. Si Alice avait écrit :

[paths]
carla = /home/carla/phrases

dans sont fichier .hg/hgrc, alors le signet aurait été renommé traveling@carla.

Fusion de signets divergents

Comme habituellement, Alice va maintenant fusionner avec l’autre tête. Normalement elle doit juste exécuter hg merge et Mercurial sélectionnera automatiquement l’autre tête de la branche comme candidat évident de la fusion. Cela ne fonctionne pas avec les signets :

alice$ hg merge
abort: branch 'default' has 4 heads - please merge with an explicit rev
(run 'hg heads .' to see heads)

Elle doit fusionner les signets divergents manuellement :

alice$ hg merge "traveling@default"
merging traveling.txt
warning: conflicts during merge.
merging traveling.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon

Il y a un conflit car Alice et Bob ont, tous les deux, ajouté une nouvelle ligne après la première ligne. Alice résoud le conflit en incorporant les deux changements dans le fichier :

alice$ cat traveling.txt
When does the bus arrive?
Two tickets, please!
<<<<<<< local
How much for a ticket?
=======
Where is the train station?
>>>>>>> other
alice$ hg resolve --tool internal:local traveling.txt
alice$ echo "Where is the train station?" >> traveling.txt

Elle vérifie la différence et comme tout semble parfait, elle crée une révision avec la fusion :

alice$ hg diff
diff -r e0c765eadfc4 traveling.txt
--- a/traveling.txt     Tue May 01 10:21:00 2012 +0000
+++ b/traveling.txt     Tue May 01 10:21:03 2012 +0000
@@ -1,3 +1,4 @@
 When does the bus arrive?
 Two tickets, please!
 How much for a ticket?
+Where is the train station?
alice$ hg commit -m "Merged with Bob" 

Après la fusion, le signet divergent est toujours là :

alice$ hg bookmarks
   greetings                 1:0b89bcda3dcf
 * traveling                 7:0e1a5b84f635
   traveling@default         6:888ae5a9e614

Alice n’en a plus besoin, donc elle le supprime :

alice$ hg bookmarks --delete "traveling@default"

Le dépôt ressemble à cela :

alice-merged-bookmarks.png

Note

Mercurial 2.3 va améliorer ce fonctionnement : hg merge va maintenant automatiquement sélectionner un signet divergent comme candidat pour la fusion. La création de la révision avec la fusion supprimera automatiquement le signet divergent.

Quand elle pousse vers Carla, le signet traveling avance automatiquement. Avant la poussée, il pointait vers 888ae5a9e614 et comme 0e1a5b84f635 est une révision enfant, le signet peut avancer aussi sur le serveur.

alice$ hg push
pushing to /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
updating bookmark traveling

Fusionner une branche

Alice et Bob ont maintenant collectés trois phrases à propos des voyages et ils décident donc de fusionner la branche traveling avec la branche principale.

Fusion

Alice effectuera la fusion. Elle commence par tirer depuis Carla pour être sûre de bien avoir les derniers changements puis elle met à jour vers la tête non nommée où Carla a édité le fichier README.txt :

alice$ hg pull
pulling from /home/carla/phrases
searching for changes
no changes found
alice$ hg update -r "head() and not bookmark()"
1 files updated, 0 files merged, 1 files removed, 0 files unresolved

In the update command, Alice used a revision set to select the changeset that is a head with no bookmark. She can see in TortoiseHg that she ended up at the correct changeset:

alice-before-merge.png

Maintenant elle fusionne simplement avec la branche traveling :

alice$ hg merge traveling
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
alice$ hg commit -m "Merged with traveling branch" 

Le résultat est comme vous l’espériez :

alice-after-merge.png

Suppression du signet

La branche a été fusionnée et le signet n’est plus utile. Alice peut donc le supprimer :

alice$ hg bookmark --delete traveling

Elle peut aussi pousser la révision de fusion :

alice$ hg push
pushing to /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 0 changes to 0 files (-1 heads)

Bien qu’elle ait supprimé le signet localement et poussé la révision de fusion, le signet existe encore sur le serveur :

alice$ hg incoming -B
comparing with /home/carla/phrases
searching for changed bookmarks
   traveling                 0e1a5b84f635

Pour le supprimer sur le serveur, Alice exécute la commande suivante :

alice$ hg push -B traveling
pushing to /home/carla/phrases
searching for changes
no changes found
deleting remote bookmark traveling

Préciser un signet qui n’existe pas localement mais existe sur le serveur le supprimera du serveur. Cela ressemble à la première publication d’un signet : hg push -B NAME qui fait pointer NAME vers la même révision sur le serveur que celle vers laquelle il pointe localement — si NAME n’existe pas localement, alors il n’existera pas non plus sur le serveur.

Alice aurait aussi pu pousser la fusion et supprimer le signet en une seule opération. On peut illustrer cela en fusionnant aussi la branche greetings :

alice$ hg merge greetings
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
alice$ hg commit -m "Merged greetings branch" 
alice$ hg bookmark --delete greetings
alice$ hg push -B greetings -r .
pushing to /home/carla/phrases
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 0 changes to 0 files (-1 heads)
deleting remote bookmark greetings

Ici -B greetings est le paramètre qui indique à Mercurial de supprimer le signet distant, et -r . de pousser la nouvelle révision de fusion : la révision . (point) est un raccourci pour la révision parent de la copie de travail. Sans le paramètre -r ., hg push aurait seulement poussé jusqu’à la révision greetings — et donc exclu la révision de fusion.

Conclusion

Les signets sont une méthode légère de suivre plusieurs lignes de développement (têtes) dans votre dépôt. Les principales caractéristiques des signets sont :

Les principales commandes pour travailler avec les signets sont :

Exercices

  1. Une personne du groupe crée un dépôt — les autres en font un clone.

  2. Créer un signet avec votre nom et effectuer quelques révisions.

  3. Publier votre signet vers le dépôt central et tirer les autres branches dans votre dépôt.

  4. See the revision set documentation and try a query like hg log -r "ancestors(NAME) - ancestors(.)" to see changesets on the branch NAME that have not yet been merged into your current revision. Revision sets also work in TortoiseHg.

  5. Mettez à jour une des autres branches et créez une révision. Poussez-la vers le serveur et faites des essais avec les signets divergents.

  6. Enable the rebase extension and try rebasing a feature branch on top of the main line of development. The bookmarks should follow along automatically.

Historique

Les premières version de Mercurial n’avaient ni branches nommées, ni signets. Les branches nommées ont été introduites dans Mercurial 0.9.2 (décembre 2006) et les signets ont été introduits deux ans plus tard. Depuis, les signets ont gagné beaucoup de fonctionnalités et de stabilité. Les fonctionnalités les plus visibles jusqu’à Mercurial 2.2 sont :

Mercurial 1.1 (décembre 2008)
Les signets sont ajoutés comme une extension standard.
Mercurial 1.6 (juin 2010)
Signets que l’on peut pousser. Précédemment les signets étaient seulement des étiquettes locales pour les révisions. Avec cette version, les signets peuvent être partagés en les publiant vers un serveur distant et les autres utilisateurs peuvent les tirer.
Mercurial 1.8 (mars 2011)
Les signets deviennent partie intégrante du cœur de Mercurial.
Mercurial 2.1 (février 2012)
Les signets divergents sont renommés quand ils sont tirés dans le dépôt local. Cela vous permet de distinguer entre toto (votre signet) et toto@alice (le signet d’Alice).

Comme les signets ont une longue histoire, il y a maintenant des guides qui contiennent des informations dépassées. Vous pouvez comparez la date de publication du guide avec l’historique ci-dessus pour savoir les fonctionnalités que le guide ne peut pas connaître.