tipos - que es un repositorio git
Contraer la historia de un repositorio git (4)
¿Es git-fast-export
lo que estás buscando?
NAME
git-fast-export - Git data exporter
SYNOPSIS
git-fast-export [options] | git-fast-import
DESCRIPTION
This program dumps the given revisions in a form suitable to be piped into git-fast-
import(1).
You can use it as a human readable bundle replacement (see git-bundle(1)), or as a kind
of an interactive git-filter-branch(1).
Tenemos un proyecto git que tiene una historia bastante grande.
Específicamente, al inicio del proyecto había bastantes archivos de recursos binarios en el proyecto, estos ya han sido eliminados ya que son efectivamente recursos externos.
Sin embargo, el tamaño de nuestro repositorio es> 200MB (el pago total es actualmente ~ 20MB) debido a que estos archivos fueron previamente comprometidos.
Lo que nos gustaría hacer es "colapsar" el historial para que el repositorio parezca haber sido creado a partir de una revisión posterior de lo que era. Por ejemplo
1-----2-----3-----4-----+---+---+
/ /
+-----+---+---+
- Repositorio creado
- Se agregó un gran conjunto de archivos binarios
- Gran conjunto de archivos binarios eliminados
- Nuevo ''inicio'' previsto del repositorio
Entonces efectivamente queremos perder la historia del proyecto antes de cierto punto. En este punto solo hay una rama, por lo que no hay ninguna complicación al tratar de tratar con múltiples puntos de inicio, etc. Sin embargo, no queremos perder todo el historial y comenzar un nuevo repositorio con la versión actual.
¿Es esto posible o estamos condenados a tener un depósito inflado para siempre?
Gracias a la publicación de JesperE busqué en git-filter-branch
, que en realidad puede ser lo que quieres. Parece que también podrías conservar tus confirmaciones anteriores, excepto que se modificarían desde que se eliminaron tus archivos grandes. De la página man de git-filter-branch :
Supongamos que desea eliminar un archivo (que contiene información confidencial o violación de derechos de autor) de todas las confirmaciones:
git filter-branch --tree-filter ''rm nombre de archivo'' HEAD
Asegúrate de leer esa página de manual ... obviamente querrías hacer esto en un clon de repuesto de tu repositorio para asegurarte de que funciona como se espera.
Puede eliminar la inflamación binaria y conservar el resto de su historial. Git te permite reordenar y ''aplastar'' las confirmaciones anteriores, de modo que puedes combinar solo las confirmaciones que agregan y eliminan tus grandes archivos binarios. Si las adiciones se hicieron todas en una confirmación y las eliminaciones en otra, esto será mucho más fácil que tratar con cada archivo.
$ git log --stat # list all commits and commit messages
Busca en esto las confirmaciones que agregan y eliminan tus archivos binarios y anota sus SHA1, digamos 2bcdef
y 3cdef3
.
Luego, para editar el historial del repositorio, use el comando rebase -i
con su opción interactiva, comenzando con el padre del compromiso donde agregó sus binarios. 2bcdef
su $ EDITOR y verá una lista de confirmaciones que comienzan con 2bcdef
:
$ git rebase -i 2bcdef^ # generate a pick list of all commits starting with 2bcdef
# Rebasing zzzzzz onto yyyyyyy
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
pick 2bcdef Add binary files and other edits
pick xxxxxx Another change
.
.
pick 3cdef3 Remove binary files; link to them as external resources
.
.
Inserta squash 3cdef3
como la segunda línea y elimina la línea que dice pick 3cdef3
de la lista. Ahora tiene una lista de acciones para la rebase
interactiva que combinará las confirmaciones que agregan y eliminan sus binarios en una confirmación cuya diferencia es cualquier otro cambio en esas confirmaciones. Luego volverá a aplicar todas las confirmaciones posteriores en orden, cuando le indique que complete:
$ git rebase --continue
Esto tomará un minuto o dos.
Ahora tiene un repositorio que ya no tiene los binarios que van o vienen. Pero seguirán ocupando espacio porque, de forma predeterminada, Git mantiene los cambios durante alrededor de 30 días antes de que puedan ser recogidos basura, por lo que puede cambiar de opinión. Si quieres eliminarlos ahora:
$ git reflog expire --expire=1.minute refs/heads/master
#all deletions up to 1 minute ago available to be garbage-collected
$ git fsck --unreachable # lists all the blobs(files) that will be garbage-collected
$ git prune
$ git gc
Ahora eliminaste la hinchazón pero mantuviste el resto de tu historial.
Puedes usar git filter-branch
con injertos para hacer que el commit número 4 sea el nuevo commit raíz de tu branch. Simplemente cree el archivo .git/info/grafts
con solo una línea que contenga el SHA1 del número de confirmación 4.
Si ahora haces un git log
gitk
o gitk
, verás que esos comandos mostrarán el número de compromiso 4 como la raíz de tu rama. Pero nada habrá cambiado realmente en su repositorio. Puede eliminar .git/info/grafts
y la salida de git log
o gitk
será como antes. Para convertir realmente el número de compromiso 4 en la nueva raíz, deberá ejecutar git filter-branch
, sin argumentos.