Datos confidenciales o demasiado consumo de memoria: hay buenas razones para querer cambiar el historial de Git. En esta publicación de blog , expliqué cómo purgar archivos del historial de Git usando BFG . Un punto débil de BFG es la falta de soporte para rutas directas , por lo que no puede eliminar archivos o carpetas específicamente en subcarpetas del historial. Con eso, es hora de buscar soluciones alternativas.
Además de la rama de filtro de git oficialmente no recomendada , git-filter-repo es una de las herramientas para limpiar el historial. Tras una breve instalación , primero analizamos el repositorio y encontramos, por ejemplo, las carpetas más grandes de la historia:
git filter-repo --analyze
Bien estar en la carpeta .git/filter-repo/analysis
generó todo tipo de archivos TXT:
directories-all-sizes.txt
extensions-all-sizes.txt
path-all-sizes.txt
- ...
Vale la pena el archivo directories-all-sizes.txt
mira más de cerca:
=== All directories by reverse size ===
Format: unpacked size, packed size, date deleted, directory name
4624417043 3796607988 <present> <toplevel>
4475940396 3778033787 <present> wp-content
4060236681 3694449320 <present> wp-content/uploads
305163809 70576241 <present> wp-content/plugins
123818107 15442735 <present> wp-includes
...
A menudo sucede que ha ignorado y eliminado durante mucho tiempo los datos HEAD en el historial (por ejemplo, la carpeta de medios de WordPress wp-content/uploads/
o uno empujado accidentalmente node_modules
- o vendor
-Aglutinante).
Generalmente recomienda git-filter-repo
después de la limpieza, empujando a un depósito nuevo y vacío. Hay numerosas razones enumeradas aquí, por eso esto tiene sentido y evita muchos problemas. Sin embargo, puede suceder que desee enviar al mismo repositorio y eso también es posible con algunos consejos.
Es importante destacar que las principales plataformas de alojamiento de código GitHub y GitLab recomendar diferentes enfoques, algunos de los cuales difieren entre sí. Por ejemplo, en GitHub eliminamos wp-content/uploads/
usando los siguientes pasos git-filter-repo
de la historia:
mkdir tmp-repo
cd tmp-repo
git clone git@github.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
mv /tmp/config-backup .git/config
git push origin --force --all
# option 2: new repo
git remote add origin git@github.com:foo/bar-new.git
git push origin --force --all
cd ..
rm -rf tmp-repo
Ahora también podemos comprobar el tamaño de forma remota (cambiar el tamaño a través de la API y en la interfaz de usuario puede tardar hasta 24 horas). Para hacer esto, abra la configuración del repositorio (si el repositorio pertenece a una organización, primero debe agregar su propia cuenta a la organización). Ahora vemos el tamaño.:
El procedimiento es ligeramente diferente en GitLab:
mkdir tmp-repo
cd tmp-repo
# option 1: same repo
# Settings > General > Advanced > Export project > download tar.gz file into tmp-repo
tar xzf 20*.tar.gz
git clone --bare --mirror project.bundle
cd project.git
git filter-repo --invert-paths --path wp-content/uploads/
cp ./filter-repo/commit-map /tmp/commit-map-1
# copying the commit-map has to be done after every single command from git filter-repo
# you need the commit-map files later
git remote remove origin
git remote add origin git@gitlab.com:foo/bar.git
# Settings > Repository > Protected branches/Protected branches >
# enable "Allowed to force push to main/master"
git push origin --force 'refs/heads/*'
git push origin --force 'refs/tags/*'
git push origin --force 'refs/replace/*'
# Settings > Repository > Protected branches/Protected branches >
# disable "Allowed to force push to main/master"
date
# wait 30 minutes (😱)
date
# Settings > Repository > upload /tmp/commit-map-X
# option 2: new repo
git clone git@gitlab.com:foo/bar.git .
git filter-repo --invert-paths --path wp-content/uploads/
git remote add origin git@gitlab.com:foo/bar-new.git
# Settings > Repository > Protected branches/Protected branches >
# enable "Allowed to force push to main/master"
git push origin --force --all
# Settings > Repository > Protected branches/Protected branches >
# disable "Allowed to force push to main/master"
cd ..
rm -rf tmp-repo
Después de otra espera de ~ 5 minutos, podemos pasar por debajo Settings > Usage Quotas
ver espacio de almacenamiento:
Después de la eliminación, es importante que todos los desarrolladores involucrados participen en los pasos finales: si un usuario ahora realiza una inserción normal con su propia copia local, los archivos grandes migrarían de regreso al repositorio central. Por lo tanto, se recomiendan las siguientes 3 opciones:
- "clon fresco del hombre pobre"
rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
- Para archivos modificados (dependiendo de la aplicación):
git checkout -- .
o.git add -A . && git commit -m "Push obscure file changes." && git push
- "empezar desde el principio"
rm -rf repo && git clone xxx .
- "tirón feo con rebase"
git pull -r
- Aquí todavía tiene el historial sin limpiar, pero en la mayoría de los casos ya no sobrescribe accidentalmente el repositorio remoto con la variante local grande
En el transcurso de las cuotas actuales (especialmente debido a las nuevas restricciones de GitLab ), siempre vale la pena verificar el tamaño del historial de sus repositorios y limpiarlos si es necesario.:
GitHub Gratis | GitLab Gratis | |
Límite máximo de tamaño de archivo | 100 MB | ∞ |
Límite máximo de tamaño de repositorio | 5000 MB | ∞ |
Límite máximo de recuento de repositorios | ∞ | ∞ |
Límite máximo de tamaño total | ∞ | 5000 MB |
Por último, también vale la pena echarle un vistazo a una variante gratuita autohospedada como Gitea tirar. Con poco esfuerzo puedes en un servidor muy delgado una instancia de Git autohospedada (GUI por SSL asegurado, Respaldo incluido, control sobre potente API) anfitrión, que también son excelentes configurar y también es superior en términos de protección de datos. Aquí, por cierto, también puedes usar git-filter-repo
Simplemente optimice los repositorios:
mkdir tmp-repo
cd tmp-repo
git clone git@git.tld.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
mv /tmp/config-backup .git/config
git push origin --mirror
# login on the remote command line and run in the repo-folder
sudo -u git git reflog expire --expire=now --all
sudo -u git git gc --aggressive --prune=now
# if you face memory limit issues, modify the git configuration
sudo -u git git config --global pack.windowMemory "100m"
sudo -u git git config --global pack.packSizeLimit "100m"
sudo -u git git config --global pack.threads "1"
# if in web ui the size does not change, make a slight
# modification to a file and push again normally
# option 2: new repo
git remote add origin git@git.tld.com:foo/bar-new.git
git push origin --force --all
cd ..
rm -rf tmp-repo
Aquí específicamente está el comando sudo -u git git gc --aggressive --prune=now
importante (el cron corriendo git gc
de lo contrario tiene uno demasiado largo tiempo de poda de 2 semanas).