Eliminar archivo del repositorio git (historial)


(resuelto, ver parte inferior del cuerpo de la pregunta)
Buscando esto desde hace mucho tiempo, lo que tengo hasta ahora es:

Prácticamente el mismo método, pero ambos dejan objetos en archivos de paquete... Pegar.
Lo que intenté:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc

Todavía tengo archivos en el paquete, y así es como lo sé:

git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3

Y esto:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune

Lo mismo...

Intentó git clone truco, se eliminaron algunos de los archivos (~3000 de ellos), pero los archivos más grandes todavía están allí...

Tengo algunos archivos legados grandes en el repositorio, ~200M, y realmente no los quiero allí... Y no quiero restablecer el repositorio a 0 :(

SOLUCIÓN: Esta es la forma más corta de deshacerse de los archivos:

  1. jaque .git / packed-refs-mi problema era que tenía un refs/remotes/origin/master línea para un repositorio remoto, elimínelo, de lo contrario git no eliminará esos archivos
  2. (facultativo) git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - para comprobar los archivos más grandes
  3. (facultativo) git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 - para comprobar cuáles son esos archivos
  4. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' - para eliminar un archivo de todas las revisiones
  5. rm -rf .git/refs/original/ - para eliminar la copia de seguridad de git
  6. git reflog expire --all --expire='0 days' - caducar todos los objetos sueltos
  7. git fsck --full --unreachable - para comprobar si hay objetos sueltos
  8. git repack -A -d - reembalaje
  9. git prune - para finalmente eliminar esos objetos
Author: Boris Churzin, 2010-01-29

8 answers

No puedo decir con seguridad sin acceso a los datos de su repositorio, pero creo que probablemente hay uno o más refs empaquetados que todavía hacen referencia a confirmaciones antiguas de antes de ejecutar git filter-branch. Esto explicaría por qué git fsck --full --unreachable no llama al blob grande un objeto inalcanzable, a pesar de que ha caducado su reflog y ha eliminado las referencias originales (desempaquetadas).

Esto es lo que haría (después de que git filter-branch y git gc se hayan hecho):

1) Asegúrese de que los refs originales son gone:

rm -rf .git/refs/original

2) Expire todas las entradas de reflog:

git reflog expire --all --expire='0 days'

3) Compruebe si hay refs empaquetados viejos

Esto podría ser potencialmente complicado, dependiendo de cuántos refs empaquetados tengas. No conozco ningún comando de Git que automatice esto, así que creo que tendrás que hacerlo manualmente. Haga una copia de seguridad de .git/packed-refs. Ahora edita .git/packed-refs. Compruebe si hay referencias antiguas (en particular, vea si contiene alguna de las referencias de .git/refs/original). Si encuentras alguno viejo que no es necesario estar allí, eliminarlos(eliminar la línea para que ref).

Después de terminar de limpiar el archivo packed-refs, vea si git fsck nota los objetos inalcanzables:

git fsck --full --unreachable

Si eso funcionó, y git fsck ahora informa que su gran blob es inalcanzable, puede pasar al siguiente paso.

4) Vuelva a empaquetar su (s) archivo (s) embalado (s)

git repack -A -d

Esto asegurará que los objetos inalcanzables se desempaqueten y permanezcan descomprimir.

5) Podar objetos sueltos (inalcanzables)

git prune

Y eso debería bastar. Git realmente debería tener una mejor manera de gestionar las referencias empaquetadas. Tal vez hay una mejor manera que no conozco. En ausencia de una mejor manera, la edición manual del archivo packed-refs podría ser la única manera de hacerlo.

 61
Author: Dan Moulding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-01 21:39:55

Recomiendo usar el BFG Repo-Cleaner, una alternativa más simple y rápida a git-filter-branch diseñada específicamente para reescribir archivos del historial de Git. Una forma en la que te hace la vida más fácil aquí es que en realidad maneja todas las referencias por defecto (todas las etiquetas, ramas, cosas como refs/remotes/origin/master, etc.) pero también es 10-50x más rápido.

Debe seguir cuidadosamente estos pasos aquí: http://rtyley.github.com/bfg-repo-cleaner/#usage - pero el bit central es solo esto: descargue el jar de BFG (requiere Java 6 o superior) y ejecute este comando:

$ java -jar bfg.jar  --delete-files file_name  my-repo.git

Cualquier archivo llamado file_name (que no esté en su última confirmación) será totalmente eliminado del historial de su repositorio. Luego puede usar git gc para limpiar los datos muertos:

$ git gc --prune=now --aggressive

El BFG es generalmente mucho más simple de usar que git-filter-branch - las opciones se adaptan en torno a estos dos casos de uso comunes:

  • Eliminación Grandes archivos locos
  • Eliminar Contraseñas, Credenciales y otros Datos privados

Revelación completa: Soy el autor del Repo-Cleaner de BFG.

 9
Author: Roberto Tyley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-16 20:06:49

Encontré que esto es muy útil con respecto a eliminar una carpeta completa, ya que lo anterior realmente no me ayudó: https://help.github.com/articles/remove-sensitive-data .

He utilizado:

git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--prune-empty --tag-name-filter cat -- --all

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
 6
Author: Mike Averto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-04 00:06:34

Estaba tratando de deshacerme de un gran archivo en la historia, y las respuestas anteriores funcionaron, hasta cierto punto. El punto es: no funcionan si tienes etiquetas. Si el commit que contiene el archivo grande es accesible desde una etiqueta, entonces necesitará ajustar el comando filter-branches de esta manera:

git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
 4
Author: BHMulder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-04 00:08:52

Ver: Cómo puedo eliminar archivos sensibles del historial de git

Lo anterior fallará si el archivo no existe en una rev. En ese caso, el interruptor 'ignore ignore-unmatch' lo arreglará:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD

Entonces, para obtener todos los objetos sueltos del repositorio:

git gc --prune='0 days ago'
 2
Author: Wayne Conrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:50

Tiene varias razones para un tamaño de repositorio git aún grande después de git gc, ya que no elimina todos los objetos sueltos.

Detallo esas razones en " reduce el tamaño del repositorio git "

Pero un truco para probar en su caso sería clone su repositorio Git "limpiado" y vea si el clon tiene el tamaño apropiado.

('"limpiado" repo ' es el que se aplica el filter-branch, y luego gc y prune)

 1
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:29

Esto debería ser cubierto por el comando git obliterate en Git Extras ( https://github.com/visionmedia/git-extras).

git obliterate <filename>
 0
Author: Spain Train,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-25 20:25:49

Tuve el mismo problema y encontré un gran tutorial en github que explica paso a paso cómo deshacerse de los archivos que ha cometido accidentalmente.

Aquí hay un pequeño resumen del procedimiento como sugirió Cupcake.

Si tiene un archivo llamado file_to_remove para eliminar del historial:

cd path_to_parent_dir

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch file_to_remove' \
  --prune-empty --tag-name-filter cat -- --all
 0
Author: Cyril Leroux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-04 09:57:07