Git: 'Eliminación permanente' (de una twig) sin rebase o filtrar-twig

Motivación: Tengo un escenario algo específico, para el cual Git parece ser una buena opción pero que, sin embargo, es lo suficientemente inusual como para requerir algún trabajo en particular. Básicamente se trata de un set de files de text (sin código) que se actualizan automáticamente como mínimo cada 10 segundos. Los cambios pueden ser considerables y, al less con el time, el tamaño del repository se vuelve relativamente grande. El repository local está en un sistema integrado sin conectividad de networking constante, por lo que el flujo de trabajo natural es recostackr las confirmaciones localmente, presionarlas cuando hay una oportunidad y luego eliminar lo que se acaba de presionar para liberar espacio, si es necesario. El historial puede ser útil para mantener el dispositivo de forma temporal, pero lo más importante es que sea posible eliminarlo del dispositivo. (Se mantiene para siempre en el control remoto). Dependiendo de unos pocos factores específicos de la aplicación, el escenario puede extenderse un poco, y podemos aprovechar la function adicional en git, pero la estructura básica que delineé debe permanecer igual.

Más específicamente, hay una copy local del repository y un control remoto, y el local solo empuja (una twig particular) al control remoto (nunca tira). El gráfico de confirmación es simple, una "línea recta" de confirmaciones una después de la otra sin líneas de fusión o paralelas. Cada vez que hay una oportunidad para presionar (como se discutió anteriormente), se creará una nueva twig para futuras confirmaciones. Así que de vez en cuando tenemos una nueva sucursal, que básicamente solo funciona para organizar la línea de time de commits. Aparte de esto, nunca cambiamos de twigs.

Por lo tanto, las antiguas twigs se pueden eliminar, y como se discutió, este es nuestro objective, especialmente cuando el espacio se convierte en una preocupación. Para 'eliminar permanentemente' las confirmaciones y la twig, probamos lo siguiente:

 date = $ (date + "% m-% d-% y -% H-% M-% S")

 git $ opt checkout -b "$ date"

 git $ opt branch -d $ to_push

 # la primera confirmación será la única confirmación 'inicial' en el maestro
 # branch, que es permanente y nunca 'eliminada'
 git $ opt replace - injerto \
     $ (git $ opt log -n 1 --pretty = "% H") \
     $ (git $ opt rev-list --max-parents = 0 HEAD)

 git $ opt reflog expire --expire = now --all
 git $ opt gc --aggressive --prune = now
 git $ opt repack -a -d -l

La variable opt solo especifica el tree de trabajo y el directory git. El injerto que realizamos (con el siguiente gc, etc.) elimina con éxito las confirmaciones de un git log ingenuo y, de hecho, libera espacio, pero no parece liberar el espacio ocupado 'por las diferencias que aún se mantienen en las confirmaciones '; por ejemplo, un file grande que se crea, se compromete y luego se elimina, seguirá ocupando espacio después de que sus compromisos se eliminen de esta manera. No tendremos files particularmente grandes en la práctica, pero supongo que este comportamiento es más general ya que los 'datos de los cambios' (diffs?) Aún se guardan en el repository, o algo así, que es lo que se preocupan por eliminar

Logré acomodar la estructura restante con algunos trucos que se me sugirieron, como quitar las twigs del globo de 'recuperación' en la configuration y ejecutar la git fetch --prune origin ; y git update-ref -d refs/remotes/origin/05-07-16--15-48-59 por ejemplo, pero esto no liberó el espacio en cuestión. La siguiente información describe el estado del repository tal como está actualmente:

 $ git log --all --oneline --graph --decorate
 * de345b6 (HEAD -> 05-07-16--15-50-56, reemplazado) sam.  mai 7 15:44:16 EDT 2016
 |  * 50272b5 sam.  mai 7 15:44:16 EDT 2016
 | /  
 |  * 0b96272 sam  mai 7 15:29:48 EDT 2016
 | /  
 |  * b764118 sam.  mai 7 15:28:13 EDT 2016
 | /  
 |  * efa0536 sam.  mai 7 15:14:45 EDT 2016
 | /  
 |  * 40c8806 sam  mai 7 15:13:57 EDT 2016
 | /  
 |  * 6f7c2f9 sam.  mai 7 15:12:26 EDT 2016
 | /  
 |  * fa33771 sam.  mai 7 15:11:21 EDT 2016
 | /  
 |  * 8698acd sam.  mai 7 15:11:08 EDT 2016
 | /  
 * b2d9486 (origen / maestro, maestro) inicial
 $ git show-ref
 de345b670e24ac68bbbf4aa7efd22598ef3c7251 refs / heads / 05-07-16--15-50-56
 b2d9486d5d427d1ae4bb88828f334454a2fb6954 refs / heads / master
 b2d9486d5d427d1ae4bb88828f334454a2fb6954 refs / remotos / origen / maestro
 0b96272e47cab0b29e2706cae83b8154f8e412ea refs / replace / 0afdaca4e6d071fc026d209249a7b0532c11122a
 b7641184c898ff08917d363435d5f45e5e9664ed refs / replace / 498f8846c6a742f96997b599f5e25f5ad20b568c
 6f7c2f9b7700b39b4fd837c34ab7911a08d5438a refs / replace / 4df4f9cf8cc01500c800f3f04cbbd655a866c9ba
 8698acd667d406fab764389b87518d133de887a6 refs / replace / 9a91b7248da808a9fc6e1531c4206a6865273005
 40c880617db664cb73390d90e1401a049bc8c303 refs / replace / 9edc1e243f4f36034a800c566fdeeac511e077a3
 efa0536a40e68d92751193fa0c6dec502d77ce72 refs / replace / d6256dbe48a10461e17ca3cf7e7c40700937d249
 fa3377117750fd81c703519038268fec89b65dce refs / replace / db9923391013d8e5d2974f328037f6315af85783
 50272b55f66b8d7c55305a3502db8e9f88b2db03 refs / replace / de345b670e24ac68bbbf4aa7efd22598ef3c7251

Con respecto a los criterios mencionados en el tema, no queremos hacer una rebase o filter-branch porque los datos en el tree de trabajo son en vivo y se actualizan con frecuencia, como se discutió. Supongo que podríamos copyr el tree de trabajo en otro lugar y luego realizar la eliminación allí, pero eso agrava aún más la restricción de espacio. E incluso si lo copymos en otro lugar y borramos datos viejos con rebase o filter-branch, tendríamos que sincronizar cualquier cambio nuevo en el repository en vivo con el copydo y copyr el copydo nuevamente en el vivo, todo atómicamente con respecto a los processs que están leyendo activamente y / o modificando los contenidos del repository, lo cual parece una molestia innecesaria, pero estamos abiertos a ello.

Otra sugerencia que nos dieron fue utilizar el format-patch y am para 'serializar' las confirmaciones y rebuild la estructura en el repository remoto después de transferirlo en forma de parches de files de text. Entonces podríamos simplemente crear un nuevo repository en el local para deshacernos de los datos antiguos. Pero esto también parece innecesariamente complejo, y básicamente parece volver a hacer el trabajo para el cual git está diseñado. Estamos abiertos a esta posibilidad (o la posibilidad de cambiar a otro VCS para esto, o algo personalizado), pero parece que estamos tentadoramente cerca de hacer que esto funcione, y git parece ajustarse bastante bien a nuestro caso de uso.

Puedo proporcionar más detalles, y también puedo recrear el repository y probar diferentes pasos y / o mostrar el resultado del command en varios pasos del process. Gracias por tu time.

Editar

Después de la sugerencia de Vampire, y su request de información adicional:

 $ git rev-list --all |  xargs -l $ git describe --all - siempre            
 replace / de345b670e24ac68bbbf4aa7efd22598ef3c7251
 replace / 0afdaca4e6d071fc026d209249a7b0532c11122a
 replace / 498f8846c6a742f96997b599f5e25f5ad20b568c
 replace / d6256dbe48a10461e17ca3cf7e7c40700937d249
 reemplace / 9edc1e243f4f36034a800c566fdeeac511e077a3
 reemplace / 4df4f9cf8cc01500c800f3f04cbbd655a866c9ba
 replace / db9923391013d8e5d2974f328037f6315af85783
 reemplace / 9a91b7248da808a9fc6e1531c4206a6865273005
 cabezas / 05-07-16--15-50-56

Tu problema es que usas git replace .
git replace hace que git pretenda que un commit es en realidad otro commit o como en tu caso el padre de un commit es el padre de otro commit.
Pero los objects originales todavía están allí, simplemente se reemplazan lógicamente para la mayoría de los commands de git, pero no se reemplazan físicamente a less que lo haga con una rebase o filter-branch o similar.

Pero si no te entendí mal, lo que realmente buscas es simple lo siguiente:

 git reset --soft <initial commit> git commit -m "recording current state as the only commit after the initial commit" 

y luego el reempaquetado y cosas para limpiar la basura

Incluso puedes rellenar esos dos commands dentro de un git alias para convertirlos en una operación atómica en Git por lo que recuerdo.