Sabemos que Git nos ofrece un sistema de ramas o branchs, que al igual que otras herramientas de control de versiones, soporta la administración de ramificaciones en los proyectos.
Sin ánimo de ahondar demasiado, digamos que la diferencia básica que Git aporta, es que en vez de crear un directorio adicional para guardar una nueva rama, lo hace de forma inmediata sin crear nuevos directorios, almacenando solo copias instantáneas, de como está el archivo en ese momento, junto a los nodos padres, lo cual también es una gran ventaja, al momento de gestionar la fusión entre las ramas con que contamos.
¿Que son las ramas?
Podríamos decir, si queremos ser muy escuetos que: una rama en Git es solo un apuntador en movimiento que redirige a su respectivo commit.
Lo explico así: al iniciar un proyecto y hacer tu primer commit, estas creando una rama principal de trabajo, también llamada master
.
A medida que creas tu código, y vas avanzando buscando una solución, tal vez necesites caminos alternativos, que te lleven a determinado punto y hasta tanto no lo alcances, no querrás incorporarlo a lo que has hecho en tu rama principal, incluso pudiera ser que nunca alcances ese punto, y simplemente necesites regresar adonde estabas antes.
Esto es posible hacerlo creando ramas de trabajo, o sea cada vez que creas una alternativa, podemos decir que estás trabajando en una rama, si a eso unimos, que sobre el propio proyecto, pueden estar trabajando diferentes integrantes de un equipo, tendremos varias ramificaciones, y al mismo tiempo si cada uno de ellos quiere probar nuevas rutas para buscar un resultado esperado, entonces crearán nuevas ramas, en un mismo árbol de proyecto.
Lo que hace a Git superior a otros, es el modo rápido y eficaz en que maneja las ramificaciones, haciendo el avance o el retroceso entre distintas ramas, algo ágil , cómodo y sencillo, lo cual facilita que durante el desarrollo, las ramas puedan crearse y unirse entre si, tantas veces como necesitemos.
Es fácil entender entonces, que este enorme potencial es de gran ayuda, para agilizar y fortalecer el modo en que creamos código.
El valor del Commit
Al escribir git add .
estas indicando a git que pase tus archivos a la zona conocida como stage, pero lo que sucede realmente es que se ejecuta una suma de control de ellos, en 40 caracteres (un resumen SHA-1
), y se almacena un blob
(copia) de cada uno en el repositorio, guardando cada suma de control, en el área de preparación (staging area
):
Al crear una orden de confirmación commit
, estamos diciéndole a Git que aceptamos que los cambios añadidos previamente con el add
al área stage
, sean procesados, y lo que hará el sistema es crear y almacenar una impresión del código de ese momento, con un grupo de metadatos explicativos como los que recoge la opción –m
.
Nuestro commit
, también creará un apuntador hacia esta impresión instantánea (piensa en una foto de ese momento), que permitirá identificarla, retornarla, o unirla a otra; o los apuntadores podrían ser varios, si lo que hay detrás de nuestro commit
, es un merge
que une varias ramas.
Suponiendo que estuvieras trabajando con 5 subdirectorios, lo que sucederá al hacer commit
es que Git realizará sumas de cada uno, que guardará como objetos árbol en el repositorio Git y creará un objeto de confirmación con los metadatos y además un apuntador al objeto árbol de la raíz del proyecto.
Hecho esto, ahora habría 7 objetos en el repositorio de tu proyecto, los 5 blobs, un árbol que no es más que la lista estructurada de lo que contiene el repositorio, y la confirmación de los cambios que el commit procesó y que apunta directamente a la raíz del árbol.
Entonces, si decides hacer más cambios y confirmarlos, el siguiente commit también tendrá un apuntador que se dirige al commit previo, de esa manera queda encadenado a la versión anterior y así sucesivamente.
Por tanto, la rama se mantiene en movimiento avanzando en cada commit, ese desplazamiento comienza al crear la rama principal master
, con el primer commit
.
¿Cómo se crea una rama?
El comando utilizado para crear una rama es :
git branch nombre de la rama
Este comando lo que hará será crear un nuevo apuntador, disponible para que dirija al ultimo commit
que has realizado.
Para crear la rama nuevo_test, escribe:
$ git branch nuevo_test
El nuevo apuntador, dirigirá al commit
en el que estés.
Aunque pueda parecer complicado, no lo es.
En este punto, habrá dos ramas, cada una con su apuntador que refieren al mismo commit, sin embargo la magia está en que existe un apuntador llamado HEAD, con una labor especial que es la de apuntar a la rama local en la que te encuentres, en este caso master, pues aunque se creó la rama nuevo_test
, con el comando branch
, aun no se ha entrado a ella.
El comando que maneja los logs, y que debemos tener siempre a mano para saber cómo vamos, y entre otras cosas, la estructura de nuestro árbol de proyecto: git log
, en su opción --decorate
nos mostrará la estructura
Por ejemplo nos devolverá algo como esto
$ git log --oneline --decorate g40ac (HEAD, master, nuevo_test) add feature ……….
Donde g40ac
será el commit
al que apuntan ambas ramas.
Moviendose entre ramas
Para moverse de una rama a la otra el comando a usar es :
git checkout
y la sintaxis si queremos ir a la rama nuevo_test es :
$ git checkout nuevo_test
Ahora el apuntador se apuntará a la rama nuevo_test
Si hacemos ahora un commit
$ git commit -a -m 'primer cambio'
Y corremos nuevamente log --decorate
veremos que la rama nuevo_test
apunta al nuevo commit junto al apuntado HEAD.
Si queremos regresar a la rama master, utilizaremos igualmente checkout
, al hacerlo, se moverá nuevamente el apuntador HEAD a la rama master
, y restituirá los archivos dejándolos tal y como estaban en el último commit de esa rama principal.
Esto, no es otra cosa que rebobinar el proyecto, dando marcha atrás en el tiempo, por tanto los cambios que hagas en adelante, serán diferentes de la versión anterior del proyecto.
Otro aspecto importante de Git, es que si no es capaz de realizar este rebobinado de un modo limpio, o sea si no puede recuperar la impresión exacta del ultimo commit, no permitirá hacer el checkout.
En definitiva para moverte entre ramas los comando son tres, branch
que crea la rama, commit
que la confirma y checkout
que te permite saltar de una a otra
Por supuesto al saltar entre ramas, cada rama tendrá diferencias en tu labor, para ver las diferencias podemos usar el comando log de este modo:
git log --oneline --decorate --graph –all
Esto mostrará el historial de los commit, indicando dónde están los apuntadores de cada ramas y como ha variado el historial.
Si ahora analizamos lo que dijimos al inicio, sobre el modo en que se compone una rama, desde el punto de vista estructural, comprenderemos porque una rama Git es un simple archivo, con los 40 caracteres de una suma de control SHA-1, vinculado a un commit específico.
De ahí su simpleza, velocidad y eficiencia.
Y listo, esto es todo.
Espero modestamente que este artículo, sirva de ayuda a alguien.
Gracias.
….un sueño es casi todo y más que nada; más que todo al soñarlo, casi nada después……