Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

article.md 15KB

title: ★ Installer un dépôt Subversion sous Ubuntu slug: installer-un-depot-subversion-sous-ubuntu date: 2006-07-07 16:50:09 type: post vignette: images/logos/livre_subversion.png contextual_title1: ★ iPheeds.org, une version iPhone pour votre blog contextual_url1: 20080723-ipheedsorg-une-version-iphone-pour-votre-blog contextual_title2: ★ Astuces et bonnes pratiques Django contextual_url2: 20080211-astuces-et-bonnes-pratiques-django contextual_title3: ★ Des CSS de qualité contextual_url3: 20070522-des-css-de-qualite

Ce billet était parti pour être une critique du livre Subversion, Pratique du développement collaboratif avec SVN mais je pense qu'il est finalement plus intéressant de prendre un exemple concrêt comme il est suggéré dans le titre du livre, l'apprentissage de Subversion passe surtout par la pratique. Ayant quelques petits scripts à mon actif, c'était le moment où jamais de m'y mettre !

Introduction

Si vous ne savez pas ce qu'est Subversion, ce billet présente peu d'intérêt pour vous mais c'est toujours intéressant de savoir que ça existe au cas où vous pourriez en avoir besoin. Subversion est un réécriture de CVS dont le principe est la gestion des versions concurrentes (la réécriture a permis de nombreuses améliorations). Cela permet l'édition d'un même fichier par plusieurs personnes en même temps et la gestion de la traçabilité des modifications (qui a fait quoi et quand en gros). Un serveur possède donc une version commune et chaque développeur travaille sur sa propre version locale qu'il syncronise avec le serveur le plus souvent possible pour éviter les conflits avec les autres développeurs en précisant à chaque fois la nature de la modification effectuée. C'est bien sûr beaucoup plus puissant mais l'idée de base est là.

Critique du livre

Rapidemment quand même, ce livre est tout ce qu'il y a de plus fonctionnel, il permet de se familiariser avec les commandes usuelles à travers de nombreux exemples. J'ai choisi ce livre car je voulais connaître les bonnes pratiques au niveau de l'organisation du code dans un dépôt. C'est toujours intéressant avant de se lancer dans de gros projets et on trouve difficilement de la documentation là-dessus (alors que toutes les commandes le sont, elles sont même directement en téléchargement sur le site d'Eyrolles ce qui est pratique si vous cherchez une commande sans avoir le livre sous les yeux).

L'ouvrage est court mais traite toutes les questions que je me posais, de la création/gestion d'un projet à l'administration du serveur, en passant par l'utilité des branches de livraison et l'intégration d'un code tiers. Le seul léger manque est l'interfaçage avec Trac dont l'auteur ne fait même pas mention, ce serait d'ailleurs un ajout intéressant pour une prochaine édition. Heureusement il existe un tutoriel en anglais très bien fait sur le site officiel si vous souhaitez aller plus loin (un tutoriel a même été rédigé en français sur Destination Linux).

Qu'est ce qui est « subversionable » ?

A peu près tout, même les binaires, mais encore faut-il que ça présente un intérêt. On stocke en général tout ce qui ne peut être généré dans le cas d'un projet de développement (par exemple vos fichiers compilés si vous possédez les sources c'est clairement inutile... sauf si votre projet est énorme bien sûr), mais certains y placent leurs sauvegardes, leur documentation, voire la totalité de leur /home, tout est possible, à vous de voir si c'est intéressant pour vous !

Personnellement, et dans le cadre de cet exemple, je n'y intègrerais que mes scripts python et plus particulièrement mon parser de fichiers PDB. Il peut être intéressant d'y placer vos fichiers de configuration système si vous avez passé du temps à les personnaliser (par exemple vos .* dans votre home :-)).

Création du dépôt

Mon script actuel se situe dans :

$ ll projects/PDBParser/

total 628 -rw-r--r-- 1 david david 101008 2006-04-20 12:00 1CDLA.pdb
-rw-r--r-- 1 david david 450198 2005-10-12 00:25 1SDK.pdb
-rw-r--r-- 1 david david 17992 2004-12-31 01:25 COPYING
-rw------- 1 david david 9168 2006-04-20 13:14 PDBParser.py
-rw------- 1 david david 3056 2006-04-20 13:20 README
-rw-r--r-- 1 david david 10253 2006-04-20 13:20 README.html

On va donc considérer que c'est ma copie locale de travail. Les fichiers *.pdb sont des données, COPYING contient la licence et README.html est généré à partir de README avec rst2html.

Pour l'exemple, je vais placer mon dépôt ou repository Subversion en local aussi à l'adresse suivante (assurez vous que ce dossier existe et que vous ayez les droits pour le faire) :

$ mkdir /home/david/work/svn/repository
$ svnadmin create /home/david/work/svn/repository/

Et effectuer l'import initial de mon code :

$ svn import -m "Import initial du script" projects/PDBParser/ file:///home/david/work/svn/repository/PDBParser/trunk

Ajout projects/PDBParser/README.html
Ajout projects/PDBParser/1SDK.pdb
Ajout projects/PDBParser/1CDLA.pdb
Ajout projects/PDBParser/COPYING
Ajout projects/PDBParser/PDBParser.py
Ajout projects/PDBParser/README

Révision 1 propagée.

Petite vérification du statut de ma copie locale :

$ svn status projects/PDBParser

? projects/PDBParser/README.html
? projects/PDBParser/1SDK.pdb
? projects/PDBParser/1CDLA.pdb
? projects/PDBParser/COPYING
? projects/PDBParser/PDBParser.py
? projects/PDBParser/README
! projects/PDBParser

Aïe, en fait il faut d'abord que ce dossier soit considéré comme une copie locale donc supprimons son contenu et récupérons ce que nous venons de placer sur le dépôt :

$ rm projects/PDBParser/*
$ svn checkout file:///home/david/work/svn/repository/PDBParser/trunk projects/PDBParser

A projects/PDBParser/README.html
A projects/PDBParser/1SDK.pdb
A projects/PDBParser/1CDLA.pdb
A projects/PDBParser/COPYING
A projects/PDBParser/PDBParser.py
A projects/PDBParser/README
Révision 1 extraite.

Ok, ça a marché, j'ai maintenant bien une copie locale de ce qui se trouve dans mon dépôt. Je peux commencer à travailler.

Ah non, j'ai dit que le README.html était généré via README donc inutile de le stocker dans le dépôt :

$ svn propedit svn:ignore projects/PDBParser/

Préciser *.html dans le fichier qui s'ouvre et le message suivant confirme sa prise en compte :

Nouvelle valeur définie pour la propriété 'svn:ignore' sur 'projects/PDBParser'

On enchaîne avec sa suppression :

$ svn remove -m "Suppression de README.html car il est généré automatiquement" projects/PDBParser/README.html

svn: Opération locale sans propagation (commit), pas de message

$ svn commit -m "Mise à jour de la suppression de README.html" projects/PDBParser/

Envoi projects/PDBParser

Révision 2 propagée.

Mise à jour et release

Maintenant que l'on a une copie locale fonctionnelle, passons à la modification du code. Prennez de bonnes habitudes en commençant par :

$ svn update projects/PDBParser

histoire d'être sûr d'avoir la dernière version du dépôt (dans notre cas c'est inutile mais si vous travaillez à plusieurs c'est primordial !).

Ok, je vais maintenant ajouter à la documentation une ligne indiquant la façon dont celle-ci est générée. Vous pouvez vérifier ce qui a été modifié via :

$ svn diff projects/PDBParser

Le retour dépend de vos modifications, c'est en général assez verbeux, si vous souhaitez juste connaître les fichiers ayant été modifiés :

$ svn status projects/PDBParser

M projects/PDBParser/README.html
M projects/PDBParser/README

Le fichier README.html a aussi été modifié mais il ne devrait pas être mis à jour dans le dépôt puisqu'il est normalement ignoré. Allons-y pour le commit du code ajouté :

$ svn commit -m "Ajout de la méthode de génération de la doc" projects/PDBParser/

Envoi projects/PDBParser/README
Envoi projects/PDBParser/README.html
Transmission des données ..
Révision 3 propagée.

Manifestement la propriété ignore a été ignorée... étrange, bon soit passons à la suite, je suis sûr qu'un gentil gourou se manifestera en commentaires ;-).

Vous pouvez à tout moment vérifier ce qu'il s'est passé sur votre projet grâce à :

$ svn log projects/PDBParser

Ok, j'ai une nouvelle version et j'ai décidé de faire une release de mon script. Il va pour cela falloir créer une branche de livraison et comme j'en suis à la version 3 on va l'appeler branche-livraison-3.1 et la placer dans repository/branches (on commence par créer les répertoires en question) :

$ svn mkdir -m "Création des branches" file:///home/david/work/svn/repository/PDBParser/branches
$ svn mkdir -m "Création de la branche de livraison 3.1" file:///home/david/work/svn/repository/PDBParser/branches/branche-livraison-3.1
$ svn copy -m "Branche de livraison 3.1 créée après correction du README" file:///home/david/work/svn/repository/PDBParser/trunk file:///home/david/work/svn/repository/PDBParser/branches/branche-livraison-3.1

Différence entre les branches et les livraisons ?

C'est assez simple, une branche est créée pour pouvoir être modifiée en cas de bug dans la version de la branche. En revanche, un tag de livraison est placé lorsque l'on veut connaître l'état du code à un instant t donné. Ainsi la branche 3.1 va être dans un premier temps taguée 3.1 puis s'il y a correction d'un bug mineur, pouvoir ensuite être taguée par exemple 3.1.1 et ainsi de suite.

Une fois la branche crée, il suffit de la taguer pour obtenir une livraison. On crée pour cela le répertoire de repository/tags, puis la marque de livraison que l'on appelera livraison-3.1 :

$ svn mkdir -m "Création des tags" file:///home/david/work/svn/repository/PDBParser/tags
$ svn copy -m "Livraison 3.1 créée après correction du README" file:///home/david/work/svn/repository/PDBParser/branches/branche-livraison-3.1 file:///home/david/work/svn/repository/PDBParser/tags/livraison-3.1

Il suffit ensuite de récupérer cette copie où l'on veut (créer le dossier avant) pour créer l'archive :

$ svn checkout file:///home/david/work/svn/repository/PDBParser/tags/livraison-3.1/trunk current/PDBParser-3.1

Et voila, plus qu'à compresser tout ça (sans les répertoires cachés ça fait plus pro).

Bon après je pourrais écrire des pages et des pages sur comment corriger un bug dans une branche particulière, switcher entre vos différentes versions, etc... mais tout a déjà été résumé dans un excellent bouquin :-). Le prochain livre commenté sera très certainement Zope, troisième édition mais c'est un pavé de 800 pages donc ça prend du temps (surtout qu'il est plutôt dense !). D'ici là de nouveaux tutoriaux pour le framework web Django devraient arriver.

Export et sauvegardes

Je viens de me rendre compte qu'il manquait une chose essentielle : l'export du dépôt pour effectuer une sauvegarde ! Avec Subversion, les propagations sont atomiques, les modifications sont soit complètement propagées, soit complètement annulées pour assurer la cohérence du système au même titre qu'une base de données. Mais attention justement, il ne faut pas faire une simple sauvegarde du dossier contenant le dépôt mais un dump du dépôt pour sauvegarder des données cohérentes même en cas de mise à jour par un autre utilisateur au même instant.

Une sauvegarde complète s'effectue donc simplement :

$ svnadmin dump work/svn/repository/ > svn_repos.20060707

* Révision 0 déchargée.
* Révision 1 déchargée.
* Révision 2 déchargée.
* Révision 3 déchargée.
* Révision 4 déchargée.
* Révision 5 déchargée.
* Révision 6 déchargée.
* Révision 7 déchargée.
* Révision 8 déchargée.

Il est préférable pour des sauvegardes quotidiennes si vous avez un dépôt conséquent de faire des sauvegardes incrémentales (option --incremental de svnadmin dump) pour ne pas tout sauver à chaque fois.

En cas de problème, il suffit de créer un nouveau dépôt et de recharger vos données :

$ svnadmin create /home/david/work/svn/repository2/
$ svnadmin load /home/david/work/svn/repository2/repository2 < svn_repos.20060707

Et toutes les transactions sont effectuées dans votre nouveau dépôt. N'oubliez jamais qu'on regrette de ne pas faire de sauvegarde que lorsqu'on perd ses données... un petit script automatique prend une heure à trouver/adapter/mettre en place mais peut sauver des heures et des heures de développement, et ça n'arrive malheureusement pas qu'aux autres ! Au même titre que le célèbre "No test, no commit", je serais tenté d'écrire "No backup, no admin".