Cycle de travail de base

Subversion dispose de nombreuses fonctionnalités, d'options, d'avertissements et de garde-fous. Mais dans une utilisation au jour le jour, vous n'utilisez qu'un petit nombre d'entre eux. Dans cette section, nous passons en revue l'utilisation quotidienne de Subversion.

Le cycle de travail typique ressemble à ceci :

  1. Mettre à jour votre copie de travail.

    • svn update

  2. Faire des changements.

    • svn add

    • svn delete

    • svn copy

    • svn move

  3. Examiner les changements effectués.

    • svn status

    • svn diff

  4. Éventuellement annuler des changements.

    • svn revert

  5. Résoudre les conflits (fusionner les modifications).

    • svn update

    • svn resolve

  6. Propager les changements.

    • svn commit

Mettre à jour votre copie de travail

Si vous travaillez en équipe sur un projet donné, vous voulez mettre à jour votre copie locale pour recevoir toutes les modifications qui ont pu être faites par les autres développeurs du projet depuis votre dernière mise à jour. Utilisez svn update pour synchroniser votre copie de travail avec la dernière version présente dans le dépôt :

$ svn update
U  truc.c
U  machin.c
Actualisé à la révision 2.

Dans cet exemple, il se trouve que quelqu'un a apporté des modifications à truc.c ainsi qu'à machin.c depuis votre dernière mise à jour et Subversion vient de répercuter ces modifications dans votre copie de travail.

Lorsque le serveur envoie des modifications vers votre copie de travail via svn update, un code, sous forme de lettre, est affiché à coté de chaque élément pour vous permettre de savoir quelles actions Subversion a effectuées pour mettre votre copie de travail à jour. Pour en savoir plus sur le sens de ces lettres, exécutez svn help update.

Apporter des modifications à votre copie de travail

Vous pouvez à présent vous mettre au travail et apporter des modifications à votre copie de travail. Il est plus commode, habituellement, de démarrer par une modification (ou un ensemble de modifications) précise, comme par exemple écrire une nouvelle fonctionnalité, corriger un bogue, etc. Les commandes Subversion dont vous vous servez pour cela sont svn add, svn delete, svn copy et svn mkdir. Cependant, si vous ne faites qu'éditer des fichiers qui sont déjà dans Subversion, vous n'avez besoin d'aucune de ces commandes jusqu'à ce que vous propagiez vos modifications.

Vous pouvez apporter deux types de modifications à votre copie de travail : des modifications de fichier et des modifications d'arborescence. Vous n'avez pas besoin de signaler à Subversion que vous allez modifier un fichier ; faites vos changements en utilisant votre éditeur de texte, un logiciel de traitement de texte, un logiciel de graphisme, ou n'importe quel autre outil que vous utilisez d'habitude. Subversion détecte automatiquement quels fichiers ont été modifiés et, en plus, il traite les fichiers binaires tout aussi facilement et tout aussi efficacement que les fichiers textes. Pour les modifications d'arborescence, vous pouvez demander à Subversion de « marquer » les fichiers et répertoires afin de programmer leur suppression, ajout, copie ou renommage. Bien que ces modifications soient immédiatement répercutées sur votre copie de travail, aucun ajout et aucune suppression ne sera répercuté sur le dépôt avant que vous ne les propagiez.

Voici un aperçu des cinq sous-commandes Subversion les plus utilisées pour faire des modifications sur l'arborescence :

svn add truc

Marque le fichier, le répertoire ou le lien symbolique truc pour ajout. Lors de la prochaine propagation, truc devient un fils de son répertoire parent. Notez que si truc est un répertoire, tout ce qui se trouve à l'intérieur de truc est marqué pour ajout. Si vous ne désirez ajouter que truc lui-même, passez l'option --depth empty.

svn delete truc

Marque le fichier, le répertoire ou le lien symbolique truc pour suppression. Si truc est un fichier ou un lien, il est immédiatement supprimé de votre copie de travail. Si truc est un répertoire, il n'est pas supprimé, mais Subversion le marque pour suppression. Quand vous propagez vos modifications, truc est complètement supprimé de votre copie de travail et du dépôt. [5]

svn copy truc bidule

Crée un nouvel élément bidule par duplication de truc et marque automatiquement bidule pour ajout. Lorsque bidule est ajouté au dépôt, lors de la prochaine propagation, son historique est enregistré (comme ayant été créé à partir de truc). svn copy ne crée pas de répertoires intermédiaires, à moins que vous ne lui passiez l'option --parents.

svn move truc bidule

Cette commande équivaut exactement à svn copy truc bidule; svn delete truc. C'est-à-dire que bidule est marqué pour ajout en tant que copie de truc et que truc est marqué pour suppression. svn move ne crée pas de répertoires intermédiaires, à moins que vous ne lui passiez l'option --parents.

svn mkdir blort

Cette commande équivaut exactement à mkdir blort; svn add blort. C'est-à-dire qu'un nouveau répertoire nommé blort est créé et marqué pour ajout.

Examiner les changements apportés

Une fois vos modifications apportées, vous devez les intégrer au dépôt. Avant de le faire, il est souvent utile de jeter un coup d'œil sur ces modifications pour savoir exactement ce que vous avez changé. En examinant les modifications avant de les intégrer au dépôt, le commentaire associé à la propagation sera souvent plus pertinent. Éventuellement, vous verrez que vous avez modifié un fichier par inadvertance et cela vous donne une chance de revenir sur ces modifications avant de les propager au dépôt. En outre, c'est une bonne occasion de passer en revue et d'examiner les modifications avant de les publier. Vous pouvez obtenir une vue d'ensemble des modifications que vous avez faites en utilisant svn status et voir le détail de ces changements en utilisant svn diff.

Subversion a été optimisé pour vous aider dans cette tâche et il est capable de faire beaucoup de choses sans communiquer avec le dépôt. En particulier, votre copie de travail conserve, dans le répertoire .svn, la « copie » de l'original de chaque fichier suivi en versions. C'est pour ça que Subversion peut vous indiquer rapidement en quoi vos fichiers ont changé, ou même vous permettre d'annuler vos changements sans contacter le dépôt.

Avoir une vue d'ensemble des changements effectués

Pour avoir une vue d'ensemble des changements que vous avez effectués, utilisez la commande svn status. C'est certainement la commande que vous utiliserez le plus.

Si vous lancez svn status sans argument à la racine de votre copie de travail, Subversion détecte toutes les modifications effectuées sur les fichiers et sur l'arborescence. Voici quelques exemples de codes que la commande svn status affiche (notez que le texte après # n'est pas affiché par svn status).

?       gribouillage.c         # le fichier n'est pas suivi en versions
A       bazar/pognon/machin.h  # le fichier sera Ajouté
C       bazar/pognon/tas.c     # le fichier entre en Conflit
                                 avec une mise à jour
D       bazar/poisson.c        # le fichier sera supprimé
                                 (Deletion en anglais)
M       truc.c                 # le contenu de truc.c a subi
                                 des Modifications

Dans ce format d'affichage, svn status affiche six colonnes de caractères, suivis par plusieurs espaces, suivis par un nom de fichier ou de répertoire. La première colonne indique le statut du fichier ou du répertoire et/ou son contenu. Les codes sont :

A élément

Le fichier, répertoire ou lien symbolique élément est marqué pour ajout au dépôt.

C élément

Le fichier élément est dans un état de conflit. C'est-à-dire que des modifications ont eu lieu dans le dépôt depuis votre dernière mise à jour et ces modifications interfèrent avec les modifications que vous avez effectuées sur votre copie de travail (et la mise à jour n'a pas résolu ce conflit). Vous devez résoudre ce conflit avant de propager vos changements vers le dépôt.

D élément

Le fichier, répertoire ou lien symbolique élément est marqué pour suppression (« Deletion » en anglais).

M élément

Le contenu du fichier élément a été modifié.

Si vous spécifiez un chemin à svn status, vous obtenez uniquement les informations relatives à ce chemin :

$ svn status bazar/poisson.c
D      bazar/poisson.c

svn status possède aussi une option --verbose (-v) pour le rendre plus verbeux : il affiche alors le statut de tous les éléments de votre copie de travail, même ceux qui n'ont pas subi de modification :

$ svn status -v
M               44        23    sally     LISEZMOI
                44        30    sally     INSTALL
M               44        20    harry     truc.c
                44        18    ira       bazar
                44        35    harry     bazar/truite.c
D               44        19    ira       bazar/poisson.c
                44        21    sally     bazar/divers
A                0         ?     ?        bazar/divers/machin.h
                44        36    harry     bazar/divers/bidule.c

C'est la « version longue » de l'affichage de svn status. Les lettres de la première colonne ont la même signification que précédemment, mais la deuxième colonne indique le numéro de révision de travail de l'élément. Les troisième et quatrième colonnes indiquent le numéro de la révision dans laquelle a eu lieu le changement le plus récent et qui l'a effectué.

Aucune des commandes citées ci-dessus n'induit de connexion vers le dépôt : elles comparent les métadonnées du répertoire .svn avec la copie de travail. Enfin, il y a l'option --show-updates (-u) qui effectue une connexion au dépôt et ajoute les informations sur les éléments périmés :

$ svn status -u -v
M      *        44        23    sally     LISEZMOI
M               44        20    harry     truc.c
       *        44        35    harry     bazar/truite.c
D               44        19    ira       bazar/poisson.c
A                0         ?     ?        bazar/divers/machin.h
État par rapport à la révision   46

Notez les deux astérisques : si vous lanciez la commande svn update, vous recevriez les changements relatifs à LISEZMOI et truite.c. Cela vous procure des informations particulièrement intéressantes : vous devez faire une mise à jour et récupérer les changements effectués sur LISEZMOI avant de propager les vôtres, sinon le dépôt rejettera votre propagation en la considérant comme périmée (le sujet est approfondi plus tard).

svn status peut afficher beaucoup plus d'informations sur les fichiers et répertoires de votre copie de travail que ce que nous venons de voir ici. Pour obtenir une description exhaustive de svn status et de ses modes d'affichage, reportez-vous à svn status.

Voir en détail les modifications que vous avez effectuées

La commande svn diff offre une autre façon d'examiner vos changements. Vous pouvez retrouver exactement ce que vous avez modifié en lançant la commande svn diff sans argument : elle affiche les changements au format diff unifié.

$ svn diff
Index: truc.c
===================================================================
--- truc.c	(révision 3)
+++ truc.c	(copie de travail)
@@ -1,7 +1,12 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>
 int main(void) {
-  printf("Soixante-quatre tranches de fromage...\n");
+  printf("Soixante-cinq tranches de fromage...\n");
 return 0;
 }
Index: LISEZMOI
===================================================================
--- LISEZMOI	(révision 3)
+++ LISEZMOI	(copie de travail)
@@ -193,3 +193,4 @@
+Pense-bête : passer au pressing.
Index: bazar/poisson.c
===================================================================
--- bazar/poisson.c	(révision 1)
+++ bazar/poisson.c	(copie de travail)
-Bienvenue dans le fichier 'poisson'.
-Plus d'informations seront disponibles prochainement.
Index: bazar/divers/machin.h
==================================================================
--- bazar/divers/machin.h	(révision 8)
+++ bazar/divers/machin.h	(copie de travail)
+Voici un nouveau fichier pour
+écrire sur les machins.

La commande svn diff produit ces lignes en comparant vos fichiers de travail aux copies « originales » en cache dans la zone .svn. Les fichiers marqués pour ajout sont affichés comme toute section de texte ajoutée, et les fichiers marqués pour suppression sont affichés comme toute section de texte supprimée.

L'affichage est conforme au format diff unifié. C'est-à-dire que les lignes supprimées commencent par le signe - et que les lignes ajoutées commencent par le signe +. svn diff affiche également le nom du fichier et la localisation dans le fichier, à l'intention du programme patch. Vous pouvez ainsi créer des « correctifs » en redirigeant la sortie de svn diff vers un fichier :

$ svn diff > fichier-correctif

Vous pouvez, par exemple, envoyer par mail le fichier correctif à un autre développeur pour relecture ou test avant de le propager vers le dépôt.

Subversion utilise son propre moteur de calcul de différences, qui produit par défaut des résultats au format diff unifié. Si vous désirez obtenir les différences dans un autre format, spécifiez un programme de comparaison externe en utilisant l'option --diff-cmd et en fournissant les paramètres que vous voulez à l'aide de l'option --extensions (-x). Par exemple, pour obtenir les différences entre votre version locale du fichier et l'original de truc.c au format « contexte » et en ignorant la casse des caractères, vous pouvez lancer la commande svn diff --diff-cmd /usr/bin/diff --extensions '-i' truc.c.

Annuler des changements sur la copie de travail

Supposons qu'en examinant la sortie de svn diff, vous vous rendiez compte que tous les changements effectués sur un fichier donné sont erronés. Peut-être auriez-vous dû laisser le fichier tel quel, ou bien peut-être qu'il serait plus facile de reprendre les changements depuis le début.

C'est l'occasion idéale pour utiliser svn revert :

$ svn revert LISEZMOI
'LISEZMOI' réinitialisé

Subversion ramène le fichier dans son état d'avant les modifications en le remplaçant par la copie de l'original stockée dans la zone .svn. Mais notez aussi que svn revert peut annuler n'importe quelle opération. Par exemple, vous pouvez décider que, après tout, vous ne voulez pas ajouter tel fichier :

$ svn status truc
?      truc

$ svn add truc
A         truc

$ svn revert truc
'truc' réinitialisé

$ svn status truc
?      truc
[Note] Note

svn revert element produit exactement le même effet qu'effacer element de votre copie de travail puis de lancer la commande svn update -r BASE element. Toutefois, si vous voulez revenir à une version antérieure d'un fichier, svn revert a un comportement notablement différent : il n'a pas besoin de contacter le dépôt pour restaurer le fichier.

Ou que vous avez peut-être effacé un fichier par mégarde :

$ svn status LISEZMOI

$ svn delete LISEZMOI
D         LISEZMOI

$ svn revert LISEZMOI
'LISEZMOI' réinitialisé

$ svn status LISEZMOI

Résoudre les conflits (fusionner des modifications)

Nous avons déjà vu que svn status -u est capable de prévoir les conflits. Supposons que vous lanciez svn update et que le résultat suivant apparaisse :

$ svn update
U  INSTALL
G  LISEZMOI
Conflit découvert dans 'machin.c'.
Sélectionner : (p) report, (df) diff complet, (e) édite,
        (h) aide pour plus d'options :

Les codes U et G ne doivent pas vous inquiéter, les fichiers correspondants ayant absorbé sans problème les modifications venant du dépôt. Les fichiers notés U (pour « Updated ») ne contenaient aucun changement local mais ont été mis à jour à partir de changements présents dans le dépôt. Le G (pour « merGed ») signifie fusionné, ce qui veut dire que le fichier avait subi des changements localement et que les changements en provenance du dépôt ont pu être appliqués sans affecter les changements locaux.

Mais les deux lignes suivantes font partie d'une fonctionnalité (apparue dans Subversion 1.5) appelée résolution interactive des conflits. Cela signifie que les changements du dépôt interfèrent avec les vôtres et que vous avez la possibilité de résoudre ce conflit. Les options les plus utilisées sont affichées, mais vous pouvez voir toutes les options possibles en tapant h :

…
(p)  report        - marquer ce conflit pour résolution ultérieure
(df) diff-complet  - montrer toutes les différences du fichier fusionné
(e)  édite         - résoudre manuellement le conflit avec un éditeur
(r)  résolu        - utiliser la version fusionnée
(mf) mien complet  - utiliser ma version (ignore les autres éditions)
(tf) autre complet - prendre la version du dépôt (perds mes éditions)
(l)  lance         - utiliser un outil externe pour résoudre le conflit
(h)  aide          - afficher cette liste

Regardons brièvement ce que recèle chaque option avant de les détailler :

(p) report

laisser le fichier en état de conflit, conflit que vous devrez résoudre après la fin de la mise à jour.

(df) diff-complet

afficher les différences entre la révision de base et le fichier en conflit au format diff unifié.

(e) édite

ouvrir le fichier en conflit avec votre éditeur de texte favori, qui est spécifié dans la variable d'environnement EDITOR.

(r) résolu

après édition du fichier, indiquer à Subversion que vous avez résolu les conflits à l'intérieur du fichier et qu'il doit accepter son contenu actuel ; en bref, vous avez « résolu » le conflit.

(mf) mien complet

ignorer les changements envoyés par le serveur et utiliser uniquement votre version locale pour le fichier concerné.

(tf) autre complet

ignorer vos changements sur le fichier concerné et utiliser la version envoyée par le serveur.

(l) lance

lancer un programme externe pour résoudre le conflit. Ceci nécessite un peu de préparation en amont.

(h) aide

afficher la liste de toutes les commandes que vous pouvez utiliser dans la résolution interactive des conflits.

Nous allons maintenant passer en revue chaque commande, en les classant par fonctionnalité.

Voir les lignes en conflit de façon interactive

Avant de décider comment résoudre un conflit de manière interactive, il est probable que vous vouliez examiner le détail des lignes en conflit. La commande « diff » (d) est faite pour ça :

…
Sélectionner : (p) report, (df) diff-complet, (e) édite,
        (h) aide pour plus d'options : d
--- .svn/text-base/sandwich.txt.svn-base      mar. 11 déc. 2007, 21:33:57
+++ .svn/tmp/tempfile.32.tmp     mar. 11 déc. 2007, 21:34:33
@@ -1 +1,5 @@
-Achète-moi un sandwich.
+<<<<<<< .mien
+Va chercher un hamburger.
+=======
+Apporte-moi un taco !
+>>>>>>> .r32
…

La première ligne du diff correspond à ce que contenait la copie de travail dans l'ancienne version (la révision BASE), la ligne suivante correspond à vos modifications et la dernière ligne contient les modifications reçues du serveur (la révision HEAD la plupart du temps). Une fois en possession de ces informations, vous êtes prêts pour la suite.

Résoudre les conflits en mode interactif

Il y a quatre façons de résoudre un conflit avec l'interface interactive : deux d'entre elles vous permettent de fusionner et d'adapter les modifications de manière interactive, alors que les deux autres vous permettent simplement de choisir une version du fichier parmi celles proposées et de passer à la suite.

Si vous désirez choisir une combinaison de vos modifications locales, vous pouvez utiliser la commande « édite » (e) pour modifier manuellement le fichier avec des marqueurs indiquant les conflits dans un éditeur de texte (déterminé par la valeur de la variable d'environnement EDITOR). L'édition manuelle de ce fichier avec votre éditeur préféré peut sembler quelque peu « bas de gamme » (voir la section intitulée « Résoudre les conflits à la main » pour une description détaillée), c'est pourquoi certains préfèrent utiliser des outils graphiques plus évolués et spécialisés dans la fusion de documents.

Pour utiliser un outil de fusion, vous devez soit configurer la variable d'environnement SVN_MERGE, soit définir l'option merge-tool-cmd dans votre fichier de configuration Subversion (voir la section intitulée « Options de configuration » pour plus de détails). Subversion passera quatre arguments à l'outil de fusion : le fichier dans sa révision BASE, la version du fichier envoyée par le serveur lors de la mise à jour, une copie du fichier contenant vos propres modifications et une copie fusionnée du fichier (contenant des marqueurs de conflits). Si votre outil attend les arguments dans un ordre ou un format différents, vous devrez écrire un script de transformation que Subversion appellera. Après avoir édité le fichier, si vous êtes satisfait de vos changements, vous pouvez indiquer à Subversion que le fichier n'est plus en conflit en utilisant la commande « résolu » (r).

Si vous décidez qu'il n'y a pas lieu d'effectuer de fusion et si choisir l'une ou l'autre des versions proposées du fichier vous convient, vous pouvez soit opter pour vos changements (c'est-à-dire « mien ») en utilisant la commande « mien complet » (mf), soit opter pour la version des autres collaborateurs en utilisant la commande « autre complet » (tf).

Remettre à plus tard la résolution d'un conflit

Le titre peut laisser penser à un paragraphe sur l'amélioration des relations conjugales, mais il s'agit bien toujours de Subversion, voyez plutôt. Si, lorsque vous effectuez une mise à jour, Subversion soulève un conflit que vous n'êtes pas prêt à résoudre, vous pouvez, fichier par fichier, taper p, pour remettre à plus tard la résolution du conflit. Si, lors de votre mise à jour, vous ne voulez résoudre aucun conflit, vous pouvez passer l'option --non-interactive à svn update et les fichiers en conflit seront automatiquement marqués C.

Le C indique un conflit, c'est-à-dire que les changements sur le serveur interfèrent avec les vôtres et vous devez donc choisir manuellement entre les différentes modifications après la fin de la procédure de mise à jour. Quand vous repoussez à plus tard la résolution d'un conflit, Subversion va accomplir trois actions qui vous aideront à repérer et à résoudre ce conflit :

  • Subversion affiche un C pendant la mise à jour et enregistre que le fichier est dans un état de conflit.

  • Si Subversion considère que le fichier peut être fusionné, il place dans le fichier des marqueurs de conflit (des chaînes de caractères spéciales qui dénotent les « contours » des conflits) pour mettre en exergue les zones de conflit (Subversion utilise la propriété svn:mime-type pour déterminer si un fichier peut subir une fusion contextuelle ligne par ligne ; voir la section intitulée « Type de contenu des fichiers » pour en apprendre davantage).

  • Pour chaque fichier en conflit, Subversion place trois fichiers supplémentaires non-suivis en versions dans votre copie de travail :

    nom_du_fichier.mine

    C'est votre fichier tel qu'il était dans votre copie de travail avant la mise à jour, c'est-à-dire sans les marqueurs de conflits. Ce fichier ne comporte que vos derniers changements (si Subversion considère que le fichier ne peut pas être fusionné, le fichier .mine n'est pas créé, car il serait identique à la version de travail).

    nom_du_fichier.rANCIENNE_REVISION

    C'est le fichier tel qu'il était à la révision BASE, avant la mise à jour de votre copie de travail. C'est donc le fichier que vous avez extrait avant de faire vos dernières modifications.

    nom_du_fichier.rNOUVELLE_REVISION

    C'est le fichier que vous venez de recevoir du serveur quand vous avez effectué la mise à jour. Ce fichier correspond à la révision HEAD du dépôt.

    Ici, ANCIENNE_REVISION est le numéro de révision du fichier dans votre répertoire .svn et NOUVELLE_REVISION est le numéro de révision de HEAD dans le dépôt.

Par exemple, Sally effectue un changement sur le fichier sandwich.txt mais elle ne propage pas immédiatement ses modifications. Pendant ce temps, Harry propage des changements sur ce même fichier. Sally met à jour sa copie de travail avant d'effectuer la propagation et un conflit apparaît, dont elle remet la résolution à plus tard :

$ svn update
Conflit découvert dans 'sandwich.txt'.
Sélectionner : (p) report, (df) diff-complet, (e) édite,
        (h) aide pour plus d'options : d
C  sandwich.txt
Actualisé à la révision 2.
$ ls -1
sandwich.txt
sandwich.txt.mine
sandwich.txt.r1
sandwich.txt.r2

À partir de là, Subversion n'autorisera pas Sally à propager le fichier sandwich.txt avant que les trois fichiers temporaires ne soient effacés :

$ svn commit -m "Quelques petits ajouts"
svn: Échec de la propagation (commit), détails :
svn: Arrêt de la propagation : '/home/sally/travail-svn/sandwich.txt'
                               demeure en conflit

Si vous avez remis à plus tard la résolution d'un conflit, vous devez le résoudre pour que Subversion vous autorise à propager vos changements. Vous pouvez le faire avec la commande svn resolve et l'option --accept suivie d'un argument.

Si vous choisissez la version du fichier que vous avez extraite avant de faire vos changements, utilisez l'argument base.

Si vous choisissez la version qui contient uniquement vos changements, utilisez l'argument mine-full.

Si vous choisissez la version la plus récente venant du serveur (et donc abandonnez tous vos changements), utilisez l'argument theirs-full.

Cependant, si vous comptez effectuer un mélange de vos modifications et des modifications rapatriées du serveur, fusionnez le fichier en conflit « à la main » (examinez et éditez les marqueurs de conflit dans le fichier) puis utilisez l'argument working.

svn resolve supprime les trois fichiers temporaires et retient la version du fichier que vous avez spécifié avec l'option --accept. Subversion considère dès lors que le fichier n'est plus dans un état de conflit :

$ svn resolve --accept working sandwich.txt
Conflit sur 'sandwich.txt' résolu

Résoudre les conflits à la main

Résoudre les conflits à la main peut paraître quelque peu intimidant la première fois. Mais avec un peu de pratique, un enfant de cinq ans y arriverait.

Prenons un exemple. Par manque de communication entre Sally (votre collaboratrice) et vous-même, vous éditez en même temps le fichier sandwich.txt. Sally propage ses changements et, quand vous mettez à jour votre copie de travail, un conflit apparaît, que vous devez résoudre en éditant sandwich.txt. Jetons un œil à ce fichier :

$ cat sandwich.txt
Tranche de pain supérieure
Mayonnaise
Laitue
Tomate
Comté
<<<<<<< .mine
Saucisson
Mortadelle
Jambon
=======
Choucroute
Poulet rôti
>>>>>>> .r2
Moutarde
Tranche de pain inférieure

Les suites de caractères inférieur-à (<), égal(=) ou supérieur-à (>) sont des marqueurs de conflit, il ne font pas partie des données elles-mêmes. Vous devrez en général vous assurer qu'elles ont disparu du fichier avant de propager vos modifications. Le texte entre les deux premiers marqueurs est constitué des modifications que vous avez apportées dans la zone de conflit :

<<<<<<< .mine
Saucisson
Mortadelle
Jambon
=======

Le texte entre le deuxième et le troisième marqueur est celui du fichier propagé par Sally :

=======
Choucroute
Poulet rôti
>>>>>>> .r2

Normalement, vous n'allez pas juste supprimer les marqueurs et les changements effectués par Sally (elle sera affreusement déçue quand on lui apportera un sandwich différent de ce qu'elle a commandé). Vous décrochez donc le téléphone, ou vous traversez le bureau, pour expliquer à Sally qu'on ne met pas de choucroute dans un sandwich. [7] Après vous être mis d'accord sur les changements à enregistrer, éditez votre fichier et enlevez les marqueurs de conflit.

Tranche de pain supérieure
Mayonnaise
Laitue
Tomate
Comté
Saucisson
Mortadelle
Jambon
Moutarde
Tranche de pain inférieure

Maintenant utilisez svn resolve et vous êtes paré pour propager vos changements :

$ svn resolve --accept working sandwich.txt
Conflit sur 'sandwich.txt' résolu
$ svn commit -m "Va pour mon sandwich et au diable celui de Sally !"

Notez que svn resolve, contrairement à la plupart des autres commandes que nous présentons dans ce chapitre, requiert que vous listiez explicitement les noms de tous les fichiers concernés. Dans tous les cas, soyez prudent et ne lancez svn resolve qu'une fois certain que vous avez résolu le conflit dans votre fichier (une fois les fichiers temporaires effacés, Subversion vous laisse propager le fichier même s'il contient toujours des marqueurs de conflit).

Si jamais vous êtes perdu lors de l'édition du fichier en conflit, vous pouvez toujours consulter les trois fichiers que Subversion a créé pour vous dans votre copie de travail, y compris le fichier tel qu'il était avant que vous ne lanciez la mise à jour. Vous pouvez même utiliser un outil externe interactif spécialisé dans les fusions pour examiner ces trois fichiers.

Abandonner vos modifications au profit de la révision la plus récente

Si vous faites face à un conflit et que vous décidez d'abandonner vos changements, vous pouvez lancer svn resolve --accept theirs-full CHEMIN-DU-CONFLIT, et Subversion abandonne vos modifications et supprime les fichiers temporaires :

$ svn update
Conflit découvert dans 'machin.c'.
Sélectionner : (p) report, (df) diff complet, (e) édite,
        (h) aide pour plus d'options :
C    sandwich.txt
Actualisé à la révision 2.
$ ls sandwich.*
sandwich.txt  sandwich.txt.mine  sandwich.txt.r2  sandwich.txt.r1
$ svn resolve --accept theirs-full sandwich.txt
Conflit sur 'sandwich.txt' résolu

Revenir en arrière : utiliser svn revert

Si vous faites face à un conflit et qu'après examen de la situation, vous décidez d'abandonner vos changements et de repartir de zéro (peu importe en fait que ce soit après un conflit ou à n'importe quel autre moment), contentez-vous de revenir en arrière sur vos changements :

$ svn revert sandwich.txt
'sandwich.txt' réinitialisé
$ ls sandwich.*
sandwich.txt

Notez que quand vous revenez en arrière sur un fichier en conflit, vous n'avez pas besoin de lancer svn resolve.

Propager vos modifications

Enfin ! Vos modifications sont terminées, vous les avez fusionnées avec celles du serveur et vous êtes prêt à les propager vers le dépôt.

La commande svn commit envoie vos changements au dépôt. Quand vous propagez un changement, vous devez l'accompagner d'un message de propagation qui décrit ce changement. Votre message est associé à la nouvelle révision que vous créez. Si votre message est bref, vous pouvez le passer en ligne de commande en utilisant l'option --message (ou -m) :

$ svn commit -m "J'ai corrigé le nombre de tranches de fromage."
Envoi        sandwich.txt
Transmission des données .
Révision 3 propagée.

Cependant, si vous avez rédigé votre message au fur et à mesure, vous souhaitez sûrement indiquer à Subversion de récupérer le message dans un fichier en lui donnant le nom du fichier avec l'option --file (-F) :

$ svn commit -F message_de_propagation
Envoi        sandwich.txt
Transmission des données .
Révision 4 propagée.

Si vous ne spécifiez ni l'option --message ni l'option --file, Subversion lance automatiquement votre éditeur de texte favori (voir les détails de editor-cmd dans la section intitulée « Fichier config ») pour que vous rédigiez le message de propagation.

[Astuce] Astuce

Si, au moment où vous rédigez votre message de propagation, vous décidez d'annuler la propagation, vous n'avez qu'à quitter l'éditeur de texte sans sauvegarder les changements. Si vous avez déjà sauvegardé le message, effacez le texte, sauvegardez à nouveau puis choisissez d'annuler :

$ svn commit
Attente de Emacs...Fait

Entrée du journal non modifié ou non précisé
a)nnule, c)ontinue, e)dite
a
$

Le dépôt ne sait pas si vos changements ont un sens ou pas (d'ailleurs, il s'en fiche) ; il vérifie seulement que personne n'a modifié, pendant que vous aviez le dos tourné, un des fichiers que vous-même avez modifié. Si c'est le cas, la propagation toute entière échoue, affichant un message vous informant qu'un ou plusieurs de vos fichiers ne sont plus à jour :

$ svn commit -m "Ajout d'une autre règle"
Envoi        regles.txt
svn: Echec de la propagation (commit), détails :
svn: Fichier '/regles.txt' obsolète
…

Notez que le phrasé exact de ce message d'erreur dépend du protocole réseau et du serveur que vous utilisez, mais l'idée reste la même.

Maintenant, vous devez lancer svn update, traiter les fusions ou conflits qui apparaissent et retenter une propagation.

Nous en avons terminé avec le cycle d'utilisation de base de Subversion. Subversion offre beaucoup d'autres fonctionnalités pour gérer votre dépôt et votre copie de travail, mais l'utilisation quotidienne de Subversion ne requiert pratiquement que les commandes que nous venons de voir dans ce chapitre. Intéressons-nous quand même à quelques commandes supplémentaires utilisées relativement souvent.



[5] Bien sûr, rien n'est jamais totalement supprimé du dépôt — seulement de la révision HEAD du dépôt. Vous pouvez récupérer tout ce que vous avez supprimé en extrayant (ou en mettant à jour votre copie de travail à) une révision précédente de celle dans laquelle vous avez fait la suppression. Lisez également la section intitulée « Résurrection des éléments effacés ».

[6] Et que vous n'avez pas de carte Wifi. Vous ne croyiez tout de même pas nous avoir aussi facilement ?

[7] Et si vous commandez ça, on vous chassera de la ville à coup de baguette rassie.