Modifier: contrairement à certaines questions similaires telles que Déplacer un référentiel SVN de plusieurs Go vers Git ou /programming/540535/managing-large-binary-files-with-git Mon scénario n'implique pas plusieurs sous-projets qui peuvent être facilement convertis en sous-carburants git, ni quelques très gros fichiers binaires qui sont bien adaptés pour git-annex. Il s'agit d'un référentiel unique où les binaires sont la suite de tests qui est étroitement couplée au code source principal de la même révision, un peu comme s'il s'agissait de ressources de temps de compilation telles que des graphiques.
J'étudie la commutation d'un ancien dépôt de code de taille moyenne / grande taille (50 utilisateurs, 60k révisions, 80Gb historique, copie de travail 2Gb) de svn. Comme le nombre d'utilisateurs a augmenté, il y a beaucoup de désabonnement dans le tronc, et les fonctionnalités sont souvent réparties sur plusieurs validations, ce qui rend la révision du code difficile à faire. De plus, sans branchement, il n'y a aucun moyen de "bloquer" le mauvais code, les révisions ne peuvent être effectuées qu'une fois qu'il est validé dans le tronc. J'examine des alternatives. J'espérais que nous pourrions passer à git, mais j'ai des problèmes.
Le problème avec le dépôt actuel en ce qui concerne git est la taille. Il y a beaucoup de vieilles cruches là-dedans, et le nettoyer avec --filter-branch lors de la conversion en git peut le réduire de l'ordre de grandeur, à environ 5-10 Go. C'est encore trop gros. La principale raison de la grande taille du référentiel est qu'il existe de nombreux documents binaires en entrée pour les tests. Ces fichiers varient entre 0,5 Mo et 30 Mo et il y en a des centaines. Ils ont également beaucoup de changements. J'ai regardé les sous-modules, git-annex, etc., mais avoir les tests dans un sous-module me semble mal, tout comme avoir l'annexe pour de nombreux fichiers pour lesquels vous voulez un historique complet.
Donc, la nature distribuée de git est vraiment ce qui m'empêche de l'adopter. Je ne me soucie pas vraiment de la distribution, je veux juste la ramification bon marché et les puissantes fonctionnalités de fusion. Comme je suppose que 99,9% des utilisateurs de git le font, nous utiliserons un référentiel central béni et nu.
Je ne suis pas sûr de comprendre pourquoi chaque utilisateur doit avoir un historique local complet lors de l'utilisation de git? Si le workflow n'est pas décentralisé, que font ces données sur les disques des utilisateurs? Je sais que dans les versions récentes de git, vous pouvez utiliser un clone peu profond avec uniquement un historique récent. Ma question est: est-il viable de le faire comme mode de fonctionnement standard pour toute une équipe? Git peut-il être configuré pour être toujours superficiel afin que vous puissiez avoir un historique complet uniquement de manière centrale, mais les utilisateurs par défaut n'ont que 1000 tours d'historique? L'option pour cela serait bien sûr de simplement convertir 1000 tours en git, et de conserver le dépôt svn pour l'archéologie. Dans ce scénario cependant, nous rencontrerions à nouveau le même problème après les plusieurs milliers de révisions suivantes des documents de test.
- Qu'est - ce qu'un bon pour l' utilisation des meilleures pratiques git avec de grandes prises en pension contenant de nombreux fichiers binaires que vous ne voulez histoire de? La plupart des meilleures pratiques et des didacticiels semblent éviter ce cas. Ils résolvent le problème de quelques énormes binaires, ou proposent de supprimer complètement les binaires.
- Le clonage superficiel est-il utilisable comme mode de fonctionnement normal ou s'agit-il d'un "hack"?
- Des sous-modules peuvent-ils être utilisés pour du code où vous avez une dépendance étroite entre la révision source principale et la révision de sous-module (comme dans les dépendances binaires au moment de la compilation ou une suite de tests unitaires)?
- Quelle est la taille «trop grand» pour un référentiel git (sur site)? Devrions-nous éviter de changer si nous pouvons le réduire à 4 Go? 2 Go?
Réponses:
Wow, c'est une longue question (et un problème complexe). Je vais essayer de l'essayer.
Il s'agit d'une décision de conception centrale avec git. Pour les raisons exactes que vous auriez besoin de demander à l'auteur (Linus Torvalds), mais pour autant que je sache, la raison principale est la vitesse: avoir tout en local (sur un disque rapide ou même mis en cache dans la RAM) rend les opérations sur l'histoire beaucoup plus rapides en évitant l'accès au réseau.
C'est le point auquel je penserais en premier. Avoir tant de fichiers binaires en constante évolution dans le contrôle de source me semble problématique (même avec SVN). Ne pouvez-vous pas utiliser une approche différente? Idées:
Contrairement au code source, un fichier binaire de 3 Mo n'est probablement pas écrit à la main. Si un outil / processus le génère, envisagez de l'intégrer dans votre build, au lieu de stocker les données.
Si ce n'est pas pratique, les fichiers binaires sont généralement mieux placés dans un référentiel d'artefacts (comme Artifactory pour Maven & co.). C'est peut-être une option pour vous.
En fait, cela ressemble à git-annex qui conviendrait parfaitement. git-annex vous permet essentiellement de stocker le contenu d'un fichier en dehors d'un référentiel git (le référentiel contient à la place un espace réservé). Vous pouvez stocker le contenu du fichier de différentes manières (dépôt git central, lecteur partagé, stockage cloud ...), et vous pouvez contrôler le contenu que vous souhaitez avoir localement.
Avez-vous peut-être mal compris le fonctionnement de git-annex? git-annex stocke l'historique complet de tous les fichiers qu'il gère - il vous permet simplement de choisir le contenu du fichier que vous souhaitez avoir localement.
Enfin, à propos de vos questions:
D'après mon expérience, les options sont généralement les suivantes:
Cela pourrait être faisable; cependant, je ne pense pas que cela résoudra votre problème:
Cela dépend de la structure du dépôt (peu / beaucoup de fichiers, etc.), de ce que vous voulez faire, de la solidité de vos ordinateurs et de votre patience :-).
Pour vous donner une idée rapide: Sur mon ordinateur portable (récent, mais de faible spécification), la validation d'un fichier de 500 Mo prend 30 à 60 secondes. Le simple listage de l'historique (git log, etc.) n'est pas affecté par les gros fichiers; des choses comme "git log -S" qui doit analyser le contenu des fichiers sont très lentes - cependant, la vitesse est principalement dominée par les E / S, donc ce n'est pas vraiment la faute de git.
Sur un dépôt de 3 Go avec une poignée de révisions, "git log -S" prend environ une minute.
Je dirais donc que deux Go sont corrects, mais pas idéaux. Plus de 10 à 20 Go le poussent probablement, mais cela pourrait être faisable - vous devriez l'essayer.
la source
Passer à git ne résoudra pas ces problèmes, ce sont des problèmes dans la façon dont vous utilisez l'outil et si vous utilisez git de la même manière, les problèmes resteront.
Vous pouvez créer des branches dans svn tout aussi facilement dans git, et la fusion est généralement tout aussi facile et présente les mêmes pièges. Git a été conçu pour fonctionner avec le code source du noyau, il a donc fait des hypothèses qui peuvent ne pas s'appliquer dans tous les cas, comme la vôtre avec de gros binaires et des historiques massifs. L'intention derrière un DVCS est que chaque utilisateur travaille efficacement seul et ne collabore qu'ultérieurement - c'est-à-dire qu'il a son propre référentiel (une copie), qu'il travaille comme il le souhaite, puis propose les modifications à quiconque le souhaite. Un système fédéré utilisé dans le développement du noyau linux est parfait pour cela - vous poussez vos modifications vers le gars suivant de la chaîne qui le fusionne avec sa base de code, puis le pousse vers le gars suivant jusqu'à ce qu'il arrive à Linus qui le met dans la version. La plupart des équipes utilisent git de la même manière, mais avec seulement 1 gars en amont qui est souvent un repo "gold" côté serveur,
Je voudrais donc d'abord changer votre flux de travail, migrer vers git uniquement une fois que vous avez une meilleure façon de travailler. Implémentez la ramification et la fusion dans SVN, si vous ne renommez pas les fichiers ou les répertoires, la fusion se passe très bien.
la source
Regardez dans la liste de diffusion GCC. La migration de l' arborescence source du compilateur GCC de SVN vers GIT est discutée en ce moment (août et septembre 2015), tout en conservant l'historique de GCC. Voir par exemple le référentiel pour la machinerie de conversion et les critères d'acceptation pour les fils de discussion de conversion git ; vous trouverez des références aux outils et procédures liés à la conversion (ce qui n'est pas aussi simple qu'il y paraît; la conversion d'un si grand historique de base de code nécessite 36 heures et environ 64 Go de RAM, IIRC)
la source
Si la conversion de l'ensemble du référentiel SVN en Git entraîne un énorme référentiel qui est impossible à cloner, vous pouvez essayer d'utiliser SubGit pour créer des miroirs Git plus petits pour certaines parties de votre référentiel Subversion.
Par exemple, vous pouvez importer et synchroniser certains sous-répertoires de votre référentiel SVN
http://domain/repos/trunk/project/src
:Pour plus de détails sur l'utilisation de SubGit, reportez-vous à sa documentation .
Dès que vous disposez du miroir Git de ce répertoire, vous pouvez utiliser le référentiel Git pour soumettre de nouvelles modifications qui se reflètent immédiatement dans le référentiel SVN. Comme vous ne synchronisez qu'une partie du référentiel SVN qui réduit considérablement la taille du référentiel Git converti et que vous pouvez toujours créer des branches, les fusionner, utiliser n'importe quel flux de travail du côté Git.
Vous pouvez également importer l'intégralité du référentiel SVN mais exclure les fichiers volumineux de la synchronisation:
Le référentiel Git résultant doit avoir une taille raisonnable et les développeurs peuvent toujours utiliser Git pour soumettre leurs modifications au référentiel Subversion.
Notez que cette solution devrait bien fonctionner pour vous si vous êtes prêt à faire fonctionner le serveur Subversion et à utiliser Git avec votre référentiel SVN.
Avertissement: je suis l'un des développeurs SubGit; SubGit est un logiciel commercial avec un certain nombre d'options gratuites disponibles.
la source
J'approche votre situation de la manière suivante:
1) Initialisez un dépôt git dans le même répertoire que votre dépôt SVN. Faites
git init
etgit remote add origin
pour commencer ce dépôt git. De cette façon, vous pouvez continuer à vous engager sur SVN et git séparément sans avoir à effectuer une conversion complète de l'un à l'autre jusqu'à ce que vous soyez prêt.2) Utilisez activement les outils bfg et filter-branch pour essayer de réduire votre dépôt git, comme indiqué ici: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
3) Utilisez git-annex, ou Git LFS, ou simplement un serveur de stockage externe pour vos gros fichiers binaires (transport des fichiers à l'aide de scripts shell au moment de la construction).
4) Une fois que vous êtes à l'aise avec la stratégie de fusion / branchement dans votre dépôt git et que vous êtes à l'aise avec la taille de votre dépôt git, vous pouvez alors effectuer une migration complète de votre svn vers git.
J'espère que cela t'aides.
la source