J'aime assez l'idée du workflow basé sur les fonctionnalités dans Git: utiliser des branches de fonctionnalités pour prendre en charge le développement parallèle.
Dans un flux de travail basé sur les fonctionnalités, je développerais mes tâches dans une branche de fonctionnalité (hors maître), et je rebaserais souvent à partir du maître pour éviter les conflits potentiels. En cas de collaboration, je pousserai/tirerez la branche de fonctionnalité vers la télécommande. Lorsque je suis prêt à intégrer à master, j'ouvre une demande de pull de ma branche de fonctionnalité à master, de sorte que les pull-demandes soient examinées par les pairs et automatiquement évaluées pour savoir si la pull-request (la fusion de ma branche de fonctionnalité en master) passe la construction et les tests unitaires. Si la pull-request est "verte", ma branche de fonctionnalité est automatiquement fusionnée avec master.
Je trouve que le flux de travail susmentionné est correct. Cependant, dans certaines publications sur Internet, ils préconisent un "développement basé sur le tronc" (par exemple 1 , 2 ).
En ce qui me concerne, le développement basé sur les troncs n'encourage pas le développement dans des branches de fonctionnalités distinctes, mais tous les développeurs deviennent des maîtres. Ce modèle encourage les développeurs à s'intégrer quotidiennement (pratique CI de Martin Fowler) au maître pour éviter les conflits (en revanche, ce que je ferais serait de rebaser ma branche de fonctionnalité sur le maître).
Je me demandais quels avantages ce modèle aurait par rapport au modèle basé sur les fonctionnalités. J'ai plusieurs doutes avec le modèle basé sur le coffre:
Comment procéder à l'examen du code? Dans le modèle basé sur les fonctionnalités, c'est facile: dans la branche des fonctionnalités. Dans le modèle basé sur les troncs, puisque tous les commits sont publiés dans master, comment puis-je les faire réviser? En fait, si je résous des conflits lors de la fusion avec master, ces commits ne sembleraient-ils pas être revus (je ne voudrais pas ça)?
Comment deux développeurs pourraient-ils collaborer sur la même fonctionnalité? Dans le modèle basé sur les fonctionnalités, les deux fonctionneraient sur la branche de fonctionnalité. Dans le modèle basé sur les troncs, tous les développeurs collaboreraient à "toutes les fonctionnalités" (d'une manière ou d'une autre). Droite?
Je crois que le modèle basé sur le tronc a été "créé" pour éviter le problème des branches de fonctionnalités à longue durée de vie qui sont leur enfer potentiel de conflit lors de la fusion avec la ligne principale. Cependant, si les branches de fonctionnalités sont de courte durée et si elles sont souvent rebasées à partir de la ligne principale, quel est le problème alors?
Merci :-)
Votre référence 1 discute déjà de certains points sur la révision de code. Cette réponse est principalement basée sur mon expérience au travail avec l'outil Gerrit et le workflow basé sur les troncs.
- Comment procéder à l'examen du code? Dans le modèle basé sur les fonctionnalités, c'est facile: dans la branche des fonctionnalités. Dans le modèle basé sur les troncs, puisque tous les commits sont publiés dans master, comment puis-je les faire réviser? En fait, si je résous des conflits lors de la fusion avec master, ces commits ne sembleraient-ils pas être revus (je ne voudrais pas ça)?
La révision du code dans le flux de travail basé sur les troncs devrait idéalement être effectuée avant que les validations ne s'intègrent dans le maître. Manuellement, les développeurs poussent leurs validations vers une branche de fonctionnalité temporaire et, une fois approuvés, rebasent ces validations dans master et les poussent (les écrasant éventuellement en une seule validation).
Gerrit automatise ce processus. Lorsque vous transférez un commit vers Gerrit, il crée un ensemble temporaire (presque invisible) de branches pour maintenir le commit en cours de révision. Au cours de la révision, toute correction apportée est modifiée dans l'engagement en cours de révision et renvoyée à Gerrit. Une fois approuvés, les commits sont intégrés dans master de manière atomique (l'utilisateur peut choisir la manière parmi les options comme rebase, cherry-pick et merge).
Gerrit est mieux utilisé pour la révision de code dans un flux de travail basé sur les troncs, car il promeut la révision validation par validation et les validations poussées n'apparaissent dans le maître qu'après avoir passé la révision (les corrections sont faites comme des modifications, donc les validations "incorrectes" ne vont jamais au maître ).
- Comment deux développeurs pourraient-ils collaborer sur la même fonctionnalité? Dans le modèle basé sur les fonctionnalités, les deux fonctionneraient sur la branche de fonctionnalité. Dans le modèle basé sur les troncs, tous les développeurs collaboreraient à "toutes les fonctionnalités" (d'une manière ou d'une autre). Droite?
Droite. Comme toutes les fonctionnalités sont développées dans la même branche, tous les développeurs s'engagent sur cette même branche. La révision du code (et l'intégration continue) donnera une certaine assurance que cette branche est toujours suffisamment stable (au moins pour le développement, sinon pour la production).
L'inconvénient est que les validations de différentes fonctionnalités complexes sont entrelacées dans le journal - l'ajout de numéros d'un système de suivi des problèmes aide beaucoup. Cependant, écraser les validations après la révision du code ou utiliser Gerrit (qui force la validation par validation, et non branche par branche), l'expérience a montré que la plupart des fonctionnalités ne sont qu'une validation unique (équivalente à la validation de fusion dans un workflow basé sur les fonctionnalités).
- Je crois que le modèle basé sur le tronc a été "créé" pour éviter le problème des branches de fonctionnalités à longue durée de vie qui sont leur enfer potentiel de conflit lors de la fusion avec la ligne principale. Cependant, si les branches de fonctionnalités sont de courte durée et si elles sont souvent rebasées à partir de la ligne principale, quel est le problème alors?
Le problème se pose lorsqu'une branche de fonction à longue durée de vie est intégrée au maître. Ensuite, chaque autre branche de fonctionnalité longue durée devra intégrer toutes les modifications de cette fonctionnalité terminée en une seule fois. C'est encore pire si les branches des fonctionnalités finies et de rebasage ont effectué un refactoring.
- Dans l'ensemble, quels avantages peuvent offrir le tronc basé sur le flux de travail basé sur les fonctionnalités?
Les plus grands avantages que j'ai vus sont:
Cependant, je voudrais recommander à nouveau d'utiliser Gerrit (ou un outil similaire) pour automatiser le processus de révision de code dans un flux de travail basé sur les troncs au lieu d'utiliser un outil conçu pour examiner les demandes d'extraction (flux de travail basé sur les fonctionnalités).
Comme vous, les développeurs de Debitoor avaient des doutes quant au développement basé sur les troncs. Pour surmonter ces problèmes, ils ont trouvé une solution innovante qu'ils appellent Koritsu.
Kōritsu est le mot japonais pour l'efficacité, et l'approche est conçue pour garantir que les développeurs ne s'interrompent ou ne se bloquent jamais. Koritsu est assez similaire aux branches de fonctionnalités de courte durée, sauf qu'il permet aux branches de fonctionnalités de vivre jusqu'à une semaine et de déployer automatiquement chaque fusion sur le tronc.
Debitoor utilise Koritsu depuis plusieurs années pour notre site Web et le développement mobile. Pour nous, cela s'est bien passé sans aucun problème. Une chose est sûre: nous ne revenons pas au développement basé sur le tronc
Notre CTO Allan a écrit un article sur les problèmes avec le développement basé sur le tronc et comment Koristu est conçu pour les résoudre. L'article comprend également une vidéo d'un discours qu'il a donné sur sa solution innovante pour le développement basé sur le tronc, qui explique tout plus en détail.