In che modo git archivia i file?


225

Ho appena iniziato a studiare git e per farlo ho iniziato a leggere il Git Community Book e in questo libro dicono che SVN e CVS memorizzano la differenza tra i file e che git archivia un'istantanea di tutti i file.

Ma non ho davvero capito cosa intendano per istantanea. Git fa davvero una copia di tutti i file in ogni commit perché è quello che ho capito dalla loro spiegazione.

PS: Se qualcuno ha una fonte migliore per imparare git, lo apprezzerei.


20
Ecco un post brillante che spiega in dettaglio come funziona git. Quello che stai cercando è probabilmente il § sul database degli oggetti.
Gregreg

Ottimo articolo che contiene collegamenti ad altre grandi risorse. Mi sono divertito con questi per un paio d'ore.
Mihai,

2
Ho trovato questo bellissimo articolo che descrive git da dentro e fuori: maryrosecook.com/blog/post/git-from-the-inside-out
Sumudu

Risposte:


275

Git include per ogni commit una copia completa di tutti i file, ad eccezione del fatto che, per il contenuto già presente nel repository Git, lo snapshot punterà semplicemente a detto contenuto anziché duplicarlo.
Ciò significa anche che diversi file con lo stesso contenuto vengono archiviati una sola volta.

Quindi uno snapshot è sostanzialmente un commit, in riferimento al contenuto di una struttura di directory.

Alcuni buoni riferimenti sono:

Dici a Git che vuoi salvare un'istantanea del tuo progetto con il comando git commit e in pratica registra un manifest di come appariranno tutti i file nel tuo progetto a quel punto

Lab 12 illustra come ottenere istantanee precedenti


Il libro progit ha la descrizione più completa di un'istantanea:

La principale differenza tra Git e qualsiasi altro VCS (inclusi Subversion e amici) è il modo in cui Git pensa ai suoi dati.
Concettualmente, la maggior parte degli altri sistemi memorizza le informazioni come un elenco di modifiche basate su file. Questi sistemi (CVS, Subversion, Perforce, Bazaar e così via) pensano alle informazioni che conservano come un insieme di file e alle modifiche apportate a ciascun file nel tempo

VCS basato su delta

Git non pensa né memorizza i suoi dati in questo modo. Invece, Git pensa ai suoi dati più come a una serie di istantanee di un mini filesystem.
Ogni volta che commetti o salvi lo stato del tuo progetto in Git, fondamentalmente scatta una foto di come appaiono tutti i tuoi file in quel momento e memorizza un riferimento a quella istantanea.
Per essere efficiente, se i file non sono stati modificati, Git non memorizza nuovamente il file, ma solo un collegamento al file identico precedente che ha già archiviato.
Git pensa ai suoi dati più come di seguito:

VCS basato su istantanee

Questa è una distinzione importante tra Git e quasi tutti gli altri VCS. Rende Git riconsiderare quasi ogni aspetto del controllo di versione che la maggior parte degli altri sistemi ha copiato dalla generazione precedente. Questo rende Git più simile a un mini filesystem con alcuni strumenti incredibilmente potenti basati su di esso, piuttosto che semplicemente un VCS.


Jan Hudec aggiunge questo importante commento :

Sebbene sia vero e importante a livello concettuale, NON è vero a livello di archiviazione.
Git usa delta per l'archiviazione .
Non solo, ma è più efficiente di qualsiasi altro sistema. Poiché non mantiene la cronologia per file, quando desidera eseguire la compressione delta, prende ogni BLOB, seleziona alcuni BLOB che probabilmente saranno simili (usando l'euristica che include l'approssimazione più vicina della versione precedente e alcuni altri), cerca di generare i delta e seleziona quello più piccolo. In questo modo può (spesso dipende dall'euristica) sfruttare altri file simili o versioni precedenti che sono più simili alla precedente. Il parametro "finestra pacchetto" consente le prestazioni di trading per la qualità di compressione delta. Il valore predefinito (10) generalmente fornisce risultati decenti, ma quando lo spazio è limitato o per accelerare i trasferimenti di rete, git gc --aggressiveutilizza il valore 250, che lo rende molto lento, ma fornisce una compressione extra per i dati della cronologia.


4
@JanHudec buon punto. Ho incluso il tuo commento nella risposta per una maggiore visibilità.
VonC

1
Qualcuno conosce il termine informatico per il modello di archiviazione simile a Git, noto anche come archivio di valori basato su hash? (o qualcosa di simile)
Joannes Vermorel,

34
Nel contesto dell'attuale domanda del PO, il primo paragrafo sembra davvero fuorviante. Non fino a quando si arriva al punto finale che si apprende che, oh sì, infatti Git fa "store [...] differenze tra i file. Davvero che informazioni è stato segnalato fino in alto e non sepolto così in profondità. Detto questo, grazie a almeno includendo la vera storia da qualche parte nella tua risposta;)
Josh O'Brien il

1
@NickVolynkin Great! Sono contento che quelle risposte stiano trovando un pubblico più vasto.
VonC,

1
Un altro buon libro: Git From The Bottom Up: ftp.newartisans.com/pub/git.from.bottom.up.pdf
Jonas Berlin,

46

Git archivia logicamente ogni file nel suo SHA1. Ciò significa che se in un repository sono presenti due file con esattamente lo stesso contenuto (o se si rinomina un file), viene memorizzata solo una copia.

Ciò significa anche che quando si modifica una piccola parte di un file e si esegue il commit, viene memorizzata un'altra copia del file. Il modo in cui git risolve questo problema sta usando i file pack. Di tanto in tanto, tutti i file "sciolti" (in realtà, non solo i file, ma anche gli oggetti contenenti informazioni di commit e di directory) da un repository vengono raccolti e compressi in un file pack. Il file del pacchetto è compresso usando zlib. E file simili sono anche delta-compressi.

Lo stesso formato viene utilizzato anche durante il pull o il push (almeno con alcuni protocolli), quindi non è necessario riconfigurare nuovamente quei file.

Il risultato di ciò è che un repository git, contenente l'intera copia di lavoro non compressa, i file recenti non compressi e i file compressi più vecchi di solito è relativamente piccolo, due volte più piccolo della dimensione della copia di lavoro. Ciò significa che è più piccolo del repository SVN con gli stessi file, anche se SVN non memorizza la cronologia localmente.


1
ah così mercuriale è più efficiente nello spazio
Ben
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.