2009-08-17 30 views
44

È possibile ottenere informazioni su quanto spazio viene sprecato dalle modifiche in ogni commit, quindi posso trovare commit che hanno aggiunto file di grandi dimensioni o molti file. Questo è tutto per cercare di ridurre le dimensioni del repository git (rebasing e forse il filtring commit)git find fat commit

+1

consideri semplicemente eseguendo 'git gc' di tanto in tanto , possibilmente come 'git gc --aggressive' – Hasturkun

+0

' git gc' (e 'git gc --prune'); '--aggresive' può anche dare risultati peggiori (ma di solito non dovrebbe), e di solito non ne vale la pena. –

+0

Questa risposta è molto meglio: http://stackoverflow.com/a/10847242/520567 – akostadinov

risposta

16

dimenticato di rispondere, la mia risposta è:

git rev-list --all --pretty=format:'%H%n%an%n%s' # get all commits 
git diff-tree -r -c -M -C --no-commit-id #{sha}  # get new blobs for each commit 
git cat-file --batch-check << blob ids    # get size of each blob 
+1

@sschuberth: Se leggo correttamente il tuo script, prende in considerazione solo i file che sono stati _aggiunti_ in un particolare commit. Non rileverà quando un file è cresciuto sostanzialmente in un commit. – kynan

+0

@kynan: hai ragione, poiché è quello che l'OP ha richiesto (e ciò di cui avevo bisogno). Ma è facile cambiare lo script per rilevare i file modificati: in pratica è sufficiente sostituire "A" con "M" nella chiamata grep. Questo riporterà la dimensione totale del file dopo la modifica (non il numero di byte aggiunti/rimossi). Accetterei volentieri una richiesta di pull su GitHub per rendere lo script più generico. – sschuberth

+7

Collegamento interrotto, lo script ora si trova [qui] (https://github.com/sschuberth/dev-scripts/blob/master/git/git-commit-size.sh) – Luke

1

git cat-file -s <object> dove <object> può riferirsi a un commit, blob, albero o tag.

21

Si potrebbe fare questo:

git ls-tree -r -t -l --full-name HEAD | sort -n -k 4 

Questo mostrerà i file più grandi nella parte inferiore (quarta colonna è il file (blob) dimensioni

Se avete bisogno di guardare a diversi rami si'. .. ll vuole cambiare HEAD per quei nomi filiale o, mettere questo in un ciclo sopra i rami, i tag, o giri siete interessati a

1
#!/bin/bash 
COMMITSHA=$1 

CURRENTSIZE=$(git ls-tree -lrt $COMMITSHA | grep blob | sed -E "s/.{53} *([0-9]*).*/\1/g" | paste -sd+ - | bc) 
PREVSIZE=$(git ls-tree -lrt $COMMITSHA^ | grep blob | sed -E "s/.{53} *([0-9]*).*/\1/g" | paste -sd+ - | bc) 
echo "$CURRENTSIZE - $PREVSIZE" | bc 
+0

E inoltre suggerisco di usare git format-patch per ottenere dimensioni di commit (ci saranno alcune dimensioni aggiuntive per l'intestazione della posta, ma in realtà se hai bisogno di eseguire il commit veloce non è troppo grande - non è così importante per ottenere la dimensione esatta, + - 1K sarà una buona precisione) –

2

git fat find N dove N è in byte restituirà tutti i file in tutta la cronologia che è maggiore di N byte.

È possibile trovare maggiori informazioni su git-grassi qui: https://github.com/cyaninc/git-fat

+0

Bummer. L'ho provato su Git Shell per Windows che viene fornito con GitHub Desktop e il comando non ha funzionato, dandomi un errore. – DucRP

3

Tutte le soluzioni fornite qui si concentrano su dimensioni dei file ma la domanda iniziale chiesto era di circa commettere dimensioni, che a mio parere, e nel mio caso, è stato più importante trovare (perché quello che volevo è sbarazzarsi di molti piccoli binari introdotti in un singolo commit, che sommati corrispondevano a un sacco di dimensioni, ma di piccole dimensioni se misurati individualmente per file).

Una soluzione che si concentra su commettere dimensioni è la condizione here, che è questo script perl:

#!/usr/bin/perl 
foreach my $rev (`git rev-list --all --pretty=oneline`) { 
    my $tot = 0; 
    ($sha = $rev) =~ s/\s.*$//; 
    foreach my $blob (`git diff-tree -r -c -M -C --no-commit-id $sha`) { 
    $blob = (split /\s/, $blob)[3]; 
    next if $blob == "0000000000000000000000000000000000000000"; # Deleted 
    my $size = `echo $blob | git cat-file --batch-check`; 
    $size = (split /\s/, $size)[2]; 
    $tot += int($size); 
    } 
    my $revn = substr($rev, 0, 40); 
# if ($tot > 1000000) { 
    print "$tot $revn " . `git show --pretty="format:" --name-only $revn | wc -l` ; 
# } 
} 

E che io chiamo così:

./git-commit-sizes.pl | sort -n -k 1