Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > Environnements de développement > Gérez vos projets à l'aide du gestionnaire de versions Subversion > Les bases - Utilisations des clients > Gérer les conflits > Lecture du tutoriel

Gérer les conflits

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : Dalshim
Visualisations : 872
Licence : Creative Commons BY-SA


Plus d'informations Plus d'informations
Dans ce mini-tuto, nous allons enfin apprendre à résoudre la chose la plus horrible... les conflits !

Comme nous l'avons déjà vu (mais un petit rappel ne fait jamais de mal), un conflit apparaît lorsque deux personnes (ou plus) décident de modifier un fichier au même moment. La plus rapide va commiter son changement sans aucun problème, mais la deuxième va devoir gérer le fait que, sur le serveur, se trouve une version plus récente que celle sur laquelle elle a travaillé.

Pour vous entraîner à gérer les conflits, il faut d'abord les créer. Pour en créer un, aucun problème, il suffit de faire un update du fichier voulu à une version antérieure, de modifier le fichier et de le commiter. Le serveur ne sera pas content puisque la version sur laquelle vous avez travaillé n'est pas la plus récente au moment du commit.

Pour éviter, lorsque vous travaillez sur les conflits, qu'il se passe des choses incompréhensibles parce que vous êtes cinq à tester les conflits sur le même fichier, créez un dossier, créez un fichier dedans et remplissez-le, faites un commit, puis un deuxième avec un autre ajout de contenu, updatez à la première version du fichier (seulement la moitié du contenu) et entraînez-vous comme ça.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Contourner le conflit

Maintenant que tout le monde se rappelle comment créer un conflit, je vous propose de mettre en place votre environnement et d'en créer un.

Alors, quelles sont les options qui viennent à nous pour contourner le problème (le résoudre nous-mêmes ou le laisser à quelqu'un d'autre !? :p ). Trois commandes en fait :


Diff



Cette commande va vous permettre de ne pas vous perdre. Vous codez plus vite que votre ombre ? Vous ne savez plus ce que vous avez modifié depuis le dernier update ? Pas de problème, svn diff est là pour vous expliquer ce que vous avez fait.

Code : Bash
1
2
svn diff [Target[@Rev]...] [-N] [-r Rev1:Rev2] [--force] [--summarize] [--no-diff-deleted] \
[--username login] [--password mdp] [--no-auth-cache]



Bon, je vous ai montré la commande entière pour que vous sachiez l'utiliser, mais ce dont vous avez besoin pour voir les différences que vous avez apportées par rapport à votre dernier update, c'est juste :
Code : Bash
1
svn diff

Et c'est tout.

À mon grand regret, je n'ai pas trouvé d'équivalent de la commande "svn diff" pour TortoiseSVN. Mais rassurez-vous, TortoiseSVN possède un outil bien plus puissant pour comparer deux versions d'un fichier, ou bien deux fichiers différents pour les fusionner dans un troisième fichier. Ce sera vu en prochaine sous-partie.


Revert



Cette commande va enlever la plupart des modifications effectuées sur les éléments (fichiers ou dossiers) depuis le dernier update.

Euh... ça veut dire quoi : "la plupart" ? Il ne va pas tout remettre ? C'est au petit bonheur la chance ?


Pas du tout ! Mais si vous regardez le manuel (si si, le manuel), vous verrez que cette option ne permet pas de restaurer des dossiers supprimés. Sinon, c'est du tout cuit.
On voit d'ici le problème de cette commande. Toutes vos modifications vont partir à la poubelle et vous allez gagner le droit de les refaire sur le nouveau fichier après un update.

Et oui, la vie est dure, mais c'est comme ça. Dans un projet, la plupart du temps, cette commande est utilisée parce que quelqu'un a édité un fichier binaire,".doc" par exemple, alors que ce n'était pas son tour dans le planning. Or le problème, c'est que SVN ne sait pas fusionner des fichiers binaires ! Dommage... il va donc falloir tout refaire.

La commande s'utilise comme suit (très peu d'options) :
Code : Bash
1
svn revert [CHEMIN] [--targets Fichier_darguments] [-R]


Resolved



Cette commande a "deux fonctions". Elle ne permet que d'indiquer qu'un conflit est résolu (comme on aurait pu s'en douter), seulement, subtilité, il y a deux façons de s'en servir.

Méthode 1


J'ai un conflit, je me casse la tête et le résous, j'indique qu'il est résolu, je commit.

Méthode 2


J'ai un problème, je ne m'en occupe pas parce que j'ai pas envie de refaire ce que j'ai fait et que c'était mon tour dans le planning, j'indique qu'il est résolu (même si ce n'est pas le cas), je commit.

Pour la méthode 1, nous allons voir comment fusionner le travail, en cas de conflit, dans la prochaine sous-partie. Pour la méthode 2, vous l'aurez compris, elle permet de ne pas avoir à tout refaire soi-même, en revanche, elle donne tout à refaire à l'autre membre de l'équipe qui a commité avant vous.

Voici son utilisation (à nouveau très peu d'options) :
Code : Bash
1
svn resolved [CHEMIN] [--targets Fichier_darguments] [-R]


Et TortoiseSVN



Et bien, à nouveau, pas besoin de se casser la tête.
Clic droit >> TortoiseSVN >> Revert
Clic droit >> TortoiseSVN >> Resolved

TortoiseSVN est très bien fait, il n'affiche pas les actions qu'il est impossible d'effectuer. Ainsi, s'il n'y a rien à résoudre (ni à revert) sur le fichier ou dossier cliqué, il ne vous proposera pas la commande !

Fusionner le conflit

Ici, nous allons apprendre à résoudre le conflit dans sa façon la plus subtile : la fusion des versions en conflit.
Pourquoi est-ce que l'on ne fait pas toujours comme ça ?

Eh bien, tout simplement parce que ce n'est pas toujours possible. Comme dit précédemment, il n'est pas possible d'user de cette méthode pour tout conflit. Elle ne fonctionnera pas avec les fichiers binaires par exemple. En revanche, elle fonctionne très bien avec les fichiers textes.

Je vais dans cette partie détailler la marche que j'ai suivie. Ça vous permettra de refaire la même pour mieux comprendre, et de vous faire utiliser un peu aussi votre esprit d'analyse. ^^

Commençons par la création du conflit :
Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
>>> svn update -r 62 Fichier\ 1.txt 
U    Fichier 1.txt
Updated to revision 62.
>>> vim Fichier\ 1.txt
>>> svn ci -m "commit d'un conflit"
Sending        Fichier 1.txt
svn: Commit failed (details follow):
svn: Your file or directory 'Fichier 1.txt' is probably out-of-date
svn: The version resource does not correspond to the resource within the transaction.  Either the requested version resource is out of date (needs to be updated), or the requested version resource is newer than the transaction root (restart the commit).
>>> ls 
Dossier 1		monajout.cpp		testFile
Fichier 1 - Copie.txt	test			youpi2.txt
Fichier 1.txt		test123.txt
argInfo			test2
>>> svn status -u Fichier\ 1.txt 
M      *       62   Fichier 1.txt
Status against revision:     76

Et voilà, ce gentil petit message d'erreur nous explique que, contre toute attente, la version sur laquelle nous nous sommes basés pour faire nos changements n'est pas à jour par rapport au serveur (ce n'est pas la plus récente). Il va donc falloir corriger le tir.

Résolution manuelle



Regardons, au hasard, ce qui se passe si l'on tente un update sur ce fichier (pas à jour mais modifié localement).

Code : Bash
1
2
3
>>> svn update Fichier\ 1.txt 
C    Fichier 1.txt
Updated to revision 76.

Notez le 'C' en première colonne qui nous indique que le fichier est Conflicted (en conflit). Mais regardons un peu plus loin.
Code : Bash
1
2
3
4
5
6
>>> ls
Dossier 1		Fichier 1.txt.r76	test2
Fichier 1 - Copie.txt	argInfo			testFile
Fichier 1.txt		monajout.cpp		youpi2.txt
Fichier 1.txt.mine	test
Fichier 1.txt.r62	test123.txt


On constate que l'update nous a rajouté tout un tas de nouveaux "Fichier 1.txt". Parmi ces nouveaux, on trouve :


Un petit coup d'oeil sur ce fameux Fichier 1.txt qui est sous contrôle de version, qu'en a fait le update ?

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
>>> svn status -uv Fichier\ 1.txt
C              76       76 SdZ-Guest    Fichier 1.txt
Status against revision:     76
>>> Cat Fichier\ 1.txt
[... Début du Fichier ...]
Et je fous la merde

Merci

<<<<<<< .mine
OM en force ! 

Création d'un conflit
=======
OM en force !

Barça en berne lol
>>>>>>> .r76


On voit que les deux modifications sont présentes dans ce fichier. À la fois les miennes, mais aussi celles faites par le commit de la révision 76. Il est assez simple de comprendre comment les différences sont séparées :

À partir de là, on garde ce que l'on veut, on remet dans l'ordre, on déclare le conflit comme resolved (résolu) pour autoriser le commit et on commit.

Code : Bash
1
2
3
4
5
6
7
>>> vim Fichier\ 1.txt
>>> svn resolved Fichier\ 1.txt
Resolved conflicted state of 'Fichier 1.txt'
>>> svn ci Fichier\ 1.txt -m "resolution du conflit"
Sending        Fichier 1.txt
Transmitting file data .
Committed revision 77.

Oui, mais ça m'a l'air très manuel cette méthode.... Il n'y a pas plus subtil ?

Eh bien, oui et non. Pour la plupart des modifications effectuées, SVN ne peut se permettre de choisir pour vous, si deux personnes on édité la même ligne (le même endroit dirons nous plutôt), quelles modifications arrivent en premier ?

Résolution automatique



En revanche il sait très bien faire le merge (la fusion) tout seul si vous n'avez pas édité les mêmes parties d'un document.

Petit exemple.
Je prends le fichier monaj.cpp que je trouve sur le SVN au moment de la rédaction.
Citation : monaj.cpp
je rajoute un fichier

et je le modifie en plus
...tant pis

un ligne après
hop

J'update sur deux working copy (copie de travail) et j'édite sur les deux le fichier. Pour le premier, je rajoute "hop" au début du fichier (en rajoutant une ligne), pour le deuxième, je rajoute "hop" à la fin du fichier (sans rajouter de ligne).
Je commit avec un puis avec l'autre.
Le deuxième commit me donne une erreur, donc j'update.

Code : Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
>>> svn up monaj.cpp 
G    monaj.cpp
Updated to revision 90.
>>> ls
Dossier 1		monaj.cpp		testFile
Fichier 1 - Copie.txt	test123.txt		youpi2.txt
Fichier 1.txt		test2
argInfo			test3
>>> cat monaj.cpp 
hop
je rajoute un fichier 

et je le modifie en plus
 ...tant pis

un ligne après
hop hop

On voit que le fichier n'est pas 'C' pour indiquer un conflit, mais 'G' pour indiquer une fusion automatique. Et on constate qu'en effet, aucun fichier .mine, .r89, .r90 n'a été créé (comme lors d'un conflit), et que le fichier monaj.cpp a bien intégré les deux modifications faites.

Et TortoiseSVN



Utilisateurs de Windows et de TortoiseSVN, regardez bien. Qu'a-t-on fait lors de cette sous-partie ? Uniquement des updates et des commits. Mais vous savez déjà faire tout ça. Donc vous savez tout faire.
Quand je vous disais que l'apprentissage d'un client n'était pas compliqué, ce n'était pas pour rien. Il faut juste la théorie et hop c'est parti.

Information tout de même, pour faire un update vers une révision précédente avec TortoiseSVN, il faut faire :
Clic droit >> TortoiseSVN >> update to revision...


Pourtant, TortoiseSVN propose quand même un GROS plus : TortoiseMerge !

Eh oui, la résolution manuelle d'un conflit est quelque peu lourde : repérer les différences entre deux fichiers et tout et tout. TortoiseSVN a mis au point un outil pour le moins performant qu'est TortoiseMerge. Vous pouvez récupérer sa documentation par ici.
Une annexe aura très certainement lieu pour apprendre à s'en servir correctement. En attendant, il faudra vous contenter de la doc.

Éviter le conflit

Maintenant que l'on a vu comment le résoudre, on va voir comment l'éviter.

Ce que l'on a déjà vu



Eh oui, tout au long du tutoriel, j'ai essayé de vous sensibiliser le plus possible aux "best practices" (les bonnes pratiques) du SVN à mettre en oeuvre pour éviter d'avoir des conflits. Petit récapitulatif :


Il est fortement conseillé d'appliquer ces bonnes pratiques !


Lock et unlock



Il existe également deux commandes qui sont là rien que pour vous, exprès pour éviter les conflits. Il s'agit de lock (verrouiller) et unlock (déverrouiller).
Ces deux commandes ont un comportement très simple. Lock va bloquer l'édition du fichier aux autres membres jusqu'à ce que vous fassiez un unlock.

Si l'on va voir l'icône associé sous TortoiseSVN, on trouve celle-ci : Icône fichier locké
Nous avons donc un très jolie petit cadenas qui nous montre que le fichier possède un lock.

Lors de votre commit sur l'élément verrouillé, il va vous être proposé de relâcher le verrou. C'est d'ailleurs le comportement par défaut. Donc si vous ne voulez pas libérer le verrou, il faut le préciser.


Regardons ce que cela donne pour l'utilisation sous TortoiseSVN et en ligne de commande. Pour TortoiseSVN, toujours aussi simple : clic droit >> TortoiseSVN >>Get lock... et clic droit >> TortoiseSVN >> Release lock.
Pour la ligne de commande :
Code : Bash
1
svn lock TARGET... [--target fichier_darguments] [-m "message"] [--force] [--force-log] [--username login] [--password mdp] [--no-auth-cache]
et
Code : Bash
1
svn unlock TARGET...  [--target fichier_darguments] [--force] [--username login] [--password mdp] [--no-auth-cache]


Alors, dans ces multiples options, vous en retrouvez quelques-unes que vous connaissez déjà, on notera d'ailleurs la possibilité de mettre un message de log sur le lock pour le justifier, mais également quelques nouvelles options :

--force ne devrait pas être utilisée. Cette option sert si vraiment quelqu'un dans le groupe a fait une connerie, a verrouillé quelque chose qu'il n'aurait pas dû ou bien l'a fait à un moment où il n'aurait pas dû.


Maintenant, vous l'aurez compris, la chose simple à faire pour éviter les conflits est de, lorsqu'on va travailler sur un fichier, le locker, verrouiller, pour être sûr qu'il n'y ait pas de conflit.
NON ! C'est une énorme erreur. Le lock se doit d'être utilisé avec parcimonie. Tout le but du merge automatique est de permettre à plusieurs personnes de travailler en même temps sur le même fichier. Si vous faites un lock à chaque fois, il y a une perte de productivité.

Le lock montre son utilité lors d'un travail sur un fichier binaire, car, je le rappelle une vingtième fois, on ne sait pas fusionner les fichiers binaires. Mais en dehors de ce cas-là, il n'est et ne devrait presque jamais être utilisé.

Vous venez de voir plusieurs méthodes pour résoudre des conflits. Le tout est maintenant de les maîtriser parce que vous aller forcément faire face à des conflits dans vos projet.
Chapitre précédent Sommaire Chapitre suivant
Retour en haut Retour en haut


Créé : le 13/05/2008 à 14:06:06
Modifié : le 11/11/2008 à 13:04:19
Avancement : 100%

L'orthographe, la grammaire et la présentation de ce tutoriel ont été vérifiées par les zCorrecteurs.
Commentaires

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 194 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.0215s (0.0104s)