2010-12-12 15 views
18

Solo per divertimento, sto provando a mettere circa git di file binari per lo più intorno a 6MB in git. Git affonda per un po 'ma invariabilmente fallisce a metà strada con il messaggio "fatale: confuso da dati sorgente oggetto instabili" seguito da uno SHA1. Sai perché? C'è un modo per risolverlo?git dice "fatale: confuso da dati origine oggetto instabili"

risposta

19

In entrambi i

  • uno o più file vengono modificati durante l'operazione, o
  • qualcosa sta causando incoerente legge (hardware per esempio in mancanza).

Versione corta: gli sviluppatori di Git non intendevano utilizzarlo su file volatili.

causa del layout * che Git utilizza per “oggetti sciolti” e la semantica del file system limitate che essa assume **, Git deve conoscere il primo byte (due caratteri esadecimali) del nome oggetto (SHA 1) di un nuovo oggetto prima che possa iniziare a memorizzare quell'oggetto.

* Le directory objects/[0-9a-f][0-9a-f]/. Vedi gitrepository-layout.
** In particolare, deve essere in grado di eseguire rinomina di file "atomici".Determinati filesystem (solitamente i filesystem di rete, in particolare AFS, credo) garantiscono la rinominazione dell'atomicità solo quando l'origine e la destinazione di un rinominato si trovano all'interno della stessa directory.

Attualmente, Git fa due SHA-1 passa sopra ogni nuovo file . Il primo passaggio viene utilizzato per verificare se Git conosce già il contenuto del file (se il suo nome oggetto SHA-1 esiste già nell'archivio oggetti). Se l'oggetto esiste già, il secondo passaggio non viene eseguito.

Per i nuovi contenuti (l'oggetto non era già nell'archivio oggetti), il file viene letto una seconda volta durante la compressione e il calcolo dello SHA-1 dei dati compressi. I dati compressi vengono scritti in un file temporaneo che viene rinominato solo nel suo nome di oggetto finale finale se il controllo iniziale SHA-1 ("già memorizzato?") Corrisponde al successivo SHA-1 (hash dei dati che sono stati compressi e scritti) . Se questi hash SHA-1 non corrispondono, Git mostra il messaggio di errore che stai vedendo e abortisce. Questo controllo degli errori è stato aggiunto in 748af44c63 che è stato rilasciato per la prima volta in Git 1.7.0.2.

+0

Abbastanza sicuro che non sia volatile, ma è ancora stato * molto * istruttivo leggere di più sull'interno di git. Credo che ora devo andare e assicurarmi che il mio disco non stia fallendo. – jbfink

+10

sicuramente sarebbe bello se dicesse "fatale: confuso da dati sorgente oggetto instabili" seguito da uno SHA1 E POI SEGUITO DAL FILE. Piuttosto fastidioso che non ti dice quale file è volatile ... Se lo facessi potrei ragionevolmente aggiungerlo o la directory al mio .gitignore –

+4

quindi qual è la soluzione per questo? –

3

due teorie:

  • Qualcosa sta scrivendo a questi file mentre si sta cercando di metterli in git.

  • Si ha una sorta di errore su disco/memoria che causa il danneggiamento dei dati.

4

Dal source, sha1 del blob viene calcolato due volte:

  • write_sha1_file_prepare
  • write_loose_object

sia chiamato da write_sha1_file (c'è anche un percorso da force_object_loose, ma è usato per i repack).

Il primo hash viene utilizzato per verificare se l'oggetto è già noto (sebbene git faccia del suo meglio per ottenere la rassicurazione del file system che i file non sono modificati, uno touch o simili gli farebbe perdere traccia); il secondo è l'hash dei dati che vengono effettivamente inseriti in zlib per la compressione, quindi scritti.

Il secondo hash potrebbe essere un po 'più costoso da calcolare a causa di zlib, il che potrebbe spiegare il motivo per cui vengono calcolati due hash (anche se questo sembra essere un incidente storico, e sto indovinando il costo delle prestazioni quando si aggiunge un nuovo oggetto più impatto rispetto alla vittoria della cpu quando si rilevano cambiamenti spuri). Qualcuno potrebbe aggiungere un fallback in modo che la logica di controllo dell'esistenza write_changed_sha1 venga rifatta con il nuovo sha1, in modo che anche quei file instabili possano essere aggiunti. Ciò sarebbe utile per i backup, quando alcuni dei file aggiunti sono aperti.

15

C'è un'altra possibilità, anche se remota. Quello sarebbe un file veramente grande (per esempio 3 o più GB) che lo mette semplicemente, git non è in grado di gestirlo. Abbiamo trovato quell'errore cercando di creare un repository in una struttura con file enormi

+0

Semplicemente è successo con un file di log multi-gigabyte che si è intrufolato in un albero di lavoro git. – fche

+0

File di grandi dimensioni (ma stabili) causano sicuramente questo errore. Il fatto che il messaggio di errore sia fuorviante e che Git non ti sveli in anticipo sulle dimensioni è una lacuna, almeno per ora, di Git. Ho provato git-annex, un modo promettente per gestire file di grandi dimensioni, ma finora non sono riuscito a farlo funzionare su OS/X. –

0

Può succedere se si prova a git svn clone o git svn recuperare un repository su un filesystem btrfs, forse qualcosa a che fare con condizioni di competizione o atomicità all'interno caratteristica della mucca btrfs.

Esempio:

git svn --authors-file=authors.map clone http://svn.example.com/svn/repo repo 

o

cd repo; git svn --authors-file=../authors.map fetch 

ho trovato una soluzione alternativa per impostazione di base directory di lavoro senza copy-on-write:

chattr +C . 

allora avete bisogno di duplicare tutti i tuoi dati (ex):

cp -fr repo repo.new; rm -fr repo; mv -f repo.new repo 

cp authors.map authors.map.new; mv -f authors.map.new authors.map 

Quindi non dovrebbe fallire (ed essere più veloce).

Problemi correlati