web-dev-qa-db-fra.com

Git peut-il traiter les fichiers Zip comme des répertoires et les fichiers à l'intérieur du Zip comme des blobs?

Le scénario

Imaginez que je suis obligé de travailler avec certains de mes fichiers toujours stockés dans .Zip des dossiers. Certains fichiers à l'intérieur du Zip sont de petits fichiers texte et changent souvent, tandis que d'autres sont plus gros mais heureusement plutôt statiques (par exemple des images).

Si je veux placer ces fichiers Zip dans un référentiel git, chaque Zip est traité comme un blob, donc chaque fois que je valide le référentiel croît de la taille du fichier Zip ... même si un seul petit fichier texte l'intérieur a changé!

Pourquoi c'est réaliste

MS Word 2007/2010 .docx et Excel .xlsx les fichiers sont des fichiers Zip ...

Ce que je veux

Existe-t-il, par hasard, un moyen de dire à git de ne pas traiter les zips comme des fichiers, mais plutôt comme des répertoires et de traiter leur contenu comme des fichiers?

Les avantages

Mais ça ne pouvait pas marcher, dites-vous?

Je me rends compte que sans métadonnées supplémentaires, cela conduirait à une certaine ambiguïté: sur un git checkout git devrait décider de créer foo.Zip/bar.txt en tant que fichier dans un répertoire normal ou un fichier Zip. Cependant, cela pourrait être résolu grâce aux options de configuration, je pense.

Deux idées sur la façon de procéder (si elle n'existe pas encore)

  • en utilisant une bibliothèque telle que minizip ou IO::Compress::Zip dans git
  • en quelque sorte, ajouter une couche de système de fichiers de telle sorte que git voit réellement les fichiers Zip comme des répertoires pour commencer
65
Jonas Heidelberg

Cela n'existe pas, mais cela pourrait facilement exister dans le cadre actuel. Tout comme git agit différemment avec l'affichage des fichiers binaires ou ascii lors de l'exécution d'un diff, on pourrait lui dire d'offrir un traitement spécial à certains types de fichiers via l'interface de configuration.

Si vous ne voulez pas changer la base de code (bien que ce soit une idée géniale que vous avez), vous pouvez également l'écrire pour vous-même en utilisant crochets pré-commit et post-checkout pour décompresser et stocker les fichiers, puis les remettre dans leur état .Zip à la caisse. Vous devez restreindre les actions aux seuls blobs/index de fichiers spécifiés par git add.

Dans les deux cas, c'est un peu de travail - c'est juste une question de savoir si les autres git félicitent sont conscients de ce qui se passe et jouent bien.

21
Jeff Ferland

Je ne sais pas si quelqu'un est toujours intéressé par cette question. Je suis confronté aux mêmes problèmes et voici ma solution qui utilise le filtre de fichiers git.

Edit: Tout d'abord, je ne peux pas le dire clairement, mais ceci [~ # ~] est [~ # ~] une réponse à la question du PO! Lisez toute la phrase avant de commenter. De plus, merci à @Toon Krijthe pour les conseils pour clarifier la solution en place.

Ma solution consiste à utiliser un filtre pour "mettre à plat" le fichier Zip dans un fichier texte monolithique étendu (peut-être énorme). Pendant l'ajout/la validation de git, le fichier Zip sera automatiquement étendu à ce format de texte pour une différence de texte normale, et lors du paiement, il sera automatiquement zippé à nouveau.

Le fichier texte est composé d'enregistrements, chacun représente un fichier dans le Zip. Vous pouvez donc penser que ce fichier texte est une image textuelle pour le Zip d'origine. Si le fichier dans le Zip est du texte en acte, il est copié dans le fichier texte; sinon, il est codé en base64 avant d'être copié dans le fichier au format texte. Cela conserve le fichier texte toujours un fichier texte.

Bien que ce filtre ne fasse pas de chaque fichier du Zip un blob, les fichiers texte sont mappés ligne à ligne, qui est l'unité du diff, tandis que les modifications des fichiers binaires peuvent être représentées par des mises à jour de leur base64 correspondante, je pense que cela équivaut à ce que l'OP imagine.

Pour plus de détails et un code de prototypage, vous pouvez lire le lien suivant:

filtre de fichier Zippey Git

Aussi, crédit à l'endroit qui m'a inspiré cette solution: Description du fonctionnement du filtre de fichiers

13
Sippey

Utilisez bup (présenté en détail dans GitMinutes # 24 )

C'est le seul système semblable à Git conçu pour traiter des fichiers volumineux (même très très gros), ce qui signifie que chaque version d'un fichier Zip ne fera qu'augmenter le dépôt de son delta (au lieu d'un copie supplémentaire complète)

Le résultat est un véritable dépôt git, qu'une commande Git ordinaire peut lire.

Je détaille comment bup diffère de Git dans " git avec de gros fichiers ".


Toute autre solution de contournement (comme git-annex) n'est pas entièrement satisfaisant, comme détaillé dans " git-annex avec des fichiers volumineux ".

11
VonC

http://tante.cc/2010/06/23/managing-Zip-based-file-formats-in-git/

(Remarque: par commentaire de Ruben , il s'agit uniquement d'obtenir un diff approprié, pas de valider des fichiers décompressés.)

Ouvrez votre fichier ~/.gitconfig (créez s'il n'existe pas déjà) et ajoutez la strophe suivante:

[diff "Zip"] textconv = décompressez -c -a

Ce qu'il fait, c'est d'utiliser "unzip -c -a FILENAME" pour convertir votre fichier zip en ASCII texte (décompressez -c décompresse en STDOUT). La prochaine chose est de créer/modifier le fichier REPOSITORY /. gitattributes et ajoutez ce qui suit

* .pptx diff = Zip

qui indique à git d'utiliser la description Zip-diffing de la configuration pour les fichiers calculant le masque donné (dans ce cas, tout se terminant par .pptx). Maintenant, git diff décompresse automatiquement les fichiers et diffs la sortie ASCII qui est un peu mieux que simplement "les fichiers binaires diffèrent". D'autre part, au désordre alambiqué que le XML correspondant des fichiers pptx est, cela n'aide pas beaucoup mais pour les fichiers Zip incluant du texte (comme par exemple les archives de code source) c'est en fait assez pratique.

5
user649198

Je pense que vous allez avoir besoin de monter un fichier Zip sur le système de fichiers. Je ne l'ai pas utilisé, mais considérez Fuse:

http://code.google.com/p/Fuse-Zip/

Il existe également ZFS pour Windows et Linux:

http://users.telenet.be/tfautre/softdev/zfs/

2
Brad

Il y a souvent des problèmes avec les fichiers pré-zippés pour les applications car ils s'attendent à ce que la méthode de compression Zip et l'ordre des fichiers soient ceux qu'ils ont choisis. Je pense que les fichiers Open Office .odf ont ce problème.

Cela dit, si vous utilisez simplement any-old-Zip comme méthode pour garder les choses ensemble, vous devriez être en mesure de créer quelques alias simples qui dézipperont et recompresseront si nécessaire. Le tout dernier Msysgit (alias Git pour Windows) a maintenant à la fois Zip et décompressez sur le côté du code Shell afin que vous puissiez les utiliser dans les alias.

Le projet sur lequel je travaille actuellement utilise des zips comme principal contrôle/archive de la version locale, donc j'essaie également d'obtenir un ensemble d'alias utilisables pour aspirer ces centaines de zips dans git (et les retirer à nouveau ;-) donc que les collègues sont heureux.

2
Philip Oakley

Rezip , similaire à Zippey by sippey , permet de gérer les fichiers Zip de manière plus agréable avec git.

Comment ça fonctionne

Lors de l'ajout/validation d'un fichier basé sur Zip, Rezip le décompresse et le recompresse sans compression, avant de l'ajouter à l'index/commit. Dans un fichier Zip non compressé, les fichiers archivés apparaissent tels quels dans leur contenu (avec quelques méta-informations binaires avant chaque fichier). Si ces fichiers archivés sont des fichiers en texte brut, cette méthode fonctionnera bien avec git.

Avantages

Le principal avantage de Rezip sur Zippey est que le fichier réel stocké dans le référentiel est toujours un fichier Zip. Ainsi, dans de nombreux cas, il fonctionnera toujours tel quel avec l'application respective (par exemple Open Office), même s'il est obtenu sans passer par un filtre de reconditionnement avec compression.

Comment utiliser

Installez le ou les filtres sur votre système:

mkdir -p ~/bin
cd ~/bin

# Download the filer executable
wget https://github.com/costerwi/rezip/blob/master/Rezip.class

# Install the add/commit filter
git config --global --replace-all filter.rezip.clean "Java -cp ~/bin Rezip --store"

# (optionally) Install the checkout filter
    git config --global --add filter.rezip.smudge "Java -cp ~/bin Rezip"

Utilisez le filtre dans votre référentiel, en ajoutant des lignes comme celles-ci à votre <repo-root>/.gitattributes fichier:

[attr]textual     diff merge text
[attr]rezip       filter=rezip textual

# MS Office
*.docx  rezip
*.xlsx  rezip
*.pptx  rezip
# OpenOffice
*.odt   rezip
*.ods   rezip
*.odp   rezip
# Misc
*.mcdx  rezip
*.slx   rezip

La partie textual est telle que ces fichiers sont réellement affichés sous forme de fichiers texte dans diffs.

2
hoijui