2011-11-03 20 views
46

Lo scenarioPuò git trattare i file zip come directory e file all'interno dello zip come blob?

Immaginate sono costretto a lavorare con alcuni dei miei file sempre memorizzati all'interno .zip file. Alcuni dei file all'interno del file zip sono piccoli file di testo e cambiano spesso, mentre altri sono più grandi ma per fortuna piuttosto statici (ad esempio immagini).

Se voglio inserire questi file zip all'interno di un repository git, ogni zip viene trattato come un blob, quindi ogni volta che commetto il repository cresce in base alla dimensione del file zip ... anche se all'interno è presente solo un piccolo file di testo cambiato!

Perchè questo è realistico

MS Word ed Excel 2007/2010 .docx.xlsx file sono file ZIP ...

Quello che voglio

è lì, per caso, un modo per dire a git di non considerare le zip come file, ma piuttosto come directory e come trattare i loro contenuti come file?

I vantaggi

  • molto più piccole dimensioni pronti contro termine, vale a dire più veloce di trasferimento/backup
  • Display changes with Git to zip's sarebbe automagically lavorare

Ma non poteva lavorare, che dici?

mi rendo conto che senza i metadati in più questo porterebbe a una certa quantità di ambiguità: su una git git checkout dovrebbe decidere se creare foo.zip/bar.txt come un file in una directory regolare o un file zip. Tuttavia questo potrebbe essere risolto attraverso le opzioni di configurazione, penserei.

Due idee come potrebbe essere fatto (se non esiste ancora)

  • utilizzando una libreria come minizip o IO::Compress::Zip all'interno git
  • in qualche modo l'aggiunta di uno strato di file system in modo tale che in realtà git vede i file zip come directory per iniziare con
+1

Lo scenario con '.docx 'i file hanno senso, ma in molti altri casi si potrebbe voler considerare il tracciamento dei singoli file normalmente con git e solo * costruire * il risultante' .zip' usando uno strumento di compilazione appropriato come 'make'. – pixelistik

+0

Considerando che due file zip che sembrano diversi tra loro possono contenere gli stessi dati esatti (ad esempio un file di testo zippato due volte con due diversi livelli di compressione), questo diventa molto più complicato. Mentre è facile rappresentare la differenza tra le due versioni dei file decompressi con poche informazioni, suppongo che rappresenti la differenza tra le due versioni dell'archivio (che è essenzialmente ciò che deve fare git) con circa il minimo di informazioni che sarebbero non -banale. – HelloGoodbye

+0

Hai mai avuto una soluzione implementata di [risposta di Jeff] (https://stackoverflow.com/a/8001900/321973) o qualcos'altro? Mi chiedo fondamentalmente la stessa eccezione [per gli archivi tar] (https://stackoverflow.com/q/37000849/321973), che dovrebbe fornire una risposta compatibile ... –

risposta

15

questo non esiste, ma potrebbe facilmente esistere in il quadro attuale. Proprio come git agisce in modo diverso con la visualizzazione di file binari o ascii durante l'esecuzione di una diff, potrebbe essere detto di offrire un trattamento speciale a determinati tipi di file attraverso l'interfaccia di configurazione.

Se non si desidera modificare il codice di base (sebbene si tratti di un'idea interessante), è possibile anche copiarlo manualmente utilizzando pre-commit and post-checkout hooks per decomprimere e archiviare i file, quindi restituirli al loro stato .zip alla cassa. Dovresti limitare le azioni solo a quei file blob/indici specificati da git add.

In entrambi i casi è un po 'di lavoro - è solo una questione di sapere se l'altro git è consapevole di cosa sta succedendo e gioca bene.

+0

Gli hook sembrano una buona direzione da guardare dentro; Ci ho pensato brevemente ma non ero sicuro che potesse funzionare. L'hook pre-commit può modificare sia il file system che l'area di staging? –

+1

@Jonas Hai mai finito per fare questo ed esiste la possibilità che tu pubblichi una soluzione funzionante? Mi piacerebbe tracciare utilmente le modifiche ai fogli di calcolo in git e CSV non è adatto ai nostri scopi. – Ruben

+0

Scusate, non ho mai seguito questo da solo ... –

2

Penso che avremo bisogno di montare un file zip sul filesystem. Non ho usato, ma prendere in considerazione FUSE:

http://code.google.com/p/fuse-zip/

C'è ZFS anche per Windows e Linux:

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

+0

Se ho capito bene, fuse-zip potrebbe sovrapporsi tra il file system e git, ma zfs dovrebbe essere compilato * in * 'git', giusto? Peccato che non sono sempre sotto Linux con quel repository, altrimenti fusibile-zip sarebbe una bella idea. –

2

Spesso ci sono problemi con i file pre-zippati per le applicazioni in quanto si aspettano che il metodo di compressione zip e l'ordine dei file siano quelli che hanno scelto. Credo che i file .odf di open office abbiano questo problema.

Detto questo, se si sta semplicemente utilizzando any-old-zip come metodo per tenere insieme le cose, si dovrebbe essere in grado di creare alcuni alias semplici che si decomprimono e si ricollegano quando richiesto. L'ultimo Msysgit (noto anche come Git per Windows) ora ha zip e unzip sul lato del codice shell, quindi puoi usarli in alias.

Il progetto su cui sto attualmente lavorando su utilizza cerniere come il principale locale controllo di versione/archivio, quindi sto anche cercando di ottenere una serie di alias praticabile per succhiare queste centinaia di cerniere in git (e farli uscire di nuovo ;-) in modo che i collaboratori siano felici.

+3

Ho appena fatto alcuni test per Word 2010 - sembra abbastanza tollerante ('deflate' con diverse dimensioni di parola,' deflate64' e cambiando l'ordine dei file nel file zip prodotto da 7zip tutto non ha buttato Word fuori). Per quanto riguarda l'utilizzo di alias, speravo di evitare qualsiasi passaggio manuale aggiuntivo ... attualmente la maggior parte dei miei commit passa attraverso TortoiseGit. –

9

Usa bup (presentata in dettaglio in GitMinutes #24)

E 'l'unico sistema di git-like progettato per gestire grandi (anche molto molto grandi) file, il che significa che tutte le versioni di un file zip aumenterà solo il repo dal suo delta (invece di una copia aggiuntiva completa)

Il risultato è un vero repository git, che un normale comando Git può leggere.

I dettagli come bup differisce da Git in "git with large files".


Qualsiasi altra soluzione (come git-annex) non è del tutto soddisfacente, come descritto in "git-annex with large files".

+1

Questo sembra molto orientato verso file molto grandi, lo scenario era orientato più verso XML come docx e xlsx (che sono spesso abbastanza piccoli) compresso. Otterrai una dimensione di pronti contro termine più piccola con bup, ma ti piacerebbe conoscere i cambiamenti effettivi nell'XML? – Ruben

+0

@Ruben questo è orientato verso file di grandi dimensioni o in numero. Ma non è molto diverso da Git in termini di diff. – VonC

+0

Sembra interessante, ma puoi usarlo con il tuo vero repository git? – kutschkem

5

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

(Nota: per ogni commento da Ruben, questo è solo su come ottenere un diff corretta, però, non si tratta di commettere file decompressi.)

Aprire il file ~/.gitconfig (se creare non esistente già) e aggiungere la seguente stanza:

[diff "zip"] = Textconv decomprimere -c -a

cosa d oes sta usando "unzip -c -a FILENAME" per convertire il file zip in testo ASCII (decomprimere -c decomprime in STDOUT). La prossima cosa è creare/modificare il file REPOSITORY/.gitattributes e aggiungere il seguente

*.pptx diff = zip

che racconta git per usare la descrizione zip-diffing dalla configurazione per file mathcing la maschera data (in questo caso tutto termina con .pptx). Ora git diff decomprime automaticamente i file e diff l'output ASCII che è un po 'meglio di solo "i file binari differiscono". D'altra parte per il caos contorto che il corrispondente XML di file pptx è, non aiuta molto ma per i file ZIP tra cui il testo (come ad esempio gli archivi del codice sorgente) questo è in realtà abbastanza a portata di mano.

+0

Si tratta solo di ottenere una corretta diff anche se non di commettere file decompressi .. – Ruben

+0

Grazie. Questo risponde alla domanda che volevo risolvere, di mostrare le modifiche ai file di testo all'interno dei miei file gzip quando 'git diff'ing. Ho usato '[diff" gzip "] = zcat' e' * .gz diff = gzip'. – spazm

10

Non sono sicuro se qualcuno è ancora interessato a questa domanda. Sto affrontando gli stessi problemi e qui è la mia soluzione che utilizza il filtro file git.

Modifica: In primo luogo, potrei non dirlo chiaro, ma questo IS una risposta alla domanda dell'OP! Leggi l'intera frase prima di commentare. Inoltre, grazie a @Toon Krijthe per il consiglio di chiarire la soluzione in atto.

La mia soluzione è utilizzare un filtro per "flat" il file zip in un file di testo espanso (potrebbe essere enorme) monolitico. Durante git add/commit il file zip verrà automaticamente espanso in questo formato di testo per la normale diffusione del testo, e durante il checkout verrà automaticamente riavviato.

Il file di testo è composto da record, ognuno rappresenta un file nel file zip. Quindi puoi dire che questo file di testo è un'immagine di testo per lo zip originale. Se il file nel file zip è di testo, viene copiato nel file di testo; in caso contrario, viene codificato in base 64 prima di essere copiato nel file di formato testo. Ciò mantiene il file di testo sempre un file di testo.

Anche se questo filtro non rende ogni file nello zip un blob, i file di testo sono mappati da linea a linea, che è l'unità del diff, mentre i cambiamenti dei file binari possono essere rappresentati dagli aggiornamenti della base64 corrispondente, penso questo è equivalente a ciò che l'OP immagina.

Per maggiori dettagli e un codice di prototipazione si può leggere il seguente link:

Zippey Git file filter

Inoltre, il credito al luogo che mi ha ispirato di questa soluzione: Description of how file filter works

+0

Questo filtro è ancora in fase di sviluppo, se avete domande o suggerimenti fatemelo sapere. – Sippey

+1

Ho provato questo e penso che dovrebbe funzionare bene per me. Vorrei solo aggiungere qualcosa alla documentazione che il file di testo lista zippey.py deve essere modificato per includere tutti i tipi di file che vuoi zippey.py riconoscere come file di testo. – mteng

+0

Questo filtro funziona alla grande! Grazie mille per aver postato questo. –