Subversion en Action

Assez parlé, il est temps de passer à la pratique. Dans cette section, nous allons montrer des exemples concrets d'utilisation de Subversion.

Copie de travail

Vous avez déjà vu ce qu'est une copie de travail; maintenant, nous allons vous montrer comment le client Subversion crée et utilise ces derniers.

Une copie de travail de Subversion est un répertoire ordinaire dans votre système de fichiers, qui contient un ensemble de fichiers. Vous pouvez éditer ces fichiers autant que vous le désirez, et, si ce sont des codes sources, vous pouvez compiler votre programme de manière habituelle. Votre copie de travail est votre espace privé de travail : Subversion n'incorporera jamais les changements d'autres personnes, ni ne mettra vos modifications à disposition des autres, tant que vous ne le faites pas explicitement.Vous pouvez de plus avoir plusieurs copies de travail du même projet.

Après avoir effectué quelques changements sur les fichiers dans votre copie de travail, et vérifié que tout marche correctement, Subversion vous donne la possibilité et les commandes pour “propager” vos changements pour les autres personnes travaillant avec vous sur le projet (en écrivant dans le dépôt). Si d'autres personnes propagent leurs propres changements, Subversion vous donne la possibilité, avec des commandes, de fusionner ces changements vers votre copie de travail. (en lisant dans le dépôt)

Une copie de travail contient quelques fichiers supplémentaires, créés et maintenus par Subversion, pour l'assister et répondre au mieux aux commandes que vous effectuez. En particulier, tous les répertoires contiennent un sous répertoire nommé .svn, qui est aussi appellé répertoire administratif de la copie de travail. Les fichiers contenus dans chaque répertoire administratif aident Subversion pour reconnaître les fichiers contenant des modifications encore non publiées, et marquent les fichiers qui sont dépassés, en respectant le travail des autres.

Un répertoire typique d'une arborescence de Subversion contient les fichiers (ou les codes sources), pour plusieurs projets; habituellement, chaque projet est contenu dans un sous-répertoire de l'arborescence du dépôt. Avec cette organisation, une copie de travail d'un utilisateur correspond souvent à une sous-arborescence du dépôt.

Par exemple, imaginons que nous avons un dépôt qui contient deux projets logiciels, paint et calc. Chaque projet dispose de sa propre arborescence de fichiers, comme le montre la Figure 2.6, “Le système de fichier du dépôt”.

Figure 2.6. Le système de fichier du dépôt

Le système de fichier du dépôt

Pour avoir une copie de travail, vous devez check out des sous-repertoires du dépôt. (Le terme “check out” ressemble a quelque chose que l'on va verrouiller ou réserver de ressources, mais ce n'est pas le cas, cela permet juste de récupérer une nouvelle copie de travail pour vous.) Par exemple, si vous check out /calc, vous aurez une copie de travail qui va ressembler à ceci:

$ svn checkout http://svn.example.com/repos/calc
A  calc
A  calc/Makefile
A  calc/integer.c
A  calc/button.c

$ ls -A calc
Makefile  integer.c  button.c  .svn/

La lettre A indique que Subversion a ajouté un certain nombre d'éléments à votre copie de travail. Vous avez désormais votre propre copie de travail personnelle du répertoire /calc du dépôt, avec une entrée supplémentaire, le répertoire .svn— qui contient un certain nombre d'informations nécessaires à Subversion, comme mentionné précédemment.

Supposons que vous effectuiez des changements sur button.c. Puisque le répertoire .svn se souvient des dates de modifications et du contenu original, Subversion peut dire que vous avez modifié le fichier. Bien sur, Subversion ne va pas rendre publique vos modifications si vous ne lui demandez pas explicitement de le faire. L'acte de publication de vos modifications est habituellement et plus couramment désigné sous le nom de soumission des (ou appliquer les ) modifications au dépôt.

Pour publier vos changements et les rendre accessibles aux autres utilisateurs, vous devez utiliser la commande commit de Subversion:

$ svn commit button.c
Sending        button.c
Transmitting file data .
Committed revision 57.

Maintenant que vos changements sur button.c ont été appliqués au dépôt; si quelqu'un récupère une copie de travail de /calc, il verra/récupèrera les changements que vous avez soumis dans la dernière version du fichier.

Imaginons que votre collaborateur, Sally, ait récupéré une copie de travail en même temps que vous. Lorsque vous appliquez les changements au fichier button.c, le répertoire de travail de Sally n'est pas modifié; Subversion modifie les copies de travail à la demande de l'utilisateur uniquement.

Pour actualiser sa version du projet, Sally doit demander à Subversion de mettre à jour sa copie de travail, en utilisant la commande update de Subversion. Cela incorporera vos changements dans sa copie de travail, ainsi que tous les changements apportés et appliqués au dépôt depuis la dernière fois qu'elle a effectué une mise à jour.

$ pwd
/home/sally/calc

$ ls -A 
.svn/ Makefile integer.c button.c

$ svn update
U button.c

Les indications fournies par la commande svn update montrent que Subversion a mis à jour le contenu du fichier button.c. Remarquez que Sally n'a pas demandé quels fichiers mettre à jour; Subversion a utilisé pour cela les informations contenues dans son répertoire .svn, et les informations disponibles dans le dépôt, et effectué son choix en conséquence.

Révisions

Effectuer un svn commit permet de publier les modifications de plusieurs fichiers et répertoires en une seule et unique transaction. Dans votre copie de travail, vous pouvez modifier, supprimer, déplacer, renommer et copier des fichiers et des répertoires, et ensuite, appliquer l'ensemble des changements sur le dépôt en une seule opération.

Dans le dépôt, chaque publication est traitée comme une transaction atomique : soit toutes les modifications réussissent et sont prises en compte, soit aucune n'est effectuée. Subversion essaie de garder au maximum cette atomicité, dans le cas d'un crash du programmme, du système, d'un problème réseau, ou n'importe quelle action utilisateur.

Chaque fois que le dépôt accepte un publication de fichier, cela crée un nouvel état dans l'arborescence de fichiers, appellé révision. À chaque révision est assigné un nombre entier unique, plus grand que celui de la révision précédente. La révision initiale, lorsque le projet vient d'être créé, est numérotée 0, et ne contient rien d'autre qu'un unique répertoire vide.

La Figure 2.7, “Le dépôt” illustre une bonne façon de se représenter le dépôt. Imaginez un tableau contenant les numéro de révision, qui s'étire de la gauche vers la droite. Chaque numéro de révision est associé à une arborescence de fichiers, et chaque arborescence de fichiers représente un “instantané” de l'état du dépôt après une publication.

Figure 2.7. Le dépôt

Le dépôt

Il est important de bien comprendre qu'une copie de travail ne correspond pas toujours à une unique révision dans le dépôt; et peut contenir, par exemple, des fichiers issus de n'importe quelle révision. Par exemple, supposons que vous synchronisiez votre copie de travail avec la révision la plus récente, la 4:

calc/Makefile:4
     integer.c:4
     button.c:4

A ce moment précis, la copie de travail correspond exactement à la révision 4 du dépôt. Maintenant, supposons que vous effectuiez des changements sur le fichier button.c, et que vous soumettiez ces changements au dépôt. En supposant qu'aucune autre soumission n'ait eu lieu, votre soumission crée la révision 5 du dépôt, et votre copie de travail va désormais ressembler à cela:

calc/Makefile:4
     integer.c:4
     button.c:5

Supposons qu'à ce moment, Sally publie ses changements sur le fichier integer.c, créant par la même occasion la révision 6. Si vous utilisez la commande svn update pour mettre à jour votre copie de travail, alors vous obtiendrez ceci:

calc/Makefile:6
     integer.c:6
     button.c:6

Les changements que Sally a effectués sur integer.c apparaissent désormais dans votre répertoire de travail, et vos changements seront toujours bien là dans button.c. Dans cet exemple, le texte du fichier Makefile est identique dans les révisions 4, 5, et 6, mais Subversion étiquette votre copie de travail de Makefile avec le numéro de révision 6, pour indiquer que c'est bien le fichier tel qu'il est actuellement. C'est pourquoi, après que vous ayez effectué un mise à jour proprement, au sommet de votre répertoire contenant la copie de travail, cette dernière correspond généralement exactement à la révision contenue dans le dépôt.

Comment les copies de travail scrutent le dépôt

Pour chaque fichier dans le répertoire de travail, Subversion enregistre deux informations essentielles dans son répertoire administratif .svn/

  • La révision de base du fichier sur lequel vous travaillez (Ceci est appellé la révision de travail du fichier), et

  • Un marqueur temporel qui indique la dernière synchronisation de votre copie locale par rapport au dépôt.

Avec ces informations, et avec les informations récupérées du dépôt, Subversion peut déterminer dans lequel des quatres états suivants un fichier de travail se trouve :

Pas de changement, et à jour

Le fichier n'a pas été modifié dans le répertoire de travail et aucune mise à jour n'a modifié ce fichier dans le dépôt depuis la dernière révision. Un svn commit du fichier ne devrait rien faire, et un svn update ne fera rien.

Changement locaux, et à jour

Le fichier a été modifié dans le répertoire de travail, et aucun changement n'a été effectué sur le fichier depuis la révision dont est issu votre changement. Il y a donc des changements locaux qui n'ont pas encore été soumis au dépôt, et un svn commit sur le fichier publiera alors vos changements dans le dépôt, et un svn update ne touchera pas votre fichier.

Pas de changement, et pas à jour

Le fichier n'a pas été modifié dans votre répertoire de travail, mais il a subi des modifications qui ont été soumises au dépôt. Le fichier doit donc éventuellement être mis à jour, pour le faire correspondre à celui de la révision publique actuelle. Un svn commit sur le fichier ne fera rien, et un svn update sur le fichier devrait mettre à jour le fichier dans votre copie de travail.

Changement locaux, et pas à jour

Le fichier a été modifié, et dans votre répertoire de travail, et dans le dépôt. Un svn commit du fichier devrait provoquer une erreur de type “out-of-date (pas à jour)”. Le fichier doit donc être mis à jour avant; un svn update devrait permettre de fusionner les changements du dépôt avec vos changement locaux. Si Subversion ne peux pas fusionner de manière satisfaisante et automatique les changements, il laisse à l'utilisateur le soin de résoudre les conflits.

Tout ceci peut donner l'impression qu'il y a beaucoup de situations à prendre en compte, mais la commande svn status vous montre l'état de chaque élément contenu dans votre répertoire de travail. Pour plus d'informations sur cette commande, voir the section called “svn status.

Copies de Travail Contenant Plusieurs Révisions

Voulant être le plus général, Subversion tente d'être le plus flexible possible. Une preuve de cette flexibilité est son habileté à avoir des copies de travail contenant des fichiers et des répertoires avec des numéros de révision de travail différents. Malheureusement, cette flexibilité tend à rendre confu le fonctionnement pour bon nombre de nouveaux utilisateurs. Si l'exemple précédent vous laisse perplexe, et que de manière générale, vous ne comprenez pas vraiment l'utilité de ces numéros de version mixtes, nous allons voir ici pourquoi ces fonctions existent, et comment en tirer parti.

Les Soumissions et Mises à jour sont séparées

Une règle fondamentale de Subversion est qu'une action de “soumission” n'est en aucun cas liée à une action de “récupération”, ou inversement. Ce n'est pas parce que vous êtes prêt à soumettre des informations et des changements au dépôt que vous êtes prêt à recevoir les changements effectués par d'autres personnes. De même, si vous avez des changements en cours, mais non finalisés, alors un svn update vous permettra de fusionner le dépôt avec votre copie, sans vous obliger à publier vos modifications.

Le premier effet de cette règle signifie qu'une copie de travail doit posséder une trace correcte des révisions mélangées, et doit également être tolérant avec ces mélanges. Cela est rendu un brin difficile par le fait que les répertoires eux-mêmes ont un numéro de révision.

Par exemple, imaginons que votre copie de travail soit entièrement en version 10. Vous éditez alors le fichier foo.html, et vous effectuez un svn commit, qui va créer la révision 15 dans le dépôt. Après que la soumission ait été effectuée, beaucoup de nouveaux utilisateurs supposent que leur copie de travail est entièrement en version 15 elle aussi. Mais ce n'est pas le cas! Il existe un certain nombre de changements, entre la version 10 et la version 15, qui ont été effectués dans le dépôt. Le client ne connait pas ces changements effectués dans le dépôt tant que vous n'avez pas lancé la commande svn update, et la commande svn commit ne récupèrera pas ces changements. Si, d'un autre coté, svn commit mettait à jour automatiquement les nouveautés, alors effectivement, votre copie de travail serait elle aussi en version 15— intégralement, mais alors nous transgresserions la règle fondamentale de Subversion pour les “soumissions” et les “récupérations”, qui doivent rester des actions séparées. La seule chose que peut faire le client Subversion est de marquer le fichier file—foo.html— comme appartenant à la révision 15. Le reste de la copie de travail restant en version 10. La seule possibilité pour passer en version 15 sur la totalité de la copie de travail est d'effectuer un svn update, qui téléchargera alors les différences, et mettra votre copie de travail à jour.

Les révisions mixtes sont normales

Le fait est que, chaque fois que vous lancez la commande svn commit, votre copie de travail contient alors des révisions différentes. Les fichiers que vous avez soumis sont marqués comme ayant un numéro de révision plus important que tous les autres. Après plusieurs soumissions (sans aucune mise à jour entre), votre copie de travail va contenir un ensemble de fichiers avec des numéros de révision très différents. Surtout si vous êtes la seule personne utilisant le dépôt, vous observerez bien ce phénomène. Pour examiner les différents numéros de révision des fichiers de votre répertoire de travail, il suffit d'utiliser la commande svn status --verbose (Voir the section called “svn status pour plus d'informations.)

Bien sur, les nouveaux utilisateurs sont rarement au fait que leur copie de travail contient parfois des révisions mixtes. Cela peut porter à confusion lors de certains cas, parce que beaucoup de commandes du client sont dépendantes de la révision de travail de l'élément sur lequel il agit. Par exemple, la commande svn log est utilisée pour afficher l'historique des changements survenus sur un fichier ou un répertoire (voir the section called “svn log). Lorsque l'utilisateur utilise cette commande sur un objet de la copie de travail, il s'attend à voir l'historique complet de l'objet. Mais si l'objet en question dispose d'un numéro de révision ancien, (sans doute parce que svn update n'a pas été executé depuis longtemps), alors ce sera l'historique de cette ancienne version qui sera affiché.

Les Révisions mixtes sont utiles

Si votre projet est suffisamment complexe, vous découvrirez assez vite que parfois, il est nécessaire de revenir “en arrière” sur certaines portions de votre répertoire de travail; vous apprendrez à le faire dans le Chapitre 3. Peut-être que vous voudrez tester une version précédente d'un sous-module contenu dans un sous-répertoire, ou alors vous voudrez voir comment un bug s'est introduit dans le code dans un fichier spécifique. C'est l'aspect “machine temporelle” du contrôle de version — le fait que vous puissiez reculer et avancer dans le temps sur une partie de votre copie de travail, grâce à l'historique.

Limitations des révisions mixtes

Malgré le fait que vous puissiez utiliser le système de révision mixte au sein de votre copie de travail, il y a certaines limitations à cette flexibilité.

Premièrement, vous ne pouvez soumettre une supression de fichier ou de répertoire qui n'est pas pleinement à jour. Si une nouvelle version d'un élément existe dans le dépôt, votre demande de suppression sera rejetée, en prévention d'une destruction accidentelle d'éléments que vous n'avez pas encore vus.

Second point, vous ne pouvez mettre à jour des métadonnées sur un répertoire si celui-ci n'est pas pleinement à jour. Vous apprendrez à attacher des “propriétés” à des éléments dans le Chapitre 6. La révision d'un répertoire de travail est définie par un ensemble d'entrées et de propriétés, et soumettre un changement de propriété sur un répertoire qui n'est pas à jour peut détruire des propriétés que vous n'avez pas encore vues.