Continuez-vous le développement dans une branche ou dans le coffre? [fermé]


170

Supposons que vous développiez un produit logiciel qui a des versions périodiques. Quelles sont les meilleures pratiques en matière de ramification et de fusion? Découper les branches de publication périodiques vers le public (ou quel que soit votre client), puis poursuivre le développement sur le tronc, ou considérer le tronc comme la version stable, le marquer périodiquement comme une version et faire votre travail expérimental dans les branches. Selon les gens, qu'est-ce que le coffre est considéré comme «or» ou comme «bac à sable»?


3
Vous vous demandez si cela peut être modifié sans svn car il est assez générique pour la gestion du contrôle de code source?
Scott Saad

4
Cela semble être une de ces questions «religieuses».
James McMahon le

@James McMahon - c'est plus qu'il y a vraiment deux meilleures pratiques qui s'excluent mutuellement, mais certaines personnes pensent qu'il n'y en a qu'une. Cela n'aide pas que SO souhaite que vous ayez une réponse correcte.
Ken Liu

Réponses:


151

J'ai essayé les deux méthodes avec une grande application commerciale.

La réponse à la meilleure méthode dépend fortement de votre situation exacte, mais j'écrirai ce que mon expérience globale a montré jusqu'à présent.

La meilleure méthode dans l'ensemble (d'après mon expérience): le coffre doit être toujours stable.

Voici quelques conseils et avantages de cette méthode:

  • Codez chaque tâche (ou ensemble de tâches associé) dans sa propre branche, vous aurez alors la flexibilité de savoir quand vous souhaitez fusionner ces tâches et effectuer une version.
  • Le contrôle qualité doit être effectué sur chaque branche avant qu'elle ne soit fusionnée avec le tronc.
  • En effectuant un contrôle qualité sur chaque branche individuelle, vous saurez exactement ce qui a causé le bogue plus facilement.
  • Cette solution s'adapte à n'importe quel nombre de développeurs.
  • Cette méthode fonctionne car le branchement est une opération presque instantanée dans SVN.
  • Marquez chaque version que vous exécutez.
  • Vous pouvez développer des fonctionnalités que vous ne prévoyez pas de publier pendant un certain temps et décider exactement quand les fusionner.
  • Pour tout travail que vous effectuez, vous pouvez avoir l'avantage de valider votre code. Si vous travaillez uniquement à partir du tronc, vous garderez probablement votre code non validé, et donc non protégé et sans historique automatique.

Si vous essayez de faire le contraire et de faire tout votre développement dans le coffre, vous aurez les problèmes suivants:

  • Problèmes de build constants pour les builds quotidiens
  • Perte de productivité lorsqu'un développeur commet un problème pour toutes les autres personnes sur le projet
  • Cycles de publication plus longs, car vous devez enfin obtenir une version stable
  • Versions moins stables

Vous n'aurez tout simplement pas la flexibilité dont vous avez besoin si vous essayez de maintenir une branche stable et le tronc comme bac à sable de développement. La raison en est que vous ne pouvez pas choisir dans le coffre ce que vous voulez mettre dans cette version stable. Tout serait déjà mélangé dans le coffre.

Le seul cas en particulier que je dirais de faire tout le développement dans le coffre, c'est lorsque vous démarrez un nouveau projet. Il peut y avoir d'autres cas également en fonction de votre situation.


En passant, les systèmes de contrôle de version distribués offrent beaucoup plus de flexibilité et je recommande vivement de passer soit à hg soit à git.


35
Désolé, mais cette réponse est fausse. Tout développement doit se faire dans le coffre. Si vous avez quelque chose à «spike» ou une fonctionnalité «risquée», créez une branche de fonctionnalité. Les branches doivent être maintenues pour chaque version du produit en production, ou s'il existe une seule version, utilisez une branche d'intégration.
Mitch Wheat

52
Je ne prétendais pas que c'était la seule façon, juste que c'était la meilleure. Bien sûr, si vous pensez avoir suffisamment de raisons pour lesquelles vous pensez que je me trompe, vous devriez le publier. Au moins ma réponse est justifiée.
Brian R. Bondy

5
Ceci est problématique, car les développeurs peuvent travailler longtemps sur une branche qui diverge du tronc principal. L'intégration de ces éléments plus tard peut produire de gros maux de tête. Pour moi, il était toujours plus facile de maintenir un coffre à la pointe de la technologie avec des exigences minimales (il faut toujours compiler) et de ramener les choses qui devraient être stabilisées pour une version.
Mnementh le

31
En réponse au message de Mnementh, je pense qu'une bonne solution est qu'un développeur devrait périodiquement fusionner le tronc dans sa branche afin de ne pas s'éloigner trop de l'état du tronc. C'est à chaque développeur de le faire assez souvent pour ne pas avoir un énorme mal de tête de réintégration à tout moment.
RjOllos

8
@Mnementh ce n'est pas une excuse. Les meilleures pratiques et le simple bon sens indiquent que tous les membres de l'équipe devraient mettre à jour leurs branches avec le tronc. Le tronc principal n'est pas censé être parfait ni ce que vous pousserez à la production, il a juste besoin de compiler et c'est pourquoi dans de bons environnements de développement, la plupart des développeurs sont très bons pour s'assurer que cela se produit et si ce n'est pas le cas, le L'équipe a le droit de donner du fil à retordre à cette personne ... également des outils comme le régulateur de vitesse et d'autres configurations de construction continue. Voilà ce qu'est l'intégration continue! Vous avez QA tester vos succursales et non votre tronc principal.
PositiveGuy

66

J'ai travaillé avec les deux techniques et je dirais que développer sur le tronc et dériver des points stables au fur et à mesure des versions est la meilleure façon de procéder.

Ces personnes ci-dessus qui objectent en disant que vous aurez:

  • Problèmes de build constants pour les builds quotidiens
  • Perte de productivité lorsqu'un développeur commet un problème pour toutes les autres personnes sur le projet

n'ont probablement pas utilisé de techniques d'intégration continue.

Il est vrai que si vous n'effectuez pas plusieurs builds de test pendant la journée, disons une fois toutes les heures environ, vous vous exposez à ces problèmes qui étrangleront rapidement le rythme du développement.

Faire plusieurs versions de test au cours de la journée entraîne rapidement des mises à jour de la base de code principale afin que d'autres puissent l'utiliser et vous alerte également pendant la journée si quelqu'un a cassé la version afin de pouvoir la réparer avant de rentrer à la maison.

Comme indiqué, ne découvrir une version cassée que lorsque la compilation nocturne pour exécuter les tests de régression échoue est une pure folie et ralentira rapidement les choses.

Lisez l'article de Martin Fowler sur l' intégration continue . Nous avons déployé notre propre système pour un projet majeur (3 000 kSLOC) sur environ 2 000 lignes de Posix sh.


1
Qu'est-ce que «l'intégration continue» a à voir avec la probabilité qu'une équipe soit en retard sur sa fonctionnalité et retarde tout un cycle de publication? C'est la meilleure façon de faire «pour vous»! Faire plusieurs builds par jour ne résout pas les problèmes potentiels autres que vous savez que cela génère! Vos arguments ne prouvent pas que c'est une meilleure façon (bien que ce soit la façon dont je le fais habituellement aussi).
Jeach

CI est nécessaire pour cette réponse, mais aussi pour celle de Brian.
jyoungdev

2
@Jeach, faire plusieurs builds par jour vous donne l'assurance qu'il se construit afin que vous puissiez exécuter des tests régulièrement, que ce soit de simples tests de fumée pendant la journée ou des tests de régression le soir. Si vous laissez la construction jusqu'à la compilation du soir pour les tests de régression, vous pouvez réinitialiser l'ensemble du projet d'un jour simplement parce que vous ne pouvez pas créer. Cela signifie que tous les développeurs ne pourront pas voir les résultats des tests de régression pour le nouveau code qu'ils ont soumis. Un coût assez élevé, simplement parce que, par exemple, quelqu'un a enregistré un code contenant une erreur de syntaxe.
Rob Wells

et si une fonctionnalité prend 2 mois à construire et une autre prend 6 mois à construire, vous devez utiliser des branches là-bas, tout ne peut pas être vérifié dans le coffre dans de tels cas
Kalpesh Soni

1
@Wolf vous confondez confusion et confusion, les gens créent des produits, tout le monde ne travaille pas pour les devops
Kalpesh Soni

36

J'ai tendance à adopter l'approche «branche de publication». Le coffre est volatil. Une fois que le temps de sortie approche, je créerais une branche de publication, que je traiterais plus prudemment. Quand c'est finalement fait, j'étiqueterais / marquerais l'état du référentiel afin de connaître la version publiée "officielle".

Je comprends qu'il existe d'autres façons de le faire - c'est juste la façon dont je l'ai fait dans le passé.


19

Tous les deux.

Le tronc est utilisé pour la majorité du développement. Mais on s'attend à ce que tous les efforts soient faits pour s'assurer que tout enregistrement dans le coffre ne le cassera pas. (partiellement vérifié par un système de construction et de test automatisé)

Les versions sont conservées dans leur propre répertoire, avec uniquement des corrections de bogues (puis fusionnées dans le coffre).

Toute nouvelle fonctionnalité qui va laisser le tronc dans un état instable ou non fonctionnel est effectué dans sa propre branche distincte, puis fusionné dans le tronc à la fin.


3
Je suis avec vous sur ce point ... les développeurs qui s'en tiennent à une seule méthode tout le temps sont le problème!
Jeach

14

J'aime et j'utilise l'approche décrite par Henrik Kniberg dans Version Control for Multiple Agile Teams . Henrik a fait un excellent travail pour expliquer comment gérer le contrôle de version dans un environnement agile avec plusieurs équipes (fonctionne également pour une seule équipe dans des environnements traditionnels) et il ne sert à rien de le paraphraser donc je posterai simplement la "feuille de triche" (qui s'explique d'elle-même) ci-dessous:

texte alternatif texte alternatif

Je l'aime parce que:

  • C'est simple: vous pouvez l'obtenir à partir de l'image.
  • Cela fonctionne (et évolue) bien sans trop de problèmes de fusion et de conflit.
  • Vous pouvez à tout moment publier des "logiciels fonctionnels" (dans un esprit agile).

Et juste au cas où ce ne serait pas assez explicite: le développement se fait dans "branche (s) de travail", le tronc est utilisé pour le code DONE (libérable). Vérifiez le contrôle de version pour plusieurs équipes agiles pour tous les détails.


Mon expérience personnelle est que cela fonctionne UNIQUEMENT pour les petites équipes, contrairement à votre commentaire «it scale». Au fur et à mesure que les équipes grandissent et que les histoires sont rebasées, toutes les autres équipes dépensent des quantités considérables d'équipe pour faire des fusions. Et sur les très gros projets (nombreux fichiers et KLOC), des problèmes de fusion commencent régulièrement à apparaître, surtout lorsqu'il y a beaucoup de volatilité du code.
Jeach

@Jeach Cela a bien fonctionné pour nous sur un grand projet avec 5 équipes organisées en équipes techniques, même si je ne nie pas que la fusion a un coût.
Pascal Thivent

11

Une bonne référence sur un processus de développement qui maintient le tronc stable et fait tout le travail dans les branches est le système de développement de qualité ultime de Divmod . Un bref résumé:

  • Tout travail effectué doit être associé à un ticket
  • Une nouvelle branche est créée pour chaque ticket où le travail pour ce ticket est effectué
  • Les modifications de cette branche ne sont pas fusionnées dans le tronc principal sans être revues par un autre membre du projet

Ils utilisent SVN pour cela, mais cela pourrait facilement être fait avec l'un des systèmes de contrôle de version distribués.


10

Je pense que votre deuxième approche (par exemple, baliser les versions et faire des choses expérimentales dans les branches, en considérant le tronc stable) est la meilleure approche.

Il doit être clair que les branches héritent de tous les bogues d'un système au moment où il est ramifié: si des correctifs sont appliqués à un tronc, vous devrez passer un par un à toutes les branches si vous maintenez les branches comme une sorte de terminateur de cycle de libération. Si vous avez déjà eu 20 versions et que vous avez découvert un bogue qui remonte à la première, vous devrez réappliquer votre correctif 20 fois.

Les branches sont censées être de véritables bacs à sable, bien que le coffre devra également jouer ce rôle: les balises indiqueront si le code est "or" à ce moment-là, adapté à la publication.


8

Nous développons sur le tronc sauf si les changements sont trop importants, déstabilisants, ou si nous approchons d'une sortie majeure de l'un de nos produits, auquel cas nous créons une branche temporaire. Nous créons également une branche permanente pour chaque version de produit individuelle. J'ai trouvé le document de Microsoft sur les directives de branchement très utile. Le tutoriel d' Eric Sink sur le branchement est également intéressant et souligne que ce qui fonctionne pour Microsoft peut être trop lourd pour certains d'entre nous. C'était dans notre cas, nous utilisons en fait l'approche qu'Eric dit que son équipe utilise.


5

Cela dépend de vos situations. Nous utilisons Perforce et avons généralement plusieurs lignes de développement. Le tronc est considéré comme "or" et tout développement se produit sur des branches qui sont fusionnées avec la ligne principale lorsqu'elles sont suffisamment stables pour s'intégrer. Cela permet de rejeter les fonctionnalités qui ne font pas la coupe et peut fournir une capacité incrémentielle solide au fil du temps que des projets / fonctionnalités indépendants peuvent récupérer.

Il y a un coût d'intégration pour la fusion et le rattrapage de nouvelles fonctionnalités intégrées dans le coffre, mais vous allez quand même souffrir de cette douleur. Le fait que tout le monde se développe sur le tronc ensemble peut conduire à une situation de far west, tandis que la ramification vous permet de mettre à l'échelle et de choisir les points auxquels vous souhaitez prendre les pilules d'intégration amères. Nous sommes actuellement dimensionnés à plus d'une centaine de développeurs sur une douzaine de projets, chacun avec plusieurs versions utilisant les mêmes composants de base, et cela fonctionne plutôt bien.

La beauté de ceci est que vous pouvez le faire de manière récursive: une grande branche de fonctionnalité peut être son propre tronc avec d'autres branches qui se détachent si elle. En outre, les versions finales ont une nouvelle branche pour vous donner un endroit pour effectuer une maintenance stable.


4

Tenter de gérer la maintenance du code de production actuel conformément aux nouveaux développements est au mieux problématique. Afin d'atténuer ces problèmes, le code doit se connecter à une ligne de maintenance une fois que les tests sont terminés et que le code est prêt à être livré. De plus, la ligne principale doit créer une branche pour aider à la stabilisation des versions, pour contenir les efforts de développement expérimental ou pour héberger les efforts de développement dont le cycle de vie s'étend sur plusieurs versions.

Une branche non liée à la maintenance ne devrait être créée qu'en cas de probabilité (ou de certitude) de collisions entre le code qu'il serait difficile de gérer autrement. Si l'agence ne résout pas un problème de logistique, elle en créera un.

Le développement de la version normale se produit dans la ligne principale. Les développeurs vérifient dans et hors de la ligne principale pour le travail de publication normal. Le travail de développement pour les correctifs du code de production actuel doit être dans la branche de cette version, puis fusionné avec la ligne principale une fois que le correctif a réussi les tests et est déployé. Le travail dans les branches autres que la maintenance doit être coordonné au cas par cas.


4

Cela dépend de la taille de votre effort de développement. Plusieurs équipes travaillant en parallèle ne pourront pas travailler efficacement toutes sur le même code (trunk). Si vous n'avez qu'un petit groupe de personnes qui travaille et que votre principale préoccupation est de couper une branche afin que vous puissiez continuer à travailler tout en retournant à la branche pour apporter des corrections de bogues au code de production actuel qui fonctionnerait. C'est une utilisation triviale de la ramification et pas trop lourde.

Si vous avez beaucoup de développement parallèle, vous voudrez avoir des branches pour chacun des efforts, mais cela exigera également plus de discipline: vous assurer que vos branches sont testées et prêtes à fusionner. La planification des fusions afin que deux groupes n'essaient pas de fusionner en même temps, etc.

Certaines branches sont en cours de développement depuis si longtemps que vous devez autoriser les fusions du tronc à la branche afin de réduire le nombre de surprises lors de la fusion finale avec le tronc.

Vous devrez expérimenter si vous avez un grand groupe de développeurs et avoir une idée de ce qui fonctionne dans votre situation. Voici une page de Microsoft qui peut être quelque peu utile: http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx


4

Nous utilisons le tronc pour le développement principal et la branche pour les travaux de maintenance des versions. Cela fonctionne bien. Mais alors les branches ne doivent être utilisées que pour des corrections de bogues, pas de changements majeurs, en particulier du côté de la base de données, nous avons une règle selon laquelle seul un changement de schéma peut se produire sur le tronc principal et jamais dans la branche.


1
Pourquoi la règle de l'absence de changement de base de données dans la branche?
Bjorn Reppen

Nous avons juste la règle car elle facilite la fusion des versions de notre base de données. Cela pourrait être dû au fait que la façon dont nous utilisons le séquençage dans les noms de fichiers de script pour mettre à jour la base de données, je suis sûr que s'il existe une méthode différente, les modifications de la base de données pourraient être modifiées sur la branche.
adriaanp

2

Si vous comptez travailler sur un cycle de publication, grande fonctionnalité, vous vous retrouvez coincé dans une branche. Sinon, nous travaillons dans le coffre et la branche pour chaque version de production au moment de la construction.

Les versions de production précédentes sont alors déplacées vers old_production_ et la version actuelle de la production est toujours uniquement la production. Tout ce que notre serveur de build sait sur la production, c'est comment déployer la branche de production, et nous lançons cette build avec un déclencheur de force.


2

Nous suivons l'approche tronc = courant de développement actuel, branche = version (s). À la livraison au client, nous branchons le coffre et continuons simplement à faire avancer le coffre. Vous devrez décider du nombre de versions que vous êtes prêt à prendre en charge. Plus vous soutenez, plus vous fusionnerez sur les corrections de bogues. Nous essayons de garder nos clients sur pas plus de 2 versions derrière le coffre. (Par exemple, Dev = 1.3, versions prises en charge 1.2 et 1.1).


1

Le tronc est généralement la principale ligne de développement.

Les versions sont ramifiées et souvent des travaux expérimentaux ou majeurs sont effectués sur les branches, puis fusionnés avec le tronc lorsqu'il est prêt à être intégré à la ligne de développement principale.


1

Le coffre doit généralement être votre principale source de développement. Sinon, vous passerez beaucoup de temps à fusionner de nouvelles fonctionnalités. Je l'ai vu faire l'autre manière et cela conduit généralement à beaucoup de maux de tête d'intégration de dernière minute.

Nous étiquetons nos versions afin de pouvoir répondre rapidement aux urgences de production sans distribuer de développement actif.


1

Pour moi, cela dépend du logiciel que j'utilise.

Sous CVS, je travaillais simplement dans "trunk" et je ne taguerais jamais / branche, car c'était vraiment pénible de faire autrement.

Dans SVN, je ferais mes trucs "avant-gardistes" dans le coffre, mais quand il était temps de faire un push de serveur, je devais être étiqueté de manière appropriée.

Je suis récemment passé à git. Maintenant, je constate que je ne travaille jamais dans le coffre. Au lieu de cela, j'utilise une branche sandbox nommée "new-featureename" puis la fusionne dans une branche fixe "current-production". Maintenant que j'y pense, je devrais vraiment créer des branches "release-VERSIONNUMBER" avant de fusionner à nouveau dans "current-production" afin de pouvoir revenir aux anciennes versions stables ...


1

Cela dépend vraiment de la façon dont votre organisation / équipe gère les versions et du SCM que vous utilisez.

  • Si la suite (dans la prochaine version) peut être facilement planifiée, vous feriez mieux de développer dans le coffre. La gestion des succursales prend plus de temps et de ressources. Mais si la suite ne peut pas être planifiée facilement (cela se produit tout le temps dans les grandes organisations), vous finirez probablement par choisir des commits (centaines / milliers) plutôt que des branches (plusieurs ou des dizaines).
  • Avec Git ou Mercurial, la gestion des branches est beaucoup plus facile que les cv et la subversion. J'opterais pour la méthodologie stable des branches tronc / sujet. C'est ce qu'utilise l'équipe git.git. lire: http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
  • Avec Subversion, j'ai d'abord appliqué la méthodologie de développement dans le coffre. Il y avait pas mal de travail en ce qui concerne la date de sortie parce qu'à chaque fois je devais choisir des commits (mon entreprise n'est pas douée pour la planification). Maintenant, je suis en quelque sorte un expert en Subversion et je connais assez bien la gestion des branches dans Subversion, donc je me dirige vers la méthodologie stable des branches tronc / sujet. Cela fonctionne beaucoup mieux qu'avant. J'essaye maintenant le fonctionnement de l'équipe git.git, bien que nous nous en tiendrons probablement à Subversion.

1

Voici le design SVN que je préfère:

  • racine
    • développement
      • branches
        • caractéristique1
        • caractéristique2
        • ...
      • tronc
    • bêta
      • Mots clés
      • tronc
    • Libération
      • Mots clés
      • tronc

Tout le travail est effectué à partir du développement / du tronc, à l'exception des fonctionnalités majeures qui nécessitent sa propre branche. Une fois le travail testé par rapport au développement / tronc, nous fusionnons les problèmes testés dans bêta / tronc. Si nécessaire, le code est testé sur le serveur bêta. Lorsque nous sommes prêts à déployer certains changements, nous fusionnons simplement les révisions appropriées dans release / trunk et déployons.

Les balises peuvent être faites dans la branche bêta ou la branche de publication afin que nous puissions garder une trace de la version spécifique pour la version bêta et la version.

Cette conception permet une grande flexibilité. Cela nous permet également de laisser facilement des révisions dans beta / trunk tout en fusionnant d'autres pour release / trunk si certaines révisions n'ont pas réussi les tests en beta.


0

La méthode que nous utilisons est l'approche Perforce, qui est longuement discutée dans le grand livre de Laura Wingerd:

http://oreilly.com/catalog/9780596101855/index.html

Bien que le livre soit centré sur la force (Wingerd est un chef de produit Perforce), les concepts peuvent être appliqués à tout ou partie des VCS.

L'approche (et la plateforme) de force nous a très bien servi. Il est utilisé dans de nombreuses entreprises (google, Intuit et, j'ai entendu dire, Microsoft Windows lui-même).

Le livre vaut bien la lecture.



0

Il n'y a pas de réponse unique pour la question de la convention de subversion à mon humble avis.

Cela dépend vraiment de la dynamique du projet et de l'entreprise qui l'utilise. Dans un environnement au rythme très rapide, lorsqu'une version peut se produire aussi souvent que tous les quelques jours, si vous essayez d'étiqueter et de créer une branche religieusement, vous vous retrouverez avec un référentiel ingérable. Dans un tel environnement, l'approche de la succursale en cas de besoin créerait un environnement beaucoup plus maintenable.

De plus, d'après mon expérience, il est extrêmement facile, d'un point de vue purement administratif, de basculer entre les méthodologies SVN lorsque vous le souhaitez.

Les deux approches que j'ai connues pour fonctionner le mieux sont la branche-quand-nécessaire, et la branche-chaque-tâche. Ce sont, bien sûr, en quelque sorte exactement le contraire les uns des autres. Comme je l'ai dit, tout dépend de la dynamique du projet.


-1

@Brian R. Bondy: Veuillez noter que ce n'est pas une solution une fois que votre équipe atteint un certain nombre de personnes / tâches traitées en parallèle sur le projet.

Une fois qu'un département QA est impliqué dans la qualité, les efforts nécessaires pour fournir une installation par succursale en cours sont tout simplement trop élevés. Pensez SOA / Clients / Serveurs / WebServices / Bases de données qui doivent tous être fournis par branche .

Cette solution manque également d'étape d'intégration.


Nous avons plusieurs QA impliqués dans notre équipe. Ils testent chaque fonctionnalité à partir d'un programme d'installation complet construit à partir de la branche avant sa fusion.
Brian R. Bondy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.