tag - Eliminar archivo.pack grande creado por git
que es un repositorio git (5)
Como loganfsmyth ya lo indicó en su answer , debe borrar el historial de git porque los archivos continúan existiendo allí incluso después de eliminarlos del repositorio. Los documentos oficiales de GitHub recomiendan BFG, que me parece más fácil de usar que el filter-branch
:
Eliminar archivos del historial
Download BFG desde su sitio web. Asegúrese de tener java instalado, luego cree un clon de duplicación y purgue el historial. Asegúrate de reemplazar YOUR_FILE_NAME
con el nombre del archivo que deseas eliminar:
git clone --mirror git://example.com/some-big-repo.git
java -jar bfg.jar --delete-files YOUR_FILE_NAME some-big-repo.git
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push
Eliminar una carpeta
Igual que el anterior pero usa --delete-folders
java -jar bfg.jar --delete-folders YOUR_FOLDER_NAME some-big-repo.git
Otras opciones
BFG también permite opciones aún más sofisticadas (ver Download ) como estas:
Eliminar todos los archivos más grandes que 100M del historial:
java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
¡Importante!
Al ejecutar BFG, tenga cuidado de que tanto YOUR_FILE_NAME
como YOUR_FOLDER_NAME
sean solo nombres de archivos / carpetas. ¡No son caminos , así que algo como foo/bar.jpg
no funcionará! En su lugar, todos los archivos / carpetas con el nombre especificado se eliminarán del historial de recompra, independientemente de la ruta o rama en la que existan.
Revisé una carga de archivos en una rama y me fusioné, luego tuve que eliminarlos y ahora me queda un gran archivo .pack del que no sé cómo deshacerme.
Eliminé todos los archivos usando git rm -rf xxxxxx
y también ejecuté la opción --cached
también.
Alguien puede decirme cómo puedo eliminar un archivo .pack grande que se encuentra actualmente en el siguiente directorio:
.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack
¿Necesito eliminar la rama que todavía tengo pero que ya no estoy usando? ¿O hay algo más que necesito para correr?
No estoy seguro de cuánta diferencia hace, pero muestra un candado contra el archivo.
Gracias
EDITAR
Aquí hay algunos extractos de mi bash_history que deberían dar una idea de cómo logré entrar en este estado (supongo que en este momento estoy trabajando en una rama de git llamada ''mi-rama'' y tengo una carpeta que contiene más carpetas / archivos):
git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/ (not sure why I ran this as well but I did)
Pensé que también ejecuté lo siguiente, pero no aparece en la bash_history con los demás:
git rm -rf --cached unwanted_folder/
También pensé que ejecuté algunos comandos de git (como git gc
) para intentar ordenar el archivo del paquete, pero tampoco aparecen en el archivo .bash_history.
El problema es que, aunque eliminó los archivos, todavía están presentes en las revisiones anteriores. Ese es el punto central de git, es que incluso si borras algo, aún puedes recuperarlo accediendo al historial.
Lo que está buscando hacer se llama reescritura del historial e involucró el comando git filter-branch
.
GitHub tiene una buena explicación del problema en su sitio. https://help.github.com/articles/remove-sensitive-data
Para responder a su pregunta de manera más directa, lo que básicamente necesita ejecutar es este comando con unwanted_folename_or_folder
reemplazado en consecuencia:
git filter-branch --index-filter ''git rm -r --cached --ignore-unmatch unwanted_folename_or_folder'' --prune-empty
Esto eliminará todas las referencias a los archivos del historial activo del repositorio.
A continuación, para realizar un ciclo de GC para forzar que todas las referencias al archivo caduquen y se eliminen del archivo de paquetes. Nada necesita ser reemplazado en estos comandos.
git for-each-ref --format=''delete %(refname)'' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --prune=now
Llego un poco tarde para el show, pero en caso de que la respuesta anterior no resolviera la consulta, encontré otra manera. Simplemente elimine el archivo grande específico de .pack. Tuve este problema donde registré un archivo grande de 2GB accidentalmente. Seguí los pasos explicados en este enlace: http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/
Una opción:
ejecute git gc
manualmente para condensar una cantidad de archivos de paquetes en uno o varios archivos de paquetes. Esta operación es persistente (es decir, el archivo de paquete grande conservará su comportamiento de compresión), por lo que puede ser beneficioso comprimir un repositorio periódicamente con git gc --aggressive
Otra opción es guardar el código y .git en algún lugar y luego eliminar el .git y comenzar a usar este código existente, creando un nuevo repositorio de git init
( git init
).
Escenario A : si sus archivos grandes solo se agregaron a una rama, no necesita ejecutar git filter-branch
. Solo necesitas eliminar la rama y ejecutar la recolección de basura:
git branch -D mybranch
git reflog expire --expire-unreachable=all --all
git gc --prune=all
Escenario B : Sin embargo, parece que, según su historial de bash, fusionó los cambios en el maestro. Si no has compartido los cambios con nadie (no hay git push
todavía). Lo más fácil sería restablecer el maestro antes de la fusión con la rama que tenía los archivos grandes. Esto eliminará todas las confirmaciones de su rama y todas las confirmaciones realizadas para dominar después de la fusión. Por lo tanto, es posible que pierda los cambios, además de los archivos grandes, que tal vez haya deseado:
git checkout master
git log # Find the commit hash just before the merge
git reset --hard <commit hash>
A continuación, ejecute los pasos del escenario A.
Escenario C : Si hubo otros cambios de la rama o cambios en el maestro después de la combinación que desea mantener, sería mejor volver a generar el maestro e incluir selectivamente las confirmaciones que desee:
git checkout master
git log # Find the commit hash just before the merge
git rebase -i <commit hash>
En su editor, elimine las líneas que correspondan a las confirmaciones que agregaron los archivos grandes, pero deje todo lo demás como está. Guardar y Salir. Su rama maestra solo debe contener lo que desea, y no archivos grandes. Tenga en cuenta que git rebase
sin -p
eliminará las confirmaciones de fusión, por lo que se le dejará un historial lineal para el maestro después de <commit hash>
. Probablemente esto esté bien para usted, pero si no, puede intentar con -p
, pero git help rebase
dice que combining -p with the -i option explicitly is generally not a good idea unless you know what you are doing
.
A continuación, ejecute los comandos del escenario A.