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 :
HTTP : le protocole utilisé par les serveurs web standards
Mercurial possède en interne un petit serveur web que vous pouvez démarrer avec la commande hg serve et qui vous permet de parcourir l’historique de votre dépôt avec un navigateur standard. Pour une utilisation plus intensive, il est recommandé d’utiliser le script hgweb.cgi.
SSH : le protocole Secure Shell est un protocole utilisé sur beaucoup de systèmes Unix.
Si vous avez déjà une connexion SSH sur un serveur avec Mercurial installé, alors l’utilisation de SSH est la manière la plus simple de cloner un dépôt. Il est possible de configurer un compte avec un accès shell restreint de manière à ce que les utilisateurs ne puissent exécuter que des commandes Mercurial et n’aient ainsi pas accès à un shell complet. Consultez le script hg-ssh pour les détails.
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.
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à.
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 .
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.
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.
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.
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.
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.
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>
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.
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/
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.
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.
Allez à https://bitbucket.org/ et créez-vous un compte personnel.
Créez un dépôt privé appelé test et clonez-le sur votre machine locale.
Ajoutez un fichier, créez une révision et poussez-la dans Bitbucket.
Faites un clone de https://bitbucket.org/aragost/hello/ sur votre machine locale.
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 ?