Saltar al contenido
KodigoSwift

Sistemas de Control de Versiones

Sistemas de Control de Versiones

Los sistemas de control de versiones son herramientas que gestionan los diversos cambios que se realizan sobre los elementos de uno o más proyectos, guardando así versiones de nuestra aplicación en todas sus fases de desarrollo. Cuando hablamos de una versión, revisión o edición de un producto, nos referimos al estado en el que se encuentra el mismo en un momento dado de su desarrollo o modificación. Una revisión donde se nos informa la fecha en la cual se ha creado, quien la ha ejecutado y por qué motivos lo ha hecho.

Estas versiones son como una instantánea / snapshot donde se registra el estado del proyecto en un momento determinado en el tiempo y se van guardando, a medida que se hacen, modificaciones al código fuente, se agregan assets, frameworks o librerías, etc. Es como si congeláramos el tiempo cada vez que apliquemos un cambio importante para luego, en caso preciso, poder volver atrás y reintentarlo desde este punto.  Me imagino que una analogía también válida y con la que la mayoría hemos interactuado serían los checkpoint en algunos juegos, las revisiones que gestionan WordPress para con nuestras publicaciones o el undo y redo que muchas veces ejecutamos sobre la edición de una foto o video o más frecuente en un documento de Word o Pages.

Creo que ya vamos entendiendo que el control de versiones lo podemos aplicar a cualquier tipo de proyecto que estemos creando en nuestro ordenador, no necesariamente de software. Pudiera ser aplicado al proceso de escribir un libro o tesis de grado, la edición de una foto o video podemos definirlo:

En un sistema de control de versiones se registran los cambios realizados sobre un archivo o conjunto de estos a lo largo del tiempo, de modo que puedas recuperar versiones específicas más adelante.

Además de todo lo antes comentado y haciendo un énfasis en el desarrollo de software: los sistemas de control de versiones dan soporte a esa necesidad que surge en todo proyecto de trabajar en distintas ramas al mismo tiempo, introduciendo cambios a nuestra aplicación, tanto en la rama de desarrollo como a la que tenemos en producción. Teóricamente, las nuevas funcionalidades de nuestra aplicación las iremos trabajando dentro de la rama de desarrollo, pero constantemente uno se encuentra resolviendo bugs, tanto en la rama de producción como en la de desarrollo. A esto me refería con movernos en el tiempo, podemos ir tanto hacia atrás como hacia adelante, podemos trabajar en varias ramas (branch) que existen en paralelo dentro de la misma línea de tiempo o historial de nuestra aplicación, la rama estable, testing o de desarrollo… ya esto lo determina cada equipo y la metodología de trabajo que se aplique (SCRUM, Modelo en Cascada… etc).

Evolución en el Control de Versiones

Como todo en este mundo, los sistemas de control de versiones han sufrido una evolución hasta nuestros días. Comenzaron a aparecer allá por los años setenta, aunque al principio eran bastante elementales. Para que se hagan una idea, en los primeros sistemas existía una restricción por la que sólo una persona podía estar a la vez tocando el mismo código. Es evidente que esto provocaba un gran retraso en los equipos de trabajo, por lo que se convirtió junto a otros aspectos en esa fuerzas de cambio que a lo largo de los años impulsó el surgimiento de nuevos sistemas de control de versiones cada vez mejores y siempre en consecuencia con las necesidades de los equipos de desarrollo.

A continuación hablaremos sobre los tres tipos o variantes principales que han surgido:

Sistema de Control de Versiones Local

Un método de control de versiones que todos hemos aplicado es copiar archivos a otros directorios, especificando variaciones en los nombres (archivo1, archivo2, archivo-final… etc) o quizás indicando la fecha y hora en que estos fueron modificados.  Estos son meros ejemplos de una gestión de versiones vetusta, que aún hoy se siguen aplicando dada la simpleza de esta solución, pero claramente no es para nada óptima y sí tremendamente propensa a errores. Es fácil olvidar en qué directorio te encuentras, y guardar accidentalmente en el archivo equivocado o sobrescribir archivos que no querías.

Para hacer frente a este problema, hace tiempo se crearon los primeros sistemas de versiones locales, estos contenían una simple base de datos en la que se llevaba un registro de todos los cambios realizados sobre los archivos. Remarcar que estamos hablando de un sistema local que no contaba con ningún respaldo en la nube y que estaba expuesto a cualquier problema de hardware o sistema operativo por lo que hacer backup de este sistema y sus archivos era mandatory.

Una de las herramientas de control de versiones más popular fue un sistema llamadorcs, que todavía podemos encontrar en muchos de los ordenadores actuales. Hasta macOS incluye el comandorcscuando instalas las herramientas de desarrollo. Esta herramienta funciona básicamente guardando conjuntos de parches (es decir, las diferencias entre archivos) de una versión a otra en un formato especial en disco; puede entonces recrear cómo era un archivo en cualquier momento sumando los distintos parches.

Sistemas de Control de Versiones Centralizados

Estos sistemas, como CVS, Subversion, y Perforce, tienen un único servidor que contiene todos los archivos versionados, y varios clientes descargan los archivos desde ese lugar central. Durante muchos años éste fue el estándar para el control de versiones y como sucede con todo en un inicio vino a resolver varios problemas y ofrecía sólidas ventajas frente a los sistemas de versiones locales. Sin embargo, esta configuración también tiene serias desventajas. La más obvia es el punto único de fallo que representa el servidor centralizado. Si ese servidor se cae durante una hora, entonces durante esa hora nadie puede colaborar o guardar cambios versionados de aquello en que están trabajando. Si el disco duro en el que se encuentra la base de datos central se corrompe, y no se han llevado copias de seguridad adecuadamente, pierdes absolutamente todo, toda la historia del proyecto salvo aquellas instantáneas que puedan haber en las máquinas locales de los desarrolladores. Los sistemas de controles de versiones locales sufren de este mismo problema, cuando tienes toda la historia del proyecto en un único lugar, te arriesgas a perderlo todo.

Sistemas de Control de Versiones Distribuidos

Es aquí donde entran los sistemas de control de versiones distribuidos (Distributed Version Control Systems en inglés). En un DVCS (como Git, Mercurial, Bazaar o Darcs), los clientes no sólo descargan la última instantánea de los archivos: también replican completamente el repositorio. Así, si un servidor muere, y estos sistemas estaban colaborando a través de él, cualquiera de los repositorios de los clientes puede copiarse en el servidor para restaurarlo. Cada vez que se descarga una instantánea, en realidad se hace una copia de seguridad completa de todos los datos. Es más, muchos de estos sistemas se las arreglan bastante bien teniendo varios repositorios con los que trabajar, por lo que puedes colaborar con distintos grupos de desarrolladores simultáneamente dentro del mismo proyecto. Esto te permite establecer varios flujos de trabajo que no son posibles en sistemas centralizados, como pueden ser los modelos jerárquicos.

¿Cuál elegir?

Tanto sistemas distribuidos como centralizados tienen ventajas e inconvenientes. Cabe mencionar que los sistemas un poco más antiguos como CVS o también Subversion, por sus características, son un poco más lentos y pesados para la máquina que funge como servidor central; mientras que en los sistemas distribuidos no es necesario que exista un servidor hacia donde enviar los cambios, pero en caso de existir se requiere de una menor capacidad de procesamiento y gestión, ya que como hemos comentado muchas de las operaciones para la gestión de versiones se hacen a nivel local.

En la actualidad prima una dinámica de trabajo colaborativa y como creo que siempre ha sido la elección muy pocas veces recae sobre nosotros. La mayoría de las empresas medianamente organizadas ya tienen todo esto establecido y construyen su metodología de trabajo sobre una realidad cada vez más común: equipos cuyos miembros trabajan sobre un mismo proyecto de manera deslocalizada, es decir que no todos se encuentran en la misma oficina, algunos trabajan a distancia desde casa o desde otro países.

Flujo de trabajo remoto.

Así que a priori, para muchos la solución es tan sencilla como tener el proyecto en la nube, ya sea en un servicio propio o en uno de terceros. Cuando necesitamos realizar una modificación al proyecto, descargamos la última versión, la actualizamos y la volvemos a subir. Pero resulta que esto tiene varios inconvenientes:

  • Estás limitado por el ancho de banda de tu conexión. Si cada vez que tienes que realizar una modificación tienes que mirar en la nube la última versión, descargarla, hacer las modificaciones, volverla a subir, y si tu conexión a internet es lenta, tu trabajo será muy engorroso.
  • ¿Qué sucede cuando otro realiza modificaciones a la vez que tú, cuando dos estáis trabajando a la vez sobre un mismo archivo? ¿Cuál es la versión válida?

Nuevamente la solución actual más óptima recae sobre los sistemas de Control de Versiones Distribuidos, donde cada miembro del equipo tiene una copia local del sistema de control de versiones. Es decir, una copia completa del historial de cambios que se han ido realizando. Cada vez que realizamos una modificación en nuestra copia ésta se reporta a la copia principal, donde es gestionada convenientemente por el administrador del proyecto.

Ventajas de los sistemas de control de versiones distribuidos sobre los centralizados.

A modo de resumen podemos decir con seguridad que los sistemas de control de versiones distribuidos están más optimizados, básicamente por su diseño y debido también a ser sistemas concebidos hace menos tiempo, más actuales. Así que en términos comparativos y respondiendo a la pregunta nos podemos quedar sin dudas con las ventajas que nos ofrecen los sistemas distribuidos frente a los sistemas centralizados ya prácticamente en desuso.

Versionado de Software

Las versiones de software son otro aspecto que creo importante abordar. En paralelo con un buen sistema de control de versiones distribuido muchas veces necesitamos también indicar su nivel de desarrollo. El versionado de software consiste en esto mismo, es el proceso de asignación de un nombre o número único a un software para indicar su nivel de madurez y el estado en el que se encuentra (Alpha, Beta, Release Candidate o Golden Master en el caso de Apple). Seguramente muchos se habrán preguntado el significado de esos números (1.0, 2.4, 10, 2020… etc) que muchas veces acompañan al nombre de ciertos software o proyectos en general. ¿Qué es lo que determinan estos números o que tomamos en cuenta cuando los elegimos? Veamos:

Versionado Tradicional

Generalmente se asigna dos números, mayor.menor (en inglés: major.minor), que se van incrementando conforme el desarrollo del software y se requiera la asignación de un nuevo nombre, código o número único. Aunque menos habituales, también puede indicarse otro número más, micro, y la fase de desarrollo en la que se encuentra el software.

Estos números aumentan cuando:
  • mayor: el software sufre grandes cambios y mejoras.
  • menor: el software sufre pequeños cambios y/o correcciones de errores.
  • micro: se aplica una corrección al software, y a su vez sufre pocos cambios.
  • fase: se indica si se encuentra en una fase de desarrollo que no sea la final o estable, es decir, una fase inestable o en pruebas. Se suele indicar con un guión seguido de la fase correspondiente en minúsculas, o un espacio seguido de la fase. Puede haber varias versiones de una misma fase, para indicar el avance en el desarrollo del software pero manteniendo la fase para indicar que todavía es inestable, indicándose añadiendo un número al final del nombre de la fase que va incrementando conforme se publiquen nuevas versiones de esta fase.

Otros Sistemas de Versionado

Existen una variedad de sistemas que no siguen el versionado tradicional. Algunos abogan por nombres más comerciales (aunque internamente usan el versionado tradicional) a los cuales aplican ciertas estrategias de venta aunque muchas veces siguiendo la lógica de cambios significativos o corrección de errores que representan los dígitos y números en el versionado tradicional, un ejemplo pudiera ser la evolución de macOS Sierra hacia macOS High Sierra. Otros proyectos, como Ubuntu, usan estos dígitos para indicar la fecha de lanzamiento, ejemplo: Ubuntu 17.04 o 17.10 donde se hace referencia al año y mes de lanzamiento, siendo 17.04 (año 2017 y mes 04).

Git vs Competencia

Git, hoy en día, es el sistema de control de versiones distribuido más utilizado a nivel mundial y no se ha vuelto el camino a seguir por ningún mandato divino y sí por mérito propio. Existen características que lo distinguen de otros sistemas de control de versiones distribuidos (Distributed Version Control Systems en inglés):

Operaciones Locales

La mayoría de las operaciones en Git sólo necesitan archivos y recursos locales para operar. Por lo general no se necesita información de ningún otro ordenador de la red. Como tienes toda la historia del proyecto ahí mismo, en tu disco local, la mayoría de las operaciones son prácticamente inmediatas. Por ejemplo, para navegar por el historial del proyecto, Git no necesita acceder al servidor (GitHub, GitLab.. etc) en pos de mostrarla, simplemente la lee directamente de tu base de datos local. De igual manera si deseas ver los cambios introducidos en un archivo entre la versión actual y la de hace dos meses, Git puede buscar el archivo en el historial y hacer un cálculo de diferencias localmente, en lugar de tener que pedirle a un servidor remoto que lo haga, u obtener una versión antigua desde la red, esto también significa que hay muy poco que no puedas hacer si estás desconectado. Si te subes a un avión o a un tren y quieres trabajar un poco, puedes confirmar tus cambios felizmente hasta que consigas una conexión de red para subirlos. En muchos otros sistemas, esto es imposible o muy doloroso. En Perforce, por ejemplo, no puedes hacer mucho cuando no estás conectado al servidor; y en Subversion y CVS, puedes editar archivos, pero no puedes confirmar los cambios a tu base de datos (porque tu base de datos no tiene conexión). Esto puede no parecer gran cosa, pero te sorprendería la diferencia que puede suponer.

Integridad

Todo en Git es verificado mediante una suma de comprobación (checksum en inglés) antes de ser almacenado, y es identificado a partir de ese momento mediante dicha suma. Esto significa que es imposible cambiar los contenidos de cualquier archivo o directorio sin que Git lo sepa. Esta funcionalidad está integrada en Git al más bajo nivel y es parte integral de su filosofía. No puedes perder información durante una transmisión o sufrir corrupción de archivos sin que Git lo detecte.

El mecanismo que usa Git para generar esta suma de comprobación se conoce como hash SHA-1. Se trata de una cadena de 40 caracteres hexadecimales (0-9 y a-f), y se calcula en base a los contenidos del archivo o estructura de directorios. Un hash SHA-1 tiene esta pinta:


Verás estos valores hash por todos lados en Git, ya que los usa con mucha frecuencia. De hecho, Git guarda todo no por nombre de archivo, sino por el valor hash de sus contenidos.

Sólo Añade Información

Cuando realizas acciones en Git, casi todas ellas sólo añaden información a la base de datos de Git. Es muy difícil conseguir que el sistema haga algo que no se pueda deshacer, o que de algún modo borre información. Como en cualquier sistema de control de versiones, puedes perder o estropear cambios que no has confirmado todavía; pero después de confirmar una instantánea en Git, es muy difícil de perder, especialmente si envías (push) tu base de datos a otro repositorio con regularidad. Esto hace que usar Git sea un placer, sabemos que podemos experimentar sin peligro de estropear gravemente las cosas.

Resumen

A lo largo de este artículo hemos visto la necesidad e importancia de los sistemas de control de versiones y sus beneficios:

  • Permite mantener un histórico de todo el desarrollo del proyecto.
  • Añade trazabilidad al desarrollo de software, ya que se puede ver qué cambios se han hecho en el código en cada versión.
  • Muestra mucha información estadística de cómo se está desarrollando el proyecto (principales autores, número de versiones, cambios, etc.).
  • Facilita mucho el trabajo en equipo.
  • Permite desarrollar varias versiones de un mismo programa a la vez.

…conocimos su evolución y los distintos tipos que existen, hemos abordado también el versionado del software y comentado acerca de Git: la opción dominante en los sistemas de control de versiones distribuidos. Llegado este punto si deseas seguir aprendiendo sobre estos temas te recomendamos nuestra introducción, instalación y configuración inicial de Git.

RECIBE CONTENIDO SIMILAR EN TU CORREO

RECIBE CONTENIDO SIMILAR EN TU CORREO

Suscríbete a nuestra lista de correo y mantente actualizado con las nuevas publicaciones.

Se ha suscrito correctamente!