Agregué, comprometí y empujé accidentalmente un archivo binario enorme con mi última confirmación en un repositorio de Git.
¿Cómo puedo hacer que Git elimine los objetos que se crearon para esa confirmación para que mi .git
directorio se reduzca a un tamaño razonable nuevamente?
Editar : Gracias por tus respuestas; Probé varias soluciones. Ninguno funcionó. Por ejemplo, el de GitHub eliminó los archivos del historial, pero el .git
tamaño del directorio 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 :-(
git-repack -a
seguido de,git-prune-packed
por ejemplo. Ver blog.felipebalbi.com/2007/12/19/…filter-branch
,gc
,repack
, ...), no, usted no debe ver ninguna entrega mala en absoluto. Esta es una señal de que la limpieza no se realizó como se esperaba.Respuestas:
¡Respondí esto en otro lugar y lo copiaré aquí ya que estoy orgulloso de ello!
... y sin más preámbulos, puedo presentarles este útil script, git-gc-all, garantizado para eliminar toda su basura git hasta que puedan generar 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 "$@"
La opción --aggressive puede resultar útil.
NOTA: esto eliminará TODAS las cosas no referenciadas, ¡así que no me vengas llorando si decides más tarde que querías quedarte con algunas de ellas!
Es posible que también debas ejecutar algo como esto primero, ¡oh, cielos, 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
Pongo todo esto en un guión, aquí:
http://sam.nipl.net/b/git-gc-all-ferocious
fuente
xargs
comando produce un error en OS X debido a una opción no reconocida. La solución más simple: instale GNU xargs a través de homebrewbrew install findutils
y reempláceloxargs
porgxargs
.Tu
git reflog expire --all
es incorrecto. Elimina las entradas de registro que son más antiguas que el tiempo de vencimiento, que por defecto es de 90 días. Utilicegit reflog expire --all --expire=now
.Mi respuesta a una pregunta similar trata sobre el problema de borrar realmente los objetos no utilizados de un repositorio.
fuente
1) Elimine el archivo del repositorio de git (y no del sistema de archivos):
git rm --cached path/to/file
2) Reducir el repositorio usando:
git gc
,o
git gc --aggressive
git prune
o una combinación de lo anterior como se sugiere en esta pregunta: Reducir el tamaño del repositorio de git
fuente
Esta guía sobre la eliminación de datos confidenciales se puede aplicar utilizando el mismo método. Volverá a escribir el historial para eliminar ese archivo de todas las revisiones en las que estaba presente. Esto es destructivo y provocará conflictos de repositorio con cualquier otro pago, por lo que debe advertir primero a los colaboradores.
Si desea mantener el binario disponible en el repositorio para otras personas, entonces no hay una forma real de hacer lo que desea. Es prácticamente todo o nada.
fuente
La clave para mí resultó ser ejecutar
git repack -A -d -f
y luegogit gc
reducir el tamaño del paquete de git único que tenía.fuente
¡Hy!
Git solo recibe los objetos que realmente necesita al clonar repositorios (si lo entiendo correctamente)
Entonces puede modificar la última confirmación eliminando el archivo agregado por error, luego enviar sus cambios al repositorio remoto (con la opción -f para sobrescribir la confirmación anterior también en el servidor)
Luego, cuando haga un nuevo clon de ese repositorio, su directorio .git debe ser tan pequeño como antes de que se comprometieran los archivos grandes.
Opcionalmente, si también desea eliminar los archivos innecesarios del servidor, puede eliminar el repositorio en el servidor y enviar su copia recién clonada (que tiene el historial completo)
fuente
Consulte "Eliminación de objetos" en el libro Pro Git:
http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects
Actualización: consulte también el limpiador de repositorios BFG: http://rtyley.github.io/bfg-repo-cleaner/
fuente
Recuerde cambiar
Filename
por el que desea eliminar del repositorio.fuente
En 2020, la documentación de git-filter-branch desaconseja su uso y recomienda utilizar una alternativa como git-filter-repo . También se puede utilizar en lugar de BFG .
Tenga en cuenta que el capítulo sobre Reescritura del historial en el libro de git no se ha actualizado. Tampoco la recomendación de GitHub sobre la eliminación de datos confidenciales.
fuente