Notxor tiene un blog

Defenestrando la vida

Control de versiones

Notxor
2022-10-23

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 con fossil.

¿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.

Notas al pie

Footnotes:

1

Para los no españoles, aclarar que es el acrónimo de Enseñanza Secundaria Obligatoria y los chavales que estarán en mi grupo, tendrán, o pueden tener, entre 11 y 16 años.

2

Montar un servidor para el repositorio remoto implica unas complejidades que se escapan de este artículo.

Categoría: cms fossil git

Comentarios

Debido a algunos ataques mailintencionados a través de la herramienta de comentarios, he decidido no proporcionar dicha opción en el Blog. Si alguien quiere comentar algo, me puede encontrar en Mastodon y en Diaspora con el nick de Notxor.

También se ha abierto un grupo en Telegram (enlace de invitación al grupo), para usuarios de esa red.

Disculpen las molestias.