2009-08-17 30 views
44

Es posible obtener información acerca de cuánto espacio se desperdicia por los cambios en cada confirmación, por lo que puedo encontrar confirmaciones que agregan archivos grandes o muchos archivos. Esto es todo para tratar de reducir el tamaño de git repo (rebasing y quizás commits de filtrado)git find fat commit

+1

Considérese simplemente ejecutando 'git gc' vez en cuando , posiblemente como 'git gc --aggressive' – Hasturkun

+0

' git gc' (y 'git gc --prune'); '--aggresive' puede incluso dar peores resultados (pero generalmente no debería), y generalmente no vale la pena. –

+0

Esta respuesta es mucho mejor: http://stackoverflow.com/a/10847242/520567 – akostadinov

Respuesta

16

olvidado contestar, mi respuesta es:

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: Si leo su script correctamente, solo tiene en cuenta los archivos que fueron agregados_ en una confirmación en particular. No detectará cuándo un archivo creció sustancialmente en una confirmación. – kynan

+0

@kynan: Tiene razón, ya que eso es lo que solicitó el OP (y lo que necesitaba). Pero es fácil cambiar la secuencia de comandos para detectar archivos modificados: básicamente basta con reemplazar "A" por "M" en la llamada grep. Eso informará el tamaño total del archivo después de la modificación (no la cantidad de bytes agregados/eliminados). Acepto gustosamente una solicitud de extracción en GitHub para que el guión sea más genérico. – sschuberth

+7

Enlace roto, la secuencia de comandos ahora se encuentra [aquí] (https://github.com/sschuberth/dev-scripts/blob/master/git/git-commit-size.sh) – Luke

1

git cat-file -s <object> donde <object> puede hacer referencia a un commit, blob, tree o tag.

21

Usted puede hacer esto:

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

Esto mostrará los archivos más grandes en la parte inferior (cuarta columna es la) tamaño de gota de archivos (

Si usted tiene que mirar en diferentes ramas ustedes'. .. ll quiere cambiar HEAD para esos nombres rama o, dicho esto en un bucle sobre las ramas, etiquetas, o revoluciones usted está interesado en

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

Y también sugiero usar git format-patch para obtener el tamaño de compromiso (habrá un tamaño adicional para el encabezado del correo, pero en realidad si necesita comprometerse rápidamente no es demasiado grande, no es tan importante para obtener el tamaño exacto, + - 1K será buena precisión) –

2

git fat find N donde N es en bytes devolverá todos los archivos en el conjunto historia que son más grandes que N bytes.

Puede encontrar más información sobre git grasa aquí: https://github.com/cyaninc/git-fat

+0

Bummer. Lo probé en Git Shell para Windows que viene con GitHub Desktop y el comando no funcionó, lo que me dio un error. – DucRP

3

Todas las soluciones que aquí se centran en los tamaños de archivo pero la pregunta original se le preguntó fue acerca cometen tamaños, que en mi opinión, y en mi caso, fue más importante de encontrar (porque lo que quería es deshacerse de muchos pequeños binarios introducidos en una única confirmación, que sumados representaba un gran tamaño, pero pequeño si se medía individualmente por archivo).

Una solución que se centra en cometer tamaños es la proporcionada here, que es el script en 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` ; 
# } 
} 

Y que llamo así:

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