Question

Supposons que vous disposiez de plusieurs branches de maintenance pour les versions existantes de votre logiciel. Certains développeurs apportent des modifications directes dans les branches de maintenance et fusionnent périodiquement dans le coffre. Vient maintenant une refactorisation complète dans la ligne de code de coffre, prévue pour une version majeure à venir. Mais cela rend les branches de maintenance fondamentalement incompatibles avec le code dans le coffre, car elles pourraient dépendre d'un code qui n'existe plus, par exemple.

Comment gérez-vous cette situation en pratique?

Était-ce utile?

La solution

Je considère qu'il incombe au développeur de la maintenance de la succursale de fusionner la modification appropriée dans l'état actuel du tronc. Il y a plusieurs possibilités:

  1. Le code dans le coffre n'a pas changé et le correctif s'applique sans conflit.
  2. Le code dans le coffre a été modifié et le correctif s’applique, mais une fusion manuelle est nécessaire.
  3. Le code dans le coffre a complètement changé et le correctif ne peut pas être appliqué. Le développeur doit évaluer si le même défaut existe dans le coffre et appliquer un correctif équivalent si nécessaire.

Les cas 1 et 2 sont les chemins de développement de maintenance habituels. Le cas 3 que vous envisagez est celui où le code de la ligne réseau ne peut accepter le correctif de maintenance sous quelque forme que ce soit. Si le développeur ne peut pas déterminer lui-même si le même problème peut exister dans le coffre, il doit alors saisir un problème dans le système de suivi des problèmes. Ce problème inciterait les développeurs de lignes réseau à examiner la raison du correctif dans la branche de maintenance et à déterminer si le même défaut pourrait toujours exister. Entrer un nouveau problème pour un défaut possible dans le coffre devrait constituer un dernier recours pour le développeur de la maintenance.

L'un des avantages des développeurs de maintenance qui souhaitent appliquer des correctifs au coffre mis à jour est de mieux se familiariser avec la nouvelle base de code. Ils finiront par manquer de travail de maintenance et devront travailler avec le nouveau coffre. Avoir au moins un niveau de connaissance de base sera très bénéfique.

Autres conseils

Il s’agit en définitive d’une question sur la communication en équipe plutôt que d’une simple question de branchement / fusion.

La première étape, comme dans tous les cas, consiste à réaliser que vous avez un problème. C’est quelque chose que vous avez fait.

Ensuite, vous devez alerter toute l'équipe sur le problème.

Une fois que vous avez fait cela, je pense qu'il y a deux chemins différents:

  1. Si les branches de maintenance sont peu utilisées, par exemple, le code publié est assez mature et ne contient pas de bogue, vous pouvez choisir de geler le code. Chaque développeur doit terminer son travail d’ici le 32 octobre et fusionner ces modifications dans le coffre. Les branches devraient alors être soit fermées, soit gelées. Ensuite, le travail peut continuer dans le coffre et le nouveau logiciel peut être publié.

  2. S'il y a des changements fréquents ou urgents et des corrections dans les branches, ce problème est plus compliqué. Il doit encore y avoir un gel du code, sinon le tronc sera encombré plusieurs fois. Mais ici, les développeurs doivent encore régler les problèmes dans l’intervalle et les transmettre aux clients. Je suggère que chaque modification dans les branches après le gel du code de la ligne de réseau soit enregistrée dans la base de données de suivi des bogues (indispensable dans chaque situation) avec une indication spéciale que cela a été corrigé dans la branche N mais pas encore fusionné avec la ligne. Cela nécessite une journalisation minutieuse afin que tous les détails pertinents soient mémorisés.

    Une fois que le coffre a été refait, mais avant qu'il soit nettoyé, mis en mémoire tampon, étiqueté et publié, examinez la base de données de bogues, en particulier les éléments corrigés dans les branches, mais pas le coffre. Sont-ils toujours pertinents? Il est maintenant temps de changer le code à nouveau, si nécessaire. Cela peut signifier un double travail pendant un court instant, mais j'espère que le code est beaucoup plus facile à gérer maintenant.

    Une fois tous les problèmes connus résolus, vous pouvez publier la nouvelle version et fermer les anciennes branches.

La seule solution que j'ai pu trouver est de créer une branche de maintenance-trunk juste avant de commencer le refactoring. Vous gérez cette nouvelle branche comme s'il s'agissait d'une ligne de réseau, en fusionnant les modifications apportées aux branches de version et de manière normale. À l’avenir, vous devrez alors faire attention à ne pas mélanger les modifications de l’ancienne et de la nouvelle base.

L’autre alternative est d’essayer, par exemple, MolhadoRef ( article de blog sur MolhadoRef et SCM avec prise en compte du refactoring ), si vous pouvez trouver un produit prêt à être produit système équivalent qui répond à vos besoins. En théorie, il s’agit d’un contrôle de source prenant en compte le refactoring. Je ne me suis pas penché sur la question depuis un moment, mais je me souviens enfin, c'était encore loin d'être un document de recherche et une preuve de concept.

En pratique, vous devrez peut-être effectuer un travail supplémentaire pour rendre vos nouvelles modifications compatibles avec les versions antérieures.

  • Étape 1: commencez à refactoriser le composant. À chaque étape, conservez l'ancienne interface, mais faites-la migrer les appels vers la nouvelle implémentation. Notez que cela peut être fait en plusieurs étapes à mesure que la nouvelle interface / API est construite. Les tests unitaires devraient pouvoir vérifier que la migration de l'ancien au nouveau fonctionne correctement, mais cette étape entraînera vraisemblablement encore une surcharge de test / d'assurance qualité.

  • Étape 2: la nouvelle version est en production; assurez-vous que tout le monde le sait. À ce stade, aucune nouvelle fonctionnalité n'est ajoutée à l'ancienne version, et tous les nouveaux appelants (ou modifiés) utilisent la nouvelle version.

  • Étape 3: Trouvez tout ce qui appelle l'ancienne interface (utilisez des outils pour le faire) et modifiez tout pour appeler la nouvelle interface. Cela entraîne probablement beaucoup de temps d’essai et d’assurance qualité. Chaque appelant peut être validé / libéré un à la fois, cependant.

  • Étape 4: à ce stade, la nouvelle version est en ligne et il ne reste plus aucun appelant ayant accès à l'ancienne version. Supprimez-le en toute sécurité.

Notez que lorsque l'API est publique et que vous ne contrôlez pas les personnes qui l'appellent (entreprises telles que Microsoft, par exemple), vous ne pourrez peut-être jamais dépasser l'étape n ° 2.

Ce processus peut être lent et nécessite beaucoup de discipline, de communication et de tests. Mais dans les cas où l’alternative joue un rattrapage / une intégration pour toujours, ce pourrait être une option raisonnable.

Étant donné que la réparation d’un bogue coûte cher, elle consiste à reproduire le problème et à tester le correctif. Pouvez-vous écrire un test automatisé qui fonctionnera dans toutes les branches, même si la correction de code doit être effectuée différemment pour chaque branche?

Au moment où vos branches de maintenance ne sont plus compatibles avec le tronc principal, il serait temps de créer de nouvelles branches à cette fin. En d’autres termes, au début du grand projet, vous vous assurez que tous vos développeurs sont conscients que de nouvelles fonctionnalités arrivent dans le coffre principal, afin de pouvoir choisir plus facilement l’endroit où vous souhaitez implémenter les correctifs. Vraisemblablement, si les modifications de code intervenant dans le tronc principal sont si importantes qu’elles rendent la maintenance non supportable, la maintenance doit alors être intégrée dans le tronc principal.

Créez une branche de maintenance et faites-la jouer le rôle de tampon entre le tronc et les versions-branches.

Les modifications apportées aux branches de version entrent dans la branche de maintenance, puis ne sont transférées au tronc que si elles le peuvent et vice versa.

Je ne pense pas qu'il y ait une solution miracle, cependant. À mesure que les branches divergent de plus en plus, elles deviennent incompatibles et vous devez donc considérer pendant combien de temps vous allez les supporter. Sinon, vous pourriez réparer les bogues plusieurs fois, mais légèrement différemment selon les branches.

C’est peut-être une suggestion très exigeante en travail, mais la première chose qui me vient à l’esprit est de tout fusionner dans le coffre. Toutes les modifications sont fusionnées dans la copie principale et conservées ensemble. Ensuite, refactorez le coffre comme vous le souhaitez. Maintenant, vous avez un coffre qui fonctionne, avec toutes les corrections mises en place.

Malheureusement, cela signifierait que toutes les corrections dans les branches de maintenance devraient être regroupées et placées dans le coffre central. Je me rends compte que ce serait beaucoup de travail, mais je pense que cela permettrait de tout refactoriser et que toute amélioration des branches de maintenance appartiendrait à la branche principale. Je suis peut-être naïf à ce sujet, mais je n'ai pas vraiment travaillé sur un projet de production et je ne sais pas non plus exactement ce qu'il y a dans les branches de maintenance. Je suppose que cela rendrait le coffre entièrement à jour et toutes vos améliorations de maintenance seraient intégrées au coffre.

Je pense que cela permettrait de maximiser la qualité de toutes vos branches et de répartir votre refactoring sur toutes les branches que vous auriez branchées après le refactoring. Ce serait également un bon moyen de réunir votre équipe pour toute la fusion.

Je vois deux manières distinctes de s’y attaquer:

1.

Des modifications importantes du coffre (comme une refactorisation majeure) ne devraient pas être effectuées dans le coffre. Ils doivent être effectués dans une branche et fusionnés dans le coffre lorsqu'ils sont suffisamment stables.

Périodiquement, les modifications apportées au coffre doivent être fusionnées avec les autres branches de maintenance. La raison pour la fusion du refactoring dans le coffre lorsqu'il est stable est que ceux-ci seront alors fusionnés dans les branches de maintenance. Toutefois, s’il n’est pas possible de rendre ces modifications stables, l’option 2 serait préférable.

Une fois les modifications apportées aux branches de maintenance, elles peuvent ensuite être fusionnées dans le coffre.

2.

Créez une branche des branches de maintenance (une branche pour chacune). Ceci sera utilisé pour fusionner le tronc avec chaque branche de maintenance. (Notez que vous devez utiliser des références externes SVN ou un équivalent pour limiter le nombre de branches de maintenance.)

Faites tout votre refactoring dans le coffre et fusionnez-le dans les branches des branches de maintenance. Lorsque vous relâchez ou pensez que le coffre est stable, fusionnez ces branches des versions de maintenance dans leurs branches respectives. Celles-ci peuvent à leur tour être fusionnées dans le coffre.

En fait, chaque branche de maintenance devient une "sous-ligne réseau".

Notez que ce scénario met en évidence le compromis entre la maintenance future et la maintenance initiale. Plus vous avez de branches et de différences dans votre code, plus la maintenance initiale est importante. La bonne partie est que la maintenance incrémentale est beaucoup plus facile.

Je ne peux que faire écho à ce que d'autres ont dit, tout en soulignant la douleur réelle que peut représenter une file d'attente de patchs.

Si vous avez une fenêtre de fusion prédéfinie (et revêtue de fer), vous ne devriez avoir que deux semaines d'enfer à gérer.

Je pense que votre meilleure option est de procéder à un refactoring itératif . Au lieu de faire tout le refactoring en un seul coup sur une branche privée, faites-le étape par étape. Apportez quelques modifications à la branche puis, lorsque vous savez qu'elles sont stables, fusionnez-les dans le coffre. Les développeurs travaillant dans d’autres branches seraient tenus de maintenir en permanence leur succursale à jour avec le coffre.

Fusionner très souvent un petit ensemble de modifications sera beaucoup moins efficace que de fusionner de grandes branches très différentes. Plus vous fusionnez, moins vous aurez de travail à faire.

Dans notre projet, nous ne corrigeons pas principalement les modifications apportées aux branches de maintenance des versions. S'il y a un bug et

  1. cela se produit à la fois dans le coffre et dans la branche principale, nous le corrigeons dans le coffre, puis nous fusionnons la modification dans la branche de maintenance (ce qui peut se produire proprement ou demander davantage de travail, auquel cas nous décidons si Ce n’est pas mieux d’avoir corrigé le bogue dans la nouvelle version seulement).
  2. ce n'est que dans la branche maintenance, il y a probablement un roi du correctif dans le coffre et nous allons à la scène numéro un.

Devez-vous disposer du nombre de branches sur lesquelles vous travaillez?

Le travail sur le coffre n'a-t-il commencé que quand il l'a fait parce que le plan de projet prévoyait que la version actuelle serait prête à être expédiée, c'est pourquoi elle a été expédiée?

Avez-vous de nombreuses branches de maintenance parce que les clients refusent de passer à la dernière version pour une raison quelconque? Si c'est le cas, indiquez la raison.

Avez-vous trop d'anciennes versions à cause de l'écart avant la prochaine version principale?

Faites-vous payer les clients qui ne feront pas de mises à jour plus pour la maintenance, car cela vous a coûté plus cher?

Réponse au commentaire:

  

Microsoft prend toujours en charge Windows XP   même si Vista est sorti

Est très vrai, cependant Microsoft ne prend toujours pas en charge Windows XP SP1 même si XP SP3 est désactivé.

Ceci n’est pas en noir et blanc. Même si vous ne pouvez pas arrêter de prendre en charge les anciennes versions, vous pourrez peut-être réduire le nombre d’anciennes versions que vous supportez. Le problème, c’est que Sales / Support aime dire oui, mais que le développement est pénible, vous devez donc engager votre personnel des ventes / support.

Comme le a souligné plusieurs scénarios possibles.

J'ajouterais un cas (2.5) où la fusion manuelle est requise, mais étant donné que vous avez déplacé une méthode loin de son emplacement d'origine, puis appliqué certaines modifications, il devient difficile de fusionner, en particulier si la "base" est Le code a également été modifié dans la section "Maintenance". branche. Ce n’est pas si rare que cela puisse paraître, en fait, déplacer une méthode vers un autre emplacement et appliquer un petit correctif est assez courant.

Nous avons développé un outil appelé Xmerge (fusion croisée) qui constitue un premier pas vers une fusion prenant en compte les refactors. Ce n'est pas encore automatique, mais cela aide à gérer les fusions complexes impliquant du code déplacé. Il est décrit ici et est déjà intégré dans Plastic SCM 2.7.

Nous travaillons sur: la détection automatique des déplacements et la possibilité de "fusionner". vers plusieurs fichiers de destination (vous déplacez le code dans un autre fichier, ce qui est également assez commun).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top