Supposons (pour simplifier) que nous avons une application avec client et serveur; existe-t-il une meilleure idée d'utiliser un référentiel pour les deux ou une paire de référentiels distincts?
Les mélanger facilitera probablement le suivi des changements corrélés et maintiendra les branches corrélées (c'est-à-dire l'évolution du protocole), mais d'un autre côté, le développement individuel sera plus encombré ...
Réponses:
Si vous utilisez git ou mercurial , vous voudrez peut-être regarder les sous - modules ou les sous - dépôts .
Le client, le serveur et leurs fichiers d'interface seraient dans leurs propres référentiels, mais seraient liés ensemble au niveau du super-référentiel . Cela vous permettrait d'effectuer une seule vérification au niveau supérieur et /
git
ou dehg
vérifier la validation appropriée de chacun des sous-modules / sous-dépôts.En ne s'engageant dans le super-référentiel que lorsque le client et le serveur étaient appropriés l'un à l'autre, le super-référentiel ne vous donnerait que la possibilité de vérifier un système fonctionnel - vous n'essaieriez donc jamais d'exécuter le nouveau client sur un ancien serveur ou vice-versa.
Les sous-modules / sous-dépôts vous offrent tous les avantages d'utiliser des référentiels séparés, ainsi que les avantages d'un référentiel monolithique unique, au détriment d'un peu plus de complexité.
Cette réponse n'est pas destinée à plaider
git
ou parhg
rapport à d'autres SCM, il se trouve simplement que je ne connais ces SCM que suffisamment bien pour savoir que cette option existe. Je ne comprends pas commentsvn
fonctionnent les externes par exemple.la source
Séparé!
En fait, j'aurais probablement trois référentiels, un pour le client et les bibliothèques client uniquement correspondantes, un pour le serveur (et les bibliothèques correspondantes) et un pour les bibliothèques partagées (incorporant les interfaces API qui exposent la fonctionnalité entre les deux , plus tout autre code partagé). Je pense que c'est vraiment la clé, le code partagé devrait aller dans un référentiel séparé. De cette façon, vous pouvez vous assurer que l'interopérabilité entre votre client et votre serveur est toujours à la même version ET est isolée de la conception de chacun de ses consommateurs.
Évidemment, cela n'est pas toujours possible, selon le cadre de communication particulier que vous utilisez, mais il y a probablement du code partagé qui dicte le format des objets de transfert de données ou les étapes de la négociation dans votre protocole personnalisé (ou un autre exemple) .
En supposant que vous avez une intégration continue et une configuration d'AQ assez décentes (une hypothèse assez large, d'après mon expérience, mais je vais néanmoins la faire. Si vous n'avez pas de service d'assurance qualité, vous devriez au moins obtenir un CI), vous ne devriez pas pas besoin d'utiliser le modèle de repo unique comme défense contre d'éventuelles erreurs de correspondance de code, soit votre serveur CI signalera l'interopérabilité de la bibliothèque, soit votre équipe QA détectera les erreurs d'exécution (ou, mieux encore, vos tests unitaires le feront).
Les avantages des référentiels fractionnés résident dans la possibilité de versionner séparément des parties distinctes d'un système. Vous voulez prendre une copie du serveur de la semaine dernière et l'exécuter avec le client de cette semaine, pour essayer de verrouiller la racine d'un problème de performances? Pas de soucis.
la source
Dans Mercurial , ce schéma peut être utilisé, en utilisant
->
pour désigner la relation subrepo:Le produit a un sous-client, un serveur. Chacun de ces éléments a ses composants en tant que sous-dépôts, éventuellement au moins un sous-référentiel partagé entre les deux.
Le balisage devrait probablement se faire sur les deux premiers niveaux, pas en dessous.
Les validations sont effectuées au niveau des composants, les superpositions suivent efficacement les branches nommées et les versions du produit. Les branches / signets nommés sont généralement meilleurs que les branches clones pour la convivialité (c'est-à-dire la formabilité) et la compatibilité avec les sous-dépôts.
hg tend vers l'hypothèse que les superpositions sont le produit et les validations sont effectuées au niveau supérieur, mais cela ne fonctionne pas particulièrement bien lorsque plusieurs produits utilisent les mêmes composants. :-)
Je ne pense pas que ce schéma changera beaucoup s'il est passé à git, mais je ne l'ai pas encore essayé dans git.
la source
Il s'agit d'un problème de gestion de configuration, pas d'un problème de contrôle de révision. Comme toujours, un programmeur utilise un tournevis pour enfoncer un clou. Déterminez comment vous allez gérer vos configurations, le contrôle de révision prendra soin de lui-même.
la source
L' approche la plus simple consiste à utiliser un référentiel unique, donc à moins que vous n'aimiez la complexité pour la complexité, cela devrait être le choix par défaut en l'absence d'arguments convaincants.
Le développement client et serveur sera-t-il assuré par différentes organisations? Y aura-t-il plusieurs implémentations du client (ou serveur)? Le client open source et l'implémentation du serveur sont-ils secrets? Si la réponse à toutes ces questions est "Non", alors quelque chose de plus complexe qu'un seul référentiel est susceptible de n'apporter que des inconvénients sans aucun avantage.
Si vous choisissez de maintenir des bases de code distinctes, vous aurez besoin de politiques claires sur la façon dont cela est administré, afin d'éviter les incompatibilités et l'enfer des dépendances. Après avoir travaillé sur les premiers hoquets, vous découvrirez peut-être que la chose la plus sûre est de toujours vérifier les deux référentiels ensemble, de les construire ensemble et de les déployer ensemble ... ce qui va évidemment à l'encontre de l'objectif de les séparer!
La modularité est une belle propriété, mais le fractionnement des référentiels n'est pas un outil pour y parvenir. Comme le paragraphe précédent l'indique, vous pouvez avoir des composants hautement couplés qui sont divisés sur plusieurs bases de code (indésirable), et de même, vous pouvez avoir des composants hautement modulaires dans la même base de code (souhaitable).
À plusieurs reprises, j'ai plaidé (avec succès) pour que mon équipe fusionne les référentiels git existants, car cela simplifiait le développement et le déploiement.
la source
Oubliez le référentiel un instant. Comment organiseriez-vous les deux projets sur votre machine si vous ne partagiez avec personne? Comment le reste de l'équipe le ferait-il? Voudriez-vous...
Placer tous les fichiers source du client et du serveur dans le même répertoire?
Créer un répertoire de projet principal contenant des sous-répertoires pour le client et le serveur?
Gardez les deux projets complètement séparés?
Une fois que vous êtes parvenu à un consensus à ce sujet en tant qu'équipe, vous êtes prêt à archiver les projets dans votre référentiel de code. Tous les outils de contrôle des révisions auxquels je peux penser sont heureux de reproduire la structure de répertoires que vous aimez - ils ne se soucient pas du tout du fichier qui appartient à quel projet. Et la différence entre avoir un référentiel ou deux (ou six) n'est généralement pas si grande, à part des différences administratives mineures.
Par exemple, avec Subversion, la plus grande différence entre des référentiels séparés pour le client et le serveur et un référentiel combiné unique réside dans la façon dont les numéros de révision changent. Avec un référentiel unique, le numéro de version augmentera chaque fois que vous validerez du code sur le client ou le serveur. Avec des référentiels séparés, une validation sur le projet de serveur ne changera pas le numéro de révision de tête pour le client.
la source