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.

Révisions pivots et révisions opérationnelles

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é.



[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é…