Sistemas de control de versiones: Git

Git Logo (imagen: Wikipedia)

Linux Torvalds

Linux Torwalds, autor del kernel de Git (Imagen: Wikipedia)

Git es un control de versiones distribuido que surge para gestionar el código fuente del kernel de Linux tras el cambio de licencia en el sistema utilizado anteriormente. El diseño es obra de Linus Torvalds y está pensado para soportar múltiples desarrolladores trabajando en distintas áreas de trabajo.

Git, a diferencia de Subversion tratado hasta ahora en la serie Control de Versiones), es de naturaleza distribuida, esto es, cada copia de trabajo es un repositorio en sí mismo y contiene todo el histórico de modificaciones. A pesar de lo que pueda parecer, crear una nueva copia del repositorio supone apenas unos segundos disponiendo de toda la información necesaria para trabajar sin conexión (en el portátil durante un largo viaje en tren) y sincronizar cambios al disponer de conexión.

Debido a su diferente visión y concepción es necesaria una primera introducción destacando sus características diferenciadoras:


Eficiencia

Git está pensado para ser eficiente y el resultado es que es muy veloz. Duplicar un repositorio lleva escasos segundos: en algunas pruebas es más ligeramente más rápido que un copy o rsync incluso sobre el disco local. Además utiliza todas las argucias disponibles para ser más eficiente en disco (por ejemplo, usa enlaces físicos a ficheros si está en el mismo sistema de ficheros).

Desarrollo no lineal

el código evoluciona en múltiples ramas paralelas que se dividen y se unen en distintos puntos. Esta cualidad simplifica la creación de ramas de experimentación que pueden fusionarse con el código principal o descartarse si no llegan a buen puerto. En contra está la desaparición del número de versión del repositorio (que carece de sentido) aunque dispone de algunos sistemas para emularlo como un “descriptor” de versión.

Captura gitk

Ejemplo de historia de Git mostrada por gitk

Posibilidad de reescribir la historia

aunque pueda parecer incongruente, permite modificar la información enviada al repositorio ya sean comentarios, contenidos de algún fichero, cambiar de orden cambios, fusionarlos o dividirlos… Esta característica es muy útil cuando se está investigando ya que permite corregir errores generados en un primer momento o corregir un error en el repositorio que rompe la compilación de la aplicación.

Autenticación criptográfica del repositorio

Para Git todos los objetos se almacenan bajo un hash SHA1 ya sean ficheros, directorios, commits… esto permite garantizar la integridad de los contenidos en todo momento. Además, es posible utilizar criptografía de clave asimétrica (usando GPG, la variante gratuita del conocido PGP) para firmar las etiquetas de las versiones liberadas.

Separación de ramas y etiquetas

En Subversion se usa un convenio para poder almacenar ramas y etiquetas en el repositorio. En Git, se trabaja fundamentalmente con ramas (que bifurcan y se fusionan) y las etiquetas son otra entidad diferente. Además, existen 3 tipos de etiquetas:

  • Etiqueta estándar que apunta a un punto del desarrollo
  • Anotación que además de apuntar un punto de desarrollo tiene un mensaje asociado
  • Firma, es una etiqueta que dispone de una firma PGP/GPG del autor. Este tipo de etiquetas permiten asegurar la autenticidad de la misma.

Detección heurística de copias

Git, a diferencia de otros sistemas de control de versiones, almacena el fichero completo en lugar de diferencias respecto al anterior. Esto le permite detectar ficheros copiados o movidos sin necesidad de utilizar algún mecanismo propio para indicar la copia.

Limpieza del espacio de trabajo

Uno de los puntos de los que pecan todos los sistemas de control de versiones es la necesidad de crear ficheros/directorios con metainformación repartidas a lo largo de los directorios del proyecto. Esto obliga a implementar una herramienta de exportación o scripts que eliminen esa metainformacion para distribuir el código.
Git únicamente crea un fichero oculto .git en la raíz de la copia de trabajo en la que se almacena toda su información sobre versiones.

Otros aspectos

Otro de sus grandes alicientes son las herramientas que proporciona: definición de alias para automatizar tareas, generación y tratamiento de parches por correo, mezcla “pulpo” de múltiples ramas de desarrollo, creación de archivos de un commit o un sistema automatizado de búsqueda del commit erróneo… Su uso básico y avanzado será descrito en próximas entregas.