2012-02-26 10 views
23

Quería encontrar los 10 archivos más grandes en mi repositorio. El guión que se me ocurrió es como sigue:¿Cómo encontrar los N archivos más grandes en un repositorio git?

REP_HOME_DIR=<top level git directory> 
max_huge_files=10 

cd ${REP_HOME_DIR} 
git verify-pack -v ${REP_HOME_DIR}/.git/objects/pack/pack-*.idx | \ 
    grep blob | \ 
    sort -r -k 3 -n | \ 
    head -${max_huge_files} | \ 
    awk '{ system("printf \"%-80s \" `git rev-list --objects --all | grep " $1 " | cut -d\" \" -f2`"); printf "Size:%5d MB Size in pack file:%5d MB\n", $3/1048576, $4/1048576; }' 
cd - 

¿Existe una manera mejor/más elegante de hacer lo mismo?

Por "archivos" me refiero a los archivos que se han registrado en el repositorio.

+0

¿Es esto realmente para cualquier directorio, o hay algo específico sobre git usted está tratando de averiguar? Por tu conducto, supongo que cualquier comando de Unix está bien? –

+0

¿Quiere decir que los archivos están siendo rastreados o los archivos en el disco? Es posible que no se correlacionen de la manera que esperas. – Daenyth

+0

Archivos que se han registrado en el repositorio. – Sumit

Respuesta

1

También puede usar du - Ejemplo: du -ah objects | sort -n -r | head -n 10. du para obtener el tamaño de los objetos, sort ellos y luego elegir los 10 primeros usando head.

+0

solo le dice al objeto no el nombre del archivo. Se requerirán trucos para ignorar los archivos del paquete también. – Sumit

13

¿Qué tal

git ls-files | xargs ls -l | sort -nrk5 | head -n 10 

git ls-files: List all the files in the repo 
xargs ls -l: perform ls -l on all the files returned in git ls-files 
sort -nrk5: Numerically reverse sort the lines based on 5th column 
head -n 10: Print the top 10 lines 
+1

Esto se basa en archivos en mi versión actual de pago. Si se cometió un archivo de 10 MB y luego fue sobrescrito por otra versión de 1 KB, este comando no mostrará ese archivo. – Sumit

+2

Esta respuesta falla cuando tiene espacios en nombres de archivo/carpetas (aunque obtiene ** algunos ** resultados). Este pequeño cambio corrige ese problema: 'git ls-files -z | xargs -0 ls -l | ordenar -nrk5 | head -n 10' –

+0

Usaría una forma más simplificada: 'git ls-files -z | xargs -0 ls -l -h -S -r'. Esto debería proporcionarle una lista de todos los archivos dentro del repositorio ordenados de menor a mayor con tamaños legibles por humanos. Si desea truncar la lista, puede usar 'head' o' tail' para ayudar. Mis 5 centavos valen ... – Hans

31

he encontrado otra manera de hacerlo:

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

Citado de: SO: git find fat commit

+9

Gran respuesta - Cambiaría un poco a 'git ls-tree -r -l --abbrev --full-name HEAD | ordenar -n -r -k 4 | head -n 10': no necesita '-t' ya que no está interesado en listados de árbol (que no dan tamaño),' --abbrev' hace que el hash sea más legible, y 'head' en lugar de' tail' da la lista en orden de tamaño descendente – dumbledad

0

Puede utilizar find para encontrar archivos de más de una umbral dado, luego páselos al git ls-files para excluir archivos sin seguimiento (p. generación de salida):

find * -type f -size +100M -print0 | xargs -0 git ls-files 

Ajuste 100M (100 megabytes) según sea necesario hasta obtener resultados.

Advertencia menor: esto no buscará archivos y carpetas "ocultos" de alto nivel (es decir, aquellos cuyos nombres comiencen con .). Esto se debe a que utilicé find * en lugar de solo find para evitar buscar en la base de datos .git.

Estaba teniendo problemas para que las soluciones sort -n funcionen (en Windows bajo Git Bash). Supongo que se debe a diferencias de sangría cuando xargs analiza argumentos, lo que xargs -0 parece hacer automáticamente para trabajar alrededor del límite de longitud de línea de comando de Windows de 32767.

6

Este bash "one-liner" muestra los 10 blobs más grandes en el repositorio, ordenado de menor a mayor. En contraste con las otras respuestas, este incluye todos los archivos rastreados por el repositorio, incluso aquellos que no están presentes en ninguna sugerencia de rama.

Es muy rápido, fácil de copiar & pegar y solo requiere las utilidades estándar de GNU.

git rev-list --objects --all \ 
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \ 
| awk '/^blob/ {print substr($0,6)}' \ 
| sort --numeric-sort --key=2 \ 
| tail \ 
| cut --complement --characters=13-40 \ 
| numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest 

Las primeras cuatro líneas implementan la funcionalidad del núcleo, el quinto limita el número de resultados, mientras que las dos últimas líneas proporcionan el buen salida legible que tiene este aspecto:

... 
0d99bb931299 530KiB path/to/some-image.jpg 
2ba44098e28f 12MiB path/to/hires-image.png 
bd1741ddce0d 63MiB path/to/some-video-1080p.mp4 

Para obtener más información, incluidos más casos de uso de filtrado y un formato de salida más adecuado para el procesamiento de scripts, consulte mi original answer para obtener una pregunta similar.

+1

no está bromeando, ¡eso es rápido! – LeoR

1

Una mejora de la respuesta de raphinesse, clasificación por tamaño con el descendiente:

git rev-list --objects --all \ 
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \ 
| awk '/^blob/ {print substr($0,6)}' \ 
| sort --numeric-sort --key=2 --reverse \ 
| head \ 
| cut --complement --characters=13-40 \ 
| numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest 
+0

Apenas lo llamaría una mejora. Es más una cuestión de preferencia. Además, si alguien quisiera invertir el orden de las líneas, simplemente podría canalizar la salida de mi script original a través de 'tac'. – raphinesse

Cuestiones relacionadas