Este artículo contiene dos partes, esta primera más teórica donde veremos distintos conceptos, y una segunda en la que nos centraremos en poner en práctica todo lo visto en esta parte.
GIT
GIT es un sistema de control de versiones distribuido, esto quiere decir, que en lugar de tener un único espacio para almacenar todo el historial de versiones, la copia del trabajo de cada desarrollador puede tener el historial completo de todos los cambios.
Es capaz de detectar los cambios que se realizan en el código desde la última versión que se guardó y mantener el historial de todos los cambios que han sido guardados.
Características principales:
- Rendimiento: utiliza algoritmos para la detección y seguimiento de los cambios y su arquitectura distribuida.
- Seguridad: está diseñado para asegurar la integridad del código fuente.
- Flexibilidad: permite la ejecución de distintos flujos de trabajo de forma simultánea. De esta manera, es útil para tanto proyectos grandes como pequeños, y para diversos sistemas y protocolos.
Las acciones en GIT se realizan con comandos desde la terminal, y aunque normalmente no los utilicemos, porque se trabaja de forma integrada en el IDE, es importante conocerlos, saber que existen por si se tuvieran que utilizan.
Por ejemplo:
- Commit: git commit -m «mensaje de confirmación»
- Add: git add <archivo>
Terminología
Repositorio:
Un repositorio en GIT es un almacén para el código fuente, los archivos necesarios para el proyecto y un registro de todos los cambios realizados en el repositorio. Tendremos tantos repositorios como proyectos en los que estemos trabajando o hayamos trabajado. De esta forma todos los proyectos estarán separados.
Los repositorios pueden ser locales o remotos. Esto deriva de que GIT sea un sistema de control de versiones distribuido. De esta forma, el mismo código puede estar en muchos sitios.
Se trabaja con ramas remotas y locales. Las ramas remotas están en el servidor, es donde se suben los proyectos de todos los colaboradores, y donde estarán todos los cambios definitivos. El desarrollador, cada vez que empieza con un nuevo proyecto, creará una copia de la remota en local para trabajar con ella.
La diferencia entre GIT y otros sistemas de control de versiones es la forma de manejar los datos. Normalmente, los sistemas de control de versiones guardan un listado de los cambios en cada archivo en cada versión. Sin embargo, GIT guarda copias instantáneas de los archivos en el momento que se confirman los cambios de una versión. De esta manera, permite garantizar la integridad de los datos.
GIT asegura todos los cambios que confirmamos con un Checksum, una suma de comprobación que se genera a partir del contenido de los archivos y hace que no se pueda modificar ningún archivo sin que GIT lo sepa y nos obligue a confirmar dicho cambio y documentarlo.
Add, Stage, Commit:
Estos son los diferentes estados por los que pasan nuestros archivos.
- Untracked: estado inicial de todos los archivos. Los objectos que creamos en nuestro repositorio local estarán sin seguimiento hasta que los añadamos al seguimiento de cambios de GIT.
- Unmodified: cuando un archivo que ya está añadido al repositorio y confirmado en algún momento anterior al actual y no se han realizado cambios sobre él desde la última versión.
- Modified: cuando un archivo ha sido modificado desde la última versión confirmada.
- Staged: cuando se añade un archivo modificado a la siguiente confirmación. Realmente, se añade a la lista de archivos que se van a confirmar cuando se realice la confirmación (commit)
Rollback:
¿Qué pasa si confirmamos algo que no debemos y todo empieza a fallar?
Tenemos dos opciones para deshacer
- – Revert: se crea una nueva confirmación deshaciendo el cambio que queremos, de esta forma se conserva el historial de cambios.
- – Reset: Reescribe el historial de confirmaciones deshaciendo los cambios que le indiquemos.
Si aún no hemos confirmado cambios, y queremos deshacer lo que estamos haciendo, tenemos la opción de checkout, que deja el objeto en el estado anterior a haber realizado nuestros cambios.
Branch, Merge:
Como se ha indicado, en GIT se trabaja con ramas.
La rama principal se llama Main (originalmente Master), y a partir de esta rama, se crean las ramas nuevas, que son las ramas en las que trabajamos, éste sería el concepto branch.
Una vez realizado nuestro trabajo, tendremos que realizar un merge para incluirlo en la rama principal.
Por otra parte, tenemos el concepto stash, utilizado para mantener los cambios en una rama mientras se trabaja en otra.
Fetch, Pull, Push, Pull Request:
En un equipo de desarrollo, es necesario contar con un lugar donde se almacene todo el código del proyecto. Normalmente, este almacenamiento se realiza de forma remota, es decir, en un servidor al que todos los colaboradores tienen acceso. En este servidor, se definen las ramas de trabajo, conocidas como ramas remotas.
Para trabajar en local con estas ramas remotas, utilizamos las ramas locales, que son copias de las ramas remotas almacenadas en los equipos de los desarrolladores.
Cuando copiamos una rama remota a nuestro entorno local (a través de un fetch), obtenemos la versión actual de esa rama en ese momento. Sin embargo, es posible que otros desarrolladores realicen cambios en la rama remota, los cuales no se sincronizan automáticamente con nuestras ramas locales. Para mantenernos actualizados, debemos traer los cambios desde la rama remota a nuestra rama local de forma periódica. Esto puede realizarse de dos maneras:
- Fetch: trae los cambios de la rama remota que aún no se tienen en la rama local, pero no los fusiona.
- Pull: trae los cambios de la rama remota que no están en la rama local y, posteriormente, los fusiona con la rama local.
Para enviar cambios desde una rama local a una remota, utilizamos el comando Push.
Para proteger el código que se añade a las ramas remotas, existen los Pull Requests. Estas son solicitudes de revisión de cambios que se generan cuando se intenta fusionar ramas remotas, lo cual ayuda a asegurar que no se añada cualquier código a ramas críticas, como Main, que suele contener el código que se despliega en producción. A cada solicitud se le asigna un revisor, que es otro colaborador del repositorio encargado de validar y aprobar los cambios propuestos antes de que se lleve a cabo la fusión.