Gérer de gros fichiers binaires avec Git


523

Je recherche des avis sur la façon de gérer les gros fichiers binaires dont dépend mon code source (application web). Nous discutons actuellement de plusieurs alternatives:

  1. Copiez les fichiers binaires à la main.
    • Pro: Pas sûr.
    • Contre: Je suis fortement contre cela, car cela augmente la probabilité d'erreurs lors de la configuration d'un nouveau site / de la migration de l'ancien. Construit un autre obstacle à franchir.
  2. Gérez-les tous avec Git .
    • Pro: Supprime la possibilité d'oublier de copier un fichier important
    • Contre: gonfle le référentiel et diminue la flexibilité pour gérer la base de code et les extractions, les clones, etc. prendront un certain temps.
  3. Référentiels séparés.
    • Pro: La vérification / le clonage du code source est plus rapide que jamais et les images sont correctement archivées dans leur propre référentiel.
    • Contra: supprime la simplicité d'avoir le seul et unique référentiel Git sur le projet. Cela introduit sûrement d'autres choses auxquelles je n'ai pas pensé.

Quelles sont vos expériences / réflexions à ce sujet?

Aussi: Quelqu'un a-t-il de l'expérience avec plusieurs référentiels Git et les gère-t-il dans un projet?

Les fichiers sont des images pour un programme qui génère des fichiers PDF avec ces fichiers. Les fichiers ne changeront pas très souvent (comme en années), mais ils sont très pertinents pour un programme. Le programme ne fonctionnera pas sans les fichiers.


26
Qu'en est-il lorsque la version contrôlant le fichier binaire est nécessaire? Je pense aux équipes d'artistes travaillant sur les actifs.
Dan

3
Si cela est nécessaire, vous devez équilibrer vos ressources disponibles (disque, bande passante, temps CPU) par rapport aux avantages que vous obtenez.
pi.

4
Notez que sans verrouillage de fichier, git n'est pas génial lorsque plusieurs personnes doivent travailler sur le même fichier binaire.
yoyo


Réponses:


177

Si le programme ne fonctionne pas sans les fichiers, il semble que les diviser en un référentiel séparé est une mauvaise idée. Nous avons de grandes suites de tests que nous divisons en un référentiel séparé, mais ce sont vraiment des fichiers "auxiliaires".

Cependant, vous pourrez peut-être gérer les fichiers dans un référentiel séparé, puis les utiliser git-submodulepour les tirer dans votre projet de manière saine. Donc, vous auriez toujours l'historique complet de toutes vos sources mais, si je comprends bien, vous n'auriez qu'une seule révision pertinente de votre sous-module d'images. L' git-submoduleinstallation devrait vous aider à garder la bonne version du code en ligne avec la bonne version des images.

Voici une bonne introduction aux sous-modules de Git Book.


11
"si je comprends bien, vous n'auriez qu'une seule révision pertinente de votre sous-module d'images." Je ne pense pas que ce soit correct.
Robin Green

22
En effet. Un sous-module est un référentiel Git complet, qui se trouve juste imbriqué dans le référentiel parent. Il connaît toute son histoire. Vous pouvez vous y engager moins fréquemment, mais si vous y stockez les mêmes choses que vous auriez dans le parent, il aura les mêmes problèmes que le parent aurait.
Cascabel

5
C'est une solution assez médiocre si vous avez de gros fichiers binaires qui changent à un intervalle régulier. Nous avons un référentiel qui est horriblement gonflé car un nouveau fichier binaire y est stocké avec chaque build. Si vous n'êtes pas sous Windows, comme mentionné ci-dessous, Annex est une bonne solution. Si vous êtes sous Windows ... devra juste continuer à chercher.
AA Grapsas

4
Un autre problème lié à la présence de fichiers binaires volumineux dans le référentiel concerne les performances. Git n'a pas été conçu pour faire face aux gros fichiers binaires et une fois que la taille du référentiel atteint 3G +, les performances chutent rapidement. Cela signifie que le fait d'avoir de gros fichiers binaires dans le référentiel limite vos options d'hébergement.
2012 à

Les sous-modules peuvent réduire les exigences de transfert de données d'extraction si vous utilisez de manière créative le sous-module: lorsque vous souhaitez mettre à jour le contenu du sous-module, créez un nouveau commit sans parent, puis pointez le superprojet (dépôt git principal) vers le commit nouvellement créé sans parent. Logiquement, cela crée un historique déconnecté pour le sous-module, mais en retour, toute version du sous-module est plus facile à transférer car cette version n'a pas d'historique.
Mikko Rantalainen

310

J'ai découvert git-annex récemment que je trouve génial. Il a été conçu pour gérer efficacement les gros fichiers. Je l'utilise pour mes collections photo / musique (etc.). Le développement de git-annex est très actif. Le contenu des fichiers peut être supprimé du référentiel Git, seule la hiérarchie de l'arborescence est suivie par Git (via des liens symboliques). Cependant, pour obtenir le contenu du fichier, une deuxième étape est nécessaire après avoir tiré / poussé, par exemple:

$ git annex add mybigfile
$ git commit -m'add mybigfile'
$ git push myremote
$ git annex copy --to myremote mybigfile ## This command copies the actual content to myremote
$ git annex drop mybigfile ## Remove content from local repo
...
$ git annex get mybigfile ## Retrieve the content
## or to specify the remote from which to get:
$ git annex copy --from myremote mybigfile

Il existe de nombreuses commandes disponibles et une excellente documentation sur le site Web. Un paquet est disponible sur Debian .


11
Whoa! Upvote for awesomeness! Cela met en œuvre une idée que j'avais récemment, et bien plus encore. C'est écrit en Haskell pas moins. Soit dit en passant, git-media est une bonne alternative.
cdunn2001

33
Mais, l'annexe ne prend pas en charge Windows. Ce qui est problématique pour les développeurs de jeux.
AA Grapsas

7
J'ai entendu dire que Steam abandonnait le support pour Windows et ajoutait le support pour Linux ...;) sérieusement, à quel point cela peut-il être difficile de porter cela? Je suppose que votre développeur de jeux moyen pourrait le faire.
Sam Watkins

4
@EstebanBrenes Le vrai problème est que dans la configuration normale, les liens symboliques Windows nécessitent des privilèges élevés pour être créés.
Laurens Holst

4
Je viens de trouver cette page . Il indique que maintenant git annexest également disponible sur Windows . Si quelqu'un l'a déjà testé dans Windows, j'aimerais connaître son expérience!
Kouichi C.Nakamura

49

Une autre solution, depuis avril 2015, est Git Large File Storage (LFS) (par GitHub).

Il utilise git-lfs (voir git-lfs.github.com ) et testé avec un serveur le supportant: lfs-test-server :
vous ne pouvez stocker des métadonnées que dans le référentiel git et le gros fichier ailleurs.

https://cloud.githubusercontent.com/assets/1319791/7051226/c4570828-ddf4-11e4-87eb-8fc165e5ece4.gif


3
lfs-test-serverest déclaré non destiné à la production. En fait, je travaille sur le serveur de production LFS ( github.com/artemkin/git-lfs-server ). Il est en cours, mais déjà utilisable, et nous le testons en interne.
Stas

Pouvez-vous extraire les versions précédentes d'un tel fichier binaire en utilisant git lfs?
mucaho

1
@mucaho Vous devriez: la syntaxe de git checkout est inchangée et le script lfs smudge doit toujours être appelé.
VonC

31

Jetez un œil à git bup qui est une extension Git pour stocker intelligemment de gros binaires dans un référentiel Git.

Vous voudriez l'avoir comme sous-module, mais vous n'aurez pas à vous soucier de la difficulté du référentiel à gérer. L'un de leurs exemples d'utilisation est le stockage d'images VM dans Git.

Je n'ai pas réellement vu de meilleurs taux de compression, mais mes référentiels ne contiennent pas de binaires vraiment volumineux.

Votre kilométrage peut varier.


3
bup fournit du stockage (en utilisant en interne des archives de parité pour la redondance et git pour la compression, la déduplication et l'historique), mais il n'étend pas git. git-annex est une extension git qui fournit un backend de stockage bup .
Tobu

@Tobu quand je posté, annexe git n'existait pas encore (dans les versions grand public)
sehe

2
bup est certainement intéressant pour gérer de gros fichiers. Je voulais souligner une différence dans l'interface utilisateur: vous utilisez des commandes bup en dehors de tout contexte de référentiel, et git est un détail d'implémentation.
Tobu

27

Vous pouvez également utiliser du git-fat . J'aime que cela ne dépend que du stock Python et rsync. Il prend également en charge le flux de travail Git habituel, avec les commandes explicites suivantes:

git fat init
git fat push
git fat pull

De plus, vous devez archiver un fichier .gitfat dans votre référentiel et modifier vos .gitattributes pour spécifier les extensions de fichier que vous souhaitez git fatgérer.

Vous ajoutez un binaire en utilisant la normale git add, qui à son tour invoque en git fatfonction de vos règles gitattributes.

Enfin, il a l'avantage que l'emplacement où vos fichiers binaires sont réellement stockés peut être partagé entre les référentiels et les utilisateurs et prend en charge tout ce qui est rsyncfait.

MISE À JOUR: N'utilisez pas git-fat si vous utilisez un pont Git-SVN. Il finira par supprimer les fichiers binaires de votre référentiel Subversion. Cependant, si vous utilisez un référentiel Git pur, cela fonctionne à merveille.


26

J'utiliserais des sous-modules (comme Pat Notz) ou deux référentiels distincts. Si vous modifiez trop souvent vos fichiers binaires, j'essaierais de minimiser l'impact de l'immense référentiel nettoyant l'historique:

J'ai eu un problème très similaire il y a plusieurs mois: ~ 21 Go de fichiers MP3, non classés (mauvais noms, mauvais id3, je ne sais pas si j'aime ce fichier MP3 ou non ...), et répliqués sur trois ordinateurs.

J'ai utilisé un disque dur externe avec le référentiel Git principal et je l'ai cloné dans chaque ordinateur. Ensuite, j'ai commencé à les classer de la manière habituelle (pousser, tirer, fusionner ... supprimer et renommer plusieurs fois).

À la fin, je n'avais que ~ 6 Go de fichiers MP3 et ~ 83 Go dans le répertoire .git. J'ai utilisé git-write-treeet git-commit-treepour créer un nouveau commit, sans ancêtre de commit, et j'ai commencé une nouvelle branche pointant vers ce commit. Le "git log" pour cette branche n'a montré qu'un seul commit.

Ensuite, j'ai supprimé l'ancienne branche, conservé uniquement la nouvelle branche, supprimé les journaux de référence et exécuté "git prune": après cela, mes dossiers .git ne pesaient que ~ 6 Go ...

Vous pouvez "purger" l'énorme dépôt de temps en temps de la même manière: vos "git clones" seront plus rapides.


J'ai fait quelque chose de similaire une fois où j'ai dû diviser un référentiel que j'ai fusionné accidentellement en deux distincts. Modèle d'utilisation intéressant cependant. :)
pi.

1
Serait-ce la même chose que juste: rm -f .git; git init; git add. ; git commit -m "Trash the history."
Pat Notz

1
Oui, c'est la même chose que dans mon boîtier mp3. Mais parfois, vous ne voulez pas toucher à vos branches et balises (pas de réduction d'espace dans les référentiels publics) mais vous voulez accélérer un "git clone / fetch / pull" d'une seule branche (moins d'espace pour dédié à cela) référentiels de succursales).
Daniel Fanjul

13

La solution que je voudrais proposer est basée sur des branches orphelines et un léger abus du mécanisme de tag, désormais appelé * Stockage binaire de tags orphelins (OTABS)

TL; DR 12-01-2017 Si vous pouvez utiliser le LFS de github ou un autre tiers, vous devriez certainement le faire. Si vous ne le pouvez pas, poursuivez votre lecture. Soyez averti, cette solution est un hack et doit être traitée comme telle.

Propriétés souhaitables d'OTABS

  • c'est une pure solution git et git only - elle fait le travail sans aucun logiciel tiers (comme git-annex) ou infrastructure tierce (comme LFS de github).
  • il stocke efficacement les fichiers binaires , c'est-à-dire qu'il ne gonfle pas l'historique de votre référentiel.
  • git pullet git fetch, y compris git fetch --allsont toujours efficaces en bande passante , c'est-à-dire que tous les gros fichiers binaires ne sont pas extraits de la télécommande par défaut.
  • cela fonctionne sous Windows .
  • il stocke tout dans un seul dépôt git .
  • il permet la suppression de binaires obsolètes (contrairement à bup).

Propriétés indésirables d'OTABS

  • cela rend git clonepotentiellement inefficace (mais pas nécessairement, selon votre utilisation). Si vous déployez cette solution, vous devrez peut-être conseiller à vos collègues d'utiliser git clone -b master --single-branch <url>plutôt que git clone. C'est parce que git clone par défaut clone littéralement le référentiel entier , y compris les choses sur lesquelles vous ne voudriez pas normalement gaspiller votre bande passante, comme les commits non référencés. Tiré du SO 4811434 .
  • cela rend la git fetch <remote> --tagsbande passante inefficace, mais pas nécessairement le stockage inefficace. Vous pouvez toujours conseiller à vos collègues de ne pas l'utiliser.
  • vous devrez périodiquement utiliser une git gcastuce pour nettoyer votre référentiel de tous les fichiers dont vous ne voulez plus.
  • ce n'est pas aussi efficace que bup ou git-bigfiles . Mais il est respectivement plus adapté à ce que vous essayez de faire et plus standard. Vous êtes susceptible de rencontrer des problèmes avec des centaines de milliers de petits fichiers ou avec des fichiers de l'ordre de gigaoctets, mais lisez la suite pour des solutions de contournement.

Ajout des fichiers binaires

Avant de commencer, assurez-vous d'avoir validé toutes vos modifications, votre arborescence de travail est à jour et votre index ne contient aucune modification non validée. Ce pourrait être une bonne idée de pousser toutes vos succursales locales vers votre télécommande (github, etc.) au cas où une catastrophe se produirait.

  1. Créez une nouvelle branche orpheline. git checkout --orphan binaryStufffera l'affaire. Cela produit une branche qui est entièrement déconnectée de toute autre branche, et le premier commit que vous ferez dans cette branche n'aura pas de parent, ce qui en fera un commit root.
  2. Nettoyez votre index à l'aide de git rm --cached * .gitignore.
  3. Respirez profondément et supprimez tout l'arbre de travail en utilisant rm -fr * .gitignore. Le .gitrépertoire interne restera intact, car le *caractère générique ne le correspond pas.
  4. Copiez dans votre VeryBigBinary.exe ou dans votre VeryHeavyDirectory /.
  5. Ajoutez-le et validez-le.
  6. Maintenant, cela devient difficile - si vous le poussez dans la télécommande en tant que branche, tous vos développeurs le téléchargeront la prochaine fois qu'ils invoqueront le git fetchcolmatage de leur connexion. Vous pouvez éviter cela en poussant une balise au lieu d'une branche. Cela peut toujours avoir un impact sur la bande passante et le stockage du système de fichiers de vos collègues s'ils ont l'habitude de taper git fetch <remote> --tags, mais lisez la suite pour une solution de contournement. Allez-y etgit tag 1.0.0bin
  7. Poussez votre tag orphelin git push <remote> 1.0.0bin.
  8. Juste pour ne jamais pousser votre branche binaire par accident, vous pouvez la supprimer git branch -D binaryStuff. Votre validation ne sera pas marquée pour la récupération de place, car une balise orpheline pointant dessus 1.0.0binest suffisante pour la maintenir en vie.

Extraire le fichier binaire

  1. Comment puis-je (ou mes collègues) récupérer le VeryBigBinary.exe dans l'arborescence de travail actuelle? Si votre branche de travail actuelle est par exemple maître, vous pouvez simplement git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. Cela échouera si vous n'avez pas 1.0.0bintéléchargé la balise orpheline , auquel cas vous devrez au git fetch <remote> 1.0.0binpréalable.
  3. Vous pouvez ajouter le VeryBigBinary.exedans votre master .gitignore, afin que personne dans votre équipe ne pollue accidentellement l'historique principal du projet avec le binaire.

Suppression complète du fichier binaire

Si vous décidez de purger complètement VeryBigBinary.exe de votre référentiel local, de votre référentiel distant et des référentiels de vos collègues, vous pouvez simplement:

  1. Supprimer la balise orpheline sur la télécommande git push <remote> :refs/tags/1.0.0bin
  2. Supprimez la balise orpheline localement (supprime toutes les autres balises non référencées) git tag -l | xargs git tag -d && git fetch --tags. Tiré de SO 1841341 avec une légère modification.
  3. Utilisez une astuce git gc pour supprimer localement votre commit désormais non référencé. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@". Il supprimera également tous les autres commits non référencés. Extrait de SO 1904860
  4. Si possible, répétez l'astuce git gc sur la télécommande. C'est possible si vous hébergez vous-même votre référentiel et cela pourrait ne pas être possible avec certains fournisseurs de git, comme github ou dans certains environnements d'entreprise. Si vous hébergez avec un fournisseur qui ne vous donne pas accès ssh à la télécommande, laissez-le. Il est possible que l'infrastructure de votre fournisseur nettoie votre commit non référencé en son temps. Si vous êtes dans un environnement d'entreprise, vous pouvez conseiller à votre service informatique d'exécuter une tâche cron de ramassage de votre télécommande une fois par semaine environ. Qu'ils le fassent ou non n'aura aucun impact sur votre équipe en termes de bande passante et de stockage, tant que vous conseillez à vos collègues de toujours le git clone -b master --single-branch <url>remplacer git clone.
  5. Tous vos collègues qui souhaitent se débarrasser des balises orphelines obsolètes n'ont qu'à appliquer les étapes 2-3.
  6. Vous pouvez ensuite répéter les étapes 1 à 8 de l' ajout de fichiers binaires pour créer une nouvelle balise orpheline 2.0.0bin. Si vous craignez que vos collègues tapent, git fetch <remote> --tagsvous pouvez en fait le nommer à nouveau 1.0.0bin. Cela garantira que la prochaine fois qu'ils récupèrent toutes les balises, les anciennes 1.0.0binne seront pas référencées et marquées pour la récupération de place ultérieure (en utilisant l'étape 3). Lorsque vous essayez d'écraser une balise sur la télécommande, vous devez utiliser -fcomme ceci:git push -f <remote> <tagname>

Épilogue

  • OTABS ne touche pas votre maître ni aucune autre branche de code source / développement. Les hachages de validation, l'ensemble de l'historique et la petite taille de ces branches ne sont pas affectés. Si vous avez déjà gonflé votre historique de code source avec des fichiers binaires, vous devrez le nettoyer comme un travail distinct. Ce script pourrait être utile.

  • Confirmé de fonctionner sur Windows avec git-bash.

  • C'est une bonne idée d'appliquer un ensemble de trics standard pour rendre le stockage des fichiers binaires plus efficace. L'exécution fréquente de git gc(sans aucun argument supplémentaire) permet à git d'optimiser le stockage sous-jacent de vos fichiers en utilisant des deltas binaires. Cependant, s'il est peu probable que vos fichiers restent similaires d'une validation à l'autre, vous pouvez désactiver complètement les deltas binaires. De plus, comme cela n'a aucun sens de compresser des fichiers déjà compressés ou cryptés, comme .zip, .jpg ou .crypt, git vous permet de désactiver la compression du stockage sous-jacent. Malheureusement, c'est un paramètre tout ou rien qui affecte également votre code source.

  • Vous souhaiterez peut-être écrire des parties d'OTABS pour permettre une utilisation plus rapide. En particulier, les étapes de script 2-3 de Suppression complète de fichiers binaires dans un updatehook git pourraient donner une sémantique convaincante mais peut-être dangereuse à git fetch ("chercher et supprimer tout ce qui est obsolète").

  • Vous voudrez peut-être ignorer l'étape 4 de la suppression complète des fichiers binaires pour conserver un historique complet de toutes les modifications binaires sur la télécommande au détriment du ballonnement du référentiel central. Les référentiels locaux resteront légers au fil du temps.

  • Dans le monde Java, il est possible de combiner cette solution avec maven --offlinepour créer une version reproductible hors ligne stockée entièrement dans votre contrôle de version (c'est plus facile avec maven qu'avec gradle). Dans le monde de Golang, il est possible de s'appuyer sur cette solution pour gérer votre GOPATH au lieu de go get. Dans le monde python, il est possible de combiner cela avec virtualenv pour produire un environnement de développement autonome sans compter sur les serveurs PyPi pour chaque build à partir de zéro.

  • Si vos fichiers binaires changent très souvent, comme des objets de construction, il pourrait être une bonne idée de scénario une solution qui stocke 5 la plupart des versions récentes des artefacts dans les balises orphelines monday_bin, tuesday_bin..., friday_binet aussi une étiquette d'orphelin pour chaque version 1.7.8bin 2.0.0bin, etc. Vous pouvez faire pivoter weekday_binet supprimer quotidiennement les anciens fichiers binaires. De cette façon, vous obtenez le meilleur des deux mondes: vous conservez tout l' historique de votre code source mais uniquement l' historique pertinent de vos dépendances binaires. Il est également très facile d'obtenir les fichiers binaires pour une balise donnée sans obtenir le code source entier avec tout son historique: git init && git remote add <name> <url> && git fetch <name> <tag>devrait le faire pour vous.


"Vous devez utiliser périodiquement git gc" - a arrêté la lecture juste là. Pourquoi quelqu'un abandonnerait-il sa dernière ceinture de sécurité au profit d'un hack?
user1643723

@ user1643723 git gcn'est pas dangereux à exécuter. Tous vos commits suspendus seront conservés en toute sécurité sur le disque dur pendant au moins 30 jours par défaut: git-scm.com/docs/git-gc
Adam Kurkiewicz

Merci pour l'écriture détaillée. Je voulais essayer cela comme un moyen de stocker certaines dépendances binaires dans mon référentiel GitHub de telle manière qu'elles ne soient pas téléchargées par défaut lorsque quelqu'un clone le référentiel, mais peuvent être téléchargées manuellement et mettre à jour le référentiel local. Cependant, j'ai eu une erreur à cette étape: git push <remote> 1.0.0bin- remote: error: GH001: Large files detected. You may want to try Git Large File Storage. Il semble que GitHub ne supporte plus cela? Le binaire en question avait une taille de 100 Mo.
user5359531

1
Pour être tout à fait honnête, si vous êtes autorisé à utiliser github pour votre travail, qu'est-ce qui vous empêche d'utiliser LFS? Les gars de github ont travaillé dur pour créer ce produit, et ils l'hébergent même pour vous et leur infrastructure est optimisée pour l'utiliser. Ce hack est destiné aux situations où vous ne pouvez vraiment pas utiliser LFS ou d'autres tiers et que vous recherchez une solution pure-git.
Adam Kurkiewicz

J'ai également mis à jour la réponse pour être plus clair sur le degré de piratage de cette solution.
Adam Kurkiewicz

13

À mon avis, si vous êtes susceptible de modifier souvent ces gros fichiers, ou si vous avez l'intention de faire beaucoup de git cloneou git checkout, alors vous devriez sérieusement envisager d'utiliser un autre référentiel Git (ou peut-être une autre façon d'accéder à ces fichiers).

Mais si vous travaillez comme nous le faisons et si vos fichiers binaires ne sont pas souvent modifiés, le premier clone / extraction sera long, mais après cela, il devrait être aussi rapide que vous le souhaitez (compte tenu du fait que vos utilisateurs continuent d'utiliser le premier référentiel cloné, ils eu).


13
Et, les repos séparés ne raccourciront pas le temps de paiement, car vous devez toujours vérifier les deux repos!
Emil Sit

Le repo séparé @EmilSit pourrait rendre la commande beaucoup plus courte si vous nettoyez régulièrement l'historique du "repo binaire". De plus, les développeurs ne seraient pas obligés de vérifier les deux dépôts à chaque fois .
FabienAndre

Pourquoi ne pas simplement demander au script de construction du module principal de récupérer les fichiers binaires du deuxième dépôt, en les extrayant un par un (comme ici: stackoverflow.com/questions/1125476/… ).
akauppi

1
Même si vos fichiers binaires ne sont pas modifiés fréquemment, les fichiers volumineux peuvent toujours tuer votre flux de travail si vous poussez souvent des branches vers le référentiel à des fins de collaboration.
Timo Reimann,

9

SVN semble gérer les deltas binaires plus efficacement que Git.

J'ai dû choisir un système de version pour la documentation (fichiers JPEG, fichiers PDF et fichiers .odt). Je viens de tester l'ajout d'un fichier JPEG et sa rotation à 90 degrés quatre fois (pour vérifier l'efficacité des deltas binaires). Le référentiel de Git a augmenté de 400%. Le référentiel de SVN n'a augmenté que de 11%.

Il semble donc que SVN soit beaucoup plus efficace avec les fichiers binaires.

Mon choix est donc Git pour le code source et SVN pour les fichiers binaires comme la documentation.


33
Vous aviez juste besoin d'exécuter "git gc" (reconditionnement et collecte des ordures) après avoir ajouté ces 4 fichiers. Git ne compresse pas immédiatement tout le contenu ajouté, de sorte que vous aurez une compression de groupe de fichiers (qui est plus efficace en termes de taille) et ne ralentirez pas la compression séparée de chaque objet ajouté. Mais même sans "git gc", git aurait finalement fait la compression pour vous (après avoir remarqué que suffisamment d'objets déballés se sont accumulés).
rossignol du

24
@jpierson J'ai créé un référentiel git vide et ajouté (et validé) une image bmp entièrement blanche avec une taille de 41 Mo, cela a abouti à un référentiel git total avec une taille de 328 Ko. Après un, git gcla taille totale du référentiel git a été réduite à 184 Ko. Ensuite, j'ai changé un seul pixel du blanc au noir et j'ai validé ce changement, la taille totale du référentiel git est passée à 388 Ko, et après une git gctaille du référentiel git total a été réduite à 184 Ko. Cela montre que git est assez bon pour compresser et trouver des deltas de fichiers binaires.
Tader

6
@jpierson A sidenote: Je viens de commenter les deltas binaires. Git va manger toute votre mémoire et échanger s'il gère des référentiels avec des fichiers volumineux (taille GB). Pour cela, utilisez git-annex (déjà mentionné dans une autre réponse) ...
Tader

12
@JanDvorak - personne ne l'a mentionné, car c'est complètement faux. Les copies de Subversion sont bon marché - svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html - vers le milieu de la page.
Joris Timmermans

12
@Tader: votre test est mauvais. Ce que vous appelez un fichier binaire ressemble en fait (du point de vue de git) à un fichier texte - le train de bits est aligné sur les octets, et il y a des différences significatives et localisées à faire; après tout, changer un pixel équivaut à changer un caractère dans un fichier texte (et qui utilise des bitmaps non compressés de nos jours?) Essayez la même expérience avec une petite vidéo, une image compressée, une machine virtuelle, un fichier zip ou autre - et vous trouverez ce git ne gère pas efficacement le delta; en effet, c'est fondamentalement impossible avec des données incompressibles.
Eamon Nerbonne

4

git clone --filter de Git 2.19 + clones peu profonds

Cette nouvelle option pourrait éventuellement devenir la solution finale au problème des fichiers binaires, si les développeurs Git et GitHub le rendent suffisamment convivial (ce qu'ils n'ont sans doute toujours pas atteint pour les sous-modules par exemple).

Il permet de récupérer uniquement les fichiers et répertoires que vous souhaitez pour le serveur et a été introduit avec une extension de protocole à distance.

Avec cela, nous pourrions d'abord faire un clone superficiel, puis automatiser les blobs à récupérer avec le système de build pour chaque type de build.

Il en existe déjà un --filter=blob:limit<size>qui permet de limiter la taille maximale des blobs à récupérer.

J'ai fourni un exemple détaillé minimal de l'apparence de la fonctionnalité: Comment puis-je cloner un sous-répertoire uniquement d'un référentiel Git?


2

Je recherche des avis sur la façon de gérer les gros fichiers binaires dont dépend mon code source (application web). Quelles sont vos expériences / réflexions à ce sujet?

Personnellement, j'ai rencontré des échecs de synchronisation avec Git avec certains de mes hôtes cloud une fois que mes données binaires d'applications Web ont dépassé la barre des 3 Go . J'avais envisagé BFT Repo Cleaner à l'époque, mais c'était comme un hack. Depuis lors, j'ai commencé à garder les fichiers en dehors de Git, au lieu d' utiliser des outils spécialement conçus comme Amazon S3 pour gérer les fichiers, la gestion des versions et la sauvegarde.

Quelqu'un a-t-il de l'expérience avec plusieurs référentiels Git et les gère-t-il dans un seul projet?

Oui. Les thèmes Hugo sont principalement gérés de cette façon. C'est un peu maladroit, mais ça fait le travail.


Ma suggestion est de choisir le bon outil pour le travail . Si c'est pour une entreprise et que vous gérez votre ligne de code sur GitHub, payez l'argent et utilisez Git-LFS. Sinon, vous pourriez explorer des options plus créatives telles que le stockage de fichiers crypté décentralisé à l' aide de la chaîne de blocs .

Les options supplémentaires à considérer incluent Minio et s3cmd .


0

Jetez un oeil à camlistore . Ce n'est pas vraiment basé sur Git, mais je le trouve plus approprié pour ce que vous devez faire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.