2010-09-26 18 views
66

Accidentalmente agregué, comprometí y empujé un gran archivo binario con mi último compromiso con un repositorio de Git.¿Cómo eliminar objetos no utilizados de un repositorio de git?

¿Cómo puedo hacer que Git elimine los objetos que fueron/fueron creados para esa confirmación, por lo que mi directorio .git vuelve a tener un tamaño razonable?

Editar: Gracias por sus respuestas; Intenté varias soluciones. Ninguno funcionó. Por ejemplo el de GitHub elimina los archivos de la historia, pero el tamaño del directorio .git no ha disminuido:

$ 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 :-(
+9

Sólo un recordatorio para los moderadores, esta pregunta 100% pertenece el SO, no superusuario – VonC

+0

Vea también http://stackoverflow.com/questions/2116778/reduce-git-repository-size/2116892#2116892 y http://stackoverflow.com/questions/685319/git-pull-error-unable-to-create -temporary-sha1-filename/685422 # 685422 – VonC

+0

Como se menciona aquí (http://stackoverflow.com/questions/685319/git-pull-error-unable-to-create-temporary-sha1-filename/685422#685422), ¿Has probado un nuevo empaque después de tu GC? 'git-reeck -a' seguido por' git-prune-packed' por ejemplo. Ver http://blog.felipebalbi.com/2007/12/19/housekeeping-your-git-repository/ – VonC

Respuesta

9

Esta guía sobre removing sensitive data puede aplicar, utilizando el mismo método. Estarás reescribiendo el historial para eliminar ese archivo de todas las revisiones en las que estuvo presente. Esto es destructivo y causará conflictos de repositorio con cualquier otro proceso de pago, así que advierte a los colaboradores primero.

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

22

Su git reflog expire --all es incorrecto. Elimina las entradas de reflog que son anteriores al tiempo de caducidad, que por defecto es de 90 días. Use git reflog expire --all --expire=now.

My answer a una pregunta similar se ocupa del problema de depurar realmente los objetos no utilizados de un repositorio.

5

Hy!

Git sólo recibe objetos que realmente necesita cuando se clona repositorios (si he entendido bien)

Así que usted puede modificar la última confirmación eliminar el archivo agregado por error, luego empuje sus cambios en el repositorio remoto (con - f opción para sobrescribir la confirmación anterior en el servidor también)

Luego, cuando crea una nueva clonación de ese repositorio, su directorio .git debe ser tan pequeño como antes de que se hayan cometido los archivos grandes.

Opcionalmente, si desea eliminar los archivos innecesarios del servidor también puede eliminar el repositorio en el servidor y empujar a su copia recién clonado (que tiene la historia completa)

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

Recuerde cambiar Filename para el que quieres eliminar del repositorio.

93

¡Respondí esto en otro lugar, y copiaré aquí ya que estoy orgulloso de ello!

... y sin más preámbulos, les presento a que esta secuencia de comandos útiles, git-gc-todo, garantizado para eliminar toda la basura git hasta que podría llegar a las variables de configuración adicionales:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ 
    -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ 
    -c gc.pruneExpire=now gc "[email protected]" 

La opción --aggressive puede ser útil.

NOTA: esto eliminará TODAS las cosillas sin referencia, ¡así que no venga a pedirme si luego decide que quiere conservar algunas de ellas!

Es posible que también tengas que ejecutar algo como esto primero, oh cariño, ¡¡¡es muy 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 

pongo todo esto en un script, aquí:

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

+0

Como en http : //stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-repo/14728706#comment20614863_14728706, +1 de nuevo. – VonC

+10

excelente: D mi malvado plan para obtener más puntos clonando respuestas ha funcionado !! 1;) –

+0

¡Sí! Esto funcionó, pero tuve que ejecutar el script completo. Ejecutar solo el comando gc (con opciones de configuración) no fue suficiente. – Daniel

11

1) Retire el archivo desde el repositorio git (& no es el sistema de archivos):

  • git rm --cached path/to/file

2) Reducir el repositorio usando:

  • git gc,

  • o git gc --aggressive

  • o git prune

o una combinación de los anteriores como se sugiere en esta pregunta: Reduce git repository size

+0

'git gc' funcionó para mí! –

6

La clave para mí Cerrado para ejecutar git repack -A -d -f y luego git gc para reducir el tamaño del paquete de git único que tenía.

Cuestiones relacionadas