Limpiar el historial de Git parte 2

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.:

GitHub: espacio en disco antes de la limpieza
GitHub: espacio en disco después de la limpieza

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:

GitLab: espacio en disco antes de la limpieza
GitLab: espacio en disco después de la limpieza

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 GratisGitLab Gratis
Límite máximo de tamaño de archivo100 MB
Límite máximo de tamaño de repositorio5000 MB
Límite máximo de recuento de repositorios
Límite máximo de tamaño total5000 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).

Atrás