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.

Recherche dans l'historique

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 :

svn diff

affiche les détails, ligne par ligne, d'un changement donné.

svn log

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.

svn cat

récupère le fichier tel qu'il existait à un numéro de révision donné et l'affiche à l'écran.

svn annotate

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.

svn list

liste les fichiers contenus dans un dossier à une révision donnée.

Détail des modifications passées

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.

Modifications locales

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
$

Comparaison entre la copie de travail et le dépôt

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
$

Comparaison entre des révisions du dépôt

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
…
$

Historique des modifications

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.

Navigation dans le dépôt

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.

Affichage du contenu d'un fichier

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
$

Affichage ligne par ligne des auteurs de modifications

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] Astuce

En fonction de votre humeur du moment ou des raisons pour lesquelles vous lancez cette commande, vous vous retrouverez à taper svn blame … ou svn praise … au lieu de la forme canonique de la commande svn annotate. Pas de souci, les développeurs de Subversion l'ont anticipé et ces alias fonctionnent parfaitement.

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.

Contenu des dossiers suivis en versions

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] 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).

Extraction d'anciennes versions au sein d'un dépôt

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] 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
…
$


[8] Vous voyez, on vous avait bien dit que Subversion était une machine à remonter le temps.