Come posso pulire la mia cartella .git? Ho ripulito la directory del mio progetto, ma .git è ancora enorme


86

Il .git / objects nella directory del mio progetto rails è ancora enorme, dopo aver eliminato centinaia di megabyte di spazzatura generata accidentalmente.

Ho provato git add -A, oltre ad altri comandi, ad aggiornare l'indice e rimuovere file inesistenti. Capisco, forse in modo errato, che i file con due nomi di caratteri nella directory sono BLOB. Ho provato a tornare ai commit precedenti, ma senza fortuna.

Cosa posso fare per pulire questa directory?

Risposte:


139
  • Se hai aggiunto i file e poi li hai rimossi, i BLOB esistono ancora ma sono sospesi. git fsckelencherà i BLOB irraggiungibili e git pruneli eliminerà.

  • Se hai aggiunto i file, eseguito il commit e poi eseguito il rollback con git reset --hard HEAD^, sono bloccati un po 'più in profondità. git fscknon elencherà alcun commit o blob pendenti, perché il reflog del tuo ramo li tiene. Ecco un modo per assicurarti che rimarranno solo gli oggetti presenti nella tua cronologia:

    git reflog expire --expire=now --all
    git repack -ad  # Remove dangling objects from packfiles
    git prune       # Remove dangling loose objects
    
  • Un altro modo è anche clonare il repository, poiché questo trasporterà solo gli oggetti che sono raggiungibili. Tuttavia, se gli oggetti penzolanti sono stati impacchettati (e se hai eseguito molte operazioni, git potrebbe essersi impacchettato automaticamente), allora un clone locale trasporterà l'intero file di pacchetto:

    git clone foo bar                 # bad
    git clone --no-hardlinks foo bar  # also bad
    

    Devi specificare un protocollo per forzare git a calcolare un nuovo pacchetto:

    git clone file://foo bar  # good
    

Sì, mi sono impegnato prima di notare il problema. Ho provato tutto tranne l'ultimo comando. Quando lo eseguo dalla directory del mio progetto "avviso: sembra che tu abbia clonato un repository vuoto". Ho letto la documentazione, ma è roba pesante. Come posso puntare il clone alla fonte corretta?
lampadine

1
@user L' file://fooURL è relativo alla directory corrente e una file:///home/me/foo(tre barre) è assoluta.
Josh Lee

Grazie! ha dimezzato le dimensioni, ma il mio pacchetto è ancora dieci volte più grande del resto del repository. Ho provato a potare ..
lampadine

1
@user Se molti commit hanno erroneamente file di grandi dimensioni, potresti voler usare git-filter-branch per selezionarli.
Josh Lee

2
Spiacenti, senza alcun effetto. Il mio responsabile dello sviluppo dice che la dimensione è ora entro un intervallo accettabile ma sfavorevole. Se hai il tempo di continuare a darmi da mangiare con il cucchiaio sarebbe eccellente, ma mi hai rimesso in piedi. Grazie jleedev.
lampadine


15

Sparkleshare ha creato 13 GB di file tmp_pack_ nel mio git dopo non essere riuscito a estrarre molte volte un enorme archivio di immagini. L'unica cosa che ha aiutato è stata ...

rm -f .git/objects/*/tmp_*

"git gc" non ha rimosso quei file.


Questa è una soluzione piuttosto bruta ma non vedo motivo per cui non funzionerebbe. Bello!
lampadine

1
Situazioni disperate richiedono misure disperate, ha funzionato a meraviglia! Tks.
medina

rm è per il comando linux? per quanto riguarda l'utente Windows quindi @cat?
gumuruh

7

Se hai ancora un grande repo dopo la potatura e il reimballaggio ( gc --aggressive --prune=tomorrow...), puoi semplicemente andare a cercare quello strano:

git rev-list --objects --all |
    while read sha1 fname
    do 
        echo -e "$(git cat-file -s $sha1)\t$\t$fname"
    done | sort -n

Questo ti darà un elenco ordinato di oggetti in dimensione crescente. Puoi usare git-filter-branch per rimuovere il colpevole dal tuo repository.

Vedere "Rimozione di oggetti" in http://progit.org/book/ch9-7.html per una guida


@DavidJames grazie per il suggerimento. L'ho reso ancora più leggibile, IMO
vedi il

Nel caso in cui qualcun altro inciampi su questo: c'è un errore di battitura negli argomenti tra parentesi: dovrebbe essere --aggressive. Ho provato a modificare, ma risulta che non puoi modificare un errore di battitura così piccolo.
hellobenallan

@ hellobenallan grazie per la nota, risolto
sehe

1

Ricorsivamente:

find ./ -iname '*.!*' -size 0 -delete
for i in */.git; do ( echo $i; cd $i/..; git gc --aggressive --prune=now --force; ); done
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.