Control de versiones
Ya he hablado sobre el control de versiones en varias ocasiones en el blog. A los lectores habituales, que creo que los hay (aunque sigo sin entender muy bien por qué) ya les sonará el haber leído algo sobre esto. Sin embargo, hoy va a ser un artículo muy introductorio. No sé exactamente cuándo publicaré este post y es posible que cuando estés leyendo este escrito, ya haya comenzado un curso de programación para alumnos de la E.S.O.1. Este año es el primero, aunque ya he hecho cursos sobre robótica en el mismo centro. Tengo pensado también preparar contenido sobre el control de versiones. Por lo tanto, es un artículo muy básico, con muchas definiciones de conceptos y poca práctica para que sirva de lectura introductoria a mis chicos. Te lo puedes saltar, si ya sabes de qué va, pero si nunca has utilizado un control de versiones o estás empezando a hacerlo, lo mismo te viene bien aprender unos pocos conceptos básicos, porque luego, cada herramienta hace de su capa un sayo y llama a las cosas como se le ocurre al iluminado que crea la herramienta.
¿Para qué sirve el control de versiones?
Antes de nada también hay que aclarar que el concepto de control de versiones es un tanto ambiguo y lo podemos encontrar nombrado de diversas maneras: SCM (Source Control Management), CVS (Concurrent Version System), SCS (Source Control System), VC (Version Control)...
A partir de esos nombres ya te puedes imaginar algunos aspectos sencillos:
- La cosa va de control, es decir, hay algo complejo que debemos manejar y gestionar de alguna manera más sencilla que el tomar notas a mano.
- También hay versiones, es decir, un mismo proyecto puede tener
varias versiones de su contenido:
- Las versiones se pueden referir al contenido generado por varias personas, que se deben guardar de manera conjunta (concurrente) en el mismo sitio, porque cada una aporta una parte del trabajo.
- Las versiones se pueden referir también a los avances que se van produciendo en el contenido de proyecto.
Estoy siendo cuidadoso de no utilizar la palabra código porque, aunque estos sistemas los desarrollaron programadores para gestionar su trabajo en equipo, se pueden utilizar para cualquier otro fin. Como por ejemplo, mantener un montón de cambios en lo artículos de un blog como éste; para hacer un trabajo escolar en equipo; para gestionar un trabajo individual complejo que puede estar sujeto a modificaciones.
¿Qué hace que sea útil un sistema de estos? Ahí van algunas posibles respuestas y no sólo una, sino todas ellas:
- Que tienes la libertad de borrar, mover, cambiar... y arrepentirte sin perder información en ningún momento. Si algo ha estado en el repositorio en una versión anterior, sigue estando en él.
- Que puedes realizar cambios en el proyecto o trabajo y los demás participantes los tendrán de forma inmediata.
- Que puedes tener algunas ramas del trabajo de forma experimental aunque luego, al final, no se integren el resultado definitivo.
- Que puedes volver en el tiempo a versiones anteriores y ver su evolución, o evolucionarlas de forma paralela en otras ramas.
- Que sabes quién, cómo y cuándo, apareció algún contenido en el proyecto, manteniendo una cronología perfecta de la evolución del mismo.
- Que tienes una copia completa en un repositorio remoto. En caso de pérdida, borrado o catástrofe, tienes una copia de seguridad completa de toda la información.
También deberías saber que existen muchos sistemas de estos: algunos son centralizados y otros distribuidos, pero no te preocupes de eso ahora, primero vamos a dar un repaso a los conceptos básicos.
Conceptos básicos
La mayoría de las veces las palabras se corresponden con los conceptos, pero en estos ámbitos no es raro encontrarse que una misma palabra, o comando, en dos sistemas de control de versiones diferentes, no corresponden al mismo concepto, o acción. O encuentras matices que hacen que la coincidencia no sea perfecta. Pero en general, podemos entender:
- Repositorio
- Es el almacén donde se guarda el contenido, un espacio donde están alojados los archivos y directorios que forman parte del proyecto... en todas sus versiones. Cada participante en el proyecto tiene su repositorio local y suele existir, al menos, uno remoto donde se guardarán los cambios de todos.
- Sistema de control de versiones
- es un programa que ayuda a mantener un repositorio donde pueden realizar cambios varias personas de manera conjunta.
- Commit
- se corresponde con la acción de guardar los cambios que hemos hecho en el repositorio. Habitualmente, esos cambios se guardan en el repositorio local.
- Trunk
- esta es la línea principal o tronco del contenido del repositorio.
- Branch
- es una escisión de la línea principal. Normalmente se utilizan para añadir características nuevas al contenido del repositorio y nos permiten experimentar sin afectar a la línea principal.
- Fork
- bifurcación de la línea principal. En algunos sistemas se le llama así a continuar el desarrollo del proyecto de manera paralela al repositorio original. En otros sistemas se utiliza para referirse a una bifurcación generada por la aplicación para resolver problemas de concurrencia. En otros puede ser el simple hecho de hacer una copia local del repositorio general.
- Log
- listado de los commits de cambios.
- Merge
- acción de juntar dos ramas del repositorio en una, por ejemplo, para volcar los cambios de una rama en la línea principal.
- Pull
- acción de descargar al repositorio local los cambios almacenados en un repositorio remoto.
- Push
- acción de enviar los cambios almacenados en el repositorio local al repositorio remoto.
- Sync
- acción de sincronizar el repositorio local con el remoto.
Existen otros conceptos y acciones que se pueden realizar en un repositorio, como revertir cambios o situarlo en determinado estado anterior. Pero los enumerados anteriormente son los más básicos y con los que hay que lidiar más a menudo en el trabajo diario.
Gestión de cambios
La gestión de los cambios tiene aspectos diferentes según el tipo de proyecto en el que estés trabajando. Si es un proyecto personal y no es necesario un seguimiento exhaustivo de la evolución del proyecto, el tener el contenido en un sistema de control de versiones, puede ser una forma de mantener una copia de seguridad. Sin embargo, hay todo un arte en subir los cambios al repositorio mediante commits.
Cada commit se convierte en una información valiosa para comprender la evolución del proyecto y cuanto más detallados estén los commits, mejor podrás comprenderlo. Cada uno de ellos lleva aparejado un mensaje de texto, que sería el título, por decirlo así, pero también se pueden añadir más mensajes para detallar el cambio realizado. La mayoría de sistemas abren un editor de texto para facilitarnos el escribir el mensaje del commit. La estructura del commit suele ser:
- Una línea de título del mensaje de commit, que suele ser obligatoria.
- Después de una línea en blanco, en el editor, se puede escribir toda la explicación que se necesite para detallar lo que se ha hecho. Esta parte es opcional, si el cambio es evidente no es necesaria. Desde la línea de comandos se pueden proporcionar varias cadenas de texto para formar el cuerpo.
¿Cómo hacer un commit?
Ten en cuenta las siguientes premisas:
- Un commit, un cambio: recuerda realizar un commit para cada cambio que hagas. Si modificas muchas cosas y agrupas todo el trabajo que has hecho durante horas en un sólo mensaje, el seguimiento de los cambios te será más difícil.
- Revisa el lenguaje: recuerda escribir claramente y con corrección un menaje descriptivo que se ajuste al cambio que has hecho.
- Sé escueto: el mensaje de título no debería tener más de 50 ó 60 caracteres. Si necesitas explicar algo más detalladamente, utiliza el cuerpo del commit para hacerlo.
- Utiliza el verbo en imperativo, por ejemplo: añade..., borra..., crea..., arregla..., etc.
- No uses puntos suspensivos, ni un punto, al final del commit, recuerda que es un título y no lo necesita.
- Si el proyecto es de código, asegúrate que el estado del repositorio permite compilar y ejecutar el programa o librería. No olvides añadir todas las dependencias y código necesario para que sea así, o puedes tener a otros compañeros volviéndose locos por un error tuyo.
La teoría es esa, o esas son las buenas maneras que deberíamos utilizar, luego algunos somos descuidados y hacemos de nuestra capa un sayo, para, al final, aprender a base de compartir repositorios con otros programadores y que te saquen los colores cuando no cuidas estos detalles.
Texto plano
Los gestores de versiones suelen funcionar bien sobre archivos de
texto plano. Recuerda que todas estas herramientas se desarrollaron
para soportar código. A los que usamos texto plano para generar
nuestros documentos, bien sea con lenguajes de marcado ligero, como
org-mode
o markdown, bien con lenguajes de marcado más pesado como
TeX, LaTeX, Lout, nos vienen muy bien estas herramientas de
gestión de cambios. Sin embargo, si utilizas muchas imágenes raster,
o documentos de ofimática cerrados, aunque los pueden gestionar, cada
cambio se almacena guardando el archivo completo, formando un
repositorio enorme y pesado. Por eso, el repositorio puede crecer en
tamaño hasta hacerse inmanejable. Si tu proyecto consiste en trabajar
sobre archivos binarios, estas herramientas no son recomendables.
Repositorios remotos
Una de las pegas que puedes encontrar en el manejo de estas herramientas es la dificultad de montar un repositorio remoto. Suele aparejar el montaje de un servidor que proporcione el acceso al mismo y no es fácil, muchas veces, encontrar un lugar donde situar el remoto al alcance de todos los miembros del equipo.2
Voy a mencionar dos estrategias muy utilizadas, aparte de la mencionada de montar un servidor, que no está al alcance de todos:
- Aprovechar la nube para que nos haga de repositorio.
- Utilizar un servicio de repositorios ya montado.
La nube
Si tenemos algún lugar en lo que se denomina la nube que sea
compartido, se puede montar un repositorio remoto allí para
sincronizar cambios. Dependiendo del sistema de control de versiones
que estés utilizando puedes tener algunos problemas para sincronizar
dichos repositorios. Por ejemplo, git
, uno de los sistemas más
extendidos para estas tareas utiliza archivos guardados en directorios
ocultos. Al colocarlos en nubes tipo NextCloud o Dropbox, debes
recordar de activar la sincronización de los archivos y directorios
ocultos o no se sincronizará correctamente.
A su vez, si está en un directorio compartido, tenemos que ser muy cuidadosos al sincronizarnos. No podemos escribir a la vez y debemos asegurarnos de que cuando lo hacemos el repositorio se encuentre actualizado con respecto a la copia remota.
Por todo ello, esta estrategia nos es útil para almacenar repositorios personales, pero es bastante difícil de mantener en el caso de proyectos con varios participantes.
Repositorios públicos
Desde hace tiempo existen servicios que nos proporcionan un espacio donde colocar nuestros repositorios. Entre los pioneros de este tipo de servicios está SourceForge. En la mayoría de los casos, para proyectos de software libre el alojamiento es gratuito, pero alojar proyectos personales o con licencias no libres, suele conllevar el pago del servicio. Podemos encontrar varios de estos servicios para alojar nuestros repositorios, aparte del ya mencionado:
- GNU Savannah: pertenece a la Free Software Fundation y está
enfocado al desarrollo de software libre. Hay que hacer una
solicitud de espacio cumpliendo los requisitos necesarios. Puede
albergar repositorios de diferentes herramientas de gestión:
cvs
,svn
,git
,hg
. - Repos privativos: suelen pertenecer a corporaciones o
empresas. Normalmente son sitios donde sólo trabajan con
git
: GitHub, GitLab, BitBucket... - Repos libres: En algunos casos podemos encontrar servidores que
funcionan de una manera más abierta y libre. Entre los que trabajan
con
git
podemos mencionar Gitea o Codeberg. También merece una mención el servicio de Chisel si quieres alojar un repositorio confossil
.
¿Qué proporcionan estos servicios?
Normalmente los servicios de alojamiento de repositorios suelen aparejar una serie de herramientas muy útiles para el desarrollo de proyectos: wiki, foros, gestión de errores, página web del proyecto, etc.
Muchas herramientas de control de versiones se centran, como git
, en
la gestión de los cambios del proyecto. Los servicios de repositorio,
también llamados servicios de forja, proporcionan esas herramientas
complementarias a la gestión del proyecto.
Otros sistemas, como fossil
, proporcionan dichas herramientas en
todos sus repositorios, incluidos los locales, por diseño.
Conclusiones
El control de versiones es una herramienta auxiliar para programación, que se puede utilizar para gestionar (casi) cualquier tipo de proyecto conjunto.
Permite seguir los cambios realizados por los participantes del equipo, especialmente en los contenidos de texto plano.
Es muy recomendable aprender cómo funciona alguno de estos sistemas.
Más recomendable aún aprender varios. En mi caso, trabajo
habitualmente con git
pero en los últimos tiempos, si necesito
alguna de las herramientas de forja, utilizo fossil
en
repositorios locales, en lugar de subirlo a uno público en la
red. Aunque cada vez más, necesito esas herramientas, porque utilizo
la wiki para anotar ideas, lo tickets para planificar tareas y
anotar errores que hay que corregir, etc.
Comentarios