Je migre un grand référentiel CVS vieux de 10 ans vers Git. Il semblait évident de diviser ce référentiel multi-projets en plusieurs Git. Mais les décideurs sont habitués à CVS, donc leur point de vue est influencé par la philosophie CVS.
Pour les convaincre de migrer d'un référentiel CVS vers différents référentiels Git, je dois leur donner quelques arguments.
Lorsque je parle avec des amis travaillant sur Git Repo depuis des années, ils disent que l'utilisation de plusieurs Git Repo est la façon d'utiliser Git. Je ne sais pas vraiment pourquoi (ils me donnent quelques idées). Je suis un débutant dans ce domaine donc je pose ici ma question.
Quels sont les arguments pour utiliser plusieurs référentiels Git au lieu d'un seul contenant différentes applications et bibliothèques de différentes équipes?
J'ai déjà listé:
*.jar
, *.pcb
, *.dll
, *.so
, *.backup
...)repo
utilisé par Android Open Source Project afin de gérer tous ces dépôts Git: Vous traitez avec plusieurs équipes et plusieurs projets. Des décennies de travail probables sont entrées dans la base de code.
La réponse courte est que vos équipes et vos projets ont des besoins et des dépendances variables.
L'approche du référentiel monolithique réduit les commits à "Tout est stable dans cette configuration !!!" (c'est-à-dire irréalistes, d'énormes engagements provenant de nombreuses équipes). Cela, ou de nombreux points intermédiaires d'incompatibilités pour de nombreux projets. Quoi qu'il en soit, il y a beaucoup d'énergie gaspillée investie dans des configurations de support qui n'ont tout simplement jamais été conçues.
Vos référentiels doivent être structurés de manière indépendante à la place et doivent avoir plusieurs référentiels qui représentent leurs dépendances. Les dépendances doivent être configurées, mises à jour et testées par les responsables du projet aux moments appropriés du développement.
Avec plusieurs référentiels (distribués), chaque équipe peut travailler de manière indépendante et minimiser l'impact sur les autres projets tout en réutilisant et en améliorant constamment les bases de code. Cela empêche également les équipes de changer de concentration/vitesse lorsque des changements viennent d'autres équipes. Le référentiel monolithique centralisé rend chaque équipe dépendante du déplacement de chaque équipe, et cela devrait être synchronisé.
Il ne semble pas y avoir d'argument en faveur du grand dépôt dans ce fil, alors en voici un:
L'avantage d'un gros dépôt avec tout votre code est que vous avez une source fiable de vérité. Tout l'état de votre projet global est représenté dans l'histoire de ce dépôt. Vous n'avez pas à vous soucier de questions comme "De quelle version de libA ai-je besoin pour construire libB à partir d'il y a 3 mois?" ou "Les tests d'intégration ont-ils commencé à échouer à cause du changement de Susan dans libC ou de Bob dans libD?" ou "Y a-t-il encore des appelants pour evilMethod ()?" Tout est dans l'histoire.
Lorsque les projets associés sont divisés en référentiels distincts, git ne garde pas trace de leurs relations pour vous. Votre système de génération doit savoir où trouver le code pour toutes ses dépendances, et plus important encore quelle version du code à construire. Vous pouvez "simplement tout construire à partir de master", mais cela rend difficile la reproduction des builds précédents, difficile d'apporter des modifications (ou des annulations) qui doivent être synchronisées entre les dépôts, et difficile de garder les branches dans un état stable.
La question n'est donc pas "Un grand repo ou plusieurs petits repos?" Il s'agit en fait "d'un grand référentiel ou de nombreux petits référentiels avec outillage ". Quel outil allez-vous utiliser? Repo (Android) et gclient (Chromium) de Google en sont deux exemples. Les sous-modules Git en sont un autre. Tous ceux-ci ont majeurinconvénients que vous devez peser contre les inconvénients d'un grand repo.
Edit: Voici quelques réponses supplémentaires Choisir entre un ou plusieurs projets dans un référentiel git?
PS: Tout cela dit, je travaille sur un outil pour, espérons-le, améliorer les choses, lorsque vous devez fractionner des dépôts ou utiliser le code d'autres personnes: https://github.com/buildinspace/per
Git a tendance à rencontrer des problèmes de performances lorsqu'il est utilisé avec de grands référentiels.
À citation Linus :
Et git n'a évidemment pas ce genre de modèle du tout. Git
fondamentalement ne regarde jamais vraiment moins que le repo entier. Même si vous limitez un peu les choses (c.-à-d. Vérifier seulement une partie, ou faire revenir l'histoire un peu en arrière), git finit toujours par se soucier de tout et transporter les connaissances.Donc git évolue vraiment mal si vous le forcez à tout regarder comme un seul énorme dépôt. Je ne pense pas que cette partie soit vraiment réparable, bien que nous puissions probablement l'améliorer.
Je souligne. Cela ne veut pas dire que le référentiel de contrôle de version de votre entreprise est "grand", mais c'est une des raisons pour lesquelles les gens ont tendance à éviter les grands référentiels dans Git.
Ils veulent [quelque chose qui peut] montrer leurs changements dans tous les projets au lieu d'essayer de se rappeler quel projet ils ont fait un changement [vers].
Sourcetree (une interface graphique Git gratuite en bière) vous permet d'enregistrer plusieurs référentiels, de les organiser en groupes logiques, puis de visualiser l'état de chacun d'eux à la fois:
Je ne suis d'aucune façon affilié à eux.
TL; DR; l'équivalent d'un référentiel git est un module CVS, pas un référentiel CVS.
CVS est conçu avec une notion de modules étant une subdivision d'un référentiel, et il est courant d'utiliser des référentiels CVS avec plusieurs modules ayant une vie assez indépendante. Par exemple, il est facile d'avoir des branches spécifiques à un module et non présentes dans un autre.
git n'a pas été conçu avec une notion de module, chaque dépôt git est limité à un module en terme CVS. Lorsque vous créez une branche, elle est valide pour l'ensemble du référentiel.
Ainsi, si vous souhaitez importer un référentiel CVS avec plusieurs modules dans git, vous feriez mieux de créer un référentiel par module, surtout si les modules ont une vie plus ou moins indépendante et ne partagent pas des choses comme la branche et les étiquettes. (En raison des différents modèles d'utilisation des branches dans CVS et git, vous pouvez même étudier l'utilité d'avoir un référentiel par branche CVS; mais pour une migration de CVS vers git, il est probable que votre flux de travail au début soit assez similaire à un workflow CVS qui ne vaut pas la peine).
Si vous êtes prêt à jouer avec eux pour apaiser, vous pouvez le configurer de cette façon . Ou cette méthode . À part cela, je pense qu'ils s'attendent à un seul point d'entrée dans le système pour accéder aux actifs.
Selon les besoins d'accès, les référentiels GIT séparés peuvent toujours être la meilleure solution, car "John Smith" peut avoir besoin d'accéder à certaines données, mais pas à d'autres données. Alors que "Suzy Que" peut être un administrateur système ayant besoin d'accéder à tout.
Si vous optez pour un seul dépôt, vous risquez de rencontrer des problèmes avec vos exigences d'accès interne. Si c'est une chose "tout le monde a un accès complet", je pourrais peut-être voir leur point de vue.
page d'aide sur la migration Git d'Eclipse suggère de réorganiser l'arborescence des répertoires CVS/SVN en plusieurs référentiels Git:
C'est le moment idéal pour refactoriser la structure de votre code. Mappez les répertoires, modules, plugins, etc. CVS/SVN actuels à leur nouveau domicile dans Git. En règle générale, un référentiel Git (.git) est créé pour chaque regroupement logique de code - un projet, un composant, etc.
Les arguments:
Le compromis ici est que chaque référentiel Git supplémentaire ajoute une surcharge supplémentaire à votre processus de développement - toutes les commandes et opérations Git se produisent au niveau d'un seul référentiel Git. D'un autre côté, chaque utilisateur du référentiel disposera d'une copie complète de l'historique du référentiel, rendant les très grands référentiels encombrants à utiliser pour les contributeurs occasionnels.
Git fonctionne sur un arbre entier à la fois, pas seulement sur le sous-répertoire dans lequel vous vous trouvez.
Disons que vous avez votre projet à
C:\MyCode\ProjectABC
Et disons que ces deux fichiers ont changé:
C:\MyCode\ProjectABC\stuff.txt
C:\MyCode\ProjectABC\Stuff\MoreStuff\morestuff.txt
Lorsque vous êtes à la racine du projet et que vous effectuez un statut git, vous verrez que ces fichiers ont changé:
stuff.txt
Stuff\MoreStuff\morestuff.txt
Si vous cd
dans le répertoire MoreStuff, voyez-vous uniquement le fichier morestuff.txt? Non, vous verrez toujours les deux fichiers, par rapport à votre position:
..\..\stuff.txt
morestuff.txt
Par conséquent, si vous regroupez tous vos projets dans un seul grand référentiel Git, chaque fois que vous allez vous enregistrer, vous devrez choisir parmi les modifications de chaque projet.
Maintenant, il pourrait y avoir des moyens d'atténuer cela; Par exemple, vous pouvez vous assurer de valider au moins temporairement vos modifications avant de passer à travailler sur un autre projet. Mais cela représente beaucoup de frais généraux que chaque membre de votre équipe devrait gérer, par rapport à le faire simplement de la bonne manière: un référentiel Git par projet.