2010-01-29 34 views
70

(resuelto, véase la parte inferior del cuerpo cuestión)
Buscando esto durante mucho tiempo, lo que tengo hasta ahora es:Quitar del repositorio git (historia)

más o menos el mismo método, pero ambos dejan objetos en archivos de paquete ... Stuck.
lo que he intentado:

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 tiene 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 

El mismo ...

Probado git clone truco, eliminó 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: Este es el camino más corto para deshacerse de los archivos:

  1. cheque .git/envasados-refs - mi problema era que tenía allí una línea refs/remotes/origin/master para un repositorio remoto, elimínelo; de lo contrario, git no eliminará esos archivos
  2. (o pcional)git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - para comprobar si los archivos más grandes
  3. (opcional)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' - EXPIRAR todos los objetos sueltos
  7. git fsck --full --unreachable - para comprobar si hay objetos sueltos
  8. git repack -A -d - volver a embalar
  9. git prune - para eliminar finalmente los objetos
+5

Soooo, tu pregunta es ...? – zneak

+0

Posibles duplicados: http://stackoverflow.com/questions/2100907/how-to-purge-a-huge-file-from-commits-history-in-git/2158271 http://stackoverflow.com/questions/872565/how-do-i-remove-sensitive-files-from-gits-history –

+0

zneak - mi pregunta está en el título. gbacon - los probó, los archivos aún permanecen en el archivo del paquete ... – Devenv

Respuesta

59

No puedo decir con seguridad que no tienen acceso a sus datos del repositorio, pero yo creo que hay probablemente uno o más refs empaquetados sigan haciendo referencia a compromisos anteriores de antes de ejecutar git filter-branch. Esto explicaría por qué git fsck --full --unreachable no llama al blob grande un objeto inalcanzable, aunque haya expirado su reflog y haya eliminado los refs originales (desempaquetados).

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

1) Asegúrese de que los árbitros originales se han ido:

rm -rf .git/refs/original

2) caducar todas reflog entradas:

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

3) Comprobar si hay viejos árbitros empaquetados

Esto podría ser complicado, dependiendo del número de árbitros compactada que tiene. 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 edite .git/packed-refs. Compruebe si hay referencias antiguas (en particular, fíjese si contiene alguno de los refs del .git/refs/original). Si encuentra alguno antiguo que no necesita estar allí, elimínelo (elimine la línea para esa referencia).

Después de terminar la limpieza del archivo packed-refs, a ver si git fsck da cuenta de los objetos inalcanzables:

git fsck --full --unreachable

Si eso funcionó, y git fsck informa ahora su gran bolsa como inalcanzable, puede pasar a la próximo paso.

4) vuelva a embalar el archivo en paquete (s)

git repack -A -d

Esto asegurará que los objetos inalcanzables consiguen desempaquetar y estancia desempaquetado.

5) podar suelto (inalcanzable) objetos

git prune

Y eso debería hacerlo. Git realmente debería tener una mejor manera de administrar refs empaquetados. Tal vez hay una mejor manera que yo no sé. A falta de una mejor manera, la edición manual del archivo packed-refs podría ser la única manera de hacerlo.

+1

¡Yey! !! Te amo ! El problema estaba en el archivo packed-refs, había refs/remotes/origin/master desde que lo estaba respaldando en algún servidor ... una vez que lo quitaba todo comenzó a desaparecer ... ¡Gracias! (actualizando el cuerpo de la pregunta con la solución completa) – Devenv

+0

¡Oh, hombre, la sugerencia acerca de los packed-ref fue muy útil! –

2

Ver: How do I remove sensitive files from git’s history

Lo anterior se producirá un error si el archivo no existe en un rev.En ese caso, el interruptor '--ignore-unmatch' lo arreglará:

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

Entonces, para conseguir todos los objetos sueltos fuera de la repostiry:

git gc --prune='0 days ago' 
+0

Sí, lo intenté, todavía tengo los archivos en el paquete, y el tamaño no cambió demasiado ... – Devenv

+0

Acabo de hacer un arenero git y lo intenté. No es bueno aquí, tampoco. Veamos lo que puedo descubrir. –

+0

Lo tengo. Ver la versión editada. –

1

Usted tiene varias razones para un alambique gran tamaño de git repo después de git gc, ya que es does not remove all loose objects.

detallo dichos motivos en "reduce the git repository size"

Pero un truco para probar en su caso sería clone your "cleaned" Git repo y ver si el clon tiene el tamaño adecuado.

(' 'limpiado' repo' ser aquel en el que se aplicaba la filter-branch, y luego gc y prune)

+0

Sí, lo probé ya, y lo probé de nuevo ahora, redujo el repositorio en 2k :) y los archivos todavía están allí ... – Devenv

+0

Lo que es extraño es 'git count-objects -v -> count: 0, size: 0, in-pack : 10021, paquetes: 1, paquete de tamaño: 244547, poda-packable: 0, basura: 0' pero: 'git clone test1 test2 -> Comprobando archivos: 100% (8509/8509), hecho' – Devenv

4

Estaba tratando de deshacerme de un archivo grande en el historial, y las respuestas anteriores funcionaron, hasta cierto punto. El punto es que no funcionan si tienes etiquetas. Si el envío contiene el archivo grande es accesible desde una etiqueta, entonces usted tendría que ajustar el filtro de ramas comando así:

git filter-branch --tag-name-filter cat \ 
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \ 
--all --tags 
0

que tenían el mismo problema y me encontré con una gran tutorial en github que explican paso a paso cómo deshacerse de los archivos que accidentalmente cometió.

Aquí hay un pequeño resumen del procedimiento sugerido por Cupcake.

Si usted tiene un archivo llamado file_to_remove eliminar de la historia:

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

Las respuestas de enlace único son altamente desaconsejables en Stack Overflow, porque si el enlace se rompe en el futuro, entonces la respuesta se vuelve inútil.Considere resumir la información relevante contenida en el enlace en su respuesta. –

+0

Actualicé mi respuesta. Gracias por el consejo. –

6

Me pareció que para ser muy útil en lo que respecta a la eliminación de una carpeta completa que la anterior realmente no me ayudan: https://help.github.com/articles/remove-sensitive-data.

utilicé:

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 
7

le recomiendo usar el BFG Repo-Cleaner, una más sencilla, rápida alternativa a git-filter-branch diseñado específicamente para reescribir los archivos de la historia de Git. Una forma en que hace la vida más fácil aquí es que 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 los pasos aquí: http://rtyley.github.com/bfg-repo-cleaner/#usage - pero la corona de perforación es sólo esto: descargar el BFG's jar (requiere Java 6 o superior) y ejecuta este comando:

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

Cualquier archivo llamado file_name (que no está en su último commit) será será totalmente eliminado del historial de su repositorio.A continuación, puede utilizar git gc para limpiar los datos muerta:

$ git gc --prune=now --aggressive 

El BFG es generalmente mucho más fácil de usar que git-filter-branch - las opciones se adaptan alrededor de estos dos casos de uso comunes:

  • Extracción loco archivos grandes
  • Extracción contraseñas, credenciales & otros datos privados

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

+0

¿Esto también limpia los datos privados de los repos remotos después de presionar? –

+0

@ThomasLauria yup, los mismos refs limpios son empujados a los repos remotos al pulsar - las instrucciones en http://rtyley.github.io/bfg-repo-cleaner/#usage deben cubrirlo. Si tiene control sobre el repositorio remoto, también puede ejecutar "git gc --prune = now --aggressive" en él después de presionar para asegurarse de que los objetos muertos también se eliminen inmediatamente de allí. –

Cuestiones relacionadas