Résoudre des conflits

De temps en temps , vous aurez un conflit au moment de mettre à jour/fusionner vos fichiers avec le référentiel ou lorsque vous migrerez votre copie de travail vers une autre URL. Il y a deux sortes de conflits:

Conflit de fichier

Un conflit sur un fichier arrive si deux (ou plus) développeurs changent les mêmes lignes d'un fichier.

Conflits dans l'arborescence

Un conflit dans l'arborescence arrive quand un développeur déplace/renomme/supprime un fichier ou un dossier, qu'un autre développeur a aussi déplacé/renommé/supprimé voire juste modifié.

Conflit de fichiers

Un conflit de fichier arrive quand 2 développeurs our plus modifient un même fichier. Dans la mesure où Subversion ne sait rien de votre projet, il laisse la résolution des conflits à la charge des développeurs. Dès qu'un conflit est détecté, vous devriez ouvrir le fichier en question, et chercher les lignes commençant par <<<<<<<. La zone en conflit est marquée de cette manière:

	<<<<<<< nom_de_fichier
		vos modifications
	=======
		code fusionné depuis le référentiel
	>>>>>>> révision
	

De plus, pour chaque conflit Subversion place trois fichiers dans votre répertoire:

nom_du_fichier.ext.mine

C'est votre fichier comme il a existé dans votre copie de travail avant que vous mettiez à jour votre copie de travail - c'est-à-dire sans marqueurs de conflit. Ce fichier a vos derniers changements et rien d'autre.

nom_du_fichier.ext.rOLDREV

C'est le fichier qui était la révision de BASE avant que vous mettiez à jour votre copie de travail. C'est-à-dire le fichier que vous avez extrait avant de faire votre dernière édition.

nom_du_fichier.ext.rNEWREV

C'est le fichier que votre client de Subversion venait de recevoir du serveur quand vous avez mis à jour votre copie de travail. Ce fichier correspond à la révision de tête du référentiel.

Vous pouvez soit lancer un outil externe de fusion / un éditeur de conflit avec TortoiseSVNÉditer les conflits soit utiliser un autre éditeur pour résoudre le conflit manuellement. Vous devrez décider à quoi devrait ressembler le code, faites les changements nécessaires et sauvegardez le fichier.

Exécutez ensuite la commande TortoiseSVNRésolu... et livrez vos modifications au référentiel. Veuillez noter que la commande de résolution ne résout pas vraiment le conflit. Il supprime juste les fichiers nom_du_fichier.ext.mine et nom_du_fichier.ext.r*, pour vous permettre de livrer vos changements.

Si vous avez des conflits avec des fichiers binaires, Subversion n'essaye pas de fusionner les fichiers lui-même. Le fichier local reste inchangé (exactement comme la dernière fois que vous l'avez modifié) et vous avez des fichiers nom_du_fichier.ext.r*. Si vous voulez renoncer à vos changements et garder la version du référentiel, utilisez simplement la commande Revenir en arrière. Si vous voulez garder votre version et écraser la version du référentiel, utilisez la commande Résolu..., livrez ensuite votre version.

Vous pouvez utiliser la commande Résolu... pour plusieurs fichiers si vous faites un clic droit sur le dossier parent et sélectionnez TortoiseSVNRésolu... Cela affichera une boîte de dialogue listant tous les fichiers en conflit dans ce dossier et vous pouvez choisir lesquels marquer comme résolus.

Conflits dans l'arborescence

Un conflit dans l'arborescence est causé quand un développeur déplace/renomme/supprime un fichier ou un répertoire, qu'un autre développeur a également déplacé/renommé/supprimé ou juste modifé. Plusieurs situations peuvent générer un conflit d'arborescence, et chacune a une solution différente.

Dans Subversion, lorsque qu'un fichier est supprimé, il l'est aussi localement, de ce fait, même s'il génère un conflit d'arborescence, aucune action de résolution de conflit de ne peut être effectuée grâce au menu contextuel du click droit. Utilisez la fenêtre Vérifier les Modifications à la place pour pouvoir accéder aux options Edition des conflits.

TortoiseSVN peut aider à trouver les endroits où fusionner les modifications, mais cela ne résoudra pas tous les conflits.Souvenez vous qu'après une mise à jour la base de travail contiendra la révision des éléments tels qu'ils étaient au moment de la mise à jour. Si vous annulez une modification après avoir fait une mise à jour l'élément reviendra à la version du référentiel, pas à l'état dans lequel était l'élément avant que vous fassiez vos modifications.

Suppression locale, édition de la mise à jour

  1. Le développeur A modifie Foo.c et en fait la livraison

  2. Le développeur B a renommé simultanément Foo.c en Bar.c dans sa copie de travail, ou simplement supprimé Foo.c ou son répertoire parent.

Une mise à jour de la copie de travail du développeur B mène à un conflit dans l'arborescence:

  • Foo.c a été supprimé de la copie de travail, mais est marqué comme étant en conflit d'arborescence.

  • Si le conflit vient d'un renommage plus que d'une suppression alors Bar.c est marqué comme ajouté, mais ne contient pas les modification du développeur A.

Le développeur B doit maintenant choisir s'il veut conserver les modifications du développeur A. Dans le cas d'un renommage de fichier, il peut fusionner les modifications de Foo.c dans le fichier renommé Bar.c. Pour des suppressions de fichier ou de répertoire il peut choisir de garder l'élément avec les modifications du développeur A et annuler la suppression. Ou, en ne faisant que marquer le conflit comme étant résolu, il annule les modifications du développeur A.

The conflict edit dialog offers to merge changes if it can find the original file of the renamed Bar.c. Depending on where the update was invoked, it may not be possible to find the source file.

Modification locale, suppression dans la mise à jour

  1. Le développeur A renomme Foo.c en Bar.c et envoie les modifications au d

  2. Le développeur B modifie Foo.c dans sa copie de travail.

Ou dans le cas d'un déplacement de répertoire ...

  1. Le développeur A déplace le réperetoire parent FooFolder vers BarFolder et soumet celui-ci au dépôt.

  2. Le développeur B modifie Foo.c dans sa copie de travail.

An update of developer B's working copy results in a tree conflict. For a simple file conflict:

  • Bar.c is added to the working copy as a normal file.

  • Foo.c is marked as added (with history) and has a tree conflict.

Pour un conflit de répertoire:

  • BarFolder is added to the working copy as a normal folder.

  • FooFolder is marked as added (with history) and has a tree conflict.

    Foo.c est marqué comme modifié.

Le développeur B doit à présent décider de garder la réorganisation du développeur A et de fusionner ses changement dans le fichier correspondant dans la nouvelle architecture, ou simplement annuler les modifications du développeur A et garder le fichier local.

Pour fusionner ses modifications locales avec la réorganisation, le développeur B doit d'abord trouver quel est le nouveau nom du fichierFoo.c dans le référentiel. Cela peut être fait en utilisant la fenêtre de commentaires. A présent les modifications doivent être réintégrées à la main dans le mesure où il n'y a aucun outil existant pour simplifier ce processus. Dès que les modifications ont été répercutées, le chemin conflictuel est redondant et peut donc être supprimé. Dans ce cas utilisez le bouton Supprimer dans la fenêtre de résolution de conflits pour faire le nettoyage et marquer le conflit comme résolu.

Si le développeur B décide que les modifications du développeur A étaient mauvaises alors elle doit choisir le bouton Garder dans la fenêtre de résolution des conflits. Cette action a pour effet de marquer le conflit du fichier/répertoire comme résolu, mais les modifications du développeur A doivent être retirées à la main. De nouveau la fenêtre de commentaires aide à trouver ce qui a été déplacé.

Suppression locale, suppression dans la mise à jour

  1. Le développeur A renomme Foo.c en Bar.c et envoie les modifications au dépôt

  2. Le développeur B renomme Foo.c en Bix.c

Une mise à jour de la copie de travail du développeur B mène à un conflit dans l'arborescence:

  • Bix.c est marqué comme ajouté avec l'historique.

  • Bar.c est ajouté dans la copie de travail avec le statut 'normal'.

  • Foo.c is marked as deleted and has a tree conflict.

Pour résoudre ce conflit, le développeur B doit trouver à quel fichier renommé/déplacé correspond la version conflictueuse de Foo.c dans le référentiel. Ce peut être fait en utilisant la fenêtre de log.

Le développeur B doit alors décider quel nouveau nom de lename>Foo.c

Dès que le développeur B a résolu manuellement le conflit, l'arborescence des conflits doit être marquée comme résolue grâce au bouton approprié dans la fenêtre d'édition des conflits.

Copie locale incomplète, modification dans la mise à jour

  1. Developer A working on trunk modifies Foo.c and commits it to the repository

  2. Le développeur B travaillant sur une branche renomme Foo.c en Bar.c et envoie les modifications au dépôt

A merge of developer A's trunk changes to developer B's branch working copy results in a tree conflict:

  • Bar.c est déjà dans la copie de travail avec le statut 'normal'.

  • Foo.c est marqué comme manquant dans l'arborescence des conflits.

To resolve this conflict, Developer B has to mark the file as resolved in the conflict editor dialog, which will remove it from the conflict list. She then has to decide whether to copy the missing file Foo.c from the repository to the working copy, whether to merge Developer A's changes to Foo.c into the renamed Bar.c or whether to ignore the changes by marking the conflict as resolved and doing nothing else.

Notez que si vous copiez le fichier manquant depuis le référentiel et que vous le marquez comme résolu, votre copie sera de nouveau retirée. Vous devez résoudre d'abord le conflit.

Modification locale, suppression dans la fusion

  1. Developer A working on trunk moves Foo.c to Bar.c and commits it to the repository

  2. Developer B working on a branch modifies Foo.c and commits it to the repository.

Il y a des cas équivalents pour les déplacements de répertoire, mais ce n'est pas encore détecté dans Subversion 1.6 ...

  1. Developer A working on trunk moves parent folder FooFolder to BarFolder and commits it to the repository.

  2. Developer B working on a branch modifies Foo.c in her working copy.

A merge of developer A's trunk changes to developer B's branch working copy results in a tree conflict:

  • Bar.c est marqué comme étant ajouté.

  • Foo.c est marqué quand ayant été modifié et comme étant en conflit dans l'arborescence.

Le développeur B doit à présent décider de garder la réorganisation du développeur A et de fusionner ses changement dans le fichier correspondant dans la nouvelle architecture, ou simplement annuler les modifications du développeur A et garder le fichier local.

Pour fusionner ses modifications locales avec les autre remaniements, le développeur B doit trouver à quel fichier renommé/déplacé correspond la version conflictueuse de Foo.c dans le dépôt. Cela peut être fait en utilisant la fenêtre de commentaires du fichier source. L'éditeur de conflit ne montre que les commentaires relatifs à la copie de travail puisqu'il ne sait pas quel chemin a été utilisé lors de la fusion, donc vous devrez le découvrir vous même. Les modifications doivent alors être fusionnées à la main puisqu'il n'existe actuellement aucun moyen d'automatiser ou de simplifier ce processus. Une fois que les changement ont été effectués, le chemin conflictueux est superflu et peut être supprimé. Dans de cas, utilisez le bouton Supprimer dans la fenêtre d'édition de conflits pour marquer le conflit comme étant résolu.

Si le développeur B décide que les modifications du développeur A étaient mauvaises elle doit alors choisir le bouton Garder dans la fenêtre de résolution de conflit. Cette action marque le conflit du fichier/répertoire comme étant résolu, mais le développeur A doit reporter ses modifications à la main. La fenêtre de commentaires du fichier source de la fusion aide à détecter ce qui a été déplacé.

Suppression locale, suppression dans la fusion

  1. Developer A working on trunk moves Foo.c to Bar.c and commits it to the repository

  2. Le développeur B travaillant sur une branche renomme Foo.c en Bix.c et envoie les modifications au dépôt

A merge of developer A's trunk changes to developer B's branch working copy results in a tree conflict:

  • Bix.c est marqué comme étant dans un état normal (non modifé).

  • Bar.c est marqué comme ajouté avec son historique.

  • Foo.c est marqué comme manquant et générant une erreur dans l'arborescence.

To resolve this conflict, Developer B has to find out to what filename the conflicted file Foo.c was renamed/moved in the repository. This can be done by using the log dialog for the merge source. The conflict editor only shows the log for the working copy as it does not know which path was used in the merge, so you will have to find that yourself.

Le développeur B doit alors décider quel nouveau nom de lename>Foo.c

Dès que le développeur B a résolu manuellement le conflit, l'arborescence des conflits doit être marquée comme résolue grâce au bouton approprié dans la fenêtre d'édition des conflits.