Services collaboratifs
- PARTAGE
- Evento
- Guide utilisateur
- Notes de version
- Filesender
- RENAvisio
- Rendez-vous
- Sourcesup
- Universalistes
Cette partie du TP est une présentation de l'utilisation de SVN en interaction avec un dépôt hébergé sur la forge SourceSup. Subversion est encore de nos jours l'un des SCM les plus utilisés au monde. Toujours maintenu et régulièrement amélioré, il est d'une utilisation simple et facilite le développement de logiciel informatique. Le TP explorera les principales commandes de SVN.
Documentation officielle de Subversion : https://subversion.apache.org/
SVN est un gestionnaire de sources. Son principe est d'héberger les sources d'un projet sur un serveur central, et de les rendre accessibles aux personnes souhaitant travailler dessus. Chaque utilisateur possède une copie de travail en local d'une des version du dépôt, souvent la dernière, afin de pouvoir effectuer des développements. Une fois les modifications effectuées, l'utilisateur les transmets au dépôt pour que les autres développeurs puissent les récupérer.
Le but est d'être capable d'utiliser un client “ligne de commande” Subversion et d'interagir sur les sources du projet, comprendre le fonctionnement des branches, de leur fusion, ainsi que la gestion des conflits. Pour cela, nous nous appuierons sur une petite application web PHP très simple, sur laquelle sera effectuée des modifications.
Mettez le numéro du poste dans le champ suivant :
Numéro de votre poste :
Pour expliciter la formation sur Subversion, nous nous appuierons sur le développement d'une petite application PHP. Cette application permettra d'afficher, de créer, modifier, supprimer des objets “person” représentant des personnes.
Le code est fourni dans le TP au fur et à mesure, ainsi que la création de la base.
# yum install emacs apache php mysql-server php-mysql
# touch /etc/yum.repos.d/wandisco-svn.repo # emacs /etc/yum.repos.d/wandisco-svn.repo
[WandiscoSVN] name=Wandisco SVN Repo baseurl=http://opensource.wandisco.com/centos/6/svn-1.8/RPMS/$basearch/ enabled=1 gpgcheck=0
# yum clean all # yum install subversion
Pour ce TP nous allons utiliser un dépôt SVN situé sur la plateforme SourceSup. Ce dépôt est lié à un projet SourceSup qui permet de gérer les droits d'accès à ce dépôt.
Les stagiaires effectuant le TP vont chacun se créer un projet sur la forge, et ainsi auront un dépôt pour leur usage.
Nom complet du projet : form-svn-XXX Etablissement : GIP RENATER Description publique du projet : projet support du TP de la formation SVN Nom Unix du projet : form-svn-XXX Code source : choisir subversion
Nous placerons les copies de travail dans le dossier /opt/ de la machine locale.
# cd /opt/
Afin de pouvoir travailler sur les sources du projet, il va falloir récupérer les sources du dépôt en local. Pour cela, une commande du client SVN permet de se connecter au serveur, de s'authentifier, puis de télécharger les fichiers. Le dépôt venant juste d'être créé et initialisé, il ne contient que la première révision.
# svn checkout --username USERNAME https://subversion.renater.fr/authscm/USERNAME/svn/form-svn-XXX /opt/form-svn-XXX A form-svn/trunk A form-svn/branches A form-svn/tags Checked out revision 1.
... [global] store-plaintext-passwords = no ...
Les sources du projet ont été récupérées en local, nous allons pouvoir travailler dessus, ajouter et modifier des fichiers. Comme indiqué dans le résultat de la commande, un dossier a été créé sur la copie de travail locale, et 3 sous dossiers sont également présents :
Maintenant que notre copie locale est fonctionnelle, nous allons pouvoir effectuer des modifications dessus.
Nous allons commencer par créer l'arborescence et les fichiers nécessaires à notre application PHP.
# cd /opt/form-svn-XXX/trunk # mkdir db apache-conf common
Un nouveau dossier ou fichier ne fait pas parti automatiquement du suivi de version. Il faut l'ajouter explicitement, avec la commande “svn add”. Cette commande permet de marquer un fichier/dossier “pour ajout”. C'est à dire qu'il sera transmis au dépôt central lors de la prochaine propagation.
# svn add db apache-conf common
A db
A apache-conf
A common
Si on ajoute un répertoire au suivi de version, par défaut tous les fichiers situés dedans sont ajouté automatiquement au suivi de version également. Nous allons initialiser une page d'accueil pour notre application ainsi qu'une page permettant de créer des objets. Pour regrouper ces pages, nous créons le dossier “www”.
# mkdir www # touch www/index.php # svn add www A www A www/index.php
On voit que tous les fichiers situés dans le dossier “www” sont marqués également “pour ajout”.
# svn mkdir nom_dossier.
# svn add --depth empty mon_dossier
Nos fichiers sont maintenant marqués comme “à ajouter” lors du prochain commit. La commande “status” permet d'afficher l'état des fichiers de la copie de travail.
# svn status A apache-conf A common A db A www A www/index.php
Le status 'A' indique que le fichier sera transmis au dépôt distant lors de la prochaine exécution de la commande “commit”.
Les fichiers et dossiers créés sur la copie de travail restent pour l'instant en local et le dépôt distant n'en a pas connaissance. Pour les transmettre à celui-ci, l'utilisateur doit exécuter la commande SVN “commit”. Celle-ci communique avec le dépôt, compare la dernière révision avec celle présente en locale. Deux cas se présente alors :
Pour l'instant, nous somme dans le cas 1, mais pour prendre l'habitude des bonnes pratiques SVN, lançons la commande “update” avant de propager nos développements.
# svn update . Updating '.': At revision 1.
Aucune mise à jour récupérer, nous pouvons exécuter notre “commit” :
# svn commit -m "ajout de l'arborescence" Adding apache-conf Adding common Adding db Adding www Adding www/index.php Transmitting file data ... Committed revision 2.
Une nouvelle révision a été créée, la numéro 2. La copie de travail locale ainsi que le dépôt distant sont passés tous les deux à cette nouvelle révision. Il est possible de le vérifier avec la commande SVN “info”
# svn info . Path: . Working Copy Root Path: /trunk/form-svn-XXX URL: https://subversion.renater.fr/form-svn-XXX Repository Root: https://subversion.renater.fr/form-svn-XXX Repository UUID: .... Revision: **1** Node Kind: directory Schedule: normal Last Changed Author: .... Last Changed Rev: **1** Last Changed Date: ....
Cette commande affiche les informations de la copie de travail locale.
# svn update . At revision 2. # svn info . Path: . Working Copy Root Path: /trunk/form-svn-XXX URL: https://subversion.renater.fr/form-svn-XXX Repository Root: https://subversion.renater.fr/form-svn-XXX Repository UUID: .... Revision: **2** Node Kind: directory Schedule: normal Last Changed Author: .... Last Changed Rev: **2** Last Changed Date: ....
# svn info https://subversion.renater.fr/form-svn-XXX Path: form-svn-XXX URL: https://subversion.renater.fr/form-svn-XXX Repository Root: https://subversion.renater.fr/form-svn-XXX Repository UUID: .... Revision: 2 Node Kind: directory Last Changed Author: .... Last Changed Rev: 2 Last Changed Date: ....
Commençons le développement de notre application. Nous allons éditer les fichiers que nous avons créé. Mais avant cela, nous allons simuler que nous ne sommes pas seul à travailler sur ce dépôt, mais deux développeurs. En effet il est fort probable que plusieurs personnes travaillent sur le même projet et donc le même dépôt.
Une première copie de travail existe déjà sur notre machine locale, nous allons en créer une seconde, indépendante de la première.
# cd /opt/ # svn checkout https://subversion.renater.fr/form-svn-XXX /opt/form-svn-XXX_copie2 A form-svn-XXX_copie2/trunk A form-svn-XXX_copie2/trunk/apache-conf A form-svn-XXX_copie2/trunk/www A form-svn-XXX_copie2/trunk/www/index.php A form-svn-XXX_copie2/branches A form-svn-XXX_copie2/tags Checked out revision 2.
# cd /opt/form-svn-XXX_copie2/trunk
# touch common/person.class.php # emacs common/person.class.php
<?php /** * Class Person */ class Person { var $id; var $prenom; var $nomfamille; var $adresse; var $ville; function __construct() { } } ?>
# svn add common/person.class.php A common/person.class.php
# svn ci -m "ajout de la classe person" Adding common/person.class.php Transmitting file data . Committed revision 3.
# cd /opt/form-svn-XXX/trunk
# touch common/person.class.php # emacs common/person.class.php
<?php /** * Class Person */ class Person { var $id; var $firstname; var $lastname; var $address; var $city; function __construct() { } } ?>
# svn add common/person.class.php # svn commit -m "ajout de la classe person" Adding common/person.class.php svn: E155011: Commit failed (details follow): svn: E155011: File '.../form-svn-XXX/trunk/common/person.class.php' is out of date svn: E175005: File 'person.class.php' already exists
# svn update . Updating '.': Conflict discovered in '/Volumes/perso/workspace/form-svn/trunk/common/person.class.php'. Select: (p) postpone, (df) diff-full, (e) edit, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options:
C common/person.class.php Updated to revision 3. Summary of conflicts: Text conflicts: 1
**<<<<<<< .mine** <?php /** * Class Person * */ class Person { var $id; var $firstname; var $lastname; var $address; var $city; function __construct() { } } ?>**=======** <?php /** * Class Person * */ class Person { var $id; var $prenom; var $nomfamille; var $adresse; var $ville; function __construct() { } } ?**>>>>>>>> .r3**
<?php /** * Class Person * */ class Person { var $id; var $firstname; var $lastname; var $address; var $city; function __construct() { } }
# svn resolved common/person.class.php Resolved conflicted state of 'common/person.class.php'
# svn ci -m "ajout de la nouvelle classe person" Sending common/person.class.php Transmitting file data . Committed revision 4.
Le déplacement d'un fichier est un peu particulier. Pour déplacer un fichier qui a déjà été commiter sur le dépôt distant, il ne faut pas utiliser la commande de base du système (mv ancien_fichier nouveau_fichier par exemple). En effet le dépôt a lui connaissance d'un fichier se situant à un chemin particulier, et si le fichier est déplacé en local sans que le client Subversion en soit averti, le dépôt ne va pas s'y retrouver lors du prochain commit.
# svn mv www/index.php www/index.php.old A www/index.php.old D www/index.php
# svn ci -m "propagation des déplacements de fichiers" Deleting www/index.php Adding www/index.php.old Committed revision 5.
Nous venons de voir qu'il ne faut pas déplacer un fichier qui a déjà été commité sans en informer subversion. Il en va de même pour une suppression de fichier. Un fichier déjà versionner ne doit pas être supprimer avec les commandes de base du système, car lors d'un prochain commit, le dépôt subversion se rendra compte qu'il manque un fichier.
# rm www/index.php.old # svn status ! www/index.php.old
Nous pouvons voir que le fichier a un status '!' indiquant que le client subversion ne retrouve pas se fichier. L'exécution d'un commit pourrait créer un conflit. Nous pouvons heureusement récupérer le fichier dans la dernière version hébergée par le dépôt.
# svn revert www/index.php.old Reverted 'www/index.php.old'
Nous avons récupéré notre fichier.
# svn cp www/index.php.old www/index.php A www/index.php
# svn del www/index.php.old
# svn status A + www/index.php D www/index.php.old
# svn ci -m "suppression d'un fichier" Adding www/index.php Deleting www/index.php.old Committed revision 6.
Notre application nécessite encore des développements, notamment l'ajout d'une fonctionnalité de création de personnes. Etant une fonctionnalité à part entière, nous allons la développer sur une branche de développement.
# svn copy https://subversion.renater.fr/form-svn-XXX/trunk https://subversion.renater.fr/form-svn-XXX/branches/create-person -m "Creation de la branche create-person" Committed revision 7.
# cd /opt/form-svn-XXX/branches # svn update . Updating '.': A create-person A create-person/apache-conf A create-person/www A create-person/www/index.php A create-person/db A create-person/common A create-person/common/person.class.php Updated to revision 7.
# touch create-person/www/create.php # emacs create-person/www/create.php
<html> <head></head> <body> <?php require_once '../common/person.class.php'; if (isset($_REQUEST) && $_REQUEST['submit']) { $person = new Person(); $person->address = $_REQUEST['address']; $person->city = $_REQUEST['city']; $person->lastname = $_REQUEST['lastname']; $person->firstname = $_REQUEST['firstname']; $person->create(); echo "Nouvelle personne créée"; } ?> <H3>Nouvelle personne</H3> <form action="create.php" method="post"> <p> Nom de famille :<br/> <input size="40" maxlength="40" type="text" name="lastname" value=""/> </p> <p> Prénom :<br/> <input size="40" maxlength="40" type="text" name="firstname" value=""/> </p> <p> Adresse :<br/> <input size="40" maxlength="40" type="text" name="address" value=""/> </p> <p> Ville :<br/> <input size="40" maxlength="40" type="text" name="city" value=""/> </p> <p> <input type="submit" name="submit" value="Valider" /> </p> </form> <a href="index.php">Accueil</a> </body>
<html> <head></head> <body> <H1>Application gestion de personnes</H1> <ul> <li><a href="create.php">Ajouter une nouvelle personne</a></li> </ul> </body>
# emacs create-person/common/person.class.php
<?php require_once '../db/database.php'; /** * Class Person * */ class Person { var $id; var $firstname; var $lastname; var $address; var $city; function __construct() { } /** * create a new person * */ function create() { $res = query_update_execute("INSERT INTO person (lastname, firstname, address, city) VALUES ('$this->lastname', '$this->firstname', '$this->address', '$this->city')"); } } ?>
# touch create-person/db/database.php # emacs create-person/db/database.php
<?php global $connection; /** * db_connect() - Connect to the database */ function db_connect() { global $connection; if ($connection != null) { return $connection; } try { $connection = mysql_connect('localhost', 'user', 'password'); return $connection; } catch ( Exception $e ) { error_log($e->getMessage()); return null; } } function query_select_execute($query) { $connection = db_connect(); $results = array(); mysql_select_db('db', $connection); $rs = mysql_query($query, $connection); while ($row = mysql_fetch_assoc($rs)) { $results[] = $row; } close_connection(); return $results; } function query_update_execute($query) { $connection = db_connect(); $results = array(); mysql_select_db('db', $connection); $rs = mysql_query($query, $connection); error_log("result :".$rs); error_log("erreur :".mysql_error($connection)); close_connection(); } function close_connection() { global $connection; return mysql_close($connection); } ?>
# service mysqld start # mysql -u root
CREATE SCHEMA db CHARACTER SET 'UTF8';
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON db.* TO 'user'@'localhost'; USE db;
CREATE TABLE person ( id int NOT NULL AUTO_INCREMENT, lastname varchar(255), firstname varchar(255), address varchar(255), city varchar(255), PRIMARY KEY (id) );
exit
# touch /etc/httpd/conf.d/form-svn-XXX.conf # emacs /etc/httpd/conf.d/form-svn-XXX.conf
<VirtualHost *:80> DocumentRoot /opt/form-svn-XXX/trunk/www <Directory "/opt/form-svn-XXX/trunk/www"> Options Indexes FollowSymLinks IncludesNOEXEC AllowOverride All Order allow,deny Allow from all ErrorDocument 404 /404.php </Directory> Alias /create-person /opt/form-svn-XXX/branches/create-person/www <Directory "/opt/form-svn-XXX/branches/create-person/www"> Options Indexes FollowSymLinks IncludesNOEXEC AllowOverride All Order allow,deny Allow from all ErrorDocument 404 /404.php </Directory> Alias /version-1.0 /opt/form-svn-XXX/branches/version-1.0/www <Directory "/opt/form-svn-XXX/branches/version-1.0/www"> Options Indexes FollowSymLinks IncludesNOEXEC AllowOverride All Order allow,deny Allow from all ErrorDocument 404 /404.php </Directory> </VirtualHost>
# service httpd restart
# cd /opt/form-svn-XXX/branches/create-person # svn diff www/index.php Index: www/index.php =================================================================== --- www/index.php (revision 7) +++ www/index.php (working copy) @@ -0,0 +1,8 @@ +<html> +<head></head> +<body> +<H1>Application gestion de personnes</H1> +<ul> +<li><a href="create.php">Ajouter une nouvelle personne</a></li> +</ul> +</body> \ No newline at end of file
# svn add www/create.php db/database.php A www/create.php A db/database.php
# svn diff .
Mais dans le cas où un grand nombre de fichiers sont modifiés, le résultat est peu lisible, il est préférable de restreindre la portée de cette commande.
# svn commit -m "ajout de creation de personnes" Sending create-person/common/person.class.php Adding create-person/db/database.php Adding create-person/www/create.php Sending create-person/www/index.php Transmitting file data .... Committed revision 8.
Notre évolution est fonctionnelle et terminée, nous pouvons donc reverser les modifications vers le dépôt central. Pour cela, nous allons fusionner la branche create-person avec le trunk. Le trunk contiendra par la suite toutes les modifications présentes sur la branche. A la suite de cette commande, une nouvelle révision sera créée, et la branche sera détruite car plus utile.
# cd /opt/form-svn-XXX/trunk # svn update . At revision 8.
# svn mergeinfo ../branches/create-person . youngest common ancestor | last full merge | | tip of branch | | | repository path 6 8 | | --| |------------ branches/create-person / / -------| |------------ trunk | 8
Cette commande nous donne des informations sur l'état des branches et du trunk. On peut voir que la création de la branche create-person à partir du trunk à la révision 6, et que ces deux branches sont maintenant à la dernière révision.
# svn merge --reintegrate https://subversion.renater.fr/form-svn-XXX/branches/create-person --- Merging differences between repository URLs into '.': A www/create.php U www/index.php A db/database.php U common/person.class.php --- Recording mergeinfo for merge between repository URLs into '.': U .
# svn status M . A + www/create.php M www/index.php A + db/database.php M common/person.class.php
# svn ci -m "integration de la branche create-person au trunk" Sending trunk Sending trunk/common/person.class.php Adding trunk/db/database.php Adding trunk/www/create.php Sending trunk/www/index.php Transmitting file data .. Committed revision 9.
Après la modification d'un fichier, si on se rend compte que la modification doit être annulée, il est possible de voir la différence entre le contenu du fichier local et celui du dépôt, mais il est plus simple de récupérer la version présente sur le dépôt.
# cd /opt/form-svn-XXX/trunk # emacs www/index.php
<html> <head></head> <body> <H1>Application gestion de personnes</H1> <ul> <li><a href="create.php">Ajouter une nouvelle personne</a></li> **<li><a href="del.php">Supprimer une personne</a></li>** </ul> </body>
# svn status M www/index.php
# svn ci -m "modification du fichier index.php" Sending www/index.php Transmitting file data . Committed revision 10.
# svn merge -r 10:9 www/index.php --- Reverse-merging r10 into 'www/index.php': U www/index.php --- Recording mergeinfo for reverse merge of r10 into 'www/index.php': G www/index.php --- Eliding mergeinfo from 'www/index.php': U www/index.php
# svn status
Comme nous avons pu le voir au long de ce TP, chaque révision est identifiée par un numéro (identifiant) qui est incrémenté à chaque commit effectué (ou création de branche/tags). Toutefois il n'est pas toujours évident d'utiliser des numéros pour manipuler les révisions. C'est pourquoi il existe des alias permettant d'exécuter les cas courants des commandes svn :
# cd /opt/form-svn-XXX_copie2/trunk
# svn diff -r BASE:HEAD Index: common/person.class.php =================================================================== --- common/person.class.php (working copy) +++ common/person.class.php (revision 10) @@ -1,16 +1,29 @@ ... ... Index: www/create.php =================================================================== --- www/create.php (revision 0) +++ www/create.php (revision 10) @@ -0,0 +1,46 @@ ... ... Index: www/index.php =================================================================== --- www/index.php (working copy) +++ www/index.php (revision 10) @@ -0,0 +1 @@ ... Index: db/database.php =================================================================== --- db/database.php (revision 0) +++ db/database.php (revision 10) @@ -0,0 +1,57 @@ ... ... Index: . =================================================================== --- . (working copy) +++ . (revision 10) Property changes on: . ___________________________________________________________________ Added: svn:mergeinfo Merged /branches/create-person:r7-8
Maintenant que notre application est prête, nous allons créer une branche de version, permettant de garder le code à déployer. Une branche de version a une durée de vie longue, elle durera le temps que la version est maintenue par l'équipe de développement. Ce genre de branche sert à recevoir des correctifs pour la version à livrer.
# svn copy https://subversion.renater.fr/form-svn-XXX/trunk https://subversion.renater.fr/form-svn-XXX/branches/version-1.0 -m "Creation de la branche version-1.0" Committed revision 11.
Maintenant que notre branche a été créée, la version 1.0 de notre application existera indépendamment de la version la plus récente (trunk). Des commits pourront être faits sur cette branche afin de corriger des bogues, reporter des légères fonctionnalités.
# cd /opt/form-svn-XXX/branches # svn update . Updating '.': A version-1.0 A version-1.0/apache-conf A version-1.0/www A version-1.0/www/create.php A version-1.0/www/index.php A version-1.0/db A version-1.0/db/database.php A version-1.0/common A version-1.0/common/person.class.php Updated to revision 11.
Lorsque le code de la branche est prêt à être livré, il faut créer un tag. Un tag se crée de la même manière qu'une branche, c'est une étiquette qui pointe vers une certaine révision. La différence principale entre une branche de version et un tag, est qu'aucun commit ne doit être effectué sur un tag. Le tag est seulement un pointeur, utilisé pour faire et refaire facilement un déploiement.
# svn copy https://subversion.renater.fr/form-svn-XXX/branches/version-1.0 https://subversion.renater.fr/form-svn-XXX/tags/version-1.0 -m "Creation du tag version-1.0" Committed revision 12.
Vous pouvez tester de récupérer cette version du dépôt, en faisant un checkout de son URL.
Les propriétés sont des attributs attachés à un ou plusieurs fichiers du dépôt et qui permettent des comportements particuliers.
Subversion propose une fonctionnalité intéressante, le remplacement de certains mots clés dans un fichier par des informations issue du versionnement de celui-ci. Subversion défini plusieurs mots clés :
Un exemple, mettre à jour la date de dernière modification d'un document requiert aux utilisateurs de rigoureusement changer la date dans le document à chaque édition du fichier. Déléguer cette tâche à Subversion permet de s'assurer que celle-ci ne sera pas oubliée.
# cd /opt/form-svn-XXX/trunk # emacs www/index.php
<?php /* * Auteur de la dernière modification : $Author$ * * Date de dernière modification : $Date$ */ ?> <html> <head></head> <body> <H1>Application gestion de personnes</H1> <ul> <li><a href="create.php">Ajouter une nouvelle personne</a></li> </ul> </body>
# svn propset svn:keywords "Date" www/index.php
# svn ci -m "ajout de la propriété 'date'" www/index.php Sending www/index.php Transmitting file data . Committed revision 13.
# more www/index.php <?php /* * Auteur de la dernière modification : $Author$ * * Date de dernière modification : $Date: 2016-02-24 11:42:00 +0100 (Wed, 24 Feb 2016) $ */ ?> <html> <head></head> <body> <H1>Application gestion de personnes</H1> <ul> <li><a href="create.php">Ajouter une nouvelle personne</a></li> </ul> </body>
Il est important de noter que si on souhaite placer plusieurs mots clés sur un fichier, il faut tous les préciser dans une seule commande svn propset, et ne pas lancer plusieurs commandes à la suite, car chaque commande écrasera la propriété précédente.
# svn propset svn:keywords "Date Author" www/index.php property 'svn:keywords' set on 'www/index.php'
# svn ci -m "ajout de la propriété 'date'" www/index.php Sending www/index.php Committed revision 14.
# more www/index.php
<?php /* * Auteur de la dernière modification : $Author: smedard $ * * Date de dernière modification : $Date: 2016-03-11 14:47:43 +0000 (Fri, 11 Mar 2016) $ */ ?> <html> <head></head> <body> <H1>Application gestion de personnes</H1> <ul> <li><a href="create.php">Ajouter une nouvelle personne</a></li> </ul> </body>
La propriété svn:ignore permet de retirer explicitement certains fichiers du contrôle de version. Par exemple, si votre IDE génère des fichiers de configurer pour son propre fonctionnement (le .classpath de Eclipse), il peut être intéressant de systématiquement mettre de côté ces fichiers en positionnant la propriété correspondante.
# cd /opt/form-svn-XXX/trunk/ # touch .tmp
# svn propset svn:ignore *.tmp . property 'svn:ignore' set on '.'
# svn status .tmp
I
# touch .bak # svn propset svn:ignore "*.bak *.tmp" . property 'svn:ignore' set on '.'
# svn status .bak .tmp
I .tmp
I .bak
# svn propset svn:ignore -F fichier_contenant_les_patrons
Le gestionnaire de source Subversion offre une fonctionnalité intéressante appelée « Hooks ».
Un hook (crochet) permet de lancer un programme personnalisé au moment où le programme principal à la tâche de l’exécuter. Pour SVN les hooks sont applicables sur les évènements de contrôle de version (commit, lock).
Deux types de 'Hooks' sont possibles :
Par défaut, un dépôt n'a pas de hook positionné. La forge propose toutefois quelques hooks à ajouter. Pour cela :
# cd /opt/form-svn-XXX/trunk # emacs common/person.class.php
# svn ci -m '' common/person.php.class Transmitting file data .svn: E165001: Commit failed (details follow): svn: E165001: Commit blocked by pre-commit hook (exit code 1) with output: ---------PRE COMMIT HOOK--------- Every commit must have a log. ---------------------------------
La propagation a été refusée car le message du log est vide. Au vue de l'importance des commentaires associés aux commits, il est intéressant d'activer ce hook.
# svn revert common/person.class.php
Depuis la forge, il est possible d'avoir une vue de son dépôt SVN, d'accéder aux différentes révisions, de voir qui a effectué un commit, etc.
Cette vue affiche l'arborescence de la dernière version du dépôt. Il est possible de naviguer entre les anciennes révisions du dépôt. Pour cela il faut indiquer quelle révision afficher dans le champ “Sticky Revision” et valider avec le bouton “Set”. Il est alors possible de descendre dans les différents dossiers du dépôt dans la révision paramétrée.
ViewVC offre aussi la possibilité d'afficher l'historique d'un fichier avec les informations principales, comme les dernières révisions avec leur auteur, leur date de création, le commentaire. Pour cela, naviguer dans l'arborescence jusqu'au fichier voulu, puis cliquer dessus.
Revision 4 - (view) (download) (annotate) - [select for diffs] Modified Wed Mar 9 21:37:32 2016 UTC (38 minutes, 7 seconds ago) by smedard File length: 169 byte(s) Diff to previous 3 ajout de la nouvelle classe person
Sur cet écran, ViewVC offre la possibilité de faire le différentiel d'un fichier entre deux révisions, pas forcément successives. Sélectionner la version que vous souhaitez comparer avec par défaut la dernière, il est aussi possible de comparer deux anciennes versions.
Tous les dépôts hébergés sur la forge SourceSup sont analysés chaque soir afin de publier sur l'interface web du projet des statistiques concernant le code et les développeurs.
Ces informations peuvent être intéressantes pour les utilisateurs s'occupant de la gestion du projet. Les statistiques étant générées dans la nuit pour chaque dépôt, il sera possible de voir celles du projet form-svn-XXX le lendemain.
Exemple de statistiques avec le projet “Sympa” :
Liste des status le plus souvent vus pour un fichier dans l'environnement de Subversion :