¿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?

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
    

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


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.


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.


@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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.