Je travaille actuellement sur un projet plus important qui contient malheureusement des fichiers dont les consignes de qualité logicielle n'étaient pas toujours suivies. Cela inclut les gros fichiers (lire 2000-4000 lignes) qui contiennent clairement plusieurs fonctionnalités distinctes.
Maintenant, je veux refactoriser ces gros fichiers en plusieurs petits. Le problème est que, vu leur taille, plusieurs personnes (moi inclus) de différentes branches travaillent sur ces fichiers. Donc, je ne peux pas vraiment me séparer de développement et de refactorisation, car il deviendra difficile de fusionner ces refactorisations avec les changements des autres peuples.
Nous pourrions bien sûr demander à tout le monde de fusionner pour développer, "geler" les fichiers (c'est-à-dire ne plus permettre à personne de les éditer), refactoriser, puis "débloquer". Mais ce n’est pas non plus une bonne chose, car cela obligerait tout le monde à arrêter son travail sur ces fichiers jusqu’à ce que le refactoring soit terminé.
Donc, y a-t-il un moyen de refactoriser, de ne demander à personne d’arrêter de travailler (trop longtemps) ou de fusionner leurs branches de fonctions pour se développer?
Réponses:
Vous avez bien compris qu'il ne s'agissait pas d'un problème technique, mais plutôt social: si vous souhaitez éviter des conflits de fusion excessifs, l'équipe doit collaborer de manière à éviter ces conflits.
Cela fait partie d'un problème plus important avec Git, dans lequel la création de branches est très facile mais la fusion peut encore demander beaucoup d'efforts. Les équipes de développement ont tendance à lancer de nombreuses branches et sont ensuite surprises de la difficulté de les fusionner, peut-être parce qu’elles essaient d’imiter le flux Git sans comprendre son contexte.
La règle générale pour les fusions rapides et faciles est d'empêcher l'accumulation de grandes différences, en particulier que les branches de fonctions doivent être de très courte durée (heures ou jours, pas mois). Une équipe de développement capable d'intégrer rapidement leurs changements verra moins de conflits de fusion. Si du code n'est pas encore prêt pour la production, il peut être possible de l'intégrer mais de le désactiver via un indicateur de fonctionnalité. Dès que le code a été intégré dans votre branche principale, il devient accessible au type de refactoring que vous essayez de faire.
C'est peut-être trop pour votre problème immédiat. Cependant, il est peut-être possible de demander à des collègues de fusionner leurs modifications ayant une incidence sur ce fichier jusqu'à la fin de la semaine afin que vous puissiez effectuer la refactorisation. S'ils attendent plus longtemps, ils devront eux-mêmes faire face aux conflits de fusion. Ce n'est pas impossible, c'est juste un travail évitable.
Vous voudrez peut-être également éviter de briser de larges bandes de code dépendant et effectuer uniquement des modifications compatibles avec les API. Par exemple, si vous souhaitez extraire certaines fonctionnalités dans un module séparé:
Ce processus en plusieurs étapes peut éviter de nombreux conflits de fusion. En particulier, il y aura des conflits uniquement si quelqu'un d'autre modifie également la fonctionnalité que vous avez extraite. Le coût de cette approche est qu’il est beaucoup plus lent que de tout changer en même temps et que vous avez temporairement deux API en double. Ce n’est pas si grave tant que quelque chose d’urgence n’interrompt cette refactorisation, la duplication est oubliée ou dépériorisée, et vous vous retrouvez avec un tas de dettes technologiques.
Mais au final, toute solution nécessitera une coordination avec votre équipe.
la source
Faites la refactorisation par petites étapes. Disons que votre gros fichier a le nom
Foo
:Ajouter un nouveau fichier vide
Bar
et le valider pour "trunk".Trouvez une petite partie du code dans
Foo
laquelle vous pouvez être déplacéBar
. Appliquez le déplacement, mettez à jour à partir du tronc, générez et testez le code, puis validez le "tronc".Répétez l' étape 2 jusqu'à ce que
Foo
etBar
avoir une taille égale (ou quelle que soit la taille que vous préférez)Ainsi, la prochaine fois que vos coéquipiers mettront à jour leurs branches à partir du tronc, ils recevront vos modifications par «petites portions» et pourront les fusionner un par un, ce qui est beaucoup plus facile que de devoir fusionner une division complète en une étape. Il en va de même lorsque, à l'étape 2, vous obtenez un conflit de fusion, car une autre personne a mis à jour la liaison entre les deux.
Cela n'éliminera pas les conflits de fusion ni la nécessité de les résoudre manuellement, mais limitera chaque conflit à une petite zone de code, ce qui est beaucoup plus facile à gérer.
Et bien sûr - communiquer le refactoring dans l'équipe. Informez vos collègues de ce que vous faites pour qu'ils sachent pourquoi ils doivent s'attendre à des conflits de fusion pour le fichier en question.
la source
rerere
option gits est activéeVous envisagez de scinder le fichier en une opération atomique, mais vous pouvez apporter des modifications intermédiaires. Le fichier est devenu petit à petit avec le temps, il peut devenir petit au fil du temps.
Choisissez une pièce qui n'a pas dû changer depuis longtemps (
git blame
peut vous aider) et séparez-la en premier. Obtenez ce changement fusionné dans les branches de chacun, puis choisissez la prochaine partie la plus facile à scinder. Peut-être même que diviser une partie est une étape trop importante et que vous devriez commencer par réorganiser d'abord le fichier volumineux.Si les gens ne fusionnent pas souvent pour se développer, vous devriez l'encourager, puis, après leur fusion, saisissez cette occasion pour séparer les parties qu'ils viennent de modifier. Ou demandez-leur de faire la scission dans le cadre de l'examen de la demande de tir.
L'idée est de progresser lentement vers votre objectif. Vous aurez l'impression que les progrès sont lents, mais vous réaliserez alors que votre code est bien meilleur. Il faut beaucoup de temps pour transformer un paquebot.
la source
Je vais suggérer une solution différente de la normale à ce problème.
Utilisez-le comme un événement de code d'équipe. Demandez à chacun d'inscrire son code dans la mesure du possible, puis aidez les autres qui travaillent encore avec le fichier. Une fois que le code de chaque personne concernée a été enregistré, trouvez une salle de conférence avec un projecteur et travaillez ensemble pour commencer à déplacer des éléments et dans de nouveaux fichiers.
Vous voudrez peut-être fixer un délai précis pour que cela ne soit pas une semaine d'arguments sans fin. Au lieu de cela, il pourrait même s'agir d'un événement hebdomadaire d'une à deux heures jusqu'à ce que vous obteniez ce qui se passe comme il se doit. Peut-être n’avez-vous besoin que d’une à deux heures pour refactoriser le fichier. Vous ne saurez pas jusqu'à ce que vous essayez, probablement.
Cela présente l'avantage de mettre tout le monde sur la même page (sans jeu de mots) lors de la refactorisation, mais cela peut également vous aider à éviter les erreurs et à obtenir l'avis d'autres personnes sur les groupements de méthodes possibles à maintenir, si nécessaire.
Faire cela de cette façon peut être considéré comme une révision de code intégrée, si vous faites ce genre de chose. Cela permet à la quantité appropriée de développeurs de signer votre code dès que vous l'avez enregistré et prêt à être revu. Vous voudrez peut-être quand même qu'ils vérifient le code pour tout ce que vous avez oublié, mais cela contribue grandement à faire en sorte que le processus de révision soit plus court.
Cela peut ne pas fonctionner dans toutes les situations, équipes ou entreprises, car le travail n'est pas distribué de manière à rendre cela facile. Cela peut également être interprété (à tort) comme une utilisation abusive du temps de développement. Ce code de groupe nécessite l’adhésion du responsable ainsi que du refactor lui-même.
Pour aider à vendre cette idée à votre responsable, mentionnez le bit de révision du code ainsi que tout le monde sachant où en sont les choses depuis le début. Empêcher les développeurs de perdre du temps à rechercher une foule de nouveaux fichiers peut être intéressant à éviter. Empêcher les développeurs de savoir où les choses se sont finalement terminées ou "complètement manquantes" est généralement une bonne chose. (Moins il y a de crises, mieux c'est, IMO.)
Une fois que vous obtenez un fichier refactorisé de cette manière, vous pourrez peut-être obtenir plus facilement l'approbation de plusieurs refactors, si cela réussit et est utile.
Cependant vous décidez de faire votre refactor, bonne chance!
la source
master
premier, vous avez au moins tout le monde dans la salle pour vous aider à gérer les fusions dans ces branches.Résoudre ce problème nécessite l'adhésion des autres équipes, car vous essayez de modifier une ressource partagée (le code lui-même). Cela étant dit, je pense qu’il ya un moyen de "s’éloigner" des énormes fichiers monolithiques sans perturber les gens.
Je recommanderais également de ne pas cibler tous les fichiers volumineux en même temps, à moins que le nombre de fichiers volumineux augmente de manière incontrôlable en plus de la taille des fichiers individuels.
Refactoriser de tels fichiers provoque souvent des problèmes inattendus. La première étape consiste à empêcher les gros fichiers d’accumuler des fonctionnalités supplémentaires allant au-delà de ce qui se trouve actuellement dans les branches maître ou de développement .
Je pense que la meilleure façon de procéder consiste à utiliser des crochets de validation qui bloquent certains ajouts aux fichiers volumineux par défaut, mais qui peuvent être remplacés par un commentaire magique dans le message de validation, par exemple
@bigfileok
. Il est important d’être en mesure d’annuler la politique de manière simple, mais traçable. Idéalement, vous devriez pouvoir exécuter le hook de validation localement et indiquer comment remplacer cette erreur particulière dans le message d'erreur lui-même . De plus, cela est juste ma préférence, mais les commentaires magiques non reconnus ou les commentaires magiques supprimant les erreurs qui ne se sont pas réellement déclenchées dans le message de validation doivent constituer un avertissement ou une erreur au moment de la validation, de sorte que vous ne formez pas par inadvertance des personnes à la suppression des points d'ancrage, qu'ils en aient besoin ou non.Le hook de validation peut rechercher de nouvelles classes ou effectuer une autre analyse statique (ad hoc ou non). Vous pouvez également simplement choisir un nombre de lignes ou de caractères supérieur de 10% à celui du fichier et indiquer que le fichier volumineux ne peut pas dépasser la nouvelle limite. Vous pouvez également rejeter des validations individuelles qui agrandissent le fichier volumineux de trop de lignes ou de caractères ou de w / e.
Une fois que le fichier volumineux cesse d’accumuler de nouvelles fonctionnalités, vous pouvez en refactoriser un élément à la fois (et réduire les seuils imposés par les crochets de validation en même temps pour empêcher sa croissance).
Finalement, les gros fichiers seront suffisamment petits pour que les crochets de validation puissent être complètement supprimés.
la source
Attendez jusqu'à la maison. Fractionner le fichier, valider et fusionner en maître.
D'autres personnes devront intégrer les modifications apportées à leurs branches de fonctionnalités le matin, comme pour toute autre modification.
la source