Gestire file binari di grandi dimensioni con Git


523

Sto cercando opinioni su come gestire file binari di grandi dimensioni da cui dipende il mio codice sorgente (applicazione web). Stiamo attualmente discutendo diverse alternative:

  1. Copia i file binari a mano.
    • Pro: Non sono sicuro.
    • Contro: sono fortemente contrario a questo, poiché aumenta la probabilità di errori durante la creazione di un nuovo sito / la migrazione di quello vecchio. Costruisce un altro ostacolo da affrontare.
  2. Gestiscili tutti con Git .
    • Pro: rimuove la possibilità di "dimenticare" di copiare un file importante
    • Contra: blocca il repository e diminuisce la flessibilità per gestire la base di codice e i checkout, i cloni, ecc. Impiegheranno molto tempo.
  3. Repository separati.
    • Pro: il checkout / la clonazione del codice sorgente è più veloce che mai e le immagini sono correttamente archiviate nel proprio repository.
    • Contra: rimuove la semplicità di avere l'unico e solo repository Git sul progetto. Sicuramente introduce alcune altre cose a cui non ho pensato.

Quali sono le tue esperienze / pensieri riguardo a questo?

Inoltre: qualcuno ha esperienza con più repository Git e gestendoli in un progetto?

I file sono immagini per un programma che genera PDF con quei file al suo interno. I file non cambieranno molto spesso (come negli anni), ma sono molto rilevanti per un programma. Il programma non funzionerà senza i file.


26
Che dire di quando è necessaria la versione che controlla il file binario? Sto pensando a team di artisti che lavorano su risorse.
Dan,

3
Se è necessario, è necessario bilanciare le risorse disponibili (disco, larghezza di banda, tempo della CPU) con i vantaggi che si ottengono.
pi.

4
Nota che senza il blocco dei file, git non è eccezionale quando più persone devono lavorare sullo stesso file binario.
yoyo


Risposte:


177

Se il programma non funziona senza i file, sembra che dividerli in un repository separato sia una cattiva idea. Disponiamo di ampie suite di test che suddividiamo in un repository separato, ma si tratta in realtà di file "ausiliari".

Tuttavia, potresti essere in grado di gestire i file in un repository separato e quindi utilizzarli git-submoduleper inserirli nel tuo progetto in modo sano. Quindi, avresti ancora la cronologia completa di tutta la tua fonte ma, a quanto ho capito, avresti solo una revisione pertinente del tuo sottomodulo di immagini. La git-submodulestruttura dovrebbe aiutarti a mantenere la versione corretta del codice in linea con la versione corretta delle immagini.

Ecco una buona introduzione ai sottomoduli di Git Book.


11
"A quanto ho capito, avresti solo una revisione pertinente del tuo sottomodulo di immagini." Non penso sia corretto.
Robin Green,

22
Infatti. Un sottomodulo è un repository Git completo, che è semplicemente nidificato all'interno del repository padre. Conosce tutta la sua storia. Potresti impegnarti meno frequentemente in esso, ma se memorizzi le stesse cose che avresti nel genitore, avrà gli stessi problemi che il genitore avrebbe.
Cascabel,

5
Questa è una soluzione piuttosto scadente se si dispone di file binari di grandi dimensioni che cambiano a intervalli regolari. Abbiamo un repository orribilmente gonfio perché un nuovo file binario viene archiviato con ogni build. Se non sei su Windows, come indicato di seguito, l'allegato è una buona soluzione. Se sei su Windows ... dovrai solo continuare a cercare.
AA Grapsas,

4
Un altro problema nell'avere file binari di grandi dimensioni nel repository sono le prestazioni. Git non è stato progettato per far fronte a file binari di grandi dimensioni e una volta che la dimensione del repository sale a 3G +, le prestazioni diminuiscono rapidamente. Ciò significa che avere grandi file binari nel repository limita le opzioni di hosting.
zoul,

I sottomoduli possono ridurre i requisiti di trasferimento dei dati di checkout se si utilizza in modo creativo il sottomodulo: quando si desidera aggiornare il contenuto del sottomodulo, creare un nuovo commit senza un genitore e quindi puntare superprogetto (repository git principale) al commit appena creato senza un genitore. Logicamente questo crea una cronologia disconnessa per il sottomodulo ma, in cambio, qualsiasi versione del sottomodulo è più facile da trasferire perché quella versione non ha cronologia.
Mikko Rantalainen,

310

Recentemente ho scoperto git-annex che trovo fantastico. È stato progettato per gestire in modo efficiente file di grandi dimensioni. Lo uso per le mie raccolte di foto / musica (ecc.). Lo sviluppo di git-annex è molto attivo. Il contenuto dei file può essere rimosso dal repository Git, solo la gerarchia dell'albero viene tracciata da Git (tramite collegamenti simbolici). Tuttavia, per ottenere il contenuto del file, dopo il pull / push è necessario un secondo passaggio, ad esempio:

$ 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

Ci sono molti comandi disponibili e c'è un'ottima documentazione sul sito web. Un pacchetto è disponibile su Debian .


11
Whoa! Miglioramento per la bellezza! Questo implementa un'idea che ho avuto di recente e molto altro. È scritto in Haskell non meno. comunque, git-media è una buona alternativa.
cdunn2001,

33
Ma l'allegato non supporta Windows. Il che è problematico per gli sviluppatori di giochi.
AA Grapsas,

7
Ho sentito che Steam sta abbandonando il supporto per Windows e aggiungendo seriamente il supporto per Linux ...;), quanto può essere difficile portarlo? Suppongo che il tuo sviluppatore di giochi medio potrebbe farlo.
Sam Watkins,

4
@EstebanBrenes Il vero punto di svolta è che nella normale configurazione i symlink di Windows richiedono privilegi elevati per la creazione.
Laurens Holst,

4
Ho appena trovato questa pagina . Si legge che ora git annexè disponibile anche su Windows . Se qualcuno lo ha mai testato su Windows, mi piacerebbe conoscere la sua esperienza!
Kouichi C. Nakamura,

49

Un'altra soluzione, da aprile 2015 è Git Large File Storage (LFS) (di GitHub).

Utilizza git-lfs (consultare git-lfs.github.com ) e testato con un server che lo supporta: lfs-test-server :
è possibile archiviare i metadati solo nel repository git e il file di grandi dimensioni altrove.

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


3
lfs-test-serverè dichiarato non destinato alla produzione. In realtà, sto lavorando al server LFS di produzione ( github.com/artemkin/git-lfs-server ). È in corso, ma è già utilizzabile e lo stiamo testando internamente.
Stas,

Puoi controllare le versioni precedenti di tale file binario usando git lfs?
mucaho,

1
@mucaho Dovresti: la sintassi di git checkout è invariata e lo script lfs smudge dovrebbe comunque essere chiamato.
VonC

31

Dai un'occhiata a git bup, che è un'estensione Git per archiviare in modo intelligente file binari di grandi dimensioni in un repository Git.

Dovresti averlo come sottomodulo, ma non dovrai preoccuparti che il repository diventi difficile da gestire. Uno dei loro casi d'uso di esempio è l'archiviazione di immagini VM in Git.

In realtà non ho visto tassi di compressione migliori, ma i miei repository non hanno binari molto grandi.

Il tuo chilometraggio può variare.


3
bup fornisce spazio di archiviazione (utilizzando internamente archivi di parità per ridondanza e git per compressione, dedup e cronologia), ma non estende git. git-annex è un'estensione git che fornisce un backend di archiviazione bup .
Tobu,

@Tobu quando l'ho pubblicato, l'allegato git non esisteva ancora (nelle versioni principali)
visto il

2
bup è sicuramente interessante per la gestione di file di grandi dimensioni. Volevo sottolineare una differenza nell'interfaccia utente: usi i comandi bup al di fuori di qualsiasi contesto di repository e git è un dettaglio di implementazione.
Tobu,

27

Puoi anche usare git-fat . Mi piace che dipende solo da Python e rsync. Supporta anche il solito flusso di lavoro Git, con i seguenti comandi autoesplicativi:

git fat init
git fat push
git fat pull

Inoltre, è necessario archiviare un file .gitfat nel repository e modificare i propri .gitattributes per specificare le estensioni dei file che si desidera git fatgestire.

Aggiungete un binario usando il normale git add, che a sua volta invoca in git fatbase alle regole di gitattributes.

Infine, ha il vantaggio che la posizione in cui sono effettivamente archiviati i file binari può essere condivisa tra repository e utenti e supporta qualsiasi rsynccosa.

AGGIORNAMENTO: non utilizzare git-fat se si utilizza un bridge Git-SVN. Finirà per rimuovere i file binari dal tuo repository Subversion. Tuttavia, se stai usando un repository Git puro, funziona magnificamente.


26

Vorrei utilizzare i sottomoduli (come Pat Notz) o due repository distinti. Se modifichi i tuoi file binari troppo spesso, proverei a ridurre al minimo l'impatto dell'enorme repository che pulisce la cronologia:

Ho avuto un problema molto simile diversi mesi fa: ~ 21 GB di file MP3, non classificati (cattivi nomi, cattivi ID3, non so se mi piace quel file MP3 o meno ...) e replicati su tre computer.

Ho usato un disco rigido esterno con il repository Git principale e l'ho clonato in ogni computer. Quindi, ho iniziato a classificarli in modo abituale (spingendo, tirando, fondendo ... eliminando e rinominando molte volte).

Alla fine, avevo solo ~ 6 GB di file MP3 e ~ 83 GB nella directory .git. Ho usato git-write-treee git-commit-treeper creare un nuovo commit, senza antenati del commit, e ho avviato un nuovo ramo che punta a quel commit. Il "registro git" per quel ramo mostrava solo un commit.

Quindi, ho eliminato il vecchio ramo, mantenuto solo il nuovo ramo, cancellato i ref-log ed eseguito "git prune": dopo ciò, le mie cartelle .git pesavano solo ~ 6 GB ...

Di tanto in tanto potresti "eliminare" l'enorme repository allo stesso modo: i tuoi "git clone" saranno più veloci.


Una volta ho fatto qualcosa di simile in cui ho dovuto dividere un repository che ho fuso accidentalmente in due distinti. Modello di utilizzo interessante però. :)
pi.

1
Sarebbe lo stesso di solo: rm -f .git; git init; git add. ; git commit -m "Elimina la cronologia."
Pat Notz,

1
Sì, è lo stesso solo nella mia custodia mp3. Ma a volte non vuoi toccare i tuoi rami e tag (nessuna riduzione dello spazio nei repository pubblici) ma vuoi velocizzare un "clone git / fetch / pull" di un solo ramo (meno spazio per dedicato a quello repository di filiali).
Daniel Fanjul,

13

La soluzione che vorrei proporre è basata su rami orfani e un leggero abuso del meccanismo dei tag, d'ora in poi denominato * Orphan Tags Binary Storage (OTABS)

TL; DR 12-01-2017 Se è possibile utilizzare LFS di github o qualche altra terza parte, si dovrebbe assolutamente. Se non puoi, continua a leggere. Attenzione, questa soluzione è un trucco e dovrebbe essere trattata come tale.

Proprietà desiderabili di OTABS

  • è una soluzione git e git pura - fa il suo lavoro senza software di terze parti (come git-annex) o infrastruttura di terze parti (come LFS di github).
  • memorizza i file binari in modo efficiente , ovvero non gonfia la cronologia del repository.
  • git pulle git fetch, inclusi git fetch --allsono ancora efficienti in termini di larghezza di banda , ovvero non tutti i file binari di grandi dimensioni vengono estratti dal telecomando per impostazione predefinita.
  • funziona su Windows .
  • memorizza tutto in un unico repository git .
  • consente la cancellazione di file binari obsoleti (a differenza di bup).

Proprietà indesiderabili di OTABS

  • rende git clonepotenzialmente inefficiente (ma non necessariamente, a seconda dell'utilizzo). Se distribuisci questa soluzione, potresti dover consigliare ai tuoi colleghi di utilizzare git clone -b master --single-branch <url>invece di git clone. Questo perché git clone per impostazione predefinita clona letteralmente l' intero repository, incluse cose su cui normalmente non si vorrebbe sprecare la larghezza di banda, come commit senza riferimenti. Tratto da SO 4811434 .
  • rende la git fetch <remote> --tagslarghezza di banda inefficiente, ma non necessariamente inefficiente per l'archiviazione. Puoi sempre consigliare ai tuoi colleghi di non usarlo.
  • dovrai periodicamente usare un git gctrucco per pulire il tuo repository da qualsiasi file che non desideri più.
  • non è efficiente come bup o git-bigfile . Ma è rispettivamente più adatto a ciò che stai cercando di fare e più pronto all'uso. È probabile che tu abbia problemi con centinaia di migliaia di file di piccole dimensioni o con file in un intervallo di gigabyte, ma continua a leggere per soluzioni alternative.

Aggiunta dei file binari

Prima di iniziare assicurati di aver eseguito il commit di tutte le modifiche, l'albero di lavoro è aggiornato e il tuo indice non contiene modifiche senza commit. Potrebbe essere una buona idea spingere tutte le filiali locali sul telecomando (github ecc.) Nel caso in cui si verifichi un disastro.

  1. Crea un nuovo ramo orfano. git checkout --orphan binaryStufffarà il trucco. Questo produce un ramo completamente disconnesso da qualsiasi altro ramo e il primo commit che farai in questo ramo non avrà un genitore, il che lo renderà un commit root.
  2. Pulisci il tuo indice usando git rm --cached * .gitignore.
  3. Fai un respiro profondo ed elimina l'intero albero di lavoro usando rm -fr * .gitignore. La .gitdirectory interna rimarrà intatta, perché il *carattere jolly non corrisponde.
  4. Copia in VeryBigBinary.exe o VeryHeavyDirectory /.
  5. Aggiungilo && commettilo.
  6. Ora diventa complicato: se lo spingi nel telecomando come una diramazione, tutti i tuoi sviluppatori lo scaricheranno la prossima volta che invocano l' git fetchintasamento della loro connessione. Puoi evitarlo premendo un tag anziché un ramo. Ciò può comunque influire sulla larghezza di banda del collega e sull'archiviazione del filesystem se hanno l'abitudine di digitare git fetch <remote> --tags, ma continuate a leggere per una soluzione alternativa. Vai avanti egit tag 1.0.0bin
  7. Invia il tuo tag orfano git push <remote> 1.0.0bin.
  8. Solo così non spingi mai accidentalmente il tuo ramo binario, puoi eliminarlo git branch -D binaryStuff. Il commit non verrà contrassegnato per la garbage collection, perché un tag orfano che punta su di esso 1.0.0binè sufficiente per mantenerlo in vita.

Verifica il file binario

  1. In che modo (o i miei colleghi) riesco a estrarre VeryBigBinary.exe nell'albero di lavoro corrente? Se il tuo attuale ramo di lavoro è ad esempio master, puoi semplicemente git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. Questo fallirà se non hai 1.0.0binscaricato il tag orfano , nel qual caso dovrai farlo in git fetch <remote> 1.0.0binanticipo.
  3. Puoi aggiungere il comando al VeryBigBinary.exetuo master .gitignore, in modo che nessuno del tuo team inquinerà accidentalmente la storia principale del progetto con il binario.

Eliminazione completa del file binario

Se decidi di eliminare completamente VeryBigBinary.exe dal tuo repository locale, dal tuo repository remoto e dai repository del tuo collega, puoi semplicemente:

  1. Elimina il tag orfano sul telecomando git push <remote> :refs/tags/1.0.0bin
  2. Elimina il tag orfano localmente (elimina tutti gli altri tag non referenziati) git tag -l | xargs git tag -d && git fetch --tags. Tratto da SO 1841341 con leggera modifica.
  3. Usa un trucco git gc per eliminare il tuo commit ora non referenziato localmente. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@". Elimina anche tutti gli altri commit senza riferimento. Tratto da SO 1904860
  4. Se possibile, ripetere il trucco git gc sul telecomando. È possibile se si esegue l'hosting autonomo del repository e potrebbe non essere possibile con alcuni provider git, come github o in alcuni ambienti aziendali. Se stai ospitando con un provider che non ti dà accesso ssh al telecomando, lascialo stare. È possibile che l'infrastruttura del tuo provider pulisca il tuo commit senza referenze nel loro dolce tempo. Se ti trovi in ​​un ambiente aziendale, puoi consigliare il tuo IT di eseguire una spazzatura cron job raccogliendo il telecomando una volta alla settimana o giù di lì. Indipendentemente dal fatto che lo facciano o meno, il tuo team non avrà alcun impatto in termini di larghezza di banda e spazio di archiviazione, a condizione che consulti sempre i tuoi colleghi git clone -b master --single-branch <url>invece di git clone.
  5. Tutti i tuoi colleghi che vogliono sbarazzarsi di tag orfani obsoleti devono solo applicare i passaggi 2-3.
  6. È quindi possibile ripetere i passaggi 1-8 di Aggiunta di file binari per creare un nuovo tag orfano 2.0.0bin. Se sei preoccupato per la digitazione dei tuoi colleghi git fetch <remote> --tags, puoi effettivamente nominarlo di nuovo 1.0.0bin. Questo farà in modo che la prossima volta che recuperino tutti i tag, i vecchi 1.0.0binsaranno senza riferimenti e contrassegnati per la successiva garbage collection (usando il passaggio 3). Quando si tenta di sovrascrivere un tag sul telecomando, è necessario utilizzare in -fquesto modo:git push -f <remote> <tagname>

Epilogo

  • OTABS non tocca il tuo master o qualsiasi altro codice sorgente / rami di sviluppo. Gli hash di commit, tutta la cronologia e le dimensioni ridotte di questi rami non sono interessati. Se hai già gonfiato la tua cronologia del codice sorgente con file binari, dovrai pulirla come un lavoro separato. Questo script potrebbe essere utile.

  • Confermato di funzionare su Windows con git-bash.

  • È una buona idea applicare una serie di trics standard per rendere più efficiente l'archiviazione dei file binari. L'esecuzione frequente di git gc(senza ulteriori argomenti) consente a git di ottimizzare l'archiviazione sottostante dei file utilizzando delta binari. Tuttavia, se è improbabile che i tuoi file rimangano simili da commit a commit, puoi disattivare delta binari del tutto. Inoltre, poiché non ha senso comprimere file già compressi o crittografati, come .zip, .jpg o .crypt, git consente di disattivare la compressione della memoria sottostante. Purtroppo è un'impostazione tutto o niente che influisce anche sul codice sorgente.

  • Potresti voler scrivere script su parti di OTABS per consentire un utilizzo più rapido. In particolare, i passaggi di script 2-3 da Eliminazione completa di file binari a un updatehook git potrebbero dare una semantica convincente ma forse pericolosa per recuperare git ("recupera ed elimina tutto ciò che non è aggiornato").

  • È possibile che si desideri saltare il passaggio 4 dell'eliminazione completa dei file binari per mantenere una cronologia completa di tutte le modifiche binarie sul telecomando a spese del gonfiamento del repository centrale. I repository locali rimarranno snelli nel tempo.

  • Nel mondo Java è possibile combinare questa soluzione con maven --offlineper creare una build offline riproducibile memorizzata interamente nel controllo della versione (è più facile con Maven che con Gradle). Nel mondo di Golang è possibile basarsi su questa soluzione per gestire GOPATH anziché go get. Nel mondo Python è possibile combinare questo con virtualenv per produrre un ambiente di sviluppo autonomo senza fare affidamento su server PyPi per ogni build da zero.

  • Se i file binari cambiano molto spesso, come artefatti costruire, potrebbe essere una buona idea per lo script di una soluzione che memorizza 5 versioni più recenti dei manufatti nei tag orfani monday_bin, tuesday_bin, ..., friday_bine anche un tag orfano per ogni release 1.7.8bin 2.0.0bin, ecc. È possibile ruotare weekday_bined eliminare i vecchi file binari ogni giorno. In questo modo ottieni il meglio da due mondi: mantieni l' intera cronologia del tuo codice sorgente ma solo la cronologia rilevante delle tue dipendenze binarie. È anche molto facile ottenere i file binari per un determinato tag senza ottenere l'intero codice sorgente con tutta la sua cronologia: git init && git remote add <name> <url> && git fetch <name> <tag>dovrebbe farlo per te.


"Devi usare periodicamente git gc" - ha smesso di leggere proprio lì. Perché qualcuno dovrebbe rinunciare alla loro ultima cintura di sicurezza in favore di qualche hack?
user1643723

@ user1643723 git gcnon è pericoloso da eseguire. Per impostazione predefinita, tutti i tuoi commit penzolanti rimarranno sul disco rigido per almeno 30 giorni per impostazione predefinita: git-scm.com/docs/git-gc
Adam Kurkiewicz,

Grazie per il commento dettagliato. Volevo provare questo come un modo per memorizzare alcune dipendenze binarie nel mio repository GitHub in modo tale che non vengano scaricate per impostazione predefinita quando qualcuno clona il repository, ma può essere scaricato manualmente e aggiornare il repository locale. Tuttavia, ho ricevuto un errore in questo passaggio: git push <remote> 1.0.0bin- remote: error: GH001: Large files detected. You may want to try Git Large File Storage. Sembra che forse GitHub non lo supporti più? Il file binario in questione aveva dimensioni di 100 MB.
user5359531,

1
Ad essere sinceri, se ti è permesso usare github per il tuo lavoro, cosa ti impedisce di usare LFS? I ragazzi di github hanno lavorato duramente per creare questo prodotto e lo stanno persino ospitando per te e la loro infrastruttura è ottimizzata per usarlo. Questo hack è pensato per situazioni in cui non puoi davvero usare LFS o altre terze parti e stai cercando una soluzione pura.
Adam Kurkiewicz, il

Ho anche aggiornato la risposta per essere più chiaro su come sia realmente confusa questa soluzione.
Adam Kurkiewicz,

13

Secondo me, se è probabile che modifichi spesso quei file di grandi dimensioni, o se intendi fare molti git cloneo git checkout, allora dovresti seriamente considerare di usare un altro repository Git (o forse un altro modo per accedere a quei file).

Ma se lavori come facciamo noi e se i tuoi file binari non vengono modificati spesso, il primo clone / checkout sarà lungo, ma dopo dovrebbe essere veloce quanto vuoi (considerando che i tuoi utenti continuano a usare il primo repository clonato aveva).


13
Inoltre, i repository separati non riducono i tempi di checkout, dal momento che è necessario verificare entrambi i repository!
Emil Sit,

@EmilSit un repository separato potrebbe rendere il checkout molto più breve se si pulisce costantemente la cronologia del "repository binario". Inoltre, gli sviluppatori non sarebbero costretti a controllare entrambi i repository ogni volta .
FabienAndre,

Perché non fare in modo che lo script di build del modulo principale recuperi i file binari dal secondo repository, estraendoli uno per uno (come qui: stackoverflow.com/questions/1125476/… ).
akauppi,

1
Anche se i file binari non vengono modificati frequentemente, i file di grandi dimensioni possono comunque interrompere il flusso di lavoro se si spinge spesso i rami nel repository a scopo di collaborazione.
Timo Reimann,

9

SVN sembra gestire i delta binari in modo più efficiente di Git.

Ho dovuto decidere un sistema di controllo delle versioni per la documentazione (file JPEG, file PDF e file .odt). Ho appena provato ad aggiungere un file JPEG e ruotarlo di 90 gradi quattro volte (per verificare l'efficacia dei delta binari). Il repository Git è cresciuto del 400%. Il repository SVN è cresciuto solo dell'11%.

Quindi sembra che SVN sia molto più efficiente con i file binari.

Quindi la mia scelta è Git per il codice sorgente e SVN per i file binari come la documentazione.


33
Avevi solo bisogno di eseguire "git gc" (reimballaggio e garbage collection) dopo aver aggiunto quei 4 file. Git non comprime immediatamente tutto il contenuto aggiunto, quindi avrai una compressione di gruppo di file (che è più efficiente in termini di dimensioni) e non avrai un rallentamento nel comprimere separatamente ogni singolo oggetto aggiunto là fuori. Ma anche senza "git gc", git avrebbe comunque fatto la compressione per te, alla fine (dopo aver notato che si sono accumulati abbastanza oggetti spacchettati).
usignolo

24
@jpierson Ho creato un repository git vuoto e ho aggiunto (e eseguito il commit) un'immagine bmp completamente bianca con una dimensione di 41 MB, questo ha prodotto un repository git totale con una dimensione di 328 KB. Dopo un git gctotale le dimensioni del repository git sono state ridotte a 184 KB. Quindi ho cambiato un singolo pixel da bianco a nero e ho eseguito il commit di questa modifica, la dimensione del repository git totale è aumentata a 388 KB e dopo che git gcla dimensione del repository git totale è stata ridotta a 184 KB. Questo dimostra che git è abbastanza buono nel comprimere e trovare delta di file binari.
Tader

6
@jpierson Un sidenote: ho appena commentato i delta binari. Git consumerà tutta la tua memoria e cambierà se sta gestendo repository con file di grandi dimensioni (GB). Per questo, usa git-annex (già menzionato in un'altra risposta) ...
Tader,

12
@JanDvorak - nessuno l'ha menzionato, perché è completamente falso. Le copie di Subversion sono economiche - svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html - verso la metà della pagina.
Joris Timmermans,

12
@Tader: il tuo test è negativo. Quello che chiami un file binario è in effetti (dal punto di vista di git) più simile a un file di testo: il bitstream è allineato a byte e ci sono differenze significative e localizzate da fare; dopo tutto, cambiare un pixel equivale sostanzialmente a cambiare un carattere in un file di testo (e chi usa bitmap non compresse al giorno d'oggi?) Prova lo stesso esperimento con un piccolo video, un'immagine compressa, una macchina virtuale, un file zip o altro - e troverai quel git non si occupa in modo efficiente del delta; infatti è fondamentalmente impossibile con dati incomprimibili.
Eamon Nerbonne,

4

git clone --filter da Git 2.19 + cloni superficiali

Questa nuova opzione potrebbe alla fine diventare la soluzione finale al problema del file binario, se Git e GitHub si sviluppano e lo rendono abbastanza intuitivo (cosa che probabilmente non hanno ancora raggiunto per i sottomoduli, ad esempio).

Permette effettivamente di recuperare solo i file e le directory desiderati per il server ed è stato introdotto insieme a un'estensione del protocollo remoto.

Con questo, potremmo prima fare un clone superficiale e quindi automatizzare quali BLOB recuperare con il sistema di compilazione per ogni tipo di compilazione.

Esiste anche un --filter=blob:limit<size>elemento che consente di limitare la dimensione massima del BLOB da recuperare.

Ho fornito un esempio minimo dettagliato di come appare la funzione: Come posso clonare una sottodirectory solo di un repository Git?


2

Sto cercando opinioni su come gestire file binari di grandi dimensioni da cui dipende il mio codice sorgente (applicazione web). Quali sono le tue esperienze / pensieri riguardo a questo?

Personalmente mi sono imbattuto in errori di sincronizzazione con Git con alcuni dei miei host cloud una volta che i miei dati binari delle applicazioni web sono stati segnati sopra il segno da 3 GB . All'epoca ho considerato BFT Repo Cleaner , ma mi è sembrato un trucco. Da allora ho iniziato a tenere i file fuori da Git, sfruttando invece strumenti appositamente creati come Amazon S3 per la gestione di file, controllo delle versioni e backup.

Qualcuno ha esperienza con più repository Git e gestendoli in un progetto?

Sì. I temi di Hugo sono gestiti principalmente in questo modo. È un po 'confuso, ma fa il lavoro.


Il mio consiglio è di scegliere lo strumento giusto per il lavoro . Se è per un'azienda e stai gestendo il tuo codice su GitHub paga i soldi e usa Git-LFS. Altrimenti potresti esplorare opzioni più creative come l' archiviazione decentralizzata e crittografata dei file utilizzando blockchain .

Altre opzioni da considerare includono Minio e s3cmd .


0

Dai un'occhiata a Dai camlistore . In realtà non è basato su Git, ma lo trovo più appropriato per quello che devi fare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.