Domanda

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

  1. Copia i file binari a mano.
    • Pro:Non è sicuro.
    • Contro:Sono fortemente contrario a questo, poiché aumenta la probabilità di errori durante la configurazione di un nuovo sito/la migrazione di quello vecchio.Costruisce un altro ostacolo da superare.
  2. Gestiscili tutti con Idiota.
    • Pro:Elimina la possibilità di "dimenticare" di copiare un file importante
    • Contro:Gonfia il repository e diminuisce la flessibilità per gestire la base di codice e i checkout, i cloni, ecc.ci vorrà un bel po'.
  3. Repository separati.
    • Pro:Il check-out/clonazione del codice sorgente è veloce come sempre e le immagini vengono adeguatamente archiviate nel proprio repository.
    • Contro:Rimuove la semplicità dell'avere il solo e unico Repository Git sul progetto.Sicuramente introduce altre cose a cui non avevo pensato.

Quali sono le vostre esperienze/pensieri a riguardo?

Anche:Qualcuno ha esperienza con più repository Git e nella loro gestione in un unico progetto?

I file sono immagini per un programma che genera PDF con tali 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.

È stato utile?

Soluzione

Se il programma non funzionerà senza i file sembra dividerli in un pronti contro termine separata è una cattiva idea. Abbiamo grandi suite di test che noi spezziamo in un repo separata ma quelli sono veramente file "ausiliari".

Tuttavia, si può essere in grado di gestire i file in un repo separata e quindi utilizzare git-submodule a tirare nel progetto in un modo sano. Quindi, si sarebbe ancora avere la storia completa di tutta la vostra fonte, ma, se ho capito bene, devi avere solo quello di revisione rilevante delle immagini modulo. L'impianto git-submodule dovrebbe aiutare a mantenere la versione corretta del codice, in linea con la versione corretta delle immagini.

Ecco un buon a sottomoduli da Git libro.

Altri suggerimenti

git-allegato di recente che trovo impressionante. E 'stato progettato per gestire in modo efficiente file di grandi dimensioni. Io lo uso per il mio foto / musica (etc.) collezioni. Lo sviluppo di git-allegato è molto attivo. Il contenuto dei file può essere rimosso dal repository Git, solo la gerarchia ad albero viene monitorata da Git (tramite collegamenti simbolici). Tuttavia, per ottenere il contenuto del file, un secondo passaggio è necessario dopo aver estratto / spingere, per 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 v'è una grande documentazione sul sito web. Un pacchetto è disponibile su Debian .

Un'altra soluzione, dall'aprile 2015 è Git Grande file Storage (LFS) (da GitHub).

Si utilizza git-LFS (vedi < a href = "https://git-lfs.github.com/" rel = "noreferrer"> git-lfs.github.com ) e testato con un server che lo sostengono: LFS-test-server "noreferrer" :
È possibile memorizzare 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

Dai un'occhiata alla git bup che è un'estensione Git per memorizzare elegantemente grandi file binari in un Git repository.

che ci si vuole avere come un modulo, ma non dovrete preoccuparvi di repository diventando difficile da gestire. Uno dei loro casi di utilizzo del campione è la memorizzazione delle immagini di macchine virtuali in Git.

Non ho effettivamente visto migliori tassi di compressione, ma i miei repository non hanno davvero grandi binari in loro.

La vostra situazione potrebbe essere diversa.

È inoltre possibile utilizzare git-grassi . Mi piace che dipende solo da magazzino Python e rsync . Supporta anche il normale flusso di lavoro Git, con i seguenti comandi autoesplicativo:

git fat init
git fat push
git fat pull

Inoltre, è necessario controllare in un file .gitfat nel repository e modificare i .gitattributes per specificare le estensioni di file che si desidera git fat da gestire.

Si aggiunge un binario utilizzando il git add normale, che a sua volta invoca git fat, sulla base di regole gitattributes.

Infine, si ha il vantaggio che la posizione in cui i binari sono in realtà memorizzati può essere condiviso tra archivi e gli utenti e supporta qualsiasi cosa rsync fa.

UPDATE: non utilizzare git-grassi se si sta utilizzando un ponte Git-SVN. Si finirà per rimuovere i file binari dal repository Subversion. Tuttavia, se si sta utilizzando un repository Git puro, funziona a meraviglia.

userei sottomoduli (come Pat Notz) o due depositi distinti. Se si modificano i file binari troppo spesso, quindi vorrei cercare di minimizzare l'impatto della enorme repository pulizia della storia:

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

è usato un disco rigido esterno con il repository Git principale, e ho clonato in ogni computer. Poi, ho iniziato a classificarli in modo abituale (spingere, tirare, la fusione ... cancellare e rinominare molte volte).

Alla fine, ho avuto solo ~ 6 GB di file MP3 e ~ 83 GB nella directory .git. Ho usato git-write-tree e git-commit-tree per creare un nuovo impegno, senza commettere gli antenati, e ho iniziato un nuovo ramo che punta a quel commit. Il "git log" per quel ramo ha mostrato solo un commit.

Poi, ho cancellato il vecchio ramo, continuavo a solo il nuovo ramo, cancellato l'arbitro-log, ed eseguire "git prune": dopo di che, le mie cartelle .git ponderazione solo ~ 6 GB ...

Si potrebbe "purga" l'immenso archivio di volta in volta nello stesso modo: Il tuo "git clone" 's sarà più veloce

.

A mio parere, se è molto probabile di modificare spesso i file di grandi dimensioni, o se avete intenzione di fare un sacco di git clone o git checkout, allora si dovrebbe seriamente considerare l'utilizzo di un altro repository Git (o forse un altro modo per accedere a tali file ).

Ma se si lavora come noi, e se i file binari non vengono spesso modificati, quindi il primo clone / checkout sarà lunga, ma dopo che dovrebbe essere veloce come si vuole (prendendo in considerazione gli utenti continuare ad usare il primo repository clonato avevano).

La soluzione che vorrei proporre si basa sui rami orfani e su un leggero abuso del meccanismo dei tag, da ora in poi denominato *Orphan Tags Binary Storage (OTAB)

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

Proprietà desiderabili di OTABS

  • è un puro idiota E solo git soluzione: svolge il 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, cioè.non gonfia la cronologia del tuo repository.
  • git pull E git fetch, Compreso git fetch --all sono ancora efficiente in termini di larghezza di banda, cioè.non tutti i file binari di grandi dimensioni vengono estratti dal remoto per impostazione predefinita.
  • funziona finestre.
  • memorizza tutto in a repository git singolo.
  • lo consente cancellazione di binari obsoleti (a differenza di bup).

Proprietà indesiderabili di OTABS

  • esso rende git clone potenzialmente inefficiente (ma non necessariamente, a seconda dell'utilizzo).Se distribuisci questa soluzione potresti dover consigliare ai tuoi colleghi di utilizzarla git clone -b master --single-branch <url> invece di git clone.Questo perché git clone per impostazione predefinita clona letteralmente intero repository, incluse cose su cui normalmente non vorresti sprecare la tua larghezza di banda, come commit senza riferimenti.Preso da SO 4811434.
  • esso rende git fetch <remote> --tags larghezza di banda inefficiente, ma non necessariamente inefficiente spazio di archiviazione.Puoi sempre consigliare ai tuoi colleghi di non usarlo.
  • dovrai utilizzare periodicamente a git gc trucco per pulire il tuo repository da tutti i file che non desideri più.
  • non è così efficiente come bup O git-bigfiles.Ma è rispettivamente più adatto a quello che stai cercando di fare e più standard.È probabile che tu abbia problemi con centinaia di migliaia di piccoli file o con file nell'ordine dei gigabyte, ma continua a leggere per soluzioni alternative.

Aggiunta dei file binari

Prima di iniziare assicurati di aver confermato tutte le modifiche, che l'albero di lavoro sia aggiornato e che l'indice non contenga modifiche non confermate.Potrebbe essere una buona idea trasferire tutte le filiali locali al tuo remoto (github ecc.) nel caso in cui dovesse verificarsi un disastro.

  1. Crea un nuovo ramo orfano. git checkout --orphan binaryStuff farà il trucco.Questo produce un ramo che è completamente disconnesso da qualsiasi altro ramo, e il primo commit che farai in questo ramo non avrà alcun genitore, il che lo renderà un commit root.
  2. Pulisci il tuo indice utilizzando git rm --cached * .gitignore.
  3. Fai un respiro profondo ed elimina l'intero albero di lavoro utilizzando rm -fr * .gitignore.Interno .git la directory rimarrà intatta, perché il file * il carattere jolly non corrisponde.
  4. Copia nel tuo VeryBigBinary.exe o nel tuo VeryHeavyDirectory/.
  5. Aggiungilo e& confermalo.
  6. Ora diventa complicato: se lo inserisci nel telecomando come ramo, tutti i tuoi sviluppatori lo scaricheranno la prossima volta che lo invocheranno git fetch intasando la loro connessione.Puoi evitarlo inserendo un tag invece di un ramo.Ciò può comunque avere un impatto sulla larghezza di banda e sullo spazio di archiviazione del file system del tuo collega se ha l'abitudine di digitare git fetch <remote> --tags, ma continua a leggere per una soluzione alternativa.Vai avanti e git tag 1.0.0bin
  7. Invia il tuo tag orfano git push <remote> 1.0.0bin.
  8. Solo per non spingere mai accidentalmente il tuo ramo binario, puoi eliminarlo git branch -D binaryStuff.Il tuo commit non verrà contrassegnato per la garbage collection, perché un tag orfano punta su di esso 1.0.0bin è sufficiente per mantenerlo in vita.

Controllo del file binario

  1. Come posso (o i miei colleghi) estrarre VeryBigBinary.exe nell'albero di lavoro corrente?Se il tuo attuale ramo lavorativo è ad esempio master puoi semplicemente git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. L'operazione fallirà se non hai il tag orfano 1.0.0bin scaricato, nel qual caso dovrai farlo git fetch <remote> 1.0.0bin in anticipo.
  3. Puoi aggiungere il VeryBigBinary.exe in quello del tuo padrone .gitignore, in modo che nessuno nel tuo team inquini accidentalmente la cronologia principale del progetto con il codice 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 senza riferimenti) git tag -l | xargs git tag -d && git fetch --tags.Preso da SO 1841341 con leggera modifica.
  3. Usa un trucco git gc per eliminare localmente il tuo commit ora senza riferimenti. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@".Eliminerà anche tutti gli altri commit senza riferimenti.Preso da SO 1904860
  4. Se possibile, ripeti il ​​trucco git gc sul telecomando.È possibile se ospiti autonomamente il tuo 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 fornisce l'accesso ssh al telecomando, lascialo stare.È possibile che l'infrastruttura del tuo provider pulisca il tuo commit senza riferimenti a suo piacimento.Se lavori in un ambiente aziendale, puoi consigliare al tuo IT di eseguire un lavoro cron di raccolta spazzatura del telecomando una volta alla settimana circa.Che lo facciano o meno non avranno alcun impatto sul tuo team in termini di larghezza di banda e spazio di archiviazione, a patto che consigli ai tuoi colleghi di farlo sempre git clone -b master --single-branch <url> invece di git clone.
  5. Tutti i tuoi colleghi che vogliono eliminare i tag orfani obsoleti devono solo applicare i passaggi 2-3.
  6. È quindi possibile ripetere i passaggi da 1 a 8 di Aggiunta dei file binari per creare un nuovo tag orfano 2.0.0bin.Se sei preoccupato per i tuoi colleghi che digitano git fetch <remote> --tags puoi effettivamente nominarlo di nuovo 1.0.0bin.Ciò assicurerà che la prossima volta verranno recuperati tutti i tag precedenti 1.0.0bin non verrà referenziato e contrassegnato per la successiva Garbage Collection (utilizzando il passaggio 3).Quando provi a sovrascrivere un tag sul telecomando devi usare -f come questo: git push -f <remote> <tagname>

Epilogo

  • OTABS non tocca il tuo master o qualsiasi altro codice sorgente/ramo di sviluppo.Gli hash di commit, tutta la cronologia e le dimensioni ridotte di questi rami non vengono influenzati.Se hai già riempito la cronologia del codice sorgente con file binari, dovrai ripulirla come un lavoro separato. Questa sceneggiatura potrebbe essere utile.

  • Confermato che funziona su Windows con git-bash.

  • È una buona idea applicare a insieme di trucchi standard per rendere più efficiente l'archiviazione dei file binari.Esecuzione frequente di git gc (senza argomenti aggiuntivi) fa sì che git ottimizzi l'archiviazione sottostante dei tuoi file utilizzando delta binari.Tuttavia, se è improbabile che i tuoi file rimangano simili da un commit all'altro, puoi disattivare del tutto i delta binari.Inoltre, poiché non ha senso comprimere file già compressi o crittografati, come .zip, .jpg o .crypt, git ti consente di disattivare la compressione dello spazio di archiviazione sottostante.Sfortunatamente si tratta di un'impostazione tutto o niente che influisce anche sul codice sorgente.

  • Potresti voler creare script di parti di OTABS per consentirne un utilizzo più rapido.In particolare, lo scripting dei passaggi 2-3 da Eliminazione completa dei file binari in un update git hook potrebbe fornire una semantica convincente ma forse pericolosa a git fetch ("recupera ed elimina tutto ciò che non è aggiornato").

  • Potresti voler saltare il passaggio 4 di Eliminazione completa dei file binari per mantenere una cronologia completa di tutte le modifiche binarie sul telecomando a costo di gonfiare il repository centrale.I repository locali rimarranno snelli nel tempo.

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

  • Se i tuoi file binari cambiano molto spesso, come la creazione di artefatti, potrebbe essere una buona idea creare uno script di una soluzione che memorizzi le 5 versioni più recenti degli artefatti nei tag orfani monday_bin, tuesday_bin, ..., friday_bin, e anche un tag orfano per ogni versione 1.7.8bin 2.0.0bin, eccetera.È possibile ruotare il weekday_bin ed elimina i vecchi file binari ogni giorno.In questo modo ottieni il meglio di due mondi:tieni il intero la cronologia del codice sorgente ma solo il file pertinente cronologia delle dipendenze binarie.È anche molto semplice ottenere i file binari per un determinato tag senza ottenere l'intero codice sorgente con tutta la sua storia: git init && git remote add <name> <url> && git fetch <name> <tag> dovrebbe farlo per te.

SVN sembra trattare delta binari più efficiente di Git.

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

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

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

git clone --filter da Git 2,19 + cloni poco profonde

Questa nuova opzione potrebbe alla fine diventare la soluzione definitiva al problema file binario, se gli sviluppatori Git e GitHub e renderlo user abbastanza gentile (che hanno probabilmente ancora non hanno raggiunto per sottomoduli per esempio).

Permette di recuperare in realtà solo i file e le directory che si desidera per il server, ed è stato introdotto insieme a un protocollo di estensione a distanza.

Con questo, si potrebbe prima fare un clone superficiale, e quindi automatizzare che blobs per andare a prendere con il sistema di generazione per ogni tipo di corporatura.

C'è anche già --filter=blob:limit<size> che consente di limitare la dimensione massima blob recuperare.

Ho fornito un esempio dettagliato di come minimo della funzione assomiglia a: Come faccio a clonare una sottodirectory solo di un repository Git?

  

Cerco opinioni su come gestire grandi file binari su cui il mio codice sorgente (applicazione web) è dipendente. Quali sono le vostre esperienze / pensieri per quanto riguarda questo?

Io personalmente ho incontrato errori di sincronizzazione con Git con alcuni dei miei ospiti di cloud una volta le mie applicazioni web di dati binari dentellato sopra il marchio 3 GB . Ho considerato BFT Repo Cleaner , al momento, ma si sentiva come un hack. Da allora ho cominciato a tenere solo file al di fuori della competenza Git, invece sfruttando strumenti costruiti appositamente come Amazon S3 per la gestione dei file, controllo delle versioni e di back-up.

  

Qualcuno ha esperienza con più repository Git e la loro gestione in un unico progetto?

Sì. Hugo temi sono principalmente gestite in questo modo. E 'un po kudgy, ma ottiene il lavoro fatto.


Il mio suggerimento è quello di scegliere lo strumento giusto per il lavoro . Se è per una società e si sta gestendo il tuo codeline su GitHub pagare il denaro e utilizzare Git-LFS. In caso contrario, si potrebbe esplorare le opzioni più creative, come decentrata, blockchain .

Ulteriori opzioni da considerare includono Minio e s3cmd .

Dai un'occhiata alla camlistore . In realtà non è basata su Git, ma trovo più appropriato per quello che hai da fare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top