¿Cómo eliminar objects no utilizados de un repository git?

Accidentalmente agregué, comprometí y empujé un gran file binary con mi último compromiso con un repository de Git.

¿Cómo puedo hacer que Git elimine los objects que fueron / fueron creados para esa confirmación, por lo que mi directory .git networkinguce a un tamaño razonable nuevamente?

Editar : gracias por tus respuestas; Intenté varias soluciones. Ninguno funcionó. Por ejemplo, el de GitHub eliminó los files del historial, pero el tamaño del directory .git no disminuyó:

 $ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;) $ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66) rm 'test_data/images/001.jpg' [...snip...] rm 'test_data/images/281.jpg' Ref 'refs/heads/master' was rewritten $ git log -p # looks nice $ rm -rf .git/refs/original/ $ git reflog expire --all $ git gc --aggressive --prune Counting objects: 625, done. Delta compression using up to 2 threads. Compressing objects: 100% (598/598), done. Writing objects: 100% (625/625), done. Total 625 (delta 351), reused 0 (delta 0) $ du -hs .git 174M .git $ # still 175 MB :-( 

¡Respondí esto en otro lugar y copyré aquí porque estoy orgulloso de eso!

… y sin más preámbulos, permítanme que les presente este guión útil, git-gc-all, que garantiza que eliminarán toda su basura git hasta que puedan llegar a tener variables de configuration adicionales:

 git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ -c gc.pruneExpire=now gc "$@" 

La opción –aggressive puede ser útil.

NOTA: esto eliminará TODAS las cositas sin reference, ¡así que no vengas a llorar si decides luego que querías conservar algunas de ellas!

También es posible que tengas que ejecutar algo como esto primero, ¡oh cariño, git es complicado!

 git remote rm origin rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/ git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d 

Puse todo esto en un guión, aquí:

http://sam.nipl.net/b/git-gc-all-ferocious

Tu git reflog expire --all es incorrecto. Elimina las inputs de reflog que son anteriores al time de caducidad, que por defecto es de 90 días. Utilice git reflog expire --all --expire=now .

Mi respuesta a una pregunta similar se refiere al problema de depurar realmente los objects no utilizados de un repository.

Se puede aplicar esta guía para eliminar datos confidenciales , utilizando el mismo método. Estarás reescribiendo el historial para eliminar ese file de todas las revisiones en las que estuvo presente. Esto es destructivo y causará conflictos de repository con cualquier otro process de pago, así que advierte a los queueboradores primero.

Si desea mantener el binary disponible en el repository para otras personas, entonces no hay una manera real de hacer lo que quiera. Es prácticamente todo o nada.

1) Elimine el file del git repo (y no el sistema de files):

  • git rm --cached path/to/file

2) Reducir el repository usando:

  • git gc ,

  • o git gc --aggressive

  • o git prune

o una combinación de los anteriores como se sugiere en esta pregunta: Reducir el tamaño del repository git

La key para mí resultó ser ejecutar git repack -A -d -f y luego git gc para networkingucir el tamaño del package de git que tenía.

Hy!

Git solo recibe objects que realmente necesita cuando clona repositorys (si lo entiendo correctamente)

De modo que puede modificar la última confirmación eliminando el file agregado por error, luego puede enviar sus cambios al repository remoto (con la opción -f para sobrescribir la confirmación anterior también en el server)

Luego, cuando hagas un nuevo clon de ese repository, su directory .git debe ser tan pequeño como antes de que se hayan cometido los files grandes.

Opcionalmente, si también desea eliminar los files innecesarios del server, puede eliminar el repository en el server e insert su copy recién clonada (que tiene el historial completo)

 git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all 

Recuerde cambiar el Filename de Filename para el que desea eliminar del repository.

Consulte "Eliminar objects" en el libro de Pro Git:

http://git-scm.com/book/es/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects

Actualización: ver también BFG repo cleaner: http://rtyley.github.io/bfg-repo-cleaner/