¿Cómo ahorra espacio Git y es rápido al mismo time?

Acabo de ver el primer tutorial de Git en http://blip.tv/play/Aeu2CAI .

¿Cómo almacena Git todas las versiones de todos los files, y cómo puede ser aún más económico en espacio que Subversion, que guarda solo la última versión del código?

Sé que esto se puede hacer usando la compression, pero eso sería a costa de la velocidad, pero esto también dice que Git es mucho más rápido (aunque donde gana el máximo es el hecho de que la mayoría de sus operaciones están fuera de línea).

Entonces, mi suposition es que

  • Git comprime los datos extensamente
  • Todavía es más rápido porque el uncompression + work es aún más rápido que el network_fetch + work de network_fetch + work de network_fetch + work

¿Estoy en lo correcto? ¿Incluso cerca?

Supongo que está preguntando cómo es posible que un clon de git (repository completo + verificación) sea más pequeño que las fonts de salida de Subversion. ¿O quisiste decir algo más?

Esta pregunta es respondida en los comentarios


Tamaño del repository

Primero, debe tener en count que, a lo largo del process de pago (versión de trabajo), Subversion almacena copys prístinas (última versión) en esos subdirectorys .svn . La copy prístina se almacena sin comprimir en Subversion.

En segundo lugar, git usa las siguientes técnicas para networkingucir el tamaño del repository:

  • cada versión de un file se almacena solo una vez; esto significa que si solo tiene dos versiones diferentes de algún file en 10 revisiones (10 confirmaciones), git solo almacena esas dos versiones, no 10.
  • los objects (y deltas, ver a continuación) se almacenan comprimidos; los files de text utilizados en la progtwigción comprimen realmente bien (alnetworkingedor del 60% del tamaño original, o el 40% de networkingucción en el tamaño de la compression)
  • después del reenvasado, los objects se almacenan en forma depurada, como una diferencia de alguna otra versión; además, git intenta orderar cadenas delta de tal manera que el delta consiste principalmente en eliminaciones (en el caso habitual de files en crecimiento, está en order de reciente aparición); Los deltas del IIRC también están comprimidos.

Rendimiento (velocidad de las operaciones)

Primero, cualquier operación que involucre a la networking sería mucho más lenta que una operación local. Por lo tanto, por ejemplo, comparar el estado actual del área de trabajo con alguna otra versión u get un logging (un historial), que en Subversión involucra connection de networking y transferencia de networking, y en Git es una operación local, sería mucho más lento en Subversión que en Git. Por cierto. esta es la diferencia entre los sistemas de control de versiones centralizadas (que utilizan el flujo de trabajo cliente-server) y los sistemas de control de versiones distribuidas (que utilizan el flujo de trabajo punto a punto), no solo entre Subversion y Git.

En segundo lugar, si lo entiendo correctamente, hoy en día la limitación no es la CPU sino IO (acceso al disco). Por lo tanto, es posible que la ganancia de tener que leer less datos del disco debido a la compression (y poder mapearlo en la memory) supere la pérdida por tener que descomprimir datos.

En tercer lugar, Git fue diseñado con el performance en mente (ver, por ejemplo, la página de GitHistory en Wiki Git):

  • El índice almacena información de statistics para files, y Git lo usa para decidir sin examinar files si los files fueron modificados o no (ver, por ejemplo, la variable de configuration core.trustctime ).
  • La profundidad delta máxima está limitada a pack.depth , que por defecto es 50. Git tiene memory caching delta para acelerar el acceso. Hay un índice de file de package (generado) para un acceso rápido a los objects en el file de package.
  • Git tiene cuidado de no tocar los files, no es necesario. Por ejemplo, al cambiar twigs o al rebobinar a otra versión, Git actualiza solo los files que han cambiado. La consecuencia de esta filosofía es que Git solo admite una expansión de palabras key mínima (al less de forma pnetworkingeterminada).
  • Git usa su propia versión de la biblioteca LibXDiff , hoy en día también para diff y merge, en lugar de llamar a la herramienta de fusión externa diff / externa.
  • Git intenta minimizar la latencia , lo que significa un buen performance percibido . Por ejemplo, genera la primera página de " git log " lo más rápido posible, y la ve casi de inmediato, incluso si generar el historial completo llevaría más time; no espera a que se genere el historial completo antes de mostrarlo.
  • Cuando busca nuevos cambios, Git comtesting qué objects tiene en común con el server y envía solo las diferencias (comprimidas) en forma de package delgado. Hay que admitir que Subversion puede (o quizás por defecto lo hace) enviar solo diferencias cuando se actualiza.

No soy un hacker de Git, y probablemente me perdí algunas técnicas y trucos que Git usa para un mejor performance. Sin embargo, tenga en count que Git usa mucho POSIX (como files mapeados en memory) para eso, por lo que la ganancia puede no ser tan grande en MS Windows.

No es una respuesta completa, pero esos comentarios (de AlBlue ) podrían ayudar en el aspecto de gestión espacial de la pregunta:

Hay un par de cosas que vale la pena aclarar aquí.

En primer lugar, es posible tener un repository Git más grande que un repository SVN ; Espero no haber insinuado que ese nunca fue el caso. Sin embargo, en la práctica, en general tiende a darse el caso de que un repository de Git ocupe less espacio en disco que un repository de SVN equivalente.
Una cosa que citan es el repository SVN único de Apache, que obviamente es masivo. Sin embargo, uno solo tiene que mirar git.apache.org , y git.apache.org que cada proyecto Apache tiene su propio repository Git. Lo que realmente se necesita es una comparación de like-for-like; en otras palabras, una salida del proyecto SVN (abdera) frente al clon del repository Git (abdera) .

Pude consultar git://git.apache.org/abdera.git . En el disco, consumió 28.8Mb.
Luego revisé la versión de SVN http://svn.apache.org/repos/asf/abdera/java/trunk/ , y consumió 34.3Mb.
Ambos numbers se tomaron de una partición montada por separado en el espacio RAM, y el número citado fue la cantidad de bytes tomados del disco.
Si usa du -sh como medio de testing, el pago de Git fue de 11Mb y el checkout de SVN fue de 17Mb.

La versión de Git de Apache Abdera me permitiría trabajar con cualquier versión del historial hasta e incluyendo la versión actual; el SVN solo tendría la copy de security de la versión actualmente desprotegida. Sin embargo, ocupa less espacio en el disco.

¿Cómo, puedes preguntar?

Bueno, para empezar, SVN crea muchos más files . El pago de SVN tiene 2959 files; el repository Git correspondiente tiene 845 files.

En segundo lugar, mientras que SVN tiene una carpeta .svn en cada nivel de la jerarquía, un repository de Git solo tiene un único depósito .git en el nivel superior . Esto significa (entre otras cosas) que cambiar el nombre de un directory a otro tiene un impacto relativamente menor en Git que en SVN, que, como es de suponer, ya tiene un impacto relativamente pequeño de todos modos.

En tercer lugar, Git almacena sus datos como objects comprimidos, mientras que SVN los almacena como copys sin comprimir . Vaya a cualquier directory .svn/text-base , y encontrará copys sin comprimir de los files (base).
Git tiene un mecanismo para comprimir todos los files (y de hecho, todo el historial) en files de package. En el caso de Abdera, .git/objects/pack/ tiene un único file .pack (que contiene todo el historial) en un file de 4.8Mb.
Entonces, el tamaño del repository es (más o less) del mismo tamaño que el código actual desprotegido en este caso, aunque no esperaría que ese sea siempre el caso.

De todos modos, tienes razón de que la historia puede llegar a ser más que el tamaño total del pago actual; pero debido a la forma en que funciona SVN, realmente tiene que acercarse al doble del tamaño para hacer una gran diferencia. Incluso entonces, la networkingucción del espacio en disco no es realmente la razón principal para usar un DVCS de todos modos; es una ventaja para algunas cosas, claro, pero no es la verdadera razón por la que la gente lo usa.

Tenga en count que Git (y Hg, y otros DVCS) tienen un problema por el que los binarys (grandes) se registran y luego se eliminan, ya que seguirán apareciendo en el repository y ocupando espacio, incluso si no están actualizados. . La compression de text se ocupa de este tipo de cosas para los files de text, pero los binarys son un problema mayor. (Hay commands administrativos que pueden actualizar el contenido de los repositorys de Git, pero tienen un costo administrativo / administrativo ligeramente más alto que CVS; git filter-branch es como svnadmin dump/filter/load ).


En cuanto al aspecto de la velocidad, lo mencioné en mi respuesta " ¿Qué tan rápido está Git sobre la subversión con operaciones remotas? " (Como dijo Linus en su presentación de Google : (parafraseando aquí) "cualquier cosa que implique una networking simplemente matará las actuaciones")

Y el documento de GitBenchmark mencionado por Jakub Narębski es una buena adición, a pesar de que no trata directamente con Subversion.
No enumera el tipo de operación que necesita para supervisar en un DVCS en cuanto a performance.

Otros puntos de reference de Git se mencionan en esta pregunta SO .