Que faire à propos de l'historique SVN important lors du passage à Git?

23

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?
Anders Forsgren
la source
J'ai cherché beaucoup d'informations à ce sujet et je n'ai rien trouvé qui réponde à ma question. Dans la question liée, les workaounrds (sous-modules, annexe etc.) fonctionneraient beaucoup mieux que dans mon scénario.
Anders Forsgren
1
Git LFS
CodesInChaos
Perforce peut être une meilleure option que git, car il est conçu pour faire face à de nombreux gros fichiers binaires, donc utilisé par de nombreux développeurs de jeux. Plasticscm vaut également le détour.
Ian
Juste un côté: évitez les sous-modules git si vous le pouvez, car ils compliquent trop le système de construction (ce qui est déjà compliqué dans votre cas).
IgorGanapolsky

Réponses:

10

Wow, c'est une longue question (et un problème complexe). Je vais essayer de l'essayer.

Je ne suis pas sûr de comprendre pourquoi chaque utilisateur doit avoir un historique local complet lors de l'utilisation de git?

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.

La principale raison de la grande taille du référentiel est qu'il y a beaucoup de 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.

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.

J'ai regardé les sous-modules, git-annex, etc., mais avoir les tests dans un sous-module semble mal, tout comme avoir l'annexe pour de nombreux fichiers pour lesquels vous voulez un historique complet.

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:

Quelle est la bonne pratique pour utiliser git avec de grands dépôts contenant de nombreux fichiers binaires pour lesquels vous voulez un historique?

D'après mon expérience, les options sont généralement les suivantes:

  • éviter le besoin de binaires dans le référentiel (les générer à la demande, les stocker ailleurs)
  • utiliser git-annex (ou une solution similaire, comme Git LFS)
  • vivre avec un gros dépôt (toutes les opérations git ne sont pas affectées par de gros fichiers, et si vous avez un ordinateur et un lecteur rapides, cela peut être tout à fait réalisable)

Le clonage superficiel est-il utilisable comme mode de fonctionnement normal ou s'agit-il d'un "hack"?

Cela pourrait être faisable; cependant, je ne pense pas que cela résoudra votre problème:

  • vous perdriez les avantages de git qui découlent de l'historique complet, comme une recherche rapide de l'historique
  • les fusions peuvent devenir délicates, car AKAIK vous devez avoir au moins l'historique de retour au point de branchement pour fusionner
  • les utilisateurs devraient recloner périodiquement pour garder la taille de leur clone petite
  • c'est juste une façon rare d'utiliser git, donc vous rencontrerez probablement des problèmes avec de nombreux outils

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?

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.

sleske
la source
Merci pour votre réponse détaillée. Je vais certainement chercher à utiliser l'annexe pour les documents de test. La barre des «performances raisonnables» est probablement «proche de svn», c'est-à-dire que si elle est nettement plus lente pour toute opération, il y aurait trop de friction pour commuter.
Anders Forsgren
Je pense que Git LFS peut également être utilisé pour le stockage de gros fichiers binaires.
IgorGanapolsky
@IgorG .: Oui, Git LFS est une alternative, il y en a d'autres. Merci de l'avoir signalé, j'ai modifié mon article.
sleske
4

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 engagé dans le tronc

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.

gbjbaanb
la source
4
"Vous pouvez créer une branche dans svn tout aussi facilement dans git, et la fusion est généralement aussi facile et a les mêmes pièges", wow, c'est une affirmation très controversée. À mon avis, la fusion dans git est généralement un jeu d'enfant et dans svn généralement un cauchemar, même dans les versions après l'introduction d'une tentative de fusion de suivi à moitié (oui, je travaille avec git, pas seulement sur ce repo). Le flux de travail que nous voulons avoir est celui où vous créez une branche de fonctionnalité, revue de code / build CI sur cette branche. Il n'y a tout simplement aucun moyen de le faire dans SVN sans une frustration massive.
Anders Forsgren
2
non, nous le faisons tout le temps ici. Je suis en train de parcourir les 157 branches de mon référentiel SVN pour voir lesquelles peuvent être supprimées. Nous branchons, développons, révisons et fusionnons presque quotidiennement ici, occasionnons parfois des problèmes, mais cela est toujours résolu en supprimant une nouvelle branche du tronc et en fusionnant les modifications (afin qu'il puisse être facilement fusionné de nouveau dans le tronc plus tard) . Cela ne s'applique cependant qu'aux branches anciennes. Si vous avez une énorme frustration, vous ne la comprenez pas assez bien. Git vous donnera également d'énormes frustrations.
gbjbaanb
2
Je n'en fais tout simplement pas l'expérience. Lorsque je travaille avec git (comme je l'ai dit, mais dans des dépôts plus petits), je trouve assez simple et naturel de créer des branches, de rebaser, d'écraser et de fusionner des fonctionnalités. Les "conflits d'arborescence après les renommages" etc. semblent beaucoup plus rares, et le fait que vous puissiez émuler une histoire linéaire et simple (via rebase + squash, etc.) est très important. Donc: pour garder la question sur le sujet (git avec de grands repos): Supposons que svn ne supporte pas le workflow dont j'ai besoin, et git le fait.
Anders Forsgren
1
Dans une entreprise précédente, nous utilisions git, et je connais quelqu'un là-bas qui perdait régulièrement son travail en l'utilisant, donc ce n'est pas un système parfait par tous les moyens! SVN n'est pas non plus, mais SVN est beaucoup mieux adapté à votre situation que git IMHO, et cela fonctionne. Sur le sujet, comment faire fonctionner git comme vous le souhaitez ... Je ne suis vraiment pas sûr que ce sera le cas, désolé.
gbjbaanb
7
@gbjbaanb si quelqu'un perd son travail avec Git, il fait quelque chose de terriblement mal.
RubberDuck
2

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)

Basile Starynkevitch
la source
Voulez-vous dire la migration de SVN vers Git? La migration d'un système de contrôle de version vers une suite de compilation semble un peu ... étrange. De plus, cela ressemble un peu plus à un commentaire qu'à une réponse.
8bittree du
Oui. Désolé pour la faute de frappe.
Basile Starynkevitch du
Merci. 36 heures sonnent comme une brise, la nôtre peut se convertir en quelques semaines ...
Anders Forsgren
2

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:

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

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:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

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.

vadishev
la source
1

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 initet git remote add originpour 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.

IgorGanapolsky
la source