aragost Trifork: Mercurial Kick Start Exercises


Interaction avec Subversion

L’extension hgsubversion transforme Mercurial en un client Subversion. Cela vous permet de profiter des révisions hors ligne et de toutes les autres caractéristiques utiles de Mercurial tout en vous permettant de pousser vos révisions vers Subversion.

Sommaire

Installation

L’extension nécessite les bindings Python pour Subversion. Sous Windows, les bindings sont fournis avec TortoiseHg. Sous Linux, vous devez chercher un paquet python-subversion dans votre gestionnaire de paquets.

Pour installer l’extension exécutez la commande :

$ hg clone https://hgsubversion.googlecode.com/hg/ hgsubversion

Ensuite ajoutez :

[extensions]
hgsubversion = path/to/hgsubversion

dans votre fichier de configuration pour charger l’extension. Si vous avez installé l’extension avec votre gestionnaire de paquet, elle a probablement été copiée dans votre chemin PYTHONPATH et vous avez juste besoin d’ajouter :

[extensions]
hgsubversion =

Utilisez hg help hgsubversion pour vérifier que l’extension est bien activée.

Cloner Subversion

Nous avons préparé un dépôt subversion avec un petit programme Hello World. Il y a dépôt pour chaque groupe, appelé hello1, hello2, …, hello5. Cloner celui correspondant à votre numéro de groupe :

alice$ hg clone http://mercurial.aragost.com/svn/helloX hello-hg 
[r1] mg: Created initial layout.
[r2] mg: First known version by Brian Kernighan, 1974.
[r3] mg: Include stdio.h.
[r4] mg: Output newline.
[r5] mg: Version 1.0.
[r6] mg: Capitalized!
[r7] mg: Comments are good.
[r8] mg: Added README.
[r9] mg: Added Makefile.
[r10] mg: Ignore compiled program.
pulled 9 revisions
updating to branch default
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
alice$ cd hello-hg

Note

Si l’URL commençant par http(s):// ne fonctionne pas, vous pouvez essayer en utilisant svn+http(s)://. Cela indique de manière explicite à Mercurial que vous voulez cloner un dépôt Subversion.

Alice inspecte le dépôt avec thg log pour vérifier que les étiquettes ont été définies correctement :

clone.png

La dernière révision de Subversion fixe la propriété svn:ignore à hello pour ignorer le binaire compilé. Dans Mercurial les modèles pour ignorer les fichiers sont contrôlés par le fichier .hgignore à la racine du dépôt. Ce fichier peut être créé avec la commande :

alice$ hg svn genignore

Normalement, nous devrions faire une révision avec la modification pour la partager avec tout le monde. Néanmoins comme, dans ce cas, Subversion est le dépôt maître, vous devriez éviter de pousser le fichier .hgignore. C’est pour cette raison que le fichier .hgignore créé s’ignore lui même. Vous pouvez le recréer de temps en temps avec la commande hg svn genignore --force.

Pousser vers Subversion

Alice peut maintenant éditer les fichiers et committer dans Mercurial :

alice$ echo "/* The End. */" >> hello.c
alice$ hg diff
diff -r e3314036fa9f hello.c
--- a/hello.c   Fri Mar 12 10:20:45 2010 +0000
+++ b/hello.c   Fri Mar 12 21:20:10 2010 +0000
@@ -7,3 +7,4 @@
        printf("Hello, World!\n");
        return 0;
 }
+/* The End. */
alice$ hg commit -m "Added footer." 

Les changements ne sont pas encore dans le serveur Subversion — comme d’habitude, hg push est nécessaire. Pousser une révision nécessite de la réécrire. En effet le serveur Subversion est le maître et c’est lui qui déterminera le nom de l’utilisateur et la date de la révision. Du côté de Mercurial, la révision est donc réécrite pour refléter cette modification des métadonnées :

alice$ hg outgoing 
comparing with http://mercurial.aragost.com/svn/helloX
changeset:   9:2dc661f0cdc8
tag:         tip
user:        Alice <alice@example.net>
date:        Fri Mar 12 21:20:15 2010 +0000
summary:     Added footer.
alice$ hg push 
pushing to http://mercurial.aragost.com/svn/helloX
searching for changes
[r11] alice: Added footer.
pulled 1 revisions
saved backup bundle to $HOME/hello-hg/.hg/strip-backup/2dc661f0cdc8-backup.hg

Vous pouvez voir la révision mise à jour avec la commande :

alice$ hg tip
changeset:   9:a545b3d1c21d
tag:         tip
user:        alice@66d5687c-2042-4ccc-9f0a-7e74790c38a1
date:        Fri Mar 12 21:25:00 2010 +0000
summary:     Added footer.

Remarquez comme l’auteur et la date de la révision ont changé car le serveur Subversion a mis à jour les métadonnées. Comme les révisions sont réécrites, vous ne devriez pas faire d’autres clones de votre dépôt Mercurial. Si vous le faites, vous devrez manuellement supprimer les vieilles révisions qui sont poussées vers Subversion.

Tirer de Subversion

Alice effectue localement quelques modifications supplémentaires dans son clone Mercurial :

alice$ hg outgoing 
comparing with http://mercurial.aragost.com/svn/helloX
changeset:   10:9a6e43d86b16
user:        Alice <alice@example.net>
date:        Fri Mar 12 21:26:00 2010 +0000
summary:     Express greater joy!

changeset:   11:f3bd093438f1
tag:         tip
user:        Alice <alice@example.net>
date:        Fri Mar 12 21:27:00 2010 +0000
summary:     Added simple MIT license header.

Pendant ce temps, le dépôt Subversion a aussi été modifié :

alice$ hg incoming 
incoming changes from http://mercurial.aragost.com/svn/helloX

revision:    12
user:        alice
date:        2010-03-12T21:26:30.0Z
message:     List email address for bug reports.
alice$ hg pull 
pulling from http://mercurial.aragost.com/svn/helloX
[r12] alice: List email address for bug reports.
pulled 1 revisions
(run 'hg update' to get a working copy)

La nouvelle version génère une branche dans l’historique :

pull.png

Quand Alice pousse, ses deux nouvelles révisions (7d780c6154fb et 12445668eefc) vont être automatiquement rebasées au-dessus de la révision qu’elle vient juste de tirer de Subversion (2099057558d2) :

alice$ hg push 
pushing to http://mercurial.aragost.com/svn/helloX
searching for changes
[r13] alice: Express greater joy!
pulled 1 revisions
saved backup bundle to $HOME/hello-hg/.hg/strip-backup/xxxxxxxxxxxx-backup.hg
[r14] alice: Added simple MIT license header.
pulled 1 revisions
saved backup bundle to $HOME/hello-hg/.hg/strip-backup/xxxxxxxxxxxx-backup.hg

À nouveau, cela est nécessaire car Subversion est un système strictement linéaire. Le nouvel historique ressemblera à :

pushed.png

Conclusion

L’extension hgsubversion vous permet d’utiliser Mercurial comme un client Subversion. Cela vous donne immédiatement les avantages suivants par rapport à un client Subversion normal :

Les personnes travaillent différemment avec leurs outils quand ils deviennent suffisamment rapides. Mercurial a été conçu pour rendre les accès locaux rapides.

Subversion oblige les personnes à publier immédiatement ces révisions. Les personnes vont donc avoir tendance à ne pas faire de révisions, surtout dans la branche principale, par peur de casser la compilation. Si les personnes travaillent sur une branche, toutes ces révisions vont polluer l’historique et rendre son analyse ultérieure plus difficile.

Mercurial laisse les personnes effectuer autant de révisions que nécessaire. Les changements peuvent être ensuite regroupés en des révisions plus significatives qui seront plus claires à relire et qui permettront d’éviter beaucoup de faux départs. Ces révisions regroupées peuvent ensuite être poussées vers le serveur Subversion.
Néanmoins il est possible de travailler d’une manière distribuée sur une nouvelle fonctionnalité. Cela nécessite seulement que les collaborateurs attendent la fin du développement de la fonctionnalité avant de la pousser vers Subversion. De cette façon vous pouvez faire autant de clones que vous voulez et pousser/tirer entre eux. Quand la fonctionnalité est terminée, vous l’intégrez à Subversion et demandez au reste de l’équipe d’abandonner leurs clones locaux et de tirer les révisions rebasées à partir du serveur Subversion.

L’extension hgsubversion peut aussi être utilisée pour effectuer une conversion vers Mercurial. Mercurial possède une extension dédiée pour la conversion, mais hgsubversion est connu pour mieux convertir certains dépôts et de manière plus fidèle.

Le problème principal de la conversion depuis Subversion (ou tout autre ancien système) vers Mercurial est le manque de rigueur des anciens systèmes. Subversion n’a ni étiquette ni branche, il a seulement une (très) forte convention qui implique qu’une copie de trunk/ vers branches/foo indique la création d’une branche nommée “foo”. Rien n’empêche quelqu’un de copier la moitié de trunk/ vers branches/foo ou de faire une révision qui modifie simultanément trunk/ et branches/foo.

Ce genre de “trucs” ne peut pas toujours être représenté d’une manière utile dans Mercurial, mais hgsubversion permet quand même une bonne interprétation de l’intention du développeur.