Je suis encore un autre utilisateur de Subversion qui a du mal à me rééduquer dans le Tao du contrôle de version distribué.
Lorsque j'utilisais Subversion, j'étais un grand fan de l'approche des projets mineurs et, avec la plupart de mes anciens employeurs, nous structurions nos succursales de référentiel; balises et tronc comme suit:
branches-+
+-personal-+
| +-alice-+
| | +-shinyNewFeature
| | +-AUTOMATED-+
| | +-shinyNewFeature
| +-bob-+
| +-AUTOMATED-+
| +-bespokeCustomerProject
+-project-+
+-shinyNewFeature
+-fixStinkyBug
tags-+
+-m20110401_releaseCandidate_0_1
+-m20110505_release_0_1
+-m20110602_milestone
trunk
Dans l'arborescence source proprement dite, nous utiliserions (quelque chose comme) la structure suivante:
(src)-+
+-developmentAutomation-+
| +-testAutomation
| +-deploymentAutomation
| +-docGeneration
| +-staticAnalysis
| +-systemTest
| +-performanceMeasurement
| +-configurationManagement
| +-utilities
+-libraries-+
| +-log-+
| | +-build
| | +-doc
| | +-test
| +-statistics-+
| | +-build
| | +-doc
| | +-test
| +-charting-+
| | +-build
| | +-doc
| | +-test
| +-distributedComputing-+
| | +-build
| | +-doc
| | +-test
| +-widgets-+
| +-build
| +-doc
| +-test
+-productLines-+
| +-flagshipProduct-+
| | +-coolFeature
| | +-anotherCoolFeature
| | +-build
| | +-doc
| | +-test
| +-coolNewProduct
+-project-+
+-bigImportantCustomer-+
| +-bespokeProjectOne
| +-bespokeProjectTwo
+-anotherImportantCustomer-+
+-anotherBespokeProject
L'idée était (et est toujours) d'utiliser la structure du référentiel pour aider à structurer la communication entre l'équipe d'ingénierie; la partie client de l'entreprise et divers autres intervenants et experts du domaine.
À savoir: les documents sources qui se trouvent dans l'un des répertoires "projet" ne sont utilisés (et gagnent de l'argent) qu'une seule fois. Les documents qui se trouvent dans l'un des répertoires "productLines" gagnent de l'argent autant de fois qu'un produit de cette ligne particulière est vendu. Les documents qui se trouvent dans l'un des répertoires des "bibliothèques" gagnent de l'argent autant de fois que n'importe lequel des produits qui les utilisent est vendu.
Il rend explicite la notion d'amortissement des coûts et aide à renforcer la prise en charge de la réutilisation des documents source dans toute l'entreprise.
Cela signifie également qu'il existe une structure commune sur laquelle nos outils d'automatisation de construction peuvent fonctionner. (Nos scripts de construction parcourent l'arborescence source à la recherche de dossiers "build" dans lesquels ils trouvent des fichiers de configuration spécifiant comment chaque composant doit être construit; un processus similaire se produit pour la génération et le test de la documentation).
De manière significative, les produits sur lesquels je travaille prennent généralement beaucoup de temps pour exécuter des tests de mesure et de caractérisation des performances; de 20 à 200 heures; générer quelque part entre plusieurs Go et plusieurs To de résultats de test / données intermédiaires traités (qui doivent être stockés et liés à une configuration de système particulière afin que l'amélioration des performances au fil du temps puisse être mesurée). Ce problème fait de la gestion de la configuration une considération importante et impose également une certaine exigence de centralisation, car généralement les ressources de calcul nécessaires pour exécuter les tests de mesure et de caractérisation des performances sont limitées; (un petit groupe de 64-128 cœurs).
Comme une dernière note; le système d'intégration continue sait qu'il doit déclencher une construction; analyse statique; test de fumée et test unitaire exécutés chaque fois que le tronc est modifié, chaque fois qu'une branche "tag" est modifiée, et chaque fois qu'une branche "AUTOMATISÉE" est modifiée. De cette façon, les développeurs individuels peuvent utiliser le système CI avec leurs branches personnelles, une capacité importante, à mon humble avis.
Maintenant, voici ma question: comment puis-je reproduire tout ce qui précède (et l'améliorer, si possible), avec Mercurial.
--Éditer:
Ma réflexion actuelle consiste à utiliser un référentiel Subversion central, à définir la structure globale, mais à autoriser l'utilisation de hg en tant que client afin que les développeurs puissent avoir des référentiels disponibles localement.
Réponses:
La réponse de Spoike est excellente, mais il y a certaines choses que je pense qu'il serait utile d'ajouter qui sont trop grandes pour les commentaires.
Organisation de la succursale
Avec Mercurial, vous pouvez joyeusement ignorer l'ensemble de votre premier organigramme. Comme l'a dit Spoke, chaque référentiel possède son propre ensemble de balises, de branches (nommées et anonymes) et peut être organisé en fonction des besoins de l'entreprise.
Si
bespokeProjectTwo
charting
vous avez besoin d'une version spéciale de la bibliothèque, vous pouvezcharting
créer une branche , ajouter les nouvelles fonctionnalités et l'utiliser dansbespokeProjectTwo
. Les nouvelles installations (et leurs bogues) ne seraient pas utilisées par d'autres projets qui feraient référence à lacharting
bibliothèque standard . Si lacharting
bibliothèque principale avait des bogues corrigés, vous pouvez fusionner ces modifications dans la branche. Si d'autres projets avaient également besoin de ces fonctionnalités, vous pouvez soit faire en sorte que ces projets utilisent la branche spéciale , soit fusionner la branche dans la ligne principale et fermer la branche.De plus, rien ne vous empêche d'avoir une politique pour structurer les noms de succursales afin de fournir des installations spécifiques comme vos succursales AUTOMATION.
Organisation du répertoire
Il n'y a aucune raison pour laquelle vous ne pouvez pas conserver votre répertoire source exactement comme il l'est avec Mercurial. La seule différence est que, alors qu'avec Subversion, vous n'avez qu'un seul
(src)
référentiel monolithique , avec Mercurial, vous feriez mieux de vous diviser en référentiels qui sont logiquement regroupés. De votre arborescence source, j'extrais probablement chacun des éléments suivants en tant que référentiels individuels:Cela permet à tout produit ou projet sur mesure d'utiliser n'importe quelle combinaison de bibliothèques, à n'importe quelle révision. Jetez un œil aux sous-référentiels mercurial pour un moyen facile de gérer les bibliothèques utilisées pour une version donnée d'un produit ou d'un projet.
Workflow
Une alternative au flux de travail suggéré par Spoike (le développeur tire du repo béni, travaille localement, émet une demande de pull et enfin l'intégrateur tire ces changements et les fusionne) serait d'utiliser le système d'intégration continue comme intermédiaire.
Comme précédemment, le développeur se retire du dépôt béni et travaille localement, mais une fois terminé, il se retire du dépôt béni à nouveau et se fusionne avant de passer à un dépôt non béni. Toutes les modifications apportées au référentiel non béni sont ensuite examinées (manuellement ou automatiquement) et déplacées vers le référentiel béni uniquement si elles sont approuvées.
Cela signifie que l'intégrateur a uniquement accepté ou rejeté une modification, pas la fusion. D'après mon expérience, il est presque toujours préférable pour le développeur qui a écrit le code d'effectuer la fusion que pour quelqu'un d'autre de le faire.
Comme suggéré dans le livre mercurial, les crochets peuvent être utilisés pour automatiser cette procédure:
Autres issues
Le problème des grands ensembles de données de test peut également être résolu en plaçant ces données de test dans un sous-référentiel mercurial . Cela empêchera le référentiel de code d'être gonflé de données de test, tout en gardant les données de test sous contrôle de révision.
la source
productLines
ou enbigImportantCustomer
tant que super-référents.D'accord, essayant de répondre simplement à cette question.
Que souhaitez-vous savoir
Première chose que vous devez savoir: Mercurial est un contrôle de version distribué et possède certaines propriétés que vous devez connaître répertoriées ci-dessous.
Le modèle habituel avec lequel les gens travaillent dans DVCS (qui est utilisé dans github et bitbucket) est de le faire semi-centralisé.
Chaque utilisateur a un référentiel public (dans certains partages ou sur un serveur sécurisé) et un référentiel privé (dans leurs propres postes de travail). Ils sont tous deux des clones du référentiel "béni" d'un intégrateur. Chaque fois qu'ils se sentent prêts à publier leur code, ils peuvent transférer les modifications de leur référentiel public. Un intégrateur peut alors choisir les utilisateurs à extraire du code dans le référentiel "béni".
Si l'intégrateur ne peut pas fusionner facilement le code d'un utilisateur, les modifications sont rejetées et il appartient à cet utilisateur particulier de mettre à jour son référentiel et de corriger lui-même la fusion. Ce n'est généralement pas si difficile si vous fusionnez souvent (car c'est moins de code qui doit être fusionné) et généralement cet utilisateur doit savoir ce qui n'a pas fonctionné avec la fusion.
Configuration des référentiels par projet
Ainsi, la configuration habituelle est que pour chaque projet, il y a ce qui suit:
Un référentiel public en lecture seule dont l'intégrateur est responsable. C'est "béni".
C'est-à-dire que tous les utilisateurs peuvent extraire / récupérer du contenu mais n'ont pas accès pour le pousser.
Chaque utilisateur peut avoir son propre clone public du référentiel.
Configuration la plus simple, car placée dans un lecteur de partage (bien que vous puissiez envisager l'hébergement tel que bitbucket). L'intégrateur reçoit les demandes d'extraction des utilisateurs et essaie d'extraire le nouveau code de ces référentiels. Lorsque les fusions sont effectuées sans accroc, elles sont placées dans le référentiel en lecture seule. Sinon, les utilisateurs sont invités à corriger les conflits de fusion qui surviennent en le mettant à jour et en le fusionnant localement.
Chaque utilisateur peut avoir ses propres clones privés du référentiel.
La bonne pratique consiste à se retirer de leur clone public, mais peu importe s'ils tirent de leur public ou de celui de l'intégrateur. Tous les commits sont identifiables de manière unique, donc la fusion des commits que vous avez oublié de récupérer dans le public est relativement facile à corriger (en poussant les modifications du privé vers le public, il obtient automatiquement les changements de l'intégrateur également).
Organisation du code source
Comme pour organiser la source du projet lui-même, vous devez réfléchir. Si un artefact doit être contrôlé par la source, mettez-le en contrôle de source. Personnellement, je n'aime pas l'idée d'archiver des artefacts créés par la génération ou l'exécution (en raison du risque élevé de conflits de fusion sur ces types d'artefacts) tels que les fichiers binaires ou les fichiers journaux.
Vous pouvez également archiver la configuration, à condition qu'ils facilitent le démarrage des développeurs et ne gâchent pas la configuration des versions ou de l'environnement de production / en direct (comme les paramètres du serveur d'application / Web). Cela conduit à l'idée que si la configuration que vous avez empêche sérieusement les développeurs de commencer dans les cinq minutes après avoir extrait le code, il doit être refactorisé. Une autre exigence est qu'il devrait être extrêmement difficile pour les développeurs de gâcher la version ou l'environnement de production / live.
Vous mentionnez que vous disposez de données de test qui doivent être liées à une version du code. Maintenant, c'est un peu plus délicat car les systèmes DVCS tels que Mercurial et Git ont tendance à ralentir lorsque vous enregistrez des données ENORMES. D'après mon expérience, cela devient vraiment insupportable après 5 Go de fichiers binaires (votre kilométrage peut varier, vous devriez donc tester comment cela fonctionne pour vous). Je recommanderais cependant que vous placiez les données générées dans son propre référentiel et que votre système de test les étiquette correctement lors de leur archivage (et / ou créez des fichiers texte pour les mêmes fins de métadonnées).
J'espère que tout cela a du sens. Veuillez commenter ci-dessous si j'ai raté certains détails ou si quelque chose doit être expliqué plus en détail et je vais essayer de le modifier.
la source