Openstuff Wiki : HowtoSVN

HomePage :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register

Utilisation de Subversion


Subversion (ou SVN en abrégé) est un logiciel OpenSource. C'est un système de contrôle de versions qui reprend les concepts de CVS. Il apporte de nombreuses nouveautés telles que :

Plus d'info sur Wikipedia

1. Création d'un référentiel


Subversion stocke toutes les données des différentes versions dans un repository ou référentiel central. Pour le créer (aucun répertoire de ce nom doit exister):
$ svnadmin create repositorySVN
$ ls repositorySVN/
conf  dav  db  format  hooks  locks  README.txt


2. Peuplement du référentiel


Les fichiers que je veux gérer avec subversion sont dans le répertoire testSVN. Je vais donc importer ces fichier dans le référentiel :
$ cd testSVN/
$ svn import file:///home/stan/repositorySVN/ -m "import initial"
Ajout         [...]

Révision 1 propagée.


3. Utilisation


3.1 Récupération des données

Pour pouvoir utiliser un référentiel Subversion, la première chose a faire est un "checkout" qui consiste a récupérer la dernière version de l'arborescence. Ceci créera donc un répertoire local.

$ svn checkout file:///home/stan/repositorySVN/
A    [...]
Révision 1 extraite.


On voit un A apparaitre avec le fichier ajouté, ceci pour l'ensemble de l'arborescence. Voici l'explication des différents codes:


A partir de la tout se fait avec la commande magique 'svn' :

$ svn help
usage : svn <sous-commande> [options] [paramètres]
Client texte interactif de Subversion, version 1.3.1.
Entrer "svn help <sous-commande>" pour l'aide sur une sous-commande.

La plupart des sous-commandes prennent en argument des répertoires et/ou
des fichiers, et s'appliquent récursivement sur les répertoires.
Si aucun argument n'est précisé à une telle sous-commande, elle s'applique
par défaut récursivement sur le répertoire courant, qui est inclus.

Sous-commandes disponibles :
   add
   blame (praise, annotate, ann)
   cat
   checkout (co)
   cleanup
   commit (ci)
   copy (cp)
   delete (del, remove, rm)
   diff (di)
   export
   help (?, h)
   import
   info
   list (ls)
   lock
   log
   merge
   mkdir
   move (mv, rename, ren)
   propdel (pdel, pd)
   propedit (pedit, pe)
   propget (pget, pg)
   proplist (plist, pl)
   propset (pset, ps)
   resolved
   revert
   status (stat, st)
   switch (sw)
   unlock
   update (up)

Subversion est un outil pour gérer des versions.
Pour plus d'informations, voir http://subversion.tigris.org/


Pour mettre a jour votre copie locale, une seule commande très simple :
$ svn update
À la révision 1



3.2 Publication des données


Une fois que vous avez fait vos changements sur votre copie locale, il faut mettre à jour le référentiel. Ceci ce fait via un commit
$ svn commit
Envoi          [...]
Transmission des données .
Révision 2 propagée.


En tapant cette commande vous êtes invité à saisir un message de propagation expliquant vos modifications. Une variable d'environement permet de choisir votre éditeur par défaut. Par exemple, pour utiliser vi :
export SVN_EDITOR=/usr/bin/vi


Il est également possible de passer le message de propagation en paramètre.
$ svn commit --message "ajout fichier toto"
Ajout          toto
Transmission des données .
Révision 2 propagée.


3.3 Commande concernant les fichiers de l'arborescence



Voici un exemple d'utilisation:

$ vi toto
$ svn add toto
A         toto
$ svn commit --message "ajout fichier toto"
Ajout          toto
Transmission des données .
Révision 2 propagée.
$ svn del toto
D         toto
$ svn commit --message "suppression fichier toto"
Suppression    toto
Révision 3 propagée.


3.4 Commande sur les modifications



3.5 Retour arrière


Oups ! Vous avez fait une erreur sur le fichier toto et vous souhaitez retrouver une ancienne version... Voyons déjà les différences :
$ svn diff -r5:HEAD toto
Index: toto
===================================================================
--- toto        (révision 5)
+++ toto        (révision 7)
@@ -1 +1,2 @@
-test
+test2
+sdfs


Entre la révision 5 et la révision actuelle (7) la ligne test a été supprimée et deux lignes ont été ajoutées. Pour retrouver le fichier comme il était à la version 5 utilisons la commande merge :
$ svn merge -rHEAD:5 toto 
U    toto
$ svn commit
Envoi          toto
Transmission des données .
Révision 8 propagée.


Donc logiquement entre la version 5 et la révision actuelle (8) plus aucune différence ne doit exister sur le fichier toto :
$ svn diff -r5:HEAD toto
$

Effectivement, c'est bien le résultat attendu.

3.6 Résolution de conflit


Nous allons voir maintenant ce qui se passe en cas de conflit. Pour cela nous allons prendre l'exemple d'un fichier modifié par deux personnes. Deux cas vont se présenter:

Pour pouvoir tester ceci, lancez deux shell, avec une copie locale sur chacun. Pensez a faire un svn update pour bien avoir la dernière version sur les deux arborescences.

3.6.1 Conflit sans chevauchement

Une fois ceci fait nous allons pouvoir créer un conflit: modifier le même fichier sur les deux copies locales en modifiant des données différentes.

La première propagation se passera normalement.
$ svn commit -m "modif 1er copie locale"
Envoi          fichier
Transmission des données .
Révision 11 propagée.


Par contre, la deuxième propagation ne pourra s'effectuer:
$ svn commit -m "modif 2eme copie locale"
Envoi          fichier
svn: Échec de la propagation (commit), détails :
svn: Le chemin 'fichier' est obsolète dans la transaction '11-1'


Regardons de plus près ... le fichier en question est obsolète: il se base sur la révision 10 alors qu'il devrait se baser sur la révision 11. Pour résoudre ce problème, il suffit donc de mettre à jour notre copie locale. Subversion s'occupera de faire la fusion (merge) tout seul.
$ svn status
?      svn-commit.tmp
M      fichier
$ svn up
G    exploitadm.ftmms
Actualisé à la révision 11.
$ svn commit -m ""modif valide 2eme copie locale"
Envoi          fichier
Transmission des données ..
Révision 12 propagée.


3.6.2 Conflit avec chevauchement

Cette fois-ci nous allons faire des modifications sur la même partie du fichier. Sur la première copie locale, je supprime une des lignes dans le fichier toto.
$ vi toto 
$ svn commit -m "modif chevauchement copie locale 1"
Envoi          toto
Transmission des données .
Révision 14 propagée.


Sur la deuxième copie locale, je modifie la ligne supprimée dans la copie locale 1:
$ vi toto
$ svn commit -m "modif chevauchement copie locale 2"
Envoi          toto
svn: Échec de la propagation (commit), détails :
svn: Le chemin 'toto' est obsolète dans la transaction '14-1'


Comme tout à l'heure, il faut mettre à jour notre copie locale:
$ svn up
C    toto
Actualisé à la révision 14.


Ici nous voyons qu'il y a un conflit que ne peut résoudre Subverison. Au mieux du G qui signifie merGe nous avons un C pour Conflict. Il va falloir intervenir à la main.

Pour chaque fichier en conflit, Subversion crée trois copies différentes dans le répertoire de travail :

$ ls toto*
toto  toto.mine  toto.r13  toto.r14


Subversion ne nous laissera pas propager nos modifications sur le fichier toto tant que les trois fichiers temporaires ne seront pas supprimés. Subversion place également dans le fichier en conflit des marqueurs pour délimiter les zones en chevauchement :
<<<<<<< .mine
ma ligne modifiée
=======
>>>>>>> .r14


Le texte entre le premier et le second marqueur correspond aux modifications que nous venons de faire (ici ma ligne modifiée). Entre le deuxième et le troisième, il s'agit de la modification faire sur la première copie locale (ici une ligne vide).

Une fois le fichier résolu (il ne faut plus qu'il y est de marqueurs), il faut lancer une commande particulière pour permettre à Subversion de savoir que le conflit est résolu. Ceci supprimera automatiquement les trois fichiers temporaires vus plus haut.
$ svn resolved toto
Conflit sur 'toto' résolu
$ svn commit -m "modif chevauchement copie locale 2"
Envoi          toto
Transmission des données .
Révision 15 propagée.


4. Mise en place d'un Hook Scripts


Il est possible avec Subversion d'exécuter des scripts automatiquement sur certains événements. On parle alors de "Hook Scripts".

Nous allons allons essayer d'envoyer automatiquement un mail à chaque nouvelle révision. Ce mail contiendra les différentes modifications. Pour ce faire nous allons utiliser la commande svnnotify. Installons le package pour avoir cette commande:
$ sudo apt-get install libsvn-notify-perl


Puis mettons en place le "hook":
$ cd /home/stan/repositorySVN/hooks/
$ cat post-commit
#!/bin/bash

/usr/bin/svnnotify -r $2 -C -d -p $1 -t stan@localhost

$ chmod +x post-commit


Maintenant à chaque nouvelle révision je reçois un mail du type:
To: stan@localhost
Subject: [8] exploitadm.ftmms: youpiii
Status: RO

Revision: 8
Author:   stan
Date:     2006-11-29 16:06:33 +0100 (Wed, 29 Nov 2006)

Log Message:
-----------
modification du fichier toto

Modified Paths:
--------------
toto.txt

Modified: toto.txt
===================================================================
--- toto.txt    2006-11-29 14:53:59 UTC (rev 7)
+++ toto.txt    2006-11-29 15:06:33 UTC (rev 8)
@@ -177,7 +177,6 @@
-dhcp15                 A       192.168.5.94
 dhcp16                 A       192.168.5.95
 dhcp17                 A       192.168.5.96


5. Connexion distante


Il existe deux moyens pour se connecter à distance à un repository :

L'authentification via svnserve peut utiliser des comptes système via une connexion SSH. Pour utiliser SSH avec svnserve il suffit que le client précise le schema svn+ssh dans l'URL:
$ svn checkout svn+ssh://stan@julien/home/stan/repositorySVN


Ici nous avons un compte stan sur la machine julien. Pour info, la config svn se trouve dans le répertoire ".svn/" du référentiel :
$ ls .svn/
empty-file  entries  format  prop-base  props  README.txt  text-base  tmp  wcprops
$ grep "julien" .svn/entries 
url="svn+ssh://stan@julien/home/stan/repositorySVN"


Pour plus d'info, consulter le livre en ligne: Version Control with Subversion
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by WikkaWiki
Page was generated in 0.0799 seconds