remove - Eliminar archivo del repositorio git(historial)
hide commits github (8)
(resuelto, ver la parte inferior del cuerpo de la pregunta)
Buscando esto por un largo tiempo, lo que tengo hasta ahora es:
- http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/ y
- http://progit.org/book/ch9-7.html
Prácticamente el mismo método, pero ambos dejan objetos en los archivos del paquete ... Atascado.
Lo que probé:
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é el truco de git clone
, eliminó algunos de los archivos (~ 3000 de ellos) pero los archivos más grandes aún 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 rápida de deshacerse de los archivos:
- compruebe .git / packed-refs: mi problema era que tenía una línea de
refs/remotes/origin/master
para un repositorio remoto, elimínelo, de lo contrario, git no eliminará esos archivos - (opcional)
git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
- para buscar los archivos más grandes - (opcional)
git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98
git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98
- para ver cuáles son esos archivos -
git filter-branch --index-filter ''git rm --cached --ignore-unmatch file_names''
- para eliminar un archivo de todas las revisiones -
rm -rf .git/refs/original/
- para eliminar la copia de seguridad de git -
git reflog expire --all --expire=''0 days''
- para caducar todos los objetos sueltos -
git fsck --full --unreachable
- para comprobar si hay objetos sueltos -
git repack -A -d
- reempaquetado -
git prune
- para finalmente eliminar esos objetos
Estaba tratando de deshacerme de un archivo grande en la historia, y las respuestas anteriores funcionaron, hasta cierto punto. El punto es que no funcionan si tienes etiquetas. Si la confirmación que contiene el archivo grande es accesible desde una etiqueta, entonces necesitarás ajustar el comando filter-branches de la siguiente manera:
git filter-branch --tag-name-filter cat /
--index-filter ''git rm --cached --ignore-unmatch huge_file_name'' -- /
--all --tags
Esto debe estar cubierto por el comando git obliterate
en Git Extras ( https://github.com/visionmedia/git-extras ).
git obliterate <filename>
Me pareció bastante útil para eliminar una carpeta completa, ya que lo anterior no me ayudó realmente: https://help.github.com/articles/remove-sensitive-data .
Solía:
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
No puedo asegurarlo sin tener acceso a los datos de su repositorio, pero creo que probablemente haya uno o más refs empaquetados que sigan haciendo referencia a las confirmaciones anteriores desde 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 el reflog y haya eliminado los refs originales (desempaquetados).
Esto es lo que haría (después de que se hayan hecho git filter-branch
y git gc
):
1) Asegúrate de que los árbitros originales hayan desaparecido:
rm -rf .git/refs/original
2) Vencer todas las entradas de reflog:
git reflog expire --all --expire=''0 days''
3) Compruebe si hay refs viejos
Esto podría ser complicado, dependiendo de la cantidad de refs empaquetados que tenga. 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 de .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 de limpiar el archivo packed-refs
, vea si git fsck
nota los objetos inalcanzables:
git fsck --full --unreachable
Si eso funcionó, y ahora git fsck
informa que tu blob grande no está disponible, puedes pasar al siguiente paso.
4) Vuelve a empacar tu (s) archivo (s) empaquetado (s)
git repack -A -d
Esto asegurará que los objetos inalcanzables se desempaqueten y permanezcan desempacados.
5) Poda objetos sueltos (inalcanzables)
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é. En ausencia de una mejor manera, la edición manual del archivo packed-refs
podría ser la única manera de hacerlo.
Recomiendo usar BFG Repo-Cleaner , una alternativa más simple y más rápida a git-filter-branch
específicamente diseñada para reescribir archivos del historial 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.
Debes seguir estos pasos cuidadosamente aquí: http://rtyley.github.com/bfg-repo-cleaner/#usage , pero el núcleo es solo esto: descarga el contenedor de BFG (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 última confirmación) será eliminado por completo del historial de su repositorio. A continuación, puede usar git gc
para limpiar los datos muertos:
$ git gc --prune=now --aggressive
El BFG es generalmente mucho más fácil de usar que git-filter-branch
: las opciones se adaptan a estos dos casos de uso comunes:
- Eliminando Crazy Big Files
- Eliminar contraseñas, credenciales y otros datos privados
Descripción completa: soy el autor de BFG Repo-Cleaner.
Tienes varias razones para un tamaño de git repo aún grande después de git gc
, ya que no elimina todos los objetos sueltos .
Detallo esas razones en " reducir el tamaño del repositorio git "
Pero un truco para probar en su caso sería clonar su repositorio de Git "limpio" y ver si el clon tiene el tamaño apropiado.
('''' limpiado '''' repo '''' es aquel en el que aplicaste la filter-branch
, y luego gc
y prune
)
Tuve el mismo problema y encontré un excelente https://help.github.com/articles/remove-sensitive-data en github que explica paso a paso cómo deshacerse de los archivos que accidentalmente cometió.
Aquí hay un pequeño resumen del procedimiento sugerido por 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
Ver: ¿Cómo elimino los archivos confidenciales del historial de git?
Lo anterior fallará si el archivo no existe en un rev. En ese caso, el modificador ''--ignore-unmatch'' lo arreglará:
git filter-branch -f --index-filter ''git rm --cached --ignore-unmatch <filename>'' HEAD
Luego, para sacar todos los objetos sueltos de la repostería:
git gc --prune=''0 days ago''