Contrôle de versions

Travailler à plusieurs

Un projet informatique implique presque toujours plusieurs développeurs travaillant simultanément.

Une conception judicieuse permet la plupart du temps que personne ne travaille simultanément sur la même partie du logiciel :

Même dans ce cas, des systèmes de gestion de codes sources partagés sont utiles pour gagner du temps et réduire les erreurs.

Contrôle de version

Un système de contrôle de versions vise à :

Approche centralisée

Chaque développeur ne dispose que d’une copie de travail. Les versions sont centralisées sur un serveur.

Cette architecture client/serveur est éprouvée, bien comprise et facile à administrer mais souffre de quelques inconvénient, en particulier de risques de corruption de données.

Systèmes emblématiques :

Approche distribuée

Chaque développeur dispose en local d’un historique des versions en plus de sa version de travail.

Ceci permet la mise en place de différentes chaînes de traitement qui ne sont pas réalisables avec les systèmes centralisés, tels que les modèles hiérarchiques.

Systèmes emblématiques :

Subversion

Terminologie

Le dépot (repository) abrite tous les projets gérés sur un serveur. Il archive toutes les versions des fichiers stockés.

Au sein d’un dépôt se trouvent un ou plusieurs projets. Les projets contiennent des fichiers organisés en arborescence.

Les copies locales ou copies de travail correspondent aux espaces de travail (workspaces) des développeurs.

Chaque modification faite au dépôt constitue une révision ou version. Le numéro de révision commence à 1 et augmente de 1 à chaque opération.

Ce qu’il faut éviter

  1. Harry et Sally mettent à jour leur copie de travail.
  1. Chacun modifie sa propre copie.
  1. Harry publie sa version en premier.
  1. Sally écrase la version de Harry par accident.

Le modèle verrouiller-modifier-libérer

Une approche répandue est de procéder ainsi :

  1. Harry verrouille un fichier du serveur avant de mettre à jour sa copie et de travailler

  2. Tant que le dépôt reste verrouillé, Sally ne peut pas obtenir le verrou

  3. Pour l’obtenir, Sally doit attendre que Harry libère le verrou en modifiant le fichier sur le serveur

En gérant des verrous fichier par fichier, on peut éviter de nombreux problèmes mais des problèmes résident :

Le modèle copier-modifier-fusionner

C’est le modèle de Subversion (SVN) ou de CVS

  1. Deux utilisateurs font une copie du même fichier
  1. Ils modifient chacun leur copie
  1. Sally publie sa version en premier
  1. Harry est informé par le dépôt que sa version est périmée/obsolète, et ne peut publier sa version
  1. Harry compare la version la plus récente à la sienne
  1. Une nouvelle version A*, fruit de la fusion, est créée
  1. Le fichier ainsi obtenu est publié
  1. Chaque utilisateur dispose désormais des modifications apportées par l’autre

Tout est dans le fusionner

L’efficacité du modèle copier-modifier-fusionner dépend de celle des algorithmes de fusion. En pratique :

Accès distant aux dépôts

Protocole Méthode d’accès
file:/// Accès direct au dépôt (sur un disque local).
http:// Accès en lecture seule, à moins d’avoir correctement configuré le protocole WebDAV
https:// Identique à http://, mais avec chiffrement SSL.
svn:// Accès via un protocole personnalisé à un serveur svnserve.
svn+ssh:// Identique à svn://, mais à travers un tunnel SSH.

Dépôts utilisables gratuitement

GUI les plus répandues

Principales commandes

Utilisation régulière :

Administration :

Mise en place de serveurs :

Principales sous-commandes de svn

On parle de sous-commandes car ce sont des options de la commande principale svn. Par exemple, pour faire une mise à jour de sa copie locale, on exécute dans un terminal la ligne de commande suivante :

$ svn update
Sous-commande Signification
add Déclare l’ajout d’une nouvelle ressource pour le prochain commit.
blame Permet de savoir quel contributeur a soumis les lignes d’un fichier.
checkout Récupère en local une version ainsi que ses méta-données depuis le dépôt.
cleanup Nettoie la copie locale pour la remettre dans un état stable.
commit Enregistre les modifications locales dans le dépôt créant ainsi une nouvelle version.
copy Copie des ressources à un autre emplacement (localement ou dans le dépôt).
delete Déclare la suppression d’une ressource existante pour le prochain commit (ou supprime directement une ressource du dépôt).
diff Calcule la différence entre deux versions (permet de créer un patch à appliquer sur une copie locale).
export Récupère une version sans métadonnées depuis le dépôt ou la copie locale.
import Envoie une arborescence locale vers le dépôt.
info Donne les informations sur l’origine de la copie locale.
lock Verrouille un fichier.
log Donne les messages de commit d’une ressource.
merge Calcule la différence entre deux versions et applique cette différence à la copie locale.
move Déclare le déplacement d’une ressource.
propdel Enlève la propriété du fichier.
propedit Édite la valeur d’une propriété.
propget Retourne la valeur d’une propriété.
proplist Donne une liste des propriétés.
propset Ajoute une propriété.
resolved Permet de déclarer qu’un conflit de modifications est résolu.
revert Revient à une version donnée d’une ressource. Les modifications locales sont écrasées.
status Indique les changements qui ont été effectués.
switch Bascule sur une version/branche différente du dépôt.
update Met à jour la copie locale existante depuis la dernière version disponible sur le dépôt.
unlock Retire un verrou.

Mise en place d’un dépôt par l’administrateur

  1. Création d’un depôt dans un dossier repo
$ svnadmin create /path-to/repo
  1. Importation initiale des fichiers du dossier hello dans le dépôt (à ne faire qu’une seule fois)
$ svn import hello file:///path-to/repo -m "import initial"

(l’option -m est obligatoire pour spécifier un message associé à la version)

Manipulation d’une copie de travail sur le même système de fichiers

  1. Création d’une copie de travail dans le dossier local workspace (à ne faire qu’une seule fois par copie)
$ svn checkout file:///path-to/repo /path-to/copie-locale

Accès distant à un dépôt

Dans les exemples ci-dessus, l’accès au dépôt se faisait sur le système de fichiers file:///.

Pour un accès distant (à partir d’une autre machine), on peut employer les protocole svn://.

Pour ce faire, il convient de démarrer un serveur svn sur la machine abritant le dépôt. On utilise à cet effet la commande svnserve.

$ svnserve -d -r /path-to/repo

Dès lors, on peut accéder aux dépôts en remplaçant les file:///path-to/repo par des svn://ADRESSE-IP ou svn://HOST-NAME.

On peut créer plusieurs dépôts sur un même serveur, et déclarer pour chacun des utilisateurs (avec mots de passe) différents.

Principales opérations sur une copie locale (commit et update)

  1. Propagation des modifications vers le dépôt
$ svn commit /path-to/copie-locale -m "quelques modifications"
  1. Mise à jour de la copie locale avec la dernière version du dépôt
$ svn update /path-to/copie-locale
  1. Mise à jour de la copie locale d’un fichier à une révision antérieure du dépôt
$ svn update -r 36 fichier

si c’est la version 36 qui est voulue

Ajout et suppression de fichiers

Ajouter, supprimer, déplacer ou renommer des fichiers sur le système de fichiers (avec des touch, des rm ou des mv par exemple) ne suffit pas.

Un fichier local n’est pris en compte par le contrôle de version que si on le spécifie explicitement par :

$ svn add nouveau-fichier

De même, une suppression simple d’un fichier ne sera pas propagée. Pour supprimer un fichier d’une copie locale, il faut le faire par subversion :

$ svn delete fichier-a-supprimer

Affichage du statut des fichiers

Le statut d’une copie de travail peut être ~ svn status /path-to/copie-locale –verbose ~

Codes associés aux fichiers locaux :

Code Signification
A Le fichier sera ajouté au dépôt
D Le fichier sera supprimé du dépôt
M Le fichier a été modifié localement depuis le dernier update
C Le fichier est source de conflits
X Le fichier est eXterne à cette copie de travail
? Le fichier n’est pas géré par subversion
! Le fichier est manquant, sans doute supprimé par un autre outil que subversion

Résolution des conflits

Les conflits peuvent intervenir au moment d’un commit, lorsque des modifications ont été faites à la fois dans la copie de travail et dans le dépôt :

  1. Pendant que nous travaillions, quelqu’un a modifié sur le dépôt un fichier au même endroit que nous.
  2. On ne peut plus faire de commit car nous pourrions écraser la modification de la personne ayant propagé la révision du fichier avant nous.

  3. La solution est de faire un update pour récupérer une copie locale du fichier conflictuel. SVN prend note de cet update.
  4. Pour une résolution manuelle, on doit se mettre d’accord avec l’autre développeur et décider de la manière de résoudre le conflit, et comment modifier le fichier.
  5. On informe SVN de ce que le conflit a été résolu par un svn resolved fichier-conflictuel
  6. On peut faire un commit et les modifications seront propagées.

Troncs, branches et tags

Bien que l’on puisse faire sans, Subversion recommande que chaque projet contienne trois dossiers :

Tronc

Le tronc est la version centrale du programme, son développement “officiel”.

Une branche est un développement secondaire mis en place

Branches

Les branches sont amenées à :

Tags

Les tags correspondent à des revisions importantes ayant donné lieu à une version publiée du projet (une release, souvent numérotée X.Y.Z).

GIT

Principales ressources

GIT vs SVN

Principales sous-commandes

Sous-commande Signification
init Initialisation d’une base git vide
add Ajout de fichiers au référentiel git
commit Propager des modifications au référentiel
log Affichage du journal de validation
status Vérification de l’état actuel
diff Trouver les différences entre les commit
branch Créer des branches
checkout Déplacer une branche et lister toutes les branches
merge Fusionner deux branches
rm Supprimer quelquechose dans le référentiel

Un commit se fait ainsi :

$ git commit

Module d’UML