Empêcher les développeurs de s'engager dans la mauvaise branche sur DVCS

12

Le problème

Je suis sur un projet logiciel qui compte une dizaine de développeurs, nous partageons le code source via Mercurial. Nous avons une branche de développement et de production par version. À plusieurs reprises au cours du projet, nous avons eu le code source d'une branche, c'est-à-dire la v1, entrant dans les branches de correctifs et de maintenance pour les versions antérieures du logiciel, c'est-à-dire la v2.

Il en résulte soit du temps passé à sauvegarder le mauvais commit, soit du mauvais code (éventuellement non-QAd) atteignant et déployé dans la mauvaise branche si nous ne remarquons pas que le code est entré dans la mauvaise branche.

Notre conception / méthode de branche et fusion

               v1-test   v1-patch1   v1-patch2
               ^---------^-----------^                v1-prod
              /         / \           \
-----------------------/   \           \              v1-dev
              \             \           \
               --------------------------\            v2-dev
                             \       \    \ 
                              ^-------^-------------  v2-prod
                              v2-test v2-patch1      

Par conséquent, nous travaillerons sur une branche de développement de versions, jusqu'à ce qu'elle soit considérée comme prête , branchez-la pour une seule branche de test / UAT / Production, où toutes les versions et la maintenance seront effectuées. Les balises sont utilisées pour créer des versions de cette branche. Pendant que la v1 est en cours de test, une branche aura été créée pour la v2 et les développeurs commenceront à travailler sur de nouvelles fonctionnalités.

Ce qui a tendance à se produire, c'est qu'un développeur engage le travail dû à la branche v2-dev dans v1-dev ou v1-prod, ou pire, il fusionne v2-dev dans v1-prod (ou des erreurs similaires).

Nous disons à la plupart des développeurs de ne pas accéder aux branches -prod , mais le code se faufile toujours. Un groupe de développeurs plus expérimentés `s'occupe 'de la branche -prod.

Il convient de noter que même si la v2 vient de commencer le développement, il peut y avoir des correctifs assez lourds dans la v1 pour résoudre les problèmes. C'est-à-dire que v1 n'obtient pas seulement le petit patch étrange.

Ce que nous avons essayé jusqu'à présent

  • Avoir une branche -prod séparée, avec des portiers. Une branche -prod devrait déclencher des avertissements par son nom et la plupart des développeurs n'ont pas besoin d'être dans cette branche. Cela n'a pas vraiment réduit le problème.
  • Sensibilisation de ce problème aux développeurs, pour essayer de les rendre plus vigilants. Encore une fois, cela n'a pas été un grand succès.

Raisons possibles que je vois pour les développeurs s'engageant dans la mauvaise branche

  • Une conception de branche trop complexe
  • Avoir un développement actif dans plusieurs branches en parallèle. (Le projet présente des symptômes de l'utilisation du modèle d'avalanche .)
  • Les développeurs ne comprennent pas assez bien le DVCS

Questions que j'ai lues qui étaient quelque peu pertinentes

J'ai lu cette question sur ne pas s'engager dans la mauvaise branche et je pense que les réponses concernant les indices visuels peuvent être utiles. Cependant, je ne suis pas entièrement convaincu que les problèmes que nous rencontrons ne sont pas les symptômes d'un problème plus fondamental.

Avec les indices visuels, nous pouvons les intégrer facilement dans la ligne de commande, mais environ la moitié de l'équipe utilise eclipse, je ne sais pas comment incorporer les indices visuels.

Question

Quelles méthodes, sous forme de logiciel, de gestion de projet ou de gouvernance, pouvons-nous utiliser pour réduire (idéalement arrêter) les engagements dans la mauvaise branche en prenant notre temps ou en salissant notre code déployé?

Un commentaire spécifique sur les raisons qui, selon moi, peuvent contribuer, comme indiqué ci-dessus, serait apprécié, mais cela ne devrait pas limiter votre réponse.

imp25
la source
16
Vous essayez de trouver une solution technique à un problème social. Si vous pensez que le problème est qu'ils ne comprennent pas le DVCS, passez du temps à former vos employés - cela sera payant à long terme si vous devez constamment perdre du temps à corriger de mauvaises fusions / validations. Si vous pensez que le problème est qu'ils sont bâclés et ne se soucient pas de leur travail, c'est un problème de gestion.
Sean McSomething, du
C'est en partie un problème de gestion, mais c'est aussi un problème d'outil pour permettre aux développeurs de faire des choix sensés.
Michael Shaw

Réponses:

22

Le problème est que vous changez la signification d'une branche au cours du processus.

Au départ, la v1 devbranche est en développement. Toutes les nouvelles fonctionnalités y vont. À un moment donné dans le futur, il devient une branche de maintenance pour la v1 releasebranche. C'est le noeud du problème.

Ce n'est pas que les développeurs sont bâclés, c'est que les autorisations et les rôles de la branche sont bâclés et sujets à changement.

Ce que vous devez faire, c'est définir le rôle de chaque branche et maintenir ce rôle. Si le rôle change, branchez-vous.

Par exemple:

 developer
  commits    |   |  |   |    |     |   |     |
             v   v  v   v    v     v   v     v
 dev  +--+---------------------+------------------->
         |           ^    ^    |           ^    ^
         |           |    |    |           |    |
 v1      +----+------+----+    |           |    |
           prod  patches       |           |    |
                               |           |    |
                               |           |    |
 v2                            +-----+-----+----+
                                  prod  patches

Dans ce modèle, les développeurs s'engagent toujours à dev. Si vous créez un correctif, vous archivez le correctif dans la branche de cette version (ou mieux encore, branchez la branche de version pour un correctif, puis fusionnez-le à nouveau dans la branche de version).

Un article que vous devriez lire (et c'est probablement un euphémisme pour «devrait») est Advanced SCM Branching Strategies par Stephen Vance.

Dans cet article, je définis d'abord la ramification dans un sens général. Je discute ensuite de diverses stratégies de ramification, en commençant par l'évident et en passant à plusieurs qui sont plus appropriées pour des efforts de développement plus importants. En cours de route, je discute des avantages et des inconvénients de chaque stratégie, en les utilisant pour motiver les changements qui composent les stratégies les plus complexes ...

Dans cet article, il identifie cinq rôles que les succursales peuvent avoir. Parfois, une branche peut remplir deux rôles et les rôles n'ont pas nécessairement besoin d'une nouvelle branche tant que les politiques de rôle ne changent pas de branche moyenne (vous verrez parfois la mention de "branche sur une politique incompatible").

Ces rôles sont:

  1. Mainline. C'est de là que sont faites les branches. Toujours se ramifier à partir de la ligne principale facilite les fusions car les deux branches auront un ancêtre commun qui n'est pas branche sur branche sur branches.
  2. Développement. C'est là que les développeurs archivent le code. On peut avoir plusieurs branches de développement pour isoler les changements à haut risque de ceux qui sont routiniers et banals.
  3. Entretien. Correction de bugs sur un environnement de production existant.
  4. Accumulation. Lors de la fusion de deux branches, on peut ne pas vouloir risquer de déstabiliser la ligne principale. Alors branchez la ligne principale, fusionnez les branches dans l'accumulateur et fusionnez à nouveau sur la ligne principale une fois que les choses sont réglées.
  5. Emballage. L'emballage d'une version se produit dans les branches de l'emballage. Cela devient souvent la version et sert à isoler l'effort de version du développement. Voir Comment gérer les validations indésirables qui interrompent les versions de versions de longue durée? pour un exemple de cas où l'emballage empiète sur le développement.

Dans votre exemple, vous avez une ligne principale en cascade (c'est un problème - cela rend les fusions plus difficiles - que se passe-t-il si vous voulez fusionner un correctif pour v1 en v2 et v3?), Une branche de développement qui devient une branche de maintenance ( changement de politique, c'est un problème).

Ok, vous dites, c'est super, mais cela a été écrit pour perforce qui est un VCS centralisé - j'utilise DVCS.

Regardons le modèle git-flow et voyons comment il s'applique.

La branche principale (bleue) est la branche de publication - pour le balisage. Ce n'est pas la ligne principale. La ligne principale est en fait la branche de développement (jaune). Les branches de libération (vertes) sont le rôle de l'emballage. Le développement à faible risque se produit dans la ligne principale, le développement à haut risque se produit dans les branches caractéristiques (rose). Dans ce modèle, l'accumulation se fait dans la branche develop. La maintenance est considérée comme un «hot fix» en rouge.

Bien que les stratégies de rôle ne correspondent pas exactement (chaque produit a son propre cycle de vie légèrement différent), elles le sont.

Cela devrait simplifier votre politique de branchement et la rendre plus facile pour toutes les personnes impliquées.

Communauté
la source
+1 Excellente réponse technique, pourrait fonctionner s'il ne la documente pas, probablement pas. Il est peu probable que le problème soit entièrement résolu à moins que la stratagie de branchement ne soit documentée avec des procédures claires.
mattnz
1
@mattnz Il existe des modèles de branchement plus avancés (ghads, je vais utiliser le mot). Cependant, «tout le monde s'engage à toujours développer» et «quand vous êtes prêt, branchez une version de dev» devrait vous permettre d'obtenir 90% de la solution. Ensuite, les seuls cas étranges sont le «travail sur un correctif», puis son «Je sais que je fais cela sur une ancienne version, passez à cette branche».
1
J'ai accepté cette réponse car elle constituera la base des changements que nous allons apporter à notre SCM. Les liens avec les stratégies de branchement SCM avancées et le modèle git-flow ont été particulièrement appréciés. Nous essaierons également d'investir dans la formation pour permettre à nos développeurs de mieux comprendre ce qu'ils font avec HG.
imp25
@ imp25 vous pouvez trouver hg-flow utile pour le côté hg plutôt que pour git.
@ imp25 (et quelques questions et réponses StackOverflow sur hgflow - stackoverflow.com/questions/14011921/… stackoverflow.com/questions/13021807/… )
3

Bien que vous ayez essayé d'utiliser une branche -prod distincte avec les gatekeepers, il semble que le référentiel soit utilisé pour effectuer les builds de production. Si les builds de production n'étaient effectués qu'à partir d'un référentiel de production, accessible en écriture uniquement par son gatekeeper, les développeurs ne pourraient pas y pousser. Cela met une charge sur le gardien, qui ne pousserait au dépôt de production qu'après examen. Bien sûr, les gens pourraient toujours se retirer du dépôt de production en cas de besoin.

Au fur et à mesure que les gens acquièrent de l'expérience, ils devraient être tournés à travers le rôle de gardien, pour acquérir la compréhension ou les soins plus profonds qui semblent manquer.

Et en règle générale, appliquez le rasoir d'Occam: toute la structure du référentiel doit être aussi simple que possible pour faire son travail.

Voir aussi le commentaire de Sean.

andy256
la source
2

Il est possible que les développeurs n'obtiennent tout simplement pas assez bien le DVCS, mais je pense qu'il est beaucoup plus probable que vous en ayez simplement trop, et les développeurs ne peuvent pas suivre ce qu'ils font d'un moment à l'autre. Ils oublient dans quelle branche ils sont censés travailler et leurs changements se retrouvent au mauvais endroit.

Je dirais que vous avez un problème avec le fait que tout le monde travaille régulièrement dans toutes ces succursales.

La suggestion de @ andy256 d'un référentiel séparé pour prod serait certainement utile, mais vous devrez peut-être envisager de répartir le travail différemment, ou peut-être d'organiser les choses de sorte qu'aucun développeur ne travaille sur plus d'une branche au cours d'une semaine donnée.

Michael Kohne
la source
1

Il semble que vous ayez identifié l'un de mes principaux ours de bogue. La majorité des outils de contrôle de source sont exactement cela, des outils de contrôle de source. Ils permettent à un tas de développeurs de travailler sur le même répertoire source, apportant des modifications et gérant les conflits. Il y a eu quelques bords rugueux le long du chemin, mais cvs, subversion, git, mercural, etc.

Ensuite, vous avez l'étape suivante, lorsque vous devez stabiliser le code pour la publication, et que vous introduisez la ramification. C'est là que les outils commencent à faire défaut aux développeurs. Les outils sont capables de créer la branche, et même d'identifier les ensembles de changements qui se sont produits sur les branches après leur branchement, mais ce n'est pas le problème auquel vous êtes confronté.

Les outils sont vraiment médiocres pour sélectionner quels changements doivent être copiés dans d'autres branches et quand cela doit se produire. Git-flow tente de résoudre ce problème en créant une stratégie de branchement qui signifie que lorsque les branches sont fusionnées, toutes ses modifications sont fusionnées, puis oblige le programmeur à faire des choix judicieux sur le moment et les branches qui sont fusionnées.

Sur un référentiel unique où tous les développeurs travaillent sur un projet qui a un seul thread de version, git flow résout le problème, mais la vie n'est pas aussi simple pour de nombreuses entreprises.

L'environnement complexe est l'endroit où vous avez plusieurs équipes responsables de différents aspects de la solution totale, effectuant des versions internes à d'autres équipes. git-flow n'est tout simplement pas capable de résoudre ce genre de problème.

La seule façon dont j'ai vu ce travail, c'est si chaque équipe est responsable de la définition de leurs versions et du contrôle du changement de leurs dépendances. Tout simplement parce que l'équipe A a publié la version 1.3, l'équipe B ne commence à utiliser la version 1.3 de l'équipe A que lorsque l'équipe B le souhaite.

En effet, une équipe de développeurs définit les groupes de modifications à déplacer, et les développeurs qui reçoivent les modifications définissent quand ils reçoivent le groupe de modifications.

Le seul outil de contrôle de source que j'ai vu qui offre vraiment cela est exact - et même alors, la plupart de vos développeurs s'en plaindront parce que l'interface graphique est trop déroutante pour eux, et elle ne se comporte pas comme une subversion ...

Michael Shaw
la source