Fusionner

Quand les branches sont utilisées pour maintenir des lignes séparées de développement, à une certaine étape vous voudrez fusionner les changements faits sur une branche vers le tronc, ou vice versa.

Il est important de comprendre comment les branches et la fusion fonctionnent dans Subversion avant de les utiliser, car cela peut devenir assez complexe. Il est fortement recommandé de lire le chapitre Branching and Merging dans le manuel de Subversion, lequel donne une description complète et beaucoup d'exemples d'utilisation.

Il faut aussi noter que fusionner arrive toujours à l'intérieur d'une copie de travail. Si vous voulez fusionner les modifications dans une branche, vous devez avoir une copie de travail pour la branche extraite, et appeler l'assistant de fusion depuis cette copie de travail en utilisant TortoiseSVNFusionner....

En général, c'est une bonne idée d'exécuter une fusion dans une copie de travail inchangée. Si vous avez fait d'autres changements dans votre CdT, livrez les d'abord. Si la fusion ne se déroule pas comme prévu, vous pouvez vouloir annuler les changements et la commande Revenir en arrière supprimera tous les changements en incluant ceux effectués avant la fusion.

Il y a trois cas d'utilisation de la fusion qui sont gérés de façons légèrement différentes, comme décrit ci-dessous. La première page de l'assistant de fusion vous demande de quelle méthode vous avez besoin.

Fusionner une plage de révisions

Cette méthode couvre le cas où vous avez fait une ou plusieurs révisions sur une branche (ou sur le tronc) et vous voulez reporter ces changements vers une autre branche.

Ce que vous demandez à Subversion est de : « Calculer les modifications nécessaires pour passer [DE] la révision 1 de la branche A [A] la révision 7 de la branche A, et d'appliquer ces modifications à la copie de travail (de la racine ou de la branche B). »

Réintégrer une branche

Cette méthode gère le cas où vous avez développé une nouvelle fonctionnalité dans une branche comme conseillé dans le manuel de Subversion. Semaine après semaine, tous les changements du tronc ont été reportés dans cette branche, et maintenant que la fonctionnalité est terminée, vous voulez l'intégrer dans le tronc. Vu que vous avez gardé la branche synchronisée avec le tronc, les dernières versions de la branche et du tronc seront absolument identiques à part vos modifications de la branche.

C'est un cas particulier de fusion de l'arborescence comme décrite plus haut, et (normalement) seule l'URL des sources à fusionner avec votre branche de développement est nécessaire. Cette fusion utilise la fonctionnalité de Subversion permettant de calculer la plage révision correcte à utiliser, et fait quelques autres tests pour s'assurer que la branche a été complètement synchronisée avec les évolutions du tronc. Cette technique empêche de défaire par erreur le travail que les autres auraient livré depuis votre dernière mise à jour.

Après la fusion, toutes les branches de développement ont été complètement fusionnées avec la version de tête. La branche est donc redondante et peut être supprimée.

A partir du moment où vous avez effectué une réintégration vous ne devriez pas continuer à travailler dans la branche. La raison est que si vous essayez plus tard de ressynchroniser celle ci au tronc, le système verra votre réintégration comme une modification du tronc qui n'a pas encore été fusionné avec la branche, et essaiera de le fusionner avec la branche ! La solution est simplement de créer une nouvelle branche depuis le tronc et continuer vers la prochaine phase de développement.

Fusionner deux arborescences différentes

C'est le cas le plus général de réintégration. Ce que vous demandez à Subversion est de « Calculer les modifications nécessaires pour aller [DE] la version de tête du tronc [A] la version de tête de la branche, et appliquer ces modifications à ma copie de travail (sur le tronc). ». Le résultat net est que le tronc est parfaitement identique à la branche.

Si votre serveur/référentiel ne supporte pas les fonctionnalités de suivi de fusion c'est alors le seul moyen de fusionner une branche avec le tronc. Vous pouveez aussi avoir besoin de cette méthode lorsque vous utilisez du code tiers et que vous devez fusionner les modifications d'un autre tiers dans votre code source. Lisez le chapitre suivant dans le livre de Subversion pour plus d'information : Branches tiers.

Fusionner une plage de révisions

Dans le champ De : entrez l'url complète du dossier de la branche ou de l'étiquette contenant les changements que vous voulez reporter dans votre copie de travail. Vous pouvez aussi cliquer sur ... pour parcourir le référentiel et trouver la branche désirée. Si vous avez déjà fusionné depuis cette branche, alors utilisez simplement la liste déroulante contenant l'historique des URLs utilisées.

Dans le champ texte Plage de révisions à fusionner entrez la liste des révisions à fusionner. Ce peut être une seule révision, une liste de révisions spécifiques séparées par des virgules, une plage de révisions séparées par un tiret, ou une combinaison de ces différentes notations.

Important

Dans TortoiseSVN, il y a une différence importante dans la manière dont est spécifiée une plage de révisions par rapport au client en ligne de commande.

Avec le client en ligne de commande vous spécifiez les modifications à fusionner avec deux révisions « limites » qui spécifient les bornes avant et après.

Dans TortoiseSVN vous spécifiez la liste des modifications à fusionner en utilisant des « panneaux de clôture/quote>. La raison de ceci devient plus clair lorsque vous utilisez la fenêtre de commentaire pour spécifier les révisions à fusionner, où chaque révision apparait comme une liste de modifiations. »

Si vous fusionnez les révisions par parties, la méthode exposée dans le livre de Subversion vous fera fusionner 100-200 cette fois ci et 200-300 la prochaine fois. Avec TortoiseSVN vous fusionneriez 100-200 cette fois et 201-300 la prochaine fois.

Cette différence à fait couler beaucoup d'encre dans les listes de diffusion. Nous reconnaissons les différences avec le client en ligne de commande, mais nous pensons qu'il est plus facile de comprendre la notation que nous avons implémenté pour la majorité des utilisateurs de l'interface.

La façon la plus facile de choisir la plage de révisions dont vous avez besoin est de cliquer sur Voir le journal, puisqu'ainsi les changements récents seront affichés avec les commentaires associés. Si vous voulez fusionner les changements d'une seule révision, sélectionnez juste cette révision. Si vous voulez fusionner les changements de plusieurs révisions, alors sélectionnez cette plage (en utilisant comme de coutume la touche Maj). Cliquez sur OK et les numéros de révision seront automatiquement insérés.

Si vous voulez revenir sur des modifications déjà livrées de votre copie de travail, sélectionnez les révisions à annuler et vérifiez bien que la case Fusion inversée est cochée.

Si vous avez déjà fusionné des changements de cette branche, avec bon espoir vous aurez fait une note de la dernière révision fusionnée dans le commentaire quand vous avez livré la modification. Dans ce cas, vous pouvez utiliser Voir le journal dans la CdT pour retrouver ce commentaire. Dans la mesure où nous considérons les révisions comme des listes de modifications, vous devriez utiliser la révision de fin de la dernière fusion comme point de départ pour celle ci. Par exemple, si vous avez fusionné les révisions 37 à 39 la dernière fois, alors le point de départ pour cette fusion devrait être la révision 40.

Si vous vous servez de la fonctionnalité de suivi de fusion de Subversion, vous n'avez pas besoin de vous souvenir des révisions déjà fusionnées - Subversion les enregistrera pour vous. Si vous laissez le champ plage de révisions vide, toutes les révisions n'ayant pas déjà été fusionnées y seront notées. Lisez la section intitulée « Suivi des fusions » pour en savoir plus.

Si d'autres personnes peuvent livrer des changements alors soyez prudents en utilisant de la révision HEAD. Elle peut ne pas faire référence à la révision à laquelle vous pensez si quelqu'un d'autre a fait une livraison après votre dernière mise à jour.

Cliquez le bouton Suivant et allez à la section intitulée « Options de fusion »

Réintégrer une branche

Figure 4.35. Assistant de fusion - Réintégration

Assistant de fusion - Réintégration


Pour fusionner une branche de fonctionnalité dans le tronc vous devez démarrer l'assistant de fusion depuis une CdT du tronc.

Dans le champ De : entrez l'URL complète du dossier contenant la branche que vous voulez réintégrer. Vous pouvez également cliquer sur le bouton ... pour parcourir le référentiel.

Il y a quelques prérequis pour pouvoir faire une réintégration. Premièrement, le serveur doit supporter le suivi de fusion. La CdT doit contenir toute la profondeur complète de l'arborescence (pas d'extractions éparses), et elle ne doit avoir aucune modifications locales, d'éléments déplacés ou mis à jour à une version autre que la tête. Toutes les modifications faite sur le tronc pendant la phase de développement de la branche doivent avoir été intégrées à la branche (ou marquées comme ayant été fusionnées). La plage de révisions à fusionner sera calculée automatiquement.

Fusionner deux arbres différents

Figure 4.36. Assitant de de fusion - Fusion d'arborescence

Assitant de de fusion - Fusion d'arborescence


Si vous utilisez cette méthode pour fusionner une branche avec le tronc, vous devez démarrer l'assistant de fusion depuis une CdT du tronc.

Dans le champ De : entrez l'URL complète du dossier du tronc. Cela peut sembler erroné, mais souvenez-vous que le tronc est l'endroit auquel vous souhaitez ajouter les modifications de la branche. Vous pouvez aussi cliquer sur ... pour parcourir le référentiel.

Remplissez le champ To: par l'adresse complète de la branche.

Dans les deux champs Depuis la révision et À la révision, entrez le numéro de la dernière révision à laquelle les deux arbres ont été synchronisés. Si vous êtes sûrs que personne d'autre ne fait de livraison vous pouvez utiliser la révision HEAD dans les deux cas. S'il y a une chance que quelqu'un d'autre ait fait une livraison depuis cette synchronisation, utilisez le numéro de la révision particulier pour éviter de perdre des livraisons plus récentes.

Vous pouvez également utiliser Voir les Messages de Log pour sélectionner la révision.

Options de fusion

Cette page de l'assistant vous permet d'accéder à des options avancées, avant de commencer le processus de fusion. La plupart du temps vous ne pouvez utiliser que les options par défaut.

Vous pouvez donner la profondeur de fusion, i.e. à quelle profondeur dans la CdT, la fusion doit aller. Les termes de profondeur utilisés sont décrits dans la section intitulée « Profondeur d'extraction ». La profondeur par défaut est Copie de travail, qui utilise la valeur existante de profondeur, et est presque toujours ce qui est nécessaire.

La plupart du temps vous voulez fusionner pour tenir compte de l'historique du fichier, de sorte que les changements relatifs à un ancêtre commun soient fusionnés. Parfois vous pouvez avoir besoin de fusionner des fichiers qui sont liés, mais pas à l'intérieur de votre référentiel. Par exemple vous pouvez avoir importé les versions 1 et 2 d'une bibliothèque tiers dans deux répertoires séparés. Bien qu'ils soient logiquement liés, Subversion n'en a aucune connaissance puisqu''il ne voit que le package que vous avez importé. Si vous essayez de fusionner ces deux arborescences vous verriez une suppression totale suivie d'un ajout total. Pour faire en sorte que Subversion n'utilise que les différences basées sur le chemin plutôt que les différences basées sur l'historique, cochez la case Ignorer l'ascendance. Plus d'informations à ce sujet dans le manuel de Subversion, Noticing or Ignoring Ancestry

Vous pouvez spécifier la gestion des caractères de fin de ligne et des espaces. Ces options sont décrites dans la section intitulée « Options de fins de ligne et d'espacement ». Le comportement par défaut est de traiter tous les espaces et les fins de lignes comme étant des modifications à part entière.

La case à cocher appelée Forcer la fusion est utilisée pour éviter les conflits d'arborescence lors de la suppression d'un fichier qui a été modifié localement ou qui n'est pas sous contrôle de version. Si le fichier est supprimé, il n'y a aucun moyen de le récupérer, ce qui explique que par défaut cette case ne soit pas cochée.

Si vous utilisez la fonction de suivi de fusion et que vous souhaitez marquer une révision comme ayant été fusionnée, sans vraiment avoir fait de fusion ici, cochez la case Enregistrer uniquement la fusion. Il y a deux raisons pour lesquelles vous pourriez être amenés à faire ceci. La fusion à effectuer est trop compliquée pour les algorithmes de fusion, vous faites donc la fusion à la main et marquez les modifications comme ayant été fusionnées de manière à ce que le suivi de fusion le sache. Ou vous voulez éviter qu'une révision particulière soit fusionnée. La marquer comme ayant été fusionnée empêchera les clients supportant le suivi de fusion de faire effectivement la fusion.

Now everything is set up, all you have to do is click on the Merge button. If you want to preview the results Test Merge simulates the merge operation, but does not modify the working copy at all. It shows you a list of the files that will be changed by a real merge, and notes files where conflicts may occur. Because merge tracking makes the merge process a lot more complicated, there is no guaranteed way to find out in advance whether the merge will complete without conflicts, so files marked as conflicted in a test merge may in fact merge without any problem.

La barre de progression de la fusion montre chaque étape du processus, avec les plages de révision concernées. Cela peut indiquer une révision de plus que prévu. Par exemple, si vous demandez de fusionner la révision 123 la barre de progression affichera « Fusion des révisions 122 à 123 ». Pour comprendre ce qui se passe, vous devez garder en mémoire que l'opération de fusion est très proche du diff. La fusion génère une liste de différences entre deux endroits du référentiel, et applique ces différences à votre CdT. La barre de progression montre simplement les points de départ et d'arrivée du diff.

Prévisualiser les résultats de la fusion

La fusion est a présent effectuée. C'est une bonne idée le résultat et vérfier que tout est conforme à vos attentes. Fussioner est normalement assez compliqué. Il y a souvent des conflits si la branche s'est beaucoup éloignée du tronc.

Pour les clients et serveurs Subversion antérieurs à la version 1.5, aucune information de fusion n'est gardée et les révisions à fusionner sont à trouver manuellement. Lorsque vous avez testé et que vous allez livrer, le commentaire de livraison devrait toujours inclure les numéros de révision inclus dans la fusion. Si vous voulez faire une autre fusion plus tard vous aurez besoin de savoir ce que vous avez déjà fusionné pour ne pas applique vos modifications plusieurs fois. Pour plus d'informations, consultez Best Practices for Merging dans la bible de Subversion.

Pour des clients et serveurs Subversion postérieurs à la version 1.5, la fonctionnalité de suivi de fusion enregistrera les révisions fusionnées et empêchera d'en fusionner une plus d'une fois. Cela vous simplifie la tâche dans la mesure où vous pouvez tout fusionner à chaque fois en étant sûr que seules les nouvelles révisions seront vraiment fusionnées.

La gestion de branches est importante. Si vous voulez conserver une branche synchronisée avec le tronc, vous devrez vous assurer de fusionner souvent de sorte que la branche et le tronc ne soient pas trop éloignés. Bien sûr, vous devez toujours éviter de fusionner plusieurs fois les mêmes modifications comme expliqué ci-dessus.

Astuce

Si vous venez de fusionner une branche avec le tronc, celui ci contient le code de la nouvelle fontionnalité, et la branche est obsolète. Vous pouvez donc la supprimer du référentiel si besoin est.

Important

Subversion ne peut pas fusionner un fichier avec un dossier et vice versa - seulement entre dossiers et entre fichiers. Si vous cliquez sur un fichier et ouvrez la boîte de dialogue fusionner, vous devez alors donner un chemin vers un fichier dans cette boîte de dialogue. Si vous choisissez un dossier et affichez la boîte de dialogue, vous devez alors spécifier une URL de dossier pour la fusion.

Suivi des fusions

A partir de la version 1.5, Subversion inclus des aides au suivi de fusion. Lorsque vous fusionnez des modifications depuis une arborescence vers une autre, les numéros de révision sont stockés et peuvent être utilisées à plusieurs fins.

  • Vous pouvez éviter le danger de fusionner deux fois la même révision (problème de fusions répétées). Dès qu'une révision a été marquée comme ayant été fusionnée, les fusions futures incluant cette révision dans leur plage de révisions l'ignoreront.

  • Quand vous fusionnez une branche dans le tronc, la fenêtre de commentaires peut vous montrer les livraisons de la branche comme faisant partie des commentaires du tronc, donnant une meilleure traçabilité des modifications.

  • Lorsque vous affichez la fenêtre de commentaires depuis la fenêtre de fusion, les révisions déjà fusionnées sont grisées.

  • Quand l'annotation d'un fichier est affichée, vous pouvez choisir de montrer les auteurs des révisions fusionnées, au lieu de la personne ayant fait la fusion.

  • Vous pouvez marquer les révisions comme n'étant pas à fusionner en les incluant dans la liste des révisions fusionnées mais sans vraiment faire la fusion.

Les informations de suivi de fusion sont stockées dans la propriété svn:mergeinfo par le client lorsqu'il effectue la fusion. Au moment de la livraison de cette fusion, le serveur stocke l'information dans la base de données, et quand vous souhaitez fusionner, commenter ou annoter, le serveur peut répondre de manière appropriée. Afin que le système fonctionne correctement, vous devez vous assurer que le serveur, le référentiel et les clients sont à jour. Les clients plus anciens ne stockeront pas la propriété svn:mergeinfo et les serveurs plus anciens ne pourront pas satisfaire à toutes les demandes des clients récents.

Apprenez en plus à propos du suivi de fusion dans la bible Subversion Merge tracking documentation.

Gérer les conflits durant la fusion.

La fusion ne se passe pas toujours très bien. Parfois, il y a des conflits, et si vous fusionnez plusieurs plages de révisions, vous voudrez généralement résoudre les conflits avant de passer à la plage de révisions suivante. TortoiseSVN vous aide dans ce processus en affichant la boite de dialogue de conflit de fusion.

Figure 4.37. La boîte de dialogue de conflit de fusion

La boîte de dialogue de conflit de fusion


It is likely that some of the changes will have merged smoothly, while other local changes conflict with changes already committed to the repository. All changes which can be merged are merged. The Merge Conflict Callback dialog gives you three different ways of handling the lines which are in conflict.

  1. Choosing Prefer local will select your local changes in every conflict. Likewise, Prefer repository will select the repository changes in every conflict. This sounds easy, but the conflicts often cover more lines than you think they will and you may get unexpected results.

  2. Normally you will want to look at the conflicts and resolve them yourself. In that case, choose the Edit Conflict which will start up your merge tool. When you are satisfied with the result, click Resolved.

  3. La dernière option est de reporter la résolution et continue l'opération de fusion. Vous pouvez choisir cette option pour le conflit courant, ou pour tous les fichiers conflictuels de la fusion. De toutes façons, s'il y a d'autres modifications dans ce fichier, la fusion ne pourra pas se faire.

Si vous ne voulez pas utiliser le mode interactif, il y a une case à cocher dans la barre de progression de la fusion Fusion non-interactive. Si celle-ci est cochée pour une fusion, et que la fusion génère des conflits, le(s) fichier(s) sont marqués comme conflictueux et l'opération de fusion continue. Vous aurez à résoudre les conflits lorsque la fusion sera terminée. Si la case n'est pas cochée, vous avez la possibilité de résoudre le conflit avant que le fichier soit marqué comme conflictuel pendant la fusion. L'avantage est que si un fichier est impliqué dans plusieurs fusions (plusieurs révisions concernent celui ci), les fusions successives pourront se passer sans encombres selon les lignes affectées. Mais bien sûr vous ne pouvez pas aller prendre un café pendant que la fusion s'exécute ;)

Fusionner une branche complétée

Si vous voulez fusionner toutes les modifications d'une branche de fonctionnalité dans le tronc, vous pouvez utiliser la commande TortoiseSVNFusoin de réintégration... depuis le menu contextuel (appuyez sur la touche Maj en faisant un click droit sur le fichier).

Figure 4.38. La boîte de dialogue de fusion

La boîte de dialogue de fusion


Cette fenêtre est très simple. Tout ce que vous avez à faire est de paramétrer la fusion, comme décrit dans la section intitulée « Options de fusion ». Le reste est fait automatiquement par TortoiseSVN grâce au suivi de fusion.

Branche de maintenance d'une fonctionnalité

Quand vous développez une nouvelle fonctionnalité dans une branche séparée c'est une bonne pratique de garder en tête la réintégration de cette branche lorsque la nouvelle fonctionnalité sera prête. Si la branche principale (le trunk) évolue en même temps, il est probable que les différences seront nombreuses, rendant l'intégration cauchemardesque.

Si la fonctionnalité est relativement simple et que le développement ne prend pas beaucoup de temps, vous pouvez adopter une solution simple, qui consiste à garder une branche distincte, que vous intégrerez lorsque le développement sera fini. Dans l'assistant de fusion, ce devrait n'être qu'un simple Fusionner une plage de révisions, la plage de révisions couvrant la période de développement de la branche.

Dans le cas où la fonctionnalité prend du temps et que vous souhaitez récupérer les évolutions du trunk, alors vous devez garder votre branche synchronisée. Cela signifie simplement que vous devez fusionner de temps en temps les évolutions du tronc dans votre branche, de manière à ce que votre branche contiennent toutes les modifications du tronc en plus de la nouvelle fonctionnalité. Le processus de synchronisation utilise la commande Fusionner une plage de révisions. Quand le développement de la fonctionnalité est achevé vous pouvez alors fusionner la branche avec le tronc (i.e. trunk) en utilisant Réintégrer une branche ou Fusionner deux arborescences.