Limpiar grandes blobs de file desactualizados de git

Mi situación es que muchos JPG voluminosos han ingresado en nuestro repository, agregando cientos de MB, mucho más que el código src en sí mismo.

Desde entonces, he optimizado estos JPG para consumir less de 1/20 de su tamaño de file, de lo contrario no hay cambio perceptible. Comprometido y empujado hacia atrás.

Sin embargo, las copys locales todavía tienen este espacio de disco utilizado en los files .git (que contiene internamente todas las versiones anteriores de todos los files). Cualquiera que tire nuevo también obtiene este espacio desperdiciado.

Nuestro maestro de origen está en Bitbucket.

He pasado un time considerable tratando de descubrir de buenas guías como

http://otomaton.wordpress.com/2012/12/17/saving-disk-space-by-garbage-collecting-in-git-repositories/ using

git gc 

o http://linux.yyz.us/git-howto.html

y ¿Cómo eliminar los files locales (sin seguimiento) del tree de trabajo actual de Git? sugerencia

 git clean -n 

¿Cuál podría ser una forma de simplemente purgar solo estos enormes files JPG de solo un compromiso particular de los files, e incluso del repository en línea de Bitbucket para que nadie tenga que volver a extraerlos? Por supuesto que queremos

  • Las versiones actuales de todos los files que se saveán
  • En la medida de lo posible, los historiales de revisión anteriores y posteriores conservaron, al less, el conocimiento meta de que hubo una confirmación (debido a que otros files no-jpg también se vieron afectados)
  • Hay más de 200 files JPG. ¿Puede esta operación hacerse de una sola vez? ¿Usar comodines como * .jpg en algún parámetro, o un bucle for?

No ha habido una versión anterior en el repository de las grandes versiones JPG de los files que no queremos.

Entre las cosas que probé:

  • Antes de nada, ¿cuánto espacio en disco usa .git?
 du 72195 ./.git 
  • Encuentra burbujas de peso pesado:
 git verify-pack -v .git/objects/pack/pack-*.idx |sort -k 3 -n |tail -39 ... 03bcb7d79c1e0a4328420bf00647319465d5d3df blob 2446210 2430913 46915147 52ea2d848645463e01d3dd143dd8d7fd24019335 blob 2467254 2443333 27573576 12d63348c0e87f9602d395e694df6a94601c12f7 blob 2506409 2485495 49346060 645fe7bfaf6ecd0140d144b4c40c19e78f103bd6 blob 2581349 2554398 10567725 72672204aa3c7aec431cba02b32ac012e52e601d blob 3084793 3041294 13122123 
  • ¿Qué contenía esa última gran mancha?
  git rev-list --objects --all |grep 72672204 72672204aa3c7aec431cba02b32ac012e52e601d images/2.jpg 
  • ¿Qué confirmaciones afectaron a este particular file images / 2.jpg (uno de los muchos cuya copy innecesaria espero matar)?
 git log --pretty=oneline --branches -- images/2.jpg 98dc75de48a63c2ab9661eb62895ac39ef331aaa MAPSDH-10 #time 30m #comment Grab live copy of Simon's source and push it onto Bitbucket repo; master@gordito,2014-04-10_13-55-02 3e7f36f0b1a913feaf43547bca4ad3a5a08957a6 MAPSDH-10 #time 30m #comment Grab live copy of Simon's source and push it onto Bitbucket repo; master@gordito,2014-04-10_13-31-49 
  • Está bien, entonces, intente eliminar solo la copy de imágenes / 2.jpg antes de confirmar # 3e7f36f0, inclusive:
  git filter-branch --index-filter 'git rm --cached --ignore-unmatch images/2.jpg' -- 3e7f36f0^.. Cannot rewrite branches: You have unstaged changes. 
  • Dado que se rechaza, simplemente quítalo del caching:
  git rm --cached --ignore-unmatch images/2.jpg rm 'images/2.jpg' 
  • Sin embargo, espero que esta versión ACTUAL de images/2.jpg aún esté en el repository.

  • Cuente el uso del espacio de files de los files locales de git:

 git count-objects -v count: 0 size: 0 in-pack: 284 packs: 1 size-pack: 72101 prune-packable: 0 garbage: 0 size-garbage: 0 
  • size-pack sigue siendo 72101 (72MB, como en origen du ). No parecía liberar 3084793 (3MB) como se esperaba, de todos modos.

Bueno, tienes estas imágenes en la historia y deberías reescribir el historial y eliminarlas permanentemente.

He escrito un script que elimina un file para siempre de git (historial incluido), aquí está:

 #!/bin/bash git filter-branch -f --prune-empty -d /dev/shm/scratch \ --index-filter "git rm --cached -f --ignore-unmatch $1" \ --tag-name-filter cat -- --all rm -rf .git/refs/original/ git reflog expire --expire=now --all git gc --prune=now git gc --aggressive --prune=now 

Puede eliminar todos sus files con él y, luego, confirmar nuevos files.

Más información: http://git-scm.com/book/ch6-4.html

PD y si quieres usar comodines: utiliza algo de magia bash como for i in *.jpg; do git-rm-forever $i; done for i in *.jpg; do git-rm-forever $i; done