Chapter 6. Collaborer avec d'autres personnes

Table of Contents

6.1. Interface web de Mercurial
6.2. Modèles de collaboration
6.2.1. Facteurs à garder en tête
6.2.2. Anarchie informelle
6.2.3. Un simple dépôt central
6.2.4. Un dépôt central hébergé
6.2.5. Travailler avec plusieurs branches
6.2.6. Feature branches
6.2.7. Le train des releases
6.2.8. Le modèle du noyau Linux
6.2.9. Collaboration pull seulement versus pull partagé
6.2.10. Lorsque la collaboration rencontre la gestion de branches
6.3. Le côté technique du partage
6.4. Partage informel avec hg serve
6.4.1. Quelques choses à garder à l'esprit
6.5. Utiliser le protocole Secure Shell (ssh)
6.5.1. Comment lire et écrire des URLs ssh
6.5.2. Trouver un client ssh pour votre système
6.5.3. Créer une paire de clef
6.5.4. Utiliser un agent d'authentification
6.5.5. Configurer correctement le serveur
6.5.6. Utilisation de la compression avec ssh
6.6. Service sur HTTP grâce à CGI
6.6.1. Liste de contrôle de la configuration du serveur web
6.6.2. Configuration élémentaire de CGI
6.6.3. Partager plusieurs dépôts avec un seul script CGI
6.6.4. Télécharger des archives de sources
6.6.5. Options de configuration web
6.7. Configuration "system-wide"
6.7.1. Rendre Mercurial moins méfiant

Comme tout outil complètement décentralisé, Mercurial n'impose pas de politique sur la façon dont les personnes devraient travailler ensemble. Cependant, si vous êtes nouveau dans les systèmes de gestion de révisions distribués, cela aide d'avoir des outils et exemples en tête lorsque vous réfléchissez à de possibles modèles de workflow.

6.1. Interface web de Mercurial

Mercurial possède une interface web puissante qui propose plusieurs fonctions utiles.

Pour une utilisation intensive, l'interface web vous permet de naviguer dans un ou une collection de dépôt. Vous pouvez voir l'historique d'un dépôt, examiner chaque modification (commentaires et "diffs"), et voir le contenu de chaque répertoire et fichier. Vous pouvez même accéder à une vue de l'historique qui vous donne une vue graphique de la relation entre les modifications individuelles et les fusions (merge).

De plus, pour l'utilisation humaine, l'interface web fournit des flux Atom et RSS des changements dans un dépôt. Ceci vous permet de souscrire à un dépôt en utilisant votre lecteur de flux favori, et être automatiquement avertis de l'activité dans ce dépôt aussi tôt qu'elle change. Je trouve cette fonctionnalité bien plus commode que le modèle qui consiste à souscrire à une mailing list à laquelle les avertissements sont envoyés, puisque cela demande aucune configuration supplémentaire de la part de la personne qui publie un dépôt.

L'interface web permet aussi aux utilisateurs distants de cloner un dépôt, récupérer (pull) les changement à partir de celui ci, et (lorsque le serveur est configuré pour l'autoriser) lui envoyer (push) des changements. Le protocole de tunnel HTTP de Mercurial compresse agressivement les données, ainsi, il fonctionne efficacement, même au-dessus des réseaux avec une faible bande passante.

La plus simple façon de démarrer avec l'interface utilisateur est d'utiliser votre navigateur web pour visiter un dépôt existant, tel que le dépôt principal de Mercurial à l'adresse http://www.selenic.com/repo/hg.

Si vous êtes intéressés pour proposer une interface web de vos propres dépôts, il y a plusieurs façons de le faire.

La façon la plus simple et la plus rapide pour commencer dans un environnement informel est d'utiliser la commande hg serve qui est la plus adaptée à un service à court terme et léger. Référez-vous à Section 6.4, “Partage informel avec hg serve plus bas pour les détails d'utilisation de cette commande.

Pour des dépôts dont la durée de vie est plus longue, où vous voudriez un service accessible en permanence, il existe plusieurs services publics d'hébergement qui sont accessibles. Certains sont libres et gratuits pour les projets Open Source, alors que d'autres offrent un hébergement commercial et payant. Une liste à jour est disponible à l'adresse : http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting.

Si vous préférez héberger vos propres dépôts, Mercurial possède un support intégré pour plusieurs technologies populaires d'hébergement, plus particulièrement CGI (Common Gateway Interface) et WSGI (Web Services Gateway Interface). Référez-vous à Section 6.6, “Service sur HTTP grâce à CGI” pour des détails sur la configuration CGI et WSGI.

6.2. Modèles de collaboration

Avec un outil convenablement flexible, prendre des décisions sur les workflows est plus un problème d'ingénierie sociale qu'un problème technique. Mercurial impose peu de limitations sur la façon dont vous pouvez structurer le flux de travail dans un projet, donc, c'est à vous et votre groupe de fixer et vivre avec un modèle qui convient à vos besoins particuliers.

6.2.1. Facteurs à garder en tête

L'aspect le plus important de tout modèle que vous devez garder en tête est la façon dont il subvient aux besoins et capacités des personnes qui l'utiliseront. Ceci pourrait sembler évident en soi ; pourtant, vous ne pouvez pas vous permettre de l'oublier à un seul moment.

Une fois, j'ai mis en place un modèle de workflow qui m'apparaissait comme parfait, mais il a causé la consternation et des conflits au sein de mon équipe de développement. En dépit de mes tentatives pour expliquer pourquoi nous avions besoin d'un ensemble complexe de branches, et comment les changements devaient couler entre eux, certains membres de l'équipe se révoltèrent. Alors qu'ils étaient pourtant des personnes sympathiques, ils ne voulaient pas prêter attention aux contraintes sur lesquelles nous étions en train d'opérer, ou, face aux conséquences de ces contraintes dans les détails du modèle que je préconisais.

Ne balayez pas les problèmes sociaux ou techniques de la main. Quelque soit le schéma que vous établirez, vous devriez planifier un protocole pour prévenir, ou rapidement vous relever de troubles que vous pouvez anticiper. Par exemple, si vous vous attendez à avoir une branche pour les changements pas-pour-release, vous devriez penser très tôt à la possibilité qu'une personne fusionne (merge) accidentellement ces changements avec une branche de release. Vous pouvez empécher ce problème particulier en écrivant un hook qui prévient les changements d'être fusionnés à partir d'une branche inopportune.

6.2.2. Anarchie informelle

Je ne voudrais pas suggérer qu'une approche tout peut arriver comme quelque chose de durable, mais il s'agit d'un modèle qui est simple à saisir et qui fonctionne parfaitement dans quelques situations inhabituelles.

Par exemple, beaucoup de projets ont un groupe distant de collaborateurs qui ne se rencontre physiquement que très rarement. Certains groupes aiment vaincre l'isolation du travail à distance en organisant occasionnellement des sprints. Dans un sprint, des personnes viennent ensemble dans un même endroit (la salle de conférence d'une société, la salle de réunion d'un hôtel, ce genre d'endroit) et y passent plusieurs jours, plus ou moins enfermés, et hackant intensément sur une poignée de projets.

Un "sprint" ou une session de "hacking" dans un café sont les endroits parfaits pour utiliser la commande hg serve puisque hg serve n'a pas besoin d'une infrastructure extraordinaire de serveurs. Vous pouvez commencer avec la commande hg serve en quelques instants, en lisant Section 6.4, “Partage informel avec hg serve plus bas Ensuite, dites simplement à la personne à côté de vous que vous exécutez un serveur, envoyez-lui l'URL par un message instantané, et vous avez immédiatement un moyen simple et rapide de travailler ensemble. Ils peuvent taper votre URL dans leur navigateur web et rapidement revoir vos changements ; ou ils peuvent récupérer chez vous un bugfix et le vérifier ; ou ils peuvent cloner une branche contenant une nouvelle fonctionnalité et la tester.

Le charme et le problème en faisant les choses ainsi, dans un mode ad-hoc est que seules les personnes qui sont au courant de vos changements, et de leur emplacement, peuvent les voir. Une telle approche informelle ne passe simplement pas à l'échelle au delà d'une poignée de personnes, puisque chacun a besoin de connaître n différents dépôts à partir des quels récupérer les changements (pull).

6.2.3. Un simple dépôt central

Pour de plus petits projets qui migrent depuis un outil de gestion de révision centralisé, la façon la plus simple de commencer est certainement d'avoir un flux de changement à partir d'un unique dépôt central. Il s'agit aussi du composant pour des schémas de workflow plus ambitieux.

Les contributeurs commencent par cloner une copie de ce dépôt. Ils peuvent récupérer les changements à n'importe quel moment où ils en ressentent le besoin, et certains (sûrement tous) développeurs ont les persmissions qui leur permettent d'envoyer leurs modifications (push) en retour lorsqu'elles sont prêtes pour que les autres personnes puissent les voir.

Dans ce modèle, il peut encore être sensé pour les gens de récupérer les changements directement entre eux, sans passer par le dépôt central. Considérez le cas où j'ai un bug fix provisoire, mais je m'inquiète de savoir si, dans le cas où je le publiais, cela ne casserait pas l'arbre des autres contributeurs s'ils la récupèreraient. Pour réduire les dommages potentiels, je peux vous demander de cloner mon dépôt dans un dépôt temporaire qui vous appartient et de le tester. Ceci nous permet de ne pas publier les modification potentiellement dangereuses tant qu'elles n'ont pas encore été un peu testées.

Si une équipe héberge son propre dépôt dans ce type de scénario, les personnes qui utilisent habituellement le protocole ssh pour envoyer (push) en toute sécurité leurs changements au dépôt central, comme docummenté dans Section 6.5, “Utiliser le protocole Secure Shell (ssh)”. Il est aussi usuel de publier une copie en lecture seule du dépôt sur HTTP comme dans Section 6.6, “Service sur HTTP grâce à CGI”. Publier sur HTTP satisfait le besoin des personnes qui n'ont pas d'accès en écriture, et ceux qui veulent utiliser leur navigateur web pour explorer l'historique du dépôt.

6.2.4. Un dépôt central hébergé

Une chose magnifique au sujet des services d'hébergement comme Bitbucket est qu'ils ne gèrent pas uniquement les détails minutieux de la configuration du serveur, tels que les comptes utilisateurs, l'authentification, les protocoles sécurisés, ils fournissent aussi une infrastructure additionnelle pour que ce modèle fonctionne bien.

Par exemple, un service d'hébergement bien conçu laissera les personnes cloner leurs copies d'un dépôt à l'aide d'un simple clic. Ceci laisse les personnes travailler dans des espaces séparés et partager leurs changements lorsqu'ils sont prêts.

De plus, un bon service d'hébergement laissera les personnes communiquer ensemble, par exemple pour dire Il y a des changements prêts pour toi pour relecture dans cet arbre.

6.2.5. Travailler avec plusieurs branches

Les projets d'une taille significative ont tendance à avancer sur plusieurs fronts en même temps. Dans le cas de logiciel, il est commun qu'un projet sorte périodiquement des releases officielles. Une release devrait ensuite aller dans le mode de maintenance pour un moment après sa première publication ; les releases de maintenance tendent à contenir seulement des corrections de bugs, et non de nouvelles fonctionnalités. En parallèle de ces releases de maintenance, une ou plusieurs futures releases doivent être en cours de développement. Les gens utilisent en général le mot branche pour référer à l'une de ces nombreuses directions légèrement différentes dans lesquelles le développement évolue.

Mercurial est particulièrement bien adapté pour gérer plusieurs branches simultanées mais non identiques. Chaque direction de développement peut vivre dans son propre dépôt central, et vous pouvez récupérez les changements de l'un ou l'autre lorsque le besoin s'en fait sentir. Parce que les dépôts sont indépendant les uns des autres, les modifications instables dans une branche de développement n'affecteront jamais une branche stable, sauf si quelqu'un fusionne (merge) explicitement ces changements dans la branche stable.

Voici un exemple sur comment cela peut se passer en pratique. Disons que vous avez une branche principale sur un serveur central.

$ hg init main
$ cd main
$ echo 'This is a boring feature.' > myfile
$ hg commit -A -m 'We have reached an important milestone!'
adding myfile

Les contributeurs le clonent, y apportent localement des modifications, les testent et envoient (push) en retour leurs changements.

Une fois que la branche principale atteint une étape assez importante pour une release, vous pouvez utiliser la commande hg tag pour donner un nom permanent à cette étape de révision.

$ hg tag v1.0
$ hg tip
changeset:   1:33e75fb73c66
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Thu Mar 17 05:08:41 2011 +0000
summary:     Added tag v1.0 for changeset 73e86f09043d

$ hg tags
tip                                1:33e75fb73c66
v1.0                               0:73e86f09043d

Disons que du developpement continue sur la branche principale.

$ cd ../main
$ echo 'This is exciting and new!' >> myfile
$ hg commit -m 'Add a new feature'
$ cat myfile
This is a boring feature.
This is exciting and new!

En utilisant le tag enregistré à l'étape importante, les gens qui clonent ce dépôt peuvent à tout moment dans le futur utiliser la commande hg update pour avoir une copie du répertoire de travail exactement comme il était lorsque cette révision "tag" a été committée.

$ cd ..
$ hg clone -U main main-old
$ cd main-old
$ hg update v1.0
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cat myfile
This is a boring feature.

De plus, immédiatement après que la branche principale soit taggée, nous pouvons maintenant cloner la branche principale sur le serveur vers une nouvelle branche stable sur le même serveur.

$ cd ..
$ hg clone -rv1.0 main stable
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

Si nous avons besoin d'effectuer des modifications à la branche stable, nous pouvons alors cloner ce dépôt, effectuer nos modifications, committer, et envoyer nos changements en retour là bas.

$ hg clone stable stable-fix
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd stable-fix
$ echo 'This is a fix to a boring feature.' > myfile
$ hg commit -m 'Fix a bug'
$ hg push
pushing to /tmp/branchingeS3nOt/stable
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

Puisque les dépôts Mercurial sont indépendants, et que Mercurial ne déplace pas les changements automatiquement, les branches stable et principale sont isolées l'une de l'autre. Les changements qui sont faits à la branche principale ne fuient pas vers la branche stable, et vice versa.

Nous allons souvent avoir envie que toutes nos correction de bugs sur la branche stable soient reportées sur la branche principale. Plutôt que de réécrire une correction de bug pour la branche principale, nous pouvons simplement récupérer (pull) et fusionner (merge) les changements de la branche stable vers la branche principal, et Mercurial se débrouillera pour rapporter ces corrections de bugs pour nous.

$ cd ../main
$ hg pull ../stable
pulling from ../stable
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)
$ hg merge
merging myfile
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m 'Bring in bugfix from stable branch'
$ cat myfile
This is a fix to a boring feature.
This is exciting and new!

La branche principale contiendra toujours des changements qui ne sont pas dans la branche stable, mais elle contiendra aussi les corrections de bugs de la branche stable. La branche stable restera non affectée par ces changements, tant qu'ils coulent de la branche stable vers la branche principale, et non dans l'autre sens.

6.2.6. Feature branches

Pour de plus gros projets, une façon efficace de gérer les changements est de diviser l'équipe en plus petits groupes. Chaque groupe a une branche partagée qui lui est attitrée, clonée à partir d'une unique branche principale utilisée pour le projet entier. Les personnes travaillant sur une branche individuelle sont typiquement isolées des développements sur les autres branches.

Figure 6.1. Feature branches

XXX add text

Lorsqu'une fonctionnalité particulière est réputée pour être dans une forme adaptée, quelqu'un de l'équipe qui s'en occupe récupère les changements (pull) à partir de la branche principale vers la branche de cette fonctionnalité, fusionne (merge) et renvoie (push) le tout vers la branche principale.

6.2.7. Le train des releases

Certains projets sont organisés comme un train élémentaire : une release est planifiée tous les quelques mois, et, toutes les fonctionnalités disponibles lorsque le train est prêt à s'arrêter sont autorisées ici.

Ce modèle ressemble à travailler avec des branches de fonctionnalités. La différence est que lorsqu'une branche de fonctionnalité rate le train, quelqu'un de l'équipe qui travaille sur cette fonctionnalité récupère (pull) et fusionne (merge) ce qui a été ajouté à la release du train dans la branche de la fonctionnalité, puis, l'équipe continue son travail au-dessus de cette release afin que leur fonctionnalité puisse être ajoutée à la prochaine release.

6.2.8. Le modèle du noyau Linux

Le développement du noyau Linux est doté d'une structure hiérarchique superficielle, entourée par un nuage de chaos apparent. Parce que la plupart des développeurs Linux utilisent git, un outil distribué de gestion de révisions avec des capacités similaires à celles de Mercurial, il est utile de décrire comment le travail se déroule dans cet environnement ; si vous aimez ces idées, l'approche se traduit correctement à travers les outils.

Au centre de la communauté siège Linus Torvalds, le créateur de Linux. Il publie un dépôt unique de sources qui est considéré comme faisant autorité sur l'arborescence par la communauté entière de développeurs. Tout le monde peut cloner l'arbre de Linus, mais il ne récupère (pull) pas les changements de n'importe quelle arborescence.

Linus a plusieurs lieutenants de confiance. Comme règle générale, il récupère (pull) tous les changements qu'ils publient, dans la plupart des cas sans même relire ces modifications. Certains de ces lieutenants sont généralement autorisés à être mainteneurs, responsables pour un sous-système spécifique du noyau. Si un hacker du noyau veut apporter des modification au sous-système qu'il veut voir intégré à l'arbre de Linus, il doit trouver le mainteneur du sous-système, et lui demander de récupérer ses changements. Si le mainteneur relit ses changements et les accepte, ils seront transmis à Linus le moment venu.

Les lieutenants individuels ont leur propre approche pour relire, accepter et publier les changements ; et pour décider quand les apporter à Linus. De plus, il y a plusieurs branches connues que les personnes utilisent pour différentes choses. Par exemple, quelques personnes maintiennent des dépôts stables de leurs versions du noyau, pour lesquels ils apportent des corrections critiques lorsque nécessaire. Certains mainteneurs publient plusieurs arbres : l'un pour les changements expérimentaux, l'un pour les changements qu'ils vont faire remonter, etc. D'autres ne publient qu'un unique arbre.

Ce modèle a deux caractéristiques remarquables. La première est qu'il s'agit de pull seulement. Vous devez demander, convaincre, ou mendier auprès d'un autre développeur pour prendre vos modifications, puisqu'il n'y a vraisemblablement pas d'arbre où plus d'une personne peut envoyer des changements (push), et qu'il n'y a pas de possibilité d'envoyer des changements (push) vers un arbre que quelqu'un d'autre contrôle.

La seconde est que c'est basé sur la réputation et l'acclamation. Si vous êtes un inconnu, Linus va probablement ignorer vos changements sans même répondre. Cependant, un mainteneur de sous-système les relira probablement, et les acceptera sûrement s'ils passent ses critères d'acceptation. Plus vous enverrez du bon code à un mainteneur, et plus celui-ci aura confiance en votre jugement et acceptera vos changements. Si vous êtes bien connu et maintenez une branche ancienne pour quelque chose que Linus n'a pas encore accepté, les gens avec un intérêt similaire devraient récupérer vos changements régulièrement pour rester à jour vis-à-vis de votre travail.

La réputation et l'acclamation ne nécessite pas de système croisé ou de limites entre les gens. Si vous êtes respectés mais que vous êtes un hacker spécialisé dans la sauvegarde, et que vous tentez de corriger un bug réseau, ce changement recevra un examen approfondi de la part du mainteneur responsable du réseau comparable à celui d'un total étranger.

Pour les personnes qui viennent d'un projet dont le milieu est plus ordonné, le processus chaotique de développement du noyau Linux en comparaison apparaît souvent totalement dément. C'est sujet aux caprices d'individus ; des personnes font des changements considérables quand ils les jugent appropriés ; et l'allure du développement est ahurissante. Et pourtant, Linux est un bout de logiciel d'une grande réussite et bien considéré.

6.2.9. Collaboration pull seulement versus pull partagé

Une source perpétuelle de heurts dans la communauté opensource est de savoir si un modèle de développement où les personnes ne peuvent que récupérer (pull) les changements d'autres est meilleur que celui dans lequel de multiples personnes peuvent envoyer (push) leurs changements vers un dépôt partagé.

Typiquement, les partisans du modèle push partagé utilisent des outils qui renforcent activement cette approche. Si vous utilisez un outil centralisé de gestion de révision comme Subversion, il n'y a pas la possibilité de choisir quel modèle utiliser : l'outil vous fournit un push partagé, et si vous voulez faire quelque chose d'autre, vous avez à changer votre propre approche à la base (comme appliquer les patchs manuellement).

Un bon outil de gestion distribuée de révisions doit supporter les deux modèles. Vous et vos collaborateurs pouvez ensuite structurer la façon dont vous travaillez ensemble en vous basant sur vos besoins et vos préférences, et non sur les contorsions que vos outils vous forcent à effectuer.

6.2.10. Lorsque la collaboration rencontre la gestion de branches

Lorsque vous et votre équipe configurez des dépôts partagés et commencez à propager vos changement dans tous les sens entre les dépôts locaux et partagés, vous commencez à être face à un défi connexe, mais un peu différent : celui de gérer les multiples directions vers lesquelles votre équipe pourrait aller au même moment. Même si ce sujet est intimement lié à la façon dont votre équipe collabore, il est suffisement dense pour mériter un traitement à part dans Chapter 8, Managing releases and branchy development.

6.3. Le côté technique du partage

Le reste de ce chapitre est consacré à la question du partage des changements avec vos collaborateurs.

6.4. Partage informel avec hg serve

La commande hg serve de Mercurial est magnifiquement conçue pour un environnement de petit groupe, soudé et rapide. Elle fournit aussi un très bon moyen d'avoir un sentiment de l'utilisation des commandes Meruciral sur un réseau.

Exécutez hg serve à l'intérieur d'un dépôt et en moins d'une seconde, cela mettra en place un serveur HTTP spécialisé ; qui va accepter les connexions de tout client, et servir les données pour ce dépôt jusqu'à ce que vous l'arrêtiez. Toute personne qui connaît l'URL du serveur que vous venez de démarrer, peut ensuite utiliser un navigateur web ou Mercurial pour lire les données de ce dépôt. Une URL pour une instance exécutée de hg serve sur un ordinateur portable ressemblera vraisemblablement à http://my-laptop.local:8000/.

La commande hg serve n'est pas un serveur web générique. Il ne peut faire que deux choses :

  • Autoriser les personnes à explorer l'historique du dépôt qu'il rend accessible, à partir d'un navigateur web normal.

  • Discuter à travers le protocole de communication de Mercurial, ainsi, les personnes peuvent exécuter hg clone ou hg pull sur les changements de ce dépôt.

En particulier, hg serve ne permettra pas aux utilisateurs distants de modifier votre dépôt. C'est destiné à une utilisation en lecture seule.

Si vous commencez avec Mercurial, il n'y a rien qui vous empêche d'utiliser hg serve pour publier un dépôt sur votre ordinateur, utilisez ensuite des commandes telles que hg clone, hg incoming, et ainsi de suite pour parler à ce serveur comme si ce dépôt était hébergé à distance. Ceci peut vous aider à rapidement familiarisé avec les commandes sur les dépôts hébergés sur un réseau.

6.4.1. Quelques choses à garder à l'esprit

Puisque il fournit un accès en lecture sans authentification à tous les clients, vous devriez utiliser la commande hg serve dans un environnement où vous ne vous inquiétez pas ou vous avez tout contrôle sur qui peut avoir accès au réseau et récupérer les données de votre dépôt.

La commande hg serve ne sait rien sur un quelconque firewall que vous auriez installé sur votre système ou réseau. Elle ne peut pas détecter ou contrôler votre logiciel de pare-feu. Si d'autre personnes ont la possibilité de dialoguer avec une instance de hg serve la seconde chose que vous devriez faire (après être sûr qu'ils utilisent l'URL correcte) est de vérifier la configuration de votre firewall.

Par défaut, hg serve écoute pour les connexions entrantes sur le port 8000. Si un autre processus est déjà en train d'écouter sur le port que vous voulez écouter, vous pouvez spécifier un port différent sur lequel écouter à l'aide de l'option -p.

Normalement, lorsque hg serve se lance, il n'affiche aucune sortie, ce qui peut être un peu énervant. Si vous voulez une confirmation que tout s'est déroulé correctement, et connaître l'URL que vous devriez fournir à vos collaborateurs, démarrez avec l'option -v.

6.5. Utiliser le protocole Secure Shell (ssh)

Vous pouvez récupérer (pull) ou envoyer (push) des changements de façon sécurisé au dessus d'une connexion utilisant le protocole Secure Shell (ssh). Pour l'utiliser avec succès, vous pourriez avoir à faire un peu de configuration du côté client ou serveur.

Si vous n'êtes pas familiers avec ssh, c'est le nom de la commande et d'un protocole réseau qui vous permet d'établir une communication sécurisée avec un autre ordinateur. Pour l'utiliser avec Mercurial, vous allez configurer un ou plusieurs comptes utilisateurs sur un serveur, comme ça, les utilisateurs distants peuvent se connecter et exécuter les commandes.

(Si vous êtes familiers avec ssh, vous allez probablement trouver quelques-unes des informations qui suivent élémentaires par nature.)

6.5.1. Comment lire et écrire des URLs ssh

Une URL ssh a tendance à ressembler à ceci :

ssh://bos@hg.serpentine.com:22/hg/hgbook
  1. Le préfixe ssh:// dit à Mercurial d'utiliser le protocole ssh.

  2. Le composant bos@ indique que le nom d'utilisateur à connecter sur le serveur. Vous pouvez le laisser vide si le nom d'utilisateur sur le serveur distant est le même que localement.

  3. La partie hg.serpentine.com donne le nom d'hôte du serveur sur lequel se connecter.

  4. Le :22 identifie le numéro de port où se connecter au serveur. Le port par défaut est 22, donc vous avez besoin de spécifier ceci que si vous n'utilisez pas le port 22.

  5. Le reste de l'URL est le chemin local du dépôt sur le serveur.

Il y a beaucoup de risque de confusion sur le chemin du composant d'une URL ssh puisqu'il n'y a pas de façon standard pour les outils de l'interpréter. Certains programmes se comportent différemment des autres lorsqu'ils traitent ces chemins. Il ne s'agit pas d'une situation idéale, mais ce n'est pas prêt de changer. Lisez les prochains paragraphes avec attention.

Mercurial traite le chemin vers un dépôt sur le serveur comme relatif au répertoire personnel de l'utilisateur sur le serveur distant. Par exemple, si un utilisateur foo sur le serveur a un répertoire personnel /home/foo, alors l'URL ssh qui contient un composant chemin de bar réfère en réalité au répertoire /home/foo/bar.

Si vous voulez spécifier un chemin relatif au répertoire personnel d'un autre utilisateur, vous pouvez préciser un chemin qui commence à l'aide du caractère tilde suivi du nom de l'utilisateur (appelons le otheruser), ainsi.

ssh://server/~otheruser/hg/repo

Et si vous voulez vraiment spécifier un chemin absolu sur le serveur, débutez le composant chemin par deux slashs comme dans cet exemple.

ssh://server//absolute/path

6.5.2. Trouver un client ssh pour votre système

La plupart des systèmes du type Unix arrivent avec OpenSSH préinstallé. Si vous utilisez un tel système, utilisez which ssh pour trouver où la commande ssh est installée (il s'agit généralement de /usr/bin). Dans le cas peu probable où il ne serait pas présent, regarder la documentation de votre système pour voir comment l'installer.

Sous Windows, le paquet TortoiseHg est livré avec une version de l'excellente commande plink de Simon Tatham, et ne devrait pas avoir besoin de plus de configuration.

6.5.3. Créer une paire de clef

Pour éviter d'avoir à chaque fois taper un mot de passe lorsque vous utilisez votre client ssh, je recommande de créer une paire de clefs.

[Tip] Les paires de clefs ne sont pas obligatoires

Mercurial ne sait rien du tout de l'authentification de ssh ou de la paire de clefs. Vous pouvez, si vous le désirez, ignorer sans risque cette section et la suivante jusqu'à ce que vous soyez fatigué de constamment retaper des mots de passe ssh.

  • Sur un système de type Unix, la commande ssh-keygen fera l'affaire.

  • Sous Windows, si vous utilisez TortoiseHg, vous devriez avoir besoin de télécharger la commande nommée puttygen à partir du site web de PuTTY pour créer une paire de clefs. Référez-vous à la documentation puttygen pour les détails sur l'utilisation de cette commande.

Lorsque vous créez une paire de clefs, il est habituellement hautement recommandé de la protéger avec un mot de passe. (Le seul moment où vous pourriez ne pas devoir le faire est lorsque vous utilisez le protocole ssh pour des tâches automatisées sur un réseau sécurisé.)

Le simple fait de créer une paire de clefs n'est cependant pas suffisant. Vous aurez besoin d'ajouter la clef publique à l'ensemble des clefs autorisées pour tout utilisateur que vous utilisez pour vous connecter à distance. Pour les serveurs utilisant OpenSSh (la grande majorité), ceci voudra dire d'ajouter la clef publique à la liste dans un fichier appelé authorized_keys dans leur répertoire .ssh.

Sur un système de type Unix, votre clef publique aura l'extension .pub. Si vous utilisez la commande puttygen sous Windows, vous pouvez sauvegarder la clef publique dans un fichier que vous choisissez ou la copier à partir de la fenêtre qui apparait directement dans le fichier authorized_keys.

6.5.4. Utiliser un agent d'authentification

Un agent d'authentification est un démon qui enregistre les mots de passe en mémoire (il oublira ainsi les mots de passe si vous vous déconnectez et reconnectez). Un client ssh sera averti si un tel agent est en fonctionnement, et lui demandera un mot de passe. S'il n'y a pas d'agent en fonctionnement, ou si l'agent ne connaît pas le mot de passe nécessaire, vous aurez à taper votre mot de passe chaque fois que Mercurial tente de communiquer avec un serveur en votre nom (ex. lorsque vous faite un pull ou un push de changements).

L'inconvénient de sauvegarder les mots de passe dans un agent est qu'il est possible pour un attaquant bien préparé de retrouver le mot de passe clair, dans certains cas, même si votre système a été redémarré. Vous devriez vous faire votre propre jugement pour savoir si ce risque est acceptable. Ceci vous exempte certainement d'un tas de répétitions.

  • Sur les systèmes de type Unix, l'agent est appelé ssh-agent, et est souvent lancé automatiquement pour vous lorsque vous vous connectez. Vous aurez besoin d'utiliser la commande ssh-add pour ajouter des mots de passe à l'entrepôt de l'agent.

  • Sous Windows, si vous utilisez TortoiseHg, la commande pageant agit comme un agent. Comme avec puttygen, vous aurez besoin de télécharger pageant à partir du site web de PuTTY et lire sa documentation. La commande pageant ajoute une icône à votre zone de notification (à droite de la barre de tâches) qui vous permettra de gérer les mots de passe stockés.

6.5.5. Configurer correctement le serveur

Parce que ssh peut être délicat à installer si c'est nouveau pour vous, différentes choses peuvent mal se passer. Ajouter Mercurial en plus, et il y a beaucoup plus de possibilités pour s'arracher les cheveux. La plupart de ces problèmes potentiels apparaissent du côté serveur, non du côté client. La bonne nouvelle est qu'une fois que vous avez une configuration qui marche, elle continue habituellement de fonctionner indéfiniment.

Avant d'essayer de faire communiquer Mercurial avec un serveur ssh, il est mieux de s'assurer que vous pouvez d'abord utiliser le ssh normal ou la commande putty pour communiquer avec le serveur. Si vous vous heurtez a des problèmes en utilisant ces commandes directement, Mercurial ne fonctionnera sûrement pas. Pire, il cachera le problème sous-jacent. Chaque fois que vous voulez déboguer des problèmes de Mercurial liés à ssh, vous devriez d'abord vous assurer que les commandes du client ssh fonctionne d'abord, avant de vous inquiéter à propos de savoir si il y a un problème avec Mercurial.

La première chose à s'assurer du côté serveur est que vous puissiez réellement vous connecter depuis une autre machine. Si vous ne pouvez pas utiliser ssh ou putty pour vous connecter, le message d'erreur que vous aurez peut vous donner quelques indices sur ce qui ne fonctionne pas. Les problèmes les plus courants sont les suivants.

  • Si vous avez une erreur connexion refusée, soit il n'y a pas de démon SSH tournant sur le serveur, soit il est inaccessible à cause de la configuration du pare-feu.

  • Si vous avez une erreur no route to host, soit vous avez une adresse incorrecte pour le serveur soit un pare-feu sérieusement verrouillé qui ne veut pas du tout reconnaître son existence.

  • Si vous avez une erreur permission denied, vous pouvez avoir mal tapé le nom d'utilisateur sur le serveur, ou vous pouvez avoir mal tapé votre passphrase de clé ou le mot de passe d'utilisateur distant.

En résumé, si vous avez des difficultés pour communiquer avec le démon ssh du serveur, d'abord assurez-vous qu'il y en a un en fonctionnement. Sur beaucoup de systèmes, il est installé, mais désactivé, par défaut. Une fois que c'est fait, vous devriez alors vérifier que le pare-feu du serveur est configuré pour permettre les connexions entrantes sur le port que le démon ssh écoute (habituellement 22). Ne vous inquiétez pas à propos de possibilités plus exotiques de mauvaise configuration tant que vous n'avez pas vérifier ces deux premières.

Si vous utilisez un agent d'authentification du côté client pour stocker les passphrases de vos clés, vous devriez être capable de vous connecter au serveur sans avoir à entrer une passphrase ou un mot de passe. Si vous devez entrer une passphrase, il y a quelques coupables possibles.

  • Vous pouvez avoir oublié d'utiliser ssh-add ou pageant pour stocker la passphrase.

  • Vous pouvez avoir stocké la passphrase pour une mauvaise clé.

Si vous devez entrer le mot de passe d'utilisateur distant, il y a quelques autres problèmes possibles à vérifier.

  • Soit le répertoire utilisateur ou le répertoire .ssh peut avoir des droits trop tolérants. Comme résultat, le démon ssh n'aura pas confiance ni ne lira le fichier authorized_keys. Par exemple, un group-writable home ou un répertoire .ssh sera souvent la cause de ce symptôme.

  • Le fichier authorized_keys de l'utilisateur peut avoir un problème. Si quelqu'un d'autre que l'utilisateur possède ou peut écrire dans ce fichier, le démon ssh n'aura pas confiance ni ne le lira.

Dans le monde idéal, vous devriez être capable d'exécuter la commande suivante avec succès, et elle devrait imprimer exactement une ligne en sortie, la date et l'heure actuelle.

ssh myserver date

Si, sur votre serveur, vous avec des scripts de connexion qui impriment des bannières ou d'autre "junk" même en fonctionnement non-interactif comme ici, vous devriez corriger cela avant de continuer, comme cela elles imprimeront des sorties que si elles fonctionnent en mode interactif. Autrement, au minimum, ces bannières encombreront les sorties de Mercurial. Pire, elles pourront potentiellement causer des problèmes avec des commandes Mercurial exécutées à distance. Mercurial essaye de détecter et d'ignorer des bannières dans des sessions ssh non-interactives, mais il n'est pas infaillible. (Si vous éditez vos scripts de connexion sur votre serveur, la manière habituelle de voir si un script de connexion fonctionne dans un shell interactif est de vérifier le code de retour de la commande tty -s.)

Lorsque vous avez vérifié que le bon vieux ssh fonctionne avec votre serveur, l'étape suivante est de s'assurer que Mercurial fonctionne sur le serveur. La commande suivant devrait fonctionnement correctement :

ssh myserver hg version

Si vous voyez un message d'erreur au lieu de la sortie normale de hg version, c'est habituellement parce que vous n'avez pas installé Mercurial dans /usr/bin. Ne vous inquiétez pas si c'est le cas ; vous n'avez pas besoin de le faire. Mais vous devriez vérifiez quelques problèmes possibles.

  • Mercurial est-il vraiment installé sur le serveur ? Je sais que cela semble évident, mais cela vaut la peine de vérifier !

  • Peut-être que le chemin de recherche de votre shell (habituellement défini via la variable d'environnementPATH) est simplement mal configuré.

  • Peut-être que votre variable d'environnement PATH pointe vers l'endroit de l'exécutable hg uniquement si la session est interactive. Ceci peut arriver si vous mettez le chemin dans le mauvais script de connextion. Regardez la documentation de votre shell pour les détails.

  • La variable d'environnement PYTHONPATH peut devoir contenir le chemin vers les modules Python de Mercurial. Elle peut ne pas être définie ; elle peut être incorrecte ; ou elle peut être définie que si la connexion est interactive.

Si vous pouvez exécuter hg version sur une connexion ssh, bravo ! Vous avez réglé les problèmes du serveur et du client. Vous devriez maintenant être capable d'utiliser Mercurial pour accéder à des dépôts hébergés par cet utilisateur sur ce serveur. Si vous avez des problèmes avec Mercurial et ssh à ce moment, essayer d'utiliser l'option --debug pour obtenir une image plus claire de ce qui se passe.

6.5.6. Utilisation de la compression avec ssh

Mercurial ne comprime pas les données quand il utilise le protocole ssh, car le protocole ssh peut comprimer de manière transparente les données. De plus, le comportement par défaut des clients ssh est de ne pas demander de la compression.

Sur n'importe quel réseau autre qu'un réseau local rapide (même un réseau sans fil), utiliser la compression améliore significativement la vitesse des opérations réseau de Mercurial. Par exemple, sur un WAN, quelqu'un a mesuré que la compression a réduit la durée pour cloner un dépôt particulièrement grand de 51 minutes à 17 minutes.

Les deux commandes ssh et plink acceptent une option -C qui active la compression. Vous pouvez facilement éditer votre ~/.hgrc pour activer la compression pour tous les usages de Mercurial du protocole ssh. Voici comment faire pour la commande habituelle ssh sur des systèmes Unix-like, par exemple.

[ui]
ssh = ssh -C

Si vous utilisez ssh sur un système Unix-like, vous pouvez le configurer pour toujours utiliser la compression lors de la connexion avec votre serveur. Pour cela, éditer votre fichier .ssh/config (qui peut ne pas encore exister), comme suit.

Host hg
  Compression yes
  HostName hg.example.com

Ceci définit un alias pour le nom d'hôte, hg. Quand vous utilisez ce nom d'hôte sur la ligne de commande ssh ou dans une URL Mercurial en protocole ssh, ssh se connectera à hg.example.com et utilisera la compression. Ceci vous offre à la fois un nom plus court à taper et la compression, chacun est une bonne chose en lui-même.

6.6. Service sur HTTP grâce à CGI

La manière la plus simple d'héberger un ou plusieurs dépôts de manière permanente est d'utiliser un serveur web et le support CGI de Mercurial.

En fonction de votre ambition, configurer l'interface CGI de Mercurial peut vous prendre de quelques instants à plusieurs heures.

Nous commencerons par le plus simple des exemples, et travailler vers une configuration plus complexe. Même pour le cas le plus élémentaire, vous devrez certainement lire et modifier la configuration de votre serveur web.

[Note] Grande tolérance à la peine exigée

Configurer un serveur web est une activité complexe, délicate, et dépendant fortement du système. Il m'est absolument impossible de vous donner les instructions qui couvriront tous les cas que vous rencontrerez. Faites comme bon vous semblera en suivant les sections ci-dessous. Soyez prêts à faire beaucoup d'erreurs, et à consacrer beaucoup de temps à lire les logs d'erreur de votre serveur.

Si vous n'avez pas un estomac solide pour tordre des configurations à maintes reprises, ou un besoin irrésistible d'héberger vos propres services, vous pourriez vouloir essayer un des services d'hébergement public que j'ai mentionné plus tôt.

6.6.1. Liste de contrôle de la configuration du serveur web

Avant de continuer, prenez quelques instants pour contrôler quelques aspects de l'installation de votre système.

  1. Avez-vous un serveur web installé ? Mac OS X et quelques distributions Linux sont fournis avec Apache, mais beaucoup d'autres systèmes peuvent ne pas avoir de serveur web installé.

  2. Si vous avez un serveur web installé, fonctionne-t-il réellement ? Sur la plupart des systèmes, même si il y a en un, il sera désactivité par défaut.

  3. Votre serveur est-il configuré pour vous permettre de faire fonctionner des programmes CGI dans le répertoire où vous prévoyer de le faire ? La plupart des serveurs désactivent explicitement l'aptitude à faire fonctionner des programmes CGI.

Si vous n'avez pas de serveur web installé, et n'avez pas d'expérience solide dans la configuration Apache, vous devriez envisager d'utiliser le serveur web lighttpd au lieu d'Apache. Apache a une réputation bien méritée de configuration baroque et déroutante. Bien que lighttpd ait moins de fonctions qu'Apache, la plupart de celles-ci ne sont pas utiles pour servir des dépôts Mercurial. Et lighttpd est incontestablement beaucoup plus facile pour débuter qu'Apache.

6.6.2. Configuration élémentaire de CGI

Sur les systèmes Unix-like, il est habituel pour les utilisateurs d'avoir un sous-répertoire nommé quelque chose comme public_html dans leur "home directory", à partir duquel ils peuvent servir des pages web. Un fichier appelé foo dans ce répertoire sera accessible à une URL de la forme http://www.example.com/username/foo.

Pour commencer, trouver le script hgweb.cgi qui devrait être présent dans votre installation de Mercurial. Si vous ne pouvez pas trouver rapidement une copie locale sur votre système, téléchargez-le simplement du dépôt maître de Mercurial à http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi.

Vous devrez copier ce script dans votre répertoire public_html, et vous assurez qu'il est exécutable.

cp .../hgweb.cgi ~/public_html
chmod 755 ~/public_html/hgweb.cgi

L'argument 755 de chmod est un peu plus général que de rendre le script exécutable: il garantit que le script est exécutable par n'importe qui, et que les permissions d'écriture pour le group et les other ne sont pas définies. Si vous laissez ces permissions d'écriture activées, le sous-système suexec d'Apache refuserait probablement d'exécuter le script. En fait, suexec insiste aussi pour que le répertoire dans lequel le script réside ne soit pas inscriptible par d'autres.

chmod 755 ~/public_html

6.6.2.1. Que pourrait-il éventuellement mal se passer ?

Une fois que vous avez copié le script CGI à sa place, allez dans un navigateur et essayer d'ouvrir l'URL http://myhostname/~myuser/hgweb.cgi, mais attendez-vous à un échec immédiat. Il y a une forte probabilité que d'essayer de visiter cette URL échouera, et il y a beaucoup de raisons possibles pour cela. En fait, vous devrez probablement trébucher sour pratiquement chacun des erreurs possibles ci-dessous, donc lisez attentivement. Les problèmes suivants sont tous ceux que j'ai rencontré sur un système tournant Fedora 7, avec une nouvelle installation d'Apache, et un compte utilisateur que j'avais créé spécialement pour réaliser cet exercice.

Votre serveur web peut avoir des répertoires "per-user" désactivés. Si vous utilisez Apache, cherchez une directive UserDir dans votre fichier de configuration. Si il n'y en a pas, les répertoires "per-user" seront désactivés. Si il en existe un, mais que sa valeur est disabled, alors les répertoires "per-user" seront désactivés. Autrement, la chaîne de caractères après UserDir donne le nom du sous-répertoire qu'Apache regardera dans votre répertoire "home", par exemplepublic_html.

Vos permissions d'accès de fichier peuvent être trop restrictives. Le serveur web doit être capable de traverser votre répertoire home et les répertoires sous votre répertoire public_html, et de lire les fichiers sous le dernier aussi. Voici une recette rapide pour vous aider à rendre vos permissions plus adéquates.

chmod 755 ~
find ~/public_html -type d -print0 | xargs -0r chmod 755
find ~/public_html -type f -print0 | xargs -0r chmod 644

L'autre possibilité avec les permissions est que vous pourriez obtenir une fenêtre complètement vide lorsque vous essayez de charger le script. Dans ce cas, c'est probablement que vos permissions d'accès sont trop permissives. Le sous-système suexec d'Apache n'exécute pas un script qui est inscriptible par le groupe ou le monde, par exemple.

Votre serveur web peut être configuration pour refuser l'exécution de programmes CGI dans votre répertoire web "per-user". Voici la configuration "per-user" par défaut d'Apache pour mon système Fedora.

<Directory /home/*/public_html>
  AllowOverride FileInfo AuthConfig Limit
  Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
  <Limit GET POST OPTIONS>
    Order allow,deny
    Allow from all
  </Limit>
  <LimitExcept GET POST OPTIONS>
    Order deny,allow Deny from all
  </LimitExcept>
</Directory>

Si vous trouvez un groupe qui ressemble à Directory dans votre configuration Apache, la directive à regarder est Options. Ajoutez ExecCGI à la fin de cette liste si cela manque, et redémarrer le serveur web.

Si vous trouvez qu'Apache vous donne le texte du script CGI au lie de l'exécuter, vous pouvez avoir besoin soit de décommenter (si déjà présent) ou d'ajouter une directive telle que celle-ci.

AddHandler cgi-script .cgi

La possibilité suivante est que vous pourriez obtenir une trace coloré Python prétendant qu'il ne peut pas importer un module relatif à mercurial. Ceci est réellement un progrès ! Le serveur est maintenant capable d'exécuter votre script CGI. Cette erreur arrive probablement si vous exécutez une installation privée de Mercurial, au lieu d'une version "system-wide". Souvenez-vous que le serveur web fait fonctionner le programme CGI sans aucune des variables d'environnement que vous considérez comme certaines dans une session interactive. Si cette erreur vous arrive, éditez une copie de hgweb.cgi et suivez les indications à l'intérieur de celui-ci pour corriger votre variable d'environnement PYTHONPATH.

Pour finir, vous êtes certain d'avoir une autre trace colorée Python : celle-ci se plaindra de ne pas pouvoir trouver /path/to/repository. Éditez votre script hgweb.cgi et remplacez la chaîne de caractères /path/to/repository par le chemin complet du dépôt que vous voulez servir.

À ce moment-là, quand vous essayez de recharger la page, vous devriez avoir une jolie vue HTML de l'historique de votre dépôt. Ouf !

6.6.2.2. Configurer lighttpd

Pour être exhaustif dans mes expériences, j'ai essayé de configurer le serveur web lighttpd devenu populaire pour servir le même dépôt que celui décrit plus haut avec Apache. J'ai déjà surmonter tous les problèmes décrits avec Apache, beaucoup ne sont pas spécifique à un serveur. Comme résultat, j'étais pratiquement sûr que mes permissions de fichiers et de répertoires étaient bonnes, et que mon script hgweb.cgi était correctement édité.

Une fois qu'Apache tournait, avoir lighttpd pour servir le dépôt était immédiat (en d'autres mots, même si vous essayez d'utiliser lighttpd, vous devriez lire la section Apache). J'ai d'abord dû éditer la section mod_access de son fichier de configuration pour activer mod_cgi et mod_userdir, les deux étaient désactivés par défaut sur mon système. J'ai ensuite ajouté quelques lignes à la fin du fichier de configuration, pour ajouter ces modules.

userdir.path = "public_html"
cgi.assign = (".cgi" => "" )

Un fois ceci fait, lighttpd a fonctionné immédiatemment pour moi. Si j'avais configuré lighttpd avant Apache, je serais sans doute tombé dans beaucoup des mêmes problèmes de configuration "system-level" comme j'ai eu avec Apache. De plus, j'ai trouvé lighttpd être notablemen plus facile à configurer qu'Apache, même si j'ai utilisé Apache depuis plus d'une décennie, et ceci était ma première expérience avec lighttpd.

6.6.3. Partager plusieurs dépôts avec un seul script CGI

Le script hgweb.cgi vous laisse seulement publier un seul dépôt, ce qui est une limitation ennuyeuse. Si vous voulez publier plus d'un dépôt sans "wracking yourself" avec de multiples copies du même script, chacune avec un nom différent, un meilleur choix est d'utiliser le script hgwebdir.cgi.

La procédure pour configurer hgwebdir.cgi est seulement un peu plus compliquée que pour hgweb.cgi. D'abord, vous devez obtenir une copie du script. Si vous n'en avez pas une sous la main, vous pouvez télécharger une copie depuis le dépôt maître de Mercurial à http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi.

Vous aurez besoin de copier ce script dans votre répertoire public_html, et vous assurer qu'il est exécutable.

cp .../hgwebdir.cgi ~/public_html
chmod 755 ~/public_html ~/public_html/hgwebdir.cgi

Avec une configuration élémentaire "out of the way", essayez de visiter http://myhostname/~myuser/hgwebdir.cgi dans votre navigateur. Il devrait afficher une liste vide de dépôts. Si vous obtenez une fenêtre vide ou un message d'erreur, essayer de parcourir la liste de problèmes potentiels dans Section 6.6.2.1, “Que pourrait-il éventuellement mal se passer ?”.

Le script hgwebdir.cgi se base sur un fichier de configuration externe. Par défaut, il cherche un fichier nommé hgweb.config dans le même répertoire que lui. Vous devrez créer ce fichier, et le rendre lisible par tout le monde. Le format de ce fichier est semblable à un fichier Windows ini, comme compris par un module Python ConfigParser [web:configparser].

La façon la plus facile de configurer hgwebdir.cgi est avec une section appellée collections. Ceci publiera automatiquement chaque dépôt sous les répertoires que vous citez. La section devrait ressembler à ceci :

[collections]
/my/root = /my/root

Mercurial interprète ceci en regardant le nom du répertoire sur la partie droite du signe = ; en trouvant les répertoires dans cette hiérarchie de répertoires ; et en utilisant le texte sur la gauche pour retirer le texte correspondant des noms qu'il listera réellement dans l'interface web. Le restant du chemin après que ce "stripping" a été réalisé est appelé un chemin virtuel (virtual path).

Étant donné l'exemple ci-dessus, si vous avez un dépôt dont le chemin local est /my/root/this/repo, le script CGI retirera le début /my/root du nom, et publiera le dépôt avec un chemin virtuel this/repo. Si l'URL de base de notre script CGI est http://myhostname/~myuser/hgwebdir.cgi, l'URL complète URL pour ce dépôt sera http://myhostname/~myuser/hgwebdir.cgi/this/repo.

Si nous remplaçons/my/root sur la gauche de cet exemple par /my, alors hgwebdir.cgi retirera seulement /my du nom du dépôt, et nous donnera comme chemin virtuel root/this/repo au lieu de this/repo.

Le script hgwebdir.cgi cherchera récursivement dans chaque répertoire listé dans la section collections de son fichier de configuration, mais, il ne cherchera pas recursivement dans les répertoires qu'il trouvera.

Le mécanisme de collections rend facile la publication de plusieurs dépôts de façon fire and forget. Vous devez seulement installer le script CGI et le fichier de configuration une seule fois. Après, vous pouvez publier ou "dépublier" un dépôt n'importe quand en le déplaçant simplement dans, ou hors de la hiérarchie de répertoire dans laquelle vous avez indiqué à hgwebdir.cgi de regarder.

6.6.3.1. Spécifier explicitement quels dépôts publier

En plus du mécanisme de collections, le script hgwebdir.cgi vous permet de publier une liste spécifique de dépôts. Pour cela, créez une section paths, avec un contenu de la forme suivante.

[paths]
repo1 = /my/path/to/some/repo
repo2 = /some/path/to/another

Dans ce cas, le chemin virtuel (le composant qui apparaîtra dans une URL) est sur la gauche de chaque définition, tandis que le chemin vers le dépôt est sur la droite. Notez qu'il n'y a pas besoin de relation entre le chemin virtuel que vous choisissez et l'emplacement d'un dépôt dans votre système de fichiers.

Si vous le souhaitez, vous pouvez utiliser les mécanismes de collections et de paths simultanément dans un seul fichier de configuration.

[Note] Prendre garde aux chemins virtuels en double

Si plusieurs dépôts ont le même chemin virtuel, hgwebdir.cgi ne signalera pas d'erreur. Au lieu de cela, il se comportera de façon imprévisible.

6.6.4. Télécharger des archives de sources

L'interface web de Mercurial laisse les utilisateurs télécharger une archive de n'importe quelle révision. Cette archive contiendra une image du répertoire de travail comme pour cette révision, mais il ne contiendra pas une copie des données du dépôt.

Par défaut, cette fonctionnalité n'est pas activée. Pour l'activer, vous devrez ajouter un élément allow_archive à la section web de votre ~/.hgrc; voyez plus loin pour des détails.

6.6.5. Options de configuration web

Les interfaces web de Mercurial (la commande hg serve, et les scripts hgweb.cgi et hgwebdir.cgi) ont un nombre d'options de configuration que vous pouvez mettre. Celles-ci appartiennent à une section appelée web.

  • allow_archive : détermine quels mécanismes de téléchargement d'archive (si il y en a) Mercurial accepte. Si vous activez cette fonctionnalité, les utilisateurs de l'interface web seront capable de télécharger une archive de n'importe quelle révision d'un dépôt qu'ils regardent. Pour activer la fonction archive, cet élément doit prendre la forme d'une série de mots pris dans la liste ci-dessous.

    • bz2: une archive tar, comprimée en utilisant la compression bzip2. Ceci a le meilleur taux de compression, mais utilise le plus de temps processeur sur le serveur.

    • gz: une archive tar, comprimée en utilisant la compression gzip.

    • zip: une archive zip, comprimée en utilisant la compression LZW. Ce format a le pire taux de compression, mais il est largement utilisé dans le monde Windows.

    Si vous fournissez une liste vide, ou n'avez pas d'entrée allow_archive du tout, cette fonctionnalité sera désactivée. Voici un exemple de comment activer les trois formats supportés.

    [web]
    allow_archive = bz2 gz zip
  • allowpull: Boolean. Détermine si l'interface web permet aux utilisateurs distants de hg pull et hg clone ce dépôt sur HTTP. Si mis à no ou false, seule la partie orienté humain de l'interface web est disponible.

  • contact: String. Une chaîne de caractères "free-form" (mais de préférence brève) identifiant la personne ou le groupe responsable du dépôt. Ceci contient souvent le nom et l'adresse électronique d'une personne ou d'une liste de distribution. Il est judicieux de placer cette entrée dans le fichier .hg/hgrc du dépôt, mais il peut être judicieux d'utiliser un ~/.hgrc global si chaque dépôt a un seul "mainteneur".

  • maxchanges: Integer. La valeur maximum par défaut du nombre de changesets à afficher dans une seule page de sortie.

  • maxfiles: Integer. Le nombre maximum par défaut de fichier modifiés à à afficher dans une seule page de sortie.

  • stripes: Integer. Si l'interface web affiche alternativement desIf the web interface displays alternating rayures pour rendre plus facile l'alignement visuel des lignes lorsque vous regarder une table, ce nombre contrôle le nombre de lignes dans chaque rayure.

  • style: Contrôle le "modèle" que Mercurial utilise pour afficher l'interface web. Mercurial est livré avec plusieurs "modèles" web.

    • coal est monochromatique.

    • gitweb émule le style visuel de l'interface web de git.

    • monoblue utilise des bleus et des gris massifs.

    • paper est le "modèle" par défaut.

    • spartan a été le "modèle" par défaut durant longtemps.

    Vous pouvez aussi spécifiez un "modèle" personnalisé à vous; voyez Chapter 11, Customizing the output of Mercurial pour des détails. Ici, vous pouvez voir comment activer le style gitweb.

    [web]
    style = gitweb
  • templates: Path. Le répertoire dans lequel chercher les fichiers "modèles". Par défaut, Mercurial cherche dans le répertoire dans lequel il a été installé.

Si vous utilisez hgwebdir.cgi, vous pouvez mettre quelques éléments de configuration dans une section web du fichier hgweb.config au lieu d'un fichier ~/.hgrc, par commodité. Ces éléments sont motd et style.

6.6.5.1. Options spécifiques à un dépôt individuel

Quelques éléments de configuration web devraient être mis dans .hg/hgrc local à un dépôt, plutôt que dans un ~/.hgrc d'utilisateur ou global.

  • description: String. Une chaîne de caractères "free-form" (mais de préférence brève) qui décrit le contenu ou le but du dépôt.

  • name: String. Le nom à utiliser pour le dépôt dans l'interface web. Ceci prime sur le nom par défaut, qui est le dernier composant du chemin du dépôt.

6.6.5.2. Options spécifiques à la commande hg serve

Certaines entrées dans la section web d'un fichier ~/.hgrc sont là seulement pour être utilisée avec la commande hg serve.

  • accesslog: Path. Le nom d'un fichier dans lequel écrire le "log" d'accès. Par défaut, la commande hg serve écrit cette information sur la sortie standard, pas dans un fichier. Les entrées de "log" sont écrites dans le format de fichier standard combined utilisé par pratiquement tous les serveurs web.

  • address: String. L'adresse locale sur laquelle le serveur devrait écouter les connexions entrantes. Par défaut, le serveur écoute sur toutes les adresses.

  • errorlog: Path. Le nom d'un fichier dans lequel écrire le "log" d'erreur. Par défaut, la commande hg serve écrit cette information sur la sortie erreur, pas dans un fichier.

  • ipv6: Boolean. Si il faut utiliser le protocole IPv6. Par défaut, IPv6 n'est pas utilisé.

  • port: Integer. Le numéro de port TCP sur lequel le serveur devrait écouter. Le numéro de port par défaut utilisé est 8000.

6.6.5.3. Choisir le bon fichier ~/.hgrc auquel ajouter les éléments web

Il est important de se souvenir qu'un serveur web comme Apache ou lighttpd fonctionnera avec un ID utilisateur qui est différent du vôtre. Les scripts CGI fonctionnant sur votre serveur, tels que hgweb.cgi, s'exécuteront habituellement aussi sous un autre ID utilisateur.

Si vous ajoutez des éléments web à votre propre fichier ~/.hgrc personnel, les scripts CGI ne pourront pas lire ce fichier ~/.hgrc. Ces réglages toucheront donc seulement le comportement de la commande hg serve quand vous l'exécuterez. Pour faire voir vos réglages aux scripts CGI, soit créez un fichier ~/.hgrc dans le répertoire "home" de l'utilisateur qui exécute votre serveur web, soit ajouter ces réglages dans un fichier hgrc "system-wide".

6.7. Configuration "system-wide"

Sur des systèmes "Unix-like" partagé par plusieurs utilisateurs (tel qu'un serveur où les gens publient des modifications), il est souvent judicieux de définir certains comportement globaux par défaut, tels que le thème à utiliser dans les interfaces web.

Si un fichier appelé /etc/mercurial/hgrc existe, Mercurial le lira au démarrage et appliquera tous les réglages de configuration qu'il trouve dans ce fichier. Il regardera aussi les fichiers finissant par une extension .rc dans un répertoire appelé /etc/mercurial/hgrc.d, et appliquera tous les réglages de configuration qu'il trouve dans chacun de ces fichiers.

6.7.1. Rendre Mercurial moins méfiant

Une situation dans laquelle un hgrc global peut être utile est si des utilisateurs "pullent" des modifications faites par d'autres utilisateurs. Par défaut, Mercurial can be useful is if users are pulling changes owned by other users. By default, Mercurial ne se fiera pas à la plupart des entrées de configuration dans un fichier .hg/hgrc à l'intérieur d'un dépôt qui appartient à un utilisateur différent. Si nous clonons ou "pullons" des modifications d'un tel dépôt, Mercurial affichera un avertissement indiquant qu'il ne fait pas confiance aux .hg/hgrc.

Si quelqu'un dans un groupe Unix particulier est dans la même équipe et devrait avoir confiance dans chaque réglage de configuration des autres, ou si nous voulons avoir confiance dans des utilisateurs particuliers, nous pouvons passer outre les défauts sceptiques de Mercurial en créant un fichier hgrc "system-wide" tel que celui qui suit ::

# Save this as e.g. /etc/mercurial/hgrc.d/trust.rc
[trusted]
# Trust all entries in any hgrc file owned by the "editors" or
# "www-data" groups.
groups = editors, www-data

# Trust entries in hgrc files owned by the following users.
users = apache, bobo