git gc –aggressive –prune=all no elimina archivos grandes del repositorio

3 minutos de lectura

git gc aggressive pruneall no elimina archivos grandes del repositorio
Zhuoyun Wei

Hay muchas preguntas SO sobre “cómo eliminar un archivo grande agregado accidentalmente del repositorio”, muchas de ellas sugieren usar git gc mando. Sin embargo, encuentro que no funciona para mí y no sé qué está pasando.

Esto es lo que he hecho:

$ git init
Initialized empty Git repository in /home/wzyboy/git/myrepo/.git/
$ echo hello >> README
$ git add README 
$ git commit -a -m 'init commit'
[master (root-commit) f21783f] init commit
 1 file changed, 1 insertion(+)
 create mode 100644 README
$ du -sh .git
152K    .git
$ cp ~/big.zip .
$ git add big.zip 
$ git commit -a -m 'adding big file'
[master 3abd0a4] adding big file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 big.zip
$ du -sh .git
77M .git
$ git log --oneline 
3abd0a4 adding big file
f21783f init commit
$ git reset --hard f21783f
HEAD is now at f21783f init commit
$ git log --oneline 
f21783f init commit
$ git gc --aggressive --prune=all
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 0 (delta 0)
$ git gc --aggressive --prune=now
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 6 (delta 0)
$ du -sh .git
77M .git
$ git version
git version 2.2.2

En la salida de la consola anterior, creé un nuevo repositorio de git, agregué un pequeño archivo de texto y el .git El directorio tiene un tamaño de 152 K, hasta ahora todo bien. Luego agregué un archivo grande en el repositorio y el directorio se hincha a 77M. Sin embargo, después de intentar eliminar el archivo grande (git reset --hard o git rebase -i), no puedo recuperar el espacio en disco reclamado por el archivo grande, no importa cómo lo ejecute git gc con diferentes opciones.

¿Alguien podría decirme por qué? git gc no funciona en mi caso? ¿Qué debo hacer para recuperar el espacio en disco? ¿Es posible recuperar el espacio en disco usando git gc en vez de git filter-branch?

Gracias.

  • git reflog expire --expire=now --all

    – Andrés C.

    04 feb.

  • @AndrewC ¡funciona! ¡Gracias!

    – Zhuoyun Wei

    04 feb.

Como sugirió Andrew C, uno debe expirar reflog para desreferenciar los objetos antes git gc pudiendo reciclar los objetos sueltos. Entonces, la forma correcta de recuperar el espacio en disco reclamado por archivos grandes agregados accidentalmente es:

git reflog expire --expire=now --all
git gc --aggressive --prune=now

Esto eliminará todos los reflogs, así que utilícelo con precaución.

  • “Esto eliminará todos los reflogs” ¿Puede explicar por qué esto puede ser un problema?

    – eri0o

    31 dic. 21 a las 21:14


  • @ eri0o Puede usar reflogs para recuperarse si accidentalmente arruinó su historial de git (por ejemplo, eliminando una rama no fusionada).

    – Zhuoyun Wei

    1 de enero a las 3:45

Un consejo que puede ayudar a evitar cualquier error tipográfico, con Git 2.18 (Q2 2018) es evitar un gc prune con referencia inexistente (llamada aquí: “nonsense“)

git gc --prune=nonsense” pasó mucho tiempo reempaquetando y luego falló silenciosamente cuando estaba subyacente “git prune --expire=nonsense” no pudo analizar su línea de comando.
Esto ha sido corregido.

Ver cometer 96913c9 (23 abr 2018) por Junio ​​C Hamano (gitster).
Ayudado por: Linus Torvalds (torvalds).
(Combinado por Junio ​​C Hamano — gitster en cometer 3915f9a, 08 de mayo de 2018)

parseopt: mango malformado --expire argumentos más bonitos

Algunos comandos que analizan --expire=<time> La opción de línea de comando se comporta de manera tonta cuando se le da una entrada sin sentido.
Por ejemplo

$ git prune --no-expire
Segmentation falut
$ git prune --expire=npw; echo $?
129

Ambos vienen de parse_opt_expiry_date_cb().

Lo primero es porque la función no está preparada para ver arg==NULL (por “--no-expire“, es una norma; “--expire” al final de la línea de comando podría hacerse pasar NULL, si se dice que el argumento es opcional, pero no lo hacemos así que no tenemos que preocuparnos por ese caso).

Esto último se debe a que no verifica el valor devuelto por el
underlying parse_expiry_date().

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad