¿Cómo puedo limpiar mi carpeta .git? Limpié el directorio de mi proyecto, pero .git sigue siendo enorme

85

El .git / objects en mi directorio de proyectos rails sigue siendo enorme, después de eliminar cientos de Megabytes de basura generada accidentalmente.

He intentado git add -A, así como otros comandos, actualizar el índice y eliminar archivos inexistentes. Deduzco, quizás incorrectamente, que los archivos con dos nombres de caracteres en el directorio son blobs. He intentado volver a las confirmaciones anteriores, pero no tuve suerte.

¿Qué puedo hacer para limpiar este directorio?

bombillas
fuente

Respuestas:

137
  • Si agregó los archivos y luego los eliminó, las manchas aún existen pero están colgando. git fsckmostrará una lista de blobs inalcanzables y git prunelos eliminará.

  • Si agregó los archivos, los comprometió y luego los revertió git reset --hard HEAD^, se atascan un poco más. git fsckno enumerará ninguna confirmación o blobs colgantes, porque el reflog de su rama los está reteniendo. Aquí hay una forma de asegurarse de que solo permanezcan los objetos que están en su historial propiamente dicho:

    git reflog expire --expire=now --all
    git repack -ad  # Remove dangling objects from packfiles
    git prune       # Remove dangling loose objects
    
  • Otra forma es también clonar el repositorio, ya que solo llevará los objetos que son accesibles. Sin embargo, si los objetos colgantes se empaquetaron (y si realizó muchas operaciones, es posible que git se haya empaquetado automáticamente), entonces un clon local llevará todo el archivo de paquete:

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

    Debes especificar un protocolo para forzar a git a calcular un nuevo paquete:

    git clone file://foo bar  # good
    
Josh Lee
fuente
Sí, me comprometí antes de darme cuenta del problema. He intentado todo menos el último comando. Cuando ejecuto esto desde el directorio de mi proyecto, "advertencia: parece que has clonado un repositorio vacío". He estado leyendo la documentación, pero es un material pesado. ¿Cómo puedo apuntar el clon a la fuente correcta?
24 bombillas
1
@user La file://fooURL es relativa al directorio actual y una file:///home/me/foo(tres barras) es absoluta.
Josh Lee
¡Gracias! eso es reducir el tamaño a la mitad, pero mi paquete sigue siendo diez veces el tamaño del resto del repositorio. He intentado podar ..
light24bulbs
1
@user Si muchas confirmaciones tienen archivos grandes erróneamente, entonces es posible que desee usar git-filter-branch para seleccionarlos.
Josh Lee
2
Lo siento, sin efecto. Mi líder de desarrollo dice que el tamaño ahora está dentro del rango aceptable pero desfavorable. Si tienes tiempo para seguir alimentándome con cuchara, sería excelente, pero me has recuperado. Gracias jleedev.
24 bombillas
33

¿Has probado el git gccomando?

ryanprayogo
fuente
3
git gc --aggressive --prunefunciona para mi. git gcno. Quizás la configuración predeterminada no sea suficiente.
Moonlight Knight
13

Sparkleshare creó 13 GB de archivos tmp_pack_ en mi git después de no poder extraer muchas veces un registro de imágenes enormes. Lo único que ayudó fue ...

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

'git gc' no eliminó esos archivos.

gato
fuente
Esa es una solución de fuerza bruta bastante, pero no veo ninguna razón para que no funcione. ¡Agradable!
24 bombillas
1
Las situaciones desesperadas requieren medidas desesperadas. ¡Funcionó a las mil maravillas! Tks.
medina
rm es para el comando linux? ¿Qué pasa con el usuario de Windows y luego @cat?
gumuruh
7

Si todavía tiene un gran repositorio después de podar y reempacar ( gc --aggressive --prune=tomorrow...) entonces simplemente puede buscar el que no sea el siguiente:

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

Esto le dará una lista ordenada de objetos en tamaño ascendente. Puede usar git-filter-branch para eliminar al culpable de su repositorio.

Consulte "Eliminación de objetos" en http://progit.org/book/ch9-7.html para obtener orientación.

sehe
fuente
@DavidJames gracias por la pista. Lo hice aún más legible, en mi opinión
vea el
En caso de que alguien más tropiece con esto: hay un error tipográfico en los argumentos entre paréntesis: debería ser --aggressive. Intenté editar, pero resulta que no puedes editar un error tipográfico tan pequeño.
hellobenallan
@hellobenallan gracias por la nota, arreglada
sehe
1

Recursivamente:

find ./ -iname '*.!*' -size 0 -delete
for i in */.git; do ( echo $i; cd $i/..; git gc --aggressive --prune=now --force; ); done
Marcelo Grebois
fuente