aragost Trifork: Mercurial Kick Start Exercises


Dépôts distants

Ce guide va vous montrer comment Mercurial peut être utilisé pour dialoguer avec des dépôts distants grâce aux protocoles HTTP et SSH.

Sommaire

Dans les premiers pas avec Mercurial , vous avez vu comment Alice et Bob pouvaient pousser et tirer entre leurs dépôts qui se trouvaient dans le même système de fichier. C’est une très bonne configuration quand Alice et Bob partagent le même système de fichier, mais la plupart des utilisateurs n’ont pas d’accès direct aux fichiers des autres utilisateurs. C’est pour cette raison que Mercurial peut utiliser une connexion réseau pour accéder à des dépôts distants.

Mercurial comprend deux protocoles :

Travailler avec des dépôts sur HTTP

Nous allons commencer par regarder comment nous pouvons interagir avec un dépôt sur HTTP. Ce protocole est très populaire car il s’intègre facilement dans l’infrastructure réseau des entreprises : quand vous avez un serveur web opérationnel qui peut être accédé sur le port 80, alors vous avez tout ce qu’il vous faut pour servir aussi des dépôts Mercurial.

Cloner sur HTTP

Nous allons commencer par laisser Alice cloner un petit dépôt d’exemple :

alice$ hg clone https://bitbucket.org/aragost/hello
destination directory: hello
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

Comme vous pouvez le voir ce n’est pas très différent de cloner sur HTTP que de cloner avec le chemin d’un système de fichier : dans les deux cas Alice finit par avoir une copie complète du dépôt et la branche default est sélectionnée.

Sous le capot, Mercurial est capable de faire des clones locaux beaucoup plus efficacement que des clones sur HTTP. Ce n’est pas seulement dû au fait que la lecture à travers un réseau est plus lente que la lecture sur un disque, mais aussi parce qu’un clone local va réutiliser l’espace disque du répertoire .hg en utilisant des hardlinks (liens en dur) entre les fichiers. Les deux clones vont donc partager l’espace disque utilisé par les deux répertoires .hg et c’est seulement les deux copies de travail qui prennent de l’espace disque supplémentaire. C’est la raison pour laquelle vous pouvez faire autant de clones locaux jetables que vous voulez.

Alice peut maintenant faire ses propres révisions dans son clone :

alice$ cd hello
alice$ echo "Hello, World!" > hello.txt
alice$ hg commit -m "Add comma" 

C’est l’essence même de la gestion de sources distribuées — Alice peut avoir son propre dépôt indépendant et travailler avec lui localement. Elle peut aussi comparer son clone avec celui du serveur distant :

alice$ hg outgoing
comparing with https://bitbucket.org/aragost/hello
searching for changes
changeset:   1:61c1daa1d929
tag:         tip
user:        Alice <alice@example.net>
date:        Sat Jan 22 10:00:00 2011 +0000
summary:     Add comma

Elle ne pourra pas pousser sa révision vers le serveur car elle ne possède pas les droits d’écriture vers ce dépôt-là.

Servir un dépôt sur HTTP

Comme indiqué précédemment, Mercurial possède un serveur web intégré. Vous pouvez l’utiliser pour partager rapidement un dépôt avec un autre ordinateur de votre réseau local ou même pour parcourir vous-même l’historique.

Alice va maintenant partager son clone du dépôt hello :

alice$ hg serve 
listening at http://localhost:8000/ (bound to 127.0.0.1:8000)

Le dépôt peut maintenant être parcouru avec un navigateur standard à l’adresse http://localhost:8000/. À cette adresse vous pouvez voir l’historique du projet, le graphe des révisions, le détail de chaque révision, la liste des étiquettes et des branches, l’annotation des fichiers et vous pouvez récupérer chaque révision dans un fichier tarball ou zip. En un mot, le serveur web est très pratique pour les humains et pour les ordinateurs :-)

Bob peut faire un clone du dépôt d’Alice :

bob$ hg clone http://localhost:$HGPORT hello
requesting all changes
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
bob$ cd hello
bob$ cat hello.txt
Hello, World!

Si Bob crée une révision et essaye de la pousser vers le dépôt d’Alice, il rencontrera l’erreur suivante :

bob$ hg push
pushing to http://localhost:8000/
searching for changes
remote: ssl required
remote: ssl required
updating 61c1daa1d929 to public failed!

L’explication est que le serveur web de Mercurial ne vous laisse pas, par défaut, pousser sur HTTP normal, il est nécessaire d’utiliser le protocole HTTPS. Alice peut désactiver cette contrainte en utilisant l’option --config web.push_ssl=No sur la ligne de commande qui sert à démarrer le serveur web. Elle va donc tuer l’ancien processus hg serve et en démarrer un nouveau :

alice$ hg serve --config web.push_ssl=No 
listening at http://localhost:8000/ (bound to 127.0.0.1:8000)

Quand Bob essaye à nouveau, il rencontre une nouvelle erreur car les dépôts sont en lecture seule par défaut :

bob$ hg push
pushing to http://localhost:8000/
searching for changes
abort: authorization failed

Remarquez que la poussée a été interrompue sans laisser à Bob la chance de pouvoir saisir un nom et un mot de passe. La raison est que le serveur web intégré ne gère pas d’authentification. C’est-à-dire qu’il n’y a pas de gestion des utilisateurs intégrée. Cela peut sembler étrange, mais l’idée est que vous ne devriez pas utiliser hg serve dans un environnement de production. À la place vous devez utiliser le script hgweb.cgi fourni avec Mercurial et ce script devra être utilisé avec un vrai serveur web tel qu’Apache. Ce serveur web aura toute l’infrastructure nécessaire pour faire une authentification d’utilisateur. Un avantage de cette configuration est que vous pouvez utiliser le système d’authentification que vous préférez : si votre configuration utilise une authentification des utilisateurs avec un annuaire LDAP, vous pouvez juste la réutiliser avec Mercurial.

Pour notre exemple, nous allons désactiver l’authentification avec une autre option de la ligne de commande :

alice$ hg serve --config web.push_ssl=No --config "web.allow_push=*" 
listening at http://localhost:8000/ (bound to 127.0.0.1:8000)

Bob peut maintenant pousser sa révision vers le dépôt d’Alice :

bob$ hg push
pushing to http://localhost:8000/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files

Ici il n’y a pas d’authentification, mais dans la plupart des dépôt du monde réel vous devrez vous authentifiez pour vous permettre de pousser des révisions (et dans certains cas aussi pour tirer des révisions). Nous parlerons de la mise en cache des informations d’authentification HTTP(S) plus bas .

Permissions des fichiers

Quand vous accédez à un dépôt avec le script hgweb.cgi, l’accès est réellement fait par le serveur web. Le serveur web s’exécute avec les droits d’un utilisateur et c’est donc cet utilisateur qui doit avoir les droits d’accès en lecture sur les fichiers du dépôt pour qu’il puisse vous les servir.

Quand les personnes poussent des révisions vers le serveur avec HTTP, c’est aussi le serveur web qui va écrire les changements dans le répertoire .hg. Les noms d’utilisateurs inclus dans les révisions ne jouent ici aucun rôle.

Travailler avec des dépôts sur SSH

L’autre protocole réseau supporté par Mercurial est SSH. Quand vous utilisez des URL SSH, Mercurial va se connecter au serveur et mettre en place un tunnel SSH entre les deux processus Mercurial. Les deux processus vont ensuite communiquer ensemble pour pousser et tirer les révisions.

Cela implique qu’il doit y avoir un compte SSH sur le serveur. Beaucoup d’administrateurs systèmes vont donc préférer utiliser le protocole HTTP car cela utilise leur serveur web existant.

Néanmoins, si vous avez un compte sur le serveur et si Mercurial est installé sur le système, alors l’utilisation du protocole SSH est très transparente pour un utilisateur. La seule chose à se souvenir est qu’il ‘agit d’une syntaxe d’URL et non d’une syntaxe de chemin SSH scp ou rsync. Donc vous devez écrire :

$ hg clone ssh://serveur/chemin/vers/dépôt

et non :

$ hg clone serveur:chemin/vers/dépôt

Remarquez aussi que chemin/vers/dépôt est un chemin relatif par rapport à votre répertoire personnel sur le serveur. Si vous voulez utiliser un chemin absolu sur le serveur, alors vous devez utiliser une URL comme cela :

$ hg clone ssh://serveur//chemin/absolu/vers/dépôt

La première barre oblique fait partie de la syntaxe de l’URL, et la seconde fait partie du chemin sur le serveur pour que l’URL précédente puisse trouver le chemin /chemin/absolu/vers/dépôt sur le serveur.

Contrairement aux URL HTTP, vous pouvez utiliser une URL SSH comme destination pour la commande hg clone. Cela vous permet d’écrire :

$ hg clone . ssh://serveur/chemin/vers/dépôt

pour cloner le dépôt actuel vers le serveur.

Permissions des fichiers

Comme Mercurial effectue une connexion sur le serveur, c’est l’utilisateur du serveur qui doit avoir les droits en lecture sur le dépôt pour que vous puissiez faire un clone ou tirer des révisions. De même, c’est l’utilisateur du serveur qui doit avoir les droits en écriture sur le dépôt pour que vous puissiez pousser des révisions.

Si vous voyez des erreurs lorsque vous poussez des révisions en SSH, alors ajoutez l’option --debug à votre commande et découvrez ainsi ce que Mercurial fait. Essayez aussi de vous connecter en SSH avec le même utilisateur et vérifiez que vous avez accès aux fichiers.

Mise en cache des informations d’authentification HTTP(S)

Quand vous dialoguez avec un serveur web, il peut demander à Mercurial un nom d’utilisateur et un mot de passe pour vous authentifier. On vous demandera alors de saisir l’information dans le prompt :

$ hg clone https://bitbucket.org/aragost/private
http authorization required
realm: Bitbucket.org HTTP
user: aragost
password: <secret>
abort: http authorization required

Comme vous devrez vous authentifier pour chaque commande qui implique le dépôt distant (les commandes telles que hg clone, hg pull, hg push, hg incoming, et hg outgoing), vous serez rapidement fatigué de le faire. Il y a plusieurs manières d’indiquer à Mercurial de sauvegarder ces informations. Nous allons vous les présenter par ordre de préférence.

Vous vous demandez peut-être comment Mercurial peut enregistrer votre phrase secrète SSH. La réponse est que vous ne pouvez pas le faire — l’authentification SSH est indépendante de Mercurial et vous devez utiliser un agent SSH standard pour enregistrer en cache votre phrase secrète.

Un agent SSH est un programme qui s’exécute en tâche de fond et conserve en mémoire une version déchiffrée de votre clef SSH privée. Quand vous effectuez une connexion SSH, le programme ssh va demander à l’agent s’il a une clef privée déchiffrée appropriée. Si c’est le cas, la connexion peut se faire sans que vous ayez besoin de saisir un mot de passe, sinon ssh vous demandera un mot de passe comme d’habitude.

Avec Linux et Mac OS X, vous pouvez ajouter votre clef à l’agent SSH avec la commande ssh-add. Avec Windows vous utiliserez Pageant avec putty.

Extension keyring

In short:

Pros: passwords are stored in a OS-specific secure backend, most secure option.

Cons: requires third-party extension.

L’extension keyring va s’accrocher à Mercurial et intercepter les demandes de mot de passe. Les mots de passe que vous saisissez sont enregistrés dans une base de données sécurisée spécifique à votre système d’exploitation, et vous n’aurez ainsi plus à les saisir. Elle enregistre les mots de passe utilisés pour les authentifications HTTP(S) et SMTP (comme le fait l’extension patchbomb parmi d’autres).

C’est la solution standard pour Windows quand vous utilisez TortoiseHg car ce dernier est livré avec l’extension et la librairie additionnelle nécessaire pour utiliser le système de mots de passe de WIndows.

Utilisation du fichier de configuration utilisateur

In short:

Pros: standard feature in Mercurial. Makes it easy to setup the password used for all repositories on a given host.

Cons: passwords are stored in a plaintext configuration file. Care must be used if the file is shared with others.

Vous enregistrez directement les informations d’authentification dans votre fichier de configuration Mercurial. Il faut utiliser la section auth :

[auth]
bb.prefix = https://bitbucket.org/
bb.username = alice
bb.password = <secret>

La section [auth] contient un certain nombre d’entrées qui sont regroupées avec une clef arbitraire que vous choisissez. Ci-dessus, nous avons utilisé bb comme clef pour Bitbucket, mais nous aurions pu en choisir une autre. Si vous voulez enregistrer des mots de passe pour d’autres sites, vous devrez utiliser une clef différente pour chacun :

[auth]
site-a.prefix = https://hg.site-a.net/
site-a.username = userA
site-a.password = <secret-a>

site-b.prefix = https://site-b.org/repos/
site-b.username = userB
site-b.password = <secret-b>

Inclus dans l’URL pour pousser et tirer

In short:

Pros: requires no out-side configuration.

Cons: password is stored in plaintext.

La dernière méthode utilise une caractéristique des spécifications des URL : elle peut contenir un nom d’utilisateur et un mot de passe. La syntaxe de l’URL est :

scheme://nom:mot_de_passe@domaine:port/chemin

Donc si vous exécutez :

hg clone https://alice:<secret>@bitbucket.org/aragost/private

alors Mercurial va automatiquement utiliser alice comme nom d’utilisateur et <secret> comme mot de passe pour se connecter à Bitbucket. Si le clone réussit alors, comme d’habitude, l’URL complète est enregistrée comme chemin par défaut dans le fichier .hg/hgrc. Comme le nom et le mot de passe sont enregistrés dans l’URL les authentifications nécessaires aux appels suivants de hg pull et hg push seront automatiques : aucune saisie ne sera nécessaire.

Configuration de raccourcis d’URL

Lorsque vous travaillez avec beaucoup de dépôts sur la même machine, alors il peut être énervant à la longue de taper toujours :

hg clone https://hg.my-long-servername.com/repos/

Raccourcissement d’URL HTTP

Mercurial a une extension standard pour vous aider à raccourcir ces URL. Vous activez l’extension schemes et vous pouvez alors ajouter ce qui suit à votre fichier de configuration :

[schemes]
bb = https://bitbucket.org/

Cela vous permet d’écrire :

hg clone bb://aragost/private

à la place de :

hg clone https://bitbucket.org/aragost/private

Après avoir activer l’extension vous pouvez consulter l’aide (hg help schemes) pour avoir la syntaxe complète.

Raccourcissement d’URL SSH

Vous pouvez aussi utiliser l’extension schemes pour les URL SSH, mais notez que OpenSSH a sa propre méthode pour raccourcir les URL SSH. Ajoutez ces lignes à votre fichier ~/.ssh/config (le créer si nécessaire) :

Host bb
Compression yes
HostName bitbucket.org
User hg

Cela vous permettra d’écrire :

hg clone ssh://bb/aragost/private

à la place de :

hg clone ssh://hg@bitbucket.org/aragost/private

Remarquez que cette configuration vous permet aussi de préciser le nom d’utilisateur qu’il est facile d’oublier lorsque l’on utilise Bitbucket avec SSH. Nous avons aussi activé la compression pour le tunnel SSH, ce qui permet d’améliorer les performances globales.

Vous pouvez faire la même chose avec Putty sous Windows (TortoiseHg en installe automatiquement une version) en configurant et enregistrant une connexion. Si vous enregistrez la configuration sous le nom bb, alors vous pouvez commencer à utiliser des URL du style ssh://bb/ dans Mercurial.

Exercices

  1. Allez à https://bitbucket.org/ et créez-vous un compte personnel.

  2. Créez un dépôt privé appelé test et clonez-le sur votre machine locale.

  3. Ajoutez un fichier, créez une révision et poussez-la dans Bitbucket.

  4. Faites un clone de https://bitbucket.org/aragost/hello/ sur votre machine locale.

  5. Créez un nouveau dépôt dans Bitbucket appelé hello et poussez le clone hello de votre machine locale vers Bitbucket.

    Remarquez comme vous pouvez pousser des révisions dans un dépôt vide. Cela est dû au fait que vous pouvez décomposer un hg clone en hg init suivi par un hg pull (mais vous n’aurez pas les hardlinks comme décrit au-dessus).

    Que se passe-t-il si vous essayez de pousser de votre clone hello vers votre clone test sur Bitbucket ? Comment Mercurial sait-il que les dépôts sont liés ?