¿Qué es Git y para qué se utiliza?

Cómo funcionan los sistemas de control de versiones
En esta guía se hablará sobre los conceptos básicos de Git. Aprenderás para qué se utiliza el control de versiones y cómo funcionan los sistemas de control de versiones. Esta información te permitirá dominar el trabajo práctico con Git.
Tareas que resuelve el control de versiones
Independientemente del lenguaje de programación o del área de desarrollo elegida, el código que escribe un programador es simplemente texto, almacenado en varios archivos en el disco. Estos archivos se agregan, eliminan y modifican regularmente. Algunos de ellos pueden contener cientos de líneas de código, mientras que otros pueden contener miles. Archivos con miles de líneas de código son algo normal en la programación.

Mientras el proyecto consista en solo un par de archivos, su desarrollo no presenta dificultades. El programador escribe código, lo ejecuta y disfruta de la vida. El cliente está satisfecho y el programador también. A medida que la base de código crece, surgen ciertas molestias que luego se convierten en problemas reales:
  • ¿Cómo evitar perder archivos de código fuente?
  • ¿Cómo protegerse contra cambios y eliminaciones accidentales?
  • ¿Cómo deshacer cambios si resultan ser incorrectos?
  • ¿Cómo mantener simultáneamente una versión de trabajo y desarrollar una nueva?
Imagina que tu proyecto consta de cientos de archivos y decenas de miles de líneas de código. Realizas una tarea, modificas 15 archivos y 300 líneas de código en el proceso, y de repente te das cuenta de que esa tarea ya no es relevante. En este punto, necesitas volver al estado del código fuente que estaba antes de los cambios. Y esto es solo uno de los muchos escenarios posibles. Otro escenario es que, mientras trabajas en el código, te das cuenta de que necesitas hacer una corrección urgente en el proyecto de producción (sitio web). No se puede implementar una nueva tarea en un estado no funcional, lo que significa que la corrección debe hacerse en la versión del código que existía antes de comenzar a trabajar en la nueva tarea.

La forma más sencilla de resolver los problemas mencionados anteriormente es copiar directorios. Desafortunadamente, este enfoque solo tiene desventajas. Transferir cambios de un directorio a otro solo es posible mediante una sobrescritura completa, ya que no se pueden rastrear cambios puntuales (solo en la memoria). Tan pronto como haya dos carpetas, comenzarás a confundirte entre ellas. Y de todos modos, este método no ayudará a dos personas a trabajar en el código al mismo tiempo.

La colaboración en el desarrollo es otro dolor de cabeza. Si dos programadores trabajan en tareas que requieren cambios en el mismo archivo, ¿cómo pueden realizar este trabajo sin dañar o sobrescribir los cambios del otro desarrollador?

Afortunadamente, este problema se resolvió en la década de 1980. Desde entonces, las herramientas han evolucionado mucho y se utilizan ampliamente no solo para el código, sino también, por ejemplo, para escribir y traducir libros. La solución es el control de versiones, que se realiza mediante programas especiales que pueden rastrear los cambios en el código. Aquí hay algunas de las muchas características de estos sistemas:
  • Volver a cualquier versión anterior del código.
  • Ver el historial de cambios.
  • Colaborar sin temor a perder datos o sobrescribir el trabajo de otra persona.
En esta guía, analizaremos los principios generales de funcionamiento de estos programas.
Cómo funciona el control de versiones
Los sistemas de control de versiones (SCV o VCS, por sus siglas en inglés) a menudo están integrados en herramientas que resultan familiares incluso a personas alejadas de la programación. Comenzaremos nuestro conocimiento con estas herramientas y, al mismo tiempo, nos sumergiremos en la terminología correspondiente.

Los servicios de sincronización de archivos entre dispositivos, como Dropbox, son utilizados por casi todos. Y todos ellos rastrean las versiones de los archivos con los que trabajan. Esto es lo que sucede: periódicamente, el programa sincroniza los archivos locales con los que están en el almacenamiento del servicio. Si el archivo local es diferente y su tiempo de modificación es posterior al del archivo en el servidor, el archivo en el servidor se convierte en parte del historial de cambios y el archivo modificado más recientemente se convierte en el actual.
En la imagen de arriba, la versión actual del archivo se muestra como "current". Todo lo demás son versiones anteriores del archivo actual. Como se puede ver, Dropbox permite restaurar cualquier versión del archivo.

Ten en cuenta esta frase:

Dropbox keeps a snapshot every time you save a file. (Dropbox guarda una instantánea cada vez que guardas un archivo)

Instantánea (snapshot) es un concepto muy importante que encontraremos en el futuro. También se le llama instantánea de estado o instantánea (traducción literal), pero para simplificar, simplemente lo llamaremos "instantánea".

En este caso, una instantánea es el archivo en sí después de los cambios. Y para comprender mejor este término, veamos la alternativa: la diferencia de cambios (diff). Imagina que, en lugar de guardar una nueva versión del archivo, Dropbox calculara la diferencia entre el archivo nuevo y el antiguo (lo cual no es difícil de hacer para archivos de texto) y solo guardara esa diferencia. ¿Por qué hacer esto, preguntarás? Este enfoque permite ahorrar espacio en el disco, aunque agrega complejidad adicional al trabajar con archivos.

En el futuro, veremos que diferentes herramientas utilizan diferentes enfoques: algunas trabajan con diferencias de cambios, otras con instantáneas. Por cierto, el término "instantánea" a menudo se aplica a los discos. Por ejemplo, puedes tomar una instantánea del disco y luego restaurar desde ese punto (como en los juegos).

Otro buen ejemplo de uso del control de versiones son los editores de texto, especialmente los basados en la web.
El servicio de Google Docs crea automáticamente instantáneas después de cada guardado automático (aproximadamente cada 5 segundos). Si el documento no ha cambiado durante este tiempo, naturalmente no se crea una nueva versión. Un conjunto de estas versiones forma el historial de cambios.

En la imagen de arriba, el historial de versiones se llama "Revision history". Revisión es un concepto fundamental en los sistemas de control de versiones. Cualquier cambio registrado en el sistema de control de versiones se llama revisión.
Ten en cuenta que una revisión y una instantánea no son lo mismo. La fijación de cambios crea una revisión, pero la revisión en sí puede contener una diferencia de cambios o una instantánea.

Por cierto, el proceso de cambiar entre revisiones también tiene su propio nombre. Cuando cargamos una revisión específica, decimos que nos cambiamos a esa revisión (checkout).
Entre las revisiones, se pueden identificar diferencias en caso de que el SCV utilice instantáneas, como lo demuestra Microsoft Word en la imagen de arriba. Esta funcionalidad no se puede subestimar, ya que a menudo es necesario ver "qué ha cambiado" no solo al trabajar con código. Te daré un ejemplo de mi propia experiencia: la aprobación de diferentes documentos legales (contratos) se realiza a través de una serie de correcciones. Después de que los abogados hayan corregido el contrato, quieres ver qué ha cambiado.

Además, en los sistemas Linux hay un comando llamado diff, que se puede usar para determinar las diferencias entre cualquier par de archivos, incluso sin usar un SCV. Estos cambios se pueden guardar en un archivo y luego, utilizando el programa patch, aplicarlos al archivo original.

diff index.js index2.js > index.patch

1c1

< const a = 5;

---

> const a = 8;

3a4

> console.log(a - b);

patch index.js -i index.patch -o index2.js
En los programas mencionados anteriormente, la creación de una revisión está vinculada a la función de guardado automático, pero esta no es la única estrategia. En total, se utilizan tres métodos:
  • Guardar.
  • Guardado automático.
  • Con un botón (comando).
El último se utiliza cuando se trabaja con código.
Tipos de sistemas de control de versiones
En todos los ejemplos anteriores, hemos considerado SCV integrados directamente en programas, especialmente en editores de texto. Y los SCV para código están separados de las herramientas de desarrollo utilizadas (aunque pueden estar integrados adicionalmente).

Esto se debe a que el código fuente es, en esencia, un conjunto de archivos de texto (y binarios). No se puede saber de antemano quién, cómo y dónde los editará. Además, la creación automática de revisiones se vuelve extremadamente incómoda.

Los SCV para código se llaman repositorios. En el trabajo, a menudo escucharás frases como "¿has hecho commit?" o "he hecho commit". Además, por lo general, en lugar de la palabra "revisión", se utiliza la palabra "commit". Y también lo haremos.

Al trabajar con código, es importante que los cambios dentro de un commit cumplan con ciertas reglas. Solo de esta manera se podrán aprovechar todas las ventajas del SCV. Estos requisitos incluyen:
  • Una buena descripción. Por lo general, comienza con un encabezado breve de una línea de no más de 50 caracteres, seguido de una línea en blanco y un texto explicativo más detallado, si es necesario. Ten en cuenta que es una buena práctica usar el modo imperativo en el encabezado: "Fix scrolling" (Arreglar desplazamiento), en lugar de "Fixed scrolling" (Desplazamiento arreglado) o "Fixes scrolling" (Arregla desplazamiento).
  • Atomicidad. Un commit debe resolver una tarea y, preferiblemente, hacerlo de principio a fin. Esto permitirá construir una historia del proyecto que sea fácil de leer y comprender. Y si es necesario, se puede revertir un cambio o moverlo a otra versión del programa fácilmente.
Además de estos requisitos básicos, hay muchas otras recomendaciones que forman parte del concepto de "buen commit".

Independientemente del SCV que utilices, el flujo de trabajo básico es el mismo. Se ve así:
  • 1
    Inicialización (creación) del repositorio.
  • 2
    Agregar nuevos archivos.
  • 3
    Commit.
  • 4
    Cualquier operación con archivos (agregar, eliminar o modificar).
  • 5
    Commit.
  • 6
    ...
Un repositorio es un conjunto de archivos y directorios que están bajo control de versiones.

Los SCV se dividen en generaciones, cada una de las cuales cambió significativamente los enfoques de trabajo.
Primera generación
RCS, SCCS
  • Trabajaban con cada archivo individualmente.
  • Solo trabajo local.
Segunda generación
CVS, SourceSafe, Subversion
  • Multifile.
  • Centralizados.
  • Requieren un servidor.
No se puede trabajar en estos sistemas sin acceso al servidor. No podrás hacer literalmente nada. No podrás ver el historial, hacer un commit, revertir a otra versión, todo esto se vuelve imposible sin acceso a la red.
Tercera generación
Git, Bazaar, Mercurial
  • Distribuidos.
  • Cada participante tiene su propio repositorio local completo.
Si se utiliza un servidor, solo se utiliza para almacenar el repositorio de referencia. En realidad, todas las copias del repositorio son iguales y pueden intercambiar información en cualquier dirección.
Conclusión
Has aprendido para qué se utiliza Git y los principios de funcionamiento de los sistemas de control de versiones. Esta información te ayudará a dominar el trabajo práctico con Git en el desarrollo de tu aprendizaje. Si tienes alguna pregunta, déjala en los comentarios.
Enlaces adicionales
Leer otros artículos de Guías
Lea otros artículos relevantes del mundo de la tecnología y el espíritu empresarial.