This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.
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.