Quali sono i limiti dei file in Git (numero e dimensioni)?


Risposte:


161

Questo messaggio dallo stesso Linus può aiutarti con alcuni altri limiti

[...] CVS, ovvero finisce per essere praticamente orientato verso un modello "un file alla volta".

Che è bello in che si può avere un milione di file, e quindi controllare solo alcuni di loro - che non avrete mai nemmeno vedere l'impatto delle altre 999,995 file.

Fondamentalmente Git non guarda mai meno dell'intero repository. Anche se limiti un po 'le cose (es. Controlla solo una porzione, o fai in modo che la storia torni indietro solo un po'), git finisce sempre con la cura dell'intera cosa, e portando la conoscenza in giro.

Quindi git si ridimensiona davvero male se lo costringi a considerare tutto come uno enorme repository. Non penso che quella parte sia davvero riparabile, anche se probabilmente possiamo migliorarla.

E sì, allora ci sono i problemi di "file di grandi dimensioni". Non so davvero cosa fare per i file di grandi dimensioni. Li facciamo schifo, lo so.

Vedi di più nella mia altra risposta : il limite con Git è che ogni repository deve rappresentare un " insieme coerente di file ", il "tutto il sistema" in sé (non è possibile taggare "parte di un repository").
Se il sistema è costituito da parti autonome (ma interdipendenti), è necessario utilizzare i sottomoduli .

Come illustrato dalla risposta di Talljoe , il limite può essere uno di sistema (un gran numero di file), ma se capisci la natura di Git (sulla coerenza dei dati rappresentata dalle sue chiavi SHA-1), realizzerai il vero "limite" è un uso : vale a dire, non si dovrebbe provare a memorizzare tutto in un repository Git, a meno che non si sia pronti a recuperare o taggare sempre tutto. Per alcuni grandi progetti, non avrebbe senso.


Per uno sguardo più approfondito ai limiti di git, vedere " git con file di grandi dimensioni "
(che menziona git-lfs : una soluzione per archiviare file di grandi dimensioni al di fuori del repository git. GitHub, aprile 2015)

I tre problemi che limitano un repository git:

  • file enormi ( xdelta per packfile è solo in memoria, il che non va bene con file di grandi dimensioni)
  • enorme numero di file , ovvero un file per BLOB e slow git gc per generare un file pack alla volta.
  • enormi pacchetti di file , con un indice di file di pacchetto inefficiente per recuperare i dati dal (grande) pacchetto di file.

Un thread più recente (febbraio 2015) illustra i fattori limitanti per un repository Git :

Alcuni cloni simultanei dal server centrale rallenteranno anche altre operazioni simultanee per altri utenti?

Non ci sono blocchi nel server durante la clonazione, quindi in teoria la clonazione non influisce su altre operazioni. Tuttavia, la clonazione può usare molta memoria (e molta CPU a meno che non si attivi la funzionalità bitmap di raggiungibilità, che è consigliabile).

Sarà ' git pulllento?

Se escludiamo il lato server, la dimensione dell'albero è il fattore principale , ma i tuoi file 25k dovrebbero andare bene (Linux ha 48k file).

' git push'?

Questo non è influenzato dalla profondità della storia del tuo repository o dalla larghezza del tuo albero, quindi dovrebbe essere veloce ..

Ah, il numero di ref può influenzare sia git-pushe git-pull.
Penso che Stefan lo sappia meglio di me in questo settore.

' git commit'? (È elencato come lento nel riferimento 3. ) ' git status'? (Rallenta di nuovo nel riferimento 3 anche se non lo vedo.)
(Anche git-add)

Ancora una volta, la dimensione del tuo albero. Alle dimensioni del tuo repository, non credo che ti debba preoccupare.

Alcune operazioni potrebbero non sembrare quotidiane ma se vengono chiamate frequentemente dal front-end Web su GitLab / Stash / GitHub ecc., Possono diventare colli di bottiglia. (ad esempio ' git branch --contains' sembra terribilmente influenzato da un gran numero di rami.)

git-blame potrebbe essere lento quando un file viene modificato molto.


4
@ Thr4wn: vedi anche stackoverflow.com/questions/1979167/git-submodule-update/... per tutto nella pagina di modulo GitPro. Per una versione più breve: stackoverflow.com/questions/2065559/...
VonC

1
Link aggiornato per la documentazione dei submoules git = git-scm.com/book/en/Git-Tools-Submodules
JHowIX

Mi chiedo davvero, con tanta sqlite e molte alternative di database disponibili su Linux, perché non potrebbero semplicemente usare un database che è facile da eseguire il backup, replicare e ridimensionare.
Akash Kava,

"git si ridimensiona davvero male se lo costringi a considerare tutto come un enorme repository" cosa dice questo sulla scalabilità dei monorepos?
effimero

@ephemer Quello che dice è ... che la citazione è di 10 anni fa. Da allora, nel 2017, Microsoft ha il suo monorepo ( devblogs.microsoft.com/bharry/... : 300GB +) e miglioramenti sono ancora imminente nel 2019: stackoverflow.com/a/57129687/6309
VonC

36

Non esiste un limite reale: tutto è denominato con un nome a 160 bit. La dimensione del file deve essere rappresentabile in un numero a 64 bit, quindi nessun limite reale lì.

C'è un limite pratico, però. Ho un repository che è ~ 8 GB con> 880.000 file e git gc richiede un po 'di tempo. L'albero di lavoro è piuttosto grande, quindi le operazioni che ispezionano l'intera directory di lavoro impiegano un po 'di tempo. Questo repository viene utilizzato solo per l'archiviazione dei dati, quindi è solo un gruppo di strumenti automatizzati che lo gestiscono. L'estrazione delle modifiche dal repository è molto, molto più rapida rispetto alla risincronizzazione degli stessi dati.

%find . -type f | wc -l
791887
%time git add .
git add .  6.48s user 13.53s system 55% cpu 36.121 total
%time git status
# On branch master
nothing to commit (working directory clean)
git status  0.00s user 0.01s system 0% cpu 47.169 total
%du -sh .
29G     .
%cd .git
%du -sh .
7.9G    .

2
Sebbene sopra esista una risposta "più corretta" a proposito dei limiti teorici, questa risposta mi sembra più utile in quanto consente di confrontare la propria situazione con la propria. Grazie.
Bananeweizen,

1
Molto interessante. Come è possibile che la copia di lavoro sia più grande della .gitdirectory? Il mio ingenuo presupposto era che .gitcontiene una copia della directory di lavoro più la cronologia, quindi deve essere più grande. Qualcuno può indicarmi una risorsa che capisca come queste dimensioni sono correlate?
bluenote10

1
@ bluenote10 Il contenuto nella .gitdirectory è compresso. Quindi è probabile che un repository con un numero relativamente basso di commit abbia una cronologia compressa più piccola rispetto alla directory di lavoro non compressa. La mia esperienza dimostra che in pratica, con il codice C ++, l'intera cronologia ha in genere le stesse dimensioni della directory di lavoro.
prapin

28

Se aggiungi file troppo grandi (GB nel mio caso, Cygwin, XP, 3 GB RAM), aspettati questo.

fatale: memoria insufficiente, malloc non è riuscito

Maggiori dettagli qui

Aggiornamento 3/2/11: Visto simile in Windows 7 x64 con Tortoise Git. Tonnellate di memoria utilizzate, risposta del sistema molto molto lenta.


17

Nel febbraio 2012, c'era un thread molto interessante sulla mailing list di Git di Joshua Redstone, un ingegnere software di Facebook che testava Git su un enorme repository di test:

Il repository di test ha 4 milioni di commit, cronologia lineare e circa 1,3 milioni di file.

I test eseguiti dimostrano che per tale repo Git è inutilizzabile (minuti di funzionamento a freddo), ma questo potrebbe cambiare in futuro. Fondamentalmente le prestazioni sono penalizzate dal numero di stat()chiamate al modulo FS del kernel, quindi dipenderà dal numero di file nel repository e dall'efficienza della cache di FS. Vedi anche questa sintesi per ulteriori discussioni.


2
+1 interessante. Ciò fa eco alle mie stesse risposte sui limiti git che descrivono in dettaglio i limiti di enormi file / numero di file / pacchetti.
VonC,


2

Dipende dal tuo significato. Esistono limiti pratici di dimensione (se hai molti file di grandi dimensioni, può diventare noiosamente lento). Se hai molti file, anche le scansioni possono rallentare.

Tuttavia, non ci sono limiti intrinseci al modello. Puoi certamente usarlo male ed essere miserabile.


1

Penso che sia utile cercare di evitare che il commit di file di grandi dimensioni faccia parte del repository (ad esempio un dump del database potrebbe essere migliore altrove), ma se si considera la dimensione del kernel nel suo repository, probabilmente ci si può aspettare di lavorare comodamente con qualcosa di più piccolo di dimensioni e meno complesso di quello.


1

Ho una generosa quantità di dati memorizzati nel mio repository come singoli frammenti JSON. Ci sono circa 75.000 file che si trovano in alcune directory e non sono davvero dannose per le prestazioni.

Il loro controllo per la prima volta è stato, ovviamente, un po 'lento.


1

Ho trovato questo tentativo di memorizzare un numero enorme di file (350k +) in un repository. Sì, negozio. Ride.

$ time git add . 
git add . 333.67s user 244.26s system 14% cpu 1:06:48.63 total

I seguenti estratti della documentazione di Bitbucket sono piuttosto interessanti.

Quando lavori con un repository DVCS clonando, spingendo, stai lavorando con l'intero repository e tutta la sua cronologia. In pratica, una volta che il repository supera i 500 MB, potresti iniziare a vedere i problemi.

... Il 94% dei clienti Bitbucket ha repository inferiori a 500 MB. Sia il kernel Linux che Android sono inferiori a 900 MB.

La soluzione consigliata in quella pagina è quella di dividere il progetto in blocchi più piccoli.


Immagino che questo sia abbastanza obsoleto. In questo momento, non sembra esserci nulla sul repository Android (né Linux) sul sito a cui ti stai collegando. Ma mi chiedo se non fosse inesatto nemmeno allora? Ad esempio confrontare questa risposta . Forse intendevano qualcos'altro?
jjj,

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.