Assez parlé, il est temps de passer à la pratique. Dans cette section, nous allons montrer des exemples concrets d'utilisation de Subversion.
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”.
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.
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.
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.
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 :
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.
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.
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.
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”.
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.
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.
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é.
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.
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.