Control de versiones
Para qué sirve un sistema de control de versiones, la diferencia entre el modelo centralizado de Subversion y el distribuido de Git, y cómo Git organiza por dentro sus objetos y sus cuatro zonas.
Qué resuelve un sistema de control de versiones
Un sistema de control de versiones registra cada cambio que se hace sobre un conjunto de ficheros y permite recuperar cualquier estado anterior. Sin él, un equipo acaba con carpetas llamadas «version_final», «version_final_2» y «version_final_buena», y con la certeza de que alguien va a sobrescribir el trabajo de otro.
- Historia: quién cambió cada línea, cuándo y con qué justificación.
- Vuelta atrás: recuperar el estado exacto que tenía el proyecto en cualquier momento pasado.
- Trabajo en paralelo: varias personas tocando el mismo proyecto sin pisarse, con resolución de conflictos cuando coinciden.
- Ramas: líneas de desarrollo separadas para un correctivo urgente o para una funcionalidad larga, sin molestar al resto.
- Trazabilidad: enlazar cada cambio con la incidencia o el requisito que lo motivó.
No se versiona solo el código fuente. Todo lo que define el sistema se lleva igual: los guiones de base de datos, la documentación, los ficheros de configuración y los elementos de gestión de la configuración, como los playbooks de Ansible que describen cómo se despliega la aplicación.
El control de versiones es la implementación práctica de la gestión de la configuración, que es una de las cuatro interfaces transversales de Métrica 3. Son la misma idea vista desde la metodología y desde la herramienta.
Para el examen
Qué implementa el control de versiones: la gestión de la configuración
Dónde encaja en Métrica 3: es una de las cuatro interfaces transversales
Centralizado frente a distribuido
En un sistema centralizado hay un único repositorio, que vive en un servidor. El desarrollador tiene en su equipo una copia de trabajo, pero no la historia: para consultar versiones antiguas, crear una rama o confirmar un cambio necesita estar conectado al servidor. Se trabaja en línea.
En un sistema distribuido cada desarrollador tiene un repositorio local completo, con toda la historia del proyecto. Casi todo se puede hacer sin salir de esa máquina y sin red: confirmar cambios, consultar el histórico, crear ramas y fusionarlas. Solo hace falta conexión para sincronizarse con los demás, subiendo y bajando cambios de un repositorio que se toma por convenio como el central.
| Aspecto | Centralizado | Distribuido |
|---|---|---|
| Dónde está la historia | Solo en el servidor | Completa en cada copia local |
| Conexión necesaria | Para casi cualquier operación | Solo para sincronizar con otros repositorios |
| Si el servidor cae | El equipo se queda parado y la historia está en riesgo | Se sigue trabajando; cualquier copia local sirve para restaurar |
| Coste de crear una rama | Alto, se usan con cuentagotas | Muy bajo, se crean para cualquier cosa |
| Ejemplos | CVS, Subversion (SVN), TFS y Visual SourceSafe | Git, Mercurial, Bazaar, Darcs y BitKeeper |
El rasgo que define el modelo distribuido no es tener copia de los ficheros, que también la hay en el centralizado, sino tener la HISTORIA entera en local. De ahí sale todo lo demás: trabajar sin red, ramas baratas y ninguna máquina imprescindible.
Sobre los nombres: el cliente gráfico más conocido de Subversion es TortoiseSVN, y sus comandos empiezan por svn. Mercurial usa hg, que es el símbolo químico del mercurio, y Bazaar usa bzr. Conviene saber además que Visual SourceSafe está retirado desde hace años y que TFS pasó a llamarse Azure DevOps Server, aunque en los temarios sigan apareciendo con su nombre antiguo.
Para el examen
Qué define al distribuido: tener la HISTORIA entera en local, no solo los ficheros
Qué permite: trabajar sin red, ramas baratas y ninguna máquina imprescindible
Git: origen y características
Git lo creó Linus Torvalds, el mismo autor del núcleo de Linux, precisamente para gestionar el desarrollo de ese núcleo cuando el sistema que venían usando dejó de estar disponible gratuitamente. Hoy es, con mucha diferencia, el sistema de control de versiones más extendido.
- Distribuido: cada clon lleva la historia completa y opera de forma autónoma, sin depender de un servidor.
- Ramas baratas: crear, cambiar y fusionar ramas es una operación rápida, así que el modelo de trabajo se apoya en ellas constantemente.
- Integridad por criptografía: cada objeto se identifica por el hash SHA-1 de su contenido, de modo que cualquier alteración cambia el identificador y se detecta.
- Varios protocolos de transporte: HTTP y HTTPS, SSH, el protocolo local sobre el sistema de ficheros y el protocolo propio de Git, que usa el puerto 9418.
El identificador de un commit no es un número correlativo: es el resumen criptográfico de su contenido. Por eso no se puede cambiar un commit antiguo sin que cambien también todos los que vienen detrás.
Matiz técnico para no dar por buena una simplificación frecuente: el hash no se calcula solo sobre el commit, sino sobre cada objeto que Git almacena. Y por las debilidades conocidas de SHA-1, las versiones modernas de Git admiten también SHA-256, aunque el uso mayoritario siga siendo SHA-1.
Para el examen
Identificador de un commit: el resumen criptográfico de su contenido
Lo que NO es: correlativo
Consecuencia: alterar un commit antiguo cambia todos los posteriores
El modelo de objetos de Git
Por dentro, Git no guarda «cambios» sino objetos, y solo maneja cuatro tipos. Entender esos cuatro es lo que hace que después todos los comandos tengan sentido.
| Objeto | Qué representa |
|---|---|
| Blob | El contenido de un fichero, sin su nombre |
| Tree (árbol) | Un directorio: la lista de nombres que hay dentro, apuntando a blobs y a otros trees |
| Commit | Una fotografía completa del proyecto en un instante, con su autor, su fecha, su mensaje y un enlace al commit anterior |
| Tag (etiqueta) | Un nombre estable para un commit concreto, típicamente para marcar una versión publicada |
Al hacer un commit se está guardando un árbol raíz, que a su vez contiene otros árboles para los subdirectorios y blobs para los ficheros. Como cada commit apunta al anterior, la historia del proyecto es una cadena que se puede recorrer hacia atrás hasta el primer commit.
Un commit no guarda «lo que cambió», guarda el estado completo del proyecto en ese momento. Lo que Git hace es reutilizar los objetos que no han cambiado, y de ahí que sea eficiente pese a guardarlo todo.
Para el examen
Qué guarda un commit: el estado completo del proyecto
Lo que NO guarda: solo lo que cambió
Por qué es eficiente: reutiliza los objetos que no han cambiado
Las cuatro zonas de trabajo
Un cambio en Git recorre cuatro zonas antes de llegar a los demás, y esa es la fuente de confusión más común para quien viene de un sistema centralizado, donde solo hay dos. Ver estas cuatro zonas claras es lo que hace que los comandos dejen de parecer arbitrarios.
| Zona | Qué contiene | Cómo se llega desde la anterior |
|---|---|---|
| Directorio de trabajo | Los ficheros tal como están ahora mismo en el disco, con los cambios sin guardar | Editando ficheros |
| Área de preparación (staging area o index) | La selección de cambios que van a formar parte del próximo commit | git add |
| Repositorio local | La historia completa de commits de tu máquina | git commit |
| Repositorio remoto | La historia compartida con el resto del equipo | git push |
El camino de vuelta también tiene sus comandos: git pull trae al equipo lo que hayan subido los demás, git checkout lleva al directorio de trabajo el contenido de una rama o de un commit del repositorio local, y git merge incorpora al directorio de trabajo el contenido de otra rama.
El área de preparación es lo que distingue a Git de casi todos sus predecesores: permite decidir qué parte de lo que has tocado entra en el commit y qué parte se queda esperando, de modo que un commit pueda contar una sola cosa aunque hayas hecho tres.
Al repositorio remoto se le llama por convenio origin, y a su rama principal origin/main. Es un nombre por defecto, no una palabra reservada: se puede tener varios remotos con nombres distintos y subir a todos ellos.
Para el examen
Las cuatro zonas: directorio de trabajo, área de preparación, repositorio local y repositorio remoto
origin: nombre por convenio del remoto; no es palabra reservada