Revisé una carga de archivos en una rama y los fusioné y luego tuve que eliminarlos y ahora me queda un archivo .pack grande del que no sé cómo deshacerme.
Eliminé todos los archivos usando git rm -rf xxxxxx
y también ejecuté la --cached
opció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
¿Solo necesito eliminar la rama que todavía tengo pero que ya no uso? ¿O hay algo más que deba ejecutar?
No estoy seguro de la diferencia, 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é llegar a este estado (supongamos que en este punto estoy trabajando en una rama de git llamada 'my-branch' 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 bash_history con los demás:
git rm -rf --cached unwanted_folder/
También pensé que había ejecutado algunos comandos git (como git gc
) para intentar ordenar el archivo del paquete, pero tampoco aparecen en el archivo .bash_history.
fuente
Respuestas:
El problema es que, aunque eliminó los archivos, todavía están presentes en revisiones anteriores. Ese es el objetivo de git, es que incluso si eliminas algo, aún puedes recuperarlo accediendo al historial.
Lo que está buscando hacer se llama reescritura del historial e involucró el
git filter-branch
comando.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
unwanted_filename_or_folder
reemplazado en consecuencia:Esto eliminará todas las referencias a los archivos del historial activo del repositorio.
Siguiente paso, realizar un ciclo de GC para forzar que todas las referencias al archivo caduquen y purguen del archivo de paquete. No es necesario reemplazar nada en estos comandos.
fuente
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
2)git reflog expire --expire=now --all
3)git gc --prune=now
bfg
mucho más fácil. También se recomienda en los documentos oficiales de github: help.github.com/articles/…Escenario A : si sus archivos grandes solo se agregaron a una rama, no necesita ejecutar
git filter-branch
. Solo necesita eliminar la rama y ejecutar la recolección de basura:Escenario B : Sin embargo, según su historial de bash, parece que fusionó los cambios en master. Si no ha compartido los cambios con nadie (
git push
todavía no ). 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 en master después de la fusión. Por lo tanto, es posible que pierda los cambios, además de los archivos grandes, que realmente deseaba:Luego, ejecute los pasos del escenario A.
Escenario C : si hubo otros cambios de la rama o cambios en el maestro después de la fusión que desea mantener, sería mejor volver a basar el maestro e incluir selectivamente las confirmaciones que desee:
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 desee y no archivos grandes. Tenga en cuenta que
git rebase
sin-p
eliminará las confirmaciones de fusión, por lo que se quedará con un historial lineal para el maestro después<commit hash>
. Esto probablemente esté bien para usted, pero si no, podría intentarlo-p
, perogit help rebase
dicecombining -p with the -i option explicitly is generally not a good idea unless you know what you are doing
.Luego, ejecute los comandos del escenario A.
fuente
Como loganfsmyth ya indicó en su respuesta , debe purgar 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 encuentro más fácil de usar que
filter-branch
:Eliminar archivos del historial
Descarga BFG de su sitio web. Asegúrese de tener Java instalado, luego cree un duplicado y purgue el historial. Asegúrese de reemplazarlo
YOUR_FILE_NAME
con el nombre del archivo que desea eliminar:Eliminar una carpeta
Igual que el anterior pero use
--delete-folders
Otras opciones
BFG también permite opciones aún más sofisticadas (ver documentos ) como estas:
Elimine todos los archivos de más de 100 M del historial:
¡Importante!
Cuando ejecute BFG, tenga cuidado de que ambos
YOUR_FILE_NAME
yYOUR_FOLDER_NAME
sean solo nombres de archivos / carpetas. No son caminos , ¡así que algo comofoo/bar.jpg
no funcionará! En su lugar, todos los archivos / carpetas con el nombre especificado se eliminarán del historial del repositorio, sin importar en qué ruta o rama existieran.fuente
bfg
herramienta a un repositorio de git local, ¿cómo debería verse el comando?Una opción:
ejecutar
git gc
manualmente para condensar una cantidad de archivos de paquete en uno o varios archivos de paquete. 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 congit gc --aggressive
Otra opción es guardar el código y .git en algún lugar y luego eliminar el .git y comenzar de nuevo a usar este código existente, creando un nuevo repositorio de git (
git init
).fuente
git gc
y bajé a solo un par de archivos de paquete, pero el grande sigue siendo uno de ellos y me gustaría deshacerme de él para poder hacer una copia de seguridad de la carpeta externamente más fácilmente (zip antes era 1 -2Mb, ahora 55Mb). A menos que alguien pueda sugerir algo más, creo que tendré que crear un git nuevo. Supongo que esto significa que perderé el acceso a las ramas que tengo actualmente, etc.Ejecute el siguiente comando, reemplazándolo
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
por la ruta del archivo que desea eliminar, no solo por su nombre de archivo. Estos argumentos:Esto eliminará a la fuerza todas las referencias a los archivos del historial activo del repositorio.
Siguiente paso, realizar un ciclo de GC para forzar que todas las referencias al archivo caduquen y purguen del archivo del paquete. No es necesario reemplazar nada en estos comandos.
fuente
Llego un poco tarde al programa, 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 en el que verifiqué accidentalmente un archivo grande de 2 GB. Seguí los pasos explicados en este enlace: http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/
fuente
esta es una solución más práctica que de codificación. zip el archivo. Abra el zip en formato de vista de archivo (diferente de descomprimir). Elimina el archivo .pack. Descomprima y reemplace la carpeta. ¡Funciona de maravilla!
fuente