svn - usados - ¿qué es un sistema control de versiones centralizado?
¿Cómo manejan los diferentes sistemas de control de versiones los archivos binarios? (5)
El principal punto de dolor está en el aspecto "Distribuido" de cualquier DVCS: está clonando todo ( todo el historial de todos los archivos)
Como los binarios no se almacenan en delta para la mayoría de ellos, y no se comprimen tan bien como el archivo de texto, si está almacenando binarios que evolucionan rápidamente, termina rápidamente con un repositorio grande que se vuelve muy engorroso para moverse (push / Halar).
Para Git, por ejemplo, mira ¿Cuáles son los límites de git? .
Los binarios no son una buena opción para la función que un VCS puede ofrecer (diff, branch, merge) y se manejan mejor en un repositorio de artefactos (como un Nexus por ejemplo).
Esto no es necesario para un CVCS (VCS centralizado) donde el repositorio podría desempeñar esa función y ser un almacenamiento para los binarios (incluso si no es su función principal)
He escuchado algunas afirmaciones de que SVN maneja los archivos binarios mejor que Git / Mercurial. ¿Es esto cierto? Si es así, ¿por qué? Por lo que puedo imaginar, ningún sistema de control de versiones (VCS) puede diferir y combinar cambios entre dos revisiones de los mismos recursos binarios.
Entonces, ¿no son todos los VCS malos manejando archivos binarios? No estoy muy al tanto de los detalles técnicos detrás de las implementaciones de VCS en particular, así que tal vez tengan algunos pros y contras.
En Subversion puedes lock archivos binarios para asegurarte de que nadie más pueda editarlos. Esto en su mayoría le asegura que nadie más modificará ese archivo binario mientras lo tiene bloqueado. Los VCS distribuidos no tienen cerraduras (y no pueden), no hay un repositorio central para que se registren en.
Git y Mercurial manejan archivos binarios con aplomo. No los corrompie, y puede verificarlos dentro y fuera. El problema es uno de tamaño.
La fuente generalmente ocupa menos espacio que los archivos binarios. Es posible que tenga 100K de archivos fuente que compilan un binario de 100Mb. Por lo tanto, almacenar una única compilación en mi repositorio podría hacer que crezca 30 veces su tamaño.
Y es aún peor:
Los sistemas de control de versiones suelen almacenar archivos a través de algún formato de diferencia. Digamos que tengo un archivo de 100 líneas y cada línea tiene un promedio de 40 caracteres. Ese archivo completo tiene un tamaño de 4K. Si cambio una línea en ese archivo y guardo ese cambio, solo estoy agregando unos 60 bytes al tamaño de mi repositorio.
Ahora, digamos que compilé y agregué ese archivo de 100Mb. Hago un cambio en mi fuente (tal vez 10K o más en cambios), recompilo y almaceno la nueva compilación binaria. Bueno, los binarios generalmente no se diferencian muy bien, por lo que es muy probable que agregue otros 100Mb de tamaño a mi repositorio. Haga algunas construcciones, y el tamaño de mi repositorio crece a varios gigabytes de tamaño, sin embargo, la parte de la fuente de mi repositorio es de hasta unas pocas docenas de kilobytes.
El problema con Git y Mercurial es que normalmente compras todo el repositorio en tu sistema. En lugar de simplemente descargar unas pocas docenas de kilobytes que pueden transferirse en unos pocos segundos, ahora estoy descargando varios gigabytes de compilaciones junto con las pocas docenas de kilobytes de datos.
Tal vez la gente dice que Subversion es mejor, ya que simplemente puedo pagar la versión que quiero en Subversion y no descargar todo el repositorio. Sin embargo, Subversion no le ofrece una manera fácil de eliminar los binarios obsoletos de su repositorio, por lo que su repositorio crecerá y crecerá de todos modos. Aún no lo recomiendo Diablos, ni siquiera lo recomiendo, incluso si el sistema de control de revisiones le permite eliminar revisiones antiguas de binarios obsoletos. (Perforce, ClearCase y CVS lo hacen). Simplemente termina siendo un gran dolor de cabeza de mantenimiento.
Ahora, esto no quiere decir que no deba almacenar ningún archivo binario. Por ejemplo, si estoy creando una página web, probablemente tenga algunos gifs y jpegs que necesito. No hay problema almacenando aquellos en Subversion o Git / Mercurial. Son relativamente pequeños, y probablemente cambien mucho menos que mi código en sí.
Lo que no debe almacenar son objetos construidos. Deben almacenarse en un repositorio de versiones y buscarse según sea necesario. Maven y Ant w / Ivy hacen un gran trabajo de esto. Y también puede usar la estructura de repositorio Maven en proyectos C, C ++ y C #.
Los archivos de texto tienen una estructura natural orientada a la línea de la que carecen los archivos binarios. Es por eso que es más difícil compararlos usando herramientas de texto comunes (diff). Si bien debería ser posible, la ventaja de la legibilidad (la razón por la que usamos el texto como nuestro formato preferido en primer lugar) se perdería al aplicar diffs a los archivos binarios.
En cuanto a su sugerencia de que todos los sistemas de control de versiones "son basura en el manejo de archivos binarios", no lo sé. En principio, no hay ninguna razón por la cual un archivo binario deba ser más lento de procesar. Prefiero decir que las ventajas de usar un VCS (seguimiento, diffs, información general) son más evidentes cuando se manejan archivos de texto.
Una aclaración sobre archivos git y binarios.
Git está comprimiendo archivos binarios y archivos de texto. Así que git no es una porquería al manejar archivos binarios como alguien sugirió.
Cualquier archivo que agregue Git se comprimirá en objetos sueltos. No importa si son binarios o de texto. Si tiene un archivo binario o de texto y lo confirma, el repositorio crecerá. Si realiza un cambio menor en el archivo y vuelve a comprometerse, su repositorio volverá a crecer aproximadamente a la misma cantidad dependiendo de la relación de compresión.
Luego haces un git gc
. Git encontrará similitudes en los archivos binarios o de texto y los comprimirá juntos. Tendrás una buena compresión si las similitudes son grandes. Si, por otro lado, no hay similitudes entre los archivos, no tendrá mucha ganancia al comprimirlos juntos en comparación con comprimirlos individualmente.
Aquí hay una prueba con una imagen de mapa de bits (binario) que he cambiado un poco:
martin@martin-laptop:~/testing123$ git init
Initialized empty Git repository in /home/martin/testing123/.git/
martin@martin-laptop:~/testing123$ ls -l
total 1252
-rw------- 1 martin martin 1279322 Jan 8 22:42 pic.bmp
martin@martin-laptop:~/testing123$ git add .
martin@martin-laptop:~/testing123$ git commit -a -m first
[master (root-commit) 53886cf] first
1 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 pic.bmp
// here is the size:
martin@martin-laptop:~/testing123$ du -s .git
1244 .git
// Changed a few pixels in the picture
martin@martin-laptop:~/testing123$ git add .
martin@martin-laptop:~/testing123$ git commit -a -m second
[master da025e1] second
1 files changed, 0 insertions(+), 0 deletions(-)
// here is the size:
martin@martin-laptop:~/testing123$ du -s .git
2364 .git
// As you can see the repo is twice as large
// Now we run git gc to compress
martin@martin-laptop:~/testing123$ git gc
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 1), reused 0 (delta 0)
// here is the size after compression:
martin@martin-laptop:~/testing123$ du -s .git
1236 .git
// we are back to a smaller size than ever...