Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato
Ce travail est placé sous la licence Creative Commons Attribution. Pour voir le contenu de cette licence, rendez-vous sur http://creativecommons.org/licenses/by/2.0/fr/. Vous pouvez aussi envoyez une lettre à Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Table des matières
Liste des illustrations
Liste des tableaux
Liste des exemples
start-commit
qui s'assure que le client sait suivre les fusions.Une mauvaise FAQ est composée non pas des questions que posent les utilisateurs, mais de celles que l'auteur de la FAQ voudrait qu'on lui pose. Peut-être avez-vous rencontré ce type de FAQ :
Q : Comment peut-on utiliser Glorbosoft XYZ pour maximiser la productivité de nos équipes ?
R : Beaucoup de nos clients veulent savoir comment maximiser la productivité avec notre nouvelle suite bureautique brevetée. La réponse est simple : cliquez sur le menu
Fichier
, puis trouvezAméliorer la productivité
plus bas, ensuite…
Le problème avec de telles FAQ, c'est qu'elles ne sont pas du tout, au sens propre, des FAQ. Personne n'a appelé le support technique et demandé « Comment pouvons-nous améliorer la productivité ? » Au lieu de ça, les gens posent des questions très précises, telles que « Comment pouvons-nous configurer le système de calendrier pour envoyer les rappels deux jours en avance au lieu de 24 heures ? » etc. Hélas, il est tellement plus facile d'imaginer des questions que de trouver celles qui sont vraiment fréquemment posées. Rédiger une vraie FAQ requiert un effort continu et une bonne organisation : tout au long de la vie du logiciel, les questions posées ainsi que leurs réponses doivent être suivies de près, puis rassemblées et organisées de façon claire et cohérente dans un tout qui doit refléter l'expérience des utilisateurs. Cela nécessite d'être patient et observateur, tel un naturaliste. Ici, pas de grandes théories ni de discours visionnaires, ce qu'il faut avant tout, c'est ouvrir les yeux et prendre des notes.
Ce que j'aime à propos de ce livre, c'est qu'il a été créé en suivant ce procédé, ce qui se ressent à chacune de ses pages. C'est le résultat direct de la rencontre des auteurs et des utilisateurs. Tout a commencé lorsque Ben Collins-Sussman remarqua que les gens posaient constamment les mêmes questions de base sur la liste de diffusion de Subversion : Quelles sont les procédures pour travailler avec Subversion ? Est-ce que les branches et les étiquettes fonctionnent comme dans les autres systèmes de gestion de versions ? Comment est-ce que je peux trouver qui a fait telle ou telle modification ?
Frustré de voir revenir les mêmes questions jour après jour, Ben travailla d'arrache-pied pendant un mois durant l'été 2002 pour écrire The Subversion Handbook, un manuel de soixante pages couvrant toutes les bases de Subversion. Le manuel ainsi écrit n'avait pas la prétention d'être complet, mais il fut distribué avec Subversion pour aider les utilisateurs à faire leurs premiers pas dans l'apprentissage de Subversion. Quand O'Reilly and Associates décidèrent de publier un livre complet sur Subversion, la voie la plus facile était la plus évidente : simplement améliorer The Subversion Handbook.
Une opportunité inhabituelle se présenta donc aux trois co-auteurs de ce nouveau livre. Officiellement, leur tâche était d'écrire un livre « académique », en partant d'une table des matières et d'une première ébauche. Mais ils avaient aussi accès à un flux constant, une quantité incontrôlable en fait, de réactions en provenance des utilisateurs. Subversion était déjà entre les mains de quelques milliers d'utilisateurs précoces, et ces derniers envoyaient des tonnes de commentaires, pas seulement sur Subversion, mais aussi sur sa documentation d'alors.
Pendant que Ben, Mike et Brian écrivaient ce livre, ils surveillèrent sans relâche la liste de diffusion et les salons de discussion de Subversion, notant consciencieusement les problèmes que rencontraient les utilisateurs dans la réalité. Assurer le suivi de ces retours d'expériences faisait de toutes façons partie intégrante de leur travail à CollabNet, et cela leur donna un énorme avantage quand ils commencèrent à rédiger la documentation de Subversion. Le livre qu'ils ont écrit repose sur un socle d'expérience pratique, pas sur une liste abstraite de bonnes intentions ; il possède à la fois les qualités du mode d'emploi et de la FAQ. Cette dualité ne saute pas immédiatement aux yeux. Lu dans l'ordre, de la première à la dernière page, ce livre décrit de manière simple un logiciel. Il y a la vue d'ensemble, l'incontournable visite guidée, le chapitre sur la configuration et l'administration, quelques sujets avancés, et bien évidemment une liste complète des commandes ainsi qu'un guide de débogage. Mais c'est quand on revient chercher dans ce livre une réponse à un problème spécifique qu'on réalise son authenticité, faite de détails révélateurs ne pouvant provenir que de cas concrets et inattendus, d'exemples tirés de situations réelles, et par-dessus tout de l'attention portée aux besoins et aux remarques des utilisateurs.
Bien sûr, personne ne peut affirmer que ce livre répondra à
toutes vos questions sur Subversion. De temps en temps, la
précision avec laquelle il anticipe vos questions vous semblera
presque télépathique ; mais d'autres fois, vous tomberez sur
une lacune dans le savoir de la communauté, et vous rentrerez
bredouille. Quand cela arrive, le mieux que vous puissiez faire
est d'envoyer un courrier électronique à
<users@subversion.apache.org>
(en anglais si possible) en y décrivant votre
problème. Les auteurs sont toujours là, à l'affût, et il ne s'agit
pas seulement des trois personnes citées sur la couverture du
livre, mais aussi de beaucoup d'autres contributeurs ayant
apporté corrections et améliorations. Pour la communauté, résoudre
votre problème est une composante agréable d'un projet bien plus
vaste, celui de peaufiner petit à petit ce livre, et finalement
Subversion lui-même, pour encore mieux coller à l'utilisation que
les gens en ont. Les auteurs sont très enthousiastes à l'idée de
communiquer avec vous, pas seulement parce qu'ils peuvent vous
aider, mais aussi parce que vous pouvez les aider. Avec Subversion,
comme avec tous les projets de logiciels libres en activité,
vous n'êtes pas seul.
Ce livre est votre premier compagnon.
« Il est important de ne pas laisser la perfection devenir l'ennemi du bien, même lorsque vous pouvez être d'accord sur ce qu'est la perfection. Encore plus lorsque vous ne le pouvez pas. Aussi déplaisant qu'il soit d'être piégé par les erreurs du passé, vous ne pouvez pas faire de progrès en ayant peur de votre propre ombre pendant la conception. » | ||
--Greg Hudson, développeur de Subversion |
Dans le monde du logiciel libre, le logiciel « Concurrent Versions System » (CVS) fut l'outil de choix pour la gestion de versions pendant de nombreuses années. Et à juste titre. CVS était lui-même libre et son mode de fonctionnement non-restrictif couplé à son support des opérations réseau permettait à des dizaines de programmeurs dispersés aux quatre coins du monde de partager leur travail. Cela collait très bien à la nature collaborative du logiciel libre. CVS et son modèle de développement semi-chaotique sont depuis devenus des pierres angulaires de la culture du logiciel libre.
Mais CVS n'était pas parfait et simplement corriger ses défauts promettait d'être un énorme effort. C'est ici que Subversion entre en jeu. Les créateurs de Subversion l'ont créé pour être un successeur de CVS et l'ont fait de façon à gagner le cœur des utilisateurs de CVS de deux façons : en concevant un logiciel libre doté d'une interface similaire à CVS et en tentant d'éviter la plupart des défauts majeurs de CVS. Bien que le résultat ne soit pas forcément la prochaine évolution majeure dans les systèmes de gestion de versions, Subversion est très puissant, parfaitement utilisable et très flexible.
Ce livre est écrit pour documenter les versions 1.8 du système de gestion de versions Apache™ Subversion®[1]. Nous avons tenté d'être aussi complet que possible dans cet ouvrage. Cependant, Subversion a une communauté prospère et dynamique ; il y a donc déjà un certain nombre de fonctionnalités et d'améliorations prévues pour des versions futures de Subversion qui peuvent modifier quelques commandes ou rendre caduques certaines notes spécifiques de ce livre.
Subversion est un logiciel libre de la catégorie systèmes de gestion de versions (VCS en anglais, pour Version Control System). Cela signifie que Subversion gère les fichiers et les répertoires, ainsi que les changements dont ils font l'objet, à travers le temps. Vous pouvez ainsi retrouver d'anciennes versions de vos données ou parcourir l'historique des changements de vos données. Cela fait dire à certains que les systèmes de gestion de versions sont en quelque sorte des « machines à remonter le temps ».
Subversion peut fonctionner en réseau, ce qui autorise un partage des données sur des ordinateurs différents. D'une certaine manière, la possibilité pour un groupe de personnes de modifier et gérer le même ensemble de données en restant derrière son propre poste de travail renforce la collaboration. Le travail peut avancer sans nécessiter un circuit unique de validation. Et comme ce qui est réalisé est suivi en versions, vous n'avez pas à craindre que la disparition du circuit de validation ne se fasse au détriment de la qualité— si de mauvaises données sont entrées, vous n'avez qu'à annuler la modification.
Certains systèmes de gestion de versions sont aussi des systèmes de gestion de configuration logicielle (GCL). Ces systèmes sont spécialement conçus pour gérer des arborescences de code source et possèdent de nombreuses fonctionnalités propres au développement logiciel, comme la reconnaissance des langages de programmation ou des outils de construction/compilation de logiciel. Subversion, cependant, ne fait pas partie de cette catégorie. C'est un système généraliste qui peut être utilisé pour gérer n'importe quel ensemble de fichiers. Pour vous ce peut être du code source ; pour d'autres cela va de la liste de courses jusqu'aux vidéos des vacances et bien au-delà.
Si, en tant qu'utilisateur ou administrateur système, vous réfléchissez à la mise en place de Subversion, la première question à vous poser est :« est-ce bien l'outil adéquat pour ce que je veux faire ? » Subversion est un marteau fantastique, mais il faut faire attention à ne pas assimiler tout problème à un clou.
En premier lieu, vous devez décider si la gestion de versions en général répond à votre besoin. Si vous voulez archiver de vieilles versions de vos fichiers et dossiers, éventuellement de les ressusciter, ou d'examiner les journaux détaillant leurs évolutions, les systèmes de gestion de versions le font très bien. Si vous avez besoin de travailler sur des documents en collaboration avec d'autres personnes (habituellement via un réseau) et de conserver la trace de qui a apporté quelles modifications, les systèmes de gestion de versions font également l'affaire. En fait, c'est pour ces raisons que les systèmes de gestion de versions tels que Subversion sont souvent utilisés dans des environnements de développement logiciel ; travailler au sein d'une équipe de développement est par nature une activité sociale où les modifications au code source sont constamment discutées, réalisées, évaluées et parfois retirées. Les outils de gestion de versions rendent très facile ce type de collaboration.
Bien sûr il existe aussi un coût lié à l'utilisation de la gestion de versions. À moins de pouvoir externaliser l'administration du système de gestion de versions, vous devrez évidemment en assumer l'administration système. En travaillant au jour le jour avec les données, vous ne pourrez pas copier, déplacer, renommer ou supprimer des fichiers de la façon dont vous le faisiez auparavant. À la place, vous devrez accomplir ces tâches via Subversion.
En supposant que cette quantité de travail supplémentaire ne vous pose pas de problème, vous devriez quand même vérifier que vous n'allez pas utiliser Subversion pour résoudre un problème que d'autres outils pourraient résoudre de manière bien plus efficace. Par exemple, parce que Subversion fournit une copie des données à tous les utilisateurs concernés, une erreur courante est de le traiter comme un système de distribution générique. Les gens utilisent parfois Subversion pour partager d'immenses collections de photos, de musique numérique ou de packs logiciels. Le problème est que ce type de donnée ne change en général jamais. La collection grandit au fil du temps, mais les fichiers individuels à l'intérieur de la collection ne changent pas. Dans ce cas, utiliser Subversion est « disproportionné ». [2] Il existe des outils plus simples, capables de copier des données efficacement sans s'embarrasser de toute la gestion du suivi des modifications, tels que rsync ou unison.
Une fois que vous avez décidé d'utiliser un système de gestion de versions, vous aurez pléthore de choix. Au moment où la première version de Subversion a été conçue et est sortie, la version prédominante de la gestion de versions était la gestion centralisée de versions— un serveur maître distant hébergeait les données suivies en versions et les utilisateurs travaillaient localement avec des copies dont l'historique était restreint. Subversion s'est rapidement imposé lors de sa sortie comme le leader incontesté de ce paradigme, étant largement adopté et remplaçant de nombreux systèmes de conception plus anciennes. Il conserve toujours cette position de leader aujourd'hui.
Beaucoup de choses ont changé depuis ce temps. Dans les années qui ont suivi la sortie de Subversion, un nouveau concept de gestion de versions, appelé gestion de versions distribuée (DVCS en anglais, pour distributed version control system), a également suscité beaucoup d'intérêt et a largement été adopté. Des outils tels que Git (https://git-scm.com/) et Mercurial (https://www.mercurial-scm.org/) se sont imposés dans ce créneau des DVCS. Les systèmes de gestion de versions distribués tirent parti du haut débit disponible pour les accès au réseau et du faible coût de stockage pour offrir une approche différente du modèle centralisé de gestion de versions. D'abord, et ce qui est le plus évident, c'est qu'il n'y a plus de serveur central hébergeant seul les données suivies en versions. Chaque utilisateur conserve dans, et travaille sur, des dépôts locaux l'historique (complet dans un sens) des données suivies en versions. Le travail collaboratif a toujours lieu, mais s'accomplit par l'échange direct entre utilisateurs d'ensembles de modifications faites à chacun des éléments suivis en versions, sans passer par un serveur central maître. En fait, toute déclaration de données « maîtres » d'un projet suivi en versions est une pure convention, adoptée par les différents collaborateurs à ce projet.
il existe des avantages et des inconvénients à chacune des approches. Les deux principaux bénéfices que l'on peut tirer des outils décentralisés sont les incroyables performances des opérations quotidiennes (parce que le dépôt des données est stocké localement) et une meilleure gestion des fusions entre branches (parce que les algorithmes de fusion sont ceux qui constituent le cœur même de ce type de logiciel). La contrepartie est que ces systèmes possèdent de manière inhérente un modèle de gestion plus compliqué, qui peut constituer un frein certain au travail collaboratif. Par ailleurs, les DVCS font bien leur travail en partie grâce au contrôle délégué à l'utilisateur, alors que les systèmes centralisés prennent ce contrôle à leur compte — la possibilité de gérer les accès en fonction du chemin dans l'arborescence, la flexibilité pour mettre à jour ou recouvrer individuellement des éléments suivis en versions, etc. Heureusement, beaucoup de grandes organisations ont convenu que le débat n'avait pas à être dogmatique et que Subversion ainsi que les DVCS tels que Git peuvent être utilisés harmonieusement ensemble dans l'organisation, chacun étant utilisé dans l'environnement qui lui convient le mieux.
Hélas, ce livre traite de Subversion, donc nous ne tenterons pas de mener une comparaison exhaustive de Subversion avec les autres outils. Le lecteur à qui il revient de choisir un système de gestion de versions est encouragé à s'enquérir de toutes les options qui s'offrent à lui et à choisir l'outil qui convient le mieux, à lui et à ses collaborateurs. Et si c'est Subversion qui a retenu ses faveurs, ce livre fournit, dans les chapitres qui suivent, des myriades d'informations détaillées pour conduire avec succès la mise en œuvre de Subversion !
Au début des années 2000, CollabNet, Inc. (maintenant connue sous le nom de Digital.ai, https://digital.ai) commença à rechercher des développeurs pour écrire un remplaçant à CVS. CollabNet fournissait [3] une suite logicielle collaborative appelée « CollabNet Enterprise Edition (CEE) » dont l'un des composants est la gestion de versions. Même si CEE utilisait CVS comme système de gestion de versions initial, les limitations de celui-ci étaient évidentes depuis le début, et CollabNet savait qu'il lui faudrait au final trouver quelque chose de mieux. Malheureusement, CVS était devenu le standard de fait dans le monde du logiciel libre, essentiellement parce qu'il n'y avait rien de mieux, en tout cas sous licence libre. Donc CollabNet décida d'écrire un nouveau système de gestion de versions ex nihilo, en conservant les idées de base de CVS, mais sans ses bogues ni ses limitations fonctionnelles.
En février 2000, CollabNet contacta Karl Fogel, l'auteur de Open Source Development with CVS (Coriolis, 1999), et lui demanda s'il aimerait travailler sur ce nouveau projet. Il se trouve qu'au même moment Karl ébauchait la conception d'un nouveau système de gestion de versions avec son ami Jim Blandy. En 1995, ils avaient créé ensemble Cyclic Software, une société fournissant des contrats de support pour CVS, et bien qu'ils aient plus tard revendu la société, ils utilisaient toujours CVS quotidiennement dans leur travail. Leurs frustrations à propos de CVS avaient conduit Jim à élaborer mentalement de meilleures façons de gérer les données suivies en versions. Il avait déjà non seulement trouvé le nom de « Subversion », mais aussi les principes de base du stockage de données de Subversion. Quand CollabNet les appela, Karl accepta immédiatement de travailler sur le projet et Jim obtint de son employeur, Red Hat Software, qu'il le délègue au projet pour une durée indéterminée. CollabNet embaucha Karl et Ben Collins-Sussman, et le travail de conception détaillée commença en mai. Grâce à des coups de pouce efficaces de Brian Behlendorf et Jason Robbins de CollabNet, et de Greg Stein (qui travaillait alors en tant que développeur indépendant, et participait aux spécifications du projet WebDAV/DeltaV), Subversion attira rapidement une communauté de développeurs actifs. Il s'avéra que beaucoup d'entre eux avaient ressenti les mêmes frustrations avec CVS et ils saisirent l'opportunité de pouvoir enfin y faire quelque chose.
L'équipe d'origine se mit d'accord sur quelques objectifs simples. Ils ne voulaient pas inventer de nouvelles méthodes de gestion de versions, ils voulaient juste corriger ce qui n'allait pas dans CVS. Ils décidèrent que Subversion reprendrait les fonctionnalités de CVS et préserverait son modèle de développement, mais ne reproduirait pas ses faiblesses les plus évidentes. Malgré le fait que Subversion devait pouvoir avoir ses propres spécificités, il devait être suffisamment semblable à CVS pour que n'importe lequel de ses utilisateurs puisse facilement passer à Subversion.
Le 31 août 2001, après 14 mois de codage, Subversion devint « auto-hébergeant ». Ce qui veut dire que les développeurs de Subversion cessèrent d'utiliser CVS pour gérer le propre code source de Subversion et commencèrent à utiliser Subversion à la place.
Bien que CollabNet ait initié le projet et qu'elle subventionne encore une grosse partie du travail (en payant les salaires complets de quelques développeurs de Subversion), Subversion fonctionne comme la plupart des projets de logiciel libre, dirigé par un ensemble de règles vagues et transparentes qui encouragent la méritocratie. En 2009, Collabnet a travaillé avec les développeurs de Subversion pour intégrer le projet dans la Apache Software Foundation (ASF), un des regroupement les plus mondialement connus de projets de logiciels libres. Les racines techniques de Subversion, les priorités de sa communauté et les pratiques de développement collaient parfaitement aux de l'ASF, dont beaucoup de membres étaient déjà des contributeurs actifs à Subversion. Début 2010, Subversion a été complètement adopté par la famille des projets phares de l'ASF, a déplacé son point d'ancrage sur le Web vers https://subversion.apache.org et a été rebaptisé « Apache Subversion ».
La Figure 1, « L'architecture de Subversion » donne une « vue d'ensemble » du schéma de conception de Subversion.
D'un côté, nous avons un dépôt Subversion qui contient toutes vos données suivies en versions. De l'autre côté, il y a votre programme client Subversion, qui gère des versions locales d'une partie de ces données suivies en versions. Entre ces deux extrêmes, il y a des chemins variés utilisant différentes couches d'accès au dépôt. Certains de ces chemins passent par des réseaux informatiques et des serveurs réseau avant d'atteindre le dépôt. D'autres court-circuitent complètement le réseau et accèdent directement au dépôt.
Une fois installé, Subversion est constitué de nombreux composants. Ce qui suit est un survol rapide de ce que vous obtenez. Ne vous inquiétez pas si certaines de ces brèves descriptions vous laissent dubitatif ; ce livre contient de nombreuses pages destinées à dissiper toute confusion.
Le programme client texte interactif.
Un programme permettant d'examiner l'état d'une copie de travail (en termes de révisions des éléments présents).
Un outil qui permet d'examiner directement un dépôt Subversion.
Un outil destiné à la création, la modification ou la réparation d'un dépôt Subversion.
Un greffon pour le serveur HTTP Apache, utilisé pour rendre votre dépôt disponible à d'autres personnes à travers un réseau.
Un serveur autonome créé sur mesure pour Subversion, pouvant fonctionner comme un processus démon ou pouvant être invoqué par SSH ; une autre façon de rendre votre dépôt accessible à d'autres personnes à travers un réseau.
Un programme qui permet de filtrer les flux d'exports de l'historique de vos dépôts.
Un programme capable de synchroniser de manière incrémentale un dépôt avec un autre dépôt à travers un réseau.
Un programme destiné à réaliser des exports et des chargements de l'historique d'un dépôt à travers un réseau.
Un programme capable d'effectuer des opérations basées sur les URL sur plusieurs dépôts en une seule opération et sans avoir besoin de passer par des copies de travail.
La première édition de ce livre a été publiée par O'Reilly Media en 2004, peu après que Subversion ait atteint la version 1.0. Depuis, le projet Subversion a régulièrement publié de nouvelles versions majeures du logiciel. Voici un résumé rapide des changements majeurs qui ont eu lieu depuis Subversion 1.0. Cette liste n'est pas exhaustive ; pour tous les détails, merci de vous rendre sur le site web de Subversion à l'adresse https://subversion.apache.org.
En version 1.1 fut introduit FSFS qui permet de stocker le dépôt sous forme de fichiers textes. Bien que les bases Berkeley DB soient toujours très utilisées et supportées par la communauté, FSFS est devenu le choix par défaut pour la création de nouveaux dépôts, grâce à sa prise en main facile et à ses besoins minimes en termes de maintenance. Dans cette version ont également été ajoutées les possibilités de suivre en versions des liens symboliques et de prendre en compte automatiquement des URL, ainsi qu'une interface utilisateur régionalisée.
La version 1.2 introduisit la possibilité de créer des verrous sur les fichiers côté serveur, sérialisant ainsi l'accès des propagations à certaines ressources. Bien que Subversion soit toujours fondamentalement un système de gestion de versions à accès simultanés, certains types de fichiers binaires (par exemple des images de synthèse) ne peuvent pas être fusionnés. Le mécanisme de verrouillage répond aux besoins de suivi en versions et de protection de ces données. Avec le verrouillage est également apparue une implémentation complète de l'auto-versionnement WebDAV, permettant aux dépôts Subversion d'être accessibles sous la forme de dossiers partagés sur le réseau. Enfin, Subversion 1.2 commença à utiliser un nouvel algorithme plus rapide de différenciation de données binaires pour compresser et récupérer de vieilles versions de fichiers.
Avec la version 1.3, le serveur svnserve sait contrôler les droits en fonction des chemins, ce qui correspondait à une fonctionnalité existant uniquement à cette époque dans le serveur Apache. Cependant, le serveur Apache bénéficia lui-même de nouvelles fonctionnalités de journalisation et les API de connexion entre Subversion et d'autres langages firent également de grands pas en avant.
En version 1.4 fut introduit un tout nouvel outil, svnsync, permettant la réplication, dans une seule direction, d'un dépôt via le réseau. Des parties importantes des métadonnées des copies de travail changèrent de format afin de ne plus utiliser XML (avec pour conséquence des gains en rapidité côté client), tandis que le gestionnaire de base de données des dépôts Berkeley DB acquit la capacité de rétablir les bases automatiquement suite à un crash du serveur.
Sortir la version 1.5 prit beaucoup plus de temps que les autres versions, mais la fonctionnalité vedette était titanesque : le suivi semi-automatisé des branches et des fusions. Ce fut une véritable bénédiction pour les utilisateurs et propulsa Subversion bien au-delà des possibilités de CVS, le plaçant à la hauteur de ses concurrents commerciaux tels que Perforce et Clearcase. En version 1.5 tout un tas d'autres fonctionnalités axées sur l'utilisateur furent introduites, telles que la résolution interactive des conflits entre fichiers, les extractions partielles, la gestion des listes de modifications côté client, une nouvelle syntaxe très puissante pour les définitions externes et le support par le serveur svnserve de l'authentification par SASL.
La version 1.6 renforça la gestion des branches et des fusions en introduisant la notion de conflits d'arborescences. Elle améliorait également plusieurs fonctionnalités déjà existantes : davantage d'options pour la résolution interactive des conflits, support d'exclusions pour les extractions partielles, définitions externes à partir de fichiers, journalisation opérationnelle pour la commande svnserve similaire à celle fournie par mod_dav_svn. Par ailleurs, le client texte interactif introduisit de nouveaux raccourcis pour référencer les URL de dépôts Subversion.
La version 1.7 constituait en premier lieu un moyen de livrer deux grosses évolutions à des composants un peu vieillissants de Subversion. Celle ayant le plus d'impact s'appelait « WC-NG » ; une réécriture complète de la bibliothèque libsvn_wc de gestion des copies de travail. La deuxième évolution était l'introduction d'un protocole HTTP plus léger pour l'interaction entre le client et le serveur Subversion. Subversion 1.7 offrait une poignée de nouvelles fonctionnalités, beaucoup de résolutions de bugs et aussi quelques notables améliorations de performances.
Dans la version 1.8, le client Subversion améliore le suivi
des renommages de fichiers et de répertoires ; la commande
svn merge a suffisamment muri pour rendre
l'utilisation de l'option --reintegrate
inutile. Certaines nouvelles valeurs de propriétés suivies en
versions peuvent être héritées des dossiers parents. Cette
fonctionnalité permet maintenant de fixer des valeurs par
défaut pour la définition des propriétés automatiques et les
motifs de noms de fichiers à ignorer, ce qui apporte de la
cohérence pour tous les utilisateurs d'un dépôt alors que,
auparavant, cela devait se gérer de manière collaborative. Il
intègre aussi un nouvel outil de fusion en ligne de commande
pour la résolution interactive des conflits. Et comme toujours,
Subversion 1.8 inclut beaucoup de fonctionnalités
supplémentaires, la résolution de bugs et des améliorations
dans le comportement et les performances.
Ce livre est écrit pour les personnes désirant utiliser Subversion pour gérer leurs données. Subversion fonctionne sur un grand nombre de systèmes d'exploitation et son interface première est en ligne de commande. Ce programme (svn) et certains programmes auxiliaires sont le sujet de ce livre.
Par souci de cohérence, les exemples du livre supposent que le
lecteur utilise un système de type Unix et qu'il est relativement
à l'aise avec ce système ainsi qu'avec les interfaces en ligne de
commande. Cela dit, le programme svn fonctionne
également sur les systèmes qui ne sont pas basés sur Unix, tel que
Microsoft Windows. Avec quelques petites exceptions, telles que
l'utilisation d'anti-slashs (\
) au lieu de
slashs (/
) dans les chemins, les entrées et
sorties de ce programme sous Windows sont identiques à leurs
équivalentes Unix.
La plupart des lecteurs sont probablement des programmeurs ou des administrateurs systèmes qui ont besoin de suivre les changements faits à du code source. C'est l'utilisation la plus courante de Subversion et c'est ce que l'on supposera tout au long des exemples du livre. Cependant, Subversion peut être utilisé pour gérer les changements pour toutes sortes de données : images, musique, bases de données, documentation, etc. Pour Subversion, toutes les données sont juste des données.
Bien que ce livre soit écrit en supposant que le lecteur n'a jamais utilisé un système de gestion de versions, nous avons aussi essayé de rendre facile le passage de CVS (et autres systèmes) à Subversion. De temps en temps, quelques encadrés mentionnent d'autres systèmes de gestion de versions et l'Annexe B, Guide Subversion à l'usage des utilisateurs de CVS résume la plupart des différences entre CVS et Subversion.
Notez également que les exemples de code source présentés au cours du livre ne sont que des exemples. Même s'ils compilent avec les commandes de compilation adéquates, ils n'ont pour but que d'illustrer une situation particulière et ne sont pas nécessairement de bons exemples de style ou techniques de programmation.
Les manuels techniques doivent toujours faire face au dilemme suivant : choisir une approche d'apprentissage descendante ou ascendante pour le lecteur ? Un adepte de l'approche descendante préférera lire ou survoler la documentation, pour obtenir une vision globale du fonctionnement du système ; à partir de ce moment seulement, il commence à utiliser le logiciel. Un adepte de l'approche ascendante est plus un autodidacte, il se jette directement dans le logiciel et en comprend au fur et à mesure les fonctionnalités, se référant au manuel en tant que de besoin. La plupart des livres sont écrits pour un certain type de lecteur et celui-ci est indubitablement orienté pour les adeptes de l'approche descendante (d'ailleurs, si vous lisez ce chapitre, c'est que vous êtes probablement dans cette catégorie !). Mais si vous êtes autodidacte, ne fuyez pas. Bien que le livre puisse être vu comme un large survol des fonctionnalités de Subversion, le contenu de chaque paragraphe est gorgé d'exemples et d'exercices pratiques. Pour les plus impatients, rendez-vous directement à l' Annexe A, Guide de démarrage rapide avec Subversion.
Quelle que soit votre manière d'apprendre, ce livre se veut utile pour des gens ayant des parcours et des compétences très variés, depuis le novice en gestion de versions jusqu'à l'administrateur système expérimenté. En fonction de votre expérience, certains chapitres vous sembleront plus ou moins importants. Nous proposons ci-dessous quelques « parcours » adaptés à différents types de lecteurs :
Nous supposons dans ce cas que vous avez déjà utilisé un système de gestion de versions et que vous voulez monter un serveur Subversion le plus rapidement possible. Le Chapitre 5, Administration d'un dépôt et le Chapitre 6, Configuration du serveur expliquent comment créer votre premier dépôt et le mettre à disposition sur le réseau. Ceci fait, le Chapitre 2, Utilisation de base et l'Annexe B, Guide Subversion à l'usage des utilisateurs de CVS sont le plus court chemin pour apprendre à utiliser le client Subversion.
Votre administrateur vient probablement de mettre en place Subversion et vous devez apprendre à utiliser le client. Si vous n'avez jamais utilisé de système de gestion de versions, alors le Chapitre 1, Notions fondamentales est une introduction indispensable aux concepts de la gestion de versions. Le Chapitre 2, Utilisation de base est un tour du propriétaire du client Subversion.
Que vous soyez utilisateur ou administrateur, votre projet va finir par prendre de l'importance. Il vous faudra apprendre comment effectuer des opérations plus pointues avec Subversion, comme utiliser des branches ou effectuer des fusions (Chapitre 4, Gestion des branches), utiliser les propriétés des objets Subversion (Chapitre 3, Sujets avancés), configurer les options d'exécution (Chapitre 7, Personnalisation de Subversion) et d'autres choses encore. Ces chapitres ne sont pas indispensables au début, mais pensez bien à les lire une fois que vous vous sentirez à l'aise avec les bases.
Vous êtes certainement déjà habitué à Subversion et vous voulez à présent étendre ses fonctionnalités ou développer un nouveau logiciel utilisant ses nombreuses API. Le Chapitre 8, Intégration de Subversion est écrit pour vous.
Le livre se termine par le Partie II, « Guide de référence des commandes Subversion ». C'est le guide de référence pour toutes les commandes de Subversion, les annexes couvrant certaines notions particulièrement utiles. Ce sont certainement les chapitres vers lesquels vous retournerez une fois la première lecture terminée.
Les chapitres qui suivent, ainsi que leur contenu, sont listés ci-dessous :
Explique les bases de la gestion de versions ainsi que les différents modèles associés, les notions de dépôts Subversion, de copies de travail et de révisions.
Une balade dans l'utilisation quotidienne de Subversion. Ce chapitre explique comment récupérer, modifier et propager des données à l'aide du client Subversion.
Ce chapitre couvre des fonctionnalités plus complexes, que les utilisateurs réguliers auront à utiliser un jour, comme les métadonnées suivies en versions, le verrouillage de fichiers et les piquets de révisions.
Ce chapitre traite des branches, des fusions et des étiquettes, y compris les bonnes pratiques pour la gestion et la fusion de branches, des cas d'école, comment revenir en arrière sur des modifications et comment passer facilement d'une branche à une autre.
Ce chapitre décrit les bases d'un dépôt Subversion, comment le créer, le configurer et en assurer la maintenance. Il présente également les outils disponibles pour toutes ces actions.
Ce chapitre explique comment configurer votre serveur
Subversion et présente différentes manières d'accéder à
votre dépôt : HTTP
, le protocole
svn
et l'accès au disque en local. Il
couvre aussi l'authentification, les autorisations et les
accès anonymes.
Ce chapitre explore les fichiers de configuration du client Subversion, décrit la prise en compte des contenus internationaux et montre comment utiliser des programmes externes conjointement avec Subversion.
Ce chapitre décrit l'architecture interne de Subversion, le système de fichiers associé et les zones administratives des copies de travail, du point de vue du programmeur. Il montre comment utiliser les API publiques pour écrire un programme qui utilise Subversion.
Ce chapitre explique de manière très détaillée chacune des sous-commandes svn, svnadmin et svnlook avec tout un tas d'exemples pour contenter l'ensemble de la famille !
Pour les impatients, l'installation de Subversion et son utilisation en moins de deux minutes chrono. Vous êtes prévenu.
Cette annexe couvre les similitudes et les différences entre Subversion et CVS, avec des suggestions pour perdre les mauvaises habitudes que vous avez acquises durant des années d'utilisation de CVS. Cela comprend les descriptions des numéros de révision de Subversion, les répertoires suivis en versions, les opérations sans connexion réseau, la distinction entre status et update, les branches, les étiquettes, les métadonnées, la résolution de conflits et l'authentification.
Cette annexe décrit en détail WebDAV et DeltaV ; elle explique comment configurer votre dépôt Subversion pour qu'il puisse être monté en lecture/écriture par des clients DAV.
Cette annexe contient une copie de la Licence Creative Commons dont ce livre fait l'objet.
Ce livre est parti de quelques morceaux de documentation écrits par les développeurs du projet Subversion, qui furent alors fusionnés en un seul travail et réécrits. En tant que tel, il a toujours été sous licence libre (cf. l'Annexe E, Copyright). En fait, le livre a été écrit sous le regard du public, faisant au départ partie intégrante du projet Subversion. Cela veut dire deux choses :
Vous trouverez toujours la version la plus récente de ce livre dans le propre dépôt Subversion du livre.
Vous pouvez modifier ce livre et le redistribuer comme vous le voulez, il est sous licence libre. Votre seule obligation est de conserver correcte l'attribution du copyright aux auteurs d'origine. Bien sûr, nous préférerions que vous envoyiez vos commentaires et vos correctifs à la communauté des développeurs Subversion, plutôt que de distribuer votre version privée de ce livre.
Le portail internet de développement de ce livre, et de la
plupart de ses traductions, est accessible à l'adresse :
https://svnbook.red-bean.com. Vous y trouverez des
liens sur les dernières parutions et les versions étiquetées du
livre dans différents formats, ainsi que des instructions pour
accéder au dépôt Subversion du livre (où se trouve son code source
XML DocBook). Vos réactions sont les bienvenues et même
encouragées. Prière de soumettre tous vos commentaires,
réclamations et correctifs concernant les sources du livre à
<svnbook-dev@red-bean.com>
.
Ce livre n'aurait pas été possible (ni très utile) si Subversion n'existait pas. C'est pourquoi les auteurs tiennent à remercier Biran Behlendorf et CollabNet pour avoir vu l'intérêt et avoir osé investir dans un nouveau projet de logiciel libre aussi risqué et ambitieux ; Jim Blandy pour le nom et le design original de Subversion, on t'aime Jim ; et Karl Fogel pour être, surtout, un si bon ami et, ensuite, un grand leader pour la communauté. [4]
Merci à O'Reilly et aux différents professionnels de l'édition qui nous ont aidés à rendre le contenu de ce livre plus attrayant à différentes étapes de sa construction : Chuck Toporek, Linda Mui, Tatiana Apandi, Mary Brady et Mary Treseler. Leur patience et leur soutien ont été extraordinaires.
Enfin, nous remercions le nombre incalculable de personnes qui ont contribué à ce livre par des relectures informelles, des suggestions et des corrections. La liste exhaustive de ces personnes serait impossible à imprimer et à maintenir ici, mais que leurs noms restent à jamais gravés dans l'historique de la gestion de versions de ce livre !
[1] Nous y ferons référence simplement par « Subversion » dans ce livre. Vous nous remercierez quand vous vous rendrez compte de l'espace que cela a économisé !
[2] Ou comme le dit un de mes amis, c'est « tuer les mouches à coup de canon ».
[3] CollabNet Enterprise Edition a depuis été remplacé par une nouvelle ligne de produits appelée Collabnet TeamForge
[4] Et puis merci, Karl, d'être trop occupé pour rédiger ce livre toi-même.
Ce chapitre est une introduction rapide à Subversion et de son approche de la gestion de versions. Nous allons commencer par une présentation des notions générales de la gestion de versions, puis étudier plus précisément les idées particulières qui se cachent derrière Subversion et enfin donner quelques exemples simples d'utilisation de Subversion.
Même si les exemples de ce chapitre mettent en scène des personnes partageant du code source, gardez à l'esprit que Subversion peut gérer n'importe quel type d'ensemble de fichiers, il n'est pas réservé aux programmeurs.
Un système de gestion de versions (ou de contrôle de versions) est un système qui garde une trace de toutes les versions (ou révisions) des fichiers et, dans certains cas, des répertoires au cours du temps. Bien sûr, simplement garder la trace de toutes les modifications apportées par un utilisateur (ou un groupe d'utilisateurs) à des fichiers et des répertoires n'est pas intéressant en tant que tel. Ce qui définit l'utilité d'un système de gestion de versions est la possibilité d'examiner les modifications apportées par chaque changement et de faciliter le retour vers n'importe quelle version.
Dans cette section, nous allons introduire des notions et des outils de haut-niveau pour la gestion de versions. Nous limiterons notre exposé aux systèmes modernes de gestions de versions— dans notre monde connecté actuel, il est de peu d'intérêt de s'attarder sur les systèmes qui ne peuvent pas fonctionner au travers des grands réseaux.
Le dépôt constitue le cœur d'un système de gestion de versions ; c'est le lieu de stockage central des données gérées. Généralement, les informations y sont organisées sous la forme d'une arborescence de fichiers, c'est-à-dire une hiérarchie classique de fichiers et de répertoires. Un certain nombre de clients se connectent au dépôt, et parcourent ou modifient ces fichiers. En modifiant des données, un client rend ces informations disponibles aux autres clients ; en lisant des données, le client reçoit des informations des autres clients. La Figure 1.1, « Un authentique système client/serveur » illustre cela.
Quel est l'intérêt ? Jusque-là, cela ressemble à la définition d'un serveur de fichiers classique. En fait, le dépôt est bien une sorte de serveur de fichiers, mais d'un type particulier. Ce qui rend le dépôt spécial, c'est qu'il se souvient de toutes les versions de chacun des fichiers.
Quand un client parcourt le dépôt, il consulte généralement la dernière version de l'arborescence du système de fichiers. Mais, et c'est là l'intérêt d'un système de gestion de versions, le client est également capable de demander au dépôt les états antérieurs du système de fichiers. Par exemple, un client peut poser des questions concernant l'historique des données, comme « Que contenait ce répertoire mercredi dernier ? » ou « Quelle est la dernière personne qui a modifié ce fichier, et quels changements a-t-elle effectués ? ». C'est le genre de questions qui est au cœur de tout logiciel de gestion de versions.
La plus-value d'un système de gestion de versions provient de sa capacité à garder une trace de toutes les versions des fichiers et répertoires, mais les autres logiciels n'intègrent pas cette notion de « versions de fichiers et répertoires ». La plupart des logiciels ne savent manipuler qu'une seule version d'un type de fichier. Alors, comment l'utilisateur du système de gestion de versions interagit-il concrètement avec un dépôt abstrait — et souvent distant — plein de multiples versions des différents fichiers ? Comment son traitement de textes, son logiciel de présentation, son éditeur de code source ou de site web, ou n'importe quel autre logiciel peut-il avoir accès à ces fichiers suivis en versions ? La réponse se trouve dans ce que la gestion de versions appelle la copie de travail.
Une copie de travail est, littéralement, une copie locale d'une version particulière des données gérées en versions par l'utilisateur, sur laquelle il est libre de travailler. Les copies de travail[5] sont vus par les autres logiciels comme n'importe quel autre répertoire rempli de fichiers, ainsi ces programmes n'ont pas besoin d'être « conscients » de la gestion de versions pour lire ou écrire des données dans ces fichiers. C'est le rôle du logiciel de gestion de versions de prendre en compte et communiquer les modifications du contenu de la copie de travail ou du dépôt.
Si la mission première d'un logiciel de gestion de versions est de tracer l'historique des différentes versions dans le temps des données numériques, une seconde mission concomitante dans n'importe quel gestionnaire de versions moderne consiste à permettre l'édition collaborative et le partage de ces données. Mais il existe différentes stratégies pour arriver à cette fin. Comprendre ces différentes stratégies est important à plusieurs titres. Tout d'abord, cela vous aidera à comparer et différencier les logiciels de gestion de versions existants, au cas où vous rencontriez d'autres logiciels similaires à Subversion. Ensuite, cela vous aidera également à utiliser plus efficacement Subversion, puisque Subversion lui-même autorise différentes façons de travailler.
Tous les logiciels de gestion de versions doivent résoudre le même problème fondamental : comment le logiciel va-t-il permettre aux utilisateurs de partager l'information, tout en les empêchant de se marcher mutuellement sur les pieds par accident ? Il est vraiment trop facile pour les utilisateurs d'écraser malencontreusement les changements effectués par d'autres dans le dépôt.
Observons le scénario décrit à la Figure 1.2, « La situation à éviter ». Supposons que nous ayons deux collaborateurs, Harry et Sally. Ils décident tous les deux d'éditer au même moment le même fichier dans le dépôt. Si Harry sauvegarde ses modifications dans le dépôt en premier, il est possible que, quelques instants plus tard, Sally les écrase avec sa propre version du fichier. Bien que la version de Harry ne soit pas perdue pour toujours, car le système se souvient de tous les changements, aucune des modifications effectuées par Harry n'est présente dans la nouvelle version du fichier de Sally, car elle n'a jamais vu les changements réalisés par Harry. De fait, le travail de Harry est perdu ou, du moins, perdu dans la version finale du fichier, et ceci probablement par accident. Il s'agit précisément d'une situation que nous voulons à tout prix éviter !
De nombreux logiciels de gestion de versions utilisent le modèle verrouiller-modifier-libérer pour résoudre le problème de plusieurs auteurs annihilant le travail des autres. Dans ce modèle, le dépôt ne permet qu'à une seule personne de modifier un fichier à un instant donné. Cette politique exclusive est gérée grâce à des verrous (lock en anglais). Harry doit « verrouiller » un fichier avant de commencer à le modifier. Si Harry a verrouillé un fichier, alors Sally ne peut pas le verrouiller et ne peut donc faire aucun changement dessus. Tout ce qu'elle peut faire, c'est lire le fichier et attendre que Harry ait fini ses changements puis libéré le verrou. Après que Harry ait libéré le fichier, Sally pourra à son tour le verrouiller et l'éditer. La Figure 1.3, « Modèle verrouiller-modifier-libérer » illustre cette solution très simple.
Le problème avec le modèle verrouiller-modifier-libérer est qu'il est relativement restrictif et devient souvent un barrage pour les utilisateurs :
Le verrouillage peut créer des problèmes d'administration. Parfois, Harry va verrouiller un fichier et oublier qu'il l'a fait. Pendant ce temps, Sally, qui est encore en train d'attendre pour éditer le fichier, est bloquée. Puis Harry part en vacances. Sally doit alors aller trouver un administrateur pour libérer le verrou de Harry. La situation finit par générer beaucoup de délais inutiles et de temps perdu.
Le verrouillage peut créer une sérialisation inutile. Que se passe-t-il lorsque Harry veut éditer le début d'un fichier texte et que Sally veut simplement éditer la fin de ce même fichier ? Ces changements ne se chevauchent pas du tout. Ils pourraient aisément éditer le fichier simultanément et il n'y aurait pas beaucoup de dégâts, en supposant que les changements soient correctement fusionnés. Dans cette situation, il n'est pas nécessaire de les forcer à éditer le fichier chacun à leur tour.
Le verrouillage peut créer un faux sentiment de sécurité. Supposons que Harry verrouille et édite le fichier A, alors qu'au même moment Sally verrouille et édite le fichier B. Que se passe-t-il si A et B dépendent l'un de l'autre et que les changements faits à chacun sont incompatibles d'un point de vue sémantique ? A et B ne fonctionnent soudainement plus ensemble. Le système de verrouillage a été incapable d'empêcher ce problème, bien qu'il ait d'une certaine manière instillé un faux sentiment de sécurité. Il est facile pour Harry et Sally d'imaginer qu'en verrouillant les fichiers, chacun commence une tâche isolée, sans danger et donc que ce n'est pas la peine de discuter à l'avance de leurs modifications incompatibles. Verrouiller devient souvent un substitut à une réelle communication.
Subversion, CVS et beaucoup d'autres logiciels de gestion de versions utilisent le modèle copier-modifier-fusionner comme alternative au verrouillage. Dans ce modèle, chaque utilisateur contacte le dépôt du projet via son client et crée une copie de travail personnelle, une sorte de version locale des fichiers et répertoires du dépôt. Les utilisateurs peuvent alors travailler, simultanément et indépendamment les uns des autres, et modifier leurs copies privées. Pour finir, les copies privées sont fusionnées au sein d'une nouvelle version finale. Le logiciel de gestion de versions fournit de l'aide afin de réaliser cette fusion, mais au final la responsabilité de s'assurer que tout se passe bien incombe à un être humain.
Voici un exemple. Supposons que Harry et Sally aient créé chacun des copies de travail du même projet, copiées à partir du dépôt. Ils travaillent simultanément et effectuent sur leur copie des modifications du même fichier A. Sally sauvegarde ses changements dans le dépôt en premier. Lorsque Harry essaie par la suite de sauvegarder ses modifications, le dépôt l'informe que son fichier A est périmé. En d'autres termes, le fichier A du dépôt a changé, d'une façon ou d'une autre, depuis la dernière fois qu'il l'avait copié. Harry demande donc à son client de fusionner tous les changements en provenance du dépôt dans sa copie de travail du fichier A. Il y a des chances que les modifications de Sally n'empiètent pas sur les siennes ; une fois qu'il a intégré les changements provenant des deux côtés, il sauvegarde sa copie de travail dans le dépôt. La Figure 1.4, « Modèle copier-modifier-fusionner » et la Figure 1.5, « Modèle copier-modifier-fusionner (suite) » illustrent ce processus.
Mais que se passe-t-il quand les modifications de Sally empiètent sur celles de Harry ? Que fait-on dans ce cas-là ? Cette situation est appelée un conflit et ne constitue pas, en général, un gros problème. Lorsque Harry demande à son logiciel client de fusionner les changements les plus récents du dépôt dans sa copie de travail, sa copie du fichier est en quelque sorte marquée comme étant dans un état de conflit : il a la possibilité de voir les deux ensembles de changements entrant en conflit et de choisir manuellement entre les deux. Notez bien qu'un logiciel ne peut pas résoudre automatiquement les conflits ; seuls les humains sont capables de comprendre et de faire les choix intelligents nécessaires. Une fois que Harry a manuellement résolu les modifications se chevauchant, par exemple après une discussion avec Sally, il peut sauvegarder le fichier fusionné en toute sécurité dans le dépôt.
Le modèle copier-modifier-fusionner peut sembler un peu chaotique mais, en pratique, il fonctionne de façon très fluide. Les utilisateurs peuvent travailler en parallèle, sans jamais devoir s'attendre les uns les autres. Lorsqu'ils travaillent sur les mêmes fichiers, il s'avère que la plupart des changements réalisés en parallèle ne se chevauchent pas du tout ; les conflits sont rares. Et le temps nécessaire à la résolution des conflits est en général bien inférieur au temps gaspillé par un système de verrouillage.
Au final, tout revient à un facteur critique : la communication entre les utilisateurs. Lorsque les utilisateurs communiquent mal, les conflits syntaxiques et sémantiques augmentent. Aucun système ne peut forcer les utilisateurs à communiquer parfaitement et aucun système ne peut détecter les conflits sémantiques. Il n'y a donc aucun intérêt à se laisser endormir par un faux sentiment de sécurité selon lequel un système de verrouillage permettrait d'éviter les conflits ; en pratique, le verrouillage semble limiter la productivité plus qu'aucun autre facteur.
Nous avons déjà indiqué que Subversion est un logiciel de gestion de versions moderne et en réseau. Comme décrit dans la section intitulée « Notions générales de la gestion de versions », un dépôt sert de cœur de stockage pour les données suivies en versions et c'est par l'intermédiaire de copies de travail que les utilisateurs et les logiciels qu'ils manipulent interagissent avec les données. Dans cette section, nous allons commencer par introduire les différentes manières dont Subversion implémente la gestion de versions.
Subversion implémente le concept de dépôt comme tout autre logiciel de gestion de versions moderne. Contrairement à une copie de travail, un dépôt Subversion est une entité abstraite qui ne peut être manipulée pratiquement que par les bibliothèques et les propres outils de Subversion. Comme la plupart des interactions d'un utilisateur de Subversion se font par l'intermédiaire du client Subversion et qu'elles ont lieu dans le contexte de la copie de travail, ce livre traite en une grande partie de la copie de travail et des actions que l'on peut y appliquer. Pour les détails du dépôt, vous pouvez cependant vous référer au Chapitre 5, Administration d'un dépôt.
Avertissement | |
---|---|
Dans Subversion, l'entité que possède chaque utilisateur du logiciel — le répertoire des fichiers suivis en versions ainsi que les métadonnées qui permettent au système de tracer les données et de communiquer avec le serveur — s'appelle la copie de travail. Bien que d'autres logiciels de gestion de versions utilisent le terme de « dépôt » pour l'entité côté client, c'est à la fois incorrect et une source fréquente de confusion d'utiliser ce terme dans ce sens là dans le contexte de Subversion. Les copies de travail sont abordées plus loin, dans la section intitulée « Copies de travail ». |
Une opération svn commit propage (c'est-à-dire communique au serveur) les modifications d'un nombre quelconque de fichiers et de répertoires en une seule opération atomique. Par opération atomique, nous entendons que, soit toutes les modifications sont prises en compte par le dépôt, soit rien n'est pris en compte. Subversion essai d'être robuste dans ce concept d'atomicité, même en cas de plantage du programme, du système, de problèmes réseau ou d'actions de la part des autres utilisateurs.
Chaque fois que le dépôt accepte une propagation (c'est-à-dire une opération svn commit), il crée un nouvel état de l'arborescence du système de fichiers que l'on appelle révision. À Chaque révision est associé un entier naturel unique, immédiatement supérieur à l'entier associé à la révision précédente. La révision initiale d'un dépôt nouvellement créé à pour numéro 0 et n'est constituée que d'un répertoire racine vide.
La Figure 1.6, « L'évolution de l'arborescence au cours du temps » illustre une manière intéressante de se représenter le dépôt. Imaginez un tableau de numéros de révisions, commençant à zéro et s'étirant de la gauche vers la droite. À Chaque numéro de révision est suspendue une arborescence du système de fichiers, qui est une photo, un « instantané » (snapshot en anglais) du dépôt prise après une propagation.
les logiciels côté client de Subversion utilisent des URL pour identifier les fichiers et répertoires suivis en versions dans les dépôts Subversion. Pour leur grande partie, ces URL utilisent la syntaxe standard, permettant de spécifier le nom du serveur et le numéro de port directement dans l'URL.
Les URL de dépôts Subversion ne se limitent pas au domaine
http://
. Comme Subversion permet à ses
clients de dialoguer de différentes manières avec les dépôts,
les URL utilisées pour se connecter diffèrent subtilement en
fonction du protocole employé. La
Tableau 1.1, « Les différents motifs d'URL pour l'accès aux dépôts » décrit la
correspondance entre les différents motifs d'URL et les méthodes
d'accès aux dépôts. Pour plus de détails sur les options du
serveur Subversion, reportez-vous au
Chapitre 6, Configuration du serveur.
Tableau 1.1. Les différents motifs d'URL pour l'accès aux dépôts
Schéma | Méthode d'accès |
---|---|
file:/// | Accès direct au dépôt (sur disque local) |
http:// | Accès par protocole WebDAV sur un serveur Apache disposant d'un connecteur Subversion |
https:// | Comme http:// , avec une
encapsulation SSL |
svn:// | Accès via un protocole personnalisé à un
serveur svnserve |
svn+ssh:// | Comme svn:// , avec une
encapsulation dans un tunnel SSH |
La gestion des URL par Subversion possède quelques particularités
qu'il convient de noter. Par exemple, les URL contenant la méthode
d'accès file://
(utilisée pour les dépôts locaux)
doivent spécifier, par convention, soit le nom de serveur
localhost
, soit pas de nom de
serveur :
D'autre part, les utilisateurs du procédé
file://
sur les plateformes Windows doivent
se servir d'une syntaxe qui est un « standard »
officieux pour accéder à leurs dépôts se trouvant sur la même
machine mais sur un disque différent du disque de travail
habituel du client. Les deux syntaxes de chemin d'URL suivantes
fonctionnent, X
étant le disque sur lequel
le dépôt se trouve :
Remarquez qu'une URL utilise des barres obliques
(/
) alors que la forme native (non-URL) d'un
chemin sous Windows utilise des barres obliques inversées
(\
).
Notez aussi que, dans la seconde syntaxe, vous devez entourer
l'URL de guillemets pour éviter que la barre verticale ne soit
interprétée comme un symbole de redirection (un
« pipe »).
Note | |
---|---|
Les URL Subversion |
Il faut noter que le client Subversion encode
automatiquement les URL en cas de besoin, exactement
comme le fait un navigateur web. Par exemple, l'URL
http://host/path with space/project/españa
— qui contient à la fois des espaces et des caractères
non ASCII— est automatiquement interprétée par Subversion
comme si vous aviez fourni
http://host/path%20with%20space/project/espa%C3%B1a
.
Si l'URL contient des espaces, prenez bien soin de les placer
entre guillemets dans la ligne de commande afin que le shell
traite le tout comme un unique argument du programme.
Il existe aussi une exception à la gestion des URL par
Subversion qui s'applique à la gestion des chemins locaux dans
beaucoup de contextes. Si le dernier élément de l'URL
ou du chemin contient le signe arobase (@
),
vous devez utiliser une syntaxe particulière, décrite dans
la section intitulée « Révisions pivots et révisions opérationnelles », afin que Subversion
prenne proprement en compte l'adresse de cette ressource.
Dans Subversion 1.6, une nouvelle notation, dite
syntaxe avec chapeau (^
) a été
introduite comme raccourci pour « l'URL du répertoire
racine du dépôt ». Par exemple, vous pouvez utiliser
^tags/gros-sandwich
pour désigner l'URL du
répertoire /tags/gros-sandwich
à la racine
du dépôt. Une telle URL est appelée URL
relative au dépôt. Remarquez que cette syntaxe d'URL
ne fonctionne que si votre répertoire de travail est une copie
de travail, le client texte interactif récupérant l'URL
de la racine du dépôt dans les métadonnées de la copie de
travail. Notez aussi que lorsque vous voulez faire référence
précisément au répertoire racine du dépôt, vous devez utiliser
^/
(avec la barre oblique terminale) et non
simplement ^
. Les utilisateurs sous Windows
ne doivent pas oublier que le caret est un caractère
d'échappement pour ce système. En conséquence, vous devez
utiliser un double caret ^^
si votre client
Subversion tourne sur une machine Windows.
Une copie de travail Subversion est une arborescence classique de répertoires de votre système local, contenant un ensemble de fichiers. Vous pouvez éditer ces fichiers comme vous le voulez et, s'il s'agit de code source, vous pouvez compiler votre programme à partir de ceux-ci de la façon habituelle. Votre copie de travail est votre espace de travail personnel privé : Subversion n'y incorpore jamais les changements d'autres personnes ni ne rend jamais disponibles vos propres changements à d'autres personnes tant que vous ne lui demanderez pas explicitement de le faire. Vous pouvez même avoir plusieurs copies de travail d'un même projet.
Après que vous ayez apporté quelques modifications aux fichiers de votre copie de travail et vérifié qu'elles fonctionnent correctement, Subversion vous fournit des commandes pour « publier » vos changements vers les autres personnes qui travaillent avec vous sur votre projet (en les transmettant au dépôt). Si d'autres personnes publient leurs propres modifications, Subversion vous fournit des commandes pour fusionner ces changements dans votre copie de travail (en les obtenant du dépôt). Remarquez que le dépôt central joue le rôle d'intermédiaire pour les changements de tout le monde dans Subversion ; les modifications ne passent pas directement d'une copie de travail à une autre copie de travail dans le processus classique.
Une copie de travail contient également quelques
fichiers supplémentaires, créés et gérés par Subversion, pour
l'aider à effectuer ces opérations. En particulier, chaque
copie de travail contient un sous-répertoire nommé
.svn
, aussi connu sous l'appellation de
répertoire administratif de votre copie
de travail. Les fichiers de ce répertoire administratif
permettent à Subversion d'identifier quels fichiers contiennent
des modifications non-publiées et quels fichiers sont périmés
vis-à-vis du travail des autres personnes.
Note | |
---|---|
Avant la version 1.7, Subversion plaçait un répertoire
|
Pour chaque fichier d'un répertoire de travail, Subversion
enregistre deux informations essentielles dans la zone
administrative .svn/
:
la révision sur laquelle votre fichier de travail est basé (qui est appelée la révision de travail du fichier) et
la date et l'heure de la dernière mise à jour de la copie locale depuis le dépôt
À partir de ces informations, en dialoguant avec le dépôt, Subversion est capable de déterminer dans lequel des quatre états suivants se trouve un fichier de travail
Le fichier est inchangé dans le répertoire de travail et aucune modification de ce fichier n'a été propagée vers le dépôt depuis sa révision de travail. Un appel à svn commit sur le fichier ne fait rien, un appel à svn update sur le fichier ne fait rien non plus.
Le fichier a été modifié dans le répertoire de travail et aucune modification du fichier n'a été propagée dans le dépôt depuis la dernière mise à jour. Il existe des modifications locales qui n'ont pas été propagées vers le dépôt, donc un appel à svn commit sur le fichier permet de publier vos modifications et un appel à svn update ne fait rien.
Le fichier n'a pas été modifié dans le répertoire de travail mais a changé dans le dépôt. Le fichier devra être mis à jour à un moment ou à un autre, pour l'amener au niveau de la dernière révision publique. Un appel à svn commit sur le fichier ne fait rien et un appel à svn update incorpore les dernières modifications dans votre copie de travail.
Le fichier a été modifié à la fois dans le répertoire de travail et dans le dépôt. Un appel à svn commit sur le fichier va échouer, renvoyant comme erreur « Périmé » (out-of-date en anglais). Le fichier doit d'abord être mis à jour ; un appel à svn update va tenter de fusionner les modifications publiques avec les modifications locales. Si Subversion ne parvient pas à réaliser automatiquement cette fusion de manière crédible, il va laisser à l'utilisateur le soin de résoudre le conflit.
Un dépôt Subversion contient bien souvent les fichiers (ou code source) de plusieurs projets ; habituellement, chaque projet est un sous-répertoire de l'arborescence du système de fichiers du dépôt. Dans cette situation, la copie de travail d'un utilisateur correspond à une sous-arborescence particulière du dépôt.
Par exemple, supposons que votre dépôt contienne deux
projets logiciels, paint
et
calc
. Chaque projet réside dans son propre
sous-répertoire racine, comme indiqué dans la Figure 1.7, « Système de fichiers du dépôt ».
Pour obtenir une copie de travail, vous devez
extraire une sous-arborescence du
répertoire (le terme « extraire »,
check out en anglais, peut vous
faire penser que cela a quelque chose à voir avec verrouiller
ou réserver des ressources, mais ce n'est pas le cas ;
cela crée simplement pour vous une copie privée du projet).
Par exemple, si vous extrayez /calc
, vous
obtenez une copie de travail qui ressemble à
ceci :
$ svn checkout http://svn.exemple.com/depot/calc A calc/Makefile A calc/entier.c A calc/bouton.c Révision 56 extraite. $ ls -A calc Makefile bouton.c entier.c .svn/ $
Les lettres A
qui s'affichent dans la
marge de gauche indiquent que Subversion est en train
d'ajouter des éléments dans votre copie de travail. Vous avez
désormais votre copie personnelle du répertoire
/calc
du dépôt, avec une entrée
supplémentaire, .svn
, qui contient des
informations complémentaires nécessaires à Subversion, comme
évoqué précédemment.
Supposons que vous fassiez des modifications à
bouton.c
. Comme le répertoire
.svn
se souvient de la date de
modification et du contenu du fichier original, Subversion
peut en déduire que vous avez modifié le fichier. Néanmoins,
Subversion ne rend pas vos modifications publiques tant que
vous ne lui dites pas de le faire. L'action de publication de
vos modifications est plus communément appelée
propagation (« commit » ou
check in en anglais et,
parfois, archivage ou
livraison en français) des
modifications au sein du dépôt.
Pour rendre publiques vos modifications, vous pouvez utiliser la commande Subversion svn commit :
$ svn commit bouton.c -m "Coquille corrigée dans bouton.c." Ajout bouton.c Transmission des données . Révision 57 propagée. $
À présent, vos modifications de
bouton.c
ont été propagées au sein du
dépôt, avec un commentaire décrivant ces changements
(« vous avez corrigé une coquille »). Si un
autre utilisateur extrait une copie de travail de
/calc/
, il verra vos modifications dans
la dernière version du fichier.
Supposons que vous ayez une collaboratrice, Sally, qui a
extrait une copie de travail de /calc
en
même temps que vous. Lorsque vous propagez votre modification
de bouton.c
, la copie de travail de Sally
reste inchangée ; Subversion ne modifie les copies de
travail qu'à la demande des utilisateurs.
Pour mettre son projet à jour, Sally peut demander à Subversion de mettre à jour (update en anglais) sa copie de travail, en utilisant la commande svn update. Cela va intégrer vos modifications dans sa copie de travail, ainsi que celles qui ont été envoyées par d'autres personnes depuis qu'elle l'avait extraite.
$ pwd /home/sally/calc $ ls -A Makefile bouton.c entier.c .svn/ $ svn update U bouton.c Actualisé à la révision 57. $
En sortie, la commande svn update
indique que Subversion a mis à jour le contenu de
bouton.c
. Remarquez que Sally n'a pas eu
besoin de spécifier quels fichiers devaient être mis à
jour ; Subversion utilise les informations contenues dans
le répertoire .svn
, ainsi que d'autres
informations en provenance du dépôt, pour décider quels
fichiers doivent être mis à jour.
Un principe général de Subversion est d'être aussi flexible que possible. Un type particulier de flexibilité est la capacité d'avoir une copie de travail contenant des fichiers et des répertoires avec un mélange de différents numéros de révision. Les copies de travail ne correspondent pas toujours à une révision unique du dépôt elles peuvent contenir des fichiers qui sont à des révisions différentes. Par exemple, supposons que vous extrayez une copie de travail d'un dépôt dont la révision la plus récente porte le numéro 4 :
calc/
Makefile:4
entier.c:4
bouton.c:4
Tel quel, le répertoire de travail correspond exactement
à la révision 4 du dépôt. Maintenant, supposons que vous
modifiez le fichier bouton.c
et que
vous propagiez cette modification. Si aucune autre propagation
n'a eu lieu entre temps, votre propagation crée la révision
5 du dépôt et votre copie de travail ressemble à :
calc/
Makefile:4
entier.c:4
bouton.c:5
Supposons que, à ce moment ci, Sally propage une
modification à entier.c
, créant ainsi la
révision 6. Si vous faites svn update pour
mettre à jour votre copie de travail, elle ressemble
à :
calc/
Makefile:6
entier.c:6
bouton.c:6
Les modifications apportées par Sally à
entier.c
apparaissent dans votre copie
de travail et vos modifications sont toujours présentes dans
bouton.c
. Dans cet exemple, le texte de
Makefile
est identique dans les révisions
4, 5 et 6 mais Subversion marque votre copie de travail
de Makefile
comme étant à la révision 6
pour indiquer qu'elle est à jour. Ainsi, quand vous effectuez
une mise à jour au niveau de la racine de votre copie de
travail, celle-ci correspond en général à une révision
donnée du dépôt.
Une des règles fondamentales de Subversion est que l'action de « pousser » ne déclenche pas une action de « tirer », ni l'inverse. Le simple fait que vous soyez prêt à soumettre vos nouvelles modifications au dépôt ne veut pas dire que vous êtes prêts à recevoir les modifications d'autres personnes. Et si vous avez de nouvelles modifications encore en cours, alors svn update fusionne élégamment les changements du dépôt avec les vôtres, plutôt que de vous forcer à les publier.
Le principal effet secondaire de cette règle est que la copie de travail a de la comptabilité supplémentaire à effectuer pour suivre les mélanges de révision et également être tolérante vis-à-vis de l'ensemble. Cela est rendu encore plus difficile par le fait que les répertoires eux-mêmes sont suivis en versions.
Par exemple, supposons que vous ayez une copie de
travail qui soit intégralement à la révision 10. Vous éditez
le fichier truc.html
et réalisez
ensuite un svn commit qui crée la
révision 15 dans le dépôt. Après que la propagation ait
réussi, nombreux sont ceux parmi les nouveaux utilisateurs
qui s'attendraient à ce que toute la copie de travail soit à
la révision 15, mais ce n'est pas le cas ! Un certain
nombre de modifications ont pu avoir lieu dans le dépôt
entre les révisions 10 et 15. Le client ne sait rien de ces
changements qui ont été apportés au dépôt, puisque vous
n'avez pas encore exécuté la commande
svn update et la commande
svn commit ne récupère pas les
nouvelles modifications. D'un autre côté, si la commande
svn commit téléchargeait automatiquement
les modifications les plus récentes, alors il serait
possible d'avoir toute la copie de travail à la révision
15 mais, dans ce cas, nous enfreindrions la règle
fondamentale selon laquelle « pousser » et
« tirer » doivent demeurer des actions
distinctes. Ainsi, la seule chose que le client Subversion
peut faire en toute sécurité est de marquer le fichier
truc.html
, et lui seulement, comme
étant à la révision 15. Le reste de la copie de travail
reste à la révision 10. Seule l'exécution de la commande
svn update permet de récupérer les
dernières modifications et de marquer la copie de travail
comme étant à la révision 15.
Le fait est qu'à chaque fois que
vous exécutez la commande svn commit,
votre copie de travail se retrouve composée d'un mélange de
révisions. Les éléments que vous venez juste de propager
sont marqués comme ayant un numéro de révision plus élevé
que tous les autres. Après plusieurs propagations (sans
mise à jour entre-temps), votre copie de travail va contenir
tout un mélange de révisions. Même si vous êtes la seule
personne à utiliser le dépôt, vous constaterez quand même
ce phénomène. Pour étudier votre propre mélange de révisions
de travail, utilisez la commande
svn status avec l'option
--verbose
(voir la section intitulée « Vue d'ensemble des changements effectués » pour plus
d'informations).
Souvent, les nouveaux utilisateurs n'ont pas du tout conscience que leur copie de travail contient des révisions mélangées. Cela peut être déroutant car beaucoup de commandes client sont sensibles à la révision de travail de l'élément qu'elles examinent. Par exemple, la commande svn log est utilisée pour afficher l'historique des modifications d'un fichier ou d'un répertoire (cf. la section intitulée « Historique des modifications »). Lorsque l'utilisateur appelle cette commande sur un objet de la copie de travail, il s'attend à obtenir l'historique complet de celui-ci. Mais si la révision de travail de l'objet est assez ancienne (souvent parce que svn update n'a pas été lancé depuis un certain temps), alors c'est l'historique de l'ancienne version de l'objet qui est affiché.
Si votre projet est suffisamment complexe, vous allez découvrir qu'il est parfois pratique d'effectuer un retour en arrière forcé (c'est-à-dire de faire une mise à jour vers une version plus ancienne que celle que vous avez déjà) sur certaines parties de votre copie de travail vers des révisions plus anciennes ; vous apprendrez comme le faire dans le Chapitre 2, Utilisation de base. Vous avez peut-être envie de tester une version précédente d'un sous-module contenu dans un sous-répertoire ou bien de comprendre comment un bogue est apparu pour la première fois dans un fichier donné. C'est le côté « machine à voyager dans le temps » d'un logiciel de gestion de versions, la fonctionnalité qui vous permet de déplacer n'importe quelle partie de votre copie de travail en avant ou en arrière dans le temps.
Quelle que soit la façon dont vous utilisez les mélanges de révision dans votre copie de travail, il existe des limites à cette flexibilité.
Premièrement, vous ne pouvez pas propager la suppression d'un fichier ou d'un répertoire qui n'est pas complètement à jour. Si une version plus récente de l'élément existe dans le dépôt, votre tentative de suppression est rejetée, afin de vous empêcher de détruire accidentellement des modifications dont vous n'aviez pas encore connaissance.
Deuxièmement, vous ne pouvez propager la modification des métadonnées d'un répertoire que si celui-ci est complètement à jour. Vous apprendrez comment associer des « propriétés » à des éléments dans le Chapitre 3, Sujets avancés. La révision de travail d'un répertoire définit un ensemble précis d'entrées et de propriétés et propager la modification d'une propriété d'un répertoire périmé risquerait de détruire des propriétés dont vous n'aviez pas encore connaissance.
Enfin, à partir de Subversion 1.7, vous ne pouvez pas utiliser par défaut une copie de travail à révisions mélangées comme cible d'une opération de fusion ; cette limitation a été introduite pour prévenir certains problèmes qui apparaissent dans ce cas.
Nous avons couvert un certain nombre de concepts fondamentaux de Subversion dans ce chapitre :
Nous avons introduit les notions de dépôt central, de copie de travail du client et d'ensemble des révisions de l'arborescence du dépôt.
Nous avons vu quelques exemples simples de la façon dont deux collaborateurs peuvent utiliser Subversion pour publier et recevoir des modifications en provenance l'un de l'autre, en utilisant le modèle « copier-modifier-fusionner ».
Nous avons évoqué la façon dont Subversion suit et gère les informations dans une copie de travail.
À présent, vous avez probablement une bonne idée générale de la façon dont Subversion fonctionne. Armé de cette connaissance, vous devez désormais être prêt à passer au chapitre suivant qui traite en détail des commandes et des fonctionnalités de Subversion.
[5] Le terme « copie de travail » peut s'appliquer à n'importe quel fichier dans sa version extraite. Cependant, la majeure partie des gens utilise ce terme pour désigner la sous-arborescence complète contenant les fichiers et répertoires gérés par le système de gestion de versions.
La théorie est utile, mais son application est tout simplement passionnante. Nous allons maintenant voir plus en détail l'utilisation de Subversion. Quand vous aurez terminé ce chapitre, vous serez capable d'effectuer toutes les tâches nécessaires à une utilisation quotidienne de Subversion. Nous allons commencer par enregistrer nos fichiers dans Subversion, puis extraire notre code. Ensuite, nous expliquons comment modifier des fichiers et examiner ces changements. Nous voyons aussi comment faire pour intégrer les changements venant d'autres personnes dans notre copie de travail, les examiner et résoudre les conflits qui pourraient apparaître.
Notez que ce chapitre ne doit pas être vu comme une liste complète de toutes les commandes de Subversion, mais plutôt comme une introduction conviviale aux opérations Subversion les plus courantes que vous êtes susceptible de rencontrer. Ici, nous supposons que vous avez lu et compris le Chapitre 1, Notions fondamentales et que vous êtes familier avec le modèle général de Subversion. Pour une liste complète de toutes les commandes, reportez-vous à la Partie II, « Guide de référence des commandes Subversion ».
Dans ce chapitre, nous considérons également que le lecteur cherche comment interagir de manière simple avec un dépôt Subversion existant. S'il n'y a pas de dépôt, il n'y a pas de copie de travail ; s'il n'y a pas de copie de travail, ce chapitre ne présente pas grand intérêt. Il existe de nombreux sites Internet qui propose d'héberger un dépôt Subversion gratuitement ou pour une somme modique. Sinon, si vous préférez mettre en place et administrer vos propres dépôts, référez-vous au Chapitre 5, Administration d'un dépôt. Mais n'espérez pas que les exemples de ce chapitre fonctionnent si vous n'avez pas accès à un dépôt Subversion.
Enfin, toutes les opérations Subversions qui contactent le dépôt à travers le réseau peuvent potentiellement nécessiter une authentification de l'utilisateur. Par souci de simplicité, nos exemples tout au long de ce chapitre n'abordent pas l'authentification. Soyez conscient que si vous souhaitez mettre en pratique les exemples fournis ici avec une instance Subversion du monde réel, vous serez certainement obligé de fournir un identifiant et un mot de passe au serveur. Lisez la section intitulée « Éléments d'authentification du client » pour une description détaillée de la façon dont Subversion gère l'authentification des utilisateurs et les éléments associés.
Il va de soi que ce livre existe dans le but d'informer et d'assister les utilisateurs de Subversion, qu'ils soient débutants ou chevronnés. Cependant, pour plus de confort, le client texte interactif de Subversion inclut sa propre documentation, réduisant le besoin d'aller chercher un livre dans les rayonnages (qu'ils soient en bois, virtuels ou quoi que soit d'autre). La commande svn help est la porte d'entrée vers cette documentation.
$ svn help Client texte interactif de Subversion, version 1.8.13. Entrer 'svn help <sous-commande>' pour l'aide sur une sous-commande. Entrer 'svn --version' pour avoir la version et les modules d'accès (RA) ou 'svn --version --quiet' pour la version seule. La plupart des sous-commandes prennent en argument des dossiers et/ou des fichiers, et s'appliquent récursivement sur les dossiers. Si aucun argument n'est précisé à une telle sous-commande, elle s'applique par défaut récursivement sur le dossier courant, qui est inclus. Sous-commandes disponibles : …
Comme indiqué dans la sortie d'écran précédente, vous pouvez
demande de l'aide sur une sous-commande particulière en lançant
svn help
. Subversion
affiche le message complet d'utilisation de cette sous-commande,
ce qui inclut la syntaxe, les options et le
comportement :SOUS_COMMANDE
$ svn help help help (?, h): Décrit l'usage de ce programme ou de ses sous-commandes. usage : help [SOUS_COMMANDE...] Options globales : --username ARG : précise le nom d'utilisateur ARG --password ARG : précise le mot de passe ARG …
Beaucoup de distributions de Subversion sur des plateformes de type Unix incluent des pages de manuel qui peuvent être affichées en utilisant la commande man, mais ces pages ne recèlent généralement que des pointeurs vers d'autres sources d'aide réelle, telles que le site Internet du projet et le site qui héberge ce livre. Par ailleurs, plusieurs entreprises proposent de l'assistance et de l'aide pour Subversion, habituellement par l'intermédiaire de forums de discussion en ligne et de prestations de conseil. Et bien sûr, Internet regorge de discussions relatives à Subversion, prêtes à être mises au jour à l'aide de votre moteur de recherche favori. L'aide de Subversion ne se trouve jamais bien loin.
Deux moyens sont à votre disposition pour enregistrer de nouveaux fichiers dans votre dépôt Subversion : svn import et svn add. Nous abordons ici la commande svn import et, plus loin dans le chapitre, la commande svn add, lorsque nous passerons en revue une journée typique avec Subversion.
La commande svn import est un moyen rapide de copier une arborescence non-suivie en versions dans le dépôt, créant des dossiers intermédiaires si nécessaire. svn import ne nécessite pas de copie de travail et vos fichiers sont immédiatement propagés dans le dépôt. Ce moyen est utilisé essentiellement quand vous avez une arborescence existante dont vous voulez suivre les changements dans votre dépôt Subversion. Par exemple :
$ svn import chemin/vers/mon/arborescence \ http://svn.exemple.com/svn/depot/un/projet \ -m "Import initial" Ajout mon-arborescence/truc.c Ajout mon-arborescence/machin.c Ajout mon-arborescence/sous-repertoire Ajout mon-arborescence/sous-repertoire/bidule.h Révision 1 propagée. $
L'exemple précédent copie le contenu d'un dossier local
mon-arborescence
dans le dossier
un/projet
du dépôt. Notez que vous n'avez
pas eu besoin de créer d'abord ce nouveau dossier,
svn import le faisant pour vous.
Immédiatement après la propagation, vous pouvez voir vos données
dans le dépôt :
$ svn list http://svn.exemple.com/svn/depot/un/projet machin.c sous-repertoire/ truc.c $
Notez qu'après la fin de l'import, l'arborescence d'origine n'est pas transformée en copie de travail. Pour commencer à travailler, vous devez extraire grâce à svn checkout une copie de travail toute fraîche de l'arborescence.
On ne peut pas être plus flexible que Subversion pour l'organisation de vos données. Comme il ne fait que suivre en versions les fichiers et les dossiers et comme il n'attache aucune sémantique à ces objets, vous avez tout loisir de disposer les données dans votre dépôt comme bon vous semble. Malheureusement, la contrepartie de cette flexibilité est qu'il est facile de se retrouver perdu quand on essaye de parcourir différents dépôts Subversion, les schémas de stockage des données pouvant être très différents voire imprévisibles.
Pour pallier cette confusion possible, nous vous
recommandons de suivre la convention suivante (établie il y a
bien longtemps, avec l'éclosion du projet Subversion
lui-même) qui consiste à nommer judicieusement quelques
dossiers du dépôt Subversion en fonction des données qu'ils
renferment. La plupart des projets possèdent « une ligne de
développement principale » identifiable, autrement appelée
tronc (trunk
en anglais), des branches, qui sont des
copies avec des variantes de la ligne de développement
principale et des étiquettes
(tags en anglais) qui sont des
instantanés de la ligne de développement que l'on a nommés. En
conséquence, nous recommandons premièrement que chaque projet
dispose d'une racine de projet bien
identifiée au sein du dépôt, un dossier sous lequel toutes
les données du projet — et uniquement les données du
projet — seront hébergées. Deuxièmement, nous
recommandons que chaque racine de projet contienne un
sous-dossier trunk
pour la ligne de
développement principale, un sous-dossier
branches
dans lequel les branches
spécifiques (ou groupes de branches) seront créées et un
sous-dossier tags
dans lequel seront
placés les instantanés (ou les groupes d'instantanés). Bien
sûr, si un dépôt n'héberge qu'un seul projet, la racine du
dépôt peut servir de racine du projet.
Voici quelques exemples :
$ svn list file:///var/svn/depot-projet-unique trunk/ branches/ tags/ $ svn list file:///var/svn/depot-multiples-projets projet-A/ projet-B/ $ svn list file:///var/svn/depot-multiples-projets/projet-A trunk/ branches/ tags/ $
Vous en apprendrez plus sur les étiquettes et les branches dans le Chapitre 4, Gestion des branches. Pour plus de détails et pour voir comment gérer plusieurs projets, reportez-vous à la section intitulée « Agencement du dépôt », et à la section intitulée « Stratégies d'organisation d'un dépôt » pour en savoir plus sur les dossiers racines d'un projet.
Subversion s'efforce de ne pas limiter le type de données que vous placez en suivi de versions. Le contenu des fichiers et les valeurs des propriétés sont stockés et transmis en tant que données binaires. la section intitulée « Type de contenu des fichiers » vous explique comment indiquer à Subversion que des opérations « textuelles » n'ont pas de sens pour un fichier particulier. Il existe toutefois quelques cas pour lesquels Subversion définit des limitations sur les informations qu'il stocke.
Subversion gère en interne certaines parties des données au format Unicode UTF-8, par exemple les noms de propriétés, les noms de chemins et les messages de trace. Cela ne veut toutefois pas dire que toutes vos interactions avec Subversion doivent faire intervenir l'UTF-8. En règle générale, les clients Subversion vont gérer de façon transparente les conversions entre l'UTF-8 et le système de codage utilisé par votre ordinateur, si cela a un sens de faire une telle conversion (ce qui est le cas pour les codages les plus courants utilisés de nos jours).
Dans les échanges WebDAV ainsi que dans des anciennes
versions de certains fichiers de gestion interne de
Subversion, les chemins sont utilisés en tant que valeurs
d'attribut XML et les noms de propriétés en tant que noms
de tags XML. Cela veut dire que les chemins ne peuvent
contenir que des caractères XML (1.0) valides et que les
noms de propriétés sont encore plus limités, ne pouvant
contenir que des caractères ASCII. Subversion interdit
également les caractères TAB
(tabulation),
CR
et LF
(caractères de fin de ligne) dans les noms de chemins pour
empêcher les chemins d'être coupés en deux lors des
comparaisons ou dans les sorties de commandes comme
svn log ou
svn status.
Bien que cela fasse beaucoup de choses à se rappeler, ces limitations sont rarement un problème en pratique. Tant que vos paramètres régionaux sont compatibles avec UTF-8 et que vous n'utilisez pas de caractères de contrôle dans les chemins, vous ne devriez pas avoir de problème pour communiquer avec Subversion. Le client texte interactif apporte un peu d'aide supplémentaire : afin de créer des versions « valides » pour un usage interne, il banalise automatiquement, si nécessaire, les caractères illégaux contenus dans les chemins d'URL que vous tapez.
Avertissement | |
---|---|
Évidemment, au moment de choisir des noms de chemins valides, Subversion n'est pas l'unique facteur limitant. Les équipes qui travaillent avec plusieurs systèmes d'exploitation doivent aussi prendre en compte les limitations imposées par ces systèmes d'exploitation. Par exemple, Windows n'autorise pas l'utilisation de la virgule dans les noms de fichiers alors qu'un utilisateur de Linux peut très bien placer un tel fichier en suivi de versions, générant des données qui ne pourront plus être extraites sous Windows. De même, ajouter plusieurs fichiers dont les noms ne diffèrent que par la casse entraîne des problèmes pour les utilisateurs de systèmes de fichiers non sensibles à la casse. En conséquence, nous vous recommandons de bien prendre aussi en compte les limitations posées par les différents systèmes d'exploitation et systèmes de fichiers. |
En général, vous commencerez à utiliser un dépôt Subversion en faisant une extraction (checkout en anglais) de votre projet. Extraire un dossier d'un dépôt crée sur votre ordinateur une copie de travail de ce dossier. Cette copie contient la dernière version (c'est-à-dire la plus récemment créée ou modifiée) du dossier et de sa sous-arborescence trouvée dans le dépôt Subversion :
$ svn checkout http://svn.exemple.com/svn/depot/trunk A trunk/LISEZMOI A trunk/INSTALL A trunk/src/main.c A trunk/src/header.h … Révision 8810 extraite. $
Alors que l'exemple précédent extrait le dossier de
base trunk
, vous pouvez tout aussi
facilement extraire un sous-dossier situé à n'importe quelle
profondeur dans le dépôt en spécifiant le sous-dossier dans
l'URL d'extraction :
$ svn checkout http://svn.exemple.com/svn/depot/trunk/src A src/main.c A src/header.h A src/lib/helpers.c … Révision 8810 extraite. $
Comme Subversion utilise le modèle copier-modifier-fusionner à la place du modèle verrouiller-modifier-libérer (voir la section intitulée « Modèles de gestion de versions »), vous pouvez commencer immédiatement à modifier les fichiers et les dossiers de votre copie de travail. Votre copie de travail n'est qu'un ensemble de fichiers et de dossiers comme les autres dans votre système. Vous pouvez y éditer des fichiers, la modifier, la déplacer, vous pouvez même supprimer toute votre copie de travail et l'oublier définitivement.
Avertissement | |
---|---|
Bien que votre copie de travail « n'est qu'un ensemble de fichiers et de dossiers comme les autres dans votre système », vous pouvez éditer vos fichiers comme vous le voulez, mais vous devez signaler à Subversion toutes vos autres opérations. Par exemple, si vous voulez copier ou déplacer un élément dans votre copie de travail, vous devez utiliser svn copy ou svn move à la place des commandes de copie ou de déplacement fournies par votre système d'exploitation. Nous aborderons plus en détail ces commandes plus loin dans ce chapitre. |
À moins que vous ne soyez prêt à propager l'ajout d'un nouveau fichier ou d'un nouveau dossier ou la modification d'un fichier ou dossier existant, il n'est pas nécessaire d'informer davantage le serveur Subversion que vous avez fait quelque chose.
Vous avez certainement remarqué que, dans les deux exemples précédents, Subversion crée la copie de travail dans un dossier nommé d'après le dernier composant de l'URL extraite. Ce comportement n'est qu'une facilité lorsque la seule information fournie à la commande svn checkout est l'URL d'extraction. Le client texte interactif de Subversion vous permet d'indiquer le nom d'un répertoire local afin d'y placer la copie de travail nouvellement créée. Par exemple :
$ svn checkout http://svn.exemple.com/svn/depot/trunk ma-copie-de-travail A ma-copie-de-travail/LISEZMOI A ma-copie-de-travail/INSTALL A ma-copie-de-travail/src/main.c A ma-copie-de-travail/src/header.h … Révision 8810 extraite. $
Le dossier ma-copie-de-travail
est créé
par la commande svn checkout s'il n'existait pas
auparavant.
Subversion dispose de nombreuses fonctionnalités, d'options, d'avertissements et de garde-fous. Mais dans une utilisation au jour le jour, vous n'utilisez qu'un petit nombre d'entre eux. Dans cette section, nous passons en revue l'utilisation quotidienne de Subversion.
Le cycle de travail typique ressemble à ceci :
Mettre à jour votre copie de travail, par l'utilisation de la commande svn update.
Faire des changements. Les changements les plus courants seront des modifications du contenu des fichiers existants. Parfois, vous aurez besoin d'ajouter, supprimer, copier ou déplacer des fichiers et des dossiers ; les commandes svn add, svn delete, svn copy et svn move prennent en charge ces modifications structurelles de la copie de travail.
Examiner les changements effectués. Les commandes svn status et svn diff sont là pour passer en revue les modifications que vous avez apportées à votre copie de travail.
Annuler des changements. Personne n'est parfait, aussi lorsque vous passez en revue vos modifications, vous pouvez constater des erreurs. Parfois, le plus simple est de repartir de zéro. La commande svn revert rétablit un fichier ou un dossier dans son état initial.
Résoudre les conflits (fusionner les modifications). Dans le temps qu'il vous faut pour réaliser et passer en revue vos modifications, d'autres utilisateurs effectuent et publient peut-être des modifications également. Vous voulez sûrement intégrer leurs changements dans votre copie de travail pour éviter qu'ils ne deviennent « périmés » quand vous voudrez les publier. Une fois encore, la commande svn update prend cette opération en charge. Si des conflits apparaissent sur votre copie locale, vous devrez les résoudre à l'aide de la commande svn resolve.
Propager les changements. La commande svn commit transmet vos modifications au dépôt et, si elles sont acceptées, créeront une nouvelle version de toutes les choses que vous avez modifiées. Maintenant, les autres aussi peuvent voir votre travail !
Si vous travaillez sur un projet donné qui est modifié par des copies de travail multiples, vous voudrez mettre à jour votre copie locale pour recevoir toutes les modifications qui ont pu être faites par les autres copies de travail depuis votre dernière mise à jour. Ce peut être des modifications que les autres membres de l'équipe de projet ont faites, ou simplement des modifications que vous avez faites vous-même sur un autre ordinateur. Afin de protéger vos données, Subversion ne vous autorise pas à publier des changements sur des fichiers ou des dossiers qui ne sont pas à jour. Il est donc toujours mieux d'avoir les dernières versions de tous les fichiers et dossiers des projets sur lesquels vous travaillez avant d'apporter vous-même des modifications.
Utilisez svn update pour synchroniser votre copie de travail avec la dernière version présente dans le dépôt :
$ svn update Mise à jour de '.' : U truc.c U machin.c Actualisé à la révision 2. $
Dans cet exemple, il se trouve que quelqu'un a propagé
des modifications à truc.c
ainsi qu'à
machin.c
depuis votre dernière mise à jour
et Subversion vient de répercuter ces modifications dans votre
copie de travail.
Lorsque le serveur envoie des modifications vers votre
copie de travail via svn
update, un code, sous forme de lettre, est affiché à
côté de chaque élément pour vous permettre de savoir quelles
actions Subversion a effectuées pour mettre votre copie de
travail à jour. Pour en savoir plus sur le sens de ces lettres,
exécutez svn help update
ou
reportez-vous à svn update (up) dans
Guide de référence de svn : le client texte interactif.
Vous pouvez à présent vous mettre au travail et apporter des modifications à votre copie de travail. Vous pouvez effectuer deux types de modifications : les modifications de fichiers et les modifications de dossiers. Vous n'avez pas à prévenir Subversion que vous voulez modifier un fichier ; faites vos modifications avec un éditeur de texte, un traitement de texte, un logiciel de dessin ou n'importe quel autre outil que vous utilisez d'habitude. Subversion détecte automatiquement quels fichiers ont été modifiés et, en plus, il traite les fichiers binaires tout aussi facilement et aussi efficacement que les fichiers textes. Les modifications dans l'arborescence sont différentes ; cela comprend l'ajout et la suppression de fichiers, le renommage de fichiers ou de dossier ainsi que la copie ou le déplacement de fichiers ou dossiers vers un nouvel emplacement. Pour les modifications d'arborescence, les opérations de Subversion consistent à « marquer » la suppression, l'ajout, la copie ou le déplacement des fichiers et dossiers. Ces modifications prennent effet immédiatement sur votre copie de travail mais aucun ajout ou suppression n'interviendra sur le dépôt avant que vous ne les propagiez.
Voici un aperçu des cinq sous-commandes Subversion les plus utilisées pour faire des modifications sur l'arborescence :
svn add TRUC
Marque le fichier, le dossier ou le lien
symbolique TRUC
pour ajout. Lors
de la prochaine propagation, TRUC
devient un fils de son dossier parent. Notez que
si TRUC
est un dossier, tout ce
qui se trouve à l'intérieur de TRUC
est marqué pour ajout. Si vous ne désirez ajouter que
TRUC
lui-même, passez l'option
--depth empty
.
svn delete TRUC
Marque le fichier, le dossier ou le lien
symbolique TRUC
pour suppression.
TRUC
est immédiatement supprimé de
votre copie de travail. Bien sûr, rien n'est jamais
totalement supprimé du dépôt — seulement de la révision
HEAD
du dépôt. Vous avez accès à
l'élément supprimé dans les révisions précédentes.
[6]
svn copy TRUC MACHIN
Crée un nouvel élément
MACHIN
par duplication de
TRUC
et marque automatiquement
MACHIN
pour ajout. Lorsque
MACHIN
est ajouté au dépôt, lors
de la prochaine propagation, son historique est
enregistré (comme ayant été créé à partir de
TRUC
). svn copy
ne crée pas de dossiers intermédiaires, à moins que
vous ne lui passiez l'option
--parents
.
svn move TRUC MACHIN
Cette commande équivaut exactement à
svn copy TRUC MACHIN; svn delete
MACHIN
. C'est-à-dire que
MACHIN
est marqué pour ajout en tant
que copie de TRUC
et que
TRUC
est marqué pour suppression.
svn move ne crée pas de dossiers
intermédiaires, à moins que vous ne lui passiez
l'option --parents
.
svn mkdir TRUC
Cette commande équivaut exactement à
mkdir TRUC; svn add TRUC
.
C'est-à-dire qu'un nouveau dossier nommé
TRUC
est créé et marqué pour
ajout.
Une fois vos modifications apportées, vous devez les intégrer au dépôt. Avant de le faire, il est souvent utile de jeter un coup d'œil sur ces modifications pour savoir exactement ce que vous avez changé. En examinant les modifications avant de les intégrer au dépôt, vous pouvez rédiger un commentaire de propagation, c'est-à-dire une description à l'attention des utilisateurs des changements propagés, ce commentaire étant conservé avec les données dans le dépôt. Éventuellement, vous verrez que vous avez modifié un fichier par inadvertance et cela vous donne une chance de revenir sur ces modifications avant de les propager au dépôt. En outre, c'est une bonne occasion de passer en revue et d'examiner les modifications avant de les publier. Vous pouvez obtenir une vue d'ensemble des modifications que vous avez faites en utilisant la commande svn status et voir le détail de ces changements en utilisant svn diff.
Pour avoir une vue d'ensemble des changements que vous avez effectués, utilisez la commande svn status. C'est certainement la commande Subversion que vous utiliserez le plus.
Astuce | |
---|---|
Parce que l'affichage produit par la commande cvs status était tellement verbeux et parce que la commande cvs update ne faisait pas qu'une mise à jour mais affichait également l'état des changements effectués localement, la plupart des utilisateurs de CVS ont appris à utiliser cvs update pour propager leurs modifications. Dans Subversion, les opérations de mise-à-jour et d'examen des changements sont complètement séparées. Reportez-vous à la section intitulée « Distinction entre les commandes status et update » pour plus de détails. |
Si vous lancez svn status sans argument à la racine de votre copie de travail, Subversion détecte toutes les modifications effectuées sur les fichiers et sur l'arborescence.
$ svn status ? gribouillage.c A bazar/pognon A bazar/pognon/nouveau.h D bazar/vieux.c M machin.c
Dans le format d'affichage par défaut, svn status affiche sept colonnes de caractères, suivis par plusieurs espaces, suivis par un nom de fichier ou de dossier. La première colonne indique le statut du fichier ou du dossier et/ou son contenu. Les codes les plus utilisés sont :
? élément
Le fichier, dossier ou lien symbolique
élément
n'est pas suivi en
versions.
A élément
Le fichier, dossier ou lien symbolique
élément
est marqué pour ajout
au dépôt.
C élément
Le fichier élément
est dans
un état de conflit. C'est-à-dire que des modifications
ont eu lieu dans le dépôt depuis votre dernière mise à
jour et ces modifications interfèrent avec les
modifications que vous avez effectuées sur votre copie
de travail (et la mise à jour n'a pas résolu ce conflit).
Vous devez résoudre ce conflit avant de propager vos
changements vers le dépôt.
D élément
Le fichier, dossier ou lien symbolique
élément
est marqué pour
suppression (Deletion en
anglais).
M élément
Le contenu du fichier élément
a été modifié.
Si vous spécifiez un chemin à svn status, vous obtenez uniquement les informations relatives à ce chemin :
$ svn status bazar/poisson.c D bazar/poisson.c
svn status possède aussi une option
--verbose
(-v
) pour la
rendre plus verbeuse : elle affiche alors le statut de
tous les éléments de votre copie de
travail, même ceux qui n'ont pas subi de
modification :
$ svn status -v M 44 23 sally LISEZMOI 44 30 sally INSTALL M 44 20 harry machin.c 44 18 ira bazar 44 35 harry bazar/truite.c D 44 19 ira bazar/poisson.c 44 21 sally bazar/divers A 0 ? ? bazar/divers/bitoniau.h 44 36 harry bazar/divers/tartempion.c
C'est la « version longue » de l'affichage de svn status. Les lettres de la première colonne ont la même signification que précédemment, mais la deuxième colonne indique le numéro de révision de travail de l'élément. Les troisième et quatrième colonnes indiquent le numéro de la révision dans laquelle a eu lieu le changement le plus récent et qui l'a effectué.
Aucune des commandes citées ci-dessus n'induit de
connexion vers le dépôt : elles comparent les métadonnées
de la zone administrative et les horodatages avec la copie de
travail. Parfois, il peut être utile de voir quels
éléments de la copie de travail ont été modifiés dans le
dépôt depuis la dernière mise à jour de la copie de
travail. À cette fin, svn status propose
l'option --show-updates
(-u
)
qui effectue une connexion au dépôt et ajoute les informations
sur les éléments périmés :
$ svn status -u -v M * 44 23 sally LISEZMOI M 44 20 harry machin.c * 44 35 harry bazar/truite.c D 44 19 ira bazar/poisson.c A 0 ? ? bazar/divers/bitoniau.h État par rapport à la révision 46
Notez les deux astérisques : si vous lanciez la
commande svn update, vous recevriez les
changements relatifs à LISEZMOI
et
truite.c
. Cela vous procure des
informations particulièrement intéressantes, puisque l'un
des éléments a fait l'objet de modifications de votre part (le
fichier LISEZMOI
) ; vous devez
faire une mise à jour et récupérer les changements effectués
sur LISEZMOI
avant de propager les
vôtres, sinon le dépôt rejettera votre propagation en la
considérant comme périmée (le sujet est approfondi plus
tard).
svn status peut afficher beaucoup
plus d'informations sur les fichiers et dossiers de votre
copie de travail que ce que nous venons de voir ici. Pour
obtenir une description exhaustive de svn
status et de ses modes d'affichage, lancez
svn help status
ou reportez-vous à
svn status (stat, st) dans
Guide de référence de svn : le client texte interactif.
La commande svn diff offre une
autre façon d'examiner vos changements. En lançant la commande
svn diff
dans le dossier racine de
votre copie de travail et sans argument, Subversion affiche
les changements que vous avez apportés dans les fichiers
lisibles par les humains de votre copie de travail. Il
affiche ces changements au format diff
unifié, un format qui décrit les changements
par des « morceaux »
(hunks ou
snippets en anglais) du
contenu des fichiers, où chaque ligne de texte est
préfixée par un code sur un caractère : une espace
signifie que la ligne n'a pas été modifiée ; un signe
moins (-
) signifie que la ligne a été
supprimée du fichier ; et un signe plus
(+
) signifie que la ligne a été ajoutée
au fichier. Dans le contexte de svn diff,
les préfixes respectivement +
et
-
montrent le contenu des lignes
respectivement avant et après vos modifications.
Voici un exemple :
$ svn diff Index: truc.c =================================================================== --- machin.c (révision 3) +++ machin.c (copie de travail) @@ -1,7 +1,12 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <stdio.h> int main(void) { - printf("Soixante-quatre tranches de fromage...\n"); + printf("Soixante-cinq tranches de fromage...\n"); return 0; } Index: LISEZMOI =================================================================== --- LISEZMOI (révision 3) +++ LISEZMOI (copie de travail) @@ -193,3 +193,4 @@ +Pense-bête : passer au pressing. Index: bazar/poisson.c =================================================================== --- bazar/poisson.c (révision 1) +++ bazar/poisson.c (copie de travail) -Bienvenue dans le fichier 'poisson'. -Plus d'informations seront disponibles prochainement. Index: bazar/divers/machin.h ================================================================== --- bazar/divers/bitoniau.h (révision 8) +++ bazar/divers/bitoniau.h (copie de travail) +Voici un nouveau fichier pour +écrire sur les petites choses.
La commande svn diff produit ces lignes en comparant vos fichiers de travail aux copies « originales » en cache dans la zone administrative. Les fichiers marqués pour ajout sont affichés comme toute section de texte ajoutée, et les fichiers marqués pour suppression sont affichés comme toute section de texte supprimée. L'affichage de svn diff est compatible avec le programme patch — et encore davantage avec l'introduction de la commande svn patch dans Subversion 1.7. Les commandes patch lisent et appliquent des correctifs (patches en anglais), c'est-à-dire des fichiers qui décrivent les modifications appliquées à un ou plusieurs fichiers. Ainsi, vous pouvez partager les modifications que vous avez faites sur votre copie de travail avec quelqu'un d'autre sans propager ces modifications, mais seulement en créant un fichier correctif obtenu par la redirection de l'affichage de svn diff.
$ svn diff > fichier-correctif $
Subversion utilise son propre moteur de calcul de
différences, qui produit par défaut des résultats au format
diff unifié. Si vous désirez obtenir les différences dans un
autre format, spécifiez un programme de comparaison externe
en utilisant l'option --diff-cmd
et en
fournissant les paramètres que vous voulez à l'aide de
l'option --extensions
(-x
).
Par exemple, pour obtenir les différences entre votre
version locale du fichier et l'original de
truc.c
au format
« contexte » et en ignorant la casse des
caractères, vous pouvez lancer la commande
suivante :
$ svn diff --diff-cmd /usr/bin/diff -x "-i" truc.c … $
Supposons qu'en examinant la sortie de
svn diff, vous vous rendiez compte que
tous les changements effectués sur un fichier donné sont
erronés. Peut-être auriez-vous dû laisser le fichier tel
quel, ou bien peut-être qu'il serait plus facile de reprendre
les changements depuis le début. Vous pourriez éditer à
nouveau le fichier et défaire tous les changements. Vous
pourriez essayer de trouver une copie du fichier tel qu'il
était avant les changements et copier son contenu à la place
de votre fichier modifié. Vous pourriez essayer d'appliquer
les changements à l'envers en utilisant svn patch
--reverse-diff
ou depuis le système d'exploitation
avec patch -R
. Et il existe probablement
encore d'autres méthodes.
Heureusement, avec Subversion annuler son travail et repartir de zéro ne nécessite pas autant d'acrobaties. Vous avez juste à utiliser la commande svn revert:
$ svn status LISEZMOI M LISEZMOI $ svn revert LISEZMOI 'LISEZMOI' réinitialisé $
Dans cet exemple, Subversion ramène le fichier dans son état d'avant les modifications en le remplaçant par la copie de l'original stockée dans la zone d'administration. Mais notez aussi que svn revert peut annuler n'importe quelle opération. Par exemple, vous pouvez décider que, après tout, vous ne voulez pas ajouter tel fichier :
$ svn status truc ? truc $ svn add truc A truc $ svn revert truc 'truc' réinitialisé $ svn status truc ? truc $
Ou, si vous avez enlevé un fichier du suivi de versions par erreur :
$ svn status LISEZMOI $ svn delete LISEZMOI D LISEZMOI $ svn revert LISEZMOI 'LISEZMOI' réinitialisé $ svn status LISEZMOI $
La commande svn revert est le parachute des gens imparfaits. Elle peut vous faire gagner un temps et une énergie considérables que vous auriez dépensé autrement à faire des corrections manuelles, voire à récupérer une copie de travail vierge juste pour retrouver un environnement de travail propre.
Nous avons déjà vu que svn status
-u
est capable de prévoir les conflits, mais
il reste à savoir gérer ces conflits. Des conflits peuvent
survenir à chaque fois que vous voulez fusionner ou intégrer
(dans le sens le plus général) des modifications en
provenance du dépôt dans votre copie de travail. Vous savez
désormais que la commande svn update
génère ce type de situation ; la fonction essentielle de
cette commande est de mettre à jour votre copie de travail en
y intégrant toutes les modifications effectuées depuis votre
dernière mise à jour. Comment Subversion vous rend-il compte
de ces conflits et comment pouvez-vous les gérer ?
Supposons que vous lanciez svn update
et que le résultat suivant apparaisse :
$ svn update Mise à jour de '.' : U INSTALL G LISEZMOI Conflit découvert dans 'machin.c'. Sélectionner : (p) report, (df) diff complet, (e) édite, (m) fusion, (mc) my side of conflict, (tc) their side of conflict, (s) voir toutes les options:
Les codes U
(qui veut dire
« mis à jour », updated
en anglais) et G
(qui veut
dire fusionné, merGed en
anglais) ne doivent pas vous inquiéter, les fichiers
correspondants ayant absorbé sans problème les modifications
venant du dépôt. Les fichiers notés
U
ne contenaient aucun
changement local mais ont été mis à jour à partir de
changements présents dans le dépôt. Le fichier marqué
G
avait subi des changements
localement, mais les changements en provenance du dépôt ont pu
être appliqués sans affecter les changements locaux.
Ce sont les quelques lignes suivantes qui sont
intéressantes. D'abord, Subversion vous avertit que sa
tentative pour fusionner les modifications en provenance du
serveur dans le fichier local machin.c
, il
a détecté que certains changements interfèrent avec
les vôtres quelqu'un a peut-être modifié la même ligne
que vous. Quelle qu'en soit la raison, Subversion marque
immédiatement le fichier comme étant dans un état de
conflit. Ensuite, il vous demande ce que vous voulez faire pour
résoudre ce conflit, vous proposant de choisir une action de
manière interactive. Les options les plus utilisées sont
affichées, mais vous pouvez voir toutes les options possibles en
tapant s
:
… Sélectionner : (p) report, (df) diff complet, (e) édite, (m) fusion, (mc) my side of conflict, (tc) their side of conflict, (s) voir toutes les options: (e) - change merged file in an editor [edit] (df) - show all changes made to merged file (r) - accept merged version of file (dc) - show all conflicts (ignoring merged version) (mc) - accept my version for all conflicts (same) [mine-conflict] (tc) - accept their version for all conflicts (same) [theirs-conflict] (mf) - accept my version of entire file (even non-conflicts) [mine-full] (tf) - accept their version of entire file (same) [theirs-full] (m) - use internal merge tool to resolve conflict (l) - launch external tool to resolve conflict [launch] (p) - mark the conflict to be resolved later [postpone] (q) - postpone all remaining conflicts (s) - show this list (also 'h', '?') Words in square brackets are the corresponding --accept option arguments. Select: (p) postpone, (df) show diff, (e) edit file, (m) fusion, (mc) my side of conflict, (tc) their side of conflict, (s) show all options:
Regardons brièvement ce que recèle chaque option avant de les détailler :
(e) edit [edit]
Ouvrir le fichier en conflit avec votre éditeur de
texte favori, qui est spécifié dans la variable
d'environnement EDITOR
.
(df) diff-full
afficher les différences entre la révision de base et le fichier en conflit au format diff unifié.
(r) resolved
Après édition du fichier, indiquer à Subversion que vous avez résolu les conflits à l'intérieur du fichier et qu'il doit accepter son contenu actuel ; en bref, vous avez « résolu » le conflit.
(dc) display-conflict
Afficher toutes les parties du fichier en conflit, en ignorant les modifications qui ont réussi à être fusionnées.
(mc) mine-conflict [mine-conflict]
ignorer les changements envoyés par le serveur qui entrent en conflit avec vos modifications locales pour le fichier concerné. Cependant, accepter et fusionner toutes les parties qui n'engendrent pas de conflit.
(tc) theirs-conflict [theirs-conflict]
Ignorer les modifications locales qui engendrent des conflits avec la version envoyée par le serveur pour le fichier concerné. Cependant, conserver toutes les parties qui n'engendrent pas de conflit pour ce fichier.
(mf) mine-full [mine-full]
Ignorer les changements envoyés par le serveur et utiliser uniquement votre version locale pour le fichier concerné.
(tf) theirs-full [theirs-full]
Ignorer vos changements sur le fichier concerné et utiliser la version envoyée par le serveur.
(m) fusion
Lancer un outil interne de fusion pour traiter le conflit. Cette option est disponible à partir de Subversion 1.8.
(l) launch
Lancer un programme externe pour résoudre le conflit. Ceci nécessite un peu de préparation en amont.
(p) postpone [postpone]
Laisser le fichier en état de conflit, conflit que vous devrez résoudre après la fin de la mise à jour.
(s) show all
Afficher la liste de toutes les commandes que vous pouvez utiliser dans la résolution interactive des conflits.
Nous allons maintenant passer en revue chaque commande, en les classant par fonctionnalité.
Avant de décider comment résoudre un conflit de
manière interactive, il est probable que vous vouliez examiner
le détail des lignes en conflit. Deux des commandes
accessibles via l'invite interactive de gestion des conflits
répondent à ce besoin. La première est la commande
df
(pour
diff-full en anglais), qui
affiche toutes les modifications locales du fichier ainsi que
les zones en conflit :
… Sélectionner : (p) report, (df) diff complet, (e) édite, (m) fusion, (mc) my side of conflict, (tc) their side of conflict, (s) voir toutes les options:df --- .svn/text-base/sandwich.txt.svn-base mar. 11 déc. 2007, 21:33:57 +++ .svn/tmp/tempfile.32.tmp mar. 11 déc. 2007, 21:34:33 @@ -1 +1,5 @@ -Achète-moi un sandwich. +<<<<<<< .mien +Va chercher un hamburger. +======= +Apporte-moi un taco ! +>>>>>>> .r32 …
La première ligne du diff correspond à ce que contenait
la copie de travail dans l'ancienne version (la révision
BASE
), la ligne suivante correspond
à vos modifications et la dernière ligne contient les
modifications reçues du serveur (la révision
HEAD
la plupart du temps).
La deuxième commande est similaire à la première mais
dc
(display
conflict en anglais) affiche uniquement les
zones en conflits, pas toutes les modifications apportées au
fichier. En plus, cette commande utilise un format d'affichage
légèrement différent qui permet de comparer facilement le
contenu du fichier tel qu'il serait dans les trois
états : original et non édité ; avec les
modifications locales et les changements provenant du serveur
qui génèrent des conflits ignorés ; uniquement les
changements provenant du serveur et vos modifications locales
qui génèrent des conflits ignorés.
Après avoir pris connaissance des informations fournies par ces commandes, vous être prêt à l'action suivante.
La manière la plus directe de résoudre interactivement un conflit utilise un outil interne de fusion. Cet outil vous demande quoi faire pour chaque modification qui pose problème et permet de fusionner et d'adapter les modifications de manière interactive. Cependant, il existe d'autres manières de faire interactivement— deux outils peuvent fusionner et adapter les modifications à l'aide d'éditeurs externes, les autres vous permettent simplement de choisir une version du fichier parmi celles proposées et de passer à la suite.
Vous avez déjà passé en revue les modifications qui posent
problème, il est donc temps de résoudre ces conflits. La
première commande qui peut vous aider est « merge »
(m
), disponible à partir de la version
1.8 de Subversion. Cette commande affiche les zones en conflit
et vous permet de choisir parmi différentes options pour chaque
zone en conflit :
Select: (p) postpone, (df) show diff, (e) edit file, (m) merge, (mc) my side of conflict, (tc) their side of conflict, (s) show all options: m Merging 'Makefile'. Conflicting section found during merge: (1) their version (at line 24) |(2) your version (at line 24) ------------------------------------------------+------------------------------------------------ top_builddir = /truc |top_builddir = /machin ------------------------------------------------+------------------------------------------------ Select: (1) use their version, (2) use your version, (12) their version first, then yours, (21) your version first, then theirs, (e1) edit their version and use the result, (e2) edit your version and use the result, (eb) edit both versions and use the result, (p) postpone this conflicting section leaving conflict markers, (a) abort file merge and return to main menu:
Comme vous le constatez, en utilisant l'outil de fusion interne, vous pouvez naviguer entre les différentes zones en conflit dans le fichier et choisir différentes stratégies de résolution, voire remettre à plus tard la résolution du conflit pour certaines zones.
Cependant, si vous souhaitez utiliser un éditeur externe pour
choisir une combinaison de vos
modifications locales, vous pouvez utiliser la commande
« édite » (e
) pour
modifier manuellement dans un éditeur de texte (configuré
en suivant les instructions données dans
la section intitulée « Utilisation d'éditeurs externes ») le fichier
avec des marqueurs indiquant les conflits. Après avoir édité
le fichier et si vous êtes satisfait de vos changements, vous
pouvez indiquer à Subversion que le fichier n'est plus en
conflit en utilisant la commande « résolu »
(r
).
En dehors de quelques puristes d'Unix, l'édition manuelle
de ce fichier avec votre éditeur préféré peut sembler quelque
peu « bas de gamme » (voir la section intitulée « Résolution des conflits à la main » pour une description
détaillée), c'est pourquoi Subversion propose d'utiliser des
outils graphiques plus évolués et spécialisés dans la fusion
de documents (voir la section intitulée « Outils de fusion externes ») avec la
commande « launch »
(lancer en français), raccourci
l
).
Il existe deux autres options qui offrent des
compromis. Les commandes respectivement
« mien-conflits » (mc
) et
« leur-conflits » (tc
)
demandent à Subversion de conserver respectivement vos
modifications locales et les modifications en provenance du
serveur pour tous les conflits rencontrés. Mais, au
contraire de « mien complet » et « autre
complet », ces commandes conservent à la fois vos
modifications et les modifications en provenance du serveur
dans les zones du fichier où il n'est pas détecté de
conflit.
Enfin, si vous décidez que vous ne voulez pas fusionner
les modifications mais simplement conserver une version du
fichier ou une autre, vous pouvez choisir votre version
(étiquetée « mine ») en sélectionnant
la commande « mine-full » (mf
)
ou choisir la version du dépôt en sélectionnant la commande
« theirs-full » (tf
).
Le titre peut laisser penser à un paragraphe sur
l'amélioration des relations conjugales, mais il s'agit bien
toujours de Subversion, voyez plutôt. Si, lorsque vous
effectuez une mise à jour, Subversion soulève un conflit
que vous n'êtes pas prêt à résoudre, vous pouvez, fichier
par fichier, taper p
, pour remettre
à plus tard la résolution du conflit. Si, lors de votre
mise à jour, vous ne voulez résoudre aucun conflit, vous
pouvez passer l'option --non-interactive
à svn update et les fichiers en conflit
sont automatiquement marqués
C
.
À partir de Subversion 1.8, un outil interne de fusion vous permet de différer la résolution de conflits pour certains conflits et de résoudre les autres. Ainsi, vous pouvez différer la résolution des conflits zone par zone et non plus uniquement fichier par fichier.
Le C
indique un
conflit, c'est-à-dire que les changements sur le serveur
interfèrent avec les vôtres et vous devez donc choisir
manuellement entre les différentes modifications après la
fin de la procédure de mise à jour. Quand vous repoussez à
plus tard la résolution d'un conflit, Subversion
accomplit trois actions qui vous aideront à repérer et à
résoudre ce conflit :
Subversion affiche un
C
pendant la mise à
jour et enregistre que le fichier est dans un état de
conflit.
Si Subversion considère que le fichier peut être
fusionné, il place dans le fichier des
marqueurs de conflit (des
chaînes de caractères spéciales qui dénotent les
« contours » des conflits) pour mettre en
exergue les zones de conflit (Subversion utilise la
propriété svn:mime-type
pour
déterminer si un fichier peut subir une fusion
contextuelle ligne par ligne ; voir
la section intitulée « Type de contenu des fichiers »
pour en apprendre davantage).
Pour chaque fichier en conflit, Subversion place trois fichiers supplémentaires non-suivis en versions dans votre copie de travail :
nom_du_fichier.mine
C'est votre fichier tel qu'il était dans votre
copie de travail avant la mise à jour,
c'est-à-dire sans les marqueurs de conflits. Ce
fichier ne comporte que vos derniers changements
(si Subversion considère que le fichier ne peut
pas être fusionné, le fichier
.mine
n'est pas créé, car il
serait identique à la version de travail).
nom_du_fichier.rANCIENNE_REV
C'est le fichier tel qu'il était à la révision
BASE
, avant la mise à jour de
votre copie de travail. C'est donc le fichier que
vous avez extrait avant de
faire vos dernières modifications,
ANCIENNE_REV
désignant le
numéro de révision de cette version de base.
nom_du_fichier.rNOUVELLE_REV
C'est le fichier que le client Subversion vient
de recevoir du serveur via l'opération de mise à
jour, où NOUVELLE_REV
désigne le numéro de révision de la mise à jour
demandée (HEAD
, à moins d'avoir
spécifié une autre révision).
Par exemple, Sally effectue un changement sur le
fichier sandwich.txt
mais elle ne
propage pas immédiatement ses modifications. Pendant ce
temps, Harry propage des changements sur ce même fichier.
Sally met à jour sa copie de travail avant d'effectuer la
propagation et un conflit apparaît, dont elle remet la
résolution à plus tard :
$ svn update Mise à jour de '.' : Conflit découvert dans 'sandwich.txt'. Select: (p) postpone, (df) show diff, (e) edit file, (m) merge, (mc) my side of conflict, (tc) their side of conflict, (s) show all options: p C sandwich.txt Actualisé à la révision 2. Résumé des conflits : Text conflicts: 1 $ ls -1 sandwich.txt sandwich.txt.mine sandwich.txt.r1 sandwich.txt.r2
À partir de là, Subversion n'autorise
pas Sally à propager le fichier
sandwich.txt
avant que les trois
fichiers temporaires ne soient effacés :
$ svn commit -m "Quelques petits ajouts" svn: Échec de la propagation (commit), détails : svn: Arrêt de la propagation : '/home/sally/travail-svn/sandwich.txt' demeure en conflit
Si vous avez remis à plus tard la résolution d'un
conflit, vous devez le résoudre pour que Subversion vous
autorise à propager vos changements. Vous pouvez le faire
avec la commande svn resolve. Cette
commande possède l'option --accept
afin de
spécifier votre manière de résoudre le conflit. Avant
Subversion 1.8, la commande svn resolve
exigeait de spécifier l'option.
Dorénavant, Subversion vous autorise à ne pas la
spécifier. Dans ce cas, Subversion passe en mode de
résolution interactif tel que présenté dans la section
précédente (voir la section intitulée « Résolution des conflits en mode interactif »). Dans cette
section, nous allons présenter l'utilisation de l'option
--accept
pour la résolution de
conflits.
L'option --accept
de la commande
svn resolve demande à Subversion d'utiliser
une des approches prédéfinies pour résoudre un conflit. Si
vous choisissez la version du fichier que vous avez extraite
avant de faire vos changements, utilisez l'argument
--accept=base
. Si vous préférez garder la
version qui contient uniquement vos changements, utilisez
l'argument --accept=mine-full
. Vous pouvez
aussi choisir la version la plus récente venant du
serveur (et donc abandonner tous vos changements) en utilisant
l'argument --accept=theirs-full
.
Il existe d'autres méthodes de résolution
« pré-emballées ». Lisez --accept
ACTION
dans
Guide de référence de svn : le client texte interactif pour en obtenir les détails.
Vous n'êtes pas limité à ces choix tout ou rien. Si vous
comptez effectuer un mélange de vos modifications et des
modifications rapatriées du serveur, fusionnez le fichier en
conflit « à la main » (examinez et éditez les
marqueurs de conflit dans le fichier) puis indiquez à
Subversion de résoudre le conflit en gardant la version de
travail dans son état actuel par la commande svn
resolve avec l'argument
--accept=working
.
La commande svn resolve supprime les
trois fichiers temporaires et retient la version du fichier
que vous avez spécifié avec l'option
--accept
. À la fin d'exécution de la
commande (en considérant bien évidemment que vous n'avez
décidé de reporter la résolution du conflit), Subversion
considère que le fichier n'est plus dans un état de
conflit :
$ svn resolve --accept working sandwich.txt Conflit sur 'sandwich.txt' résolu
Résoudre les conflits à la main peut paraître quelque peu intimidant la première fois. Mais avec un peu de pratique, un enfant de cinq ans y arriverait.
Prenons un exemple. Par manque de communication entre
Sally (votre collaboratrice) et vous-même, vous éditez en
même temps le fichier sandwich.txt
.
Sally propage ses changements et, quand vous mettez à jour
votre copie de travail, un conflit apparaît, que vous devez
résoudre en éditant sandwich.txt
.
Jetons un œil à ce fichier :
$ cat sandwich.txt Tranche de pain supérieure Mayonnaise Laitue Tomate Comté <<<<<<< .mine Saucisson Mortadelle Jambon ======= Choucroute Poulet rôti >>>>>>> .r2 Moutarde Tranche de pain inférieure
Les suites de caractères inférieur-à
(<
), égal(=
) ou
supérieur-à (>
) sont des marqueurs de
conflit, ils ne font pas partie des données elles-mêmes.
Vous devrez en général vous assurer qu'elles ont disparu du
fichier avant de propager vos modifications. Le texte entre
les deux premiers marqueurs est constitué des modifications
que vous avez apportées dans la zone de
conflit :
<<<<<<< .mine Saucisson Mortadelle Jambon =======
Le texte entre le deuxième et le troisième marqueur est celui du fichier propagé par Sally :
======= Choucroute Poulet rôti >>>>>>> .r2
Normalement, vous n'allez pas juste supprimer les marqueurs et les changements effectués par Sally (elle sera affreusement déçue quand on lui apportera un sandwich différent de ce qu'elle a commandé). Vous décrochez donc le téléphone, ou vous traversez le bureau, pour expliquer à Sally qu'on ne met pas de choucroute dans un sandwich. [7] Après vous être mis d'accord sur les changements à enregistrer, éditez votre fichier et enlevez les marqueurs de conflit.
Tranche de pain supérieure Mayonnaise Laitue Tomate Comté Saucisson Mortadelle Jambon Moutarde Tranche de pain inférieure
Maintenant utilisez svn resolve et vous êtes paré pour propager vos changements :
$ svn resolve --accept working sandwich.txt Conflit sur 'sandwich.txt' résolu $ svn commit -m "Va pour mon sandwich et au diable celui de Sally !"
Soyez prudent et ne lancez svn resolve qu'une fois certain que vous avez résolu le conflit dans votre fichier : une fois les fichiers temporaires effacés, Subversion vous laisse propager le fichier même s'il contient toujours des marqueurs de conflit.
Si jamais vous êtes perdu lors de l'édition du fichier en conflit, vous pouvez toujours consulter les trois fichiers que Subversion a créé pour vous dans votre copie de travail, y compris le fichier tel qu'il était avant que vous ne lanciez la mise à jour. Vous pouvez même utiliser un outil externe interactif spécialisé dans les fusions pour examiner ces trois fichiers.
Si vous faites face à un conflit et que vous
décidez d'abandonner vos changements, vous pouvez lancer
svn resolve --accept theirs-full
,
Subversion abandonne alors vos modifications et supprime les
fichiers temporaires :CHEMIN-DU-CONFLIT
$ svn update Conflit découvert dans 'machin.c'. Sélectionner : (p) report, (df) diff complet, (e) édite, (h) aide pour plus d'options : C sandwich.txt Actualisé à la révision 2. $ ls sandwich.* sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1 $ svn resolve --accept theirs-full sandwich.txt Conflit sur 'sandwich.txt' résolu $
Si vous faites face à un conflit et qu'après examen de la situation, vous décidez d'abandonner vos changements et de repartir de zéro (peu importe en fait que ce soit après un conflit ou à n'importe quel autre moment), contentez-vous de revenir en arrière sur vos changements :
$ svn revert sandwich.txt 'sandwich.txt' réinitialisé $ ls sandwich.* sandwich.txt
Notez que quand vous revenez en arrière sur un fichier en conflit, vous n'avez pas besoin de lancer svn resolve.
Enfin ! Vos modifications sont terminées, vous les avez fusionnées avec celles du serveur et vous êtes prêt à les propager vers le dépôt.
La commande svn commit envoie vos
changements au dépôt. Quand vous propagez un changement,
vous devez l'accompagner d'un commentaire de propagation qui décrit
ce changement. Votre commentaire est associé à la nouvelle révision
que vous créez. Si votre commentaire est bref, vous pouvez le passer
en ligne de commande en utilisant l'option
--message
(ou -m
) :
$ svn commit -m "Nombre de tranches de fromage corrigé." Envoi sandwich.txt Transmission des données . Révision 3 propagée.
Cependant, si vous avez rédigé votre commentaire au fur et à
mesure, vous souhaitez sûrement indiquer à Subversion de le
récupérer dans un fichier en lui donnant le nom
du fichier avec l'option --file
(-F
) :
$ svn commit -F commentaire_de_propagation Envoi sandwich.txt Transmission des données . Révision 4 propagée.
Si vous ne spécifiez ni l'option --message
ni l'option --file
, Subversion lance
automatiquement votre éditeur de texte favori (voir les
détails de editor-cmd
dans
la section intitulée « Configuration générale ») pour
que vous rédigiez le commentaire de propagation.
Astuce | |
---|---|
Si, au moment où vous rédigez votre commentaire de propagation, vous décidez d'annuler la propagation, vous n'avez qu'à quitter l'éditeur de texte sans sauvegarder les changements. Si vous avez déjà sauvegardé le commentaire, effacez le texte, sauvegardez à nouveau puis choisissez d'annuler : $ svn commit Attente de Emacs...Fait Entrée du journal non modifié ou non précisé a)nnule, c)ontinue, e)dite a $ |
Le dépôt ne sait pas si vos changements ont un sens ou pas ; il vérifie seulement que personne n'a modifié, pendant que vous aviez le dos tourné, un des fichiers que vous-même avez modifié. Si c'est le cas, la propagation toute entière échoue, affichant un message vous informant qu'un ou plusieurs de vos fichiers ne sont plus à jour :
$ svn commit -m "Ajout d'une autre règle" Envoi règles.txt Transmission des données . svn: E155011: Echec de la propagation (commit), détails : svn: E155011: Fichier '/règles.txt' obsolète …
Notez que le phrasé exact de ce message d'erreur dépend du protocole réseau et du serveur que vous utilisez, mais l'idée reste la même.
À ce moment là, vous devez lancer svn
update
, traiter les fusions ou conflits qui
apparaissent et retenter une propagation.
Nous en avons terminé avec le cycle d'utilisation de base de Subversion. Subversion offre beaucoup d'autres fonctionnalités pour gérer votre dépôt et votre copie de travail, mais l'utilisation quotidienne de Subversion ne requiert pratiquement que les commandes que nous venons de voir dans ce chapitre. Intéressons-nous quand même à quelques commandes supplémentaires utilisées relativement souvent.
Votre dépôt Subversion est comme une machine à remonter le temps. Il garde une trace de tous les changements propagés et permet de parcourir cet historique en examinant aussi bien les versions précédentes des fichiers et des dossiers que les métadonnées associées. D'une simple commande Subversion, vous pouvez extraire (ou restaurer) une copie de travail du dépôt tel qu'il était à n'importe quelle date ou numéro de révision passée. Cependant, vous voulez parfois juste sonder le passé sans y retourner.
Plusieurs commandes renvoient des informations sur l'historique des données présentes dans le dépôt :
affiche les détails, ligne par ligne, d'un changement donné.
fournit beaucoup d'informations : les commentaires de propagation avec la date et l'auteur de la révision ainsi que les chemins qui ont été modifiés à chaque révision.
récupère le fichier tel qu'il existait à un numéro de révision donné et l'affiche à l'écran.
récupère un fichier humainement lisible tel qu'il existait à un numéro de révision donné, affiche son contenu sous la forme d'un tableau avec, pour chaque ligne, les informations relatives au dernier changement de celle-ci.
liste les fichiers contenus dans un dossier à une révision donnée.
Nous avons déjà vu la commande svn diff, qui affiche les différences entre fichiers au format diff unifié ; nous l'avons utilisée pour afficher les modifications locales effectuées sur notre copie de travail avant de les propager vers le dépôt.
En fait, il y a trois façons différentes d'utiliser svn diff :
Examiner des modifications locales.
Comparer votre copie de travail au dépôt.
Comparer des révisions du dépôt.
Comme nous l'avons vu précédemment,
svn diff
, s'il est invoqué sans
option, compare les fichiers de votre copie de travail à
leurs versions « originales » gardées en cache
dans la zone .svn
:
$ svn diff Index: règles.txt =================================================================== --- règles.txt (révision 3) +++ règles.txt (copie de travail) @@ -1,4 +1,5 @@ Être attentif envers les autres Liberté = Responsabilité Tout dans la modération -Mâcher la bouche ouverte +Mâcher la bouche fermée +Écouter quand les autres parlent $
Si un seul numéro de révision est fourni à l'option
--revision
(-r
), votre
copie de travail est comparée à la révision spécifiée du
dépôt :
$ svn diff -r 3 règles.txt Index: règles.txt =================================================================== --- règles.txt (révision 3) +++ règles.txt (copie de travail) @@ -1,4 +1,5 @@ Être attentif envers les autres Liberté = Responsabilité Tout dans la modération -Mâcher la bouche ouverte +Mâcher la bouche fermée +Écouter quand les autres parlent $
Si deux numéros de révision sont fournis à l'option
--revision
(-r
), séparés
par le caractère deux-points (:
), les deux
révisions sont directement comparées :
$ svn diff -r 2:3 règles.txt Index: règles.txt =================================================================== --- règles.txt (révision 2) +++ règles.txt (révision 3) @@ -1,4 +1,4 @@ Être attentif envers les autres -Liberté = Glace au chocolat +Liberté = Responsabilité Tout dans la modération Mâcher la bouche ouverte $
Une autre façon de comparer une révision à la
précédente, plus conviviale, est d'utiliser l'option
--change
(-c
) :
$ svn diff -c 3 règles.txt Index: règles.txt =================================================================== --- règles.txt (révision 2) +++ règles.txt (révision 3) @@ -1,4 +1,4 @@ Être attentif envers les autres -Liberté = Glace au chocolat +Liberté = Responsabilité Tout dans la modération Mâcher la bouche ouverte $
Enfin, vous pouvez comparer des révisions du dépôt même si vous n'avez pas de copie de travail en local sur votre ordinateur, simplement en incluant l'URL appropriée sur la ligne de commande :
$ svn diff -c 5 http://svn.exemple.com/depot/exemple/trunk/texte/règles.txt … $
Pour connaître l'historique d'un fichier ou d'un dossier, utilisez la commande svn log. Elle affiche la liste des gens qui ont modifié le fichier ou le dossier en question, le numéro de chaque révision où il a changé, l'heure et la date de cette révision et, s'il y en avait un, le commentaire associé à la propagation :
$ svn log ------------------------------------------------------------------------ r3 | sally | 2008-05-15 23:09:28 -0500 (jeu. 15 Mai 2008) | 1 ligne Ajout des lignes include et correction du nombre de tranches de fromage. ------------------------------------------------------------------------ r2 | harry | 2008-05-14 18:43:15 -0500 (mer. 14 Mai 2008) | 3 lignes Ajout des méthodes main(). ------------------------------------------------------------------------ r1 | sally | 2008-05-10 19:50:31 -0500 (sam. 10 Mai 2008) | 1 ligne Import initial ------------------------------------------------------------------------
Notez que, par défaut, l'historique est affiché en ordre
chronologique inverse. Si vous voulez afficher un intervalle
de révisions donné dans un ordre particulier ou juste une
seule révision, ajoutez l'option
--revision
(-r
) :
Tableau 2.1. Requêtes classiques dans l'historique
Commande | Description |
---|---|
svn log -r 5:19 | Affiche l'historique a partir de la révision 5 jusqu'à la révision 19 dans l'ordre chronologique. |
svn log -r 19:5 | Affiche l'historique à partir de la révision 5 jusqu'à la révision 19 dans l'ordre chronologique inverse. |
svn log -r 8 | Affiche l'historique pour la révision 8 uniquement. |
Vous pouvez aussi afficher l'historique d'un fichier ou d'un dossier particulier. Par exemple :
$ svn log truc.c … $ svn log http://truc.com/svn/trunk/code/truc.c …
Ceci n'affiche le contenu de l'historique que pour les révisions dans lesquelles le fichier de travail (ou l'URL) a changé.
Si vous voulez obtenir plus d'informations sur un fichier
ou un dossier, svn log accepte également l'option
--verbose
(-v
). Comme
Subversion autorise les déplacements et les copies de
dossiers et de fichiers, il est important de pouvoir
tracer ces modifications de chemin dans le système de
fichiers. Ainsi, en mode verbeux, svn log
affiche la liste des déplacements au cours de la révision
concernée :
$ svn log -r 8 -v ------------------------------------------------------------------------ r8 | sally | 2008-05-21 13:19:25 -0500 (mer. 21 Mai 2008) | 1 ligne Chemins modifiés : M /trunk/code/truc.c M /trunk/code/machin.h A /trunk/code/doc/LISEZMOI Machination du bidule.
svn log accepte aussi l'option
--quiet
(-q
), qui permet
de ne pas afficher le contenu du commentaire de propagation. En
combinaison avec --verbose
,
svn log n'affiche que les noms des
fichiers qui ont changé.
Depuis Subversion 1.7, les utilisateurs du client texte
interactif bénéficient du mode d'affichage spécial de
svn log qui intègre un format similaire à
celui produit par svn diff, que nous avons
abordé précédemment. Si vous lancez svn log
avec l'option --diff
, Subversion ajoute, à
chaque partie de l'historique d'une révision, une édition des
différences au style diff. C'est très
pratique pour visualiser à la fois les changements
sémantiques, de haut niveau et les modifications ligne par
ligne d'une révision.
À partir de Subversion 1.8, svn log
reconnait les options --search
et
--search-and
. Ces options vous permettent
de filtrer la sortie de svn log en fonction
du motif que vous fournissez. Lorsque vous utilisez ces options,
le commentaire de propagation n'est affiché que si l'auteur, la
date, le commentaire ou la liste des chemins modifiés correspond
au motif fourni.
Grâce aux commandes svn cat et svn list, vous pouvez afficher des révisions variées des fichiers et dossiers sans changer la révision de votre copie de travail. En fait, vous n'avez même pas besoin d'avoir une copie de travail pour les utiliser.
Si vous voulez examiner une version antérieure d'un fichier et pas nécessairement les différences entre deux fichiers, vous pouvez utiliser svn cat :
$ svn cat -r 2 règles.txt Être attentif envers les autres Liberté = Glace au chocolat Tout dans la modération Mâcher la bouche ouverte $
Vous pouvez également rediriger la sortie de svn cat directement dans un fichier :
$ svn cat -r 2 règles.txt > règles.txt.v2 $
La commande svn annotate ressemble beaucoup à la commande svn cat que nous venons d'aborder à la section précédente. Cette commande affiche aussi le contenu du fichier suivi en versions mais utilise un format en tableau. Chaque ligne, en plus du contenu du fichier, indique également le nom de l'utilisateur, le numéro de la révision et (optionnellement) l'horodatage de la révision dans laquelle la ligne a été modifiée pour la dernière fois.
Quand vous lui spécifiez comme argument un fichier de la copie de travail, svn annotate affiche par défaut les attributs du fichier correspondant à la version de la copie de travail.
$ svn annotate règles.txt 1 harry Être attentif envers les autres 3 sally Liberté = Responsabilité 1 harry Tout dans la modération - - Mâcher la bouche fermée - - Écouter quand les autres parlent
Remarquez que, pour certaines lignes, il n'y a pas
d'auteur indiqué. C'est parce que ces lignes ont été
modifiées dans la copie de travail du fichier. De cette
façon, svn annotate devient un outil
supplémentaire pour visualiser quelles lignes du fichier
vous avez modifiées. Vous pouvez utiliser le mot-clé
BASE
(voir la section intitulée « Mots-clés de révision ») pour visualiser la
version non modifiée du fichier telle qu'elle est stockée
dans votre copie de travail.
$ svn annotate règles.txt@BASE 1 harry Être attentif envers les autres 3 sally Liberté = Responsabilité 1 harry Tout dans la modération 1 harry Mâcher la bouche ouverte
L'option --verbose (-v)
demande à
svn annotate d'inclure également pour
chaque ligne l'horodatage de la révision. Cela augmentant de
manière significative la largeur de chaque ligne, nous nous
passerons d'exemple pour cette option.
De même que pour svn cat, vous pouvez demander à svn annotate d'afficher les versions précédentes du fichier. C'est une astuce particulièrement utile lorsque, après avoir trouvé qui a modifié telle ligne dans le fichier, vous voulez savoir qui avait écrit la version précédente de cette ligne.
$ svn blame règles.txt -r 2 1 harry Être attentif envers les autres 1 harry Liberté = Glace au chocolat 1 harry Tout dans la modération 1 harry Mâcher la bouche ouverte
Au contraire de svn cat, le
fonctionnement de svn annotate est
fortement corrélé à la notion de « ligne » d'un
fichier texte lisible par un humain. Ainsi, si vous essayez
de lancer la commande sur un fichier que Subversion considère
non lisible par un humain (en raison de
sa propriété svn:mime-type
, voir la section intitulée « Type de contenu des fichiers » pour les
détails), vous obtiendrez un message d'erreur.
$ svn annotate images/logo.png Skipping binary file (use --force to treat as text): 'images/logo.png' $
Comme l'indique le message d'erreur, vous pouvez spécifier
l'option --force
pour outrepasser la
vérification et effectuer les annotations comme pour tout
fichier contenant des lignes et lisible par un humain.
Naturellement, si vous forcez Subversion à effectuer des
annotations sur un fichier non textuel, vous obtiendrez ce
à quoi vous devez vous attendre : un cafouillis
incompréhensible.
$ svn annotate images/logo.png --force 6 harry \211PNG 6 harry ^Z 6 harry 7 harry \274\361\MI\300\365\353^X\300…
Astuce | |
---|---|
En fonction de votre humeur du moment ou des raisons
pour lesquelles vous lancez cette commande, vous vous
retrouverez à taper |
Pour finir, comme pour beaucoup de commandes de Subversion qui interrogent les fichiers suivis en versions, svn annotate peut faire référence aux fichiers par leur URL dans le dépôt, ce qui permet un accès aux informations même sans disposer d'une copie de travail.
La commande svn list liste les fichiers présents dans un dossier du dépôt sans pour autant les télécharger :
$ svn list http://svn.exemple.com/depot/projet LISEZMOI branches/ tags/ trunk/
Si vous désirez une liste plus détaillée, passez
l'option --verbose
(-v
)
et vous obtenez alors quelque chose comme ceci :
$ svn list -v http://svn.exemple.com/depot/projet 23351 sally 05 fev., 13:26 ./ 20620 sally 1084 13 janv. 2006 LISEZMOI 23339 harry 02 sept., 01:40 branches/ 23198 harry 23 janv., 17:17 tags/ 23351 sally 27 fevr., 13:26 trunk/
Les colonnes vous indiquent la révision à laquelle le fichier ou le dossier a été modifié pour la dernière fois, qui est l'auteur de ce changement, la taille du fichier si c'en est un, la date de dernière modification et le nom de l'élément.
Avertissement | |
---|---|
La commande svn list sans argument prend pour cible l'URL du dépôt correspondant au dossier local en cours, pas le dossier en cours de la copie de travail. Après tout, si vous voulez voir le contenu de votre dossier local, vous pouvez utiliser ls, tout simplement (ou l'équivalent sur votre système non-Unix). |
En plus de toutes les commandes citées précédemment, vous
pouvez utiliser svn update et
svn checkout avec l'option
--revision
pour ramener une copie de
travail complète « dans le passé » :
[8]
# met le dossier courant tel qu'il était à la révision 1729. $ svn update -r 1729 Mise à jour de '.' : … $
Astuce | |
---|---|
Beaucoup de nouveaux utilisateurs de Subversion essaient d'utiliser la commande svn update comme dans cet exemple pour « annuler » des modifications propagées, mais cela ne fonctionne pas parce que vous ne pouvez pas propager des changements que vous avez obtenus en remontant le temps d'une copie de travail si le contenu des fichiers a changé dans des révisions plus récentes. Reportez-vous à la section intitulée « Résurrection des éléments effacés » pour une description de comment « annuler » une propagation. |
Si vous préférez créer une nouvelle copie de travail
complète à partir d'un instantané plus ancien, vous pouvez
modifier l'appel classique à svn checkout. De
même que pour svn update, vous pouvez passer
l'option --revision
(-r
).
Mais pour des raisons que nous explicitons dans la section intitulée « Révisions pivots et révisions opérationnelles », vous voudrez certainement
spécifier la révision cible comme une partie de l'URL
étendue suivant la syntaxe de Subversion.
# Extraie la branche principale à la révision 1729. $ svn checkout http://svn.exemple.com/svn/depot/trunk@1729 trunk-1729 … # Extraie la branche principale actuelle telle qu'elle était # à la révision 1729. $ svn checkout http://svn.exemple.com/svn/depot/trunk -r 1729 trunk-1729 … $
Enfin, si vous êtes en train de réaliser une version
officielle et que vous voulez empaqueter vos fichiers et
dossiers suivis en versions, vous pouvez utiliser la
commande svn export pour créer une copie
locale de tout ou partie de votre dépôt sans que la zone
administrative .svn
ne soit incluse. La
syntaxe de base de cette sous-commande est identique à celle de
svn checkout :
# Exporte la branche principale à partir de la dernière révision. $ svn export http://svn.exemple.com/svn/depot/trunk trunk-export … # Exporte la branche principale à partir de la révision 1729. $ svn export http://svn.exemple.com/svn/depot/trunk@1729 trunk-1729 … # Exporte la branche principale actuelle, telle qu'elle était à la # révision 1729. $ svn export http://svn.example.com/svn/repo/trunk -r 1729 trunk-1729 … $
Maintenant que nous avons traité les tâches quotidiennes pour lesquelles vous utiliserez Subversion, nous allons passer en revue quelques tâches administratives liées à votre copie de travail.
Subversion ne conserve sur le serveur aucune trace de l'état ni de l'existence des copies de travail, il n'y a donc aucun impact côté serveur si des copies de travail traînent un peu partout. De la même façon, pas besoin de prévenir le serveur quand vous effacez une copie de travail.
Si vous envisagez de réutiliser une copie de travail, ça ne pose aucun problème de la laisser sur le disque jusqu'à ce que vous soyez prêts à l'utiliser à nouveau et, le moment venu, il suffit de lancer svn update pour la mettre à jour et ainsi la rendre utilisable.
Cependant, si vous êtes certain de ne plus utiliser une
copie de travail, vous pouvez la supprimer entièrement, en
utilisant les commandes de votre système d'exploitation. Vous
seriez cependant bien inspiré d'y jeter un œil avant, en
lançant la commande svn status
afin
d'examiner tous les fichiers marqués d'un ?
pour vous assurer qu'ils ne sont d'aucune importance.
Quand Subversion modifie votre copie de travail (ou toute information dans la zone administrative), il essaie de le faire de la manière la plus sûre possible. Avant de modifier votre copie de travail, Subversion inscrit ses intentions dans un fichier de traces. Ensuite, il exécute les commandes du fichier de traces pour appliquer les modifications demandées, en plaçant un verrou sur la partie concernée de la copie de travail pendant cette opération (pour empêcher d'autres clients Subversion d'accéder à cette copie de travail au beau milieu des changements). Pour finir, Subversion enlève son verrou et supprime le fichier de traces. D'un point de vue architectural, c'est le même fonctionnement qu'un système de fichiers journalisé. Si une opération Subversion est interrompue (par exemple si le processus est tué ou si la machine plante), le fichier de traces reste sur le disque. En exécutant de nouveau le fichier de traces, Subversion peut terminer l'opération en cours et votre copie de travail retrouve un état cohérent.
C'est exactement ce que fait la commande
svn cleanup : elle trouve et exécute les
fichiers de traces restant dans votre copie de travail, en
enlevant les verrous au passage. Si un beau jour Subversion
vous indique qu'une partie de votre copie de travail est
verrouillée (locked en anglais),
c'est la commande qu'il faut lancer. Par ailleurs,
svn status vous informe des verrous posés
dans la copie de travail, en affichant un L
devant les éléments verrouillés :
$ svn status L un-repertoire M un-repertoire/truc.c $ svn cleanup $ svn status M un-repertoire/truc.c
Ne confondez pas ces verrous agissant sur la copie de travail avec les verrous ordinaires que les utilisateurs de Subversion créent quand ils utilisent le modèle de gestion de versions parallèles verrouiller-modifier-libérer ; voir l'encadré Les différents types de « verrous » pour des éclaircissements.
Jusqu'à présent, nous nous sommes occupés des conflits intéressant le contenu des fichiers. Quand vos collaborateurs et vous faites des changements qui interfèrent dans le même fichier, Subversion vous force à fusionner ces changements avant de pouvoir les propager. [9]
Mais que se passe-t-il si vos collaborateurs déplacent ou suppriment un fichier sur lequel vous êtes en train de travailler ? À la suite d'un malentendu, quelqu'un a pensé que le fichier devait être supprimé alors qu'un autre veut toujours propager des modifications sur le fichier. Ou à l'occasion d'un réusinage de code, des collaborateurs ont renommé des fichiers et déplacé des dossiers. Si vous travailliez toujours sur ces fichiers, les modifications devront sûrement s'appliquer aux fichiers à leurs nouveaux emplacements. Ces conflits, qui se manifestent au niveau de la structure des dossiers plutôt que dans le contenu des fichiers eux-mêmes, portent le nom de conflits d'arborescences.
Comme pour les conflits textuels, les conflits d'arborescences empêchent la propagation d'avoir lieu en l'état, donnant l'opportunité à l'utilisateur d'examiner les conflits qui se présentent dans la copie de travail et de les résoudre avant de réaliser la propagation.
Prenons l'exemple d'un projet logiciel sur lequel vous travaillez et qui ressemble à ceci :
$ svn list -Rv svn://svn.exemple.com/trunk/ 13 harry 06 sept., 10:34 ./ 13 harry 27 06 sept., 10:34 COPYING 13 harry 41 06 sept., 10:32 Makefile 13 harry 53 06 sept., 10:34 LISEZMOI 13 harry 06 sept., 10:32 code/ 13 harry 54 06 sept., 10:32 code/machin.c 13 harry 130 06 sept., 10:32 code/truc.c $
Plus tard, lors de la révision 14, votre collaborateur
Harry renomme le fichier machin.c
en
bidule.c
. Malheureusement, vous n'y
prêtez pas attention toute de suite. Vous êtes occupé à
réaliser un ensemble de modifications différent, dont
certaines concernent machin.c
:
$ svn diff Index: code/truc.c =================================================================== --- code/truc.c (revision 13) +++ code/truc.c (copie de travail) @@ -3,5 +3,5 @@ int main(int argc, char *argv[]) { printf("Je n'aime pas être baladé !\n%s", machin()); - return 0; + return 1; } Index: code/machin.c =================================================================== --- code/machin.c (revision 13) +++ code/machin.c (copie de travail) @@ -1,4 +1,4 @@ const char *machin(void) { - return "Moi non plus !\n"; + return "Bah, moi j'aime bien être ballotté !\n"; } $
Vous commencez à réaliser que quelqu'un a modifié
machin.c
quand votre tentative de
propagation échoue :
$ svn commit -m "Quelques petits changements." Envoi code/machin.c Transmission des données . svn: E155011: Échec de la propagation (commit), détails : svn: E155011: Fichier '/home/svn/projet/code/machin.c' obsolète svn: E160013: Fichier non trouvé : transaction '14-e', chemin '/code/machin.c' $
À ce moment, vous devez lancer svn update.Non seulement votre copie de travail est mise à jour et vous pouvez voir les modifications effectuées par Harry, mais aussi l'arborescence est marquée comme étant en conflit afin que vous puissiez réellement mesurer ce qui a été modifié et résoudre le conflit proprement.
$ svn update Mise à jour de '.' : C code/machin.c A code/bidule.c U Makefile Actualisé à la révision 14. Résumé des conflits : Arborescences en conflit : 1
Dans la sortie qu'elle produit, svn update indique un conflit d'arborescence en utilisant un C majuscule dans la quatrième colonne. svn status fournit plus de détails sur ce conflit :
$ svn status M code/truc.c A + C code/machin.c > local edit, incoming delete upon update Résumé des conflits : Arborescences en conflit : 1 $
Notez que machin.c
est automatiquement
marqué pour ajout dans votre copie de travail, ce qui simplifie
les choses si vous décidez de conserver le fichier.
Du fait qu'un déplacement dans Subversion est implémenté comme une copie suivie d'un effacement et que ces deux opérations ne peuvent pas être corrélées facilement lors d'une mise à jour, tout ce que Subversion peut vous dire c'est que la mise à jour va effacer le fichier sur lequel vous avez fait des modifications. L'effacement peut faire partie d'un déplacement ou n'être simplement qu'un effacement en tant que tel. Déterminer exactement quelle est la sémantique associée à cette modification dans le dépôt est important : vous devez savoir dans quelle mesure vos modifications s'intègrent dans l'évolution générale du projet. Lisez donc les commentaires de propagation, discutez avec vos collaborateurs, étudiez les lignes modifiées à l'aide de la visualisation « diff ». Bref, faites ce que vous avez à faire pour déterminer quelle est la conduite à tenir dans ce cas précis.
Ici, le commentaire de propagation de Harry vous donne toutes les informations utiles.
$ svn log -r14 ^/trunk ------------------------------------------------------------------------ r14 | harry | 2011-09-06 10:38:17 -0400 (dim. 06. sept. 2011) | 1 ligne Chemins modifiés: M /Makefile D /code/machin.c A /code/bidule.c (de /code/machin.c:13) J'ai renommé machin.c en bidule.c et modifié le Makefile en conséquence. ------------------------------------------------------------------------ $
svn info affiche les URL des éléments en conflit. L'URL de gauche indique la source locale du conflit alors que l'URL droite indique la source externe du conflit. Ces URL vous montrent où vous devez commencer à chercher les modifications qui génèrent le conflit dans l'historique du dépôt.
$ svn info code/machin.c Chemin: code/machin.c Nom: machin.c URL: http://svn.exemple.com/svn/depot/trunk/code/machin.c … Tree conflict: local edit, incoming delete upon update Source gauche: (fichier) ^/trunk/code/machin.c@4 Source droit: (aucun) ^/trunk/code/machin.c@5 $
On dit que machin.c
est victime du
conflit d'arborescence. Il ne peut pas être propagé tant que
le conflit n'est pas résolu :
$ svn commit -m "Petites résolutions de problèmes" svn: E155015: Échec de la propagation (commit), détails : svn: E155015: Arrêt de la propagation : '/home/svn/projet/code/machin.c' demeure en conflit $
Pour résoudre ce conflit, vous devez soit approuver soit rejeter le déplacement effectué par Harry.
Si vous approuvez le déplacement, votre
machin.c
est superflu. Vous pouvez alors
l'effacer et marquer le conflit comme résolu. Mais
attendez : vous avez effectué des modifications dans ce
fichier ! Avant d'effacer machin.c
,
vous devez décider si les modifications que vous avez
effectuées doivent être appliquées ailleurs, par exemple
dans le nouveau fichier bidule.c
, qui
contient en effet tout l'ancien code de
machin.c
. Considérons que vos
modifications doivent « suivre le mouvement ».
Subversion n'est pas assez perfectionné pour faire ce travail
à votre place[10], vous devez donc faire ces
modifications manuellement.
Dans notre exemple, vous pourriez manuellement refaire vos
modifications sur machin.c
assez
facilement — ce n'était qu'un seul changement de ligne
après tout. Cependant, ce n'est pas toujours le cas, c'est
pourquoi nous allons voir une approche qui peut s'appliquer sur
de plus gros changements. Nous commencerons par utiliser
svn diff pour générer un fichier patch.
Ensuite, nous allons modifier les entêtes de ce fichier patch
pour pointer vers le nouveau nom de notre fichier déplacé.
Finalement, nous appliquons à nouveau le fichier patch modifié
sur la copie de travail.
$ svn diff code/machin.c > FICHIER_CORRECTIF $ cat FICHIER_CORRECTIF Index: code/machin.c =================================================================== --- code/machin.c (révision 14) +++ code/machin.c (copie de travail) @@ -1,4 +1,4 @@ const char *machin(void) { - return "Moi non plus!\n"; + return "Bah, moi j'aime bien être ballotté !\n"; } $ ### Editer FICHIER_CORRECTIF pour pointer vers code/bidule.c au lieu de code/machin.c $ cat FICHIER_CORRECTIF Index: code/bidule.c =================================================================== --- code/bidule.c (révision 14) +++ code/bidule.c (copie de travail) @@ -1,4 +1,4 @@ const char *machin(void) { - return "Moi non plus!\n"; + return "Bah, moi j'aime bien être ballotté !\n"; } $ svn patch FICHIER_CORRECTIF U code/bidule.c $
Maintenant que les changements que vous aviez faits
originellement sur machin.c
ont été
correctement reproduits dans bidule.c
, vous
pouvez effacer machin.c
et résoudre le
conflit en indiquant que vous choisissez la version de la copie
de travail comme valide.
$ svn delete --force code/machin.c D code/machin.c $ svn resolve --accept=working code/machin.c Conflit sur 'code/machin.c' résolu $ svn status M code/bidule.c M code/truc.c $ svn diff Index: code/truc.c =================================================================== --- code/truc.c (revision 14) +++ code/truc.c (working copy) @@ -3,5 +3,5 @@ int main(int argc, char *argv[]) { printf("Je n'aime pas être baladé !\n%s", machin()); - return 0; + return 1; } Index: code/bidule.c =================================================================== --- code/bidule.c (revision 14) +++ code/bidule.c (working copy) @@ -1,4 +1,4 @@ const char *machin(void) { - return "Moi non plus!\n"; + return "Bah, moi j'aime bien être ballotté !\n"; } $
Mais que se passe-t-il si vous n'êtes pas d'accord avec le
déplacement ? Eh bien, dans ce cas, vous pouvez effacer
bidule.c
après vous être assuré que
celui-ci ne contient pas de modification postérieure à son
renommage que vous souhaiteriez conserver (n'oubliez pas non
plus de revenir sur les modifications effectuées par Harry sur
Makefile
). Comme
machin.c
est déjà prévu d'être ajouté
lors de la prochaine propagation, il n'y a rien de plus à
faire et le conflit peut être marqué comme résolu :
$ svn delete --force code/bidule.c D code/bidule.c $ svn resolve --accept=working code/machin.c Conflit sur 'code/machin.c' résolu $ svn status M code/truc.c A + code/machin.c D code/bidule.c M Makefile $ svn diff Index: code/truc.c =================================================================== --- code/truc.c (revision 14) +++ code/truc.c (copie de travail) @@ -3,5 +3,5 @@ int main(int argc, char *argv[]) { printf("Je n'aime pas être baladé !\n%s", machin()); - return 0; + return 1; } Index: code/machin.c =================================================================== --- code/machin.c (revision 14) +++ code/machin.c (copie de travail) @@ -1,4 +1,4 @@ const char *machin(void) { - return "Moi non plus!\n"; + return "Bah, moi j'aime bien être ballotté !\n"; } Index: code/bidule.c =================================================================== --- code/bidule.c (revision 14) +++ code/bidule.c (copie de travail) @@ -1,4 +0,0 @@ -const char *machin(void) -{ - return "Moi non plus!\n"; -} Index: Makefile =================================================================== --- Makefile (revision 14) +++ Makefile (copie de travail) @@ -1,2 +1,2 @@ truc: - $(CC) -o $@ code/truc.c code/bidule.c + $(CC) -o $@ code/truc.c code/machin.c
Vous avez résolu votre premier conflit d'arborescence. Vous pouvez propager vos modifications et vous plaindre auprès de Harry à la pause café à propos de la surcharge de travail qu'il vous a infligée.
Nous en avons maintenant terminé avec la plupart des commandes du client Subversion. Les exceptions notables concernent les branches et la fusion (voir le Chapitre 4, Gestion des branches) ainsi que les propriétés (voir le la section intitulée « Propriétés »). Cependant, prenez le temps de parcourir le Guide de référence de svn : le client texte interactif pour vous faire une idée de toutes les commandes de Subversion et de la manière dont vous pouvez les utiliser pour rendre votre travail plus convivial.
[6] Si vous avez l'intention de recouvrer cet élément
afin qu'il soit de nouveau présent dans
HEAD
, lisez la section intitulée « Résurrection des éléments effacés ».
[7] Et si vous commandez ça, on vous chassera de la ville à coup de baguette rassie.
[8] Vous voyez, on vous avait bien dit que Subversion était une machine à remonter le temps.
[9] Certes, vous pouvez simplement marquer les fichiers en conflits comme résolus et les propager, si vous le voulez vraiment. Mais c'est rarement le cas en pratique.
[10] Dans certains cas, il arrive que Subversion 1.5 ou 1.6 fasse le transfert pour vous, mais cette fonctionnalité un peu « ça passe ou ça casse » a été enlevée dans Subversion 1.7.
Si vous lisez ce livre chapitre par chapitre, du début à la fin, vous avez acquis maintenant suffisamment de connaissance du fonctionnement de Subversion pour effectuer les opérations les plus courantes de gestion de versions. Vous savez comment extraire une copie de travail du dépôt Subversion. Vous n'avez aucune difficulté à propager vos modifications et à recevoir des mises à jour en utilisant les commandes svn commit et svn update. Vous avez probablement acquis le réflexe, presque inconscient, de lancer la commande svn status. Bref, vous êtes apte à utiliser Subversion dans un environnement normal pour tout type de projet.
Mais les fonctionnalités de Subversion ne s'arrêtent pas aux « opérations courantes de gestion de versions ». Il possède d'autres atouts, en plus de permettre simplement le partage de fichiers et de dossiers depuis un dépôt central.
Ce chapitre dévoile certaines fonctionnalités de Subversion qui, bien qu'importantes, ne sont pas d'une utilisation quotidienne pour un utilisateur normal. Nous supposons que vous êtes familier avec les possibilités de base de gestion de versions sur les fichiers et dossiers. Sinon, reportez-vous au Chapitre 1, Notions fondamentales et au Chapitre 2, Utilisation de base. Une fois que vous maîtriserez ces bases et que vous aurez assimilé ce chapitre, vous serez un super-utilisateur de Subversion !
Comme vous avez pu le constater dans la section intitulée « Révisions », les numéros de révision dans Subversion sont d'une grande simplicité, formant une suite d'entiers incrémentés au fur et à mesure des changements propagés dans le dépôt. Néanmoins, il ne faudra pas longtemps avant que vous ne puissiez plus vous rappeler exactement quel changement correspond à quelle révision. Heureusement, le fonctionnement normal de Subversion ne requiert pas souvent que vous fournissiez explicitement un numéro de révision pour une opération. Pour les opérations qui nécessitent vraiment un numéro de révision, c'est généralement un numéro de révision que vous avez vu soit dans un mail de propagation, soit dans la sortie d'une autre opération Subversion, soit dans un autre contexte où ce numéro possédait une signification particulière.
Note | |
---|---|
Faire référence aux numéros de révision avec le préfixe
« |
À l'occasion, vous aurez besoin d'indiquer un moment précis dans le temps pour lequel vous n'avez pas encore le numéro de révision sous la main ou en mémoire. C'est pourquoi, en sus des numéros de révision, la commande svn autorise d'autres formes d'appellations pour les révisions : les mots-clés de révision et les dates de révision.
Note | |
---|---|
Les différentes formes d'appellations pour les révisions
peuvent être mélangées et comparées pour définir des intervalles
de révisions. Par exemple, vous pouvez spécifier |
Le client Subversion accepte une grande variété de mots-clés
de révision. En tant qu'argument de l'option
--revision
(-r
) ces mots-clés
peuvent être utilisés en lieu et place des numéros et sont
remplacés par les numéros correspondants par
Subversion :
HEAD
La dernière (c'est-à-dire la plus récente) révision présente dans le dépôt.
BASE
Le numéro de révision d'un élément de la copie de travail. Si l'élément a été modifié localement, la « version BASE » fait référence à l'élément tel qu'il était sans ces modifications locales.
COMMITTED
La révision la plus récente avant (ou égale à)
BASE
, dans laquelle un élément a
changé.
PREV
La révision précédant
immédiatement la dernière révision dans laquelle un
élément a changé. Techniquement, cela revient à
COMMITTED
−1.
Comme vous pouvez le deviner d'après leur description, les
mots-clés de révision PREV
,
BASE
et COMMITTED
ne sont
utilisés que pour faire référence à un chemin dans la copie de
travail ; ils ne s'appliquent pas à des URL du dépôt. En
revanche, HEAD
peut être utilisé avec les
deux types de chemin (local ou URL du dépôt).
Vous trouvez ci-dessous des exemples de l'utilisation de ces mots-clés :
$ svn diff -r PREV:COMMITTED machin.c # affiche le dernier changement propagé concernant machin.c $ svn log -r HEAD # affiche le commentaire associé à la dernière propagation dans le dépôt. $ svn diff -r HEAD # compare votre copie de travail (avec tous ses changements locaux) # à la dernière version de l'arborescence correspondante du dépôt. $ svn diff -r BASE:HEAD machin.c # compare la version non modifiée localement de machin.c avec la dernière # version de machin.c dans le dépôt. $ svn log -r BASE:HEAD # affiche, pour le dossier suivi en versions courant, les commentaires # de propagation depuis la dernière mise à jour (svn update). $ svn update -r PREV machin.c # revient une version en arrière pour le fichier machin.c. Ceci diminue # de un la révision de la version de travail du fichier machin.c. $ svn diff -r BASE:14 machin.c # compare la version non modifiée localement de machin.c avec # la version de ce fichier à la révision 14.
Les numéros de révision n'ont aucune signification en dehors
du système de gestion de versions. Cependant, parfois, vous avez
besoin d'associer une date réelle à un moment précis de
l'historique des versions. À cette fin, l'option
--revision
(-r
) accepte comme
argument une date placée entre accolades ({
et }
). Subversion accepte les dates et les
heures aux formats définis dans le standard ISO-8601 ainsi que
quelques autres formats. Voici quelques exemples :
$ svn update -r {2006-02-17} $ svn update -r {15:30} $ svn update -r {15:30:00.200000} $ svn update -r {"2006-02-17 15:30"} $ svn update -r {"2006-02-17 15:30 +0230"} $ svn update -r {2006-02-17T15:30} $ svn update -r {2006-02-17T15:30Z} $ svn update -r {2006-02-17T15:30-04:00} $ svn update -r {20060217T1530} $ svn update -r {20060217T1530Z} $ svn update -r {20060217T1530-0500} …
Note | |
---|---|
Gardez à l'esprit que la plupart des interpréteurs de commandes (shells) requièrent de mettre les dates qui contiennent des espaces entre guillemets ou « d'échapper » les espaces. Certains interpréteurs peuvent aussi poser problème avec les accolades si elles ne sont pas échappées. Consulter la documentation de votre interpréteur pour connaître les spécificités de votre environnement. |
Quand vous spécifiez une date, Subversion convertit cette date vers le numéro de révision le plus récent du dépôt à la date spécifiée. Puis, il continue son travail avec ce numéro de révision :
$ svn log -r {2006-11-28} ------------------------------------------------------------------------ r12 | ira | 2006-11-27 12:31:51 -0600 (lun. 27 nov. 2006) | 6 lignes …
Vous pouvez également utiliser des intervalles de dates. Subversion trouve alors les révisions incluses entre ces deux dates :
$ svn log -r {2006-11-20}:{2006-11-29} …
Avertissement | |
---|---|
L'aptitude de Subversion à convertir correctement les horodatages de révisions en numéros de révision repose sur le fait que les horodatages de révisions sont ordonnées de manière croissante (plus le numéro est élevé, plus l'horodatage est récent). Mais l'horodatage d'une révision étant stocké comme une propriété modifiable et non suivie en versions de la révision (reportez-vous à la section intitulée « Propriétés »), les horodatages peuvent être modifiés et ne plus suivre la chronologie réelle. Aujourd'hui, cela n'affecte pas la plupart des opérations de Subversion (c'est le numéro de révision qui est l'identifiant primaire d'une révision). Mais si l'ordonnacement des horodatages n'est pas maintenu, il y a de grandes chances que l'utilisation des dates pour spécifier des intervalles de révisions dans votre dépôt ne fournisse pas les résultats attendus. Combiner les historiques de plusieurs dépôts pour n'en former qu'un (tel que décrit dans la section intitulée « Migration des données d'un dépôt ») est la cause principale de ce type de situation. |
Continuellement, nous copions, déplaçons, renommons et remplaçons des fichiers et des dossiers sur nos ordinateurs. Et votre système de gestion de versions ne doit pas être un obstacle à ces opérations sur les fichiers et dossiers suivis en versions. La gestion des fichiers par Subversion se fait pratiquement oublier, étant presque aussi flexible pour les fichiers suivis en versions que pour les autres. Mais cette flexibilité signifie qu'au cours de la vie de votre dépôt un objet suivi en versions a un certain nombre de chemins et qu'un chemin donné peut représenter plusieurs objets suivis en versions tout à fait différents. Cela ajoute un niveau de complexité supplémentaire dans les actions sur les chemins et les objets.
Subversion est plutôt adroit pour détecter les « changements d'adresses » dans l'historique du suivi de versions d'un objet. Par exemple, si vous demandez l'historique d'un fichier qui a été renommé la semaine dernière, Subversion fournit ce journal :la révision dans laquelle s'est produit le changement de nom et les journaux pertinents avant et après ce renommage. Ainsi, la plupart du temps, vous n'avez pas à vous préoccuper de ces opérations. Mais il arrive que Subversion ait besoin de votre aide pour lever des ambiguïtés.
L'exemple correspondant le plus simple est quand un fichier ou
un dossier est supprimé du suivi de versions, puis qu'un
nouveau dossier ou fichier est créé avec le même nom et ajouté
au suivi de versions. L'objet qui a été effacé et celui qui a été
ajouté plus tard ne sont pas les mêmes. Ils se trouve qu'ils ont
juste le même chemin (/trunk/objet
par
exemple). Que signifie alors de demander à Subversion l'historique
de /trunk/objet
? La question
concerne-t-elle l'objet actuellement à cet emplacement ou l'objet
précédent qui a été supprimé ? Ou encore les opérations sur
tous les objets qui ont résidé à cet
emplacement ? Subversion a besoin de savoir ce que vous
demandez réellement.
Et, en raison des déplacements, l'historique des objets suivis
en versions peut être beaucoup plus tordu que cela. Par exemple,
vous pouvez avoir un dossier appelé
concept
, contenant une ébauche de projet
logiciel sur lequel vous vous êtes essayé. Il se peut que ce
projet mûrisse et que l'idée soit pertinente au point que, chose
inimaginable, vous décidiez de donner un nom au projet
[11].
Imaginons que vous nommiez ce logiciel
Frabnaggilywort
. Il semble alors logique de
renommer le dossier concept
en
frabnaggilywort
pour refléter le nom du
projet. L'eau coule sous les ponts et Frabnaggilywort sort en
version 1.0, est téléchargé et utilisé quotidiennement par des
tonnes de gens qui veulent se faciliter la vie.
Quelle belle histoire ! Mais elle ne s'arrête pas là.
Comme vous avez une âme d'entrepreneur, vous avez déjà une autre
idée derrière la tête : vous créez donc un nouveau dossier
concept
et la boucle est bouclée. En fait,
ce cycle recommence plusieurs fois au fil du temps, à chaque fois
à partir de ce vieux dossier concept
qui, quelquefois, est renommé, quand l'idée plaît et, d'autres
fois, est effacé quand l'idée ne convient pas. En plus, pour être
réellement tordu, vous donnez parfois à
concept
un autre nom temporaire, puis
renommez ce même dossier concept
pour une
raison quelconque.
Avec de tels scénarios, demander à Subversion d'apprendre à travailler avec ces renommages multiples est un peu comme dire à un automobiliste de la banlieue de prendre la direction de Paris et de prendre à gauche sur « la rue du Château » : il croisera la rue du Château à Asnières, La Garenne-Colombes, Nanterre, Neuilly, Rueil-Malmaison, … et, non, ce n'est pas la même rue à chaque fois. De la même manière, Subversion a besoin d'un peu plus de précisions pour travailler correctement.
Heureusement, Subversion vous permet de lui indiquer
de quelle rue du Château vous parlez exactement. Le mécanisme
utilisé s'appelle les révisions pivots
et vous les fournissez à Subversion uniquement pour identifier de
manière unique une ligne de l'historique. Comme il y a au plus
un objet suivi en versions à un endroit et à un moment donnés (ou
plus précisément à une révision donnée), la combinaison d'un
chemin et d'une révision pivot est tout ce dont vous avez
besoin pour désigner une ligne spécifique de l'historique. Les
révisions pivots sont indiquées au client texte interactif Subversion
en utilisant la notation at (on l'appelle
ainsi parce que la syntaxe de la commande utilise le signe
« arobase » :@
) suivi de la
révision pivot demandée, en fin de chemin.
Mais alors qu'en est-il de l'option
--revision
(-r
) dont nous avons
tant parlé dans ce livre ? Cette révision (ou ensemble de
révisions) est appelée la révision
opérationnelle (ou intervalle de révisions
opérationnelles). Une fois qu'une ligne particulière
de l'historique a été identifiée en utilisant un chemin et une
révision pivot, Subversion effectue la requête en utilisant la
révision opérationnelle (ou l'intervallle de révisions
opérationnelles). Pour reprendre notre analogie avec les rues
françaises, si on vous dit d'aller au 15 de la rue du Château à
Rueil-Malmaison [12],
vous pouvez penser que « la rue du Château »
est le chemin dans le système de fichiers et
« Rueil-Malmaison » la révision pivot. Ces deux
informations identifient de manière unique une route donnée et
vous évitent de parcourir une autre rue du Château à
la recherche de votre destination finale. Maintenant, vous pouvez
rechercher le « 15 » comme numéro de révision
opérationnelle puisque nous savons exactement
où aller.
Supposons que nous ayons créé notre dépôt il y a longtemps et
que dans la révision 1 nous ayons ajouté notre premier
dossier concept
ainsi qu'un fichier
IDÉE
, situé dans ce dossier, contenant la
description du concept. Nous avons ensuite ajouté et modifié de
véritables lignes de code. À la révision 20, nous avons renommé ce
dossier en frabnaggilywort
. Lors de la
révision 27, nous développons un nouveau concept et un nouveau
dossier concept
est créé pour l'héberger,
avec un nouveau fichier IDÉE
pour le décrire.
Cinq ans et vingt mille révisions passent, comme dans tout bon
roman d'amour.
À présent, plusieurs années plus tard, nous nous demandons à
quoi ressemblait le fichier IDÉE
en révision
1. Mais Subversion a besoin de savoir si nous demandons à quoi
ressemble le fichier actuel tel qu'il était
lors de la révision 1 ou si nous demandons le contenu du fichier
positionné dans l'arborescence à concept/IDÉE
au moment de la révision 1. Ces questions ont certainement des
réponses différentes et grâce aux révisions pivots, nous
pouvons poser ces deux questions. Pour obtenir le contenu du
fichier IDÉE
actuel tel qu'il était dans
cette vieille révision, tapez :
$ svn cat -r 1 concept/IDÉE svn: E195012: Impossible de trouver la localisation dans le dépôt de 'concept/IDÉE' pour la révision 1
Bien sûr, dans cet exemple, le fichier
IDÉE
actuel n'existait pas lors de la
révision 1, c'est pourquoi Subversion renvoie une erreur. La
commande ci-dessus est un raccourci pour la notation plus longue
qui explicite la révision pivot. La notation complète est
donc :
$ svn cat -r 1 concept/IDÉE@BASE svn: E195012: Impossible de trouver la localisation dans le dépôt de 'concept/IDÉE' pour la révision 1
On obtient bien le résultat attendu.
Le lecteur perspicace est certainement en train de se demander
si la syntaxe des révisions pivots ne pose pas de problèmes
pour les chemins ou les URL qui comportent déjà le signe arobase.
Après tout, comment svn peut-il savoir si
nouveau@11
est le nom d'un dossier dans mon
arborescence ou juste la syntaxe pour « révision 11 de
nouveau
» ? Dieu merci, alors que
svn opte par défaut pour cette dernière
hypothèse, il existe une solution de contournement triviale :
il suffit juste d'ajouter un signe arobase à la fin du
chemin, comme ceci : nouveau@11@
.
svn ne s'intéresse qu'au dernier arobase de
l'argument et il n'est pas considéré comme illégal d'omettre le
spécificateur de révision pivot après cet arobase. Cette
solution de contournement s'applique même aux chemins qui se
terminent par arobase (utilisez
nom-du-fichier@@
pour désigner le fichier
nom-du-fichier@
.
Posons maintenant l'autre question : dans la révision 1,
quel était le contenu du fichier qui occupait l'adresse
concept/IDÉE
à ce moment là ? Nous
allons utiliser explicitement une révision pivot pour nous
aider :
$ svn cat concept/IDÉE@1 L'idée de ce projet est de fournir un logiciel qui peut frabber un naggily wort. Frabber les naggilys worts est particulièrement difficile et ne pas le faire correctement aurait des conséquences inimaginables. Nous devons donc utiliser des mécanismes de vérification des entrées et des données du dernier cri.
Remarquez que cette fois nous n'avons pas fourni de révision opérationnelle. C'est parce que, quand aucune révision opérationnelle n'est spécifiée, Subversion considère que le numéro de révision opérationnelle est égal au numéro de révision pivot.
Comme vous pouvez le constater, la résultat de la commande
semble être correct. Le texte parle même de "frabber les naggilys
worts", ce qui laisse supposer que c'est certainement le fichier
décrivant le logiciel maintenant connu sous le nom de
Frabnaggilywort. En fait, on peut le vérifier en combinant une
révision pivot explicite et une révision opérationnelle explicite.
Nous savons que dans HEAD
, le projet
Frabnaggilywort se situe dans le dossier
frabnaggilywort
. Nous spécifions donc que
nous voulons voir à quoi ressemblait le fichier
frabnaggilywort/IDÉE
identifié dans
HEAD
au moment de la révision 1.
$ svn cat -r 1 frabnaggilywort/IDÉE@HEAD L'idée de ce projet est de fournir un logiciel qui peut frabber un naggily wort. Frabber les naggilys worts est particulièrement difficile et ne pas le faire correctement aurait des conséquences inimaginables. Nous devons donc utiliser des mécanismes de vérification des entrées et des données du dernier cri.
Vous pouvez aussi spécifier des révisions pivots et des
révisions opérationnelles moins triviales. Par exemple, disons
que frabnaggilywort
a été effacé de
HEAD
, mais nous savons qu'il existait en
révision 20 et nous voulons voir les différences entre la
révision 4 et la révision 10 pour son fichier
IDÉE
. Nous pouvons utiliser la révision pivot
20 en conjonction avec l'URL qu'avait le fichier
frabnaggilywort/IDÉE
dans la révision 20
et utiliser 4 et 10 pour spécifier l'intervalle de révisions
opérationnelles.
$ svn diff -r 4:10 http://svn.red-bean.com/projets/frabnaggilywort/IDÉE@20 Index: frabnaggilywort/IDÉE =================================================================== --- frabnaggilywort/IDÉE (révision 4) +++ frabnaggilywort/IDÉE (révision 10) @@ -1,5 +1,5 @@ -L'idée de ce projet est de fournir un logiciel qui peut frabber un -naggily wort. Frabber les naggilys worts est particulièrement difficile -et ne pas le faire correctement aurait des conséquences inimaginables. -Nous devons donc utiliser des mécanismes de vérification des -entrées et des données du dernier cri. +L'idée de ce projet est de fournir un logiciel client-serveur qui peut +frabber un naggily wort de manière distante. Frabber les naggilys worts +est particulièrement difficile et ne pas le faire correctement aurait +des conséquences inimaginables. Nous devons donc utiliser des mécanismes +de vérification des entrées et des données du dernier cri.
Heureusement, la plupart d'entre vous n'auront pas à faire face à des situations aussi complexes. Mais si jamais c'est le cas, rappelez-vous que les révisions pivots sont les informations complémentaires dont a besoin Subversion pour lever toute ambiguïté.
Nous avons vu en détail comment Subversion stocke et récupère les différentes versions des fichiers et dossiers dans le dépôt. Des chapitres entiers ont décrit cette fonctionnalité fondamentale de l'outil. Et si la gestion de versions se limitait à ça, Subversion couvrirait déjà complètement les besoins attendus pour un système de gestion de versions.
Mais ce n'est pas tout.
En plus de gérer les versions de vos dossiers et de vos fichiers, Subversion fournit une interface pour ajouter, modifier et supprimer des méta-données suivies en versions pour chacun de vos dossiers et de vos fichiers. On appelle ces méta-données des propriétés. Elles peuvent être pensées comme des tableaux à deux colonnes, qui associent des noms de propriétés à des valeurs arbitraires, pour chaque élément de votre copie de travail. En termes simples, vous pouvez assigner n'importe quel nom et n'importe quelle valeur à vos propriétés, à la seule condition que le nom ne contiennent que des caractères ASCII. Et l'atout principal de ces propriétés réside dans le fait que ces propriétés sont également suivies en versions, tout comme le contenu textuel de vos fichiers. Vous pouvez modifier, propager et revenir en arrière sur les propriétés aussi facilement que sur le contenu des fichiers. L'envoi et la réception des changements concernant les propriétés intervient lors de vos propagations et mises à jour : vous n'avez pas à changer vos habitudes pour les utiliser.
Note | |
---|---|
Subversion a réservé pour son propre usage les propriétés
dont le nom commence par |
Les propriétés sont aussi présentes ailleurs dans Subversion. De la même manière que pour les fichiers et dossiers, chaque révision en tant que telle peut avoir des propriétés arbitraires associées. Les mêmes contraintes s'appliquent : nom lisible par un humain et valeur arbitraire, éventuellement binaire. La différence principale est que les propriétés des révisions ne sont pas suivies en versions. Autrement dit, si vous changez la valeur ou si vous supprimez une propriété d'une révision, il n'y a pas moyen, en utilisant Subversion, de revenir à la valeur précédente.
Subversion ne fournit pas de recommandation particulière quant
à l'utilisation des propriétés. Il demande seulement de ne pas
utiliser de nom de propriété qui commence par le préfixe
svn:
. C'est l'espace de noms qu'il garde pour
son propre usage. Et Subversion utilise bien lui-même les
propriétés, suivies en versions ou pas. Certaines propriétés
suivies en versions ont une signification particulière ou des
effets particuliers quand elles font référence à un fichier ou à
un dossier, ou stockent des informations relatives à la
révision à laquelle elles sont rattachées. Certaines propriétés de
révision sont automatiquement rattachées à une révision par la
procédure de propagation et stockent des informations relatives à
cette révision. La plupart de ces propriétés sont mentionnées
ailleurs dans ce chapitre ou dans d'autres chapitres comme faisant
partie de sujets plus généraux. Pour une liste exhaustive des
propriétés pré-définies de Subversion, référez-vous à
la section intitulée « Propriétés réservées à l'usage de Subversion ».
Note | |
---|---|
Bien que Subversion crée automatiquement des propriétés à
chaque révision ( |
Dans cette section, nous examinons l'utilité des propriétés, à la fois pour l'utilisateur et pour Subversion lui-même. Vous apprendrez les sous-commandes svn relatives aux propriétés et comment la modification des propriétés change votre manière habituelle d'utiliser Subversion.
À l'instar de Subversion, qui utilise les propriétés pour stocker des méta-données sur les fichiers, les dossiers et les révisions qu'il gère, vous pouvez faire une utilisation similaire des propriétés. Vous pouvez trouver utile d'avoir un endroit, près de vos données suivies en versions, pour stocker des méta-données relatives à vos données.
Imaginons que vous vouliez créer un site Web qui héberge beaucoup de photos et qui les affiche avec une légende et une date. D'accord, mais votre collection de photos change constamment, donc vous voulez automatiser le plus possible la gestion du site. Ces photos peuvent être relativement volumineuses et vous voulez pouvoir fournir des miniatures à vos visiteurs, comme c'est généralement le cas sur ce genre de site.
Certes, vous pouvez le faire en utilisant des fichiers
traditionnels. C'est-à-dire que vous avez votre
image123.jpg
et une
image123-thumbnail.jpg
côte à côte dans un
dossier. Ou, si vous voulez garder les mêmes noms de fichier,
vous placez vos miniatures dans un dossier différent, comme
thumbnails/image123.jpg
. Vous pouvez
également stocker vos légendes et dates de la même façon,
séparées encore une fois du fichier image original. Mais le
problème est que votre collection de fichiers s'agrandit de
plusieurs fichiers à chaque nouvelle photo ajoutée au
site.
Maintenant, considérons le même site Web conçu en utilisant
les propriétés des fichiers fournies par Subversion. Imaginez un
simple fichier image, image123.jpg
, et un
ensemble de propriétés relatives à ce fichier nommées
légende
, date
et même
miniature
. À présent, le dossier de votre
copie de travail se gère beaucoup plus facilement ; en fait,
vu du navigateur, il semble ne contenir que des images. Mais vos
scripts d'automatisation vont plus loin : ils savent qu'ils
peuvent utiliser les commandes svn (ou mieux,
ils peuvent utiliser les connecteurs spécifiques au langage
utilisé, voir la section intitulée « Utilisation des API ») pour
extraire les informations dont votre site a besoin sans avoir à
lire un fichier d'index ou à jouer avec des chemins de
fichiers.
Note | |
---|---|
Bien que Subversion n'impose que peu de restrictions sur les noms et les valeurs des propriétés, il n'a pas été conçu pour gérer de façon optimale des valeurs de propriétés de grande taille ou un grand nombre de propriétés sur un fichier ou un dossier donné. Subversion garde souvent en mémoire en même temps tous les noms et valeurs de propriétés associés à un élément, ce qui peut engendrer des problèmes de performance lors de l'utilisation de très gros ensembles de propriétés. |
On utilise également fréquemment des propriétés de révisions
personnalisées. Une utilisation classique est d'avoir une
propriété qui contient un identifiant en provenance d'un autre
outil de gestion et de l'associer à une révision. Par exemple,
l'outil de gestion est utilisé pour suivre les bogues et la
révision corrige le bogue associé à l'identifiant. Il s'agit
parfois aussi d'utiliser des noms plus conviviaux pour les
révisions : il peut être difficile de se remémorer que la
révision 1935 correspond à une révision qui a subi la totalité
des tests, alors qu'une propriété
resultat-des-tests
avec la valeur
tout ok
est autrement plus utile.
$ svn commit -m "Corrige la dernière régression connue." \ --with-revprop "resultat-des-tests=tout ok" Envoi lib/crit_bits.c Transmission des données . Révision 912 propagée. $
La commande svn offre différentes possibilités pour ajouter ou modifier des propriétés sur les fichiers et les dossiers. Pour les propriétés avec des valeurs courtes, lisibles par un humain, la solution la plus simple est sûrement de spécifier le nom de la propriété et sa valeur en ligne de commande avec la sous-commande svn propset :
$ svn propset copyright '(c) 2006 Red-Bean Software' calc/bouton.c Propriété 'copyright' définie sur 'calc/bouton.c' $
Mais nous avons vanté la souplesse de Subversion pour
spécifier les valeurs des propriétés. Ainsi, si vous envisagez
d'avoir des valeurs de plusieurs lignes de texte, ou même une
valeur binaire, la passer en ligne de commande ne vous convient
pas. La sous-commande svn propset accepte donc
l'option --file
(-F
) pour
spécifier le nom d'un fichier qui contient la nouvelle valeur de
la propriété.
$ svn propset licence -F /chemin/vers/LICENCE calc/bouton.c Propriété 'licence' définie sur 'calc/bouton.c' $
Il y a quelques restrictions sur les noms de propriétés. Un
nom de propriété doit commencer par une lettre, le caractère
deux points (:
), ou le caractère souligné
(_
) ; ensuite, vous pouvez aussi
utiliser des chiffres, des tirets (-
) et des
points (.
)
[13].
En plus de la commande propset, svn dispose de la commande propedit. Cette commande utilise l'éditeur de texte pré-configuré (reportez-vous à la section intitulée « Configuration générale ») pour ajouter ou modifier des propriétés. Quand vous exécutez la commande, svn lance votre éditeur de texte avec un fichier temporaire qui contient la valeur actuelle de la propriété (ou un contenu vierge si vous ajoutez une nouvelle propriété). Vous pouvez alors modifier la valeur dans l'éditeur de texte pour y placer votre nouvelle valeur, sauvegarder le fichier temporaire et quitter l'éditeur. Si Subversion détecte que la valeur a effectivement changé, il la prend en compte. Si vous quittez l'éditeur sans faire de changement, la propriété n'est pas modifiée :
$ svn propedit copyright calc/bouton.c ### sortez de l'éditeur sans faire de modification Pas de modification de la propriété 'copyright' sur 'calc/bouton.c' $
Vous pouvez noter que, à l'instar des autres commandes svn, celles relatives aux propriétés fonctionnent aussi sur des chemins multiples. Vous pouvez ainsi modifier les propriétés d'un ensemble de fichiers en une seule commande. Par exemple, nous aurions pu taper :
$ svn propset copyright '(c) 2006 Red-Bean Software' calc/* Propriété 'copyright' définie sur 'calc/Makefile' Propriété 'copyright' définie sur 'calc/bouton.c' Propriété 'copyright' définie sur 'calc/entier.c' … $
Toutes ces manipulations de propriétés ne seraient pas vraiment utiles si vous ne pouviez pas récupérer facilement la valeur d'une propriété. Subversion propose donc deux sous-commandes pour afficher les noms et les valeurs des propriétés associées aux fichiers et dossiers. La commande svn proplist fournit la liste des noms de propriétés qui existent dans un chemin. Une fois que vous connaissez les noms des propriétés d'un élément, vous pouvez obtenir les valeurs correspondantes avec la commande svn propget. Cette commande affiche sur la sortie standard la valeur de la propriété dont le nom et le chemin (ou l'ensemble des chemins) ont été passés en paramètres.
$ svn proplist calc/bouton.c Propriétés sur 'calc/bouton.c': copyright licence $ svn propget copyright calc/bouton.c (c) 2006 Red-Bean Software $
Il y a même une variante de la commande
proplist qui liste à la fois le nom et la
valeur de toutes les propriétés. Ajoutez simplement l'option
--verbose
(-v
) à la
commande :
$ svn proplist -v calc/bouton.c Propriétés sur 'calc/bouton.c': copyright (c) 2006 Red-Bean Software license ================================================================ Copyright (c) 2006 Red-Bean Software. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the recipe for Fitz's famous red-beans-and-rice. …
La dernière sous-commande relative aux propriétés est propdel. Puisque Subversion vous autorise à stocker des propriétés avec une valeur vide, vous ne pouvez pas supprimer une propriété en utilisant svn propedit ou svn propset. Par exemple, la commande suivante ne produit pas le résultat escompté :
$ svn propset licence calc/bouton.c Propriété 'licence' définie sur 'calc/bouton.c' $ svn proplist -v calc/bouton.c Propriétés sur 'calc/bouton.c': copyright (c) 2006 Red-Bean Software license $
Vous devez utiliser la sous-commande propdel pour supprimer complètement une propriété. La syntaxe est similaire aux autres commandes sur les propriétés :
$ svn propdel license calc/bouton.c Propriété 'licence' supprimée de 'calc/bouton.c'. $ svn proplist -v calc/bouton.c Propriétés sur 'calc/bouton.c': copyright (c) 2006 Red-Bean Software $
Vous souvenez-vous des propriétés de révision non suivies en
versions ? Vous pouvez les modifier elles-aussi en
utilisant les mêmes sous-commandes svn que
nous venons de décrire. Il suffit juste d'ajouter l'option
--revprop
au client texte interactif et de spécifier
la révision à laquelle s'applique la modification. Puisque les
numéros de révisions s'appliquent à l'ensemble de l'arborescence,
vous n'avez pas besoin d'indiquer un chemin pour ces commandes,
du moment que vous êtes dans une copie de travail du dépôt
contenant la révision dont vous voulez modifier la propriété.
Autrement, vous pouvez simplement fournir n'importe quelle URL
du dépôt en question (y compris l'URL racine). Par exemple,
imaginons que vous vouliez remplacer le commentaire associé à la
propagation d'une révision précédente
[14].
Si le dossier actuel fait partie de votre copie de travail du
dépôt, vous pouvez simplement lancer la commande
svn propset sans spécifier de
chemin :
$ svn propset svn:log "* bouton.c: corrige un avertissement du compilateur." -r11 --revprop Nouvelle valeur définie pour la propriété 'svn:log' à la révision du dépôt '11' $
Et même si vous n'avez pas extrait de copie de travail du dépôt, vous pouvez toujours modifier la propriété en indiquant l'URL racine du dépôt :
$ svn propset svn:log "* bouton.c: corrige un avertissement du compilateur." -r11 --revprop \ http://svn.exemple.com/depot/projet Nouvelle valeur définie pour la propriété 'svn:log' à la révision du dépôt '11' $
Notez que le droit de modifier cette propriété non suivie en versions doit être explicitement ajouté par l'administrateur du dépôt (voir la section intitulée « Correction des commentaires de propagation »). En effet, la propriété n'étant pas suivie en versions, vous risquez une perte d'informations si vous la modifiez à tort et à travers. L'administrateur du dépôt peut mettre en place des protections contre ce type d'incident et, par défaut, la modification de propriétés non suivies en versions est désactivée.
Astuce | |
---|---|
Dans la mesure du possible, il est recommandé d'utiliser svn propedit au lieu de svn propset. Bien que le résultat soit identique, la première permet de visualiser la valeur actuelle de la propriété que l'on veut modifier, ce qui aide à vérifier que l'on fait bien ce que l'on pense faire. C'est particulièrement vrai dans le cas des propriétés non suivies en versions. Il est aussi beaucoup plus facile de modifier un texte de plusieurs lignes dans un éditeur de texte qu'en ligne de commande. |
Maintenant que vous êtes familier avec toutes les sous-commandes svn relatives aux propriétés, voyons comment la modification des propriétés change le cycle habituel d'utilisation de Subversion. Comme mentionné précédemment, les propriétés des fichiers et dossiers sont suivies en versions, à l'instar du contenu des fichiers. En conséquence, Subversion offre les mêmes possibilités pour fusionner (proprement ou quand apparaissent des conflits) vos modifications avec celles des autres collaborateurs.
De même que pour le contenu des fichiers, les modifications de propriétés sont locales. Elles ne deviennent permanentes que quand vous les propagez dans le dépôt via svn commit. Vos modifications sur les propriétés peuvent aussi être annulées facilement : la commande svn revert restaure vos fichiers et dossiers dans leur état d'avant les modifications, y compris pour les propriétés. Vous pouvez également obtenir des informations intéressantes sur l'état des propriétés de vos fichiers et dossiers en utilisant les commandes svn status et svn diff.
$ svn status calc/bouton.c M calc/bouton.c $ svn diff calc/bouton.c Modification de propriétés sur calc/bouton.c ___________________________________________________________________ Added: copyright ## -0,0 +1 ## +(c) 2006 Red-Bean Software $
Remarquez que la sous-commande status
place le M
dans la deuxième colonne plutôt
que dans la première. C'est parce que nous avons modifié les
propriétés de calc/bouton.c
, mais pas son
contenu. Si nous avions changé les deux, nous aurions vu le
M
dans la première colonne également
(reportez-vous à la section intitulée « Vue d'ensemble des changements effectués »).
Vous avez peut-être remarqué que Subversion affiche les différences au niveau des propriétés d'une manière non standard. Certes, vous pouvez toujours rediriger la sortie de svn diff pour créer un fichier correctif utilisable : le programme patch ignore ce qui concerne les propriétés (comme il ignore tout ce qu'il ne comprend pas). Malheureusement, cela signifie aussi que pour appliquer intégralement un correctif généré par svn diff, les modifications concernant les propriétés doivent être faites à la main.
Subversion 1.7 améliore la situation sur deux points. D'abord, son affichage non standard des différences de propriétés est au moins traitable par machine — c'est une amélioration par rapport à l'affichage des propriétés des versions antérieures à la 1.7. Ensuite, Subversion 1.7 introduit la sous-commande svn patch, conçue spécifiquement pour prendre en charge les informations supplémentaires que génère la sortie de svn diff afin d'appliquer les changements à la copie de travail. Ainsi, pour ce qui nous concerne directement dans ce chapitre, les différences de propriétés indiquées dans les fichiers diff produits par svn diff de Subversion 1.7 ou ultérieur peuvent être appliqués automatiquement à une copie de travail par la commande svn patch. Pour plus d'informations concernant svn patch, référez-vous à svn patch dans Guide de référence de svn : le client texte interactif.
Note | |
---|---|
Il existe une exception à l'indication des modifications
de propriétés que rapporte la commande svn
diff : les modifications à la propriété
spéciale de Subversion |
Subversion 1.8 introduit le concept de propriétés héritées. Il n'y a rien de particulier concernant une propriété qui fait qu'on peut en hériter. En fait, on peut hériter de toutes les propriétés suivies en versions ! La principale différence entre les propriétés suivies en version avant Subversion 1.8 et après est que ces dernières proposent un mécanisme pour trouver les propriétés définies sur des chemins cibles parents même si ces parents ne se trouvent plus dans la copie de travail.
L'héritage de propriété se concrètise par l'intermédiaire de
quelques commandes. D'abord, les sous-commandes
svn proplist et svn propget
peuvent retrouver toutes les propriétés de parents de chemins
d'une URL ou d'une copie de travail en utilisant l'option
--show-inherited-props
. Vous pouvez vous
représenter cette option comme étant l'opposé de l'option
--recursive
: au lieu de parcourir
récursivement « vers le bas » les sous-dossiers
de la cible, les sous-commandes avec l'option
--show-inherited-props
parcourrent « vers
le haut » les dossiers parents de la cible. Les
sous-commandes svnlook propget et
svnlook proplist peuvent aussi utiliser
l'option --show-inherited-props
de la même
manière.
Regardons un exemple pour mieux en comprendre le
fonctinnement. La commande propget récursive ci-dessous
appliquée à la racine de la copie de travail trouve la propriété
svn:auto-props
définie à la fois sur la
cible et sur l'un de ses sous-dossiers
site
:
$ svn pg svn:auto-props --verbose -R . Propriétés sur '.': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native Propriétés sur 'site': svn:auto-props *.html = svn:eol-style=native
Si nous spécifions comme cible de la sous-commande le
sous-dossier site
et que nous utilisons
l'option --show-inherited-props
, nous trouvons
que la propriété svn:auto-props
est définie
sur la cible et son parent. Les propriétés
des parents sont affichées en tant que
« héritées » :
$ svn pg svn:auto-props --verbose --show-inherited-props site Propriétés héritées sur 'site' de '.': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native Propriétés sur 'site': svn:auto-props *.html = svn:eol-style=native
Dans les exemples précédents, la racine de la copie de
travail correspond à la racine du dépôt, mais les propriétés
peuvent aussi être héritées de l'extérieur de la copie de
travail quand les racines ne coïncident pas. Réalisons une
extraction du dossier site
de l'exemple
précédent et faisons-en la racine de notre copie de
travail :
$ svn co http://svn.exemple.com/depot site-ct A site-ct/publication A site-ct/publication/ch2.html A site-ct/publication/actualités.html A site-ct/publication/ch3.html A site-ct/publication/faq.html A site-ct/publication/index.html A site-ct/publication/ch1.html U site-ct Révision 19 extraite. $ cd site-ct
Maintenant, quand nous cherchons les propriétés héritées sur un chemin d'une copie de travail, nous pouvons constater qu'une propriété est héritée d'un parent de la copie de travail et une est héritée d'un parent du dépôt, c'est-à-dire à un emplacement « au-dessus » de la racine de la copie de travail :
$ svn pg svn:auto-props --verbose --show-inherited-props publication Propriétés héritées sur 'publication', de 'http://svn.exemple.com/depot': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native Propriétés héritées sur 'publication', de '.': svn:auto-props *.html = svn:eol-style=native
Avertissement | |
---|---|
Vous ne pouvez hériter de propriétés des chemins dans des dépôts pour lesquels vous avez un droit en lecture — regardez la section intitulée « Authentification et contrôle d'accès intégrés » et la section intitulée « Contrôle d'accès ». Si vous n'avez pas de droit de lecture à un chemin parent alors tout se passe comme si le parent n'avait pas de propriété définie. |
Comme indiqué précédemment, les commandes
svnlook proplist et svnlook
propget acceptent l'option
--show-inherited-props
, mais au lieu de
travailler sur des copies de travail ou des URL, elles
travaillent sur des chemins de dépôts :
$ svnlook pg repos svn:auto-props /site/publication --show-inherited-props -v Propriétés héritées sur '/site/publish' de '/': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native Propriétés héritées sur '/site/publish' de '/site': svn:auto-props *.html = svn:eol-style=native
Les propriétés héritées en amont de la racine d'une copie de travail sont mises en cache dans la zone administrative de la copie de travail au momemnt de l'extraction et des mises à jour de la copie de travail. Cela signifie que vous n'avez pas besoin d'accéder au dépôt pour visualiser les propriétés héritées. Cela permet aux sous-commandes Subversion qui n'accèdent tradionnellement pas au dépôt (par exemple svn add) de restées « déconnectées » tout en ayant accès aux propriétés héritées de chemins qui ne sont pas dans la copie de travail. Cependant, cela signifie aussi que les propriétés héritées en amont de la racine de la copie de travail peuvent avoir été modifiées depuis la dernière mise à jour, ce qui rend votre cache local obsolète. Donc, si vous avez absolument besoin des dernières valeurs de propriétés héritées, il est toujours préférable de d'abord mettre à jour votre copie de travail ou de requêter directement le dépôt.
Arrivé à ce point, vous devez vous dire : « pas
mal, mais à quoi cela sert-il vraiment ? ». En tant
que tel, l'héritage de propriété n'est pas très utile. Avant la
version 1.8, toutes les propriétés svn:*
que Subversion se réserve (et possiblement toutes les propriétés
spécifiques définies par les utilisateurs) s'appliquaient
seulement sur le chemin sur lequel elles étaient définies ou, au
plus, sur les enfants directs des chemins[15]. Les propriétés héritées sont un moyen
utilisé par Subversion pour accomplir d'autres choses
intéressantes, comme définir des propriétés
automatiques avec svn:auto-props
ou des
bannissements sur tout le dépôt avec la propriété
svn:global-ignores
. Reportez-vous à la section intitulée « Configuration automatique des propriétés » et la section intitulée « Occultation des éléments non suivis en versions » pour plus
d'informations sur ces propriétés spéciales et les manières de
les utiliser.
Astuce | |
---|---|
Aujourd'hui les propriétés héritables sont surtout
utiles pour le fonctionnement de
|
Les propriétés constituent une fonctionnalité très puissante de Subversion et sont un élément central de nombreuses fonctionnalités de Subversion présentées ailleurs dans ce chapitre ainsi que dans les autres chapitres : comparaisons et fusions textuelles, substitution de mots-clés, transformation des retours à la ligne, etc. Mais pour profiter pleinement des propriétés, il faut les placer sur les dossiers et fichiers adéquats. Malheureusement, cette étape peut passer à la trappe dans le train-train quotidien, d'autant plus qu'oublier de configurer une propriété n'engendre généralement pas une erreur qui saute aux yeux (du moins comparativement à oublier d'ajouter un fichier dans la gestion de versions). Pour vous aider à placer vos propriétés au bon endroit, Subversion propose deux fonctionnalités simples mais néanmoins utiles.
Au moment d'introduire un fichier en suivi de versions à
l'aide de la commande svn add ou
svn import, Subversion essaie de vous aider
en configurant automatiquement certaines propriétés communes des
fichiers. D'abord, sur les systèmes d'exploitation dont le
système de fichiers utilise un bit « exécutable »,
Subversion ajoute automatiquement la propriété
svn:executable
aux nouveaux fichiers, ajoutés
ou importés, qui ont ce bit activé (voir la section intitulée « Fichiers exécutables ou non » plus loin
dans ce chapitre pour plus de détails sur cette
propriété).
Ensuite, Subversion essaie de déterminer le type MIME du
fichier. Si vous avez configuré le paramètre
mime-types-files
, Subversion essaie de
trouver un type MIME correspondant à l'extension du nom de
fichier. Si un tel type MIME existe, il définit
automatiquement la propriété svn:mime-type
avec la valeur du type trouvé. S'il ne trouve pas de type MIME
correspondant ou s'il n'existe pas de fichier définissant les
correspondances, Subversion applique des heuristiques pour
déterminer le type MIME. En fonction de la façon dont il a été
compilé, Subversion 1.7 peut utiliser des bibliothèques qui
scrutent le contenu du fichier[16] pour déterminer son type. En dernier recours,
Subversion utilise sa propre heuristique très basique pour
déterminer si le fichier contient des éléments non textuels.
Si c'est le cas, Subversion attribue automatiquement la valeur
propriété application/octet-stream
(type MIME
générique indiquant « une suite d'octets ») à la
propriété svn:mime-type
. Bien sûr, si
Subversion se trompe ou si vous voulez indiquer un type plus
précis (par exemple image/png
ou
application/x-shockwave-flash
), vous pouvez
toujours supprimer ou modifier cette propriété (pour d'avantage
d'informations sur la gestion des types MIME par Subversion,
reportez vous à la section intitulée « Type de contenu des fichiers » plus loin dans
ce chapitre).
Note | |
---|---|
L'encodage UTF-16 est communément utilisé pour des fichiers dont le contenu sémantique est textuel par nature, mais cet encodage utilise beaucoup les octets en dehors de l'intervalle typique ASCII. Ainsi, Subversion aura tendance à classer de tels fichiers dans la catégorie binaire, au grand regret des utilisateurs qui souhaitent pouvoir effectuer des comparaisons et des fusions, de la substitution de mots-clés ou d'autres manipulations sur ces fichiers. |
Subversion fournit également, via
sa zone de configuration
(voir la section intitulée « Zone de configuration des exécutables »), une fonction de
renseignement automatique des propriétés, plus flexible, qui
vous permet de créer des associations entre, d'une part, des
motifs de noms de fichiers et, d'autre part, des noms de
propriétés / valeurs de propriétés. Là encore, ces
associations modifient le comportement des commandes
add et import, pouvant non
seulement passer outre la décision prise par défaut
d'attribution d'une propriété de type MIME mais pouvant aussi
définir d'autres propriétés, qu'elles soient utilisées par
Subversion ou personnalisées. Par exemple, vous pouvez créer une
association qui, à chaque ajout d'un fichier JPEG (c'est-à-dire
dont le nom est du type *.jpg
), fixe la
propriété svn:mime-type
de ce fichier à la
valeur image/jpeg
. Ou alors affecte à tout
fichierde type *.cpp
la propriété
svn:eol-style
avec la valeur
native
et la propriété
svn:keywords
avec la valeur
Id
. Reportez-vous à la section intitulée « Configuration générale » pour plus
d'informations sur la configuration de cette fonction.
Bien que la configuration automatique de propriétés par
la zone de configuration soit certainement très facile
d'utilisation, les administrateurs de Subversion préféreront
peut-être définir automatiquement, sur un serveur donné, un
ensemble de propriétés pour tous les clients qui se connectent
pour des extractions. Les clients Subversion 1.8 et plus récents
possèdent cette fonctionnalité
via la propriété héritable
svn:auto-props
.
La propriété svn:auto-props
fonctionne
comme la zone de configuration pour automatiquement définir des
propriétés sur les fichiers lorsqu'ils sont ajoutés ou importés.
La valeur de la propriété svn:auto-props
doit
être la même que celle de auto-props
dans la
zone de configuration (c'est-à-dire un nombre quelconque de
paires clé-valeur au format
MOTIF_FICHIER = NOM_PROPRIETE=VALEUR[;NOM_PROPRIETE=VALEUR ...]).
Comme pour l'option de configuration
auto-props
, la propriété
svn:auto-props
peut être ignorée en
spécifiant l'option --no-auto-props
, mais
contrairement à l'option de la zone de configuration, la
propriété svn:auto-props
n'est
pas désactivée par l'option de la zone de
configuration enable-auto-props
définie à
no
.
Par exemple, considérons que vous avez extrait une copie de
travail du tronc (trunk
) et que avez besoin
d'ajouter un nouveau fichier (nous supposons que les propriétés
automatiques sont désactivées dans votre zone de
configuration) :
$ svn st ? calc/données.c $ svn add calc/données.c A calc/données.c $ svn proplist -v calc/données.c Propriétés sur 'calc/données.c': svn:eol-style native
Vous notez qu'après avoir placé le fichier
données.c
sous suivi de versions, la
propriété svn:eol-style
a automatiquement été
définie sur lui. Puisque nous avons supposé que l'option de la
zone de configuration auto-props
est
désactivée, nous savons que la propriété
svn:auto-props
doit être définie sur un
chemin parent de données.c
. En utilisant la
commande svn propget avec l'option
--show-inherited-props
, nous pouvons vérifier
que c'est effectivement le cas :
$ svn propget svn:auto-props --show-inherited-props -v calc Propriétés héritées sur 'calc' de 'http://svn.exemple.com/depot': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native
Au contraire de la propriété
svn:global-ignores
et de la directive
homologue de la zone de configuration
global-ignores
, qui se combinent, la
propriété svn:auto-props
prévaut sur l'option de la zone de
configuration auto-props
si elle définit une
propriété automatique pour le même motif
que la zone de configuration. Les propriétés automatiques
héritées[17] d'un chemin peuvent aussi
prévaloir sur un motif identique hérité
d'un chemin différent. L'ordre de priorité est défini comme
suit :
Une propriété automatique, pour un motif donné, définie
par svn:auto-props
prévaut sur la même
propriété automatique pour un motif identique définie par
auto-props
dansla zone de
configuration.
Si une propriété automatique, pour un motif donné, est
héritée depuis plus d'un chemin parent par la propriété
svn:auto-props
, le chemin parent le plus
près prévaut sur les chemins parents plus éloignés.
Une propriété automatique, pour un motif donné, définie
par la propriété svn:auto-props
explicitement appliquée à un chemin prévaut sur la même (ou
les mêmes) propriétés automatiques pour un motif identique
héritées de parents.
Prenons un exemple. Supposons que nous avons ce contenu dans le fichier de configuration:
[miscellany] enable-auto-props = yes [auto-props] *.py = svn:eol-style=CR *.c = svn:eol-style=CR *.h = svn:eol-style=CR *.cpp = svn:eol-style=CR
Vous voulez ajouter trois fichiers dans le dossier
calc
de votre copie de travail:
$ svn st ? calc/données-binding.cpp ? calc/données.c ? calc/éditeur.py
Vérifions que svn:auto-props
s'applique
sur calc
:
$ svn propget svn:auto-props -v --show-inherited-props calc Propriétés héritées sur 'calc' de 'http://svn.exemple.com/depot': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native Propriétés héritées sur 'calc' de '.': svn:auto-props *.py = svn:eol-style=native *.c = svn:keywords=Auteur Date Id Rev URL
Quand nous ajoutons ces trois fichiers, qu'attendons nous
pour auto-props
? Nous ajoutons le trio
au suivi de versions et nous vérifions :
$ svn add calc --force A calc/données-binding.cpp A calc/données.c A calc/éditeur.py
Le nom de fichier données-binding.cpp
ne correspond qu'à un seul motif, *.cpp =
svn:eol-style=CR
dans la zone de configuration,
donc la propriété svn:eol-style
est
évidemment définie à CR
:
$ svn proplist -v calc/données-binding.cpp Propriétés sur 'calc/données-binding.cpp': svn:eol-style CR
Le nom de fichier éditeur.py
correspond
à un seul motif dans la zone de configuration et à deux pour la
propriété svn:auto-props
mais, en raison de
l'ordre de priorité défini auparavant, la propriété définie
explicitement sur calc
, *.py =
svn:eol-style=native
, est prioritaire. Donc la
propriété svn:eol-style
est définie à
native:
:
$ svn proplist -v calc/éditeur.py Propriétés sur 'calc/éditeur.py': svn:eol-style native
Le nom de fichier données.c
correspond
à des motifs dans la zone de configuration et dans les
propriétés héritées svn:auto-props
. La
propriété automatique svn:keywords
n'est
définie qu'une seule fois, sur calc
, donc
données.c
possède automatiquement cette
propriété. svn:auto-props
sur
calc
ne définit pas de valeur pour
svn:eol-style
, donc le parent le plus proche
http://svn.exemple.com/depot
, définit la
valeur :
$ svn proplist -v calc/données.c Propriétés sur 'calc/données.c': svn:eol-style native svn:keywords Auteur Date Id Rev URL
Avertissement | |
---|---|
L'application des priorités est uniquement valable pour
des motifs identiques. Si un nom de
fichier à ajouter ou importer correspond à plus d'un motif,
alors il n'y a aucune garantie concernant le motif des
propriétés automatiques qui est appliqué. Par exemple, disons
que vous voulez ajouter le fichier
*.c* = svn:eol-style=native *.cpp = svn:eol-style=native;svn:keywords=Auteur Date Id Rev URL Comme |
Un dernier point sur svn:auto-props
.
Cette propriété (tout comme
svn:global-ignores
, voir la section intitulée « Occultation des éléments non suivis en versions ») ne constitue
qu'une indication aux clients qui
comprennent la signification de cette propriété. Les clients
plus anciens ignorent ces propriétés, l'option
--no-auto-props
les laisse de côté, un
utilisateur peut très bien modifier ou supprimer les propriétés
automatiquement après qu'elles aient été définies ; il
existe pléthore de moyens de passer outre les indications
fournies par le contenu de svn:auto-props
.
Sachant cela, les administrateurs doivent toujours utiliser des
procédures automatiques (hook
scripts en anglais) pour valider la politique
des propriétés qu'ils souhaitent mettre en place ; ils
peuvent ainsi rejeter les propagations qui ne respectent pas
les règles. Reportez-vous à la section intitulée « Mise en place des procédures automatiques »
pour plus de détails sur les procédures automatiques du
dépôt.
Dans cette section, nous allons brièvement aborder toutes les propriétés que Subversion réserve à son propre usage. Nous regardons les deux types de propriétés, celles associées à un fichier ou un dossier particulier suivi en versions et celles associées aux révisions
Les propriétés suivies en versions que Subversion réserve à son propre usage sont les suivantes :
svn:auto-props
Si elle est définie sur un dossier, la valeur est un ensemble de définitions de propriétés qui s'appliquent à tous les fichiers sous le dossier. Voir la section intitulée « Configuration automatique des propriétés ».
svn:executable
Si elle est définie sur un fichier, le client rendra le fichier exécutable sur les copies de travail d'un système de type Unix. Voir la section intitulée « Fichiers exécutables ou non ».
svn:mime-type
Si elle est définie sur un fichier, la valeur indique le type MIME du fichier. Cela permet au client de décider si des fusions à partir des lignes sont pertinentes lors des mises à jour et cela peut aussi affecter le comportement des fichiers lorsqu'on les parcourt avec un navigateur web. Voir la section intitulée « Type de contenu des fichiers ».
svn:ignore
Si elle est définie sur un dossier, la valeur est une liste de motifs de noms de fichiers non suivis en versions que les sous-commandes svn status et autres ignoreront. Voir la section intitulée « Occultation des éléments non suivis en versions ».
svn:global-ignores
Si elle définie sur un dossier, la valeur est une
liste de motifs de noms de fichiers non suivis
en versions que les sous-commandes
svn status et autres ignoreront. Au
contraire de svn:ignore
, les motifs
s'appliquent à toute la
sous-arborescence du dossier et pas seulement aux
noms de fichiers qui sont fils directs du dossier.
Voir la section intitulée « Occultation des éléments non suivis en versions ».
svn:keywords
Si elle est définie sur un fichier, la valeur indique au client comment remplacer des mots-clés particuliers à l'intérieur du fichier. Voir la section intitulée « Substitution de mots-clés ».
svn:eol-style
Si elle est définie sur fichier, la valeur indique au client comment les fins de ligne doivent être comprises dans la copie de travail et dans les exports d'arborescences. Voir la section intitulée « Caractères de fin de ligne » et svn export.
svn:externals
Si elle est définie sur un dossier, la valeur est une liste sur plusieurs lignes de chemins et d'URL que le client doit extraire. Voir la section intitulée « Définition de références externes ».
svn:special
Si elle est définie sur un ficiher, elle indique que ce fichier n'est pas ordinaire, mais est plutôt un lien symbolique ou autre objet spécial.[18]
svn:needs-lock
Si elle est définie sur un fichier, elle indique au client de placer le fichier en lecture seule dans la copie de travail, pour rappeler que ce fichier doit être verrouillé avant toute édition. Voir la section intitulée « Communication par l'intermédiaire des verrous ».
svn:mergeinfo
Utilisée par Subversion pour suivre les métadonnées liées aux fusions. Voir la section intitulée « Mergeinfo et aperçus » pour les détails vous ne devriez jamais éditer cette propriété à moins de réellement savoir ce que vous faites.
Les propriétés suivantes, toujours réservées par Subversion pour son propre usage, ne sont pas suivies en versions et s'appliquent aux révisions. La plupart d'entre elles apparaissent sur chaque révision dans le dépôt, stockant des informations importantes sur l'origine et la nature des modifications faites par cette révision.
svn:author
Si elle est définie, elle contient le nom de l'utilisateur authentifié qui a créé la révision. Si elle n'est pas définie, la révision a été propagée de manière anonyme.
svn:autoversioned
Si elle est définie, la révision a été créée par un mécanisme d'autoversionnage automatique. Voir la section intitulée « Gestion de versions automatique ».
svn:date
Contient l'horodatage UTC correspondant à la création de la révision, au format ISO 8601. La valeur provient de l'horloge du serveur, pas du client.
svn:log
Contient le commentaire de propagation relatif à la révision.
Certains outils connexes de la collection Subversion (svnrdump et svnsync) utilisent également les propriétés non suivies en version pour stocker des informations les concernant. Ces propriétés sont présentes uniquement sur la révision 0 des dépôts sur lesquels ces outils opèrent. Pour plus d'information sur svnrdump et svnsync, reportez-vous à Chapitre 5, Administration d'un dépôt. Les propriétés créées et gérées par ces outils sont les suivantes :
svn:rdump-lock
Utilisée pour mettre en œuvre un accès exclusif temporaire au dépôt par la commande svnrdump load. Cette propriété est généralement présente seulement quand une opération de ce type est en cours (ou quand une commande svnrdump a échoué à se déconnecter proprement du dépôt). Cette propriété n'a de sens que si elle est définie sur la révision 0.
svn:sync-currently-copying
Contient le numéro de révision du dépôt source qui est en train d'être recopié sur le dépôt cible par la commande svnsync. Cette propriété n'a de sens que si elle est définie sur la révision 0.
svn:sync-from-uuid
Contient l'UUID du dépôt dont le dépôt cible est un mirroir, créé par l'outil svnsync. Cette propriété n'a de sens que si elle est définie sur la révision 0.
svn:sync-from-url
Contient l'URL du dépôt dont le dépôt cible est un mirroir, créé par l'outil svnsync. Cette propriété n'a de sens que si elle est définie sur la révision 0.
svn:sync-last-merged-rev
Contient le numéro de révision du dépôt source qui a été dupliqué avec succès le plus récemment sur le dépôt cible. Cette propriété n'a de sens que si elle est définie sur la révision 0.
svn:sync-lock
Utilisée pour mettre en œuvre un accès exclusif temporaire au dépôt par la commande de duplication svnsync. Cette propriété est généralement présente seulement quand une opération de ce type est en cours (ou quand une commande svnsync a échoué à se déconnecter proprement du dépôt). Cette propriété n'a de sens que si elle est définie sur la révision 0.
Heureusement pour les utilisateurs de Subversion qui travaillent sur différents ordinateurs et systèmes d'exploitation, le comportement du client texte interactif est pratiquement identique sur tous les systèmes. Si vous vous débrouillez avec svn sur un système, vous devriez vous en sortir sur n'importe quel système.
Cependant, ce n'est pas toujours le cas pour d'autres types de logiciels ou pour les fichiers que vous gérez dans Subversion. Par exemple, sur un système Windows, la définition d'un « fichier texte » est similaire à la définition de Linux, mais avec une différence notable pour ce qui concerne les retours à la ligne. Il y a aussi d'autres différences. Les plateformes Unix (et Subversion) supportent la notion de lien symbolique ; Windows non. Les plateformes Unix utilisent les permissions du fichier pour déterminer si un fichier est exécutable ; Windows utilise l'extension du fichier.
Subversion n'a pas la possibilité d'unifier toutes ces définitions et ces implémentations. Tout ce qu'il peut faire, c'est aider au maximum l'utilisateur qui travaille sur plusieurs systèmes et plusieurs ordinateurs. Cette section décrit comment Subversion s'y prend.
Subversion fait partie des nombreuses applications qui
reconnaissent et utilisent les types MIME (Multipurpose Internet
Mail Extensions). Ainsi, la valeur de la propriété
svn:mime-type
permet, en plus de stocker le
type de contenu d'un fichier, de changer le comportement de
Subversion lui-même.
Par exemple, un avantage fourni par cette reconnaissance de
type par Subversion est la possibilité de fusion contextuelle,
ligne par ligne, des changements reçus lors d'une mise à jour.
En revanche, pour les fichiers contenant autre chose que du
texte, il n'y a souvent pas de concept de « ligne ».
En conséquence, pour les fichiers suivis en versions dont la
propriété svn:mime-type
contient une valeur
de type MIME non textuel (généralement un intitulé qui ne
commence pas par text/
, bien qu'il y ait des
exceptions), Subversion ne tente pas de fusion contextuelle
pendant la mise à jour. À la place, chaque fois que vous avez
modifié localement un fichier binaire qui a été mis à jour sur
le dépôt, Subversion ne touche pas à votre fichier mais crée
deux nouveaux fichiers. Un fichier avec l'extension
.oldrev
qui contient la version du fichier
à la révision BASE. Un autre fichier avec l'extension
.newrev
qui contient la version à jour du
fichier. Ce comportement est dicté par la volonté d'éviter que
l'utilisateur ne tente d'effectuer une fusion qui échouerait
parce que les fichiers ne peuvent tout simplement pas être
fusionnés.
De plus, puisque le fait d'afficher les différences et les
modifications ligne par ligne est, c'est évident, dépendant de
la signification que l'on accorde à une « ligne » du
fichier considéré, les fichiers dont le type MIME n'est pas
compatible avec du texte déclenchent par défaut des erreurs
lorsqu'ils sont la cible de sous-commandes telles que
svn diff et svn annotate.
Cela peut s'avérer particulièrement frustrant pour les
utilisateurs de fichiers XML dont la propriété
svn:mime-type
est définie avec une valeur
comme application/xml
qui n'est pas
interprétée par Subversion comme lisible par un humain car
relativement ambigüe. Heureusement, ces sous-commandes proposent
l'option --force
pour obliger Subversion à
essayer d'opérer sur ces fichiers malgré leur apparente
illisibilité pour un humain.
Avertissement | |
---|---|
La propriété |
Subversion fournit plusieurs mécanismes pour définir
automatiquement la propriété svn:mime-type
sur un fichier suivi en versions. Consultez la section intitulée « Configuration automatique des propriétés » pour en obtenir les
détails.
Par ailleurs, si la propriété
svn:mime-type
est définie, alors le greffon
Apache pour Subversion utilise cette valeur pour renseigner le
champ Content-type:
de l'en-tête HTTP en
réponse à une requête GET. Cela fournit au navigateur Web une
indication très importante pour pouvoir afficher correctement le
fichier, quand vous l'utilisez pour parcourir le contenu du
dépôt Subversion.
Sur beaucoup de systèmes d'exploitation, la capacité de
rendre un fichier exécutable dépend d'un bit dit
« exécutable ». Habituellement, ce bit est désactivé
par défaut et doit être explicitement activé par l'utilisateur
pour chaque fichier concerné. Ce serait une perte de temps
énorme d'avoir à se rappeler exactement quel fichier, parmi ceux
que l'on vient d'extraire du dépôt, doit avoir le bit exécutable
positionné et ensuite de devoir le faire manuellement. C'est
pourquoi Subversion fournit la propriété
svn:executable
pour spécifier que le bit
exécutable doit être activé pour le fichier concerné. Subversion
s'occupe lui-même de cette tâche quand il rapatrie de tels
fichiers dans la copie de travail locale.
Cette propriété n'a aucun effet sur les systèmes de fichiers
qui ne possèdent pas le concept du bit exécutable, tels que
FAT32 et NTFS
[20].
Par ailleurs, bien qu'elle n'ait pas de valeurs définies,
Subversion lui attribue la valeur *
lorsqu'il active cette propriété. Enfin, cette propriété n'est
valide que sur des fichiers, pas sur des dossiers.
Pour tout fichier suivi en versions, Subversion considère
que le contenu est lisible par un humain sauf si la propriété
svn:mime-type
indique le contraire. En
règle générale, Subversion utilise cette information pour
déterminer s'il est possible d'effectuer une comparaison
contextuelle pour ce fichier. Sinon, pour Subversion, les octets
sont des octets.
Cela veut dire que par défaut, Subversion ne
s'intéresse pas au type de caractère utilisé pour marquer les
fins de lignes
(EOL en anglais, pour
End Of Line). Malheureusement,
des conventions différentes sont utilisées suivant les systèmes
d'exploitation pour indiquer une fin de ligne de texte dans un
fichier. Par exemple, les logiciels sous Windows utilisent
généralement une paire de caractères de contrôle ASCII : un
retour chariot (CR
, carriage
return) suivi par un saut de ligne
(LF
, line feed).
Les logiciels Unix, cependant, utilisent uniquement le caractère
LF
pour indiquer les fins de lignes.
Tous les programmes ne savent pas gérer les fichiers
utilisant un marqueur de fin de ligne « exogène » au
système d'exploitation sur lequel ils tournent. Ainsi, il n'est
pas rare de voir les programmes Unix traiter le marqueur
CR
des fichiers Windows comme un caractère
normal (en affichant à l'écran un ^M
) et les
programmes Windows combiner en une seule ligne immense un fichier
Unix parce qu'ils n'y ont pas trouvé la combinaison retour
chariot-passage à la ligne (CR-LF
).
Cette incapacité de traiter correctement les marqueurs de fin de ligne d'autres plates-formes peut être assez frustrante pour ceux qui partagent des fichiers entre différents systèmes d'exploitation. Prenons l'exemple d'un fichier de code source qui est édité par des développeurs à la fois sous Windows et sous Unix. Si tous les développeurs utilisent des outils qui se plient à la convention utilisée par le fichier, pas de problème.
Mais, en pratique, de nombreux outils largement utilisés soit ne parviennent pas à lire correctement un fichier utilisant une convention différente pour les fins de ligne, soit ils convertissent les fins de lignes au format local lors de la sauvegarde. Dans le premier cas, le développeur doit utiliser des outils externes (tels que dos2unix et son compagnon unix2dos) pour préparer le fichier avant l'édition. Dans le deuxième cas, pas besoin de préparation. Mais dans les deux cas, le fichier résultant diffère de l'original littéralement pour toutes les lignes ! Avant de propager ses changements, l'utilisateur a deux choix. Soit il utilise un utilitaire de conversion pour revenir à la même convention qu'avant l'édition. Soit il propage le fichier avec la nouvelle convention de fin de ligne.
Au final, les deux hypothèses conduisent à une perte de temps et des modifications inutiles sur les fichiers propagés. La perte de temps est déjà pénible. Mais si en plus la propagation change chaque ligne du fichier, trouver quelle ligne a effectivement changé devient non trivial. À quel endroit ce bogue a-t-il réellement été corrigé ? Dans quelle ligne y avait-il cette erreur de syntaxe ?
La solution à ce problème est la propriété
svn:eol-style
(eol pour End Of
Line). Quand cette propriété possède une valeur
valide, Subversion l'utilise pour déterminer quel traitement il
doit appliquer pour que le fichier ne change pas de convention à
chaque propagation provenant d'un système d'exploitation
différent. Les valeurs valides sont :
native
Ceci force le fichier à adopter la convention
utilisée par le système d'exploitation sur lequel
s'exécute Subversion. En d'autres termes, si un
utilisateur d'une machine Windows récupère une copie de
travail d'un fichier dont la propriété
svn:eol-style
vaut
native
, ce fichier contiendra le
marqueur CRLF
pour indiquer les fins de
ligne. Un utilisateur Unix qui récupère une copie de
travail qui contient le même fichier verra simplement
LF
pour indiquer les fins de ligne sur
sa copie.
Notez que Subversion stocke en fait le fichier dans
le dépôt en utilisant le marqueur standard
LF
indépendamment du système
d'exploitation. Cela reste toutefois tout à fait
transparent pour l'utilisateur.
CRLF
Le fichier contiendra le marqueur
CRLF
pour indiquer les fins de ligne,
quel que soit le système d'exploitation..
LF
Le fichier contiendra le marqueur
LF
pour indiquer les fins de ligne,
quel que soit le système d'exploitation.
CR
Le fichier contiendra le marqueur
CR
pour indiquer les fins de ligne,
quel que soit le système d'exploitation. Ce marqueur de
fin de ligne n'est pas très courant.
Dans n'importe quelle copie de travail, il y a de grandes chances que les fichiers et dossiers suivis en versions côtoient d'autres fichiers et dossiers non suivis en versions ou qui n'ont pas lieu de l'être. Les éditeurs de texte remplissent les dossiers avec des fichiers de sauvegarde. Les compilateurs créent des fichiers intermédiaires (ou même des fichiers finaux) que vous ne voudrez pas suivre en versions. Et les utilisateurs eux-mêmes déposent des fichiers et des dossiers où bon leur semble, souvent dans des copies de travail locales.
Il est ridicule de penser que les copies de travail Subversion échappent à ce type de méli-mélo. En fait, Subversion prend en compte (c'est une fonctionnalité) dès le début que les copies de travail sont des dossiers comme les autres, comme ceux qui ne sont pas suivis en versions. Mais ces fichiers et dossiers qui-n-ont-pas-vocation-à-être-suivis-en-versions peuvent perturber les utilisateurs de Subversion. Par exemple, comme les commandes svn add et svn import sont récursives par défaut et ne savent pas quels fichiers de l'arborescence vous voulez suivre ou non en versions, il est relativement facile d'ajouter au suivi de versions des éléments que vous ne vouliez pas suivre. Et comme la commande svn status liste, par défaut, tous les éléments intéressants de la copie de travail, y compris les fichiers et dossiers non suivis en versions, son affichage devient rapidement confus avec de tels imbroglios.
C'est pourquoi Subversion fournit plusieurs méthodes pour pouvoir lui indiquer quels fichiers vous souhaitez ignorer. La première implique l'utilisation de la zone de configuration (voir la section intitulée « Zone de configuration des exécutables ») et, par conséquent, s'applique à toutes les opérations Subversion qui utilisent cette zone de configuration, généralement toutes celles de l'ordinateur ou d'un utilisateur particulier de l'ordinateur. Deux autres méthodes utilisent les propriétés Subversion des dossiers et sont plus liées à l'arborescence suivie en versions elle-même. Par conséquent, elles affectent tous ceux qui possèdent une copie de travail de cette arborescence. Tous ces mécanismes utilisent des motifs de noms de fichiers (des chaines de caractères simples ou des jokers) pour trouver des correspondances avec les noms de fichiers qu'il faut ignorer.
La zone de configuration de Subversion propose une directive,
global-ignores
, dont la valeur est un ensemble
de motifs de noms de fichiers séparés par des espaces. Le client
Subversion compare ces motifs aux noms des fichiers que l'on tente
d'ajouter au suivi de versions, ainsi qu'aux noms des fichiers non
suivis en versions détectés par la commande svn
status. Si un nom de fichier correspond au motif,
Subversion ignore totalement ce fichier. C'est particulièrement
utile pour les fichiers que vous ne voulez jamais suivre en
versions, comme les fichiers de sauvegarde créés par les éditeurs
de texte (par exemple, les fichiers *~
et
.*~
créés par Emacs).
Pour un dossier suivi en versions, la propriété
svn:ignore
est supposée contenir une liste de
motifs de noms de fichiers (un motif par ligne) que Subversion
utilise pour déterminer quels objets ignorer dans le dossier
concerné. Ces motifs ne remplacent pas les motifs inscrits dans
la directive global-ignores
de la zone de
configuration, mais s'ajoutent à cette liste. Veuillez également
noter que, contrairement à la directive
global-ignores
, les motifs de la propriété
svn:ignore
s'appliquent uniquement au dossier pour lequel la propriété est
définie et pas à ses sous-dossiers. La propriété
svn:ignore
est utile pour indiquer à Subversion
d'ignorer les fichiers susceptibles d'être présents dans la copie
de travail de ce dossier chez chaque utilisateur comme les fichiers
produits par les compilateurs ou, pour citer un exemple plus approprié
à ce livre, les fichiers HTML, PDF ou PostScript générés par la
conversion des fichiers sources DocBook XML vers un format de fichier
plus lisible.
Subversion 1.8 fournit une version plus puissante de la
propriété svn:ignore
: la propriété
svn:global-ignores
. Comme la propriété
svn:ignore
,
svn:global-ignores
ne peut être définie que
pour un dossier et elle contient les motifs de noms de fichiers
que Subversions doit ignorer[21]. Ces motifs à
ignorer sont aussi ajoutés aux motifs définis dans la zone de
configuration par la directive global-ignores
et à ceux définis par la propriété svn:ignore
.
Contrairemen à svn:ignore
, la propriété
svn:global-ignores
s'hérite[22] et elle s'applique à tous les
chemins placés sous le dossier sur lequel la propriété est
définie, pas seulement les fils directs de ce dossier.
Note | |
---|---|
Le support des motifs de fichiers à ignorer dans Subversion s'applique uniquement à la procédure d'ajout de fichiers et dossiers non suivis en versions vers la gestion de versions. Une fois que l'objet est suivi en versions par Subversion, les mécanismes permettant d'ignorer certains fichiers selon des motifs prédéfinis ne s'appliquent plus. Autrement dit, ne pensez pas que Subversion ne propagera pas les changements que vous avez faits à un fichier suivi en versions simplement parce que son nom correspond à un motif à ignorer : Subversion prend toujours en compte l'ensemble des objets qu'il gère. |
La liste globale des motifs à ignorer définie dans la
directive global-ignores
de la zone de
configuration reste une affaire de goût[23], car elle doit davantage s'intégrer à la
collection d'outils de l'utilisateur que répondre aux besoins
d'une copie de travail particulière. C'est pourquoi le reste de
cette section s'attache à décrire l'utilisation des propriétés
svn:ignore
et
svn:global-ignores
.
Prenons par exemple le résultat suivant de la commande svn status :
M calc/bouton.c ? calc/calculatrice ? calc/donnees.c ? calc/debug_log ? calc/debug_log.1 ? calc/debug_log.2.gz ? calc/debug_log.3.gz
Dans cet exemple, des modifications ont été faites sur les
propriétés de bouton.c
et il y a aussi des
fichiers non suivis en versions : le programme
calculatrice
(résultat de votre dernière
compilation du code source), un fichier source
donnees.c
et un ensemble de fichiers de
traces pour le débogage. Vous êtes conscient du fait que compiler
votre code engendre à chaque fois la création du programme
calculatrice
[24].
Vous savez également que vous avez toujours des fichiers de
traces qui traînent. On peut faire ce constat pour toutes les
copies de travail locales de ce projet, pas seulement la vôtre. Et
vous savez que cela ne vous intéresse pas et que cela n'intéresse
très probablement aucun autre développeur, de voir ces fichiers
apparaître à chaque commande svn status. Vous
allez donc utiliser svn propedit svn:ignore calc
pour ajouter des motifs à ignorer pour le dossier
calc
.
$ svn propget svn:ignore calc calculatrice debug_log* $
Après avoir ajouté cette propriété, vous avez une propriété
modifiée localement dans votre dossier
calc
. Mais notez les autres différences sur
le résultat de la commande
svn status :
$ svn status M calc M calc/bouton.c ? calc/donnees.c
Maintenant, tout le superflu a disparu ! Bien sûr, votre
programme compilé et les fichiers de trace sont toujours présents
dans votre copie locale. Subversion ne vous présente pas ces
fichiers présents mais non suivis en versions, c'est tout. Et
maintenant que ces parasites sont supprimés de l'affichage, il ne
vous reste plus que les éléments intéressants, tels que le fichier
source donnees.c
que vous avez
probablement oublié d'ajouter au suivi de versions.
Bien évidemment, ce compte-rendu plus succinct de l'état de
votre copie de travail locale n'est pas le seul possible. Si vous
voulez voir les fichiers ignorés dans le compte-rendu, vous pouvez
ajouter l'option --no-ignore
à la commande
Subversion :
$ svn status --no-ignore M calc M calc/bouton.c I calc/calculatrice ? calc/donnees.c I calc/debug_log I calc/debug_log.1 I calc/debug_log.2.gz I calc/debug_log.3.gz
Tous les fichiers non suivis en versions auparavant occultés
apparaissent de nouveau, mais avec un état I
pour Ignoré. Mais attendez, qu'en est-il du fichier
wip.1.diff
? La propriété
svn:ignore
définie sur
calc
ne comporte aucun motif qui corresponde
à ce nom de fichier, alors pourquoi est-il occulté[25] ? La réponse réside dans la troisième méthode
qu'utilise Subversion pour ignorer les chemins non suivis en
versions, la propriété héritée
svn:global-ignores
. Utilisez la sous-commande
svn propget avec l'option
--show-inherited-props
,vous verrez alors que la
propriété svn:global-ignores
est définie à la
racine de votre copie de travail et, pour sûr, qu'elle définit
un motif qui correspond au nom de fichier cherché :
$ svn pg svn:global-ignores calc -v --show-inherited-props Propriétés héritées sur 'calc' de '.': svn:global-ignores *.diff *.patch
Comme mentionné auparavant, la liste des motifs de fichiers à
ignorer est aussi utilisée par svn add et
svn import. Ces deux opérations demandent à
Subversion de gérer un ensemble de fichiers et de dossiers.
Plutôt que de forcer l'utilisateur à choisir dans l'arborescence
quels fichiers il souhaite suivre en versions, Subversion utilise
les motifs de fichiers à ignorer, à la fois la liste globale et
ceux définis par dossier, pour déterminer quels fichiers suivre
(ou ne pas suivre) en versions dans sa procédure récursive d'ajout
ou d'import. Là encore, vous pouvez utiliser l'option
--no-ignore
pour indiquer à Subversion d'ignorer
ces listes et de d'agir effectivement sur tous les fichiers et
dossiers présents.
Astuce | |
---|---|
Même si |
Subversion a la capacité de substituer des mots-clés dans les fichiers suivis en versions par des informations dynamiques et utiles. Les mots-clés fournissent généralement des indications sur les dernières modifications faites au fichier. Comme ces informations changent à chaque fois que le fichier change et, plus spécifiquement, juste après que le fichier change, c'est compliqué pour tout processus, excepté pour le système de gestion de versions, de garder les données à jour. Sans outil automatique, adieu la pertinence de ces informations !
Par exemple, prenons un document dont vous voulez
afficher la date de dernière modification. Vous pouvez charger
chaque contributeur du document de renseigner le champ
correspondant juste avant de propager ses changements. Mais un
jour ou l'autre, quelqu'un oubliera de le faire. Demandez plutôt
à Subversion de substituer le mot-clé
LastChangedDate
. Vous contrôlez où est inséré
le mot-clé dans votre document en plaçant un signet à l'endroit
voulu dans le fichier. Ce signet est juste une chaîne de
caractères formatée comme ceci :
$
NomDuMotClé
$
.
Ajouter un signet dans votre fichier ne fait rien de particulier. Subversion n"essayera jamais de le substituer tant que vous ne lui demandez pas explicitement de le faire. Après tout, vous êtes peut-être en train de rédiger un document[26] sur l'utilisation des mots-clés et vous ne voulez pas que Subversion substitue à vos beaux exemples de signets non substitués leur valeur réelle !.
Pour indiquer à Subversion que vous voulez substituer les
mots-clés d'un fichier particulier, nous nous tournons une fois
de plus vers les sous-commandes relatives aux propriétés. La
propriété svn:keywords
, quand elle est définie
sur un fichier suivi en versions, contrôle quels mots-clés doivent
être substitués dans ce fichier. Elle doit contenir une liste de
mots-clés ou d'alias séparés par des espaces.
Par exemple, admettons que vous ayez un fichier suivi en
versions nommé météo.txt
qui ressemble à
ceci :
Voici les dernières prévisions de nos spécialistes : $LastChangedDate$ $Rev$ Les cumulus sont de plus en plus nombreux au fur et à mesure que l'été approche.
Sans la propriété svn:keywords
définie sur
ce fichier, Subversion ne fait rien de spécial. À présent, si
nous activons les substitutions pour le mot-clé
LastChangedDate
:
$ svn propset svn:keywords "Date Author" météo.txt Propriété 'svn:keywords' définie sur 'météo.txt' $
Vous venez d'effectuer une modification locale des propriétés
du fichier météo.txt
. Vous ne verrez aucun
changement dans le contenu du fichier (à moins d'avoir fait des
modifications avant d'activer la propriété). Notez que le fichier
contenait un signet pour le mot-clé Rev
et que
nous n'avons pas inclus ce mot-clé dans la valeur de la propriété.
Subversion ignore simplement les requêtes de substitutions de
mots-clés qui ne sont pas présents dans le fichier et ne
substitue pas de mot-clé qui ne soit pas présent dans la valeur
de la propriété svn:keywords
.
Immédiatement après avoir propagé cette modification de
propriété, Subversion met à jour votre copie de travail avec le
nouveau texte substitué. Au lieu de voir votre signet
$LastChangedDate$
, vous voyez le résultat de la
substitution. Ce résultat contient aussi le nom du mot-clé et est
toujours entouré par des caractères dollar ($
).
Comme prévu, le mot-clé Rev
n'a pas été
substitué parce que nous n'avons pas demandé qu'il le soit.
Notez également que la substitution s'est bien passée alors
que nous avons indiqué Date Author
comme valeur
de propriété svn:keywords
et que le signet
utilisait l'alias
$LastChangedDate$
:
Voici les dernières prévisions de nos spécialistes : $LastChangedDate: 2006-07-22 21:42:37 -0700 (sam. 22 juil. 2006) $ $Rev$ Les cumulus sont de plus en plus nombreux au fur et à mesure que l'été approche.
Si quelqu'un d'autre propage une modification de
météo.txt
, votre copie de ce fichier
continue à afficher la même valeur substituée de mot-clé,
jusqu'à ce que vous mettiez à jour votre copie de travail. Aux
mots-clés de météo.txt
sont alors à nouveau
substituées les informations qui se rapportent à la plus récente
propagation du fichier.
Tous les mots-clés sont sensibles à la casse des caractères
quand ils apparaissent en tant que signets : vous devez
placer les majuscules aux bons endroits pour que le mot-clé soit
effectivement remplacé. Vous devez aussi considérer que la
valeur de la propriété svn:keywords
est
sensible à la casse (case-sensitive
en anglais) : certains mots-clés sont reconnus
indépendamment de la casse, mais ce comportement est
obsolète.
Subversion définit la liste des mots-clés disponibles pour les substitutions. Cette liste contient les cinq mots-clés suivants (certains d'entre eux ont des alias que vous pouvez aussi utiliser) :
Date
Ce mot-clé indique la date du dernier changement connu
dans le dépôt. Il est de la forme
$Date: 2006-07-22 21:42:37 -0700 (sam.
22 juil. 2006) $
. Il peut également être spécifié
en tant que LastChangedDate
.
Contrairement au mot-clé Id
, qui utilise
l'heure UTC, le mot-clé Date
affiche la
date et l'heure locales.
Revision
Ce mot-clé indique la dernière révision connue pour
laquelle le fichier a changé dans le dépôt. Il fournit une
réponse du type $Revision: 144 $
.
Il peut aussi être spécifié en tant que
LastChangedRevision
ou
Rev
..
Author
Ce mot-clé indique le nom du dernier utilisateur qui a
modifié le fichier dans le dépôt et retourne une valeur du
type $Author: harry $
. Il peut aussi être
spécifié en tant que
LastChangedBy
.
HeadURL
Ce mot-clé décrit l'URL complète de la dernière version
du fichier dans le dépôt et ressemble à $HeadURL:
http://svn.exemple.com/depot/trunk/calc.c $
. Il
peut être abrégé en URL
.
Id
Ce mot-clé est une combinaison abrégée des autres
mots-clés. Sa substitution donne quelque chose comme
$Id: calc.c 148 2006-07-28 21:30:43Z sally $
,
que l'on interprète comme suit : « Le fichier
calc.c
a été modifié en dernier par
l'utilisateur sally
lors de la révision
148 le 28 juillet 2006 au soir. » La date et l'heure
affichées sont en heure UTC, contrairement au mot-clé
Date
qui utilise l'heure locale.
Header
Ce mot-clé est similaire au mot-clé
Id
, mais contient l'URL complète de la
dernière révision de l'élément, à l'identique de
HeadURL
. Sa substitution donne un
résultat du type $Header:
http://svn.exemple.com/depot/trunk/calc.c 148 2006-07-28
21:30:43Z sally $
.
Une bonne partie des définitions qui précèdent utilisent la locution « dernière … connue » ou quelque chose d'équivalent. Rappelez-vous que la substitution des mots-clés est une opération effectuée côté client et que votre client ne connaît pas les changements qui ont eu lieu dans le dépôt depuis votre dernière mise à jour. Si vous ne mettez jamais à jour de votre copie de travail locale, vos mots-clés restent figés à la même valeur même si des changements ont lieu régulièrement dans le dépôt.
En complément de ces mots-clés et alias prédéfinis,
Subversion 1.8 vous permet de définir et d'utiliser les mots-clés
personnalisés. Pour définir un mot-clé personnalisé, ajoutez une
jeton à la propriété svn:keywords
avec la
syntaxe suivante :
.
MyMot-Clé
=FORMAT
MyMot-Clé
est le nom du mot-clé (celui
que vous utiliserez dans le signet) et
FORMAT
est une chaine formatée dans
laquelle l'information sera insérée lorsque le mot-clé sera
substitué dans votre fichier.
La syntaxe de la chaine formatée utilisée pour les mots-clés personnalisés accepte les codes de substitution suivants :
%a
L'auteur de la révision
%r
.
%b
Le nom de fichier de l'URL du fichier.
%d
La date de la révision
%r
au format court.
%D
La date de la révision
%r
au format long.
%P
Le chemin du fichier, relativement à la racine du dépôt.
%r
La dernière révision connue pour laquelle ce fichier a
été modifié dans le dépôt (c'est la même révision que pour
le mot-clé Revision
).
%R
L'URL de la racine du dépôt.
%u
L'URL du fichier.
%_
Un caractère « espace » (la définition d'un mot-clé ne peut pas contenir d'espace).
%%
Le caractère pourcent ('%
').
%H
Équivaut à %P%_%r%_%d%_%a
.
%I
Équivaut à %b%_%r%_%d%_%a
.
Comme vous pouvez le constater, beaucoup de codes de format reprennent les informations disponibles dans les mots-clés prédéfinis. Mais bien ûr, les mots-clés personnalisés vous offrent plus de souplesse dans l'organisation de l'information. Par exemple, vous pouvez avoir envie d'avoir un mot-clé dans vos fichiers qui donne le chemin relatif dans le dépôt du fichier et la dernière révision qui le modifie, formattée à votre convenance pour une meilleure lisibilité. Pour ce faire, vous devez d'abord définir votre mot-clé personnalisé :
$ svn pset svn:keywords "CheminRev=%P,%_r%r" calc/bouton.c Propriété 'svn:keywords' définie sur 'bouton.c' $
Ensuite, vous devez éditer votre fichier pour ajouter le
signet pour votre mot-clé, ce qui nous donne dans ce cas
$CheminRev$
. Après avoir propagé ces
modifications, si vous regardez le contenu du fichier, vous
constaterez que le mot-clé a été substitué conformément au
résultat attendu : où le fichier contenait
$CheminRev$
, il contient maintenant
$cheminRev: trunk/calc/bouton.c, r23 $
.
Note | |
---|---|
Subversion tronque automatiquement toute expansion de mot-clé qui dépasse 255 caractères de long. Les définitions de mots-clés dont le nom dépasse 255 caractères sont aussi ignorées. |
Vous pouvez aussi demander à Subversion de conserver une
longueur constante (en nombre d'octets consommés) pour la
substitution d'un mot-clé. En utilisant la séquence double
deux-points (::
), suivi par le nombre
de caractères désiré, vous définissez la largeur voulue. Quand
Subversion substituera le mot-clé pour le mot-clé et sa valeur, il
ne remplacera que les caractères espaces, laissant le reste du
champ de mot-clé inchangé. Si la valeur de substitution est plus
courte que la largeur définie, il y aura des caractères de
remplissage à la fin du champ substitué ; si elle est trop
longue, elle sera tronquée avec un caractère spécial
« dièse » (#
) juste avant le caractère
dollar qui sert de délimiteur de fin.
Par exemple, supposons que vous ayez un document dans lequel vous avez un paragraphe avec des données tabulées qui représentent les mots-clés Subversion du document. Si vous utilisez la syntaxe originale Subversion pour la substitution des mots-clés, votre fichier ressemblera à :
$Rev$: Révision de la dernière propagation $Author$: Auteur de la dernière propagation $Date$: Date de la dernière propagation
Tel quel, cela semble joli et bien aligné. Mais quand vous allez propager ce fichier (avec la substitution des mots-clés activée, bien évidemment), vous verrez :
$Rev: 12 $: révision de la dernière propagation $Author: harry $: auteur de la dernière propagation $Date: 2006-03-15 02:33:03 -0500 (mer. 15 Mar 2006) $: date de la dernière propagation
Le résultat n'est pas très heureux. Vous êtes alors tenté d'ajuster le fichier après la substitution pour le remettre en forme. Mais cela ne fonctionne que tant que les substitutions de mots-clés gardent la même longueur. Si le numéro de la dernière révision propagée passe de 99 à 100 par exemple, ou si une autre personne avec un nom d'utilisateur plus long propage le fichier, tout le travail est à refaire. Cependant, si vous travaillez avec Subversion 1.2 ou plus récent, vous pouvez utiliser la nouvelle syntaxe des mots-clés à longueur fixe et spécifier la largeur adéquate de certains champs ; le fichier ressemble alors à ceci :
$Rev:: $: révision de la dernière propagation $Author:: $: auteur de la dernière propagation $Date:: $: date de la dernière propagation
Propagez les modifications du fichier. Cette fois, Subversion prend
en compte la nouvelle syntaxe des mots-clés à longueur fixe et conserve
la largeur des champs telle que définie en complétant en tant que de
besoin entre le double deux-points et le dollar de fin. Après
substitution, la largeur des champs n'a pas changé : les valeurs
courtes comme Rev
et Author
sont
complétées avec des espaces et le champ Date
, trop
long, est tronqué par un caractère dièse :
$Rev:: 13 $: révision de la dernière propagation $Author:: harry $: auteur de la dernière propagation $Date:: 2006-03-15 0#$: date de la dernière propagation
L'utilisation de champs de mots-clés à longueur fixe est particulièrement utile lorsque vous faites des substitutions dans des fichiers dont le format est complexe et fait lui-même usage de champs à longueurs fixes ou lorsque la place disponible pour le stockage du champ de donnée est vraiment trop difficile à changer en dehors de l'application native elle-même. Bien sûr, dans le cas de fichiers binaires, vous devez toujours faire très attention à ce que les substitutions de mots-clés (à longueur fixe ou non) ne cassent pas l'intégrité du fichier. Bien que cela semble facile, cela peut être étonnament difficile pour la plupart des formats de fichiers binaires utilisés de nos jours et vous ne devez pas sous-estimer l'ampleur de cette tâche !
Avertissement | |
---|---|
Soyez conscient que, comme la taille d'un mot-clé est mesurée en octets, les valeurs utilisant des données codées sur plusieurs octets peuvent être corrompues. Par exemple, un nom d'utilisateur qui contient des caractères au format UTF-8 codés sur plusieurs octets risque d'être tronqué en plein milieu d'un de ces caractères multi-octets. Cette troncature est valide au niveau du traitement des octets mais résulte en une chaîne UTF-8 incorrecte en raison du caractère final tronqué. Il est ainsi possible que certaines applications, au moment de charger le fichier, remarquent que le texte UTF-8 est invalide, considèrent tout le fichier comme corrompu et refusent de travailler dessus. En conséquence, lorsque vous utilisez les mots-clés à longueur fixe, veillez à choisir une taille adaptée à des valeurs pouvant contenir des caractères éventuellement codés sur plusieurs octets. |
Par défaut, la plupart des opérations Subversion sur des dossiers agissent de manière récursive. Par exemple, svn checkout crée une copie de travail avec tous les fichiers et dossiers de la zone spécifiée du dépôt, en descendant récursivement dans l'arborescence du dépôt pour en copier la structure complète sur votre disque local. Subversion 1.5 introduit une nouvelle fonctionnalité appelée répertoires clairsemés (ou extractions superficielles) qui permet d'obtenir facilement une copie de travail (ou une simple portion d'une copie de travail) moins profonde que via la récursion complète, avec la possibilité de n'extraire que plus tard les dossiers et les fichiers ignorés auparavant.
Par exemple, imaginons un dépôt dont l'arborescence des fichiers et dossiers est constituée des noms des membres d'une famille et de leurs animaux de compagnie (c'est assurément un exemple bizarre, mais soit). Un svn checkout standard nous donne une copie de travail de l'ensemble de l'arborescence :
$ svn checkout file:///var/svn/depot maman A maman/fils A maman/fils/petit-fils A maman/fille A maman/fille/petite-fille1 A maman/fille/petite-fille1/lapinou1.txt A maman/fille/petite-fille1/lapinou2.txt A maman/fille/petite-fille2 A maman/fille/poissonou.txt A maman/minou1.txt A maman/toutou1.txt Révision 1 extraite. $
Maintenant, extrayons la même arborescence, mais cette fois en demandant à Subversion de nous donner uniquement le dossier racine sans les enfants :
$ svn checkout file:///var/svn/depot maman-vide --depth empty Révision 1 extraite. $
Remarquez que nous avons ajouté l'option --depth
à la commande svn checkout originale. Cette
option existe pour de nombreuses sous-commandes Subversion et est
similaire aux options --non-recursive
(-N
) et --recursive
(-R
). En fait, elle combine, améliore, remplace
et, à terme, rend obsolète ces deux options plus anciennes. Déjà,
elle permet à l'utilisateur de spécifier le niveau de profondeur de la
récursion de façon plus précise, en ajoutant des niveaux auparavant non
supportés (ou supportés de manière peu satisfaisante). Voici les
valeurs de niveau de profondeur de récursion que vous pouvez ajouter à
vos requêtes Subversion :
--depth empty
Inclut uniquement la cible immédiate de l'opération, sans aucun fichier ou dossier fils.
--depth files
Inclut la cible immédiate de l'opération et tous les fichiers fils immédiats.
--depth immediates
Inclut la cible immédiate de l'opération et tous ses sous-dossiers et fils immédiats. Les dossiers fils seront eux-mêmes vides.
--depth infinity
Inclut la cible immédiate, les fichiers et dossiers fils, les fils des fils et ainsi de suite de façon à réaliser une récursion complète.
Bien sûr, la simple combinaison de deux options existantes en une seule ne constitue pas une nouvelle fonctionnalité méritant une section complète de ce livre. Heureusement, il y a plus à en dire. Ce concept de profondeur de récursion ne s'applique pas uniquement aux opérations réalisées avec le client Subversion mais il s'étend aussi à la description de la copie de travail elle-même, en tant que niveau associé de manière permanente par la copie de travail à chaque élément. La force de ce concept est cette permanence. La copie de travail se rappelle le niveau de profondeur que vous avez choisi pour chaque élément qui la compose, jusqu'à ce que vous en changiez. Par défaut, les commandes Subversion agissent sur les éléments présents dans la copie de travail, indépendamment de leur niveau de récursion propre.
Astuce | |
---|---|
Vous pouvez vérifier le niveau de profondeur d'une copie de travail en utilisant la commande svn info. Si le niveau de récursion n'est pas infini, svn info affiche une ligne indiquant le niveau de profondeur : $ svn info maman-immediats | grep '^Profondeur :' Profondeur : immédiates $ |
Ces premiers exemples comportaient des extractions avec un niveau infini de profondeur (la valeur par défaut de svn checkout) ou avec un niveau nul. Voyons maintenant des exemples avec d'autres valeurs de niveau de profondeur :
$ svn checkout file:///var/svn/depot maman-fichiers --depth files A maman-fichiers/minou1.txt A maman-fichiers/toutou1.txt Révision 1 extraite. $ svn checkout file:///var/svn/depot maman-immediats --depth immediates A maman-immediats/fils A maman-immediats/fille A maman-immediats/minou1.txt A maman-immediats/toutou1.txt Révision 1 extraite. $
Comme indiqué, chacun de ces deux niveaux se situe quelque part entre la cible toute simple et la récursion complète.
Nous avons utilisé la commande svn checkout
pour nos exemples, mais l'option --depth
est
également accessible depuis beaucoup d'autres commandes Subversion.
Pour ces autres commandes, spécifier un niveau de profondeur de la
récursion est une manière de limiter le rayon d'action d'une opération à
un niveau, à l'instar des vieilles options
--non-recursive
(-N
) et
--recursive
(-R
). Cela veut dire
que lorsque vous travaillez sur une copie de travail d'un certain
niveau et que vous faites une opération sur un niveau plus faible,
l'opération est limitée à ce niveau faible. En fait, on peut
généraliser ce raisonnement : pour une copie de travail d'un
niveau de profondeur de récursion arbitraire (éventuellement hétérogène)
et pour une commande Subversion comportant un niveau de profondeur, la
commande conserve le niveau de récursion associé aux éléments de
la copie de travail tout en limitant le rayon d'action de
l'opération au niveau demandé (ou celui par défaut).
En plus de l'option --depth
, les sous-commandes
svn update et svn switch acceptent
une deuxième option relative au niveau de profondeur de la
récursion : --set-depth
. C'est cette option qui
vous permet de changer le niveau de profondeur de la récursion associé à
un élément d'une copie de travail. Regardez ce qui se passe après avoir
extrait notre niveau zéro puis graduellement augmenté le niveau de
profondeur de la récursion en utilisant la commande svn update
--set-depth
:NOUVELLE-PROFONDEUR
CIBLE
$ svn update --set-depth files maman-vide A maman-vide/minou1.txt A maman-vide/toutou1.txt Actualisé à la révision 1. $ svn update --set-depth immediates maman-vide A maman-vide/fils A maman-vide/fille Actualisé à la révision 1. $ svn update --set-depth infinity maman-vide A maman-vide/fils/petit-fils A maman-vide/fille/petite-fille1 A maman-vide/fille/petite-fille1/lapinou1.txt A maman-vide/fille/petite-fille1/lapinou2.txt A maman-vide/fille/petite-fille2 A maman-vide/fille/poissonou1.txt Actualisé à la révision 1. $
Au fur et à mesure que nous avons augmenté le niveau de profondeur de la récursion, le dépôt a complété progressivement notre arborescence.
Dans notre exemple, nous n'avons agi que sur la racine de notre copie de travail, en changeant la valeur du niveau associé de profondeur de la récursion. Mais nous pouvons aussi changer de façon indépendante le niveau associé de profondeur de la récursion à chaque sous-dossier de la copie de travail. Une utilisation minutieuse de cette option nous permet de récupérer uniquement certaines portions de la copie de travail, en laissant de côté toutes les autres portions (d'où le nom « clairsemé » de la fonctionnalité). Voici un exemple montrant comment construire une portion d'une branche de notre arbre généalogique, activer la récursion totale sur une autre branche et élaguer le reste (qui ne sera donc pas sur notre disque dur).
$ rm -rf maman-vide $ svn checkout file:///var/svn/depot maman-vide --depth empty Révision 1 extraite. $ svn update --set-depth empty maman-vide/fils A maman-vide/fils Actualisé à la révision 1. $ svn update --set-depth empty maman-vide/fille A maman-vide/fille Actualisé à la révision 1. $ svn update --set-depth infinity maman-vide/fille/petite-fille1 A maman-vide/fille/petite-fille1 A maman-vide/fille/petite-fille1/lapinou1.txt A maman-vide/fille/petite-fille1/lapinou2.txt Actualisé à la révision 1. $
Heureusement, même avec différents niveaux de récursion
définis au sein d'une même copie de travail, les actions sur la
copie de travail ne s'en trouvent pas plus compliquées. Vous
pouvez toujours effectuer des modifications et les propager,
revenir en arrière ou afficher les modifications locales de
votre copie de travail sans spécifier d'option particulière (y
compris --depth
et
--set-depth
) aux dites commandes. Même
svn update fonctionne normalement quand on ne
lui fournit pas de niveau de récursion spécifique : elle met
à jour les cibles de la copie de travail qui sont présentes en
tenant compte des niveaux de récursion qui leur sont
associés.
Vous devez vous demander : « Bien. Mais quand
aurais-je besoin d'utiliser ça ? » Un cas classique est
lié à une architecture du dépôt particulière : lorsque de
nombreux projets et modules logiciels liés cohabitent au même
niveau dans un dépôt (trunk/projet1
,
trunk/projet2
,
trunk/projet3
, etc.). Dans de tels scénarios,
il est probable que seuls quelques projets vous intéressent
personnellement, sans doute pas plus d'un projet principal et de
quelques autres modules dont il dépend. Vous pouvez extraire une
copie de travail pour chacune de ces arborescences, mais ces
copies de travail sont séparées et, par conséquent, il peut être
fastidieux d'effectuer des opérations sur plusieurs ou sur
l'ensemble des copies de travail en même temps. L'autre solution
est d'utiliser la fonctionnalité de répertoires clairsemés, en
construisant une seule copie de travail qui ne contient que les
modules qui vous intéressent. Vous partez d'une extraction du
dossier parent commun aux différents projets avec un niveau
zéro de profondeur de récursion (empty-depth), puis vous mettez à jour
avec un niveau infini de récursion les éléments que vous voulez
récupérer, comme nous l'avons fait dans l'exemple précédent. Voyez ça
comme un système d'inclusion optionnelle des éléments qui peuplent la
copie de travail.
L'implémentation des extractions superficielles de Subversion
1.5 était relativement bonne mais elle ne permettait pas de diminuer le
niveau de profondeur de récursion d'un élément de la copie de travail.
Subversion 1.6 pallie ce problème. Par exemple, si vous lancez
svn update --set-depth empty
sur une copie
de travail de niveau de récursion infini, vous ne conserverez que le
dossier sommital[27]. Subversion 1.6 introduit également une autre
valeur de profondeur de récursion pour l'option
--set-depth
: exclude
. En
indiquant --set-depth exclude
à svn
update, la cible de la mise à jour sera entièrement supprimée
de la copie de travail, le dossier cible lui-même étant lui aussi
supprimé. C'est utile lorsqu'il y a davantage d'éléments de la copie de
travail que vous voulez garder par rapport à ce que vous voulez
supprimer.
Considérons un dossier avec des centaines de sous-dossiers,
dont un que vous ne voulez pas voir dans votre copie de travail. En
utilisant une approche « additive » des dossiers
clairsemés, vous pourriez l'extraire avec un niveau de profondeur nul,
puis explicitement augmenter (en utilisant svn update
--set-depth infinity
) le niveau de profondeur pour tous les
autres sous-dossiers.
$ svn checkout http://svn.exemple.com/depot/plein-de-repertoires --depth empty … $ svn update --set-depth infinity plein-de-repertoires/rep-voulu-1 … $ svn update --set-depth infinity plein-de-repertoires/rep-voulu-2 … $ svn update --set-depth infinity plein-de-repertoires/rep-voulu-3 … ### etc., etc.
C'est peut-être un peu fastidieux, d'autant que vous n'avez pas les « souches » de ces dossiers dans votre copie de travail pour les manipuler. Une telle copie de travail aurait de plus une caractéristique que vous ne soupçonnez pas ou ne voulez pas : si quelqu'un d'autre crée un sous-dossier dans le dossier racine, vous ne le recevrez pas lors de vos mises à jour.
À partir de Subversion 1.6, vous pouvez adopter une approche
différente. En premier lieu, faites une extraction du dossier en
entier. Ensuite, lancez svn update --set-depth
exclude
sur le dossier que vous ne voulez pas voir.
$ svn checkout http://svn.exemple.com/depot/plein-de-repertoires … $ svn update --set-depth exclude plein-de-repertoires/j-en-veux-pas D plein-de-repertoires/j-en-veux-pas $
Cette approche laisse votre copie de travail avec le même contenu que la première approche, mais si un sous-dossier est créé au niveau du dossier racine, il apparaîtra lors de la mise à jour de votre copie de travail. L'inconvénient de cette approche est que vous devez extraire tout le sous-dossier que vous ne voulez pas garder afin de pouvoir dire à Subversion que vous n'en voulez pas. Il n'est pas impossible que ce sous-dossier soit trop gros pour votre disque dur (ce qui pourrait expliquer, après tout, que vous n'en voulez pas dans votre copie de travail).
Note | |
---|---|
Alors qu'exclure un élément existant de la copie de travail
ne fait pas partie de la commande svn update, vous
avez sans doute remarqué que la sortie de |
Dans une telle situation, vous pouvez adopter une approche
intermédiaire. D'abord, faites une extraction du dossier racine avec
l'option --depth immediates
. Puis, faites une extraction
du dossier que vous ne souhaitez pas conserver avec
svn update --set-depth exclude
. Enfin, récupérez
tous les éléments qui restent à un niveau de profondeur infini, ce qui
relativement facile puisque tous sont visibles par votre interpréteur de
commandes.
$ svn checkout http://svn.exemple.com/depot/plein-de-repertoires --depth immediates … $ svn update --set-depth exclude plein-de-repertoires/j-en-veux-pas D plein-de-repertoires/j-en-veux-pas $ svn update --set-depth infinity plein-de-repertoires/* … $
Cette fois encore, votre copie de travail contiendra la même chose que dans les deux cas précédents. Mais maintenant, chaque fois qu'un nouveau fichier ou sous-dossier sera propagé au niveau du dossier racine, vous le recevrez (à un niveau de profondeur nul) au moment de votre mise à jour. Vous pouvez décider à ce stade ce que vous voulez faire avec ce nouvel élément : le récupérer avec un niveau de profondeur infini ou l'exclure.
Le modèle copier-modifier-fusionner de gestion de versions de Subversion repose sur ses algorithmes de fusion, notamment sur la manière dont ils gèrent les conflits quand de multiples collaborateurs modifient le même fichier simultanément. Subversion lui-même ne propose qu'un seul algorithme de ce type, un algorithme qui détecte les modifications par trois méthodes et qui est suffisamment intelligent pour gérer les données à la ligne près. Subversion vous permet également d'utiliser en plus des outils externes lors du processus de fusion (comme indiqué dans la section intitulée « Programmes externes de comparaison de trois fichiers » et la section intitulée « Outils de fusion externes »), parfois encore meilleurs que ceux inclus dans Subversion, proposant par exemple une granularité plus fine allant jusqu'au mot, voire au caractère, au lieu de s'arrêter à la ligne. Mais, en règle générale, ces algorithmes ne fonctionnent que sur des fichiers texte. Le paysage est beaucoup plus sombre lorsque l'on recherche des outils de fusion pour des formats de fichiers non-texte. Et quand vous ne trouvez pas d'outil capable de fusionner de tels fichiers, les limites du modèle copier-modifier-fusionner se font vite sentir.
Prenons un exemple de la vie réelle où ce type de problème apparaît. Harry et Sally sont deux graphistes travaillant sur le même projet (du marketing pour le patron d'un garage). Au cœur d'une affiche de ce projet se trouve l'image d'une voiture dont la carrosserie a besoin d'être réparée, stockée dans un fichier image au format PNG. L'agencement de l'affiche est pratiquement terminé, et Harry et Sally sont contents de la photo qu'ils ont choisie pour leur voiture endommagée : une Ford Mustang bleue de 1967, avec un gnon sur l'aile avant gauche.
C'est alors, comme c'est souvent le cas dans le domaine du
graphisme, que des contraintes extérieures imposent de changer la
couleur de la voiture. Sally met donc à jour sa copie de travail à
la révision HEAD
, lance son outil d'édition de
photos et commence à modifier la photo de manière à obtenir une
voiture rouge cerise. Pendant ce temps, Harry, particulièrement
inspiré ce jour-là, décide que l'image serait plus percutante si
la voiture était davantage endommagée. Lui aussi met à jour sa
copie de travail à la révision HEAD
, puis
dessine des fissures sur le pare-brise. Il termine son travail
avant que Sally ne termine le sien, admire son chef-d'œuvre et
propage les changements. Peu après, Sally en termine avec la
nouvelle couleur de la voiture et essaie de propager ses
modifications. Mais, comme prévu, Subversion ne parvient pas à
valider la propagation et informe Sally que sa version de l'image
est dorénavant obsolète.
Voilà où résident les difficultés : si Harry et Sally avaient effectué leurs changements sur un fichier texte, Sally aurait simplement mis à jour sa copie de travail, recevant au passage les modifications de Harry. Dans le pire des cas, ils auraient modifié la même portion du fichier et Sally aurait eu à résoudre les conflits manuellement. Mais, ici, nous avons affaire à des images binaires, pas des fichiers texte. Et s'il est relativement facile de décrire ce que devrait être l'image finale, il y a très peu de chances qu'un logiciel soit suffisamment intelligent pour détecter les parties communes de l'image sur laquelle les artistes ont travaillé, les changements effectués par Harry et les changements effectués par Sally et pour en tirer une image d'une Mustang rouge avec un pare-brise fissuré !
Clairement, les choses se seraient mieux passées si Harry et Sally avaient sérialisé leurs modifications : par exemple, si Harry avait attendu et dessiné ses fissures sur la voiture nouvellement rouge de Sally, ou si Sally avait changé la couleur d'une voiture avec un pare-brise déjà fissuré. Comme indiqué dans la section intitulée « Modèle copier-modifier-fusionner », la plupart de ces problèmes disparaissent complètement quand une communication parfaite existe entre Harry et Sally [28]. Mais comme un système de gestion de versions est en fait un mode de communication, il s'ensuit que si ce type de logiciel facilite la sérialisation de tâches d'édition non parallélisables, c'est plutôt une bonne chose. C'est ici que l'implémentation du concept verrouiller-modifier-libérer dans Subversion prend tout son sens. Il est temps de parler de la fonctionnalité de verrouillage de Subversion, qui est similaire aux mécanismes permettant de « réserver pour modifications » des fichiers dans d'autres systèmes de gestion de versions.
En fin de compte, la fonctionnalité de verrouillage existe afin de minimiser les pertes de temps et les efforts. En autorisant un utilisateur à s'arroger logiciellement le droit exclusif de modifier un fichier dans le dépôt, cet utilisateur peut être suffisamment confiant dans le fait que son travail ne sera pas vain — la propagation de ses changements réussira. Aussi, en signifiant aux autres utilisateurs qu'une sérialisation a lieu pour un objet suivi en versions, ces utilisateurs peuvent raisonnablement s'attendre à ce que cet objet soit modifié par quelqu'un d'autre. Eux aussi peuvent alors éviter de perdre leur temps et leur énergie sur des modifications qui ne peuvent pas être fusionnées en raison d'un problème d'obsolescence du fichier correspondant.
La fonctionnalité de verrouillage de Subversion comporte en fait plusieurs facettes, qui permettent entre autres de verrouiller un fichier suivi en versions[29] (demander le droit exclusif de modification sur le fichier), de le déverrouiller (abandonner le droit exclusif de modification), de voir la liste des fichiers qui sont verrouillés et par qui, d'annoter des fichiers pour lesquels le verrouillage est fortement recommandé avant édition, etc. Dans cette section, nous abordons toutes les facettes de cette fonctionnalité de verrouillage.
Dans un dépôt Subversion, un verrou est une méta-donnée qui alloue à un utilisateur un accès exclusif en écriture sur un fichier. Cet utilisateur est appelé détenteur du verrou. Chaque verrou possède également un identifiant unique, en général une longue chaîne de caractères, appelé jeton de verrouillage. Le dépôt gère les verrous en assurant in fine leur création, leur application et leur suppression. Si une propagation tente de modifier ou effacer un fichier verrouillé (ou effacer un dossier parent dudit fichier), le dépôt demande deux informations : que le client effectuant la propagation s'authentifie en tant que détenteur du verrou et que le jeton de verrouillage soit fourni lors de la procédure de propagation afin de montrer que le client sait bien quel verrou il utilise.
Pour illustrer la création d'un verrou, reprenons notre exemple de graphistes travaillant sur les mêmes fichiers images binaires. Harry a décidé de changer cette image JPEG. Pour interdire aux autres collaborateurs d'effectuer des changements sur le fichier pendant qu'il le modifie (et pour les avertir qu'il va modifier ce fichier), il verrouille le fichier dans le dépôt en utilisant la commande svn lock :
$ svn lock banane.jpg -m "Édition du fichier pour la livraison de demain." 'banane.jpg' verrouillé par l'utilisateur 'harry'. $
Il y a plusieurs points intéressants dans l'exemple
ci-dessus : d'abord, notez que Harry utilise l'option
--message
(-m
) de
svn lock. Comme svn
commit, la commande svn lock
accepte des commentaires (soit via
--message
(-m
), soit
via --file
(-F
)) pour indiquer la raison du verrouillage du
fichier. En revanche, contrairement à svn
commit, svn lock n'exige pas
automatiquement un message en lançant votre éditeur de texte
préféré. Les commentaires de verrouillage sont optionnels, mais
néanmoins recommandés pour faciliter la communication entre
collaborateurs.
Ensuite, la tentative de verrouillage a réussi. Cela signifie que le fichier n'était pas préalablement verrouillé et que Harry disposait de la dernière version du fichier. Si la copie de travail de Harry avait été obsolète, le dépôt aurait refusé la demande, forçant Harry à effectuer une mise à jour (svn update) et à relancer ensuite la commande de verrouillage. La commande de verrouillage aurait également échoué si le fichier avait déjà été verrouillé par quelqu'un d'autre.
Comme vous pouvez le constater, la commande svn lock affiche la confirmation que le verrouillage a réussi. Dès lors, le verrouillage du fichier apparaît dans le résultat des commandes svn status et svn info :
$ svn status K banane.jpg $ svn info banane.jpg Chemin : banane.jpg Nom : banane.jpg URL : http://svn.exemple.com/depot/projet/banane.jpg Racine du dépôt : http://svn.exemple.com/depot UUID du dépôt : edb2f264-5ef2-0310-a47a-87b0ce17a8ec Revision: 2198 Type de nœud : file Tâche programmée : normale Auteur de la dernière modification : frank Révision de la dernière modification : 1950 Date de la dernière modification : 2006-03-15 12:43:04 -0600 (mer. 15 mars 2006) Texte mis à jour : 2006-06-08 19:23:07 -0500 (jeu. 08 juin 2006) Propriétés mis à jour : 2006-06-08 19:23:07 -0500 (jeu. 08 juin 2006) Somme de contrôle: 3b110d3b10638f5d1f4fe0f436a5a2a5 Nom de verrou : opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e Propriétaire du verrou : harry Verrou créé : 2006-06-14 17:20:31 -0500 (mer. 14 juin 2006) Commentaire du verrou (1 ligne): Édition du fichier pour la livraison de demain. $
Le fait que la commande svn info, qui ne
contacte pas le dépôt quand elle porte sur un chemin d'une copie
de travail, affiche bien le jeton de verrouillage, révèle une
caractéristique importante des jetons de verrouillage : ils
sont intégrés dans la copie de travail. La présence du jeton de
verrouillage est primordiale. Il authorise la copie de travail
à utiliser le verrou ultérieurement. Par ailleurs, la
commande svn status affiche un
K
(raccourci pour locKed
— « verrouillé » en anglais) avant le nom du
fichier, indiquant que le jeton de verrouillage est présent.
Maintenant que Harry a verrouillé banane.jpg
,
Sally ne peut ni modifier ni effacer ce fichier :
$ svn delete banane.jpg D banane.jpg $ svn commit -m "Suppression des fichiers inutiles." Suppression banane.jpg svn: E175002: Échec de la propagation (commit), (détails): svn: E175002: Suppression de '/depot/projet/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banane.jpg': 423 Verrouillé (http://svn.exemple.com) $
Mais Harry, après avoir fait ses retouches sur sa belle banane jaune, peut propager ses changements sur le fichier. C'est parce qu'il s'authentifie en tant que détenteur du verrou et aussi parce que sa copie de travail possède le bon jeton de verrouillage :
$ svn status M K banane.jpg $ svn commit -m "Rendu la banane plus jaune." Envoi banane.jpg Transmission des données . Révision 2201 propagée. $ svn status $
Notez qu'après que la propagation est terminée, svn
status permet de voir que le jeton de verrouillage
n'est plus présent dans la copie de travail. C'est le
comportement normal de svn commit : elle
recherche dans la copie de travail (ou dans une liste de cibles,
si vous fournissez une telle liste) les modifications effectuées
localement et elle envoie les jetons de verrouillage qu'elle
trouve durant sa recherche au serveur, en tant que partie
intégrante du processus de propagation. Après que la propagation
a réussi, tous les verrous du dépôt qui ont été mentionnés sont
libérés, même ceux pour lesquels les fichiers n'ont
pas été propagés. Ce comportement a pour but de
dissuader les utilisateurs d'être négligents avec leurs verrous
ou de garder des verrous trop longtemps. Si Harry verrouille au
hasard trente fichiers dans un répertoire nommé
Images
parce qu'il n'est pas sûr de savoir
quels fichiers il doit modifier et qu'il ne modifie finalement
que quatre fichiers, alors quand il lance la commande
svn commit Images
, la procédure libère
les trente verrous.
Ce mode de fonctionnement (libérer automatiquement les
verrous) peut être modifié avec l'option
--no-unlock
de svn commit.
C'est utile quand vous voulez propager des changements mais que
vous prévoyez d'effectuer des changements supplémentaires et
que donc vous avez toujours besoin des verrous. Vous pouvez
également en faire le fonctionnement par défaut en réglant
l'option no-unlock
dans la zone de
configuration (voir
la section intitulée « Zone de configuration des exécutables »).
Bien sûr, verrouiller un fichier n'oblige pas l'utilisateur à propager une modification sur ce modifier. Le verrou peut être libéré n'importe quand avec la commande svn unlock :
$ svn unlock banane.c 'banane.c' déverrouillé.
Quand une propagation échoue parce que quelqu'un d'autre a
posé un verrou, il est facile de savoir pourquoi. La commande la
plus simple est svn status -u
:
$ svn status -u M 23 truc.c M O 32 raisin.jpg * 72 machin.h État par rapport à la révision 105 $
Dans cet exemple, Sally peut voir que non seulement sa
copie de travail de machin.h
n'est plus à jour,
mais aussi qu'un des deux fichiers qu'elle prévoie de propager
est verrouillé dans le dépôt. La lettre O
(Others — autres en
anglais) indique qu'un verrou est posé sur ce fichier et qu'il a été
créé par quelqu'un d'autre. Si elle essayait de lancer svn
commit, le verrou sur raisin.jpg
l'en
empêcherait. Sally est laissée dans l'expectative de savoir qui a posé
le verrou, quand et pourquoi. Là encore, svn info
trouve la réponse :
$ svn info ^/raisin.jpg Chemin : raisin.jpg Nom : raisin.jpg URL: http://svn.exemple.com/depot/projet/raisin.jpg UUID du dépôt : edb2f264-5ef2-0310-a47a-87b0ce17a8ec Révision: 105 Type de nœud : file Auteur de la dernière modification : sally Révision de la dernière modification : 32 Texte mis à jour : 2006-01-25 12:43:04 -0600 (Sun, 25 Jan 2006) Nom de verrou : opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b Propriétaire du verrou : harry Verrou créé : 2006-02-16 13:29:18 -0500 (jeu. 16 févr. 2006) Commentaire du verrou (1 ligne): Besoin de faire une retouche rapide sur cette image. $
De la même manière que svn info peut être utilisée pour examiner les objets de la copie de travail, elle peut être utilisée pour examiner les objets du dépôt. Si l'argument principal de svn info est un chemin de la copie de travail, alors toutes les informations stockées localement sont affichées ; toute mention d'un verrou signifie que la copie de travail détient un jeton de verrouillage (si le fichier est verrouillé par un autre utilisateur ou depuis une autre copie de travail, alors lancer svn info sur la copie de travail ne renvoie aucune information relative au verrou). Si l'argument principal de svn info est une URL, alors les informations affichées se rapportent à la dernière version de l'objet dans le dépôt et toute mention d'un verrou concerne le verrou en cours sur l'objet.
Ainsi, dans notre exemple, Sally peut voir que Harry a verrouillé le fichier le 16 février pour effectuer une « retouche rapide ». Comme nous sommes en juin, elle suspecte qu'il a probablement oublié le verrou. Elle pourrait téléphoner à Harry pour le lui signaler et lui demander de libérer le verrou. S'il n'est pas joignable, elle peut toujours essayer de forcer le verrou elle-même, ou demander à un administrateur de le faire.
Un verrou n'est pas quelque chose de sacré : dans la configuration par défaut de Subversion, les verrous peuvent être libérés non seulement par leur détenteur, mais aussi par n'importe qui d'autre. Quand quelqu'un d'autre que le détenteur d'un verrou le libère, nous appelons ça casser le verrou.
Avec un statut d'administrateur, il est facile de casser un verrou. Les programmes svnlook et svnadmin peuvent afficher et casser les verrous directement dans le dépôt (pour plus d'informations sur ces outils, reportez-vous à la section intitulée « Boîte à outils de l'administrateur »).
$ svnadmin lslocks /var/svn/depot Chemin : /projet2/images/banane.jpg Chaîne UUID : opaquelocktoken:c32b4d88-e8fb-2310-abb3-153ff1236923 Propriétaire : frank Créé : 2006-06-15 13:29:18 -0500 (jeu. 15 juin 2006) Expire : Commentaire (1 ligne): J'améliore encore la couleur jaune. Chemin : /projet/raisin.jpg Chaîne UUID : opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b Propriétaire : harry Créé : 2006-02-16 13:29:18 -0500 (jeu. 16 fév. 2006) Expire : Commentaire (1 ligne): Besoin de faire une retouche rapide sur cette image. $ svnadmin rmlocks /var/svn/depot /projet/raisin.jpg '/projet/raisin.jpg' déverrouillé $
L'option la plus intéressante est celle qui permet aux
utilisateurs de casser les verrous détenus par d'autres
personnes à travers le réseau. Pour ce faire, Sally doit
simplement ajouter l'option --force
à la
commande svn unlock :
$ svn status -u M 23 machin.c M O 32 raisin.jpg * 72 truc.h État par rapport à la révision 105 $ svn unlock raisin.jpg svn: E195013: 'raisin.jpg' n'est pas verrouillé dans cette copie de travail. $ svn info raisin.jpg | grep ^URL URL: http://svn.exemple.com/depot/projet/raisin.jpg $ svn unlock http://svn.exemple.com/depot/projet/raisin.jpg svn: warning: W160039: Unlock failed on 'raisin.jpg' (403 Forbidden) $ svn unlock --force http://svn.exemple.com/depot/projet/raisin.jpg 'raisin.jpg' déverrouillé. $
Ainsi, la tentative initiale de Sally pour libérer le verrou
a échoué parce qu'elle a lancé svn unlock
directement sur le fichier de sa copie de travail, où aucun
jeton de verrouillage n'était présent. Pour casser le verrou
directement dans le dépôt, elle doit passer une URL à
svn unlock. Son premier essai pour casser le
verrou avec l'URL échoue car elle ne peut pas s'authentifier
comme détentrice du verrou (et elle n'a pas non plus le jeton de
verrouillage). Mais quand elle passe l'option
--force
, les pré-requis d'authentification et
d'autorisation sont ignorés et le verrou est cassé.
Casser le verrou peut ne pas être suffisant. Dans
l'exemple, Sally ne veut pas seulement casser le verrou oublié
par Harry, mais également re-verrouiller le fichier pour son
propre usage. Elle peut le faire en lançant svn
unlock avec l'option --force
puis
svn lock à la suite, mais il existe une petite
chance que quelqu'un d'autre verrouille le fichier entre les deux
commandes. La meilleure solution est donc de voler le
verrou, ce qui implique de casser et re-verrouiller
le fichier en une seule opération atomique. Pour ce faire, Sally
passe l'option --force
à la commande svn
lock :
$ svn lock raisin.jpg svn: avertissement : W160035: Path '/project/raisin.jpg' is already locked by user 'harry' in filesystem '/var/svn/repos/db' $ svn lock --force raisin.jpg 'raisin.jpg' verrouillé par l'utilisateur 'sally'. $
Dans tous les cas, que le verrou soit cassé ou volé, Harry est bon pour une bonne surprise. La copie de travail de Harry contient toujours le jeton de verrouillage original, mais le verrou n'existe plus. Le jeton de verrouillage est dit défunt. Le verrou associé au jeton de verrouillage a été soit cassé (il n'existe plus dans le dépôt) soit volé (remplacé par un autre verrou). Quoi qu'il en soit, Harry peut voir ce qu'il en est en demandant à svn status de contacter le dépôt :
$ svn status K raisin.jpg $ svn status -u B 32 raisin.jpg À la révision 105. $ svn update Updating '.': B raisin.jpg À la révision 105. $ svn status $
Si le verrou dans le dépôt a été cassé, alors
svn status --show-updates
affiche un
B
(pour Broken —
« cassé » en anglais) à côté du fichier. Si un nouveau
verrou existe en lieu et place de l'ancien, alors un
T
(pour sTolen —
« volé » en anglais) est affiché. Finalement,
svn update détecte les jetons de verrouillage
défunts et les supprime de la copie de travail.
Nous avons vu comment svn lock et svn unlock peuvent être utilisés pour poser, libérer, casser ou voler des verrous. Cela résout le problème de la sérialisation des accès à un fichier. Mais qu'en est-il du problème plus vaste d'éviter les pertes de temps ?
Par exemple, supposons que Harry verrouille un fichier image
et commence à l'éditer. Pendant ce temps, loin de là, Sally veut
faire la même chose. Elle ne pense pas à faire un svn
status -u
et n'a donc pas la moindre idée que Harry a déjà
verrouillé le fichier. Elle passe des heures à modifier le fichier et
quand elle tente de propager ses changements, elle découvre soit que le
fichier est verrouillé, soit que son propre fichier n'était pas à jour.
Quoi qu'il en soit, ses modifications ne peuvent pas être fusionnées
avec celles de Harry. L'un des deux doit passer ses modifications par
pertes et profits, un temps conséquent a été gaspillé.
La solution proposée par Subversion à ce problème est de
fournir un mécanisme pour rappeler aux utilisateurs qu'un fichier
devrait être verrouillé avant de faire des
modifications. Ce mécanisme est mis en œuvre par une propriété
spéciale : svn:needs-lock
. Si cette
propriété est associée à un fichier (quelle que soit sa valeur,
qui n'est pas prise en compte), alors Subversion essaie
d'utiliser les permissions du système de fichiers pour le placer
en lecture seule — à moins, bien sûr, que l'utilisateur
ait explicitement verrouillé le fichier. Quand un jeton de
verrouillage est présent (indiquant que
svn lock a été lancée), le fichier est placé
en lecture-écriture. Quand le verrou est libéré, le fichier
passe de nouveau en lecture seule.
La théorie est donc que si le fichier image a cette propriété définie, alors Sally remarquera tout de suite quelque chose d'étrange à l'ouverture du fichier : beaucoup d'applications avertissent l'utilisateur immédiatement quand un fichier en lecture seule est ouvert pour édition et pratiquement toutes l'empêchent de sauvegarder ses modifications dans le fichier. Cela lui rappelle de verrouiller le fichier avant de l'éditer, découvrant ainsi le verrou pré-existant :
$ /usr/local/bin/gimp raisin.jpg gimp: erreur: le fichier est en lecture seule ! $ ls -l raisin.jpg -r--r--r-- 1 sally sally 215589 juin 8 19:23 raisin.jpg $ svn lock raisin.jpg svn: avertissement : W160035: Échec de la demande de verrou : '/projet/raisin.jpg' is already locked by user 'harry' in filesystem '/var/svn/depot/db' $ svn info http://svn.exemple.com/depot/projet/raisin.jpg | grep errou Nom de verrou : opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b Propriétaire du verrou : harry Verrou créé : 2006-06-08 07:29:18 -0500 (jeu. 08 juin 2006) Commentaire de verrouillage (1 ligne): J'effectue quelques retouches. Je le verrouille pour deux heures. $
Astuce | |
---|---|
Les utilisateurs et les administrateurs sont tous
encouragés à positionner la propriété
|
Notez que cette propriété est un outil de communication qui fonctionne indépendamment de la politique de verrouillage. Autrement dit, n'importe quel fichier peut être verrouillé, que cette propriété existe ou pas. Et réciproquement, l'existence de cette propriété ne rend pas obligatoire le verrouillage pour pouvoir propager des modifications.
Malheureusement, le système n'est pas parfait. Il est possible que, même si le fichier possède la propriété, l'avertissement de lecture seule ne marche pas. Quelquefois, les applications ne suivent pas les normes et « piratent » le fichier en lecture seule, autorisant sans rien dire l'utilisateur à modifier et sauvegarder le fichier. Subversion ne peut pas faire grand chose dans ce genre de cas : au final, rien ne remplace une bonne communication entre les membres d'une équipe [30].
Parfois il peut être utile de construire une copie de travail issue de différentes extractions. Par exemple, vous pouvez avoir envie d'avoir différents sous-répertoires provenant de différents endroits du dépôt ou même carrément de différents dépôts. Vous pouvez arriver à un tel enchevêtrement manuellement, en utilisant svn checkout, pour créer le genre de structure voulu pour votre copie de travail. Mais si cette configuration est importante pour tous les utilisateurs de votre dépôt, chacun doit effectuer les mêmes opérations d'extraction que vous.
Heureusement, Subversion supporte la définition
de références externes. Une définition de référence externe
est une association entre un répertoire local et une URL (et idéalement
un numéro de révision particulier) pour un répertoire suivi en versions.
Dans Subversion, vous déclarez les définitions de références externes
dans des groupes en utilisant la propriété
svn:externals
. Vous pouvez créer et modifier cette
propriété en utilisant svn propset ou svn
propedit (voir la section intitulée « Manipuler les propriétés »).
Elle peut être définie sur tous les répertoires suivis en versions et
sa valeur décrit à la fois l'URL du dépôt externe et le répertoire côté
client dans lequel est extrait cette URL.
L'un des attraits de la propriété svn:externals
est qu'une fois qu'elle est définie pour un répertoire suivi en versions,
chaque utilisateur qui extrait une copie de travail de ce répertoire
bénéficie des définitions de références externes. En d'autres termes, une
fois qu'un utilisateur a fait l'effort de définir la structure de la
copie de travail imbriquée, tout le monde en bénéficie
automatiquement : Subversion, lors de l'extraction de la copie de
travail originale, extraie également les copies de travail
externes.
Avertissement | |
---|---|
Les sous-dossiers cibles des définitions de références externes ne doivent pas déjà exister sur votre système ou sur le systèmes des autres utilisateurs : Subversion les crée lors de l'extraction des copies de travail externes. |
Vous bénéficiez avec les définitions de références externes de tous
les avantages liés aux propriétés Subversion. Les définitions sont
suivies en versions. Si vous avez besoin de changer une définition de
référence externe, vous pouvez le faire à l'aide des sous-commandes
classiques sur les propriétés. Quand vous propagez des modifications
relatives à la propriété svn:externals
, Subversion
synchronise les éléments extraits par rapport à la définition de
références externes modifiée dès que vous lancez svn
update
. Tous ceux qui mettent à jour leur copie de travail
reçoivent vos modifications concernant les définitions de références
externes.
Astuce | |
---|---|
Comme la valeur de la propriété |
Les versions de Subversion antérieures à 1.5 utilisent un format de définitions externes qui est un tableau sur plusieurs lignes composées de sous-dossiers (relativement au dossier suivi en versions sur lequel est définie la propriété), d'indicateurs de révision optionnels et l'URL, absolue et complètement qualifiée, du dépôt Subversion. Par exemple :
$ svn propget svn:externals calc # Ressources suivies en versions ailleurs tierce-partie/sons http://svn.exemple.com/depot/sons tierce-partie/themes -r148 http://svn.exemple.com/projet-themes tierce-partie/themes/outils -r21 http://svn.exemple.com/outils-themes $
Dans l'exemple précédent, trois définitions externes sont définies.
La première est « libre », elle fait référence
à la révision HEAD de sa cible. Les deux autres ont des révisions
spécifiques déclarées. L'exemple montre aussi que les lignes qui
commencent par un croisillon (#
) sont considérées
comme des commentaires et ignorées dans l'analyse des définitions
externes.
Quand quelqu'un extrait une copie de travail du dossier
calc
décrit dans l'exemple ci-dessus, Subversion
extrait également les éléments trouvés dans les définitions de références
externes.
$ svn checkout http://svn.exemple.com/depot/calc A calc A calc/Makefile A calc/entier.c A calc/bouton.c Révision 148 extraite. Récupération de la référence externe dans 'calc/tierce-partie/sons' A calc/tierce-partie/sons/ding.ogg A calc/tierce-partie/sons/dong.ogg A calc/tierce-partie/sons/clang.ogg … A calc/tierce-partie/sons/bang.ogg A calc/tierce-partie/sons/twang.ogg Révision 14 extraite. Récupération de la référence externe dans 'calc/tierce-partie/themes' …
À partir de la version 1.5 de Subversion, un nouveau format de la
propriété svn:externals
est supporté. Les références
externes sont toujours multi-lignes mais l'ordre et le format des
différentes informations ont changé. La nouvelle syntaxe ressemble plus à
l'ordre des arguments que vous passez à la commande svn
checkout : l'indicateur optionnel de révision est placé en
premier, puis l'URL du dépôt Subversion externe et, enfin, le
sous-dossier local relatif. Notez cependant que cette fois-ci nous
n'avons pas indiqué « URL absolue et complètement qualifiée »
pour le dépôt externe. En effet, le nouveau format accepte les URL
relatives et les URL avec des révisions pivots. L'exemple précédent sur
les références externes donne avec Subversion 1.5 :
$ svn propget svn:externals calc # Ressources suivies en versions ailleurs http://svn.exemple.com/depot/sons tierce-partie/sons -r148 http://svn.exemple.com/projet-themes tierce-partie/themes -r21 http://svn.exemple.com/outils-themes tierce-partie/themes/outils $
En utilisant la syntaxe avec les révisions pivots (décrite en détail dans la section intitulée « Révisions pivots et révisions opérationnelles »), il peut aussi être écrit comme ceci :
$ svn propget svn:externals calc # Ressources suivies en versions ailleurs http://svn.exemple.com/depot/sons tierce-partie/sons http://svn.exemple.com/projet-themes@148 tierce-partie/themes http://svn.exemple.com/outils-themes@21 tierce-partie/themes/outils $
Astuce | |
---|---|
Il est particulièrement conseillé d'utiliser des numéros de révision explicites dans toutes vos références externes. Ainsi, vous conservez la possibilité de décider quand rapatrier une nouvelle version de vos informations externes et quelle version exacte rapatrier. En plus de vous éviter la surprise de recevoir des changements effectués sur des dépôts tiers dont vous n'avez pas la maîtrise, l'utilisation de numéros de révisions explicites signifie aussi que, si vous revenez à une version de travail antérieure, vos références externes reviendront elles aussi dans l'état où elles étaient au moment de cette version antérieure. Cela signifie aussi que les copies de travail externes sont actualisées pour refléter leur état au moment de la révision antérieure. Pour des projets logiciels, cela peut faire la différence entre la réussite et l'échec de la compilation d'une version antérieure d'un code source complexe. |
Pour la plupart des dépôts, les trois formats de références
externes ont le même effet au final. Ils apportent tous les mêmes
avantages. Malheureusement, ils possèdent aussi les mêmes
inconvénients. Puisque les références indiquées utilisent des URL
absolues, déplacer ou copier un répertoire auquel elles sont
rattachées n'affecte pas ce qui est extrait en externe (alors
qu'une référence relative est, bien évidemment, déplacée avec le
répertoire). Cela peut vous induire en erreur, voire être
assez frustrant, dans certaines situations. Par exemple, imaginons un
dossier racine appelé mon-projet
pour
lequel nous avons défini des références externes dans un
sous-dossier (mon-projet/un-rep
)
vers la dernière révision d'un autre sous-dossier
(mon-projet/rep-externe
).
$ svn checkout http://svn.exemple.com/projets . A mon-projet A mon-projet/un-rep A mon-projet/rep-externe … Récupération de la référence externe dans 'mon-projet/un-rep/sous-rep' Référence externe actualisée à la révision 11. Actualisé à la révision 11. $ svn propget svn:externals mon-projet/un-rep sous-rep http://svn.exemple.com/projets/mon-projet/rep-externe $
Maintenant utilisez la commande
svn move pour renommer le répertoire
mon-projet
. À ce moment là, vos
définitions de références externes pointent toujours vers un
chemin sous le répertoire mon-projet
, même si
ce répertoire n'existe plus.
$ svn move -q mon-projet nouveau-projet $ svn commit -m "Renommé mon-projet en nouveau-projet." Suppression mon-projet Ajout nouveau-projet Révision 12 propagée. $ svn update Mise à jour de '.' : svn: warning: W200000: Erreur dans la récupération de la référence externe dans 'nouveau-projet/un-rep/sous-rep' svn: warning: W170000: Le dépôt http://svn.exemple.com/projets/mon-projet/rep-externe n'existe pas À la révision 12. $
De plus, les URL absolues utilisées par les références
externes peuvent causer des problèmes pour les dépôts accessibles
via plusieurs types d'URL. Par exemple, si votre serveur
Subversion est configuré pour autoriser tout le monde à consulter
le dépôt via http://
ou
https://
, mais que les opérations de propagation
doivent être effectuées uniquement via
https://
, vous vous retrouvez bien embêté. Si vos
références externes pointent vers une URL de type
http://
, vous ne pouvez pas effectuer de propagation
depuis les copies de travail créées via
ces références externes. D'un autre côté, si vous utilisez la forme
https://
pour les URL, ceux qui voudront
effectuer des consultations via
http://
, parce que leur client ne sait pas traiter le
https://
, sont incapables de récupérer les éléments
externes. Soyez conscient également que si vous avez besoin de déplacer
toute votre copie de travail (avec svn switch et
l'option --relocate
), les références externes ne
seront pas mises à jour en conséquence.
Subversion 1.5 franchit un grand pas dans la résolution de ces soucis. Comme indiqué précédemment, les URL utilisées dans le nouveau format des définitions des références externes peuvent être relatives. Par ailleurs, Subversion autorise une syntaxe magique pour spécifier plusieurs types d'URL relatives.
../
Relative à l'URL du répertoire sur lequel la
propriété svn:externals
est
définie.
^/
Relative à la racine du dépôt pour lequel la
propriété svn:externals
est suivie en
versions.
//
Relative au type d'URL du répertoire sur lequel
la propriété svn:externals
est
définie.
/
Relative à l'URL du serveur sur lequel la
propriété svn:externals
est suivie en
versions.
^/../NOM-DÉPÔT
Relative à un dépôt frère sous le même emplacement
SVNParentPath
-que le dépôt dans laquelle la
référence svn:externals
est
définie.
Donc, considérons pour la quatrième fois la définition de nos références externes de l'exemple précédent et utilisons la nouvelle syntaxe de différentes manière. Nous obtenons :
$ svn propget svn:externals calc # Ressources suivies en versions ailleurs ^/sons tierce-partie/sons /themes@148 tierce-partie/themes //svn.exemple.com/outils-themes@21 tierce-partie/themes/outils $
Subversion 1.6 apporta deux nouvelles améliorations aux définitions
de références externes. D'abord, il ajouta un mécanisme d'échappement et
mise entre guillemets à la syntaxe afin de traiter correctement des
chemins de copies de travail externes contenant des espaces. Cela posait
auparavant des problèmes car l'espace est un délimiteur de champs dans
les définitions de références externes. Maintenant, vous n'avez qu'à
entourer la spécification du chemin entre des guillemets doubles
("
) ou échapper les caractères qui posent
problème dans le chemin avec la barre oblique inversée
(\
). Bien sûr, si l'URL de la
référence externe comporte des espaces, vous devrez utiliser l'encodage
standard des URI pour les représenter.
$ svn propget svn:externals paint http://svn.site-tiers.fr/depot/Mon%20projet "Mon projet" http://svn.site-tiers.fr/depot/%22Avec%20des%20guillemets%22 \"Avec\ des\ guillemets\" $
Subversion 1.6 introduit également le support pour la définition de références externes de fichiers. Les définitions de références externes de fichiers sont configurées de la même manière que les répertoires externes et apparaissent comme des fichiers suivis en versions dans la copie de travail.
Par exemple, supposons que vous ayez le fichier
/trunk/couleurs_vélo/bleu.html
dans votre dépôt et
que vous souhaitiez que ce fichier, tel qu'il était dans la révision 40,
apparaisse dans votre copie de travail de
/trunk/www/
comme le fichier
vert.html
.
La définition de référence externe nécessaire pour obtenir ce résultat devrait vous être familière maintenant :
$ svn propget svn:externals www/ ^/trunk/couleurs_vélo/bleu.html@40 vert.html $ svn update Mise à jour de '.' : Récupération de la référence externe dans 'www' : E www/vert.html Référence externe à la révision 40. À la révision 103. $ svn status X www/vert.html $
Comme vous pouvez le voir dans l'exemple ci-dessus, Subversion
annote les fichiers externes avec la lettre E
quand
ils sont rappatriés vers la copie de travail et avec la lettre
X
lors de l'affichage de l'état de la copie de
travail.
Avertissement | |
---|---|
Alors que les définitions de références externes pour un répertoire peuvent placer le répertoire à n'importe quelle profondeur et créer les répertoires intermédiaires manquants, les définitions de fichiers externes doivent être placées dans une copie de travail qui a déjà fait l'objet d'une extraction. |
Lorsque vous examinez un fichier externe à l'aide de la commande svn info, vous pouvez voir l'URL et la révision qui sont à l'origine du fichier.
$ svn info www/vert.html Chemin : www/vert.html Nom : green.html Chemin racine de la copie de travail : /home/harry/projects/my-project URL : http://svn.example.com/projects/my-project/trunk/bikeshed/blue.html Relative URL: ^/trunk/bikeshed/blue.html Racine du dépôt : http://svn.example.com/projects/my-project UUID du dépôt : b2a368dc-7564-11de-bb2b-113435390e17 Révision: 40 Type de nœud : fichier Tâche programmée : normale Auteur de la dernière modification : harry Révision de la dernière modification : 40 Date de la dernière modification : 2009-07-20 20:38:20 +0100 (lun. 20 juil. 2009) Texte mis à jour : 2009-07-20 23:22:36 +0100 (lun. 20 juil. 2009) Somme de contrôle : 01a58b04617b92492d99662c3837b33b $
Parce que les fichier externes sont traités dans la copie de travail
comme des fichiers suivis en versions, ils peuvent être modifiés et
même propagés s'ils font référence à un fichier à la révision
HEAD
. Les modifications propagées sont répercutées
dans le fichier externe comme dans le fichier référencé. Cependant, dans
notre exemple, nous avons pointé vers un fichier à une révision
antérieure, c'est pourquoi une tentative de propagation du fichier
externe échoue :
$ svn status M X www/vert.html $ svn commit -m "change la couleur" www/vert.html Envoi www/vert.html svn: E155011: Échec de la propagation (commit), détails : svn: E155011: Fichier '/trunk/couleurs_vélo/bleu.html' obsolète $
Gardez cela à l'esprit quand vous définissez des références vers
des fichiers externes. Si vous avez besoin de pointer vers une révision
particulière d'un fichier, vous ne pourrez pas modifier ce fichier
externe. Si vous voulez pouvoir modifier le fichier externe, vous ne
pouvez pas spécifier une révision autre que HEAD
,
ce qui est implicite si aucune révision n'est spécifiée.
Malheureusement, le support des références externes de Subversion
reste largement perfectible. Les fichiers et les répertoires externes
possèdent leur lot d'inconvénients. Quel que soit le type de référence
externe, le sous-répertoire local faisant partie de la définition ne
peut pas contenir d'indicateurs vers le répertoire parent
« ..
» (par exemple
../../skins/perso
). Les fichiers externes ne
peuvent pas faire référence à des fichiers d'autres dépôts. L'URL d'un
fichier externe doit toujours être dans le même dépôt que sa cible.
Aussi, les fichiers externes ne peuvent pas être déplacés ou effacés.
C'est la propriété svn:externals
qui doit être
modifiée à la place. Cependant, les fichiers externes peuvent être
copiés.
Ce qui est peut-être le plus ennuyeux, c'est que les copies de
travail créées via le support de définition de références externes sont
toujours déconnectées de la copie de travail primaire (sur laquelle le
répertoire suivi en versions possède la propriété
svn:externals
). Et Subversion continue à fonctionner
seulement sur des copies de travail conjointes. Ainsi, par exemple, si
vous voulez propager des modifications que vous avez faites sur une ou
plus de ces copies de travail externes, vous devez lancer
svn commit explicitement sur ces copies de travail
(la propagation sur la copie de travail initiale ne se répercute pas
sur les copies externes).
Nous avons déjà mentionné quelques inconvénients de l'ancienne
syntaxe svn:externals
et comment la nouvelle syntaxe
des versions plus récentes que Subversion 1.5 résolvent ce problème.
Mais soyez vigilant lorsque vous utilisez cette nouvelle syntaxe de ne
pas introduire de nouveaux problèmes par inadvertance. Par exemple,
alors que les nouveaux clients sont capables de reconnaitre et
prendre en charge l'ancienne syntaxe de défintion des références
externes, les clients pré-1.5 ne peuvent pas
analyser correctement la nouvelle syntaxe. Si vous changez vos
définitions de références externes au nouveau format, vous forcez tous
ceux qui utilisent ces références externes à effectivement mettre à
niveau leur client Subversion vers une version capable de lire ce
format. De même, soyez attentif à ne pas naïvement déplacer la portion
-r
de la définition
(l'ancien format utilise cette révision comme pivot, mais le nouveau
format l'utilise comme révision opérationnelle avec une révision pivot
à NNN
HEAD
, sauf mention contraire lisez la section intitulée « Révisions pivots et révisions opérationnelles » pour une explication complète de cette
distinction).
Avertissement | |
---|---|
Les copies de travail externes sont toujours des copies de travail
totalement auto-suffisantes. Vous pouvez effectuez les opérations que
vous effectueriez sur toute autre copie de travail. Cela peut
s'avérer très utile, vous permettant d'examiner une copie de travail
externe indépendamment de toute copie de travail primaire dont la
propriété |
Tout comme les commandes svn checkout,
svn update, svn switch et
svn export qui gèrent les sous-répertoires
disjoints (ou déconnectés) depuis lesquels les
références externes sont extraites, la commande svn
status reconnait les définitions de références externes. Elle
affiche un statut sous le code X
pour les
sous-répertoires externes disjoints, puis explore récursivement ces
sous-répertoires pour afficher le statut des éléments externes
eux-mêmes. Vous pouvez spécifier l'option
--ignore-externals
à n'importe laquelle de ces
sous-commandes pour désactiver le traitement des définitions des
références externes.
Il est très courant pour un développeur d'avoir à effectuer, en même temps, des modifications multiples n'ayant rien à voir entre elles sur une portion de code donnée. Ce n'est pas nécessairement la preuve d'une mauvaise gestion de son temps, ni d'une forme de masochisme numérique. Un ingénieur de développement repère souvent des bogues annexes lorsqu'il travaille sur un morceau de code particulier. Ou alors c'est une fois rendu à mi-chemin d'un changement important qu'il prend conscience que la solution qu'il a choisie serait mieux propagée sous la forme de plusieurs unités logiques plus petites, ces unités pouvant se recouper, affecter des fichiers différents d'un même module ou même toucher à des lignes différentes d'un même fichier.
Plusieurs méthodes sont à disposition des développeurs pour gérer ces ensembles de modifications. Certains développeurs utilisent des copies de travail séparées, du même dépôt, pour y conserver les progrès faits pour chaque changement. D'autres développeurs choisissent de créer au sein du dépôt des branches fonctionnelles à durée de vie très courte et d'utiliser une unique copie de travail qu'ils font pointer selon les besoins du moment vers une branche de ce type ou vers une autre. Enfin, d'autres développeurs utilisent les outils diff et patch pour sauvegarder et restaurer des changements non propagés sur les fichiers touchés par les modifications. Chacune de ces méthodes a des avantages et des inconvénients et, en général, le détail des changements à effectuer influence fortement le choix de la méthode utilisée pour les distinguer.
Subversion fournit la fonctionnalité des listes de modifications, qui vient s'ajouter aux méthodes mentionnées ci-dessus. Les listes de modifications sont en gros des étiquettes arbitraires (une au plus par fichier pour l'instant) attachées à des fichiers de la copie de travail dans le seul but de regrouper plusieurs fichiers ensemble. Les utilisateurs de bon nombre de logiciels fournis par Google sont déjà habitués à ce concept. Dans Gmail, vous associez des étiquettes arbitraires à des e-mails et plusieurs e-mails peuvent être considérés comme faisant partie du même groupe s'ils partagent une étiquette donnée. Dès lors, ne voir qu'un groupe d'e-mails portant la même étiquette n'est plus qu'un simple jeu d'affichage. De nombreux autres sites web 2.0 possèdent des mécanismes similaires. Prenez par exemple les « tags » (« étiquette » en anglais) utilisés sur des sites comme YouTube ou Flickr, les « catégories » utilisées pour regrouper les articles de blogs, etc. Aujourd'hui les gens ont compris que l'organisation des données est essentielle et la façon dont ces données sont organisées doit être flexible. Le vieux paradigme des répertoires et des fichiers est bien trop rigide pour certaines applications.
Cette fonctionnalité de Subversion vous permet de créer des listes de modifications en étiquetant les fichiers que vous voulez inclure, de supprimer ces étiquettes et de limiter le rayon d'action des sous-commandes aux seuls fichiers qui portent l'étiquette donnée. Dans ce paragraphe, nous allons voir en détails comment accomplir ces actions.
Vous pouvez créer, modifier et supprimer des listes de modifications en utilisant la commande svn changelist. Plus précisément, vous pouvez utiliser cette commande pour activer ou désactiver l'association d'une liste de modifications avec un fichier donné de la copie de travail. La création d'une liste de modifications a lieu la première fois que vous étiquetez un fichier avec ce nom de liste ; elle n'est supprimée que quand vous effacez l'étiquette du dernier fichier qui la portait. Examinons un cas concret pour illustrer ces notions.
Harry est en train de corriger des bogues dans le module de logique mathématique de l'application « calculatrice ». Son travail l'amène à modifier deux fichiers :
$ svn status M entier.c M ops-math.c $
En testant son correctif, Harry s'aperçoit que ses
modifications lui indiquent qu'un bogue collatéral existe au
sein de la logique de l'interface utilisateur, située dans le
fichier bouton.c
. Harry décide alors qu'il
va aussi corriger ce bogue, dans une propagation séparée de ses
propres correctifs mathématiques. Dans une copie de travail de
petite taille, ne contenant qu'une poignée de fichiers, et pour
juste quelques modifications logiques, Harry pourrait
probablement gérer mentalement ces deux ensembles logiques de
modifications sans le moindre problème. Mais aujourd'hui il a
décidé qu'il allait utiliser les listes de modifications de
Subversion, pour faire une faveur aux auteurs de ce livre.
Harry commence par créer une première liste de modifications et y associe les deux premiers fichiers qu'il a déjà modifié. Pour ce faire, il utilise la commande svn changelist afin d'associer le même nom arbitraire de liste de modifications aux deux fichiers :
$ svn changelist correctifs-maths entier.c ops-math.c A [correctifs-maths] entier.c A [correctifs-maths] ops-math.c $ svn status --- Liste de changements 'correctifs-maths' : M entier.c M ops-math.c $
Comme vous pouvez le constater, le résultat de svn status reflète bien ce nouvel ensemble.
Harry se lance alors dans la correction du problème d'interface graphique collatéral. Puisqu'il sait quel fichier il va modifier, il associe également ce chemin à une liste de modifications. Mais malencontreusement Harry associe ce troisième fichier à la même liste de modifications que les deux premiers :
$ svn changelist correctifs-maths bouton.c A [math-fixes] bouton.c $ svn status --- :Liste de changements 'correctifs-maths' : bouton.c M entier.c M ops-math.c $
Par chance, Harry prend conscience de son erreur. Deux
options se présentent alors à lui. Il peut supprimer
l'association de bouton.c
avec la liste de
modifications, puis lui associer un nouveau nom de liste de
modifications :
$ svn changelist --remove bouton.c D [correctifs-maths] bouton.c $ svn changelist correctifs-graphiques bouton.c A [correctifs-graphiques] bouton.c $
Ou alors il peut sauter l'étape de suppression et juste
associer un nouveau nom de liste de modifications à
bouton.c
. Dans ce cas, Subversion signale à
Harry que bouton.c
va être supprimé de la
première liste de modifications :
$ svn changelist correctifs-graphiques bouton.c D [correctifs-maths] bouton.c A [correctifs-graphiques] bouton.c $ svn status --- Liste de changements 'correctifs-graphiques' : bouton.c --- Liste de changements 'correctifs-maths' : M entier.c M ops-maths.c $
Harry dispose donc à présent de deux listes de modifications
distinctes dans sa copie de travail et svn
status présente ses résultats en les regroupant par
liste de modifications. Notez que bien qu'Harry n'ait pas encore
modifié bouton.c
, celui-ci est quand même
mentionné par svn status car une liste de
modifications lui est associée. Les listes de modifications
peuvent être associées, ou enlevées, aux fichiers à tout moment,
indépendamment du fait que ces fichiers contiennent des
modifications locales ou pas.
Harry règle maintenant le problème de l'interface graphique
dans bouton.c
.
$ svn status --- Liste de changements 'correctifs-graphiques': M bouton.c --- Liste de changements 'correctifs-maths': M entier.c M ops-math.c $
Le regroupement visuel qu'Harry constate en sortie de
svn status, comme indiqué précédemment, est
intéressant d'un point de vue esthétique, mais pas vraiment
utile. La commande status n'est qu'une des
commandes qu'il est susceptible de lancer sur sa copie de
travail. Heureusement, bon nombre des autres opérations de
Subversion sont capables d'agir sur les listes de modifications
grâce à l'option --changelist
.
Quand l'option --changelist
est présente,
les commandes Subversion limitent leur champ d'action aux
fichiers auxquels est associé le nom de liste de modifications
donné. Si Harry veut voir quels changements il a effectué sur
les fichiers de sa liste correctifs-maths
, il
pourrait lister explicitement les fichiers
faisant partie de cette liste de modifications avec la
commande svn diff.
$ svn diff entier.c ops-math.c Index: entier.c =================================================================== --- entier.c (révision 1157) +++ entier.c (copie de travail) … Index: ops-math.c =================================================================== --- ops-math.c (révision 1157) +++ ops-math.c (copie de travail) … $
Cette méthode fonctionne bien pour un petit nombre de fichiers, mais qu'en est-il si Harry a modifié une vingtaine ou une trentaine de fichiers ? Fournir la liste de tous ces fichiers serait assez pénible. Mais puisqu'il utilise les listes de modifications, Harry peut désormais éviter de lister explicitement tous les fichiers et ne donner à la place que le nom de la liste de modifications :
$ svn diff --changelist correctifs-maths Index: entier.c =================================================================== --- entier.c (révision 1157) +++ entier.c (copie de travail) … Index: ops-math.c =================================================================== --- ops-math.c (révision 1157) +++ ops-math.c (copie de travail) … $
Et au moment de lancer la propagation, Harry peut à nouveau
se servir de l'option --changelist
pour limiter
le rayon d'action de la propagation aux fichiers de sa liste de
modifications. Par exemple, il peut propager ses changements
concernant l'interface graphique en lançant :
$ svn commit -m "Corrigé un bug de l'interface graphique découvert en travaillant sur la logique mathématique." \ --changelist correctifs-graphiques Envoi bouton.c Transmission des données . Révision 1158 propagée. $
En fait, la commande svn commit accepte
une deuxième option liée aux listes de modifications :
--keep-changelists
. Normalement, l'association
des listes de modifications avec les fichiers est supprimée dès
que ceux-ci ont été propagés. Mais si l'option
--keep-changelists
est ajoutée sur la ligne de
commande, les fichiers propagés (qui ne sont donc plus dans
l'état modifié) restent associés aux listes de modifications
en question. Dans tous les cas, propager des fichiers faisant
partie d'une liste de modification laisse les autres listes de
modifications intactes.
$ svn status --- Liste de changements 'correctifs-maths': M entier.c M ops-math.c $
Note | |
---|---|
L'option |
Même la commande svn changelist accepte
l'option --changelist
. Ceci vous permet de
renommer ou supprimer facilement une liste de
modifications :
$ svn changelist bogues-maths --changelist correctifs-maths --depth infinity . D [correctifs-maths] entier.c A [bogues-maths] entier.c D [correctifs-maths] ops-math.c A [bogues-maths] ops-math.c $ svn changelist --remove --changelist bogues-maths --depth infinity . D [bogues-maths] entier.c D [bogues-maths] ops-math.c $
Enfin, vous pouvez spécifier plusieurs instances de l'option
--changelist
dans une même ligne de commande.
Ceci limite le champ d'action de votre opération aux fichiers
faisant partie de toutes les listes de modifications
spécifiées.
La fonctionnalité de listes de modifications de Subversion est un outil très pratique pour créer des groupes de fichiers au sein de la copie de travail, mais elle a cependant quelques limitations. Les listes de modifications sont des objets contenus à l'intérieur d'une copie de travail, ce qui signifie que les associations entre fichiers et listes de modifications ne peuvent pas être propagées vers le dépôt, ni partagées avec d'autres utilisateurs. Les listes de modifications ne peuvent être associées qu'à des fichiers, Subversion n'offre pas cette possibilité pour les répertoires. Enfin, vous pouvez avoir au plus un nom de liste de modifications associé à un fichier donné. C'est ici que l'analogie avec les articles de blogs et les services d'étiquetage de photos en ligne part en fumée. S'il vous faut associer un fichier à plusieurs listes de modifications, vous êtes coincé.
À un moment ou à un autre, vous aurez besoin de
comprendre comment le client Subversion communique avec le
serveur. La couche réseau de Subversion est abstraite,
c'est-à-dire que les clients Subversion ont le même comportement
quel que soit le type de serveur auquel ils ont affaire. Qu'ils
communiquent via le protocole HTTP (http://
)
avec un serveur HTTP Apache ou via le protocole Subversion
(svn://
) avec svnserve,
le modèle de communication réseau est le même. Dans cette section,
nous expliquons les fondamentaux de ce modèle de communication
réseau, y compris la façon dont Subversion gère les
authentifications et les autorisations.
Le client Subversion passe la plupart de son temps à gérer des copies de travail. Cependant, quand il a besoin d'informations disponibles dans un dépôt distant, il envoie une requête sur le réseau et le serveur lui répond. Les détails du protocole réseau sont cachés à l'utilisateur : le client essaie d'accéder à une URL et, suivant le format de cette URL, utilise un protocole particulier pour contacter le serveur (voir la section intitulée « URL des dépôts Subversion »).
Astuce | |
---|---|
Tapez |
Quand le serveur reçoit une requête d'un client, il demande souvent au client de s'identifier. Il envoie un défi d'authentification vers le client et le client répond en fournissant les éléments d'authentification au serveur. Une fois cette authentification terminée, le serveur répond à la requête originale du client. Remarquez que ce fonctionnement est différent de celui de CVS où le client envoie systématiquement au préalable ses identifiants de connexion (procédure de « log in »), avant même de formuler la moindre requête. Dans Subversion, le serveur requiert explicitement l'authentification du client (par un défi d'authentification) au moment approprié, au lieu que ce soit le client qui s'authentifie a priori. Certaines opérations sont donc effectuées plus élégamment. Par exemple, si un serveur est configuré pour laisser tout le monde accéder au dépôt en lecture, alors le serveur n'envoie jamais de défi d'authentification quand un client tente un svn checkout.
Si une requête d'un client conduit à la création d'une
nouvelle révision du dépôt (par exemple un svn
commit), alors Subversion utilise le nom d'utilisateur
fourni lors de la phase d'authentification comme auteur de la
révision. C'est-à-dire que le nom d'utilisateur est stocké dans
la propriété svn:author
de la nouvelle
révision (voir la section intitulée « Propriétés réservées à l'usage de Subversion »). Si le
client n'a pas été authentifié (en d'autres termes, si le
serveur n'a jamais envoyé de défi d'authentification), alors la
propriété svn:author
de la révision est
vide.
Beaucoup de serveurs sont configurés afin de requérir une authentification. Parfois, les opérations de lecture sont autorisées aux utilisateurs anonymes alors que les opérations d'écriture nécessitent une authentification. Dans d'autres cas, à la fois les opérations de lecture et d'écriture requièrent une authentification. Les différentes options du serveur Subversion gèrent différents protocoles d'authentification mais, du point de vue de l'utilisateur, l'authentification se résume typiquement à un identifiant et un mot de passe. Les clients Subversion offrent différentes façon de gérer les éléments d'authentification de l'utilisateur, depuis la saisie interactive de l'identifiant et du mot de passe jusqu'à la mise en cache des éléments dans un conteneur chiffré ou non sur le disque.
Ici, le lecteur soucieux de sécurité va immédiatement bondir de son siège : « Mettre en cache des mots de passe sur le disque ? Quelle horreur ! Jamais ! ». Ne vous inquiétez pas outre mesure : ce n'est pas aussi terrible que ça en a l'air. Les paragraphes qui suivent vont détailler les différents types de cache pour les éléments d'authentification que Subversion utilise, les phases où il les utilise et comment désactiver cette fonctionnalité en totalité ou en partie.
Subversion propose une solution à ceux qui en ont assez de taper leur nom d'utilisateur et mot de passe à tout bout de champs. Par défaut, dès que le client texte interactif passe avec succès un défi d'authentification, les éléments d'authentification sont mis en cache sur le disque et associés à la combinaison du nom du serveur, son port et le domaine d'authentification. Ce cache sera automatiquement consulté lors des prochains défis, l'utilisateur n'ayant plus à retaper ses éléments d'authentification. Si aucun élément convenable n'est présent dans le cache, ou si les éléments du cache échouent à l'authentification, le client invitera l'utilisateur à fournir les informations nécessaires.
Les développeurs de Subversion reconnaissent que le stockage sur disque des éléments d'authentification peut consistuer une vulnérabilité. C'est pourquoi Subversion est capable de fonctionner avec les différents mécanismes offerts par le système d'exploitation et l'environnement de travail pour minimiser les risques de fuites d'information.
Sous Windows, le client Subversion stocke les mots de
passe dans le répertoire
%APPDATA%/Subversion/auth/
. Sous Windows
2000 et ses successeurs, le client Subversion utilise les
services cryptographiques standards de Windows pour chiffrer le
mot de passe sur le disque. Comme la clé de chiffrement est gérée
par Windows et qu'elle est associée à l'identifiant de connexion
de l'utilisateur, lui seul peut déchiffrer le mot de passe en
cache. Notez que si le mot de passe de l'utilisateur est
réinitialisé par un administrateur, tous les mots de passe en
cache deviennent indéchiffrables. Le client Subversion agit comme
s'ils n'existaient pas, en redemandant le mot de passe quand
c'est nécessaire.
De manière similaire, sur Mac OS X, le client Subversion stocke tous les mots de passe dans le jeton de connexion (géré par le service « Keychain »), qui est protégé par le mot de passe du compte utilisateur. La configuration des « préférences utilisateur » peut imposer une politique plus stricte, comme demander le mot de passe du compte utilisateur à chaque fois qu'un mot de passe Subversion est utilisé.
Pour les systèmes de type Unix, il n'existe pas de
standard de service de type « Keychain ». Cependant,
le client Subversion sait stocker de manière sûre les mots de
passe en utilisant les services « Gnome Keyring »,
« KDE Wallet » et « GnuPG Agent ». Aussi,
avant de stocker les mots de passe sans chiffrement dans la zone
de cache ~/.subversion/auth/
, le client
Subversion demandera à l'utilisateur l'autorisation de le faire.
Notez que la zone de cache auth/
reste
protégée par les droits système et seul l'utilisateur (le
propriétaire) des données peut les lire. Les droits sur les
fichiers fournis par le système d'exploitation protègent les mots
de passe vis-à-vis des autres utilisateurs non administrateurs
sur le même système, pour autant qu'ils n'aient pas un accès
physique direct au dispositif de stockage du répertoire de
l'utilisateur ou aux sauvegardes.
Bien sûr, si vous êtes complètement paranoïaque, aucun de ces mécanismes n'est parfait. Ainsi, pour ceux qui sont prêts à sacrifier le confort d'utilisation au profit de la sécurité absolue, Subversion fournit de nombreuses façons de désactiver les systèmes de cache d'authentification.
Quand vous effectuez une opération Subversion qui nécessite de vous authentifier, par défaut Subversion essaie de mettre en cache vos éléments d'authentification sur le disque sous une forme chiffrée. Sur certains systèmes, Subversion peut être incapable de chiffrer vos éléments d'authentification. Dans ce cas, Subversion vous demandera si vous voulez vraiment mettre en cache vos éléments d'authentification sur le disque sous forme claire :
$ svn checkout https://host.example.com:443/svn/private-repo ----------------------------------------------------------------------- ATTENTION! Your password for authentication realm: <https://host.example.com:443> Subversion Repository can only be stored to disk unencrypted! You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/tmp/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)?
Si vous voulez profiter de la facilité de ne pas avoir à entrer
votre mot de passe à chaque nouvelle opération, vous pouvez
répondre yes
à cette invite. Si vous ne voulez
pas stocker votre mot de passe en clair et que vous ne voulez pas
que Subversion vous pose la question à chaque fois, vous pouvez
désactiver la mise en cache en clair des mots de passe, soit de
manière permanente, soit en fonction du serveur auquel vous vous
connectez.
Avertissement | |
---|---|
Au moment de faire votre choix concernant la mise en cache des mots de passe, vérifier la politique de sécurité relative à votre poste de travail. Beaucoup d'entreprises ont des règles strictes sur le stockage des mots de passe de leurs employés. |
Pour désactiver de manière permanente la mise en cache des
mots de passe en clair, ajouter la ligne
store-plaintext-passwords = no
à la section
[global]
du fichier de configuration
servers
de votre machine locale. Pour la
désactiver uniquement pour un serveur particulier, utiliser la
même directive dans la section appropriée du fichier de
configuration servers
(pour plus de détails,
reportez-vous à
la section intitulée « Options de configuration » dans
Chapitre 7, Personnalisation de Subversion.)
Pour désactiver la mise en cache des mots de passe pour les
opérations en ligne de commande, utilisez l'option
--no-auth-cache
. Pour désactiver la mise en cache
de manière permanente, ajoutez l'option store-passwords =
no
dans le fichier de configuration Subversion de votre
machine.
Il arrive que les utilisateurs veuillent effacer certains
mots de passe du cache disque. Pour ce faire, vous devez vous
rendre dans la zone auth/
et effacer
manuellement le fichier de cache approprié. Les éléments
d'authentification sont mis en cache dans des fichiers
individuels ; si vous affichez chaque fichier, vous voyez
des clés et des valeurs. La clé
svn:realmstring
décrit le domaine du serveur
auquel est associé le fichier :
$ ls ~/.subversion/auth/svn.simple/ 5671adf2865e267db74f09ba6f872c28 3893ed123b39500bca8a0b382839198e 5c3c22968347b390f349ff340196ed39 $ cat ~/.subversion/auth/svn.simple/5671adf2865e267db74f09ba6f872c28 K 8 username V 3 joe K 8 password V 4 blah K 15 svn:realmstring V 45 <https://svn.domaine.fr:443> dépôt de Paul END
Une fois le bon fichier trouvé, effacez-le.
Toutes les opérations en ligne de commandes acceptent les
options --username
et --password
,
qui vous permettent de spécifier respectivement un nom
d'utilisateur et un mot de passe afin que Subversion ne soit pas
obligé de vous inviter à les entrer. C'est particulièrement
pratique si vous devez invoquer Subversion dans un script et que
vous ne pouvez pas vous fier au fait que Subversion trouvera des
éléments d'authentification valides dans le cache pour vous. Ces
options sont aussi utiles lorsque Subversion a déjà mis en cache
les éléments d'authentification pour vous, mais que vous savez que
vous ne voulez pas utiliser ces éléments. Vous pouvez omettre
l'option --password
si vous souhaitez que
Subversion utilise seulement le nom d'utilisateur fourni mais
continue à demander un mot de passe pour cet utilisateur.
La façon dont svn gère
l'authentification, avec un zoom sur les options
--username
et --password
.
Beaucoup de sous-commandes du client acceptent ces options, mais
il est important de comprendre que l'utilisation de ces options
n'envoie pas automatiquement les éléments
d'authentification au serveur. Comme vu précédemment, le serveur
demande explicitement l'authentification au
client quand il estime que c'est nécessaire ; le client ne
les envoie pas à sa convenance. Même si un nom d'utilisateur
et/ou un mot de passe sont passés en option, ils ne sont
envoyés au serveur que si celui-ci les demande. Ces options sont
couramment utilisées pour s'authentifier sous un nom
d'utilisateur différent de celui que Subversion aurait choisi
par défaut (comme votre nom de compte système), ou quand on ne
veut pas de commande interactive (par exemple, utilisation de la
commande svn dans un script).
Note | |
---|---|
Une erreur classique consiste à mal configurer un serveur
de telle sorte qu'il n'envoie jamais de défi
d'authentification. Quand les utilisateurs passent les options
|
En résumé, voici comment un client Subversion se comporte quand il reçoit un défi d'authentification :
D'abord, le client vérifie si l'utilisateur a spécifié
explicitement des éléments d'authentification dans la ligne
de commande (options --username
et/ou
--password
). Si c'est le cas, le client
essaie de s'authentifier auprès du serveur avec ces
éléménts.
Si les éléments d'authentification ne sont pas passés en
ligne de commande, ou si ceux qui ont été fournis ne sont pas
valides, le client regarde dans la zone
auth/
s'il trouve le nom, le port et
le domaine du serveur pour voir si l'utilisateur a déjà les
éléments d'authentification en cache. Si c'est le cas, il
essaie d'utiliser ces éléments pour s'authentifier.
Finalement, si les mécanismes précédents ont abouti à
des échecs d'authentification sur le serveur, le client se
résout à demander les éléments à l'utilisateur (à moins
qu'il ne lui ait été indiqué de ne pas le faire
via l'option
--non-interactive
ou son équivalent
spécifique au client).
Si le client réussit à s'authentifier par l'une ou l'autre de ces méthodes, il essaie de mettre en cache les éléments d'authentification sur le disque (à moins que cette fonctionnalité ne soit désactivée, comme indiqué auparavant).
Comme nous l'avons indiqué dans la section intitulée « Copies de travail », la copie de travail Subversion est une sorte de zone de transit où l'utilisateur peut effectuer des modifications privées à ses données suivies en versions et, une fois que ces modifications sont terminées et prêtes à être partagées, il peut les propager vers le dépôt. Cela ne doit donc pas vous surprendre si l'on vous dit que la majeure partie des interactions que vous aurez avec Subversion seront des demandes au client Subversion de faire quelque chose concernant un ou plusieurs éléments de la copie de travail locale. Même pour les opérations qui ne manipulent pas de données de la copie de travail elle-même (telles que svn log par exemple), il est souvent plus facile d'utiliser un fichier ou un dossier de la copie de travail comme cible de l'opération.
Clairement, l'approche canonique pour effectuer des modifications sur vos données suivies en versions se fait via une propagation d'une copie de travail Subversion. Heureusement, ce n'est pas l'unique façon de faire. Les utilisateurs de Subversion qui ont besoin de faire des modifications simples à leurs données suivies en versions peuvent le faire en s'affranchissant du coût d'une copie de travail. Dans cette section, nous allons décrire quelques opérations de ce type.
Le client texte interactif Subversion sait faire plusieurs opérations en utilisant des URL du dépôt et sans copie de travail afin d'effectuer des modifications simples. Certaines sont décrites ailleurs dans ce livre, mais nous vous en donnons la liste exhaustive ici.
Certainement la plus évidente des opérations à distance de type propagation est la comande svn import. Nous décrivons cette commande dans la section intitulée « Importation de fichiers et de dossiers » lorsque nous expliquons comment insérer facilement une arborescence complète de données non suivies en versions dans un dépôt Subversion afin de démarrer le processus de suivi de versions sur ces données.
Les commandes svn mkdir et svn delete, lorsqu'elle ciblent des URL, sont aussi des opérations de type propagation. Elles permettent respectivement à l'utilisateur de créer un ou plusieurs nouveaux dossiers suivis en versions ou supprimer (récursivement) un ou plusieurs fichiers ou dossiers suivis en versions, sans l'utilisation d'une copie de travail. Chaque fois que vous entrez une de ces commandes, le client communique avec le serveur de la même manière que s'il décrivait la propagation de l'ajout d'un dossier ou de la suppression d'un élément de la copie de travail. S'il n'y a pas de problème ou de conflit détecté par cette opération, le serveur propage les ajouts ou les suppressions dans une nouvelle révision unique.
Vous pouvez utiliser svn copy ou svn move avec deux URL (une URL source de la copie/déplacement et une URL destination) pour propager des copies ou des déplacements de fichiers ou dossiers directement dans le dépôt. Ces opérations s'avèrent être les plus coûteuses quand elles sont effectuées à l'intérieur d'une copie de travail alors qu'elles s'exécutent en temps constant lorsqu'elles sont effectuées à distance en utilisant des URL du dépôt. En fait, l'opération distante svn copy est communément utilisée pour créer des branches dans Subversion, comme nous le montrons dans la section intitulée « Création d'une branche ».
Comme pour la commande svn commit habituelle,
vous pouvez spécifier un commentaire de propagation avec toutes ces
commandes pour décrire les modifications que vous effectuez. Utilisez
l'option --file (-F)
ou --message
(-m)
, sinon autorisez le client à vous inviter à lui
fournir un commentaire de propagation.
Enfin, il y a plusieurs opérations relatives aux propriétés non suivies en versions que vous pouvez effectuer directement sur le dépôt. En fait, les propriétés de révisions sont quelques peu uniques dans ce contexte, puisqu'elles ne sont pas stockées dans les copies de travail et, par conséquent. doivent être modifiées sans toucher à la copie de travail. Reportez-vous à la section intitulée « Propriétés » pour une description détaillée de la façon de gérer les propriétés dans Subversion.
Un inconvénient de la propagation à distance par le
client texte interactif est que vous êtes limité à une seule
opération (réellement un type d'opération) par propagation. Par
exemple, il est parfaitement naturel et possible de, disons,
utiliser svn delete suivi de svn
mkdir dans une copie de travail pour remplacer un
répertoire suivi en versions existant avec un tout neuf. Lorsque vous
propagez ces opérations, une seule nouvelle révision est créée dans
le dépôt et cette révision comporte le remplacement complet de votre
répertoire. Vous ne pouvez pas faire la même chose en opération à
distance en utilisant le client texte interactif, tout en préservant
l'unité de la transaction (svn delete
URL
créera une nouvelle révision
qui supprime le répertoire et svn mkdir
URL
créera une deuxième révision
qui recrée le répertoire).
Heureusement, Subversion fournit un utilitaire séparé qui a pour vocation de permettre aux utilisateurs d'enchaîner un ensemble d'opérations à distance et de les propager comme une modification atomique. Cet outil est svnmucc, pour Subversion Multiple URL Command Client (que l'on pourrait traduire par client Subversion pour les commandes avec de multiples URL) :
$ svnmucc --help …Subversion multiple URL command client usage: svnmucc ACTION... Perform one or more Subversion repository URL-based ACTIONs, committing the result as a (single) new revision. Actions: cp REV SRC-URL DST-URL : copy SRC-URL@REV to DST-URL mkdir URL : create new directory URL mv SRC-URL DST-URL : move SRC-URL to DST-URL rm URL : delete URL put SRC-FILE URL : add or modify file URL with contents copied from SRC-FILE (use "-" to read from standard input) propset NAME VALUE URL : set property NAME on URL to VALUE propsetf NAME FILE URL : set property NAME on URL to value read from FILE propdel NAME URL : delete property NAME from URL …
svnmucc est inlus dans le code source du projet Subversion depuis de nombreuses années (en tant que commande mucc historiquement), mais c'est seulement à partir de Subversion 1.8 qu'il est devenu un membre à part entière de la panoplie des utilitaires en ligne de commande de Subversion.
L'utilitaire svnmucc peut effectuer toutes
les manipulations que svn fait. Mais, au contraire
de svn, svnmucc ne comporte pas
de sous-commande. La syntaxe adoptée consiste à lui fournir une liste
d'actions et d'opérandes dans une seule ligne de commande (ou depuis
un fichier, via l'option
--extra-args (-X)
). Certaines actions autorisées
par svnmucc singent le fonctionnement du client
texte interactif. Vous aurez noté dans la sortie de la commande
précédente que les cp
, mkdir
,
mv
et rm
ressemblent
bigrement aux commandes que nous avons citées dans
la section intitulée « Opérations du client texte interactif à distance ». Mais
souvenez-vous que la différence fondamentale réside dans le fait que
vous pouvez enchaîner plusieurs actions dans une seule ligne de
commande et que cela ne générera qu'une seule révision dans le
dépôt.
Prenons l'exemple précédent qui consiste à simplement remplacer un répertoire à distance. En utilisant svnmucc, vous le feriez ainsi :
$ svnmucc rm http://svn.exemple.fr/projets/pour-jouer \ mkdir http://svn.exemple.fr/projets/pour-jouer \ -m "Remplace mon vieux projet pour-jouer par un tout neuf." r22 propagée par harry le 2013-01-15T21:45:26.442865Z $
Comme vous pouvez le constater, svnmucc a réalisé en une seule révision ce qui aurait nécessité deux révision pour svn (sans copie de travail à disposition).
Avertissement | |
---|---|
Une autre différence entre svnmucc et svn réside dans le fait que le premier ne vous demandera pas d'entrer un commentaire de propagation si vous ne le fournissez pas via la ligne de commande. En lieu et place, il utilisera un message par défaut (ce qui est relativement inutile). |
L'utilitaire svnmucc n'est pas simplement limité aux actions que svn ferait tout aussi bien. Il introduit des fonctionnalités supplémentaires que l'on ne trouve pas dans le client texte interactif. Par exemple, vous pouvez utiliser l'action put pour ajouter ou modifier un fichier dans le dépôt, en copiant le contenu d'un fichier présent sur votre machine locale ou depuis le flux de l'entrée standard. Cet outil permet aussi de manipuler les propriétés des fichiers et dossiers suivis en versions avec les actions propset, propsetf et propdel, explicitement ou en copiant les valeurs des propriétés à partir d'un fichier local. Ces actions ne sont pas possible depuis le client texte interactif à l'heure actuelle.
Il est temps de préciser la différence entre ce que peut faire svnmucc et ce qu'il est souhaitable qu'il fasse. Deux exemples viennent à l'esprit :
« On demandera beaucoup à qui l'on a beaucoup donné. » | ||
--Jesus |
« Un grand pouvoir implique de grandes responsabilités. » | ||
--"Spiderman" Oncle Ben de Peter Parker |
Comme vous travaillez sans copie de travail, il est impossible pour Subversion de détecter des conflits avant la propagation. Lors d'une utilisation classique de svn, les changements qui sont propagés vers le serveur sont comparés à une version de base déterminée du fichier ou du répertoire, afin de ne pas écraser par inadvertance des modifications concurrentes apportées par un autre membre de l'équipe. Le serveur connait la version du fichier que vous aviez avant vos modifications et il sait si d'autres gens ont changé ce fichier depuis la révision que vous détenez. Ce sont ces informations dont le serveur a besoin pour refuser votre propagation et qu'elle n'écrase pas les changements faits par quelqu'un d'autre ; il vous force alors à intégrer ces changements dans votre copie de travail et à reconsidérer vos propres modifications. Avec svnmucc, il n'y a pas de copie de travail, ce qui vous donne la possibilité de contourner ces sécurités et d'agir comme si l'état courant du dépot était celui qui vous sert de base de travail. Heureusement, il est évident pour vous qu'un tel pouvoir ne s'utilise pas à la légère.
Heureusement, svnmucc vous permet de poser un
garde-fou lors de son utilisation. Afin d'offrir un mécanisme de
sécurité comparable à l'utilisation d'une copie de travail,
svnmucc propose l'option
--revision (-r)
. Avec cette option, vous pouvez
spécifier manuellement une révision de base pour les modifications
que vous essayez de propager. Cette révision de base est idéalement
la plus récente du dépôt dont vous ayez connaissance.
Avertissement | |
---|---|
Nous encourageons fermement les utilisateurs à utiliser, et de
manière appropriée, l'option |
L'utilisation appropriée de svnmucc put
démontre sans équivoque comment l'option
--revision (-r)
doit être invoquée. Considérons que
Harry veuille modifier le fichier suivi en versions
LISEZMOI
sans s'embêter à rappatrier une copie
de travail complète (nous supposons qu'il n'y a pas d'autre raison
de disposer d'une copie de travail pour cette action, telles que le
lancement de scripts avant de propager une révision pour vérifier
qu'elle satisfait certains critères). Il doit en premier lieu décider
avec quelle révision du fichier il va travailler. Typiquement, les
utilisateurs souhaitent travailler avec la version la plus à jour
d'un fichier. Ainsi, Harry effectue la requête relative à la
révision de la dernière modification du fichier et modifie le contenu
du fichier dans un fichier temporaire local :
$ svn info http://svn.exemple.com/projets/bac-à-sable/LISEZMOI Chemin : LISEZMOI URL : http://svn.exemple.com/projets/bac-à-sable/LISEZMOI Relative URL : ^/bac-à-sable/LISEZMOI Racine du dépôt : http://svn.example.com/projects UUID du dépôt : 13f79535-47bb-0310-9956-ffa450edef68 Révision : 22 Type de nœud : fichier Auteur de la dernière modification : sally Révision de la dernière modification : 14 Date de la dernière modification : 2012-09-02 10:34:09 -0400 (dim. 02 sep. 2012) $ svn cat -r 14 http://svn.exemple.com/projets/bac-à-sable/LISEZMOI \ > LISEZMOI.tempo $
Harry possède maintenant une copie du fichier
LISEZMOI
tel qu'il était lors de sa dernière
modification. Il fait ses modifications dans cette copie du fichier.
Naturellement, lorsqu'il a terminé, il veut propager ces
modifications vers le dépôt.
Maintenant, si Harry utilise naïvement
svnmucc put …
, pour remplacer le
contenu de LISEZMOI
dans le dépôt par le
contenu de son fichier local, il fait un abus de pouvoir avec
svnmucc. Que se passe-t-il si, quelques
microsecondes avant sa propagation, Sally a aussi modifié le
fichier LISEZMOI
? Tout comme
svn, svnmucc n'essaiera pas de
fusionner sur le serveur les modifications de chacun pour les
préserver. Non, svnmucc remplacera simplement la
dernière version du fichier par la nouvelle qu'on lui donne. Harry
n'en aura pas conscience, Sally sera furieuse.
$ svnmucc put LISEZMOI.tempo \ http://svn.exemple.com/projets/bac-à-sable/LISEZMOI \ -m "Modifié le fichier LISEZMOI." r24 propagée par harry le 2013-01-21T16:21:23.100133Z $ Message from sally@shell.example.com on pts/2 at 16:26 ... Il faut qu'on se parle. Maintenant. EOF
À la place, Harry doit rappeler la révision qu'il a utilisée
comme base de travail à la commande svnmucc
via l'option
--revision (-r)
. Ainsi, le serveur pourra rejeter
la propagation si, par malheur, Harry essaie de modifier un élément
obsolète :
$ svnmucc -r 14 put LISEZMOI.tempo \ http://svn.exemple.com/projets/bac-à-sable/LISEZMOI \ -m "Modifié le fichier LISEZMOI." svnmucc: E170004: Item '/bac-à-sable/LISEZMOI' est obsolète. $
Comme toutes les autres options de svnmucc,
l'option --revision (-r)
est globale pour la
commande, c'est-à-dire qu'elle s'applique à toutes les actions
spécifiées dans la commande. Cela vous permet d'avoir les mêmes
sortes de garde-fous que si vous aviez extrait une copie de travail
du dépôt tout entier (et donc comme si vous travailliez sur une
copie de travail uniformisée à la même révision), vous aviez effectué
vos modifications sur cette copie de travail, puis vous aviez propagé
toutes les modifications en même temps.
Comme vous pouvez le constater, svnmucc trouve bien sa place dans la boite à outils Subversion. Pour une référence complète des possibilités de cet outil, reportez-vous à Guide de référence de svnmucc : client texte Subversion pour URL multiples.
Après avoir lu ce chapitre, vous devez désormais avoir une bonne compréhension de certaines fonctionnalités de Subversion qui, bien qu'elles ne servent pas systématiquement à chaque utilisation du système de gestion de versions, peuvent rendre de grands services. Ne vous arrêtez pas là ! Lisez le chapitre suivant, où vous découvrirez les branches, les étiquettes et les fusions. Vous aurez alors la maîtrise quasi-complète du client Subversion. Bien que nos avocats ne nous autorisent pas à vous promettre quoi que ce soit, ces connaissances supplémentaires feront déjà de vous quelqu'un de bien plus branché. [31]
[11] « Sulli, il ne faut pas l'appeler ! Tu commences par l'appeler et tu finis par t'attacher », Bob Razowski (le cyclope de Monstres et Cie).
[12] Au 15 de la rue du Château à Rueil-Malmaison se trouve un musée d'histoire (consacré à Joséphine, épouse de Napoléon). Cela nous a semblé approprié…
[13] Pour ceux qui connaissent le XML, c'est à peu près le sous-ensemble ASCII pour la syntaxe du champ "Name" en XML.
[14] Corriger les fautes d'orthographe, les erreurs de
grammaire et les informations simplement erronées au sein
des commentaires de propagation est peut-être l'usage le plus
courant de l'option --revprop
.
[15]
L'exception notable à cet état de fait est la propriété
svn:mergeinfo
qui est héritable, voir
la section intitulée « Mergeinfo et aperçus »
[16] Actuellement, la
bibliohèque utilisée est libmagic
.
[17] Rappelez-vous que les utilisateurs ne
peuvent hériter de propriétés pour lesquelles ils ont un droit
en lecture. Donc si un administrateur définit la propriété
svn:auto-props
sur un chemin parent très
ascendant (par exemple à la racine du dépôt), il doit s'assurer
que tous les utilisateurs possèdent le droit de lecture sur ce
chemin ou la configuration automatique de propriété voulue ne
fonctionnera pas.
[18] Au moment de la rédaction de ce livre, les liens symboliques sont en fait les seuls objets « spéciaux » traités. Mais rien n'interdit qu'il y en ait d'autres dans des versions futures de Subversion.
[19] Ca vous semble dur ? Et bien, à la même période,
WordPerfect utilisait aussi .DOC
comme extension préférée de son format de fichier
propriétaire !
[20] Les systèmes de fichiers Windows utilisent les extensions
des fichiers (telles que
.EXE
, .BAT
et
.COM
) pour indiquer que les fichiers
sont exécutables.
[21] Les motifs de la
propriété svn:global-ignores
doivent être
séparés par des blancs (comme pour la directive
global-ignores
de la zone de configuration),
pas uniquement des fins de lignes (au contraire de la propriété
svn:ignore
).
[22] Naturellement, seuls les clients Subversion 1.8 ou plus
récents reconnaîtront l'héritage et la signification de la
propriété svn:global-ignores
!
[23] Bien que ce soit une affaire de goût, si vous ne
définissez pas explicitement de valeur pour la directive
global-ignores
dans la zone de configuration,
soit avec votre ensemble préféré de motifs, soit avec une
chaine vide, alors Subversion utilise une valeur par défaut.
Regardez l'entrée global-ignores
dans
la section intitulée « Configuration générale ».
[24] N'est-ce pas précisément la finalité d'un système de compilation ?
[25] Supposons que vous n'avez pas non plus de motif qui
corresponde dans la directive global-ignores
de la zone de configuration.
[26] …ou peut-être même un paragraphe d'un livre…
[27] En toute sécurité, bien sûr. Comme dans les autres situations, Subversion laissera sur le disque tous les fichiers que vous avez modifiés ou qui ne sont pas suivis en versions.
[28] À ce propos, un peu de communication n'aurait pas non plus été un mauvais remède pour leurs homonymes hollywoodiens.
[29] Pour l'instant, Subversion ne permet pas de poser de verrou sur un dossier.
[30] À part, peut-être, la fusion mentale vulcaine.
[31] Aucun achat nécessaire. Offre soumise à conditions. Aucune garantie de branchitude, ni explicite ni implicite, n'est fournie. Les performances passées ne préjugent pas des performances futures.
« 君子务本 (C'est sur le Tronc qu'un gentleman travaille). » | ||
--Confucius |
La création et la fusion de branches sont des concepts fondamentaux des systèmes de gestion de versions, simples à expliquer d'un point de vue conceptuel mais offrant suffisamment de complexité et de nuances pour mériter un chapitre dans ce livre. Nous allons introduire le concept général de ces opérations ainsi que l'approche, quelque peu unique, adoptée par Subversion. Ce chapitre suppose que vous êtes déjà familier avec les notions de bases de Subversion (expliquées dans le Chapitre 1, Notions fondamentales)
Supposons que votre travail soit de maintenir un document pour une division de votre entreprise, un manuel par exemple. Un beau jour, une autre division vous demande le même manuel, mais avec quelques parties « modifiées » spécialement pour elle, puisqu'elle fait les choses légèrement différemment.
Que faites-vous dans cette situation ? Tout naturellement, vous créez une seconde copie du document et commencez à maintenir les deux copies séparément. Puis, quand chaque division vous demande de faire des petites modifications, vous les incorporez dans une copie ou dans l'autre.
Vous voulez souvent faire la même modification dans les deux copies. Par exemple, si vous découvrez une coquille dans la première copie, il est très probable que la même coquille existe dans la deuxième copie. Les deux documents sont presque identiques, après tout ; ils ne diffèrent qu'en quelques points mineurs et spécifiques.
Voilà le concept de branche, c'est-à-dire une ligne de développement qui existe indépendamment d'une autre ligne, mais partage cependant une histoire commune avec elle, si vous remontez suffisamment loin en arrière dans le temps. Une branche commence toujours sa vie en tant que copie de quelque chose, puis diffère à partir de là, selon une histoire qui lui est propre (voir la Figure 4.1, « Branches de développement »).
Subversion possède des commandes pour vous aider à maintenir des branches parallèles de vos fichiers et répertoires. Il vous permet de créer des branches en faisant des copies de vos données et se souvient que les copies sont liées les unes aux autres. Il vous aide aussi à dupliquer les modifications d'une branche vers une autre. Enfin, il permet que des portions de votre copie de travail correspondent à différentes branches, afin que vous puissiez « mélanger » différentes lignes de développement dans votre travail quotidien.
Rendu à ce chapitre, vous devriez avoir compris que chaque propagation crée une arborescence de fichiers entièrement nouvelle (appelée « révision ») dans le dépôt. Si ce n'est pas le cas, retournez vous informer sur les révisions dans la section intitulée « Révisions ».
Pour ce chapitre, nous reprendrons le même exemple qu'au
Chapitre 1, Notions fondamentales. Souvenez-vous que votre
collaboratrice Sally et vous partagez un dépôt qui contient
deux projets, paint
et
calc
. Notez cependant que dans la
Figure 4.2, « Structure initiale du dépôt », le dossier de
chaque projet contient désormais des sous-dossiers nommés
trunk
et branches
.
Les raisons de cette arborescence apparaîtront bientôt
clairement.
Comme avant, supposons que Sally et vous avez tous deux une
copie de travail du projet « calc ». Plus
spécifiquement, vous avez chacun une copie de travail de
/calc/trunk
. Tous les fichiers du projet
sont dans ce sous-dossier plutôt que dans
/calc
lui-même, parce que votre équipe a
décidé que la « ligne principale » de développement
du projet allait se situer
dans /calc/trunk
.
Disons que l'on vous a attribué la tâche d'implémenter une
fonctionnalité du logiciel qui prendra longtemps à écrire et
touchera à tous les fichiers du projet. Le problème immédiat est
que vous ne voulez pas déranger Sally, qui est en train de
corriger des bogues mineurs ici et là. Elle a besoin que la
dernière version du projet
(dans /calc/trunk
) demeure en permanence
utilisable. Si vous commencez à propager des changements petit
à petit, vous allez sûrement rendre les choses difficiles pour
Sally (ainsi que pour d'autres membres de l'équipe).
Une stratégie possible est de vous isoler : vous pouvez
arrêter de partager des informations avec Sally pendant une
semaine ou deux. C'est-à-dire commencer à modifier et à
réorganiser les fichiers dans votre copie de travail, mais
sans effectuer de propagation ni de mise à jour avant que vous
n'ayez complètement terminé la tâche. Cette stratégie comporte
certains risques. Premièrement, ce n'est pas sans danger. La
plupart des gens aiment propager leurs modifications fréquemment,
au cas où leur copie de travail aurait un accident. Deuxièmement,
ce n'est pas très flexible. Si vous travaillez sur différents
ordinateurs (vous avez peut-être une copie de travail de
/calc/trunk
sur deux machines différentes),
vous aurez besoin de transférer manuellement vos changements entre
les deux, ou bien de travailler sur une seule machine. De la même
façon, il est difficile de partager vos changements en cours avec
quelqu'un d'autre. Une des « bonnes pratiques » du
monde du développement logiciel est de permettre à vos pairs de
passer votre travail en revue au fur et à mesure. Si personne n'a
accès à vos propagations intermédiaires, vous vous coupez
d'éventuelles critiques et risquez de partir dans une mauvaise
direction pendant des semaines avant que quelqu'un ne s'en
aperçoive. Enfin, quand vous en aurez fini avec tous vos
changements, vous pourriez avoir du mal à fusionner votre travail
avec le code du reste de l'équipe. Sally (et les autres) peuvent
avoir apporté de nombreux autres changements au dépôt, changements
qui seront difficiles à incorporer dans votre copie de travail,
notamment si vous lancez svn update après des
semaines d'isolation.
Une solution bien meilleure est de créer votre propre branche, ou ligne de développement, dans le dépôt. Ceci vous permettra de sauvegarder fréquemment votre travail un peu boiteux sans interférer avec vos collaborateurs ; vous pourrez toutefois partager une sélection d'informations avec eux. Vous découvrirez comment tout cela fonctionne exactement au fur et à mesure de ce chapitre.
Créer une branche est très simple : il s'agit juste de
faire une copie du projet dans le dépôt avec la commande
svn copy. Subversion est capable de copier
non seulement de simples fichiers, mais aussi des dossiers
entiers. Dans le cas présent, vous voulez faire une copie du
dossier /calc/trunk
. Où doit résider la
nouvelle copie ? Là où vous le désirez, cette décision
faisant partie de la gestion du projet. Enfin, votre branche se
doit de posséder un nom, pour la distinguer des autres branches.
Là encore, le nom que vous choisissez importe peu à Subversion
(vous pouvez utiliser le nom qui vous convient personnellement
ou à votre équipe).
Supposons que votre équipe (comme la plupart des équipes)
ait pour convention de créer les branches dans le répertoire
branches
qui se trouve au même niveau que
la branche principale de votre projet (le répertoire
/calc/branches
dans notre scénario). Comme
vous manquez d'inspiration, vous vous décidez pour
ma-branche-calc
come nom pour votre branche.
Cela veut dire que vous allez créer un nouveau dossier,
/calc/branches/ma-branche-calc
,
qui commence ainsi sa vie en tant que copie de
/calc/trunk
.
Vous avez peut-être déjà utilisé svn copy pour copier un fichier vers un autre à l'intérieur d'une copie de travail. Mais il peut aussi être utilisé pour effectuer une copie distante (une copie qui propage immédiatement une nouvelle révision dans le dépôt et pour laquelle aucune copie de travail n'est nécessaire). Il suffit juste de copier une URL vers une autre :
$ svn copy ^/calc/trunk ^/calc/branches/ma-branche-calc \ -m "Création d'une branche privée à partir de /calc/trunk." Révision 341 propagée. $
Cette commande entraîne une opération quasi-instantanée
dans le dépôt, créant un nouveau dossier à la révision 341.
Ce nouveau dossier est une copie de
/calc/trunk
, comme l'illustre la
Figure 4.3, « Dépôt avec nouvelle copie »
[32].
Bien qu'il soit aussi possible de créer une branche en
utilisant svn copy pour dupliquer un dossier
à l'intérieur de la copie de travail, cette technique n'est
pas recommandée. Elle peut s'avérer assez lente, en fait !
Copier un dossier côté client est une opération linéaire en
terme de durée, puisque chaque fichier et chaque dossier doit
être dupliqué sur le disque local. Copier un dossier sur le
serveur, par contre, est une opération dont la durée est
constante et c'est ainsi que la plupart des gens créent
des branches. En plus, cette façon de faire engendre le risque
de copier des copies de travail à révisions mélangées. Ce n'est
pas intrinsèquement dangereux, mais peut causer des
complications inutiles plus tard lors des fusions.
Maintenant que vous avez créé votre branche du projet, vous pouvez extraire une nouvelle copie de travail et commencer à l'utiliser :
$ svn checkout http://svn.exemple.com/depot/calc/branches/ma-branche-calc A ma-branche-calc/doc A ma-branche-calc/src A ma-branche-calc/doc/INSTALL A ma-branche-calc/src/reel.c A ma-branche-calc/src/main.c A ma-branche-calc/src/bouton.c A ma-branche-calc/src/entier.c A ma-branche-calc/Makefile A ma-branche-calc/LISEZMOI Révision 341 extraite. $
Cette copie de travail n'a rien de spéciale ; elle
correspond juste à un dossier différent du dépôt. Cependant,
quand vous propagerez vos modifications, Sally ne les verra
pas quand elle effectuera une mise à jour, car sa copie de
travail correspond à calc/trunk
(pensez
bien à lire la section intitulée « Parcours des branches » plus
loin dans ce chapitre : la commande
svn switch est une méthode alternative
pour créer une copie de travail d'une branche).
Imaginons qu'une semaine passe et que les propagations suivantes ont lieu :
Vous modifiez
/calc/branches/ma-branche-calc/src/bouton.c
,
ce qui crée la révision 342.
Vous modifiez
/calc/branches/ma-branche-calc/src/entier.c
,
ce qui crée la révision 343.
Sally modifie
/calc/trunk/src/entier.c
, ce qui crée
la révision 344.
À présent, deux lignes de développement indépendantes (voir
la Figure 4.4, « Historique des branches d'un fichier ») existent
pour entier.c
.
Les choses deviennent intéressantes quand on regarde
l'historique des modifications apportées à votre copie de
entier.c
:
$ pwd /home/utilisateur/ma-branche-calc $ svn log -v src/entier.c ------------------------------------------------------------------------ r343 | utilisateur | 2002-11-07 15:27:56 -0600 (jeu. 07 nov. 2002) | 2 lignes Chemins modifiés : M /calc/branches/ma-branche-calc/src/entier.c * entier.c: machiné le bidule. ------------------------------------------------------------------------ r341 | utilisateur | 2002-11-03 15:27:56 -0600 (jeu. 07 nov. 2002) | 2 lignes Chemins modifiés : A /calc/branches/ma-branche-calc (from /calc/trunk:340) Création d'une branche privée à partir de /calc/trunk. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (mar. 29 oct. 2002) | 2 lignes Chemins modifiés : M /calc/trunk/src/entier.c * entier.c: modifié une docstring. ------------------------------------------------------------------------ … ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (ven. 22 fev. 2002) | 2 lignes Chemins modifiés : A /calc/trunk/src/entier.c * entier.c: modifié l'API trucplusse. ------------------------------------------------------------------------ r8 | sally | 2002-01-17 16:55:36 -0500 (mar. 17 jan. 2002) | 1 ligne Changed paths: A /calc/trunk/Makefile A /calc/trunk/LISEZMOI A /calc/trunk/doc/INSTALL A /calc/trunk/src/bouton.c A /calc/trunk/src/entier.c A /calc/trunk/src/main.c A /calc/trunk/src/reel.c Import initial du code dans trunk pour le projet calc. ------------------------------------------------------------------------
Notez bien que Subversion reprend tout l'historique du
entier.c
de votre branche à travers le
temps, remontant même au delà du point où il a été copié. Il
liste la création d'une branche en tant qu'élément de
l'historique, parce qu'entier.c
a été
copié implicitement lorsque calc/trunk
tout entier a été copié. Maintenant regardez ce qui se passe
quand Sally lance la même commande sur sa copie du
fichier :
$ pwd /home/sally/calc $ svn log -v src/entier.c ------------------------------------------------------------------------ r344 | sally | 2002-11-07 15:27:56 -0600 (jeu. 07 nov. 2002) | 2 lignes Chemins modifiés : M /calc/trunk/src/entier.c * entier.c: réusinage des fonctions trucmuches. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (mar. 29 oct. 2002) | 2 lignes Chemins modifiés : M /calc/trunk/entier.c * entier.c: modifié une docstring. ------------------------------------------------------------------------ … ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (ven. 22 fev. 2002) | 2 lignes Chemins modifiés : A /calc/trunk/src/entier.c * entier.c: modifié l'API trucplusse. ------------------------------------------------------------------------ r8 | sally | 2002-01-17 16:55:36 -0500 (mar. 17 jan. 2002) | 1 ligne Changed paths: A /calc/trunk/Makefile A /calc/trunk/LISEZMOI A /calc/trunk/doc/INSTALL A /calc/trunk/src/bouton.c A /calc/trunk/src/entier.c A /calc/trunk/src/main.c A /calc/trunk/src/reel.c Import initial du code dans trunk pour le projet calc. ------------------------------------------------------------------------
Sally voit la modification due à sa propre révision 344, mais pas le changement que vous avez effectué dans la révision 343. Pour Subversion, ces deux propagations ont touché des fichiers différents dans des dossiers distincts. Néanmoins, Subversion indique bien que les deux fichiers partagent une histoire commune. Avant que la copie de branche n'ait été faite en révision 341, les fichiers ne faisaient qu'un. C'est pourquoi Sally et vous voyez tous les deux les modifications apportées entre les révisions 8 et 303.
Il y a deux leçons importantes à retenir de ce paragraphe. Premièrement, Subversion n'a pas de notion interne de branche — il sait seulement faire des copies. Quand vous copiez un dossier, le dossier qui en résulte n'est une « branche » que parce que vous le considérez comme tel. Vous aurez beau envisager ce dossier différemment ou le traiter différemment, pour Subversion c'est juste un dossier ordinaire auquel sont associées des informations extérieures relatives à son historique.
Deuxièmement, en raison de ce mécanisme de copie, les
branches de Subversion existent en tant que
dossiers classiques du système de fichiers
du dépôt. En cela, Subversion diffère des autres systèmes
de gestion de versions, où les branches sont définies par
l'ajout d'« étiquettes »
(labels en anglais)
extra-dimensionnelles à des groupes de fichiers. L'emplacement
du dossier de votre branche importe peu à Subversion. La plupart
des équipes ont pour convention de placer toutes les branches
dans un dossier /branches
, mais vous êtes
libre d'inventer la convention qui vous plaît.
Désormais, Sally et vous travaillez sur des branches parallèles du projet : vous travaillez sur une branche privée et Sally travaille sur le tronc (trunk en anglais), la branche de développement principale.
Pour les projets qui ont un grand nombre de contributeurs, il est d'usage que la plupart des gens ait des copies de travail du tronc. Dès que quelqu'un doit faire des modifications de longue haleine, susceptibles de perturber le tronc, une procédure standard est qu'il crée une branche privée et qu'il y propage les modifications jusqu'à ce que tout le travail soit terminé.
Bref, la bonne nouvelle est que Sally et vous n'empiétez pas l'un sur l'autre. La mauvaise nouvelle est qu'il est très facile de dériver chacun de son côté. Rappelez-vous qu'un des problèmes lié à la stratégie d'« isolement » est que lorsque vous en aurez fini avec votre branche, il risque d'être quasi impossible de refusionner vos modifications dans le tronc sans avoir à faire face à un grand nombre de conflits.
À la place, Sally et vous pourriez continuer de partager vos changements au fur et à mesure de votre travail. C'est à vous de décider quelles modifications valent la peine d'être partagées ; Subversion vous offre la possibilité de « copier » sélectivement des modifications entre les branches. Et quand vous aurez tout fini dans votre branche, l'ensemble de vos modifications pourra être recopié en entier vers le tronc. Dans la terminologie Subversion, l'action générale de réplication des modifications d'une branche vers une autre s'appelle la fusion et elle s'effectue à l'aide de plusieurs exécutions de la sous-commande svn merge.
Dans les exemples qui suivent, nous supposons que le client et le serveur Subversion sont tous deux en version 1.8 (ou plus récente). Si l'un ou l'autre sont en version plus ancienne que la 1.5, les choses sont plus compliquées : le système ne gére pas les changements de façon automatique et vous devrez utiliser des méthodes manuelles pénibles pour obtenir des résultats similaires. Vous devrez en effet toujours utiliser la syntaxe détaillée de la fusion spécifiant l'éventail des révisions à répliquer (voir la section intitulée « Syntaxe de la fusion : pour tout vous dire » plus loin dans ce chapitre) et penser à garder trace de ce qui a déjà été fusionné et de ce qui ne l'a pas encore été. Pour cette raison, nous recommandons fortement de vous assurer que client et serveur sont au moins en version 1.5.
Avant que nous n'allions plus loin, nous devons vous avertir que les pages suivantes contiennent de nombreuses discussions portant sur les « modifications ». Beaucoup de gens ayant de l'expérience dans les systèmes de gestion de versions utilisent le terme « modifications » et le terme « ensemble de modifications » de façon interchangeable et nous allons donc clarifier ce que Subversion entend par ensemble de modifications (changeset en anglais).
Chacun semble avoir sa propre définition, variant légèrement, d'un ensemble de modifications, ou tout du moins a une attente différente quant à leur traitement par le système de gestion de versions. En ce qui nous concerne, disons qu'un ensemble de modifications n'est qu'un simple regroupement de modifications identifié par un nom unique. Les modifications peuvent inclure des changements textuels du contenu des fichiers, des modifications de l'arborescence ou des ajustements portant sur les méta-données. En langage plus courant, un ensemble de modifications n'est qu'un correctif avec un nom auquel vous pouvez vous référer.
Dans Subversion, un numéro de révision globale
N
désigne une arborescence dans le
dépôt : c'est ce à quoi le dépôt ressemblait après la
N
-ième propagation. C'est aussi le
nom implicite d'un ensemble de modifications : si vous
comparez l'arborescence N
avec
l'arborescence N
-1, vous pouvez en
déduire exactement le correctif qui a été propagé. Pour cette
raison, il est facile de se représenter une révision
N
non seulement comme une
arborescence, mais aussi comme un ensemble de modifications. Si
vous utilisez un système de gestion des incidents pour gérer vos
bogues, vous pouvez utiliser les numéros de révision pour vous
référer à des correctifs particuliers permettant de résoudre des
bogues — par exemple, « cet incident a été corrigé
par r9238 ». Quelqu'un peut alors lancer svn
log -r 9238
pour obtenir le détail des modifications
qui ont corrigé le bogue et lancer svn diff -c
9238
pour voir le correctif lui-même. De plus (comme
nous le verrons bientôt), la commande svn
merge de Subversion est capable d'utiliser les numéros
de révision. Vous pouvez fusionner des listes de modifications
spécifiques d'une branche à une autre en les nommant dans les
paramètres de la fusion : donner comme argument
-c 9238
à svn merge
fusionne la liste de modifications r9238 avec votre copie de
travail.
Continuons avec notre exemple précédent et imaginons
qu'une semaine a passé depuis que vous avez commencé à
travailler sur votre branche privée. Votre nouvelle
fonctionnalité n'est pas encore terminée, mais en même temps
vous savez que d'autres personnes de votre équipe ont continué
à faire des modifications importantes sur l'arborescence
/trunk
du projet. Vous avez intérêt à
recopier ces modifications dans votre propre branche, juste
pour vous assurer qu'elles se combinent bien avec vos propres
modifications. Cette opération s'effectue par fusion
automatique de synchronisation (une opération de
fusion destinée à garder votre branche synchronisée avec les
modifications faites dans l'arborescence
« ancestrale » de création de ladite branche).
Une fusion automatique est simplement une fusion
pour laquelle vous ne fournissez que le minimum d'informations
requis (c'est-à-dire une seule source et une copie de travail
pour destination) et que vous laissez Subversion déterminer
quels modifications doivent être fusionnées — dans une
fusion automatique, aucun ensemble de modifications n'est passé
à la commande svn merge par l'option
-r
ou -c
.
Astuce | |
---|---|
En fait, c'est là une bonne pratique : synchroniser fréquemment votre branche avec la ligne de développement principale permet d'éviter les conflits « surprises » le jour où vous reversez vos modifications dans le tronc. |
Subversion connaît l'historique de votre branche et sait à quel moment elle s'est séparée du tronc. Afin de récupérer les modifications du tronc les plus récentes et les plus importantes, assurez-vous en premier lieu que votre copie de travail est « propre », c'est-à-dire que svn status ne liste aucune modification locale. Puis lancez juste :
$ pwd /home/user/ma-branche-calc $ svn merge ^/calc/trunk --- Fusion de r341 à r351 dans '.': --- Stockage des informations de fusion (mergeinfo) de r345 à r356 dans '.' : U bouton.c U entier.c $
La syntaxe de base, svn merge
, indique à Subversion
qu'il doit fusionner toutes les modifications récentes depuis
l'URL vers le répertoire de travail actuel (qui est bien souvent
la racine de votre copie de travail). Remarquez que nous
utilisons la syntaxe circonflexe
(URL
^
)[33] afin d'éviter
d'avoir à taper l'URL complète jusqu'au
trunk
. Remarquez également la notification
de Subversion « Recording mergeinfo for merge
… ». Ceci vous indique que la fusion met à jour la
propriété svn:mergeinfo
. Nous aborderons
cette propriété et les notifications plus loin dans ce chapitre,
dans
la section intitulée « Mergeinfo et aperçus ».
À la fin de cet exemple, votre copie de travail de la branche contient de nouvelles modifications locales qui correspondent à toutes les modifications qui ont eu lieu sur le tronc depuis la création de votre branche :
$ svn status M . M Makefile M doc/INSTALL M src/bouton.c M src/reel.c
Maintenant, le plus sage consiste à examiner attentivement
chaque modification avec svn diff, puis à
compiler et tester votre branche. Notez que le répertoire
de travail actuel (« .
») a
aussi été modifié.
La commande svn diff indique que sa propriété
svn:mergeinfo
a été créée.
$ svn diff --depth empty . Index: . =================================================================== --- . (révision 351) +++ . (copie de travail) Modification de propriétés sur . ___________________________________________________________________ Ajouté : svn:mergeinfo Fusionné /calc/trunk:r341-351
Cette nouvelle propriété contient d'importantes métadonnées relatives à la fusion que vous ne devez pas modifier, car elles sont nécessaires aux futures commandes svn merge (nous en apprendrons plus sur ces métadonnées plus loin dans ce chapitre).
Après cette fusion, vous êtes susceptible de devoir résoudre
quelques conflits (de même que lorsque vous effectuez une mise à
jour avec svn update) ou d'effectuer des
corrections à la main pour que les choses fonctionnent
correctement : rappelez-vous que l'absence de conflits
syntaxiques ne veut pas dire l'absence de
conflits sémantiques ! Si vous
rencontrez de sérieux problèmes, vous pouvez toujours abandonner
vos modifications locales en lançant la commande svn
revert . -R
et ouvrir une conversation qui promet
d'être longue avec vos collaborateurs sur le thème « c'est
quoi ce truc ? ». Mais si les choses se passent bien,
vous pouvez propager les modifications dans le
dépôt :
$ svn commit -m "Synchronisation des dernières modifications du tronc avec ma-branche-calc." Envoi . Envoi Makefile Envoi doc/INSTALL Envoi src/bouton.c Envoi src/reel.c Transmission des données . Révision 352 propagée.
À ce stade, votre branche privée est « en phase » avec le tronc et vous pouvez dormir tranquille car vous savez que vous pouvez continuer à travailler dans votre coin tout en ne dérivant pas trop par rapport au reste de l'équipe.
Supposons qu'une autre semaine s'est écoulée. Vous avez propagé des modifications supplémentaires dans votre branche et vos camarades ont également continué à améliorer le tronc. Une fois encore, vous aimeriez répercuter les dernières modifications du tronc vers votre branche et ainsi être en phase. Lancez juste la même commande svn merge à nouveau !
$ svn merge ^/calc/trunk svn: E195020: Cannot merge into mixed-revision working copy [352:357]; try updating first $
Ça par exemple, nous ne attendions pas à ça ! Après
avoir fait des modifications dans votre branche cette semaine,
vous vous retrouvez avec une copie de travail à révisions
mélangées (voir
la section intitulée « Copies de travail mixtes, à révisions mélangées »). Avec
Subversion 1.7 ou plus récent, la sous-commande svn
merge interdit par défaut les fusions dans les copies
de travail à révisions mélangées. Sans rentrer dans les détails,
cela résulte de la façon dont la trace des fusions est conservée
dans la propriété svn:mergeinfo
(lisez
la section intitulée « Mergeinfo et aperçus » pour
les détails). Des fusions dans les copies de travail à révisions
mélangées peuvent créer des conflits textuels ou
d'arborescence[34]. Nous ne voulons pas conflit
inutile, c'est pourquoi nous mettons à jour la copie de travail
et nous réessayons la fusion.
$ svn up Mise à jour de '.' : Actualisé à la révision 361. $ svn merge ^/calc/trunk --- Fusion de r352 à r361 dans '.': U src/reel.c U src/main.c -- Stockage des informations de fusion (mergeinfo) de r352 à r361 dans '.' : U .
Subversion sait quelles sont les modifications du tronc que vous avez déjà répercutées vers votre branche, il ne répercute donc que les modifications que vous n'avez pas encore. Une fois de plus, vous devrez compiler, tester et propager avec svn commit les modifications locales à votre branche.
Dans la plupart des exemples de ce chapitre, la cible de la fusion est le répertoire racine d'une branche (voir la section intitulée « Définition d'une branche »). Bien que ce soit une bonne pratique, vous aurez peut-être l'occasion de devoir fusionner avec un enfant de la racine de votre branche. Ce type de fusion est appelé une fusion de sous-arborescence et les informations de fusions (« mergeinfo ») stockées pour décrire cela s'appellent les informations de fusion de sous-arborescence ou mergeinfo de sous-arborecences. Il n'y a rien de particulier à signaler pour les fusions de sous-arborescences et les mergeinfo de sous-arborescences. En fait, il n'y a vraiment qu'un seul point à retenir pour ces concepts : l'enregistrement complet des fusions pour une branche peut ne pas être contenu uniquement dans le mergeinfo de la racine de la branche. Vous pouvez avoir à prendre en compte les mergeinfos des sous-arborescences pour obtenir le décompte total. Heureusement, Subversion le fait pour vous et vous n'aurez que rarement l'occasion de vous en préoccuper personnellement. Un court exemple vaut mieux qu'un long discours :
# We devons fusionner r958 depuis le tronc vers branches/proj-X/doc/INSTALL, # mais cette révision touche aussi main.c, que nous ne voulons pas fusionner : $ svn log --verbose --quiet -r 958 ^/ ------------------------------------------------------------------------ r958 | bruce | 2011-10-20 13:28:11 -0400 (jeu. 20 oct 2011) Chemins modifiés : M /trunk/doc/INSTALL M /trunk/src/main.c ------------------------------------------------------------------------ # Pas de problème, nous allons effectuer une fusion d'arborescence # directement sur le fichier INSTALL, mais d'abord notons les # informations de mergeinfo relatives à la racine de la branche : $ cd branches/proj-X $ svn propget svn:mergeinfo --recursive Propriétés sur '.' svn:mergeinfo /trunk:651-652 # Maintenant nous effectuons la fusion d'arborescence. # Remarquez que la source et la destination de la fusion pointent sur INSTALL : $ svn merge ^/trunk/doc/INSTALL doc/INSTALL -c 958 -- Fusion de r958 dans 'doc/INSTALL': U doc/INSTALL -- Stockage des informations de fusion (mergeinfo) de r958 dans 'doc/INSTALL' : G doc/INSTALL # Une fois la fusion effectuée, l'information de fusion de l'arboresence # est disponible dans INSTALL : $ svn propget svn:mergeinfo --recursive Propriétés sur '.' : svn:mergeinfo /trunk:651-652 Propriétés sur 'doc/INSTALL' : svn:mergeinfo /trunk/doc/INSTALL:651-652,958 # Que se passe-t-il si nous décidons maintenant d'avoir l'intégralité de # r958 ? Facile, nous avons seulement à répéter l'opération de fusion # de cette révision, mais cette fois à la racine de la branche. # Subversion prend en compte les informations de fusion sur INSTALL et # n'essaie pas de fusionner quoi ce soit sur ce fichier ; seuls les # changements sur main.c sont fusionnés. $ svn merge ^/subversion/trunk . -c 958 -- Fusion de r958 dans '.': U src/main.c -- Stockage des informations de fusion (mergeinfo) de r958 dans '.' : U . -- Nettoyage des informations de fusion (mergeinfo) de 'doc/INSTALL' : U doc/INSTALL
Vous devez vous demander pourquoi
INSTALL
dans l'exemple ci-dessus possède
des informations de fusion pour r651-652 alors que nous
n'avons fusionné que r958. C'est en raison de l'héritage des
informations de fusion, que nous abordons dans l'encart particulier
Héritages des informations de fusion. Notez aussi que les informations de fusion de
l'arborescence ont été supprimées (ou « nettoyées »)
de doc/INSTALL
. Ce
nettoyage des informations de fusion a
lieu quand Subversion détecte des informations
redondantes.
Astuce | |
---|---|
Avant Subversion 1.7, les fusions mettaient à jour de manière inconditionnelle les informations de fusion sous la destination pour décrire la fusion. Pour les utilisateurs qui ont beaucoup d'informations de fusion sur leurs arborescences, cela voulait dire que même des fusions relativement « simles » (par exemple une fusion qui ne concerne qu'un seul fichier) impliquaient des modifications de mergeinfo dans toutes les sous-arborescences, y compris celles qui n'avaient pas de lien de parenté avec le(s) chemin(s) concerné(s). Cela engendrait de la confusion et de la frustration. Subversion 1.7 et suivants répondent à ce problème en ne mettant à jour que les informations de fusion des arborescences qui ont des liens de parenté avec les chemins modifiés par la fusion (c'est-à-dire les chemins modifiés, ajoutés ou supprimés par application d'un changement, voir la section intitulée « Syntaxe de la fusion : pour tout vous dire »). La cible de la fusion fait exception à ce comportement ; les informations de fusion de la cible de fusion sont toujours mises à jour décrire la fusion, même si l'application de la fusion ne produit aucun changement. |
Que se passe-t-il quand vous finissez enfin votre travail ? Votre nouvelle fonctionnalité est terminée et vous êtes prêt à fusionner les changements de votre branche avec le tronc (pour que votre équipe puisse bénéficier du fruit de votre travail). La procédure est simple. Premièrement, synchronisez à nouveau votre branche avec le tronc, comme vous le faites depuis le début [35]
$ svn up # (pour être sûr que la copie de travail est à jour) Mise à jour de '.' : À la révision 378. $ svn merge ^/calc/trunk --- Fusion de r362 à r378 dans '.': U src/main.c --- Stockage des informations de fusion (mergeinfo) de r381 à r385 dans '.' : U . $ # compiler, tester, ... $ svn commit -m "Fusion finale des modifications du tronc dans ma-branche-calc." Envoi . Envoi src/main.c Transmission des données . Révision 379 propagée.
À présent, utilisez la sous-commande
svn merge pour répercuter automatiquement les
modifications de votre branche sur le tronc. Ce type de fusion
est appelée
une fusion de « réintégration
automatique ». Vous aurez besoin d'une copie de travail de
/calc/trunk
. Vous pouvez vous la procurer
soit en effectuant un svn checkout, soit en
reprenant une vieille copie de travail du tronc, soit en
utilisant svn switch (voir
la section intitulée « Parcours des branches »).
Astuce | |
---|---|
Le terme « réintégration » provient de l'option
|
Votre copie de travail du tronc ne doit avoir aucune modification locale, aucun chemin qui ne pointe vers une autre branche et ne pas comporter de mélange de révisions (voir la section intitulée « Copies de travail mixtes, à révisions mélangées »). Bien que ce soient de bonnes pratiques pour les fusions de toute façon, c'est particulièrement obligatoire pour une fusion de réintégration automatique.
Une fois que vous avez une copie de travail propre du tronc, vous êtes prêt pour y fusionner votre branche :
$ pwd /home/utilisateur/calc-trunk $ svn update Mise à jour '.' : À la révision 390. $ svn merge ^/calc/branches/ma-branche-calc --- Fusion des différences des URLs du dépôt vers '.' : U src/reel.c U src/main.c U Makefile -- Stockage des informations de fusion (mergeinfo) des URLs du dépôt vers '.' : U . $ # compiler, tester, vérifier, ... $ svn commit -m "ma-branche-calc réintégrée dans le tronc !" Envoi . Envoi Makefile Envoi src/main.c Envoi src/reel.c Transmission des données ... Révision 380 propagée.
Félicitations, votre branche a maintenant réintégré la
ligne de développement principale. Notez que la fusion de
réintégration automatique a effectué un travail différent de ce
que vous avez fait jusqu'à maintenant. Auparavant, nous
demandions à svn merge de récupérer le
« prochain lot de modifications » d'une ligne de
développement (le tronc en l'occurence) et de l'appliquer à une
autre (votre branche). C'est assez simple à réaliser et à chaque
fois Subversion sait reprendre là où il s'était arrêté. Dans
nos exemples précédents, vous pouvez constater qu'il fusionne en
premier les modifications 341:351 de
/calc/trunk
vers
/calc/branches/ma-branche-calc
;
ensuite il continue en fusionnant l'intervalle
immédiatement suivant, 351:361. Quand il effectue la
synchronisation finale, il fusionne l'intervalle 361:378.
Cependant, quand il fusionne
/calc/branches/ma-branche-calc
vers /calc/trunk
, la logique sous-jacente
est assez différente. Votre branche dédiée est à présent un
amoncellement de modifications provenant à la fois du tronc
et de votre branche privée et il n'y a donc pas d'intervalle
de révisions contigues à recopier. En utilisant la fusion
automatique, vous demandez à Subversion de ne recopier
que les modifications spécifiques à votre
branche (et en fait il le fait en comparant la version la plus
récente de l'arborescence du tronc avec la version la plus
récente de l'arborescence de la branche :
la différence qui en résulte constitue exactement les
modifications de votre branche !).
Gardez à l'esprit que les fusions de réintégration
automatiques ne fonctionnent que dans le cas cité ci-dessus. En
raison de cette configuration particulière et des autres
prérequis annoncés précédemment (une copie de travail à
jour[36] sans révisions
mélangées, sans chemins qui pointent vers d'autres branches ou
modifications locales), elles ne fonctionneront pas en
combinaison avec la plupart des autres options de la
sous-commande svn merge. Vous obtiendrez une
erreur si vous utilisez n'importe laquelle des options
non-globales autres que celles-ci :
--accept
, --dry-run
,
--diff3-cmd
, --extensions
ou --quiet
.
Maintenant que votre branche privée a réintégré le tronc, vous voudrez peut-être la supprimer du dépôt :
$ svn delete ^/calc/branches/ma-branche-calc \ -m "Supprime ma-branche-calc, réintégrée dans le tronc à r391." …
Mais attendez ! L'historique de votre branche ne
possède-t-il pas une certaine valeur ? Et si un beau
jour quelqu'un voulait auditer l'évolution de votre
fonctionnalité et examiner toutes les modifications de
votre branche ? Pas la peine de s'inquiéter.
Souvenez-vous que, même si votre branche n'est plus visible
dans le dossier /calc/branches
, son
existence demeure une partie immuable de l'historique du dépôt.
Une simple commande svn log appliquée à l'URL
/calc/branches
vous renverra l'historique
complet de votre branche. Votre branche pourrait même
ressusciter un jour ou l'autre, si vous le désirez (voir
la section intitulée « Résurrection des éléments effacés »).
Si vous décidez de ne pas détruire votre branche après réintégration dans le tronc, vous pouvez continuer à effectuer des fusions de synchronisation depuis le tronc puis réintégrer la branche à nouveau [37]. Si vous adoptez ce comportement, seules les modifications effectuées sur votre branche après la réintégration seront fusionnées vers le tronc.
Le mécanisme de base que Subversion utilise pour gérer
les ensembles de modifications, c'est-à-dire quelles
modifications ont été fusionnées dans quelles branches, est
l'enregistrement de données dans des propriétés suivies en
versions. Plus précisément, les informations de fusion sont
conservées dans la propriété svn:mergeinfo
qui est associée aux fichiers et aux dossiers (si les propriétés
de Subversion ne vous sont pas familières, c'est le moment de
lire la section intitulée « Propriétés »).
Vous pouvez examiner cette propriété comme n'importe quelle autre propriété suivie en versions :
$ cd ma-branche-calc $ svn pg svn:mergeinfo -v Propriétés sur '.' svn:mergeinfo /calc/trunk:341-378
Avertissement | |
---|---|
Bien qu'il soit possible de modifier soi-même
|
Astuce | |
---|---|
La quantité de |
La propriété svn:mergeinfo
est manipulée
automatiquement par Subversion à chaque fois que vous lancez
svn merge. Sa valeur indique quelles
modifications (pour un chemin donné) ont été recopiées dans
le dossier en question. Dans le cas présent, le chemin d'origine
de la fusion des modifications est
/calc/trunk
et le dossier qui a reçu les
modifications spécifiées est
/calc/branches/ma-branche-calc
. Les
vieilles versions de Subversion tenaient à jour la propriété
svn:mergeinfo
silencieusement. Vous en
détectiez quand même les modifications, après une fusion, lors
de l'utilisation des sous-commandes svn diff
ou svn status, mais la fusion en elle-même
n'indiquait rien de la modification de la propriété
svn:mergeinfo
. Dans les versions 1.7 et
ultérieures de Subversion, ce n'est plus le cas puisque
plusieurs notifications vous avertissent de la mise à jour de
la propriété svn:mergeinfo
par une opération
de fusion. Ces notifications commencent toutes par
« --- Stockage des informations de fusion
(mergeinfo) » et sont indiquées à la fin de l'opération
de fusion. Contrairement aux autres notifications de la fusion,
elles ne décrivent pas les modifications apportées à la copie
de travail (voir
la section intitulée « Syntaxe de la fusion : pour tout vous dire »),
mais plutôt la conservation des modifications effectuées
pour garder la trace de ce qui a été fusionné.
Il existe également une sous-commande,
svn mergeinfo, qui peut être utile pour
voir les relations de fusions entre deux branches ;
particulièrement, quels ensembles de modifications un
dossier a absorbés, mais aussi quels ensembles de modifications
il est encore susceptible de recevoir. Ceci donne une sorte
d'aperçu du prochain ensemble de modifications que
svn merge recopiera vers
votre branche. Par défaut, svn mergeinfo
donne un aperçu graphique de la relation entre les branches.
Pour en revenir à notre exemple précédent, nous utilisons la
sous-commande pour analyser la relation entre
/calc/trunk
et
/calc/branches/ma-branche-calc
:
$ cd ma-branche-calc $svn mergeinfo ^/calc/trunk youngest common ancestor | last full merge | | tip of branch | | | repository path 340 382 | | -------| |------------ calc/trunk \ / \ / --| |------------ calc/branches/ma-branche-calc | | 379 382
Le diagramme indique que
/calc/branches/ma-branche-calc
a été copié
à partir de /calc/trunk@340
et que la
fusion automatique la plus récente était la fusion de
réintégration que nous avons faite depuis la branche vers le
tronc à r380. Notez que le diagramme n'indique
pas les quatre fusions de synchronisation que nous
avons effectuées aux révisions 352, 362, 372 et 379. Seule la
fusion automatique la plus récente est indiquée, quelle que soit
sa direction [38]. Cet affichage
par défaut est utile pour obtenir un aperçu des fusions entre
deux branches, mais pour voir les révisions spécifiques qui ont
fait l'objet d'une fusion, nous utilisons l'option
--show-revs=merged
:
$ svn mergeinfo ^/calc/trunk --show-revs merged r344 r345 r346 … r366 r367 r368
De la même manière, pour voir quelles modifications sont
éligibles pour une fusion depuis le tronc vers la branche, nous
pouvons utiliser l'option
--show-revs=eligible
:
$ svn mergeinfo ^/calc/trunk --show-revs eligible r380 r381 r382
La sous-commande svn mergeinfo requiert
une URL « source » (d'où proviennent les
modifications) et prend optionnellement une URL
« cible » (où les modifications sont fusionnées). Si
aucune URL cible n'est fournie, Subversion suppose que le
répertoire courant est la cible. Dans l'exemple précédent, comme
nous interrogeons notre copie de travail de la branche, la
commande suppose que nous nous intéressons aux modifications
que nous souhaitons apporter à
/calc/branches/ma-branche-calc
depuis l'URL
du tronc telle que spécifiée.
Depuis Subversion 1.7, la sous-commande svn
mergeinfo peut également traiter les informations de
fusion de la sous-arborescence et les informations de fusion non
héritables. Elle traite les informations de fusion de
sous-arborescence avec les options --recursive
ou --depth
, et les informations de fusion non
héritables sont traitées par défaut.
Considérons que nous avons une branche avec à la fois une sous-arborescence et des informations de fusion non héritables :
$ svn pg svn:mergeinfo -vR # informations de fusion non héritables Propriétés sur '.' svn:mergeinfo /calc/trunk:354,385-388* # sous-arborescence d'informations de fusion Propriétés sur 'doc/INSTALL' svn:mergeinfo /calc/trunk/Makefile:354,380
Dans les informations de fusion ci-dessus, nous voyons que
r385-388 a été fusionnée seulement à la racine de la branche
et dans aucun des enfants de la racine. Nous voyons aussi que
r380 a été fusionnée seulement dans
Makefile
. Quand nous utilisons
svn mergeinfo avec l'option
--recursive
pour voir ce qui a été fusionné
depuis /calc/trunk
vers cette branche, nous
voyons trois révisions qui sont marquées avec
*
:
$ svn mergeinfo -R --show-revs=merged ^/calc/trunk . r354 r380* r385 r386 r387* r388*
Cette marque *
indique des révisions qui
ont fait l'objet de fusions partielles vers
la cible en question (la signification est la même que lorsque
nous cherchons des révisions éligibles). Dans cet exemple, cela
signifie que si nous essayons de fusionner r380, r387 ou r388
depuis ^/trunk
alors des modifications
seront apportées. De la même manière, puisque r354, r385 et r386
ne sont pas marquées avec
*
, nous savons que fusionner à nouveau ces
révisions ne produira aucun changement.[39]
Une autre manière d'obtenir un aperçu plus précis d'une
opération de fusion est d'utiliser l'option
--dry-run
:
$ svn merge ^/paint/trunk ma-branche-peinture --dry-run --- Fusion de r290 à r383 dans 'ma-branche-peinture': U ma-branche-peinture/src/palettes.c U ma-branche-peinture/src/brosses.c U ma-branche-peinture/Makefile $ svn status # rien ne s'affiche, la copie de travail n'a pas changé.
L'option --dry-run
n'effectue en fait
pas de modification locale sur la copie de travail. Elle ne
fait qu'indiquer les codes d'état qui
seraient affichés par une vraie fusion.
Ceci permet d'obtenir un « aperçu général »
d'une fusion potentielle, pour les fois où
svn diff renvoie trop de détails.
Astuce | |
---|---|
Après avoir effectué une opération de fusion, mais avant
d'en avoir propagé les résultats, vous pouvez utiliser
|
Bien sûr, la meilleure façon d'avoir un aperçu d'une
opération de fusion est tout simplement de la réaliser !
Souvenez-vous que lancer svn merge n'est
pas une opération risquée en soi (à moins que vous ayez
effectué des modifications locales dans votre copie de
travail, mais nous avons déjà souligné que vous ne devriez
pas faire de fusion dans de telles circonstances). Si les
résultats de la fusion ne vous plaisent pas, lancez juste
svn revert . -R
pour ôter les
modifications de votre copie de travail et réessayez la
commande avec des options différentes. La fusion n'est
définitive qu'une fois que vous en avez propagé
les résultats par svn commit.
Un usage très répandu de svn merge
est le retour en arrière sur une modification qui a déjà
été propagée. Supposons que vous travaillez tranquillement
sur une copie de travail de /calc/trunk
et que vous découvrez tout à coup que la modification faite
il y a longtemps lors de la révision 392, qui affectait
plusieurs fichier sources, est complètement incorrecte.
Elle n'aurait jamais du être propagée. Vous pouvez utiliser
svn merge pour « revenir en
arrière » sur ces modifications dans votre copie de
travail, puis propager les modifications locales au dépôt. Il
vous suffit juste de spécifier une différence
inversée (en indiquant soit
--revision 392:391
, soit
--change -392
, les deux se valent).
$ svn merge ^/calc/trunk . -c-392 -- Fusion inverse de r392 dans '.' : U src/reel.c U src/main.c U src/bouton.c U src/entier.c -- Stockage des informations de fusion (mergeinfo) inverse de r392 vers '.' : U . $ svn st M src/bouton.c M src/entier.c M src/main.c M src/reel.c $ svn diff … # vérifions que les modifications ont été annulées … $ svn commit -m "Retour en arrière sur les modifications propagées en r392." Envoi src/bouton.c Envoi src/entier.c Envoi src/main.c Envoi src/reel.c Envoi entier.c Transmission des données .... Révision 399 propagée.
Comme nous l'avons signalé précédemment, une façon de se
représenter une révision du dépôt est de la considérer comme
un ensemble de modifications spécifique. En utilisant l'option
-r
, vous pouvez demander à
svn merge d'appliquer un ensemble de
modifications, ou tout un groupe d'ensembles de modifications,
à votre copie de travail. Dans le cas présent, pour revenir
en arrière, nous demandons à svn merge
d'appliquer dans le sens inverse
l'ensemble de modifications r392 à notre copie de
travail.
Gardez à l'esprit que revenir en arrière sur une
modification de cette façon est similaire à toute autre
opération svn merge, vous devez donc ensuite
utiliser svn status et svn
diff pour vous assurer que votre travail est dans
l'état que vous voulez, puis utiliser svn
commit pour propager la version finale au dépôt. Après
la propagation, cet ensemble de modifications particulier n'est
plus présent dans la révision HEAD
.
À nouveau vous vous dites : bon, ceci n'a pas vraiment annulé la propagation, n'est-ce pas ? La modification existe toujours en révision 392. Si quelqu'un extrait une version du projet calc entre les révisions 392 et 398, il verra toujours la mauvaise modification, non ?
Oui, c'est vrai. Quand nous parlons de
« supprimer » une modification, il s'agit de la
supprimer de la révision HEAD
. La
modification originale existe toujours dans l'historique du
dépôt. Dans la plupart des situations, c'est suffisant. La
plupart des gens ne s'intéressent d'ailleurs qu'à la révision
HEAD
du projet. Il y a des cas particuliers,
cependant, où l'on voudra vraiment détruire toute preuve de
la propagation (quelqu'un a peut-être accidentellement propagé
un document confidentiel). Cela ne s'avère pas si facile, parce
que Subversion a été conçu délibérément pour ne jamais perdre
d'information. Les révisions sont des arborescences immuables
qui sont empilées les unes par dessus les autres. Supprimer
une révision de l'historique créerait un effet domino,
engendrant le chaos dans les révisions ultérieures et
invalidant potentiellement toutes les copies de
travail [40].
Ce qu'il y a de formidable dans les systèmes de gestion
de versions, c'est que les informations ne sont jamais
perdues. Même si vous effacez un fichier ou un dossier, s'il
disparaît bien de la révision HEAD
, l'objet
existe toujours dans les révisions précédentes. Une des
questions les plus courantes que posent les nouveaux
utilisateurs est : « Comment est-ce que je récupère
mon ancien fichier ou dossier ? »
La première étape est de définir exactement quel élément vous essayez de ressusciter. Voici une métaphore utile : vous pouvez imaginer votre objet dans le dépôt comme existant dans une sorte de système à deux dimensions. La première coordonnée est une révision correspondant à une arborescence particulière ; la deuxième coordonnée est un chemin à l'intérieur de cette arborescence. Ainsi, toute version d'un fichier ou d'un dossier peut être définie par une paire de coordonnées qui lui est propre (souvenez-vous de la syntaxe des « révisions pivots » : machin.c@224, mentionnée dans la section intitulée « Révisions pivots et révisions opérationnelles »).
Tout d'abord, vous allez peut-être avoir besoin de
svn log pour identifier précisément les
coordonnées du fichier ou dossier que vous voulez ressusciter.
À cette fin, une bonne stratégie est de lancer
svn log --verbose
dans un dossier qui
contenait votre élément effacé. L'option
--verbose
(-v
) renvoie la
liste de tous les éléments modifiés par chaque révision ;
il vous suffit alors de trouver la révision dans laquelle
vous avez effacé le fichier ou le dossier en question.
Vous pouvez accomplir cette recherche soit visuellement
soit en utilisant un autre outil pour examiner
le résultat de la commande svn log
(via grep ou
peut-être via une recherche
incrémentale dans un éditeur). Si vous savez que l'élément en
question a été effacé recemment, vous pouvez utiliser l'option
--limit
pour conserver un affichage de
l'historique suffisamment bref afin d'être exploité
manuellement.
$ cd calc/trunk $ svn log -v --limit 3 ------------------------------------------------------------------------ r401 | sally | 2013-02-18 23:15:44 -0500 (mar. 19 fév. 2013) | 1 ligne Chemins modifiés : M /calc/trunk/src/main.c Suite à r400 : corrections de coquilles dans le texte d'aide. ------------------------------------------------------------------------ r400 | bill | 2013-02-19 20:55:08 -0500 (mar. 19 fév. 2013) | 4 lignes Chemins modifiés : M /calc/trunk/src/main.c D /calc/trunk/src/reel.c * calc/trunk/src/main.c: mise à jour du texte d'aide. * calc/trunk/src/reel.c: fichier supprimé, aucune API de ce fichier n'est encore utilisée. ------------------------------------------------------------------------ r399 | sally | 2013-02-19 20:05:14 -0500 (mar. 19 fév. 2013) | 1 ligne Chemins modifiés : M /calc/trunk/src/bouton.c M /calc/trunk/src/entier.c M /calc/trunk/src/main.c M /calc/trunk/src/reel.c Retour en arrière sur les modifications propagées en r392. ------------------------------------------------------------------------
Dans l'exemple ci-dessus, nous supposons que vous
recherchez un fichier effacé nommé reel.c
.
En examinant le journal du dossier parent, vous avez découvert
que ce fichier a été effacé en révision 400. La dernière
version du fichier à avoir existé était donc dans la révision
précédant celle-ci. Conclusion : vous voulez ressusciter
le chemin /calc/trunk/reel.c
tel qu'il
était en révision 399.
Voilà, c'était la partie difficile : la recherche. Maintenant que vous savez ce que vous voulez récupérer, deux options s'offrent à vous.
Une possibilité serait d'utiliser
svn merge pour appliquer la révision 400
« à l'envers » (nous avons déjà parlé de comment
revenir sur des modifications dans la section intitulée « Retour en arrière sur des modifications »). Ceci aurait
pour effet de ré-ajouter reel.c
en tant
que modification locale. Le fichier serait alors programmé
pour être ajouté et après la propagation le fichier existerait
à nouveau dans HEAD
.
Cependant, dans cet exemple particulier, ce n'est
probablement pas la meilleure stratégie. Appliquer la
révision 400 à l'envers programmerait non seulement l'ajout
de reel.c
, mais le commentaire de propagation
indique qu'il reviendrait aussi sur certaines modifications
de main.c
, ce que vous ne voulez pas.
Vous pourriez certainement fusionner à l'envers la révision
808 et ensuite revenir sur les modifications locales faites
dans main.c
, mais cette technique
fonctionne mal à plus grande échelle. Que dire si 90 fichiers
avaient été modifiés en révision 400 ?
Une seconde stratégie, plus ciblée, est de ne pas utiliser svn merge du tout, mais plutôt d'utiliser la commande svn copy. Copiez juste la révision et le chemin exacts (vos deux « coordonnées ») du dépôt vers votre copie de travail :
$ svn copy ^/calc/trunk/src/reel.c@399 ./reel.c A reel.c $ svn st A + reel.c # Propager la résurrection …
Le symbole plus dans le résultat de la commande
svn status indique que l'élément n'est
pas simplement programmé pour ajout, mais programmé pour ajout
« avec son historique ». Subversion se souviendra
d'où il a été copié. Dans le futur, lancer
svn log sur ce fichier parcourra tout son
historique en passant par la résurrection du fichier ainsi que
tout ce qui précédait la révision 399. En d'autres termes,
ce nouveau reel.c
n'est pas vraiment
nouveau ; c'est un descendant direct du fichier original
qui avait été effacé. En général c'est une bonne chose, dont
l'utilité est avérée. Si cependant vous vouliez récupérer
le fichier sans conserver de lien
historique avec l'ancien fichier, la technique suivante
fonctionnerait tout aussi bien :
$ svn cat ^/calc/trunk/reel.c@399 > ./reel.c $ svn add reel.c A reel.c # Propager la résurrection …
Bien que notre exemple ne porte que sur la résurrection d'un fichier, remarquez que ces mêmes techniques fonctionnent tout aussi bien pour ressusciter des dossiers effacés. Remarquez aussi que cette résurrection ne doit pas forcément avoir lieu dans votre copie de travail ; elle peut avoir lieu entièrement dans le dépôt :
$ svn copy ^/calc/trunk/src/reel.c@399 ^/calc/trunk/src/reel.c \ -m "Ressuscite reel.c depuis la révision 399." Révision 402 propagée. $ svn up Mise à jour de '.' : A reel.c À la révision 402.
Ici finit la magie automatisée. Tôt ou tard, une fois que vous maîtrisez bien la gestion des branches et les fusions, vous allez vous retrouver à demander à Subversion de fusionner des modifications spécifiques d'un endroit à un autre. Pour faire cela, vous allez devoir commencer à passer des paramètres plus compliqués à svn merge. Le paragraphe suivant décrit la syntaxe complète de la commande et aborde un certain nombre de scénarios d'utilisation courants qui exploitent la commande.
De la même façon que le terme « ensemble de modifications » est utilisé couramment dans les systèmes de gestion de versions, le terme « sélectionner à la main » l'est aussi. Il désigne l'action de choisir une liste de modifications particulière au sein d'une branche et de la recopier dans une autre. Sélectionner à la main peut aussi faire référence à l'action de dupliquer un ensemble de modifications (pas nécessairement contiguës !) d'une branche vers une autre. Ceci est en opposition avec des scénarios de fusion plus courants, où l'ensemble de révisions contiguës « suivant » est dupliqué automatiquement.
Pourquoi voudrait-on ne recopier qu'une modification
unique ? Cela arrive plus souvent qu'on ne croit. Par
exemple, imaginons que vous ayez créé une branche pour une
nouvelle fonctionnalité
/calc/branches/ma-branche-nouvelle-calc
copiée à
partir de /calc/trunk
:
$ svn log ^/calc/branches/ma-branche-nouvelle-calc -v -r403 ------------------------------------------------------------------------ r403 | user | 2013-02-20 03:26:12 -0500 (mer. 20 fév. 2013) | 1 ligne Chemins modifiés : A /calc/branches/ma-branche-nouvelle-calc (de /calc/trunk:402) Création d'une nouvelle branche calc pour la fonctionnalité 'X'. ------------------------------------------------------------------------
À la machine à café, vous apprenez par hasard que Sally a
apporté une modification intéressante à
main.c
dans le tronc. Vous reportant à
l'historique des propagations du tronc, vous vous apercevez
qu'elle a corrigé un bogue crucial en révision 413, qui
impacte directement la fonctionnalité sur laquelle vous êtes
en train de travailler. Vous n'êtes peut-être pas encore prêt
à fusionner toutes les modifications du tronc dans votre
branche, mais vous avez certainement besoin de ce correctif
pour continuer votre travail.
$ svn log ^/calc/trunk -r413 -v ------------------------------------------------------------------------ r413 | sally | 2013-02-21 01:57:51 -0500 (jeu. 21 fév. 2013) | 3 lignes Chemins modifiés : M /calc/trunk/src/main.c Corrige le problème #22 'Passer une valeur null dans l'argument truc de machin() devrait être toléré, mais cela produit un plantage'. ------------------------------------------------------------------------ $ svn diff ^/calc/trunk -c413 Index: src/main.c =================================================================== --- src/main.c (revision 412) +++ src/main.c (revision 413) @@ -34,6 +34,7 @@ … Détails de la correction …
De la même façon que vous avez utilisé svn diff dans l'exemple précédent pour examiner la révision 413, vous pouvez passer le même paramètre à svn merge :
$ cd ma-branche-nouvelle-calc $ svn merge ^/calc/trunk -c413 --- Fusion de r413 dans '.': U src/main.c -- Stockage des informations de fusion (mergeinfo) de r413 dans '.' : U . $ svn st M . M src/main.c
Vous pouvez à présent lancer les procédures habituelles
de tests, avant de propager cette modification à votre branche.
Après la propagation, Subversion met à jour la propriété
svn:mergeinfo
de votre branche pour indiquer
que r413 a été fusionnée dans la branche. Cela empêche qu'une
future fusion automatique de synchronisation ne tente
d'appliquer une nouvelle fois r413 (fusionner une même
modification dans une même branche aboutit presque toujours
à un conflit !). Notez aussi les informations de fusion
/calc/branches/my-calc-branch:341-379
. Cela
a été enregistré lors de la précédente fusion de réintégration
vers /calc/trunk
depuis la branche
/calc/branches/ma-branche-calc
que nous
avons effectué en r380. Quand nous avons créé la branche
ma-branche-nouvelle-calc
en r403, les
informations de fusion sont venues avec le reste de la
copie.
$ svn pg svn:mergeinfo -v Propriétés sur '.' : svn:mergeinfo /calc/branches/ma-branche-calc:341-379 /calc/trunk:413
Vous pouvez remarquer que mergeinfo ne marque pas r413 comme « éligible » pour une fusion puisqu'elle a été déjà fusionnée :
$ svn mergeinfo ^/calc/trunk --show-revs eligible r404 r405 r406 r407 r409 r410 r411 r412 r414 r415 r416 … r455 r456 r457
Ce qui précède signifie que, quand le temps sera venu de
faire une fusion de synchronisation automatique, Subversion
séparera la fusion en deux parties : d'abord il fusionnera
toutes les révisions éligibles jusqu'à r412, puis il fusionnera
toutes les révisions éligibles depuis r414 jusqu'à la révision
HEAD
. Comme nous avons déjà sélectionné à la
main r413, cette modification est sautée :
$ svn merge ^/calc/trunk --- Fusion de r403 à r412 dans '.': U doc/INSTALL U src/main.c U src/bouton.c U src/entier.c U Makefile U LISEZMOI --- Fusion de r414 à r458 dans '.': G doc/INSTALL G src/main.c G src/entier.c G Makefile --- Stockage des informations de fusion (mergeinfo) de r403 à r458 dans '.' : U .
Ce type d'utilisation de la copie (ou rétroportage) de correctifs d'une branche à une autre est peut-être la raison la plus répandue pour sélectionner à la main des modifications ; le cas se présente très souvent, par exemple lorsqu'une équipe gère une « branche de production » du logiciel (ce thème est développé dans la section intitulée « Branches de publication »).
Avertissement | |
---|---|
Avez-vous remarqué la façon dont, dans le dernier exemple, le lancement de la fusion a eu pour effet l'application de deux ensembles distincts de fusions ? La commande svn merge a appliqué deux correctifs indépendants à votre copie de travail, afin de sauter l'ensemble de modifications 413, que votre branche contenait déjà. Il n'y a rien de mal en soi là-dedans, sauf que ça risque de rendre plus délicate la résolution des conflits. Si le premier groupe de modifications engendre des conflits, vous devrez les résoudre de façon interactive pour que la procédure de fusion puisse continuer et appliquer le deuxième groupe de modifications. Si vous remettez à plus tard un conflit lié à la première vague de modifications, la commande de fusion renverra au final un message d'erreur et vous devrez résoudre le conflit avant de lancer la fusion une deuxième fois pour récupérer le reste des modifications. |
Avertissement : bien que svn diff et svn merge soient conceptuellement très similaires, leur syntaxe est différente dans de nombreux cas. Pour plus de détails, reportez-vous au Guide de référence de svn : le client texte interactif ou consultez svn help. Par exemple, svn merge demande en entrée, en tant que cible, le chemin d'une copie de travail, c'est-à-dire un emplacement où il va appliquer le correctif généré. Si la cible n'est pas spécifiée, elle suppose que vous essayez d'exécuter l'une des opérations suivantes :
Vous voulez fusionner les modifications du dossier dans votre dossier de travail en cours.
Vous voulez fusionner les modifications d'un fichier donné dans un fichier du même nom existant dans votre dossier de travail en cours.
Si vous fusionnez un dossier et que vous n'avez pas encore spécifié de cible, svn merge suppose qu'il est dans la première situation et essaie d'appliquer les modifications dans votre dossier en cours. Si vous fusionnez un fichier et que ce fichier (ou un fichier du même nom) existe dans votre dossier de travail en cours, svn merge suppose qu'il est dans la seconde situation et essaie d'appliquer les modifications au fichier local du même nom.
Nous venons de voir des exemples d'utilisation de la commande svn merge et nous allons bientôt en voir plusieurs autres. Si vous n'avez pas bien assimilé le le fonctionnement des fusions, rassurez-vous, vous n'êtes pas un cas isolé. De nombreux utilisateurs (en particulier ceux qui découvrent la gestion de versions) commencent par une phase de perplexité au sujet de la syntaxe de la commande, ainsi que quand et comment utiliser cette fonctionnalité. Mais, en fait, cette commande est bien plus simple que vous ne le pensez ! Il y a une technique très simple pour comprendre comment svn merge agit.
La raison principale de la confusion est le nom de la commande. Le terme merge (« fusionner » en anglais) indique en quelque sorte que les branches vont être combinées, ou qu'un mystérieux mélange des données va avoir lieu. Ce n'est pas le cas. Un nom plus approprié pour cette commande aurait pu être « comparer-et-appliquer », car c'est là tout ce qui se passe : deux arborescences sont comparées et les différences sont appliquées à une copie de travail.
Si vous utilisez svn merge pour effectuer de simples copies de modifications entre branches, elle fait généralement ce qu'il faut automatiquement. Par exemple, une commande telle que :
$ svn merge ^/calc/branches/une-branche
tente de dupliquer toutes les modifications faites
dans une-branche
vers votre répertoire
de travail actuel, qui est sans doute une copie de travail
partageant des liens historiques avec la branche. La commande
est suffisamment intelligente pour ne copier que les
modifications que votre copie de travail ne possède pas
encore. Si vous répétez cette commande une fois par semaine,
elle ne copie que les modifications « les plus
récentes » qui ont eu lieu depuis la dernière
fusion.
Si vous choisissez d'utiliser la commande svn merge dans sa version intégrale en lui fournissant les groupes de révisions spécifiques à copier, la commande prend trois paramètres :
une arborescence initiale (souvent appelée côté gauche de la comparaison) ;
une arborescence finale (souvent appelée côté droit de la comparaison) ;
une copie de travail qui reçoit les différences en tant que modifications locales (souvent appelée cible de la fusion).
Une fois ces trois paramètres fournis, les deux arborescences sont comparées et les différences sont appliquées à la copie de travail cible en tant que modifications locales. Une fois que la commande s'est terminée, le résultat est le même que si vous aviez édité les fichiers à la main ou lancé diverses commandes svn add ou svn delete vous-même. Si le résultat vous plaît, vous pouvez le propager. S'il ne vous plaît pas, vous pouvez toujours lancer svn revert pour revenir en arrière sur toutes les modifications.
La syntaxe de svn merge est assez flexible quant à la façon de spécifier les trois paramètres. Voici quelques exemples :
$ svn merge http://svn.exemple.com/depot/branche1@150 \ http://svn.exemple.com/depot/branche2@212 \ ma-copie-de-travail $ svn merge -r 100:200 http://svn.exemple.com/depot/trunk ma-copie-de-travail $ svn merge -r 100:200 http://svn.exemple.com/depot/trunk
La première syntaxe liste les trois arguments de façon explicite, spécifiant chaque arborescence sous la forme URL@REV et incluant la copie de travail cible. La deuxième syntaxe peut être utilisée comme raccourci pour les cas où vous comparez des révisions différentes de la même URL. Ce type de fusion est appelée (pour des raisons évidentes) une fusion « à 2-URL ». La dernière syntaxe indique que le paramètre copie de travail est optionnel ; s'il est omis, elle utilise par défaut le répertoire en cours.
Si le premier exemple donne la syntaxe
« complète » de svn merge,
celle-ci doit être utilisée avec grande prudence ; elle
peut en effet aboutir à des fusions qui n'enregistrent pas la
moindre méta-donnée svn:mergeinfo
. Le
paragraphe suivant évoque ceci plus en détail.
Subversion essaie de générer des métadonnées de fusion
dès qu'il le peut, afin de rendre plus intelligentes les
invocations suivantes de svn merge.
Néanmoins, il reste des situations où les données
svn:mergeinfo
ne sont ni créées ni modifiées.
Pensez à être prudent avec les scénarios suivants :
Si vous demandez à svn merge de comparer deux URLs qui n'ont pas de lien entre elles, un correctif est quand même généré et appliqué à votre copie de travail, mais aucune métadonnée de fusion n'est créée. Il n'y a pas d'historique commun aux deux sources et les futures fusions « intelligentes » dépendent de cet historique commun.
Bien qu'il soit possible de lancer une commande telle
que svn merge -r 100:200
,
le correctif résultant ne comporte aucune métadonnée
historique de fusion. À la date d'aujourd'hui, Subversion
n'est pas capable de représenter des URL de dépôts
différents au sein de la propriété
http://svn.projetexterieur.com/depot/trunk
svn:mergeinfo
.
--ignore-ancestry
Si ce paramètre est passé à svn merge, il force la logique de fusion à générer les différences sans réfléchir, de la même façon que svn diff les génère, en ignorant toute considération historique. Nous traitons ce point plus loin dans ce chapitre dans la section intitulée « Prise en compte ou non de l'ascendance ».
Précédemment dans ce chapitre (dans
la section intitulée « Retour en arrière sur des modifications »),
nous avons vu comment utiliser svn
merge pour appliquer un « correctif
inversé », comme moyen de revenir en arrière sur des
modifications. Si cette technique est utilisée pour
revenir sur une modification faite à l'historique propre
d'un objet (par exemple, propager r5 au tronc, puis
revenir immédiatement en arrière sur r5 en utilisant
svn merge . -c -5
), ce type de
fusion ne touche pas aux informations de fusion
(mergeinfo
) enregistrées
[41].
Tout comme la commande svn update, svn merge applique les modifications à votre copie de travail. Elle est donc aussi susceptible de créer des conflits. Cependant, les conflits engendrés par svn merge sont parfois différents et ce paragraphe va expliquer ces différences.
Pour commencer, supposons que votre copie de travail n'a pas de modification locale en cours. Quand vous lancez svn update pour la mettre à jour à une révision particulière, les modifications envoyées par le serveur s'appliquent toujours « proprement » à votre copie de travail. Le serveur génère le delta en comparant deux arborescences : d'une part un instantané virtuel de votre copie de travail, d'autre part l'arborescence de la révision qui vous intéresse. Parce que la partie gauche de la comparaison est parfaitement égale à ce que vous avez déjà, il est garanti que le delta va convertir correctement votre copie de travail en l'arborescence de droite.
Mais svn merge ne dispose pas de telles garanties et peut être bien plus chaotique : l'utilisateur avancé peut demander au serveur de comparer n'importe quelle paire d'arborescences, même des arborescences n'ayant aucun rapport avec la copie de travail ! Cela laisse potentiellement beaucoup de place à l'erreur humaine. Les utilisateurs vont parfois comparer deux arborescences qui ne sont pas les bonnes, créant ainsi un delta qui ne s'appliquera pas proprement. La sous-commande svn merge fera de son mieux pour appliquer la plus grande partie possible du delta, mais ça risque d'être impossible pour certains morceaux. Un conflit d'arborescences inattendu est un bon indice pour détecter que vous avez fusionné un mauvais delta
$ svn merge ^/calc/trunk -r104:115 --- Fusion de r105 à r115 dans '.' : C doc C src/bouton.c C src/entier.c C src/reel.c C src/main.c -- Stockage des informations de fusion (mergeinfo) de r105 à r115 dans '.' : U . Résumé des conflits : Arborescences en conflit : 3 $ svn st M . ! C doc > local dir missing, incoming dir edit upon merge ! C src/button.c > local file missing, incoming file edit upon merge ! C src/integer.c > local file missing, incoming file edit upon merge ! C src/main.c > local file missing, incoming file edit upon merge ! C src/real.c > local file missing, incoming file edit upon merge Résumé des conflits : Arborescences en conflit : 5
Dans l'exemple précédent, il est possible que
doc
et les quatre fichiers
*.c
existent dans les deux instantanés
de la branche en question. Le delta résultant tente de modifier
le contenu des fichiers dans votre copie de travail mais ces
fichiers n'existent pas dans la copie de travail. Quoi qu'il en
soit, un nombre élevé de conflits d'arborescences signifie
généralement que l'utilisateur compare les mauvaises
arborescences ou qu'il essaie de fusionner vers une mauvaise
copie de travail ; c'est le signe classique d'une erreur
de l'utilisateur. Quand ça arrive, il est facile de revenir
en arrière de manière récursive sur toutes les modifications
créées par la fusion
(svn revert . --recursive
), d'effacer
tout fichier ou dossier non suivi en versions restant après le
retour en arrière et de relancer svn merge
avec des paramètres différents.
Soyez aussi conscient qu'une fusion dans une copie de travail sans modification locale peut produire également des conflits textuels.
$ svn st $ svn merge ^/paint/trunk -r289:291 --- Fusion de r290 à r291 dans '.' : C Makefile -- Stockage des informations de fusion (mergeinfo) de r290 à r291 dans '.' : U . Résumé des conflits : Text conflicts: 1 Conflit découvert dans le fichier 'Makefile'. Select: (p) postpone, (df) diff-full, (e) edit, (m) merge, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p $ svn st M . C Makefile ? Makefile.merge-left.r289 ? Makefile.merge-right.r291 ? Makefile.working Résumé des conflits : Text conflicts: 2
Comment un conflit peut-il se produire ? Encore une fois, parce que l'utilisateur peut demander à svn merge de calculer et appliquer n'importe quel vieux delta sur la copie de travail, ce delta pouvant contenir des modifications textuelles qui ne s'appliquent pas proprement à un fichier de la copie de travail, même si ce fichier ne comporte aucune modification locale.
Une autre petite différence entre svn
update et svn merge réside dans le
nom des fichiers textuels créés lorsqu'un conflit survient. Dans
la section intitulée « Résolution des conflits », nous avons vu qu'une
mise à jour produit des fichiers nommés
nom_du_fichier.mine
,
nom_du_fichier.rANCIENNE_REV
et
nom_du_fichier.rNOUVELLE_REV
. Quand
svn merge génère un conflit,
elle crée trois fichiers dont les noms sont
nom_du_fichier.working
,
nom_du_fichier.merge-left.rANCIENNE_REV
et
nom_du_fichier.merge-right.rNOUVELLE_REV
.
Dans ce cas, les termes « merge-left »
(fusion-gauche en anglais) et « merge-right »
(fusion-droite en anglais) indiquent de quel côté de la
comparaison d'arborescences provient le fichier en
question ;
« rANCIENNE_REV » indique la révision du côté gauche
et « rNOUVELLE_REV » indique la révision du côté
droit. Dans tous les cas, ces noms différenciés vous aident à
distinguer les conflits qui résultent d'une mise à jour de ceux
qui résultent d'une fusion.
Il peut parfois y avoir un ensemble de modifications
particulier dont vous ne voulez pas qu'il soit fusionné
automatiquement. Par exemple, peut–être que l'habitude dans
votre équipe est d'effectuer tout nouveau travail de
développement dans /trunk
, mais d'être
plus conservateur en ce qui concerne le rétroportage des
modifications vers une branche stable que vous utilisez
pour la publication. À l'extrême, vous pouvez sélectionner
à la main des ensembles de modifications individuels du tronc
à porter vers la branche : juste les changements qui
sont suffisamment stables pour être acceptables. Peut-être
que les choses ne sont pas aussi strictes après tout ;
peut-être que la plupart du temps vous aimeriez juste laisser
svn merge fusionner automatiquement la
plupart des modifications du tronc vers la branche. Dans ce
cas, il vous faudrait une façon de masquer quelques
modifications particulières, c'est-à-dire d'empêcher qu'elles
ne soient fusionnées automatiquement.
Pour bloquer une liste de modifications, vous devez faire
croire à Subversion que la modification a déjà été fusionnée.
Pour cela, il est possible de lancer la sous-commande de fusion
avec l'option --record-only
. Cette option
demande à Subversion d'enregistrer les informations de fusion
comme s'il avait réellement effectué la fusion, mais aucun
changement n'est effectivement appliqué :
$ cd ma-branche-calc $ svn merge ^/calc/trunk -r386:388 --record-only --- Stockage des informations de fusion (mergeinfo) de r387 à r388 dans '.' : U . # Seules les informations de fusion sont modifiées. $ svn st M . $ svn pg svn:mergeinfo -vR Propriétés sur '.' : svn:mergeinfo /calc/trunk:341-378,387-388 $ svn commit -m "Bloque r387-388 vis-à-vis d'une fusion vers ma-branche-calc." Envoi . Révision 461 propagée.
Depuis Subversion 1.7, les fusions avec
--record-only
sont transitives. Cela veut dire
que, en plus d'enregistrer les informations de fusion décrivant
la ou les révisions bloquées, toute modification de la
propriété svn:mergeinfo
dans la source de la
fusion est aussi appliquée. Par exemple, supposons que nous
voulions bloquer la fonctionnalité "paint-python-wrapper" d'être
fusionnée depuis ^/paint/trunk
vers la
branche ^/paint/branches/paint-1.0.x
. Nous
savons que le travail sur cette fonctionnalité a été effectué
dans sa propre branche, qui a été réintégrée dans
/paint/trunk
au moment de la révision
465 :
$ svn log -v -r465 ^/paint/trunk ------------------------------------------------------------------------ r465 | joe | 2013-02-25 14:05:12 -0500 (lun. 25 fév. 2013) | 1 ligne Chemins modifiés : M /paint/trunk A /paint/trunk/python (de /paint/branches/paint-python-wrapper/python:464) Réintégration de Paint Python Wrapper. ------------------------------------------------------------------------
Comme la révision 465 était une fusion de réintégration, nous savons que les informations de fusion ont été enregistrées pour décrire cette fusion :
$ svn diff ^/paint/trunk --depth empty -c465 Index: . =================================================================== --- . (revision 464) +++ . (revision 465) Modification de propriétés sur . ___________________________________________________________________ Added: svn:mergeinfo Fusionné /paint/branches/paint-python-wrapper:r463-464
Maintenant, simplement bloquer les fusions de la révision
465 de /paint/trunk
n'est pas suffisant car
quelqu'un pourrait fusionner r462:464 directement depuis
/paint/branches/paint-python-wrapper
.
Heureusement, grace à la transitivité de
--record-only
, les fusions seront interdites.
La fusion --record-only
applique le delta
calculé à partir de svn:mergeinfo
à la
révision 465, bloquant par conséquent les fusions de cette
modification directement depuis
/paint/trunk
et
indirectement depuis
/paint/branches/paint-python-wrapper
:
$ cd paint/branches/paint-1.0.x $ svn merge ^/paint/trunk --record-only -c465 --- Fusion de r465 dans '.' : U . --- Stockage des informations de fusion (mergeinfo) de r465 dans '.' : G . $ svn diff --depth empty Index: . =================================================================== --- . (révision 462) +++ . (copie de travail) Modification de propriétés sur . ___________________________________________________________________ Added: svn:mergeinfo Fusionné /paint/branches/paint-python-wrapper:r463-464 Fusionné /paint/trunk:r465 $ svn ci -m "Blocage du wrapper Python dans la version 1.0 de paint." Envoi . Révision 466 propagée.
Maintenant, toute tentative de fusionner la fonctionnalité
vers /paint/trunk
est
inopérante :
$ svn merge ^/paint/trunk -c465 --- Stockage des informations de fusion (mergeinfo) de r456 dans '.' : U . $ svn st # Rien n'a changé ! $ svn merge ^/paint/branches/paint-python-wrapper -r462:464 --- Stockage des informations de fusion (mergeinfo) de r463 bis r464 in '.' : U . $ svn st # Rien n'a changé ! $
Si, plus tard, vous vous rendez compte que vous avez besoin
de fusionner la fonctionnalité bloquée vers
/paint/trunk
, vous avez deux possibilités.
Vous pouvez rejouer à l'envers la fusion r466 (la révision dans
laquelle vous avez bloqué la fonctionnalité), comme cela a été
montré dans la section intitulée « Retour en arrière sur des modifications ».
Une fois que vous avez propagé cette modification, vous pouvez
recommencer la fusion de r465 de
/paint/trunk
. L'autre façon, vous pouvez
simplement rejouer la fusion de r465 depuis
/paint/trunk
avec l'option
--ignore-ancestry
. Cela forcera la fusion à
ignorer les informations contenues dans mergeinfo et appliquera
simplement les changements demandés, comme indiqué dans
la section intitulée « Prise en compte ou non de l'ascendance ».
$ svn merge ^/paint/trunk -c465 --ignore-ancestry --- Fusion de r465 in '.' : A python A python/paint.py G .
Bloquer des modifications avec l'option
--record-only
fonctionne, mais cela peut
s'avérer dangereux.Le problème principal est que nous ne faisons
pas clairement la différence entre
« J'ai déjà cette modification » et
« Je n'ai pas cette modification, mais je n'en veux pas
pour le moment. ». En fait, nous mentons au système, en
lui faisant croire que la modification a déjà été fusionnée. Ce
qui transfère vers vous, l'utilisateur, la responsabilité de
vous rappeler que la modification n'a en fait pas été fusionnée,
qu'elle n'était tout simplement pas voulue. Il n'y a pas moyen
de demander à Subversion la liste des « listes des
modifications bloquées ». Si vous voulez en conserver la
trace (afin de pouvoir les débloquer un jour), vous devrez les
consigner dans un fichier texte quelque part, ou peut-être
dans une propriété inventée de toutes pièces pour
l'occasion.
Une des fonctionnalités principales de tout système de gestion de versions est de conserver la trace de qui a modifié quoi et quand ils l'ont fait. Les sous-commandes svn log et svn blame sont les outils adaptés pour cela : quand on les applique à des fichiers individuels, ils renvoient non seulement l'historique des ensembles de modifications qui ont touché le fichier, mais aussi exactement quel utilisateur a écrit quelle ligne de code et quand il l'a fait.
Cependant, quand des modifications commencent à être copiées entre des branches, les choses se compliquent. Par exemple, si vous interrogiez svn log sur l'historique de votre branche fonctionnelle, elle renverrait exactement toutes les révisions qui ont touché cette branche :
$ cd ma-branche-calc $ svn log -q ------------------------------------------------------------------------ r461 | utilisateur | 2013-02-25 05:57:48 -0500 (lun. 25 fév. 2013) ------------------------------------------------------------------------ r379 | utilisateur | 2013-02-18 10:56:35 -0500 (lun. 18 fév. 2013) ------------------------------------------------------------------------ r378 | utilisateur | 2013-02-18 09:48:28 -0500 (lun. 18 fév. 2013) ------------------------------------------------------------------------ … ------------------------------------------------------------------------ r8 | sally | 2013-01-17 16:55:36 -0500 (jeu. 17 janv. 2013) ------------------------------------------------------------------------ r7 | bill | 2013-01-17 16:49:36 -0500 (jeu. 17 janv. 2013) ------------------------------------------------------------------------ r3 | bill | 2013-01-17 09:07:04 -0500 (jeu. 17 janv. 2013) ------------------------------------------------------------------------
Mais est-ce bien là une description adéquate de tous les changements qui ont eu lieu sur cette branche ? Ce qui manque ici, c'est le fait que les révisions 352, 362, 372 et 379 résultaient en fait de fusions en provenance du tronc. Si vous regardez plus en détail l'historique d'une de ces révisions, vous ne verrez nulle part les multiples ensembles de modifications du tronc qui ont été reportés sur la branche :
$ svn log ^/calc/branches/ma-branche-calc -r352 -v ------------------------------------------------------------------------ r352 | utilisateur | 2013-02-16 09:35:18 -0500 (sam. 16 fév. 2013) | 1 ligne Chemins modifiés : M /calc/branches/ma-branche-calc M /calc/branches/ma-branche-calc/Makefile M /calc/branches/ma-branche-calc/doc/INSTALL M /calc/branches/ma-branche-calc/src/bouton.c M /calc/branches/ma-branche-calc/src/reel.c Synchronisation des dernières modifications du tronc dans ma-branche-calc.
Il se trouve que nous savons que cette fusion vers la
branche n'était qu'une fusion de modifications du tronc.
Comment pouvons-nous également voir ces modifications du
tronc ? La réponse est d'utiliser l'option
--use-merge-history
(-g
).
Cette option donne le détail des modifications
« filles » qui faisaient partie de la fusion.
$ svn log ^/calc/branches/my-calc-branch -r352 -v -g ------------------------------------------------------------------------ r352 | utilisateur | 2013-02-16 09:35:18 -0500 (sam. 16 fév. 2013) | 1 ligne Chemins modifiés : M /calc/branches/ma-branche-calc M /calc/branches/ma-branche-calc/Makefile M /calc/branches/ma-branche-calc/doc/INSTALL M /calc/branches/ma-branche-calc/src/bouton.c M /calc/branches/ma-branche-calc/src/reel.c Synchronisation des dernières modifications du tronc dans ma-branche-calc. ------------------------------------------------------------------------ r351 | sally | 2013-02-16 08:04:22 -0500 (sam. 16 fév. 2013) | 2 lignes Chemins modifiés : M /calc/trunk/src/real.c Fusion via : r352 Travail sur le tronc du projet calc. ------------------------------------------------------------------------ … ------------------------------------------------------------------------ r345 | sally | 2013-02-15 16:51:17 -0500 (ven. 15 fév. 2013) | 2 lignes Chemins modifiés : M /calc/trunk/Makefile M /calc/trunk/src/entier.c Fusion via : r352 Travail sur le tronc du projet calc. ------------------------------------------------------------------------ r344 | sally | 2013-02-15 16:44:44 -0500 (ven. 15 fév. 2013) | 1 ligne Chemins modifiés : M /calc/trunk/src/entier.c Fusion via : r352 Réusinage des fonctions trucmuches.
En forçant l'opération svn log à utiliser l'historique des fusions, nous obtenons non seulement la révision que nous avions demandé (r352), mais aussi les deux révisions qui l'accompagnaient — deux modifications du tronc faites par Sally. C'est une image bien plus complète de l'historique !
La commande svn blame accepte également
l'option --use-merge-history
(-g
). Si cette option est omise, quelqu'un
qui regarderait un relevé annoté ligne par ligne pour
bouton.c
risquerait d'avoir l'impression
erronée que vous êtes responsable des lignes qui ont corrigé
une certaine erreur :
$ svn blame src/button.c … 352 utilisateur retval = inverse_func(button, path); 352 utilisateur return retval; 352 utilisateur } …
Et bien qu'il soit vrai que vous avez propagé ces trois lignes lors de la révision 352, deux d'entre elles ont en fait été écrites par Sally auparavant, en révision 348, et ont été injectées dans votre branche lors d'une fusion de synchronisation :
$ svn blame button.c -g … G 348 sally retval = inverse_func(button, path); G 348 sally return retval; 352 utilisateur } …
À présent, nous savons qui doit réellement être tenu responsable pour ces deux lignes de code !
Si vous discutez avec un développeur Subversion, il est probable qu'il fasse référence au terme d'ascendance. Ce mot est utilisé pour décrire la relation entre deux objets dans un dépôt : s'ils sont liés l'un à l'autre, un des objets est alors qualifié d'ancêtre de l'autre.
Par exemple, supposons que vous propagiez la révision 100
qui contient une modification d'un fichier
truc.c
. Dès lors,
truc.c@99
est un « ancêtre »
de truc.c@100
. En revanche, supposons
que vous propagiez la suppression de
truc.c
en révision 101 et ensuite
l'ajout d'un nouveau fichier du même nom en révision 102.
Dans ce cas, truc.c@99
et
truc.c@102
pourraient sembler
apparentés (ils ont le même chemin), mais en fait ce sont
des objets complètement différents au sein du dépôt. Ils ne
partagent aucun historique ou « ascendance ».
Nous abordons ce point pour mettre en évidence une
différence importante entre svn diff et
svn merge. La première commande ignore
toute ascendance, tandis que la seconde y est particulièrement
sensible. Par exemple, si vous demandez à svn
diff de comparer les révisions 99 et 102 de
truc.c
, vous obtenez des différences basées
sur les lignes ; la commande svn diff
compare deux chemins à l'aveugle. Mais si vous demandez à
svn merge de comparer les deux mêmes objets,
elle remarque qu'ils ne sont pas liés et essaie d'abord de
supprimer l'ancien fichier, puis d'ajouter le nouveau
fichier ; le résultat indique une suppression puis un
ajout :
D truc.c A truc.c
La plupart des fusions impliquent de comparer des
arborescences qui ont une relation d'ascendance de l'une à
l'autre ; c'est pourquoi svn merge a ce
comportement par défaut. Cependant, à l'occasion, vous pourriez
vouloir que la commande svn merge compare
deux arborescences sans relation d'ascendance entre elles. Par
exemple, vous avez peut-être importé deux arborescences de code
source représentant des publications différentes de deux
fournisseurs d'un projet logiciel (voir la section intitulée « Branches fournisseurs »). Si vous demandez à
svn merge de comparer les deux arborescences,
vous verrez la première arborescence complètement supprimée,
puis l'ajout de la seconde arborescence toute entière !
Dans ce genre de situations, vous attendez de svn
merge qu'il effectue une comparaison basée sur les
chemins uniquement, en ignorant toute relation entre les
fichiers et les dossiers. Ajoutez l'option
--ignore-ancestry
à votre commande
svn merge et elle se comportera comme
svn diff (et inversement, l'option
--notice-ancestry
fera se comporter
svn diff comme la commande
svn merge).
Astuce | |
---|---|
L'option |
Il arrive souvent qu'on veuille réorganiser le code source, en particulier dans les projets logiciels en Java. Les fichiers et les répertoires sont déplacés et renommés, causant souvent de grandes perturbations pour tous ceux qui travaillent sur le projet. Ceci semble être le cas idéal où utiliser une branche, n'est-ce pas ? Créer une branche, réorganiser les choses, et ensuite fusionner la branche vers le tronc, non ?
Hélas, ce scénario ne fonctionne pas si bien pour le moment et est même considéré comme l'une des faiblesses de Subversion. Le problème est que la commande svn update de Subversion n'est pas aussi robuste qu'elle le devrait, en particulier en ce qui concerne les opérations de copies et de déplacements.
Quand vous utilisez svn copy pour dupliquer un fichier, le dépôt se souvient d'où venait le nouveau fichier, mais il ne transmet pas cette information au client qui lance svn update ou svn merge. Au lieu de dire au client « Copie ce fichier que tu as déjà vers ce nouvel emplacement », il envoie un fichier entièrement nouveau. Ceci peut engendrer des problèmes, notamment des conflits d'arborescences dans le cas de renommage de fichiers, pour ce qui concerne la nouvelle copie et la suppression de l'ancien emplacement. Un fait peu connu à propos de Subversion est qu'il lui manque de « vrais renommages » — la commande svn move n'est rien de plus que l'agrégation de svn copy et svn delete.
Par exemple, supposons que vous travaillez sur votre branche
privée /calc/branches/ma-branche-calc
.
D'abord, vous effectuez une fusion automatique de
synchronisation avec /calc/trunk
et vous la
propagez dans r470 :
$ cd calc/trunk $ svn merge ^/calc/trunk --- Fusion des différences des URLs du dépôt vers '.' : U doc/INSTALL A FAQ U src/main.c U src/bouton.c U src/entier.c U Makefile U LISEZMOI U . -- Stockage des informations de fusion (mergeinfo) des URLs du dépôt dans '.' : U . $ svn ci -m "Synchronisation des changements de ^/calc/trunk jusqu'à r469." Envoi . Envoi Makefile Envoi LISEZMOI Envoi FAQ Envoi doc/INSTALL Envoi src/main.c Envoi src/bouton.c Envoi src/entier.c Transmission des données .... Révision 470 propagée.
Puis vous renommez entier.c
en tout.c
dans r471 et vous effectuez des
modifications dans ce même fichier dans r473. Concrètement, vous
avez créé un nouveau fichier dans votre branche (c'est une copie
du fichier original avec quelques modifications) et vous avez
effacé le fichier original. Pendant ce temps, sur
/calc/trunk
, Sally a propagé des
améliorations de son cru au fichier
entier.c
lors de la r472 :
$ svn log -v -r472 ^/calc/trunk ------------------------------------------------------------------------ r472 | sally | 2013-02-26 07:05:18 -0500 (dim. 26 fév. 2013) | 1 ligne Chemins modifiés : M /calc/trunk/src/entier.c Travail d'amélioration de entier.c sur le tronc. ------------------------------------------------------------------------
C'est alors que vous décidez de fusionner votre branche vers le tronc. Comment Subversion combine-t-il le renommage et les modifications que vous avez faits avec les modifications de Sally ?
$ svn merge ^/calc/branches/ma-branche-calc --- Fusion des différences des URLs du dépôt dans '.' : C src/entier.c U src/reel.c A src/tout.c --- Stockage des informations de fusion (mergeinfo) des URLs du dépôt dans '.' : U . Résumé des conflits: conflits d'arborescences : 1 $ svn st M . C src/entier.c > local file edit, incoming file delete upon merge M src/reel.c A + src/tout.c Résumé des conflits: conflits d'arborescences : 1
La réponse est que Subversion ne combinera
pas les modifications, mais générera un conflit
d'arborescences[42]parce qu'il a besoin de votre aide
pour déterminer quelle part de vos modifications et quelle part
des modifications de Sally doivent finalement se retrouver dans
tout.c
,ou même si le renommage a tout
simplement lieu d'être !
Vous devrez résoudre le conflit d'arborescences avant de pouvoir propager la fusion, ce qui requiert un minimum d'intervention manuelle de votre part, voir la section intitulée « Gestion des conflits d'arborescences ». La morale de cette histoire, c'est que tant que Subversion ne se sera pas amélioré, soyez vigilant lors des fusions avec copies et renommages d'une branche vers une autre et, lorsque vous le faites, préparez-vous à effectuer des résolutions manuelles.
Si vous venez juste de mettre à niveau votre serveur Subversion
à la version 1.5 ou plus, il existe un risque significatif que
les clients Subversion pré-1.5 sèment la pagaille dans votre
suivi automatique des fusions. Pourquoi ? Quand un client
Subversion pré-1.5 exécute svn merge, il ne
modifie pas du tout la valeur de la propriété
svn:mergeinfo
. La propagation qui s'ensuit,
bien qu'elle soit le résultat d'une fusion, n'envoie donc
aucune indication au dépôt au sujet des modifications
dupliquées — ces informations sont perdues. Par la
suite, lorsque des clients « qui prennent en compte les
fusions » tentent d'effectuer une fusion automatique,
ils rencontreront probablement toutes sortes de conflits
résultant des fusions répétées.
Si votre équipe et vous dépendez des fonctionnalités de
suivi des fusions de Subversion, vous voudrez peut-être
configurer votre dépôt pour qu'il empêche les anciens clients
de propager des modifications. La méthode la plus simple est
d'examiner le paramètre « capabilities » dans la
procédure automatique de début de propagation
(start-commit
). Si le client
indique être capable de gérer les mergeinfo
,
la procédure automatique peut l'autoriser à commencer la
propagation. Si le client n'indique pas en être capable, la
procédure automatique doit lui refuser la propagation.
Exemple 4.1, « Procédure automatique de vérification des capacités de
suivi des fusions avant une propagation » donne un
exemple d'une telle procédure automatique.
Exemple 4.1. Procédure automatique de vérification des capacités de suivi des fusions avant une propagation
# -*- coding: utf-8 -*- #!/usr/bin/env python import sys # La procédure automatique start-commit est appelée après la création # de la transaction Subversion et peuplée avec propriétés de révision # # # [1] CHEMIN-DEPOT (le chemin du dépôt) # [2] UTILISATEUR (l'utilisateur authentifié qui tente la propagation) # [3] CAPACITES (liste des capacités qu'annonce le client, # les éléments sont séparés par des ':' # voir ci-dessous) # [4] NOM-TRANSACTION (nom de la transaction qui vient d'être créée) capacites = sys.argv[3].split(':') if "mergeinfo" not in capacites: sys.stderr.write("Les propagations depuis un client non capable de" "suivre les fusions sont interdites. " "Veuillez mettre à niveau votre client à " "Subversion 1.5 ou plus récent.\n") sys.exit(1) sys.exit(0)
Pour plus d'informations sur les procédures automatiques, reportez-vous au la section intitulée « Mise en place des procédures automatiques ».
En fin de compte, la fonctionnalité de suivi des fusions
de Subversion possède une mécanique interne extrêmement
complexe et la propriété svn:mergeinfo
est la seule lorgnette dont l'utilisateur dispose pour
observer cette mécanique.
Quand et pourquoi les informations de fusions sont enregistrées par une fusion peut parfois être difficile à comprendre. De plus, la gestion des informations de fusions comporte tout un ensemble de taxonomies et de règles, telles que les informations « explicites » et celles « implicites », les révisions « effectives » et les « non-effectives », le « nettoyage » et « l'héritage » d'un dossier parent vers les dossiers enfants.
Nous avons choisi de ne pas couvrir en détail ces sujets dans ce livre pour plusieurs raisons. Premièrement, l'utilisateur moyen serait totalement submergé par le niveau de détail disponible. Deuxièmement, et c'est le plus important, nous estimons que l'utilisateur moyen ne doit pas avoir à comprendre ces concepts ; en tant que détails d'implémentation, ils restent à l'arrière-plan. Malgré tout, si vous appréciez ce genre de choses, vous en trouverez une formidable vue d'ensemble dans un article posté sur le site internet de Collabnet (aujourd'hui recopié sur le site Web de Subversion) : https://subversion.apache.org/blog/2008-05-06-merge-info.html.
Pour le moment, si vous voulez rester à l'écart de la complexité du suivi de fusions, nous vous recommandons de vous en tenir simplement aux bonnes pratiques suivantes :
Pour les branches fonctionnelles à courte durée de vie, suivez la procédure simple décrite dans la section intitulée « Fusions : pratiques de base ».
Evitez les fusions sous les sous-arborescences et de générer des informations de fusions sur les sous-dossiers. Ne pratiquez de fusions que sur la racine de la branche, pas sur des sous-répertoires. la section intitulée « Fusions de sous-arborescences et mergeinfo »).
Ne modifiez jamais la propriété
svn:mergeinfo
directement ;
utilisez svn merge avec l'option
--record-only
pour appliquer une
modification désirée à cette métadonnée (comme expliqué
dans la section intitulée « Blocage de modifications »).
Votre cible de fusion devrait toujours être une copie de travail qui est la racine d'une arborescence complète représentant une seule position dans le dépôt à un moment bien précis dans le temps :
mettez à jour avant de fusionner ! N'utilisez
pas l'option --allow-mixed-revisions
pour fusionner vers des copies de travail à révisions
mélangées.
ne fusionnez pas vers des cibles dont des dossiers pointent vers d'autres branches (tels que décrits dans la section intitulée « Parcours des branches »).
évitez les fusions vers des cibles avec des
répertoires clairsemés. De la même manières, ne
fusionnez pas pour des profondeurs autres que
--depth=infinity
Assurez-vous de toujours avoir l'accès complet en lecture à toutes vos sources de fusion et l'accès en lecture/écriture à l'ensemble de la cible de la fusion.
Bien sûr, vous pouvez être amené parfois à devoir violer certaines bonnes pratiques. Dans ce cas, ne vous inquietez pas, soyez seulement conscient des conséquences que cela engendre.
La commande svn switch transforme une
copie de travail existante de telle sorte qu'elle pointe vers
une branche différente. Bien que la connaissance de cette
commande ne soit pas absolument nécessaire pour travailler avec
des branches, elle fournit un raccourci utile. Dans l'un de nos
exemples précédents, après avoir créé votre branche privée, vous
avez extrait une toute nouvelle copie de travail du nouveau
répertoire du dépôt. À la place, vous pouvez simplement
demander à Subversion de modifier votre copie de travail de
/calc/trunk
pour qu'elle pointe vers
l'emplacement de la nouvelle branche :
$ cd calc $ svn info | grep URL URL: http://svn.exemple.com/depot/calc/trunk $ svn switch ^/calc/branches/ma-branche-calc U entier.c U bouton.c U Makefile Actualisé à la révision 341. $ svn info | grep URL URL: http://svn.exemple.com/depot/calc/branches/ma-branche-calc
« Faire pointer » (ou « déporter ») une copie de travail qui n'a pas de modifications locales vers une branche différente a pour résultat que la copie de travail a exactement le même aspect que si vous aviez effectué une extraction brute du répertoire. C'est en général plus efficace d'utiliser cette commande, car les différences entre les branches sont souvent minimes. Le serveur n'envoie que le minimum de modifications nécessaire pour faire pointer votre copie de travail vers le répertoire de la branche.
La commande svn switch accepte également
l'option --revision
(-r
), pour
que que vous ne soyez pas obligé de faire pointer votre copie de
travail vers la révision HEAD
de la
branche.
Bien sûr, beaucoup de projets sont plus compliqués que
notre exemple calc
et contiennent de
multiples sous-dossiers. Les utilisateurs de Subversion suivent
souvent un algorithme précis quand ils utilisent des
branches :
Copier le « tronc » entier du projet vers une nouvelle branche ;
Ne déporter qu'une partie de la copie de travail du tronc pour qu'elle pointe sur la branche.
En d'autres termes, si un utilisateur sait que le travail sur la branche ne doit avoir lieu que sur un sous-dossier donné, il utilise svn switch pour ne faire pointer que ce sous-dossier vers la branche (ou parfois des utilisateurs ne vont faire pointer qu'un unique fichier de travail vers la branche !). De cette façon, l'utilisateur peut continuer à recevoir les mises à jour normales du « tronc » vers la plus grande partie de sa copie de travail, mais les portions déportées ne seront pas touchées (à moins que quelqu'un ne propage une modification à sa branche). Cette fonctionnalité ajoute une dimension complètement nouvelle au concept de « copie de travail mixte » : les copies de travail peuvent non seulement contenir un mélange de révisions de travail, mais elles peuvent également contenir un mélange d'emplacements du dépôt.
Astuce | |
---|---|
Typiquement, les sous-dossiers déportés partagent un ancêtre
commun avec l'emplacement d'où ils ont été déportés. Cependant,
svn switch peut déporter un sous-dossier pour
refléter un emplacement du dépôt qui ne partage aucun ancêtre
avec ce sous-dossier. Pour ce faire, vous devez utiliser
l'option |
Si votre copie de travail contient un certain nombre de sous-arborescences pointant vers des emplacements variés du dépôt, elle continue à fonctionner normalement. Quand vous la mettez à jour, vous recevez comme il se doit les correctifs pour chaque sous-arborescence. Quand vous effectuez une propagation, vos modifications locales s'appliquent toujours au dépôt en tant qu'une unique modification atomique.
Remarquez que, bien qu'il soit possible pour votre copie de travail de pointer vers une variété d'emplacements du dépôt, ces emplacements doivent tous faire partie du même dépôt. Les dépôts Subversion ne sont pas encore capables de communiquer entre eux ; cette fonctionnalité est prévue à l'avenir [43].
Astuce | |
---|---|
Les administrateurs qui doivent modifier l'URL d'un dépôt
accessible via HTTP sont
encouragés à ajouter à leur fichier de configuration
|
Parce que svn switch est essentiellement une variante de svn update, elle se comporte de la même manière ; toute modification locale présente dans votre copie de travail est préservée lorsque de nouvelles données arrivent en provenance du dépôt.
Astuce | |
---|---|
Vous-êtes vous déjà trouvés dans une situation où vous
effectuez des modifications complexes (dans votre copie de
travail de $ svn copy http://svn.exemple.com/depot/calc/trunk \ http://svn.exemple.com/depot/calc/branches/nouvelle-branche \ -m "Création de la branche 'nouvelle-branche'." Révision 353 propagée. $ svn switch http://svn.exemple.com/depot/calc/branches/nouvelle-branche À la révision 353. La commande svn switch, à l'instar de svn update, préserve vos modifications locales. Désormais, votre copie de travail pointe vers la branche nouvellement créée et la prochaine fois que vous lancerez svn commit vos modifications y seront envoyées. |
Un autre concept courant en gestion de versions est l'étiquette (parfois appelée tag). Une étiquette n'est qu'un « instantané » d'un projet à un moment donné. Dans Subversion, cette idée semble être présente partout. Chaque révision du dépôt est exactement cela : un instantané du système de fichiers pris après chaque propagation.
Cependant les gens veulent souvent donner des noms plus
conviviaux aux étiquettes, tel que
version-1.0
. Et ils veulent prendre des
instantanés de sous-sections plus restreintes du système de
fichiers. Après tout, ce n'est pas si facile de se rappeler
que la version 1.0 d'un logiciel donné correspond à un
sous-dossier particulier de la révision 4822.
Une fois encore, svn copy vient à la
rescousse. Si vous voulez créer un instantané de
/calc/trunk
identique à ce qu'il est
dans la révision HEAD
, faites-en
une copie :
$ svn copy http://svn.exemple.com/depot/calc/trunk \ http://svn.exemple.com/depot/calc/tags/version-1.0 \ -m "Étiquetage de la version 1.0 du projet 'calc'." Révision 902 propagée.
Cet exemple présuppose qu'un répertoire
/calc/tags
existe déjà (s'il n'existe
pas, vous pouvez le créer en utilisant
svn mkdir). Une fois la copie terminée,
le nouveau dossier version-1.0
sera pour
toujours un instantané du dossier /trunk
tel qu'il était en révision HEAD
au moment
où vous avez effectué la copie. Bien sûr, vous voudriez
peut-être être plus précis quant à quelle révision vous copiez,
au cas où quelqu'un d'autre aurait propagé des modifications
au projet pendant que vous regardiez ailleurs. Donc si vous
savez que la révision 901 de /calc/trunk
est exactement l'instantané que vous voulez, vous pouvez le
spécifier en passant -r 901
à la commande
svn copy.
Mais attendez un moment : cette procédure de création d'étiquette, n'est-ce pas la même procédure que nous avons utilisé pour créer une branche ? En fait, oui. Dans Subversion, il n'y pas de différence entre une étiquette et une branche. Toutes deux ne sont que des répertoires ordinaires qui sont créés par copie. Comme pour les branches, la seule raison qui fasse qu'un répertoire copié soit une « étiquette » est que les humains ont décidé de le traiter de cette façon : aussi longtemps que personne ne propage de modification à ce répertoire, il reste un instantané. Si les gens commencent à y propager des choses, il devient une branche.
Si vous administrez un dépôt, il y a deux approches possibles pour gérer les étiquettes. La première approche est une politique de « non-intervention » : en tant que convention définie pour le projet, vous décidez où vos étiquettes sont placées et vous vous assurez que tous les utilisateurs savent comment traiter les répertoires qu'ils copient (c'est-à-dire que vous vous assurez qu'ils savent qu'ils ne doivent rien y propager). La seconde approche est plus paranoïaque : vous pouvez utiliser un des contrôles d'accès fournis avec Subversion pour empêcher que quiconque ne puisse faire autre chose dans la zone des étiquettes que d'y créer de nouvelles copies (voir le Chapitre 6, Configuration du serveur). L'approche paranoïaque n'est cependant pas nécessaire, en général. Si un utilisateur propage accidentellement une modification à un répertoire d'étiquettes, vous pouvez simplement revenir en arrière sur cette modification comme expliqué dans le paragraphe précédent. C'est ça la gestion de versions, après tout !
Il vous arrivera sûrement de vouloir que votre « instantané » soit plus compliqué qu'un simple répertoire à une unique révision donnée.
Par exemple, imaginons que votre projet est bien plus
vaste que notre exemple calc
:
supposons qu'il contient un bon nombre de sous-dossiers et bien
plus de fichiers encore. Au cours de votre travail, vous pouvez
très bien décider que vous avez besoin de créer une copie de
travail destinée à des fonctionnalités particulières et à des
corrections de bogues. Pour cela vous pouvez antidater de
manière sélective des fichiers ou dossiers à des révisions
données (en utilisant généreusement svn
update avec l'option -r
), déporter
des fichiers et des dossiers vers des branches particulières (au
moyen de svn switch) ou même effectuer
manuellement un tas de modifications locales. Quand vous en avez
terminé, votre copie de travail est un vrai bazar, fait
d'emplacements du dépôt à des révisions différentes. Mais après
l'avoir testée, vous êtes alors certain que c'est l'exacte
combinaison de données que vous vouliez étiqueter.
C'est alors le moment de prendre un cliché. Copier une URL vers une autre ne fonctionnera pas cette fois. Dans le cas présent, vous voulez prendre un cliché de l'arrangement exact de votre copie de travail et le placer dans le dépôt. Par chance, svn copy possède en fait quatre utilisations différentes (au sujet desquelles vous pouvez obtenir des informations au Partie II, « Guide de référence des commandes Subversion »), dont la possibilité de copier une arborescence de travail vers le dépôt :
$ ls ma-copie-de-travail/ $ svn copy ma-copie-de-travail \ http://svn.exemple.com/depot/calc/tags/mon-etiquette \ -m "Étiquette l'état de ma copie de travail existante." Révision 940 propagée.
Désormais il y a un nouveau répertoire dans le dépôt,
/calc/tags/mon-etiquette
, qui est un
instantané exact de votre copie de travail : révisions
mixtes, URL, modifications locales et tout et
tout…
D'autres utilisateurs ont trouvé des usages intéressants pour cette fonctionnalité. Il y a parfois des situations où votre copie de travail contient un paquet de modifications locales que vous aimeriez montrer à un collaborateur. Au lieu de lancer svn diff et d'envoyer un fichier patch (qui ne listera pas les modifications de répertoires, de liens symboliques ou de propriétés), vous pouvez utiliser svn copy pour « envoyer » votre copie de travail vers une zone privée du dépôt. Votre collaborateur peut ensuite soit extraire une copie carbone de votre copie de travail, soit utiliser svn merge pour recevoir exactement vos modifications.
Bien que ce soit une méthode élégante pour mettre à disposition un instantané rapide de votre copie de travail, remarquez que ce n'est pas une bonne manière de créer une branche initialement. La création de branche devrait être un évènement en soi, tandis que cette méthode combine la création d'une branche avec des modifications supplémentaires apportées aux fichiers, le tout au sein d'une seule révision. Ceci rend très difficile (à terme) d'identifier un unique numéro de révision en tant que point de création de la branche.
À ce stade, vous vous êtes certainement rendu compte que Subversion est extrêmement flexible. Parce qu'il implémente les branches et les étiquettes avec le même mécanisme sous-jacent (des copies de répertoires) et parce que les branches et les étiquettes apparaissent au sein de l'espace standard du système de fichiers, beaucoup de gens sont intimidés par Subversion. Il est presque trop flexible. Dans ce paragraphe, nous proposons des suggestions pour organiser et gérer vos données au fil du temps.
Il existe des méthodes standard recommandées pour
structurer un dépôt. La plupart des gens créent un répertoire
trunk
pour la « ligne de développement
principale » (le tronc), un répertoire
branches
qui contiendra les copies de
branches et un répertoire tags
qui
contiendra les copies étiquetées. Si un dépôt ne comprend qu'un
seul projet, les gens créent souvent les dossiers suivants
à la racine :
/
trunk/
branches/
tags/
Si un dépôt contient plusieurs projets, les administrateurs indexent généralement la structure du dépôt par projet (voir la section intitulée « Stratégies d'organisation d'un dépôt » pour en savoir plus sur les « dossiers racine d'un projet »), mais en voici directement un exemple :
/
paint/
trunk/
branches/
tags/
calc/
trunk/
branches/
tags/
Bien sûr, vous restez libre d'ignorer ces agencements courants. Vous pouvez créer toutes sortes de variantes, selon ce qui fonctionne le mieux pour vous ou pour votre équipe. Souvenez-vous que quel que soit votre choix, ce n'est pas un engagement définitif. Vous pouvez réorganiser votre dépôt à tout moment. Parce que les branches et les étiquettes sont des répertoires ordinaires, la commande svn move peut les déplacer ou les renommer selon vos désirs. Passer d'un agencement à un autre consiste juste à lancer une série d'opérations de déplacement côté serveur ; si vous n'aimez pas la façon dont les choses sont organisées dans le dépôt, modifiez juste leur agencement.
Souvenez-vous néanmoins que bien qu'il soit facile de déplacer des dossiers, vous devez aussi rester attentif à vos utilisateurs. Vos modifications sont susceptibles de déboussoler ceux qui ont des copies de travail existantes. Si un utilisateur a une copie de travail d'un répertoire donné du dépôt, votre opération svn move risque de supprimer ce chemin de la révision la plus récente. Lorsque par la suite l'utilisateur lancera svn update, il se verra annoncer que sa copie de travail pointe vers un chemin qui n'existe plus et sera contraint d'effectuer un svn switch vers le nouvel emplacement.
Une autre fonctionnalité intéressante liée aux principes
de fonctionnement de Subversion est que les branches et les
étiquettes peuvent avoir des durées de vie limitées, tout
comme n'importe quel autre élément suivi en versions. Par
exemple, supposons que vous avez enfin terminé votre travail
sur votre branche personnelle du projet
calc
. Après avoir fusionné toutes vos
modifications vers /calc/trunk
, le
répertoire contenant votre branche privée n'a plus de raison
d'exister :
$ svn delete http://svn.exemple.com/depot/calc/branches/ma-branche-calc \ -m "Suppression d'une branche obsolète du projet calc." Révision 474 propagée.
Astuce | |
---|---|
Rappelez-vous que, comme indiqué dans la section précédente, si votre copie de travail pointe vers un chemin du dépôt qui a été supprimé, une erreur apparaitra à la prochaine mise à jour : $ svn up Actualise '.' : svn: E160005: chemin '/calc/branches/my-calc-branch' n'existe pas Vous n'avez qu'à basculer votre copie de travail vers un chemin qui existe encore : $ svn sw ^/calc/trunk D src/tout.c U src/reel.c A src/entier.c U . Actualisé à la révision 474. |
Et maintenant votre branche a disparu. Bien sûr, elle n'a
pas vraiment disparu : le répertoire est juste absent de
la révision HEAD
, ne gênant plus personne.
Si vous utilisez svn checkout,
svn switch ou svn list
pour examiner une révision plus ancienne, vous pourrez toujours
voir votre vieille branche.
Si la navigation dans votre dossier supprimé ne vous suffit
pas, vous pouvez toujours le récupérer. Ressusciter des données
est très facile dans Subversion. S'il y a un dossier (ou un
fichier) supprimé que vous aimeriez faire réapparaître dans
HEAD
, utilisez simplement svn
copy pour le copier depuis l'ancienne
révision :
$ svn copy ^/calc/branches/ma-branche-calc@473 \ ^/calc/branches/ma-branche-calc \ -m "Restaure ma-branche-calc." Révision 475 propagée.
Dans notre exemple, votre branche personnelle a eu une durée
de vie relativement limitée : vous l'aviez peut-être créée
pour corriger un bogue ou implémenter une nouvelle
fonctionnalité. Quand votre tâche est finie, il en va de même
pour la branche. Cependant, en développement logiciel, il est
aussi courant d'avoir deux branches « principales »
côte à côte pour de très longues périodes. Par exemple,
supposons que le moment est venu de publier une version stable
du projet calc
pour le public. Vous savez
qu'il faudra quelques mois pour éliminer les bogues du logiciel.
Vous ne voulez pas que les gens ajoutent de nouvelles
fonctionnalités au projet, mais vous ne voulez pas non plus dire
à tous les développeurs d'arrêter de programmer. Donc à la
place, vous créez une branche « stable » du logiciel
qui ne changera pas beaucoup :
$ svn copy ^/calc/trunk ^/calc/branches/stable-1.0 \ -m "Création de la branche stable du projet calc." Révision 476 propagée.
Dès lors les développeurs sont libres de continuer à ajouter
des fonctionnalités de pointe (ou expérimentales) à
/calc/trunk
et vous pouvez poser comme
convention pour le projet que seules les corrections de bogues
seront propagées dans
/calc/branches/stable-1.0
. C'est-à-dire
qu'au fur et à mesure que les gens continuent de travailler
sur le tronc, quelqu'un reporte de façon sélective les
corrections de bogues vers la branche stable. Même après que la
branche stable aura été publiée, vous continuerez probablement à
maintenir la branche pendant longtemps, c'est-à-dire pour aussi
longtemps que vous continuerez à fournir aux clients un support
sur cette version. Nous évoquons ceci plus en détails dans le
prochain paragraphe.
Il existe de nombreux usages pour la création et la fusion des branches ; ce paragraphe décrit les plus courants.
Le plus souvent, la gestion de versions est utilisée pour le développement de logiciels, voici donc un coup d'œil rapide à deux des modèles les plus courants de création et de fusion de branches utilisés par les équipes de programmeurs. Si vous ne vous servez pas de Subversion pour développer des logiciels, n'hésitez pas à sauter ce paragraphe. Si vous êtes un développeur de logiciels qui utilise la gestion de versions pour la première fois, soyez très attentifs, car ces modèles sont souvent considérés comme des bonnes pratiques par les développeurs plus expérimentés. Ces procédures ne sont pas spécifiques à Subversion ; elles sont applicables à tout système de gestion de versions. Néanmoins, les voir explicitées en termes Subversion peut aider.
En général un logiciel suit un cycle de vie classique, répétant les trois étapes suivantes en boucle : code, test, publication. Il y a deux problèmes avec ce processus. Premièrement, les développeurs doivent continuer à écrire de nouvelles fonctionnalités pendant que les équipes d'assurance qualité prennent le temps de tester des versions supposées stables du logiciel. Les nouveaux développements ne peuvent pas s'arrêter pendant que le logiciel est en cours de test. Deuxièmement, l'équipe doit presque toujours effectuer le support des versions anciennes et publiées du logiciel ; si un bogue est découvert dans le code le plus récent, il existe probablement aussi dans les versions qui ont été publiées et les clients voudront obtenir le correctif pour ce bogue sans avoir à attendre la publication d'une nouvelle version majeure.
C'est là où la gestion de versions peut s'avérer utile. La procédure standard ressemble à ceci :
Les développeurs propagent tout nouveau
travail vers le tronc. Les modifications
quotidiennes sont propagées vers
/trunk
: nouvelles
fonctionnalités, corrections de bogues, etc.
Le tronc est copié vers une branche « de
publication ». Lorsque l'équipe estime que
le logiciel est prêt à être publié (disons en version 1.0),
/trunk
peut être copié vers
/branches/1.0
.
Les équipes continuent à travailler en
parallèle. Une équipe commence à tester
rigoureusement la branche de publication, pendant qu'une
autre équipe continue avec les nouvelles tâches (disons pour
la version 2.0) sur /trunk
. Si des
bogues sont découverts dans l'un ou l'autre des
emplacements, les correctifs sont reportés de l'un à l'autre
selon les besoins. Il arrive cependant un moment où même ce
processus s'arrête. La branche est « gelée » pour
les tous derniers tests juste avant publication.
La branche est étiquetée et
publiée. Quand les tests sont terminés,
/branches/1.0
est copiée vers
/tags/1.0.0
en tant que cliché de
référence. L'étiquette est exportée et livrée aux
clients.
La branche est gérée au fil du
temps. Pendant que le travail continue sur
/trunk
en vue de la version 2.0, les
correctifs de bogues continuent à être reportés de
/trunk
à
/branches/1.0
. Lorsque suffisamment de
correctifs se sont accumulés, les responsables peuvent
décider de publier une version 1.0.1 :
/branches/1.0
est copiée vers
/tags/1.0.1
et cette étiquette est
exportée et publiée.
Ce processus entier se répète au fur et à mesure que le logiciel gagne en maturité : quand le travail pour la version 2.0 est terminé, une nouvelle branche de publication 2.0 est créée, testée, étiquetée et finalement publiée. Au bout de quelques années, le dépôt finit par avoir un certain nombre de branches de publication en mode « maintenance » et un certain nombre d'étiquettes représentant les versions finales publiées.
Une branche fonctionnelle est
la sorte de branche qui est l'exemple dominant dans ce chapitre
(celle sur laquelle vous travailliez pendant que Sally
continuait à travailler sur /trunk
). C'est
une branche temporaire créée pour travailler sur un changement
complexe sans interférer avec la stabilité de
/trunk
. À la différence des branches de
publication (dont le support doit parfois être prolongé très
longtemps), les branches fonctionnelles naissent, sont utilisées
pendant un temps, sont fusionnées vers le tronc et sont
finalement supprimées. Elles ont une utilité limitée dans le
temps.
Encore une fois, les stratégies varient énormément au
sujet du moment approprié pour créer une branche fonctionnelle.
Certains projets n'utilisent jamais de branche
fonctionnelle : n'importe qui peut propager des
modifications à /trunk
. L'avantage de ce
système est qu'il est simple : personne n'a besoin d'être
formé aux branches ou aux fusions. L'inconvénient est que le
code du tronc est souvent instable ou inutilisable. D'autres
projets utilisent les branches à l'extrême : une
modification n'est jamais propagée
directement dans le tronc. Même les modifications les plus
triviales sont faites au sein d'une branche à courte durée de
vie, vérifiées attentivement, puis fusionnées vers le tronc.
La branche est ensuite supprimée. Ce système garantit que le
tronc restera exceptionnellement stable et utilisable à tout
moment, mais aux dépens des coûts de gestion liés à cette
procédure très lourde.
En général, les projets choisissent une approche à mi-chemin
entre les deux. Ils insistent généralement pour qu'à tout
moment /trunk
puisse être compilé et
passe avec succès les tests de régression. Une branche
fonctionnelle n'est nécessaire que quand une modification
nécessite un grand nombre de propagations susceptibles de
déstabiliser le tronc. Une bonne méthode empirique est de se
poser la question suivante : si le développeur
travaillait pendant plusieurs jours en isolation et ensuite
propageait cette grosse modification en une seule fois
(afin que /trunk
ne soit jamais
déstabilisé), est-ce que ce serait une modification trop
grosse à vérifier ? Si la réponse à cette question est
« oui », alors la modification devrait être
développée sur une branche fonctionnelle. Au fur et à mesure
que le développeur propage ses modifications incrémentales dans
la branche, elles peuvent facilement être vérifiées par ses
pairs.
Finalement, il reste la question de savoir quelle est la meilleure méthode pour garder une branche synchronisée avec le tronc au fur et à mesure que le travail avance. Comme nous l'avons mentionné précédemment, il est très risqué de travailler sur une branche pendant des semaines ou des mois ; le tronc continuera sûrement à recevoir des modifications, au point que les deux lignes de développement risquent de s'éloigner tellement l'une de l'autre qu'essayer de fusionner la branche vers le tronc devienne un cauchemar.
Le mieux pour éviter une telle situation est de fusionner régulièrement les modifications du tronc vers la branche. Faites-en une habitude : une fois par semaine, fusionnez les modifications du tronc de la semaine précédente vers la branche.
Le moment arrivera où vous serez prêt à fusionner la branche fonctionnelle « synchronisée » vers le tronc. Commencez donc par effectuer une dernière fusion des modifications les plus récentes du tronc vers la branche. Une fois que c'est fait, les dernières versions de la branche et du tronc sont absolument identiques, mises à part vos propres modifications sur la branche. Vous êtes alors en mesure de lancer une fusion automatique de réintégration de la branche vers le tronc :
$ cd copie-de-travail-du-tronc $ svn update À la révision 1910. $ svn merge ^/calc/branches/ma-branche --- Fusion des différences des URLs du dépôt vers '.': U reel.c U entier.c A nouveau-dossier A nouveau-dossier/nouveau-fichier U . …
Une autre façon de concevoir ce modèle est d'imaginer que votre synchronisation hebdomadaire du tronc vers la branche est analogue au lancement de svn update dans une copie de travail, tandis que l'étape finale de fusion est analogue au lancement de svn commit depuis une copie de travail. Après tout, une copie de travail n'est rien d'autre qu'une branche privée très superficielle : c'est une branche qui n'est capable de ne contenir qu'une seule modification à la fois.
Comme c'est particulièrement le cas en développement logiciel, les données que vous gérez dans votre système de gestion de versions ont souvent un lien étroit avec les données de quelqu'un d'autre, ou en sont peut-être dépendantes. Généralement, les besoins de votre projet vous obligent à rester aussi à jour que possible avec les données fournies par cette entité externe, sans sacrifier la stabilité de votre propre projet. Ce scénario arrive très souvent, partout où les informations générées par un groupe de personnes ont un effet direct sur celles qui sont générées par un autre groupe de personnes.
Par exemple, il arrive que des développeurs de logiciel travaillent sur une application qui utilise une bibliothèque tierce. Subversion a justement une relation de ce type avec la bibliothèque Apache Portable Runtime (APR) (voir la section intitulée « APR, la bibliothèque Apache de portabilité des exécutables »). Le code source de Subversion dépend de la bibliothèque APR pour tous ses besoins de portabilité. Durant les étapes initiales de développement de Subversion, le projet suivait les changements de l'interface de programmation d'APR de près, restant toujours « à la pointe » des évolutions du code de la bibliothèque. Maintenant que APR et Subversion ont tous deux gagné en maturité, Subversion n'essaie de se synchroniser avec l'interface de programmation de l'APR qu'à des étapes de publication stables et bien testées.
Donc, si votre projet dépend des informations de quelqu'un d'autre, vous pourriez tenter de synchroniser ces informations avec les vôtres de plusieurs manières. La plus pénible serait de donner des instructions orales ou écrites à tous les contributeurs de votre projet, leur demandant de s'assurer qu'ils disposent des bonnes versions de ces informations tierces dont votre projet a besoin. Si les informations tierces sont gérées dans un dépôt Subversion, vous pourriez aussi utiliser les définitions externes de Subversion pour en fait « agrafer » des versions spécifiques de ces informations à un endroit quelconque dans le dossier de votre copie de travail (voir la section intitulée « Définition de références externes »).
Mais parfois vous voulez gérer des modifications personnalisées de ce code tierce à l'intérieur de votre propre système de gestion de versions. En reprenant l'exemple du développement logiciel, les programmeurs peuvent vouloir apporter des modifications à cette bibliothèque tierce pour leurs propres besoins. Ces modifications incluent peut-être de nouvelles fonctionnalités ou des corrections de bogues, gérées en interne seulement jusqu'à ce qu'elles soient incluses dans une version officielle de la bibliothèque tierce. Ou alors ces changements ne seront peut-être jamais remontés vers ceux qui gèrent cette bibliothèque, existant seulement en tant qu'optimisations « maison » permettant de mieux adapter la bibliothèque aux besoin des développeurs du logiciel.
À présent vous êtes face à une situation intéressante. Votre projet pourrait héberger ses modifications maison des données tierces de manière désordonnée, par exemple en utilisant des correctifs de type patch ou des versions alternatives complètes des fichiers et dossiers. Mais ces méthodes deviennent rapidement de vrais casse-tête à gérer, nécessitant des mécanismes pour reporter vos modifications maison au code tierce et nécessitant le report de ces modifications à chaque version successive du code tierce dont vous dépendez.
La solution de ce problème est d'utiliser des branches fournisseurs. Une branche fournisseur est une arborescence au sein de votre propre système de gestion de versions qui contient des informations fournies par une entité tierce, ou fournisseur. Chaque version des données du fournisseur que vous décidez d'incorporer dans votre projet est appelée une livraison fournisseur.
Les branches fournisseur présentent deux avantages. Premièrement, en incluant la livraison fournisseur actuellement supportée dans votre propre système de gestion de versions, vous avez la garantie que les membres de votre projet n'auront jamais besoin de se demander s'ils ont la bonne version des données du fournisseur. Ils reçoivent simplement la bonne version pendant les mises à jour usuelles de leur copie de travail. Deuxièmement, parce que ces données font partie de votre propre dépôt Subversion, vous pouvez y conserver vos modifications maison : vous n'avez plus besoin d'une méthode automatisée (ou pire, manuelle) pour reporter vos propres changements.
Malheureusement, il n'existe pas de « meilleure » façon pour gérer les branches fournisseurs dans Subversion. La flexibilité offerte par le système permet plusieurs approches différentes, chacune ayant ses avantages et ses inconvénients, et aucune ne peut être considérée comme « la méthode qui tue » pour ce problème. Nous allons décrire quelques unes des approches sans rentrer dans les détails dans les paragraphes qui suivent, en prenant comme exemple un projet logiciel qui dépend d'une bibliothèque tierce.
Gérer des modifications personnalisées d'une bibliothèque tierce met en jeu trois sources de données : la version de la bibliothèque tierce sur laquelle vos modifications ont porté la dernière fois, la version personnalisée (c'est-à-dire la branche fournisseur actuelle) de cette bibliothèque qui est utilisée par votre projet et toute nouvelle version de la bibliothèque externe dont vous espérez sûrement effectuer la mise à niveau. Gérer la branche fournisseur (qui doit résider dans le dépôt de votre code source, par définition) consiste alors essentiellement à effectuer des fusions (au sens général du terme). Mais chaque équipe peut choisir sa méthode pour ce qui concerne les autres sources de données : les versions originales du code source de la bibliothèque tierce. Donc, nous avons plusieurs façons pour effectuer les fusions requises.
Stricto sensu, il existe deux façons de faire ces fusions. Afin de simplifier et de rester concret dans ce paragraphe, nous supposons qu'il n'y a qu'une seule branche fournisseur qui est mise à niveau lors de chaque mise à jour des bibliothèques tierces (qui décrivent les différences entre les versions courantes et les nouvelles versions des sources de la bibliothèque).
Note | |
---|---|
Une autre approche est de créer une nouvelle branche fournisseur pour chaque version de la bibliothèque, en appliquant les différences entre la bibliothèque originale courante et la version personnalisée vers la nouvelle branche. Cette approche n'est pas mauvaise, nous ne nous sentons juste pas obligés de documenter ici toutes les façons de faire. |
Les paragraphes suivants décrivent comment créer et gérer
une branche fournisseur suivant quelques scénarios différents.
Dans les exemples qui suivent, nous supposons que la
bibliothèque tierce s'appelle libcomplex et que nous allons
implémenter une branche fournisseur basée sur libcomplex 1.0.0
qui est stockée dans notre dépôt à l'emplacement
^/vendor/libcomplex-perso
. Nous allons voir
comment nous pouvons mettre à niveau vers libcomplex 1.0.1 tout
en préservant nos personnalisations de cette
bibliothèque.
Dans un premier temps, regardons comment gérer une branche fournisseur lorsque la bibliothèque originale est accessible par Subversion. Pour les besoins de cet exemple, nous allons considérer que la bibliothèque libcomplex dont nous avons parlé est développée dans un dépôt Subversion librement accessible et que les développeurs utilisent une procédure de publication de bon aloi qui comporte la création d'une étiquette pour chaque version stable publiée.
Depuis Subversion 1.5, la sous-commande svn merge est capable d'effectuer ce que l'on appelle des fusions avec un dépôt externe, où les sources de la fusion sont stockées dans un dépôt différent du dépôt dont la copie de travail, cible de la fusion, a été extraite. Et dans Subversion 1.8, le comportement de svn copy a été modifié de manière à ce que l'arborescence résultante d'une copie depuis un dépôt externe vers une copie de travail existante soit incorporée dans cette copie de travail et placée pour ajout lors de la prochaine propagation. C'est cette fonctionnalité de copie à partir d'un dépôt externe que nous allons utiliser pour initier notre branche fournisseur.
Créons donc notre branche fournisseur. Nous commençons par créer un dossier d'accueil pour toutes les branches fournisseurs dans notre dépôt puis nous extrayons une copie de travail à cet emplacement.
$ svn mkdir http://svn.exemple.com/projets/vendor \ -m "Création d'un conteneur pour les branches fournisseurs." Révision 1160 propagée. $ svn checkout http://svn.exemple.com/projets/vendor \ /chemin/vers/fournisseur Révision 1160 extraite. $
Maintenant nous allons profiter de la capacité de Subversion à copier un dépôt externe pour obtenir une copie exacte de libcomplex 1.0.0 (y compris les propriétés Subversion stockées dans ces fichiers et dossiers) à partir du dépôt du fournisseur.
$ cd /chemin/vers/fournisseur $ svn copy http://svn.monfournisseur.fr/depot/libcomplex/tags/1.0.0 \ libcomplex-perso --- Copying from foreign repository URL 'http://svn.monfournisseur.fr/depot/libcomplex/tags/1.0.0' : A libcomplex-perso A libcomplex-perso/README A libcomplex-perso/LICENSE … A libcomplex-perso/src/code.c A libcomplex-perso/tests A libcomplex-perso/tests/TODO $ svn commit -m "Initialisation de la branche fournisseur libcomplex avec libcomplex 1.0.0." Ajout libcomplex-custom Ajout libcomplex-custom/README Ajout libcomplex-custom/LICENSE … Ajout libcomplex-custom/src Ajout libcomplex-custom/src/code.h Ajout libcomplex-custom/src/code.c Transmission des données ....................................... Révision 1161 propagée. $
Note | |
---|---|
Si vous êtes amené à utiliser une vieille version de
Subversion, la meilleure façon d'approcher cette nouvelle
fonctionnalité de svn copy est d'importer
une copie de travail (avec svn import) de
la version étiquetée du fournisseur, en spécifiant bien les
options |
Maintenant que nous avons la branche fournisseur basée sur libcomplex 1.0.0, nous pouvons commencer à personnaliser libcomplex pour satisfaire nos besoins, en propageant les modifications directement vers la branche fournisseur que nous avons créée. Et bien sûr, nous pouvons commencer à utiliser libcomplex dans notre propre application.
Quelques temps plus tard, les développeurs de libcomplex publient une nouvelle version de leur bibliothèque, la version 1.0.1. Après avoir passé en revue les modifications, nous décidons de mettre à niveau notre branche fournisseur vers cette nouvelle version. Et c'est ici que l'opération de fusion à partir d'un dépôt externe de Subversion est utile. Nous avons dans notre branche fournisseur la libcomplex 1.0.0 originale plus nos personnalisations. Nous avons besoin maintenant d'y insérer l'ensemble des modifications que le fournisseur a effectué entre 1.0.0 et 1.0.1, idéalement sans fracasser nos personnalisations. C'est précisément ce que la forme de svn merge à 2-URL sait faire.
$ cd /chemin/vers/fournisseur $ svn merge http://svn.autrefournisseur.com/depot/libcomplex/tags/1.0.0 \ http://svn.autrefournisseur.com/depot/libcomplex/tags/1.0.1 \ libcomplex-perso -- Fusion des différences des URLs du dépôt externe dans '.': U libcomplex-perso/src/code.h C libcomplex-perso/src/code.c U libcomplex-perso/README Résumé des conflits : Text conflicts: 1 Conflit découvert dans le fichier 'libcomplex-custom/src/code.c'. Select: (p) postpone, (df) diff-full, (e) edit, (m) merge, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options:
Comme vous pouvez le constater, svn merge a fusionné les modifications pour obtenir libcomplex 1.0.1 à partir de libcomplex 1.0.0 dans votre copie de travail. Dans cet exemple, il a même découvert et marqué un fichier comme étant en conflit. Il semble que le fournisseur a modifié une zone d'un des fichiers que nous avons personnalisé. Subversion détecte ce conflit et nous donne la possibilité de le résoudre de manière sécurisée, c'est-à-dire que nos modifications à ce qui est maintenant libcomplex 1.0.1 puissent continuer à faire sens. Pour plus d'informations sur la résolution des conflits de ce type, reportez-vous à la section intitulée « Résolution des conflits ».
Une fois que nous avons résolu les conflits et effectué nos tests ou passé en revue ce que est nécessaire, nous pouvons propager les modifications vers notre branche fournisseur.
$ svn status libcomplex-perso M libcomplex-perso/src/code.h M libcomplex-perso/src/code.c M libcomplex-perso/README $ svn commit -m "Mise à niveau de la branche fournisseur vers libcomplex 1.0.1." \ libcomplex-perso Sending libcomplex-perso/README Sending libcomplex-perso/src/code.h Sending libcomplex-perso/src/code.c Transmission des données ... Révision 1282 propagée. $
Voilà, à grosses mailles, comment gérer des branches fournisseurs quand les sources originales sont accessible par Subversion. Il faut noter quand même quelques manques. D'abord, les fusions de dépôts externes ne sont pas automatiquement tracées par Subversion lui-même comme le sont les fusions internes au dépôt. Cela veut dire que c'est à l'utilisateur de savoir quels changements ont été appliqués sur la branche fournisseur et de construire lui-même la prochaine fusion pour mettre à niveau la branche. De plus, comme c'est le cas pour toutes les fusions faites par Subversion, les renommages à l'intérieur des sources de la fusion peuvent entrainer certaines complications et frustrations. Malheureusement, à l'heure actuelle, nous n'avons pas de recommandation particulière réellement valable pour vous soulager dans ce cas.
Dans le paragraphe précédent (la section intitulée « Branches fournisseurs depuis des dépôts externes ») nous avons vu comment implémenter et maintenir une branche fournisseur quand celui-ci fournit un accès via Subversion, ce qui est le scénario idéal pour les branches fournisseurs. Subversion se distingue particulièrement lorsqu'il s'agit de fusionner des contenus gérés par Subversion. Malheureusement, ce n'est pas toujours le cas. Souvent, un projet dépend d'une bibliothèque qui n'est accessible que via des mécanismes non-Subversion, tels que des archives compressées de code source. Dans ces circonstances, nous recommandons fortement de faire tout ce que vous pouvez pour insérer ces données non-Subversion dans Subversion de la manière la plus propre possible. Examinons donc une approche de branche fournisseur dans laquelle les différentes versions de la bibliothèque tierce sont répliquées dans votre propre dépôt.
Configurer la branche fournisseur pour la première fois est très simple, vraiment. Dans notre exemple, nous considérons que libcomplex 1.0.0 est fournie dans une archive compressée classique. Pour créer notre branche fournisseur, nous allons dans un premier temps copier le contenu de l'archive dans notre dépôt comme une sorte d'arborescence étiquetée fournisseur en lecture seule (par convention uniquement).
$ tar xvfz libcomplex-1.0.0.tar.gz libcomplex-1.0.0/ libcomplex-1.0.0/README libcomplex-1.0.0/LICENSE … libcomplex-1.0.0/src/code.c libcomplex-1.0.0/tests libcomplex-1.0.0/tests/TODO $ svn import libcomplex-1.0.0 \ http://svn.exemple.com/projets/vendor/libcomplex-1.0.0 \ --no-ignore --no-auto-props \ -m "import des sources de libcomplex 1.0.0." Ajout libcomplex-custom Ajout libcomplex-custom/README Ajout libcomplex-custom/LICENSE … Ajout libcomplex-custom/src Ajout libcomplex-custom/src/code.h Ajout libcomplex-custom/src/code.c Transmission des données ....................................... Révision 1160 propagée. $
Notez que dans l'exemple, nous avons utilisé l'option
--no-ignore
pour l'import de manière à ce que
Subversion récupère bien tous les fichiers de la livraison. Nous
avons également utilisé l'option
--no-auto-props
afin que notre client n'affecte
pas de lui-même des propriétés qui ne seraient pas présentes
dans l'archive officielle[44].
Maintenant que la première archive du fournisseur est présente dans notre dépôt, nous pouvons nous en servir comme point de départ pour créer notre branche fournisseur en utilisant svn copy comme pour toute autre branche.
$ svn copy http://svn.exemple.com/projets/vendor/libcomplex-1.0.0 \ http://svn.exemple.com/projets/vendor/libcomplex-perso \ -m "Initialisation de la branche fournisseur libcomplex à partir de libcomplex 1.0.0." Révision 1161 propagée. $
Parfait. Ici, nous avons une branche fournisseur basée sur libcomplex 1.0.0. Nous sommes maintenant aptes à personnaliser libcomplex pour nos besoins propres, en propageant directement les modifications vers la branche fournisseur que nous venons de créer. Puis, nous pouvons utilisé notre libcomplex personnalisée dans nos applications.
Quelques temps plus tard, libcomplex 1.0.1 est publiée. Après avoir passé en revue les modifications, nous décidons de mettre à niveau notre branche fournisseur vers cette nouvelle version. Afin d'effectuer cette mise à niveau, nous devons essentiellement appliquer le même ensemble de modifications à notre branche fournisseur que le fournisseur a fait entre la version 1.0.0 et la version 1.0.1 de sa bibliothèque, ceci sans écraser nos propres personnalisations. La façon la plus sûre de le faire est d'insérer libcomplex 1.0.1 dans notre dépôt, comme un delta vis-à-vis du code de libcomplex 1.0.0 de notre dépôt. Ensuite, nous utilisons la forme 2-URL de la sous-commande svn merge pour répliquer ces mêmes modifications vers notre branche fournisseur.
Il existe plusieurs manières d'insérer correctement libcomplex 1.0.1 dans notre dépôt[45]. L'approche que nous décrivons ici est relativement rudimentaire, mais elle convient pour illustrer notre exemple.
Rappelez-vous que nous voulons que notre replique de la livraison libcomplex-1.0.1 partage des ancêtres avec notre livraison 1.0.0, afin de produire plus tard les meilleurs résultats quand nous devrons fusionner les modifications entre les archives vers la branche fournisseur. Nous allons commencer par créer une branche libcomplex-1.0.1 comme copie de notre branche « étiquetée fournisseur » libcomplex-1.0.0. Cette copie sera destinée à devenir une réplique de libcomplex 1.0.1.
$ svn copy http://svn.exemple.com/projets/vendor/libcomplex-1.0.0 \ http://svn.exemple.com/projets/vendor/libcomplex-1.0.1 \ -m "Construction de la zone pour accueillir libcomplex 1.0.1." Révision 1282 propagée. $
Nous avons besoin maintenant d'avoir une copie de travail de
notre branche libcomplex-1.0.1 et de la faire ressembler à
libcomplex 1.0.1. Pour ce faire, nous allons profiter du fait
que svn checkout peut agir en superposition
dans un répertoire existant et, si l'option
--force
est fournie, alors les différences
entre l'arborescence extraite et l'arborescence cible sur
laquelle est appliquée l'extraction sont marquées comme
modifications locales de la nouvelle copie de travail.
$ tar xvfz libcomplex-1.0.1.tar.gz libcomplex-1.0.1/ libcomplex-1.0.1/README libcomplex-1.0.1/LICENSE … libcomplex-1.0.1/src/code.c libcomplex-1.0.1/tests libcomplex-1.0.1/tests/TODO $ svn checkout http://svn.exemple.com/projets/vendor/libcomplex-1.0.1 \ libcomplex-1.0.1 \ --force E libcomplex-1.0.1/README E libcomplex-1.0.1/LICENSE E libcomplex-1.0.1/INSTALL … E libcomplex-1.0.1/src/code.c E libcomplex-1.0.1/tests E libcomplex-1.0.1/tests/TODO Révision 1282 extraite. $ svn status libcomplex-1.0.1 M libcomplex-1.0.1/src/code.h M libcomplex-1.0.1/src/code.c M libcomplex-1.0.1/README $
Comme vous pouvez le constater, après avoir extrait ce qu'était réellement libcomplex 1.0.0 « par dessus » l'archive décompressée de libcomplex 1.0.1, nous obtenons une copie de travail avec des modifications locales (les modifications qui correspondent aux différences entre la précédente version du fournisseur que nous avions intégrée et la nouvelle).
Certes, c'est un exemple particulièrement simple. Les modifications pour effectuer la mise à niveau ne font intervenir que quelques modifications dans des fichiers existants. Dans la réalité, les nouvelles versions des bibliothèques tierces ajoutent ou déplacent sûrement des fichiers ou des dossiers, renomment des fichiers ou des dossiers, etc. Dans ces cas, il sera plus compliqué de calquer la nouvelle version étiquetée avec la livraison qu'elle est censée représenter. Nous laissons en exercice au lecteur la résolution des détails de cette transformation[46].
Quelle que soit la manière dont nous y sommes arrivés, nous disposons maintenant d'une copie de travail de la nouvelle version étiquetée qui reflète exactement la livraison originale du fournisseur. Nous pouvons maintenant propager ces modifications à notre dépôt.
$ svn commit -m "Mise à niveau de la branche fournisseur vers libcomplex 1.0.1." \ libcomplex-1.0.1 Envoi libcomplex-1.0.1/README Envoi libcomplex-1.0.1/src/code.h Envoi libcomplex-1.0.1/src/code.c Transmission des données ... Révision 1283 propagée. $
Nous sommes finalement prêt à mettre à niveau notre branche fournisseur, notre but étant d'obtenir les changements faits par le fournisseur entre les versions 1.0.0 et 1.0.1 de sa bibliothèque dans notre branche fournisseur. C'est là que la forme à 2-URL de svn merge, appliquée à une copie de travail de notre branche fournisseur, entre en scène.
$ svn checkout http://svn.exemple.com/projets/vendor/libcomplex-perso \ libcomplex-perso E libcomplex-perso/README E libcomplex-perso/LICENSE E libcomplex-perso/INSTALL … E libcomplex-perso/src/code.c E libcomplex-perso/tests E libcomplex-perso/tests/TODO Révision 1283 extraite. $ cd libcomplex-perso $ svn merge ^/vendor/libcomplex-1.0.0 \ ^/vendor/libcomplex-1.0.1 --- Fusion des différences entre les URL du dépôt dans '.' : U src/code.h C src/code.c U README Résumé des conflits : Text conflicts: 1 Conflit découvert dans le fichier 'src/code.c'. Select: (p) postpone, (df) diff-full, (e) edit, (m) merge, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options:
Comme vous pouvez le constater, svn merge a fusionné les modifications demandées dans notre copie de travail, marquant un conflit où le fournisseur a modifié la même zone d'un fichier que nous lors de notre personnalisation. Subversion détecte le conflit et nous donne l'opportunité de le résoudre (en utilisant les méthodes décrites dans la section intitulée « Résolution des conflits ») de façon à ce que nos personnalisations relatives à ce qui est maintenant libcomplex 1.0.1 fassent toujours sens. Une fois que nous avons résolu les conflits et effectué les tests et revues nécessaires, nous pouvons propager les modifications à notre branche fournisseur.
$ svn status M src/code.h M src/code.c M README $ svn commit -m "Mise à niveau de la branche fournisseur vers libcomplex 1.0.1." Envoi README Envoi src/code.h Envoi src/code.c Transmission des données ... Révision 1294 propagée. $
La mise à niveau de notre branche fournisseur est terminée. Et la prochaine fois que nous aurons besoin de mettre à niveau cette branche, nous suivrons la même procédure.
Créer une branche ou ne pas créer une branche ? Voilà une question intéressante. Ce chapitre vous a montré jusqu'à maintenant force détails quant aux créations de branches et aux fusions, des sujets qui ont historiquement été la plus grande source de confusion pour les utilisateurs. Comme si l'enchainement mécanique des actions qui sont mises en œuvre dans la création et la fusion de branches n'était pas assez compliqué, quelques utilisateurs restent à se demander si cela vaut le coup de créer une branche ou pas. Comme vous l'avez appris, Subversion gère les scénarios classiques de création et gestion de branches. Ainsi, la décision de créer ou pas une branche d'un projet ne relève pas de critères techniques. C'est davantage les impacts sociaux qui pèsent le plus dans la décision. Examinons quelques avantages et inconvénients d'utiliser des branches dans un projet logiciel.
Le bénéfice le plus évident de travailler sur une branche est l'isolation. Les modifications faites à la branche n'affectent pas les autres lignes de développement du projet ; les modifications des autres lignes n'affectent pas la branche. Dans un certain sens, une branche peut servir de terrain d'expérimentation de nouvelles fonctionnalités, de correction pour des bogues complexes, des réécritures majeures du code, etc. Peu importe la quantité de choses cassées dans la branche de Sally, Harry et le reste de l'équipe peuvent continuer leur travail sans entrave, en dehors de la branche.
Les branches fournissent aussi un mécanisme très élégant pour organiser les modifications qui sont reliées entre elles dans des ensembles immédiatement reconnaissables. Par exemple, les modifications qui résolvent complètement un bogue particulier peuvent se trouver dans une liste de révisions dont les numéros ne se suivent pas. Vous pouvez les énoncer comme « les révisions 1534, 1543, 1587 und 1588 ». Vous les indiquerez sûrement à la main (ou autrement) dans le système de suivi de bogues qui prend en compte ce bogue. Lorsque vous porterez cette correction de bogue vers d'autres versions du produit, vous devrez vous assurer que vous n'oubliez aucune révision. Mais si ces modifications ont toutes été faites dans la même branche, vous pourrez vous référer uniquement à cette branche, par son nom, dans les conversations, dans les commentaires du système de suivi de bogues et lorsque vous portez les modifications ailleurs.
L'inconvénient des branches, cependant, c'est que cette isolation forte qui les rend si utiles peut parfois aller à l'encontre du besoin de collaboration de l'équipe de projet. En fonction des habitudes de travail de vos collègues, les modifications faites à votre branches ne recevront peut-être pas toutes les revues, critiques et tests que subissent les changements de la ligne principale de développement. L'isolation de la branche peut encourager les utilisateurs à oublier certaines bonnes pratiques de la gestion de versions, entrainant un historique des versions difficile à exploiter a posteriori. Les développeurs de branches à longue durée de vie doivent parfois travailler beaucoup plus dur pour s'assurer que la direction vers laquelle évolue leur branche isolée est bien en harmonie avec la direction prise par leurs collègues dans la ligne de développement principale. Maintenant, ces inconvénients peuvent s'avérer sans objet si le développement de la branche consiste justement à explorer une nouvelle souche du logiciel dont le résultat n'a pas vocation à réintégrer la ligne de développement principale (l'application stricte des politiques de développement ne doit pas freiner l'innovation !). En tout état de cause, les projets retirent en général un bon bénéfice d'une approche méthodique dans la gestion de versions où le code et les modifications font l'objet d'un passage en revue et de compréhension par plus d'un membre de l'équipe.
En fin de compte, nous ne proclamons pas qu'il n'y a aucun
inconvénient technique à créer des branches. Pardonnez-nous de
« diverger » quelque peu dans ce paragraphe. Si vous
réfléchissez bien, à chaque fois que vous extrayez une copie de
travail Subversion, vous créez en quelque sorte une branche de
votre projet. C'est une branche d'une sorte un peu spéciale, qui
ne réside que sur la machine cliente, pas dans le dépôt. Vous
synchronisez cette branche avec les modifications faites dans le
dépôt par la commande svn update (qui agit
d'une certaine manière comme une version simplifiée de la commande
svn merge
[47].
Vous réintégrer effectivement la branche à chaque fois que vous
lancez svn commit. Ainsi, dans un certain sens,
les utilisateurs de Subversion créent des branches et les
fusionnent sans arrêt. Compte tenu des similitudes entre la mise
à jour et la fusion, il n'est pas étonnant que les points durs de
Subversion (la gestion des renommages des fichiers et de dossiers
ainsi que les conflits d'arborescences) soient aussi
problématiques pour les opérations svn update
et svn merge. Malheureusement, svn
merge souffre encore plus, précisément parce que, alors
que svn update n'est qu'un cas particulier,
simplifié, d'une opération de fusion, une véritable opération de
fusion Subversion n'est pas un cas particulier ou simplifié. C'est
pourquoi les opérations de fusion sont beaucoup plus lentes de les
mises à jour, demandent d'avoir un traçage de l'historique
(via la propriété
svn:mergeinfo
que nous avons abordée dans ce
chapitre) et des calculs sur cet historique, introduisant
généralement beaucoup d'occasions pour que quelque chose se passe
de travers.
Créer une branche ou ne pas créer une branche ? Finalement, cela dépend des besoins de votre équipe pour trouver le juste équilibre entre le travail collaboratif et l'isolation.
Nous avons traité de nombreux sujets dans ce chapitre. Nous avons présenté les concepts d'étiquettes et de branches et montré comment Subversion implémente ces concepts en copiant des répertoires avec la commande svn copy. Nous avons expliqué comment utiliser svn merge pour copier des modifications d'une branche à l'autre ou pour revenir en arrière sur des modifications non-satisfaisantes. Nous avons étudié l'utilisation de svn switch pour créer des copies de travail mixtes, pointant vers des emplacements variés d'un dépôt. Et nous avons évoqué la façon dont on peut gérer l'organisation et le cycle de vie des branches dans un dépôt.
Tâchez de garder en mémoire la devise de Subversion : les branches et les étiquettes ne coûtent quasiment rien. Donc n'ayez pas peur de les utiliser quand vous en avez besoin !
En guise de pense-bête face à toutes les opérations dont nous avons parlé, voici un tableau de référence très pratique, à consulter lorsque vous commencerez à utiliser des branches.
Tableau 4.1. Commandes de gestion des branches et des fusions
Action | Commande |
---|---|
Créer une branche ou une étiquette | svn copy |
Faire pointer une copie de travail vers une branche ou une étiquette | svn switch |
Synchroniser une branche avec le tronc | svn merge |
Voir l'historique des fusions ou les ensembles de modifications susceptibles d'être fusionnés | svn mergeinfo |
Réintégrer une branche dans le tronc | svn merge |
Fusionner une modification précise | svn merge -c |
Fusionner un intervalle de modifications | svn merge -r |
Empêcher qu'une modification ne soit fusionnée automatiquement | svn merge -c |
Prévisualiser une fusion | svn merge |
Abandonner une fusion | svn revert -R . |
Ressusciter un élément de l'historique | svn copy |
Revenir en arrière sur une modification déjà propagée | svn merge -c - |
Examiner l'historique en tenant compte des informations de fusion | svn log -g; svn blame -g |
Créer une version étiquetée à partir d'une copie de travail | svn copy . |
Réorganiser une branche ou une version étiquetée | svn move |
Supprimer une branche ou une version étiquetée | svn delete |
[32] Subversion n'accepte pas les copies entre des dépôts distincts. Quand vous utilisez des URLs avec svn copy et svn move, vous ne pouvez copier que des éléments faisant partie du même dépôt.
[33] Cette notation a été introduite par Subversion 1.6
[34] L'option
--allow-mixed-revisions
de la sous-commande
svn merge vous permet de lever cette
interdiction, mais vous ne devriez le faire que si vous
comprenez les implications et que vous avez une bonne raison de
le faire.
[35] Depuis Subversion 1.7 vous n'avez pas absolument besoin de resynchroniser complètement votre branche avec le tronc comme nous le faisons dans cet exemple. Si votre branche est effectivement synchronisée par une série de fusions d'arborescences alors la réintégration fonctionnera, mais demandez-vous, si la branche est effectivement synchronisée, pourquoi effectuez-vous des fusions d'arborescences ? Le faire est pratiquement toujours inutilement complexe.
[36] les fusions de réintégration automatiques sont autorisées si la cible est une extraction partielle (voir la section intitulée « Répertoires clairsemés »), mais alors chaque chemin concerné par le calcul de différence et qui est « absent » en raison de l'extraction partielle sera ignoré, ce qui n'est probablement pas ce que vous recherchez !
[37] Seul Subversion 1.8 autorise cette réutilisation d'une branche. Les précédentes versions demandaient quelques manipulations préalables afin de pouvoir réintegrer à nouveau une branche. Consultez les versions antérieures de ce chapitre pour plus d'informations : https://svnbook.red-bean.com/fr/1.5/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.reintegrate
[38] Par « direction », nous entendons les fusions soit du tronc vers la branche (synchronisation automatique), soit de la branche vers le tronc (réintégration automatique).
[39] C'est un bon exemple de révisions non-effectives pour la fusion.
[40] Le projet Subversion prévoit néanmoins d'implémenter, un jour, une commande qui accomplirait la tâche de supprimer des informations de façon permanente. En attendant, en guise de palliatif, voir la section intitulée « svndumpfilter ».
[41] À noter qu'après être revenu en arrière sur une
révision de cette manière, nous ne serions plus
capables de ré-appliquer cette révision avec
svn merge . -c 5
, puisque
les informations de fusion marqueraient déjà r5 comme
ayant été appliquée. Nous serions alors obligés
d'utiliser l'option --ignore-ancestry
pour forcer la commande de fusion à ignorer le contenu
de mergeinfo !
[42] Si Sally n'avait pas propagé ses
modifications dans r472, alors Subversion aurait remarqué que
entier.c
dans la copie de travail cible
était identique à entier.c
du côté gauche
de la fusion et aurait permis le succès de votre renommage sans
conflit d'arborescence :
$ svn merge ^/calc/branches/ma-branche-calc --- Fusion des différences entre les URLs du dépôt dans '.' : U src/reel.c A src/tout.c D src/entier.c --- Stockage des informations de fusion (mergeinfo) des URLs du dépôt dans '.' : U .
[43] Vous pouvez cependant utiliser svn relocate si l'URL de votre serveur change et si vous ne voulez pas abandonner votre copie de travail existante. Reportez-vous à svn relocate dans Guide de référence de svn : le client texte interactif pour des détails et des exemples.
[44] Techniquement, nous pourrions laisser la fonctionnalité auto-props faire son travail mais l'essentiel,c'est que chaque archive du fournisseur subisse exactement le même traitement pour les propriétés automatiques.
[45] Utiliser une autre svn import ne serait pas correct, puisque libcomplex 1.0.1 et 1.0.0 se retrouveraient sans aucun ancêtre commun.
[46] Un début de solution peut
être :svn add --force
/chemin/vers/copie-de-travail --no-ignore
--no-auto-props
est super pratique pour ajouter tout
nouvel élément de la version fournisseur en suivi de versions
dans cette situation.
[47] En fait, vous pourriez
utiliser svn merge
-r
dans votre copie de travail pour fusionner toutes
les modifications en provenance du dépôt depuis votre dernière
extraction si vous le vouliez !DERNIERE_REV_EXTRAITE
:HEAD
.
Le dépôt Subversion est le centre de stockage de toutes vos données suivies en versions. Ainsi, il est de facto l'objet de toute l'attention et de tous les soins de l'administrateur. Bien que ce soit un élément ne nécessitant pas énormément de maintenance, il est important de comprendre comment le configurer et le surveiller de manière à éviter d'éventuels problèmes et à résoudre proprement ceux qui se présentent.
Dans ce chapitre, nous expliquons comment créer et configurer un dépôt Subversion. Nous abordons également la maintenance du dépôt, en donnant des exemples d'utilisation des divers outils fournis avec Subversion. Nous étudions quelques questions et erreurs communes et nous donnons des conseils sur l'organisation des données dans le dépôt.
Si vous n'envisagez pas d'utiliser un dépôt Subversion autrement qu'en simple utilisateur des données (c'est-à-dire en utilisant un client Subversion), vous pouvez sauter ce chapitre. Cependant, si vous êtes (ou si vous êtes appelé à être) l'administrateur d'un dépôt[48], ce chapitre est fait pour vous.
Avant d'aborder le vaste sujet de l'administration d'un dépôt, définissons plus précisément ce qu'est un dépôt. À quoi ressemble-t-il ? Que ressent-il ? Est-ce qu'il préfère son thé chaud ou glacé, sucré, avec une tranche de citron ? En tant qu'administrateur, vous vous devez de comprendre de quoi est composé un dépôt, à la fois au niveau du système d'exploitation (à quoi ressemble le dépôt et comment il réagit vis-à-vis des outils autres que Subversion) et au niveau logique de l'organisation des données (comment elles sont représentées à l'intérieur du dépôt).
Du point de vue d'un explorateur de fichiers classique (comme Windows Explorer) ou d'un outil de navigation du système de fichiers en ligne de commande, un dépôt Subversion n'est rien d'autre qu'un répertoire contenant plein de choses. Il y a des sous-dossiers avec des fichiers de configuration lisibles par un humain, des sous-dossiers avec des fichiers de données binaires déjà bien moins lisibles, etc. À l'instar d'autres parties de Subversion, la modularité est une préoccupation majeure et l'organisation hiérarchique prévaut sur le bazar. Ainsi, un rapide coup d'œil dans un dépôt ordinaire est suffisant pour obtenir la liste des composants essentiels d'un dépôt :
$ ls dépot conf/ db/ format hooks/ locks/ README.txt
Effectuons un survol rapide de ce que nous voyons dans ce répertoire (ne vous inquiétez pas si vous ne comprenez pas tous les termes employés, ils sont expliqués dans ce chapitre ou ailleurs dans ce livre) :
Un dossier destiné à accueillir les fichiers de configuration.
Le magasin de données pour toutes vos données suivies en versions[49].
Ce fichier décrit le schéma d'organisation interne du
dépôt. Il se trouve que le sous-dossier
db
contient parfois aussi un fichier
format
qui ne décrit que le contenu de
ce sous-dossier et ne doit pas être confondu avec ce
fichier.
Ce dossier contient les modèles de procédures automatiques (et les procédures automatiques elles-mêmes, une fois installées).
Ce répertoire est utilisé pour les fichiers de verrous du dépôt Subversion, de façon à gérer les accès concurrents au dépôt.
Un petit fichier qui ne fait qu'informer son lecteur qu'il se trouve dans un dépôt Subversion.
Note | |
---|---|
Avant Subversion 1.5, la structure du dépôt sur le
disque contenait toujours un sous-dossier
|
Bien sûr, quand on y accède via les bibliothèques Subversion, cet ensemble de fichiers et de dossiers se transforme en un système de fichiers suivis en versions virtuel, complet et comportant une gestion des événements personnalisable. Ce système de fichiers possède ses propres notions de répertoires et de fichiers, très similaires aux notions des systèmes de fichiers réels (tels que NTFS, FAT32, ext3, etc.). Mais c'est un système de fichiers spécial : il base ces répertoires et ces fichiers sur les révisions, conservant l'historique de tous les changements effectués de manière sûre et pérenne. C'est là que la totalité de vos données suivies en versions réside.
En grande partie grâce à la conception épurée du dépôt Subversion et des technologies sous-jacentes, il est particulièrement aisé de créer et configurer un dépôt. Il y a quelques choix préliminaires à faire mais l'essentiel du travail de création et de configuration d'un dépôt Subversion est simple et convivial, facilement reproductible si vous êtes amené à effectuer des installations multiples.
Voici quelques questions à se poser avant toute chose :
Quelles données vont être hébergées dans le dépôt (ou les dépôts) et quelle en sera l'organisation ?
Où sera placé le dépôt et comment les utilisateurs y accéderont-ils ?
De quels types de contrôle d'accès avez-vous besoin ?
Dans cette section, nous essayons de vous aider à répondre à ces questions.
Bien que Subversion vous permette de déplacer des fichiers et des répertoires suivis en versions sans perte d'information et qu'il fournisse même des outils pour déplacer des ensembles complets de données suivies en version d'un dépôt à un autre, ces opérations peuvent perturber le travail des autres collaborateurs qui accèdent souvent au dépôt et qui s'attendent à trouver chaque chose à sa place. Ainsi, avant de créer un nouveau dépôt, essayez de vous projeter un peu dans le futur ; préparez à l'avance le passage de vos données sous gestion de versions. Cette réflexion sur la manière d'organiser vos données dans le dépôt vous évitera de futurs et nombreux maux de tête.
Supposons qu'en tant qu'administrateur d'un dépôt, vous êtes responsable de l'administration du système de gestion de versions pour plusieurs projets. La première décision à prendre est de choisir entre un seul dépôt pour tous les projets et un dépôt par projet, ou bien un compromis entre ces deux solutions.
Un seul dépôt pour tous les projets offre des avantages, ne serait-ce que pour la maintenance unifiée. Un seul dépôt signifie qu'il n'y a qu'un seul jeu de procédures automatiques, une seule sauvegarde à gérer, un seul jeu d'opérations de déchargement et de chargement à effectuer si la nouvelle version de Subversion est incompatible avec l'ancienne version, etc. Vous pouvez également déplacer facilement des données entre les projets, sans perdre l'historique de ces informations.
Les inconvénients à utiliser un seul dépôt sont que les différents projets auront certainement des besoins différents en termes de gestion des événements, comme la notification par e-mail des propagations à des listes d'adresses différentes ou des définitions différentes de ce qui constitue une propagation légitime. Bien sûr, ce ne sont pas des problèmes insurmontables — cela implique juste que vos procédures automatiques doivent tenir compte de l'organisation du dépôt dans lequel elles sont invoquées plutôt que de considérer que l'ensemble du dépôt est associé à un seul groupe d'utilisateurs. Rappelez-vous également que Subversion utilise des numéros de révisions globaux au dépôt. Bien que ces numéros ne possèdent pas de pouvoirs magiques particuliers, certaines personnes n'aiment pas voir le numéro de révision augmenter alors qu'elles n'ont pas touché à leur propre projet[52].
On peut aussi adopter une approche intermédiaire. Par exemple, les projets peuvent être regroupés par thème. Vous pouvez avoir quelques dépôts, avec une poignée de projets dans chaque dépôt. Ainsi, les projets susceptibles de partager des données le font aisément et les développeurs sont tenus au courant des avancées des projets en relation avec les leurs par le biais des nouvelles révisions du dépôt.
Une fois l'organisation des dépôts définie, il faut se
préoccuper de la hiérarchie des répertoires à l'intérieur des
dépôts eux-mêmes. Comme Subversion utilise de simples copies de
répertoires pour créer les branches et les étiquettes (voir le
Chapitre 4, Gestion des branches), la communauté Subversion
recommande de choisir un endroit dans le dépôt pour la
racine de chaque projet (le répertoire
dont la sous-arborescence contient toutes les données relatives
à un projet) et d'y placer trois sous-répertoires :
trunk
(« tronc » en français),
le dossier qui héberge les principaux développements
du projet ; branches
, le dossier
dans lequel seront créées les différentes variations de la
ligne de développement principale ; et
tags
(« étiquettes » en
français), qui contient un ensemble d'instantanés de
l'arborescence (les instantanés sont créés, voire détruits, mais
jamais modifiés)[53].
Par exemple, votre dépôt peut ressembler à ceci :
/
calc/
trunk/
tags/
branches/
calendrier/
trunk/
tags/
branches/
tableur
trunk/
tags/
branches/
…
Veuillez noter que l'emplacement du projet dans le dépôt n'est pas important. Si vous n'avez qu'un seul projet par dépôt, il est logique de placer la racine du projet à la racine du dépôt correspondant. Si vous avez plusieurs projets, vous voulez peut-être les classer par groupes dans des sous-répertoires communs du dépôt, en fonction des objectifs ou du code à partager par exemple, ou tout simplement en les groupant par ordre alphabétique. Voici un exemple :
/
utilitaires
calc/
trunk/
tags/
branches/
calendrier
trunk/
tags/
branches/
…
bureautique/
tableur/
trunk/
tags/
branches/
…
Organisez votre dépôt comme vous le sentez. Subversion n'a aucune exigence en la matière — pour lui, un répertoire est un répertoire. L'objectif est d'avoir une organisation qui réponde aux besoins des collaborateurs des différents projets.
Cependant, par souci de transparence, nous indiquons une
autre organisation également très répandue. Dans cette
organisation, les répertoires trunk
,
tags
et branches
sont
situés à la racine du dépôt et les projets sont placés dans des
sous-répertoires juste en dessous, comme ceci :
/
trunk/
calc/
calendrier/
tableur/
…
tags/
calc/
calendrier/
tableur/
…
branches/
calc/
calendrier/
tableur/
…
Il n'y a rien d'incorrect dans une telle organisation, mais elle peut ne pas être très intuitive pour vos utilisateurs. En particulier dans des situations complexes avec plusieurs projets et un grand nombre d'utilisateurs, dont la plupart ne connaissent qu'un ou deux projets du dépôt. Mais cette approche « plusieurs projets par branche » a tendance à favoriser l'ouverture de chaque projet sur les autres et pousse à envisager l'ensemble des projets comme une seule entité. Cela reste un problème social. Nous aimons l'organisation suggérée au début pour des raisons purement pratiques : il est plus facile de faire des requêtes (ou des modifications, des migrations) sur l'historique complet d'un projet quand une sous-arborescence du dépôt contient l'ensemble des données (passé, présent, étiquettes et branches) de ce projet et elles seules.
Avant de créer votre dépôt Subversion, vous devez vous demander où il va résider. Cette question est fortement liée à une myriade d'autres questions telles que : qui sont les utilisateurs (sont-ils à l'intérieur de votre réseau interne, derrière le pare-feu de votre entreprise, ou bien s'agit-il de n'importe qui, n'importe où sur Internet ?), comment les utilisateurs accèdent au dépôt (via un serveur Subversion ou directement), quels autres services vous fournissez autour de Subversion (une interface pour navigateur Web, des notifications par email des propagations, etc.), quelle est votre politique de sauvegarde et ainsi de suite.
Le choix et la configuration du serveur sont abordés au Chapitre 6, Configuration du serveur, mais nous voulons signaler dès maintenant que certains choix pour l'une ou l'autre de ces questions ont des implications sur l'endroit où implémenter votre serveur. Par exemple, certains scénarios de déploiement nécessitent, pour plusieurs ordinateurs, l'accès au dépôt via un système de fichiers distant ou l'utilisation de plusieurs dépôts dont les contenus sont répartis géographiquement afin d'offrir des accès performants à tous les utilisateurs quels que soient leurs emplacements. Étudier chaque cas possible de déploiement de Subversion est à la fois impossible et hors du champ de ce livre. Nous vous encourageons simplement à considérer les différentes options présentées dans ces pages et ailleurs dans d'autres références, puis de planifier vos déploiements en conséquence.
Le contrôle d'accès dans Subversion est presqu'entièrement géré par le processus serveur. Nous abordons les serveurs fournis par Subversion dans Chapitre 6, Configuration du serveur et nous expliquons le contrôle d'accès basé sur les chemins spécifiquement dans la section intitulée « Contrôle d'accès basé sur les chemins ». En complément du contrôle d'accès des utilisateurs, vous devez vous assurer de l'accès à votre dépôt par les programmes hébergés sur votre machine et qui ont besoin cet accès. Là encore, reportez-vous à Chapitre 6, Configuration du serveur pour trouver toutes les informtions utiles pour prendre vos décisions.
Dans ce chapitre (dans la section intitulée « Stratégies de déploiement d'un dépôt »), nous avons passé en revue quelques décisions importantes à prendre avant de créer et de configurer votre dépôt Subversion. Maintenant nous allons enfin mettre les mains dans le cambouis ! Dans cette section, nous voyons comment créer un dépôt Subversion et comment le configurer pour qu'il effectue des actions personnalisées lorsque certains événements ont lieu.
La création d'un dépôt Subversion est une tâche incroyablement simple. L'utilitaire svnadmin, fourni avec Subversion, dispose d'une sous-commande qui est justement destinée à cela (svnadmin create) :
$ # Créer un dépôt $ svnadmin create /var/svn/depot $
Si l'on considère que le répertoire parent
/var/svn
existe déjà et que vous avez les
droits suffisants pour modifier ce répertoire, la commande
précédente crée un nouveau dépôt dans le répertoire
/var/svn/depot
avec le magasin de données
par défaut (FSFS). Vous pouvez choisir explicitement le type de
système de fichiers avec l'option --fs-type
qui
accepte comme argument soit fsfs
,
soit bdb
.
$ # Créer un dépôt FSFS $ svnadmin create --fs-type fsfs /var/svn/depot $
$ # Créer un dépôt Berkeley DB $ svnadmin create --fs-type bdb /var/svn/depot $
Après l'exécution de cette simple commande, vous disposez d'un dépôt Subversion. En fonction de la manière dont vos utilisateurs accéderont à ce nouveau dépôt, vous aurez peut-être besoin de bidouiller les droits du système de fichiers. Mais comme l'administration système de base est plutôt hors de propos dans ce livre, nous laissons en exercice au lecteur le soin d'explorer plus avant ce sujet.
Astuce | |
---|---|
Le chemin en argument de svnadmin est
juste un chemin classique du système de fichiers, pas une URL
comme celles que le client svn utilise pour
spécifier un dépôt. Les commandes svnadmin
et svnlook sont toutes les deux considérées
comme des utilitaires coté serveur : elles sont utilisées
sur la machine qui héberge le dépôt pour examiner ou modifier
certains aspects du dépôt et ne sont pas capables d'effectuer
des actions via le réseau. Une erreur classique des nouveaux
utilisateurs de Subversion est d'essayer de passer une URL
(même « locale » comme |
Dans le sous-répertoire db/
de votre
dépôt, vous trouvez l'implémentation du système de fichiers
suivi en versions. Le nouveau système de fichiers suivi en
versions de votre dépôt commence sa vie à la révision 0, qui est
définie comme contenant le répertoire racine
(/
) et lui seul. Initialement, la révision
0 possède une seule propriété de révision,
svn:date
, dont la valeur est la date de
création du dépôt.
Maintenant que vous disposez d'un dépôt, il est temps de le personnaliser.
Avertissement | |
---|---|
Alors que certaines parties d'un dépôt Subversion sont conçues pour être examinées et modifiées « à la main » (comme les fichiers de configuration et les procédures automatiques), vous ne devez pas (et vous ne devriez pas avoir besoin de) modifier les autres parties « à la main ». L'outil svnadmin est censé être suffisant pour toutes les modifications à apporter à votre dépôt, mais vous pouvez également vous servir d'outils tiers pour configurer les parties adéquates du dépôt. Ne tentez surtout pas de manipuler manuellement l'historique du suivi de versions en touchant aux fichiers du magasin de données du dépôt ! |
Une procédure automatique (hook en anglais) est un programme activé par certains événements du dépôt, comme la création d'une nouvelle révision ou la modification d'une propriété non suivie en versions. Certaines procédures automatiques (appelées « pré-hooks ») sont déclenchées avant l'opération sur le dépôt et permettent à la fois de rendre compte de ce qui va se passer et d'empêcher que cela se passe. D'autres procédures automatiques (appelées « post-hooks ») sont déclenchées après la fin d'un événement et servent à effectuer des tâches de surveillance (mais pas de modification) du dépôt. Chaque procédure automatique reçoit suffisamment d'informations pour déterminer la nature de l'événement, les modifications proposées (ou effectuées) du dépôt et le nom d'utilisateur de la personne qui a déclenché l'événement.
Le sous-répertoire hooks
contient, par
défaut, des modèles pour diverses procédures
automatiques :
$ ls depot/hooks/ post-commit.tmpl post-unlock.tmpl pre-revprop-change.tmpl post-lock.tmpl pre-commit.tmpl pre-unlock.tmpl post-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl $
Il y a un modèle pour chaque type de procédure automatique
que le dépôt Subversion sait prendre en charge ; en
examinant le contenu de ces modèles de scripts, vous pouvez
voir ce qui déclenche le script et quelles données sont passées
en paramètres. Vous trouvez également dans beaucoup de ces
scripts des exemples d'utilisation permettant de réaliser des
tâches récurrentes utiles, en conjonction avec d'autres
programmes fournis avec Subversion. Concrètement, pour activer
une procédure automatique, il suffit de placer dans le
répertoire depot/hooks
un programme ou un
script exécutable, qui sera invoqué
via le nom de la procédure
automatique (comme start-commit pour le début
d'une propagation ou post-commit pour la fin
d'une propagation).
Sur les plateformes Unix, cela veut dire fournir un
programme ou un script (pouvant être un script shell, un
programme Python, l'exécutable binaire d'un programme en C ou
tout un tas d'autres choses) dont le nom est exactement le nom
de la procédure automatique. Bien sûr, les modèles qui sont
fournis ne le sont pas juste à titre d'information. Le moyen le
plus facile pour mettre en place une procédure automatique sur
les plateformes Unix consiste tout simplement à copier le
fichier du modèle adéquat vers un nouveau fichier qui n'aura
pas l'extension .tmpl
, d'adapter son
contenu à votre environnement et de vous assurer qu'il est
exécutable. Sous Windows, comme l'extension du fichier détermine
s'il est exécutable ou non, vous devez fournir un programme
dont la base du nom est le nom de la procédure automatique et
dont l'extension est l'une de celles reconnue comme exécutable
par Windows, comme .exe
pour les programmes
ou .bat
pour les fichiers batch.
Les procédures automatiques de Subversion sont lancées par l'utilisateur propriétaire du processus ayant accès au dépôt Subversion. La plupart du temps, on accède au dépôt via un serveur Subversion, donc cet utilisateur est le même que celui qui fait tourner le processus serveur sur le système. Les procédures automatiques elles-mêmes doivent être configurées pour être exécutables, au niveau du système d'exploitation, par ledit utilisateur. Cela implique également que tout programme ou fichier (y compris le dépôt Subversion) utilisé directement ou indirectement par la procédure automatique l'est par ledit utilisateur. En d'autres termes, faites bien attention aux problèmes de droits d'accès et d'exécution qui peuvent empêcher les procédures automatiques d'effectuer correctement les tâches pour lesquelles elles ont été conçues.
Il y a plusieurs procédures automatiques implémentées dans le dépôt Subversion et vous pouvez obtenir des détails sur chacune d'elles dans Guide de référence des procédures automatiques de Subversion. En tant qu'administrateur du dépôt, vous devez décider quelles procédures automatiques vous voulez mettre en œuvre (c'est-à-dire les nommer correctement et leur donner les droits appropriés) et de quelle manière. Lorsque vous prenez cette décision, gardez à l'esprit l'architecture de votre dépôt. Par exemple, si vous vous servez de la configuration du serveur pour déterminer les droits de propagation sur votre dépôt, vous n'avez pas besoin de mettre en place un contrôle d'accès de ce style via les procédures automatiques.
Par défaut, le dépôt Subversion exécute les procédures
automatiques avec un environnement vide — c'est-à-dire
sans aucune variable d'environnement définie, même pas
$PATH
(ou %PATH%
sous Windows). C'est ainsi que de nombreux administrateurs
sont perplexes lorsque leurs programmes fonctionnent
correctement à la main mais pas dans Subversion. Assurez-vous
de définir explicitement toutes les variables d'environnement
nécessaires dans votre procédure automatique.
Subversion 1.8 introduit une nouvelle façon de gérer
l'environnement dans lequel s'exécutent les procédures
automatiques, le fichier de configuration de l'environnement
des procédures automatiques. Si le serveur Subversion trouve
un fichier nommé hooks-env
dans le
sous-répertoire conf/
du dépôt, il
analyse ce fichier à la manière d'un fichier .INI et insère
les options et variables qu'il a trouvées dans l'environnement
de la procédure automatique via
des variables d'environnement.
La syntaxe du fichier hooks-env
est
très simple : chaque nom de section correspond à la
procédure automatique à laquelle la section s'applique (tels
que [pre-commit]
ou
[post-revprop-change]
) et les éléments à
l'intérieur des sections sont les variables d'environnement
dont on souhaite définir les valeurs. En plus, il existe une
section générale [default]
, qui permet
de définir la valeur de variables d'environnement pour
toutes les procédures automatiques (sauf
si cette variable est explicitement redéfinie à l'intérieur
d'une section particulière à une procédure automatique).
Exemple 5.1, « hooks-env (configuration personnalisée de
l'environnement des procédures automatiques) »
fournit un exemple de fichier de configuration
hooks-env
.
Exemple 5.1. hooks-env (configuration personnalisée de l'environnement des procédures automatiques)
# Toutes les procédures seront configurées en français encodé en UTF-8 # et auront le répertoire contenant nos utilitaires dans leur chemin # par défaut. [default] LANG = fr_FR.UTF-8 PATH = /usr/local/svn/tools:/usr/bin # Les procédures post-commit et post-revprop-change ont aussi besoin # de nos programmes personnalisés pour la synchronisation [post-commit] PATH = /usr/local/synctools-1.1/bin:%(PATH)s [post-revprop-change] PATH = /usr/local/synctools-1.1/bin:%(PATH)s
Note | |
---|---|
Exemple 5.1, « hooks-env (configuration personnalisée de
l'environnement des procédures automatiques) »
montre aussi la fonctionnalité de substitution des chaînes
de caractères de l'analyseur du fichier de configuration.
Dans cet exemple, la valeur de l'option
|
Bien sûr, avoir exactement les mêmes informations dans
chaque fichier de configuration de l'environnement des
procédures automatiques, dans chaque répertoire
conf/
de chaque dépôt serait vite très
lourd, surtout quand vous devez les modifier tous. C'est
pourquoi le serveur Subversion vous permet de spécifier un
emplacement alternatif (possiblement partagé) pour ces
informations de configuration.
Les procédures automatiques du dépôt permettent de réaliser une large palette de fonctions, mais la plupart sont en fait utilisées pour quelques actions simples : la notification, la validation et la réplication.
Les procédures de notification sont celles qui indiquent
à quelqu'un que quelque chose est arrivé. Celles que l'on
retrouve le plus souvent dans l'utilisation de Subversion
envoient des courriels de compte-rendu de propagation (resp.
de modification de propriété de révision) aux membres du
projet, elles sont pilotées par la procédure automatique
post-commit
(resp.
post-revprop-change
). Il existe beaucoup
d'autres types de notification, depuis l'intégration dans
un outil de suivi de bogues jusqu'au robot IRC qui annonce
que quelque chose a changé dans le dépôt.
Pour ce qui concerne la validation, les procédures
automatiques start-commit
et
pre-commit
sont largement utilisées pour
autoriser ou interdire des propagations en fonction de
divers critères : l'auteur de la propagation, le format
ou le contenu du commentaire de propagation voire même des
détails de bas-niveau relatifs aux modifications faites aux
fichiers et dossiers par la propagation. De la même manière,
la procédure automatique pre-revprop-change
agit comme un point de passage obligé pour les modifications
des propriétés de révisions, ce qui est particulièrement utile
compte tenu du fait que les propriétés de révisions ne sont
pas suivies en versions et ne sont donc modifiées qu'en
détruisant l'ancienne valeur.
Une catégorie de validation des modifications se
généralise depuis la sortie de Subversion 1.5 : la
validation du logiciel client lui-même. Quand la
fonctionnalité de suivi des fusions (qui est décrite en
détails dans Chapitre 4, Gestion des branches) est apparue
dans Subversion 1.5, les administrateurs de Subversion ont eu
besoin de s'assurer que, une fois que certains commençaient à
utiliser cette fonctionnalité, alors tous
leurs fusions devaient être suivies. Afin de réduire la chance
que quelqu'un propage une fusion non suivie vers le dépôt, ils
ont utilisé la procédure automatique
start-commit
pour examiner les capacités
annoncées par le client Subversion. Si celui-ci n'indiquait
pas savoir suivre les fusions, la propagation était interdite
avec un message pour l'utilisateur lui indiquant de mettre à
niveau le client Subversion !
Exemple 5.2, « procédure automatique start-commit
qui s'assure que le client sait suivre les fusions. » donne un
exemple de script start-commit
qui
implémente précisément cette fonction.
Exemple 5.2. procédure automatique start-commit
qui s'assure que le client sait suivre les fusions.
#!/usr/bin/env python import sys # sys.argv[3] contient la liste, séparée par des ':', des capacités du client if 'mergeinfo' not in sys.argv[3].split(':'): sys.stderr.write("""\ ERREUR : les propagations (commit) vers ce dépôt ne sont possible qu'avec des clients qui savent suivre les fusions. Veuillez mettre à niveau votre client à Subversion 1.5 ou ultérieur. """) sys.exit(1)
Depuis Subversion 1.8, les clients qui propagent
des modifications sur un serveur Subversion 1.8 fournissent
toujours une chaîne indiquant leurs capacités mais fournissent
aussi des informations complémentaires les concernant en
utilisant des propriétés éphémères de
transaction. Ces propriétés éphémères de
transaction sont principalement des propriétés de révision qui
sont définies sur la transaction de propagation par le client
dès qu'il a l'occasion de le faire au moment de la
propagation. Elle sont automatiquement supprimées par le
serveur juste avant que la transaction ne devienne une
révision. Vous pouvez inspecter ces propriétés, pendant le
laps de temps séparant les procédures automatiques
start-commit
et
pre-commit
, à l'aide des
mêmes outils que ceux que vous utilisez pour inspecter les
autres propriétés non suivies en versions.
Vous trouverez ci-après les propriétés éphémères de transactions que Subversion reconnait actuellement :
svn:txn-client-compat-version
Contient la chaîne de caractères indiquant la version de la bibliothèque Subversion dont le client se réclame compatible. C'est utile pour décider si le client implémente le jeu de fonctionnalités suffisant pour gérer proprement les données du dépôt.
svn:txn-user-agent
Contient la chaîne de caractères décrivant le « programme utilisateur » (user agent en anglais) qui effectue la propagation. La bibliothèque Subversion définit la première partie de cette chaîne mais un programme tiers qui utilise l'API (client avec une interface graphique, etc.) peut y ajouter des informations personnalisées.
Note | |
---|---|
alors que la plupart des clients vont transmettre les
propriétés éphémères de transaction assez tôt dans le
processus de transaction et pouvoir ainsi être examinées par
la procédure automatique |
Comme nous l'avons déjà noté, les propriétés éphémères de
transaction sont supprimées de la transaction juste avant
qu'elle ne soit promue en nouvelle révision. Certains
administrateurs peuvent vouloir conserver les informations de
ces propriétés pour plus tard. Nous vous conseillons alors
d'utiliser la procédure automatique
pre-commit
pour copier les valeurs des
propriétés vers de nouvelles propriétés avec un nom différent.
En fait, le code source distribué avec Subversion fournit un
script persist-ephemeral-txnprops.py
(situé dans le dossier
tools/hook-scripts/
),
qui fait exactement cela.
La troisième catégorie que l'on rencontre souvent dans l'utilisation des procédures automatiques concerne la réplication. Que ce soit pour simplement faire une copie de sauvegarde ou pour un scénario impliquant des dépôts mirroirs, les procédures automatiques peuvent s'avérer critiques. Lisez la section intitulée « Sauvegarde d'un dépôt » et la section intitulée « Réplication d'un dépôt » pour davantage d'informations sur ces aspects de la maintenance du dépôt.
Comme vous pouvez l'imaginer, il n'est pas concevable
d'avoir un de procédures automatiques et de scripts divers
qui ne soient librement accessibles que ce soit au sein de la
communauté Subversion ou ailleurs. En fait, la distribution
Subversion fournit plusieurs procédures automatiques utilisées
un peu partout dans son répertoire
tools/hook-scripts/
.
Cependant, si vous ne trouvez pas votre bonheur dans ce
répertoire, vous pouvez écrire la vôtre. Lisez Chapitre 8, Intégration de Subversion pour obtenir des informations sur
le développement d'applications utilisant l'API publique de
Subversion.
Avertissement | |
---|---|
les procédures automatiques sont capables de faire tout et
n'importe quoi, mais leurs auteurs doivent faire preuve de
modération. Il pourrait être tentant, disons, d'utiliser les
procédures automatiques pour corriger automatiquement des erreurs,
des coquilles ou des violations de la politique dans les fichiers
propagés. Malheureusement, une telle action peut engendrer des
problèmes. Subversion conserve en cache, côté client, certaines
parties des données du dépôt et, si vous modifiez une transaction
de propagation de cette façon, ces caches seront périmés sans que
cela ne puisse être détecté. De telles incohérences peuvent
aboutir à des comportements surprenants et inattendus. Autant il
est généralement correct d'ajouter des propriétés de transaction
par une procédure automatique, autant tout le reste dans une
transaction de propagation doit être considéré comme en lecture
seule. Au lieu de modifier une transaction pour la rendre plus
policée, contentez-vous de vérifier la
transaction dans la procédure automatique
|
Avec Subversion 1.6, le système de fichiers FSFS possède
plusieurs paramètres que l'administrateur peut configurer pour
piloter finement les performances ou l'utilisation du disque
de leurs dépôts. Vous pouvez trouver ces options (et leur
documentation) dans le fichier db/fsfs.conf
du dépôt.
Assurer la maintenance d'un dépôt Subversion peut être intimidant, certainement parce que les systèmes qui comprennent une base de données sont complexes. Le faire bien est une question de maîtrise des outils — connaître leur fonction, quand les utiliser et comment. Cette section vous présente les outils fournis par Subversion pour assurer l'administration du dépôt et décrit leur maniement pour réaliser des opérations telles que migrations de données, mises à jour, sauvegardes et nettoyages.
Subversion fournit une poignée d'utilitaires pour créer, inspecter, modifier et réparer votre dépôt. Étudions de plus près chacun de ces outils.
Le programme svnadmin est le meilleur ami de l'administrateur de dépôts. En plus de fournir la possibilité de créer des dépôts Subversion, ce programme vous permet d'effectuer de nombreuses opérations de maintenance sur ces dépôts. La syntaxe de svnadmin est similaire à celle des autres programmes en ligne de commande de Subversion :
$ svnadmin help usage général : svnadmin SOUS_COMMANDE DÉPÔT [ARGS & OPTIONS ...] Entrer 'svnadmin help <sous-commande>' pour une aide spécifique. Entrer 'svnadmin --version' pour avoir la version et les modules de stockages. Sous-commandes disponibles : crashtest create deltify …
Au début de ce chapitre (dans la section intitulée « Création d'un dépôt »), nous vous avons présenté la sous-commande svnadmin create. Beaucoup d'autres sous-commandes svnadmin sont couvertes plus loin dans ce chapitre. Vous pouvez également consulter Guide de référence de svnadmin : administration des dépôts Subversion pour une liste complète des sous-commandes et des fonctionnalités qu'elles apportent.
svnlook est un outil de
Subversion pour examiner les différentes révisions et
transactions (qui sont des révisions en
cours de création) dans un dépôt. Aucune modification n'est
faite au dépôt par cet outil. svnlook
est généralement utilisé par les procédures automatiques du
dépôt pour signaler les changements qui vont être propagés
(dans le cas de la procédure automatique
pre-commit
) ou qui viennent d'être propagés
(dans le cas de la procédure automatique
post-commit
). Un administrateur peut être
amené à utiliser cet outil à des fins de diagnostic.
La syntaxe de svnlook est particulièrement simple :
$ svnlook help usage général : svnlook SOUS_COMMANDE CHEMIN_DÉPÔT [ARGS & OPTIONS...] Note : Quand --revision ou --transaction ne sont pas précisées, les sous- commandes qui en ont besoin utilisent la révision la plus récente. Entrer 'svnlook help <sous-commande>' pour une aide spécifique. Entrer 'svnlook --version' pour avoir la version et les modules de stockage. …
Beaucoup de sous-commandes svnlook
peuvent être appliquées soit à une révision soit à une
arborescence de transaction, affichant les informations à
propos de l'arborescence elle-même ou les différences par
rapport à la révision précédente du dépôt. Pour spécifier
quelle révision ou quelle transaction examiner, utilisez
respectivement les options --revision
(-r
) et --transaction
(-t
). En l'absence des options
--revision
(-r
)
ou --transaction
(-t
),
svnlook examine la révision la plus
récente (la révision HEAD
) du dépôt.
Ainsi, les deux commandes suivantes font exactement la même
chose si la révision la plus récente du dépôt situé à
l'emplacement /var/svn/depot
porte le
numéro 19 :
$ svnlook info /var/svn/depot $ svnlook info /var/svn/depot -r 19
Signalons une exception à ces règles concernant les sous-commandes : la sous-commande svnlook youngest ne prend aucune option et affiche simplement le numéro de la révision la plus récente du dépôt :
$ svnlook youngest /var/svn/depot 19 $
Note | |
---|---|
Gardez à l'esprit que les seules transactions que vous
pouvez examiner sont celles qui n'ont pas été propagées. La
plupart des dépôts ne comportent pas de transactions de ce
type parce que les transactions sont habituellement soit
propagées (auquel cas vous devriez y avoir accès sous la
forme de révisions via
l'option |
La sortie de svnlook est conçue pour être à la fois lisible par un humain et analysable par une machine. Prenons, par exemple, la sortie de la sous-commande svnlook info :
$ svnlook info /var/svn/depot sally 2002-11-04 09:29:13 -0600 (lun. 04 nov. 2002) 27 J'ai ajouté le traditionnel Arbre grec. $
La sortie de svnlook info est constituée des éléments suivants, par ordre d'apparition :
L'auteur, suivi d'un passage à la ligne.
La date, suivie d'un passage à la ligne.
Le nombre de caractères du commentaire de propagation, suivi d'un passage à la ligne.
Le commentaire de propagation lui-même, suivi d'un passage à la ligne.
Cette sortie est lisible par un humain, ce qui veut dire que les éléments tels que la date sont représentés par du texte simple au lieu d'un obscur code (comme le nombre de nanosecondes depuis le passage aux nouveaux francs). Mais cette sortie est aussi analysable par une machine — parce que le commentaire de propagation peut comporter plusieurs lignes et n'est pas limité en taille, svnlook affiche la longueur du commentaire avant le commentaire lui-même. Cela permet aux scripts et autres utilitaires faisant appel à cette commande de prendre des décisions opportunes à propos du commentaire de propagation, comme savoir combien de mémoire allouer pour le commentaire ou au moins savoir combien d'octets sauter dans le cas où les données affichées par svnlook ne sont pas les dernières données du flux.
svnlook peut répondre à un tas d'autres requêtes : afficher des sous-ensembles des informations précédemment citées, lister récursivement les arborescences suivies en versions des répertoires, lister les chemins modifiés lors de telle révision ou transaction, afficher les différences de contenu et de propriétés pour les fichiers et répertoires, etc. Reportez-vous à Guide de référence de svnlook : outil d'exploration du contenu d'un dépôt Subversion pour la liste complète des fonctionnalités offertes par svnlook.
Bien que ce ne soit pas l'outil qu'un administrateur utilise le plus, svndumpfilter fournit une fonctionnalité d'un genre très particulier qui est d'une grande utilité : la possibilité de modifier rapidement et facilement des flux de l'historique du dépôt Subversion en agissant en tant que filtre sur les chemins.
La syntaxe de svndumpfilter est la suivante :
$ svndumpfilter help usage général : svndumpfilter SOUS_COMMANDE [ARGS & OPTIONS ...] Entrer 'svndumpfilter help <sous-commande>' pour l'aide spécifique. Entrer 'svndumpfilter --version' pour avoir le numéro de version du programme. Sous-commandes disponibles : exclude include help (?, h)
Il n'y a que deux sous-commandes intéressantes : svndumpfilter exclude et svndumpfilter include. Elles vous permettent de choisir entre l'inclusion implicite et l'inclusion explicite des chemins dans le flux. Vous en saurez plus sur ces sous-commandes et sur l'utilité si particulière de svndumpfilter plus loin dans ce chapitre, dans la section intitulée « Filtrage de l'historique d'un dépôt ».
Le programme svnrdump est, pour faire simple, essentiellement une variante qui fonctionne avec un réseau des sous-commandes svnadmin dump et svnadmin load.
$ svnrdump help usage général : svnrdump SOUS_COMMANDE DÉPÔT [-r BAS[:HAUT]] Entrer 'svnrdump help <sous-commande>' pour une aide spécifique. Entrer 'svnrdump --version' pour la version et les modules d'accès (RA). Sous-commandes disponibles : dump load help (?, h) $
Nous entrerons dans le détail de l'utilisation des commandes svnrdump et svnadmin plus loin dans ce chapitre (voir la section intitulée « Migration des données d'un dépôt »).
Le programme svnsync fournit toutes les fonctionnalités requises pour faire fonctionner un miroir en lecture seule d'un dépôt Subversion. Ce programme a une et une seule fonction : transférer l'historique d'un dépôt vers un autre dépôt. Et, bien qu'il y ait différentes manières de faire, sa force réside dans sa capacité de travailler à distance : les dépôts « source » et « destination » peuvent être sur deux ordinateurs différents et svnsync sur un troisième.
Comme vous vous en doutez, svnsync possède une syntaxe très proche des autres programmes déjà mentionnés dans ce chapitre :
$ svnsync help usage général : svnsync SOUS_COMMANDE DÉPÔT [ARGS & OPTIONS ...] Entrer 'svnsync help <sous-commande>' pour une aide spécifique. Entrer 'svnsync --version' pour la version et les modules d'accès (RA). Sous-commandes disponibles : initialize (init) synchronize (sync) copy-revprops info help (?, h) $
Nous revenons en détail sur la réplication de dépôts avec svnsync plus loin dans ce chapitre (voir la section intitulée « Réplication d'un dépôt »).
Bien qu'il ne fasse pas officiellement partie des outils
Subversion, le script fsfs-reshard.py
(situé dans le répertoire
tools/server-side
du code source de
Subversion) est un outil particulièrement utile à
l'administrateur pour optimiser les performances de dépôts
Subversion utilisant un magasin de données FSFS. Les dépôts FSFS
contiennent des fichiers qui décrivent les changements apportés
dans chaque révision. Parfois ces
fichiers sont conservés dans un même répertoire, parfois ils
sont répartis (sharded en
anglais, d'où le nom du script) dans plusieurs répertoires.
Les versions anciennes de FSFS contenaient tous les fichiers de révision dans un répertoire unique qui grandissait (un fichier par nouvelle révision) au fur et à mesure. Cela entrainait des problèmes sur les systèmes qui ont des limites fixées sur le nombre maximum de fichiers dans un répertoire et cela pouvait engendrer des chutes de performances sur certains systèmes.
>À partir de la version 1.5, Subversion crée des dépôts FSFS en utilisant une disposition légèrement modifiée dans laquelle le contenu du répertoire des fichiers de révisions est éparpillé (c'est-à-dire réparti dans plusieurs sous-répertoires). Cela peut réduire de manière considérable le temps nécessaire au système pour trouver n'importe quel fichier et ainsi améliore la performance globale de Subversion lors des lectures dans le dépôt.
Le nombre de fichiers autorisés dans un sous-répertoire donné est configurable (les valeurs par défaut sont toutefois raisonnables pour la plupart des plateformes connues), mais modifier cette configuration après que le dépôt a été utilisé depuis quelque temps peut empêcher Subversion de retrouver les fichiers qu'il cherche. C'est l'objet de la commande fsfs-reshard.py.
fsfs-reshard.py remanie la structure du dépôt pour se conformer au nombre de sous-répertoires demandés et met à jour la configuration du dépôt pour conserver cette modification. Utilisé en combinaison avec svnadmin upgrade , c'est particulièrement utile pour convertir un dépôt Subversion pre-1.5 vers le dernier schéma réparti de Subversion (ce que Subversion ne fait pas automatiquement pour vous). Vous pouvez aussi ajuster finement cette valeur dans un dépôt déjà réparti.
Il arrive qu'un utilisateur se trompe dans son commentaire de
propagation (une faute d'orthographe ou une coquille, par
exemple). Si le dépôt est configuré (en utilisant la procédure
automatique pre-revprop-change
, voir la section intitulée « Mise en place des procédures automatiques ») pour accepter les
modifications de ce commentaire après la fin de la propagation,
l'utilisateur peut corriger son commentaire à distance en utilisant
svn propset (voir svn propset (pset, ps)). Cependant, en raison de la
possibilité de perte d'information irrémédiable, les dépôts
Subversion ne sont pas configurés, par défaut, pour autoriser
les modifications de propriétés non suivies en versions —
sauf de la part d'un administrateur.
Si un administrateur est amené à changer un commentaire de
propagation, il peut le faire avec svnadmin
setlog. Cette commande change le commentaire de
propagation (la propriété svn:log
) d'une
révision donnée du dépôt, la nouvelle valeur étant lue dans un
fichier.
$ echo "Voici le nouveau commentaire de propagation, en version corrigée" > nouveau-commentaire.txt $ svnadmin setlog mon-depot nouveau-commentaire.txt -r 388
La commande svnadmin setlog, par défaut,
possède les mêmes garde-fous pour empêcher de modifier des
propriétés non suivies en versions qu'un client distant (les
procédures automatiques pre-revprop-change
et
post-revprop-change
sont toujours activées et
doivent donc être configurées afin d'accepter ce type de
changement. Mais un administrateur peut contourner ces
protections en passant l'option --bypass-hooks
à la commande svnadmin setlog.
Avertissement | |
---|---|
Souvenez-vous cependant que, en contournant les procédures automatiques, vous êtes susceptible de ne pas activer certaines actions telles que la notification par email du changement des propriétés, la sauvegarde par les systèmes qui surveillent les propriétés non suivies en versions, etc. En d'autres termes, faites particulièrement attention aux changements que vous apportez et à la manière dont vous le faites. |
Bien que le coût de stockage ait diminué de manière drastique ces dernières années, l'utilisation de l'espace disque reste une des préoccupations de l'administrateur qui doit suivre en versions de grandes quantités de données. Chaque élément de l'historique de chaque donnée stockée dans un dépôt actif doit être sauvegardé ailleurs, peut-être même de nombreuses fois dans le cas de sauvegardes tournantes. Il est utile de savoir quelles données d'un dépôt Subversion doivent rester sur le site de production, lesquelles doivent être sauvegardées et lesquelles peuvent être supprimées sans risque.
Pour garder un dépôt petit, Subversion utilise la différenciation (ou « stockage différentiel ») à l'intérieur du dépôt lui-même. La différenciation implique l'encodage de la représentation d'un groupe de données sous la forme d'un ensemble de différences par rapport à un autre groupe de données. Si les deux groupes de données sont très similaires, la différenciation économise de l'espace pour le groupe différencié — au lieu de prendre le même espace que les données originales, le groupe occupe juste l'espace nécessaire pour dire : « je ressemble à l'autre groupe de données là-bas, sauf pour les deux ou trois changements qui suivent ». Au final, l'espace occupé par l'ensemble des données du dépôt (c'est-à-dire le contenu des fichiers suivis en versions) est beaucoup plus petit que la représentation textuelle originale de ces données.
Le stockage sous forme différenciée a fait partie de l'architecture conceptuelle de Subverson dès le début de sa conception ; et il a subi des améliorations au cours des ans. Les dépôts créés avec la version 1.4 ou ultérieure de Subversion bénéficient de la compression du contenu des fichiers « pleins-textes ». Les dépôts créés avec la version 1.6 ou ultérieure de Subversion économisent davantage d'espace disque grace au partage de représentation, une fonctionnalité qui permet à plusieurs fichiers ou révisions de fichiers dont le contenu est identique de faire référence à une seule instance partagée de ce contenu plutôt que chacun n'en conserve sa propre copie.
Bien que rares, il y a des circonstances dans lesquelles le déroulement d'une propagation Subversion peut mal se terminer, laissant derrière elle dans le dépôt des restes de cette tentative de propagation : une transaction inachevée et toutes les modifications de fichiers et de répertoires associées. Il peut y avoir plusieurs raisons à cet échec : l'utilisateur a peut-être brutalement interrompu l'opération côté client ou bien une coupure réseau s'est peut-être produite au milieu de l'opération. Quoi qu'il en soit, des transactions mortes peuvent apparaître. Elles ne sont pas dangereuses mais elles consomment inutilement de l'espace disque. Un administrateur consciencieux se doit néanmoins de les supprimer.
Vous pouvez utiliser la commande svnadmin lstxns pour obtenir la liste des noms des transactions non encore réglées :
$ svnadmin lstxns mon-depot 19 3a1 a45 $
Chaque élément de la sortie de cette commande peut être
passé en argument de svnlook (avec l'option
--transaction
(-t
))
pour déterminer qui est à l'origine de la transaction, quand
elle a eu lieu et quels types de changements ont été effectués
— ces informations sont très utiles pour savoir si on
peut supprimer la transaction sans arrière pensée ! Si
vous décidez effectivement de supprimer la transaction, son
nom peut être passé à svnadmin rmtxns qui
fera le nettoyage adéquat. En fait, svnadmin
rmtxns peut directement prendre en entrée la sortie
de svnadmin lstxns !
$ svnadmin rmtxns mon-depot `svnadmin lstxns mon-depot` $
Si vous utilisez ces deux sous-commandes ainsi, vous devriez envisager de rendre votre dépôt temporairement indisponible pour les clients. De cette manière, personne ne peut initier une transaction légitime avant que le nettoyage n'ait commencé. L'exemple Exemple 5.3, « txn-info.sh (lister les transactions inachevées) » contient quelques lignes de script shell qui peuvent produire les informations relatives à chaque transaction inachevée de votre dépôt.
Exemple 5.3. txn-info.sh (lister les transactions inachevées)
#!/bin/sh ### Produit les informations relatives à toutes les transactions ### inachevées d'un dépôt Subversion DEPOT="${1}" if [ "x$DEPOT" = x ] ; then echo "utilisation: $0 CHEMIN_VERS_LE_DEPOT" exit fi for TXN in `svnadmin lstxns ${DEPOT}`; do echo "---[ Transaction ${TXN} ]-------------------------------------------" svnlook info "${DEPOT}" -t "${TXN}" done
La sortie produite par ce script est, en bref, la concaténation des différents groupes d'informations fournis par svnlook info (voir la section intitulée « svnlook ») et ressemble à ceci :
$ txn-info.sh mon-depot ---[ Transaction 19 ]------------------------------------------- sally 2001-09-04 11:57:19 -0500 (mar. 04 sep. 2001) 0 ---[ Transaction 3a1 ]------------------------------------------- harry 2001-09-10 16:50:30 -0500 (lun. 10 sep. 2001) 39 Tentative de propagation dans un réseau capricieux ---[ Transaction a45 ]------------------------------------------- sally 2001-09-12 11:09:28 -0500 (mer. 12 sep. 2001) 0 $
Une transaction initiée depuis longtemps correspond en général à une propagation qui a été interrompue ou qui a échoué. L'horodatage de la transaction peut fournir des informations intéressantes — par exemple, quelle est la probabilité qu'une transaction commencée il y a neuf mois soit toujours active ?
En résumé, la décision de supprimer une transaction ne doit pas être prise à la légère. D'autres sources d'informations (comme les journaux d'Apache sur les erreurs et les accès, les journaux opérationnels de Subversion, l'historique des révisions Subversion, etc.) peuvent aider à la prise de décision. Et bien sûr, l'administrateur peut toujours entrer en contact (par email, par exemple) avec l'auteur d'une transaction qui semble abandonnée pour vérifier que c'est bien le cas.
Les dépôts FSFS contiennent des fichiers de révision qui décrivent, pour chaque révision, les modifications apportées et les propriétés de la révision concernée. Les dépôts créés avec des versions de Subversion antérieures à 1.5 gardent ces fichiers dans deux dossiers (un dossier pour chaque type de fichier). Au fur et à mesure que les révisions sont propagées dans le dépôt, Subversion dépose autant de fichiers dans ces dossiers. Avec le temps, le nombre de fichiers dans chaque dossier peut se révéler relativement important. Cela peut être la cause de chutes de performances sur certains systèmes de fichiers réseaux.
Le premier problème est que le système d'exploitation doit référencer ces fichiers sur une courte période de temps. Cela conduit à une mauvaise utilisation du cache disque et, en conséquence, à plus de temps pour les recherches sur les gros disques. C'est pour cette raison que Subversion est pénalisé lorsqu'il accède à vos données suivies en versions.
Le deuxième problème est un peu plus subtil. En raison de la manière dont la plupart des systèmes de fichiers allouent l'espace disque, chaque fichier utilise sur le disque plus de place qu'il n'en prend réellement. Cette quantité d'espace disque nécessaire pour stocker un seul fichier peut atteindre de 2 à 16 kilooctets par fichier, en fonction du type de système de fichiers. Cela se traduit directement par un gachis d'espace disque à chaque révision pour les dépôts FSFS. L'effet est d'autant plus sensible pour les dépôts qui ont de petites révisions, puisque le surplus d'espace nécessaire pour stocker le fichier de révision dépasse rapidement la taille des données effectivement stockées.
Afin de résoudre ce problème, Subversion 1.6 introduit la commande svnadmin pack. En « tassant » (pack en anglais) tous les fichiers d'un dépôt fragmenté dans un seul fichier et en supprimant les fichiers correspondants à chaque révision, svnadmin pack remplace la fragmentation par un seul fichier. Ainsi,le cache du système de fichiers est plus performant et le temps d'accès aux fichiers est réduit.
Subversion peut tasser des dépôts fragmentés qui ont été mis à niveau vers le système de fichiers 1.6 ou ultérieur (voir svnadmin upgrade dans Guide de référence de svnadmin : administration des dépôts Subversion). Pour le faire, lancez simplement svnadmin pack sur le dépôt:
$ svnadmin pack /var/svn/depot Packing shard 0...done. Packing shard 1...done. Packing shard 2...done. … Packing shard 34...done. Packing shard 35...done. Packing shard 36...done. $
Comme le processus de tassage obtient les verrous
nécessaires avant de faire son travail, vous pouvez lancer la
commande sur un dépôt en service, ou même comme action dans la
procédure automatique post-commit
. Tasser
un dépôt déjà tassé est autorisé, mais n'aura aucun effet sur
l'utilisation de l'espace disque par le dépôt.
La commande svnadmin pack n'a aucun effet sur un dépôt BDB.
Un système de fichiers Subversion a ses données réparties dans les fichiers du dépôt d'une manière que seuls les développeurs Subversion eux-mêmes comprennent (et s'y intéressent). Il peut cependant y avoir des circonstances qui obligent à copier ou déplacer l'ensemble (ou une partie) des données d'un dépôt à un autre.
Subversion fournit cette fonctionnalité par le biais des flux de déchargement du dépôt. Un flux de déchargement de dépôt (« fichier dump » ou dump file en anglais, quand il est stocké dans un fichier sur le disque) est un format de fichier portable, contenant des données brutes, qui décrit les différentes révisions de votre dépôt — ce qui a été modifié, par qui, quand, etc. Ce fichier dump est le principal mécanisme utilisé pour réorganiser des historiques de versions — en partie ou en totalité, avec ou sans modification — entre des dépôts. Et Subversion fournit les outils nécessaires à la création et au chargement de ces fichiers dump : les sous-commandes svnadmin dump et svnadmin load respectivement.
Avertissement | |
---|---|
Bien que le format des fichiers dump de Subversion contienne des parties lisibles par les humains et une structure familière (elle ressemble au format décrit par la RFC 822, utilisé pour la plupart des emails), ce n'est pas un format de fichier purement textuel. C'est un format de fichier binaire, très sensible aux modifications faites à son contenu. Par exemple, de nombreux éditeurs de textes corrompent le fichier en convertissant les caractères de fin de ligne. |
Il existe de nombreuses raisons de décharger et recharger les données d'un dépôt Subversion. Aux premiers temps de Subversion, la principale raison était l'évolution de Subversion lui-même. Au fur et à mesure que Subversion gagnait en maturité, des changements faits sur les schémas des magasins de données sous-jacents entraînaient des problèmes de compatibilité avec les versions précédentes du dépôt, ce qui obligeait les utilisateurs à décharger les données de leurs dépôts en utilisant la version précédente de Subversion puis à recharger ces données dans un dépôt tout neuf créé avec la nouvelle version de Subversion. Il n'y a pas eu de changement de schéma de ce type depuis la version 1.0 de Subversion et les développeurs ont promis de ne pas forcer les utilisateurs à décharger et recharger leurs dépôts lors du passage d'une version mineure à une autre (par exemple entre la version 1.3 et la version 1.4) de Subversion. Mais il existe néanmoins des raisons de décharger et recharger ses données, comme le redéploiement d'un dépôt Berkeley DB sur un nouveau système d'exploitation ou sur une architecture CPU différente, la migration du magasin de données de Berkeley DB à FSFS et réciproquement ou (comme nous le voyons dans ce chapitre à la section intitulée « Filtrage de l'historique d'un dépôt ») la purge de données suivies en version de l'historique du dépôt.
Note | |
---|---|
Le format de déchargement des dépôts Subversion ne décrit que l'évolution des éléments suivis en version. Il ne contient pas d'information sur les transactions inachevées, les verrous utilisateurs sur les chemins du système de fichiers, la configuration personnalisée du dépôt ou du serveur (y compris les procédures automatiques) et ainsi de suite. |
Le format de déchargement des dépôts permet la conversion depuis un système de stockage différent ou depuis un autre système de gestion de versions. Comme le format du fichier est, pour sa plus grande partie, lisible par un humain, il doit être relativement facile de décrire des ensembles de modifications génériques (chacun étant traité comme une nouvelle révision) en utilisant ce format de fichier. En fait, l'utilitaire cvs2svn (voir la section intitulée « Conversion d'un dépôt CVS vers Subversion ») utilise le format dump pour décrire le contenu d'un dépôt CVS afin de pouvoir le copier dans un dépôt Subversion.
Pour le moment, nous nous concentrons sur la migration de données d'un dépôt entre différents dépôts Subversion et cela fait l'objet des sections qui suivent.
Quelle que soit la raison pour laquelle vous voulez migrer votre historique de dépôt, l'utilisation des sous-commandes svnadmin dump et svnadmin load est simplissime. svnadmin dump affiche un intervalle de révisions du dépôt, chacune utilisant le format des fichiers dump Subversion. Le fichier dump est envoyé sur la sortie standard tandis que les messages d'information sont envoyés sur la sortie d'erreur. Ceci vous permet de rediriger le flux standard vers un fichier tout en visualisant ce qui se passe dans votre terminal. Par exemple :
$ svnlook youngest mon-depot 26 $ svnadmin dump mon-depot > fichier-dump * Révision 0 déchargée. * Révision 1 déchargée. * Révision 2 déchargée. … * Révision 25 déchargée. * Révision 26 déchargée.
À la fin de la procédure, vous obtiendrez un fichier
unique (fichier-dump
dans l'exemple
précédent) qui contient toutes les données stockées dans votre
dépôt pour l'intervalle de révisions demandé. Notez que
svnadmin dump lit les arborescences des
révisions du dépôt de la même manière que tout autre processus
« lecteur » (par exemple svn
checkout), vous pouvez donc sans risque lancer cette
commande à n'importe quel moment.
La commande jumelle, svnadmin load, recherche dans l'entrée standard la structure d'un fichier dump Subversion puis insère les révisions déchargées dans le dépôt de destination spécifié. Elle fournit elle aussi des informations sur le déroulement de l'opération, cette fois en utilisant la sortie standard :
$ svnadmin load nouveau-depot < fichier-dump <<< Début d'une nouvelle transaction basée sur la révision 1 * édition du chemin : A ... fait. * édition du chemin : A/B ... fait. … ------- Révision 1 propagée (commit) >>> <<< Début d'une nouvelle transaction basée sur la révision 2 * édition du chemin : A/mu ... fait. * édition du chemin : A/D/G/rho ... fait. ------- Révision 2 propagée (commit) >>> … <<< Début d'une nouvelle transaction basée sur la révision 25 * édition du chemin : A/D/gamma ... fait. ------- Révision 25 propagée (commit) >>> <<< Début d'une nouvelle transaction basée sur la révision 26 * édition du chemin : A/Z/zeta ... fait. * édition du chemin : A/mu ... fait. ------- Révision 26 propagée (commit) >>>
Le résultat d'un chargement est l'ajout de nouvelle
révisions à un dépôt — comme si vous faisiez des
propagations vers ce dépôt avec un client Subversion
classique. De la même manière que pour une propagation, vous
pouvez utiliser les procédures automatiques pour effectuer des
actions particulières avant et après chaque propagation faite
par la procédure de chargement. En passant les options
--use-pre-commit-hook
et
--use-post-commit-hook
(respectivement) à
svnadmin load, vous demandez à Subversion
d'exécuter les procédures automatiques
pre-commit
et
post-commit
(respectivement) pour chaque
révision chargée. Un exemple d'utilisation de ces options est
de s'assurer que les révisions chargées passent par les mêmes
étapes de validation qu'une propagation normale. Bien sûr,
utilisez ces options avec prudence — si votre
procédure automatique post-commit
envoie
des emails à une liste de diffusion pour chaque nouvelle
propagation, vous ne voulez peut-être pas envoyer des
centaines voire des milliers d'emails de notification à la
suite vers cette liste ! Vous pouvez en apprendre
davantage sur l'utilisation des procédures automatiques dans
la section intitulée « Mise en place des procédures automatiques ».
Notez que puisque svnadmin utilise
l'entrée et la sortie standards pour le déchargement et le
rechargement, les administrateurs les plus intrépides peuvent
tenter des choses du genre (peut-être même en utilisant
différentes versions de svnadmin de chaque
côté de la barre verticale |
) :
$ svnadmin create nouveau-depot $ svnadmin dump vieux-depot | svnadmin load nouveau-depot
Par défaut, un fichier dump prend beaucoup de place
(beaucoup plus que le dépôt lui-même). C'est parce que, par
défaut, chaque version de chaque fichier est écrite en entier
dans le fichier dump. C'est le comportement le plus simple et
le plus rapide et cela convient bien si vous redirigez le flux
de données directement vers un autre processus (comme un
programme de compression, de filtrage ou de chargement). Mais
si vous créez un fichier dump dans une optique de stockage à
long terme, vous voudrez sans doute économiser de l'espace
disque en utilisant l'option --deltas
. Avec
cette option, les révisions successives des fichiers sont
écrites en tant que différences binaires et compressées (de la
même manière que pour le stockage des fichiers dans le dépôt).
Cette option ralentit le processus mais le fichier résultant a
une taille beaucoup plus proche de celle du dépôt
original.
Nous avons mentionné auparavant que svnadmin
dump affiche un intervalle de révisions. Pour
spécifier une révision unique ou un intervalle à décharger,
utilisez l'option --revision
(-r
). Si vous omettez cette option, toutes
les révisions existantes sont affichées :
$ svnadmin dump mon-depot -r 23 > rev-23.fichier-dump $ svnadmin dump mon-depot -r 100:200 > revs-100-200.fichier-dump
Au fur et à mesure que Subversion décharge chaque nouvelle révision, il n'affiche que le minimum d'informations nécessaire à un futur chargement pour re-générer la révision à partir de la précédente. En d'autres termes, pour n'importe quelle révision du fichier dump, seuls les éléments ayant subi une modification dans cette révision apparaissent dans le fichier dump. La seule exception à cette règle concerne la première révision qui est déchargée par la commande svnadmin dump courante.
Par défaut, Subversion n'exprime pas la première révision déchargée sous forme de différences à appliquer à la révision précédente. En effet, il n'y a pas de révision précédente dans le fichier dump ! Et puis Subversion ne peut pas connaître l'état du dépôt dans lequel les données vont être chargées (si jamais elles le sont). Pour s'assurer que la sortie de chaque exécution de svnadmin dump est auto-suffisante, la première révision déchargée est, par défaut, une représentation complète de chaque répertoire, de chaque fichier et de chaque propriété de cette révision du dépôt.
Vous pouvez toujours modifier ce comportement par défaut.
Si vous ajoutez l'option --incremental
quand
vous déchargez le dépôt, svnadmin compare
la première révision déchargée à la révision précédente du
dépôt (de la même manière qu'il traite toutes les autres
révisions qui sont déchargées). Il affiche alors la première
révision de la même manière que le reste des révisions dans
l'intervalle demandé (en ne mentionnant que les changements
contenus dans cette révision). L'avantage est que vous pouvez
créer plusieurs petits fichiers dump qui peuvent être chargés
les uns à la suite des autres au lieu d'un unique gros
fichier. Par exemple :
$ svnadmin dump mon-depot -r 0:1000 > fichier-dump1 $ svnadmin dump mon-depot -r 1001:2000 --incremental > fichier-dump2 $ svnadmin dump mon-depot -r 2001:3000 --incremental > fichier-dump3
Ces fichiers dump peuvent maintenant être chargés dans un nouveau dépôt avec la séquence de commandes suivante :
$ svnadmin load nouveau-depot < fichier-dump1 $ svnadmin load nouveau-depot < fichier-dump2 $ svnadmin load nouveau-depot < fichier-dump3
Une autre astuce consiste à utiliser l'option
--incremental
pour ajouter un nouvel
intervalle de révisions à un fichier dump existant.
Par exemple, vous pouvez avoir une procédure automatique
post-commit
qui ajoute simplement à un
fichier dump le contenu de la révision qui a déclenché la
procédure. Ou alors vous pouvez avoir un script qui tourne la
nuit pour ajouter à un fichier dump les données de toutes les
révisions qui ont eu lieu depuis le dernier lancement du
script. Ainsi, svnadmin dump est une
manière de réaliser des sauvegardes des changements de votre
dépôt au fil du temps, dans l'éventualité d'un plantage
système ou de toute autre événement catastrophique.
Les fichiers dump peuvent aussi être utilisés pour
fusionner le contenu de différents dépôts en un seul dépôt. En
utilisant l'option --parent-dir
de
svnadmin load, vous pouvez spécifier un
nouveau répertoire racine virtuel pour la procédure de
chargement. Ainsi, si vous avez des fichiers dump pour trois
dépôts (disons fichier-dump-calc
,
fichier-dump-cal
et
fichier-dump-tab
) vous pouvez commencer
par créer un nouveau dépôt pour les héberger
tous :
$ svnadmin create /var/svn/projets $
Ensuite, créez dans le dépôt les nouveaux répertoires qui vont encapsuler le contenu de chacun des trois dépôts précédents :
$ svn mkdir -m "Racines initiales des projets" \ file:///var/svn/projets/calc \ file:///var/svn/projets/calendrier \ file:///var/svn/projets/tableur Révision 1 propagée. $
Enfin, chargez chaque fichier dump dans le répertoire correspondant du nouveau dépôt :
$ svnadmin load /var/svn/projets --parent-dir calc < fichier-dump-calc … $ svnadmin load /var/svn/projets --parent-dir calendrier < fichier-dump-cal … $ svnadmin load /var/svn/projets --parent-dir spreadsheet < fichier-dump-tab … $
Dans Subversion 1.7, la commande svnrdump a rejoint la trousse à outils Subversion. Elle est plutôt spécialisée en tant que version réseau de svnadmin dump et svnadmin load, que nous avons vu en détail dans la section intitulée « Migration des données d'un dépôt à l'aide de svnadmin ». svnrdump dump génère un flux dump à partir d'un dépôt distant, en l'affichant sur la sortie standard ; svnrdump load lit un flux depuis l'entrée standard et le charge dans un dépôt distant. En utilisant svnrdump, vous pouvez générer des dumps incrémentaux tout comme vous le feriez avec svnadmin dump. Vous pouvez même décharger une sous-arborescence d'un dépôt (ce que ne peut pas faire svnadmin dump).
La principale différence est que vous n'avez pas besoin d'avoir un accès direct au dépôt avec svnrdump car elle utilise les mêmes protocoles définis par Repository Access (RA) que le client texte interactif Subversion. Ainsi, vous serez peut-être amené à fournir des éléments d'authentification. Aussi, vous actions à distance sont soumises aux droits qui vous sont octroyés par la configuration du serveur Subversion.
Note | |
---|---|
svnrdump dump requiert que le serveur
soit en version 1.4 au moins. Elle génère des flux dump du
type de ceux générés lorsque vous spécifiez l'option
|
Note | |
---|---|
Comme elle modifie les propriétés de révisions après
avoir propagé les nouvelles révisions, svnrdump
load requiert que le dépôt cible soit configuré
afin d'autoriser les modifications de propriétés
via la procédure automatique
|
Comme vous pouvez vous y attendre, vous pouvez utiliser svnadmin et svnrdump de concert. Vous pouvez, par exemple, utililser svnrdump dump pour générer un flux dump depuis un dépôt distant et rediriger ce flux vers svnadmin load pour copier tout l'historique de ce dépôt vers un dépôt local. Vous pouvez tout aussi bien effectuer l'inverse, copier l'historique d'un dépôt local vers un distant.
Astuce | |
---|---|
Si vous utiliser des URL de type
|
Puisque Subversion stocke votre historique du suivi de versions en utilisant, au minimum, des algorithmes de différenciation binaire et de la compression de données (le tout, potentiellement, dans un système de gestion de bases de données complètement opaque), il est maladroit, et en tous cas fortement déconseillé, d'essayer de le modifier manuellement, sachant qu'en plus c'est assez difficile. Et une fois que des données ont été stockées dans votre dépôt, Subversion ne fournit généralement pas de moyen simple pour enlever ces données[54]. Mais, inévitablement, il y a des cas où vous voulez manipuler l'historique de votre dépôt. Par exemple pour supprimer tous les occurrences d'un fichier qui a été accidentellement ajouté au dépôt (alors qu'il ne devrait pas y être)[55]. Ou bien lorsque vous avez plusieurs projets qui partagent le même dépôt et que vous décidez de leur attribuer chacun le leur. Pour accomplir ce genre de tâches, les administrateurs ont besoin d'une représentation des données de leurs dépôts plus souple et plus facile à gérer : les fichiers dump Subversion.
Comme indiqué précédemment dans la section intitulée « Migration des données d'un dépôt », le format des fichiers dump Subversion est une représentation lisible par les humains des modifications apportées au cours du temps aux données suivies en versions. Utilisez la commande svnadmin dump ou svnrdump dump pour extraire les données et svnadmin load ou svnrdump load pour les charger dans un nouveau dépôt. Le gros atout de l'aspect « lisible par les humains » des fichiers dump est que, si vous y tenez, vous pouvez en inspecter le contenu et le modifier. Bien sûr, la contrepartie est que, si vous avez un fichier dump d'un dépôt actif depuis plusieurs années, cela vous prendra un certain temps pour en inspecter manuellement le contenu et le modifier, un temps certain même.
C'est là qu'intervient svndumpfilter. Ce programme agit comme un filtre sur les chemins pour les flux de déchargement/chargement d'un dépôt. Vous n'avez qu'à lui fournir une liste de chemins que vous voulez conserver ou une liste de chemins que vous voulez éliminer et ensuite rediriger le flux de dump de vos données à travers ce filtre. Vous obtenez un flux modifié qui ne contient que les données suivies en versions des chemins que vous avez demandés (explicitement ou implicitement).
Prenons un exemple concret d'utilisation de ce programme. Précédemment dans ce chapitre (voir la section intitulée « Stratégies d'organisation d'un dépôt »), nous avons décrit le processus de décision permettant de choisir l'organisation des données de votre dépôt (utiliser un dépôt par projet ou les combiner, comment organiser les répertoires au sein du dépôt, etc.). Mais il peut arriver qu'après un certain nombre de révisions vous repensiez votre organisation et vouliez la modifier. Une modification classique est de déplacer plusieurs projets qui partagent le même dépôt vers des dépôts propres à chacun d'eux.
Notre dépôt imaginaire contient trois projets :
calc
, calendrier
et
tableur
. Ils se trouvent côte à côte comme
ceci :
/
calc/
trunk/
branches/
tags/
calendrier/
trunk/
branches/
tags/
tableur/
trunk/
branches/
tags/
Pour placer ces trois projets dans leur dépôts propres, nous commençons par décharger tout le dépôt :
$ svnadmin dump /var/svn/depot > fichier-dump-depot * Révision 0 déchargée. * Révision 1 déchargée. * Révision 2 déchargée. * Révision 3 déchargée. … $
Ensuite, nous passons ce fichier dump à travers le filtre, en n'incluant à chaque fois qu'un seul répertoire racine. Nous obtenons trois nouveaux fichiers dump :
$ svndumpfilter include calc < fichier-dump-depot > fichier-dump-calc … $ svndumpfilter include calendrier < fichier-dump-depot > fichier-dump-cal … $ svndumpfilter include tableur < fichier-dump-depot > fichier-dump-tab … $
C'est le moment de prendre une décision. Chacun de vos
fichiers dump générera un dépôt valide, mais il conservera les
chemins exactement comme ils étaient dans le dépôt original.
Cela veut dire que même si vous obtenez un dépôt propre à votre
projet calc
ce dépôt aura toujours un
répertoire racine calc
. Si vous voulez que
les répertoires trunk
,
tags
et branches
soient
placés à la racine de votre dépôt, vous devez alors éditer les
fichiers dump, en modifiant les en-têtes
Node-path
et
Node-copyfrom-path
pour qu'ils ne contiennent
plus de référence au répertoire calc/
. Vous
devez également supprimer la section des données qui crée le
répertoire calc
. Elle ressemble à
ceci :
Node-path: calc Node-action: add Node-kind: dir Content-length: 0
Avertissement | |
---|---|
Si vous envisagez d'éditer à la main le fichier dump pour
enlever un répertoire à la racine, assurez-vous que votre
éditeur n'est pas configuré pour convertir les caractères de
fin de ligne vers le format natif (par exemple
de |
Tout ce qu'il reste à faire à présent, c'est de créer vos trois nouveaux dépôts et de charger chaque fichier dump dans le bon dépôt, en ignorant l'UUID contenu dans chaque flux dump :
$ svnadmin create calc $ svnadmin load --ignore-uuid calc < fichier-dump-calc <<< Début d'une nouvelle transaction basée sur la révision 1 * édition du chemin : Makefile ... fait. * édition du chemin : bouton.c ... fait. … $ svnadmin create calendrier $ svnadmin load --ignore-uuid calendrier < fichier-dump-cal <<< Début d'une nouvelle transaction basée sur la révision 1 * édition du chemin : Makefile ... fait. * édition du chemin : cal.c ... fait. … $ svnadmin create tableur $ svnadmin load --ignore-uuid tableur < fichier-dump-tab <<< Début d'une nouvelle transaction basée sur la révision 1 * édition du chemin : Makefile ... fait. * édition du chemin : tableur.c ... fait. … $
Les deux sous-commandes svndumpfilter possèdent des options pour décider comment traiter les révisions « vides ». Si une révision donnée ne contient que des modifications concernant des chemins qui ont été filtrés, cette révision dorénavant vide peut être considérée comme inintéressante voire indésirable. Pour permettre à l'utilisateur de décider que faire de telles révisions, svndumpfilter propose les options suivantes :
--drop-empty-revs
Ne générer aucune révision vide ; elles sont tout simplement ignorées.
--renumber-revs
Si les révisions vides sont ignorées (avec l'option
--drop-empty-revs
), changer les numéros
de révision restants pour qu'il n'y ait pas de trous
dans la séquence de numérotation.
--preserve-revprops
Si les révisions vides ne sont pas ignorées, garder les propriétés de la révision (commentaire de propagation, auteur, date, propriétés personnalisées, etc.) pour ces révisions vides. Autrement les révisions vides ne contiennent que l'horodatage original et un message expliquant que c'est à cause de svndumpfilter que cette révision est vide.
Alors que svndumpfilter peut s'avérer
très utile et permet de gagner énormément de temps, il est
affublé malheureusement de deux chausse-trappes. D'abord, cet
utilitaire est extrêmement sensible à la sémantique des chemins.
Prêtez attention à la manière dont sont spécifiés les chemins
dans votre fichier dump, avec ou sans barre oblique
(/
) initiale. Regardez pour cela les en-têtes
Node-path
et
Node-copyfrom-path
.
… Node-path: tableur/Makefile …
Si les chemins ont une barre oblique initiale, vous devez inclure des barres obliques au début de chaque chemin que vous indiquez à svndumpfilter include et svndumpfilter exclude (et s'ils n'en ont pas, n'incluez pas de barre oblique au début). Pour aller plus loin, si votre fichier dump contient à la fois des chemins avec et des chemins sans barre oblique initiale, pour quelque raison que ce soit[56], vous devrez probablement normaliser les chemins en adoptant une des deux conventions.
En outre, les chemins qui ont été copiés peuvent vous donner quelques soucis. Subversion supporte les opérations de copie dans le dépôt, c'est-à-dire quand un nouveau chemin est créé par la copie d'un autre chemin qui existe déjà. Il est possible qu'à un certain moment de la vie de votre dépôt, vous ayez copié un fichier ou un répertoire d'un endroit que svndumpfilter a exclu vers un endroit qui est inclus. Pour rendre les données du dump cohérentes, svndumpfilter doit bien inclure l'ajout du nouveau chemin — y compris le contenu de tous les fichiers créés par la copie — mais en tant que copie d'un chemin source qui n'existe pas dans le flux des données filtrées. Mais puisque le format dump de Subversion ne contient que ce qui a été modifié dans chaque révision, le contenu de la source de la copie risque de ne pas être disponible. Si vous êtes susceptible d'avoir la moindre copie de ce type dans votre dépôt, vous devrez peut-être repenser votre ensemble de chemins à inclure/exclure, pour y inclure aussi les chemins qui ont servi de sources à des opérations de copie qui vous posent problème.
Enfin, svndumpfilter effectue un filtrage
des chemins pour le moins littéral. Si vous essayez de copier
l'historique d'un projet dont la racine est
trunk/mon-projet
et de le déplacer dans
son propre dépôt, vous utiliserez évidemment la commande
svndumpfilter include pour conserver tous les
changements dans et sous trunk/mon-projet
.
Mais le fichier dump résultant ne fait aucune hypothèse sur le
dépôt dans lequel vous allez charger ces données. En
particulier, les données déchargées peuvent commencer par la
révision qui a ajouté le répertoire
trunk/mon-projet
mais ne pas
contenir les directives pour créer le
répertoire trunk
lui-même (parce que
trunk
ne correspond pas au filtre utilisé).
Vous devez vous assurer que tous les répertoires à la présence
desquels le flux de données déchargées s'attend existent
réellement dans le dépôt destination, avant d'essayer de charger
le flux de données à l'intérieur.
Divers scénarios montrent l'intérêt d'avoir un dépôt Subversion dont l'historique des versions est exactement le même que celui d'un autre dépôt. Le plus évident est probablement celui de maintenir un dépôt de secours, utilisé quand le dépôt principal est inaccessible en raison d'un problème matériel, d'une coupure réseau ou de tout autre souci de ce type. D'autres scénarios comprennent le déploiement de dépôts redondants pour distribuer la charge sur plusieurs serveurs, les mises à niveau transparentes et d'autres encore.
Subversion fournit un programme pour gérer de tels scénarios : svnsync. Il fonctionne essentiellement en demandant au serveur Subversion de « rejouer » les révisions, une par une. Il utilise ces informations sur les révisions pour répéter une propagation identique sur un autre dépôt. Aucun des deux dépôts n'a besoin d'être accessible localement sur la machine où svnsync tourne : ses paramètres sont des URL de dépôt et tout le travail est effectué via les interfaces d'accès au dépôt (Repository Access en anglais, ou RA) de Subversion. Tout ce dont il a besoin est un accès en lecture au dépôt source et un accès en lecture/écriture au dépôt de destination.
Note | |
---|---|
Quand vous utilisez svnsync sur un dépôt source distant, le serveur Subversion de ce dépôt doit être en version 1.4 ou supérieure. |
Supposons que vous avez un dépôt source que vous voulez répliquer ; il vous faut alors disposer d'un dépôt destination qui servira de miroir. Ce dépôt cible peut utiliser n'importe quel magasin de données disponible (voir À propos des magasins de données), les couches d'abstraction de Subversion s'assurent que ces détails ne vous impactent pas. Par défaut, ce dépôt ne doit comporter aucun historique (nous aborderons une exception à cette règle plus loin dans cette section).
Le protocole utilisé par svnsync pour transmettre les informations de révision est particulièrement sensible aux divergences entre les historiques suivies en versions de la source et de la destination. Pour cette raison, bien que svnsync ne puisse pas exiger que le dépôt destination soit en lecture seule[57], autoriser des modifications d'historique sur le dépôt destination par un mécanisme externe autre que le processus de réplication mène droit au désastre.
Avertissement | |
---|---|
Ne modifiez pas le dépôt miroir de sorte que son historique de version diffère de celui du dépôt source. Les seules propagations et modifications de propriétés de révisions qui doivent avoir lieu sur ce dépôt miroir sont celles effectuées par l'outil svnsync. |
Une autre exigence concernant le dépôt destination est que
le processus svnsync doit être autorisé à
modifier les propriétés de révision. Comme
svnsync fonctionne dans le cadre du système
des procédures automatiques du dépôt, l'état par défaut du
dépôt (qui consiste à interdire les modifications des
propriétés de révision, voir pre-revprop-change dans
Guide de référence des procédures automatiques de Subversion) n'est pas suffisant.
Vous devez activer explicitement la procédure automatique
pre-revprop-change
et votre script doit
autoriser svnsync à définir et à modifier
les propriétés de révision. Une fois ces dispositions prises,
vous êtes parés pour commencer la réplication des révisions du
dépôt.
Astuce | |
---|---|
Il est de bon ton de mettre un place un contrôle d'accès pour autoriser le processus de réplication de votre dépôt à faire ce qu'il a à faire tout en interdisant aux autres utilisateurs de modifier le contenu de votre dépôt miroir. |
Examinons maintenant l'utilisation de svnsync dans un scénario classique de réplication. Nous saupoudrons le discours de quelques recommandations pratiques que vous êtes libre d'ignorer si elles ne sont pas nécessaires ou pas applicables à votre environnement.
nous allons répliquer le dépôt public qui contient le code source de ce livre et mettre ce miroir à disposition sur Internet, sur une machine différente de celle qui héberge le dépôt original. Cet hôte distant possède une configuration globale qui autorise les accès anonymes en lecture mais requiert une authentification pour modifier les dépôts (pardonnez-nous de passer rapidement sur les détails de la configuration du serveur Subversion pour le moment, mais ces aspects sont traités en profondeur dans le Chapitre 6, Configuration du serveur.). Et pour rendre l'exemple plus intéressant, et uniquement pour cela, nous piloterons la réplication depuis une troisième machine — en l'occurrence, celle que nous sommes en train d'utiliser.
Dans un premier temps, nous allons créer le dépôt qui servira de miroir. Cette étape et les deux suivantes requièrent l'accès à la ligne de commande de la machine sur laquelle le miroir sera hébergé. Toutefois, une fois que ce dépôt sera complètement configuré, nous n'aurons plus besoin d'y avoir accès directement.
$ ssh admin@svn.exemple.com \ "svnadmin create /var/svn/miroir-svn" admin@svn.exemple.com's password: ******** $
À ce stade, nous disposons d'un dépôt et, en raison de la
configuration de notre serveur, ce dépôt est accessible
directement depuis Internet. Maintenant, puisque nous ne
voulons pas que quoi que ce soit modifie notre dépôt en dehors
du processus de réplication, nous devons trouver un moyen de
distinguer ce processus des autres prétendants aux
propagations. Pour ce faire, nous utilisons un identifiant
d'utilisateur dédié à notre processus. Seules les propagations
et les modifications de propriétés de révisions effectuées par
l'identifiant spécial id-sync
sont
autorisées.
Nous allons utiliser le système de procédures automatiques
du dépôt à la fois pour autoriser le processus de réplication
à faire ce qu'il doit faire et pour garantir qu'il soit le
seul à le faire. Nous implémentons donc deux des procédures
automatiques du dépôt :
pre-revprop-change
et
start-commit
. Le script
pre-revprop-change
est présenté dans
l'Exemple 5.4, « Procédure automatique pre-revprop-change du dépôt
miroir » et, pour résumer, vérifie que l'utilisateur qui essaie de
modifier les propriétés est bien notre utilisateur
id-sync
. Si c'est bien le cas, la
modification est autorisée ; sinon, elle est
refusée.
Exemple 5.4. Procédure automatique pre-revprop-change du dépôt miroir
#!/bin/sh USER="$3" if [ "$USER" = "id-sync" ]; then exit 0; fi echo "Seul l'utilisateur id-sync est autorisé à modifier les propriétés de révision." >&2 exit 1
Voilà pour les modifications des propriétés de révision.
Maintenant nous devons nous assurer que seul l'utilisateur
id-sync
est autorisé à propager de
nouvelles révisions dans le dépôt. Ce que nous allons faire en
utilisant une procédure automatique
start-commit
telle que celle présentée dans
l'Exemple 5.5, « Procédure automatique start-commit du dépôt
miroir ».
Exemple 5.5. Procédure automatique start-commit du dépôt miroir
#!/bin/sh USER="$2" if [ "$USER" = "id-sync" ]; then exit 0; fi echo "Seul l'utilisateur id-sync est autorisé à effectuer des propagations." >&2 exit 1
Après avoir installé nos procédures automatiques et s'être assuré qu'elles sont exécutables par le serveur Subversion, nous en avons terminé avec l'installation de notre dépôt miroir. Maintenant, nous allons effectivement lancer la réplication.
La première chose à faire avec svnsync est d'enregistrer dans notre dépôt destination le fait qu'il sera un miroir du dépôt source. Nous utilisons donc la sous-commande svnsync initialize. Nous fournissons des URL qui pointent vers les répertoires racines des dépôts destination et source, respectivement. Dans Subversion 1.4, c'est obligatoire — seule la réplication de dépôts complets est permise. Depuis Subversion 1.5, cependant, vous pouvez aussi utiliser svnsync pour répliquer uniquement des sous-arborescences du dépôt.
$ svnsync help init initialize (init): usage : svnsync initialize DEST_URL SOURCE_URL Initialise un dépôt destination pour être synchronisé à partir d'un autre dépôt. … $ svnsync initialize http://svn.exemple.com/miroir-svn \ http://svn.code.sf.net/p/svnbook/source \ --sync-username id-sync --sync-password mdp-sync Propriétés copiées pour la révision 0. $
Notre dépôt destination se souviendra maintenant qu'il est
un miroir du dépôt public du code source de ce livre. Notez
que nous avons fourni un identifiant et un mot de passe en
arguments à svnsync — c'était exigé
par la procédure automatique
pre-revprop-change
de notre dépôt
miroir.
Note | |
---|---|
Dans Subversion 1.4, les valeurs assignées aux options
|
Abordons maintenant la partie amusante. En une seule sous-commande, nous pouvons demander à svnsync de copier toutes les révisions qui n'ont pas encore été répliquées du dépôt source vers le dépôt destination[58]. La sous-commande svnsync synchronize fouille dans les propriétés de révision spéciales du dépôt destination pour déterminer la dernière révision qui a été répliquée, en l'occurrence la révision 0. Ensuite, elle interroge le dépôt source pour savoir quelle est la dernière révision propagée dans ce dépôt. Enfin, elle demande au dépôt source de commencer à envoyer toutes les révisions entre la révision 0 et la dernière révision. Au moment où svnsync reçoit la réponse du dépôt source, elle commence la retransmission des révisions vers le dépôt destination en tant que nouvelles propagations.
$ svnsync help synchronize synchronize (sync): Usage : svnsync synchronize URL_DEST [URL_SOURCE] Tranfère toutes les révisions en attente vers la destination à partir de la source avec laquelle elles ont été initialisées. … $ svnsync synchronize http://svn.exemple.com/miroir-svn \ http://svn.code.sf.net/p/svnbook/source Transmission des données ........................................ Révision 1 propagée. Propriétés copiées pour la révision 1. Transmission des données .. Révision 2 propagée. Propriétés copiées pour la révision 2. Transmission des données ..... Révision 3 propagée. Propriétés copiées pour la révision 3. … Transmission des données .. Révision 4063 propagée. Propriétés copiées pour la révision 4063. Transmission des données . Révision 4064 propagée. Propriétés copiées pour la révision 4064. Transmission des données .... Révision 4065 propagée. Propriétés copiées pour la révision 4065. $
Il est intéressant de noter ici que, pour chaque révision
répliquée, il y a d'abord propagation de la révision dans le
dépôt destination, puis des changements de propriétés ont
lieu. C'est parce que la propagation initiale est effectuée
par (et donc attribuée à) l'utilisateur
id-sync
et qu'elle est horodatée lors de la
création de la nouvelle révision. Et aussi parce que les
interfaces d'accès au dépôt Subversion n'autorisent pas la
définition de propriétés de révision au sein d'une
propagation. C'est pourquoi svnsync fait
suivre la réplication par une série de modifications de
propriétés qui copient dans le dépôt destination toutes les
propriétés de révision trouvées dans le dépôt source pour
cette révision. Cela a également pour effet de corriger
l'auteur et l'horodatage de la révision pour être cohérent
avec le dépôt source.
Notez également que svnsync documente tout ce qu'il fait en détail, afin de pouvoir être interrompu ou redémarré sans remettre en cause l'intégrité des données répliquées. Si une panne réseau survient pendant la réplication d'un dépôt, relancez simplement la commande svnsync synchronize et elle reprendra tranquillement là où elle s'était arrêtée. En fait, au fur et à mesure que de nouvelles révisions apparaissent dans le dépôt source, c'est précisément ce qu'il faut faire pour conserver votre miroir à jour.
Avertissement | |
---|---|
Parmi les informations stockées par le mirroir, svnsync enregistre l'URL source avec laquelle il a été initialisé. Ainsi, les appels suivants à svnsync ne requièrent pas de fournir l'URL source dans la ligne de commande. Cependant, pour plus de sécurité, nous recommandons que vous continuyez à le faire. En fonction de la manière dont il a été déployé, il peut s'avérer risqué pour svnsync de faire confiance à l'URL source qu'il récupère dépôt mirroir et depuis laquelle il récupère les données suivies en versions. |
Le procédé est cependant peu élégant. Comme les propriétés des révisions Subversion peuvent être modifiées n'importe quand dans la vie du dépôt et comme elles ne conservent pas de trace des modifications effectuées, les processus de réplication doivent faire particulièrement attention à ces propriétés. Si vous avez déjà répliqué les quinze premières révisions d'un dépôt et que quelqu'un modifie une propriété de révision concernant la révision 12, svnsync ne sait pas qu'il faut revenir en arrière et modifier la copie de la révision 12. Vous devez le lui indiquer manuellement en utilisant la sous-commande svnsync copy-revprops (ou à l'aide d'autres outils), ce qui re-réplique toutes les propriétés de révision pour une révision particulière ou un ensemble de révisions.
copy-revprops: usage : 1. svnsync copy-revprops URL_DEST [URL_SOURCE] 2. svnsync copy-revprops URL_DEST REV[:REV2] … $ svnsync copy-revprops http://svn.exemple.com/mirroir-svn 12 Propriétés copiées pour la révision 12. $
C'en est fini pour la présentation rapide de la
réplication de dépôt. Vous voudrez sûrement automatiser un
certain nombre de choses autour de ce processus. Par exemple,
alors que notre exemple présentait une mise en place
« tirer-et-pousser », vous êtes susceptible de
vouloir que ce soit le dépôt source qui pousse les
modifications vers un ou plusieurs miroirs prédéfinis lors de
l'exécution des procédures automatiques
post-commit
et
post-revprop-change
. Ceci permettrait au
miroir d'être à jour presque en temps réel.
svnsync n'est pas limitée à la copie intégrale de tout ce qui se trouve dans le dépôt. Elle peut aussi prendre en compte toute une variation de réplications partielles. Par exemple, bien que ce ne soit pas une situation très courante, svnsync sait répliquer des dépôts pour lesquels l'identifiant qu'elle utilise pour s'authentifier n'a que des droits partiels en lecture. Elle copie simplement les parties du dépôt qu'elle est autorisée à voir. Un tel miroir n'est clairement pas une bonne solution de sauvegarde..
Avec Subversion 1.5, svnsync a acquis la capacité de répliquer uniquement un sous-ensemble d'un dépôt plutôt que le dépôt entier. La procédure pour configurer et assurer la maintenance d'un tel miroir est exactement la même que pour répliquer un dépôt entier, excepté lors du passage de l'URL du dépôt source à svnsync init : vous spécifiez l'URL d'un sous-dossier à l'intérieur du dépôt. La synchronisation du miroir ne copie que les modifications relatives à l'arborescence sous le répertoire indiqué. Notez quand même quelques restrictions sur cette fonction : premièrement, vous ne pouvez pas répliquer plusieurs sous-dossiers disjoints du dépôt source vers un unique dépôt miroir — vous devez dans ce cas répliquer un répertoire parent qui est commun à tous les répertoires que vous voulez répliquer ; deuxièmement, la logique de filtrage est entièrement basée sur le chemin d'accès donc, si le sous-dossier que vous répliquez a été renommé par le passé, votre miroir ne contiendra que les révisions depuis lesquelles il a le nom indiqué dans l'URL que vous avez spécifiée. Et, de la même manière, si le sous-dossier source est renommé dans le futur, le processus de synchronisation ne répliquera plus les données à partir du moment où l'URL que vous avez spécifiée ne sera plus valide.
Nous avons mentionné le coût de mise en place d'un mirroir
pour un dépôt existant. Pour beaucoup, le coût apparent de
transmettre des milliers (voire des millions) de révisions de
l'historique vers un nouveau dépôt mirroir avec
svnsync est le point d'arrêt final.
Heureusement, Subversion 1.7 offre une porte de sortie avec la
nouvelle option --allow-non-empty
de
svnsync initialize. Cette option vous
permet d'initialiser un dépôt comme mirroir d'un autre en
courtcircuitant la vérification que le dépôt à initialiser
possède bien un historique vide. À la lecture de nos
précédents avertissements sur la sensibilité du processus de
réplication, vous devriez pressentir que cette option à
n'utiliser qu'avec la plus grande prudence. Mais elle est
terriblement efficace si vous avez les droits d'accès au dépôt
source et que vous pouvez faire une copie physique du dépôt,
puis initialiser cette copie en tant que nouveau
mirroir :
$ svnadmin hotcopy /chemin/vers/depot /chemin/vers/depot-mirroir $ ### créer le fichier /chemin/vers/depot-mirroir/hooks/pre-revprop-change $ svnsync initialize file:///chemin/vers/depot-mirroir \ file:///chemin/vers/depot svnsync: E000022: Le dépôt destination contient déjà des révisions ; utilisez éventuellement l'option --allow-non-empty si ces révisions correspondent à leurs contreparties dans le dépôt source $ svnsync initialize --allow-non-empty file:///chemin/vers/depot-mirroir \ file:///chemin/vers/depot Propriétés copiées pour la révision 32042. $
Les administrateurs qui utilisent une version antérieure
à Subversion 1.7 (et qui n'ont donc pas accès à l'option
--allow-non-empty
de
svnsync initialize) peuvent atteindre le
même résultat en manipulant
précautionneusement la propriété de la
révision r0 sur la copie du dépôt qui a vocation à devenir un
mirroir. Utilisez svnadmin setrevprop pour
créer les mêmes propriétés de journalisation que
svnsync aurait créées.
Nous avons vu deux façons de répliquer l'historique des révisions d'un dépôt vers un autre. Regardons maintenant les choses du point de vue de l'utilisateur. Comment les réplications et les diverses situations qui y font appel affectent-elles les clients Subversion ?
Tant que l'on considère les interactions relatives aux dépôts et mirroirs, une copie de travail unique peut interagir avec les deux, mais vous devrez jongler un peu pour y arriver. D'abord, vous devez vous assurer que le dépôt primaire et le mirroir possèdent bien le même UUID (ce qui n'est pas le cas par défaut). Reportez-vous à la section intitulée « Gestion des identifiants uniques (UUID) des dépôts » plus loin dans ce chapitre pour en savoir davantage.
Une fois que les dépôts possèdent le même UUID, vous pouvez utiliser svn relocate pour faire pointer votre copie de travail vers le dépôt avec lequel vous souhaitez travailler ; cette procédure est décrite dans svn relocate dans Partie II, « Guide de référence des commandes Subversion ». Un danger vous guette ici cependant, car si les dépôts ne sont pas parfaitement synchrones, une copie de travail à jour et pointant vers le dépôt principal sera, si vous la faites pointer vers un mirroir obsolète, déboussolée par la perte apparente et soudaine des révisions qu'elle s'attend à trouver dans le dépôt. Elle renverra des erreurs pour vous le signaler. Si jamais cela survient, vous pouvez refaire pointer votre copie de travail vers le dépôt primaire et, soit attendre que le dépôt mirroir se mette à jour, soit remonter dans le temps votre copie de travail vers une révision dont vous savez qu'elle figure dans le dépôt mirroir, puis tenter à nouveau de faire pointer votre copie de travail vers ce mirroir.
Enfin, soyez conscient que la réplication des révisions fournie par svnsync n'est que cela : une réplication de révisions. Seules les informations pouvant être contenues dans le format de fichier dump des dépôts Subversion peuvent être répliquées. Ainsi, les outils tels que svnsync (et svnrdump que nous avons vu dans la section intitulée « Migration des données d'un dépôt en utilisant svnrdump ») possèdent les mêmes limites intrinsèques aux fichiers dump. Ils ne répliquent pas les procédures automatiques, les transactions non propagées ou les verrous posés par les utilisateurs sur les chemins du dépôt.
En dépit des nombreux progrès de la technologie depuis l'avènement de l'informatique moderne, une chose reste certaine : le pire n'est jamais très loin. L'alimentation électrique tombe en panne, les réseaux subissent des coupures, les mémoires vives crament, les disques durs flanchent, et ce même pour le plus consciencieux des administrateurs. Nous en venons donc maintenant à un sujet très important : comment réaliser des copies de sauvegarde des données de votre dépôt.
Les administrateurs de dépôts Subversion disposent de deux méthodes de sauvegarde : la complète et l'incrémentale. Une sauvegarde complète d'un dépôt implique de récupérer d'un seul coup toutes les informations nécessaires pour reconstruire complètement ce dépôt dans le cas d'une catastrophe. Habituellement, cela consiste à dupliquer, littéralement, la totalité du répertoire du dépôt (ce qui inclut l'environnement Berkeley DB ou FSFS). Les sauvegardes incrémentales sont plus restreintes : elles ne sauvegardent que les données du dépôt qui ont changé depuis la sauvegarde précédente.
Pour ce qui concerne les sauvegardes complètes, l'approche naïve pourrait sembler satisfaisante. Mais à moins d'interdire temporairement tout accès au dépôt, une simple copie récursive du répertoire risque de créer une sauvegarde corrompue. Dans le cas d'une base de données Berkeley DB, la documentation décrit un certain ordre de copie des fichiers qui garantit une copie de sauvegarde valide. Un ordre similaire existe avec les données FSFS. Mais vous n'avez pas à implémenter ces algorithmes vous-même, puisque l'équipe de développement de Subversion l'a déjà fait pour vous. La commande svnadmin hotcopy prend soin de tout ça afin de réaliser une copie à chaud de votre dépôt. Et son invocation est aussi triviale que la commande Unix cp ou qu'une copie sous Windows :
$ svnadmin hotcopy /var/svn/depot /var/svn/depot-sauvegarde
La sauvegarde générée est un dépôt Subversion totalement fonctionnel, capable de prendre immédiatement la place de votre dépôt en production si les choses tournent au vinaigre.
Des outils additionnels existent également autour de cette
commande. Le répertoire tools/backup
du
code source de Subversion contient le script
hot-backup.py. Ce script ajoute de la gestion
de sauvegardes par-dessus svnadmin hotcopy,
permettant de ne garder que les dernières sauvegardes (le nombre
de sauvegardes à conserver est configurable) de chaque dépôt. Il
gère automatiquement les noms des répertoires sauvegardés pour
éviter les collisions avec les précédentes sauvegardes et
élimine par rotation les sauvegardes les plus anciennes. Même
si vous réalisez aussi des sauvegardes incrémentales, cette
commande vous servira peut-être régulièrement. Par exemple, vous
pouvez utiliser hot-backup.py dans un outil
permettant le lancement différé de commandes (tel que
cron sur les systèmes Unix) afin de le lancer
toutes les nuits (ou à tout autre intervalle de temps qui vous
convient mieux).
Quelques administrateurs utilisent un autre mécanisme de
sauvegarde basé sur la génération et le stockage de flux dump
des dépôts. Nous avons décrit dans la section intitulée « Migration des données d'un dépôt » comment utiliser
svnadmin dump avec l'option
--incremental
pour réaliser une sauvegarde
incrémentale d'une révision ou d'un intervalle de révisions
donné. Et bien sûr, vous pouvez réaliser une sauvegarde complète
en omettant l'option --incremental
dans la
commande. Cette méthode comporte certains avantages, entre
autres que le format de vos informations sauvegardées est
flexible (il n'est pas lié à une plateforme, à un type de
magasin de données ou à une version particulière de Subversion
ou des bibliothèques qu'il utilise). Mais cette flexibilité a un
coût, à savoir le temps de restauration des données, qui en plus
augmente avec chaque nouvelle révision propagée dans le dépôt. Aussi,
comme c'est le cas pour un tas d'autres méthodes de sauvegarde, les
modifications sur les propriétés de révision qui sont effectuées
après une sauvegarde de ladite révision ne sont pas prises en
compte par l'utilisation de flux de dump incrémentaux ne se
chevauchant pas. C'est pourquoi nous recommandons de ne pas se
reposer uniquement sur le type de sauvegarde basé sur les
fichiers dump.
À partir de Subversion 1.8, svnadmin
hotcopy accepte l'option
--incremental
et gère la copie à chaud des
dépôts FSFS. Dans le mode de copie à chaud incrémentale, les
données des révisions qui ont déjà été copiées vers le dépôt de
destination ne seront pas copiées à nouveau. Lorsque l'option
--incremental
est utilisée avec
svnadmin hotcopy, Subversion ne copie que les
nouvelles révisions, les révisions dont la taille a changé et
celles dont l'horodatage a été modifié depuis la précédente
opération de copie à chaud. De plus, les performances de
svnadmin hotcopy --incremental ne sont
limitées que par les entrées/sorties disques, au contraire de
svnsync ou svnadmin dump
--incremental. En conséquence, les copies à chaud
incrémentales peuvent vous faire économiser beaucoup de temps
lors de la sauvegarde d'un gros dépôt.
Comme vous pouvez le constater, chaque type de sauvegarde a ses avantages et ses inconvénients. La méthode la plus facile est de loin la sauvegarde à chaud complète, qui fournit toujours une copie conforme et fonctionnelle de votre dépôt. En cas d'accident sur votre dépôt de production, vous pouvez effectuer une restauration à partir de votre sauvegarde par une simple copie récursive de répertoire. Malheureusement, si vous maintenez plusieurs sauvegardes de votre dépôt, chaque sauvegarde consomme autant d'espace disque que votre dépôt en production. Les sauvegardes incrémentales, en revanche, sont plus rapides à réaliser et prennent moins de place. Mais le processus de restauration peut s'avérer pénible, avec souvent plusieurs sauvegardes incrémentales à appliquer. D'autres méthodes ont leurs propres bizarreries. Les administrateurs doivent trouver le juste milieu entre le coût des sauvegardes et le coût de la restauration.
Le programme svnsync (voir la section intitulée « Réplication d'un dépôt ») fournit en fait une approche médiane assez pratique. Si vous synchronisez régulièrement un miroir en lecture seule avec votre dépôt principal, ce miroir en lecture seule se révèle être un bon candidat pour prendre le relais du dépôt défaillant en cas de besoin. Le principal inconvénient de cette méthode est que seules les données suivies en versions sont synchronisées — les fichiers de configuration du dépôt, les verrous utilisateurs sur les chemins ou d'autres éléments stockés physiquement dans le répertoire du dépôt mais pas dans le système de fichiers virtuel du dépôt ne sont pas pris en charge par svnsync.
Quelle que soit la méthode de sauvegarde utilisée, les
administrateurs doivent savoir comment les modifications des
propriétés non suivies en versions des révisions sont prises en
compte (ou pas). Puisque ces modifications elles-mêmes ne créent
pas de nouvelles révisions, elles n'activent pas les
procédures automatiques post-commit
ni même
éventuellement les procédures automatiques
pre-revprop-change
et
post-revprop-change
[59].
Et puisque vous pouvez modifier les propriétés de révision sans
respecter l'ordre chronologique (vous pouvez changer n'importe
quelle propriété de révision à n'importe quel moment), une
sauvegarde incrémentale des dernières révisions pourrait ne pas
intégrer la modification d'une propriété de révision qui faisait
partie d'une sauvegarde précédente.
En règle générale, seuls les plus paranoïaques ont besoin de sauvegarder le dépôt entier, disons, à chaque propagation. Cependant, en considérant qu'un dépôt donné possède des mécanismes de redondance autres avec une certaine granularité (tels que des courriels envoyés à chaque propagation ou des fichiers dumps incrémentaux), réaliser une copie à chaud de la base de données, dans le cadre des sauvegardes nocturnes quotidiennes des systèmes, est une bonne pratique d'administration. Ce sont vos données, protégez-les autant que vous le voulez.
Bien souvent, la meilleure approche de sauvegarde d'un dépôt consiste à ne pas mettre tous ses œufs dans le même panier, en utilisant une combinaison des méthodes décrites ici. Les développeurs Subversion, par exemple, sauvegardent le code source de Subversion chaque nuit en utilisant hot-backup.py et effectuent une copie distante par rsync de ces sauvegardes complètes ; ils conservent plusieurs archives de tous les emails de notification des propagations et des changements de propriétés ; ils ont également des miroirs maintenus par divers volontaires qui utilisent svnsync. Votre solution peut ressembler à cela, mais elle doit être adaptée à vos besoins et maintenir l'équilibre entre commodité et paranoïa. Et quoi que vous fassiez, vérifiez la validité de vos sauvegardes de temps en temps (à quoi servirait une roue de secours crevée ?). Bien que tout ceci n'empêche pas votre matériel de subir les affres du destin[60], cela vous aidera certainement à vous sortir de ces situations délicates.
Chaque dépôt Subversion possède un identifiant unique (Universally Unique IDentifier en anglais ou UUID). Cet UUID est utilisé par les clients Subversion pour vérifier l'identité d'un dépôt quand les autres formes de vérification ne sont pas satisfaisantes (telles que l'URL du dépôt qui peut varier avec le temps). En général, les administrateurs de dépôts n'ont jamais (ou très rarement) à se préoccuper des UUID autrement que comme d'un détail d'implémentation bas niveau de Subversion. Parfois, cependant, il faut prêter attention à ce détail.
En règle générale, les UUID de vos dépôts de production doivent être uniques. C'est le but, après tout, des UUID. Mais il y a des cas où vous voulez que les UUID de deux dépôts soient identiques. Par exemple, quand vous faites une copie de sauvegarde d'un dépôt, vous voulez que cette sauvegarde soit une réplique exacte de l'original afin que, dans le cas où vous restaureriez la sauvegarde pour remplacer le dépôt de production, ceci soit transparent pour les utilisateurs. Quand vous déchargez et chargez l'historique d'un dépôt (comme décrit précédemment dans la section intitulée « Migration des données d'un dépôt »), vous devez décider si vous incluez l'UUID dans le flux de données déchargées (le fichier dump) qui va dans le nouveau dépôt. Les circonstances vous imposeront la marche à suivre.
Il y a plusieurs façons de faire pour attribuer (ou modifier) un UUID à un dépôt, le cas échéant. Depuis Subversion 1.5, il suffit d'utiliser la commande svnadmin setuuid. Si vous fournissez un UUID explicite à cette sous-commande, elle valide le format de l'UUID et fixe l'identifiant unique du dépôt à cette valeur. Si vous omettez l'UUID, un nouvel UUID est généré automatiquement pour votre dépôt.
$ svnlook uuid /var/svn/depot cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec $ svnadmin setuuid /var/svn/depot # créer un nouvel UUID $ svnlook uuid /var/svn/depot 3c3c38fe-acc0-11dc-acbc-1b37ff1c8e7c $ svnadmin setuuid /var/svn/depot \ cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec # restaure l'ancien UUID $ svnlook uuid /var/svn/depot cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec $
Pour ceux qui utilisent une version de Subversion antérieure
à 1.5, ces tâches sont un peu plus compliquées. Vous pouvez
attribuer explicitement un UUID en redirigeant le flux d'un
fichier dump qui comporte le nouvel UUID avec la commande
svnadmin load --force-uuid
.CHEMIN-DU-DEPOT
$ svnadmin load --force-uuid /var/svn/depot <<EOF SVN-fs-dump-format-version: 2 UUID: cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec EOF $ svnlook uuid /var/svn/depot cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec $
Faire générer un nouvel UUID à une ancienne version de Subversion n'est pas aussi simple. La meilleure façon de faire est certainement de trouver un moyen de générer un UUID puis d'affecter explicitement cet UUID au dépôt.
Les données d'un dépôt Subversion sont toutes contenues dans l'arborescence du répertoire du dépôt. Ainsi, vous pouvez déplacer un dépôt Subversion vers un autre endroit du disque, renommer un dépôt, copier un dépôt ou effacer un dépôt entier en utilisant les outils de votre système d'exploitation pour manipuler les répertoires — mv, cp -a et rm -r pour les plateformes Unix ; copy, move et rmdir /s /q sous Windows ; cliquodrome avec de nombreux explorateurs graphiques, etc.
Bien sûr, il y a souvent d'autres choses à faire lors de ce genre de manipulations. Par exemple, vous voulez peut-être mettre à jour la configuration de votre serveur Subversion pour le faire pointer vers le nouveau chemin du dépôt déplacé ou pour supprimer les éléments de configuration relatifs à un dépôt ayant été effacé. Si vous avez des processus automatiques qui publient des informations à partir de vos dépôts, ou qui leur sont relatives, ils doivent sûrement être mis à jour. La configuration des procédures automatiques a peut-être besoin d'être modifiée. Les utilisateurs doivent être informés. La liste est longue, mais vous avez sûrement des procédures d'exploitation et des règles d'administration de votre dépôt Subversion qui vous indiquent ce qu'il faut faire.
Dans le cas d'un dépôt copié, vous devez aussi prendre en compte le fait que Subversion utilise l'identifiant unique UUID pour distinguer les dépôts. Si vous copiez un dépôt en utilisant la commande typique de copie récursive de votre interpréteur de commande, vous vous retrouvez avec deux dépôts absolument identiques, y compris en ce qui concerne l'UUID. Dans certains cas, c'est ce que l'on cherche. Dans d'autres cas, non. Vous devez alors générer un nouvel UUID pour l'un des deux dépôts identiques. Lisez la section intitulée « Gestion des identifiants uniques (UUID) des dépôts » pour plus d'informations sur la gestion des UUID.
À présent vous devez avoir une compréhension de base de la création, la configuration et l'administration des dépôts Subversion. Nous vous avons présenté les différents outils qui vous assistent dans ces tâches. Tout au long de ce chapitre, nous avons identifié quelques chausse-trappes d'administration et proposé des solutions pour les éviter.
Tout ce qui vous reste à faire est de décider quelles données passionnantes vous allez héberger dans votre dépôt et, finalement, comment les mettre à disposition sur un réseau. Le prochain chapitre est entièrement consacré au travail en réseau.
[48] Cela peut sembler prestigieux et noble, mais nous ne faisons référence en fait qu'à une personne intéressée par le monde mystérieux qui se cache derrière la copie de travail que chacun détient.
[49] Strictement parlant, Subversion n'oblige pas à ce que les données suivies en versions soient stockées ici et il existe des variantes (quoique propriétaires) de stockage des données qui ne stockent pas réellement leurs données dans ce dossier.
[50] NdT : souvent désigné par backend en anglais (sans équivalent en français) ou, ce qui peut être source de confusion, « le système de fichiers) »
[51] Souvent prononcé « feuzz-feuzz » par Jack Repenning (ce livre, cependant, suppose que le lecteur pense « eff-ess-eff-ess »).
[52] Que ce soit par ignorance ou par la définition absurde de métriques de développement, les numéros globaux de révision sont craints alors qu'ils sont bien peu de chose et certainement pas à prendre en considération quand vous décidez de l'agencement de vos projets et de vos dépôts.
[53] Le trio trunk
,
tags
et branches
est quelquefois appelé « les répertoires TTB »
(the TTB directories
en anglais).
[54] C'est d'ailleurs pour cela que vous utilisez un système de gestion de versions, non ?
[55] Des suppressions délibérées et avisées de données suivies en versions peuvent effectivement être justifiées par des cas d'utilisation réels. C'est pourquoi une fonctionnalité « d'oblitération » est une des fonctionnalités les plus demandées pour Subversion et les développeurs de Subversion espèrent pouvoir la fournir bientôt.
[56] Bien que svnadmin dump ait une politique cohérente concernant la barre oblique initiale (aussi appelée « slash » — il ne l'inclut pas), d'autres programmes qui génèrent des fichiers dump sont susceptibles de ne pas être aussi cohérents.
[57] En fait, le dépôt ne peut pas être complètement en lecture seule, sinon svnsync lui-même aurait du mal à y copier l'historique des révisions.
[58] Nous avertissons le lecteur que, bien qu'il lui suffise de quelques secondes pour lire ce paragraphe et l'exemple qui suit, le temps nécessaire pour réaliser une opération de réplication est, disons, un peu plus long.
[59] La commande svnadmin setlog peut être utilisée de manière à contourner les procédures automatiques.
[60] Vous savez, le fameux « concours de circonstances », celui auquel vous êtes arrivé premier.
Un dépôt Subversion hébergé sur une machine donnée est
accessible simultanément par des clients fonctionnant sur cette même
machine en utilisant la méthode file://
. Mais la
configuration typique de Subversion consiste en une machine serveur
unique à laquelle accèdent des clients tournant sur les ordinateurs
de tout le bureau — ou, peut-être, de partout dans le
monde.
Ce chapitre décrit comment rendre visible votre dépôt Subversion en dehors de la machine hôte pour qu'il soit utilisable par des clients distants. Nous couvrons les mécanismes serveurs disponibles actuellement pour Subversion, leur configuration et leur utilisation. À la fin de ce chapitre, vous devriez être apte à décider quelle configuration réseau convient à vos besoins et comprendre comment mettre en place cette configuration sur votre machine hôte.
Subversion a été conçu avec une couche réseau abstraite. Cela signifie que l'on peut accéder de façon automatisée à un dépôt par toute sorte de protocoles client/serveur, et que l'interface (l'API) d'accès au dépôt du client permet aux programmeurs d'écrire des greffons implémentant les protocoles réseaux appropriés. En théorie, Subversion peut utiliser un nombre infini d'implémentations réseau. En pratique, il n'existe à ce jour que deux serveurs largement déployés.
Apache est un serveur web extrêmement populaire ; en utilisant le module mod_dav_svn, Apache a accès au dépôt et peut le rendre accessible aux clients via le protocole WebDAV/DeltaV, qui est une extension d'HTTP. Comme Apache est un serveur très complet, il inclut un grand nombre de fonctionnalités « gratuitement », telles que : communications chiffrées par SSL, journalisation, intégration avec bon nombre de systèmes d'authentification tiers et navigation web limitée des dépôts.
À l'opposé vous trouvez svnserve : un petit programme serveur, léger, qui communique via un protocole sur mesure avec les clients. Parce que ce protocole a été conçu spécialement pour Subversion et possède la notion d'états (à la différence d'HTTP), il offre des opérations significativement plus rapides, certes aux dépens de certaines fonctionnalités. Bien qu'il sache utiliser SASL pour offrir toute une gamme d'options d'authentification et de chiffrement, il ne possède ni journalisation ni navigation web intégrée. Il est néanmoins très facile à mettre en place et constitue souvent le meilleur choix pour de petites équipes débutant avec Subversion.
Une troisième option consiste à utiliser
svnserve encapsulé dans une connexion SSH. Même
si ce scénario utilise toujours svnserve, il
diffère quelque peu, en termes de fonctionnalités, d'un
déploiement svnserve traditionnel. SSH sert à
chiffrer toutes les communications. Par ailleurs,
l'authentification utilise exclusivement SSH, ce qui nécessite des
comptes utilisateurs au niveau système sur le serveur hôte (à la
différence de « svnserve simple », qui possède ses
propres comptes utilisateurs privés). Enfin, avec ce type de
déploiement, un processus svnserve temporaire
privé est créé pour chaque utilisateur qui se connecte, ce qui
équivaut (du point de vue des permissions) à permettre à un groupe
d'utilisateurs locaux d'accéder au dépôt
via des URL
file://
. Les autorisations d'accès basées sur
des chemins n'ont donc aucun sens, puisque chaque utilisateur
accède directement aux fichiers de la base de données du
dépôt.
Le Tableau 6.1, « Comparaison des fonctionnalités des serveurs Subversion » présente un résumé rapide des trois types courants de déploiements de serveurs.
Tableau 6.1. Comparaison des fonctionnalités des serveurs Subversion
Fonctionnalité | Apache + mod_dav_svn | svnserve | svnserve sur SSH |
---|---|---|---|
Authentification | Authentification HTTP(S) de base, certificats X.509, LDAP, NTLM, ou tout autre mécanisme compatible avec Apache. | CRAM-MD5 par défaut ; LDAP, NTLM, ou tout autre mécanisme compatible avec SASL. | SSH |
Comptes utilisateurs | Fichiers privés ou tout autre mécanisme compatible avec Apache (LDAP, SQL, etc.). | Fichiers privés ou tout autre mécanisme compatible avec SASL (LDAP, SQL, etc.). | Comptes utilisateurs du système. |
Contrôle d'accès | L'accès en lecture/écriture peut être autorisé sur le dépôt tout entier ou restreint à des chemins spécifiés. | L'accès en lecture/écriture peut être autorisé sur le dépôt tout entier ou restreint à des chemins spécifiés. | L'accès en lecture/écriture ne peut être autorisé que sur le dépôt tout entier. |
Chiffrement | Disponible via SSL (option). | Disponible via les fonctionnalités optionnelles de SASL. | Inhérent à toute connexion SSH. |
Journalisation | Journaux Apache complets de chaque requête HTTP et journalisation « de haut niveau » des opérations de Subversion. | Uniquement la journalisation « de haut niveau » des opérations de Subversion. | Uniquement la journalisation « de haut niveau » des opérations de Subversion. |
Interopérabilité | Accessible par tout client WebDAV. | Ne peut communiquer qu'avec des clients svn. | Ne peut communiquer qu'avec des clients svn. |
Accès via une interface Web | Support intégré limité ou via des outils tiers tels que ViewVC. | Uniquement via des outils tiers tels que ViewVC. | Uniquement via des outils tiers tels que ViewVC. |
Réplication serveur de type maître-esclave | Possibilité d'un mandataire transparent pour l'écriture (de l'esclave vers le maître). | Possibilité de créer seulement des serveurs esclaves en lecture seule. | Possibilité de créer seulement des serveurs esclaves en lecture seule. |
Vitesse | Relativement plus lent. | Relativement plus rapide. | Relativement plus rapide. |
Mise en place | Relativement complexe. | Extrêmement simple. | Relativement simple. |
Et alors, quel serveur vous faut-il ? Quel est le meilleur ?
Bien évidemment, il n'y a pas de bonne réponse à cette question. Chaque équipe a des besoins propres et les différents serveurs représentent des compromis différents. Le projet Subversion lui-même ne recommande pas un serveur plus qu'un autre, ni ne considère qu'un serveur est plus « officiel » qu'un autre.
Voici quelques argumentaires qui vous aideront à choisir entre un déploiement et un autre, ainsi que quelques raisons de ne pas choisir l'un d'entre eux.
facile et rapide à mettre en place ;
le protocole réseau possède la notion d'états et est significativement plus rapide que WebDAV ;
pas besoin de créer des comptes utilisateurs système sur le serveur ;
le mot de passe ne circule pas sur le réseau.
par défaut, seule une méthode d'authentification est disponible, le protocole réseau n'est pas chiffré et le serveur enregistre les mots de passe en clair (tous ces éléments peuvent être modifiés en configurant SASL, mais cela requiert un peu plus de travail) ;
Pas de journalisation avancée ;
pas de navigation web intégrée (il vous faut installer un serveur web séparé et un logiciel de navigation du dépôt pour ajouter cette fonctionnalité).
le protocole réseau possède la notion d'états et est significativement plus rapide que WebDAV ;
vous pouvez tirer parti des comptes SSH existants et de l'infrastructure déjà mise en place pour les utilisateurs ;
tout le trafic réseau est chiffré.
il n'y a qu'un seul choix possible de méthode d'authentification ;
Les possibilités de journalisation sont limitées ;
les utilisateurs doivent être membres du même groupe système ou utiliser une clé SSH partagée ;
mal utilisé, il peut aboutir à des problèmes de droits sur les fichiers.
il permet à Subversion d'utiliser n'importe lequel des nombreux systèmes d'authentification déjà intégrés dans Apache ;
pas besoin de créer des comptes système sur le serveur ;
journalisation Apache complète disponible ;
le trafic réseau peut être chiffré par SSL ;
HTTP(S) fonctionne généralement même derrière des pare-feux d'entreprise ;
la possibilité de parcourir le dépôt avec un navigateur Web est disponible nativement ;
le dépôt peut être monté en tant que lecteur réseau à des fins de gestion de versionstransparente (voir la section intitulée « Gestion de versions automatique »).
significativement plus lent que svnserve, car HTTP est un protocole sans état et nécessite plus d'allers et retours réseau ;
la mise en place initiale peut s'avérer complexe.
En général, les auteurs de ce livre recommandent une installation ordinaire de svnserve aux petites équipes qui débutent avec Subversion ; c'est le plus simple à installer et celui qui pose le moins de problèmes de maintenance. Vous pouvez toujours passer au déploiement d'un serveur plus complexe au fur et à mesure que vos besoins évoluent.
Voici quelques recommandations et astuces générales, basées sur des années de support aux utilisateurs :
si vous essayez de mettre en place le serveur le plus simple possible pour votre groupe, une installation ordinaire de svnserve est la voie la plus sûre et la plus rapide. Notez cependant que les données de votre dépôt circuleront en clair sur le réseau. Si votre déploiement se situe entièrement à l'intérieur du LAN ou du VPN de votre compagnie, ce n'est pas un problème. Si le dépôt est accessible sur Internet, il serait bon de vous assurer que son contenu n'est pas sensible (par exemple s'il ne contient que du code open source), ou alors de faire l'effort supplémentaire de configurer SASL pour chiffrer les communications réseau ;
si vous devez vous insérer au sein de systèmes d'authentification déjà en place (LDAP, Active Directory, NTLM, X.509, etc.), il vous faudra utiliser soit le serveur basé sur Apache, soit svnserve configuré avec SASL ;
que vous ayez décidé d'utiliser Apache ou un banal
svnserve, créez un utilisateur
svn
unique sur votre système et
utilisez-le pour faire tourner le processus serveur.
Assurez-vous également que la totalité du répertoire du dépôt
est la propriété de cet utilisateur. Du point de vue de la
sécurité, les données du dépôt restent ainsi englobées et
protégées par l'application des droits gérés par le système
de fichiers du système d'exploitation et sont modifiables
uniquement par le processus serveur Subversion
lui-même ;
si vous disposez d'une infrastructure existante basée principalement sur des comptes SSH et si vos utilisateurs possèdent déjà des comptes système sur la machine qui sert de serveur, il est logique de déployer une solution svnserve sur SSH. Dans le cas contraire, nous ne recommandons généralement pas cette option au public. Il est considéré comme plus sûr de donner l'accès au dépôt à vos utilisateurs au moyen de comptes (imaginaires) gérés par svnserve ou Apache plutôt que par de véritables comptes système. Si vous voulez vraiment chiffrer les communications, nous vous recommandons d'utiliser Apache avec chiffrement SSL ou svnserve avec chiffrement SASL à la place ;
ne vous laissez pas séduire par l'idée très simple de
donner l'accès à un dépôt à tous vos utilisateurs
directement via des URL
file://
. Même si le dépôt est accessible
à tous sur un lecteur réseau, c'est une mauvaise idée. Elle
ôte toutes les couches de protection entre les utilisateurs
et le dépôt : les utilisateurs peuvent corrompre
accidentellement (ou intentionnellement) la base de données
du dépôt, il est difficile de mettre le dépôt hors ligne
pour inspection ou pour mise à niveau et vous risquez
d'aboutir à de graves problèmes de droits sur les fichiers
(voir la section intitulée « Accès au dépôt par plusieurs méthodes »).
Remarquez que c'est aussi une des raisons pour laquelle nous
déconseillons d'accéder aux dépôts via des URL
svn+ssh://
: du point de vue de la
sécurité, c'est en fait comme si les utilisateurs locaux y
accédaient via
file://
, ce qui peut entraîner exactement
les mêmes problèmes si l'administrateur ne fait pas preuve
de prudence.
Le programme svnserve est un
serveur léger, capable de dialoguer avec des clients sur un réseau
TCP/IP en utilisant un protocole dédié avec gestion des états. Les
clients contactent le serveur svnserve en
utilisant une URL qui commence par svn://
ou
svn+ssh://
. Cette section explique différentes
mises en œuvre de svnserve, l'authentification
des clients sur le serveur et la configuration d'un contrôle
d'accès approprié pour vos dépôts.
Il existe différentes façons de démarrer le programme svnserve :
lancer svnserve en tant que serveur autonome, à l'écoute de requêtes ;
utiliser le démon Unix inetd pour lancer une instance temporaire de svnserve quand une requête arrive sur un port déterminé ;
utiliser SSH pour lancer une instance temporaire de svnserve dans un tunnel chiffré ;
lancer svnserve en tant que service Microsoft Windows ;
lancer svnserve en tant que tâche launchd.
Les sections qui suivent vont détailler ces différentes mises en œuvre de svnserve.
Le plus facile est de démarrer
svnserve en tant que serveur autonome. Pour
ce faire, utilisez l'option -d
(d pour
« daemon » qui est l'appellation consacrée pour les
serveurs Unix) :
$ svnserve -d $ # svnserve est maintenant actif, en écoute sur le port 3690
Lorsque vous lancez svnserve en serveur
autonome, vous pouvez utiliser les options
--listen-port
et
--listen-host
pour spécifier le port et
l'adresse voulus pour « écouter ».
Une fois le serveur démarré de cette manière, tous les
dépôts présents sur votre machine seront accessibles par le
réseau. Un client doit spécifier un chemin
absolu dans l'URL du dépôt. Par exemple, si un
dépôt est situé sous /var/svn/projet-1
,
un client l'atteindra par
svn://hote.exemple.com/var/svn/projet-1
. Pour
renforcer la sécurité, vous pouvez passer l'option
-r
à svnserve afin de
restreindre l'export aux dépôts situés sous le chemin indiqué.
Par exemple :
$ svnserve -d -r /var/svn …
L'utilisation de l'option -r
modifie le
chemin que le serveur considère comme la racine du système de
fichiers à exporter. Les clients utiliseront alors des URL ne
comportant pas cette portion du chemin (ce qui rend les URL
plus courtes et plus discrètes) :
$ svn checkout svn://hote.exemple.com/projet-1 …
Si vous désirez que inetd lance
le processus, il vous faudra passer l'option
-i
(--inetd
). Dans l'exemple
suivant, nous montrons le résultat de la commande
svnserve -i
, mais notez bien que ce c'est
pas de cette manière que l'on démarre le serveur ;
reportez-vous aux paragraphes qui suivent l'exemple pour
savoir comment configurer inetd pour qu'il
démarre svnserve.
$ svnserve -i ( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops d\ epth log-revprops atomic-revprops partial-replay ) ) )
Quand on l'invoque avec l'option --inetd
,
svnserve tente de communiquer avec un
client Subversion via l'entrée
et la sortie standards (stdin
et
stdout
) en utilisant un protocole
spécifique. C'est le comportement habituel de tout programme
lancé par inetd. L'IANA a réservé le port
3690 pour le protocole Subversion ; sur un système Unix
vous pouvez donc ajouter au fichier
/etc/services
les lignes suivantes (si
elles n'existent pas déjà) :
svn 3690/tcp # Subversion svn 3690/udp # Subversion
Si votre système utilise un serveur
inetd classique de type Unix, vous pouvez
ajouter la ligne suivante au fichier
/etc/inetd.conf
:
svn stream tcp nowait proprio-svn /usr/bin/svnserve svnserve -i
Assurez-vous que l'utilisateur « proprio-svn »
possède des droits d'accès appropriés pour vos dépôts. Dès
lors, quand une connexion client arrive sur le port 3690,
inetd va créer un processus
svnserve pour lui répondre. Bien sûr, vous
pouvez également ajouter l'option -r
à cette
ligne de configuration, pour restreindre les dépôts qui sont
exportés.
Certains systèmes d'exploitation fournissent le
serveur xinetd en lieu et place de
inetd. Fort heureusement, vous pouvez
configurer svnserve pour s'interfacer aussi
avec xinetd. Pour ce faire, vous devez
créer un fichier /etc/xinetd.d/svn
avec
le contenu suivant :
# default: on
# description: serveur Subversion pour le protocole svn
service svn
{
disabled = no
port = 3690
socket_type = stream
protocol = tcp
wait = no
user = proprio-svn
server = /usr/local/bin/svnserve
server_args = -i -r /chemin/vers/les/dépôts
}
Vérifier que le fichier /etc/services
contient bien les références des ports relatifs au protocole
svn
(comme indiqué dans
la section intitulée « svnserve via inetd »), sinon le serveur ne démarrera pas correctement.
Sur les distributions de type Redhat, vous devez activer le nouveau service à l'aide de la commande chkconfig --add svn. Ensuite, vous pourrez activer ou désactiver le serveur au moyen de l'interface graphique.
Le mode tunnel est une troisième façon de lancer
svnserve,
via
l'option -t
. Ce mode présuppose qu'un
programme de connexion à distance tel que
rsh ou ssh a permis
à un utilisateur de s'authentifier avec succès et lance alors
un processus privé svnserve pour
le compte de cet utilisateur (remarquez qu'en tant
qu'utilisateur vous aurez rarement, sinon jamais, l'occasion
de lancer svnserve avec l'option
-t
en ligne de commande ; c'est le
serveur SSH qui le fait à votre place). Le programme
svnserve se comporte alors normalement
(utilisation des entrées/sorties stdin
et
stdout
) et suppose que le trafic est
redirigé automatiquement vers le client par un tunnel. Quand
svnserve est lancé par un gestionnaire de
tunnel comme ici, soyez sûr que l'utilisateur authentifié
possède les droits suffisants de lecture et d'écriture sur
les fichiers de la base de données. C'est essentiellement la
même chose que quand un utilisateur local accède au dépôt
via des URL
file://
.
Cette option est décrite en détail plus loin dans ce chapitre, dans la section intitulée « Encapsulation de svnserve dans un tunnel SSH ».
Si votre système Windows est un descendant de
Windows NT (Windows 2000 ou plus récent), vous pouvez lancer
svnserve en tant que service Windows. C'est
généralement une méthode bien plus agréable que de le
lancer en démon indépendant via l'option (-d)
.
Utiliser le mode démon nécessite de lancer une console, de
taper une commande et ensuite de laisser la fenêtre de la
console tourner indéfiniment. Un service Windows, au contraire,
tourne à l'arrière-plan, peut être lancé automatiquement au
démarrage et peut être démarré ou arrêté à l'aide de la même
interface d'administration que les autres services
Windows.
Vous devrez définir le nouveau service en utilisant l'outil en ligne de commande SC.EXE. De façon analogue à la ligne de configuration inetd, il vous faudra fournir la commande de lancement précise de svnserve pour que Windows le lance au démarrage :
C:\> sc create svn binpath= "C:\svn\bin\svnserve.exe --service -r C:\depot" displayname= "Serveur Subversion" depend= Tcpip start= auto
Ceci définit un nouveau service Windows nommé
« svn », qui exécute une commande particulière
svnserve.exe quand il démarre (dont la
racine est, dans ce cas, C:\depot
). Il y
a toutefois un certain nombre de précautions à prendre avec
cet exemple.
Premièrement, remarquez que le programme
svnserve.exe doit toujours être lancé avec
l'option --service
. Toute autre option de
svnserve doit ensuite être spécifiée sur la
même ligne, mais vous ne pouvez pas ajouter d'options qui
seraient en conflit avec celle-ci, telles que
--daemon (-d)
, --tunnel
,
ou --inetd (-i)
. D'autres options, comme
-r
ou --listen-port
ne
posent pas de problème. Deuxièmement, faites attention aux
espaces quand vous tapez la commande
SC.EXE : les groupes clé=
valeur
ne doivent pas comporter d'espace dans
clé=
et doivent comporter exactement une
espace avant valeur
. Enfin, faites
attention aux espaces présentes dans la ligne de commande que
vous indiquez. Si le nom d'un répertoire contient des espaces
(ou tout autre caractère qui ait besoin d'être banalisé),
placez l'ensemble du contenu de binpath
entre guillemets, qui doivent eux-mêmes être banalisés :
C:\> sc create svn binpath= "\"C:\program files\svn\bin\svnserve.exe\" --service -r C:\depot" displayname= "Serveur Subversion" depend= Tcpip start= auto
Notez aussi que le terme binpath
prête
à confusion : sa valeur est une ligne de
commande, pas le chemin d'accès à un exécutable.
C'est pourquoi vous devez l'entourer de guillemets s'il
contient des espaces.
Une fois que le service a été créé, il peut être arrêté, démarré ou interrogé à l'aide des outils standards de l'interface graphique (le programme « Services » des outils d'administration) ou de la ligne de commande :
C:\> net stop svn C:\> net start svn
Le service peut aussi être désinstallé (c'est-à-dire
supprimé) en effaçant sa définition :
sc delete svn
. Prenez soin d'arrêter le
service auparavant ! Le programme
SC.EXE possède de nombreuses autres
sous-commandes ; tapez sc /?
en ligne de commande pour en savoir plus.
Mac OS X (10.4 et supérieur) utilise launchd pour gérer les processus, y compris les démons, de la machine et des utilisateurs. Une tâche launchd est spécifiée par des paramètres dans un fichier de propriétés XML et la commande launchctl sert à gérer le cycle de vie de ces tâches.
Quand il est configuré pour fonctionner en tant que tâche
launchd, svnserve est
automatiquement lancé à la demande dès qu'un trafic réseau
entrant de type Subversion svn://
doit être
pris en charge. C'est beaucoup plus pratique qu'une
configuration qui demande à lancer svnserve
en tant que processus permanent en arrière-plan.
Pour configurer svnserve en tant que
tâche launchd, commencez par créer un
fichier de définition de la tâche nommé
/Library/LaunchDaemons/org.apache.subversion.svnserve.plist
.
Exemple 6.1, « Exemple de fichier de définition de tâche launchd pour
svnserve »
donne un exemple d'un tel fichier.
Exemple 6.1. Exemple de fichier de définition de tâche launchd pour svnserve
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.apache.subversion.svnserve</string> <key>ServiceDescription</key> <string>Accès aux dépôts Subversion locaux en utilisant le protocole svn://</string> <key>ProgramArguments</key> <array> <string>/usr/bin/svnserve</string> <string>--inetd</string> <string>--root=/var/svn</string> </array> <key>UserName</key> <string>proprio-svn</string> <key>GroupName</key> <string>proprio-svn</string> <key>inetdCompatibility</key> <dict> <key>Wait</key> <false/> </dict> <key>Sockets</key> <dict> <key>Listeners</key> <array> <dict> <key>SockServiceName</key> <string>svn</string> <key>Bonjour</key> <true/> </dict> </array> </dict> </dict> </plist>
Avertissement | |
---|---|
Le système launchd peut être
difficile à appréhender. Heureusement, la documentation
existe pour les commandes décrites dans cette section. Par
exemple, lancez |
Une fois le fichier de définition de tâche créé, vous pouvez activer la tâche en utilisant launchctl load :
$ sudo launchctl load \ -w /Library/LaunchDaemons/org.apache.subversion.svnserve.plist
Pour être tout à fait franc, cette commande ne lance pas
réellement svnserve immédiatement. Elle
indique simplement à launchd comment lancer
svnserve lorsqu'un flux entrant arrive sur
le port svn
il sera stoppé après que
le flux a été pris en charge.
Note | |
---|---|
Comme nous voulons que svnserve soit
une tâche accessible sur toute la machine, nous devons
utiliser sudo pour gérer la tâche avec
les droits d'administrateur. Notez également que les clés
|
Désactiver la tâche est tout aussi facile à faire ; utilisez launchctl unload :
$ sudo launchctl unload \ -w /Library/LaunchDaemons/org.apache.subversion.svnserve.plist
launchctl vous propose aussi
d'interroger l'état des tâches. Si la tâche est chargée, il
y aura une ligne qui mentionne le Label
spécifié dans le fichier de définition de la
tâche :
$ sudo launchctl list | grep org.apache.subversion.svnserve - 0 org.apache.subversion.svnserve $
Quand un client se connecte au processus svnserve, les choses suivantes se passent :
Le client sélectionne un dépôt particulier.
Le serveur analyse le fichier
conf/svnserve.conf
de ce dépôt et
commence à suivre les politiques d'authentification et de
contrôle d'accès qui y sont décrites.
En fonction des politiques définies, une des choses suivantes a lieu :
Le client est autorisé à lancer des requêtes anonymes, sans jamais recevoir le moindre défi d'authentification.
Le client peut recevoir un défi d'authentification à tout instant.
Si l'on est en mode tunnel, le client déclare lui-même avoir déjà satisfait à une authentification externe (généralement par SSH).
Le serveur svnserve ne sait envoyer, par défaut, que des défis d'authentification CRAM-MD5[61]. Plus précisément, le serveur envoie une petite quantité de données aux clients. Le client utilise l'algorithme de hachage MD5 pour créer une empreinte combinant les données et le mot de passe, puis renvoie l'empreinte en guise de réponse. Le serveur effectue le même calcul avec le mot de passe enregistré pour vérifier que le résultat est identique. Le mot de passe ne circule ainsi jamais en clair sur le réseau.
Si votre serveur svnserve a été compilé en incluant le support de SASL, non seulement il sait comment envoyer des défis CRAM-MD5, mais il connaît aussi probablement un grand nombre d'autres mécanismes d'authentification. Consultez la section intitulée « Utilisation de svnserve avec SASL » plus loin dans ce chapitre pour savoir comment configurer l'authentification et le chiffrement avec SASL.
Le client peut bien sûr aussi être authentifié en externe par un gestionnaire de tunnel tel que ssh. Dans ce cas, le serveur se contente de prendre l'identifiant par lequel il a été lancé et de s'en servir comme utilisateur authentifié. Pour plus de détails, reportez-vous plus loin à la section intitulée « Encapsulation de svnserve dans un tunnel SSH ».
Vous avez sûrement déjà deviné que le fichier
svnserve.conf
est le mécanisme central qui
contrôle l'accès au dépôt. Lorsqu'il est utilisé en combinaison
avec d'autres fichiers décrits dans cette section, ce fichier de
configuration permet à l'administrateur de définir complètement
les politiques d'authentification des utilisateurs et de contrôle
d'accès. Tous les fichiers que nous allons présenter utilisent le
format commun des fichiers de configuration (voir la section intitulée « Zone de configuration des exécutables ») :
les noms de paragraphes sont entourés de crochets
([
et ]
), les lignes de
commentaires commencent par des dièses (#
) et
chaque paragraphe contient des variables spécifiques qui peuvent
être définies (variable = valeur
). Examinons
maintenant ces fichiers et apprenons à les utiliser.
Pour ce qui suit, la section [general]
de svnserve.conf
contient toutes les
variables dont vous avez besoin. Commencez par modifier les
valeurs de toutes les variables : choisissez un nom pour
le fichier qui contiendra vos noms d'utilisateur ainsi que
vos mots de passe et choisissez un domaine
d'authentification :
[general] password-db = fichier-utilisateurs realm = exemple de domaine
Le domaine (realm
dans le fichier de
configuration) est un nom que vous définissez. Il indique aux
clients à quelle sorte d'« espace de noms » ils se
connectent ; le client Subversion l'affiche dans l'invite
d'authentification et l'utilise comme clé (en combinaison avec
le nom de machine et le port du serveur) pour mettre en cache
les éléments d'authentification sur le disque (voir la section intitulée « Mise en cache des éléments d'authentification »). La variable
password-db
pointe vers un fichier séparé
qui contient une liste de noms d'utilisateurs et de mots de
passe, utilisant le même format usuel. Par exemple :
[users] harry = motdepassemachin sally = motdepassebidule
La valeur de password-db
peut
correspondre à un chemin absolu ou à un chemin relatif vers le
fichier des utilisateurs. Pour de nombreux administrateurs,
conserver le fichier dans la zone conf/
,
aux côtés de svnserve.conf
, est une
solution simple et facile. D'un autre côté, il se pourrait que
deux dépôts, voire plus, doivent partager le même
fichier ; dans ce cas, le fichier devrait sans doute être
situé dans un répertoire plus accessible. Les dépôts
partageant le même fichier utilisateurs devraient aussi être
configurés de sorte qu'ils soient dans le même domaine,
puisque la liste des utilisateurs définit, par essence, un
domaine d'authentification. Quel que soit l'emplacement du
fichier, faites attention à positionner les droits en
lecture/écriture de façon appropriée. Si vous savez sous quel
nom d'utilisateur svnserve fonctionnera,
restreignez l'accès au fichier utilisateurs en
conséquence.
Il y a deux variables supplémentaires à définir dans le
fichier svnserve.conf
: elles
déterminent ce que les utilisateurs non-authentifiés
(anonymes) et les utilisateurs authentifiés ont le droit de
faire. Les variables anon-access
et auth-access
peuvent contenir les valeurs
none
, read
, ou
write
. Choisir la valeur
none
empêche à la fois lecture et
écriture ; read
autorise l'accès en
lecture seule au dépôt et write
autorise
l'accès complet en lecture/écriture au dépôt.
Par exemple :
[general] password-db = fichier-utilisateurs realm = exemple de domaine # les utilisateurs anonymes ne peuvent accéder au dépôt qu'en lecture anon-access = read # les utilisateurs authentifiés peuvent à la fois lire et écrire auth-access = write
Les lignes présentes dans le fichier contiennent en fait les valeurs par défaut des variables, au cas où vous oublieriez de les définir. Si vous voulez être encore plus prudent, vous pouvez complètement interdire les accès anonymes :
[general] password-db = fichier-utilisateurs realm = exemple de domaine # les utilisateurs anonymes ne sont pas autorisés anon-access = none # les utilisateurs authentifiés peuvent à la fois lire et écrire auth-access = write
Le processus serveur sait interpréter non seulement ce
contrôle d'accès générique, mais aussi des restrictions
d'accès plus fines associées à des fichiers et répertoires
spécifiques du dépôt. Pour utiliser cette fonctionnalité, vous
devez définir un fichier contenant des règles plus détaillées,
puis faire pointer la variable authz-db
vers ce fichier :
[general] password-db = fichier-utilisateurs realm = exemple de domaine # Règles d'accès propres à certains emplacements authz-db = fichier-authz
Nous étudions la syntaxe du fichier authz plus loin dans
ce chapitre, dans la section intitulée « Contrôle d'accès basé sur les chemins ». Notez que la
variable authz-db
n'est pas mutuellement
exclusive avec les variables anon-access
et auth-access
; si toutes les
variables sont définies en même temps,
toutes les règles doivent être
satisfaites pour que l'accès soit autorisé.
L'authentification par CRAM-MD5 suffit aux besoins de bon nombre d'équipes. Cependant, si votre serveur (et vos clients Subversion) ont été compilés avec la bibliothèque « Cyrus Simple Authentication and Security Layer » (SASL), vous avez à votre disposition un certain nombre d'options d'authentification et de chiffrement.
Normalement, quand un client Subversion se connecte à svnserve, le serveur envoie un message de bienvenue qui liste les fonctionnalités qu'il supporte et le client répond avec une liste similaire. Si le serveur est configuré pour exiger une authentification, il envoie ensuite un défi listant les mécanismes d'authentification disponibles ; le client répond en choisissant un des mécanismes et l'authentification se déroule ensuite par quelques échanges de messages. Même quand SASL n'est pas présent dans la liste, le client et le serveur sont capables d'utiliser les mécanismes CRAM-MD5 et ANONYMOUS (voir la section intitulée « Authentification et contrôle d'accès intégrés »). Si le serveur et le client ont été compilés pour inclure SASL, un certain nombre d'autres mécanismes d'authentification sont éventuellement disponibles. Néanmoins, vous devez configurer explicitement SASL sur le serveur pour qu'ils soient proposés.
Pour activer les mécanismes spécifiques à SASL sur le
serveur, il faut faire deux actions. D'abord, créez un
paragraphe [sasl]
dans le fichier
svnserve.conf
de votre dépôt avec le
couple clé/valeur initial :
[sasl] use-sasl = true
Ensuite, créez le fichier principal de configuration de
SASL, appelé svn.conf
, à un endroit où la
bibliothèque SASL saura le trouver (généralement dans un
répertoire où sont situés les greffons SASL). Vous devez
localiser le répertoire des greffons de votre système, tel que
/usr/lib/sasl2/
ou
/etc/sasl2/
(notez qu'il ne
s'agit pas là du fichier
svnserve.conf
qui réside dans votre
dépôt !).
Sur un serveur Windows vous devez aussi éditer la base de
registre (à l'aide d'un outil tel que
regedit) pour indiquer à SASL les
emplacements où chercher. Créez une clé nommée
[HKEY_LOCAL_MACHINE\SOFTWARE\Carnegie
Mellon\Project Cyrus\SASL Library]
et placez-y deux
clés : l'une appelée SearchPath
(dont la valeur est le chemin du répertoire contenant les
bibliothèques de greffons SASL
sasl*.dll
) et l'autre appelée
ConfFile
(dont la valeur est le chemin du
répertoire parent contenant le fichier
svn.conf
que vous avez créé).
Parce que SASL fournit de très nombreux mécanismes
d'authentification, il serait insensé (et bien au-delà du
cadre de ce livre) d'essayer de décrire toutes les
configurations serveurs possibles. Nous vous recommandons
plutôt de lire la documentation fournie dans le
sous-répertoire doc/
du code source de
SASL. Elle décrit en détail chaque mécanisme, ainsi que la
manière de configurer le serveur correctement pour chacun
d'entre eux. Dans ce paragraphe, nous nous contentons de
donner un exemple simple de configuration du mécanisme
DIGEST-MD5. Par exemple, si votre fichier
svn.conf
contient ce qui
suit :
pwcheck_method: auxprop auxprop_plugin: sasldb sasldb_path: /etc/ma_bdd_sasl mech_list: DIGEST-MD5
vous demandez à SASL de proposer le mécanisme DIGEST-MD5
aux clients et de comparer les mots de passe des utilisateurs
à une base de mots de passe privée située à l'emplacement
/etc/ma_bdd_sasl
. Un administrateur
système pourra ensuite utiliser le programme
saslpasswd2 pour ajouter ou modifier les
noms d'utilisateurs et les mots de passe contenus dans cette
base de données :
$ saslpasswd2 -c -f /etc/ma_bdd_sasl -u domaine utilisateur
Quelques consignes de prudence : tout d'abord,
l'argument « domaine » qui est passé à
saslpasswd2 doit correspondre au même
domaine que celui que vous avez défini dans le fichier
svnserve.conf
; s'ils ne
correspondent pas, l'authentification échouera. En outre, à
cause d'une limitation de SASL, ce domaine commun doit être
une chaîne sans espace. Enfin, si vous décidez d'utiliser la
base de données standard de mots de passe SASL, assurez-vous
que le programme svnserve a accès en
lecture à ce fichier (et éventuellement aussi en écriture, si
vous utilisez un mécanisme tel que OTP).
Ceci est une manière simple de configurer SASL. De nombreux autres mécanismes d'authentification sont disponibles et les mots de passe peuvent être conservés dans des conteneurs différents, par exemple des annuaires LDAP ou des bases de données SQL. Reportez-vous à la documentation complète de SASL pour plus de détails.
Souvenez-vous que si vous configurez votre serveur pour qu'il n'autorise que certains mécanismes d'authentification SASL, tous les clients qui se connectent ont l'obligation de supporter SASL. Tout client Subversion compilé sans SASL (ce qui inclut tous les clients antérieurs à la version 1.5) est incapable de se connecter. D'un autre côté, ce type de restriction est peut-être exactement ce que vous recherchez (« Mes clients doivent tous utiliser Kerberos ! »). Néanmoins, si vous voulez permettre à des clients non-SASL de se connecter, pensez bien à inclure le mécanisme CRAM-MD5 dans les choix possibles. Tous les clients savent utiliser CRAM-MD5, qu'ils aient des fonctionnalités SASL ou pas.
SASL est également capable d'effectuer le chiffrement des
données si un mécanisme particulier le supporte. Le mécanisme
intégré CRAM-MD5 ne supporte pas le chiffrement, mais
DIGEST-MD5 le supporte et d'autres mécanismes tels que SRP
requièrent l'utilisation de la bibliothèque OpenSSL. Pour
activer ou désactiver différents niveaux de chiffrement, vous
pouvez définir deux variables dans le fichier
svnserve.conf
de votre
dépôt :
[sasl] use-sasl = true min-encryption = 128 max-encryption = 256
Les variables min-encryption
et
max-encryption
contrôlent le niveau de
chiffrement exigé par le serveur. Pour désactiver complètement
le chiffrement, mettez les deux valeurs à 0. Pour activer une
simple somme de contrôle sur les données (par exemple pour
empêcher toute manipulation douteuse et garantir l'intégrité
des données sans chiffrement), mettez les deux valeurs à 1.
Si vous voulez autoriser le chiffrement, sans que ce soit
obligatoire, mettez 0 pour la valeur minimale et un nombre de
bits donné pour la valeur maximale. Pour exiger un chiffrement
inconditionnel, mettez les deux valeurs à un nombre plus grand
que 1. Dans l'exemple précédent, nous obligeons les clients à
utiliser au moins un chiffrement 128 bits et au plus un
chiffrement 256 bits.
L'authentification intégrée (ainsi que SASL) peuvent être très pratiques, car ils évitent d'avoir à créer de véritables comptes systèmes. D'un autre côté, certains administrateurs ont déjà des systèmes d'authentification bien établis en place. Dans ce cas, tous les utilisateurs du projet possèdent déjà des comptes systèmes et peuvent se connecter au serveur par SSH.
Utiliser SSH en conjonction avec svnserve
est facile. Le client utilise juste une URL
svn+ssh://
pour se connecter :
$ whoami harry $ svn list svn+ssh://hote.exemple.com/depot/projet harryssh@hote.exemple.com's password: ***** truc machin bidule …
Dans cet exemple, le client Subversion lance un processus
local ssh, se connecte à
hote.exemple.com
, s'authentifie en tant que
harryssh
(en accord avec la configuration SSH
des utilisateurs) puis un processus svnserve
privé est généré automatiquement sur la machine distante,
processus dont le propriétaire est l'utilisateur
harryssh
. La commande
svnserve est lancée en mode tunnel
(-t
) et son protocole réseau est encapsulé dans
la connexion chiffrée par ssh, le
gestionnaire de tunnel. Si le client effectue une propagation,
l'auteur de la nouvelle révision sera l'utilisateur authentifié
(harryssh
).
Ce qu'il est important de comprendre ici est que le client Subversion ne se connecte pas à un serveur svnserve fonctionnant en permanence. Cette méthode d'accès ne requiert pas la présence d'un démon, ni ne vérifie s'il y en a un qui tourne. Elle se base entièrement sur la capacité de ssh à générer un processus svnserve temporaire, qui ensuite se termine une fois la connexion SSH close.
Quand vous utilisez des URL svn+ssh://
pour accéder à un dépôt, souvenez-vous que c'est le programme
ssh qui envoie l'invite d'authentification,
pas le client svn. Cela
signifie qu'il n'y a pas de mise en cache automatique de mots de
passe (voir la section intitulée « Mise en cache des éléments d'authentification »). Le
fonctionnement du client Subversion fait qu'il accède souvent au
dépôt par des connexions multiples, bien que les utilisateurs ne
s'en rendent habituellement pas compte grâce à la fonctionnalité
de mise en cache du mot de passe. Lorsque vous utilisez des URL
svn+ssh://
, les utilisateurs risquent de
trouver ça pénible que ssh demande le mot de
passe de façon répétitive pour toute connexion vers l'extérieur.
La solution est d'utiliser un outil séparé de mise en cache du
mot de passe, tel que ssh-agent sur Unix ou
pageant sur Windows.
Quand le trafic passe par un tunnel, les accès sont
contrôlés principalement par les droits sur les fichiers de la
base de données liés au système d'exploitation ; c'est
quasiment pareil que si Harry accédait au dépôt directement via
une URL file://
. Si plusieurs utilisateurs
systèmes accèdent au dépôt directement, il est de bon ton de
les placer dans un même groupe et vous devez faire attention aux
umasks (prenez soin de lire la section intitulée « Accès au dépôt par plusieurs méthodes » plus loin dans ce
chapitre). Mais même dans le cas de l'encapsulation, vous pouvez
toujours utiliser le fichier svnserve.conf
pour bloquer l'accès, en spécifiant juste auth-access =
read
ou auth-access =
none
[62].
Vous vous attendez à ce que cette histoire d'encapsulation
SSH se termine ici, mais ce n'est pas le cas. Subversion vous
permet de créer des comportements d'encapsulation personnalisés
dans votre fichier de configuration (voir la section intitulée « Zone de configuration des exécutables »). Par exemple, supposons que
vous vouliez utiliser RSH au lieu de SSH[63].
Dans le paragraphe [tunnels]
de votre fichier
config
, définissez-le comme
ceci :
[tunnels] rsh = rsh --
À présent vous pouvez utiliser cette nouvelle définition
d'encapsulation par le biais d'un schéma d'URL qui correspond au
nom de votre nouvelle variable :
svn+rsh://hote/chemin
. Lorsqu'il utilise le
nouveau type d'URL, le client Subversion lance en fait en
arrière-plan la commande rsh -- hote
svnserve -t
. Si vous incluez un nom d'utilisateur
dans l'URL (par exemple
svn+rsh://nomdutilisateur@hote/chemin
), le
client va l'inclure dans sa commande (rsh --
nomdutilisateur@hote svnserve -t
).
Avertissement | |
---|---|
Notez que quand nous avons défini un tunnel sur RSH, nous
avons ajouté l'argument |
Mais vous pouvez définir des schémas d'encapsulation bien plus évolués :
[tunnels] joessh = $JOESSH /opt/alternate/ssh -p 29934 --
Cet exemple illustre plusieurs choses. D'abord, il indique
comment faire pour que le client Subversion lance un exécutable
d'encapsulation particulier (celui situé à l'emplacement
/opt/alternate/ssh
) avec des options
particulières. Dans ce cas, se connecter à une URL
svn+joessh://
lance un exécutable SSH
particulier avec les arguments -p 29934
(utile
si vous voulez que le programme d'encapsulation se connecte à un
port non standard).
Ensuite, il indique comment définir une variable
d'environnement personnalisée capable de remplacer le nom du
programme d'encapsulation. Configurer la variable d'environnement
SVN_SSH
est un moyen simple de modifier le
programme d'encapsulation par défaut. Mais s'il vous faut
différents programmes d'encapsulation pour différents serveurs,
chacun se connectant par exemple à un port différent ou passant
des options différentes à SSH, vous pouvez utiliser le mécanisme
illustré dans cet exemple. Concrètement, si nous donnons une
valeur à la variable d'environnement JOESSH
,
cette valeur remplacera la totalité de la valeur de la variable
d'encapsulation — $JOESSH serait
exécuté au lieu de /opt/alternate/ssh
-p 29934
.
Il est possible de contrôler non seulement la manière dont le client lance ssh, mais aussi le comportement de sshd sur votre machine. Dans ce paragraphe, nous indiquons comment contrôler la commande svnserve précise qui est exécutée par sshd, ainsi que comment faire pour que plusieurs utilisateurs partagent un même compte système.
Pour commencer, localisez le répertoire
« home » du compte utilisateur que vous utilisez
pour lancer svnserve. Assurez-vous que ce
compte possède un biclé de clés publique/privée et que
l'utilisateur peut se connecter en s'authentifiant par la
méthode à clé publique. L'authentification par mot de passe ne
fonctionnera pas, puisque toutes les astuces SSH qui suivent
consistent à utiliser le fichier
authorized_keys
.
S'il n'existe pas déjà, créez le fichier
authorized_keys
(sur Unix, c'est
généralement ~/.ssh/authorized_keys
).
Chaque ligne de ce fichier décrit une clé publique autorisée à
se connecter. Ces ligne sont généralement de la
forme :
ssh-dsa AAAABtce9euch… utilisateur@exemple.com
Le premier champ décrit le type de clé, le second champ
est la clé elle-même, encodée en base 64, et le troisième
champ est un commentaire. Cependant, c'est un fait moins connu
que la ligne toute entière peut être précédée par un champ
command
:
command="programme" ssh-dsa AAAABtce9euch… utilisateur@exemple.com
Quand le champ command
est présent, le
serveur SSH va lancer le programme indiqué en lieu et place de
l'habituel svnserve en mode tunnel que le
client Subversion a demandé. En découlent un certain nombre
d'astuces côté serveur. Dans les exemples suivants, nous
abrégeons les lignes du fichier par :
command="programme" TYPE CLÉ COMMENTAIRE
Comme nous pouvons spécifier la commande exécutée côté serveur, il devient facile de désigner un exécutable svnserve spécifique et de lui passer des arguments supplémentaires :
command="/chemin/vers/svnserve -t -r /racine/virtuelle" TYPE CLÉ COMMENTAIRE
Dans cet exemple, /chemin/vers/svnserve
peut être un script personnalisé construit autour de
svnserve qui spécifie le umask à utiliser
(voir la section intitulée « Accès au dépôt par plusieurs méthodes »). Il
indique aussi comment « ancrer »
svnserve dans un répertoire racine virtuel,
ce qui est aussi très souvent utilisé quand
svnserve fonctionne en tant que démon. Le
but est soit de restreindre l'accès à certaines parties du
système, soit simplement d'éviter que l'utilisateur ait à
taper un chemin absolu dans l'URL
svn+ssh://
.
Il est également possible d'avoir plusieurs utilisateurs
partageant un compte utilisateur unique. Au lieu de créer un
compte système distinct pour chaque utilisateur, générez
plutôt un biclé de clés publique/privée pour chaque personne.
Placez ensuite chaque clé publique dans le fichier
authorized_users
, une par ligne, et
utilisez l'option --tunnel-user
:
command="svnserve -t --tunnel-user=harry" TYPE1 CLÉ1 harry@exemple.com command="svnserve -t --tunnel-user=sally" TYPE2 CLÉ2 sally@exemple.com
Cet exemple permet à la fois à Harry et à Sally de se
connecter au même compte utilisateur avec l'authentification
via leur clé publique. Une
commande propre à chacun sera exécutée ; l'option
--tunnel-user
signale à
svnserve que l'argument fourni doit être
considéré comme le nom de l'utilisateur authentifié. Sans
--tunnel-user
, toutes les propagations
sembleraient venir du même compte utilisateur partagé.
Finalement, un dernier avertissement : autoriser
l'accès d'un utilisateur au serveur
via une clé publique dans un
compte partagé n'empêche pas forcément d'autres formes
d'accès SSH, même si vous avez spécifié une valeur pour le
champ command
dans le fichier
authorized_keys
. Par exemple,
l'utilisateur aura toujours accès au shell via SSH, il sera
capable rediriger les flux X11 ou tout autre port de votre
serveur. Pour accorder le moins de droits possibles à
l'utilisateur, vous pouvez spécifier des options de
restriction immédiatement après la commande du champ
command
:
command="svnserve -t --tunnel-user=harry",no-port-forwarding,no-agent-forw arding,no-X11-forwarding,no-pty TYPE1 CLÉ1 harry@exemple.com
Notez bien que tout ceci doit tenir sur une seule ligne,
vraiment sur une seule ligne, car les fichiers SSH
authorized_keys
n'autorisent même pas le
caractère habituel de continuation de ligne
(\
). L'unique raison pour laquelle nous
avons rajouté une coupure est pour que cela tienne dans le
format physique d'un livre.
Dans les sections précédentes, nous avons mentionné
plusieurs options de configuration à placer dans le fichier
svnserve.conf
pour configurer Subversion
lorsque l'accès se fait via
svnserve. Dans cette section, nous faisons
un rapide résumé de toutes les options
de configuration reconnues par ce serveur.
Le fichier de configuration
svnserve.conf
utilise un format classique
de type .INI, avec des couples nom/valeur des options groupées
dans des sections (notez que c'est aussi le type de format
utilisé par la zone de configuration des exécutables du client
Subversion). Nous décrivons ici chaque section et les options
possible dans chacune d'elles.
Par défaut, svnserve lit les fichiers de
configuration spécifique à chaque dépôt situé à
conf/svnserve.conf
dans l'arborescence physique
du dépôt. Pour utiliser un seul fichier de configuration qui
s'applique à l'ensemble des dépôts hébergés par une instance de
svnserve, utilisez l'option
--config-file
au lancement du serveur.
Note | |
---|---|
Dans les sections suivante, nous faisons référence au fichier
de configuration de svnserve par son nom
canonique, |
La section intitulée [general]
contient les
options de configuration les plus utilisées et qui concernent le
comportement global de svnserve.
anon-access
Définit le niveau d'accès pour les utilisateurs non
authentifiés (anonymous). Les valeurs possibles sont
write
, read
et
none
; read
est la valeur par défaut.
auth-access
Définit le niveau d'accès pour les utilisateurs
authentifiés. Les valeurs possibles sont
write
, read
et
none
; write
est la valeur par défaut.
authz-db
Spécifie l'emplacement du fichier contenant les droits
d'accès, tels que décrits dans
la section intitulée « Introduction au contrôle d'accès basé sur les
chemins ». Si vous utilisez un chemin normal, alors celui-ci est
considéré comme relatif au répertoire contenant le fichier de
configuration svnserve.conf
sauf si ce
chemin commence par une barre oblique (/
).
Si aucun chemin n'est spécifié, le contrôle d'accès basé sur
les chemins n'est pas activé.
En particulier, vous pouvez spécifier l'emplacement
d'un fichier, suivi en versions dans un dépôt Subversion,
qui contient les règles de droits d'accès. Utilisez une
URL locale (i.e. qui commence par
file://
) pour faire référence à un
fichier de droits d'accès dont la portée est
« absolue ». Ou bien, utilisez une URL relative
(i.e. qui commence par ^/
) pour indiquer
à svnserve de consulter pour chaque
dépôt le fichier stocké à l'emplacement spécifié dans ce
dépôt précis.
force-username-case
Spécifie la casse appliquée aux identifiants avant
d'effectuer la comparaison avec les règles du fichier
de contrôle d'accès (specifié par l'option
authz-db
). Les valeurs possibles sont
upper
(pour passer les identifiants
en majuscules)), lower
(pour passer
les identifiants en minuscules) et
none
(pour ne rien faire). Par
défaut, svnserve ne fait
rien.
groups-db
Spécifie le chemin vers le fichier de description
des groupes.Si vous utilisez un chemin normal, alors
celui-ci est considéré comme relatif au répertoire
contenant le fichier de configuration
svnserve.conf
sauf si ce
chemin commence par une barre oblique
(/
).
Vous pouvez aussi spécifier l'emplacement d'un
fichier de description des groupes qui est suivi en
versions dans un dépôt Subversion. Utilisez une
URL locale (i.e. qui commence par
file://
) pour faire référence à un
fichier dont la portée est « absolue ». Ou
bien, utilisez une URL relative (i.e. qui commence par
^/
) pour indiquer à
svnserve de consulter pour chaque
dépôt le fichier de description des groupes stocké à
l'emplacement spécifié dans ce dépôt précis.
hooks-env
Spécifie le chemin du fichier de configuration de
l'environnement des procédures automatiques. Cette
option surcharge l'emplacement par défaut défini par
dépôt et peut être utilisée pour configurer fichier
unique de définition de l'environnement des procédures
automatiques valable pour de mutiples dépôts, si un
chemin absolu est utilisé. Sinon, l'emplacement du
fichier est considéré comme relatif au répertoire
contenant le fichier de configuration
the svnserve.conf
.
Reportez-vous à la section intitulée « Configuration de l'environnement des procédures automatiques » pour des informations détaillées relatives au fichier de configuration de l'environnement des procédures automatiques.
password-db
Spécifie le chemin du fichier contenant la base de
données des mots de passe. Le chemin est considéré
comme relatif au répertoire contenant le fichier de
configuration svnserve.conf
sauf
si ce chemin commence par une barre oblique
(/
). Notez que si vous utilisez
SASL, cette option est ignorée.
realm
Spécifie le domaine d'authentification du dépôt. Ce domaine est utilisé par le client pour associer les éléments d'authentification dont il dispose en cache à un dépôt ou un ensemble de dépôts. Ainsi, il est préférable de spécifier un domaine unique à chaque dépôt qui ne partage pas de base de données d'authentification avec d'autres dépôts. Par défaut, l'UUID du dépôt est utilisé comme domaine d'authentification.
La section [sasl]
contient la
configuration spécifique au mécanisme « Cyrus Simple
Authentication and Security Layer (SASL) » de
svnserve. Lisez
la section intitulée « Utilisation de svnserve avec SASL » pour une
description détaillée de cette fonctionnalité et des
avantages qu'elle procure.
max-encryption
Spécifie (en nombre de bits) la solidité maximum de
la couche de chiffrement. La valeur 0
signifie « pas de sécurité » et la valeur
1
signifie « vérification
d'intégrité seulement ». La valeur par défaut
est 256
(chiffrement 256
bits).
min-encryption
Spécifie (en nombre de bits) la solidité minimum
de la couche de chiffrement. La valeur
0
signifie « pas de
sécurité » et la valeur
1
signifie « vérification
d'intégrité seulement ». La valeur par défaut
est 0
(pas de sécurité).
use-sasl
Spécifie (avec true
ou false
value) si Cyrus SASL doit
être mis en œuvre. Notez que cette fonctionnalité
n'est disponible que si svnserve
a été compilé en conséquence. Cette fonctionnalité
est désactivée par défaut.
Le serveur HTTP Apache est un serveur réseau à tout faire que Subversion sait exploiter. ViaVia un module adapté, httpd rend les dépôts Subversion accessibles aux clients par le protocole WebDAV/DeltaV[64], qui est une extension de HTTP 1.1. Ce protocole se base sur HTTP, le protocole omniprésent à la base du World Wide Web, lui ajoute des fonctionnalités d'écriture et, en particulier, d'écriture avec gestion de versions. Le résultat est un système robuste et standardisé qui est inclus dans le logiciel Apache 2.0, supporté par de nombreux systèmes d'exploitation et outils tiers, et qui ne demande pas aux administrateurs réseaux d'ouvrir un port réseau supplémentaire[65]. Bien qu'un serveur Apache-Subversion ait plus de fonctionnalités que svnserve, il est aussi un peu plus difficile à mettre en place. La flexibilité a bien souvent pour contrepartie la complexité.
Une grande partie de ce qui va suivre fait référence à des directives de configuration d'Apache. Bien que l'utilisation de ces directives soit illustrée par quelques exemples, les décrire complètement va bien au-delà du sujet de ce chapitre. L'équipe Apache tient à jour une documentation excellente, disponible publiquement sur leur site web à l'adresse https://httpd.apache.org. Par exemple, le guide de référence complet des directives de configuration est situé à l'adresse https://httpd.apache.org/docs/current/mod/directives.html.
En outre, au fur et à mesure des changements que vous
apporterez à votre configuration d'Apache, il est probable que
vous commettrez des erreurs. Si vous n'êtes pas déjà familier avec
le sous-système de journalisation d'Apache, vous devrez apprendre
à le connaître. Dans votre fichier httpd.conf
,
des directives spécifient l'emplacement sur le disque des journaux
d'accès et d'erreurs générés par Apache (les directives
CustomLog
et ErrorLog
respectivement). Le module mod_dav_svn de
Subversion utilise également l'interface de journalisation des
erreurs d'Apache. Pensez à naviguer dans ces fichiers lorsque vous
recherchez des informations susceptibles de vous aider à trouver
l'origine d'un problème.
Pour mettre à disposition votre dépôt sur le réseau par HTTP, il vous faut quatre composants, disponibles dans deux paquets. Il vous faut Apache httpd 2.0 ou plus récent, le module DAV mod_dav fourni avec, Subversion et le module mod_dav_svn implémentant le système de fichiers, qui est fourni avec Subversion. Une fois que vous avez tous ces composants, la procédure de mise en réseau de votre dépôt est aussi simple que :
faire fonctionner httpd avec le module mod_dav ;
installer le module mod_dav_svn derrière mod_dav (mod_dav_svn utilise les bibliothèques Subversion pour accéder au dépôt) ;
configurer le fichier httpd.conf
pour exporter (ou « exposer ») le dépôt.
Vous pouvez accomplir les deux premières tâches citées
supra
soit en compilant httpd et Subversion à
partir du code source, soit en installant les paquets binaires
précompilés correspondants sur votre système. Les informations
les plus récentes sur la façon de compiler Subversion dans le
cadre d'une utilisation en conjonction avec le serveur
HTTP Apache, sur la compilation et sur la configuration
d'Apache lui-même dans cet objectif, sont consultables dans le
fichier INSTALL
situé à la racine de
l'arborescence du code source de Subversion.
Une fois que les composants requis sont installés sur votre
système, il ne reste plus qu'à configurer Apache au moyen de son
fichier httpd.conf
. Indiquez à Apache de
charger le module mod_dav_svn grâce à la
directive LoadModule
. Cette directive doit
précéder tout autre élément de configuration lié à Subversion.
Si votre serveur Apache a été installé avec la configuration par
défaut, votre module mod_dav_svn devrait
avoir été installé dans le sous-répertoire
modules
du répertoire d'installation
d'Apache (souvent /usr/local/apache2
). La
directive LoadModule
a une syntaxe très
simple, faisant correspondre un nom de module à l'emplacement
sur le disque d'une bibliothèque partagée :
LoadModule dav_svn_module modules/mod_dav_svn.so
Apache interprète le chemin donné dans la directive
LoadModule
comme étant relatif à sa propre
racine. Si vous l'avez configuré comme indiqué
supra,
Apache cherchera le module Subversion DAV dans son propre
sous-dossier modules/
. En fonction de la
façon dont Subversion a été installé sur votre machine, vous
aurez peut-être besoin de spécifier un chemin différent pour
cette bibliothèque, voire un chemin absolu comme dans l'exemple
suivant :
LoadModule dav_svn_module C:/Subversion/libexec/mod_dav_svn.so
Notez que si mod_dav a aussi été compilé
sous forme de bibliothèque partagée (et non par une édition de
liens statiques qui le place alors directement dans l'exécutable
httpd), il vous faudra une directive
LoadModule
pour celui-ci. Assurez-vous
qu'elle est placée avant la ligne
mod_dav_svn :
LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so
Plus loin dans votre fichier de configuration, vous
devez indiquer à Apache l'endroit où réside votre dépôt (ou vos
dépôts) Subversion. La directive Location
possède une syntaxe de type XML, qui commence par une balise de
début, se termine par une balise de fin et contient diverses autres
directives de configuration au milieu. Le sens de la directive
Location
est de faire faire à Apache quelque
chose de spécial quand il traite les requêtes adressées à une
URL donnée ou à une de ses filles. Dans le cas de Subversion, il
faut qu'Apache fasse traiter par la couche DAV les URL pointant
vers les ressources suivies en versions. Vous pouvez indiquer à
Apache de déléguer le traitement de toutes les URL dont la
partie chemin d'accès (la partie de l'URL qui suit le nom du
serveur et le numéro de port optionnel) commence par
/depot/
à un gestionnaire de DAV dont le
dépôt est situé à l'adresse
/var/svn/mon-depot
en utilisant la syntaxe
httpd.conf
suivante :
<Location /repos> DAV svn SVNPath /var/svn/mon-depot </Location>
Si vous avez l'intention de gérer plusieurs dépôts
Subversion résidant dans le même répertoire parent sur votre
disque local, vous pouvez utiliser une directive alternative,
SVNParentPath
, pour faire état de ce
répertoire parent commun. Par exemple, si vous savez que vous
allez créer plusieurs dépôts Subversion dans le répertoire
/var/svn
, auxquels on accédera par des URL
telles que http://mon.serveur.com/svn/depot1
,
http://mon.serveur.com/svn/depot2
, etc., vous
pouvez utiliser la syntaxe de configuration de
httpd.conf
de l'exemple
suivant :
<Location /svn> DAV svn # à toute URL "/svn/truc" correspond un dépôt /var/svn/truc SVNParentPath /var/svn </Location>
Par cette syntaxe, Apache va déléguer le traitement de
toutes les URL dont le chemin d'accès commence par
/svn/
au gestionnaire DAV de Subversion,
qui ensuite supposera que tous les éléments du répertoire
spécifié dans la directive SVNParentPath
sont
en fait des dépôts Subversion. C'est une syntaxe
particulièrement pratique dans le sens où, à la différence de
celles utilisant la directive SVNPath
, vous
n'avez pas besoin de redémarrer Apache pour mettre à
disposition ou enlever de nouveaux dépôts sur le réseau.
Vérifiez bien que, quand vous définissez votre nouvelle
directive Location
, elle n'interfère pas avec
d'autres emplacements exportés. Par exemple, si votre
DocumentRoot
(c'est-à-dire le répertoire
racine des fichiers qu'Apache expose sur le web) principal est
exporté vers /www
, n'exportez pas de dépôt
Subversion vers <Location /www/depot>
.
Si une requête arrivait pour l'URI
/www/depot/machin.c
, Apache ne saurait pas
s'il doit chercher un fichier depot/machin.c
dans son DocumentRoot
ou s'il doit déléguer à
mod_dav_svn la tâche de renvoyer
machin.c
qui se trouve dans le dépôt
Subversion. Ceci aboutit souvent à une erreur du serveur de la
forme 301 Moved Permanently
.
À présent, il nous faut examiner sérieusement la question des droits d'accès. Si vous utilisez Apache depuis un certain temps en tant que serveur web principal, vous hébergez certainement pas mal de contenu : des pages web, des scripts, etc. Ces éléments ont déjà été configurés avec un ensemble de droits qui leur permet de fonctionner avec Apache, ou plus exactement qui permet à Apache de travailler avec ces fichiers. Apache, quand on l'utilise en tant que serveur Subversion, a aussi besoin de droits d'accès corrects pour lire et écrire dans votre dépôt.
Vous devez mettre en place les droits d'accès qui satisfont
les besoins de Subversion sans mettre à mal l'installation des
pages web et scripts pré-existants. Ceci implique peut-être de
modifier les droits d'accès de votre dépôt Subversion pour
qu'ils correspondent à ceux utilisés par les autres éléments
qu'Apache gère, ou bien utiliser les directives
User
et Group
du fichier httpd.conf
pour spécifier
qu'Apache doit fonctionner avec l'identifiant et le groupe qui
est propriétaire de votre dépôt Subversion. Il n'y a pas une
façon unique de mettre en place les droits d'accès et chaque
administrateur a ses propres raisons pour faire les choses d'une
manière ou d'une autre. Soyez juste conscient que les problèmes
liés aux droits d'accès sont peut-être le point le plus négligé
lors de la configuration d'un dépôt avec Apache.
À ce stade, si vous avez configuré
httpd.conf
avec quelque chose du
style :
<Location /svn> DAV svn SVNParentPath /var/svn </Location>
votre dépôt est à présent accessible
« anonymement » par tout le monde. Jusqu'à ce que
configuriez des politiques d'authentification et de contrôle
d'accès, les dépôts Subversion que vous rendez disponibles
via la directive
Location
sont généralement accessibles à
tous. En d'autres termes :
N'importe qui peut utiliser un client Subversion pour extraire une copie de travail d'une URL du dépôt (ou de n'importe lequel de ses sous-répertoires).
N'importe qui peut naviguer interactivement dans la dernière révision du dépôt rien qu'en allant avec un navigateur web à l'URL du dépôt.
N'importe qui peut effectuer des propagations vers le dépôt.
Bien sûr, vous avez peut-être déjà mis en place une
procédure automatique pre-commit
pour
empêcher les propagations (voir la section intitulée « Mise en place des procédures automatiques »). Mais en progressant
dans la lecture de ce chapitre, vous verrez qu'il est également
possible d'utiliser les méthodes intégrées dans Apache pour
restreindre les accès de façon spécifique.
Astuce | |
---|---|
Demander une authentification vous protège contre les utilisateurs illégitimes qui accèdent au dépôt mais ne garantit la confidentialité des utilisateurs légitimes sur le réseau. Reportez-vous à la section intitulée « Encapsulation du trafic réseau avec SSL » pour savoir comment configurer votre serveur pour activer l'encapsulation SSL, ce qui apportera une couche supplémentaire de protection. |
La manière la plus facile d'authentifier un client est le mécanisme d'authentification « Basic » de HTTP, qui utilise juste un nom d'utilisateur et un mot de passe pour vérifier que l'utilisateur est bien celui qu'il prétend être. Apache fournit l'utilitaire htpasswd[66] pour gérer la liste des noms d'utilisateurs et mots de passe acceptés.
Avertissement | |
---|---|
L'authentification basique est
extrêmement peu sûre car elle envoie
le mots de passe sur le réseau, pratiquement en clair. Lisez
la section intitulée « Authentification par condensat
(Digest) » pour
obtenir des détails sur l'utilisation du mécanisme par
condensat ( |
Commençons par créer un fichier de mots de passe et donnons un accès à Sally et à Harry :
$ ### Première fois : utilisez -c pour créer le fichier $ ### Ajoutez -m pour MD5 afin de chiffrer le mot de passe et ainsi le rendre plus sûr $ htpasswd -cm /etc/auth-svn.htpasswd harry New password: ***** Re-type new password: ***** Adding password for user harry $ htpasswd -m /etc/auth-svn.htpasswd sally New password: ******* Re-type new password: ******* Adding password for user sally $
Ensuite, vous devez vérifier que Apache dispose des droits
d'accès aux modules qui offrent l'authentification basique et
les fonctionnalités afférentes :
mod_auth_basic,
mod_authn_file et
mod_authz_user. Généralement, ces modules
sont compilés dans httpd lui-même, mais si
ce n'estpas le cas, vous devrez charger ceux qui ne le sont
pas explicitement en utilisant la directive
LoadModule
:
LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authz_user_module moduels/mod_authz_user.so
Après vous être assuré que Apache a accès auxdites
fonctionnalités, vous devrez ajouter quelques directives dans
le bloc <Location>
pour indiquer à
Apache quel type d'authentification vous souhaitez utiliser et
comment le faire :
<Location /svn> DAV svn SVNParentPath /var/svn # Authentication: Basic AuthName "Depot Subversion" AuthType Basic AuthBasicProvider file AuthUserFile /etc/auth-svn.htpasswd </Location>
Ces directives fonctionnent ainsi :
AuthName
est une chaîne de
caractères arbitraire que vous choisissez pour définir le
domaine d'authentification. La plupart des navigateurs
affichent cette chaîne dans la boîte de dialogue au moment
de demander le nom d'utilisateur et le mot de
passe.
AuthType
spécifie le type
d'authentification à utiliser.
AuthBasicProvider
spécifie le
fournisseur de l'authentification basique pour cet
emplacement. Dans notre exemple, nous consultons un
fichier local de mots de passe.
AuthUserFile
spécifie l'emplacement
du fichier de mots de passe à utiliser.
Ce bloc <Location>
n'est pas
encore complet et il ne sert pas à grand chose pour l'instant.
Il indique juste à Apache que, si un
contrôle d'accès est requis, Apache doit demander un nom
d'utilisateur et un mot de passe au client Subversion. En
effet, dès qu'un contrôle d'accès est requis, Apache exige
également l'authentification. Ce qui manque ici, cependant, ce
sont les directives qui indiquent à Apache quelles
sortes de requêtes client requièrent un contrôle
d'accès ; pour l'instant, aucune requête n'en requiert.
La chose la plus simple à faire alors est de spécifier que
toutes les requêtes demandent un
contrôle d'accès en ajoutant
Require valid-user
au bloc :
<Location /svn> DAV svn SVNParentPath /var/svn # Authentification: basique AuthName "Depot Subversion" AuthType Basic AuthBasicProvider file AuthUserFile /etc/auth-svn.htpasswd # contrôle d'accès : utilisateurs authentifiés seulement Require valid-user </Location>
Prenez bien soin de lire la section intitulée « Contrôle d'accès » pour plus de
détails sur la directive Require
et sur les
autres manières de mettre en œuvre des politiques de contrôle
d'accès.
Note | |
---|---|
La valeur par défaut pour l'option
|
La méthode d'authentification Digest
,
améliore la méthode basique dans le sens où elle permet au
serveur de vérifier l'identité du client sans envoyer
le mot de passe en clair sur le réseau. Chacun de leur côté,
le client et le serveur calculent un condensat
(hash ou
digest en anglais) à partir de
l'identifiant, du mot de passe, de l'URI demandée et d'un
nonce (nombre utilisé une seule fois)
fourni par le serveur et changé à chaque demande
d'authentification. Le client envoie son condensat au serveur
et celui-ci vérifie si le condensat correspond à ses
attentes.
Configurer Apache pour la méthode d'authentification
Digest
est facile. En premier lieu,
assurez-vous que le module mod_auth_digest
est disponible (à la place de
mod_auth_basic) et effectuez les petites
variations suivantes par rapport à notre exemple
précédent :
<Location /svn> DAV svn SVNParentPath /var/svn # Authentification: condensat AuthName "Depot Subversion" AuthType Digest AuthDigestProvider file AuthUserFile /etc/auth-svn.htdigest # contrôle d'accès : utilisateurs authentifiés seulement Require valid-user </Location>
Notez que AuthType
vaut maintenant
Digest
et que nous avons spécifié un
chemin différent pour AuthUserFile
.
L'authentification par condensat utilise un format de fichier
différent de l'authentification basique, créé et géré par
l'utilitaire htdigest
[67] d'Apache, et non
htpasswd. L'authentification par condensat
utilise aussi le concept de
realm (« domaine
d'authentification » en français), dont la valeur est
indiquée dans la directive AuthName
.
Note | |
---|---|
Pour l'authentification par condensat, le fournisseur
d'authentification est choisi en utilisant la directive
|
Le fichier des mots de passe peut être créé ainsi :
$ ### Première fois : utilisez -c pour créer le fichier $ htdigest -c /etc/auth-svn.htdigest "Depot Subversion" harry Adding password for harry in realm Depot Subversion. New password: ***** Re-type new password: ***** $ htdigest /etc/auth-svn.htdigest "Depot Subversion" sally Adding user sally in realm Depot Subversion. New password: ******* Re-type new password: ******* $
À ce point, vous avez configuré l'authentification mais pas le contrôle d'accès. Apache est capable de vérifier les identités que proclament les clients mais on ne lui a pas encore indiqué quand autoriser ou interdire l'accès aux clients qui proclament ces identités. Cette section décrit deux stratégies pour contrôler les accès à vos dépôts.
La méthode la plus simple de contrôle d'accès est d'autoriser certains utilisateurs pour un accès en lecture seule à un dépôt ou en lecture/écriture à un dépôt.
Vous pouvez restreindre les accès sur toutes les
opérations d'un dépôt en ajoutant la directive
Require valid-user
directement dans le bloc
<Location>
. L'exemple fourni dans
la section intitulée « Authentification par condensat
(Digest) »
autorise seulement les clients qui ont passé avec succès
l'authentification et leur permet de tout faire avec le dépôt
Subversion :
<Location /svn> DAV svn SVNParentPath /var/svn # Authentification : condensat AuthName "Depot Subversion" AuthType Digest AuthUserFile /etc/auth-svn.htdigest # contrôle d'accès : utilisateurs authentifiés seulement Require valid-user </Location>
Mais vous n'êtes pas obligé d'être aussi sévère. Par
exemple, le serveur hébergeant le code source de Subversion à
http://svn.apache.org/repos/asf/subversion
permet à n'importe qui d'effectuer des accès en lecture seule
(tels que des extractions de copies de travail ou parcourir
le dépôt), mais il restreint les opérations d'écriture aux
utilisateurs authentifiés. Les directives
Limit
et LimitExcept
permettent ce type de comportement. À l'instar de
Location
, ces blocs possèdent une étiquette
de début et une de fin, et vous pouvez les insérer dans des
blocs <Location>
.
Les paramètres inclus dans les directives
Limit
et LimitExcept
sont les types de requêtes concernés par ces blocs. Ainsi, par
exemple pour autoriser l'accès en lecture seule aux
utilisateurs anonymes, vous utiliserez la directive
LimitExcept
(en lui donnant
GET
, PROPFIND
,
OPTIONS
et REPORT
comme
types de requête autorisés) et vous placerez la directive
Require valid-user
citée précédemment
dans le bloc <LimitExcept>
au lieu de
juste la placer dans le bloc
<Location>
.
<Location /svn> DAV svn SVNParentPath /var/svn # Authentification : condensat AuthName "Depot Subversion" AuthType Digest AuthUserFile /etc/auth-svn.htdigest # contrôle d'accès : utilisateurs authentifiés : écriture # anonymes : lecture seule <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
Ce ne sont là que quelques exemples simples. Pour des
informations plus poussées sur le contrôle d'accès d'Apache et
la directive Require
, jetez un œil à la
section Security
du recueil des didacticiels
de la documentation Apache à l'adresse https://httpd.apache.org/docs-2.0/misc/tutorials.html.
Il est également possible de mettre en place des droits d'accès avec une granularité plus fine en utilisant le module mod_authz_svn. Ce module Apache se saisit des diverses URL opaques qui transitent entre le client et le serveur, demande à mod_dav_svn de les décoder et ensuite met éventuellement son veto à certaines requêtes en se basant sur les politiques d'accès définies dans un fichier de configuration.
Si vous avez compilé Subversion à partir du code source,
mod_authz_svn est automatiquement inclus et
installé aux côtés de mod_dav_svn. De
nombreux exécutables distribués l'installent automatiquement
aussi. Pour vérifier s'il est installé correctement,
assurez-vous qu'il vient juste après la directive
LoadModule
de
mod_dav_svn dans le fichier
httpd.conf
:
LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so
Pour activer ce module, vous devez configurer votre bloc
<Location>
pour qu'il utilise la directive
AuthzSVNAccessFile
; elle spécifie
quel fichier contient les politiques de contrôle d'accès aux
chemins de vos dépôts. À partir de Subversion 1.7, vous pouvez
aussi utiliser la directive
AuthzSVNReposRelativeAccessFile
pour spécifier
un fichier de contrôle d'accès spécifique par dépôt (nous allons
étudier le format de ce fichier un peu plus tard).
Apache est flexible, vous avez donc la possibilité de configurer votre bloc selon une méthode à choisir parmi trois. Pour commencer, choisissez une des méthodes de configuration de base (les exemples suivants sont très simples ; reportez-vous à la documentation Apache qui contient beaucoup plus de détails sur les options d'authentification et de contrôle d'accès d'Apache).
L'approche la plus simple consiste à donner l'accès à tout le monde. Dans ce scénario, Apache n'envoie jamais de défi d'authentification, tous les utilisateurs sont donc traités en tant qu'« anonymes » (voir l'Exemple 6.2, « Exemple-type de configuration : accès anonyme »).
Exemple 6.2. Exemple-type de configuration : accès anonyme
<Location /depot> DAV svn SVNParentPath /var/svn # Authentification : aucune # Contrôle d'accès : par répertoire AuthzSVNAccessFile /chemin/vers/fichier/acces </Location>
À l'opposé sur l'échelle de la paranoïa, vous pouvez
configurer votre bloc de telle sorte qu'il exige que tout le
monde s'authentifie. Ici, tous les clients doivent fournir un
mot de passe pour prouver leur identité. Votre bloc exige
l'authentification inconditionnelle
via la directive
Require valid-user
et définit le moyen de
s'authentifier (voir l'Exemple 6.3, « Exemple-type de configuration : accès
authentifié »).
Exemple 6.3. Exemple-type de configuration : accès authentifié
<Location /repos> DAV svn SVNParentPath /var/svn # Authentification : condensat AuthType Digest AuthName "Depot Subversion" AuthUserFile /etc/auth-svn.htdigest # Contrôle d'accès : par répertoire, # seuls les utilisateurs authentifiés ont accès au dépôt AuthzSVNAccessFile /chemin/vers/fichier/acces Require valid-user </Location>
Une troisième méthode très pratiquée consiste à
autoriser à la fois des accès anonymes et des accès
authentifiés. Par exemple, de nombreux administrateurs
désirent autoriser les utilisateurs anonymes à lire certains
répertoires dans les dépôts mais ne veulent voir que des
utilisateurs authentifiés accéder en lecture (ou en écriture)
dans des zones plus sensibles. Dans cette configuration, tous
les utilisateurs commencent par accéder au dépôt de façon
anonyme. Si votre politique de contrôle d'accès exige un
véritable nom d'utilisateur à un moment ou à un autre, Apache
demandera au client de s'authentifier. Pour ce faire, vous
devez utiliser à la fois la directive Satisfy
Any
et la directive Require
valid-user
(voir l'Exemple 6.4, « Exemple-type de configuration : accès mixte
authentifié/anonyme »).
Exemple 6.4. Exemple-type de configuration : accès mixte authentifié/anonyme
<Location /repos> DAV svn SVNParentPath /var/svn # Authentification : Digest AuthName "Depot Subversion" AuthType Digest AuthUserFile /etc/auth-svn.htdigest # Contrôle d'accès : par répertoire # d'abord essayer l'accès anonyme # s'authentifier si nécessaire AuthzSVNAccessFile /chemin/vers/fichier/accès Satisfy Any Require valid-user </Location>
L'étape suivante consiste à créer un fichier contenant les règles d'accès particulières pour chaque chemin de votre dépôt. Nous en parlons en détails plus loin dans ce chapitre, à la section intitulée « Contrôle d'accès basé sur les chemins ».
Le module mod_dav_svn se donne beaucoup
de peine pour assurer que les données que vous avez désignées
comme « interdites » ne soient pas divulguées
accidentellement. Cela veut dire qu'il doit surveiller
étroitement tous les chemins d'accès et tous les contenus des
fichiers renvoyés par des commandes telles que svn
checkout et svn update.
Si ces commandes tombent sur un chemin qui n'est pas lisible à
cause d'une politique de contrôle d'accès, le chemin est
généralement totalement omis. Dans le cas d'une recherche
d'historique ou de renommage, par exemple une commande
telle que svn cat -r ANCIENNE_REVISION
truc.c
sur un fichier qui a été renommé il y a
longtemps, le suivi des renommages va simplement s'arrêter si
un des anciens noms de l'objet se révèle être en accès
restreint en lecture.
Ces contrôles sur les chemins peuvent parfois être assez
coûteux, tout particulièrement dans le cas de svn
log. Quand il demande une liste de révisions, le
serveur examine chaque chemin modifié dans chaque révision et
vérifie qu'il a le droit d'être lu. Si un chemin interdit est
découvert, il est omis de la liste des chemins modifiés par
la révision (obtenue habituellement par l'option
--verbose
) et le commentaire de propagation est
entièrement supprimé. Il va sans dire que ceci peut prendre un
certain temps pour les révisions qui ont touché à un grand
nombre de fichiers. C'est le coût de la sécurité : même
si vous n'avez pas du tout configuré de module tel que
mod_authz_svn, le module
mod_dav_svn va quand même demander à
httpd Apache de vérifier les droits
d'accès pour chaque chemin. Le module
mod_dav_svn n'est pas au courant de la
liste des modules de contrôle d'accès qui ont été installés,
donc tout ce qu'il peut faire est de demander à Apache de
lancer les modules correspondants, quels qu'ils soient.
D'un autre côté, il existe une sorte d'échappatoire qui
vous permet d'échanger la sécurité contre de la vitesse. Si
vous ne mettez pas en œuvre de contrôle d'accès sur les
chemins (c'est-à-dire, si vous n'utilisez ni
mod_authz_svn ni un module similaire), vous
pouvez désactiver tous ces contrôles sur les chemins. Dans
votre fichier httpd.conf
, utilisez la
directive SVNPathAuthz
comme illustré dans
l'Exemple 6.5, « Désactiver complètement les contrôles sur les
chemins ».
Exemple 6.5. Désactiver complètement les contrôles sur les chemins
<Location /depot> DAV svn SVNParentPath /var/svn SVNPathAuthz off </Location>
La directive SVNPathAuthz
est activée
(« on ») par défaut. Quand on la désactive
(« off »), tous les contrôles d'accès basés sur les
chemins sont désactivés ; mod_dav_svn
arrête de demander un contrôle d'accès chaque chemin qu'il
traite.
À partir de Subversion 1.8, le fichier de contrôle d'accès peut être stocké dans un dépôt Subversion. Il est possible de stocker ce ficher dans le dépôt même pour lequel sont gérés les droits d'accès, ou dans un autre dépôt. Cette approche permet d'avoir les fonctionnalités de gestion de versions pour la configuration du contrôle d'accès aux chemins.
Les deux directives de configuration
AuthzSVNAccessFile
et
AuthzSVNReposRelativeAccessFile
permettent
de spécifier l'emplacement du fichier de contrôle d'accès à
l'intérieur d'un dépôt. Ces directives reconnaissent les
URL absolues de type file://
et les URL
relatives aux dépôts (celles qui commencent par
^/
).
Par exemple, il est possible de spécifier une URL absolue pour un fichier de contrôle d'accès comme le montre Exemple 6.6, « Utilisation d'un fichier de contrôle d'accès unique suivi en versions à l'intérieur d'un dépôt ».
Exemple 6.6. Utilisation d'un fichier de contrôle d'accès unique suivi en versions à l'intérieur d'un dépôt
<Location /dépôt> DAV svn SVNParentPath /var/svn AuthzSVNAccessFile file:///var/svn/dépôt-authz/authz </Location>
Vous pouvez aussi spécifier une URL relative pointant vers un fichier à l'intérieur du dépôt lui-même, comme montré dans Exemple 6.7, « Utilisation d'un fichier de contrôle d'accès spécifique pour chaque dépôt ».
Exemple 6.7. Utilisation d'un fichier de contrôle d'accès spécifique pour chaque dépôt
<Location /dépôt> DAV svn SVNParentPath /var/svn AuthzSVNReposRelativeAccessFile ^/authz </Location>
Lorsque vous vous connectez à un dépôt
via http://
,
tout le trafic généré par Subversion est envoyé en clair sur le
réseau. Cela veut dire que les extractions, les propagations et
les mises à jour peuvent être interceptées par une entité non
autorisée qui « écoute » le trafic réseau. Chiffrer
le trafic en utilisant SSL vous permet de protéger l'envoi
d'informations sensibles sur le réseau.
Si un client Subversion est compilé pour l'utilisation de
SSL, il peut alors se connecter au serveur Apache en utilisant
des URL de type https://
, ce qui chiffrera
tout le trafic avec une clé de session propre à chaque
connexion. La bibliothèque WebDAV utilisée par le client
Subversion n'est pas seulement capable de vérifier le certificat
présenté par le serveur mais peut aussi utiliser des
certificats clients au cas où le serveur le demande.
La création de certificats SSL clients et serveurs ainsi que la configuration d'Apache pour les utiliser sort du cadre de ce livre. Il existe beaucoup de références, y compris la propre documentation d'Apache (https://httpd.apache.org/docs/current/ssl/), qui décrivent comment faire.
Astuce | |
---|---|
Les certificats SSL produits par des sociétés bien connues sont généralement payants mais vous pouvez, au minimum, configurer Apache pour utiliser un certificat auto-signé qui a été généré avec, par exemple, OpenSSL (https://www.openssl.org).[68] |
Quand il se connecte à une serveur Apache en
https://
, un client Subversion peut
recevoir deux types de réponse :
un certificat serveur ;
un défi pour un certificat client.
Quand le client reçoit un certificat serveur, il doit vérifier que le serveur est bien celui qu'il prétend être. OpenSSL réalise cette tâche en examinant le signataire du certificat serveur, appelé autorité de certification (AC en français, CA pour certificat authority en anglais). Si OpenSSL ne fait pas confiance à cette AC, ou si un autre problème apparaît (tel qu'un certificat ayant expiré ou alors le nom de la machine qui ne correspond pas à ce qui est indiqué dans le certificat), le client texte interactif Subversion vous demande si vous voulez quand même faire confiance à ce certificat serveur :
$ svn list https://hote.exemple.com/depot/projet Error validating server certificate for 'https://hote.exemple.com:443': - The certificate is not issued by a trusted authority. Use the fingerprint to validate the certificate manually! Certificate information: - Hostname: hote.exemple.com - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT - Issuer: CA, exemple.com, Sometown, California, US - Fingerprint: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b (R)eject, accept (t)emporarily or accept (p)ermanently?
Vous pourriez voir cette même question dans votre
navigateur (car c'est aussi un client HTTP tout comme
Subversion). Si vous choisissez l'option
(p)
permanent, Subversion placera le
certificat serveur en cache dans votre zone privée de
configuration (dossier auth/
) ainsi que
votre nom d'utilisateur et votre mot de passe (voir
la section intitulée « Éléments d'authentification du client »). Il fera
alors automatiquement confiance au certificat dans le
futur.
Votre fichier servers
de la zone de
configuration vous permet aussi de spécifier des AC de
confiance, que ce soit globalement ou hôte par hôte.
Affectez simplement une liste (dont les éléments sont
séparés par des points-virgules) de chemins vers des
certificats d'AC encodés au format PEM à la variable
ssl-authority-files
:
[global] ssl-authority-files = /chemin/vers/certificat-AC1.pem;/chemin/vers/certificat-AC2.pem
Beaucoup d'installations d'OpenSSL sont fournies avec
une liste d'autorités « universellement de
confiance ». Pour que le client Subversion fasse
confiance à ces autorités, affectez la valeur
true
à la variable
ssl-trust-default-ca
.
Quand le client reçoit un défi d'authentification, cela veut dire que le serveur demande au client de prouver son identité. Le client doit renvoyer un certificat signé par une AC qui a la confiance du serveur ainsi qu'une réponse de défi (Challenge Response en anglais) qui prouve que le client possède la clé privée associée au certificat. La clé privée et le certificat sont généralement stockés à l'intérieur d'un conteneur chiffré sur le disque et sont protégés par une phrase de passe. Quand Subversion reçoit le défi, il vous demande le chemin vers le conteneur et la phrase de passe qui protège son accès :
$ svn list https://hote.exemple.com/depot/projet Authentication realm: https://hote.exemple.com:443 Client certificate filename: /chemin/vers/mon/conteneur.p12 Passphrase for '/chemin/vers/mon/conteneur.p12': ********
Notez que les éléments d'authentification du client sont
stockés dans un conteneur dont l'extension est
.p12
. Pour utiliser un certificat client
avec Subversion, il doit être au format PKCS#12, ce qui est
un standard. La plupart des navigateurs Web savent importer
et exporter des certificats dans ce format. Une autre
possibilité est d'utiliser les utilitaires en ligne de
commande d'OpenSSL pour convertir des certificats existants
au format PKCS#12.
Le fichier servers
de la zone de
configuration vous permet d'automatiser la phase de défi
pour les hôtes que vous spécifiez. Si vous définissez les
variables ssl-client-cert-file
et
ssl-client-cert-password
, Subversion
répond automatiquement aux défis demandés par les serveurs
sans vous solliciter :
[groups] serveur_exemple = hote.exemple.com [serveur_exemple] ssl-client-cert-file = /chemin/vers/mon/conteneur.p12 ssl-client-cert-password = maphrasedepasseestlongue
Les plus exigeants en matière de sécurité interdiront
l'affectation des phrases de passe dans la
variable ssl-client-cert-password
car
celles-ci sont alors stockées en clair sur le disque.
Le serveur HTTP Apache a été conçu pour être performant
mais vous pouvez modifier la configuration par défaut pour
gagner encore en performances pour votre service Subversion.
Dans cette section, nous allons vous proposer quelques
modifications de configuration de
httpd.conf
. Comprenez cependant que
certaines des modifications proposées affectent le comportement
général du serveur, et pas seulement le service Subversion.
Ainsi, vous devez prendre en compte l'ensemble de ces services
pour décider s'il est opportun d'effectuer ou non les
modifications proposées.
Par défaut, le serveur HTTP Apache est configuré pour
autoriser la réutilisation d'une même connexion serveur par
plusieurs requêtes client. C'est particulièrement avantageux
pour Subversion car, au contraire de beaucoup d'applications
sur HTTP, Subversion peut générer très rapidement des
centaines voire des milliers de requêtes vers un serveur pour
une seule opération et le coût d'ouvrir une nouvelle connexion
vers un serveur n'est pas négligeable. Subversion veut faire
rentrer le maximum de requêtes dans une seule connexion avant
que celle-ci ne soit fermée par le serveur. La directive
KeepAlive
est un booléen qui active ou
désactive cette réutilisation de connexion et, comme indiqué
précédemment, sa valeur par défaut est
On
.
Mais il existe une autre directive qui limite le nombre
de requêtes qu'un client peut soumettre sur une seule
connexion : la directive
MaxKeepAliveRequests
. La valeur par défaut
pour cette option est 100
. C'était
probablement suffisant pour les vieilles versions de
Subversion, mais Subversion 1.8 utilise une bibliothèque de
communication différente (appelée Serf) qui préfère lancer
plusieurs petites requêtes pour récupérer des informations
bien précises plutôt que de demander au serveur de transmettre
d'énormes quantités de données en une seule réponse. Nous vous
recommandons d'augmenter la valeur affectée à l'option
MaxKeepAliveRequests
à au moins
1000
.
# # KeepAlive: autoriser ou pas les connexions persistantes (plus d'une # requête par connexion). Mettre la valeur "Off" pour la désactiver. # KeepAlive On # # MaxKeepAliveRequests: nombre maximum de requêtes autorisées pour une # connexion persistante. Mettre à 0 pour autoriser un nombre illimité. # Nous recommandons de laisser ce nombre élevé pour améliorer les # performances. # MaxKeepAliveRequests 1000
La plus grosse différence entre le client Subversion 1.8
et ses prédécesseurs concerne la manière dont il effectue les
opérations de mises à jour (svn checkout,
svn update, svn switch,
etc.). Les vieux clients, qui utilisaient la bibliothèque HTTP
Neon pour les communications, préféraient demander au serveur
l'ensemble des informations dans une seule requête. Les
administrateurs pouvaient alors voir, dans les journaux de
connexions du serveur, la négociation initiale de la
transaction puis une requête REPORT
dont la
réponse était énorme. Cette réponse contenait l'extraction ou
la mise à jour dans son ensemble !
Les clients Subversion qui utilisent la bibliothèque HTTP
Serf (ce qui inclut tous les clients basés sur Subversion 1.8)
envoient toujours la requête REPORT
mais
avec des paramètres légèrement différents. Ces paramètres ne
demandent pas au serveur d'envoyer toutes les données
relatives à l'opération mais d'envoyer seulement une liste de
vérifications des choses spécifiques que le client devra
récupérer auprès du serveur pour accomplir l'opération. Dans
le journal access_log
du serveur, la
ligne REPORT
est suivie par beaucoup de
petites requêtes (GET
et, pour les vieilles
versions de Subversion, PROPFIND
).
Chacune des deux approches a ses avantages et ses
inconvénients. Comme nous l'avons déjà mentionné, les mises à
jour groupées (bulk updates en
anglais) produisent beaucoup moins de lignes dans les journaux
du serveur mais un processus fils du serveur Apache HTTP est
entièrement dédié à cette opération, qui peut se révéler
particulièrement longue, jusqu'à sa fin. Les mises à jour
par petites touches permettent de mettre en place des caches
(ce qui contribuera à améliorer les performances) mais vont
générer dans les journaux un nombre de lignes sans commune
mesure avec l'approche par mises à jour groupées. En
conséquence, les administrateurs auront leur mot à dire sur la
méthode utilisée par les clients pour se mettre à jour.
Subversion 1.6 a ainsi introduit la directive
SVNAllowBulkUpdates
de
mod_dav_svn : un simple booléen pour
laisser aux administrateurs le choix de spécifier si le
serveur accepte les requêtes de mises à jour groupées. Avec
Subversion 1.8, cette directive s'est complétée avec la
possibilité d'indiquer Prefer
en plus de
On
et Off
. Quand
SVNAllowBulkUpdates
vaut
Prefer
, les clients qui reconnaissent cette
option (c'est-à-dire les versions 1.8 ou plus récentes)
tenteront des mises à jour groupées à moins d'avoir été
configurés autrement.
Nous avons couvert la plupart des options d'authentification et de contrôle d'accès pour Apache et mod_dav_svn. Mais il existe encore quelques autres directives d'Apache qui méritent d'être abordées.
Un des avantages les plus frappants d'avoir une
configuration Apache/WebDAV pour votre dépôt Subversion est
que les révisions les plus récentes de vos fichiers et
répertoires suivis en versions sont immédiatement consultables
à l'aide d'un navigateur web classique. Puisque Subversion
utilise des URL pour identifier les ressources suivies en
versions, ces URL utilisées pour accéder aux dépôts
via HTTP peuvent être tapées
directement dans un navigateur web. Votre navigateur enverra
une requête HTTP GET
pour cette URL ;
selon que cette URL représente ou non un fichier ou un
répertoire suivi en versions, mod_dav_svn
renverra soit la liste des éléments du répertoire, soit le
contenu du fichier.
Comme les URL ne contiennent pas d'informations relatives à la version de la ressource qui vous intéresse, mod_dav_svn renverra toujours la version la plus récente. Cette fonctionnalité a un merveilleux effet secondaire : vous pouvez partager avec vos pairs des URL Subversion en guise de références à des documents et ces URL pointeront toujours vers la dernière version des documents. Bien sûr, vous pouvez aussi utiliser ces URL en tant que liens hypertextes dans d'autres sites web.
Depuis Subversion 1.6, mod_dav_svn
reconnait une syntaxe d'URI particulière pour examiner les
vieilles révisions des fichiers et des répertoires. Cette
syntaxe utilise la partie « requête » de l'URL
pour spécifier une révision pivot ou une révision
opérationnelle. Subversion utilisera ces arguments pour
déterminer la version du fichier ou du répertoire que vous
voulez afficher dans votre navigateur. Ajoutez la paire
p=
,
où REV_PIVOT
REV_PIVOT
est un numéro
de révision, pour spécifier la révision pivot que vous
souhaitez appliquer à la requête. Utilisez
r=
, où
REV
REV
est un numéro de révision,
pour spécifier une révision opérationnelle.
Par exemple, si vous voulez voir la dernière version du
fichier LISEZMOI.txt
situé dans
/trunk
de votre projet, faites pointer
votre navigateur vers l'URL de ce fichier, qui devrait
ressembler à quelque chose comme ceci :
http://hote.exemple.com/depot/projet/trunk/LISEZMOI.txt
Si vous voulez voir une version plus ancienne de ce fichier, ajouter une révision opérationnelle à l'URL:
http://hote.exemple.com/depot/projet/trunk/LISEZMOI.txt?r=1234
Que se passe-t-il si ce que vous voulez voir n'existe plus dans la révision la plus récente du dépôt ? C'est maintenant qu'une révision pivot est utile :
http://hote.exemple.com/depot/projet/trunk/LISEZMOI.txt?p=321
Et bien sûr, vous pouvez combiner une révision pivot et une révision opérationnelle pour dénicher l'élément précis que vous souhaitez voir :
http://hote.exemple.com/depot/projet/trunk/LISEZMOI.txt?p=123&r=21
L'URL ci-dessus affichera la révision 21 de l'objet qui,
dans la révision 123, se trouvait à
/trunk/chose-renommée.txt
dans le
dépôt. Reportez-vous à la section intitulée « Révisions pivots et révisions opérationnelles » pour une explication détaillée des concepts de
« révision pivot » et « révision
opérationnelle », ils peuvent être relativement
difficiles à appréhender.
À partir de Subversion 1.8,
mod_dav_svn a acquis la capacité de
substituer des mots-clés. Quand
mod_dav_svn trouve dans l'URL de la
requête un argument kw=1
, il substitue
les mots-clés au moment de renvoyer la réponse. Ne pas
spécifier de paramètre kw
ou lui affecter
une valeur autre que 1
entraine le
comportement par défaut, c'est-à-dire renvoyer le
contenu du fichier sans avoir substitué les
mots-clés.
Puisque la substitution des mots-clés est typiquement une opération réalisée par le client Subversion, dans le cadre de l'administration et la gestion des copies de travail, ce moyen de substituer les mots-clés par le serveur trouve toute son utilité dans le cas où vous n'utilisez pas de copie de travail.
Par exemple, si vous souhaitez voir la dernière version
du fichier LISEZMOI.txt
situé dans
/trunk
avec les mots-clés substitués,
ajoutez l'argument kw=1
dans l'URL de
votre requête :
http://hote.exemple.com/depot/projet/trunk/LISEZMOI.txt?kw=1
À l'instar de l'opération côté client, seuls les
mots-clés qui sont explicitement désignés
via la propriété
svn:keywords
du fichier concerné seront
substitués. Lisez la section intitulée « Substitution de mots-clés » pour une
description détaillée de la substitution de
mots-clés.
Pour mémoire, mod_dav_svn n'offre qu'une capacité réduite de navigation dans le dépot. Vous pouvez visualiser la liste des fichiers d'un répertoire et le contenu des fichiers mais pas les propriétés de révision (telles que les commentaires de propagation) ou les propriétés des fichiers et répertoires. Pour ceux qui ont besoin de naviguer plus finement dans les dépôts et leurs historiques, un certain nombre de logiciels tiers répondent présent. Par exemple, nous pouvons citer ViewVC (https://viewvc.org), Trac (https://trac.edgewall.org) et WebSVN (https://websvnphp.github.io). Ces outils tiers ne touchent pas à la « navigabilité » native offerte par mod_dav_svn et proposent généralement tout un tas de fonctionnalités supplémentaires, y compris l'affichage des propriétés comme mentionné, l'affichage des différences entre plusieurs révisions, etc.
Quand il consulte un dépôt Subversion, le navigateur web
obtient un indice pour savoir comment rendre le contenu d'un
fichier en examinant l'entête
Content-Type:
qui fait partie de la
réponse envoyée par Apache à la requête HTTP
GET
. La valeur de cet entête est en
quelque sorte un type MIME. Par défaut, Apache va indiquer
aux navigateurs web que tous les fichiers du dépôt sont du
type MIME par défaut, en général
text/plain
. Cela peut s'avérer assez
frustrant, si un utilisateur désire visualiser les fichiers
du dépôt de manière plus appropriée — par exemple, un
fichier truc.html
du dépôt sera bien
plus lisible s'il est rendu dans le navigateur en tant que
fichier HTML.
Pour rendre ceci possible, il suffit de vous assurer que
vos fichiers portent bien la propriété
svn:mime-type
. Plus de détails sur ce
sujet sont disponibles dans la section intitulée « Type de contenu des fichiers » et vous
pouvez même configurer votre dépôt pour qu'il associe
automatiquement la valeur de
svn:mime-type
appropriée aux fichiers qui
arrivent dans le dépôt pour la première fois ;
reportez-vous à la section intitulée « Configuration automatique des propriétés ».
Donc, dans notre exemple, si quelqu'un attribuait la
valeur text/html
à la propriété
svn:mime-type
du fichier
truc.html
, Apache indiquerait avec
raison à votre navigateur web de rendre le fichier comme
une page HTML. On pourrait aussi associer des propriétés
ayant des valeurs image/*
appropriées aux
fichiers d'images et, en fin de compte, faire qu'un site web
entier soit consultable directement à travers un
dépôt ! Ceci ne pose en général pas de problème, du
moment que le site web ne possède pas de contenu généré
dynamiquement.
En général, vous utiliserez principalement des URL de
fichiers suivis en versions ; après tout c'est là que
le contenu intéressant réside. Mais vous aurez peut-être
l'occasion de naviguer dans le contenu d'un répertoire
Subversion et vous remarquerez rapidement que le code HTML
généré pour afficher la liste des éléments du répertoire
est très rudimentaire, et certainement pas conçu pour être
agréable d'un point de vue esthétique (ni même intéressant).
Afin d'activer la personnalisation de l'affichage de ces
répertoires, Subversion fournit une fonctionnalité d'index
XML. La présence d'une directive
SVNIndexXSLT
dans le bloc
Location
du fichier
httpd.conf
de votre dépôt conduira
mod_dav_svn à générer un résultat en XML
quand il affiche la liste des éléments d'un répertoire et à
faire référence à la feuille de style XSLT de votre
choix :
<Location /svn> DAV svn SVNParentPath /var/svn SVNIndexXSLT "/svnindex.xsl" … </Location>
À l'aide de la directive SVNIndexXSLT
et d'une feuille de style XSLT faisant preuve de créativité,
vous pouvez adapter les listes de contenus de répertoires aux
couleurs et illustrations utilisées dans d'autres
parties de votre site web. Ou, si vous préférez, vous pouvez
utiliser les exemples de feuilles de style fournis dans le
répertoire tools/xslt/
du code source de
Subversion. Gardez à l'esprit que le chemin d'accès fourni à la
directive SVNIndexXSLT
est en fait une
URL — les navigateurs doivent être capables de lire vos
feuilles de style pour les utiliser !
Si vous desservez un ensemble de dépôts à partir d'une
URL unique via la directive
SVNParentPath
, il est possible de faire
afficher par Apache tous les dépôts disponibles dans un
navigateur web. Il suffit d'activer la directive
SVNListParentPath
:
<Location /svn> DAV svn SVNParentPath /var/svn SVNListParentPath on … </Location>
Si un utilisateur pointe son navigateur web à l'URL
http://hote.exemple.com/svn/
, il verra
une liste de tous les dépôts Subversion situés dans
/var/svn
. Évidemment, ceci peut poser
des problèmes de sécurité ; cette fonctionnalité est
donc désactivée par défaut.
Comme Apache est avant tout un serveur HTTP, il contient
des fonctionnalités de journalisation d'une flexibilité
fantastique. Détailler toutes les façons dont la
journalisation peut être configurée sort du cadre de ce livre,
mais nous voulons quand même vous faire remarquer que même le
fichier httpd.conf
le plus générique
conduit Apache à créer deux fichiers de journalisation :
error_log
et access_log
. Ces journaux peuvent
apparaître à différents endroits, mais sont en général créés
dans la zone de journalisation de votre installation Apache
(sur Unix, ils résident souvent dans
/usr/local/apache2/logs/
).
Le fichier error_log
décrit toutes
les erreurs internes qu'Apache rencontre au cours de son
fonctionnement. Le fichier access_log
enregistre toutes les requêtes HTTP reçues par Apache. Ceci
permet de voir facilement, par exemple, à partir de quelles
adresses IP les clients Subversion se connectent, à quelle
fréquence un client donné utilise le serveur, quels
utilisateurs se sont authentifiés correctement et quelles
requêtes ont échoué ou réussi.
Malheureusement, parce qu'HTTP est un protocole sans
notion d'état, même la plus simple opération du client
Subversion génère plusieurs requêtes réseau. Il est donc très
difficile d'examiner le fichier
access_log
et d'en déduire ce que le
client faisait — la plupart des opérations se présentent
sous la forme de séries de requêtes
PROPPATCH
, GET
,
PUT
et REPORT
énigmatiques. Pour couronner le tout, de nombreuses opérations
du client envoient des séries de requêtes quasi-identiques, il
est donc encore plus difficile de les distinguer.
Cependant, mod_dav_svn peut venir à votre rescousse. En activant la fonctionnalité de « journalisation opérationnelle », vous pouvez demander à mod_dav_svn de créer un fichier séparé décrivant quelles sortes d'opérations de haut niveau vos clients effectuent.
Pour ce faire, vous devez utiliser la directive
CustomLog
d'Apache (qui est expliquée en
détail dans la documentation Apache). Prenez soin de placer
cette directive en dehors de votre bloc
Location
de Subversion :
<Location /svn> DAV svn … </Location> CustomLog logs/journal-svn "%t %u %{SVN-ACTION}e" env=SVN-ACTION
Dans cet exemple, nous demandons à Apache de créer un
fichier journal spécial, journal-svn
,
dans le répertoire habituel de journaux d'Apache
(logs
). Les variables
%t
et %u
sont remplacées
par l'horodatage et le nom d'utilisateur de la requête,
respectivement. Les points importants sont les deux instances
de SVN-ACTION
. Quand Apache trouve cette
variable, il lui substitue la valeur de la variable
d'environnement SVN-ACTION
, modifiée
automatiquement par mod_dav_svn
quand il détecte une action haut-niveau du client.
Ainsi, au lieu d'avoir à interpréter un fichier
access_log
traditionnel qui ressemble
à :
[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/vcc/default HTTP/1.1" 207 398 [26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/bln/59 HTTP/1.1" 207 449 [26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc HTTP/1.1" 207 647 [26/Jan/2007:22:25:29 -0600] "REPORT /svn/calc/!svn/vcc/default HTTP/1.1" 200 607 [26/Jan/2007:22:25:31 -0600] "OPTIONS /svn/calc HTTP/1.1" 200 188 [26/Jan/2007:22:25:31 -0600] "MKACTIVITY /svn/calc/!svn/act/e6035ef7-5df0-4ac0-b811-4be7c823f998 HTTP/1.1" 201 227 …
vous pouvez vous contenter de parcourir le fichier
journal-svn
qui est bien plus
intelligible :
[26/Jan/2007:22:24:20 -0600] - get-dir /tags r1729 props [26/Jan/2007:22:24:27 -0600] - update /trunk r1729 depth=infinity [26/Jan/2007:22:25:29 -0600] - status /trunk/foo r1729 depth=infinity [26/Jan/2007:22:25:31 -0600] sally commit r1730
En complément de la variable d'environnement
SVN-ACTION
, mod_dav_svn
définit aussi les variables SVN-REPOS
et
(resp.) SVN-REPOS-NAME
, qui contiennent le
chemin dans le système de fichiers vers le dépôt et (resp.) le
nom simple. Vous voudrez peut-être inclure des références à
ces variables dans la chaîne de caractères qui définit le
format dans CustomLog
, surtout si vous
combinez dans ce fichier les journaux en provenance de
plusieurs dépôts. Pour obtenir une liste exhaustive de toutes
les actions journalisées, reportez-vous à la section intitulée « Journalisation du haut-niveau ».
Évidemment, plus Apache journalise d'informations relatives aux activités de Subversion, plus le journal prend de place sur le disque. Il n'est pas rare qu'un serveur Subversion à gros trafic génère plusieurs gigaoctets de journaux par jour. Tout aussi évidemment, les journaux ne sont utiles que si vous pouvez en extraire de l'information pertinente et les journaux gigantesques peuvent rapidement devenir difficiles à exploiter. Il existe diverses solutions pour gérer les journaux d'Apache qui sortent du cadre de ce livre. Nous préconisons aux administrateurs d'utiliser la rotation des journaux et l'archivage qui leur convient le mieux.
Mais que faire si Subversion génère simplement trop de journaux pour pouvoir les exploiter ? Par exemple, dans la section intitulée « Mises à jour groupées », nous avons indiqué que certaines approches que les clients Subversion utilisent pour leurs extractions ou d'autres opérations de mise à jour peuvent faire grandir rapidement la taille des journaux parce que chaque requête, pour chaque information élémentaire de la mise à jour, est journalisée (alors que ce n'était pas le cas pour les versions précédentes de Subversion). Dans ce cas, vous devriez envisager une configuration très particulière d'Apache pour ne pas journaliser, de manière sélective, l'ensemble des activités.
Le module mod_setenvif du serveur HTTP
Apache propose une directive SetEnvIf
qui
est utile pour définir de manière conditionnelle des variables
d'environnement. Ainsi, la directive
CustomLog
peut être configurée pour ne
journaliser que certaines requêtes en fonction de la valeur de
variables d'environnement. Vous trouverez un exemple de
configuration qui demande au serveur de ne
pas journaliser les requêtes GET
et PROPFIND
visant des URL Subversion
privées.
# Correspondance pour tout, juste pour initialiser la variable 'dans_depot'. SetEnvIf Request_URI "^" dans_depot=0 # Activer "dans_depot" si la requête pointe vers une URL Subversion privée. SetEnvIf Request_URI "/!svn/" dans_depot=1 # Désactiver "ne_pas_journaliser" pour les types de requêtes que # nous ne voulons pas journaliser SetEnvIf Request_Method "GET" ne_pas_journaliser SetEnvIf Request_Method "PROPFIND" ne_pas_journaliser # Désactiver "ne_pas_journaliser" pour les URL Subversion qui ne sont pas privées. SetEnvIf dans_depot 0 !ne_pas_journaliser # Journaliser la requête, seulement si "ne_pas_journaliser" n'est pas activée CustomLog logs/access_log env=!ne_pas_journaliser
En utilisant cette configuration,httpd
journalisera toujours les requêtes GET
qui
pointent vers des URL Subversion publiques. Ce sont les types
de requêtes émises par les navigateurs Web lorsqu'un
utilisateur navigue dans le dépôt directement. Mais les
requêtes GET
et PROPFIND
qui pointent vers des URL Subversion dites
« privées » (ce sont les types de requêtes
utilisées pour passer en revue individuellement chacun des
fichiers lors d'une opération d'extraction) ne seront pas
journalisées.
Un des avantages notables d'Apache comme serveur Subversion est qu'il peut être configuré pour effectuer de la réplication. Par exemple, imaginez que votre équipe soit répartie sur quatre sites dans différents coins du globe. Le dépôt Subversion ne peut exister que sur un de ces sites, ce qui signifie que les trois autres sites n'auront pas un accès très satisfaisant — ils devront sans doute faire avec un trafic plus lent et des temps de réponse plus longs lors des mises à jour et des propagations. Une solution très puissante est de mettre en place un système constitué d'un serveur Apache maître et de plusieurs serveurs Apache esclaves. Si vous placez un serveur esclave sur chacun des sites, les utilisateurs peuvent extraire une copie de travail de l'esclave qui est le plus proche d'eux. Toutes les requêtes de lecture vont au serveur esclave local. Les requêtes d'écriture sont automatiquement routées vers l'unique serveur maître. Lorsque la propagation se termine, le maître « pousse » la nouvelle révision vers chaque serveur esclave en utilisant l'outil de réplication svnsync.
Cette configuration permet une immense amélioration de la vitesse perçue par les utilisateurs, car le trafic d'un client Subversion est généralement constitué à 80 - 90 % de requêtes de lecture. Et ces requêtes étant traitées par un serveur local, le gain est énorme.
Dans cette section, nous vous accompagnons dans la mise en place standard de ce système comportant un maître unique et plusieurs esclaves. Cependant, gardez à l'esprit que vos serveurs doivent faire tourner au moins Apache 2.2.0 (avec le module mod_proxy chargé) et Subversion 1.5 (mod_dav_svn).
Note | |
---|---|
Ceci est juste un exemple de la façon dont vous pouvez configurer un serveur mandataire Subversion. Il existe d'autres approches. Par exemple, plutôt que d'avoir un serveur maître qui pousse les modifications vers chaque serveur esclave, les esclaves pourraient aller chercher ces modifications périodiquement sur le serveur maître. Ou bien le serveur pourrait pousser les modifications vers un seul serveur esclave, charge à ce serveur esclave de les pousser vers un autre serveur esclave et ainsi de suite pour atteindre tous les serveurs esclaves. Nous conseillons aux administrateurs d'utiliser cette section comme point de départ pour comprendre les bases d'un déploiement d'un serveur mandataire WebDAV Subversion, puis d'implémenter l'approche qui convient le mieux à leur organisation. |
Pour commencer, configurez le fichier
httpd.conf
de votre serveur maître de
la façon habituelle. Mettez le dépôt à disposition à un
certain emplacement URI et configurez l'authentification
ainsi que le contrôle d'accès comme vous le souhaitez. Une
fois que c'est fait, configurez chacun de vos serveurs
« esclaves » exactement de la même manière, mais
ajoutez la directive SVNMasterURI
au
bloc :
<Location /svn> DAV svn SVNPath /var/svn/depot SVNMasterURI http://maitre.exemple.com/svn … </Location>
Cette nouvelle directive indique à un serveur esclave de rediriger toutes les requêtes d'écriture vers le maître (ce qui est accompli automatiquement par le module mod_proxy d'Apache). Les requêtes ordinaires de lecture, cependant, sont toujours traitées par les esclaves. Assurez-vous que vos serveurs maître et esclaves ont tous des configurations identiques d'authentification et de contrôle d'accès ; En cas de problème de synchronisation, cela peut vous amener à vous arracher les cheveux.
Ensuite nous devons nous occuper du problème de la récursion infinie. Avec la configuration actuelle, imaginez ce qui se va se passer quand un client Subversion va effectuer une propagation vers le serveur maître. Une fois la propagation terminée, le serveur utilise svnsync pour répliquer la nouvelle révision vers chaque esclave. Mais comme svnsync ne se présente que comme un simple client en train d'effectuer une propagation, l'esclave va immédiatement tenter d'envoyer vers le maître la requête d'écriture qui vient d'arriver ! Et là, patatras !
La solution consiste à s'arranger pour que le maître
pousse les révisions vers un emplacement
<Location>
distinct au sein des
dépôts esclaves. Cet emplacement est configuré
non pas pour servir de mandataire pour
les requêtes d'écriture mais pour accepter les propagations
normales en provenance de l'adresse IP du maître (et
seulement de lui) :
<Location /svn-proxy-sync> DAV svn SVNPath /var/svn/depot Order deny,allow Deny from all # Ne laisse que le serveur ayant l'adresse indiquée accéder à cet emplacement : Allow from 10.20.30.40 … </Location>
Une fois que vous avez configuré les blocs
Location
du maître et des esclaves, vous
devez configurer le maître pour que la réplication vers les
esclaves fonctionne. Ceci se fait de la manière habituelle,
en utilisant svnsync. Si vous n'êtes pas
familier avec cet outil, reportez-vous à la section intitulée « Réplication avec svnsync » pour
plus de détails.
Tout d'abord, assurez-vous que chaque dépôt esclave
possède une procédure automatique
pre-revprop-change
qui autorise les
modifications de propriétés de révisions à distance (cette
étape fait partie de la procédure standard pour un serveur
qui reçoit les révisions de svnsync).
Ensuite, connectez-vous au serveur maître et configurez
l'URI de chaque dépôt esclave pour qu'il reçoive les données
en provenance du dépôt maître sur le disque
local :
$ svnsync init http://esclave1.exemple.com/svn-proxy-sync \ file://var/svn/depot Propriétés copiées pour la révision 0. $ svnsync init http://esclave2.exemple.com/svn-proxy-sync \ file://var/svn/depot Propriétés copiées pour la révision 0. $ svnsync init http://esclave3.exemple.com/svn-proxy-sync \ file://var/svn/depot Propriétés copiées pour la révision 0. # Effectue la réplication initiale $ svnsync sync http://esclave1.exemple.com/svn-proxy-sync \ file://var/svn/depot Transmission des données ........................................ Révision 1 propagée. Propriétés copiées pour la révision 1. Transmission des données .. Révision 2 propagée. Propriétés copiées pour la révision 2. … $ svnsync sync http://esclave2.exemple.com/svn-proxy-sync \ file://var/svn/depot Transmission des données ........................................ Révision 1 propagée. Propriétés copiées pour la révision 1. Transmission des données .. Révision 2 propagée. Propriétés copiées pour la révision 2. … $ svnsync sync http://esclave3.exemple.com/svn-proxy-sync \ file://var/svn/depot Transmission des données ........................................ Révision 1 propagée. Propriétés copiées pour la révision 1. Transmission des données .. Révision 2 propagée. Propriétés copiées pour la révision 2. …
Une fois ceci fait, nous configurons la procédure
automatique post-propagation
(post-commit
) du serveur maître pour
qu'elle lance svnsync sur chaque serveur
esclave :
#!/bin/sh # Procédure post-propagation pour répliquer les révisions # nouvellement propagées vers les esclaves svnsync sync http://esclave1.exemple.com/svn-proxy-sync \ file:///var/svn/depot > /dev/null 2>&1 & svnsync sync http://esclave2.exemple.com/svn-proxy-sync \ file:///var/svn/depot > /dev/null 2>&1 & svnsync sync http://esclave3.exemple.com/svn-proxy-sync \ file:///var/svn/depot > /dev/null 2>&1 &
Les symboles en plus à la fin de chaque ligne ne sont
pas nécessaires, mais constituent un moyen astucieux
d'autoriser svnsync à lancer des
commandes qui fonctionneront à l'arrière-plan, de telle
sorte que le client Subversion ne se retrouvera pas à
attendre indéfiniment que la propagation se termine. En
plus de cette procédure post-propagation
(post-commit
), vous aurez également
besoin d'une procédure automatique
post-revprop-change
pour que, disons,
quand un utilisateur modifie un commentaire de propagation, les
serveurs esclaves reçoivent aussi cette
modification :
#!/bin/sh # Procédure post-revprop-change pour répliquer les modifications # des propriétés de révisions vers les esclaves REV=${2} svnsync copy-revprops http://esclave1.exemple.com/svn-proxy-sync \ file:///var/svn/depot \ -r ${REV} > /dev/null 2>&1 & svnsync copy-revprops http://esclave2.exemple.com/svn-proxy-sync \ file:///var/svn/depot \ -r ${REV} > /dev/null 2>&1 & svnsync copy-revprops http://esclave3.exemple.com/svn-proxy-sync \ file:///var/svn/depot \ -r ${REV} > /dev/null 2>&1 &
La seule chose que nous n'avons pas abordé concerne les verrous (ceux de la commande svn lock). Comme ces verrous sont gérés strictement par le serveur maître au moment des propagations ; mais toutes les informations relatives aux verrous sont distribuées au moment des opérations de lectures telles que svn updateet svn status par le serveur esclave. Ainsi, la configuration complète maître/esclaves se doit de répliquer les informations de verrouillage du maître vers les esclaves. Malheureusement, la plupart des mécanismes qui sont utilisés pour effectuer cette réplication sont confrontés à un problème à un moment ou à un autre[69]. De nombreuses équipes n'utilisent pas du tout les fonctionnalités de verrouillage de Subversion, il s'agit donc peut-être pour vous d'un faux problème. Pour ceux qui utilisent les verrous, nous n'avons malheureusement pas de solution simple et universelle pour combler cette lacune.
Votre système de réplication maître/esclave doit à présent être prêt à l'emploi. Cependant, quelques consignes de prudence sont de mise. Souvenez-vous que la réplication n'est pas totalement robuste en ce qui concerne les plantages machine ou réseau. Par exemple, si l'une des commandes svnsync automatisées demeure inachevée, pour quelque raison que ce soit, les esclaves vont commencer à être décalés. Par exemple, vos utilisateurs distants verront qu'ils ont propagé la révision 100, mais quand ils exécuteront svn update, leur serveur local leur indiquera que la révision 100 n'existe pas encore ! Bien sûr, le problème se réglera automatiquement dès qu'une autre propagation aura lieu et que la commande svnsync qui s'ensuit aura fonctionné — cette synchronisation répliquera toutes les révisions en attente. Néanmoins, vous pouvez décider de mettre en place une surveillance des décalages, vérifiant le bon fonctionnement de la synchronisation et qui, en cas de problème, déclenche une nouvelle exécution de svnsync.
Une autre limitation de modèle de déploiement avec mandataires concerne ceux qui ont des versions différentes de Subversion installées sur les différents maîtres et esclaves. Chaque nouvelle version de Subversion peut (et c'est souvent le cas) ajouter des nouvelles fonctionnalités au protocole réseau utilisé entre le serveur et les clients. Comme la négociation des fonctionnalités possibles intervient à la connexion au serveur esclave, ce sont les capacités annoncées par le serveur esclaves qui sont utilisées. Mais les opérations d'écriture sont transmises au serveur maître pratiquement littéralement. En conséquence, Le risque est que le serveur esclave négocie avec le client l'utilisation de fonctionnalités qui sont possibles avec l'esclave mais que le serveur maître ne comprenne pas parce qu'il fait tourner une version plus ancienne de Subversion, ce qui fait échouer la transaction.
Subversion 1.8 prévient ce type de problème en
introduisant une nouvelle directive de configuration
Apache, SVNMasterVersion
. En configurant
chacun de vos serveurs esclaves avec
SVNMasterVersion
définie à la version
de l'instance du serveur Subversion qui tourne sur votre
maître, les serveurs esclaves peuvent négocier de manière
adéquate le support des fonctionnalités avec le
client.
Malheureusement, Subversion 1.7 ne reconnait pas
la directive de configuration
SVNMasterVersion
et est réputé pour
avoir des problèmes avec ces lignes.Si vous déployez un
serveur esclave en Subversion 1.7 devant un maître en
version antérieure à la 1.7, vous configurerez le bloc
<Location>
de votre serveur
esclave avec la directive suivante :
SVNAdvertiseV2Protocol Off
.
Astuce | |
---|---|
Pour obtenir le meilleur fonctionnement possible, essayez de faire tourner la même version de Subversion sur le maître et sur les esclaves. |
Il y a également plusieurs fonctionnalités fournies par
Apache, en tant que serveur web robuste, dont on peut tirer
profit pour améliorer les fonctionnalités ou la sécurité de
Subversion. Le client Subversion est capable d'utiliser SSL
(Secure Socket Layer, le protocole de sécurisation des
échanges sur internet, présenté auparavant). Si votre client
Subversion a été compilé en incluant le support de SSL, il
peut accéder à votre serveur Apache en utilisant des URL
https://
et bénéficier d'une session réseau
avec un chiffrement de grande qualité.
D'autres fonctionnalités de la relation Apache/Subversion sont également tout aussi utiles, comme la possibilité de spécifier un port personnalisé (au lieu du port HTTP par défaut, 80) ou un nom de domaine virtuel par lequel accéder au dépôt Subversion ou encore la possibilité d'accéder au dépôt via un serveur mandataire HTTP.
Enfin, comme mod_dav_svn se sert d'un sous-ensemble du protocole WebDAV/DeltaV pour communiquer, il est possible d'accéder au dépôt depuis des clients DAV tiers. La possibilité de monter un serveur DAV en tant que « dossier partagé » réseau standard est intégrée dans la plupart des systèmes d'exploitation modernes (Win32, OS X et Linux). C'est un sujet compliqué, mais merveilleux une fois mis en place. Pour plus de détails, consultez l'Annexe C, WebDAV et la gestion de versions automatique.
Notez qu'il y a un certain nombre d'autres petits
« bricolages » que l'on peut faire autour de
mod_dav_svn qui sont trop obscurs pour être
mentionnés dans ce chapitre. Pour voir la liste complète de
toutes les directives httpd.conf
auxquelles mod_dav_svn obéit, reportez-vous
à la section intitulée « Directives de configuration de mod_dav_svn ».
Dans les sections supra, nous
avons mentionné de nombreuses directives que les administrateurs
peuvent utiliser dans leurs fichiers
httpd.conf
pour activer des options et
configurer leur « offre de service ». Chaque
directive a fait l'objet d'une introduction et d'une brève
présentation de la fonctionnalité qu'elle pilote. Dans cette
section, nous allons rapidement résumer
toutes les directives proposées par à la
fois le serveur HTTP Apache et les modules Subversion qui sont
livrés avec la distribution standard Subversion.
Les directive de configuration infra sont reconnues et interprétées par le module Subversion du serveur HTTP Apache mod_dav_svn.
DAV svn
Doit être incluse dans tout bloc
Directory
ou
Location
d'un dépôt Subversion. Elle
indique à httpd d'utiliser le module
mod_dav pour répondre à toutes les
requêtes.
SVNActivitiesDB
chemin-vers-répertoire
Spécifie l'emplacement dans le système de fichiers
de la base de données qui stocke les rapports
d'activités. Par défaut, mod_dav_svn
crée et utilise un répertoire dans le dépôt appelé
dav/activities.d
. Le chemin
spécifié par cette option doit être un chemin
absolu.
Si elle est incluse dans un bloc
SVNParentPath
,
mod_dav_svn ajoute le nom du
répertoire au chemin spécifié ici. Par
exemple :
<Location /svn> DAV svn # toute URL "/svn/foo" correspond à un dépôt dans # /net/svn.nfs/depots/truc SVNParentPath "/net/svn.nfs/depots" # toute URL "/svn/foo" correspond à un fichier d'activités dans # /var/db/svn/activites/truc SVNActivitiesDB "/var/db/svn/activites" </Location>
SVNAdvertiseV2Protocol On|Off
Nouveau dans Subversion 1.7. Cette directive indique
si mod_dav_svn annonce la
compatibilité pour la nouvelle version du protocole HTTP
qui a été introduite dans cette version. La plupart des
administrateurs n'utilisent pas cette directive (dont
la valeur par défaut est On
) car elle
préfère bénéficier des performances accrues offertes par
le nouveau protocole. Cependant, si vous configurez un
serveur en tant que mandataire en écriture devant un
serveur qui n'est pas compatible avec le nouveau
protocole, affectez la valeur Off
à
cette directive.
SVNAllowBulkUpdates On|Off|Prefer
Autorise la compatibilité avec les réponses
« tout compris » pour les requêtes de mises
à jour de type REPORT
. Les clients
Subversion utilisent des requêtes
REPORT
vers
mod_dav_svn pour obtenir des
informations lors des extractions et des mises à jour.
Ils peuvent demander au serveur d'envoyer les
informations soit sous la forme d'une seule réponse
(groupée ou bulk en anglais)
englobant les informations de toute l'arborescence, soit
sous la forme de skeltas qui ne
contiennent que l'information juste suffisante pour que
le client sache quelles données
supplémentaires il doit demander au
serveur dans les requêtes suivantes. Quand cette directive
est incluse avec la valeur Off
,
mod_dav_svn ne répond que par des
skeltas aux requêtes de type REPORT
,
quel que soit le type de réponse demandé par le
client.
La valeur par défaut pour cette directive est
On
, ce qui permet au serveur de
répondre aux requêtes de mises-à-jour en utilisant
le type de réponse (groupée ou skelta) demandé par le
client. À partir de Subversion 1.8, cette directive
reconnaît également la valeur Prefer
.
Son comportement est similaire à On
sauf que le serveur annonce au client qu'il
préfère traiter les requêtes
groupées.
Beaucoup d'entre vous n'utiliseront pas du tout
cette directive. Elle existe principalement pour les
administrateurs qui souhaitent (pour des raisons de
sécurité ou d'audit) forcer les clients Subversion à
réclamer individuellement chaque fichier et répertoire
dont il a besoin pour la mise à jour ou l'extraction,
laissant toute une série de traces de requêtes
GET
et PROPFIND
dans les journaux d'Apache.
SVNAutoversioning On|Off
Quand la valeur est On
, autorise
les requêtes en écriture depuis des clients WebDAV à
créer automatiquement des propagations. Un commentaire de
propagation générique est créé et joint à la révision.
Si vous autorisez l'auto-versionnement, vous définirez
certainement aussi ModMimeUsePathInfo
On
afin que mod_mime puisse
affecter automatiquement le bon type MIME à la propriété
svn:mime-type
(dans la mesure où
mod_mime en est capable, bien sûr).
Pour plus d'informations, lisez Annexe C, WebDAV et la gestion de versions automatique. La valeur par défaut est
Off
.
SVNCacheFullTexts On|Off
Lorsque la valeur est On
, cela
demande à Subversion de mettre en cache, s'il y a
suffisamment de place, le contenu textuel. Une
amélioration significative des performances du serveur
est prévisible (voir aussi la directive
SVNInMemoryCacheSize
). La valeur par
défaut est Off
.
SVNCacheTextDeltas On|Off
Quand la valeur est On
, cela
demande à Subversion de mettre en cache, s'il y a
suffisamment de place, le contenu des deltas. Une
amélioration significative des performances du serveur
est prévisible (voir aussi la directive
SVNInMemoryCacheSize
). La valeur par
défaut est Off
.
SVNCompressionLevel
niveau
Spécifie le niveau de compression utilisé lors de
l'envoi des fichiers sur le réseau. Une valeur de
0
interdit la compression et
9
constitue la valeur maximale.
5
est la valeur par défaut.
SVNHooksEnv
chemin-vers-fichier
Spécifie l'emplacement du fichier de configuration de l'environnement des procédures automatiques. Ce fichier est utilisé pour décrire l'environnement initial dans lequel sont exécutés les procédures automatiques. Pour davantage d'informations sur cette fonctionnalité, lisez la section intitulée « Configuration de l'environnement des procédures automatiques ».
SVNIndexXSLT
directory-path
Spécifie l'URI d'une transformation XSL pour l'index d'un répertoire. Cette directive est optionnelle.
SVNInMemoryCacheSize
taille
Spécifie la taille maximum (en kilooctets) de la
mémoire cache par processus Subversion. La valeur par
défaut est 16384
; utilisez la
valeur 0
pour ne pas avoir de
cache.
SVNListParentPath On|Off
Si vous affectez la valeur On
,
une requête GET
sur
SVNParentPath
listera tous les
dépôts sous ce chemin. La valeur par défaut est
Off
.
SVNMasterURI
url
Spécifie l'URI du dépôt du serveur maître Subversion (utilisée dans le cas d'un serveur mandataire en écriture).
SVNMasterVersion
X.Y
Spécifie le numéro de version de l'instance Subversion qui héberge le dépôt maître (utilisé pour un mandataire en écriture).
SVNParentPath
directory-path
Spécifie l'emplacement dans le système de fichiers
d'un répertoire parent dont les dossiers enfants sont
des dépôts Subversion. Dans un bloc de configuration
pour un dépôt Subversion, ou bien cette directive est
présente, ou bien c'est la variable
SVNPath
.
SVNPath
chemin-vers-repertoire
Spécifie l'emplacement dans le système de fichiers
des fichiers stockant le dépôt Subversion.
Dans un bloc de configuration pour un dépôt Subversion,
ou bien cette directive est présente, ou bien c'est la
variable SVNParentPath
.
SVNPathAuthz On|Off|short_circuit
Configure le contrôle d'accès sur les chemins en
autorisant (On
) les sous-requêtes,
en les désactivant (Off
;
reportez-vous à la section intitulée « Désactivation du contrôle sur les chemins »)
ou en demandant directement à
mod_authz_svn
(short_circuit
). La valeur par
défaut est On
.
SVNReposName
nom
Spécifie le nom du dépôt Subversion à utiliser dans
les réponses à des requêtes HTTP GET
.
Cette valeur sera ajoutée au début du titre dans tous
les affichages de répertoires (qui sont transmis lorsque
vous naviguez dans un dépôt Subversion avec un
navigateur Web). Cette directive est optionnelle.
Note | |
---|---|
Subversion n'utilise pas le nom du dépôt tel que configuré par cette directive lorsqu'il établit les correspondances dans les règles de contrôle d'accès. Les noms de dépôts utilisés dans ce fichier sont toujours pris à partir de l'URL du dépôt. Lisez la section intitulée « Introduction au contrôle d'accès basé sur les chemins » pour obtenir des détails. |
SVNSpecialURI
composant
Spécifie l'URI d'un composant (espace de noms) pour
les ressources spéciales Subversion. La valeur par
défaut est !svn
et la majorité des
administrateurs n'utilisera jamais cette directive.
Définissez la uniquement si vous avez absolument besoin
d'avoir un fichier dont le nom est
!svn
dans votre dépôt. Si vous
changez cette valeur sur un serveur déjà en service,
cela cassera toutes les copies de travail déjà
extraites et vos utilisateurs vous pourchasseront avec
des piques et des fers portés au rouge.
SVNUseUTF8 On|Off
Quand la valeur est On
,
mod_dav_svn communique avec les
procédures automatiques en utilisant les chemins racines
du dépôt encodés en UTF-8 et il s'attend à ce que les
procédures automatiques génèrent des sorties (tels que
les messages d'erreurs) aussi en UTF-8. La valeur par
défaut est Off
, ce qui signifie que
mod_dav_svn suppose que les
procédures automatiques interagissent en ASCII 7 bits.
Cette option est disponible pour Subversion 1.8 et
ultérieurs.
Note | |
---|---|
Les administrateurs doivent s'assurer que l'encodage attendu par les procédures automatiques est bien conforme à celui utilisé pour toutes les façons dont elles peuvent être appelées. Par exemple, si un dépôt est accessible à la fois par httpd et par svnserve, svnserve doit être configuré aussi pour utiliser UTF-8 (en définissant correctement les « locales » dans l'environnement) si cette option est définie pour mod_dav_svn. Aussi, les chemins dans le système de fichiers local qui contiennent des caractères non ASCII et qui sont référencés par ces procédures (tels que les chemins racines des dépôts) doivent être proprement encodés dans le système de fichiers pour correspondre aux attendus des procédures automatiques. |
Les directives de configurations suivantes concernent mod_authz_svn, le module Subversion pour le contrôle d'accès basé sur les chemins du serveur HTTP Apache. Pour une description approfondie du contrôle d'accès basé sur les chemins dans Subversion, reportez-vous à la section intitulée « Contrôle d'accès basé sur les chemins ».
AuthzForceUsernameCase Upper|Lower
Définissez la valeur à Upper
(resp. Lower
) pour convertir
l'identifiant en majuscules (resp. minuscules) avant de
le soumettre au contrôle d'accès. Comme les identifiants
sont comparés avec le fichier de contrôle d'accès en
étant sensibles à la casse, cette directive permet au
moins de normaliser des identifiants dont la casse varie
vers un ensemble cohérent.
AuthzSVNAccessFile
chemin-vers-fichier
Consulte le fichier
chemin-vers-fichier
pour le
contrôle d'accès des chemins dans le dépôt Subversion. Dans
un bloc de configuration d'un dépôt Subversion ou d'un
ensemble de dépôts, soit cette directive, soit
AuthzSVNReposRelativeAccessFile
peuvent
être présentes, mais pas les deux.
À partir de Subversion 1.8,
AuthzSVNAccessFile
accepte une URL qui
pointe vers un fichier stocké dans un dépôt Subversion. Il
est possible de stocker le fichier dans le même dépôt que
celui où les règles de contrôle d'accès s'appliquent, ou dans
un autre dépôt.
AuthzSVNAnonymous On|Off
Définissez à Off
pour désactiver
deux comportements particuliers de ce module :
l'interaction avec la directive Satisfy
Any
et le forçage de la politique de contrôle
d'accès même si aucune directive
Require
n'est présente. La valeur par
défaut pour cette directive est
On
.
AuthzSVNAuthoritative On|Off
Définissez à Off
pour déléguer
le contrôle d'accès à des modules plus bas. La valeur
par défaut pour cette directive est
On
.
AuthzSVNNoAuthWhenAnonymousAllowed On|Off
Définissez à On
pour supprimer
l'authentification et le contrôle d'accès pour les
requêtes pour lesquelles les utiilisateurs anonymes sont
autorisés. La valeur par défaut pour cette directive est
On
.
AuthzSVNReposRelativeAccessFile
chemin-vers-fichier
Consulter chemin-vers-fichier
pour les règles de contrôle d'accès relatives aux chemins
dans le dépôt Subversion. Au contraire de
AuthzSVNAccessFile
, le chemin spécifié
dans AuthzSVNReposRelativeAccessFile
est relatif au répertoire conf/
dans le
dépôt sur le système de fichiers. En d'autres termes,
chemin-vers-fichier
spécifie un
fichier par dépôt qui doit être accessible par ce chemin
relatif dans tous les dépôts. Dans un bloc du fichier de
configuration, soit cette directive, soit
AuthzSVNAccessFile
doit être présente,
mais pas les deux. Cette options est disponible à partir
de Subversion 1.7.
À partir de Subversion 1.8,
AuthzSVNReposRelativeAccessFile
accepte une
URL pointant vers un fichier situé à l'intérieur d'un dépôt
Subversion. Il est possible que ce fichier soit à l'intérieur
du même dépôt que celui dont on définit les règles de contrôle
d'accès, ou à l'intérieur d'un autre dépôt.
Apache et svnserve sont tous deux capables d'accorder ou de refuser l'accès aux utilisateurs. Généralement c'est géré globalement au niveau du dépôt : un utilisateur peut accéder (ou pas) au dépôt en lecture et il peut accéder (ou pas) au dépôt en écriture.
Il est pourtant aussi possible de définir des règles d'accès possédant une granularité plus fine. Un ensemble d'utilisateurs peut alors obtenir le droit d'écrire dans certains répertoires du dépôt mais pas dans d'autres ; parallèlement, un autre répertoire peut très bien ne pas être accessible en lecture pour la majorité des utilisateurs. Il est même possible de restreindre l'accès fichier par fichier.
Les deux types de serveurs utilisent un format de fichier commun pour décrire les règles d'accès basées sur les chemins. Dans cette section, nous allons expliquer ce format de fichier et comment configurer le serveur Subversion afin qu'il l'utilise pour gérer un contrôle d'accès basé sur les chemins.
Subversion permet le contrôle d'accès basé sur les chemins
avec Apache via son module
mod_authz_svn, qui doit être chargé en
utilisant la directive LoadModule
dans
httpd.conf
de la même manière que pour le
chargement du module mod_dav_svn. Pour
activer l'utilisation du module pour vos dépôts, vous devez
ajouter les directives AuthzSVNAccessFile
ou
AuthzSVNReposRelativeAccessFile
(toujours dans le fichier httpd.conf
) en les
faisant pointer vers votre propre fichier contenant les règles
de contrôle d'accès (pour une explication détaillée, consultez
la section intitulée « Contrôle d'accès par répertoire »).
Pour configurer le contrôle d'accès basé sur les chemins
avec svnserve,faites simplement pointer la
variable de configuration authz-db
(qui se trouve dans le fichier
svnserve.conf
) vers votre fichier contenant
les règles de contrôle d'accès.
Une fois que votre serveur sait où chercher les règles de contrôle d'accès, il est temps de définir ces règles.
La syntaxe du fichier est la même syntaxe que celle utilisée
dans svnserve.conf
et dans les fichiers de
configuration. Les lignes commençant par un dièse
(#
) sont ignorées. Dans la forme la plus
simple, chaque section désigne un dépôt et un chemin à
l'intérieur de celui-ci. En d'autres termes, sauf pour quelques
sections particulières, les noms de sections se présentent sous
deux formes : soit nom-depot:chemin
,
soit [chemin]
quand
AuthzSVNAccessFile
est utilisé. Si vous avez
configuré un contrôle d'accès aux fichiers du dépôt
via la directive
AuthzSVNReposRelativeAccessFile
, vous devriez
toujours utiliser seulement la forme [path]
.
Les noms d'utilisateurs authentifiés sont les noms des options à
l'intérieur de chaque section ; la valeur de chaque option
décrit le niveau d'accès de cet utilisateur au chemin du dépôt :
soit r
(lecture seule), soit rw
(lecture/écriture). Si l'utilisateur ne figure pas dans la
section, l'accès n'est pas autorisé.
Note | |
---|---|
Les chemins utilisés dans les sections du fichier de
contrôle d'accès doivent être spécifiés en utilisant le
« style interne » de Subversion, ce qui veut
simplement dire qu'ils doivent être encodés en UTF-8 et
utiliser comme séparateur de répertoires la barre oblique
( |
Voici un exemple simple pour montrer à quoi ressemble
un fichier de configuration du contrôle d'accès où Sally possède
des droits en lecture seule et Harry des droits en
lecture/écriture pour le chemin
/branches/calc/bug-142
(et tous ses
enfants) dans le dépôt calc
:
[calc:/branches/calc/bug-142] harry = rw sally = r
Avertissement | |
---|---|
Avant la version 1.7, Subversion ne distinguait pas la casse des caractères pour les noms de dépôts et de chemins dans le cadre du contrôle d'accès, il convertissait le tout en minuscules avant d'effectuer la confrontation avec le contenu du fichier de contrôle d'accès. Dorénavant, il est sensible à la casse. Si vous mettez à jour un serveur vers la version 1.7 à partir d'une version antérieure, passez en revue votre fichier de contrôle d'accès pour vérifier que la casse est correcte. |
Le nom du dépôt tel qu'il est évalué par le sous-système de
contrôle d'accès dérive directement du chemin du dépôt. La
manière exacte dont se déroule cette évaluation diffère en
fonction de la valeur de deux options.
mod_dav_svn utilise seulement le nom du
dépôt figurant dans l'URL de la racine du
dépôt[71],
alors que svnserve utilise l'ensemble du
chemin relatif à partir de la racine du serveur (indiquée dans
l'option --root
(-r
) de la
ligne de commande) vers le dépôt.
Avertissement | |
---|---|
mod_dav_svn et
svnserve évaluant le nom de dépôt de deux
manières différentes, cela peut conduire à des problèmes
lorsque les deux serveurs fonctionnent simultanément sur la
machine. Naturellement, un administrateur préférerait faire
pointer les deux configurations des serveurs sur le même
fichier de contrôle d'accès. Cependant, afin que cela
fonctionne, vous devez vous assurer que la partie du nom de
dépôt qui figure dans le nom de section est compatible avec
l'idée que se fait le serveur du nom de dépôt. Par exemple,
en configurant la racine de svnserve pour
qu'elle soit la même que la valeur de la directive
|
Si vous utilisez la directive
SVNParentPath
, il est important de spécifier
les noms de dépôts dans vos sections. Si vous l'oubliez, à une
section comme [/un/repertoire]
correspondra
le chemin /un/repertoire
dans
chaque dépôt. Cependant, si vous utilisez
la directive SVNPath
, il suffit d'indiquer
les chemins dans vos sections (après tout, il n'y a qu'un seul
dépôt).
Les droits sont hérités d'un répertoire parent dans le système de fichiers. Cela veut dire que vous pouvez spécifier un sous-répertoire avec des droits différents pour Sally. Si nous continuons avec l'exemple précédent, nous pouvons autoriser Sally à écrire vers un répertoire fils de la branche où elle ne possède que des droits de lecture :
[calc:/branches/calc/bug-142] harry = rw sally = r # Sally peut écrire seulement dans le sous-répertoire "test" [calc:/branches/calc/bogue-142/test] sally = rw
Maintenant Sally peut écrire dans le sous-répertoire
test
de la branche, mais ne peut toujours que
lire les autres parties. Harry, en attendant, continue à avoir les
droits d'accès complets en lecture écriture sur toute la
branche.
Il est aussi possible d'interdire explicitement l'accès à quelqu'un grâce aux règles d'héritage, en attribuant la valeur vide à un nom d'utilisateur :
[calc:/branches/calc/bogue-142] harry = rw sally = r [calc:/branches/calc/bogue-142/secret] harry =
Dans cet exemple, Harry a les droits de lecture/écriture sur
l'arborescence bogue-142
toute entière, mais
n'a absolument pas accès au répertoire secret
contenu dans celle-ci.
Astuce | |
---|---|
Ce qu'il faut retenir est que le chemin le plus spécifique est choisi en premier. Le serveur tente de trouver une correspondance avec le chemin lui-même, puis avec son chemin parent, puis avec le parent du parent, etc. Le résultat est que tout chemin spécifié dans le fichier des accès prendra le pas sur les droits hérités de ses répertoires parents. De la même manière, les sections qui spécifient un nom de
dépôt sont prioritaires sur celles qui n'en spécifient
pas : si |
Par défaut, personne n'a accès au dépôt. Cela signifie que
si vous démarrez avec un fichier vide, vous voudrez probablement
au moins donner les droits de lecture sur la racine du dépôt à
tous les utilisateurs. Vous pouvez accomplir ceci en utilisant
la variable astérisque (*
), qui désigne
« tous les utilisateurs » :
[/] * = r
C'est une configuration très répandue ; notez qu'aucun
nom de dépôt n'est mentionné dans le nom de la section. Ceci
rend tous les dépôts accessibles en lecture à tous les
utilisateurs. Une fois que tous les utilisateurs ont l'accès en
lecture aux dépôts, vous pouvez accorder des droits d'écriture
(rw
) explicites à certains utilisateurs sur
des sous-répertoires spécifiques à l'intérieur de dépôts
spécifiques.
Notez que, bien que tous les exemples supra font référence à des répertoires, c'est simplement parce qu'il est plus commun de définir des droits d'accès sur des répertoires. Mais vous pouvez également restreindre les accès sur des fichiers.
[agenda:/projets/agenda/chef.ics] harry = rw sally = r
Le fichier des accès vous permet aussi de définir des
groupes entiers d'utilisateurs, à la façon du fichier Unix
/etc/group
. Créez donc une section
groups
dans votre fichiers d'accès et
décrivez vos groupes dans cette section : chaque nom de
variable définit le nom d'un groupe et la valeur est une liste
d'identifiants, séparés par des virgules, qui constituent les
membres de ce groupe.
[groups] developpeurs-calc = harry, sally, joe developpeurs-paint = frank, sally, jane tout-le-monde = harry, sally, joe, frank, sally, jane
Les droits d'accès peuvent être accordés aux groupes de la
même façon qu'à de simples utilisateurs. Il faut juste les
mettre en évidence par le préfixe « at »
(@
) :
[calc:/projets/calc] @developpeurs-calc = rw [paint:/projets/paint] jane = r @developpeurs-paint = rw
Un autre fait notable est que les droits définis pour les
groupes ne sont pas écrasés par les droits individuels. En fait,
c'est la combinaison de tous les droits qui
s'applique. Dans l'exemple précédent, Jane est membre du groupe
développeurs-paint
, qui a les droits de
lecture/écriture. Combiné avec la règle
jane = r
, cela donne toujours les droits de
lecture/écriture à Jane. Les droits pour les membres d'un groupe
ne peuvent être que étendus au delà des droits du groupe.
Restreindre les droits d'utilisateurs qui font partie d'un groupe
n'est pas possible.
Les groupes peuvent aussi contenir d'autres groupes :
[groups] developpeurs-calc = harry, sally, joe developpeurs-paint = frank, sally, jane tout-le-monde = @developpeurs-calc, @developpeurs-paint
Certains systèmes d'authentification attendent et utilisent
des noms d'utilisateurs relativement courts tels que ceux que
nous avons décrits ici — harry
,
sally
, joe
, etc. Mais
d'autres systèmes d'authentification, comme ceux qui
utilisent des bases LDAP ou des certificats clients SSL, peuvent
utiliser des noms d'utilisateurs beaucoup plus complexes. Par
exemple, le nom d'utilisateur d'Harry dans un système protégé
par LDAP pourrait très bien être : CN=Harold
Hacker,OU=Engineers,DC=red-bean,DC=com
. Avec des noms
d'utilisateurs de ce type, le fichier des accès devient
rapidement illisible, avec des noms d'utilisateurs longs ou
obscurs qui peuvent facilement être mal orthographiés.
Heureusement, Subversion 1.5 a introduit les alias dans la syntaxe du fichier de contrôle d'accès. Vous n'avez ainsi à taper le nom d'utilisateur complexe entier qu'une seule fois, au sein d'un paragraphe qui lui attribue un alias bien plus digeste.
Les alias sont définis dans la section
aliases
du fichier de contrôle d'accès.
Chaque nom de variable déclarée dans cette section définit un
alias et la valeur de cette variable est l'identifiant réel
Subversion qui est derrière l'alias.
[aliases] harry = CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com sally = CN=Sally Swatterbug,OU=Engineers,DC=red-bean,DC=com joe = CN=Gerald I. Joseph,OU=Engineers,DC=red-bean,DC=com …
Une fois défini votre ensemble d'alias, vous pouvez faire
référence à ces utilisateurs en d'autres endroits du fichier par
leurs alias, partout là où vous auriez sinon entré leur
véritables noms d'utilisateurs. Il faut juste ajouter une
esperluette (&
) juste avant l'alias pour
le distinguer des noms d'utilisateurs classiques :
[groups] developpeurs-calc = &harry, &sally, &joe developpeurs-paint = &frank, &sally, &jane tout-le-monde = @developpeurs-calc, @developpeurs-paint
Vous pouvez aussi choisir d'utiliser des alias si les noms de vos utilisateurs changent souvent. Ainsi vous n'aurez que la table des alias à mettre à jour quand des modifications de noms d'utilisateurs auront lieu, au lieu d'avoir à effectuer des opérations de recherches-et-remplacements-globaux sur la totalité du fichier.
À partir de Subversion 1.5, le fichier de contrôle d'accès
reconnait aussi des mots-clés « magiques » afin de
vous aider à créer des règles basées sur le statut
d'authentification de l'utilisateurs. Ainsi le mot-clé
$authenticated
est utilisé pour désigner un
utilisateur (quel qu'il soit) authentifié. Vous pouvez utiliser
ce mot-clé à la place d'un identifiant, d'un alias ou d'un nom
de groupe dans vos règles de contrôle d'accès. De la même
manière, le mot-clé $anonymous
désigne
n'importe qui qui n'est pas
authentifié.
[agenda:/projets/agenda] $anonymous = r $authenticated = rw
Un autre élément magique de la syntaxe des fichiers de
contrôle d'accès est le caractère tilde (~
)
qui est un marqueur d'exclusion. Dans vos règles de contrôle
d'accès, si vous préfixez un identifiant, un alias, un groupe
ou un mot-clé d'authentification avec le caractère tilde,
Subversion applique la règle aux utilisateurs qui
ne vérifient pas la règle. Bien que
inutilement complexe, le bloc suivant est équivalent à celui
du précédent exemple :
[agenda:/projets/agenda] ~$authenticated = r ~$anonymous = rw
Un exemple moins simpliste pourrait ressembler à :
[groups] developpeurs-calc = &harry, &sally, &joe proprios-calc = &hewlett, &packard calc = @developpeurs-calc, @proprios-calc # tous les participants à calc ont les droits de lecture/écriture ... [calc:/projets/calc] @calc = rw # ...mais seuls les propriétaires peuvent faire et modifier des étiquettes. [calc:/projets/calc/tags] ~@proprios-calc = r
Si vous utilisez Apache en tant que serveur Subversion et que vous avez rendu certains sous-répertoires de votre dépôt inaccessibles en lecture à certains utilisateurs, vous devez être au courant d'un comportement potentiellement non-optimal de la commande svn checkout.
En fonction de la bibliothèque de communication HTTP que le client Subversion utilise, il envoie potentiellement une requête au serveur pour recevoir tout le contenu de l'extraction ou de la mise à jour dans une réponse unique (dont la taille peut être assez importante). Quand le serveur reçoit la requête, c'est la seule opportunité dont dispose Apache pour demander à l'utilisateur de s'authentifier. Ceci a des effets secondaires assez étonnants. Par exemple, si un certain sous-répertoire du dépôt n'est accessible en lecture qu'à l'utilisateur Sally et que l'utilisateur Harry extrait un répertoire parent, le client répondra à la demande d'authentification initiale en tant que Harry. Au fur et à mesure que le serveur génère la réponse, il n'a aucun moyen de renvoyer un défi d'authentification quand il atteint le sous-répertoire spécial ; ainsi le sous-répertoire tout entier est omis, plutôt que de demander à l'utilisateur de se ré-authentifier en tant que Sally le moment venu.
De même, si la racine du dépôt est accessible en lecture anonymement, l'extraction se fera entièrement sans authentification, omettant, encore une fois, le répertoire non-lisible, plutôt que d'envoyer une demande d'authentification au cours de l'opération[72].
À la fois Apache httpd et Subversion svnserve offrent la possibilité de journaliser les opérations Subversion à un haut-niveau. La configuration de chacun des serveurs pour obtenir ce niveau de journalisation se fait différemment, bien sûr, mais les deux produisent des sorties qui respectent une syntaxe uniforme.
Pour active la journalisation de haut-niveau de
svnserve, vous n'avez qu'à utiliser l'option
--log-file
de la ligne de commande quand vous
démarrer le serveur, en indiquant en paramètre de l'option le
fichier vers lequel svnserve doit écrire la
journalisation.
$ svnserve -d -r /chemin/vers/depots --log-file /var/log/svn.log
Activer cette journalisation dans Apache est un peu plus compliqué, mais cela ne reste qu'une extension de la configuration de la journalisation Apache de base (reportez-vous à la section intitulée « Journalisation Apache » pour plus de détails).
Ce qui suit est une liste de messages de journalisation des actions Subversion produite par le mécanisme de journalisation de haut-niveau, suivi par un ou plusieurs exemples des messages de journalisation tels qu'ils apparaissent dans les journaux.
checkout-or-export /path r62 depth=infinity
commit harry r100
diff /path r15:20 depth=infinity ignore-ancestry diff /path1@15 /path2@20 depth=infinity ignore-ancestry
get-dir /trunk r17 text
get-file /path r20 props
get-file-revs /path r12:15 include-merged-revisions
get-mergeinfo (/path1 /path2)
lock /path steal
log (/path1,/path2,/path3) r20:90 discover-changed-paths revprops=()
replay /path r19
change-rev-prop r50 propertyname
rev-proplist r34
status /path r62 depth=infinity
switch /pathA /pathB@50 depth=infinity
unlock /path break
update /path r17 send-copyfrom-args
Afin de faciliter le travail des administrateurs qui
souhaitent effectuer des traitements sur leurs journaux (pour
produire des rapports ou les analyser), le code source de
Subversion est fourni avec un module Python (situé à
tools/server-side/svn_server_log_parse.py
)
qui peut être utilisé pour analyser la journalisation produite
par Subversion.
Les développeurs de Subversion n'envisagent pas de fournir un service tel que le serveur Subversion sans pouvoir configurer finement celui-ci. Subversion n'est pas particulièrement gourmand en termes de ressources mémoire ou processeur, mais chaque service gagne à être optimisé, surtout quand l'utilisation de ce service explose[73]. Dans cette section, nous exposons quelques manières d'ajuster la configuration du serveur Subversion pour offrir encore davantage de performance et de capacité à monter en charge.
Généralement, le travail le plus coûteux du serveur Subversion consiste à récupérer les données dans le dépôt. Subversion 1.6 essayait de réduire ce coût en introduisant la mise en cache en mémoire de certains types de données qu'il lisait dans le dépôt. Subversion 1.7 va un cran plus loin, en mettant en cache non seulement le résultat de certaines des opérations les plus coûteuses mais aussi en offrant les moyens de configurer finement la taille et le comportement du cache pour tous les serveurs.
Pour svnserve, vous pouvez spécifier la
taille du cache en utilisant l'option
--memory-cache-size
(-M
)
de la ligne de commande. Vous pouvez aussi imposer à
svnserve de mettre en cache le texte complet
(resp. les deltas calculés) via
l'option --cache-fulltexts
(resp.
--cache-txdeltas
).
$ svnserve -d -r /chemin/vers/depots \ --memory-cache-size 1024 \ --cache-txdeltas yes \ --cache-fulltexts yes … $
mod_dav_svn est configurable de la même
manière à travers les directives de
httpd.conf
. Les directives
SVNInMemoryCacheSize
,
SVNCacheFullTexts
et
SVNCacheTextDeltas
peuvent être utilisées
pour définir les caractéristiques du cache de données.
<IfModule dav_svn_module> # Autorise 1 Go de cache de données pour le texte et les deltas. SVNInMemoryCacheSize 1048576 SVNCacheTextDeltas On SVNCacheFullTexts On </IfModule>
Alors quels réglages utiliser ? Vous devez déjà
prendre en compte les ressources dont dispose votre serveur.
Pour obtenir un gain avec le cache, vous devrez probablement
avoir un cache capable de contenir tous les fichiers dont les
accès sont réguliers dans votre dépôt (par exemple, la
sous-arborescence trunk
de votre
projet).
Astuce | |
---|---|
Spécifier une taille de cache de
|
Note | |
---|---|
Actuellement, seuls les dépôts utilisant le magasin de données FSFS mettent en œuvre le mécanisme de cache. |
Compresser les données qui transitent sur le réseau peut
réduire significativement la taille des données transmises, au
détriment d'une consommation CPU sur le serveur et le client.
En fonction de la capacité du processeur de votre serveur, des
données que récupèrent vos clients sur vos serveurs et de la
bande passante disponible sur le réseau, il peut être avantageux
d'ajuster le taux de compression défini sur votre serveur avant
d'envoyer les données sur le réseau. Pour vous aider dans cette
phase de configuration, Subversion 1.7 propose l'option
--compression
(-c
) pour
svnserve et la directive
SVNCompressionLevel
pour
mod_dav_svn. Les deux acceptent une valeur
entière comprise entre 0 et 9 (inclus), 9 offrant la plus grande
compression et 0 désactivant toute compression.
Par exemple, sur un réseau local (LAN) Gigabit, il n'est pas pertinent de compresser les données (qui doivent être aussi décompressées par les clients) car le réseau est tellement rapide que les utilisateurs ne verront pas le gain de diminuer la charge réseau. En revanche, les serveurs dont les clients sont connectés via des connexions bas débit seront bien inspirés de minimiser les flux réseau vers ces clients.
Nous venons de voir différentes méthodes d'accès à un dépôt. Est-il possible — et sans danger — d'accéder simultanément à un dépôt par différentes méthodes ? La réponse est oui, à condition d'être un petit peu prévoyant.
À un instant donné, les processus suivants peuvent avoir besoin de l'accès en lecture ou en écriture au dépôt :
des utilisateurs classiques du système se connectant à
l'aide d'un client Subversion à des URL
file://
sous leur propre
identité ;
des utilisateurs classiques du système se connectant à des processus svnserve privés générés par SSH (dont le propriétaire est l'utilisateur lui-même) et accédant au dépôt ;
un processus svnserve — soit un serveur autonome, soit un processus lancé par inetd — dont le propriétaire est un utilisateur dédié ;
un processus httpd Apache, dont le propriétaire est un utilisateur dédié.
Les problèmes les plus courants rencontrés par les
administrateurs sont des problèmes de droits et de propriété pour
le dépôt. Chaque processus de la liste précédente a-t-il les
droits de lecture et d'écriture sur les fichiers sous-jacents du
dépôt ? En supposant que vous ayez un système d'exploitation
de type Unix, une approche naïve de ce problème serait de placer
chaque utilisateur potentiel du dépôt dans un groupe
svn
unique et de faire posséder le dépôt tout
entier par ce groupe. Mais cela ne suffit même pas, car un
processus risque de modifier les fichiers de la base de données en
utilisant un umask inadapté qui va interdire l'accès aux autres
utilisateurs.
L'étape suivante consiste donc, après avoir mis en place un
groupe commun pour les utilisateurs du dépôt, à forcer tout
processus qui accède au dépôt à utiliser un umask correct. Pour
les utilisateurs qui accèdent directement au dépôt, vous pouvez
« envelopper » le programme svnserve dans un script
(wrapper en anglais) qui commence
par lancer la commande umask 002
et qui, seulement ensuite, appelle
le véritable programme client svn.
Vous pouvez également écrire un script similaire pour le programme
svnserve et ajouter la commande
umask 002
au script de démarrage d'Apache,
apachectl
. Par exemple :
$ cat /usr/bin/svn #!/bin/sh umask 002 /usr/bin/svn-real "$@"
Sur les systèmes de type Unix, on rencontre souvent un autre
problème classique. Si vous avez un dépôt Berkeley DB, par
exemple, il crée de temps en temps de nouveaux fichiers pour la
journalisation. Même si le dépôt Berkeley DB est entièrement
possédé par le groupe svn
, ces nouveaux
journaux ne seront pas nécessairement possédés par le même groupe,
ce qui crée des problèmes de droits supplémentaires pour vos
utilisateurs. Une bonne façon de contourner ce problème est
d'activer le bit SUID du groupe sur le répertoire
db
du dépôt, ce qui a pour résultat que tous
les nouveaux fichiers journaux créés ont le même propriétaire que
le répertoire parent.
Une fois ces manipulations effectuées, vos dépôts devraient être accessibles par tous les processus nécessaires. Tout ceci peut sembler un petit peu confus et compliqué, mais les problèmes d'accès en écriture par plusieurs utilisateurs à des fichiers partagés sont des problèmes très classiques, qui ne sont pas souvent résolus avec élégance.
Heureusement, la plupart des administrateurs
n'auront jamais besoin d'une configuration
aussi complexe. Les utilisateurs qui désirent accéder aux dépôts
résidant sur une même machine ne sont pas limités aux URL d'accès
file://
— ils peuvent généralement
contacter le serveur http Apache ou le
serveur svnserve en utilisant
localhost
comme nom de serveur dans leurs URL
http://
ou svn://
. Et
assurer la maintenance de plusieurs processus serveurs pour vos
dépôts Subversion vous créera plus de soucis qu'autre chose. Nous
vous recommandons de choisir un seul serveur (celui qui correspond
le mieux à vos besoins) et de vous y tenir !
[61] Voir la RFC 2195.
[62] Notez qu'utiliser le moindre contrôle d'accès avec svnserve n'a de sens que si les utilisateurs ne peuvent pas le contourner en accédant directement au répertoire du dépôt en utilisant d'autres outils (tels que cd ou vi) ; comment mettre en place de telles restrictions est décrit dans la section intitulée « Contrôle de la commande à exécuter ».
[63] Nous ne le recommandons vraiment pas, car RSH est significativement moins sécurisé que SSH.
[65] C'est une chose qu'ils détestent faire.
[68] Bien que les certificats auto-signés sont vulnérables à une attaque dite « Man-in-the-Middle » (homme du milieu en anglais) au moment où le client voit le certificat pour la première fois, une telle attaque reste beaucoup plus complexe à mettre en œuvre lors d'une écoute occasionnelle que le simple fait de récupérer des mots de passe qui passent en clair.
[69] https://subversion.apache.org/issue3457 suit ces problèmes.
[70] Un thème récurrent dans ce livre !
[71] N'importe quel nom de dépôt,
lisible par un humain et configuré par la directive
SVNReposName
de
httpd.conf
est ignoré par le sous-système
de contrôle d'accès. Vos sections du fichier de contrôle d'accès
doivent faire référence aux dépôts par le chemin interne au
serveur comme cela a été décrit précédemment.
[72] Pour plus d'informations sur ce comportement, lisez l'article de blog Authz and Anon Authn Agony sur https://subversion.apache.org/blog/2007-03-27-authz-and-anon-authn-agony.html (article en anglais).
[73] Dans le cas de Subversion, l'explosion est due, bien sûr, à son nom très cool. Et aussi à sa popularité, sa fiabilité, sa facilité d'utilisation, …
La gestion de versions est un sujet complexe, au moins autant un art qu'une science, qui offre une myriade de façons d'accomplir chaque tâche. En lisant ce livre, vous avez expérimenté les sous-commandes Subversion en ligne de commande et les options pour modifier leur comportement. Dans ce chapitre, nous passons en revue les moyens de personnaliser le fonctionnement de Subversion : la configuration des options d'exécution, l'utilisation d'applications externes pour faciliter certains traitements, les interactions de Subversion avec la configuration des paramètres régionaux du système d'exploitation, etc.
Subversion permet à l'utilisateur de contrôler finement son comportement. Beaucoup d'options ont vocation à s'appliquer à l'ensemble des opérations de Subversion. Ainsi, plutôt que de forcer les utilisateurs à se souvenir d'arguments en ligne de commande pour spécifier ces options et de les utiliser à chaque invocation, Subversion utilise des fichiers de configuration, conservés dans une zone de configuration spécifique à Subversion.
La zone de configuration Subversion consiste en une hiérarchie à deux niveaux constituée de noms d'options et de leurs valeurs. Habituellement, cela se traduit par un répertoire dédié qui contient les fichiers de configuration (le premier niveau) : des fichiers texte au format standard INI (dont les « sections » constituent le deuxième niveau). Vous pouvez facilement éditer ces fichiers à l'aide de votre éditeur de texte favori (tel qu'Emacs ou vi). Ils contiennent des directives lues par le client Subversion afin de déterminer le comportement par défaut choisi par l'utilisateur.
La première fois que le client texte interactif
svn est exécuté, il crée une zone de
configuration propre à l'utilisateur. Sur les systèmes de type
Unix, cette zone est un répertoire nommé
.subversion
dans le répertoire personnel
de l'utilisateur. Sur les systèmes Windows, Subversion crée un
dossier nommé Subversion
, généralement
dans la zone Application Data
du
répertoire qui contient le profil de l'utilisateur (qui est
habituellement, au passage, un répertoire caché). Cependant,
sur cette plateforme, l'emplacement exact du profil
utilisateur varie d'un système à l'autre et est dicté par la
base de registre Windows[74].
Nous nous référons à cette zone de configuration propre à
l'utilisateur en utilisant son nom Unix :
.subversion
.
En plus de la zone de configuration propre à
l'utilisateur, Subversion reconnaît l'existence d'une zone de
configuration globale pour le système. Cela permet aux
administrateurs du système d'établir une configuration par
défaut pour l'ensemble des utilisateurs d'une machine donnée.
Notez que la zone de configuration globale seule ne fixe pas de
politique obligatoire : les réglages de l'utilisateur sont
prioritaires par rapport aux réglages globaux et les options
de la ligne de commande ont toujours le dernier mot. Sur les
plateformes de type Unix, la zone de configuration globale
doit se trouver dans le répertoire
/etc/subversion
; sur les machines
Windows, Subversion cherche un répertoire
Subversion
dans le dossier commun
Application Data
(là encore, l'endroit
exact dépend de la base de registre Windows). Au contraire de
la zone propre à l'utilisateur, le programme
svn ne tente pas de créer la zone de
configuration globale.
La zone de configuration propre à l'utilisateur contient
actuellement trois fichiers : deux fichiers de
configuration (config
et
servers
) et un fichier
README.txt
qui décrit le format INI. Lors
de leur création, ces fichiers contiennent les valeurs par
défaut de toutes les options supportées par Subversion,
généralement mises en commentaire et groupées avec une
description textuelle de l'effet de la clé sur le
fonctionnement de Subversion. Pour modifier un comportement
précis, il suffit de charger le fichier de configuration dans
un éditeur de texte et de changer la valeur de l'option
correspondante. Si, par la suite, vous voulez rétablir les
valeurs par défaut, vous n'avez qu'à supprimer ou renommer
votre répertoire de configuration puis lancer une commande
svn inoffensive, telle que
svn --version
. Un nouveau répertoire
de configuration sera créé, qui contiendra les valeurs par
défaut.
Subversion vous permet de supplanter chaque valeur
des options de configuration avec l'option
--config-option
, ce qui peut s'avérer pratique
si vous devez modifier (très) temporairement le comportement de
l'application. Pour plus d'informations sur l'utilisation de
cette option, reportez-vous à
Options de svn.
La zone de configuration propre à l'utilisateur contient
également un cache pour les données d'authentification. Le
répertoire auth
héberge un ensemble de
sous-répertoires qui contiennent des informations mises en
cache, relatives aux différentes méthodes d'authentification
utilisées par Subversion. Ce répertoire est créé de telle
manière que seul l'utilisateur concerné ait accès à son
contenu.
En plus de la zone de configuration classique contenant les fichiers INI, les clients Subversion qui tournent sur une plateforme Windows peuvent aussi utiliser la base de registre Windows pour stocker leurs données de configuration. Les noms des options et leurs valeurs sont les mêmes que dans les fichiers INI. La hiérarchie « fichier/section » est également présente, bien que traitée de manière légèrement différente : dans ce cas, les fichiers et les sections sont juste des niveaux dans l'arborescence des clés de registres.
Subversion cherche les valeurs de configuration
applicables à tout le système sous la clé
HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion
.
Par exemple, l'option global-ignores
, qui
se trouve dans la section [miscellany]
du
fichier config
, est située dans
HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Config\Miscellany\global-ignores
.
Les valeurs propres à un utilisateur doivent être stockées sous
HKEY_CURRENT_USER\Software\Tigris.org\Subversion
.
Les options de configuration de la base de registre sont analysées avant les options des fichiers INI ; elles sont donc supplantées par les valeurs trouvées dans les fichiers de configuration. En d'autres termes, Subversion cherche les options de configuration dans l'ordre suivant sur un système Windows (les plus prioritaires sont citées en premier) :
les options en ligne de commande ;
les fichiers INI propres à l'utilisateur ;
les valeurs de la base de registre propres à l'utilisateur ;
les fichiers INI applicables à l'ensemble du système ;
les valeurs de la base de registre applicables à l'ensemble du système.
Par ailleurs, la base de registre Windows ne comprend pas
vraiment la notion de « mise en commentaire ».
Cependant, Subversion ignorera toute clé dont le nom commence
par le caractère dièse (#
). Cela vous
permet de mettre en commentaire efficacement une option
Subversion sans avoir à effacer entièrement la clé de la base
de registre, ce qui simplifie clairement la procédure de
restauration de l'option.
Le client texte interactif svn
n'écrit jamais dans la base de registre et ne tentera pas d'y
créer une zone de configuration par défaut. Vous pouvez créer
les clés dont vous avez besoin en utilisant le programme
REGEDIT. Une autre façon de faire consiste à
créer un fichier .reg
(tel que celui
donné dans l'Exemple 7.1, « Exemple de fichier de modification de la base
de registre (.reg) »)
puis à double-cliquer sur l'icône de ce fichier dans
l'explorateur Windows afin d'appliquer les modifications
à votre base de registre.
Exemple 7.1. Exemple de fichier de modification de la base de registre (.reg)
REGEDIT4 [HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Servers\groups] [HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Servers\global] "#http-auth-types"="basic;digest;negotiate" "#http-compression"="yes" "#http-library"="" "#http-proxy-exceptions"="" "#http-proxy-host"="" "#http-proxy-password"="" "#http-proxy-port"="" "#http-proxy-username"="" "#http-timeout"="0" "#neon-debug-mask"="" "#ssl-authority-files"="" "#ssl-client-cert-file"="" "#ssl-client-cert-password"="" "#ssl-pkcs11-provider"="" "#ssl-trust-default-ca"="" "#store-auth-creds"="yes" "#store-passwords"="yes" "#store-plaintext-passwords"="ask" "#store-ssl-client-cert-pp"="yes" "#store-ssl-client-cert-pp-plaintext"="ask" "#username"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\auth] "#password-stores"="windows-cryptoapi" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\helpers] "#diff-cmd"="" "#diff-extensions"="-u" "#diff3-cmd"="" "#diff3-has-program-arg"="" "#editor-cmd"="notepad" "#merge-tool-cmd"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\tunnels] [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\miscellany] "#enable-auto-props"="no" "#global-ignores"="*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store" "#interactive-conflicts"="yes" "#log-encoding"="" "#mime-types-file"="" "#no-unlock"="no" "#preserved-conflict-file-exts"="doc ppt xls od?" "#use-commit-times"="no" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\auto-props]
L'exemple précédent présente le contenu d'un fichier
.reg
qui contient quelques-unes des
options les plus communément utilisées et leurs valeurs
par défaut. Notez la présence de réglages propres à
l'utilisateur (notamment l'éditeur de texte et le stockage
des mots de passe) ainsi que des réglages applicables à
l'ensemble du système (comme les options relatives au
mandataire réseau). Notez également que toutes les options
sont mises en commentaire. Il ne vous reste qu'à supprimer
le caractère dièse (#
) initial des noms
d'options et à leur affecter la valeur que vous
souhaitez.
Dans cette section, nous allons nous intéresser aux options de configuration des programmes que la version actuelle de Subversion comprend.
Le fichier config
contient le reste
des options de configuration de Subversion, celles qui ne
concernent pas le réseau. Actuellement, il n'existe que
quelques options mais elles sont tout de même regroupées dans
des sections en vue d'ajouts futurs.
La section [auth]
contient les
paramètres liés à l'authentification et aux droits sur le
dépôt. Il contient les paramètres suivants :
password-stores
Cette liste délimitée par des virgules spécifie
quel magasin de stockage de mot de passe (s'il en
existe) Subversion doit utiliser pour sauver et
récupérer les éléments d'authentification. Elle indique
également dans quel ordre Subversion doit les essayer.
La valeur par défaut est gnome-keyring,
kwallet, keychain, gpg-agent, windows-crypto-api
qui désigne respectiviement le trousseau GNOME, celui de
KDE, celui de Mac OS X, l'agent GnuPG et l'API
cryptographique de Microsoft Windows. Les magasins qui ne
sont pas disponibles sur le système sont ignorés.
store-passwords
Cette option est obsolète dans le fichier
config
. Elle fait maintenant partie
de la configuration propre à chaque serveur dans le
fichier servers
. Reportez-vous à
la section intitulée « Configuration spécifique à un serveur »
pour plus de détails.
store-auth-creds
Cette option est obsolète dans le fichier
config
. Elle fait maintenant partie
de la configuration propre à chaque serveur dans le
fichier servers
. Reportez-vous à
la section intitulée « Configuration spécifique à un serveur »
pour plus de détails.
La section [helpers]
contrôle quelles
applications tierces Subversion utilise pour accomplir
certaines tâches. Les options licites pour cette section
sont :
diff-cmd
Spécifiez ici le chemin absolu vers un programme que Subversion utilisera pour générer l'affichage « diff » (celui produit par la commande svn diff). Par défaut, Subversion utilise une bibliothèque interne pour les deltas. Si vous spécifiez une valeur, Subversion utilisera ce programme tiers. Lisez la section intitulée « Utilisation des outils externes de comparaison et de fusion » pour plus de détails sur l'utilisation de tels programmes.
diff-extensions
Comme pour l'option en ligne de commande
--extensions
(-x
),
spécifiez ici les options complémentaires que vous
souhaitez passer au programme tiers des deltas.
L'ensemble des options ayant un sens varie en fonction
du programme utilisé pour traiter les deltas. Lisez la
sortie produite par svn help diff
pour obtenir des détails. La valeur par défaut de cette
option est -u
.
diff3-cmd
Spécifiez ici le chemin absolu vers un programme de traitement des deltas à trois entrées. Subversion utilisera ce programme pour fusionner les changements effectués par l'utilisateur avec ceux reçus par le dépôt. Par défaut, Subversion utilise une bibliothèque interne de traitement des deltas. Si vous spécifiez une valeur, Subversion utilisera ce programme tiers. Reportez-vous à la section intitulée « Utilisation des outils externes de comparaison et de fusion » pour plus de détails sur l'utilisation de tels programmes.
diff3-has-program-arg
Cette option binaire doit être positionnée à
true
si le programme spécifié par
l'option diff3-cmd
accepte comme
paramètre l'option
--diff-program
.
editor-cmd
Spécifiez ici le programme que Subversion utilisera pour demander à l'utilisateur de renseigner des métadonnées ou pour résoudre des conflits de manière interactive. Lisez la section intitulée « Utilisation d'éditeurs externes » pour plus de détails sur l'utilisation d'éditeurs de textes tiers avec Subversion.
merge-tool-cmd
Spécifiez ici le programme tiers que Subversion utilisera pour effectuer des fusions à trois entrées sur vos fichiers suivis en versions. Lisez la section intitulée « Utilisation des outils externes de comparaison et de fusion » pour plus de détails sur l'utilisation de tels programmes.
La section [tunnels]
vous permet de
définir des tunnels lors de l'utilisation de
svnserve avec le protocole de connexion
svn://
. Pour plus de détails, lisez
la section intitulée « Encapsulation de svnserve dans un tunnel SSH ».
La section [miscellany]
contient tout
ce qui n'a pas été mis ailleurs[75]. Dans cette section, vous
trouverez :
enable-auto-props
Elle demande à Subversion d'ajouter automatiquement
des propriétés sur les fichiers ajoutés ou importés. La
valeur par défaut est no
(c'est-à-dire non), vous devez donc la basculer sur
yes
pour activer la fonctionnalité.
La section [auto-props]
de ce fichier
spécifie quelles propriétés doivent être définies sur
ces fichiers.
global-ignores
Lorsque vous lancez la commande svn
status, Subversion liste les fichiers et
dossiers non suivis en versions avec ceux suivis en
versions, en les notant avec le caractère
?
(voir la section intitulée « Vue d'ensemble des changements effectués »). Parfois, il
n'est pas commode de voir ces éléments non suivis en
versions sans intérêt (par exemple les fichiers objets
produits par la compilation du programme) dans la sortie
de la commande. L'option
global-ignores
est une liste de
motifs, séparés par des espaces, qui décrit les noms de
fichiers et dossiers que Subversion doit ignorer sauf
s'ils sont suivis en versions. La valeur par défaut est
*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a
*.pyc *.pyo *.rej *~ #*# .#* .*.swp
.DS_Store
.
De la même façon que svn status,
les commandes svn add et svn
import ignorent les fichiers qui correspondent
aux éléments de la liste quand ils passent en revue un
dossier. Vous pouvez redéfinir ce comportement pour une
exécution de chacune de ces commandes en spécifiant
explicitement le nom de fichier ou en utilisant l'option
binaire --no-ignore
en ligne de
commande.
Pour plus d'informations sur la gestion des éléments à ignorer, reportez-vous à la section intitulée « Occultation des éléments non suivis en versions ».
interactive-conflicts
C'est une option booléenne qui spécifie si
Subversion doit essayer de résoudre les conflits en mode
interactif. Si cette valeur est yes
(ce qui est la valeur par défaut), Subversion demandera
à l'utilisateur d'indiquer comment traiter les conflits
comme cela a été montré dans la section intitulée « Résolution des conflits ». Sinon, il annotera
les fichiers comme étant en conflit et continue son
opération, reportant la résolution à plus tard.
log-encoding
Cette variable définit l'encodage des caractères
pour les commentaires de propagations. C'est une forme
permanente de l'option --encoding
(voir
Options de svn). Le dépôt Subversion
stocke les commentaires de propagation en UTF-8 et suppose
que vos commentaires de propagations sont écrits en utilisant
l'encodage par défaut de votre système. Vous pouvez donc
spécifier ici l'encodage utilisé pour vos commentaires de
propagation si ceux-ci sont écrits en utilisant un
encodage différent.
mime-types-file
Cette option, apparue avec Subversion 1.5, spécifie
le chemin d'un fichier de correspondance pour les types
MIME, sur le même modèle que le fichier
mime.types
des serveurs HTTP
Apache. Subversion utilise ce fichier pour associer un
type MIME aux fichiers qui viennent d'être ajoutés ou
importés. Lisez la section intitulée « Configuration automatique des propriétés » et la section intitulée « Type de contenu des fichiers » pour
plus d'informations sur la détection et l'utilisation
du type des fichiers par Subversion.
no-unlock
Cette option booléenne correspond à l'option
--no-unlock
de la commande svn
commit. Elle indique à Subversion de ne pas
libérer les verrous posés sur les fichiers que vous
venez de propager. Si cette option est définie à
yes
, Subversion ne libérera jamais
automatiquement les verrous, il vous laissera le soin de
lancer explicitement la commande svn
unlock. La valeur par défaut est
no
.
preserved-conflict-file-exts
La valeur de cette option est une liste d'extensions de fichiers (séparées par des espaces) que Subversion doit préserver quand il génère des noms de fichiers lors des conflits. Par défaut, cette liste est vide. C'est une nouvelle option apparue dans Subversion 1.5.
Quand Subversion détecte des conflits dans les
modifications effectuées sur un fichier, il soumet la
résolution de ces conflits à l'utilisateur. Pour aider
l'utilisateur à les résoudre, Subversion garde une
copie originale des différentes versions en lice du
fichier dans la copie de travail. Par défaut, ces
fichiers ont des noms construits en ajoutant au nom de
fichier original une extension particulière telle que
.mine
ou .REV
(où REV
est un numéro de
révision). Ceci peut être gênant sur les systèmes
d'exploitation qui utilisent les extensions de noms
de fichiers pour déterminer l'application par défaut
à utiliser pour ouvrir et éditer le fichier, le fichier
avec la nouvelle extension n'étant plus automatiquement
ouvert dans l'application prévue. Par exemple, si le
fichier NotesDeVersion.pdf
est en
conflit, les fichiers générés risquent de s'appeler
NotesDeVersion.pdf.mine
ou
NotesDeVersion.pdf.r4231
. Bien
que votre système soit peut-être configuré pour ouvrir
les fichiers .pdf
avec Acrobat
Reader, il n'existe sûrement pas d'application
préconfigurée pour ouvrir les fichiers avec
l'extension .r4231
.
Vous pouvez arranger cela en utilisant cette option de
configuration. Pour les fichiers dont l'extension est
spécifiée, Subversion ajoutera au nom des fichiers générés
l'extension particulière liée au conflit, mais il rajoutera
aussi à la suite l'extension originale. Dans l'exemple
précédent, en supposant que pdf
est une
des extensions configurée dans la liste ci-dessus, les noms
des fichiers générés pour
NotesDeVersion.pdf
vont être
NotesDeVersion.pdf.mine.pdf
et
NotesDeVersion.pdf.r4231.pdf
.
Comme chaque fichier se termine par
.pdf
, l'application appropriée
sera utilisée pour les visualiser.
use-commit-times
Normalement, les fichiers de votre copie de travail ont un horodatage qui indique la dernière fois qu'ils ont été modifiés par une action, que ce soit votre éditeur ou une commande svn. C'est généralement le comportement attendu par les développeurs de logiciels, car les chaînes de compilation utilisent souvent ces horodatages pour déterminer quels fichiers ont besoin d'être recompilés.
Toutefois, il existe certaines situations où l'on désire
que l'horodatage des fichiers de la copie de travail indique
la dernière modification dans le dépôt. La commande
svn export fixe toujours l'horodatage sur
les arborescences qu'elle produit à l'« horodatage de la
dernière propagation ». En configurant cette variable
à yes
,les commandes svn
checkout, svn update,
svn switch et svn
revert fixeront l'horodatage des fichiers qu'elles
modifient à l'horodatage de la dernière propagation.
La section [auto-props]
contrôle la
possibilité par le client Subversion de positionner
automatiquement certaines propriétés sur les fichiers qui
sont ajoutés ou importés. Elle contient un nombre arbitraire
de paires clé-valeur au format MOTIF =
NOM_PROPRIETE=VALEUR[;NOM_PROPRIETE=VALEUR ...]
,
où MOTIF
est un motif de nom de fichier
qui correspond à un ou plusieurs noms de fichiers et le
reste de la ligne est une liste d'affectations (séparées
par des points-virgules) de valeurs à des propriétés. Si
vous avez besoin de points-virgules dans les noms de propriétés
ou pour leurs valeurs, vous pouvez « échapper » ce
caractère en le doublant.
$ cat ~/.subversion/config … [auto-props] *.c = svn:eol-style=native *.html = svn:eol-style=native;svn:mime-type=text/html;; charset=UTF8 *.sh = svn:eol-style=native;svn:executable … $ cd projets/mon-projet $ svn status ? www/index.html $ svn add www/index.html A www/index.html $ svn diff www/index.html … Modification de propriétés sur www/index.html ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/html; charset=UTF8 Added: svn:eol-style ## -0,0 +1 ## +native $
Si un nom de fichier correspond à plusieurs motifs, autant de
propriétés seront positionnées ; cependant, il n'y a
aucune garantie que les auto-props seront appliquées dans
l'ordre dans lequel elles apparaissent dans le fichier
config
; il ne faut donc pas
définir de règles susceptibles d'en écraser d'autres. Vous
pouvez trouver de nombreux exemples d'utilisation
d'auto-props dans le fichier config
.
Enfin, n'oubliez pas de positionner
enable-auto-props
à yes
dans la section [miscellany]
si vous voulez
activer auto-props.
Depuis Subversion 1.8 la section
[working-copy]
permet de configurer les copies
de travail. Les options reconnues dans cette section
sont :
exclusive-locking-clients
Cette option active le verrouillage exclusif de SQLite
pour le client, ce qui permet d'améliorer les performances
dans le cas de copies de travail stockées sur des disques
réseaux. En affectant svn
à cette
variable, vous demandez au client texte interactif de
Subversion d'utiliser le verrouillage exclusif. Cela diminue
le temps pris par le verrouillage, mais cela signifie qu'un
seul client Subversion pourra accéder à la copie de travail
à la fois. Un deuxième client qui essaie d'accéder à la copie
de travail verrouillée sera bloqué pendant dix secondes puis
recevra une erreur. Dans la plupart des cas, le verrouillage
partagé est préférable mais si la copie de travail est
stockée sur un disque réseau plutôt que sur un disque local,
le temps de verrouillage est plus significatif. Lorsque
vous travaillez sur de grosses copies de travail sur des
disques réseau, le verrouillage exclusif peut apporter une
amélioration sensible des performances, en étant jusqu'à deux
ou trois fois plus rapide dans certains cas. Cette option est
apparue dans Subversion 1.8.
exclusive-locking
En affectant true
à cette variable,
vous activez le verrouillage exclusif SQLite des copies de
travail pour tous les clients Subversion 1.8. L'activation
de cette option peut engendrer des erreurs sur certains
clients. La valeur par défaut est false
.
Cette option est apparue avec Subversion 1.8.
Le fichier servers
contient les
options de configuration relatives aux couches réseau. Il
y a deux sections spéciales dans ce fichier :
[groups]
et [global]
.
La section [groups]
n'est rien d'autre
qu'un tableau de références croisées. Les clés de cette
section sont les noms des autres sections du fichier ;
ses valeurs sont des globs (des
représentations textuelles qui peuvent contenir des
caractères joker) qui sont comparés aux noms des machines
auxquelles des requêtes Subversion sont envoyées.
[groups] babasses-red-beans = *.red-bean.com collabnet = svn.collab.net [babasses-red-beans] … [collabnet] …
Quand vous utilisez Subversion en réseau, il essaie de faire
correspondre le nom du serveur auquel il tente de se connecter avec
un nom de groupe de la section [groups]
. Si une
correspondance existe, Subversion vérifie alors s'il existe dans le
fichier servers
une section dont le nom est
le nom du groupe correspondant. Le cas échéant, il tire de cette
section la configuration réseau à appliquer.
La section [global]
contient la configuration
à appliquer à tous les serveurs qui ne correspondent à aucun glob
de la section [groups]
. Les options disponibles
dans cette section sont exactement les mêmes que pour les autres
sections du fichier (exceptée bien sûr la section spéciale
[groups]
) et sont :
http-auth-types
C'est une liste (dont les éléments sont séparés par
des points-virgules) de méthodes d'authentification que le
client acceptera. Les méthodes valides sont
basic
, digest
et
negotiate
, sachant que le comportement par
défaut est d'accepter n'importe quelle méthode. Un client qui
ne veut pas transmettre en clair ses éléments
d'authentification peut, par exemple, affecter la valeur
digest;negotiate
à cette option (et ne
mentionnera donc pas basic
). Notez que
cette option n'est prise en compte que par le module
Subversion pour les accès HTTP basé sur la bibliothèque
Neon.
http-compression
Cette option spécifie si Subversion doit envoyer des
requêtes réseau compressées vers les serveurs DAV. La valeur
par défaut est yes
(cependant, la
compression ne sera effective que si la couche réseau a été
compilée avec le support de la compression). En affectant la
valeur no
, vous désactivez la compression
et vous pourrez alors analyser plus facilement les
transmissions réseau.
http-library
La variable http-library
permet de
spécifier (de manière générale ou pour un groupe de serveurs
particuliers seulement) lequel des modules d'accès WebDAV
vous souhaitez utiliser. Avant la version 1.8, Subversion
proposait deux modules : l'implémentation originale
libsvn_ra_neon
(choisie avec la valeur
neon
) et la plus récente
libsvn_ra_serf
(choisie avec la valeur
serf
). Depuis Subversion 1.8, seule
libsvn_ra_serf
reste disponible.
Cette option reste présente, cependant, car le fichier de
configuration se veut aussi indépendant que possible de la
version de Subversion. Les utilisateurs qui disposent de
plusieurs versions de Subversion installées sur leur système
peuvent vouloir utiliser libsvn_ra_neon
pour des sites sur lesquels ils se connectent avec de
vieilles versions de Subversion.
http-proxy-exceptions
Cette option contient une liste de motifs (séparés par des virgules) de noms de machines qui doivent être contactées directement, sans passer par le mandataire. La syntaxe des motifs est la même que celle utilisée par le shell Unix pour les noms de fichiers. L'accès aux dépôts d'une machine dont le nom correspond à l'un de ces motifs se fera sans passer par un mandataire.
http-proxy-host
Cette option contient le nom de la machine mandataire pour les requêtes HTTP de Subversion. La valeur par défaut est vide, ce qui signifie que Subversion ne tentera pas de faire passer ses requêtes par un mandataire mais essaiera de contacter la machine de destination directement.
http-proxy-password
Cette option spécifie le mot de passe à fournir à la machine mandataire. Par défaut, la valeur est vide.
http-proxy-port
Cette option contient le numéro du port à utiliser sur la machine mandataire. Par défaut, la valeur est vide.
http-proxy-username
Cette option spécifie le nom d'utilisateur à fournir à la machine mandataire. Par défaut, la valeur est vide.
http-timeout
Cette option contient la durée maximum, en secondes,
pendant laquelle Subversion attend la réponse du serveur. Si
vous rencontrez des problèmes d'opérations Subversion qui
expirent à cause d'une connexion réseau trop lente, vous
devez augmenter cette valeur. Avec Subversion 1.8 (ou des
versions plus anciennes utilisant le module HTTP basé sur
Serf), utilisez la valeur 0
pour
désactiver le délai d'attente maximal.
neon-debug-mask
Spécifier ici un masque binaire sous la forme d'un entier
que la bibliothèque HTTP sous-jacente Neon utilise pour
définir le type d'affichage de débogage que vous voulez. La
valeur par défaut est 0
, ce qui n'affiche
aucune information de débogage. Avant la version 1.8, la
plupart des clients Subversion utilisaient Neon
(via le module d'accès au
dépôt libsvn_ra_neon
) pour les
communications WebDAV/HTTP entre le client et le serveur. Le
support de libsvn_ra_neon
a été enlevé
dans Subversion 1.8 ce qui rend cette option obsolète pour
les nouvelles installations de Subversion.
ssl-authority-files
Cette option contient une liste de chemins (séparés par des points-virgules) vers les fichiers contenant les certificats des autorités de certifications (abrégé en AC en français et CA en anglais) qui doivent être reconnues comme de confiance par le client Subversion lors des accès aux dépôts en HTTPS.
ssl-client-cert-file
Si un hôte (ou un ensemble d'hôtes) demande un certificat SSL au client, vous serez invité à fournir le chemin de votre certificat. En affectant un chemin à cette variable, Subversion sera capable de trouver automatiquement votre certificat et ne vous sollicitera pas. Il n'existe pas d'emplacement standard pour stocker un certificat utilisateur sur le disque ; Subversion va le chercher à l'endroit que vous lui spécifiez.
ssl-client-cert-password
Si votre certificat client SSL est protégé par une
phrase de passe, Subversion vous la demandera à chaque fois
que le certificat est utilisé. Si vous trouvez cela pénible
(et que cela ne vous dérange pas que cette phrase de passe
soit stockée dans le fichier servers
),
vous pouvez affecter la phrase de passe de votre certificat à
cette variable. Vous ne serez plus sollicité.
ssl-pkcs11-provider
La valeur affectée à cette option est le nom du fournisseur PKCS#11 auquel Subversion demande un certificat client SSL (si le serveur en demande un). Cette option n'est pertinente que pour le module HTTP basé sur Neon, qui a été enlevé de Subversion dans la version 1.8.
ssl-trust-default-ca
Mettez cette variable à yes
si vous voulez que Subversion fasse automatiquement
confiance à l'ensemble des autorités de certification
livrées par défaut avec OpenSSL.
store-auth-creds
cette option est équivalente à
store-passwords
sauf qu'elle applique la
mise en cache sur le disque (ou non) à
l'ensemble des informations
d'authentification : identifiants, mots de passe,
certificats serveur et tout autre type d'élément pouvant être
mis en cache.
store-passwords
Cette option demande à Subversion de garder en cache
(ou non) les mots de passe qui sont tapés par l'utilisateur
en réponse aux demandes d'authentification des serveurs. La
valeur par défaut est yes
. Remplacez cette
valeur par no
pour désactiver la mise en
cache sur le disque. Vous pouvez outrepasser cette option
pour un appel donné d'une commande svn en
utilisant l'option de ligne de commande
--no-auth-cache
(pour les sous-commandes qui
acceptent cette option). Pour plus d'informations, consultez
la section intitulée « Mise en cache des éléments d'authentification ». Notez
que, indépendamment de la valeur pour cette option,
Subversion ne stockera jamais les mots de passe en clair à
moins que l'option
store-plaintext-passwords
ne soit
positionnée aussi à yes
.
store-plaintext-passwords
Cette variable n'est important que pour les systèmes de
type Unix. Elle contrôle ce que le client Subversion fait
lorsque le mot de passe pour le domaine d'authentification en
cours ne peut être mis en cache sur le disque que en clair,
dans la zone ~/.subversion/auth/
. Vous
pouvez affecter yes
(resp.
no
) pour autoriser (resp. interdire) la
mise en cache des mots de passe en clair. La valeur par
défaut est ask
, ce qui entraine que le
client Subversion vous demande ce qu'il faut faire à chaque
fois qu'un nouveau mot de passe doit être ajouté dans la
zone de cache ~/.subversion/auth/
.
store-ssl-client-cert-pp
Cette option contrôle si Subversion met en cache les
phrases de passe pour les certificats SSL clients de
l'utilisateur. La valeur par défaut est
yes
. Vous pouvez fixer la valeur à
no
pour interdire la
mise en cache des phrases de passe.
store-ssl-client-cert-pp-plaintext
Cette variable contrôle si Subversion, au moment de la
mise en cache de la phrase de passe d'un certificat SSL
client, sera autorisé à le faire en stockant cette
information en clair sur le disque. La valeur par défaut est
ask
, ce qui entraine que le
client Subversion vous demande ce qu'il faut faire à chaque
fois qu'une nouvelle phrase de passe doit être ajoutée dans
la zone de cache ~/.subversion/auth/
.
Vous pouvez définir la valeur à yes
ou
no
pour indiquer votre préférence et ainsi
éviter d'être sollicité à chaque fois.
La localisation (aussi appelée régionalisation) consiste à modifier le comportement d'un programme pour qu'il agisse d'une manière propre à une région. Quand un programme formate les nombres et les dates d'une façon particulière pour votre région du monde ou quand il affiche des messages (ou accepte des entrées) dans votre langue maternelle, le programme est dit localisé. Cette section décrit les étapes qu'a franchi Subversion pour être localisable.
En général, les systèmes d'exploitation modernes intègrent la notion de « paramètres régionaux courants » (current locale en anglais), c'est-à-dire la région ou le pays dont les conventions sont appliquées. Ces conventions, généralement choisies par un mécanisme de configuration pour la durée du fonctionnement d'un programme sur l'ordinateur, affectent la façon dont les données sont présentées à l'utilisateur ainsi que la façon dont les entrées de l'utilisateur sont traitées.
Sur la majorité des systèmes de type Unix, vous pouvez vérifier la valeur des paramètres régionaux en cours en lançant la commande locale :
$ locale LANG= LC_COLLATE="C" LC_CTYPE="C" LC_MESSAGES="C" LC_MONETARY="C" LC_NUMERIC="C" LC_TIME="C" LC_ALL="C" $
L'affichage comprend une liste de variables d'environnement
relatives à des conventions locales et leurs valeurs. Dans cet
exemple, toutes les variables possèdent la valeur par défaut
C
, mais les utilisateurs peuvent modifier ces
valeurs et leur affecter des valeurs propres à leur pays ou à leur
langue. Par exemple, si quelqu'un fixe la valeur de la variable
LC_TIME
à fr_CA
, les programmes
sauront qu'ils doivent afficher les dates et les heures conformément
aux attentes des Canadiens francophones. Et si quelqu'un fixe la
valeur de la variable LC_MESSAGES
à
zh_TW
, les programmes sauront qu'ils doivent
afficher les messages à destination de l'utilisateur en chinois
traditionnel. Modifier la variable LC_ALL
équivaut
à donner à toutes les variables de paramètres régionaux la valeur
choisie pour LC_ALL
. La valeur de la variable
LANG
est utilisée par défaut pour toute variable
de paramètre régional qui n'a pas de valeur attribuée. Pour voir la
liste de toutes les variables de paramètres régionaux sur un système
Unix, lancez la commande locale -a
.
Sous Windows, la configuration des paramètres régionaux s'effectue par l'intermédiaire de l'élément « Options régionales, date, heure et langue » du panneau de configuration. Vous pouvez y voir et y sélectionner les valeurs de chacune des variables disponibles, voire personnaliser les conventions d'affichage de nombreux paramètres (à un niveau de détail presque maladif).
Le client Subversion, svn, utilise la
configuration courante des paramètres régionaux de deux manières.
D'abord, il prend en compte la valeur de la variable
LC_MESSAGES
et essaie d'afficher tous les messages
dans la langue indiquée. Par exemple :
$ export LC_MESSAGES=de_DE $ svn help cat cat: Gibt den Inhalt der angegebenen Dateien oder URLs aus. Aufruf: cat ZIEL[@REV]... …
Ce comportement est identique sur les systèmes Unix et
Windows. Notez cependant que, bien que votre système
d'exploitation puisse supporter certaines valeurs de
paramètres régionaux, Subversion ne parle peut-être pas toutes
ces langues. Afin d'afficher ces messages localisés, des
volontaires (humains) doivent fournir des traductions dans
chaque langue. Les traductions sont écrites en utilisant le
paquetage GNU gettext, ce qui produit des modules de
traduction dont l'extension du nom de fichier est
.mo
. Par exemple, le fichier des
traductions allemandes s'appelle de.mo
.
Ces fichiers de traductions sont installés quelque part sur
votre système. Sous Unix, ils sont généralement placés dans
/usr/share/locale/
, alors que sous Windows
on les trouve souvent dans le dossier
\share\locale\
de la zone d'installation
de Subversion. Une fois installé, un module est renommé
d'après le programme pour lequel il fournit des traductions.
Par exemple, le fichier de.mo
sera
peut-être finalement installé en tant que
/usr/share/locale/de/LC_MESSAGES/subversion.mo
.
En parcourant les fichiers .mo
installés,
vous pouvez voir quelles langues le client Subversion
parle.
La prise en compte des paramètres régionaux se fait aussi au niveau de la façon dont svn interprète vos entrées. Le dépôt stocke tous les chemins, noms de fichiers et commentaires de propagation en Unicode, plus exactement en UTF-8. En ce sens, le dépôt est internationalé, c'est-à-dire que le dépôt peut accepter des entrées en n'importe quelle langue. Cela signifie cependant que le client Subversion ne doit envoyer vers le dépôt que des noms de fichiers et des commentaires de propagation en UTF-8. Pour ce faire, il doit convertir les données depuis les paramètres régionaux courants vers l'UTF-8.
Par exemple, supposons que vous créez un fichier nommé
caffè.txt
et qu'ensuite, lorsque vous propagez
ce fichier, vous fournissez le commentaire de propagation suivant :
« Adesso il caffè è più forte ». Le nom du fichier et le
commentaire de propagation contiennent tous deux des caractères
non-ASCII, mais puisque vos paramètres régionaux sont
it_IT
, le client Subversion sait qu'il doit les
interpréter comme de l'italien. Il utilise alors un jeu de caractères
italiens pour convertir ces données en UTF-8 avant de les envoyer au
dépôt.
Remarquez que, bien que le dépôt exige des noms de fichiers et des commentaires de propagation au format UTF-8, il ne s'intéresse pas au contenu du fichier. Subversion traite le contenu des fichiers comme des chaînes d'octets « opaques » ; ni le client ni le serveur ne tentent de comprendre le jeu de caractères ou le codage du contenu d'un fichier.
La manière la plus évidente d'entrer des données dans Subversion
consiste à ajouter des fichiers sous gestion de versions, propager des
changements sur ces fichiers, etc. Mais d'autres informations
existent dans le dépôt Subversion à côté des données constituées par
les simples fichiers suivis en versions. Certaines de ces informations
— les commentaires de propagation, les commentaires sur les verrous et les
valeurs de certaines propriétés — ont naturellement tendance à être
textuelles et sont explicitement fournies par les utilisateurs. En
général, ces informations peuvent être fournies à Subversion à l'aide
du client texte interactif en utilisant les options
--message
(-m
) et
--file
(-F
) dans le cadre des
sous-commandes appropriées.
Chacune de ces options a des avantages et des inconvénients. Par
exemple, quand vous effectuez une propagation, l'option
--file
(-F
) fonctionne bien si vous
avez déjà préparé un fichier texte qui contient votre commentaire de
propagation. Si vous ne l'avez pas fait, vous pouvez toujours utiliser
l'option --message
(-m
) pour stipuler
votre commentaire en ligne de commande. Malheureusement, composer un
commentaire de plus d'une ligne en ligne de commande peut être assez
délicat. Les utilisateurs veulent plus de flexibilité : ils
veulent pouvoir écrire un commentaire de propagation multi-lignes, sans
contrainte de format et à la demande.
Subversion répond à cette attente en vous permettant de spécifier un éditeur de texte externe qui sera lancé au besoin, vous offrant ainsi un moyen plus puissant pour entrer des méta-données textuelles. Il y a plusieurs manières d'indiquer à Subversion quel éditeur vous voulez utiliser. Subversion vérifie les choses suivantes, dans l'ordre spécifié, avant de lancer un tel éditeur :
l'option en ligne de commande
--editor-cmd
;
la variable d'environnement
SVN_EDITOR
;
l'option de configuration
editor-cmd
;
la variable d'environnement
VISUAL
;
la variable d'environnement
EDITOR
;
éventuellement, une valeur par défaut spécifiée dans une des bibliothèques de Subversion (non présente dans les distributions officielles).
La valeur de n'importe laquelle de ces options ou variables est le début de la ligne de commande qui sera exécutée par le shell. Subversion ajoute à cette ligne de commande une espace et le chemin vers un fichier temporaire à éditer. Ainsi, pour être utilisé avec Subversion, l'éditeur spécifié ou configuré doit pouvoir être appelé avec pour dernier argument de sa ligne de commande le fichier à éditer, il doit être capable de sauvegarder le fichier au même endroit et il doit retourner zéro comme code de retour, pour indiquer la réussite de l'opération.
Comme indiqué, les éditeurs externes peuvent être utilisés pour
fournir les commentaires de propagation à n'importe quelle sous-commande
de propagation (telle que svn commit ou svn
import, svn mkdir ou svn
delete quand vous fournissez une URL cible, etc.) et
Subversion essaie de lancer l'éditeur automatiquement si vous ne
spécifiez ni l'option --message
(-m
)
ni l'option --file
(-F
). La commande
svn propedit est presque entièrement construite
autour de l'utilisation d'un éditeur de texte externe. À partir de la
version 1.5, Subversion utilise également l'éditeur de texte externe
configuré quand l'utilisateur demande le lancement d'un éditeur lors de
la résolution interactive de conflits. Bizarrement, il ne semble pas y
avoir de moyen d'utiliser un éditeur externe pour fournir un
commentaire de verrouillage de manière interactive.
L'interface entre Subversion et les outils de comparaison (de deux
ou trois fichiers) remonte à l'époque où Subversion, pour afficher les
différences de manière contextuelle, utilisait directement la suite
d'outils GNU de comparaison, plus précisément les utilitaires
diff et diff3. Pour obtenir le
comportement désiré par Subversion, l'appel à ces programmes se faisait
avec une ribambelle d'options et de paramètres dont la plupart étaient
spécifiques à ces utilitaires. Plus tard, Subversion s'est doté de sa
propre bibliothèque de comparaison et, afin de conserver la possibilité
de choisir, les options --diff-cmd
et
--diff3-cmd
ont été ajoutées au client texte
interactif pour que les utilisateurs allergiques à la nouvelle
bibliothèque puissent indiquer facilement leur souhait de se servir des
utilitaires GNU diff et diff3. Si ces options étaient utilisées,
Subversion ignorait purement et simplement sa bibliothèque interne de
comparaison et appelait alors ces programmes externes, avec leurs
listes d'arguments longue comme un jour sans pain et leurs autres
spécificités. Les choses sont restées en l'état.
Il n'a pas fallu longtemps pour que les adeptes de Subversion comprennent que si l'on pouvait utiliser les utilitaires GNU diff et diff3 situés à un endroit précis du disque, on pouvait alors aussi profiter de ce mécanisme pour utiliser d'autres outils de comparaison. Après tout, Subversion ne vérifiait pas que les programmes qu'il lançait faisaient bien partie de la suite des outils GNU de comparaison. Mais la seule chose que l'on peut configurer dans l'utilisation de programmes externes est leur emplacement sur le disque ; pas les options, ni l'ordre des paramètres, ni le reste. Subversion continue à envoyer toutes les options des utilitaires GNU à votre programme de comparaison, indépendamment du fait que votre programme en tienne compte ou non. Et c'est là que la plupart des utilisateurs ne comprennent pas la logique de la chose.
Note | |
---|---|
La décision de lancer une comparaison entre deux ou trois
fichiers dans le cadre d'une opération Subversion est entièrement du
ressort de Subversion et est conditionnée, en autres, au fait que les
fichiers soient lisibles par un humain comme indiqué par leur
propriété |
Bien plus tard, Subversion 1.5 introduisit la résolution
interactive des conflits (décrite dans la section intitulée « Résolution des conflits »). L'une des options proposées à
l'utilisateur est de lancer un outil de fusion externe. Si cette action
est choisie, Subversion consultera l'option
merge-tool-cmd
de la zone de configuration des
exécutables, susceptible de contenir le nom d'un outil externe de
fusion. S'il en trouve un, il lancera cet outil.
Note | |
---|---|
Bien que l'objectif soit globalement le même entre les outils qui comparent trois fichiers et les outils de fusion (trouver une un découpage des fichiers de manière à ce que les modifications soient clairement séparées sans se perturber), Subversion met en œuvre chacune de ces options à des moments différents et pour des raisons différentes. Le moteur de comparaison pour trois fichiers ou son pendant externe sont utilisés lorsqu'une interaction avec l'utilisateur n'est pas requise. En fait, de tels outils induisent des délais significatifs qui peuvent produire des erreurs dans certaines opérations de Subversion. C'est l'outil de fusion externe qui a vocation à être utilisé de manière interactive. |
Maintenant, bien que l'interface entre Subversion et un outil de fusion externe soit nettement moins compliquée que celle entre Subversion et les outils diff et diff3, la probabilité de trouver un tel outil dont les conventions d'appel sont exactement les mêmes que Subversion sont très faibles. La clé pour utiliser des outils externes de différenciation et de fusion avec Subversion, c'est d'encapsuler ces outils dans des scripts d'interface qui convertiront les entrées en provenance de Subversion en quelque chose d'intelligible pour votre outil, puis de convertir en retour la sortie de votre outil vers le format que Subversion attend. Les sections qui suivent couvrent les détails des attendus de Subversion.
Subversion appelle les programmes externes de comparaison avec des paramètres compatibles avec la suite d'outils de comparaison GNU et s'attend à ce que le programme renvoie un code d'erreur signifiant la réussite de la comparaison. Pour la plupart des programmes de comparaison alternatifs, seuls les sixième et septième arguments, indiquant les chemins vers les fichiers à comparer, respectivement placés à gauche et à droite, sont intéressants. Notez que Subversion lance le programme de comparaison pour chaque fichier concerné par l'opération Subversion, ce qui peut vous amener à avoir plusieurs instances simultanément si votre programme fonctionne de manière asynchrone (ou s'il est placé en arrière-plan). Enfin, Subversion s'attend à ce que votre programme retourne un code d'erreur de 1 s'il a détecté des différences ou 0 sinon. Tout autre code d'erreur est considéré comme une erreur fatale [76].
L'Exemple 7.2, « diffwrap.py » et l'Exemple 7.3, « diffwrap.bat » sont des modèles de scripts d'interface pour un outil externe de comparaison, respectivement en langage Python et en langage de script Windows.
Exemple 7.2. diffwrap.py
#!/usr/bin/env python import sys import os # Indiquez ici le chemin de votre outil de comparaison favori. DIFF = "/usr/local/bin/mon-diff-perso" # Subversion fournit les chemins voulus dans les deux derniers arguments. GAUCHE = sys.argv[-2] DROITE = sys.argv[-1] # Appelons la commande de comparaison (modifiez la ligne suivante # en accord avec votre programme de comparaison). cmd = [DIFF, '--left', GAUCHE, '--right', DROITE] os.execv(cmd[0], cmd) # Le code d'erreur renvoyé doit être : # 0 si aucune différence n'est détectée, # 1 s'il y a des différences. # Tout autre code est traité comme une erreur fatale.
Exemple 7.3. diffwrap.bat
@ECHO OFF REM Indiquez ici le chemin de votre outil de comparaison favori. SET DIFF="C:\Program Files\Super Progs\Mon Diff Perso.exe" REM Subversion fournit les chemins voulus dans les deux derniers arguments. REM Ce sont les paramètres 6 et 7 (sauf si vous utilisez svn diff -x, REM auquel cas tout est possible). SET GAUCHE=%6 SET DROITE=%7 REM Appelons la commande de comparaison (modifiez la ligne suivante REM en accord avec votre programme de comparaison). %DIFF% --left %GAUCHE% --right %DROITE% REM Le code d'erreur renvoyé doit être : REM 0 si aucune différence n'est détectée, REM 1 s'il y a des différences. REM Tout autre code est traité comme une erreur fatale.
Subversion appelle les programmes externes de comparaison de trois fichiers pour effectuer des fusions sans interaction avec l'utilisateur. Lorsqu'il est configuré pour utiliser un programme externe, il appelle ce programme avec des paramètres compatibles avec l'outil GNU diff3 et s'attend à ce que le programme externe retourne un code d'erreur correct et que le fichier résultant de l'opération de fusion soit envoyé vers la sortie standard (de façon à ce que Subversion puisse le rediriger vers le fichier suivi en versions approprié). Pour la plupart des programmes de fusion alternatifs, seuls les neuvième, dixième et onzième arguments (les chemins des fichiers qui contiennent les versions « mien », « original » et « leur » respectivement) sont intéressants. Notez que puisque Subversion utilise la sortie de votre programme de fusion, votre script d'interface ne doit pas se terminer avant que la sortie n'ait été fournie à Subversion. Quand il se termine, il doit retourner un code d'erreur de 0 si la fusion s'est correctement déroulée ou de 1 si des conflits non résolus persistent dans la sortie. Tout autre code d'erreur est considéré comme une erreur fatale.
L'Exemple 7.4, « diff3wrap.py » et l'Exemple 7.5, « diff3wrap.bat » sont des modèles pour des scripts d'interface vers un programme externe de comparaison de trois fichiers en langage Python et script Windows respectivement.
Exemple 7.4. diff3wrap.py
#!/usr/bin/env python import sys import os # Indiquez ici le chemin de votre outil de comparaison de 3 fichiers favori. DIFF3 = "/usr/local/bin/mon-diff3-favori" # Subversion fournit les chemins voulus dans les trois derniers arguments. MIEN = sys.argv[-3] VIEUX = sys.argv[-2] LEUR = sys.argv[-1] # Appelons la commande de comparaison (modifiez la ligne suivante # en accord avec votre outil). cmd = [DIFF3, '--older', VIEUX, '--mine', MIEN, '--yours', LEUR] os.execv(cmd[0], cmd) # Après avoir effectué la fusion, le script doit envoyer le # contenu du fichier résultant vers la sortie standard (stdout) # Faites le à votre convenance. # Le code d'erreur renvoyé doit être : # 0 si la fusion a bien fonctionné, # 1 s'il reste des conflits non résolus. # Tout autre code est traité comme une erreur fatale.
Exemple 7.5. diff3wrap.bat
@ECHO OFF REM Indiquez ici le chemin de votre outil de comparaison favori. SET DIFF3="C:\Program Files\Super Progs\Mon Diff3 Favori.exe" REM Subversion fournit les chemins voulus dans les trois derniers arguments. REM Ce sont les paramètres 9, 10 et 11. Mais nous n'avons accès qu'à REM neuf paramètres en même temps, nous effectuons donc deux décalages REM pour obtenir les paramètres manquants. SHIFT SHIFT SET MIEN=%7 SET VIEUX=%8 SET LEUR=%9 REM Appelons la commande de comparaison (modifiez la ligne suivante REM en accord avec votre outil). %DIFF3% --older %VIEUX% --mine %MIEN% --yours %LEUR% REM Après avoir effectué la fusion, le script doit envoyer le REM contenu du fichier résultant vers la sortie standard (stdout) REM Faites le à votre convenance. REM Le code d'erreur renvoyé doit être : REM 0 si la fusion a bien fonctionné, REM 1 s'il reste des conflits non résolus. REM Tout autre code est traité comme une erreur fatale.
Subversion peut faire appel à un outil de fusion externe dans le cadre de la résolution interactive de conflits. Il fournit alors les arguments suivants à ce programme : le chemin vers le fichier original non modifié, le chemin vers le fichier « theirs » qui contient les modifications en provenance du dépôt, le chemin vers le fichier dans lequel doivent être insérées les modifications une fois les conflits résolus et le chemin vers la copie de travail du fichier en conflit. L'outil de fusion est censé retourner un code d'erreur de 0 si la fusion s'est correctement déroulée ou de 1 si des conflits non résolus persistent dans la sortie. Tout autre code d'erreur est considéré comme une erreur fatale.
L'Exemple 7.6, « mergewrap.py » et l'Exemple 7.7, « mergewrap.bat » fournissent des modèles de scripts d'interface pour encapsuler un outil de fusion, en langage Python et script Windows respectivement.
Exemple 7.6. mergewrap.py
#!/usr/bin/env python import sys import os # Indiquez ici le chemin vers votre outil de fusion favori. MERGE = "/usr/local/bin/mon-outil-de-fusion" # Subversion fournit les chemins voulus BASE = sys.argv[1] LEUR = sys.argv[2] MIEN = sys.argv[3] FUSIONNE = sys.argv[4] COPIE_TRAVAIL = sys.argv[5] # Appelons la commande de fusion (modifiez la ligne suivante # en accord avec votre outil de fusion). cmd = [MERGE, '--base', BASE, '--mine', MIEN, '--theirs', LEUR, '--outfile', FUSIONNE] os.execv(cmd[0], cmd) # Le code d'erreur renvoyé doit être : # 0 si la fusion a bien fonctionné, # 1 s'il reste des conflits non résolus. # Tout autre code est traité comme une erreur fatale.
Exemple 7.7. mergewrap.bat
@ECHO OFF REM Indiquez ici le chemin vers votre outil de fusion favori. SET MERGE="C:\Program Files\Mes Outils Perso\Mon Outil de Fusion.exe" REM Subversion fournit les chemins voulus SET BASE=%1 SET LEUR=%2 SET MIEN=%3 SET FUSIONNE=%4 SET COPIE_TRAVAIL=%5 REM Appelons la commande de fusion (modifiez la ligne suivante REM en accord avec votre outil de fusion). %MERGE% --base %BASE% --mine %MIEN% --theirs %LEUR% --outfile %FUSIONNE% REM Le code d'erreur renvoyé doit être : REM 0 si la fusion a bien fonctionné, REM 1 s'il reste des conflits non résolus. REM Tout autre code est traité comme une erreur fatale.
Quelquefois il n'y a qu'une façon de bien faire les choses, quelquefois il en existe plusieurs. Les développeurs de Subversion comprennent que, bien que le plus souvent son comportement est acceptable par la plupart des utilisateurs, il y a des fonctionnalités pour lesquelles il n'existe pas de consensus. Dans ces situations, Subversion permet à l'utilisateur de spécifier le comportement qu'il désire voir appliquer.
Dans ce chapitre, nous avons examiné le système de configuration des exécutables de Subversion ainsi que d'autres mécanismes permettant de contrôler le comportement de certaines actions. Si vous êtes développeur, le prochain chapitre vous emmènera un cran plus loin. Il décrit comment vous pouvez personnaliser davantage Subversion en écrivant vos propres programmes en remplacement des bibliothèques Subversion.
[74] La variable d'environnement APPDATA
pointe vers la zone Application Data
,
vous pouvez donc toujours faire référence à ce dossier en
utilisant %APPDATA%\Subversion
.
[75] C'est un peu le repas de fin de semaine préparéavec les restes.
[76] Le manuel du diff GNU indique : « Un code de retour valant 0 signifie qu'aucune différence n'a été trouvée, 1 signifie que des différences sont apparues, 2 indique une erreur ».
Subversion est conçu de manière modulaire : il est constitué d'un ensemble de bibliothèques écrites en langage C. Chaque bibliothèque a un but et une interface de programmation (API, application programming interface en anglais) bien définis ; cette interface est disponible non seulement pour le propre usage de Subversion mais aussi pour n'importe quel programme qui souhaite inclure ou piloter Subversion d'une manière ou d'une autre. De plus, l'API Subversion est non seulement disponible pour les programmes écrits en langage C, mais aussi pour les programmes écrits dans des langages de plus haut niveau tels que Python, Perl, Java et Ruby.
Ce chapitre est destiné à ceux qui souhaitent interagir avec Subversion au moyen de son API publique ou d'une de ses nombreuses interfaces avec d'autres langages. Si vous souhaitez écrire des scripts robustes qui encapsulent les fonctionnalités de Subversion afin de vous rendre la vie plus facile, si vous essayez de développer des intégrations plus poussées entre Subversion et d'autres logiciels ou si vous êtes juste intéressé par les nombreux modules de Subversion et ce qu'ils ont à offrir, ce chapitre est fait pour vous. Si, par contre, vous ne vous voyez pas participer à Subversion à ce niveau, vous pouvez sauter ce chapitre sans la moindre crainte pour vos compétences en tant qu'utilisateur de Subversion.
Chaque bibliothèque au sein de Subversion peut être classée
dans une des trois couches principales : la couche dépôt, la
couche d'accès au dépôt (RA pour Repository
Access en anglais) et la couche client (voir la
Figure 1, « L'architecture de Subversion » de la préface).
Nous allons examiner ces trois couches rapidement mais, d'abord,
passons brièvement en revue les différentes bibliothèques de
Subversion. Pour des raisons de cohérence, nous nous référons à
ces bibliothèques par leurs noms Unix sans extension
(libsvn_fs
, libsvn_wc
,
mod_dav_svn
, etc.).
interface principale pour les programmes clients ;
routines de recherche de différences pour les arborescences et les flux d'octets ;
routines de recherche de différences et de fusions contextuelles ;
chargeur de modules et outils communs pour le système de fichiers ;
gestion du magasin de données Berkeley DB ;
gestion du magasin de données natif FSFS ;
outils communs pour l'accès au dépôt et chargeur de modules ;
module d'accès au dépôt en local ;
autre module (expérimental) d'accès au dépôt par le protocole WebDAV ;
modèle d'accès au dépôt par le protocole Subversion ;
interface du dépôt ;
diverses routines utiles ;
bibliothèque pour la gestion de la copie de travail locale ;
module Apache d'authentification pour les accès aux dépôts Subversion par WebDAV ;
module Apache de correspondance entre les opérations WebDAV et les opérations Subversion.
Le fait que le mot « divers » n'apparaisse qu'une seule fois dans la liste précédente est plutôt un bon signe. L'équipe de développement de Subversion est particulièrement soucieuse de placer les fonctionnalités dans les couches et bibliothèques appropriées. Un des plus grands avantages de cette conception modulaire, du point de vue du développeur, est sûrement l'absence de complexité. En tant que développeur, vous pouvez vous forger rapidement une image mentale de cette architecture et ainsi trouver relativement facilement l'emplacement des fonctionnalités qui vous intéressent.
Un autre avantage de la modularité est la possibilité de
remplacer un module par une autre bibliothèque qui implémente la
même API sans affecter le reste du code. Dans un certain sens,
c'est ce qui se passe déjà dans Subversion. Les bibliothèques
libsvn_ra_local
,
libsvn_ra_serf
et
libsvn_ra_svn
implémentent toutes la même
interface et fonctionnent comme des greffons pour
libsvn_ra
. Et toutes les trois communiquent
avec la couche dépôt — libsvn_ra_local
se connectant directement au dépôt, les trois autres le faisant à
travers le réseau.
libsvn_fs_base
et
libsvn_fs_fs
sont un autre exemple de
bibliothèques qui implémentent les mêmes fonctionnalités de
différentes manières — les deux sont des greffons pour la
bibliothèque commune libsvn_fs
.
Le client lui-même illustre également les avantages de la
modularité dans l'architecture de Subversion. La bibliothèque
libsvn_client
est un point d'entrée unique
pour la plupart des fonctionnalités nécessaires à la conception
d'un client Subversion fonctionnel (voir la section intitulée « Couche client »). Ainsi, bien que la
distribution Subversion fournisse seulement le programme en ligne
de commande svn, de nombreux programmes tiers
fournissent différents types d'IHM. Ces interfaces graphiques
utilisent la même API que le client en ligne de commande fourni en
standard. Depuis le début, cette modularité joue un rôle majeur
dans la prolifération des différents clients Subversion, sous la
forme de clients autonomes ou greffés dans des environnements de
développement intégrés (IDE en
anglais) et, par extension, dans l'adoption formidablement rapide
de Subversion lui-même.
Quand nous faisons référence à la couche
dépôt de Subversion, nous parlons généralement de deux
concepts de base : l'implémentation du système de fichiers suivi
en versions (auquel on accède via
libsvn_fs
et qui est supporté par les
greffons associés libsvn_fs_base
et
libsvn_fs_fs
) et la logique du dépôt qui
l'habille (telle qu'elle est implémentée dans
libsvn_repos
). Ces bibliothèques
fournissent les mécanismes de stockage et de comptes-rendus pour
les différentes révisions de vos données suivies en versions.
Cette couche est connectée à la couche client
via la couche d'accès au dépôt et est,
du point de vue de l'utilisateur de Subversion, le « truc à
l'autre bout de la ligne ».
Le système de fichiers Subversion n'est pas un système de fichiers de bas niveau que vous pourriez installer sur votre système d'exploitation (tels que NTFS ou ext2 pour Linux) mais un système de fichiers virtuel. Plutôt que de stocker les fichiers et répertoires comme des fichiers et des répertoires réels (du type de ceux dans lesquels vous naviguez avec votre navigateur de fichiers), il utilise un des deux magasins de données abstraits disponibles : soit le système de gestion de bases de données Berkeley DB, soit une représentation dans des fichiers ordinaires, dite « à plat » (pour en apprendre plus sur les deux magasins de données, reportez-vous à À propos des magasins de données). La communauté de développement Subversion a même exprimé le souhait que les futures versions de Subversion puissent utiliser d'autres magasins de données, peut-être à travers un mécanisme tel que ODBC (Open Database Connectivity, standard ouvert de connexion à des bases de données). En fait, Google a fait quelque chose de semblable avant de lancer le service « Google Code Project Hosting » (Hébergement de code source de projets) : ils ont annoncé mi-2006 que les membres de leur équipe open source avaient écrit un nouveau greffon propriétaire de système de fichiers pour Subversion, qui utilisait leur base de données « Google ultra-scalable Bigtable » comme magasin de données.
L'API du système de fichiers, mise à disposition par
libsvn_fs
, contient les fonctionnalités que
vous pouvez attendre de n'importe quel autre système de
fichiers : vous pouvez créer et supprimer des fichiers et
des répertoires, les copier et les déplacer, modifier le contenu
d'un fichier, etc. Elle possède également des caractéristiques
peu communes comme la capacité d'ajouter, modifier et supprimer
des méta-données (« propriétés ») sur chaque fichier
ou répertoire. En outre, le système de fichiers Subversion est
un système de fichiers suivi en versions, ce qui veut dire que
si vous faites des modifications dans votre arborescence,
Subversion se souvient de l'état de votre arborescence avant les
modifications. Et il se souvient aussi de l'état avant les
modifications précédentes, et de l'état encore antérieur, et ainsi
de suite. Vous pouvez ainsi remonter le temps (c'est-à-dire les
versions) jusqu'au moment où vous avez commencé à ajouter des
éléments dans le système de fichiers.
Toutes les modifications faites sur l'arborescence ont pour contexte les transactions de propagation de Subversion. Ce qui suit est la démarche générale simplifiée de modification du système de fichiers :
commencer une transaction de propagation de Subversion ;
effectuer les modifications (ajouts, suppressions, modifications de propriétés, etc.) ;
clore la transaction.
Une fois que la transaction est terminée, les modifications du système de fichiers sont stockées de façon permanente en tant qu'éléments de l'historique. Chacun de ces cycles génère une nouvelle révision de l'arborescence et chaque révision est accessible pour toujours sous la forme d'un cliché, immuable, de l'état de l'arborescence à un moment précis.
La majeure partie des fonctionnalités offertes par l'interface du
système de fichiers traite d'actions relatives à un chemin unique du
système de fichiers. C'est-à-dire que, vu de l'extérieur du système
de fichiers, le mécanisme de base pour décrire et accéder à une
révision donnée d'un fichier ou d'un répertoire utilise des chemins
classiques tels que /machin/bidule
, de la même
manière que quand vous indiquez un fichier ou un répertoire dans
votre interface en ligne de commande favorite. Vous ajoutez de
nouveaux fichiers ou répertoires en passant leur
« futur » chemin à la fonction idoine de l'API. Vous
faites des requêtes sur ces éléments avec le même
mécanisme.
Cependant, contrairement à la plupart des systèmes de fichiers, le chemin n'est pas une information suffisante pour identifier un fichier ou un répertoire dans Subversion. Représentez-vous l'arborescence des répertoires comme un système à deux dimensions, où l'on atteint les frères d'un nœud en se déplaçant horizontalement, à droite ou à gauche, et où la navigation dans les sous-répertoires de ce nœud peut être assimilée à un mouvement vers le bas. La Figure 8.1, « Fichiers et répertoires en deux dimensions » illustre ce concept pour une arborescence classique.
Ici, la différence est que le système de fichiers Subversion
possède une élégante troisième dimension que la plupart des
systèmes de fichiers n'ont pas : le temps[77]. Dans l'interface du système de
fichiers, presque chaque fonction qui demande un argument de type
chemin
attend également un argument de type
racine
(dénommé en fait
svn_fs_root_t
). Cet argument décrit soit une
révision, soit une transaction (qui est en fait la genèse d'une
révision) et fournit la troisième dimension, l'élément de contexte
indispensable pour différencier /machin/bidule
dans la révision 32 et le même chemin dans la révision 98. La Figure 8.2, « Prise en compte du temps — la troisième dimension de la
gestion de versions ! » présente l'historique
des révisions comme une dimension supplémentaire de l'univers du
système de fichiers Subversion.
Comme nous l'avons déjà mentionné, l'API de
libsvn_fs
ressemble à s'y méprendre à celle
de n'importe quel autre système de fichiers, sauf qu'on y a ajouté la
formidable capacité de gestion des versions. Elle a été conçue pour
être utilisable par n'importe quel programme ayant besoin d'un
système de fichiers suivi en versions. Et ce n'est pas un hasard si
Subversion lui-même est intéressé par une telle fonctionnalité. Mais,
bien que cette API soit suffisante pour effectuer une gestion de
versions basique des fichiers et des répertoires, Subversion en
demande plus, et c'est là que libsvn_repos
entre
en scène.
La bibliothèque du dépôt Subversion
(libsvn_repos
) se situe (logiquement parlant)
au-dessus de l'API libsvn_fs
et elle fournit des
fonctionnalités supplémentaires allant au-delà de la logique
sous-jacente du système de fichiers suivi en versions. Elle ne masque
pas entièrement chaque fonction du système de fichiers — seules
certaines étapes importantes dans le cycle général de l'activité du
système de fichiers sont encapsulées par l'interface du dépôt. Parmi
les fonctions encapsulées, on peut citer la création et la
propagation des transactions Subversion et la modification des
propriétés de révisions. Ces actions particulières sont encapsulées
par la couche dépôt parce qu'elles ont des procédures automatiques
associées. Le système des procédures automatiques du dépôt n'est
pas strictement concomitant à l'implémentation d'un système de
fichiers suivi en versions, c'est pourquoi il réside dans la
bibliothèque d'encapsulation du dépôt.
Le mécanisme des procédures automatiques n'est pas l'unique
raison qui a conduit à séparer logiquement la bibliothèque du
dépôt du reste du code du système de fichiers. L'API de
libsvn_repos
fournit à Subversion un
certain nombre d'autres possibilités intéressantes. Parmi elles,
on peut citer :
créer, ouvrir, détruire et effectuer des actions de restauration sur un dépôt Subversion et le système de fichiers inclus dans ce dépôt ;
décrire les différences entre deux arborescences ;
obtenir les commentaires de propagation associés à toutes les révisions (ou certaines) qui ont modifié un ensemble de fichiers du système de fichiers ;
générer des images (« dumps ») du système de fichiers lisibles par l'utilisateur — ces images étant des représentations complètes des révisions du système de fichiers ;
analyser ces images et les charger dans un autre dépôt Subversion.
Comme Subversion continue à évoluer, la bibliothèque du dépôt grandit avec la bibliothèque du système de fichiers pour offrir davantage de fonctionnalités et des options configurables.
Si la couche Dépôt de Subversion est « à l'autre
bout de la ligne », la couche d'accès au dépôt (RA pour
repository access en anglais)
est la ligne en tant que telle. Chargée d'organiser les données
entre les bibliothèques client et le dépôt, cette couche inclut
la bibliothèque de chargement du module
libsvn_ra
, les modules RA eux-mêmes (qui
incluent à l'heure actuelle libsvn_ra_local
,
libsvn_ra_serf
et
libsvn_ra_svn
) et toute bibliothèque
supplémentaire requise par un ou plusieurs de ces modules RA
(par exemple, le module Apache mod_dav_svn
ou le serveur de libsvn_ra_svn
,
svnserve).
Comme Subversion utilise les URL pour identifier les
dépôts à contacter, la partie de l'URL qui indique le protocole
(habituellement file://
,
http://
, https://
,
svn://
ou svn+ssh://
) est
utilisée pour déterminer quel module RA gère les communications.
Chaque module indique la liste des protocoles qu'il connaît afin que
le chargeur RA puisse déterminer, à l'exécution, quel module utiliser
pour la tâche en cours. Vous pouvez obtenir la liste des modules RA
disponibles pour votre client Subversion en ligne de commande,
ainsi que les protocoles qu'ils prennent en charge, en lançant
la commande svn --version
:
$ svn --version svn, version 1.8.16 (r1740329) compiled Apr 29 2016, 17:10:07 Copyright (C) 2016 The Apache Software Foundation. This software consists of contributions made by many people; see the NOTICE file for more information. Subversion is open source software, see http://subversion.apache.org/ Les modules d'accès à un dépôt (RA) suivants sont disponibles : * ra_svn : Module d'accès à un dépôt avec le protocole réseau propre de svn. - avec authentification Cyrus SASL - gère le schéma d'URL 'svn' * ra_local : Module d'accès à un dépôt sur un disque local. - gère le schéma d'URL 'file' * ra_serf : Module for accessing a repository via WebDAV protocol using serf. - using serf 1.3.8 - gère le schéma d'URL 'http' - gère le schéma d'URL 'https' $
L'API publique exportée par la couche RA contient les
fonctionnalités nécessaires pour envoyer des données suivies en
versions vers le dépôt et pour en recevoir. Chacun des greffons
RA disponibles est capable d'effectuer ces tâches en utilisant
un protocole particulier : libsvn_ra_dav
utilise le protocole HTTP/WebDAV (avec chiffrement SSL en
option) pour communiquer avec un serveur HTTP Apache sur lequel
tourne le module serveur Subversion
mod_dav_svn
;
libsvn_ra_svn
utilise un protocole réseau
propre à Subversion pour communiquer avec le programme
svnserve, et ainsi de suite.
Ceux qui désirent accéder à un dépôt Subversion en utilisant un autre protocole comprendront rapidement pourquoi la couche d'accès au dépôt est modulaire ! Les développeurs peuvent tout simplement écrire une nouvelle bibliothèque qui implémente l'interface RA d'un côté et qui communique avec le dépôt de l'autre. Votre nouvelle bibliothèque peut utiliser des protocoles réseaux existants ou vous pouvez en inventer de nouveaux. Vous pouvez ainsi utiliser les communications inter-processus (IPC pour interprocess communication en anglais) ou même, soyons fou, implémenter un protocole basé sur l'email. Subversion apporte les API, à vous d'apporter la créativité.
Côté client, tout se passe dans la copie de travail Subversion. Le gros des fonctionnalités implémentées par les bibliothèques client existe dans le seul but de gérer les copies de travail locales — des répertoires pleins de fichiers et d'autres sous-répertoires qui sont une sorte de copie locale et modifiable d'un ou plusieurs dépôts — et de propager les changements vers et depuis la couche d'accès au dépôt.
La bibliothèque de Subversion pour la copie de travail,
libsvn_wc
, est directement responsable de
la gestion des données dans les copies de travail. Pour ce
faire, la bibliothèque stocke dans un sous-répertoire spécial
des données d'administration relatives à la copie de travail.
Ce sous-répertoire, nommé .svn
, est présent dans
chaque copie de travail ; il contient tout un tas de
fichiers et de répertoires qui enregistrent l'état de la copie de
travail et fournit un espace privé pour les actions
d'administration. Pour les habitués de CVS, ce sous-répertoire
.svn
a des objectifs similaires aux
répertoires administratifs CVS
que l'on
trouve dans les copies de travail CVS.
La bibliothèque client de Subversion,
libsvn_client
, est celle qui a le plus de
responsabilités : son rôle est de mélanger les
fonctionnalités de la bibliothèque de la copie de travail avec
celles de la couche d'accès au dépôt (RA) afin de fournir l'API
de plus haut niveau, utilisable par n'importe quelle application
qui voudrait effectuer des actions générales de gestion de
versions. Par exemple, la fonction
svn_client_checkout()
prend une URL en
argument. Elle passe cette URL à la couche RA et ouvre une
session authentifiée avec le dépôt concerné. Elle demande
ensuite au dépôt l'arborescence requise, envoie cette
arborescence à la bibliothèque de la copie de travail, qui
écrit alors une copie de travail complète sur le disque (les
répertoires .svn
et tout le reste).
La bibliothèque client est conçue pour être utilisée par
n'importe quelle application. Alors que le code source de
Subversion inclut un client standard en ligne de commande, le
but recherché est qu'il soit très facile d'écrire un nombre
quelconque de clients dotés d'un environnement graphique
(GUI en anglais) par-dessus
cette bibliothèque client. Il n'y a pas de raison que les
nouveaux environnements graphiques (ou les nouveaux clients en
fait) pour Subversion ne soient que des sur-couches au client
en ligne de commande : ils ont un accès total, via
l'API libsvn_client
, aux mêmes
fonctionnalités, données et autres mécanismes que le client en
ligne de commande utilise. En fait, le code source de Subversion
contient un petit programme en C (que vous pouvez trouver dans
tools/examples/minimal_client.c
) qui montre
comment utiliser en pratique l'API Subversion pour créer un
programme client simple.
Développer des applications utilisant les API des
bibliothèques Subversion est plutôt simple. Subversion est d'abord
un ensemble de bibliothèques en langage C, avec des fichiers
d'en-têtes (.h
) situés dans le répertoire
subversion/include
de l'arborescence des
sources. Ces en-têtes sont copiés dans votre arborescence système
(par exemple /usr/local/include
)
quand vous compilez et installez Subversion à partir des sources.
Ces en-têtes contiennent l'ensemble des fonctions et des types
censés être accessibles aux utilisateurs des bibliothèques
Subversion. La communauté des développeurs Subversion apporte
beaucoup d'attention à la disponibilité et la qualité de la
documentation des API publiques — reportez-vous directement
aux fichiers d'en-têtes pour cette documentation.
Quand vous examinez les fichiers d'en-tête publics, la
première chose que vous remarquez est que les types de données
et les fonctions ont un espace de nommage réservé. Cela veut dire
que tous les noms de symboles Subversion publics commencent par
svn_
, suivi d'un code indiquant la bibliothèque
dans laquelle le symbole est défini (par exemple
wc
, client
,
fs
, etc.), suivi d'un unique caractère
souligné (_
) puis du reste du nom du symbole. Les
fonctions semi-publiques (utilisées par plusieurs fichiers au sein
d'une bibliothèque mais pas par du code extérieur à cette
bibliothèque, on peut les trouver au sein des répertoires de la
bibliothèque) suivent une règle de nommage légèrement différente
dans le sens où, au lieu d'un unique caractère souligné
après le code indiquant la bibliothèque, elles utilisent deux
caractères souligné consécutifs (_ _
).
Les fonctions qui sont propres à un fichier source (c'est-à-dire
privées) n'ont pas de préfixe particulier et sont déclarées avec
le mot-clé static
. Bien sûr, un compilateur n'a
que faire de ces conventions de nommage, mais elles sont une aide
précieuse pour clarifier la portée d'une fonction ou d'un type de
données particuliers.
Une autre bonne source d'informations sur la programmation avec les API Subversion est constituée par les bonnes pratiques de programmation au sein du projet lui-même, que vous pouvez trouver à l'adresse suivante https://subversion.apache.org/docs/community-guide/ (pages en anglais). Ce document contient des informations particulièrement utiles qui, bien que destinées aux développeurs (ou aux personnes désireuses de le devenir) de Subversion lui-même, peuvent également servir à tous ceux qui développent des applications utilisant Subversion comme bibliothèque tierce [78].
À côté des types de données propres à Subversion, vous
trouverez de nombreuses références à des types de données qui
commencent par apr_
: ce sont les
symboles de la bibliothèque pour la portabilité d'Apache
(Apache Portable Runtime en
anglais, soit APR). APR est un jeu de bibliothèques Apache,
originellement extraites du code source du serveur
pour essayer de séparer ce qui dépendait du système
d'exploitation de ce qui n'en dépendait pas. Au final, on
obtient une bibliothèque qui fournit une API permettant
d'effectuer des opérations qui changent un peu (ou beaucoup) en
fonction du système d'exploitation. Alors que le serveur HTTP
Apache était le premier utilisateur (et pour cause) de la
bibliothèque APR, les développeurs Subversion ont immédiatement
perçu les avantages qu'il y a à utiliser APR. Cela signifie
qu'il n'y a pratiquement aucun code spécifique à un système
d'exploitation dans Subversion en tant que tel. Cela veut aussi
dire que le client Subversion peut être compilé et exécuté
partout où un serveur Apache peut l'être. Actuellement, cette
liste comprend toutes les variantes d'Unix, Win32, BeOS, OS/2 et
Mac OS X.
En plus de fournir des implémentations fiables des appels
systèmes qui diffèrent d'un système d'exploitation à l'autre
[79],
APR fournit à Subversion un accès direct à de nombreux types de
données personnalisés tels que les tableaux dynamiques et les
tables de hachage. Subversion utilise abondamment ces types de
données et le type de données APR le plus utilisé, que l'on
retrouve dans presque tous les prototypes de l'API Subversion,
est apr_pool_t
— le réservoir de
mémoire (memory pool en anglais)
APR. Subversion utilise les réservoirs de mémoire
en interne pour tous ses besoins d'allocation mémoire
(à moins qu'une bibliothèque externe ne requière
un autre mécanisme de gestion de la mémoire pour les
données transmises via son API)
[80]
et, bien qu'une personne qui utilise l'API Subversion ne soit
pas obligée d'en faire autant, elle doit fournir des réservoirs
aux fonctions de l'API qui en ont besoin. Cela implique que les
utilisateurs de l'API Subversion doivent
également inclure l'APR lors de l'édition de liens, doivent
appeler apr_initialize()
pour initialiser
le sous-système APR et doivent ensuite créer et gérer des
réservoirs de mémoire pour les appels à l'API Subversion,
généralement en utilisant svn_pool_create()
,
svn_pool_clear()
et
svn_pool_destroy()
.
Pour faciliter le fonctionnement asynchrone et offir aux consommateurs de l'API C de Subversion des point d'ancrage pour récupérer l'information de manière aussi souple que possible, beaucoup de fonctions de l'API acceptent deux paramètres : un pointeur vers une fonction de rappel (callback en anglais) et un pointeur vers un bloc mémoire appelé bâton qui contient le contexte de la fonction de rappel.
Subversion a été conçu pour effectuer à distance des
opérations de gestion de versions. À ce titre, les possibilités
d'internationalisation (i18n) ont fait l'objet d'une attention
toute particulière. Après tout, « à distance » peut
vouloir dire depuis un ordinateur situé « dans le même
bureau », mais aussi « à l'autre bout de la
planète ». Pour faciliter cette prise en compte, toutes
les interfaces publiques de Subversion qui acceptent des chemins
comme argument s'attendent à ce que ces chemins soient rendus
canoniques — la façon la plus facile de le faire étant de
les passer en argument à la fonction
svn_path_canonicalize()
— et codés
dans le format UTF-8. Cela signifie, par exemple, que tout
nouveau programme client qui pilote l'interface
libsvn_client
doit d'abord convertir les
chemins depuis le codage local vers UTF-8 avant de fournir ces
chemins à la bibliothèque Subversion, puis doit reconvertir tout
chemin renvoyé par Subversion vers le codage local avant
d'utiliser ce chemin à des fins externes à Subversion.
Heureusement, Subversion fournit un ensemble de fonctions (voir
subversion/include/svn_utf.h
) que tout
programme peut utiliser pour réaliser ces conversions.
De plus, les API Subversion demandent que toutes les URL
passées en paramètres respectent le format URI. Ainsi, au lieu
de désigner par file:///home/utilisateur/Mon fichier.txt
l'URL d'un fichier nommé Mon fichier.txt
situé dans le répertoire home/utilisateur
,
vous devez utiliser
file:///home/utilisateur/Mon%20fichier.txt
. Là
encore, Subversion fournit des fonctions utiles à votre
application — svn_path_uri_encode()
et svn_path_uri_decode()
pour coder et
décoder, respectivement, des URI.
Si vous désirez utiliser les bibliothèques Subversion à
partir d'un autre langage que le C (par exemple un programme
Python ou Perl), Subversion offre cette possibilité
via le générateur simplifié
d'interface et d'encapsulation
(Simplified Wrapper and Interface
Generator ou SWIG en anglais).
Les interfaces SWIG de Subversion sont situées
dans le répertoire subversion/bindings/swig
.
Elles sont toujours en cours d'évolution mais sont utilisables.
Elles vous permettent d'appeler les fonctions de l'API
Subversion indirectement, en utilisant des interfaces qui
traduisent les types de données natifs de votre langage de
programmation vers les types de données utilisés par les
bibliothèques C de Subversion.
De gros efforts ont été fournis pour produire des interfaces SWIG pleinement fonctionnelles pour Python, Perl et Ruby. D'une certaine manière, le travail effectué pour réaliser les interfaces vers ces langages est réutilisable pour produire des interfaces vers d'autres langages supportés par SWIG (ce qui inclut, entre autres, des versions de C#, Guile, Java, MzScheme, OCaml, PHP et Tcl). Cependant, vous aurez besoin d'un peu de programmation supplémentaire pour aider SWIG à faire les traductions entre les langages pour les API complexes. Pour plus d'informations sur SWIG lui-même, visitez le site Web du projet à l'adresse suivante : https://www.swig.org/ (site en anglais).
Subversion fournit également une interface vers le langage
Java. L'interface javahl (située dans
subversion/bindings/java
dans
l'arborescence des sources Subversion) n'est pas basée sur SWIG
mais est un mélange de Java et de JNI codé à la main. Javahl
couvre le plus gros des API du client Subversion et se destine
principalement aux développeurs d'environnements de
développement intégrés (IDE) et de clients Subversion en
Java.
Les interfaces Subversion vers les langages de programmation ne sont pas suivies avec le même niveau d'exigence que les modules du cœur de Subversion, mais peuvent généralement être utilisées en production. De nombreuses applications, de nombreux scripts, des clients graphiques alternatifs et des outils tiers utilisent aujourd'hui sans problème les interfaces vers les langages de programmation afin d'intégrer les fonctionnalités de Subversion.
Veuillez tout de même noter qu'il existe d'autres options pour s'interfacer avec Subversion dans d'autres langages : les interfaces pour Subversion qui ne sont pas fournies par la communauté de développement Subversion. Parmi les plus populaires, deux d'entre elles méritent d'être citées. D'abord, l'interface PySVN de Barry Scott (https://pysvn.sourceforge.io/) est une interface reconnue vers Python. PySVN se targue d'une interface plus « pythonique » que les API « orientées C » fournies par l'interface standard de Subversion vers Python. Et si vous recherchez une implémentation 100 % Java de Subversion, jetez un œil à SVNKit (https://svnkit.com/), qui est une ré-écriture complète de Subversion en Java.
L'Exemple 8.1, « Utilisation de la couche dépôt »
contient un bout de code (écrit en C) qui illustre plusieurs
concepts que nous venons d'aborder. Il utilise à la fois
l'interface du dépôt et celle du système de fichiers (comme
dénoté par les préfixes svn_repos_
et
svn_fs_
des noms de fonctions) pour créer une
nouvelle révision dans laquelle un répertoire est ajouté. Vous
pouvez y observer l'utilisation du réservoir de mémoire APR qui
est utilisé pour les besoins d'allocation mémoire. En outre, le
code révèle le côté obscur de la gestion des erreurs de
Subversion : toutes les erreurs Subversion doivent être
explicitement prises en compte pour éviter des fuites de mémoire
(et dans certains cas, le plantage de l'application).
Exemple 8.1. Utilisation de la couche dépôt
/* Convertit une erreur Subversion en un simple code d'erreur booléen * * NOTE: Les erreurs Subversion doivent être effacées (en utilisant * svn_error_clear()) parce qu'elles sont allouées depuis le * réservoir global, sinon cela produit une fuite de mémoire. */ #define INT_ERR(expr) \ do { \ svn_error_t *__temperr = (expr); \ if (__temperr) \ { \ svn_error_clear(__temperr); \ return 1; \ } \ return 0; \ } while (0) /* Crée un nouveau répertoire NOUVEAU_REP dans le dépôt Subversion * situé à CHEMIN_DEPOT. Effectue toutes les allocations mémoire dans * RESERVOIR. Cette fonction créera une nouvelle révision pour l'ajout * de NOUVEAU_REP. Elle retourne zéro si l'opération se termine * correctement, une valeur différente de zéro sinon. */ static int cree_nouveau_rep(const char *chemin_depot, const char *nouveau_rep, apr_pool_t *reservoir) { svn_error_t *err; svn_repos_t *depot; svn_fs_t *fs; svn_revnum_t derniere_rev; svn_fs_txn_t *transaction; svn_fs_root_t *racine_transaction; const char *chaine_conflit; /* Ouvre le dépôt situé à chemin_depot. */ INT_ERR(svn_repos_open(&depot, chemin_depot, reservoir)); /* Obtient un pointeur sur l'objet du système de fichiers qui est * stocké dans CHEMIN_DEPOT. */ fs = svn_repos_fs(depot); /* Demande au système de fichiers de nous fournir le numéro de la * révision la plus récente. */ INT_ERR(svn_fs_youngest_rev(&derniere_rev, fs, reservoir)); /* Commence une nouvelle transaction qui est basée sur DERNIERE_REV. * Nous aurons moins de chance de voir notre propagation rejetée pour * cause de conflit si nous effectuons toujours nos changements à partir du * dernier instantané de l'arborescence du système de fichiers. */ INT_ERR(svn_repos_fs_begin_txn_for_commit2(&transaction, depot, derniere_rev, apr_hash_make(reservoir), reservoir)); /* Maintenant qu'une nouvelle transaction Subversion est commencée, * obtient l'objet racine qui représente cette transaction. */ INT_ERR(svn_fs_txn_root(&racine_transaction, transaction, reservoir)); /* Crée un nouveau répertoire sous la racine de la transaction, au * chemin NOUVEAU_REP. */ INT_ERR(svn_fs_make_dir(racine_transaction, nouveau_rep, reservoir)); /* Propage la transaction, créant une nouvelle révision du système de * fichiers incluant le nouveau répertoire. */ err = svn_repos_fs_commit_txn(&chaine_conflit, depot, &derniere_rev, transaction, reservoir); if (! err) { /* Pas d'erreur ? Excellent ! Indique brièvement la réussite * de l'opération. */ printf("Le répertoire '%s' a été ajouté en tant que nouvelle " "révision '%ld'.\n", nouveau_rep, derniere_rev); } else if (err->apr_err == SVN_ERR_FS_CONFLICT) { /* Oh-oh. La propagation a échoué pour cause de conflit (il semble * que quelqu'un d'autre a effectué des changements dans la même * zone du système de fichiers que celle que nous avons essayé de * modifier). Affiche un message d'erreur. */ printf("Un conflit s'est produit pour le chemin '%s' lors de" " l'ajout du répertoire '%s' au dépôt '%s'.\n", chaine_conflit, nouveau_rep, chemin_depot); } else { /* Une autre erreur s'est produite. Affiche un message d'erreur. */ printf("Une erreur s'est produite lors de l'ajout du " "répertoire '%s' au dépôt '%s'.\n", nouveau_rep, chemin_depot); } INT_ERR(err); }
Notez que dans l'Exemple 8.1, « Utilisation de la couche dépôt », le code aurait
tout aussi bien pu propager la transaction en utilisant
svn_fs_commit_txn()
. Mais l'API du système
de fichiers ignore tout des mécanismes de procédures
automatiques de la bibliothèque du dépôt. Si vous voulez que
votre dépôt Subversion effectue automatiquement certaines tâches
externes à Subversion chaque fois qu'une transaction est
propagée (par exemple envoyer un mail qui décrit les changements
effectués dans la transaction à la liste de diffusion des
développeurs), vous devez utiliser la version de la fonction
encapsulée dans libsvn_repos
qui ajoute la
fonctionnalité d'activation des procédures automatiques :
svn_repos_fs_commit_txn()
(pour davantage
d'informations sur les procédures automatiques des dépôts
Subversion, consultez la section intitulée « Mise en place des procédures automatiques »).
Maintenant, changeons de langage. L'Exemple 8.2, « Utilisation de la couche dépôt en Python » est un programme de démonstration qui utilise l'interface SWIG vers Python pour parcourir récursivement la dernière révision du dépôt et afficher les différents chemins trouvés lors de ce parcours.
Exemple 8.2. Utilisation de la couche dépôt en Python
#!/usr/bin/python """Parcourir un dépôt en affichant les chemins des objets suivis en versions.""" import sys import os.path import svn.fs, svn.core, svn.repos def parcourir_rep_systemedefichiers(racine, repertoire): """Parcourt récursivement le REPERTOIRE situé sous RACINE dans le système de fichiers. Renvoie la liste de tous les chemins sous et de REPERTOIRE.""" # Affiche le nom de ce chemin. print repertoire + "/" # Obtient les entrées du répertoire REPERTOIRE. entrees = svn.fs.svn_fs_dir_entries(racine, repertoire) # Pour chaque entrée noms = entrees.keys() for nom in noms: # Calcule le chemin complet de l'entrée. chemin_complet = repertoire + '/' + nom # Si l'entrée est un répertoire, effectue une récursion. La # récursion retournera une liste comprenant l'entrée et tous ses # enfants, que l'on ajoutera à notre liste. if svn.fs.svn_fs_is_dir(racine, chemin_complet): parcourir_rep_systemedefichiers(racine, chemin_complet) else: # Sinon, c'est un fichier donc l'afficher maintenant. print chemin_complet def parcourir_la_plus_recente_revision(chemin_depot): """Ouvre le dépôt situé à CHEMIN_DEPOT et effectue un parcours récursif de la révision la plus récente.""" # Ouvre le dépôt situé à CHEMIN_DEPOT et obtient une référence de # son système de fichiers suivi en versions. objet_depot = svn.repos.svn_repos_open(chemin_depot) objet_fs = svn.repos.svn_repos_fs(objet_depot) # Obtient la révision la plus récente (HEAD). rev_la_plus_recente = svn.fs.svn_fs_youngest_rev(objet_fs) # Ouvre un objet racine représentant la révision la plus récente. objet_racine = svn.fs.svn_fs_revision_root(objet_fs, rev_la_plus_recente) # Effectue le parcours récursif. parcourir_rep_systemedefichiers(objet_racine, "") if __name__ == "__main__": # Vérifie que l'on est appelé correctement. if len(sys.argv) != 2: sys.stderr.write("Usage: %s CHEMIN_DEPOT\n" % (os.path.basename(sys.argv[0]))) sys.exit(1) # Transforme la chaîne en chemin canonique. chemin_depot = svn.core.svn_path_canonicalize(sys.argv[1]) # Et c'est parti ! parcourir_la_plus_recente_revision(chemin_depot)
Le même programme en C aurait besoin de faire appel aux réservoirs de mémoire d'APR. Mais Python gère l'utilisation de la mémoire automatiquement et l'interface Subversion vers Python se plie à cette convention. En C, vous auriez utilisé des types de données personnalisés (tels que ceux fournis par la bibliothèque APR) pour représenter la table de hachage des entrées et la liste des chemins, mais Python sait gérer nativement les tables de hachage (appelés « dictionnaires ») ainsi que les listes et possède une riche collection de fonctions pour travailler sur ces types de données. C'est pourquoi SWIG (avec l'aide de la couche d'interface vers les langages de programmation de Subversion, un peu modifiée) prend soin de faire correspondre ces types de données personnalisés aux types de données natifs du langage cible. On obtient ainsi une interface plus intuitive pour les utilisateurs de ce langage.
L'interface de Subversion vers Python peut également être
utilisée pour effectuer des opérations dans la copie de travail.
Dans la section précédente de ce chapitre, nous avons mentionné
l'interface libsvn_client
et le fait
qu'elle a été conçue dans le seul but de faciliter l'écriture
d'un client Subversion. L'Exemple 8.3, « Une version de status en Python » est un court
exemple d'utilisation de cette bibliothèque via l'interface
Python SWIG pour re-créer une version à petite échelle de la
commande svn status.
Exemple 8.3. Une version de status en Python
#!/usr/bin/env python """Parcourir un répertoire d'une copie de travail en affichant les informations d'état.""" import sys import os.path import getopt import svn.core, svn.client, svn.wc def generer_code_etat(etat): """Traduit la valeur d'état vers un code à un caractère en utilisant la même logique que le client Subversion en ligne de commande.""" association_etat = { svn.wc.svn_wc_status_none : ' ', svn.wc.svn_wc_status_normal : ' ', svn.wc.svn_wc_status_added : 'A', svn.wc.svn_wc_status_missing : '!', svn.wc.svn_wc_status_incomplete : '!', svn.wc.svn_wc_status_deleted : 'D', svn.wc.svn_wc_status_replaced : 'R', svn.wc.svn_wc_status_modified : 'M', svn.wc.svn_wc_status_merged : 'G', svn.wc.svn_wc_status_conflicted : 'C', svn.wc.svn_wc_status_obstructed : '~', svn.wc.svn_wc_status_ignored : 'I', svn.wc.svn_wc_status_external : 'X', svn.wc.svn_wc_status_unversioned : '?', } return association_etat.get(etat, '?') def trouver_etat(chemin_copie_travail, verbeux): # Construit le "bâton" de contexte client. ctx = svn.client.svn_client_ctx_t() def _status_callback(path, etat): """Une fonction de renvoi ("callback") pour svn_client_status.""" # Affiche le chemin, moins la partie déjà présente # dans la racine du parcours. text_status = generer_code_etat(etat.text_status) prop_status = generer_code_etat(etat.prop_status) print '%s%s %s' % (text_status, prop_status, path) # Effectue le parcours des états, en utilisant _status_callback() # comme fonction de renvoi ("callback"). revision = svn.core.svn_opt_revision_t() revision.type = svn.core.svn_opt_revision_head svn.client.svn_client_status2(chemin_copie_travail, revision, _status_callback, svn.core.svn_depth_infinity, verbeux, 0, 0, 1, ctx) def utilisation_et_sortie(code_erreur): """Affiche le message d'utilisation et sort avec CODE_ERREUR.""" stream = code_erreur and sys.stderr or sys.stdout stream.write("""Usage: %s OPTIONS CHEMIN_COPIE_TRAVAIL Options: --help, -h : Affiche ce message d'aide. --verbose, -v : Affiche l'état de tous les objets, sans exception. """ % (os.path.basename(sys.argv[0]))) sys.exit(code_erreur) if __name__ == '__main__': # Analyse les options de la ligne de commande. try: opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose"]) except getopt.GetoptError: utilisation_et_sortie(1) verbeux = 0 for opt, arg in opts: if opt in ("-h", "--help"): utilisation_et_sortie(0) if opt in ("-v", "--verbeux"): verbeux = 1 if len(args) != 1: utilisation_et_sortie(2) # Transforme le chemin en chemin canonique. chemin_copie_travail = svn.core.svn_path_canonicalize(args[0]) # Et c'est parti ! try: trouver_etat(chemin_copie_travail, verbeux) except svn.core.SubversionException, e: sys.stderr.write("Erreur (%d): %s\n" % (e.apr_err, e.message)) sys.exit(1)
Comme dans le cas de l'Exemple 8.2, « Utilisation de la couche dépôt en Python », ce programme voit sa mémoire gérée automatiquement et utilise en grande partie les types de données classiques de Python.
Avertissement | |
---|---|
Rendez canoniques les chemins que vous fournit l'utilisateur
grâce aux fonctions |
Un point particulièrement intéressant pour les utilisateurs de
Python est que l'API Subversion implémente des fonctions de rappel
(callback functions en anglais).
Comme indiqué précédemment, l'API C Subversion fait une utilisation
libérale du paradigme des fonctions de rappel. Les fonctions de
l'API, qui acceptent en C une fonction et un bâton, n'acceptent
qu'une fonction de rappel comme paramètre en Python. Comment, dans
ce cas, l'appelant peut-il passer des informations de contexte à
la fonction de rappel ? En Python, il suffit de tirer parti des
règles de portée et des valeurs par défaut pour les paramètres. Vous
pouvez en voir un exemple dans l'Exemple 8.3, « Une version de status en Python ». La fonction
svn_client_status2()
reçoit une fonction de
rappel (_status_callback()
) mais pas de
bâton — _status_callback()
accède à
la chaine fournie par l'utilisateur parce que la recherche du nom de
variable échoue dans l'espace de noms de la fonction et bascule
automatiquement à l'espace de noms supérieur.
L'une des plus formidables caractéristiques de Subversion n'est pas accessible avec le client en ligne de commande ou via d'autres outils. C'est le fait que Subversion a été conçu pour être modulaire et fournir une API publique stable de manière à ce que des développeurs tiers — tel que vous, peut-être — puissent écrire des logiciels qui pilotent les fonctionnalités du cœur de Subversion.
Dans ce chapitre, nous avons approfondi notre vision de l'architecture de Subversion, examiné ses couches logiques et décrit son API publique, celle-là même qu'utilisent les propres couches de Subversion pour communiquer entre elles. De nombreux développeurs ont imaginé des utilisations intéressantes de l'API Subversion, de la simple procédure automatique jusqu'à des systèmes de gestion de versions complètement différents, en passant par l'intégration de Subversion dans d'autres applications. Et vous, quelle utilisation originale en tirerez-vous ?
[77] Nous comprenons que cela puisse être un choc énorme pour les amateurs de science-fiction, qui ont longtemps cru que le Temps était en fait la quatrième dimension. Nous nous excusons pour le traumatisme psychologique causé par l'affirmation de cette théorie divergente.
[78] Après tout, Subversion utilise aussi les API Subversion.
[79] Subversion utilise les appels système et les types de données ANSI autant que possible.
[80] Neon et Berkeley DB par exemple.
[81] La redistribution sous quelque forme que ce soit doit être accompagnée d'information sur la manière d'obtenir le code source complet du logiciel qui utilise SVNKit. Voir https://svnkit.com/license.html pour les détails.
svn est le client texte interactif officiel de Subversion. Ses fonctionnalités sont accessibles via un ensemble de sous-commandes dont la plupart acceptent plusieurs options pour contrôler très finement le comportement du programme.
Lorsque vous utilisez le programme svn, les sous-commandes et les paramètres qui ne sont pas des options doivent apparaître dans un ordre bien spécifié dans la ligne de commande. Les options, quant à elles, peuvent être indiquées n'importe où dans la ligne de commande (après le nom du programme, bien sûr) et, en général, leur ordre est sans importance. Par exemple, toutes les lignes de commandes qui suivent sont valides pour exécuter svn status et sont interprétées exactement de la même manière :
$ svn -vq status mon-fichier $ svn status -v -q mon-fichier $ svn -q status -v mon-fichier $ svn status -vq mon-fichier $ svn status mon-fichier -qv
Les sections qui suivent décrivent chaque sous-commande et les options correspondantes du client texte interactif svn, avec quelques exemples d'utilisations typiques pour chaque sous-commande.
Bien que Subversion accepte différentes options en fonction
des sous-commandes, toutes les options gardent leur
signification quelle que soit la sous-commande avec laquelle
elles sont utilisées — elles font partie d'un seul
« espace de noms ». Par exemple, l'option
--verbose
(-v
) signifie
toujours « être plus bavard », quelle que soit la
sous-commande utilisée.
Le client en ligne de commande svn renvoie généralement rapidement une erreur si vous lui indiquez une option qui ne s'applique pas à la sous-commande spécifiée. Cependant, depuis la version 1.5 de Subversion, plusieurs options sont acceptées par toutes (ou presque) les sous-commandes, même si elles n'ont pas d'effet dans certains cas (cette modification a été apportée principalement pour faciliter l'encapsulation du client dans des scripts). Elles sont regroupées dans la rubrique « options globales » des messages d'explication des commandes, comme vous pouvez le voir dans l'extrait de sortie suivant :
$ svn help upgrade upgrade: Mise à jour des meta-données du format de stockage de la copie de travail. usage : upgrade CHEMIN... Les modifications locales sont préservées. Options valides: -q [--quiet] : n'affiche rien, ou seulement des informations résumées Options globales : --username ARG : précise le nom d'utilisateur ARG --password ARG : précise le mot de passe ARG --no-auth-cache : ne conserve pas les éléments d'authentification --non-interactive : do no interactive prompting (default is to prompt only if standard input is a terminal device) --force-interactive : do interactive prompting even if standard input is not a terminal device --trust-server-cert : accepte les certificats serveur SSL d'authorités inconnues sans confirmation (mais seulement avec '--non-interactive') --config-dir ARG : fichiers de configuration dans ce répertoire --config-option ARG : configuration des options utilisateurs avec le format : FICHIER:SECTION:OPTION=[VALEUR] Par exemple : servers:global:http-library=serf $
Les sous-commandes svn reconnaissent les options suivantes :
Options de svn
--accept
ACTION
Précise l'attitude à adopter pour la résolution
automatique de conflits et désactive l'interface interactive qui
demande à l'utilisateur quelle action appliquer. Bien que les
actions possibles dépendent de la sous-commande utilisée,
Subversion accepte les valeurs suivantes (courtes et longues)
pour le paramètre ACTION
:
postpone
(p
)Ne rien résoudre du tout mais marquer les éléments comme étant en conflits.
edit
(e
)Ouvrir chaque fichier (au format texte) en conflit dans un éditeur de texte pour une résolution à la main.
launch
(l
)Lancer un outil interactif de résolution de conflits et de fusion pour chaque fichier en conflit.
base
Choisir le fichier de la révision
BASE
(non modifié) avant d'essayer d'y
intégrer les modifications en provenance du serveur pour
donner la copie de travail.
working
Choisir la version actuelle de la copie de travail (i.e. Subversion suppose que vous avez géré manuellement le conflit en amont).
mine-full
(mf
)Résoudre les fichiers en conflits en préservant toutes les modifications locales et en ignorant les modifications en provenance du serveur pour l'opération qui a créé le conflit.
theirs-full
(tf
)Résoudre les fichiers en conflits en ignorant toutes les modifications locales et en intégrant les modifications en provenance du serveur pour l'opération qui a créé le conflit.
mine-conflict
(mc
)Résoudre les fichiers en conflits en préférant les modifications locales par rapport aux modifications en provenance du serveur pour les régions des fichiers qui génèrent des conflits.
theirs-conflict
(tc
)Résoudre les fichiers en conflits en préférant les modifications en provenance du serveur par rapport aux modifications locales pour les régions des fichiers qui génèrent des conflits.
Consultez la sortie de svn help
SOUS-COMMANDE
pour voir
exactement quelles actions sont possibles pour chaque
sous-commande qui vous intéresse.
--allow-mixed-revisions
Désactiver la vérification (qui est faite par défaut par svn merge depuis Subversion 1.7) que la cible d'une opération de fusion et que tous ses fils concernent bien une révision unique. Bien que fusionner vers une copie de travail représentant une révision unique est une bonne pratique, cette option peut être utilisée pour autoriser des fusions sur des copies de travail à révisions mélangées si nécessaire.
--auto-props
Activer les propriétés automatiques (suivant les règles
définies dans la zone de configuration), remplaçant alors la
directive enable-auto-props
dans le fichier de
configuration config
.
--change
(-c
) ARG
Effectuer l'opération demandée en utilisant un
« changement » particulier. Cette option est du sucre
syntaxique pour spécifier
-r
.
Certaines sous-commandes autorisent une liste de numéros de
révisions séparés par des virgules comme argument (par exemple,
ARG-1
:ARG
-c
).
Autrement, vous pouvez fournir deux arguments séparés par un
tiret (comme dans ARG1
,ARG2
,ARG3
-c
)
pour identifier un intervalle de révisions entre
ARG1
-ARG2
ARG1
et
ARG2
inclus. Enfin, si le numéro de
révision en argument est négatif, cela veut dire que l'intervalle
de révision doit être pris à l'envers : -c
-45
est équivalent à -r
45:44
.
--changelist
(--cl
) ARG
N'opérer que sur les membres de la liste de changements
nomméeARG
. Vous pouvez utiliser cette
option plusieurs fois pour spécifier un ensemble de listes de
changements.
--config-dir
DIR
Lire la configuration dans le répertoire spécifié plutôt qu'à
l'endroit par défaut (.subversion
dans le
répertoire de l'utilisateur).
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--config-option
CONFSPEC
Définir, pour la durée de la commande, la valeur d'une option
de configuration. CONFSPEC
est une
chaine qui spécifie l'espace de noms, le nom et la valeur de
l'option de configuration que vous voulez assigner, sous la forme
FICHIER
:SECTION
:OPTION
=[VALEUR
].
Dans cette syntaxe, FICHIER
et
SECTION
représentent le fichier de la
zone de configuration (soit config
, soit
servers
) et la section qui contient l'option
dont vous voulez définir la valeur.
OPTION
est, bien sûr, l'option
elle-même et VALEUR
est la valeur
(s'il y en a une) que vous voulez assigner à cette option. Par
exemple, pour désactiver temporairement l'utilisation de la
compression dans le protocole HTTP , utilisez
--config-option=servers:global:http-compression=no
.
Vous pouvez utiliser cette option plusieurs fois pour changer
plusieurs valeurs d'options pour la commande en cours.
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--depth
ARG
Limiter l'opération à une certaine profondeur de
l'arborescence. ARG
peut prendre les
valeurs suivantes :
empty
(uniquement la cible elle-même),
files
(la cible et tous ses fichiers qui sont
enfants immédiats),
immediates
(la cible et tous ses enfants
immédiats),
infinity
(la cible et tous ses descendants
— la récursion est complète).
--diff
Activer un mode spécial pour l'affichage de svn log qui inclut l'analyse des différences (comme svn diff) pour chaque révision.
--diff-cmd
CMD
Utiliser un programme externe pour afficher les différences
entre fichiers. Quand svn diff est invoquée
sans cette option, elle utilise le moteur interne de Subversion
qui fournit un format unifié par défaut. Si vous voulez utiliser
un programme externe, ajoutez l'option
--diff-cmd
. Vous pouvez spécifier des options à
ce programme externe à l'aide de l'option
--extensions
(-x
.
--diff3-cmd
CMD
Spécifie une commande externe pour réaliser la comparaison entre 3 fichiers (utilisé pour fusionner les modifications ligne à ligne des fichiers).
--dry-run
Effectuer toutes les étapes de la commande, mais sans écrire effectivement les changements — que ce soit sur le disque local ou sur le dépôt.
--editor-cmd
CMD
Spécifie un programme externe pour éditer l'entrée du
journal de propagation ou une valeur de propriété. Voir la
section editor-cmd
dans la section intitulée « Configuration générale » pour savoir
comment spécifier un éditeur par défaut.
--encoding
ENC
L'entrée du journal de propagation est encodée avec le jeu de caractères ENC. La valeur par défaut est l'encodage utilisé par votre système d'exploitation conformément à la régionalisation active. Vous devez spécifier explicitement l'encodage si votre entrée du journal de propagation utilise un autre encodage que la valeur par défaut.
--extensions
(-x
) ARG
Spécifie un ou plusieurs arguments à passer à la commande diff externe. Les valeurs possibles sont :
--ignore-space-change
(-b
)Ignorer les modifications relatives aux espaces.
--ignore-all-space
(-w
)Ignorer tous les espaces.
--ignore-eol-style
Ignorer les modifications de caractère de fin de ligne (EOL).
--show-c-function
(-p
)Imprimer le nom de la fonction C dans l'affichage des différences.
--unified
(-u
)Afficher trois lignes de contexte pour le diff unifié.
La valeur par défaut de ARG
est -u
. Si vous voulez passez plusieurs
arguments, vous devez les encapsuler dans des guillemets.
Notez que si Subversion est configuré pour invoquer un
programme externe pour les différence, la valeur de l'option
--extensions
(-x
) n'est pas
restreinte aux paramètres cités
supra, mais peut être constituée
de tout argument que Subversion passera à
ce programme externe.
--file
(-F
) NOM_FICHIER
Utiliser le contenu du fichier NOM_FICHIER pour la commande spécifiée, le traitement exact variant suivant les sous-commandes. Par exemple, svn commit utilise le contenu comme entrée du journal de propagation alors que svn propset l'utilise comme valeur de la propriété.
--force
Force l'exécution de l'opération. Subversion interdit certaines opérations en temps normal mais vous pouvez passer outre et indiquer à Subversion : « oui, je sais ce que je fais et les conséquences que cela peut avoir, alors laisse-moi faire ». En utilisant une métaphore, on pourrait dire que cela revient à travailler sur un circuit électrique sous tension ; si vous ne savez pas ce que vous faites, vous prendrez sûrement une bonne décharge.
--force-log
Valide la source de l'entrée du journal de propagation
passée avec l'option --message
(-m
) ou --file
(-F
). Par défaut, Subversion renvoie une erreur
si les paramètres de ces options ressemblent à des cibles de la
sous-commande. Par exemple, si vous passez le chemin d'un fichier
suivi en versions à l'option --file
(-F
), Subversion considère que vous avez fait
une erreur, c'est-à-dire que le chemin indiqué devait plutôt être
la cible de la commande et que vous avez oublié de fournir le nom
d'un fichier — non suivi en versions — comme source
pour l'entrée du journal de propagation. Pour confirmer votre
intention et passer outre cette erreur, passez l'option
--force-log
aux sous-commandes qui prennent des
entrées du journal de propagation comme arguments.
--force-interactive
Forces the svn command-line client to run in interactive mode when standard input is not a terminal device.
Note | |
---|---|
This option is accepted by all svn subcommands. |
--git
Activer un mode d'affichage spécial pour la commande svn diff, destiné à assurer la compatibilité avec le système de gestion de versions Git.
--help
(-h
, -?
)Si elle est utilisée avec une ou plusieurs autres sous-commandes, affiche l'aide intégrée pour chacune d'elles. Utilisée seule, elle affiche l'aide générale relative au client texte interactif.
--ignore-ancestry
Ignorer l'héritage pour évaluer les différences (ne se fier qu'au chemin en tant que tel). Désactiver aussi Suivi de fusions lorsque elle est utilisée avec la sous-commande svn merge.
--ignore-externals
Ignorer les définitions de références externes ainsi que les copies de travail associées.
--ignore-keywords
Désactiver la substitution des mots-clés.
--ignore-properties
Ordonne à svn diff de ne pas afficher ce qui concerne la modification des propriétés.
--ignore-whitespace
Ordonne à svn patch d'ignorer les espaces quand il recherche le contexte d'un correctif.
--incremental
Produire un affichage avec un format compatible pour la concaténation.
--internal-diff
Utiliser le moteur interne de calcul des différences même si un programme externe est spécifié dans la zone de configuration de l'utilisateur.
--keep-changelists
Ne pas détruire les listes de changements après la propagation.
--keep-local
Garder une copie locale d'un fichier ou répertoire (utilisée avec la commande svn delete).
--limit
(-l
) NUM
Afficher seulement les NUM
premières entrées du journal de propagation.
--message
(-m
) MESSAGE
Indique que vous spécifiez, sur la ligne de commande à la suite de cette option, soit une entrée du journal de propagation, soit un commentaire de verrouillage. Par exemple :
$ svn commit -m "Ils ne font pas de glace."
--native-eol
ARG
Ordonne à svn export d'utiliser la
séquence de fin de ligne spécifiée comme si c'était celle en
vigueur sur la plateforme cliente. ARG
peut prendre les valeurs CR
,
LF
ou CRLF
.
--new
ARG
Utiliser ARG
comme nouvelle cible
(à utiliser avec la commande svn diff).
--no-auth-cache
Ne pas stocker en cache les éléments d'authentification (par exemple l'identifiant et le mot de passe) dans la zone de configuration de Subversion.
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--no-auto-props
Désactiver les propriétés automatiques, remplaçant alors la
directive enable-auto-props
de la
zone de configuration.
--no-diff-added
Ne pas afficher les différences pour les fichiers ajoutés. Le comportement par défaut lorsque vous ajoutez un fichier est d'afficher les différences comme si vous aviez ajouté tout le contenu du fichier à un fichier initialement vide.
--no-diff-deleted
Ne pas afficher les différences pour les fichiers supprimés. Le comportement par défaut de svn diff est d'afficher les différences comme si vous aviez toujours le fichier et que celui-ci était vide.
--no-ignore
Afficher les fichiers qui seraient normalement omis dans la
liste de statut en raison de la correspondance avec un motif de
noms de fichiers présent dans l'option de configuration
global-ignores
ou dans la propriété
svn:ignore
. Voir la section intitulée « Configuration générale » et la section intitulée « Occultation des éléments non suivis en versions » pour plus
d'information.
--no-unlock
Ne pas déverrouiller les fichiers : le comportement par défaut de la propagation (svn commit) est de déverrouiller tous les fichiers propagés. Voir la section intitulée « Verrouillage » pour plus d'information.
--non-interactive
Désactiver toutes les invites, par exemple les demandes pour l'authentification et la résolution de conflits. Cette option est utile si vous lancez Subversion dans un script automatique et qu'il est préférable que Subversion s'arrête plutôt qu'il n'attende une entrée de l'utilisateur.
Beginning with Subversion 1.8, the svn
command-line client, by default, is non-interactive when standard
input is not a terminal device. Pass the
--force-interactive
option to make the client run
in interactive mode.
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--non-recursive
(-N
)Obsolète. Interdire à une
sous-commande de descendre dans les sous-répertoires. La plupart
des sous-commandes descendent par défaut dans les sous-répertoires
(comportement récursif), mais quelques unes ne le font pas. Les
utilisateurs ne devraient pas utiliser cette option mais plutôt
celle plus précise --depth
. Pour la plupart des
sous-commandes, spécifier l'option
--non-recursive
produit le même résultat que
--depth=files
mais il existe des
exceptions : svn status en mode non
récursif opère à la profondeur immediates
et
la forme non récursive de svn revert,
svn add et svn commit
opèrent à la profondeur empty
.
--notice-ancestry
Prendre en compte l'héritage pour évaluer les différences.
--old
ARG
Utiliser ARG
comme ancien
répertoire (utilisée avec la commande svn
diff).
--parents
Créer (s'ils n'existent pas) et ajouter (s'ils ne sont pas suivis en versions) les répertoires parents à une copie de travail locale ou à un dépôt dans le cadre d'une opération. Cette option est particulièrement utile pour créer automatiquement plusieurs répertoires quand aucun n'existe. Si elle concerne une URL, tous les répertoires seront créés par une seule et même propagation.
--password
MOT_DE_PASSE
Spécifie le mot de passe à utiliser pour s'authentifier auprès d'un serveur Subversion. Si le mot de passe n'est pas fourni ou s'il est incorrect, Subversion vous demandera cette information quand il en aura besoin.
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--patch-compatible
Ordonne à svn diff de produire un
affichage compatible avec les outils tiers d'application de
correctifs. Vous obtenez avec cette option le même résultat que
lorsque vous lancez svn diff avec les options
--show-copies-as-adds
--ignore-properties
.
--properties-only
N'afficher que les modifications de propriétés avec svn diff.
--quiet
(-q
)N'afficher que ce qui est essentiel pendant une opération.
--record-only
Avec svn merge, enregistrer l'opération comme effectuée dans l'historique mais ne rien faire.
--recursive
(-R
)Rendre la sous-commande récursive dans les sous-répertoires. Beaucoup de sous-commandes sont récursives par défaut.
--reintegrate
Obsolète. Utilisée avec la sous-commande svn merge, fusionner tous les changements de la branche spécifique dans sa branche ancêtre. Depuis Subversion 1.8, la sous-commande svn merge détecte automatiquement ce cas et effectue la fusion correctement. Voir la section intitulée « Réintegration d'une branche » pour plus de détails.
--relocate
Obsolète. Utilisée avec la sous-commande svn switch, changer l'emplacement du dépôt auquel votre copie de travail fait référence. L'approche conseillée depuis Subversion 1.7 consiste à utiliser la sous-commande svn relocate. Voir svn relocate pour plus de détails et un exemple.
--remove
Utilisée avec svn changelist pour effacer l'association (l'opération par défaut effectue l'association) entre la (ou les) cible(s) et une liste de changements.
--reverse-diff
Ordonne à svn patch d'interpréter à l'envers le correctif fourni en entrée (traiter les lignes supprimées comme ajoutées et réciproquement).
--revision
(-r
) REV
Indique que vous allez fournir une révision (ou un intervalle
de révisions) pour une opération particulière. Vous pouvez
fournir des numéros de révisions, des mots-clés de révision ou
des dates (encadrées par des accolades) comme arguments à
l'option revision
. Si vous voulez spécifier un
intervalle de révisions, vous devez fournir deux révisions
séparées par le symbole deux points (:
). Par
exemple :
$ svn log -r 1729 $ svn log -r 1729:HEAD $ svn log -r 1729:1744 $ svn log -r {2001-12-04}:{2002-02-17} $ svn log -r 1729:{2002-02-17}
Voir la section intitulée « Mots-clés de révision » pour plus d'informations.
--revprop
Opérer sur une propriété de révision au lieu d'une propriété
de fichier ou de dossier. Cette option requiert de passer aussi
une révision en paramètre à l'option --revision
(-r
).
--search
ARG
Filtrer les commentaires de propagation pour ne montre que
ceux qui correspondent au motif ARG
recherché. Les commentaires de propagation ne sont affichés que
si les motifs recherchés correspondent pour l'auteur, la date ou
le commentaire de propagation lui-même (à moins que l'option
--quiet
ne soit spécifiée) ou, si l'option
--verbose
est aussi spécifiée, un chemin
modifié. Si plusieurs options --search
sont
spécifiées, un commentaire de propagation est affiché s'il
correspond à au moins un motif. Si l'option
--limit
est utilisée, la recherche est limitée
dans le nombre de commentaires et ce n'est pas le nombre de
commentaires affichés (et donc qui correspondent) qui est
limité.
Le motif de recherche (appelé glob ou motif de filtrage du shell) peut contenir des caractères normaux et les caractères spéciaux suivants :
?
Correspond à n'importe quel caractère unique.
*
Correspond à n'importe quelle chaîne de caractères, y compris la chaîne vide.
[ABC]
Correspond à n'importe quel caractère qui figure à l'intérieur des crochets.
--search-and
ARG
L'argument de cette option est combiné avec le motif de
l'option précédente --search
ou
--search-and
de la ligne de commande. Les
commentaires de propagation ne sont affichés que s'ils
correspondent à la combinaison des motifs recherchés.
--set-depth
ARG
Fixer (de manière permanente) la profondeur de la copie de
travail à partir de ce répertoire à l'une des valeurs
suivantes : empty
,
files
, immediates
ou
infinity
. Pour une explication détaillée de
ce que cela signifie et sur l'utilisation de cette option,
reportez-vous à la section intitulée « Répertoires clairsemés ».
--show-copies-as-adds
Activer un mode de sortie spécial pour svn diff dans lequel la différence de contenu pour un fichier créé par une opération de copie apparaît comme un fichier nouveau (où chaque ligne a été ajoutée à un fichier vide) plutôt que comme un delta vis-à-vis du fichier original à partir duquel la copie a été faite.
--show-inherited-props
Ordonne à svn propget et svn proplist d'afficher les propriétés suivies en versions héritées par le fichier ou dossier cible.
--show-revs
ARG
Utilisée pour indiquer à svn mergeinfo de
n'afficher qu'une certaine classe des informations de fusions.
ARG
peut prendre les valeurs
merged
ou eligible
, pour
indiquer de voir les révisions soit déjà fusionnées, soit
éligibles à une future fusion depuis l'URL source
spécifiée.
--show-updates
(-u
)Afficher les informations relatives aux fichiers de la copie de travail qui ne sont plus à jour. Cela ne met pas à jour les fichiers — cela ne fait qu'afficher le nom des fichiers qui seront mis à jour lors de la prochaine commande svn update.
--stop-on-copy
Indique à une sous-commande Subversion qui parcourt l'héritage d'une ressource suivie en versions de s'arrêter lorsque une copie — c'est-à-dire un emplacement dans l'héritage où la ressource a été copiée depuis un autre endroit dans le dépôt — est trouvée.
--strict
Utiliser une sémantique stricte, notion plutôt vague sauf pour certaines sous-commandes spécifiques (pour ne pas la citer, svn propget).
--strip
NUM
Utilisé avec svn patch pour ignorer les
NUM
premiers composants des chemins
trouvés dans le fichier correctif en entrée.
--summarize
Afficher seulement les notifications de haut-niveau sur l'opération en cours et oublier les détails.
--targets
NOM_FICHIER
Prendre la liste de fichiers cibles pour l'opération dans le
fichier NOM_FICHIER
au lieu de prendre
les fichiers fournis dans la ligne de commande.
NOM_FICHIER
doit contenir un chemin
par ligne et chaque chemin doit suivre le même encodage et
formatage que s'il avait été fourni directement en argument de la
ligne de commande.
--trust-server-cert
Lorsqu'elle est utilisée avec
--non-interactive
, ordonne à Subversion
d'accepter les certificats SSL serveurs signés par des autorités
inconnues sans en informer l'utilisateur. Pour des raisons de
sécurité, vous ne devriez utiliser cette option que lorsque vous
êtes certain de l'intégrité du serveur distant et du
réseau.
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--use-merge-history
(-g
)Utiliser ou afficher des informations supplémentaires sur l'historique de la fusion.
--username
IDENTIFIANT
Spécifie l'identifiant (ou nom d'utilisateur) à utiliser pour s'authentifier auprès d'un serveur Subversion. S'il n'est pas fourni ou s'il est incorrect, Subversion vous demandera cette information quand il en aura besoin.
Note | |
---|---|
Cette option est acceptée par toutes les sous-commandes svn. |
--verbose
(-v
)Afficher autant d'informations que possible durant l'exécution de la sous-commande. Cela se traduit par l'affichage de champs supplémentaires, d'informations détaillées à propos de chaque fichier ou d'informations complémentaires relatives aux actions menées.
--version
Afficher les informations sur la version du client. Ces
informations comprennent le numéro de version du client ainsi que
la liste de tous les modules d'accès à un dépôt disponibles. Avec
l'option --quiet
(-q
), elle ne
fait qu'afficher le numéro de version dans un format
compact.
--with-all-revprops
Utilisée avec l'option --xml
de
svn log, récupèrer et afficher toutes les
propriétés de révisions (les propriétés standards utilisées par
Subversion mais aussi celles définies par l'utilisateur).
--with-no-revprops
Utilisée avec l'option --xml
de
svn log, ne pas afficher les propriétés de
révisions (y compris le commentaire de propagation, l'auteur et la
date de révision) dans le flux de sortie.
--with-revprop
ARG
Quand elle est utilisée avec une commande qui écrit dans le
dépôt, fixer une propriété de révision, en utilisant le format
NOM=VALEUR
, en affectant
VALEUR
à
NOM
. Quand elle est utilisée avec
svn log dans le mode --xml
,
afficher la valeur de ARG
.
--xml
Produire un affichage au format XML. Les schémas XML pour
cet affichage (au format RELAX NG) sont contenus dans le dossier
subversion/svn/schema/
du code source de
Subversion.
svn add — Ajouter des fichiers, répertoires et liens symboliques.
svn add CHEMIN...
Prévoir l'ajout au dépôt des fichiers, répertoires et liens symboliques de la copie de travail. Ils seront transférés et ajoutés au dépôt lors de la prochaine propagation. Si vous ajoutez quelque chose et que vous changez d'avis avant de faire une propagation, vous pouvez annuler l'ajout en utilisant svn revert.
Pour ajouter un fichier à votre copie de travail :
$ svn add truc.c A truc.c
Lors de l'ajout d'un répertoire, le comportement par défaut de svn add est récursif :
$ svn add rep-test A rep-test A rep-test/a A rep-test/b A rep-test/c A rep-test/d
Vous pouvez ajouter un répertoire sans inclure son contenu :
$ svn add --depth=empty autre-rep A autre-rep
Si vous essayez d'ajouter un élément qui est déjà suivi en
versions, la commande échoue. Ce comportement déjoue le cas le plus
fréquent où un utilisateur veut inclure dans Subversion tous les
dossiers et éléments non suivis en versions dans une arborescence
partiellement suivie en versions. Pour passer outre ce comportement
par défaut et forcer Subversion à explorer récursivement tous les
dossiers, même ceux déjà suivis en versions, passez l'option
--force
:
$ svn add rep-suivi svn: avertissement W150002 : '/home/cmpilato/projets/subversion/site' est déjà sous gestionnaire de version svn: E200009: Impossible d'ajouter toutes les cibles car certaines sont déjà versionnées svn: E200009: Cible illégale pour l'opération demandée $ svn add rep-suivi --force A rep-suivi/machin.c A rep-suivi/un-rep/bidule.c A (bin) rep-suivi/autre-rep/docs/truc.doc …
svn blame (praise, annotate, ann) — Afficher les informations de révisions et d'auteurs en plus du contenu pour les fichiers ou URL spécifiés.
svn blame CIBLE[@REV]...
Afficher les informations de révisions et d'auteur en plus du contenu pour les fichiers ou URL spécifiés. Chaque ligne de texte est annotée en début par l'identifiant de l'auteur et le numéro de révision pour le dernier changement correspondant à la ligne.
Si vous voulez voir les auteurs de chaque ligne de votre fichier
source lisezmoi.txt
de votre dépôt
test :
$ svn blame http://svn.red-bean.com/depot/test/lisezmoi.txt 3 sally Ceci est un fichier LISEZMOI. 5 harry Pas la peine de le lire, le patron est marteau. 3 sally …
Même si svn blame dit que c'est Harry qui a
modifié le fichier lisezmoi.txt
dans la
révision 5, comprenez bien que cette sous-commande est très
tatillonne sur la définition de modification. Avant de taper sur
Harry pour insubordination, prenez en compte qu'il n'a peut-être
effectué que des modifications de forme et qu'il n'a pas touché à la
sémantique du fichier. Peut-être n'a-t-il que lancé un script qui
supprime les espaces inutiles en fin de lignes. Vous devez examiner
finement les changements apportés et le commentaire de propagation
pour comprendre exactement ce que Harry a modifié dans ce fichier
lors de la révision 5.
$ svn log -c 5 http://svn.red-bean.com/depot/test/lisezmoi.txt -------------------------------------------------------------------- r5 | harry | 2008-05-29 07:26:12 -0600 (Thu, 29 May 2008) | 1 ligne Propage les résultats de 'double-espace-après-virgule.sh'. -------------------------------------------------------------------- $ svn diff -c 5 http://svn.red-bean.com/depot/test/lisezmoi.txt Index: http://svn.red-bean.com/depot/test/lisezmoi.txt =================================================================== --- http://svn.red-bean.com/depot/test/lisezmoi.txt (revision 4) +++ http://svn.red-bean.com/depot/test/lisezmoi.txt (revision 5) @@ -1,5 +1,5 @@ Ceci est un fichier LISEZMOI. -Pas la peine de le lire, le patron est marteau. +Pas la peine de le lire, le patron est marteau. INSTRUCTIONS ============ $
Effectivement, Harry n'a fait que modifier les espaces de cette
ligne. Heureusement, l'option --extensions
(-x
) peut vous aider à déterminer la dernière
modification utile pour une ligne de texte. Par
exemple, voici comment visualiser les informations de journalisation
tout en omettant les modifications relatives aux
espaces ::
$ svn blame -x -b http://svn.red-bean.com/depot/test/lisezmoi.txt 3 sally Ceci est un fichier LISEZMOI. 4 jess Pas la peine de le lire, le patron est marteau. 3 sally …
Si vous utilisez l'option --xml
, vous obtenez
une sortie XML décrivant les informations de journalisation mais
pas le contenu des lignes elles-mêmes :
$ svn blame --xml http://svn.red-bean.com/depot/test/lisezmoi.txt <?xml version="1.0"?> <blame> <target path="lisezmoi.txt"> <entry line-number="1"> <commit revision="3"> <author>sally</author> <date>2008-05-25T19:12:31.428953Z</date> </commit> </entry> <entry line-number="2"> <commit revision="5"> <author>harry</author> <date>2008-05-29T13:26:12.293121Z</date> </commit> </entry> <entry line-number="3"> … </entry> </target> </blame> $
svn cat — Afficher le contenu des fichiers ou URL spécifiés.
svn cat CIBLE[@REV]...
Afficher le contenu des fichiers ou URL spécifiés. Pour afficher la liste du contenu des répertoires, voir svn list plus loin dans ce chapitre.
Si vous voulez voir le contenu de
lisezmoi.txt
dans votre dépôt sans pour autant
l'extraire dans votre copie de travail :
$ svn cat http://svn.red-bean.com/depot/test/lisezmoi.txt Ceci est un fichier LISEZMOI. Pas la peine de le lire, le patron est marteau. INSTRUCTIONS ============ Step 1: Faire ci. Step 2: Faire ça. $
Vous pouvez aussi afficher une version spécifique des fichiers.
$ svn cat -r 3 http://svn.red-bean.com/depot/test/lisezmoi.txt Ceci est un fichier LISEZMOI. INSTRUCTIONS ============ Step 1: Faire ci. Step 2: Faire ça. $
Note | |
---|---|
Vous développerez peut-être un réflexe à utiliser svn
cat pour visualiser le contenu de vos fichiers de
travail. Mais gardez à l'esprit que la révision pivot pour
svn cat sur la copie de travail est
|
Astuce | |
---|---|
Si votre copie de travail est obsolète (ou si vous avez des
modifications locales) et que vous voulez voir la révision
|
svn changelist (cl) — Associer (ou dissocier) des fichiers d'une liste de changements.
changelist NOM_CL CIBLE...
changelist --remove CIBLE...
Utilisée pour répartir les fichiers d'une copie de travail dans des listes de changements (groupes logiques dotés d'un nom) dans le but de faciliter le travail de l'utilisateur travaillant sur plusieurs ensembles de fichiers dans une seule copie de travail.
Editer trois fichiers et les ajouter à une liste de changements. Puis propager uniquement les fichiers associés à cette liste de changements :
$ svn changelist pb1729 machin.c bidule.c truc.c A [pb1729] machin.c A [pb1729] bidule.c A [pb1729] truc.c $ svn status A un-autre-fichier.c A test/un-test.c --- Liste de changements 'pb1729' : A machin.c A bidule.c A truc.c $ svn commit --changelist pb1729 -m "Règle le problème 1729." Envoi bidule.c Envoi truc.c Envoi machin.c Transmission des données . Révision 2 propagée. $ svn status A un-autre-fichier.c A test/un-test.c
Notez que seuls les fichiers associés à la liste de changements
pb1729
ont été propagés.
svn checkout (co) — Extraire une copie de travail à partir d'un dépôt.
svn checkout URL[@REV]... [CHEMIN]
Extraire une copie de travail à partir d'un dépôt. Si
CHEMIN
n'est pas spécifié, le nom de
fichier de l'URL (basename) est
utilisé comme destination. Si plusieurs URL sont fournies, chacune
est extraite dans un sous-répertoire de
CHEMIN
, avec comme nom de sous-répertoire
le nom de fichier de l'URL.
Extraire une copie de travail dans le répertoire
mien
:
$ svn checkout file:///var/svn/depot/test mien A mien/a A mien/b A mien/c A mien/d Révision 20 extraite. $ ls mien
Extraire deux répertoires différents vers deux copies de travail séparées :
$ svn checkout file:///var/svn/depot/test \ file:///var/svn/depot/quizz A test/a A test/b A test/c A test/d Révision 20 extraite. A quizz/l A quizz/m Révision 13 extraite. $ ls quizz test
Extraire deux répertoires différents vers deux copies de travail
séparées, mais les place toutes les deux dans un répertoire appelé
copies-de-travail
:
$ svn checkout file:///var/svn/depot/test \ file:///var/svn/depot/quiz \ copies-de-travail A copies-de-travail/test/a A copies-de-travail/test/b A copies-de-travail/test/c A copies-de-travail/test/d Révision 20 extraite. A copies-de-travail/quizz/l A copies-de-travail/quizz/m Révision 13 extraite. $ ls copies-de-travail
Si vous interrompez l'extraction (ou si n'importe quoi interromp l'extraction, comme la perte du réseau par exemple), vous pouvez recommencer l'extraction en invoquant exactement la même commande ou en mettant à jour la copie incomplète :
$ svn checkout file:///var/svn/depot/test mien A mien/a A mien/b ^C svn: E200015: Signal capté $ svn checkout file:///var/svn/depot/test mien A mien/c ^C svn: E200015: Signal capté $ svn update mien A mien/d Révision 20 extraite. $
Si vous voulez extraire une révision qui n'est pas la plus
récente, vous pouvez le faire à l'aide de l'option
--revision
(-r
) de la commande
svn checkout :
$ svn checkout -r 2 file:///var/svn/depot/test mien A mien/a Révision 2 extraite. $
Avant la version 1.7, Subversion se plaignait par défaut si vous
essayiez d'extraire un dossier au-dessus d'un dossier existant qui
contenait des fichiers ou des sous-dossiers que l'extraction
elle-même aurait créés. Subversion 1.7 se comporte différemment, en
autorisant l'extraction mais en marquant tous les objets bloquants
en conflit. Utilisez l'option --force
pour
outrepasser cette protection. Quand vous faites une extraction avec
l'option --force
, tout fichier non suivi en versions
dans l'arborescence cible qui bloquerait l'extraction sera placé en
suivi en versions, mais avec son contenu actuel tel quel. Si ce
contenu n'est pas celui du fichier du dépôt (qui a été téléchargé
dans le cadre de l'extraction), le fichier apparaît comme ayant des
modifications locales (les différences entre la version suivie en
version extraite du dépôt et la version non suivie en versions que
vous aviez avant l'extraction) une fois l'extraction terminée.
$ mkdir projet $ mkdir projet/lib $ touch projet/lib/fichier.c $ svn checkout file:///var/svn/depot/projet/trunk projet svn: Failed to add directory 'projet/lib': an unversioned directory of the sa me name already exists $ svn checkout file:///var/svn/depot/projet/trunk projet --force E project/lib A project/lib/sous-rep E project/lib/fichier.c A project/lib/autre-fichier.c A project/include/header.h Révision 21 extraite. $ svn status wc M project/lib/fichier.c $ svn diff wc Index: project/lib/fichier.c =================================================================== --- project/lib/fichier.c (revision 1) +++ project/lib/fichier.c (working copy) @@ -3 +0,0 @@ -/* fichier.c: Code pour agir fichier-ment. */ -#include <stdio.h> -/* Pas très productif aujourd'hui */ $
Comme dans toute autre copie de travail, vous avez les mêmes choix possibles : annuler toutes ou certaines des « modifications » locales, les propager ou continuer à travailler sur votre copie de travail.
Cette fonctionnalité est particulièrement utile pour effectuer
des imports « sur place » d'arborescences non suivies en
versions. En commençant par importer l'arborescence dans le dépôt,
puis en faisant une extraction du nouveau dépôt par dessus
l'arborescence non suivie en versions avec l'option
--force
, vous transformez effectivement
l'arborescence non suivie en versions en copie de travail.
$ svn mkdir -m "Créer la racine de nouveau-projet." \ file://var/svn/depot/nouveau-projet $ svn import -m "Import initial du code source de nouveau-projet." \ nouveau-projet \ file://var/svn/depot/nouveau-projet/trunk Ajout nouveau-projet/include Ajout nouveau-projet/include/nouveau-projet.h Ajout nouveau-projet/lib Ajout nouveau-projet/lib/helpers.c Ajout nouveau-projet/lib/base.c Ajout nouveau-projet/notes Ajout nouveau-projet/notes/LISEZMOI Révision 22 propagée. $ svn checkout file://`pwd`/depot-1.6/nouveau-projet/trunk nouveau-projet --force E nouveau-projet/include E nouveau-projet/include/nouveau-projet.h E nouveau-projet/lib E nouveau-projet/lib/helpers.c E nouveau-projet/lib/base.c E nouveau-projet/notes E nouveau-projet/notes/LISEZMOI Révision 2 extraite. $ svn status nouveau-projet $
svn cleanup — Nettoyer récursivement la copie de travail.
svn cleanup [CHEMIN...]
Nettoyer récursivement la copie de travail en enlevant les
verrous et en reprenant les opérations en cours. Si jamais vous
obtenez une erreur copie de travail verrouillée
lancez cette commande pour supprimer les verrous et remettre votre
copie de travail dans un état utilsable.
Si, pour quelque raison que ce soit, une commande svn
update échoue suite à un problème de programme diff externe
(par exemple en raison d'une entrée utilisateur incorrecte ou d'un
problème réseau), passez l'option --diff3-cmd
pour
autoriser cleanup à terminer l'opération de fusion
avec votre programme diff externe. Vous pouvez aussi spécifier un
répertoire de configuration particulier avec l'option
--config-dir
, mais vous ne devriez avoir à utiliser
ces options qu'extrêmement rarement.
svn commit (ci) — Envoyer les modifications de la copie de travail vers le dépôt.
svn commit [CHEMIN...]
Envoyer les modifications de la copie de travail vers le dépôt.
Si vous ne fournissez pas d'entrée du journal avec votre propagation
en utilisant soit l'option --file
, soit l'option
--message
, svn lance votre
éditeur de texte pour que vous en rédigiez une. Lisez le paragraphe
relatif à la liste editor-cmd
dans la section intitulée « Configuration générale ».
svn commit propage tous les jetons de
verrouillage qu'il trouve et déverrouille tous les verrous sur les
CHEMIN
s propagés (récursivement) à moins
que l'option --no-unlock
ne soit spécifiée.
Astuce | |
---|---|
Si vous commencez une propagation et que subversion lance votre éditeur de texte pour rédiger l'entrée du journal de propagation, vous pouvez toujours abandonner la propagation. Si vous voulez l'abandonner, quitter simplement l'éditeur sans sauvegarder le commentaire de propagation ; Subversion vous demande alors si vous voulez abandonner, continuer sans rien écrire dans le journal de propagation ou éditer à nouveau le commentaire. |
Propager une simple modification sur un fichier avec l'entrée du
journal de propagation indiquée dans la ligne de commande et la cible
implicite étant le répertoire courant
(« .
») :
$ svn commit -m "ajout de la Foire Aux Questions." Envoi a Transmission des données . Révision 3 propagée.
Propager une modification sur le fichier
machin.c
(spécifié explicitement sur la ligne de
commande) avec l'entrée du journal de propagation dans le fichier
nommé msg
:
$ svn commit -F msg machin.c Envoi machin.c Transmission des données . Révision 5 propagée.
Si vous voulez utiliser un fichier suivi en versions pour votre
entrée du journal de propagation avec l'option
--file
, vous devez également spécifier l'option
--force-log
:
$ svn commit --file fichier-versionné.txt machin.c svn: Le fichier de l'entrée du journal est versionné; forcer avec '--force-log' $ svn commit --force-log --file fichier-versionné.txt machin.c Envoi machin.c Transmission des données . Révision 6 propagée.
Pour propager un fichier à supprimer :
$ svn commit -m "Fichier 'c' supprimé." Suppression c Révision 7 propagée.
svn copy (cp) — Copier un ou plusieurs fichiers ou répertoires dans une copie de travail ou dans le dépôt.
svn copy SRC[@REV]... DST
Copier un ou plusieurs fichiers ou répertoires dans une copie de
travail ou dans le dépôt. Lors de la copie de plusieurs sources,
elles seront ajoutées en tant que fils de
DST
, qui doit être un répertoire.
SRC
et DST
peuvent être dans la copie de travail(WC) ou une URL :
Copier et prévoir pour ajout un élément (avec reprise de l'historique).
Propager immédiatement une copie de WC vers URL.
Extraire l'URL dans WC et le prévoir pour ajout.
Copier complètement côté serveur. Utilisé habituellement pour créer des branches ou des étiquettes.
S'il n'y pas de révision pivot (c-à-d.
@
) spécifiée, la révision
@REV
BASE
est utilisée par défaut pour les fichiers
copiés depuis la copie de travail et la révision
HEAD
est utilisée par défaut pour les fichiers
copiés depuis une URL.
Note | |
---|---|
Vous ne pouvez copier que des fichiers provenant d'un même dépôt. Subversion n'est pas capable d'effectuer des copies inter-dépôts. |
Copier un élément dans la copie de travail (la copie est prévue pour ajout ; rien n'est écrit dans le dépôt avant que vous n'effectuyez une propagation) :
$ svn copy machin.txt bidule.txt A bidule.txt $ svn status A + bidule.txt
Copier plusieurs fichiers de la copie de travail dans un répertoire :
$ svn cp bat.c truc.c qux.c src A src/bat.c A src/truc.c A src/qux.c
Copier la révision 8 de bat.c
dans la copie
de travail sous un autre nom :
$ svn cp -r 8 bat.c un-vieux-bat.c A un-vieux-bat.c
Copier un élément de la copie de travail vers une URL dans le dépôt (ceci provoque immédiatement une propagation, c'est pourquoi vous devez fournir une entrée dans le journal de propagation) :
$ svn copy proche.txt file:///var/svn/depot/test/tres-loin.txt -m "Copie distante." Révision 8 propagée.
Copier un élément du dépôt vers la copie de travail (ceci ne fait que prévoir la copie — rien ne se passe sur le dépôt tant que vous ne faites pas de propagation) :
$ svn copy file:///var/svn/depot/test/tres-loin -r 6 près-d-ici A près-d-ici
Astuce | |
---|---|
C'est la méthode recommandée pour ressuciter un fichier disparu dans le dépôt ! |
Et enfin, copier entre deux URL :
$ svn copy file:///var/svn/depot/test/tres-loin \ file:///var/svn/depot/test/là-bas -m "copie distante." Révision 9 propagée.
$ svn copy file:///var/svn/depot/test/trunk \ file:///var/svn/depot/test/tags/0.6.32-pre-officielle \ -m "création d'une étiquette" Révision 12 propagée.
Astuce | |
---|---|
C'est la méthode la plus facile pour « étiqueter »
une révision dans le dépôt — faites juste svn
copy de cette révision (généralement, c'est
|
Et ne vous inquietez pas si vous avez oublié de créer votre étiquette — vous pouvez toujours indiquer une vieille révision et étiqueter quand bon vous semble :
$ svn copy -r 11 file:///var/svn/depot/test/trunk \ file:///var/svn/depot/test/tags/0.6.32-pre-officielle \ -m "Oublié de créer l'étiquette à la révision 11" Révision 13 propagée.
svn delete (del, remove, rm) — Supprimer un élément de la copie de travail ou du dépôt.
svn delete CHEMIN...
svn delete URL...
Les éléments spécifiés par CHEMIN
sont prévus pour être supprimés lors de la prochaine propagation.
Les fichiers (et répertoires) qui n'ont pas été propagés sont
immédiatement supprimés de la copie de travail à moins que l'option
--keep-local
ne soit spécifiée. La commande ne
supprime ni ne modifie aucun élément qui n'est pas suivi en
versions ; utilisez l'option --force
pour
passer outre ce comportement.
Les éléments sous forme d'URL sont supprimés du dépôt par une propagation immédiate. Si plusieurs URL sont passées en paramètre, la propagation est atomique.
Utiliser svn pour supprimer un fichier de la copie de travail supprime la copie locale du fichier mais, surtout, cela prévoit de supprimer le fichier du dépôt. Lors de la prochaine propagation, le fichier est supprimé du dépôt.
$ svn delete mon-fichier D mon-fichier $ svn commit -m "Supprimé le fichier 'mon-fichier'." Suppression mon-fichier Transmission des données . Révision 14 propagée.
Supprimer une URL, en revanche, est immédiat. C'est pourquoi vous devez fournir une entrée dans le journal de propagation :
$ svn delete -m "Suppression du fichier 'ton-fichier'" \ file:///var/svn/depot/test/ton-fichier Révision 15 propagée.
Voici un exemple montrant comment forcer la suppression d'un fichier qui comporte des modifications locales :
$ svn delete là-bas svn: E195006: Utiliser --force pour passer cette restriction svn: E195006: 'là-bas' a des modifications locales $ svn delete --force là-bas D là-bas
Utilisez l'option --keep-local
pour passer
outre le comportement par défaut de svn delete qui
consiste à supprimer aussi le fichier cible qui est prévu d'être
enlevé du suivi de version. C'est utile quand vous réalisez que vous
avez propagé par erreur l'ajout d'un fichier dont vous aviez besoin
au sein de votre copie de travail mais qui n'avait pas à être suivi
en versions.
$ svn delete --keep-local conf/programme.conf D conf/programme.conf $ svn commit -m "Supprimer le fichier de configuration ajouté par erreur." Deleting conf/program.conf Transmission des données . Révision 21 propagée. $ svn status ? conf/programme.conf $
Note | |
---|---|
Le comportement de l'option |
svn diff (di) — Afficher les différences entre deux révisions ou chemins.
diff [-c M | -r N[:M]] [CIBLE[@REV]...]
diff [-r N[:M]] --old=VCIBLE[@VREV] [--new=NCIBLE[@NREV]] [CHEMIN...]
diff VURL[@VREV] NURL[@NREV]
Afficher les différences entre deux chemins. Vous pouvez utiliser svn diff selon différentes formes :
Tapez juste svn diff pour afficher les modifications faites localement à une copie de travail.
Afficher les modifications faites à
CIBLE
entre deux révisions telles
qu'elles apparaissent lors de la révision
REV
. Les
CIBLE
s peuvent faire référence à des
chemins de la copie de travail ou à des
URL
. Si les
CIBLE
s font référence à des chemins de
la copie de travail, alors N
vaut par
défaut BASE
et M
à la copie de travail ; si les
CIBLE
s font référence à des
URL
, alors
N
doit être spécifié et
M
vaut par défaut
HEAD
. L'option -c M
est
équivalente à -r N:M
avec
N = M-1
. L'utilisation de
-c -M
correspond à l'inverse :
-r M:N
avec N = M-1
.
Afficher les différences entre
VCIBLE
vue en
VREV
et
NCIBLE
vue en
NREV
. Les
CHEMIN
s, s'ils sont spécifiés, sont
relatifs à VCIBLE
et
NCIBLE
et restreignent l'affichage des
différences à ces chemins. VCIBLE
et
NCIBLE
peuvent faire référence à des
chemins de la copie de travail ou des
URL[@REV]
.
NCIBLE
vaut par défaut
VCIBLE
si elle n'est pas spécifiée.
-r N
entraine que
VREV
vaut par défaut
N
; -r N:M
entraine
que VREV
vaut par défaut
N
et NREV
vaut par défaut M
.
svn diff VURL[@VREV]
NURL[@NREV]
est un raccourci pour
svn diff --old=VURL[@OVREV]
--new=NURL[@NREV]
.
svn diff -r N:M URL
est un raccourci pour
svn diff -r N:M --old=URL --new=URL
.
svn diff [-r N[:M]] URL1[@N]
URL2[@M]
est un raccourci pour svn
diff [-r N[:M]] --old=URL1 --new=URL2
.
Si CIBLE
est une URL, alors les
révisions N
et M
peuvent être passées via l'option
--revision
(-r
) ou en utilisant la
notation « @ » décrite précédemment.
Si CIBLE
est un chemin de la copie de
travail, le comportement par défaut (sans option
--revision
) est d'afficher les différences entre les
versions « de base » et la copie de travail de
CIBLE
. Si l'option
--revision
est spécifiée dans cette forme, cela
correspond à :
--revision N:M
Le serveur compare CIBLE@N
et CIBLE@M
.
--revision N
Le client compare CIBLE@N
à la
copie de travail.
Si la syntaxe alternative est utilisée, le serveur compare
URL1
et URL2
aux révisions N
et
M
, respectivement. Si l'une ou l'autre
des révisions N
et
M
n'est pas spécifiée, la valeur
HEAD
est prise par défaut.
Par défaut, svn diff ignore l'héritage des
fichiers et ne fait que comparer le contenu des fichiers spécifiés.
Si vous utilisez l'option --notice-ancestry
,
l'héritage des chemins en question sera pris en compte lors de la
comparaison des révisions (c-à-d. que si vous lancez svn
diff sur deux fichiers dont le contenu est identique mais
qui ont des héritages différents, l'affichage correspond à un fichier
supprimé puis ajouté de nouveau).
--change
(-c
)ARG
--changelist
(--cl
)ARG
--depth
ARG
--diff-cmd
CMD
--extensions
(-x
)ARG
--force
--git
--ignore-properties
--internal-diff
--new
ARG
--no-diff-added
--no-diff-deleted
--notice-ancestry
--old
ARG
--patch-compatible
--properties-only
--revision
(-r
)REV
--show-copies-as-adds
--summarize
--xml
Comparer BASE
et la copie de travail (c'est
l'utilisation la plus fréquente de svn
diff) :
$ svn diff COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (révision 4404) +++ COMMITTERS (copie de travail)
Regarder ce qui a changé dans le fichier
COMMITTERS
depuis la révision 9115 :
$ svn diff -c 9115 COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (révision 3900) +++ COMMITTERS (copie de travail)
Regarder ce qui change dans la copie de travail par rapport aux anciennes révisions :
$ svn diff -r 3900 COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (révision 3900) +++ COMMITTERS (copie de travail)
Comparer la révision 3000 à la révision 3500 en utilisant la syntaxe « @ » :
$ svn diff http://svn.collab.net/repos/svn/trunk/COMMITTERS@3000 \ http://svn.collab.net/repos/svn/trunk/COMMITTERS@3500 Index: COMMITTERS =================================================================== --- COMMITTERS (révision 3000) +++ COMMITTERS (révision 3500) …
Comparer la révision 3000 à la révision 3500 en utilisant la notation pour les intervalles (on ne passe qu'une seule fois l'URL dans ce cas) :
$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk/COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (révision 3000) +++ COMMITTERS (révision 3500)
Comparer la révision 3000 à la révision 3500 de tous les fichiers
dans trunk
en utilisant la notation pour les
intervalles :
$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk
Comparer la révision 3000 à la révision 3500 de seulement trois
fichiers dans trunk
en utilisant la notation
pour les intervalles :
$ svn diff -r 3000:3500 --old http://svn.collab.net/repos/svn/trunk \ COMMITTERS README HACKING
Si vous avez une copie de travail, vous pouvez obtenir ces différences sans taper de longues URL :
$ svn diff -r 3000:3500 COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (révision 3000) +++ COMMITTERS (révision 3500)
Utiliser l'option --diff-cmd
CMD
-x
pour passer
directement des paramètres au programme diff externe :
$ svn diff --diff-cmd /usr/bin/diff -x "-i -b" COMMITTERS Index: COMMITTERS =================================================================== 0a1,2 > Ceci est un test >
Pour finir, vous pouvez utiliser l'option --xml
avec l'option --summarize
pour afficher un document
XML décrivant les modifications apportées entre les révisions, mais
pas le contenu des différences en tant que tel :
$ svn diff --summarize --xml http://svn.red-bean.com/repos/test@r2 \ http://svn.red-bean.com/repos/test <?xml version="1.0"?> <diff> <paths> <path props="none" kind="file" item="modified">http://svn.red-bean.com/repos/test/sandwich.txt</path> <path props="none" kind="file" item="deleted">http://svn.red-bean.com/repos/test/burrito.txt</path> <path props="none" kind="dir" item="added">http://svn.red-bean.com/repos/test/snacks</path> </paths> </diff>
svn export — Créer une copie non versionnée d'une arborescence.
svn export [-r REV] URL[@REV_PIVOT] [CHEMIN]
svn export [-r REV] CHEMIN1[@REV_PIVOT] [CHEMIN2]
La première forme exporte une copie non versionnée d'un dépôt
spécifié par URL
— à la révision
REV
si elle est spécifiée ; sinon,
à HEAD
, vers CHEMIN
. Si
CHEMIN
est omis, le nom de fichier
(basename) de
URL
est utilisé comme nom du répertoire
local.
La deuxième forme exporte une copie non versionnée de la copie de
travail spécifiée par CHEMIN1
vers
CHEMIN2
. Toutes les modifications locales
sont préservées mais les fichiers qui ne sont pas suivis en versions
ne sont pas copiés.
Exporter depuis la copie de travail (n'affiche pas tous les fichiers et répertoires) :
$ svn export une-copie-travail mon-export Fin d'exportation.
Exporter directement depuis le dépôt (affiche chaque fichier et répertoire) :
$ svn export file:///var/svn/depot mon-export A mon-export/test A mon-export/quizz … Exporté à la révision 15.
Lorsque vous produisez une archive spécifique à un système
d'exploitation donné, il peut être utile de faire l'export en
utilisant le caractère de fin de ligne correspondant au système
d'exploitation. L'option --native-eol
est prévue à
cet effet, mais elle ne s'applique qu'aux fichiers qui possèdent la
propriété svn:eol-style =native
. Par exemple, pour
exporter une arborescence avec le marqueur de fin de ligne CRLF
(convient pour une archive .zip
Windows),
tapez :
$ svn export file:///var/svn/depot mon-export --native-eol CRLF A mon-export/test A mon-export/quizz … Exporté à la révision 15.
Vous pouvez spécifier LR
,
CR
ou CRLF
comme marqueur de
fin de ligne à l'option --native-eol
.
svn help (h, ?) — À l'aide !
svn help [SOUS-COMMANDE...]
svn import — Propager un fichier ou une arboresence non versionnée dans le dépôt.
svn import [CHEMIN] URL
Propage récursivement une copie de
CHEMIN
vers
URL
. Si CHEMIN
est omis, « .
» est la valeur par
défaut. Les répertoires parents sont créés dans le dépôt autant que
nécessaire. Les éléments non suivis en versions tels que les
descripteurs de périphériques et les tubes de communication
(pipe en anglais) sont ignorés même si
l'option --force
est spécifiée.
Importer le répertoire local mon-projet
vers
trunk/misc
dans le dépôt. Le répertoire
trunk/misc
n'a pas besoin d'exister avant
l'import — svn import crée récursivement
les répertoires pour vous.
$ svn import -m "Nouvel import" mon-projet \ http://svn.red-bean.com/repos/trunk/misc Ajout mon-projet/echantillon.txt … Transmission des données ......... Révision 16 propagée.
Attention, cette commande ne crée pas de
répertoire mon-projet
dans le dépôt. Si vous
voulez le faire, ajoutez simplement mon-projet
à
la fin de l'URL :
$ svn import -m "Nouvel import" mon-projet \ http://svn.red-bean.com/repos/trunk/misc/mon-projet Ajout mon-projet/echantillon.txt … Transmission des données ......... Révision 16 propagée.
Après avoir importé des données, notez que l'arborescence originale n'est pas placée en suivi de versions. Pour commencer à travailler, vous devez toujours extraire une copie de travail de l'arborescence à l'aide de la commande svn checkout.
svn info — Afficher les informations sur des éléments locaux ou distants.
svn info [CIBLE[@REV]...]
Afficher les informations sur des éléments de la copie de travail ou du dépôt. Les informations susceptibles d'être affichées sont, pour les deux formess :
les informations relatives au dépôt sur lequel l'objet est suivi en versions ;
la dernière propagation en date relatçve à l'objet suivi en versions ;
les verrous posés sur l'objet ;
la tâche programmée pour cet objet (ajout, suppression, copie, etc.) ;
la situation de conflit.
svn info affiche toutes les informations pertinentes qu'elle trouve pour les éléments dans la copie de travail. Elle affiche les informations concernant les fichiers :
$ svn info machin.c Chemin : machin.c Nom : machin.c Chemin racine de la copie de travail : /home/sally/projects/test URL : http://svn.red-bean.com/repos/test/machin.c Relative URL: ^/machin.c Racine du dépôt : http://svn.red-bean.com/repos/test UUID du dépôt : 5e7d134a-54fb-0310-bd04-b611643e5c25 Révision: 4417 Type de nœud : fichier Tâche programmée : normale Auteur de la dernière modification : sally Révision de la dernière modification : 20 Date de la dernière modification : 2003-01-13 16:43:13 -0600 (lun. 13 jan 2003) Texte mis à jour : 2003-01-16 21:18:16 -0600 (Thu, 16 Jan 2003) Propriétés mises à jour : 2003-01-13 21:50:19 -0600 (lun. 13 jan 2003) Somme de contrôle : d6aeb60b0662ccceb6bce4bac344cb66
Elle affiche aussi des informations sur les répertoires :
$ svn info vendors Chemmin : vendors Chemin racine de la copie de travail : /home/sally/projects/test URL : http://svn.red-bean.com/repos/test/vendors Relative URL: ^/vendors Racine du dépôt : http://svn.red-bean.com/repos/test UUID du dépôt : 5e7d134a-54fb-0310-bd04-b611643e5c25 Révision: 19 Type de nœud : répertoire Tâche programmée : normale Auteur de la dernière modification : harry Révision de la dernière modification : 19 Date de la dernière modification : 2003-01-16 23:21:19 -0600 (jeu. 16 jan 2003) Properties mises à jour : 2003-01-16 23:39:02 -0600 (jeu. 16 jan 2003)
svn info traite aussi les URL (notez que dans
cet exemple, le fichier lisezmoi.doc
est
verrouillé et donc l'information relative à ce verrouillage est
fournie) :
$ svn info http://svn.red-bean.com/repos/test/lisezmoi.doc Chemin : lisezmoi.doc Nom : lisezmoi.doc URL : http://svn.red-bean.com/repos/test/lisezmoi.doc Relative URL: ^/lisezmoi.doc Racine du dépôt : http://svn.red-bean.com/repos/test UUID du dépôt : 5e7d134a-54fb-0310-bd04-b611643e5c25 Révision: 1 Type de nœud : fichier Tâche programmée : normale Auteur de la dernière modification : sally Révision de la dernière modification : 42 Date de la dernière modification : 2003-01-14 23:21:19 -0600 (mar. 14 jan 2003) Nom de verrou : opaquelocktoken:14011d4b-54fb-0310-8541-dbd16bd471b2 Propriétaire du verrou : harry Verrou créé : 2003-01-15 17:35:12 -0600 (mer. 15 jan 2003) Lock Comment (1 line): Mon commentaire pour le verrou de test
Pour finir, l'affichage de svn info est
disponible au format XML en spécifiant l'option
--xml
:
$ svn info --xml http://svn.red-bean.com/repos/test <?xml version="1.0"?> <info> <entry kind="dir" path="." revision="1"> <url>http://svn.red-bean.com/repos/test</url> <relative-url>^/</relative-url> <repository> <root>http://svn.red-bean.com/repos/test</root> <uuid>5e7d134a-54fb-0310-bd04-b611643e5c25</uuid> </repository> <wc-info> <schedule>normal</schedule> <depth>infinity</depth> </wc-info> <commit revision="1"> <author>sally</author> <date>2003-01-15T23:35:12.847647Z</date> </commit> </entry> </info>
svn list (ls) — Lister le contenu de répertoires dans le dépôt.
svn list [CIBLE[@REV]...]
Lister chaque fichier CIBLE
et le
contenu de chaque répertoire CIBLE
comme
ils existent dans le dépôt. Si CIBLE
est
un chemin de la copie de travail, alors l'URL correspondante sur le
dépôt est utilisée.
Par défaut, la CIBLE
est
« .
», c'est-à-dire l'URL du dépôt
pour le répertoire courant de la copie de travail.
Avec l'option --verbose
, svn
list affiche les champs suivants pour chaque
élément :
le numéro de révision de la dernière propagation ;
l'auteur de la dernière propagation ;
Si l'élément est verrouillé, la lettre « O » (lisez la section svn info pour plus de détails) ;
la taille (en octets) ;
la date et l'heure de la dernière propagation.
Avec l'option --xml
, l'affichage est au format
XML format (avec une entête et un élément document qui encadre le
tout à moins que l'option --incremental
soit aussi
spécifiée). Toute l'information disponible est affichée, l'option
--verbose
n'est pas acceptée.
svn list est particulièrement utile quand vous voulez visualiser des fichiers dans le dépôt sans les télécharger dans votre copie de travail :
$ svn list http://svn.red-bean.com/repos/test/support LISEZMOI.txt INSTALL exemples/ …
Vous pouvez passer l'option --verbose
pour
obtenir des informations complémentaires, un peu comme la commande
Unix ls -l :
$ svn list -v file:///var/svn/depot 16 sally 28361 Jan 16 23:18 LISEZMOI.txt 27 sally 0 Jan 18 15:27 INSTALL 24 harry Jan 18 11:27 exemples/
Vous pouvez obtenir un affichage au format XML avec la commande
svn list en spécifiant l'option
--xml
:
$ svn list --xml http://svn.red-bean.com/repos/test <?xml version="1.0"?> <lists> <list path="http://svn.red-bean.com/repos/test"> <entry kind="dir"> <name>exemples</name> <size>0</size> <commit revision="24"> <author>harry</author> <date>2008-01-18T06:35:53.048870Z</date> </commit> </entry> … </list> </lists>
Pour plus de détails, lisez la section précédente la section intitulée « Contenu des dossiers suivis en versions ».
svn lock — Verrouiller des chemins ou des URL dans le dépôt, afin qu'aucun autre utilisateur ne puisse propager (commit) des modifications les concernant.
svn lock CIBLE...
Verrouiller chaque CIBLE
. Si une
CIBLE
est déjà verrouillée par un autre
utilisateur, affiche un avertissement et continue de verrouiller les
autres CIBLE
s. Utilisez l'option
--force
pour voler un verrou à un autre utilisateur
ou à une autre copie de travail.
Verrouiller deux fichiers de la copie de travail :
$ svn lock arbre.jpg maison.jpg 'arbre.jpg' verrouillé par l'utilisateur 'harry'. 'maison.jpg' verrouillé par l'utilisateur 'harry'.
Verrouiller un fichier dans la copie de travail qui est déjà verrouillé par un autre utilisateur :
$ svn lock arbre.jpg svn: avertissement : W1600035: Chemin '/arbre.jpg' déjà verrouillé par \ l'utilisateur 'sally' dans le système de fichiers '/var/svn/depot/db' $ svn lock --force arbre.jpg 'arbre.jpg' verrouillé par l'utilisateur 'harry'.
Verrouiller un fichier sans copie de travail :
$ svn lock http://svn.red-bean.com/repos/test/arbre.jpg 'arbre.jpg' verrouillé par l'utilisateur 'harry'.
Pour davantage de détails, référez-vous à la section intitulée « Verrouillage ».
svn log — Afficher les entrées du journal de propagation.
svn log [CHEMIN]
svn log URL[@REV] [CHEMIN...]
Afficher les entrées du journal de propagation du dépôt. Si aucun
argument n'est fourni, svn log affiche les entrées
du journal de propagation pour tous les fichiers et répertoires dans
(et y compris) le répertoire courant de la copie de travail. Vous
pouvez affiner votre requête en spécifiant un chemin, une ou
plusieurs révisions, ou une combinaison des deux. L'intervalle de
révisions par défaut pour un chemin local est
BASE:1
.
Si vous spécifiez une URL simple, la commande affiche les entrées
du journal pour tout ce que contient l'URL. Si vous ajoutez des
chemins après l'URL, seules les entrées relatives aux chemins
spécifiés sont affichées. L'intervalle de révisions par défaut pour
une URL est HEAD:1
.
Avec l'option --verbose
, svn
log affiche également tous les chemins modifiés pour chaque
entrée du journal. Avec l'option --quiet
,
svn log n'affiche pas le corps de l'entrée du
journal (cette option est compatible avec l'option
--verbose
).
Chaque entrée du journal est affichée seulement une fois, même
si, parmi les chemins explicitement demandés, plus d'un a été modifié
pour cette révision. Les entrées du journal suivent l'historique de
la copie de travail par défaut. Utilisez l'option
--stop-on-copy
pour désactiver ce comportement, ce
qui peut être utile pour déterminer à quel moment une branche a été
créée.
--change
(-c
)ARG
--depth
ARG
--diff
--diff-cmd
CMD
--extensions
(-x
)ARG
--incremental
--internal-diff
--limit
(-l
)NUM
--quiet
(-q
)--revision
(-r
)REV
--search
ARG
--search-and
ARG
--stop-on-copy
--targets
NOM_FICHIER
--use-merge-history
(-g
)--verbose
(-v
)--with-all-revprops
--with-no-revprops
--with-revprop
ARG
--xml
Vous pouvez visualiser les entrées du journal pour tous les
chemins qui ont été modifiés dans la copie de travail en lançant la
commande svn log
depuis le répertoire
racine :
$ svn log ------------------------------------------------------------------------ r20 | harry | 2003-01-17 22:56:19 -0600 (ven. 17 jan 2003) | 1 ligne Peaufinage. ------------------------------------------------------------------------ r17 | sally | 2003-01-16 23:21:19 -0600 (jeu. 16 jan 2003) | 2 lignes …
Examiner toutes les entrées du journal pour un fichier particulier de la copie de travail :
$ svn log machin.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (lun. 13 jan 2003) | 1 ligne Ajouté des définitions. ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (mar. 07 jan 2003) | 3 lignes …
Si vous n'avez pas de copie de travail sous la main, vous pouvez examiner les entrées du dépôt :
$ svn log http://svn.red-bean.com/repos/test/machin.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (lun. 13 jan 2003) | 1 ligne Ajouté des définitions. ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (mar. 07 jan 2003) | 3 lignes …
Si vous voulez spécifier plusieurs chemins distincts sous la même
URL, vous pouvez utiliser la syntaxe URL
[CHEMIN...]
:
$ svn log http://svn.red-bean.com/repos/test/ machin.c bidule.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (lun. 13 jan 2003) | 1 ligne Ajouté des définitions. ------------------------------------------------------------------------ r31 | harry | 2003-01-10 12:25:08 -0600 (ven. 10 jan 2003) | 1 ligne Ajouté le nouveau fichier bidule.c ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (mar. 07 jan 2003) | 3 lignes …
L'option --verbose
demande à svn
log d'inclure les informations relatives aux chemins
modifiés pour chaque révision affichée. Ces chemins sont affichés, un
chemin par ligne, avec le code d'action qui indique quel changement a
été effectué sur le chemin.
$ svn log -v http://svn.red-bean.com/repos/test/ machin.c bidule.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (lun. 13 jan 2003) | 1 ligne Chemins modifiés : M /machin.c Ajouté des définitions. ------------------------------------------------------------------------ r31 | harry | 2003-01-10 12:25:08 -0600 (ven. 10 jan 2003) | 1 ligne Chemins modifiés : A /bidule.c Ajouté le nouveau fichier bidule.c ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (mar. 07 jan 2003) | 3 lignes …
svn log n'utilise qu'une poignée de codes d'action, les mêmes que ceux utilisés par la commande svn update :
A
l'élément a été ajouté ;
D
l'élément a été supprimé (Deleted en anglais) ;
M
les propriétés ou le contenu de l'élément ont été modifiés ;
R
l'élément a été remplacé par un autre au même endroit.
En plus des codes d'action qui précèdent les chemins modifiés,
svn log avec l'option --verbose
indique si le chemin a été ajouté ou remplacé par le fait d'une
opération de copie. Il le signale en affichant (de
après le chemin.COPIE-DE-CHEMIN
:COPIE-DE-REV
)
Quand vous concaténez la sortie de plusieurs commandes
svn log, il peut être judicieux d'utiliser
l'option --incremental
. svn
log affiche normalement une ligne de tirets avant chaque
entrée de journal, après chaque entrée conséquente et après la
derniere entrée du journal. Si vous lancez svn log
sur un intervalle de deux révisions, vous obtenez la sortie
suivante :
$ svn log -r 14:15 ------------------------------------------------------------------------ r14 | … ------------------------------------------------------------------------ r15 | … ------------------------------------------------------------------------
Cependant, si vous voulez rassembler, dans un fichier, deux entrées du journal qui ne se suivent pas, vous lancerez des commandes comme ceci :
$ svn log -r 14 > mon-journal $ svn log -r 19 >> mon-journal $ svn log -r 27 >> mon-journal $ cat mon-journal ------------------------------------------------------------------------ r14 | … ------------------------------------------------------------------------ ------------------------------------------------------------------------ r19 | … ------------------------------------------------------------------------ ------------------------------------------------------------------------ r27 | … ------------------------------------------------------------------------
Vous pouvez éviter l'inconvénient des doubles lignes de tirets
dans votre fichier en utilisant l'option
--incremental
:
$ svn log --incremental -r 14 > mon-journal $ svn log --incremental -r 19 >> mon-journal $ svn log --incremental -r 27 >> mon-journal $ cat mon-journal ------------------------------------------------------------------------ r14 | … ------------------------------------------------------------------------ r19 | … ------------------------------------------------------------------------ r27 | …
L'option --incremental
fournit le même type de
fonctionnalité quand elle est utilisée avec l'option
--xml
:
$ svn log --xml --incremental -r 1 sandwich.txt <logentry revision="1"> <author>harry</author> <date>2008-06-03T06:35:53.048870Z</date> <msg>Initial Import.</msg> </logentry>
Astuce | |
---|---|
Quelquefois, quand vous lancez la commande svn log sur un chemin spécifique et une révision spécifique, vous ne voyez aucune entrée de journal, comme dans le cas suivant : $ svn log -r 20 http://svn.red-bean.com/pas-modifié.txt ------------------------------------------------------------------------ Cela signifie simplement que le chemin n'a pas été modifié lors de la révision spécifiée. Pour obtenir l'entrée de journal correspondante à cette révision, soit lancez l'opération de log sur l'URL racine du dépôt, soit sur un chemin dont vous savez qu'il a été modifié lors de cette révision : $ svn log -r 20 modifié.txt ------------------------------------------------------------------------ r20 | sally | 2003-01-17 22:56:19 -0600 (ven. 17 jan 2003) | 1 ligne Effectué un changement. ------------------------------------------------------------------------ |
À partir de Subversion 1.7, les utilisateurs disposent d'un mode
d'affichage spécial qui combine les informations de svn
log et de ce qu'affiche svn diff pour
la même cible à chaque révision. Tapez simplement svn
log avec l'option --diff
pour activer ce
mode d'affichage.
$ svn log -r 20 modifié.txt --diff ------------------------------------------------------------------------ r20 | sally | 2003-01-17 22:56:19 -0600 (ven. 17 jan 2003) | 1 ligne Effectué un changement. Index: modifié.txt =================================================================== --- modifié.txt (revision 19) +++ modifié.txt (revision 20) @@ -1 +1,2 @@ Ceci est le fichier 'modifié.txt'. +Nous ajoutons du texte très intéressant à cet endroit ! ------------------------------------------------------------------------ $
Comme pour svn diff, vous pouvez utiliser
toutes les options relatives aux différences, y compris
--depth
, --diff-cmd
et --extensions
(-x
).
À partir de Subversion 1.8, les utilisateurs peuvent filtrer la
sortie de svn log avec les options
--search
et --search-and
. Avec ces
options, l'entrée de journal n'est affichée que si l'auteur de la
révision, la date, le texte du commentaire ou la liste des chemins
modifiés correspondent au motif de recherche. La recherche sur les
chemins modifiés requiert l'option --verbose
, sinon
svn log n'affiche pas les chemins modifiés et
ceux-ci ne peuvent donc pas être filtrés.
Le motif de recherche (aussi appelé glob ou motif de filtrage du shell) peut contenir des caractères normaux et les caractères spéciaux suivants :
?
correspond à n'importe quel caractère unique ;
*
correspond à n'importe quelle chaîne de caractères, y compris la chaîne vide ;
[ABC]
correspond à n'importe quel caractère qui figure à l'intérieur des crochets.
Si vous utilisez plusieurs paramètres --search
,
vous obtenez les entrées qui correspondent à au moins un motif de
recherche. Par exemple :
$ svn log --search sally --search harry https://svn.red-bean.com/repos/test ------------------------------------------------------------------------ r1701 | sally | 2011-10-12 22:35:30 -0600 (mer. 12 oct 2011) | 1 ligne Ajouté un pense-bête. ------------------------------------------------------------------------ r1564 | harry | 2011-10-09 22:35:30 -0600 (dim. 09 oct 2011) | 1 ligne Fusionné r1560 vers la branche 1.0.x. ------------------------------------------------------------------------ $
Si vous utilisez l'option --search
avec
--search-and
, vous obtenez les entrées qui
correspondent à la combinaison des motifs de recherche des deux
options. Par exemple :
$ svn log --verbose --search sally --search-and /truc/machin https://svn.red-bean.com/repos/test ------------------------------------------------------------------------ r1555 | sally | 2011-07-15 22:33:14 -0600 (Fri, 15 Jul 2011) | 1 line Changed paths: M /truc/machin/src.c Correction de coquilles. ------------------------------------------------------------------------ r1530 | sally | 2011-07-13 07:24:11 -0600 (Wed, 13 Jul 2011) | 1 line Changed paths: M /truc/machin M /truc/build Modification de quelques propriétés svn:ignore. ------------------------------------------------------------------------ $
Astuce | |
---|---|
Les options |
svn merge — Appliquer les différences entre deux sources à une copie de travail.
svn merge SOURCE[@REV] [CIBLE_COPIE_TRAVAIL]
svn merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [CIBLE_COPIE_TRAVAIL]
svn merge SOURCE1[@N] SOURCE2[@M] [CIBLE_COPIE_TRAVAIL]
Dans les trois formes,
CIBLE_COPIE_TRAVAIL
désigne le chemin de
la copie de travail qui reçoit les différences. Si vous omettez
CIBLE_COPIE_TRAVAIL
, les modifications
sont appliquées dans le répertoire de travail courant, à moins que
les sources n'aient un nom de répertoire identique qui correspond à
un nom de fichier dans le répertoire courant. Dans ce cas, les
différences sont appliquées à ce fichier.
Dans les deux première formes,
SOURCE
peut être soit une URL, soit une
copie de travail (dans ce cas, l'URL correspondante est utilisée).
Si la révision pivot REV
n'est pas
spécifiée, alors HEAD
est pris par défaut. Dans
la troisième forme, les mêmes règles s'appliquent pour
SOURCE1
,
SOURCE2
,
M
et
N
avec pour seule différence que si une
source est un chemin de la copie de travail, alors la révision pivot
doit être spécifiée explicitement.
Fusions automatiques
La première forme est appelée « fusion
automatique » et est utilisée pour effectuer des fusions de
« synchronisation » et
« réintégration ». Les fusions de
« synchronisation » fusionnent les modifications
éligibles vers une branche
(CIBLE_COPIE_TRAVAIL
) depuis la
branche ancêtre (SOURCE
). Les
modifications « éligibles » sont définies comme celles
qui n'ont pas déjà été fusionnées à partir de
SOURCE
vers
CIBLE_COPIE_TRAVAIL
. Lisez
la section intitulée « Garder une branche synchronisée » pour
une explication en profondeur.
Les fusions de « réintégrations » consistent à
fusionner les modifications faites sur une branche fonctionnelle
(SOURCE
) en retour vers la branche
ancêtre (CIBLE_COPIE_TRAVAIL
). Lisez
la section intitulée « Réintegration d'une branche » et
la section intitulée « Branches fonctionnelles » pour les
explications.
Fusions avec sélection à la main
La deuxième forme est appelée une fusion avec
« sélection à main »
(cherry-pick en anglais) et est
utilisée pour fusionner un ensemble explicite de modifications
d'une branche vers une autre. SOURCE
dans la révision REV
est comparée à
ce qu'elle était entre les révisions N
et M
pour chaque intervalle de
révisions spécifié. Voir la section intitulée « Sélection à la main » pour plus de
précisions.
Astuce | |
---|---|
Plusieurs |
Fusions à deux URL
Dans la troisième forme, appelée « fusion à deux 2
URL », les différences entre
SOURCE1
à la révision
N
et
SOURCE2
à la révision
M
sont calculées et appliquées à
CIBLE_COPIE_TRAVAIL
. Les révisions
par défaut sont HEAD
si elles sont
omises.
Si Suivi de fusions
est actif, alors Subversion conserve des métadonnées traçant les
opérations de fusion (la propriété svn:mergeinfo
)
quand les deux sources sont reliées par un ancêtre commun (si la
première source est un ancêtre de la deuxième ou vice-versa). Ce
comportement est garanti lorsqu'il s'agit d'une fusion automatique.
Subversion prendra soin de vérifier les métadonnées déjà existantes
de la cible dans la copie de travail pour déterminer quelles
révisions doivent être fusionnées et ainsi éviter d'appliquer
plusieurs fois des modifications.
Contrairement à svn diff, la commande de fusion prend en compte la généalogie d'un fichier pour calculer ce qu'il faut faire. C'est particulièrement important lorsqu'il s'agit de fusionner des modifications d'une branche vers une autre alors que vous avez renommé un fichier dans une branche mais pas dans l'autre.
Astuce | |
---|---|
L'option |
Réintègrer une branche vers le tronc, en considérant que la copie
de travail du tronc est à jour, l'option --verbose
affichant des informations complémentaires sur ce que fait la fusion
avant d'appliquer réellement les différences ; c'est utile
lors des grosses opérations qui peuvent prendre un certain
temps :
$ svn merge ^/branches/branche-améliorations-calc trunk --verbose checking branch relationship... calculating automatic merge... --- Merging --- Fusion de r12 à r37 dans 'trunk': U trunk/calc/brosse.c --- Stockage des informations de fusion (mergeinfo) de r12 à r37 dans 'trunk': U trunk $ # compilation, tests, vérifications ... $ svn commit trunk -m "Réintégration des améliorations de calc dans le tronc !" Envoi trunk Envoi trunk/calc/brush.c Transmission des données . Révision 38 propagée.
« Sélectionner à la main » une simple modification sur un fichier :
$ svn merge ^/trunk/calc/brosse.c branches/1.x/calc/brosse.c -c38 --- Fusion de r38 dans 'branches/1.x/calc/brosse.c': U branches/1.x/calc/brosse.c --- Stockage des informations de fusion (mergeinfo) de r38 dans 'brosse.c': G branches/1.x/calc/brosse.c
Fusionner les différences entre deux branches sans relations dans une troisième branche :
$ svn merge ^/vendor-drop/vendor-1.0 ^/vendor-drop/vendor-1.1 \ trunk --ignore-ancestry --- Fusion des différences des URLs du dépôt vers 'trunk' : U trunk/draw/draw.py
svn mergeinfo — Afficher les informations liées aux fusions. Voir la section intitulée « Mergeinfo et aperçus » pour les détails.
svn mergeinfo URL_SOURCE[@REV] [CIBLE[@REV]]
Afficher les informations liées aux fusions (ou fusions
potentielles) entre URL_SOURCE
et
CIBLE
. Si l'option
--show-revs
n'est pas fournie, affiche les révisions
qui ont été fusionnées depuis URL_SOURCE
vers CIBLE
. Sinon, affiche soit
merged
, soit eligible
comme
spécifié par l'option --show-revs
.
Représenter graphiquement un résumé des fusions d'une branche vers une autre :
$ svn mergeinfo ^/trunk branche-fonctionnelle youngest last repos. common full tip of path of ancestor merge branch branch 11 16 33 | | | -------| |------------ trunk \ \ \ \ --| |------------ branche-fonctionnelle | 33
Lister les révisions où a eu lieu une opération de fusion d'une branche vers une autre :
$ svn mergeinfo ^/trunk branche-fonctionnelle --show-revs merged r15 r16
Lister les révisions éligibles à être fusionnées d'une branche vers une autre.
$ svn mergeinfo ^/trunk branche-fonctionnelle --show-revs eligible r28 r30
svn mkdir — Créer un nouveau répertoire et le placer en suivi de versions.
svn mkdir CHEMIN...
svn mkdir URL...
Créer un répertoire avec le nom fourni comme dernière composante
(basename) de
CHEMIN
ou URL
.
Un répertoire spécifié par un CHEMIN
dans
la copie de travail est prévu pour ajout lors de la prochaine
propagation. Un répertoire spécifié par une URL est directement créé
dans le dépôt par une propagation immédiate. Si plusieurs URL sont
spécifiées, les répertoires sont créés atomiquement. Dans les deux
cas, les répertoires intermédiaires doivent déjà exister sauf si
l'option --parents
est spécifiée.
Créer un répertoire dans la copie de travail :
$ svn mkdir nouveau-rep A nouveau-rep
En créer un dans le dépôt (cela entraine une propagation, il faut donc fournir une entrée de journal) :
$ svn mkdir -m "Création d'un nouveau répertoire." \ http://svn.red-bean.com/repos/nouveau-rep Révision 26 propagée.
svn move (mv) — Déplacer un fichier ou un répertoire.
svn move SRC... DST
Déplacer des fichiers ou des répertoires dans la copie de travail ou dans le dépôt.
Astuce | |
---|---|
Cette commande est équivalente à une svn copy suivi d'une svn delete. |
Quand plusieurs sources sont déplacées, elles sont ajoutées en
tant que fils de DST
, qui doit être un
répertoire.
Note | |
---|---|
Subversion n'accepte pas les déplacements entre les copies de travail et les URL. De plus, vous ne pouvez déplacer des fichiers qu'à l'intérieur d'un même dépôt (Subversion n'accepte pas les déplacements inter-dépôts). Subversion accepte les déplacements selon les formes suivantes à l'intérieur d'un dépôt : |
déplacer et prévoir pour ajout (avec historique) le fichier ou répertoire ;
renommage complet côté serveur.
Lorsque vous déplacez de grosses arborescences, vous devez être conscient que les déplacements URL → URL sont moins lourds que WC → WC. Déplacer un nœud à l'intérieur d'une copie de travail ne fait pas que modifier la table d'entrées d'un répertoire, cela copie les fichiers, gère les fichiers temporaires et réalise l'expansion des mots-clés, ce qui peut être significativement plus lent.
Gardez aussi à l'esprit que un déplacement WC → WC dans une copie de travail à révisions mélangées peut conduire à des résultats inattendus (voir la section intitulée « Copies de travail mixtes, à révisions mélangées »).
Déplacer un fichier de la copie de travail :
$ svn move machin.c bidule.c A bidule.c D machin.c
Déplacer plusieurs fichiers de la copie de travail vers un sous-répertoire :
$ svn move truc.c bat.c qux.c src A src/truc.c D truc.c A src/bat.c D bat.c A src/qux.c D qux.c
Déplacer un fichier dans le dépôt (cela entraine une propagation, il faut donc fournir une entrée de journal) :
$ svn move -m "Déplace un fichier" http://svn.red-bean.com/repos/machin.c \ http://svn.red-bean.com/repos/bidule.c Révision 27 propagée.
svn patch — Appliquer les modifications représentées par un fichier correctif au format unidiff dans la copie de travail.
svn patch FICHIER_CORRECTIF [CHEMIN]
Cette sous-commande applique les changements décrits dans le
fichier FICHIER_CORRECTIF
qui doit être au
format unidiff vers la copie de travail
CHEMIN
. Comme pour la plupart des autres
sous-commandes de copie, si CHEMIN
est
omis, les modifications sont apportées au répertoire courant de la
copie de travail. Un correctif unidiff convenable pour être appliqué
à une copie de travail peut être produit par la commande
svn diff ou par un outil tiers. Tout contenu qui
n'est pas au format unidiff dans le fichier correctif est
ignoré.
Toute modification listée dans le fichier correctif est soit
appliquée soit rejetée. Si la correspondance d'une modification n'est
pas trouvée exactement où elle devrait être, elle peut être appliquée
en amont ou en aval dans le fichier si la correspondance y est
trouvée en fonction des lignes de contexte fournies dans le correctif.
Une modification peut aussi être appliquée « au jugé »,
c'est-à-dire quand une ou plusieurs lignes du contexte sont ignorées
pour trouver une correspondance dans le fichier. Si aucun contexte
correspondant ne peut être trouvé, la modification est en conflit et
est écrite dans un fichier de rejet qui porte l'extension
.svnpatch.rej
.
svn patch rend compte pour chaque fichier ou répertoire du travail effectué par une lettre code, à la façon de svn update. Les lettre codes ont les significations suivantes :
A
Ajouté.
D
Supprimé (Deleted en anglais).
C
En conflit.
G
Fusionné (Merged) en anglais).
U
Mis à jour (Updated en anglais).
Les comptes-rendus relatifs aux modifications appliquées avec un
décalage ou « au jugé » sont indiqués par une ligne
commençant par le symbole ">
". Nous vous
conseillons de la passer en revue avec attention.
Si un correctif supprime tout le contenu d'un fichier, ce fichier est automatiquement marqué pour suppression. De la même manière, si un correctif crée un nouveau fichier, ce fichier est automatiquement placé dans la liste des fichiers à ajouter. Utilisez svn revert pour annuler les suppressions ou ajouts que vous ne validez pas.
Appliquer un simple correctif qui a été crée par la commande
svn diff. Le fichier correctif crée un nouveau
fichier, en supprime un autre et modifie le contenu ainsi que les
propriétés d'un troisième. Voici le correctif lui-même (nous
considérons qu'il s'appelle, quelle imagination,
PATCH
) :
Index: fichier-supprimé =================================================================== --- fichier-supprimé (revision 3) +++ fichier-supprimé (working copy) @@ -1 +0,0 @@ -Ce fichier sera supprimé. Index: fichier-modifié =================================================================== --- fichier-modifié (revision 4) +++ fichier-modifié (working copy) @@ -1,6 +1,6 @@ The letters in a line of text Could make your day much better. But expanded into paragraphs, -I'd tell of kangaroos and calves +I'd tell of monkeys and giraffes Until you were all smiles and laughs From my letter made of letters. Modification de propriétés sur fichier-modifié ___________________________________________________________________ Added: propname ## -0,0 +1 ## +propvalue Index: added-file =================================================================== --- fichier-ajouté (revision 0) +++ fichier-ajouté (working copy) @@ -0,0 +1 @@ +Ceci est un fichier ajouté.
Nous pouvons appliquer le correctif précédent à une autre copie de travail depuis notre dépôt en utilisant svn patch et en vérifiant que le travail a bien été fait grace à svn diff :
$ cd /une/autre/copie-travail $ svn patch /chemin/vers/PATCH D deleted-file UU changed-file A added-file $ svn diff Index: fichier-supprimé =================================================================== --- fichier-supprimé (revision 3) +++ fichier-supprimé (working copy) @@ -1 +0,0 @@ -Ce fichier sera supprimé. Index: fichier-modifié =================================================================== --- fichier-modifié (revision 4) +++ fichier-modifié (working copy) @@ -1,6 +1,6 @@ The letters in a line of text Could make your day much better. But expanded into paragraphs, -I'd tell of kangaroos and calves +I'd tell of monkeys and giraffes Until you were all smiles and laughs From my letter made of letters. Modification de propriétés sur fichier-modifié ___________________________________________________________________ Added: propname ## -0,0 +1 ## +propvalue Index: added-file =================================================================== --- fichier-ajouté (revision 0) +++ fichier-ajouté (working copy) @@ -0,0 +1 @@ +Ceci est un fichier ajouté. $
Parfois, vous pouvez avoir besoin que Subversion interprète le
correctif « à l'envers » : que ce qui doit être
ajouté soit enlevé et vice-versa. Utilisez alors l'option
--reverse-diff
. Dans l'exemple suivant, nous
écrasons un correctif qui décrit les modifications de notre copie
de travail puis nous appliquons ce correctif à l'envers pour annuler
ces changements.
$ svn status M truc.c $ svn diff > PATCH $ cat PATCH Index: truc.c =================================================================== --- truc.c (revision 128) +++ truc.c (working copy) @@ -1003,7 +1003,7 @@ return ERROR_ON_THE_G_STRING; /* Faire quelque chose dans la boucle. */ - for (i = 0; i < txns->nelts; i++) + for (i = 0; i < txns->nelts; i--) { status = faire_quelque_chose(i); if (status) $ svn patch --reverse-diff PATCH U truc.c $ svn status $
svn propdel (pdel, pd) — Supprimer une propriété d'un élément.
svn propdel NOM_PROP [CHEMIN...]
svn propdel NOM_PROP --revprop -r REV [CIBLE]
Supprimer les propriétés des fichiers, des répertoires ou des
révisions. La première forme supprime les propriétés suivies en
versions de votre copie de travail et la deuxième forme supprime à
distance les propriétés non suivies en versions d'une révision du
dépôt (CIBLE
permet juste de préciser le
dépôt à utiliser).
Supprimer une propriété d'un fichier de votre copie de travail :
$ svn propdel svn:mime-type un-script Propriété 'svn:mime-type' supprimée de 'un-script'.
Supprimer une propriété de révision :
$ svn propdel --revprop -r 26 date-de-publication Propriété 'date-de-publication' supprimée de la révision 26 du dépôt
svn propedit (pedit, pe) — Modifier une propriété d'un ou plusieurs éléments suivis en versions. Voir svn propset (pset, ps) plus loin dans ce chapitre.
svn propedit NOM_PROP CIBLE...
svn propedit NOM_PROP --revprop -r REV [CIBLE]
Modifie une ou plusieurs propriétés en utilisant votre éditeur
préféré. La première forme modifie les propriétés suivies en versions
de votre copie de travail et la deuxième forme modifie à distance des
propriétés non suivies en versions d'une révision d'un dépôt
(CIBLE
permet juste de préciser le dépôt à
utiliser).
Avec svn propedit il est très facile de modifier des propriétés contenant plusieurs valeurs :
$ svn propedit svn:keywords machin.c # svn lance votre éditeur favori en prenant en entrée le # contenu actuel de la propriété svn:keywords. Pour ajouter # plusieurs valeurs, en placer une par ligne. # Quand vous sauvez le fichier temporaire et sortez de l'éditeur, # Subversion relira le fichier temporaire et utilisera son contenu # comme nouvelle valeur de la propriété. Nouvelle valeur définie pour la propriété 'svn:keywords' sur 'machin.c' $
svn propget (pget, pg) — Afficher la valeur d'une propriété.
svn propget NOM_PROP [CIBLE[@REV]...]
svn propget NOM_PROP --revprop -r REV [URL]
Afficher la valeur d'une propriété définie sur des fichiers, des répertoires ou des révisions. Ŀa première forme affiche la valeur d'une propriété suivie en versions d'un ou plusieurs éléments de votre copie de travail et la deuxième forme affiche des propriétés suivies en versions d'une révision d'un dépôt. Voir la section intitulée « Propriétés » pour de plus amples informations sur les propriétés.
Examiner une propriété d'un fichier de votre copie de travail :
$ svn propget svn:keywords machin.c Author Date Rev
De même pour une propriété de révision :
$ svn propget svn:log --revprop -r 20 Démarré le journal d'activités.
Pour obtenir un affichage plus structuré des propriétés, utilisez
l'option --verbose
(-v
) :
$ svn propget svn:keywords machin.c --verbose Propriétés sur 'machin.c' svn:keywords Author Date Rev
Examiner les propriétés suivies en versions héritées par l'URL
dans votre dépôt en utilisant l'option
--show-inherited-props
:
$ svn pg svn:global-ignores --verbose --show-inherited-props ^/branches/1.x Propriétés héritées sur 'http://svn.example.com/repos/branches/1.x', de 'http://svn.example.com/repos' svn:global-ignores *.diff *.patch
Par défaut, svn propget ajoute un saut de
ligne à la fin de chaque valeur de propriété qu'elle affiche. La
plupart du temps, c'est très convenable. Mais parfois, quand vous
voulez vraiment avoir la valeur exacte de la propriété, peut-être
parce que ce n'est pas du texte mais un format binaire (tel qu'un
aperçu JPEG stocké en tant que valeur de propriété par exemple).
Pour désactiver l'affichage amélioré des valeurs de propriétés,
utilisez l'option --strict
.
Enfin, il est possible d'obtenir la sortie de svn
propget au format XML avec l'option
--xml
:
$ svn propget --xml svn:ignore . <?xml version="1.0"?> <properties> <target path=""> <property name="svn:ignore">*.o </property> </target> </properties>
svn proplist (plist, pl) — Lister toutes les propriétés.
svn proplist [CIBLE[@REV]...]
svn proplist --revprop -r REV [CIBLE]
Lister toutes les propriétés existentes sur les fichiers,
répertoires ou révisions. La première forme liste les propriétés
suivies en versions de votre copie de travail et la deuxième forme
liste les propriétés définies sur une révision d'un dépôt
(CIBLE
permet juste de préciser le dépôt à
utiliser).
proplist peut être utilisée pour obtenir la liste des propriétés d'un élément de votre copie de travail :
$ svn proplist machin.c Propriétés sur 'machin.c' svn:mime-type svn:keywords proprietaire
Grâce à l'option --verbose
, svn
proplist peut s'avérer très utile car elle affiche alors en
plus les valeurs des propriétés :
$ svn proplist --verbose machin.c Propriétés sur 'machin.c' svn:mime-type text/plain svn:keywords Author Date Rev proprietaire sally
Lister toutes les propriétés suivies en versions héritées par
un fichier dans votre copie de travail en utilisant l'option
--show-inherited-props
:
$ svn proplist --show-inherited-props machin.c Propriétés sur 'machin.c', depuis 'http://svn.exemple.com/depot' svn:auto-props svn:global-ignores Propriétés héritées sur 'machin.c', depuis '/home/theob/svn/copies-travail/baz-wc' svn:auto-props
Enfin, il est possible d'obtenir la sortie de svn
proplist au format XML avec l'option
--xml
:
$ svn proplist --xml <?xml version="1.0"?> <properties> <target path="."> <property name="svn:ignore"/> </target> </properties>
svn propset (pset, ps) — Associer la valeur PROP_VAL
à la
propriété PROP_NOM
pour des fichiers,
répertoires ou révisions.
svn propset NOM_PROP [VALEUR_PROP | -F FICHIER_VALEURS] CHEMIN...
svn propset NOM_PROP --revprop -r REV [VALEUR_PROP | -F FICHIER_VALEURS] [CIBLE]
Associer à NOM_PROP
la valeur
VALEUR_PROP
sur des fichiers, répertoires
ou révisions. Le premier exemple définit la modification locale de la
propriété suivie en versions dans la copie de travail et la deuxième
forme définit un changement à distance d'une propriété de révision du
dépôt non suivie en versions (CIBLE
permet
juste de préciser le dépôt à utiliser).
Astuce | |
---|---|
Subversion possède un certain nombre de propriétés « spéciales » permettant de modifier la façon dont il fonctionne. Voir la section intitulée « Propriétés réservées à l'usage de Subversion » pour plus d'informations sur ces propriétés. |
Définir le type MIME d'un fichier :
$ svn propset svn:mime-type image/jpeg truc.jpg Propriété 'svn:mime-type' définie sur 'truc.jpg'
Sur un système de type Unix, pour qu'un fichier devienne exécutable :
$ svn propset svn:executable ON un-script Propriété 'svn:executable' définie sur 'un-script'
Vous disposez peut-être de règles internes consistant à définir certaines propriétés utiles à vos collègues :
$ svn propset proprietaire sally machin.c Propriété 'proprietaire' définie sur 'machin.c'
Si une erreur a été commise dans le commentaire de propagation
d'une révision donnée et que vous désirez la corriger, utilisez
l'option --revprop
et affectez à
svn:log
le contenu du nouveau
commentaire :
$ svn propset --revprop -r 25 svn:log "Compte-rendu du voyage à New York." Propriété 'svn:log' définie à la révision du dépôt 25
Ou bien si vous ne disposez pas d'une copie de travail, vous pouvez fournir une URL :
$ svn propset --revprop -r 26 svn:log "Jour sans." \ http://svn.red-bean.com/repos Propriété 'svn:log' définie à la révision du dépôt 26
Enfin, vous pouvez indiquer à propset de lire le contenu de la propriété dans un fichier. Vous pourriez même utiliser ceci pour donner une valeur binaire à cette propriété :
$ svn propset icone-du-proprietaire -F sally.jpg bidule.c Propriété 'icone-du-proprietaire' définie sur 'bidule.c'
Note | |
---|---|
Par défaut il n'est pas possible de modifier les propriétés de
révision d'un dépôt Subversion. L'administrateur du dépôt doit
explicitement activer la modification des propriétés de révision
en créant une procédure automatique appelée
|
svn relocate — Faire pointer une copie de travail vers une autre URL racine de dépôt.
svn relocate PREFIX-SRC PREFIX-DST [CHEMINS...]
svn relocate URL-DST [CHEMIN]
Il arrive qu'un administrateur doive changer l'emplacement (tout
du moins du point de vue de l'utilisateur) d'un dépôt. Le contenu du
dépôt ne change pas mais l'URL racine du dépôt si. Le nom d'hôte peut
aussi varier parce que le dépôt est accessible
via une autre machine. Ou encore,
le type d'URL change parce que le dépôt est maintenant accessible en
SSL (en utilisant https://
) au lieu du simple
HTTP). Ainsi, les raisons pour changer l'emplacement d'un dépôt ne
manquent pas. Mais, idéalement, un « changement
d'adresse » d'un dépôt ne devrait pas rendre inutilisable du
jour au lendemain toutes les copies de travail qui pointent vers ce
dépôt. Et heureusement, ce n'est pas le cas. Plutôt que de forcer
les utilisateurs à extraire une nouvelle copie de travail quand un
dépôt est déplacé, Subversion fournit la commande svn
relocate qui modifie les métadonnées de la zone
administrative de la copie de travail pour pointer vers la nouvelle
adresse du dépôt.
La première forme de svn relocate permet de
mettre à jour une ou plusieurs copies en effectuant essentiellement
un rechercher-remplacer dans les URL racines des dépôts des copies
de travail. Subversion remplace la sous-chaîne initiale
PREFIX-SRC
par la chaîne
PREFIX-DST
dans ces URL. Le préfixe
d'URL de la source peut être aussi grand que nécessaire pour le
différencier. Manifestement, pour utiliser cette forme, vous devez
connaître à la fois l'URL racine actuelle du dépôt vers lequel pointe
la copie de travail et la nouvelle URL de ce dépôt. Vous pouvez
utiliser svn info pour déterminer la
première.
La deuxième forme ne requiert pas de connaître l'URL racine du
dépôt actuel vers lequel pointe la copie de travail mais seulement
la nouvelle URL (URL-DST
) vers laquelle
pointer. Avec cette forme, une seule copie de travail peut être
déplacée à la fois.
Avertissement | |
---|---|
Les utilisateurs ont souvent du mal à faire la différence entre svn switch et svn relocate. Voici une règle générale :
|
Commençons par une copie de travail qui pointe vers l'URL d'un dépôt local :
$ svn info | grep URL: URL: file:///var/svn/depot/trunk $
L'administrateur décide de renommer le répertoire qui héberge le dépôt. Nous avons manqué l'annonce et nous nous retrouvons avec une erreur la fois suivante où nous essayons de mettre à jour notre copie de travail.
$ svn up Mise à jour de '.' : svn: E180001: Unable to connect to a repository at URL 'file:///var/svn/depot/trunk' svn: E180001: Impossible d'ouvrir une session ra_local pour l'URL svn: E180001: Le dépôt 'file:///var/svn/depot/trunk' n'a pu être ouvert
Après avoir alpagué l'administrateur à la machine à café, nous prenons connaissance du déplacement du dépôt et de sa nouvelle URL. Plutôt que d'extraire une nouvelle copie de travail, nous demandons simplement à Subversion de modifier les métadonnées de la copie de travail pour pointer vers le nouvel emplacement du dépôt.
$ svn relocate file:///var/svn/nouveau-depot/trunk $
Subversion ne nous dit pas grand chose sur ce qu'il vient de faire mais il n'a pas signalé d'erreur non plus, c'est le principal. Voyons si la copie de travail est de nouveau fonctionnelle :.
$ svn up Updating '.': A lib/nouveau.c M src/code.h M src/headers.h …
Note | |
---|---|
Là encore, cette commande n'affecte que les seules métadonnées de la copie de travail. Elle ne touchera pas au contenu de vos fichiers suivis ou non en versions, ne fera pas d'opérations sur le dépôt (telles que des propagations ou mises à jour), etc. |
Quelques mois plus tard, nous apprenons que la société déplace les machines de développement sur des serveurs dédiés et que nous devons dorénavant utiliser HTTP pour accéder au dépôt. Nous faisons encore pointer notre copie de travail vers un nouvel emplacement :
$ svn relocate http://svn.ma-societe.com/depot/trunk $
Maintenant, chaque fois que nous effectuons un tel déplacement, Subversion contacte le dépôt (à sa nouvelle URL, bien sûr) pour vérifier quelques éléments.
D'abord, il compare l'uuID du dépôt avec la valeur qu'il a stockée dans la copie de travail. Si les UUID ne correspondent pas, le déplacement de la copie de travail n'est pas autorisé. Peut-être ne s'agit-il pas du même dépôt après tout ?
Ensuite, Subversion s'assure que les métadonnées de la copie de travail mise à jour sont conformes à l'emplacement du répertoire à l'intérieur du dépôt. Subversion ne vous laisse pas accidentellement faire pointer une copie de travail d'une branche de votre dépôt vers l'URL d'une autre branche à l'intérieur du même dépôt (c'est le rôle de la commande svn switch décrite dans svn switch (sw).)
Enfin, Subversion n'autorise pas de déplacer une sous-arborescence de la copie de travail. Si vous devez faire pointer la copie de travail vers un nouvel emplacement, vous devez prendre tout le paquet. Cela évite des problèmes d'intégrité pour les métadonnées et protège le comportement de la copie de travail en général (et, soit dit en passant, vous auriez certainement du mal à trouver une bonne raison de déplacer uniquement une partie de votre copie de travail).
Examinons un dernier déplacement possible. Après avoir utilisé
HTTP pendant un certain temps, la société migre vers un accès en SSL
uniquement. Maintenant, le seul changement à l'URL du dépôt concerne
le type d'accès qui passe de http://
à
https://
. Il existe deux façons pour faire pointer
notre copie de travail vers le nouvel emplacement. La première est
de faire exactement comme nous l'avons fait jusqu'ici :
$ svn relocate https://svn.ma-societe.com/depot/trunk $
La deuxième consiste à demander à Subversion de permuter les préfixes qui ont changé dans l'URL :
$ svn relocate http https $
Les deux méthodes produisent une copie de travail avec des métadonnées qui pointent vers le bon emplacement de dépôt.
Par défaut, svn relocate parcourt toutes les
copies de travail externes incluses dans votre copie de travail et
essaie de déplacer aussi ces copies de travail. Utilisez l'option
--ignore-externals
, pour désactiver ce
comportement.
svn resolve — Résoudre les conflits sur les fichiers et répertoires de la copie de travail.
svn resolve [CHEMINS...]
Résoudre les fichiers et répertoires marqués « en
conflit » dans la copie de travail. Cette commande ne résoud
pas sémantiquement les marques de conflit ; cependant, elle
remplace CHEMIN
avec la version spécifiée
par l'argument de l'option --accept
puis supprime
les fichiers créés lors de la signalisation du conflit. Cela permet à
CHEMINS
d'être à nouveau propagés,
c'est-à-dire que Subversion considère que les conflits ont été
« résolus ».
Reportez-vous à la section intitulée « Résolution des conflits » pour une description en profondeur de la gestion de conflits.
Voici un exemple où, après avoir reporté un conflit durant la
mise à jour, svn resolve remplace tous les
conflits du fichier machin.c
par vos
modifications :
$ svn update Conflit découvert dans le fichier 'machin.c'. Sélectionner : (p) report, (df) diff complet, (e) édite, (mc) mine-conflict, (tc) theirs-conflict, (h) aide pour plus d'options :p C machin.c Actualisé à la révision 5. Résumé des conflits : Text conflicts: 1 $ svn resolve --accept mine-full machin.c Conflit sur 'machin.c' résolu
svn resolved — Obsolète. Supprimer les marques « en conflit » des fichiers et répertoires de la copie de travail.
svn resolved CHEMINS...
Cette commande est obsolète et a été remplacée par svn
resolve --accept working
. Lisez svn resolve dans la section précédente pour
plus de détails.CHEMINS
Supprimer les marques « en conflit » sur les fichiers
et répertoires de la copie de travail. Cette commande ne résoud pas
sémantiquement les conflits ; elle supprime simplement les
fichiers créés lors de la signalisation du conflit et permet à
CHEMINS
d'être à nouveau propagés.
C'est-à-dire qu'elle indique à Subversion que les conflits ont été
résolus. Reportez-vous à la section intitulée « Résolution des conflits »
pour une description en profondeur de la gestion des conflits.
Si une mise à jour détecte un conflit, votre copie de travail comporte trois nouveaux fichiers :
$ svn update C machin.c Actualisé à la révision 31. $ ls machin.c machin.c.mine machin.c.r30 machin.c.r31
Une fois que vous avez résolu les conflits et que
machin.c
est prêt à être propagé, lancez
svn resolved pour indiquer à votre copie de
travail que vous avez pris les choses en main.
Avertissement | |
---|---|
Vous pouvez simplement supprimer les fichiers associés au conflit et effectuer une propagation, mais svn resolved met à jour des données de suivi dans la zone d'administration en plus de supprimer les fichiers associés au conflit. C'est pourquoi nous recommandons d'utiliser cette commande. |
svn revert — Restaurer l'état initial.
svn revert CHEMINS...
Restaurer l'état des fichiers et répertoires en annulant les modifications apportées localement et supprime les marques de conflit. svn revert restaure non seulement le contenu des éléments de la copie de travail, mais également les valeurs des propriétés. En fait, vous pouvez l'utiliser pour annuler toute opération planifiée que vous avez initiée (par exemple, l'ajout ou la suppression de fichiers peuvent être « déplanifiés »).
Annuler les changements apportés à un fichier :
$ svn revert machin.c 'machin.c' réinitialisé
Si vous voulez restaurer l'état initial de tout un répertoire,
utilisez l'option --depth=infinity
:
$ svn revert --depth=infinity . 'nouveau-rep/un-fichier' réinitialisé 'machin.c' réinitialisé 'bidule.txt' réinitialisé
Enfin, pour annuler toute opération planifiée :
$ svn add betise.txt oulala A betise.txt A oulala A oulala/opla.c $ svn revert betise.txt oulala 'betise.txt' réinitialisé 'oulala' réinitialisé $ svn status ? betise.txt ? oulala
Avertissement | |
---|---|
svn revert est dangereux par nature puisque sa finalité est de supprimer des données (vos modifications non propagées). Une fois lancée, Subversion ne peut en aucun cas récuperer les modifications non propagées. Si vous ne spécifiez aucune cible à svn revert, elle ne fait rien — ce comportement est destiné à vous protéger d'une perte accidentelle de données de votre copie de travail. Vous devez fournir au moins une cible à svn revert. |
svn status (stat, st) — Afficher l'état des fichiers et des répertoires de la copie de travail.
svn status [CHEMIN...]
Afficher l'état des fichiers et des répertoires de la copie de
travail. Sans arguments, elle affiche simplement les éléments
modifiés (pas d'accès au dépôt). Avec l'option
--show-updates
(-u
), elle affiche
la révision en cours et les éléments obsolètes. Avec l'option
--verbose
(-v
), elle affiche les
informations de révision complètes pour chaque élément. Avec l'option
--quiet
(-q
), elle affiche
uniquement des informations résumées sur les éléments modifiés
localement.
Les sept premières colonnes de l'affichage mesurent un caractère de large et chaque colone apporte des informations complémentaires sur chaque élément de la copie de travail.
La première colonne indique si un élément est ajouté, supprimé ou modifié :
' '
Pas de modification.
'A'
Élement prévu d'être ajouté.
'D'
Élément prévu d'être supprimé (Deletion en anglais).
'M'
Élément modifié.
'R'
Élément remplacé dans la copie de travail. Cela veut dire que le fichier a été prévu d'être supprimé puis un nouveau fichier avec le même nom a été prévu d'être ajouté à sa place.
'C'
Le contenu (par opposition aux propriétés) de l'élément est en conflit avec les mises à jour reçues depuis le dépôt.
'X'
Élément faisant partie d'une définition externe.
'I'
Élément ignoré (par exemple en raison d'une propriété
svn:ignore
).
'?'
Élément non suivi en versions.
'!'
Élément manquant (par exemple si vous l'avez déplacé ou effacé sans utiliser la commande svn). Cela indique également qu'un répertoire n'est pas complet (une extraction ou une mise à jour a été interrompue).
'~'
Élément géré en tant qu'un certain type d'objet (fichier, répertoire, lien) mais qui a été remplacé par un objet de type différent.
La deuxième colonne indique l'état des propriétés des fichiers ou répertoires :
' '
Pas de modification.
'M'
Les propriétés de l'élément ont été modifiées.
'C'
Les propriétés de cet élément sont en conflit avec les mises à jour des propriétés reçues depuis le dépôt.
La troisième colonne indique si le répertoire de la copie de travail est verrouillé (voir la section intitulée « Parfois, il suffit de faire le ménage ») :
' '
Élément non verrouillé.
'L'
Élément verrouillé (Locked en anglais).
La quatrième colonne indique si la prochaine propagation de l'élément comportera une reprise de l'historique :
' '
Pas de reprise de l'historique prévue.
'+'
Ajout avec reprise de l'historique prévue.
La cinquième colonne indique si l'élément est ré-aiguillé par rapport à son parent (voir la section intitulée « Parcours des branches ») :
' '
L'élément est un fils du répertoire parent.
'S'
L'élément a été ré-aiguillé (Switched en anglais).
La sixième colonne fournit les informations de verrouillage :
' '
Quand --show-updates
(-u
)
est spécifiée, le fichier n'est pas verrouillé. Si
--show-updates
(-u
)
n'est pas spécifiée, cela veut simplement
dire que le fichier n'est pas verrouillé dans la copie de
travail.
'K'
Fichier verrouillé par cette copie de travail (locKed en anglais).
'O'
Fichier verrouillé soit par un autre utilisateur, soit par
une autre copie de travail. Ceci n'est possible qu'en utilisant
l'option --show-updates
(-u
).
'T'
Fichier verrouillé par cette copie de travail mais le
verrou a été « volé » et n'est plus valide
(stolen en anglais). Le fichier
est verrouillé dans le dépôt. Ceci n'est possible qu'en
utilisant l'option --show-updates
(-u
).
'B'
Fichier verrouillé par cette copie de travail mais le
verrou a été « cassé » et n'est plus valide
(broken en anglais). Le fichier
n'est plus verrouillé. Ceci n'est possible qu'en utilisant
l'option --show-updates
(-u
).
La septième colonne concerne les éléments qui sont en conflit d'arborescence :
' '
Élément qui ne fait pas partie d'un conflit d'arborescence.
'C'
Élément qui fait partie d'un conflit d'arborescence.
La huitième colonne est toujours vide.
Les informations relatives à l'obsolescence apparaissent
dans la neuvième colonne (uniquement si l'option
--show-updates
(-u
) est
spécifiée) :
' '
L'élément de la copie de travail est à jour.
'*'
Une nouvelle version de l'élément existe sur le serveur.
Les champs restants sont de largeur variable et séparés
par des espaces. Le numéro de la révision de travail est le champ
suivant si l'option --show-updates
(-u
) ou
--verbose
(-v
) est
spécifiée.
Si l'option --verbose
(-v
) est spécifiée, le numéro et l'auteur de la
dernière révision propagée sont affichés.
Le chemin de la copie de travail est toujours le dernier champ affiché et peut inclure des espaces.
Voici la manière la plus facile de déterminer les modifications que vous avez apportées à votre copie de travail :
$ svn status wc M wc/bidule.c A + wc/qax.c
Si vous voulez trouver quels fichiers dans votre copie de travail
sont obsolètes, spécifiez l'option --show-updates
(-u
). Cela ne modifiera pas
votre copie de travail. Dans l'exemple suivant, vous pouvez voir que
wc/machin.c
a été modifié dans le dépôt depuis
la dernière mise à jour dans notre copie de travail :
$ svn status --show-updates wc M 965 wc/bidule.c * 965 wc/machin.c A + 965 wc/qax.c État par rapport à la révision 981
Note | |
---|---|
|
Le maximum d'informations que vous pouvez obtenir à l'aide de la sous-commande status est le suivant :
$ svn status -u -v wc M 965 938 sally wc/bidule.c * 965 922 harry wc/machin.c A + 965 687 harry wc/qax.c 965 687 harry wc/zig.c État par rapport à la révision 981
Enfin, vous pouvez demander à svn status
d'afficher les résultats au format XML en spéficiant l'option
--xml
:
$ svn status --xml wc <?xml version="1.0"?> <status> <target path="wc"> <entry path="qax.c"> <wc-status props="none" item="added" revision="0"> </wc-status> </entry> <entry path="bidule.c"> <wc-status props="normal" item="modified" revision="965"> <commit revision="965"> <author>sally</author> <date>2008-05-28T06:35:53.048870Z</date> </commit> </wc-status> </entry> </target> </status>
Pour beaucoup plus d'exemples utilisant la commande svn status, lisez la section intitulée « Vue d'ensemble des changements effectués ».
svn switch (sw) — Mettre à jour la copie de travail à partir d'une nouvelle URL.
svn switch URL[@REV_PIVOT] [CHEMIN]
svn switch --relocate FROM TO [CHEMIN...]
La première forme de cette sous-commande (sans l'option
--relocate
) actualise votre copie de travail en la
faisant pointer sur une nouvelle URL. C'est la manière de faire avec
Subversion pour utiliser une nouvelle branche pour votre copie de
travail. Si REV_PIVOT
est spécifié, cela
indique dans quelle révision chercher pour déterminer la cible.
Reportez-vous à la section intitulée « Parcours des branches » pour une
description en profondeur de la gestion des branches.
Note | |
---|---|
À partir de Subversion 1.7, la commande svn
switch demande par défaut que l'URL vers laquelle vous
faites pointer votre copie de travail possède un ancêtre commun
avec la copie de travail actuelle. Vous pouvez passer outre ce
comportement en spécifiant l'option
|
Si l'option --force
est utilisée, les chemins
non gérés en versions de la copie de travail qui font obstacle à
l'ajout, par la commande de ré-aiguillage, de chemins ayant le même
nom ne font pas échouer automatiquement l'opération. Si le chemin
faisant obstacle est du même type (fichier ou répertoire) que le
chemin correspondant dans le dépôt, il passe sous gestion de versions
mais son contenu est laissé tel quel dans la copie de travail. Cela
veut dire que les enfants d'un répertoire non géré en versions
peuvent également faire obstacle et se retrouver gérés en versions.
Pour les fichiers, toute différence entre l'obstacle et le dépôt est
gérée comme une modification locale à la copie de travail. Toutes les
propriétés du dépôt sont appliquées au chemin qui fait
obstacle.
Comme pour la plupart des sous-commandes, vous pouvez limiter le
périmètre d'action de l'opération de ré-aiguillage à une profondeur
de l'arborescence en utilisant l'option --depth
. De
la même manière, vous pouvez utiliser l'option
--set-depth
pour définir un nouveau niveau de
récursion « permanent » associé à la cible de
ré-aiguillage.
L'option --relocate
est obsolète depuis
Subversion 1.7. Utilisez à la place la commande
svn relocate (décrite dans svn relocate) pour suivre un déplacement du
dépôt.
Vous pointez actuellement vers le répertoire
vendors
qui a fait l'objet d'un déplacement vers
le répertoire vendors-with-fix
. Vous voulez
maintenant que votre copie de travail pointe vers cette nouvelle
branche :
$ svn switch http://svn.red-bean.com/repos/branches/vendors-with-fix . U mon-projet/machin.txt U mon-projet/bidule.txt U mon-projet/truc.c U mon-projet/qux.c À la révision 31.
Pour revenir sur la branche initiale, vous n'avez qu'à fournir l'emplacement dans le dépôt à partir duquel vous avez extrait votre copie de travail :
$ svn switch http://svn.red-bean.com/repos/trunk/vendors . U mon-projet/machin.txt U mon-projet/bidule.txt U mon-projet/truc.c U mon-projet/qux.c À la révision 31.
Astuce | |
---|---|
Vous pouvez ne ré-aiguiller qu'une partie de votre copie de travail vers une branche si vous ne voulez pas basculer l'ensemble de votre copie de travail, mais ce n'est pas recommandé en général. Il est très aisé d'oublier que vous l'avez fait et ainsi de propager accidentellement des modifications à la fois à la branche ré-aiguillée et celle qui n'a pas bougé de votre arborescence. |
svn unlock — Déverrouiller des chemins de la copie de travail ou des URL.
svn unlock CIBLE...
Déverrouiller chaque CIBLE
. Si une
CIBLE
est verrouillée par un autre
utilisateur ou s'il n'existe pas de jeton de verrouillage valide dans
la copie de travail, affiche un avertissement et continue à
déverrouiller le reste des CIBLE
s.
Utilisez l'option --force
pour casser un verrou
appartenant à un autre utilisateur ou à une autre copie de
travail.
Déverrouiller deux fichiers de votre copie de travail :
$ svn unlock arbre.jpg maison.jpg '/arbre.jpg' déverrouillé. '/maison.jpg' déverrouillé.
Déverrouiller un fichier dans votre copie de travail qui est verrouillé par un autre utilisateur :
$ svn unlock arbre.jpg svn: 'arbre.jpg' n'est pas verrouillé dans cette copie de travail $ svn unlock --force arbre.jpg 'arbre.jpg' déverrouillé.
Déverrouiller un fichier sans copie de travail :
$ svn unlock http://svn.red-bean.com/depot/test/arbre.jpg 'arbre.jpg' déverrouillé.
Pour plus de détails, reportez-vous à la section intitulée « Verrouillage ».
svn update (up) — Mettre à jour la copie de travail.
svn update [CHEMIN...]
svn update actualise la copie de travail par
rapport au dépôt. Si aucune révision n'est spécifiée, elle actualise
par rapport à la révision HEAD
. Sinon, elle
synchronise la copie de travail à la révision spécifiée par l'option
--revision
. La procédure de synchronisation suivie
par svn update inclut la suppression des verrous
dépassés (voir la section intitulée « Parfois, il suffit de faire le ménage ») trouvés dans la
copie de travail.
Pour chaque élément mis à jour, elle affiche une ligne avec un caractère indiquant l'action effectuée. Ces caractères ont la signification suivante :
A
Ajouté.
B
Verrou cassé (troisième colonne seulement — broken en anglais).
D
Effacé (deleted en anglais).
U
Mis à jour (Updated en anglais).
C
En conflit.
G
Fusionné (merged en anglais).
E
Existant.
Un caractère dans la première colonne signifie une mise à jour du fichier existant, alors que les mises à jour des propriétés de fichiers apparaissent dans la deuxième colonne. Les informations de verrouillage sont affichées dans la troisième colonne.
Comme pour la plupart des sous-commandes, vous pouvez limiter le
périmètre d'action de l'opération de mise à jour à une profondeur de
l'arborescence en utilisant l'option --depth
. De la
même manière, vous pouvez utiliser l'option
--set-depth
pour définir un nouveau niveau de
récursion associé à la cible de mise à jour.
Récupèrer les modifications apportées au dépôt depuis la dernière mise à jour :
$ svn update A nouveau-rep/toggle.c A nouveau-rep/disclose.c A nouveau-rep/launch.c D nouveau-rep/LISEZ-MOI Actualisé à la révision 32.
Vous pouvez aussi « mettre à jour » votre copie de travail vers une vieille révision (Subversion ne connait pas le concept de fichier « sticky » défini dans CVS ; reportez-vous à Annexe B, Guide Subversion à l'usage des utilisateurs de CVS) :
$ svn update -r30 A nouveau-rep/LISEZ-MOI D nouveau-rep/toggle.c D nouveau-rep/disclose.c D nouveau-rep/launch.c U machin.c Actualisé à la révision 30.
Astuce | |
---|---|
Si vous voulez examiner un seul fichier dans une révision antérieure, vous pouvez préférer l'utilisation de svn cat — cela ne modifiera pas votre copie de travail. |
svn update constitue le premier mécanisme
pour configurer des copies de travail à répertoires clairsemés. Quand
vous l'utilisez avec l'option --set-depth
, la mise
à jour omet ou réintègre individuellement les membres de la copie de
travail en modifiant leur profondeur associée vers la profondeur
spécifiée (en allant chercher l'information dans le dépôt si
nécessaire). Reportez-vous à la section intitulée « Répertoires clairsemés » pour plus d'informations sur les répertoires clairsemés.
Vous pouvez mettre à jour plusieurs cibles avec une seule commande, Subversion omet silencieusement les cibles qui ne sont pas suivies en versions et, depuis Subversion 1.7, inclut un résumé de la mise à jour qu'il vient d'effectuer :
$ cd mes-projets $ svn update * Mise à jour de 'calc' : U bouton.c U entier.c À la révision 394. Skipped 'tempfile.tmp' Mise à jour de 'paint' : A palettes.c U brushes.c À la révision 60. Mise à jour de 'ziptastic' : À la révision 43. Résumé des mises à jour : 'calc' actualisé à la révision 394. 'paint' actualisé à la révision 60. 'zipstatic' actualisé à la révision 43. Résumé des conflits : Skipped paths: 1 $
svn upgrade — Mettre à niveau le format de stockage des métadonnées d'une copie de travail.
svn upgrade [CHEMIN...]
Au fur et à mesure que les versions de Subversion se succèdent, le format de stockage des métadonnées des copies de travail évolue pour prendre en compte de nouvelles fonctionnalités ou corriger des bugs. Les vieilles versions de Subversion mettent à niveau automatiquement les copies de travail vers le nouveau format la première fois que le logiciel est utilisé. À partir de Subversion 1.7, la mise à niveau des copies de travail doit être effectué explicitement par l'utilisateur. svn upgrade permet de déclencher cette mise à niveau.
Si vous essayez d'utiliser Subversion 1.7 sur une copie de travail créée avec une ancienne version de Subversion, vous obtenez l'erreur suivante :
$ svn status svn: E155036: Please see the 'svn upgrade' command svn: E155036: Working copy '/home/sally/project' is too old (format 10, create d by Subversion 1.6) $
Utilisez la commande svn upgrade pour mettre à niveau la copie de travail vers le format le plus récent de stockage des métadonnées compris par votre version de Subversion.
$ svn upgrade Upgraded '.' Upgraded 'A' Upgraded 'A/B' Upgraded 'A/B/E' Upgraded 'A/B/F' Upgraded 'A/C' Upgraded 'A/D' Upgraded 'A/D/G' Upgraded 'A/D/H' $ svn status D A/B/E/alpha M A/D/gamma A A/newfile $
Notez que svn upgrade conserve les modifications locales présentes dans la copie de travail au moment de la mise à niveau.
Avertissement | |
---|---|
De même que pour les mises à niveau automatiques effectuées par le passé, les copies de travail mises à niveau explicitement sont inutilisables avec les anciennes versions de Subversion. |
svnadmin est l'outil d'administration pour surveiller et réparer votre dépôt Subversion. Pour des informations détaillées sur l'administration d'un dépôt, reportez-vous à la section intitulée « svnadmin ».
Comme svnadmin fonctionne par un accès direct au dépôt (et ne peut ainsi être utilisé que sur la machine qui héberge le dépôt), il fait référence au dépôt par un chemin et non par une URL.
Les options de svnadmin sont globales, de la même manière que pour svn :
Options de svnadmin
--bdb-log-keep
(spécifique au magasin de données Berkeley DB) désactiver la suppression des fichiers de journalisation automatique de la base de données. Disposer de ces fichiers de journalisation peut être appréciable si vous devez effectuer une restauration après une panne catastrophique sur le dépôt.
--bdb-txn-nosync
(spécifique au magasin de données Berkeley DB)
désactiver fsync lors des validations des transactions de
la base de données. Utilisée avec la commande
svnadmin create pour créer un dépôt avec
magasin de données Berkeley DB dont l'option
DB_TXN_NOSYNC
est activée (cela
améliore la vitesse du dépôt mais comporte certains
risques).
--bypass-hooks
Ne pas utiliser le système des procédures automatiques du dépôt.
--bypass-prop-validation
Lors du chargement d'un fichier dump, ne pas utiliser le système qui valide les valeurs des propriétés.
--clean-logs
Supprimer les fichiers de journalisation inutiles de la base de données Berkeley DB.
--compatible-version
ARG
Utiliser le format de dépôt compatible avec la version
ARG
de Subversion.
--config-dir
REPERTOIRE
Lire la configuration dans le répertoire spécifié au
lieu de l'endroit par défaut
(.subversion
dans le répertoire de
l'utilisateur).
--deltas
Lors de la création d'un fichier dump du dépôt, écrire les modifications dans les propriétés suivies en versions et le contenu des fichiers sous la forme de deltas par rapport à leurs valeurs précédentes.
--file
(-F
) NOM_FICHIER
Utiliser le contenu du fichier passé en paramètre pour la sous-commande.
--fs-type
ARG
Lors de la création d'un dépôt, utiliser
ARG
comme type de magasin de
données.
ARG
peut valoir soit
bdb
, soit fsfs
.
--force-uuid
Par défaut, lorsque des données sont introduites dans
un dépôt qui contient déjà des révisions,
svnadmin ignore l'UUID
du flux dump. Cette option force le dépôt à adopter
l'UUID
indiqué dans le flux dump.
--ignore-uuid
Par défaut, lorsque des données sont introduites dans
un dépôt vide, svnadmin prend
l'UUID
fourni par le flux dump. Cette
option force le dépôt à ignorer l'UUID
du
flux.
--incremental
Lors de la décharge (dump) d'une révision, ne produit que la différence avec la révision précédente plutôt que le texte complet habituel.
--memory-cache-size
(-M
) ARG
Configurer la taille (en mégaoctets) de la mémoire
cache utilisée pour les opérations redondantes. La valeur
par défaut est 16
. Cette valeur n'est
utilisée que pour les magasins de données de type
FSFS.
--parent-dir
REPERTOIRE
Lors du chargement d'un flux dump, prend
REPERTOIRE
comme racine de
l'arborescence plutôt que
/
.
--pre-1.4-compatible
Obsolète. Voir l'option
--compatible-version
. Lors de la création
d'un nouveau dépôt, utiliser un format compatible avec les
versions de Subversion antérieures à Subversion 1.4.
--pre-1.5-compatible
Obsolète. Voir l'option
--compatible-version
. Lors de la création
d'un nouveau dépôt, utiliser un format compatible avec les
versions de Subversion antérieures à Subversion 1.5.
--pre-1.6-compatible
Obsolète. Voir l'option
--compatible-version
. Lors de la création
d'un nouveau dépôt, utiliser un format compatible avec les
versions de Subversion antérieures à Subversion 1.6.
--revision
(-r
) ARG
Spécifie une révision particulière sur laquelle s'effectue l'opération.
--quiet
(-q
)Ne pas afficher le déroulement de l'opération — afficher uniquement les erreurs.
--use-post-commit-hook
Lors du chargement d'un fichier dump, exécuter la
procédure automatique post-commit
du
dépôt après chaque nouvelle révision chargée.
--use-post-revprop-change-hook
Lors du changement d'une propriété de révision,
exécuter la procédure automatique
post-revprop-change
du dépôt après la
modification de la propriété.
--use-pre-commit-hook
Lors du chargement d'un fichier dump, exécuter la
procédure automatique pre-commit
du
dépôt avant de conclure chaque nouvelle révision chargée.
Si la procédure automatique échoue, la propagation est
abandonnée et la procédure de chargement s'arrête.
--use-pre-revprop-change-hook
Lors du changement d'une propriété de révision,
exécuter la procédure automatique
pre-revprop-change
du dépôt avant de
modifier la propriété. Si la procédure automatique échoue,
la modification est annulée et le programme s'arrête.
--wait
Pour les opérations qui nécessitent un accès exclusif au dépôt, attendre jusqu'à ce que le verrou du dépôt se libère au lieu de s'arrêter immédiatement avec une erreur.
svnadmin crashtest — Simuler l'arrêt brutal d'un processus.
svnadmin crashtest CHEMIN_DÉPÔT
Ouvrir le dépôt situé à
CHEMIN_DÉPÔT
, puis s'arrêter. Cela
simule un processus qui se termine brutalement alors qu'il
détient un descripteur ouvert sur le dépôt. Cette
sous-commande est utilisée pour tester le rétablissement
automatique du dépôt (une nouvelle fonctionnalité de
Berkeley DB 4.4). Il est peu probable que vous ayez besoin
de lancer cette sous-commande.
svnadmin create — Créer un nouveau dépôt vide.
svnadmin create CHEMIN_DÉPÔT
Créer un nouveau dépôt vide à l'emplacement spécifié. Si
le répertoire spécifié n'existe pas, il est créé pour
vous[82]. Depuis Subversion
1.2, svnadmin crée les nouveaux dépôts en
utilisant le magasin de données FSFS
par
défaut.
Bien que svnadmin create crée le
répertoire de base pour un nouveau dépôt, il ne crée pas les
répertoires intermédiaires. Par exemple, si vous avez un
répertoire vide appelé /var/svn
, créer
/var/svn/depot
fonctionne, alors que la
tentative de créer
/var/svn/sous-repertoire/depot
échoue
avec une erreur. Gardez aussi en mémoire que, en fonction de
l'endroit où vous créez votre dépôt, vous devrez peut-être
lancer svnadmin create sous l'identité d'un
utilisateur avec privilèges (tel que
root
).
Créer un nouveau dépôt est aussi simple que ça :
$ cd /var/svn $ svnadmin create depot $
Dans Subversion 1.0, un dépôt est toujours créé avec un
magasin de données Berkeley DB. Dans Subversion 1.1, le
magasin de données par défaut est Berkeley DB, mais un
magasin de données FSFS peut être demandé
via l'option
--fs-type
:
$ cd /var/svn $ svnadmin create depot --fs-type fsfs $
[82] Rappelez-vous que svnadmin ne fonctionne qu'avec des chemins sur votre système de fichiers local, pas avec des URL.
svnadmin deltify — Ne stocker que les différences dans un intervalle de révisions.
svnadmin deltify [-r BAS[:HAUT]] CHEMIN_DÉPÔT
svnadmin deltify n'existe dans les versions actuelles de Subversion que pour des raisons historiques. Cette commande est désormais obsolète.
Elle date du temps où Subersion offrait un contrôle plus fin à l'administrateur sur les stratégies de compression des données dans le dépôt. Cela s'est avéré être beaucoup de complexité pour un gain très faible, c'est pourquoi cette « fonctionnalité » a disparu.
svnadmin dump — Décharger le contenu du système de fichiers vers
stdout
.
svnadmin dump CHEMIN_DÉPÔT [-r BAS[:HAUT]] [--incremental] [--deltas]
Décharger le contenu du système de fichiers vers
stdout
dans le format portable
« dump », L'avancement de l'opération est envoyé vers
stderr
. Les révisions de
BAS
jusqu'à
HAUT
sont déchargées. Si aucune
révision n'est spécifiée, toutes les révisions sont déchargées.
Si seule BAS
est spécifiée, décharge
uniquement cette révision. Reportez-vous à la section intitulée « Migration des données d'un dépôt » pour la description
pratique de l'utilisation de cette commande.
Par défaut, le flux dump Subversion ne contient qu'une seule révision (la première dans l'intervalle demandé) dans laquelle tous les fichiers et les répertoires sont indiqués comme ayant été ajoutés d'un seul coup ; les autres révisions (spécifiées par l'intervalle de révisions) ne contiennent que les fichiers et les répertoires qui ont été modifiés par ces révisions. Pour un fichier modifié, le contenu entier du fichier (en représentation plein-texte), ainsi que ses propriétés, est présent dans le fichier dump. Pour un répertoire, toutes les propriétés sont présentes.
Deux options modifient le comportement par défaut du
générateur de flux dump. La première est l'option
--incremental
qui force la première révision
à ne contenir que les fichiers et répertoires modifiés lors de
cette révision (au lieu de l'ensemble de l'arborescence) au même
format que les autres révisions d'un flux dump. Cette option est
utile pour générer un fichier dump relativement petit pour être
chargé dans un autre dépôt qui est déjà au courant des révisions
précédentes du dépôt original.
L'autre option est --deltas
. Cette option
indique à svnadmin dump de, au lieu de
générer des représentations en plein-texte du contenu des
fichiers et la liste des propriétés, générer uniquement le delta
des éléments concernés par rapport à leur version antérieure.
Cette option réduit (drastiquement dans certains cas) la taille
du fichier dump produit par svnadmin dump. Il
y a cependant des inconvénients à utiliser cette option :
la production de fichiers dump delta est plus consommatrice de
puissance CPU, ces fichiers ne peuvent pas être traités par
svndumpfilter et ils se révèlent être moins
facilement compressés par des outils tiers tels que
gzip ou bzip2.
Astuce | |
---|---|
À partir de Subversion 1.8,
svndumpfilter peut traiter les flux
« deltifiés ». Avant cette version,
svndumpfilter ne pouvait pas traiter les
flux dump générés en utilisant l'option
|
Décharger complètement le dépôt :
$ svnadmin dump /var/svn/depot > depot-complet.dump * Révision 0 déchargée. * Révision 1 déchargée. * Révision 2 déchargée. …
Décharger seulement l'incrément d'une seule révision du dépôt :
$ svnadmin dump /var/svn/depot -r 21 --incremental > increment.dump * Révision 21 déchargée.
svnadmin freeze — Empêcher les propagations vers le dépôt pendant que vous faites tourner un autre programme.
svnadmin freeze CHEMIN_DÉPÔT PROGRAMME [ARG...]
svnadmin freeze --file NOM_FICHIER PROGRAMME [ARG...]
Cette sous-commande empêche des propagations concourantes
sur le dépôt CHEMIN_DÉPÔT
(i.e. elle « gèle »,
freeze en anglais, le dépôt)
pendant que PROGRAMME
s'exécute avec
les arguments ARG
. Les clients qui
essaient de propager des modifications sont mis en attente
jusqu'à ce que le dépôt soit de nouveau disponible. Cette
sous-commande a pour vocation de permettre des sauvegardes à
chaud par des outils tiers tels que
rsync.
Si l'option --file
est utilisée, alors
tous les dépôts listés dans
NOM_FICHIER
sont gelés. Le format de
ce fichier est une liste de
CHEMIN_DÉPÔT
, séparés par des sauts
de ligne. Les dépôts sont gelés dans l'ordre dans lequel ils
sont listés dans le fichier.
svnadmin hotcopy — Effectuer une copie à chaud d'un dépôt.
svnadmin hotcopy CHEMIN_DÉPÔT
NOUVEAU_CHEMIN_DÉPÔT
Cette commande effectue une sauvegarde « à chaud » de votre dépôt, y compris les procédures automatiques, les fichiers de configuration et, bien sûr, les fichiers de la base de données. Vous pouvez lancer cette commande à n'importe quel moment pour effectuer une sauvegarde de votre dépôt, indépendamment de l'activité concernant votre dépôt.
Avant Subversion 1.8, svnadmin hotcopy
effectuait obligatoirement une copie complète du dépôt source.
À partir de Subversion 1.8, elle sait effectuer des copies
incrémentales vers un dépôt déjà existant, copie du dépôt
source. En passant l'option --incremental
à
svnadmin hotcopy, vous pouvez demander à
Subversion de copier seulement les nouvelles révisions et les
révisions dont la taille ou l'horodatage ont été modifiés.
L'UUID du dépôt de destination doit être identique à l'UUID du
dépôt source. Le mode de copie à chaud n'est disponible que pour
les dépôts avec un magasin de données FSFS.
Si vous spécifiez l'option --clean-logs
,
svnadmin effectue la copie à chaud de votre
dépôt et supprime ensuite les journaux inutiles de la base de
données Berkeley DB du dépôt original.
Avertissement | |
---|---|
Comme indiqué dans la section intitulée « Limites architecturales », les dépôts Berkeley DB copiés à chaud ne sont pas portables d'un système d'exploitation à l'autre, ni entre des machines dont l'architecture CPU est différente (ordonnancement différent des bits de poids fort et de poids faible ou « endianness »). |
svnadmin list-dblogs — Demander à la base de données Berkeley DB quels sont
les fichiers de journalisation existants pour un dépôt
Subversion donné (s'applique uniquement aux dépôts dont le
magasin de données est du type
bdb
).
svnadmin list-dblogs CHEMIN_DÉPÔT
Le gestionnaire de bases de données Berkeley DB crée des
fichiers de journalisation de tous les changements apportés au
dépôt, ce qui permet un rétablissement si une catastrophe
survient. À moins d'activer l'option
DB_LOG_AUTOREMOVE
, les fichiers de
journalisation s'accumulent, bien que la plupart ne soient plus
utilisés et puissent être supprimés pour récupérer de l'espace
disque. Reportez-vous à la section intitulée « Gestion de l'espace disque » pour davantage
d'information.
svnadmin list-unused-dblogs — Demander au gestionnaire Berkeley DB quels fichiers de
journalisation peuvent être effacés (s'applique uniquement aux
dépôts dont le magasin de données est du type
bdb
).
svnadmin list-unused-dblogs
CHEMIN_DÉPÔT
Le gestionnaire de bases de données Berkeley DB crée des
fichiers de journalisation de tous les changements apportés au
dépôt, ce qui permet un rétablissement si une catastrophe
survient. À moins d'activer l'option
DB_LOG_AUTOREMOVE
, les fichiers de
journalisation s'accumulent, bien que la plupart ne soient plus
utilisés et puissent être supprimés pour récupérer de l'espace
disque. Reportez-vous à la section intitulée « Gestion de l'espace disque » pour davantage
d'information.
svnadmin load — Charger un flux dump à partir de
stdin
.
svnadmin load CHEMIN_DÉPÔT
[-r BAS[:HAUT]]
Charger un flux dump depuis stdin
, en
propageant de nouvelles révisions dans le système de fichiers du
dépôt. L'avancement de l'opération est affiché sur
stdout
. Si aucune révision n'est passée en
paramètre, lire et propager toutes les révivsions. Mais si
l'option --revision
(-r
) est
fournie, lire et propager de la révision
BAS
jusqu'à
la révision HAUT
seulement. Si seule
BAS
est fournie, charger uniquement
cette révision.
Avant Subversion 1.8, svnadmin load ne
savait que charger toutes les révisions que le flux dump
contenait. Aujourd'hui, svnadmin load
reconnait l'option --revision
(-r
) qui agit comme un
filtre pour le flux de révisions. Cela permet de ne charger
qu'un intervalle de révisions à partir d'un flux dump, et ainsi
d'effectuer la maintenance ou la réorganisation du dépôt
beaucoup plus facilement.
Cet exemple montre le début de chargement d'un dépôt à partir d'un fichier de sauvegarde (créé, bien sûr, avec la commande svnadmin dump) :
$ svnadmin load /var/svn/restauré < sauvegarde-depot <<< Début d'une nouvelle transaction basée sur la révision 1 * ajout de : test ... fait. * ajout de : test/a ... fait. …
Ou, si vous voulez le charger dans un sous-répertoire :
$ svnadmin load --parent-dir nouveau/sous-repertoire/pour/projet \ /var/svn/restauré < sauvegarde-depot <<< Début d'une nouvelle transaction basée sur la révision 1 * ajout de : test ... fait. * ajout de : test/a ... fait. …
Les nouvelles versions de Subversion sont devenues plus
strictes sur le format des valeurs des propriétés internes à
Subversion. Bien sûr, les propriétés créées avec les anciennes
versions de Subversions n'ont pas bénéficié de cette rigueur et
peuvent s'avérer mal formatées. Les flux dump stockent les
valeurs de propriétés telles quelles. Ceci peut conduire, lors
de chargement de flux avec Subversion 1.8 de valeurs de propriétés
mal formatées dans le dépôt, à des erreurs de
validation. Il existe plusieurs palliatifs. Une première option
consiste à réparer manuellement les valeurs de propriétés qui
posent problème dans le dépôt source et regénérer un flux dump.
Une deuxième solution consiste à modifier manuellement le flux
dump lui-même pour corriger les valeurs de propriétés. Enfin, si
vous n'avez pas envie de corriger le problème tout de suite, vous
pouvez utiliser l'option
--bypass-prop-validation
avec
svnadmin load.
svnadmin lock — Verrouiller un chemin dans le dépôt directement.
svnadmin lock CHEMIN_DÉPÔT CHEMIN_DANS_DÉPÔT
NOM_UTILISATEUR FICHIER [JETON]
svnadmin lslocks — Afficher la description de tous les verrous.
svnadmin lslocks CHEMIN_DÉPÔT
[CHEMIN_DANS_DÉPÔT]
Afficher la description de tous les verrous dans le dépôt
CHEMIN_DÉPÔT
sous le chemin
CHEMIN_DANS_DÉPÔT
. Si
CHEMIN_DANS_DÉPÔT
n'est pas fourni,
la valeur par défaut est la racine du dépôt.
Afficher l'unique fichier verrouillé dans le dépôt situé
dans /var/svn/depot
:
$ svnadmin lslocks /var/svn/depot Chemin : /arbre.jpg Chaîne UUID : opaquelocktoken:ab00ddf0-6afb-0310-9cd0-dda813329753 Propriétaire : harry Créé : 2005-07-08 17:27:36 -0500 (ven. 08 Jul 2005) Expire : Commentaire (1 ligne): Retouche sur la branche la plus haute du cyprès plat au premier plan.
svnadmin lstxns — Afficher le nom de toutes les transactions mortes.
svnadmin lstxns CHEMIN_DÉPÔT
Afficher le nom de toutes les transactions inachevées. Reportez-vous à la section intitulée « Suppression des transactions mortes » pour savoir comment des transactions peuvent être mortes et ce que vous devriez faire avec.
svnadmin pack — Compacter le dépôt vers un mode de stockage plus efficace, si possible.
svnadmin pack CHEMIN_DÉPÔT
Voir la section intitulée « Tasser le système de fichiers FSFS » pour davantage d'informations.
svnadmin recover — Remettre la base de données d'un dépôt dans un état
consistant (s'applique uniquement aux dépôts utilisant un
magasin de données de type bdb
). En
complément, si le fichier depot/conf/passwd
n'existe pas, un fichier de mots de passe par défaut est
créé.
svnadmin recover CHEMIN_DÉPÔT
Lancez cette commande si vous obtenez une erreur indiquant que votre dépôt doit être rétabli.
Rétablir un dépôt planté :
$ svnadmin recover /var/svn/depot/ Verrou du dépôt acquis. Patientez ; le rétablissement du dépôt peut être long... Fin du rétablissement. La dernière révision du dépôt est 34
Rétablir la base de données nécessite d'obtenir un verrou exclusif sur le dépôt (cela ressemble à « verrou de base de données » ; lisez l'encadré Les différents types de « verrous ».) Si un autre processus est en train d'accéder au dépôt, svnadmin recover se termine avec l'erreur :
$ svnadmin recover /var/svn/depot svn: Échec de l'obtention de l'accès exclusif au dépôt ; peut-être processus tel 'httpd', 'svnserve' ou 'svn' a-t-il ouvert le dépôt ? $
L'option --wait
, force svnadmin
recover à attendre que les autres processus se
déconnectent :
$ svnadmin recover /var/svn/depot --wait Attente du verrou sur le dépôt ; un autre processus le tient-il ? ### le temps passe… Verrou du dépôt acquis. Patientez ; le rétablissement du dépôt peut être long... Fin du rétablissement. La dernière révision du dépôt est 34
svnadmin rmlocks — Effacer inconditionnellement un ou plusieurs verrous du dépôt.
svnadmin rmlocks CHEMIN_DÉPÔT
CHEMIN_VERROUILLÉ...
svnadmin rmtxns — Supprimer des transactions d'un dépôt.
svnadmin rmtxns CHEMIN_DÉPÔT
NOM_DE_TRANSACTION...
Supprime les transactions en cours dans le dépôt. Cette fonctionnalité est décrite en détail dans la section intitulée « Suppression des transactions mortes ».
Supprimer les transactions dont les noms sont fournis :
$ svnadmin rmtxns /var/svn/depot/ 1w 1x
Les choses étant bien faites, la sortie de lstxns convient bien comme entrée de rmtxns :
$ svnadmin rmtxns /var/svn/depot/ $(svnadmin lstxns /var/svn/depot/)
Cet exemple a supprimé toutes les transactions inachevées de votre dépôt.
svnadmin setlog — Définir l'entrée du journal pour une révision.
svnadmin setlog CHEMIN_DÉPÔT -r REV
FICHIER
Définir l'entrée du journal pour la révision
REV
au contenu du fichier
FICHIER
.
Cela revient à utiliser svn propset avec
l'option --revprop
pour définir la propriété
svn:log
de la révision, sauf que vous pouvez
également utiliser l'option --bypass-hooks
pour
éviter les procédures automatiques pre-commit
et
post-commit
, ce qui est utile si la procédure
automatique pre-revprop-change
n'autorise pas les
modifications de propriétés de révision.
Avertissement | |
---|---|
Les propriétés de révision ne sont pas gérées en versions, donc cette commande écrase de manière irréversible la précédente entrée dans le journal. |
svnadmin setrevprop — Définir une propriété de révision.
svnadmin setrevprop CHEMIN_DÉPÔT -r REV NOM
FICHIER
Définir la propriété NOM
de la
révision REV
au contenu du fichier
FICHIER
. Utilisez les options
--use-pre-revprop-change-hook
ou
--use-post-revprop-change-hook
pour activer
les procédures automatiques relatives aux propriétés de
révision (par exemple si vous voulez notifier la modification
aux utilisateurs par la procédure automatique
post-revprop-change
).
svnadmin setuuid — Redéfinir l'identifiant unique (UUID) du dépôt.
svnadmin setuuid CHEMIN_DÉPÔT
[NOUVEAU_UUID]
Redéfinir l'identifiant unique (UUID) du dépôt situé dans
CHEMIN_DÉPÔT
. Si
NOUVEAU_UUID
est fourni, il est
utilisé comme nouvel identifiant ; sinon, un nouvel
identifiant est généré pour le dépôt.
Vous avez synchronisé (avec svnsync)
/var/svn/depot
vers
/var/svn/nouveau-depot
et vous voulez
utiliser nouveau-depot
comme dépôt par
défaut. Il est alors opportun de fixer la valeur de
l'identifiant unique de nouveau-depot
à la
même valeur que l'identifiant de
depot
ainsi vos utilisateurs n'auront
pas à extraire une nouvelle copie de travail pour s'adapter à la
nouvelle configuration :
$ svnadmin setuuid /var/svn/nouveau-depot 2109a8dd-854f-0410-ad31-d604008985ab
Comme vous pouvez le constater, svnadmin setuuid n'affiche rien en cas de succès.
svnadmin unlock — Déverrouiller un chemin dans le dépôt directement.
svnadmin unlock CHEMIN_DÉPÔT CHEMIN_VERROUILLÉ
IDENTIFIANT JETON
svnadmin upgrade — Mettre le dépôt à la dernière version supportée du schéma.
svnadmin upgrade CHEMIN_DÉPÔT
Mettre le dépôt situé à
CHEMIN_DÉPÔT
à la dernière version
supportée du schéma.
Cette fonctionnalité est un « petit plus » offert aux administrateurs qui veulent profiter des nouvelles fonctionnalités de Subversion sans avoir à passer par une opération coûteuse de déchargement et chargement complet du dépôt. Ainsi, svnadmin upgrade ne fait que le strict minimum pour effectuer la mise à jour, tout en gardant l'intégrité du dépôt. Alors qu'un déchargement suivi d'un chargement (svnadmin dump puis svnadmin load) garantissent un état optimisé du dépôt, svnadmin upgrade ne le garantit pas.
Avertissement | |
---|---|
Vous devriez toujours effectuer une sauvegarde avant upgrade. |
svnadmin verify — Vérifier les données stockées dans le dépôt.
svnadmin verify CHEMIN_DÉPÔT
Lancez cette commande si vous désirez vérifier l'intégrité de votre dépôt. Elle parcourt toutes les révisions du dépôt et les décharge en interne sans se préoccuper du flux produit (c'est une bonne pratique de lancer régulièrement ce programme pour prévenir les pannes latentes de disque dur et le vieillissement lié au stockage sur supports magnétiques (« bitrot »)). Si cette commande échoue (ce qu'elle fait au moindre problème), cela signifie qu'au moins une révision de votre dépôt est corrompue ; vous devriez alors restaurer la révision corrompue depuis une sauvegarde (vous avez bien fait une sauvegarde, n'est-ce pas ?).
svnlook est un utilitaire en ligne de commande pour examiner le contenu d'un dépôt Subversion. Il n'effectue aucune modification sur le dépôt, se contentant juste de « jeter des coups d'œil ». svnlook est utilisé typiquement par les procédures automatiques, mais un administrateur de dépôt peut aussi y trouver un intérêt à des fins de diagnostic.
Comme svnlook fonctionne par un accès direct au dépôt (et ne peut ainsi être utilisé que sur la machine qui héberge le dépôt), il fait référence au dépôt par un chemin et non par une URL.
Si aucune révision ou transaction n'est spécifiée, svnlook utilise par défaut la révision la plus jeune (c'est-à-dire récente) du dépôt.
Les options de svnlook sont globales, de la même manière que pour svn et svnadmin ; Cependant, la plupart des options ne s'appliquent qu'à une seule sous-commande puisque le périmètre des fonctionnalités de svnlook est (intentionnellement) limité :
Options de svnlook
--copy-info
Détailler les informations relatives aux sources de copies.
--diff-cmd
CMD
Utiliser un programme externe pour montrer les différences
entre fichiers. Quand svnlook diff est
appelé sans cette option, il utilise le moteur de calcul de
différences interne à Subversion, qui produit des diffs unifiés
par défaut. Si vous voulez utiliser un programme externe pour ce
calcul, utilisez l'option --diff-cmd
. Vous
pouvez alors passer des options complémentaires à ce programme
externe en utilisant l'option --extensions
(-x
).
--diff-copy-from
Afficher les différences par rapport à la source de la copie.
--extensions
(-x
) ARG
Spécifie les personnalisations que Subversion doit apporter lors du calcul des différences. Les extensions possibles sont :
--ignore-space-change
(-b
)Ignorer les modifications relatives au nombre d'espaces.
--ignore-all-space
(-w
)Ignorer toutes les espaces.
--ignore-eol-style
Ignorer les modifications relatives aux caractères de fins de lignes.
--show-c-function
(-p
)Afficher le nom des fonctions C dans la sortie du diff.
--unified
(-u
)Afficher trois lignes de contexte, conformément au standard diff unifié.
La valeur par défaut est -u
.
Notez que quand Subversion est configuré pour faire appel
à un programme diff externe, la valeur de l'option
--extensions
(-x
) n'est pas
restreinte aux options citées
supra, mais peut comprendre
n'importe quelle argument que Subversion
doit passer au programme externe. Si vous souhaitez passer
plusieurs arguments, vous devez les mettre tous à l'intérieur
de guillemets.
--full-paths
Afficher les chemins complets plutôt qu'une représentation hiérarchique indentée des composantes des chemins.
--ignore-properties
Ignorer les modifications de propriétés.
--limit
(-l
) ARG
Limiter l'affichage à ARG
éléments
maximum ARG
.
--no-diff-deleted
Ne pas afficher les différences relatives aux fichiers supprimés. Le comportement par défaut quand un fichier est supprimé dans une révision consiste à afficher les mêmes différences que si le fichier était toujours présent mais que son contenu ait été complètement enlevé.
--no-diff-added
Ne pas afficher les différences relatives aux fichiers ajoutés. Le comportement par défaut quand un fichier est ajouté dans une révision consiste à afficher les mêmes différences que si vous aviez ajouté tout le contenu du fichier dans un fichier existant et vide.
--non-recursive
(-N
)Ne travailler que sur ce seul répertoire.
--properties-only
N'afficher que les modifications de propriétés.
--revision
(-r
) REV
Travailler sur la révision passée en paramètre.
--revprop
Travailler sur les propriétés de révision au lieu des
propriétés de fichiers ou répertoires. Cette option requiert de
passer aussi l'option --revision
(-r
) pour spécifier la révision sur laquelle
travailler.
--show-inherited-props
Avec svnlook propgetet svnlook proplist, afficher aussi les propriétés héritées par un chemin.
--transaction
(-t
) ID
Travailler sur la transaction ID
passée en paramètre.
--show-ids
Afficher l'identifiant du nœud de révision pour chaque objet dans l'arborescence.
--verbose
(-v
)Être bavard. Par exemple, lorsqu'elle est utilisée avec svnlook proplist, Subversion affiche non seulement la liste des propriétés mais également leurs valeurs.
--xml
Afficher au format XML.
svnlook cat — Afficher le contenu d'un fichier.
svnlook cat CHEMIN_DÉPÔT CHEMIN_DANS_DÉPÔT
La commande suivante affiche le contenu du fichier
/trunk/LISEZ-MOI
pour la transaction
ax8
:
$ svnlook cat -t ax8 /var/svn/depot /trunk/LISEZ-MOI Subversion, un système de gestion de versions. ============================================== $LastChangedDate: 2003-07-17 10:45:25 -0500 (jeu. 17 juil. 2003) $ Contents: I. QUELQUES RÉFÉRENCES II. DOCUMENTATION III. PARTICIPER À LA COMMUNAUTÉ SUBVERSION …
svnlook changed — Afficher les chemins modifiés.
svnlook changed CHEMIN_DÉPÔT
Afficher les chemins qui ont été modifiés par une révision ou une transaction particulière, avec les mêmes codes lettres que svn status dans les deux premières colonnes :
'A '
Élément ajouté au dépôt.
'D '
Élément supprimé du dépôt.
'U '
Le contenu du fichier a été modifié.
'_U'
Les propriétés de l'élément ont été modifiées ; notez le caractère « souligné » en tête.
'UU'
Le contenu du fichier et les propriétés ont été modifiés.
Les fichiers et les répertoires peuvent être distingués par le
fait que les noms de répertoires sont suivis d'une barre oblique
« /
».
Cet exemple montre la liste de toutes les modifications apportées
aux fichiers et aux répertoires par la révision 39 sur un dépôt de
test. Notez que le premier élément est un répertoire comme l'indique
la barre oblique (/
) finale :
$ svnlook changed -r 39 /var/svn/depot A trunk/magasin/epicerie/ A trunk/magasin/epicerie/chips.txt A trunk/magasin/epicerie/sandwich.txt A trunk/magasin/epicerie/vinaigre.txt U trunk/magasin/boulangerie/petit-pain.txt _U trunk/magasin/boulangerie/croissant.txt UU trunk/magasin/boulangerie/chausson-aux-pommes.txt D trunk/magasin/boulangerie/baguette.txt
Voici un exemple qui montre une révision dans laquelle un fichier a été renommé :
$ svnlook changed -r 64 /var/svn/depot A trunk/magasin/boulangerie/toast.txt D trunk/magasin/boulangerie/pain.txt
Malheureusement, rien dans l'affichage précédent n'indique la
relation entre le fichier supprimé et le fichier ajouté. Utilisez
l'option --copy-info
pour faire apparaître cette
relation :
$ svnlook changed -r 64 --copy-info /var/svn/depot A + trunk/magasin/boulangerie/toast.txt (from trunk/magasin/boulangerie/pain.txt:r63) D trunk/magasin/boulangerie/pain.txt
svnlook diff — Afficher les différences pour les fichiers et les propriétés modifiés.
svnlook diff CHEMIN_DÉPÔT
Cet exemple montre un fichier nouvellement ajouté (vide), un fichier effacé et un fichier copié :
$ svnlook diff -r 40 /var/svn/depot/ Copié: trunk/marinade.txt (from rev 39, trunk/magasin/epicerie/vinaigre.txt) ============================================================================== --- trunk/marinade.txt (rev 0) +++ trunk/marinade.txt 2013-01-29 20:39:17 UTC (rev 40) @@ -0,0 +1 @@ +Le vinaigre permet de conserver les cornichons. Effacé: trunk/magasin/epicerie/vinaigre.txt =================================================================== --- trunk/magasin/epicerie/vinaigre.txt (rev 39) +++ trunk/magasin/epicerie/vinaigre.txt 2013-01-29 20:39:17 UTC (rev 49) @@ -1 +0,0 @@ -Le vinaigre permet de conserver toutes sortes d'aliments. Modifié: trunk/magasin/epicerie/logo.jpg =================================================================== (Binary files differ) Ajouté: trunk/magasin/epicerie/soda.txt =================================================================== $
Par défaut, svnlook diff traite les fichiers
copiés pratiquement comme des fichiers ajoutés, en affichant
entièrement leur contenu, seule l'étiquette en tête diffère.
Cependant, vous pouvez utiliser l'option
--diff-copy-from
pour forcer
svnlook diff à considérer q'un fichier copié ne
mérite d'être mentionné que s'il diffère du fichier dont il est
issu et de décrire effectivement ces différences.
$ svnlook diff -r 40 /var/svn/depot/ --diff-copy-from Copié: trunk/marinade.txt (from rev 39, trunk/magasin/epicerie/vinaigre.txt) ============================================================================== --- trunk/magasin/epicerie/vinaigre.txt 2013-01-29 20:39:17 UTC (rev 39) +++ trunk/marinade.txt 2013-01-29 20:39:17 UTC (rev 40) @@ -1 +1 @@ -Le vinaigre permet de conserver toutes sortes d'aliments. +Le vinaigre permet de conserver les cornichons. Effacé: trunk/magasin/epicerie/vinaigre.txt =================================================================== --- trunk/magasin/epicerie/vinaigre.txt (rev 39) +++ trunk/magasin/epicerie/vinaigre.txt 2013-01-29 20:39:17 UTC (rev 49) @@ -1 +0,0 @@ -Le vinaigre permet de conserver les cornichons. Modifié: trunk/magasin/epicerie/logo.jpg =================================================================== (Binary files differ) Ajouté: trunk/magasin/epicerie/soda.txt =================================================================== $
Utiliser l'option --no-diff-deleted
pour ne pas
afficher ce qui concerne les fichiers effacés.
$ svnlook diff -r 40 /var/svn/repos --no-diff-deleted Copié: trunk/marinade.txt (from rev 39, trunk/magasin/epicerie/vinaigre.txt) ============================================================================== --- trunk/marinade.txt (rev 0) +++ trunk/marinade.txt 2013-01-29 20:39:17 UTC (rev 40) @@ -0,0 +1 @@ +Le vinaigre permet de conserver les cornichons. Modifié: trunk/magasin/epicerie/logo.jpg =================================================================== (Binary files differ) Ajouté: trunk/magasin/epicerie/soda.txt =================================================================== $
Notez que dans tous les exemples
supra, quand un fichier a une valeur
de propriété svn:mime-type
qui indique un type non
textuel, les différences ne sont pas explicitement affichées.
svnlook dirs-changed — Afficher les répertoires modifiés.
svnlook dirs-changed CHEMIN_DÉPÔT
svnlook filesize — Afficher la taille (en octets) d'un fichier suivi en versions.
svnlook filesize CHEMIN_DÉPÔT
CHEMIN_DANS_DÉPÔT
Afficher la taille (en octets) du fichier situé à
CHEMIN_DANS_DÉPÔT
dans la révision
HEAD
du dépôt identifié par
CHEMIN_DÉPÔT
. La taille est un entier
affiché en base 10 et suivi par un caractère de fin de ligne.
Utilisez l'option --revision
(-r
)
ou --transaction
(-t
) pour
spécifier une version particulière (autre que HEAD
)
du fichier.
svnlook help (h, ?) — À l'aide !
Aussi svnlook -h
et svnlook
-?
.
svnlook history — Afficher l'historique d'un chemin dans le dépôt (ou de la racine du dépôt si aucun chemin n'est spécifié).
svnlook history CHEMIN_DÉPÔT
[CHEMIN_DANS_DÉPÔT]
Afficher l'historique d'un chemin dans le dépôt (ou de la racine du dépôt si aucun chemin n'est spécifié).
Cet exemple affiche l'historique pour le chemin
/branches/librairie
pour la révision 13 dans
notre dépôt de test :
$ svnlook history -r 13 /var/svn/depot /branches/librairie --show-ids REVISION CHEMIN <ID> -------- --------- 13 /branches/librairie <1.1.r13/390> 12 /branches/librairie <1.1.r12/413> 11 /branches/librairie <1.1.r11/0> 9 /trunk <1.0.r9/551> 8 /trunk <1.0.r8/131357096> 7 /trunk <1.0.r7/294> 6 /trunk <1.0.r6/353> 5 /trunk <1.0.r5/349> 4 /trunk <1.0.r4/332> 3 /trunk <1.0.r3/335> 2 /trunk <1.0.r2/295> 1 /trunk <1.0.r1/532>
svnlook info — Afficher l'auteur, la date, la taille et le contenu de l'entrée du journal.
svnlook info CHEMIN_DÉPÔT
svnlook lock — Décrire le verrou sur le chemin dans le dépôt, s'il existe.
svnlook lock CHEMIN_DÉPÔT
CHEMIN_DANS_DÉPÔT
Afficher toutes les informations disponibles sur le verrou
appliqué sur CHEMIN_DANS_DÉPÔT
. Si
CHEMIN_DANS_DÉPÔT
n'est pas verrouillé,
ne rien afficher.
Cet exemple affiche la description du verrou posé sur le fichier
arbre.jpg
:
$ svnlook lock /var/svn/depot arbre.jpg Chaîne UUID : opaquelocktoken:ab00ddf0-6afb-0310-9cd0-dda813329753 Propriétaire du verrou : harry Verrou créé: 2005-07-08 17:27:36 -0500 (ven. 08 jul 2005) Expire : Commentaire (1 ligne): Retouche sur la branche la plus haute du cyprès plat au premier plan.
svnlook log — Afficher l'entrée du journal, suivie par un caractère de fin de ligne.
svnlook log CHEMIN_DÉPÔT
svnlook propget (pget, pg) — Afficher la valeur brute de la propriété pour un chemin du dépôt.
svnlook propget CHEMIN_DÉPÔT NOM_PROP
[CHEMIN_DANS_DÉPÔT]
Afficher la valeur de la propriété « assaisonnement »
du fichier /trunk/sandwich
pour la révision
HEAD
:
$ svnlook pg /var/svn/depot assaisonnement /trunk/sandwich moutarde
Afficher la valeur héritée de la propriété
svn:auto-props
du répertoire
/trunk
pour la révision 14 :
$ svnlook pg depot svn:auto-props trunk --show-inherited-props -v -r14 Inherited properties on '/trunk', from '/': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native
svnlook proplist (plist, pl) — Afficher les noms et valeurs des propriétés d'un fichier ou d'un répertoire.
svnlook proplist CHEMIN_DÉPÔT
[CHEMIN_DANS_DÉPÔT]
Lister les propriétés d'un chemin dans le dépôt. Avec l'option
--verbose
, affiche également les valeurs
afférentes.
Afficher le nom des propriétés du fichier
/trunk/LISEZ-MOI
pour la révision
HEAD
:
$ svnlook proplist /var/svn/depot /trunk/LISEZ-MOI original-author svn:mime-type
Voici la même commande que dans l'exemple précédent, mais cette fois en affichant aussi les valeurs des propriétés :
$ svnlook --verbose proplist /var/svn/depot /trunk/LISEZ-MOI original-author : harry svn:mime-type : text/plain
Afficher les propriétés héritées par un répertoire :
$ svnlook pl /var/svn/depot branches --show-inherited-props -v Inherited properties on '/branches', from '/': svn:auto-props *.py = svn:eol-style=native *.c = svn:eol-style=native *.h = svn:eol-style=native svn:global-ignores *.diff *.patch Propriétés sur '/branches':
svnlook tree — Afficher l'arborescence.
svnlook tree CHEMIN_DÉPÔT
[CHEMIN_DANS_DÉPÔT]
Afficher l'arborescence, en commençant par
CHEMIN_DANS_DÉPÔT
(s'il est fourni, sinon
à partir de la racine) en affichant optionnellement les identifiants
de révision des nœuds.
Afficher l'arborescence pour la révision 13 de notre dépôt de test :
$ svnlook tree -r 13 /var/svn/depot / trunk/ bouton.c Makefile entier.c branches/ librairie/ bouton.c Makefile entier.c …
Utiliser l'option --show-ids
pour afficher
également les identifiants des nœuds de révision (identifiants
uniques internes créés par l'implémentation du système de fichiers
interne de gestion de versions de Subversion) :
:
$ svnlook tree -r 13 /var/svn/depot --show-ids / <0.0.r13/811> trunk/ <1.0.r9/551> bouton.c <2.0.r9/238> Makefile <3.0.r7/41> entier.c <4.0.r6/98> branches/ <5.0.r13/593> librairie/ <1.1.r13/390> bouton.c <2.1.r12/85> Makefile <3.0.r7/41> entier.c <4.1.r13/109> …
Pour obtenir un affichage pouvant être analyser par des
programmes, utilisez l'option --full-paths
, ce qui
produit l'affichage du chemin complet pour chaque élément de
l'arborescence et n'utilise pas d'indentation pour matérialiser la
hiérarchie :
$ svnlook tree -r 13 /var/svn/repos --show-ids --full-paths / <0.0.r13/811> trunk/ <1.0.r9/551> trunk/bouton.c <2.0.r9/238> trunk/Makefile <3.0.r7/41> trunk/entier.c <4.0.r6/98> branches/ <5.0.r13/593> branches/librairie/ <1.1.r13/390> branches/librairie/bouton.c <2.1.r12/85> branches/librairie/Makefile <3.0.r7/41> branches/librairie/entier.c <4.1.r13/109> …
svnlook uuid — Afficher l'UUID (ou identifiant unique) du dépôt.
svnlook uuid CHEMIN_DÉPÔT
svnserve — Offrir l'accès aux dépôts Subversion via un protocole réseau sur mesure.
svnserve [-d | -i | -t | -X] OPTIONS...
La commande svnserve permet les accès aux dépôts Subversion en utilisant le protocole réseau sur mesure de Subversion.
Vous pouvez faire tourner svnserve en tant
que serveur autonome (pour les clients qui utilisent la méthode
d'accès svn://
) ; Vous pouvez aussi avoir
un démon tel que inetd ou
xinetd qui le lance pour vous à la demande (aussi
pour svn://
) ou vous pouvez avoir
sshd qui le lance à la demande pour les clients
utilisant la méthode d'accès svn+ssh://
.
À moins que l'option --config-file
ne soit
spécifiée sur la ligne de commande, une fois que le client a
choisi un dépôt en spécifiant son URL, svnserve
lit le fichier conf/svnserve.conf
dans le
répertoire du dépôt pour déterminer les réglages spécifiques au
dépôt tels que la base de données d'authentification à utiliser ou
quelle politique de contrôle d'accès appliquer. Reportez-vous à
la section intitulée « svnserve, un serveur sur mesure » pour les détails
relatifs au fichier svnserve.conf
.
Au contraire des commandes décrites précédemment, svnserve ne possède pas de sous-commande, elle est entièrement contrôlée par les options.
--cache-fulltexts
ARG
Activer la fonctionnalité de mise en cache du contenu des fichiers textes (ne concerne que les dépôts FSFS).
--cache-txdeltas
ARG
Activer la fonctionnalité de mise en cache des deltas de fichiers (ne concerne que les dépôts FSFS).
--compression
NIVEAU
Spécifie le niveau de compression utilisé pour les
transmissions sur le réseau par un entier compris entre 0 et 9
inclus. Une valeur de 9
offre la compression
la plus élevée, 5
est la valeur par défaut
et 0
interdit la compression.
--config-file
NOM_FICHIER
Lorsque spécifiée, svnserve lit le
fichier NOM_FICHIER
au démarrage du
programme et garde en cache la configuration de
svnserve. Les configurations référencées
dans le fichier pour les mots de passe et le contrôle d'accès
sont lues à chaque connexion. svnserve
ne lit aucun fichier de configuration
conf/svnserve.conf
spécifique à un dépôt
lorsque cette option est utilisée. Reportez-vous à
la section intitulée « svnserve, un serveur sur mesure » pour les détails du
format de fichier spécifique à cette option.
--daemon
(-d
)Lancer svnserve en mode démon.
svnserve passe en arrière-plan et répond aux
connexions TCP/IP sur le port svn
(3690 par
défaut).
--foreground
Quand elle est utilisée avec l'option
-d
, indique à svnserve
de rester en avant-plan. Cette option est principalement
utilisée à des fins de débogage.
--inetd
(-i
)Indique à svnserve d'utiliser l'entrée
standard (stdin
) et la sortie standard
(stdout
), comme requis pour une
utilisation avec inetd.
--help
(-h
)Afficher un court descriptif du programme et sortir.
--listen-host
HOTE
Indique à svnserve d'écouter sur
l'interface spécifiée par HOTE
,
qui peut être soit une adresse IP soit un nom d'hôte.
--listen-once
(-X
)Accepter une connexion sur le port svn
,
y répondre puis terminer. Cette option est principalement
utilisée à des fins de débogage.
--listen-port
PORT
Écouter le port PORT
quand
svnserve fonctionne en tant que démon (les
démons FreeBSD n'écoutent par défaut que sur les adresses IPv6
— Cette option indique d'écouter également sur les
adresses IPv4).
--log-file
NOM_FICHIER
Créer (si nécessaire) et utiliser le fichier
NOM_FICHIER
pour stocker les journaux de
Subversion, sous le même format que ceux produits par
mod_dav_svn. Voir
la section intitulée « Journalisation du haut-niveau » pour
les détails.
--memory-cache-size
(-M
) ARG
Configure la taille (en mégaoctets) de la mémoire cache
utilisée pour diminuer les opérations redondantes (ce cache ne
concerne que les dépôts FSFS). La valeur par défaut est
16
.
--pid-file
NOM_FICHIER
Écrire l'identifiant de processus utilisé dans
NOM_FICHIER
; l'utilisateur
sous lequel svnserve tourne doit
avoir le droit d'écrire dans ce fichier.
--prefer-ipv6
(-6
)Lors de la résolution du nom d'hôte pour l'écoute de port, préférer une réponse en IPv6 par rapport à une réponse IPv4. IPv4 est préféré par défaut.
--quiet
Désactiver les notifications sur l'avancement du déroulement du programme. Les erreurs sont toujours affichées.
--root
(-r
) RACINE
Définir la racine virtuelle pour les dépôts accessibles par svnserve. Les chemins dans les URL fournies par le client sont interprétés relativement à cette racine et le client ne peut pas sortir de cette arborescence.
--threads
(-T
)En fonctionnement en mode démon, créer un processus léger (thread) plutôt qu'un nouveau processus pour chaque connexion (par exemple lors d'un fonctionnement sous Windows). Le processus svnserve passe toujours en arrière-plan au démarrage.
--tunnel
(-t
)Fonctionner en mode tunnel, qui est le même que le mode de
fonctionnement de inetd : les deux
modes répondent aux connexions sur l'entrée et la sortie
standards (stdin
/stdout
)
puis terminent, sauf que la connexion est considérée comme
déjà authentifiée (l'identifiant correspond à l'UID courant).
Ce drapeau est passé automatiquement pour vous par le client
quand il utilise un tunnel tel que le programme
ssh. Cela signifie que vous aurez rarement
le besoin de passer cette option vous-même
à svnserve. Aussi, si vous vous surprenez à
taper svnserve --tunnel
sur une ligne de
commande et que vous vous demandez quoi faire par la suite,
reportez-vous à la section intitulée « Encapsulation de svnserve dans un tunnel SSH ».
--tunnel-user
NOM
Utilisée en conjonction avec l'option
--tunnel
, indique à
svnserve que
NOM
est l'utilisateur authentifié,
plutôt que l'UID du processus svnserve.
Cette option est utile pour les utilisateurs qui souhaitent
partager un compte unique pour SSH, mais qui veulent continuer
à avoir des identités différentes pour les propagations.
--version
Afficher les informations de version ainsi que la liste des modules d'accès aux dépôts disponibles, puis terminer.
svnversion — Résumer la révision locale d'une copie de travail.
svnversion [OPTIONS] [CHEMIN_COPIE_TRAVAIL [FIN_URL]]
svnversion est un programme qui produit des informations résumées à partir des révisions utilisées et des modifications effectuées sur la copie de travail. Le numéro de révision, ou l'intervalle, produit est écrit sur la sortie standard.
Il est d'usage d'utiliser ce résultat dans la chaîne de compilation pour définir le numéro de version d'un programme.
FIN_URL
, si elle est spécifiée, est la
partie de la fin de l'URL à utiliser pour déterminer si
CHEMIN_COPIE_TRAVAIL
a été ré-aiguillé
(la détection de ré-aiguillage à l'intérieur de
CHEMIN_COPIE_TRAVAIL
ne prend pas en
compte FIN_URL
).
Quand CHEMIN_COPIE_TRAVAIL
n'est pas
spécifié, le répertoire courant est utilisé.
FIN_URL
ne peut pas être spécifié
si CHEMIN_COPIE_TRAVAIL
ne l'est
pas.
De même que pour svnserve, svnversion n'a pas de sous-commande, seulement des options :
--no-newline
(-n
)Pas de fin de ligne habituel en fin d'affichage.
--committed
(-c
)Utiliser la dernière révision propagée plutôt que les révisions courantes (c'est-à-dire les plus récentes disponibles localement).
--help
(-h
)Afficher l'aide du programme.
--quiet
(-q
)N'afficher que les informations essentielles pendant le déroulement du programme.
--version
Afficher la version de svnversion et terminer sans erreur.
Si la copie de travail est issue d'une unique révision (par exemple, immédiatement après une mise à jour par svn update), alors le numéro de révision correspondant est affiché :
$ svnversion 4168
Vous pouvez ajouter FIN_URL
pour être
sûr que la copie de travail n'a pas été ré-aiguillée ailleurs que ce
que vous pensez. Notez que
CHEMIN_COPIE_TRAVAIL
est indispensable
dans ce cas :
$ svnversion . /var/svn/trunk 4168
Pour une copie de travail qui utilise des révisions mélangées, l'intervalle des révisions utilisées localement est affiché :
$ svnversion 4123:4168
Si la copie de travail contient des modifications locales, un
'M
' est ajouté à la fin :
$ svnversion 4168M
Si la copie de travail a été re-aiguillée, un
'S
' (pour switched)
est ajouté à la fin :
$ svnversion 4168S
svnversion vous informe également si la copie
de travail cible est à répertoires clairsemés (voir la section intitulée « Répertoires clairsemés ») en ajoutant un
'P
' à la sortie :
$ svnversion 4168P
Ainsi, voici le résultat pour une copie de travail issues de plusieurs révisions, re-aiguillée, à répertoires clairsemés et qui contient des modifications locales :
$ svnversion 4123:4168MSP
svnsync est l'outil de réplication de dépôt à distance de Subversion. En clair, il vous permet de rejouer les propagations d'un dépôt sur un autre dépôt.
Dans tout scénario de réplication, il y a deux dépôts : le dépôt source et le dépôt miroir (ou « destination »). Le dépôt source est le dépôt à partir duquel svnsync lit les révisions. Le dépôt miroir est le dépôt sur lequel svnsync applique les propagations lues sur le dépôt source. Chacun des dépôts peut être un dépôt local ou distant (ils sont toujours uniquement désignés par leur URL).
Le processus svnsync requiert un accès uniquement en lecture sur le dépôt source ; il ne tente jamais aucune modification sur celui-ci. En revanche, bien évidemment, svnsync a besoin d'un accès en lecture et écriture sur le dépôt miroir.
Avertissement | |
---|---|
svnsync est particulièrement sensible aux modifications faites sur le dépôt miroir qui ne sont pas issues d'une opération de réplication. Pour éviter ce genre d'ennui, il est recommandé que svnsync soit le seul processus autorisé à modifier le dépôt miroir. |
Les options de svnsync sont globales, de même que pour svn et svnadmin :
Options
--allow-non-empty
Ne pas vérifier (ce que svnsync initialize fait par défaut) que le dépôt en cours d'initialisation est vide de tout historique.
--config-dir
REPERTOIRE
Lire les informations de configuration dans le répertoire
spécifié plutôt qu'à l'emplacement par défaut
(.subversion
dans le répertoire de
l'utilisateur).
--config-option
CONFSPEC
Définir, pour la durée de la commande, la valeur d'une
option de configuration.
CONFSPEC
est une chaîne de caractères
qui spécifie l'espace de nom de l'option de configuration, son
nom et la valeur que vous voulez lui assigner, formatée
ainsi :
FICHIER
:SECTION
:OPTION
=[VALEUR
]
Dans cette syntaxe, FICHIER
et
SECTION
sont des fichiers de la zone
de configuration (soit
config
ou
servers
) et de la section où se trouve
l'option dont vous voulez changer la valeur.
OPTION
est, bien sûr, le nom de
l'option elle-même et
VALEUR
est la valeur (si vous la
donnez) que vous voulez assigner à l'option. Par exemple, pour
désactiver temporairement la compression dans le protocole HTTP,
utilisez
--config-option=servers:global:http-compression=no
.
Vous pouvez utiliser cette option plusieurs fois pour modifier
les valeurs de plusieurs options temporairement.
--disable-locking
Contourner le dispositif de contrôle d'accès exclusif et considérer que l'accès exclusif au dépôt miroir est assuré par un mécanisme extérieur.
--no-auth-cache
Ne pas conserver les éléments d'authentification (par exemple l'identifiant et le mot de passe) dans les zones de configuration de Subversion.
--non-interactive
Dans le cas d'un échec d'authentification ou de droits insuffisants, ne pas demander d'éléments d'authentification (par exemple identifiant et mot de passe) de manière interactive. Cette option est utile quand vous lancez Subversion dans un script totalement automatique et qu'il est plus pertinent de faire échouer Subversion plutôt que d'attendre une réponse interactive.
--quiet
(-q
)N'afficher que ce qui est essentiel pendant l'opération.
--revision
(-r
) ARG
Utilisé avec svnsync copy-revprops pour spécifier une révision ou un intervalle de révision sur lequel effectuer l'opération.
--source-password
MOT_DE_PASSE
Précise le mot de passe à utiliser pour s'authentifier auprès du serveur Subversion source. Si cette option n'est pas fournie ou si elle ne permet pas de s'authentifier correctement, Subversion demande, en tant que de besoin, le mot de passe de manière interactive.
--source-prop-encoding ARG
Considérer que les propriétés de révisions du dépôt source
sont stockées au format ARG
et les
transcoder en UTF-8 avant de les copier dans le dépôt
miroir.
--source-username
NOM
Utiliser le nom d'utilisateur spécifié pour s'authentifier auprès du serveur Subversion source. Si cette option n'est pas fournie ou si elle ne permet pas de s'authentifier correctement, Subversion demande, en tant que de besoin, le nom d'utilisateur de manière interactive.
--steal-lock
Casser, si nécessaire, les verrous qui assurent l'accès exclusif au dépôt miroir. Cette option ne doit être utilisée que lorsqu'un verrou bloque l'accès au dépôt miroir et que vous savez que ce verrou est obsolète, c'est-à-dire quand vous êtes certain qu'aucun autre processus svnsync n'est en train d'accéder à ce dépôt.
--sync-password
MOT_DE_PASSE
Utiliser le mot de passe spécifié pour s'authentifier auprès du serveur Subversion destination. Si cette option n'est pas fournie ou si elle ne permet pas de s'authentifier correctement, Subversion demande, en tant que de besoin, le mot de passe de manière interactive.
--sync-username
NOM
Utiliser le nom d'utilisateur spécifié pour s'authentifier auprès du serveur Subversion destination. Si cette option n'est pas fournie ou si elle ne permet pas de s'authentifier correctement, Subversion demande, en tant que de besoin, le nom d'utilisateur de manière interactive.
--trust-server-cert
Utilisée avec --non-interactive
, accepter
les certificats SSL serveurs signés par des autorités inconnues
sans en informer l'utilisateur.
svnsync copy-revprops — Copier toutes les propriétés de révision pour une révision donnée (ou un intervalle de révisions) du dépôt source vers le dépôt miroir.
svnsync copy-revprops URL_DEST [URL_SOURCE]
svnsync copy-revprops URL_DEST REV[:REV2]
Comme les propriétés de révision Subversion peuvent être modifiées à n'importe quel moment, il est possible que des propriétés d'une révision donnée soient modifiées après que la révision a été répliquée sur le dépôt miroir. Comme la commande svnsync synchronize n'opère que sur un intervalle de révisions qui n'ont pas encore été répliquées, elle ne remarque pas la modification d'une propriété en dehors de cet intervalle. Si rien n'est fait pour contrer ce phénomène, cela entraine une divergence entre les valeurs des propriétés de révision du dépôt source et du dépôt miroir. svnsync copy-revprops répond à ce problème : utilisez-la pour resynchroniser les propriétés de révision pour une révision donnée ou pour un intervalle de révisions.
Quand URL_SOURCE
est fourni,
svnsync l'utilise comme URL du dépôt que l'on veut
répliquer. Généralement, URL_SOURCE
est
exactement la même URL que celle utilisée avec la commande
svnsync initialize quand le miroir a été mis en
place. Vous pouvez choisir, néanmoins, d'omettre
URL_SOURCE
dans ce cas,
svnsync consulte le dépôt miroir pour déterminer
l'URL source à utiliser.
Avertissement | |
---|---|
Nous recommandons vivement de spécifier l'URL source sur la ligne de commande, spécialement quand des utilisateurs non de confiance ont le droit d'écriture sur les propriétés de la révision 0, utilisées par svnsync pour se coordonner. |
svnsync help — À l'aide !
svnsync help
Cette sous-commande est utile quand vous vous retrouvez prisonnier dans une prison à l'étranger sans connexion Internet ni exemplaire de ce livre, mais que vous avez un hotspot WiFi à portée et que vous voulez répliquer votre dépôt vers le serveur de sauvegarde de Marcel Au Couteau situé dans une cellule du bloc D.
svnsync info — Afficher les informations relatives à la synchronisation d'un dépôt miroir.
svnsync info URL_DEST
Affichier l'URL source de la synchronisation, l'UUID du dépôt
source et la dernière révision fusionnée depuis la source vers le
dépôt de destination à l'
URL_DEST
.
svnsync initialize (init) — Initialiser un dépôt miroir pour une synchronisation à partir d'un dépôt source.
svnsync initialize URL_MIROIR URL_SOURCE
svnsync initialize vérifie que le dépôt répond aux exigences d'un dépôt miroir vierge (il n'y a pas d'historique et la modification des propriétés de révision est autorisée), puis enregistre les informations administratives initiales qui associent le dépôt miroir au dépôt source. C'est la première opération svnsync que vous lancez sur un dépôt miroir « en devenir ».
D'habitude, URL_SOURCE
est l'URL du
dossier racine du dépôt Subversion que vous souhaitez répliquer.
Subversion 1.5 ou ultérieur autorisent svnsync à
ne répliquer qu'une partie du dépôt source, vous devez alors
spécifier pour URL_SOURCE
l'URL du
sous-dossier dans le dépôt source que vous souhaitez
répliquer.
Par défaut, les prérequis déjà mentionnés pour le miroir sont
qu'il doit autoriser les modifications de propriétés de révisions et
qu'il ne doit contenir aucun historique. Cependant, depuis
Subversion 1.7, vous pouvez désactiver la vérification que le serveur
de destination est vide en utilisant l'option
--allow-non-empty
. Bien que l'utilisation de cette
option ne doit pas devenir une habitude (puisqu'elle courtciruite un
dispositif de protection), elle s'avère utile dans un cas très
fréquent : initialiser une copie d'un dépôt en tant que miroir
de l'original. C'est particulièrement pratique lorsque vous mettez
en place des nouveaux miroirs de dépôts qui contiennent des
historiques très volumineux. Plutôt que d'initialiser un nouveau
dépôt vierge comme miroir puis de synchroniser tout l'historique,
les administrateurs gagneront un certain temps à
d'abord faire une copie du dépôt en service (par exemple avec
svnadmin hotcopy), puis à utiliser
svnsync initialize --allow-non-empty pour
initialiser cette copie en tant que miroir, qui reflète déjà le
contenu de l'original.
Tenter d'initialiser un dépôt qui ne peut pas modifier les propriétés de révision :
$ svnsync initialize file:///var/svn/depot-miroir \ http://svn.exemple.com/depot svnsync: E165006: Le dépôt n'est pas configuré pour accepter les modifications de propriétés de révision ; parler à l'administrateur de la procédure automatique (hook) pre-revprop-change $
Initialiser un dépôt en tant que miroir, après avoir créé une
procédure automatique pre-revprop-change
qui
autorise les modifications des propriétés de révision :
$ svnsync initialize file:///var/svn/depot-miroir http://svn.exemple.com/depot Propriétés copiées pour la révision 0. $
svnsync synchronize (sync) — Transférer toutes les révisions en attente depuis le dépôt source vers le dépôt miroir.
svnsync synchronize URL_DEST [URL_SOURCE]
La commande svnsync synchronize effectue le gros du travail de réplication. Après avoir consulté le dépôt miroir pour connaître les révisions déjà copiées, elle commence la copie des révisions qui n'ont pas encore été copiées depuis le dépôt source.
svnsync synchronize peut être interrompue et redémarrée sans souci.
Quand URL_SOURCE
est fournie,
svnsync l'utilise comme URL à répliquer.
Généralement, URL_SOURCE
est la même que
celle qui a été utilisée pour svnsync initialize
lors de la mise en place du miroir. Vous pouvez cependant omettre
URL_SOURCE
, svnsync
consulte alors les enregistrements du dépôt miroir pour déterminer
l'URL source qui doit être utilisée.
Avertissement | |
---|---|
Nous recommandons vivement de spécifier l'URL source sur la ligne de commande, spécialement quand des utilisateurs non de confiance ont le droit d'écriture sur les propriétés de la révision 0, utilisées par svnsync pour se coordonner. |
Copier les révisions en attente du dépôt source vers le dépôt miroir :
$ svnsync synchronize file:///var/svn/depot-miroir \ http://svn.exemple.com/depot Révision 1 propagée. Propriétés copiées pour la révision 1. Révision 2 propagée. Propriétés copiées pour la révision 2. Révision 3 propagée. Propriétés copiées pour la révision 3. … Révision 45 propagée. Propriétés copiées pour la révision 45. Transmission des données . Révision 46 propagée. Propriétés copiées pour la révision 46. Transmission des données . Révision 47 propagée. Propriétés copiées pour la révision 47. $
svnrdump a rejoint la collection d'outils Subversion lors de la sortie de Subversion 1.7. La meilleure façon de le décrire consiste à dire que c'est une version en réseau de svnadmin dump et svnadmin load, mis ensemble et fourni en tant que programme particulier à lui seul. Nous présentons la procédure de décharge et charge des données d'un dépôt (en utilisant svnadmin et svnrdump) dans la section intitulée « Migration des données d'un dépôt ».
Les options de svnrdump sont globales, de la même manière que pour svn et svnadmin :
Options de svnrdump
--config-dir
REPERTOIRE
Lire la configuration dans le répertoire spécifié plutôt que
dans l'emplacement par défaut (.subversion
dans le répertoire de l'utilisateur).
--config-option
FICHIER
:SECTION
:OPTION
=[VALEUR
]Définir, pour la durée de la commande, la valeur d'une option
de configuration. CONFSPEC
est une
chaine qui spécifie l'espace de noms, le nom et la valeur de
l'option de configuration que vous voulez assigner, sous la forme
FICHIER
:SECTION
:OPTION
=[VALEUR
].
Dans cette syntaxe, FICHIER
et
SECTION
représentent le fichier de la
zone de configuration (soit config
, soit
servers
) et la section qui contient l'option
dont vous voulez définir la valeur.
OPTION
est, bien sûr, l'option
elle-même et VALEUR
est la valeur
(s'il y en a une) que vous voulez assigner à cette option. Par
exemple, pour désactiver temporairement l'utilisation de la
compression dans le protocole HTTP, utilisez
--config-option=servers:global:http-compression=no
.
Vous pouvez utiliser cette option plusieurs fois pour changer
plusieurs valeurs d'options pour la commande en cours.
--incremental
Décharger la révision ou l'intervalle de révisions en tant que différences par rapport à la révision précédente, au lieu du comportement par défaut qui consiste à décharger complètement la première révision de l'intervalle.
--no-auth-cache
Ne pas conserver les éléments d'authentification (par exemple l'identifiant et le mot de passe) dans les répertoires de configuration de Subversion.
--non-interactive
Dans le cas d'un échec d'authentification ou de droits insuffisants, ne pas faire de demande interactive pour les éléments d'authentification (par exemple l'identifiant ou le mot de passe). Cette option est utile quand vous lancez Subversion dans un script totalement automatique et qu'il est plus pertinent de faire échouer Subversion plutôt que d'attendre une réponse interactive.
--password
MOT_DE_PASSE
Utiliser le mot de passe
MOT_DE_PASSE
pour s'authentifier
auprès du serveur Subversion. Si cette option n'est pas fournie
ou si elle ne permet pas de s'authentifier correctement,
Subversion vous demande, en tant que de besoin, le mot de passe
de manière interactive.
--quiet
(-q
)N'afficher que ce qui est essentiel pendant une opération.
--revision
(-r
) REV
Travailler sur la révision ARG
ou
sur l'intervalle REV
.
--trust-server-cert
Utilisée avec --non-interactive
, accepter
les certificats SSL serveurs signés par des autorités inconnues
sans en informer l'utilisateur.
--username
NOM
Spécifie l'identifiant (ou nom d'utilisateur) à utiliser pour s'authentifier auprès d'un serveur Subversion. S'il n'est pas fourni ou s'il est incorrect, Subversion vous demandera cette information quand il en aura besoin.
svnrdump dump
svnrdump dump URL_SOURCE
Décharger les révisions du dépôt situé à
URL_SOURCE
, en dirigeant le flux produit
sur la sortie standard. Par défaut, tout l'historique est inclus dans
le flux dump mais l'opération peut être limitée en utilisant l'option
--revision
(-r
).
Générer un flux dump de tout l'historique d'un dépôt distant (on considère que l'utilisateur qui lance la commande possède les droits suffisants pour accéder à l'ensemble des chemins dans le dépôt) :
$ svnrdump dump http://svn.exemple.com/depot/calc > dump-complet * Dumped revision 0. * Dumped revision 1. * Dumped revision 2. …
Générer un flux dump incrémental d'une seule révision du même dépôt :
$ svnrdump dump http://svn.exemple.com/depot/calc \ -r 21 --incremental > dump-incrémental * Dumped revision 21. $
svnrdump help — À l'aide !
svnrdump help
svnrdump load
svnrdump load URL_DEST
Lire sur l'entrée standard le flux dump correspondant au contenu
d'un dépôt Subversion et charger ce contenu dans le dépôt situé à
DEST_URL
.
Décharger le contenu du dépôt local et utiliser svnrdump load pour transférer le contenu dans un dépôt distant :
$ svnadmin dump -q /var/svn/depot/nouveau-projet | \ svnrdump load http://svn.exemple.com/depot/nouveau-projet * Loaded revision 0 * Loaded revision 1. * Loaded revision 2. …
Note | |
---|---|
Pour fonctionner correctement,
svnrdump load requiert que le dépôt cible soit
configuré pour accepter les modifications des propriétés de
révisions via la procédure
automatique |
svndumpfilter est un utilitaire en ligne de commande pour supprimer une partie de l'historique dans un fichier dump, soit en excluant, soit en ne gardant que, des chemins commençant par une ou plusieurs racines spéficiées. Pour plus de détails, référez-vous à la section intitulée « svndumpfilter ».
Les options de svndumpfilter sont globales, de la même manière que pour les commandes svn et svnadmin :
Options de svndumpfilter
--drop-empty-revs
En cas de filtrage, supprimer toutes les révisions vides (c'est-à-dire celles qui ne modifient pas le dépôt) du flux dump résultant.
--drop-all-empty-revs
Supprimer toutes les révisions vides trouvées dans le flux dump (sauf la révision 0).
--pattern
Traiter les préfixes de chemins fournis à la commande de filtrage comme des motifs de recherche plutôt que comme des chemins explicites.
--renumber-revs
Renuméroter les révisions qui restent après le filtrage.
--skip-missing-merge-sources
Omettre les sources fusionnées qui ont été supprimées par le filtrage. Sans cette option, svndumpfilter termine avec une erreur si l'origine d'une fusion a été supprimée alors que le chemin fusionné a été gardé par le filtrage.
--preserve-revprops
Si tous les noeuds d'une révision sont supprimés par le
filtrage et que l'option --drop-empty-revs
n'est
pas spécifiée, le comportement par défaut de
svndumpfilter consiste à supprimer toutes les
propriétés de révision sauf la date et l'entrée du journal (qui
indiquera simplement que la révision est vide). Spécifier cette
option préserve les propriétés de révision (ce qui peut avoir du
sens ou pas puisque les modifications afférentes ne figureront
plus dans le flux dump).
--targets
NOM_FICHIER
Lire les préfixes de chemins contenus dans le fichier
NOM_FICHIER
(un préfixe par ligne).
Cette option est particulièrement utile dans les filtrages
complexes qui demandent davantage de préfixes que ce qu'autorise
le système d'exploitation dans une seule ligne de
commande.
--quiet
Ne pas afficher les statistiques de filtrage.
svndumpfilter exclude — Exclure du flux dump résultant les chemins spécifiés.
svndumpfilter exclude PRÉFIXE...
Cette commande exclut du flux dump les chemins qui commencent par
le ou les PRÉFIXE
passés en
paramètres.
Nous avons un fichier dump issu d'un dépôt qui contient un
certain nombre de répertoires concernant des piques-niques et nous
voulons garder tout sauf la partie relative à
sandwichs
de ce dépôt. Nous excluons uniquement
ce chemin :
$ svndumpfilter exclude sandwichs < fichier-dump > fichier-dump-filtré Exclusion des préfixes : '/sandwichs' Révision 0 propagée en 0 Révision 1 propagée en 1 Révision 2 propagée en 2 Révision 3 propagée en 3 Révision 4 propagée en 4 1 nœud éliminé : '/sandwichs' $
Depuis Subversion 1.7, svndumpfilter peut
traiter l'argument PRÉFIXE
non
seulement comme une sous-chaîne ordinaire mais aussi en tant que
motif de fichiers. Ainsi, par exemple, si vous voulez exclure les
chemins qui se terminent par .OLD
, vous pouvez
entrer la commande suivante :
$ svndumpfilter exclude --pattern "*.OLD" < fichier-dump > fichier-dump-filtré Exclusion des motifs de préfixes : '/*.OLD' Révision 0 propagée en 0 Révision 1 propagée en 1 Révision 2 propagée en 2 Révision 3 propagée en 3 Révision 4 propagée en 4 3 nœuds éliminés : '/condiments/sel.OLD' '/condiments/poivre.OLD' '/garniture/fromage.OLD' $
svndumpfilter include — Exclure du flux dump résultant tous les chemins qui ne sont pas spécifiés.
svndumpfilter include PRÉFIXE...
Cette commande ne retient dans le flux dump que les chemins qui
commencent par le ou les PRÉFIXE
passés en
paramètres (excluant de fait tous les autres chemins).
Nous avons un fichier dump issu d'un dépôt qui contient un
certain nombre de répertoires concernant des piques-niques et nous
voulons garder uniquement la partie relative à
sandwichs
de ce dépôt. Nous allons inclure
uniquement ce chemin :
$ svndumpfilter include sandwichs < fichier-dump > fichier-dump-filtré Inclusion des préfixes : '/sandwichs' Revision 0 propagée en 0 Revision 1 propagée en 1 Revision 2 propagée en 2 Revision 3 propagée en 3 Revision 4 propagée en 4 12 nœuds éliminés : '/condiments' '/condiments/poivre' '/condiments/poivre.OLD' '/condiments/sel' '/condiments/sel.OLD' '/boissons' '/encas' '/fournitures' '/garnitures' '/garnitures/fromage' '/garnitures/fromage.OLD' '/garnitures/laitue' $
Depuis Subversion 1.7, svndumpfilter peut
traiter l'argument PRÉFIXE
non
seulement comme une sous-chaîne ordinaire mais aussi en tant que
motif de fichiers. Ainsi, par exemple, si vous voulez n'inclure que
les chemins qui se terminent par as
, vous pouvez
entrer la commande suivante :
$ svndumpfilter include --pattern "*ks" < fichier-dump > fichier-dump-filtré Inclusion des motifs de préfixes : '/*as' Revision 0 propagée en 0 Revision 1 propagée en 1 Revision 2 propagée en 2 Revision 3 propagée en 3 Revision 4 propagée en 4 11 nœuds éliminés : '/condiments' '/condiments/poivre' '/condiments/poivre.OLD' '/condiments/sel' '/condiments/sel.OLD' '/boissons' '/fournitures' '/garnitures' '/garnitures/fromage' '/garnitures/fromage.OLD' '/garnitures/laitue' $
svndumpfilter help — À l'aide !
svndumpfilter help [SOUS_COMMANDE...]
Le client texte Subversion pour URL multiples (Subversion Multiple URL Command Client, svnmucc) est un outil pour effectuer n'importe quelles modifications sur un dépôt sans disposer de copie de travail. Pour ce qui concerne les actions à distance sur un dépôt, les fonctionnalités de cet outil dépassent très largement ce qu'il est possible de faire avec le client texte interactif Subversion. Par exemple, svnmucc n'est pas limité à une seule modification par propagation. Il est aussi capable de modifier le contenu des fichiers et les propriétés suivies en versions, toujours sans copie de travail, ce qui est actuellement impossible avec svn.
Cette documentation de référence décrit l'outil svnmucc et les différentes actions de modification que vous pouvez faire avec lui.
svnmucc — Effectuer une ou plusieurs actions sur un dépôt Subversion et propager les modifications résultantes dans une nouvelle révision atomique.
svnmucc
ACTION…
svnmucc est un programme pour modifier des
données suivies en versions par Subversion sans utiliser une copie
de travail. Il permet d'effectuer les opérations directement
via les URL des fichiers et dossiers
du dépôt que l'utilisateur souhaite modifier. Chaque invocation de
la commande svnmucc tente une ou plusieurs
ACTION
s, en propageant de manière atomique
les modifications résultantes dans une unique nouvelle
révision.
svnmucc comprend les actions suivantes (et leurs paramètres), qui peuvent être combinées dans des séquences ordonnées dans la ligne de commande :
REV
URL_SRC
URL_DST
Copier le fichier ou dossier situé à
URL_SRC
dans la révision
REV
vers
URL_DST
.
URL
Créer un nouveau dossier à
URL
. Le dossier parent de
URL
doit déjà exister (ou avoir été
créé par une action svnmucc précédente) car
cette commande ne permet pas de créer automatiquement les
dossiers parents intermédiaires manquants.
.
URL_SRC
URL_DST
Déplacer le fichier ou dossier situé à
SRC-URL
vers
DST-URL
.
URL
Effacer le fichier ou dossier situé à
URL
.
FICHIER_SOURCE
URL
Ajouter un nouveau fichier (ou modifier un fichier
existant) situé à
URL
en copiant le contenu du fichier
local SRC-FILE
. Notez que
SRC-FILE
peut valoir
-
pour que svnmucc lise
l'entrée standard plutôt qu'un fichier du système de fichiers
local.
NOM_PROPRIÉTÉ
VALEUR
URL
Définir la valeur de la propriété
NOM_PROPRIÉTÉ
de l'élément situé à
URL
à VALEUR
.
NOM_PROPRIÉTÉ
FICHIER
URL
Définir la valeur de la propriété
NOM_PROPRIÉTÉ
de l'élément situé à
URL
au contenu du fichier FICHIER
.
NOM_PROPRIÉTÉ
URL
Effacer la propriété NOM_PROPRIÉTÉ
de l'élément situé à URL
.
Les options spécifiées sur une ligne de commande à svnmucc sont globales à toutes les actions effectuées par cette ligne de commande. La liste des options comprises par cet outil est la suivante :
--config-dir
REP
Lire la configuration dans le répertoire spécifié plutôt
qu'à l'endroit par défaut (.subversion
dans le répertoire de l'utilisateur).
--config-option
CONFSPEC
Définir, pour la durée de la commande, la valeur d'une
option de configuration.
CONFSPEC
est une chaîne de caractères
qui spécifie l'espace de nom de l'option de configuration, son
nom et la valeur que vous voulez lui assigner, formatée
ainsi :
FICHIER
:SECTION
:OPTION
=[VALEUR
]
Dans cette syntaxe, FICHIER
et
SECTION
sont des fichiers de la zone
de configuration (config
ou
servers
) et de la section où se trouve
l'option dont vous voulez changer la valeur.
OPTION
est, bien sûr, le nom de
l'option elle-même et
VALEUR
est la valeur (si vous la
donnez) que vous voulez assigner à l'option. Par exemple, pour
désactiver temporairement la compression dans le protocole
HTTP, utilisez
--config-option=servers:global:http-compression=no
.
Vous pouvez utiliser cette option plusieurs fois pour modifier
les valeurs de plusieurs options temporairement.
--extra-args
(-X
)
FICHIER_ARGS
Lire les arguments supplémentaires (qu'on aurait placés
dans la ligne de commande) dans
FICHIER_ARGS
, un argument par ligne.
Notez que FICHIER_ARGS
peut valoir
-
pour indiquer que les arguments
supplémentaires doivent être lus depuis l'entrée
standard.
--file
(-F
)
FICHIER_MSG
Utiliser le contenu de
FICHIER_MSG
comme commentaire de
propagation.
--help
(-h
,
-?
)Afficher le mode d'emploi du programme et terminer.
--message
(-m
)
MSG
Utiliser MSG
comme commentaire
de propagation.
--no-auth-cache
Ne pas conserver les éléments d'authentification (par exemple l'identifiant et le mot de passe) dans les zones de configuration de Subversion.
--non-interactive
Ne rien demander de manière interactive (par exemple identifiant et mot de passe).
--revision
(-r
)
REV
Utiliser REV
comme révision
de base pour toutes les modifications faites
via les actions
svnmucc. Cette option est particulièrement
importante et son utilisation est vivement encouragée pour
modifier des éléments suivis en versions, afin d'éviter
d'annuler des changements faits de manière concomittante par
les autres membres de l'équipe.
--root-url
(-U
)
URL_RACINE
Utiliser URL_RACINE
comme URL de
référence. Les autres cibles seront relatives à cette URL.
Cette URL n'a pas besoin d'être l'URL racine du dépôt (celle
qui est indiquée par svn info). Ce peut être
n'importe quelle URL commune aux différentes cibles qui sont
spécifiées dans les actions svnmucc.
--password
(-p
)
MOT_DE_PASSE
Spécifie le mot de passe à utiliser pour s'authentifier auprès d'un serveur Subversion. Si le mot de passe n'est pas fourni ou s'il est incorrect, Subversion vous demandera cette information quand il en aura besoin.
--username
IDENTIFIANT
Spécifie l'identifiant (ou nom d'utilisateur) à utiliser pour s'authentifier auprès d'un serveur Subversion. S'il n'est pas fourni ou s'il est incorrect, Subversion vous demandera cette information quand il en aura besoin.
--version
Afficher les informations sur la version du programme et terminer.
--with-revprop
NOM_PROPRIÉTÉ
=VALEUR
Définir la valeur de la propriété de révision
NOM_PROPRIÉTÉ
à
VALEUR
dans la révision qui est
propagée.
Pour modifier le contenu d'un fichier (de manière sûre) sans utiliser de copie de travail, utilisez svn cat pour récupérer le contenu actuel du ficheir et svnmucc put pour propager le contenu modifié.
$ # Définir quelques variables utiles $ export URL_FICHIER=http://svn.exemple.com/projets/bac-à-sable/LISEZMOI $ export REV_BASE=`LC_ALL=C svn info ${URL_FICHIER} | \ grep '^Last Changed Rev' | cut -d ' ' -f 2` $ # Obtenir une copie du fichier avec son contenu actuel $ svn cat ${URL_FICHIER}@${REV_BASE} > /tmp/LISEZMOI.tempo $ # Modifier le fichier (copié) $ vi /tmp/LISEZMOI.tempo $ # Propager le nouveau contenu du fichier. $ svnmucc -r ${REV_BASE} put LISEZMOI.tempo ${URL_FICHIER} \ -m "Quelques modifs dans LISEZMOI." r24 committed by harry at 2013-01-21T16:21:23.100133Z $ # Un peu de nettoyage pour terminer. $ rm /tmp/LISEZMOI.tempo
Appliquer une démarche similaire pour modifier une propriété de fichier ou de dossier. Utiliser simplement svn propget et svnmucc propsetf au lieu de svn cat et svnmucc put.
$ # Définir quelques variables utiles $ export URL_PROJET=http://svn.exemple.com/projets/bac-à-sable $ export REV_BASE=`LC_ALL=C svn info ${URL_PROJET} | \ grep '^Last Changed Rev' | cut -d ' ' -f 2` $ # Obtenir une copie du fichier avec son contenu actuel $ svn -r {REV_BASE} propget license ${URL_PROJET} > /tmp/prop.tempo $ # Modifier la valeur de la propriété $ vi /tmp/prop.tempo $ # Propager la nouvelle valeur de propriété. $ svnmucc -r ${REV_BASE} propsetf prop.tempo ${URL_PROJET} \ -m "Modifié la propriété Licence de la racine du projet." r25 committed by harry at 2013-01-21T16:24:11.375936Z $ # Un peu de nettoyage pour terminer. $ rm /tmp/prop.tempo
Regardons maintenant quelques exemples avec plusieurs opérations.
Pour implémenter une « étiquette mobile » où une unique étiquette évolue pour pointer vers différents instantanés (par exemple la dernière version stable) d'un projet, utilisez svnmucc rm et svnmucc cp:
$ svnmucc -U http://svn.exemple.com/projets/bidule \ rm tags/dernière-stable \ cp HEAD trunk tags/dernière-stable \ -m "Ajusté l'étiquette 'dernière-stable'." r134 committed by harry at 2013-01-12T11:02:16.142536Z $
Dans l'exemple supra, nous avons
subtilement introduit l'option --root-url (-U)
.
Vous pouvez utiliser cette option pour définir une URL de référence
par rapport à laquelle toutes les autres URL seront relatives (cela
vous fera aussi gagner quelques caractères dans la ligne de
commande).
L'exemple infra montre l'utilisation de svnmucc pour, en une seule propagation, créer une nouvelle version étiquetée pour le projet qui inclut un fichier de description nouveau et efface un dossier qui ne doit pas apparaître dans, disons, une archive publiée.
$ echo "Création de la version publiée 1.2.0." | \ svnmucc -U http://svn.exemple.com/projets/bidule \ -m "Création de la version étiquetée 1.2.0." \ -- \ cp HEAD trunk tags/1.2.0 \ rm tags/1.2.0/notes-de-développements \ put - tags/1.2.0/LISEZMOI.tag r164 committed by cmpilato at 2013-01-22T05:26:15.563327Z $ svn log -c 164 -v http://svn.exemple.com/projets/bidule ------------------------------------------------------------------------ r164 | cmpilato | 2013-01-22 00:26:15 -0500 (mar. 22 jan 2013) | 1 ligne Chemins modifiés : A /tags/1.2.0 (de /trunk:163) A /tags/1.2.0/LISEZMOI.tag D /tags/1.2.0/notes-de-développement Création de la version étiquetée 1.2.0. $
L'exemple supra montre non
seulement comment effectuer différentes actions dans une seule
ligne de commande svnmucc mais aussi l'utilisation
de l'entrée standard pour définir le contenu d'un nouveau fichier.
Notez la présence de --
pour indiquer la fin des
options dans la ligne de commande. C'est nécessaire pour que le
-
de svnmucc put ne soit pas
interprété comme un indicateur d'une nouvelle option.
Les dépôts Subversion fournissent des procédures automatiques (hook en anglais) dont l'objet principal est de pouvoir étendre facilement les fonctionnalités de Subversion à des moments clés des opérations importantes. Les procédures automatiques sont implémentées sous la forme de programmes exécutés par Subversion lui-même à ces moments clés (avant et après une propagation, avant et après le verrouillage d'un fichier par un utilisateur, etc.).
Pour chaque procédure automatique, Subversion lance le
programme qui se trouve dans le sous-dossier
hooks/
de l'emplacement du dépôt sur le
système de fichiers et dont le nom correspond à la
procédure voulue. Par exemple, sur un système de type Unix, le
programme correspondant à la procédure automatique exécutée avant
une propagation doit se trouver à
.
Ce peut être un exécutable binaire, un script shell, un programme
Python, etc. Sur un système Windows, le programme doit se trouver
au même emplacement mais doit se nommer
CHEMIN_DÉPÔT
/hooks/start-commitSTART-COMMIT.EXE
ou
START-COMMIT.BAT
au lieu de simplement
start-commit
.
Ce guide de référence décrit les différentes procédures automatiques proposées par Subversion, détaillant le moment où est appelée la procédure, ses paramètres d'entrée et la manière dont elle modifie le comportement de Subversion.
start-commit — Notification du début d'une propagation.
start-commit
CHEMIN_DÉPÔT
UTILISATEUR
CAPACITÉS
NOM_TRANSACTION
La procédure automatique start-commit
est activée immédiatement après que la transaction de
propagation ne soit créée et que ses propriétés ne soient fixées
aux valeurs initiales. Typiquement, elle est utilisée pour
décider rapidement s'il convient d'interdire la propagation, en
évitant d'attendre que le long processus de propagation n'échoue
à la fin en raison, par exemple, de droits insuffisants alloués
à l'utilisateur pour propager une révision ou d'invalidation de
métadonnées relatives à la propagation.
Si le code de retour de la procédure automatique
start-commit
est non nul, la propagation est
arrêtée, la transaction de propagation détruite et tout ce qui a
été écrit vers stderr
est renvoyé vers le
client.
La procédure automatique start-commit
n'a pas vocation à valider le contenu d'une propagation
puisqu'elle est appelée avant qu'aucune modification de fichier
ou de répertoire ne soit transmise. Utilisez la procédure
automatique pre-commit
(qui est décrite dans
pre-commit dans ce guide
de référence) pour cela.
Note | |
---|---|
Avant Subversion 1.8, Subversion appelait la procédure
automatique |
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt
identifiant (authentifié) de l'utilisateur qui initie la propagation ;
liste, dont les éléments sont séparés par des virgules,
de capacités que le client passe au serveur, dont
depth
, mergeinfo
et
log-revprops
(à partir de
Subversion 1.5) ;
nom de la transaction de propagation (nouveau dans Subversion 1.8)
pre-commit — Notification juste avant la fin de la propagation.
pre-commit
REPOS-PATH
TXN-NAME
La procédure automatique pre-commit
est
activée juste avant que la transaction de propagation ne génère
une nouvelle révision. Cette procédure automatique est
typiquement utilisée pour protéger le dépôt vis-à-vis de
propagations qui ne respectent pas certaines règles relatives au
contenu ou au chemin (par exemple, votre dépôt peut imposer que
les propagations sur une certaine branche incluent un numéro de
ticket de l'outil de gestion de suivi des bogues ou alors que
l'entrée du journal de propagation ne soit pas vide).
Si le code de retour de la procédure automatique
pre-commit
est non nul, la propagation est
annulée, la transaction de propagation supprimée et tout ce qui
a été écrit vers stderr
est renvoyé vers le
client.
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
nom de la transaction de propagation.
En complément, Subversion passe les jetons de verrouillage
fournis par le client à la procédure automatique en utilisant
l'entrée standard. Lorsqu'il y en a, ils sont placés dans
l'enchaînement composé d'une ligne qui contient
LOCK-TOKENS:
suivie par autant de lignes que
de jetons contenant chacune les informations de chaque
jeton : l'URI au format échappé du chemin dans le
système de fichiers du dépôt du chemin verrouillé, suivi par un
caractère pipe (|
) indiquant la séparation et
enfin la chaine de caractère identifiant le verrou.
post-commit — Notification d'une propagation réussie.
post-commit
CHEMIN_DÉPÔT
RÉVISION
NOM_TRANSACTION
La procédure automatique post-commit
est activée après que la transaction ait été validée et que la
nouvelle révision soit créée. La plupart des administrateurs
utilisent cette procédure automatique pour envoyer des e-mails
décrivant la propagation ou pour notifier à d'autres outils
(tels que les outils de gestion pour le suivi de bogues) qu'une
nouvelle propagation a eu lieu. Certains utilisent cette
procédure automatique pour déclencher une sauvegarde.
Si le code de retour de la procédure automatique
post-commit
est non nul, la propagation
a bien eu lieu puisqu'elle est déjà
terminée. Cependant, tout ce qui a été écrit vers
stderr
est renvoyé vers le client, afin de
trouver plus facilement la raison de l'échec de la procédure
automatique.
pre-revprop-change — Notification avant le changement d'une propriété de révision.
pre-revprop-change
CHEMIN_DÉPÔT
RÉVISION
UTILISATEUR
NOM_PROPRIÉTÉ
ACTION
La procédure automatique
pre-revprop-change
est activée juste avant la
modification d'une propriété de révision quand elle n'a pas lieu
dans le cadre d'une propagation normale. Contrairement aux
autres procédures automatiques, la configuration par défaut de
cette procédure automatique est d'interdire l'action demandée.
La procédure automatique doit exister effectivement et le code
de retour doit être nul pour autoriser la modification d'une
propriété de révision.
Si la procédure automatique
pre-revprop-change
n'existe pas, ne possède
pas les droits d'exécution ou si le code de retour n'est pas
nul, la propriété n'est pas modifiée et tout ce qui a été écrit
vers stderr
est renvoyé vers le
client.
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
révision dont une propriété va être modifiée ;
identifiant (authentifié) de l'utilisateur qui demande la modification de la propriété ;
Nom de la propriété à modifier ;
Description de la modification :
A
(ajout),
D
(suppression) ou M
(modification).
Par ailleurs, Subversion fournit la nouvelle valeur de la propriété à la procédure automatique via l'entrée standard.
post-revprop-change — Notification d'une modification de propriété de révision réussie.
post-revprop-change
CHEMIN_DÉPÔT
RÉVISION
UTILISATEUR
NOM_PROPRIÉTÉ
ACTION
La procédure automatique
post-revprop-change
est activée immédiatement
après la modification d'une propriété de révision, quand elle
n'a pas lieu dans le cadre d'une propagation normale. Comme vous
pouvez le deviner à la lecture de la description de son
homologue, la procédure automatique
pre-revprop-change
, cette procédure
automatique ne peut être activée que si
pre-revprop-change
est implémentée. Cette
procédure automatique est principalement utilisée pour envoyer
des e-mails de notification qu'une propriété a été
modifiée.
Si le code de retour de la procédure automatique
post-revprop-change
est non nul, la
modification a bien eu lieu puisqu'elle est
déjà terminée. Cependant, tout ce qui a été écrit vers
stderr
est renvoyé vers le client, afin de
trouver plus facilement la raison de l'échec de la procédure
automatique.
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
révision dont une propriété a été modifiée ;
identifiant (authentifié) de l'utilisateur qui a effectué la modification de la propriété ;
nom de la propriété modifiée ;
Description de la modification :
A
(ajout),
D
(suppression) ou M
(modification).
Par ailleurs, Subversion fournit la valeur précédente de la propriété à la procédure automatique via l'entrée standard.
pre-lock — Notification d'une demande de verrouillage d'un chemin.
pre-lock
CHEMIN_DÉPÔT
CHEMIN
UTILISATEUR
COMMENTAIRE
DRAPEAU_CASSAGE
La procédure automatique pre-lock
est
activée lorsque quelqu'un demande à verrouiller un chemin. Elle
peut être utilisée pour empêcher tout verrouillage ou pour
définir une politique plus complexe où tels utilisateurs sont
autorisés à verrouiller tels chemins. Si la procédure
automatique détecte un verrou pré-existant, elle peut aussi
décider si l'utilisateur est autorisé à « voler » ce
verrou pré-existant.
Si le code de retour de la procédure automatique
pre-lock
est non nul, le verrouillage est
annulé et tout ce qui a été écrit vers
stderr
est renvoyé vers le client.
La procédure automatique peut aussi imposer le jeton de verrouillage qui sera utilisé en affichant le jeton sur la sortie standard. Pour cette raison, les implémentations de cette procédure automatique doivent bien faire attention à ce qu'elles écrivent sur la sorie standard.
Avertissement | |
---|---|
Si la procédure automatique |
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
chemin géré en versions qui va être verrouillé ;
identifiant (authentifié) de l'utilisateur qui demande le verrouillage.
Commentaire fourni lorsque le verrou a été créé
1
si l'utilisateur essaie de casser
un verrou existant ; 0
sinon.
post-lock — Notification d'un verrouillage de chemin réussi.
post-lock
CHEMIN_DÉPÔT
UTILISATEUR
La procédure automatique post-lock
est
activée après qu'un ou plusieurs chemins aient été verrouillés.
Elle est utilisée typiquement pour envoyer des e-mails de
notification signalant ce verrouillage.
Si le code de retour de la procédure automatique
post-lock
est non nul, le verrouillage
a bien lieu puisqu'il est déjà effectif.
Cependant, tout ce qui a été écrit vers
stderr
est renvoyé vers le client, afin de
trouver plus facilement la raison de l'échec de la procédure
automatique.
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
identifiant (authentifié) de l'utilisateur qui a effectué le verrouillage ;
En complément, la liste des chemins verrouillés est fournie à la procédure automatique via l'entrée standard, un chemin par ligne.
pre-unlock — Notification d'une demande de déverrouillage d'un chemin.
pre-unlock
CHEMIN_DÉPÔT
CHEMIN
UTILISATEUR
JETON
DRAPEAU_CASSAGE
La procédure automatique pre-unlock
est
activée lorsque quelqu'un demande à supprimer un verrou sur un
fichier. Elle peut être utilisée pour définir des politiques
qui spécifient que tels utilisateurs sont autorisés à
déverrouiller tels chemins. Ceci est particulièrement important
dans le cadre de votre politique globale de verrouillage. Si un
utilisateur A verrouille un fichier, est-ce que l'utilisateur B
est autorisé à casser ce verrou ? Qu'en est-il si le verrou
est âgé de plus d'une semaine ? Ce type de politique peut
être implémenté par la procédure automatique.
Si le code de retour de la procédure automatique
pre-unlock
est non nul, le déverrouillage
n'a pas lieu et tout ce qui a été écrit vers
stderr
est renvoyé vers le client.
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
Chemin géré en versions qui va être déverrouillé ;
identifiant (authentifié) de l'utilisateur qui demande le déverrouillage ;
jeton de verrouillage associé au verrou qui doit être supprimé ;
1
si l'utilisateur essai de casser le
verrou ; 0
sinon.
post-unlock — Notification d'un déverrouillage de chemin réussi.
post-unlock
CHEMIN_DÉPÔT
UTILISATEUR
La procédure automatique post-unlock
est
activée après qu'un ou plusieurs chemins aient été d
éverrouillés. Elle est utilisée typiquement pour envoyer des
e-mails de notification signalant ce déverrouillage.
Si le code de retour de la procédure automatique
post-unlock
est non nul, le déverrouillage
a bien eu lieu. Cependant, tout ce qui a
été écrit vers stderr
est renvoyé vers le
client, afin de trouver plus facilement la raison de l'échec de
la procédure automatique.
Les arguments de la ligne de commande passés à la procédure automatique sont, dans l'ordre :
chemin du dépôt ;
identifiant (authentifié) de l'utilisateur qui a effectué le déverrouillage ;
En complément, la liste des chemins déverrouillés est fournie à la procédure automatique via l'entrée standard, un chemin par ligne.
Si vous êtes pressé d'installer et d'utiliser Subversion (et que vous aimez apprendre en expérimentant), cette annexe vous indique comment créer un dépôt, importer votre code puis comment en extraire une copie de travail. Tout au long de l'exposé, nous vous fournissons des liens vers les chapitres correspondants de ce livre.
Avertissement | |
---|---|
Si vous débutez avec les concepts de suivi de versions ou avec le modèle « Copier-Modifier-Fusionner » utilisé par CVS et Subversion, nous vous conseillons de lire le Chapitre 1, Notions fondamentales avant d'aller plus loin. |
Subversion est construit sur une couche de portabilité appelée APR (Apache Portable Runtime en anglais, pour bibliothèque Apache de portabilité des exécutables). Cette bibliothèque APR fournit toutes les interfaces dont Subversion a besoin pour fonctionner sur différents systèmes d'exploitation : accès aux disques, au réseau, gestion de la mémoire, et bien d'autres choses encore. La couche d'abstraction apportée par APR permet aux clients et serveurs Subversion de fonctionner sur tous les systèmes d'exploitation sur lesquels fonctionnent les applications utilisant l'APR : Windows, Linux, tous les systèmes BSD, Mac OS X, NetWare entre autres.
Note | |
---|---|
Bien que la bibliothèque APR fasse partie du serveur HTTP Apache (la commande httpd) et que httpd puisse être utilisée en tant que serveur de dépôts Subversion, httpd n'est pas un composant indispensable pour une installation de Subversion. |
La manière la plus simple d'obtenir Subversion est de télécharger un programme précompilé pour votre système d'exploitation. Le site Web de Subversion (https://subversion.apache.org) tient à disposition de nombreux paquets produits par des volontaires. Le site contient généralement des exécutables avec une interface graphique d'installation pour les utilisateurs de systèmes Microsoft. Si votre système d'exploitation est de type Unix, vous pouvez utiliser le gestionnaire de paquets fourni avec votre distribution (RPM, DEB, l'arbre des ports, etc.) pour obtenir Subversion.
Sinon, vous pouvez aussi compiler Subversion directement
à partir des sources, bien que ce ne soit pas toujours facile
(si vous n'avez pas l'habitude de compiler vos logiciels,
choisissez plutôt de télécharger un paquet précompilé pour votre
distribution). Sur le site Web de Subversion, téléchargez la
dernière version du code source. Puis, après l'avoir décompacté,
suivez les instructions fournies dans le fichier
INSTALL
pour la compilation.
Si vous êtes de ceux qui aiment avoir la toute dernière version des logiciels, vous pouvez aussi obtenir le code source de Subversion depuis le dépôt Subversion. Évidemment, il faudra pour y parvenir que vous disposiez déjà d'un client Subversion… Mais, si c'est le cas, vous pouvez extraire une copie de travail du dépôt contenant le code source de Subversion à l'adresse https://svn.apache.org/repos/asf/subversion[83] :
$ svn checkout https://svn.apache.org/repos/asf/subversion/trunk subversion A subversion/HACKING A subversion/INSTALL A subversion/README A subversion/autogen.sh A subversion/build.conf …
La commande précédente crée une copie de travail de la dernière
version (non officielle) du code source de Subversion dans un
sous-répertoire appelé subversion
de votre
répertoire de travail courant. Vous pouvez modifier le dernier
argument à votre convenance. Indépendamment du nom que vous donnez
au répertoire contenant la nouvelle copie de travail, une fois
cette opération terminée, vous aurez à votre disposition le code
source de Subversion. Bien sûr, il vous faudra encore récupérer
quelques autres bibliothèques (apr, apr-util, etc.)— consultez
le fichier INSTALL
dans le répertoire racine
de la copie de travail pour plus de détails.
« Vérifiez que le dossier de votre siège est relevé, que votre ceinture est correctement bouclée et que la tablette devant vous est rangée et verrouillée. Personnel de cabine, attention au décollage… »
Ce qui suit est un bref tutoriel qui couvre quelques opérations élémentaires, ainsi que la configuration de base de Subversion. Une fois que vous l'aurez terminé, vous devriez avoir une compréhension globale de la façon dont Subversion peut être utilisé.
Note | |
---|---|
Les exemples utilisés dans cette annexe supposent que vous
disposez de svn (le client en ligne de commande
de Subversion) et de svnadmin (l'outil
d'administration) prêts à l'emploi sur un système de type Unix
(ce tutoriel fonctionne également en ligne de commande sous
Windows, sous réserve de quelques adaptations triviales). Nous
supposons également que vous utilisez la version 1.2 ou ultérieure
de Subversion (tapez |
Subversion stocke toutes les données suivies en versions dans un dépôt central. Pour commencer, créez un nouveau dépôt :
$ cd /var/svn $ svnadmin create depot $ ls depot conf/ dav/ db/ format hooks/ locks/ README.txt
Cette commande crée un nouveau dépôt Subversion dans le répertoire
/var/svn/depot
, en créant le répertoire
depot
s'il n'existe pas déjà. Ce répertoire
contient (entre autres choses) un ensemble de fichiers constituant une
base de données. Vous ne verrez pas vos fichiers suivis en versions si
vous examinez le contenu de ces fichiers. Pour plus d'informations sur
la création et la maintenance des dépôts, consultez le
Chapitre 5, Administration d'un dépôt.
Dans Subversion, il n'existe pas de concept de « projet ». Le dépôt est juste un système de fichiers virtuel suivi en versions, une arborescence qui peut contenir tout ce que vous voulez. Certains administrateurs préfèrent ne stocker qu'un seul projet par dépôt, d'autres préfèrent stocker plusieurs projets par dépôt en les plaçant dans des répertoires distincts. Les mérites de chacune de ces approches sont discutés dans la section intitulée « Stratégies d'organisation d'un dépôt ». De toute façon, le dépôt ne fait que gérer des fichiers et des répertoires, c'est donc aux humains de faire le lien entre répertoires et « projets ». Ainsi, bien que vous trouverez mention de projets dans ce livre, gardez en mémoire que nous ne parlons jamais que d'un répertoire (ou d'un ensemble de répertoires) du dépôt.
Dans cet exemple, nous supposons que vous avez déjà une sorte de
projet (c'est-à-dire un ensemble de fichiers et de répertoires) que
vous voulez importer dans votre dépôt Subversion tout neuf.
Commencez par organiser vos données dans un répertoire unique appelé
mon-projet
(ou quoi que ce soit d'autre). Pour
des raisons que nous expliquons au
Chapitre 4, Gestion des branches, la structure de votre
arborescence doit contenir trois répertoires à la racine :
branches
, tags
, et
trunk
. Le répertoire trunk
doit contenir toutes vos données et les répertoires
branches
et tags
doivent être vides :
/tmp/
mon-projet/
branches/
tags/
trunk/
machin.c
truc.c
Makefile
…
Les sous-répertoires branches
,
tags
et trunk
ne sont pas réellement requis par Subversion. Ils font simplement
partie des conventions d'utilisation que vous voudrez certainement
suivre par la suite.
Une fois l'arborescence de vos données prête, importez-la dans le dépôt avec la commande svn import (reportez-vous à la section intitulée « Enregistrement de données dans le dépôt ») :
$ svn import /tmp/mon-projet file:///var/svn/depot/mon-projet \ -m "Import initial" Ajout /tmp/mon-projet/branches Ajout /tmp/mon-projet/tags Ajout /tmp/mon-projet/trunk Ajout /tmp/mon-projet/trunk/Makefile Ajout /tmp/mon-projet/trunk/machin.c Ajout /tmp/mon-projet/trunk/truc.c … Révision 1 propagée. $
À présent, le dépôt contient cette arborescence de données. Comme
indiqué précédemment, vous ne verrez pas vos fichiers directement en
regardant dans le dépôt : ils sont stockés dans un magasin de
données. Mais le système de fichiers imaginaire du dépôt contient
désormais un répertoire racine appelé mon-projet
,
qui à son tour contient vos données.
Notez que le répertoire original
/tmp/mon-projet
n'a pas été modifié ;
Subversion ignore tout de son existence (en fait, vous pouvez même le
supprimer si vous voulez). Pour commencer à manipuler les données du
dépôt, vous devez créer une nouvelle « copie de travail »
des données, une sorte d'espace de travail privé. Demandez à Subversion
de vous « extraire » une copie de travail du répertoire
mon-projet/trunk
du dépôt :
$ svn checkout file:///var/svn/depot/mon-projet/trunk monprojet A monprojet/Makefile A monprojet/machin.c A monprojet/truc.c … Révision 1 extraite.
À présent, vous disposez d'une copie personnelle d'une partie
du dépôt, située dans un nouveau répertoire appelé
monprojet
. Vous pouvez éditer les fichiers
dans votre copie de travail puis propager ces changements vers le
dépôt.
Entrez dans le répertoire de votre copie de travail et éditez le contenu d'un fichier ;
lancez la commande svn diff
pour
obtenir la liste des différences que vos modifications ont
engendrée ;
lancez la commande svn commit
pour
propager la nouvelle version de votre fichier vers le
dépôt ;
lancez la commande svn update
pour
« mettre à jour » votre copie de travail à partir
du dépôt.
Pour une description complète de ce que vous pouvez faire avec votre copie de travail, reportez-vous au Chapitre 2, Utilisation de base.
Dès lors, vous pouvez mettre votre dépôt à disposition sur le réseau. Consultez le Chapitre 6, Configuration du serveur pour découvrir les différents serveurs disponibles et la manière de les configurer.
[83] Notez que l'URL que l'on extrait dans cet exemple ne se
termine pas par subversion
, mais par un
sous-répertoire nommé trunk
. Reportez-vous
à notre discussion sur le modèle de gestion des branches de
Subversion pour en comprendre la raison.
Cette annexe est un guide pour les utilisateurs de CVS qui découvrent Subversion. Il est essentiellement constitué d'une liste de différences, « au doigt mouillé », entre les deux systèmes. Pour chaque section, nous fournissons autant que possible les références des chapitres pertinents.
Bien que le but de Subversion soit de s'emparer de la communauté des utilisateurs actuels et futurs de CVS, de nouvelles fonctionnalités et des changements conceptuels étaient nécessaires pour corriger certains comportements « malencontreux » de CVS. Cela signifie que, en tant qu'utilisateur de CVS, vous devrez vous défaire de certaines habitudes — celles dont vous avez oublié combien elles vous semblaient bizarres au début.
Dans CVS, les numéros de révisions sont associés à un fichier. Ceci est du au fait que CVS stocke ses données dans des fichiers RCS ; à chaque fichier est associé un fichier RCS dans le dépôt et la structure du dépôt correspond plus ou moins à l'arborescence de votre projet.
Dans Subversion, le dépôt ressemble à un système de fichiers unique. Chaque propagation conduit à un système de fichiers entièrement nouveau ; au fond, le dépôt est un tableau d'arborescences de fichiers. Chacune de ces arborescences est étiquetée avec un numéro de révision. Quand quelqu'un parle de la « révision 54 », il parle d'une arborescence particulière (et indirectement, de l'état du système de fichiers après la cinquante-quatrième propagation).
Techniquement, il n'est pas correct de parler de
« la révision 5 du fichier machin.c
».
À la place, on devrait dire « machin.c
tel qu'il était en révision 5 ». Soyez également prudent
quand vous faites des suppositions sur les évolutions d'un
fichier. Dans CVS, les révisions 5 et 6 de
machin.c
sont toujours différentes. Dans
Subversion, le plus probable est que machin.c
n'a pas changé entre les révisions 5 et
6.
De la même manière, dans CVS, une étiquette et une branche
sont des annotations sur un fichier ou sur l'information de
version de ce fichier. En revanche, dans Subversion, une branche
ou une étiquette sont des copies complètes d'une arborescence
(situées respectivement par convention dans les répertoires
branches/
et tags/
qui
se trouvent à la racine de l'arborescence du dépôt, à côté de
trunk/
). Dans l'ensemble du dépôt, plusieurs
versions de chaque fichier peuvent être visibles : la
dernière version à l'intérieur de chaque branche, la version au
sein de chaque étiquette et, bien sûr, la dernière version dans le
tronc lui-même (sous /trunk
). Ainsi, pour
être vraiment précis, il convient de dire
« machin.c
tel qu'il était dans
branches/IDÉE1
à la révision
5 ».
Pour plus de détails sur ce sujet, consultez la section intitulée « Révisions ».
Subversion assure le suivi de l'arborescence entière, pas seulement des fichiers. C'est une des raisons majeures pour lesquelles Subversion a été créé, dans le but de se substituer à CVS.
Voilà ce que cela implique, du point de vue d'un ancien utilisateur de CVS :
Les commandes svn add et svn
delete fonctionnent désormais aussi sur les
répertoires, de la même manière que sur les fichiers. Idem
pour svn copy et
svn move. Cependant, ces commandes n'ont
pas d'effet immédiat sur le dépôt ; en effet, elles ne
font que planifier l'ajout ou la
suppression des éléments concernés. Aucun changement n'a lieu
dans le dépôt tant que vous n'effectuez pas de propagation
(commande svn commit
).
Les répertoires ne sont plus de simples conteneurs ;
ils possèdent un numéro de révision tout comme les fichiers
(ou pour être plus précis, il faut parler du « répertoire
machin/
tel qu'il était à la révision
5 »).
Approfondissons ce dernier point. La gestion de versions d'un répertoire est un problème difficile ; comme nous voulons autoriser des copies de travail à cheval sur plusieurs révisions, des limitations apparaissent quand on essaie de pousser le modèle trop loin.
D'un point de vue théorique, nous définissons « la
révision 5 du répertoire machin
» comme
un ensemble d'entrées et de propriétés du répertoire. Maintenant,
supposons que nous ajoutons et supprimons des fichiers de
machin
, puis que nous propageons ces
modifications. Dire que nous avons toujours la révision 5 de
machin
est un mensonge. Cependant, si nous
changeons le numéro de révision de
machin
après la propagation, c'est aussi un
mensonge ; il peut y avoir d'autres changements sur
machin
que nous n'avons pas encore reçus
parce que nous n'avons pas encore effectué de mise à jour
(commande svn update).
Subversion traite ce problème en conservant discrètement, dans
la zone .svn
, le détail des ajouts et des
suppressions propagés. Par la suite, quand vous lancez
svn update
, ces informations sont prises en
compte et combinées avec celles du dépôt et le nouveau numéro de
révision du répertoire est alors positionné correctement. Ainsi,
c'est seulement après une mise à jour que vous pouvez
affirmer, sans risque de vous tromper, que vous disposez d'une
révision « parfaite » d'un répertoire.
La plupart du temps, votre copie de travail contient des
répertoires « imparfaitement » synchronisés.
De la même manière, un problème survient si vous essayez de propager des modifications de propriétés sur un répertoire. Normalement, la propagation devrait ajuster le numéro de révision du répertoire de la copie de travail locale. Mais là encore, ce serait un mensonge puisqu'il peut y avoir des ajouts et des suppressions que le répertoire n'a pas encore reçu en raison de la mise à jour qui n'a pas encore eu lieu. En conséquence, il n'est pas permis de propager des changements sur les propriétés d'un répertoire sans que ce répertoire ne soit préalablement mis à jour.
Pour plus d'informations sur les limitations de la gestion de versions des répertoires, reportez-vous à la section intitulée « Copies de travail mixtes, à révisions mélangées ».
Ces dernières années, l'espace de stockage sur disques est devenu outrageusement bon marché et abondant, alors que ce n'est pas le cas pour la bande passante disponible sur le réseau. En conséquence, les copies de travail Subversion ont été optimisées pour économiser la ressource la plus rare.
Le répertoire administratif .svn
a le
même objectif que le répertoire CVS
, à la
différence près qu'il stocke également des copies
« originales » en lecture seule de vos fichiers. Ceci
permet beaucoup d'opérations sans connexion réseau :
liste les modifications locales que vous avez apportées (voir la section intitulée « Vue d'ensemble des changements effectués ») ;
donne le détail de vos modifications (voir la section intitulée « Détail des modifications effectuées localement ») ;
supprime vos modifications locales (voir la section intitulée « Annulation des changements de la copie de travail »).
Par ailleurs, les fichiers originaux en cache permettent au client Subversion de n'envoyer que les différences au moment de la propagation, ce que CVS ne sait pas faire.
La dernière sous-commande de la liste (svn
revert) est nouvelle. Elle supprime non seulement les
modifications locales mais aussi annule les opérations planifiées
telles que les ajouts et les suppressions. Bien que supprimer le
fichier puis lancer svn
update
fonctionne toujours, cette méthode détourne la
mise à jour de sa vocation. Et puis, tant que nous y
sommes…
Subversion essaie de dissiper la confusion qui règne entre les commandes cvs status et cvs update.
La commande cvs status a deux
objectifs : d'abord, lister pour l'utilisateur les
modifications locales de la version de travail et, ensuite,
indiquer à l'utilisateur quels fichiers ne sont plus à jour.
Malheureusement, en raison de l'affichage peu lisible de la
commande cvs status
, beaucoup
d'utilisateurs de CVS n'utilisent plus cette commande. À la place,
ils ont pris l'habitude de lancer cvs update
ou cvs -n update
pour visualiser leurs
changements rapidement. Si les utilisateurs oublient d'utiliser
l'option -n
, cela a pour effet de bord de
fusionner des changements du dépôt qu'ils ne sont pas forcément
prêts à prendre en compte.
Subversion supprime ce cafouillage en facilitant la lecture de svn status à la fois pour les humains et pour les programmes d'analyse de texte. De plus, svn update n'affiche que les informations relatives aux fichiers qui ont été mis à jour côté dépôt, pas les modifications locales.
La commande svn status liste tous les fichiers qui ont des modifications locales. Par défaut, le dépôt n'est pas contacté. Bien que cette sous-commande accepte un bon nombre d'options, voici les plus utilisées :
-u
contacte le dépôt pour déterminer et lister les informations de mise à jour ;
-v
liste tous les éléments suivis en versions ;
-N
exécution non récursive (ne pas descendre dans les sous-répertoires).
La commande svn status possède deux formats de sortie. Dans le mode « court », mode par défaut, les modifications locales sont présentées comme ceci :
$ svn status M machin.c M truc/bidule.c
Si vous spécifiez l'option --show-updates
(-u
), un format d'affichage plus long est
utilisé :
$ svn status -u M 1047 machin.c * 1045 tetes.html * dessin.png M 1050 truc/bidule.c État par rapport à la révision 1066
Dans ce cas, deux nouvelles colonnes font leur apparition.
La deuxième colonne contient une astérisque si le fichier ou le
répertoire n'est plus à jour. La troisième colonne contient le
numéro de révision de la copie de travail pour l'élément
considéré. Dans l'exemple précédent, l'astérisque indique que
tetes.html
serait modifié lors d'une mise à
jour et que dessin.png
est un nouveau
fichier dans le dépôt (l'absence d'un numéro de révision pour
dessin.png
indique qu'il n'existe pas encore
dans la copie de travail locale).
Pour une présentation plus détaillée de svn status, avec l'explication des codes de statut vus dans l'exemple précédent, lisez la section intitulée « Vue d'ensemble des changements effectués ».
La commande svn update met à jour votre copie de travail et n'affiche que les informations relatives aux fichiers qui ont été mis à jour.
Subversion combine les codes CVS P
et
U
dans le seul code U
.
Quand une fusion ou un conflit apparaît, Subversion se contente
d'afficher G
ou C
, plutôt
qu'une phrase complète, pour indiquer ce qui se passe.
Pour plus d'informations sur svn update, reportez-vous à la section intitulée « Mise à jour de la copie de travail ».
Subversion ne fait pas de différence entre l'espace du système de fichiers et l'espace des branches ; les branches et les étiquettes sont de simples répertoires du système de fichiers. C'est probablement le saut psychologique le plus important que les utilisateurs de CVS doivent faire. Pour tout savoir sur ce sujet, rendez-vous au Chapitre 4, Gestion des branches.
Avertissement | |
---|---|
Puisque Subversion traite les branches et les étiquettes comme de simples répertoires, les différentes lignes de développement de votre projet sont probablement hébergées dans des sous-répertoires du répertoire du projet principal. En conséquence, n'oubliez pas de faire vos extractions en spécifiant l'URL du sous-répertoire qui contient la ligne de développement que vous désirez et pas l'URL racine du projet. Sinon, il y a de grandes chances pour que vous récupériez une copie complète de votre projet, y compris toutes les branches et toutes les étiquettes[84]. |
Une nouvelle fonctionnalité de Subversion est la possibilité d'affecter des métadonnées arbitraires (ou « propriétés ») aux fichiers et répertoires. Les propriétés sont des couples nom/valeur arbitraires associés aux fichiers et répertoires de votre copie de travail locale.
Pour définir ou récupérer un nom de propriété, utilisez les sous-commandes svn propset et svn propget. Pour obtenir la liste de toutes les propriétés d'un objet, utilisez svn proplist.
Pour plus d'informations, reportez-vous à la section intitulée « Propriétés ».
CVS signale les conflits par des « marqueurs de
conflits » insérés directement dans les fichiers puis
affiche un C
pendant l'opération de mise à jour
ou de fusion. Historiquement, ce comportement a généré beaucoup de
problèmes, car CVS ne finit pas son travail. Beaucoup
d'utilisateurs oublient (ou ne voient pas) le C
une fois qu'il disparaît de l'écran. Ils oublient aussi souvent
que les marqueurs de conflit sont toujours présents et,
accidentellement, propagent des fichiers contenant ces marqueurs
de conflit.
Subversion corrige ce problème de deux façons. D'abord, quand un conflit est détecté sur un fichier, Subversion enregistre le fait que le fichier est en conflit et refuse de propager des modifications concernant ce fichier tant que vous ne résolvez pas explicitement le conflit. Ensuite, Subversion 1.5 propose une résolution interactive des conflits, ce qui vous permet de résoudre les conflits au moment où ils apparaissent, plutôt que d'avoir à revenir dessus une fois que la fusion ou la mise à jour est terminée. Consultez la section intitulée « Résolution des conflits » pour plus d'informations sur la résolution des conflits avec Subversion.
En général, Subversion se débrouille mieux avec les fichiers binaires que CVS. Comme CVS utilise RCS, il est seulement capable de stocker successivement des copies entières d'un fichier binaire modifié. Subversion, en revanche, utilise un algorithme de différenciation binaire, indépendant du contenu textuel ou binaire des fichiers, pour déterminer les différences entre les fichiers. Cela veut dire que tous les fichiers sont stockés de manière différentielle (compressée) dans le dépôt.
Les utilisateurs de CVS doivent marquer les fichiers binaires
avec l'indicateur -kb
pour empêcher que les
données ne soient corrompues (par l'expansion des mots-clés et les
conversions de fins de lignes). Ils oublient quelquefois de le
faire.
Subversion utilise une approche plus paranoïaque. Premièrement, il ne fait aucune substitution de mot-clé ou de fin de ligne à moins qu'on ne le lui demande explicitement (voir la section intitulée « Substitution de mots-clés » et la section intitulée « Caractères de fin de ligne » pour plus de détails). Par défaut, Subversion considère que les fichiers de données sont des suites littérales d'octets et les fichiers sont toujours stockés dans le dépôt dans un état « non-converti ».
Deuxièmement, Subversion conserve une notion interne pour le contenu de chaque fichier : « texte » ou « binaire ». Mais cette notion ne s'applique qu'à la copie de travail locale. Lors d'un svn update, Subversion effectue des fusions contextuelles sur les fichiers texte modifiés localement mais ne tente pas d'en faire autant pour les fichiers binaires.
Pour déterminer si une fusion contextuelle est possible,
Subversion examine la propriété svn:mime-type
.
Si le fichier ne possède pas la propriété
svn:mime-type
ou si le type MIME est textuel
(par exemple text/*
), Subversion considère que
c'est du texte. Sinon, Subversion considère que le fichier est
binaire. Subversion aide également les utilisateurs en incluant
l'exécution d'un algorithme de détection des fichiers binaires
dans les commandes svn import
et svn add. Ces commandes tentent de deviner
puis affectent (éventuellement) un type binaire à la propriété
svn:mime-type
du fichier ajouté (si Subversion
se trompe dans la détection, l'utilisateur peut toujours supprimer
ou éditer à la main la propriété).
Contrairement à CVS, une copie de travail locale de Subversion sait qu'elle est l'extraction d'un module. Cela signifie que si quelqu'un change la définition du module (par exemple ajoute ou supprime des composants), un appel à svn update met à jour la copie de travail correctement, en ajoutant et supprimant les composants concernés.
Subversion définit les modules comme une liste de répertoires formant une propriété d'un répertoire ; voir la section intitulée « Définition de références externes ».
Avec le pserver de CVS, vous devez vous connecter au serveur (en utilisant la commande cvs login) avant n'importe quelle opération de lecture ou d'écriture — parfois, vous devez même vous authentifier pour des opérations en mode anonyme. Avec un dépôt Subversion utilisant Apache httpd ou svnserve, vous n'avez pas besoin de vous authentifier a priori (si une opération nécessite que vous vous authentifiez, le serveur vous demande de le faire, que ce soit par identifiant et mot de passe, certificat client ou les deux). Ainsi, si votre dépôt est accessible en lecture pour tous, vous n'avez pas besoin de vous authentifier pour les opérations de lecture.
Comme CVS, Subversion met en cache sur le disque vos éléments
d'authentification (dans votre répertoire
~/.subversion/auth/
) à moins que vous ne lui
spécifiez le contraire avec l'option
--no-auth-cache
.
Ce comportement possède une exception : l'accès à un
serveur svnserve via un tunnel SSH, en
utilisant les URL de type svn+ssh://
. Dans ce
cas, le programme ssh vous demande toujours de
vous authentifier avant d'ouvrir le tunnel.
La meilleure façon d'habituer les utilisateurs CVS à Subversion est certainement de les laisser continuer à travailler sur leurs projets en utilisant le nouveau système. Et, bien que cela puisse être fait par un import « à plat » dans le dépôt Subversion d'un dépôt CVS exporté, la solution la plus aboutie implique de transférer d'un système à l'autre non seulement la dernière version des données mais aussi tout l'historique qui va avec. C'est un problème particulièrement ardu ; cela implique, parmi d'autres complications, de déterminer les modifications qui vont ensemble, en l'absence d'atomicité et de mécanisme de conversion entre les politiques totalement contradictoires de gestion des branches des deux systèmes. Néanmoins, il existe quelques outils qui se prétendent capables de convertir, au moins en partie, des dépôts CVS en dépôts Subversion.
L'outil le plus populaire (et le plus abouti) est cvs2svn (http://cvs2svn.tigris.org/ site en anglais), un programme en Python créé à l'origine par des membres de la communauté de développement Subversion elle-même. Cet outil n'est censé être lancé qu'une seule fois : il analyse votre dépôt CVS en plusieurs passes et essaie d'en déduire des propagations, des branches et des étiquettes autant qu'il le peut. Au final, le résultat est soit un dépôt Subversion soit un fichier dump Subversion représentant l'historique du code. Consultez le site web pour le détail des instructions et les précautions d'usage.
WebDAV est une extension de HTTP qui devient de plus en plus courante comme standard pour le partage de fichiers. De nos jours, les systèmes d'exploitation sont de plus en plus « connectés » et beaucoup supportent maintenant nativement le montage de « partages » mis à disposition par des serveurs WebDAV.
Si vous utilisez Apache comme serveur réseau pour Subversion, on peut dire que d'une certaine manière vous faites aussi tourner un serveur WebDAV. Cette annexe donne quelques notions générales sur ce protocole, la manière dont Subversion l'utilise et l'état actuel de l'interopérabilité entre Subversion et d'autres logiciels compatibles WebDAV.
DAV signifie Distributed Authoring and Versioning, que l'on pourrait traduire par « Écriture distribuée et gestion de versions ». La RFC 2518 définit un ensemble de concepts et d'extensions sur la base du protocole HTTP 1.1 afin de faire du Web un support de lecture/écriture plus universel. L'idée est qu'un serveur Web compatible WebDAV peut être considéré comme un serveur de fichiers générique ; les clients peuvent « monter » des répertoires partagés, au-dessus d'une couche HTTP, et ces répertoires se comportent pratiquement comme les autres systèmes de fichiers en réseau (tels que NFS ou SMB).
Là où le bât blesse, c'est que, malgré l'acronyme, les spécifications de la RFC ne décrivent en fait aucun façon d'assurer la gestion de versions. Les clients et serveurs WebDAV de base considèrent que chaque fichier ou répertoire n'existe qu'en une seule version, qui peut être ré-écrite autant de fois que l'on veut.
Comme la RFC 2518 a ignoré les concepts de gestion de versions, un autre groupe de travail a hérité de la responsabilité d'écrire la RFC 3253 quelques années plus tard. La nouvelle RFC ajoute le concept de gestion de versions à WebDAV, en rendant sa signification au « V » de « DAV », d'où le terme « DeltaV ». Les clients et serveurs WebDAV/DeltaV sont souvent appelés « DeltaV » tout court, puisque DeltaV implique obligatoirement la prise en compte de WebDAV.
Le standard WebDAV initial a connu un grand succès. Tous les systèmes d'exploitation modernes ont un client WebDAV intégré (nous les abordons en détail plus tard) et de nombreux logiciels sont également capables de communiquer via ce protocole :Microsoft Office, Dreamweaver, Photoshop pour n'en citer que quelques uns. Côté serveur, le serveur HTTP Apache dispose de services WebDAV depuis 1998 et est considéré de facto comme la référence en matière de logiciel libre. Il existe plusieurs autres serveurs WebDAV commerciaux, dont le propre serveur de Microsoft, IIS.
Malheureusement, DeltaV n'a pas connu un grand succès. Il est très difficile de trouver des clients ou des serveurs DeltaV. Les rares qui existent sont des serveurs commerciaux plus ou moins inconnus ; l'interopérabilité est donc très difficile à tester. Il n'est pas évident de trouver pourquoi DeltaV n'a pas percé. Certains mettent en cause des spécifications trop complexes. D'autres arguent du fait que, contrairement à WebDAV, qui est une technologie de masse (même les utilisateurs les moins férus d'informatique aiment partager des fichiers en réseau), ses fonctionnalités de gestion de versions intéressent peu ou ne sont pas nécessaires à la majorité des gens. Enfin, certains sont persuadés que DeltaV n'intéresse pas grand monde parce qu'il n'existe aucun serveur libre qui l'implémente correctement.
Quand Subversion était encore en phase de conception, l'utilisation d'Apache comme serveur réseau paraissait une très bonne idée. Il possédait déjà un module pour fournir des services WebDAV et DeltaV était une spécification relativement jeune. L'idée était que le module serveur de Subversion (mod_dav_svn) évoluerait pour devenir l'implémentation libre de référence de DeltaV. Malheureusement, DeltaV possède un modèle de gestion de versions très particulier, qui n'est pas vraiment compatible avec le modèle de Subversion. Certains concepts pouvaient être adaptés, mais d'autres non.
Quelles conséquences en tirer ?
Premièrement, le client Subversion n'est pas un client DeltaV
complet. Il a besoin d'informations de la part du serveur que
DeltaV est incapable de lui fournir, ce qui implique qu'il dépend
en grande partie de requêtes
HTTP REPORT
spécifiques à Subversion que seul
mod_dav_svn sait interpréter.
Deuxièmement, mod_dav_svn n'implémente pas toutes les fonctionnalités d'un serveur DeltaV. De nombreux éléments des spécifications du protocole DeltaV ne sont pas pertinents dans le cas de Subversion et n'ont donc pas été implémentés.
Savoir si cela valait la peine de combler ces lacunes a fait l'objet d'un long débat au sein de la communauté des développeurs Subversion. La communauté a finalement officiellement décidé d'abandonner le support complet de DeltaV. Depuis Subversion 1.7, le client et le serveur implémentent plusieurs simplifications « hors clous » du standard DeltaV[85] et il est probable que d'autres adaptations de ce genre suivent. Ces versions de Subversion continueront à offrir une compatibilité avec les anciennes versions, mais aucun travail ne sera fait pour améliorer la couverture des spécifications (Subversion s'écarte délibérément du DeltaV strict comme protocole HTTP de base).
Bien que le client Subversion ne soit pas un client DeltaV complet et que le serveur Subversion n'implémente pas toutes les fonctionnalités d'un serveur DeltaV, il faut se féliciter de l'existence d'une petite lueur d'intéropérabilité WebDAV : la gestion de versions automatique.
La gestion de versions automatique est une fonctionnalité
optionnelle définie dans le standard DeltaV. Un serveur DeltaV
classique n'autorise pas un client WebDAV non compatible à
effectuer des opérations PUT
sur un fichier
suivi en versions. Pour modifier un tel fichier, le serveur exige
un enchaînement précis de requêtes de gestion de versions :
quelque chose comme
MKACTIVITY
, CHECKOUT
,
PUT
, CHECKIN
(c'est-à-dire : créer une activité, extraire le fichier
suivi en versions, renvoyer le fichier modifié et assortir cette
modification d'un commentaire). Mais si le serveur DeltaV supporte
la fonctionnalité de gestion de versions automatique, les requêtes
en écriture des clients WebDAV ordinaires sont acceptées. Le
serveur agit comme si le client avait envoyé
l'enchaînement de requêtes approprié, en faisant une propagation
« sous le manteau ». En d'autres termes, la gestion de
versions automatique permet à un serveur DeltaV de communiquer
avec des clients WebDAV ordinaires qui ne disposent pas de
fonctionnalités de gestion de versions.
Comme beaucoup de systèmes d'exploitation ont des clients WebDAV intégrés, cette fonctionnalité est particulièrement intéressante pour les administrateurs qui travaillent avec des utilisateurs non techniciens. Imaginez un bureau avec des utilisateurs « ordinaires » sous Microsoft Windows ou Mac OS. Chaque utilisateur « monte » le dépôt Subversion qui apparaît comme un lecteur réseau classique. Ils utilisent le partage réseau comme ils l'ont toujours fait : ils ouvrent les fichiers, les modifient et les sauvegardent. Pendant ce temps, le serveur assure automatiquement la gestion de versions. L'administrateur (ou tout autre utilisateur sachant le faire) peut toujours utiliser un client Subversion pour effectuer des requêtes sur l'historique des fichiers ou récupérer une vieille version.
Ce scénario n'est pas de la science-fiction : c'est du
concret qui fonctionne. Pour activer la gestion de versions automatique
dans mod_dav_svn, utilisez la directive
SVNAutoversioning
dans le bloc
Location
du fichier
httpd.conf
, comme dans l'exemple
suivant :
<Location /depot> DAV svn SVNPath /var/svn/depot SVNAutoversioning on </Location>
Quand la gestion de versions automatique de Subversion est active, les requêtes en écriture des clients WebDAV sont automatiquement transformées en propagations. Un commentaire de propagation générique est créé et associé automatiquement à chaque révision.
Cependant, avant d'activer cette fonctionnalité, comprenez
bien dans quoi vous vous engagez. Les clients WebDAV ont tendance
à effectuer beaucoup de requêtes en écriture,
ce qui engendre un nombre astronomique de propagations
automatiques. Par exemple, lors d'une sauvegarde d'un fichier,
beaucoup de clients effectuent un PUT
pour un
fichier de 0 octets (pour signifier qu'ils réservent le nom)
suivi par un autre PUT
avec les données
effectives du fichier. La simple écriture d'un fichier entraîne
ainsi deux propagations distinctes. Tenez également compte du fait
que de nombreuses applications effectuent des sauvegardes
automatiques régulièrement, toutes les cinq minutes par exemple,
qui se traduisent par autant de propagations.
Si vous avez une procédure automatique qui envoie un e-mail
après chaque propagation (post-commit
), il est
conseillé de désactiver cet envoi soit complètement soit au moins
pour certaines parties du dépôt, selon que ces e-mails vous
semblent apporter une plus-value ou pas. De plus, une
procédure automatique post-commit
bien pensée peut
distinguer une propagation générée par la gestion de versions
automatique d'une propagation classique. L'astuce consiste à examiner
la propriété de révision dénommée svn:autoversioned
.
Si elle est présente, la propagation est issue d'un client
WebDAV.
Une autre caractéristique utile et complémentaire de la gestion
de versions automatique de Subversion est fournie par le module
mod_mime d'Apache. Si un client WebDAV ajoute
un nouveau fichier au dépôt, l'utilisateur n'a pas l'occasion de
lui adjoindre la propriété svn:mime-type
. Dans
ce cas, il se peut que, lors de la navigation dans un répertoire
partagé WebDAV, l'icône du fichier soit générique et qu'aucune
application ne soit associée à ce fichier. Une solution peut être
qu'un administrateur système (ou toute autre personne sachant
utiliser Subversion) extraie une copie de travail et définisse
manuellement la propriété svn:mime-type
sur les
fichiers concernés. Mais c'est un peu comme tenter de remplir le
tonneau des Danaïdes, alors qu'il suffit de placer la directive
ModMimeUsePathInfo
dans le bloc
<Location>
de Subversion.
<Location /depot> DAV svn SVNPath /var/svn/depot SVNAutoversioning on ModMimeUsePathInfo on </Location>
Cette directive autorise mod_mime à déduire
automatiquement le type MIME des nouveaux fichiers qui entrent
dans le dépôt de la gestion de versions automatique. Ce module
examine l'extension du nom de fichier et éventuellement le contenu
de celui-ci ; si certains motifs sont repérés, la propriété
svn:mime-type
est automatiquement
renseignée.
Les clients WebDAV peuvent être classés en trois catégories : applications autonomes, greffons pour explorateurs de fichiers et implémentations de systèmes de fichiers. Ces catégories définissent à grosses mailles les types de fonctionnalités WebDAV offertes aux utilisateurs. Le Tableau C.1, « Principaux clients WebDAV » contient notre répartition en catégories et fournit une brève description des principaux logiciels compatibles WebDAV. Vous trouverez plus d'informations sur ces logiciels, ainsi que sur les catégories auxquelles ils appartiennent, dans les sections à suivre.
Tableau C.1. Principaux clients WebDAV
Logiciel | Type | Windows | Mac | Linux | Description |
---|---|---|---|---|---|
Adobe Photoshop | Application WebDAV autonome | X | Logiciel de retouche d'images, capable d'accéder directement à des URL WebDAV, en lecture et en écriture | ||
cadaver | Application WebDAV autonome | X | X | Client WebDAV en ligne de commande, supportant des opérations de transfert de fichiers, d'arborescences et de verrouillage | |
DAV Explorer | Application WebDAV autonome | X | X | X | Interface graphique en Java dont le but est de parcourir des partages WebDAV |
Adobe Dreamweaver | Application WebDAV autonome | X | Logiciel de création Web, capable d'accéder directement à des URL WebDAV, en lecture et en écriture | ||
Microsoft Office | Application WebDAV autonome | X | Suite bureautique dont plusieurs composants sont capables d'accéder directement à des URL WebDAV, en lecture et en écriture | ||
Dossiers Web de Microsoft | Greffon WebDAV pour explorateur de fichiers | X | Explorateur de fichiers avec interface graphique capable d'effectuer des opérations sur les arborescences de partages WebDAV | ||
GNOME Nautilus | Greffon WebDAV pour explorateur de fichiers | X | Explorateur de fichiers avec interface graphique capable d'effectuer des opérations sur les arborescences de partages WebDAV | ||
KDE Konqueror | Greffon WebDAV pour explorateur de fichiers | X | Explorateur de fichiers avec interface graphique capable d'effectuer des opérations sur les arborescences de partages WebDAV | ||
Mac OS X | Implémentation d'un système de fichiers WebDAV | X | Système d'exploitation capable de monter des partages WebDAV nativement | ||
Novell NetDrive | Implémentation d'un système de fichiers WebDAV | X | Logiciel qui permet d'affecter des partages réseaux WebDAV à des lecteurs réseaux Windows | ||
SRT WebDrive | Implémentation d'un système de fichiers WebDAV | X | Logiciel de transfert de fichiers qui, entre autres choses, permet d'affecter des partages réseaux WebDAV à des lecteurs réseaux Windows | ||
davfs2 | Implémentation d'un système de fichiers WebDAV | X | Pilote de système de fichiers Linux qui permet de monter des partages WebDAV |
Une application WebDAV est un programme qui communique avec un serveur WebDAV en utilisant les protocoles WebDAV. Nous allons passer en revue les programmes les plus populaires dans cette catégorie.
Sous Windows, plusieurs applications bien connues intègrent nativement un client WebDAV, par exemple Microsoft Office[86], Photoshop d'Adobe et Dreamweaver. Ils sont capables d'accéder à des URL WebDAV, à la fois en lecture et en écriture, et ont tendance à faire un usage intensif des verrous WebDAV lors de l'édition d'un fichier.
Notez que bien que beaucoup de ces programmes fonctionnent également sous Mac OS X, ils ne semblent pas directement supporter WebDAV sur cette plateforme. En fait, sous Mac OS X, la boîte de dialogue
ne permet d'entrer ni un chemin ni une URL. Il est probable que le support de WebDAV ait été délibérément laissé de côté sur les versions Macintosh de ces programmes, puisque le système de fichiers de bas niveau d'OS X est déjà lui-même hautement compatible avec WebDAV.cadaver (cadavre en français) est un
programme Unix rudimentaire en ligne de commande pour
parcourir et modifier des partages WebDAV. Il utilise la
bibliothèque HTTP neon (ce qui n'est pas très surprenant puisque
neon
et cadaver sont écrits
par le même auteur). cadaver est un logiciel
libre (licence GPL) disponible à l'adresse https://notroj.github.io/cadaver/ (site en anglais).
L'utilisation de cadaver est similaire à l'utilisation d'un programme FTP en ligne de commande et se révèle donc extrêmement utile pour effectuer du débogage sur WebDAV. Il peut être utilisé pour transférer rapidement plusieurs fichiers du serveur vers son ordinateur ou de son ordinateur vers le serveur, pour examiner les propriétés et pour copier, déplacer, verrouiller ou déverrouiller les fichiers :
$ cadaver http://hote/depot dav:/depot/> ls Listing collection `/depot/': succeeded. Coll: > machintruc 0 May 10 16:19 > auteur.el 2864 May 4 16:18 > preuve-en-poeme.txt 1461 May 5 15:09 > cote-d-azur.jpg 66737 May 5 15:09 dav:/depot/> put LISEZMOI Uploading LISEZMOI to `/depot/LISEZMOI': Progress: [=============================>] 100.0% of 357 bytes succeeded. dav:/depot/> get preuve-en-poeme.txt Downloading `/depot/preuve-en-poeme.txt' to preuve-en-poeme.txt: Progress: [=============================>] 100.0% of 1461 bytes succeeded.
DAV Explorer est un autre client WebDAV autonome, écrit en Java. Il est sous une licence libre de type Apache et est disponible à l'adresse https://www.davexplorer.org/ (site en anglais). Il peut faire tout ce que fait cadaver et a l'avantage d'être portable, ainsi que d'avoir une interface graphique plus conviviale. C'est aussi un des premiers clients à supporter le nouveau protocole « WebDAV Access Control Protocol » (RFC 3744).
Bien sûr, le fait que DAV Explorer supporte les
listes de contrôle d'accès (ACL) n'a aucun intérêt pour nous,
puisque mod_dav_svn ne les supporte pas. Le
support limité de certaines commandes DeltaV par
cadaver et DAV Explorer n'est pas
particulièrement utile non plus puisqu'ils n'autorisent pas
les requêtes MKACTIVITY
. Mais cela n'est
pas pertinent de toute manière ; nous considérons que
tous ces clients se connectent à des dépôts avec gestion de
versions automatique.
Certains explorateurs de fichiers avec interface graphique bien connus disposent de greffons pour WebDAV qui permettent à l'utilisateur de parcourir un partage DAV comme si c'était un répertoire sur l'ordinateur local et d'effectuer des opérations de base sur l'arborescence partagée. Par exemple, Windows Explorer est capable de parcourir un serveur WebDAV en tant qu'« emplacement réseau ». Les utilisateurs peuvent glisser-déposer des fichiers depuis et vers le bureau, ou peuvent renommer, copier ou effacer des fichiers comme d'habitude. Mais comme cette fonctionnalité est propre à l'explorateur de fichiers, le partage DAV n'est pas visible par les applications ordinaires. Toutes les interactions DAV doivent passer par l'intermédiaire de l'interface de l'explorateur.
Microsoft faisait partie du groupe de travail sur les spécifications WebDAV et a commencé à livrer un client WebDAV avec Windows 98, sous le nom de « Dossiers Web ». Ce client était également livré avec Windows NT 4.0 et Windows 2000.
Le client originel « Dossiers Web » était une extension de l'explorateur Windows, la principale interface utilisée pour parcourir le système de fichiers. Il fonctionne plutôt bien. Sous Windows 98, l'extension doit être explicitement installée si « Dossiers Web » n'est pas visible dans « Mon Ordinateur ». Sous Windows 2000, ajoutez simplement un nouveau « Favori réseau », entrez l'URL et le partage WebDAV apparaît, prêt à être parcouru.
Avec la sortie de Windows XP, Microsoft a commencé à
livrer une nouvelle version de « Dossiers Web »,
connue sous le nom de mini-redirecteur WebDAV. Cette nouvelle
implémentation est un client permettant au niveau du système
de fichiers de monter les partages WebDAV en tant que lecteurs
réseau. Malheureusement, cette implémentation est
incroyablement boguée. Le client essaie généralement de
convertir les URL HTTP (http://hote/depot
)
en notation UNC (\\hote\depot
) ;
il essaie aussi souvent d'utiliser l'authentification de
domaine Windows pour répondre aux défis d'authentification de
la méthode basic-auth d'HTTP en envoyant les identifiants sous
la forme HOTE\identifiant
. Ces problèmes
d'interopérabilité sont graves et sont décrits un peu partout
sur le Web, à la grande frustration de beaucoup
d'utilisateurs. Même Greg Stein, l'auteur initial du module
Apache WebDAV, affirme sèchement que les
« Dossiers Web » de Windows XP ne peuvent
tout simplement pas fonctionner avec un serveur Apache.
La version initiale des « Dossiers Web » de Windows Vista semble être pratiquement la même que celle de Windows XP et les problèmes sont donc les mêmes. Avec de la chance, Microsoft corrigera ces problèmes dans un Service Pack de Vista.
Cependant, il semble qu'il existe des solutions de contournement, à la fois pour XP et pour Vista, qui permettent aux « Dossiers Web » de fonctionner avec un serveur Apache. Les témoignages des utilisateurs de ces solutions sont majoritairement positifs, c'est pourquoi nous les signalons ici.
Avec Windows XP, vous avez deux options : la
première, chercher sur le site Web de Microsoft le correctif
KB907306, « Mise à jour de logiciels pour les dossiers
Web ». Ceci devrait résoudre vos problèmes. Si ce n'est
pas le cas, il semble que la version originale pré-XP des
« Dossiers Web » soit toujours fournie avec le
système. Vous pouvez y accéder en allant sur
« Favoris Réseau » et en ajoutant un nouveau
« Favori réseau ». Quand le système vous
demande d'entrer une URL, saisissez l'URL du dépôt
en incluant un numéro de port dans cette
URL. Par exemple, vous devez entrer
http://hote:80/depot
au lieu de
http://hote/depot
. Répondez ensuite
avec vos identifiants Subversion à toute demande
d'authentification.
Avec Windows Vista, le même correctif KB907306 devrait
faire l'affaire. Mais il est possible qu'il reste d'autres
problèmes. Certains utilisateurs rapportent que Vista
considère toute connexion http://
comme non
sécurisée et fait donc échouer toute tentative
d'authentification avec Apache à moins que la connexion
n'utilise https://
. Si vous ne pouvez pas
vous connecter à un dépôt Subversion en SSL, vous pouvez
modifier la base de registre du système pour inhiber ce
comportement. Changez uniquement la valeur de la clé
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel
de 1
à 2
. Et
finalement, en guise d'avertissement : assurez-vous de
faire pointer votre favori réseau vers le répertoire racine du
dépôt (/
), plutôt que vers un
sous-répertoire comme /trunk
. Les
« Dossiers Web » de Vista semblent ne
fonctionner qu'avec les répertoires racines des dépôts.
En général, et bien que ces astuces puissent vous être utiles, vous serez peut-être mieux servi avec un client WebDAV tiers tel que WebDrive ou NetDrive.
Nautilus est l'explorateur/navigateur de fichiers officiel du bureau GNOME (https://www.gnome.org) et Konqueror est l'explorateur/navigateur de fichiers officiel du bureau KDE (https://www.kde.org). Ces deux applications disposent d'un client WebDAV intégré dans l'explorateur de fichiers et elles peuvent se connecter sans problème à un dépôt utilisant la gestion de versions automatique.
Dans Nautilus (GNOME), choisissez l'élément de menu
et entrez l'URL dans la boîte de dialogue qui s'affiche. Le dépôt s'affiche alors comme n'importe quel autre système de fichiers.Dans Konqueror (KDE), vous devez utiliser la syntaxe
webdav://
pour entrer une URL dans la barre
d'adresse. Si vous entrez une URL en
http://
, Konqueror se comporte comme un
navigateur classique. Vous risquez alors de voir le contenu du
répertoire dans une page HTML classique produite par
mod_dav_svn. Si vous entrez
webdav://hote/depot
à la place de
http://hote/depot
, Konqueror devient un
client WebDAV et affiche le dépôt comme un système de
fichiers.
L'implémentation en système de fichiers peut être considérée avec raison comme le meilleur type de client WebDAV. Il est alors implanté en tant que module bas-niveau, généralement au sein du noyau du système d'exploitation. Cela signifie qu'un partage DAV est monté comme tout autre système de fichiers en réseau, de la même manière qu'un partage NFS est monté sous Unix ou qu'un lecteur réseau est affecté à un partage SMB sous Windows. Au final, ce type de client fournit l'accès WebDAV en lecture/écriture de manière transparente à tous les programmes. Les applications ne sont même pas conscientes des requêtes WebDAV qu'elles génèrent.
WebDrive et NetDrive sont tous deux d'excellents produits commerciaux qui permettent, sous Windows, d'affecter un lecteur réseau à un partage WebDAV. Vous pouvez ainsi effectuer des opérations sur ces pseudo-lecteurs WebDAV aussi facilement et de la même manière que sur un disque dur local. Vous pouvez vous procurer WebDrive auprès de South River Technologies (https://www.webdrive.com/). NetDrive de Novell est disponible gratuitement en ligne mais exige d'avoir une licence Netware.
Le système d'exploitation OS X d'Apple possède un
client WebDAV intégré sous forme de système de fichiers.
Depuis Finder (l'explorateur de fichiers), choisissez l'élément
de menu mount depuis le terminal Darwin, en
utilisant le type de système de fichiers
webdav
:
$ mount -t webdav http://svn.exemple.com/depot/projet /mon/point/de/montage $
Notez que si votre module mod_dav_svn est plus ancien que la version 1.2, OS X refuse de monter le partage en lecture/écriture ; il apparaît en lecture seule. C'est parce que OS X exige le verrouillage pour les partages en lecture/écriture, et la possibilité de verrouiller des fichiers n'est apparue que dans Subversion 1.2.
Par ailleurs, le client WebDAV d'OS X peut de temps
en temps se montrer très sensible aux redirections HTTP. Si
OS X est incapable de monter le dépôt, vous devrez
peut-être activer la directive BrowserMatch
dans le fichier de configuration
httpd.conf
du serveur Apache :
BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
davfs2 est un module de système de fichiers du noyau Linux. Le projet est hébergé à l'adresse https://savannah.nongnu.org/projects/davfs2. Une fois davfs2 installé, vous pouvez monter un partage réseau WebDAV en utilisant la commande mount habituelle de Linux :
$ mount.davfs http://hote/depot /mnt/dav
Quand, il y a bien longtemps, Subversion débutait dans le stockage des données suivies en versions, il utilisait un magasin de données basé sur le moteur de base de données transactionnelle Berkeley DB (BDB)[87] Au fur et à mesure que le produit a gagné en maturité, ce magasin de données a été rejoint (puis surpassé) par un autre, le dorsal FSFS qui est utilisé par la grande majorité des dépôts Subversion aujourd'hui. Avec Subversion 1.8, la communauté de développement Subversion a annoncé que le magasin de données BDB était officiellement obsolète.
Cette annexe documente quelques particularités d'administration propres aux dépôts BDB. Ces particularités étaient, dans les versions précédentes de ce livre, détaillées tout au long du livre.
Un environnement Berkeley DB peut encapsuler une ou plusieurs bases de données, fichiers de journalisation, de région et de configuration. L'environnement Berkeley DB a un ensemble propre de valeurs configurées par défaut comme le nombre de verrous autorisés à un instant donné, la taille maximum des fichiers de journalisation, etc. La logique du système de fichiers Subversion ajoute des valeurs par défaut pour différentes options de configuration du gestionnaire Berkeley DB. Cependant, il se peut que votre dépôt nécessite une configuration différente en raison de l'architecture de vos données et des méthodes d'accès.
Les concepteurs du gestionnaire de bases de données Berkeley DB
sont conscients que les besoins varient entre les différentes
applications et environnements de bases de données, c'est pourquoi ils
fournissent des mécanismes pour modifier, à l'exécution, une grande
partie des valeurs des options de configuration. BDB vérifie la
présence d'un fichier nommé DB_CONFIG
dans le
répertoire d'environnement (à savoir le sous-répertoire
db
du dépôt) et en extrait les valeurs des
options.
Subversion crée ce fichier lorsqu'il crée le reste du dépôt. Le fichier contient initialement des options par défaut ainsi que des pointeurs vers la documentation en ligne de Berkeley DB afin de vous renseigner sur l'utilisation de ces options.
$ svnadmin create --fstype bdb /var/svn/dépôt $ ls /var/svn/dépôt/db changes __db.003 __db.register log.0000000001 revisions checksum-reps __db.004 format miscellaneous strings copies __db.005 fs-type node-origins transactions __db.001 __db.006 locks nodes uuids __db.002 DB_CONFIG lock-tokens representations $
Bien sûr, vous êtes libre d'ajouter n'importe quelle option prise
en compte par Berkeley DB dans votre fichier
DB_CONFIG
. Soyez juste attentif au fait que, bien
que Subversion n'essaie jamais de lire ou interpréter le contenu de ce
fichier et qu'il n'en utilise pas directement la configuration, les
changements induits dans le comportement de Berkeley DB ne doivent pas
aller à l'encontre du comportement attendu par Subversion. Par
ailleurs, les changements effectués dans DB_CONFIG
ne sont pris en considération qu'après avoir effectué une restauration
de l'environnement de la base de données avec la commande
svnadmin recover.
Le magasin de données transactionnel Berkeley DB offre toutes les garanties d'un gestionnaire de base de données de premier ordre. Mais chaque médaille à son revers et nous devons vous avertir de quelques limitations du gestionnaire de bases de données Berkeley DB.
Les environnements du gestionnaire de bases de données Berkeley DB ne sont pas portables. Vous ne pouvez pas simplement copier un dépôt Subversion qui a été créé sur un système Unix vers un système Windows et espérer qu'il fonctionne. Bien que la majeure partie de la base de données Berkeley DB soit indépendante de l'architecture, d'autres aspects de l'environnement ne le sont pas.
Ensuite, Subversion utilise le gestionnaire de bases de données Berkeley DB de telle façon que cela ne fonctionne pas sur un système Windows 95/98 ; si vous avez besoin d'héberger un dépôt géré par BDB sur une machine Windows, adoptez Windows 2000 ou plus.
Alors que le gestionnaire de bases de données Berkeley DB prétend fonctionner correctement sur un système de fichiers en réseau, pour peu que celui-ci respecte des caractéristiques particulières[88], la plupart des systèmes de fichiers en réseau et des systèmes dédiés n'atteignent pas ces pré-requis. Et en aucun cas il ne vous est possible de partager ce dépôt sur un système de fichiers en réseau entre plusieurs clients (alors que c'est quand même l'intérêt principal d'un dépôt accessible sur un partage réseau).
Avertissement | |
---|---|
Si vous tentez d'utiliser le gestionnaire de bases de données Berkeley DB sur un système de fichiers en réseau non compatible, les résultats sont imprévisibles ; vous vous apercevrez peut-être immédiatement de mystérieuses erreurs, mais il se peut qu'il se passe des mois avant que vous ne découvriez que votre base de données de dépôt est corrompue. Songez sérieusement à utiliser un magasin FSFS pour les dépôts qui doivent être hébergés sur un partage réseau. |
Comme la bibliothèque du gestionnaire de bases de données Berkeley DB est directement incluse dans Subversion, elle est plus sensible aux interruptions qu'une base de données relationnelle classique. La plupart des systèmes SQL, par exemple, disposent d'un processus serveur dédié qui coordonne tous les accès aux tables. Si un programme qui accède aux tables plante pour une raison ou une autre, le processus serveur de la base de données s'en aperçoit et fait le ménage. Et comme le processus serveur est le seul processus accédant réellement aux tables, les applications n'ont pas à se soucier des conflits de droits.
Cependant, ce n'est pas le cas avec le gestionnaire de bases de données Berkeley DB. Subversion (et les programmes utilisant les bibliothèques de Subversion) accèdent aux tables directement, ce qui veut dire que le plantage d'un programme peut laisser la base de données dans un état temporairement incohérent et inaccessible. Quand cela arrive, un administrateur doit demander au gestionnaire de bases de données Berkeley DB de revenir à un point de contrôle, ce qui est assez ennuyeux. D'autres incidents peuvent faire planter la base de données, comme des conflits entre programmes pour la possession ou les droits sur les fichiers de la base de données.
Note | |
---|---|
La version 4.4 du gestionnaire de bases de données Berkeley DB permet à Subversion (version 1.4 ou plus) de restaurer un environnement Berkeley DB automatiquement et de manière transparente en cas de besoin. Quand un processus Subversion se greffe sur l'environnement d'un dépôt Berkeley DB, il utilise un mécanisme d'enregistrement pour détecter d'éventuels problèmes de déconnexion antérieurs, effectue les restaurations nécessaires puis passe à la suite comme si de rien n'était. Cela n'élimine pas complètement les plantages du dépôt, mais les actions humaines nécessaires pour revenir à une situation normale sont considérablement réduites. |
En théorie, la maintenance d'un dépôt BDB ressemble à celle d'un dépôt FSFS. Historiquement, cependant, les dépôts Berkeley DB ont tendance à requérir un peu plus de tendresse[89] pour rester opérationnels. Cette section couvre ces aspects particuliers d'une administration d'une base de données Berkeley.
Comme indiqué dans la section intitulée « Tolérance aux pannes et restauration », un dépôt Berkeley DB peut se retrouver bloqué s'il n'est pas arrêté proprement. Quand cela arrive, un administrateur doit faire revenir la base de données en arrière jusque dans un état cohérent. Ceci ne concerne cependant que les dépôts BDB — si vous utilisez FSFS, vous n'êtes pas concerné. Et pour ceux qui utilisent Subversion 1.4 avec Berkeley DB version 4.4 ou plus, vous constaterez que Subversion est devenu beaucoup plus résilient face à ce type de problème. Certes, mais des plantages de dépôts Berkeley DB arrivent encore et un administrateur doit savoir comment réagir dans de telles circonstances.
Pour protéger les données du dépôt, le gestionnaire Berkeley DB utilise un mécanisme de verrouillage. Ce mécanisme s'assure que les éléments de la base de données ne sont pas modifiés en même temps par plusieurs utilisateurs et que chaque processus voit les données dans un état cohérent lors de la lecture de la base de données. Quand un processus a besoin de modifier quelque chose dans la base de données, il vérifie d'abord l'existence d'un verrou sur les données concernées. Si les données ne sont pas verrouillées, le processus les verrouille, effectue les changements qu'il veut puis déverrouille les données. Les autres processus sont obligés d'attendre que le verrou soit libéré avant d'être autorisés à accéder aux données de cette zone (ceci n'a rien à voir avec les verrous que vous, utilisateur, pouvez appliquer sur les fichiers suivis en versions dans le dépôt ; nous essayons de lever l'ambiguïté créée par l'emploi de cette terminologie commune dans l'encadré Les différents types de « verrous ».)
Au cours de l'utilisation de votre dépôt Subversion, des erreurs fatales ou des interruptions peuvent empêcher un processus de supprimer des verrous qu'il a placés dans la base de données. Cela conduit à des plantages du magasin de données. Lorsque cela arrive, toutes les tentatives d'accès au dépôt se soldent par un échec (puisque chaque nouvel arrivant attend que le verrou se libère, ce qui n'est pas prêt d'arriver).
Si cela arrive à votre dépôt, ne paniquez pas. Le système de fichiers Berkeley DB tire parti des transactions de la base de données, des points de contrôle et de la journalisation préalable à toute écriture pour garantir que seuls les événements les plus catastrophiques[90] soient à même de détruire définitivement un environnement de base de données. Un administrateur suffisamment paranoïaque conserve des sauvegardes des données du dépôt dans un endroit distinct, mais attendez un peu avant de vous diriger vers l'armoire de rangement des sauvegardes.
Appliquez plutôt la recette suivante pour tenter de « faire repartir » votre dépôt :
assurez-vous qu'aucun processus n'accède au dépôt (ou ne tente de le faire). Pour les dépôts en réseau, cela implique d'arrêter le serveur HTTP Apache ou le démon svnserve ;
prenez l'identité de l'utilisateur qui possède et gère le dépôt. C'est important, puisque rétablir un dépôt avec un autre utilisateur peut modifier les droits d'accès des fichiers du dépôt de telle manière que votre dépôt soit toujours inaccessible même après la remise en service ;
Lancez la commande svnadmin recover :
$ svnadmin recover /var/svn/depot Verrou du dépôt acquis. Patientez ; le rétablissement du dépôt peut être long... Fin du rétablissement. La dernière révision du dépôt est 19 $
Cette commande peut durer plusieurs minutes ;
redémarrez le processus serveur.
Cette procédure fonctionne dans presque tous les cas de
plantage. Faites attention à ce qu'elle soit lancée par
l'utilisateur qui possède et gère la base de données, pas forcément
root
. La procédure de rétablissement peut
impliquer de récréer en partant de zéro certains fichiers de
la base de données (de la mémoire partagée, par exemple). Un
rétablissement par root
créerait ces fichiers
avec root
comme propriétaire, ce qui veut
dire que même après que vous ayez rétabli l'accès à votre dépôt,
les utilisateurs de base n'y auront pas accès.
Avant la publication de Berkeley DB 4.2, les plus gros consommateurs d'espace disque pour les dépôts Subversion basés sur BDB étaient les fichiers de journalisation dans lesquels le gestionnaire Berkeley DB effectue les pré-écritures avant de modifier la base de données elle-même. Ces fichiers recensent toutes les actions menées pour modifier la base de données, étape par étape ; alors que les fichiers de la base de données, à un instant donné, ne reflètent qu'un état particulier, les fichiers de journalisation contiennent l'ensemble de tous les changements opérés entre chaque état successif. Ainsi, ils peuvent grossir assez rapidement.
Heureusement, à partir de la version 4.2 de Berkeley DB,
l'environnement de la base de données est capable de supprimer ses
propres fichiers non utilisés automatiquement. Tout dépôt créé en
utilisant svnadmin compilé avec la version 4.2 de
Berkeley DB (ou suivantes) est configuré pour supprimer
automatiquement les fichiers de journalisation. Si vous ne voulez pas
activer cette fonctionnalité, passez simplement l'option
--bdb-log-keep
à la commande svnadmin
create. Si vous oubliez de le faire ou si vous changez
d'avis plus tard, éditez simplement le fichier
DB_CONFIG
qui se trouve dans le répertoire
db
de votre dépôt, commentez la ligne qui
contient la directive set_flags DB_LOG_AUTOREMOVE
puis lancez svnadmin recover sur votre dépôt pour
que le changement de configuration prenne effet.
Sans suppression automatique des fichiers de journalisation, les journaux vont s'accumuler au fur et à mesure de l'utilisation de votre dépôt. Cela peut être considéré comme une fonctionnalité du gestionnaire de bases de données (vous êtes en mesure de recréer entièrement votre base de données en utilisant uniquement vos fichiers de journalisation, c'est pourquoi ceux-ci sont utiles pour le rétablissement de la base après une catastrophe). Mais en général, vous voudrez archiver les fichiers de journalisation qui ne sont plus utilisés par la base de données et ensuite les enlever du disque pour conserver de l'espace libre. Utilisez la commande svnadmin list-unused-dblogs pour avoir la liste des fichiers de journalisation inutilisés :
$ svnadmin list-unused-dblogs /var/svn/dépôt /var/svn/dépôt/log.0000000031 /var/svn/dépôt/log.0000000032 /var/svn/dépôt/log.0000000033 … $ rm `svnadmin list-unused-dblogs /var/svn/dépôt` ## espace disque récupéré !
Avertissement | |
---|---|
Les dépôts BDB qui utilisent les fichiers de journalisation pour les sauvegardes ou les rétablissements après incident ne doivent pas activer la suppression automatique des fichiers de journalisation. La reconstruction des données d'un dépôt à partir des fichiers de journalisation ne peut être effectuée que si tous les fichiers de journalisation sont accessibles. Si quelques fichiers de journalisation sont supprimés du disque avant que le système de sauvegarde n'ait pu les copier ailleurs, l'ensemble incomplet des fichiers de journalisation est totalementinutile. |
Si vous utilisez un dépôt avec une base Berkeley DB, à la fois
les données et la structure de votre système de fichiers suivis en
versions résident dans un ensemble de tables de la base de données
qui sont situées dans le sous-répertoire db/
de
votre dépôt. Ce sous-répertoire est un répertoire d'environnement
classique de base de données Berkeley DB et n'importe quel outil de
base de données Berkeley, généralement fourni avec la distribution
Berkeley, peut y être utilisé.
Pour un usage quotidien, ces outils ne sont pas nécessaires. La plupart des fonctionnalités dont les dépôts Subversion ont besoin ont été dupliquées dans l'outil svnadmin. Par exemple, svnadmin list-unused-dblogs et svnadmin list-dblogs fournissent un sous-ensemble des fonctionnalités offertes par l'utilitaire db_archive de Berkeley DB et svnadmin recover reproduit les utilisations courantes de l'utilitaire db_recover.
Cependant, il reste quelques utilitaires Berkeley DB que vous pourriez trouver utiles. Les programmes db_dump et db_load fonctionnent avec, pour la lecture et l'écriture respectivement, un format de fichier personnalisé qui décrit les clés et les valeurs d'une base de données Berkeley DB. Puisque les bases de données Berkeley DB ne sont pas portables d'une architecture de machine à une autre, ce format est utile pour transférer les bases de données entre deux machines, indépendamment de l'architecture et du système d'exploitation. Comme nous le décrivons plus loin dans ce chapitre, vous pouvez aussi utiliser svnadmin dump et svnadmin load pour faire la même chose, mais db_dump et db_load peuvent accomplir certaines tâches tout aussi bien et beaucoup plus vite. Ils peuvent aussi être utiles si un expert Berkeley DB, pour une raison ou pour une autre, doit manipuler les données directement dans la base de données d'un dépôt BDB (les utilitaires Subversion ne le vous permettent pas). De plus, l'utilitaire db_stat peut fournir des informations utiles sur l'état de votre environnement Berkeley DB, y compris des statistiques détaillées concernant les sous-systèmes de verrouillage et de stockage.
Pour davantage d'informations sur la suite d'outils Berkeley DB, consultez la documentation en ligne sur le site Internet d'Oracle, dans la section Berkeley DB : https://docs.oracle.com/cd/E17275_01/html/api_reference/C/utilities.html. /> (ce site est en anglais).
[87] D'accord, si l'on veut être parfaitement exact, il a commencé par utiliser des fichiers XML. Mais cela n'a jamais eu pour objectif d'être publié.
[88] Berkeley DB requiert que le système de fichiers sous-jacent implémente strictement la sémantique POSIX sur les verrous et, plus important encore, la possibilité de projeter les fichiers directement en mémoire vive.
[89] Nous sommes dans un monde de brutes !
[90] Par exemple, disque dur + gros aimant à côté = désastre.
Copyright (c) 2002-2016 Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato.
Ce travail est placé sous la licence Creative Commons Attribution. Pour voir le contenu de cette licence, rendez-vous sur http://creativecommons.org/licenses/by/2.0/fr/. Vous pouvez aussi envoyez une lettre à Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Un résumé de la licence est donné ci-dessous, suivi du texte intégral.
-------------------------------------------------------------------- Vous êtes autorisé à : * Partager — copier, distribuer et communiquer le matériel par tous moyens et sous tous formats * Adapter — remixer, transformer et créer à partir du matériel pour toute utilisation, y compris commerciale. L'Offrant ne peut retirer les autorisations concédées par la licence tant que vous appliquez les termes de cette licence. Selon les conditions suivantes : Attribution — Vous devez créditer l'Œuvre, intégrer un lien vers la licence et indiquer si des modifications ont été effectuées à l'Œuvre. Vous devez indiquer ces informations par tous les moyens raisonnables, sans toutefois suggérer que l'Offrant vous soutient ou soutient la façon dont vous avez utilisé son Œuvre. Pas de restrictions complémentaires — Vous n'êtes pas autorisé à appliquer des conditions légales ou des mesures techniques qui restreindraient légalement autrui à utiliser l'Œuvre dans les conditions décrites par la licence. Notes: Vous n'êtes pas dans l'obligation de respecter la licence pour les éléments ou matériel appartenant au domaine public ou dans le cas où l'utilisation que vous souhaitez faire est couverte par une exception. Aucune garantie n'est donnée. Il se peut que la licence ne vous donne pas toutes les permissions nécessaires pour votre utilisation. Par exemple, certains droits comme les droits moraux, le droit des données personnelles et le droit à l'image sont susceptibles de limiter votre utilisation. ==================================================================== Contrat L'Œuvre (telle que définie ci-dessous) est mise à disposition selon les termes du présent contrat appelé Contrat Public Creative Commons (dénommé ici « CPCC » ou « Contrat »). L'Œuvre est protégée par le droit de la propriété littéraire et artistique (droit d'auteur, droits voisins, droits des producteurs de bases de données) ou toute autre loi applicable. Toute utilisation de l'Œuvre autrement qu'explicitement autorisée selon ce Contrat ou le droit applicable est interdite. L'exercice sur l'Œuvre de tout droit proposé par le présent contrat vaut acceptation de celui-ci. Selon les termes et les obligations du présent contrat, la partie Offrante propose à la partie Acceptante l'exercice de certains droits présentés ci-après, et l'Acceptant en approuve les termes et conditions d'utilisation. 1. Définitions a. « Œuvre » : œuvre de l'esprit protégeable par le droit de la propriété littéraire et artistique ou toute loi applicable et qui est mise à disposition selon les termes du présent Contrat. b. « Œuvre dite Collective » : une œuvre dans laquelle l'œuvre, dans sa forme intégrale et non modifiée, est assemblée en un ensemble collectif avec d'autres contributions qui constituent en elles-mêmes des œuvres séparées et indépendantes. Constituent notamment des Œuvres dites Collectives les publications périodiques, les anthologies ou les encyclopédies. Aux termes de la présente autorisation, une œuvre qui constitue une Œuvre dite Collective ne sera pas considérée comme une Œuvre dite Dérivée (telle que définie ci-après). c. « Œuvre dite Dérivée » : une œuvre créée soit à partir de l'Œuvre seule, soit à partir de l'Œuvre et d'autres œuvres préexistantes. Constituent notamment des Œuvres dites Dérivées les traductions, les arrangements musicaux, les adaptations théâtrales, littéraires ou cinématographiques, les enregistrements sonores, les reproductions par un art ou un procédé quelconque, les résumés, ou toute autre forme sous laquelle l'Œuvre puisse être remaniée, modifiée, transformée ou adaptée, à l'exception d'une œuvre qui constitue une Œuvre dite Collective. Une Œuvre dite Collective ne sera pas considérée comme une Œuvre dite Dérivée aux termes du présent Contrat. Dans le cas où l'Œuvre serait une composition musicale ou un enregistrement sonore, la synchronisation de l'œuvre avec une image animée sera considérée comme une Œuvre dite Dérivée pour les propos de ce Contrat. d. « Auteur original » : la ou les personnes physiques qui ont créé l'Œuvre. e. « Offrant » : la ou les personne(s) physique(s) ou morale(s) qui proposent la mise à disposition de l'Œuvre selon les termes du présent Contrat. f. « Acceptant » : la personne physique ou morale qui accepte le présent contrat et exerce des droits sans en avoir violé les termes au préalable ou qui a reçu l'autorisation expresse de l'Offrant d'exercer des droits dans le cadre du présent contrat malgré une précédente violation de ce contrat. 2. Exceptions aux droits exclusifs. Aucune disposition de ce contrat n'a pour intention de réduire, limiter ou restreindre les prérogatives issues des exceptions aux droits, de l'épuisement des droits ou d'autres limitations aux droits exclusifs des ayants droit selon le droit de la propriété littéraire et artistique ou les autres lois applicables. 3. Autorisation. Soumis aux termes et conditions définis dans cette autorisation, et ceci pendant toute la durée de protection de l'Œuvre par le droit de la propriété littéraire et artistique ou le droit applicable, l'Offrant accorde à l'Acceptant l'autorisation mondiale d'exercer à titre gratuit et non exclusif les droits suivants : a reproduire l'Œuvre, incorporer l'Œuvre dans une ou plusieurs Œuvres dites Collectives et reproduire l'Œuvre telle qu'incorporée dans lesdites Œuvres dites Collectives; b créer et reproduire des Œuvres dites Dérivées; c distribuer des exemplaires ou enregistrements, présenter, représenter ou communiquer l'Œuvre au public par tout procédé technique, y compris incorporée dans des Œuvres Collectives; d distribuer des exemplaires ou phonogrammes, présenter, représenter ou communiquer au public des Œuvres dites Dérivées par tout procédé technique; e lorsque l'Œuvre est une base de données, extraire et réutiliser des parties substantielles de l'Œuvre. Les droits mentionnés ci-dessus peuvent être exercés sur tous les supports, médias, procédés techniques et formats. Les droits ci-dessus incluent le droit d'effectuer les modifications nécessaires techniquement à l'exercice des droits dans d'autres formats et procédés techniques. L'exercice de tous les droits qui ne sont pas expressément autorisés par l'Offrant ou dont il n'aurait pas la gestion demeure réservé, notamment les mécanismes de gestion collective obligatoire applicables décrits à l'article 4(c). 4. Restrictions. L'autorisation accordée par l'article 3 est expressément assujettie et limitée par le respect des restrictions suivantes : a L'Acceptant peut reproduire, distribuer, représenter ou communiquer au public l'Œuvre y compris par voie numérique uniquement selon les termes de ce Contrat. L'Acceptant doit inclure une copie ou l'adresse Internet (Identifiant Uniforme de Ressource) du présent Contrat à toute reproduction ou enregistrement de l'Œuvre que l'Acceptant distribue, représente ou communique au public y compris par voie numérique. L'Acceptant ne peut pas offrir ou imposer de conditions d'utilisation de l'Œuvre qui altèrent ou restreignent les termes du présent Contrat ou l'exercice des droits qui y sont accordés au bénéficiaire. L'Acceptant ne peut pas céder de droits sur l'Œuvre. L'Acceptant doit conserver intactes toutes les informations qui renvoient à ce Contrat et à l'exonération de responsabilité. L'Acceptant ne peut pas reproduire, distribuer, représenter ou communiquer au public l'Œuvre, y compris par voie numérique, en utilisant une mesure technique de contrôle d'accès ou de contrôle d'utilisation qui serait contradictoire avec les termes de cet Accord contractuel. Les mentions ci-dessus s'appliquent à l'Œuvre telle qu'incorporée dans une Œuvre dite Collective, mais, en dehors de l'Œuvre en elle-même, ne soumettent pas l'Œuvre dite Collective, aux termes du présent Contrat. Si l'Acceptant crée une Œuvre dite Collective, à la demande de tout Offrant, il devra, dans la mesure du possible, retirer de l'Œuvre dite Collective toute référence au dit Offrant, comme demandé. Si l'Acceptant crée une Œuvre dite Collective, à la demande de tout Auteur, il devra, dans la mesure du possible, retirer de l'Œuvre dite Collective toute référence au dit Auteur, comme demandé. Si l'Acceptant crée une Œuvre dite Dérivée, à la demande de tout Offrant, il devra, dans la mesure du possible, retirer de l'Œuvre dite Dérivée toute référence au dit Offrant, comme demandé. Si l'Acceptant crée une Œuvre dite Dérivée, à la demande de tout Auteur, il devra, dans la mesure du possible, retirer de l'Œuvre dite Dérivée toute référence au dit Auteur, comme demandé. b Si l'Acceptant reproduit, distribue, représente ou communique au public, y compris par voie numérique, l'Œuvre ou toute Œuvre dite Dérivée ou toute Œuvre dite Collective, il doit conserver intactes toutes les informations sur le régime des droits et en attribuer la paternité à l'Auteur Original, de manière raisonnable au regard au médium ou au moyen utilisé. Il doit communiquer le nom de l'Auteur Original ou son éventuel pseudonyme s'il est indiqué ; le titre de l'Œuvre Originale s'il est indiqué ; dans la mesure du possible, l'adresse Internet ou Identifiant Uniforme de Ressource (URI), s'il existe, spécifié par l'Offrant comme associé à l'Œuvre, à moins que cette adresse ne renvoie pas aux informations légales (paternité et conditions d'utilisation de l'Œuvre). Dans le cas d'une Œuvre dite Dérivée, il doit indiquer les éléments identifiant l'utilisation l'Œuvre dans l'Œuvre dite Dérivée par exemple « Traduction anglaise de l'Œuvre par l'Auteur Original » ou « Scénario basé sur l'Œuvre par l'Auteur Original ». Ces obligations d'attribution de paternité doivent être exécutées de manière raisonnable. Cependant, dans le cas d'une Œuvre dite Dérivée ou d'une Œuvre dite Collective, ces informations doivent, au minimum, apparaître à la place et de manière aussi visible que celles à laquelle apparaissent les informations de même nature. c Dans le cas où une utilisation de l'Œuvre serait soumise à un régime légal de gestion collective obligatoire, l'Offrant se réserve le droit exclusif de collecter ces redevances par l'intermédiaire de la société de perception et de répartition des droits compétente. Sont notamment concernés la radiodiffusion et la communication dans un lieu public de phonogrammes publiés à des fins de commerce, certains cas de retransmission par câble et satellite, la copie privée d'Œuvres fixées sur phonogrammes ou vidéogrammes, la reproduction par reprographie. 5. Garantie et exonération de responsabilité a En mettant l'Œuvre à la disposition du public selon les termes de ce Contrat, l'Offrant déclare de bonne foi qu'à sa connaissance et dans les limites d'une enquête raisonnable : i L'Offrant a obtenu tous les droits sur l'Œuvre nécessaires pour pouvoir autoriser l'exercice des droits accordés par le présent Contrat, et permettre la jouissance paisible et l'exercice licite de ces droits, ceci sans que l'Acceptant n'ait aucune obligation de verser de rémunération ou tout autre paiement ou droits, dans la limite des mécanismes de gestion collective obligatoire applicables décrits à l'article 4(e); ii L'Œuvre n'est constitutive ni d'une violation des droits de tiers, notamment du droit de la propriété littéraire et artistique, du droit des marques, du droit de l'information, du droit civil ou de tout autre droit, ni de diffamation, de violation de la vie privée ou de tout autre préjudice délictuel à l'égard de toute tierce partie. b A l'exception des situations expressément mentionnées dans le présent Contrat ou dans un autre accord écrit, ou exigées par la loi applicable, l'Œuvre est mise à disposition en l'état sans garantie d'aucune sorte, qu'elle soit expresse ou tacite, y compris à l'égard du contenu ou de l'exactitude de l'Œuvre. 6. Limitation de responsabilité. A l'exception des garanties d'ordre public imposées par la loi applicable et des réparations imposées par le régime de la responsabilité vis-à-vis d'un tiers en raison de la violation des garanties prévues par l'article 5 du présent contrat, l'Offrant ne sera en aucun cas tenu responsable vis-à-vis de l'Acceptant, sur la base d'aucune théorie légale ni en raison d'aucun préjudice direct, indirect, matériel ou moral, résultant de l'exécution du présent Contrat ou de l'utilisation de l'Œuvre, y compris dans l'hypothèse où l'Offrant avait connaissance de la possible existence d'un tel préjudice. 7. Résiliation a Tout manquement aux termes du contrat par l'Acceptant entraîne la résiliation automatique du Contrat et la fin des droits qui en découlent. Cependant, le contrat conserve ses effets envers les personnes physiques ou morales qui ont reçu de la part de l'Acceptant, en exécution du présent contrat, la mise à disposition d'Œuvres dites Dérivées, ou d'Œuvres dites Collectives, ceci tant qu'elles respectent pleinement leurs obligations. Les sections 1, 2, 5, 6 et 7 du contrat continuent à s'appliquer après la résiliation de celui-ci. b Dans les limites indiquées ci-dessus, le présent Contrat s'applique pendant toute la durée de protection de l'Œuvre selon le droit applicable. Néanmoins, l'Offrant se réserve à tout moment le droit d'exploiter l'Œuvre sous des conditions contractuelles différentes, ou d'en cesser la diffusion; cependant, le recours à cette option ne doit pas conduire à retirer les effets du présent Contrat (ou de tout contrat qui a été ou doit être accordé selon les termes de ce Contrat), et ce Contrat continuera à s'appliquer dans tous ses effets jusqu'à ce que sa résiliation intervienne dans les conditions décrites ci-dessus. 8. Divers a A chaque reproduction ou communication au public par voie numérique de l'Œuvre ou d'une Œuvre dite Collective par l'Acceptant, l'Offrant propose au bénéficiaire une offre de mise à disposition de l'Œuvre dans des termes et conditions identiques à ceux accordés à la partie Acceptante dans le présent Contrat. b A chaque reproduction ou communication au public par voie numérique d'une Œuvre dite Dérivée par l'Acceptant, l'Offrant propose au bénéficiaire une offre de mise à disposition du bénéficiaire de l'Œuvre originale dans des termes et conditions identiques à ceux accordés à la partie Acceptante dans le présent Contrat. c La nullité ou l'inapplicabilité d'une quelconque disposition de ce Contrat au regard de la loi applicable n'affecte pas celle des autres dispositions qui resteront pleinement valides et applicables. Sans action additionnelle par les parties à cet accord, lesdites dispositions devront être interprétées dans la mesure minimum nécessaire à leur validité et leur applicabilité. d Aucune limite, renonciation ou modification des termes ou dispositions du présent Contrat ne pourra être acceptée sans le consentement écrit et signé de la partie compétente. e Ce Contrat constitue le seul accord entre les parties à propos de l'Œuvre mise ici à disposition. Il n'existe aucun élément annexe, accord supplémentaire ou mandat portant sur cette Œuvre en dehors des éléments mentionnés ici. L'Offrant ne sera tenu par aucune disposition supplémentaire qui pourrait apparaître dans une quelconque communication en provenance de l'Acceptant. Ce Contrat ne peut être modifié sans l'accord mutuel écrit de l'Offrant et de l'Acceptant. Le droit applicable est le droit français.