Actualizar un equipo de desarrollo con el historial de repo de Git reescrito, eliminando archivos grandes


Tengo un repositorio git con algunos binarios muy grandes. Ya no los necesito, y no me importa poder obtener los archivos de confirmaciones anteriores. Por lo tanto, para reducir el tamaño del repositorio, quiero eliminar los binarios del historial por completo.

Después de una búsqueda en la web, llegué a la conclusión de que mi mejor (solo?) option is to use git-filter-branch:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' HEAD

¿Esto parece un buen enfoque hasta ahora?

Asumiendo que la respuesta es sí, tengo otro problema con el que lidiar. El git el manual tiene esta advertencia :

¡ATENCIÓN! El historial reescrito tendrá diferentes nombres de objeto para todos los objetos y no convergerá con la rama original. Usted no será capaz de empujar y distribuir fácilmente la rama reescrita en la parte superior de la rama original. Por favor, no use este comando si no conoce todas las implicaciones, y evite usarlo de todos modos, si una simple confirmación única sería suficiente para solucionar su problema. (Consulte la sección "RECUPERACIÓN DE REBASE ASCENDENTE" en git-rebase(1) para más información sobre reescribir el historial publicado.)

Tenemos un repositorio remoto en nuestro servidor. Cada desarrollador empuja hacia y tira de ella. Basado en la advertencia anterior (y mi comprensión de cómo funciona git-filter-branch), no creo que pueda ejecutar git-filter-branch en mi copia local y luego empujar los cambios.

Por lo tanto, estoy planeando ir a través de los siguientes pasos:

  1. Dile a todos mis desarrolladores que se comprometan, empujen y dejen de trabajar para un trozo.
  2. Inicie sesión en el servidor y ejecute el filtro en el repositorio central.
  3. Haga que todos borren sus copias antiguas y clonen de nuevo desde el servidor.

¿Esto suena bien? Es esta la mejor solución?

Author: Roberto Tyley, 2010-12-14

4 answers

Sí, su solución funcionará. También tiene otra opción: en lugar de hacer esto en el repositorio central, ejecute el filtro en su clon y luego empuje hacia atrás con git push --force --all. Esto obligará al servidor a aceptar las nuevas ramas de su repositorio. Esto reemplaza solo el paso 2; los otros pasos serán los mismos.

Si sus desarrolladores son bastante expertos en Git, entonces es posible que no tengan que eliminar sus copias antiguas; por ejemplo, podrían obtener los nuevos controles remotos y reorganizar sus ramas de temas como adecuado.

 18
Author: cdhowie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-14 20:55:49

Su plan es bueno (aunque sería mejor realizar el filtrado en un clon desnudo de su repositorio, en lugar del servidor central), pero en preferencia a git-filter-branch debería usar mi BFG Repo-Cleaner, una alternativa más rápida y simple a git-filter-branch diseñada específicamente para eliminar archivos grandes de los repositorios Git.

Descargue el Java jar (requiere Java 6 o superior) y ejecute este comando:

$ java -jar bfg.jar  --strip-blobs-bigger-than 1MB  my-repo.git

Cualquier blob de más de 1 MB de tamaño (que no está en su latest commit) será totalmente eliminado del historial de su repositorio. Luego puede usar git gc para limpiar los datos muertos:

$ git gc --prune=now --aggressive

El BFG es típicamente 10-50x más rápido que correr git-filter-branch y las opciones se adaptan alrededor de estos dos casos de uso comunes:

  • Eliminar Archivos grandes locos
  • Eliminar Contraseñas, Credenciales y otros Datos privados
 9
Author: Roberto Tyley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-19 13:02:29

Si no haces que tus desarrolladores vuelvan a clonar, es probable que se las arreglen para arrastrar los archivos grandes de nuevo. Por ejemplo, si se empalman cuidadosamente en el nuevo historial que creará y luego sucede con git merge desde una rama de proyecto local que no se rebasó, los padres de la confirmación de fusión incluirán la rama de proyecto que finalmente apunta a todo el historial que borró con git filter-branch.

 5
Author: Ben Jackson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-14 21:01:21

Su solución no está completa. Debe incluir --tag-name-filter cat como argumento para filtrar la rama de modo que las etiquetas que contienen los archivos grandes también se cambien. También deberías modificar todas las referencias en lugar de solo HEAD ya que el commit podría estar en varias ramas.

Aquí hay un código mejor:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' --tag-name-filter cat -- --all

Github tiene una buena guía: https://help.github.com/articles/remove-sensitive-data

 3
Author: Jason Axelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-16 21:43:59