Ir al contenido principal

Git y control de versiones

Cuando trabajamos en el desarrollo de algún tipo de proyecto, uno de los problemas más habituales es la revisión de lo que se escribe o se diseña. Para el desarrollo de software existen herramientas especializadas para el control de versiones. Son básicamente una base de datos en la que vamos guardando versiones de un determinado fichero, y con la que podemos comparar fácilmente los cambios entre dos versiones determinadas. Cuando para un determinado proyecto software se coordinan media docena de programadores trabajando sobre varios miles de ficheros a lo largo de un año, es un elemento muy importante para el buen desarrollo del proyecto.

Tiempo atras RCS y VCS fueron dos de las primeras herramientas para el control de versiones. La primera era una herramienta de control para el trabajo individual que trabajaba exclusivamente sobre un equipo en forma local. A partir de ella, a principios de los 90 se desarrollo VCS para permitir mantener una base de datos de versiones centralizada en un servidor, que podía ser sincronizada entre diferentes equipos locales usando SSH. Posteriormente en torno al año 2000 evolucionaron en el primero sistema de control de versiones para programadores de uso generalizado: SVN.

SVN nació como una herramienta de control de código fuente centralizada. En un servidor central se guardaban las versiones de los ficheros de código, y los diferentes programadores sincronizaban sus archivos localmente. La facilidad para trabajar sobre un protocolo de comunicación genérico, como es HTTP, y los controles de integridad hicieron que su uso creciera rápidamente.

Con SVN el control de versiones de un proyecto era sencillo:

  1. Se creaba un proyecto en un servidor remoto, en el que se iba a almacenar todo el código y sus revisiones.
  2. Cuando un programador se unía a un proyecto se sincronizaba con el repositorio remoto, y copia en su equipo local la última versión de los ficheros del proyecto.
  3. El programador modifica ficheros en base a los requisitos necesarios.
  4. Cuando el programador validaba los cambios, enviaba al servidor los ficheros modificados.
  5. El servidor comprobaba que ningún otro programador hubiera modificado esos ficheros, y en ese caso aceptaba los cambios.
  6. Si otro programador había introducido cambios en esos ficheros, era necesario "descargar los cambios del otro programador", y corregir cualquier problema o incosistencia.
  7. Cada cierto tiempo era necesario hacer una descarga de la última versión de los ficheros para tener bien actualizados los cambios de otros programadores.

Al cabo de unos años de uso de SVN, se vieron varias carencias en el sistema que complicaban su uso para el desarrollo ágil. Fruto de esas carencias surgió GIT como sistema de control de versiones. Dicha aplicación es a día de hoy la que tiene un uso más generalizado. Para entender las carencias de SVN debemos entender los cambios en el desarrollo entre el modelo tradicional o cascada, y el modelo ágil que empezaron a ocurrir a mediados de la decada del 2000 (y en los que aun estamos en proceso de transición).

  • Básicamente en el desarrollo en cascada, un equipo de programación recibía una enorme lista de requisitos para construir un software determinado.
  • Esa lista de requisitos estaba cerrada y validada por todos los interesados.
  • En muchos casos había una lista detallada de validaciones a cumplir.
  • El equipo de desarrollo se ponía a trabajar "a destajo" para entregar el software requerido en un periodo de bastantes meses (no era raro tener periodos de desarrollo de más de un año).
  • Cada programador implementaba el código para solucionar un requisito y lo iba incorporando al control de versiones.
  • Si existía algún problema en una versión se buscaba en el historial del código el punto donde se produciá el error, y se trabajaba en las correcciones.
  • Cuando todas las funcionalidades estaban validadas y terminadas se entregaba el software.
  • Tras la entrega del software, se trabaja en mantenimiento y evolutivos. Pequeñas correcciones a errores inesperados que se hacían cuando aparecían, y pequeñas modificaciones que se requerían tras una aprovación previa.

La clave aqui era que, todo el trabajo estaba organizado de antemano. Todo el trabajo que se iba desarrollando se iba a incorporar al final, y el control de versiones ofrecía un doble función: bitacora de todo lo que iba ocurriendo, y salvavidas cuando alguna prueba salía mal.

Ese enfoque cambia con el desarrollo ágil: la base del desarrollo ágil es la entrega continua de "partes" del software. Cuando se aprueba un proyecto de software ágil, se aprueba una "idea general", y una plan de entregas por partes. "El primer viernes de cada mes se entrega una versión con nuevas funcionalidades, y todos los martes se publican parches con correcciones de problemas".

  • Las ventanas de desarrollo son mucho más pequeñas, y los programadores se ven obligados a hacer mucho más trabajo en paralelo sobre los mismos ficheros, en consecuencia aumenta muchísimo la cantidad de conflictos (varios programadores introduciendo cambios sobre el mismo ficheros).
  • Las entregas son obligatorias: nada garantiza que un desarrollo que haya iniciado un programador se vaya a completar a tiempo para la próxima entrega. Es muy habitual tener desarrollos intermedios que no se pueden integrar para las entregas. Hay que empezar a gestionar de forma separada versiones de trabajo, y versiones de entrega.
  • La entrega del software se hace desde el principio, y la corrección de errores, y los trabajos evoluitivos se mezclan con los trabajos de construcción del software. Aumenta la presión para gestionar versiones de trabajo, versiones de entrega, y versiones de correcciones. Todas esas versiones tiene que ser mezcladas cada poco tiempo.
  • Con un ritmo de entrega tan alto, es fácil encontrarse con una versión distinta del software cada semana. En empresas muy grandes, es incluso probable tener diferentes servidores ejecutando el software, y no todos con las mismas versiones. Es importante tener la seguridad de saber que versión hay en cada momento, y que código corresponde a cada versión para poder auditar errores y seguridad.

Los equipos de trabajo introducen una serie de "buenas prácticas" para que usando SVN se pueda dar soporte a todos estos cambios. Nace la metodología llamada: "TTB" se crea un directorio TRUNK en el repositorio para tener el código listo para entregar, un directorio TAGS donde se copia el código a una carpeta con número de versión cada vez que se hace una entrega, y una carpeta BRANCH donde cada programador crea una carpeta con nombre por cada funcionalidad sobre la que empieza a trabajar.

  • Cuando un programador empezaba a implementar una nueva funcionalidad, creaba una carpeta dentro de BRANCHES con un nombre significativo ("Noticiacon-email") y tenía una copia de todo el proyecto en dicha carpeta. Trabajaba sobre esa carpeta, hasta completar el desarrollo.
  • Cuando el desarrollo de una funcionalidad estaba terminado: se comparaba la carpeta de BRANCHES con TRUNK, se incorporaban todos los cambios que otros programadores pudieran haber echo sobre TRUNK, y tras validar esos cambios, se copiaba el código sobre TRUNK.
  • En TRUNK sólo había una versión estable y validada. Cuando se hacía una entrega de una versión del código se creaba una copia de trunk en la carpeta TAGS.

Sin embargo SVN no estaba diseñado para trabajar de ese modo, y el rendimiento se degrabada rápidamente. Merges para comparar los cambios del código que podían tardar más de media hora, bases de datos locales que se corrompían en algun directorio, y obligaban a volver a coger la versión del servidor remoto, y copiar los ficheros a mano...

En 2005 surge GIT, dando soporte nativo a esa forma de trabajo. Esta diseñado para trabajar con diferentes bases de datos de versiones, y facilitar la integración entre ramas. Todas las operaciones que comentamos antes, que son tan habituales durante el desarrollo ágil estan contempladas en el diseño de GIT. Su rendimiento a la hora de cambiar entre ramas o hacer mezclas de las mismas es casi instantaneo, y hace que los programadores se sientan cómodos trabajando con ellas. La mayoría de los programadores que trabajan con SVN sienten una enorme pereza a la hora de cambiar de rama, y de la misma forma, suelen reservar casí un día entero al trabajo de mezclar ramas... al pasar a git: esos dos limitantes desaparecen.

Si has encontrado este ladrillo interesante, quieres empezar a usar git para controlar las versiones y te preguntas "como organizar las ramas": puedes echarle un ojo a las técnicas de nombrado de ramas (gitflow) sobre las que he comentado alguna pincelada aqui

Igualmente, si te ha surgido la duda de cómo numerar las versiones del software entregado, también te invito a darle un ojo en este enlace.

Comentarios