¿Por qué los repositorios Git / Mercurial usan menos espacio?

15

He leído en varias discusiones aquí y en SO que los repositorios de DVCS usan aproximadamente el mismo espacio o menos que sus contrapartes centralizadas. Puede que me lo haya perdido, pero no he encontrado una buena explicación de por qué. ¿Nadie sabe?

Alex Florescu
fuente
1
No lo he hecho, gracias! Entonces, entiendo por aquellos que hay dos respuestas: compresión usando zlib y guardar objetos como archivos de paquete cuando sea posible. ¡Los ejemplos de Mozilla también son geniales!
Alex Florescu
1
@Alex No, eso pierde la razón principal. SVN guarda instantáneas completas, Git y Mercurial solo guardan la revisión HEAD y las diferencias. El uso de la compresión convencional puede brindarle las mejores tasas de compresión de 60 a 80%. Usar diffs podría darte hasta un 99%. Sin embargo, estos números se sacan de mi trasero: los números reales pueden diferir; Sin embargo, la tendencia será la misma.
Konrad Rudolph
@KonradRudolph, ¿no es eso de lo que se tratan los archivos de paquete?
Alex Florescu
@Alex no realmente. Hasta donde yo sé, el paquete de archivos también está empacando múltiples archivos en uno. Esto no está necesariamente relacionado.
Konrad Rudolph

Respuestas:

18

Desde mi propia experiencia, las siguientes afirmaciones son ciertas:

  • Git es muy eficiente en el almacenamiento de archivos de texto, y solo almacena estos archivos que fueron cambiados. entonces, al hacer una comparación de SVN y Git para comparar los tamaños de repositorio, pueden ser similares o incluso puede haber una pequeña ventaja para Git.
  • Esto es completamente incorrecto si compara el tamaño de los repositorios donde una cantidad significativa de archivos son archivos de Office (como MS Word, Excel, PowerPoint, ...). Aquí Git también almacena copias completas, lo que significa que 10 pequeños cambios en una pila de diapositivas de PowerPoint dan como resultado 10 copias completas, donde Subversion solo almacena un diferencial binario, que puede ser un factor de 100 más pequeño.

Si compara la ubicación de pago (que es un repositorio en sí mismo con Git), la historia es totalmente diferente:

  • Subversion almacena para cada archivo una copia completa, por lo que el tamaño de su ubicación de pago es normalmente 2 veces el tamaño de los archivos mismos.
  • Git almacena el historial completo del repositorio localmente, por lo que, dependiendo del tamaño del historial, esto puede ser más pequeño o mucho más grande que el de la copia de pago de Subversion.

Si compara la cantidad de bytes que tiene que bajar o cargar, es diferente nuevamente.

  • Subversion normalmente tiene que enviar o recibir menos bytes, ya que solo envía diferencias. Tiene que hacer eso en cada confirmación y actualización.
  • Git tiene que obtener todo el repositorio (inicialmente), y luego envía archivos completos (¿comprimidos?) Que no es tan diferente para los archivos de texto, pero puede ser diferente para los archivos binarios. Y sí, Git solo hace eso cuando empujas o sacas algo al repositorio remoto.

Entonces, al final, comparas manzanas con naranjas, y dependiendo de lo que quieras hacer con Subversion o Git, el resultado puede ser diferente.


@jk preguntó sobre copias completas o diferencias binarias, y no pude responder esa pregunta. Le pregunté a Matthew McCullough que dio un taller de Git últimamente en Jax 2012 (que visité). Se ha tomado el tiempo (muchas gracias a él) para explicar con detalle el funcionamiento interno de Git. Entonces, sí, hay una compresión trabajando allí (y haré un experimento con un archivo de Microsoft Office también y lo compararé con su esencia), pero no, la compresión se realiza en todo el archivo. Citando de su esencia:

Los objetos sueltos se escriben en formato comprimido, pero no delta en el momento de cada confirmación.

mliebelt
fuente
1
¿estás seguro de que git almacena copias completas de los archivos de Office? Creo que también almacena diferencias binarias. Por supuesto, el verdadero problema con este tipo de archivos es que a menudo ya están comprimidos, por lo que un pequeño cambio puede hacer que todo el archivo cambie
jk.
2
Le pregunté a alguien (por correo electrónico) que sabe mucho más que yo e incluirá su respuesta en mi respuesta en ese momento.
mliebelt
66
Git trata los archivos de texto y binarios exactamente de la misma manera en todos los aspectos con respecto al almacenamiento. Los objetos sueltos vs. empaquetados no están relacionados con el texto vs. binario. La razón por la que los archivos binarios a menudo resultan en diferencias mucho más grandes que los archivos de texto es porque muchos formatos binarios (incluidos todos los nuevos formatos de oficina) ya están comprimidos y, por lo tanto, incluso un pequeño cambio en el contenido a menudo causa un gran cambio en la burbuja binaria resultante. Esto es igualmente preocupante para git y subversion, pero la subversión solo tiene la penalización en el servidor, mientras que git en todas partes.
Jan Hudec
44
Los objetos sueltos vs. empaquetados no tienen nada que ver con el texto vs. binario. Es la amortización del difícil trabajo de encontrar las diferencias binarias. La velocidad es una característica importante de git, por lo que durante la operación regular, git solo comprime los nuevos datos y los coloca en el repositorio. Esto es objetos sueltos. Entonces, cuando lo solicita llamando git gco se acumulan demasiados objetos sueltos, encuentra buenos candidatos para comprimirlos delta (git puede diferir de otros que no sean versiones anteriores), almacena los deltas en un "paquete" y elimina los objetos sueltos.
Jan Hudec
3
Para aquellos que están interesados ​​en los números del mundo real: acabo de comparar dos copias de trabajo del mismo repositorio. La copia de trabajo SVN es de aproximadamente 2,9 GB, la copia de trabajo GIT es de aproximadamente 0,8 GB.
JensG