Esto es git [episodio 1]: conceptos básicos parte 2

20 de junio de 2016
7 min. de lectura

En el capítulo anterior tocamos la primera parte de los conceptos básicos de git. Vimos cómo crear un repositorio local y cómo crear nuestro primer commit del proyecto. Hoy vamos a continuar con la segunda parte de conceptos básicos.


Tomaremos como ejemplo el proyecto que teníamos en la entrada anterior. Solo que ahora vamos a suponer que el proyecto ha pasado por varios commits y que ha tenido algunos cambios. En este momento nuestro proyecto posee la estructura contemplada la siguiente estructura:

Como vemos en la estructura, tenemos una carpeta css que posee dos archivos, y por fuera tenemos uno nuevo, index.html. Bien, vamos a crear dos archivos nuevos, uno llamado no-track.html y otro con el título si-track.html, de tal manera que nuestro proyecto se vea de la siguiente forma. 

.gitignore 

Ahora vamos a plantear un caso particular en el que solo nos interesa mantener el tracking de versionamiento o trazabilidad de un solo archivo de los que creamos a lo largo del desarrollo; al otro no le haremos tracking. Lo primero que vamos a usar es nuestro comando preferido: git status.

En nuestra terminal de comandos, Git nos dirá que tenemos dos archivos Untracked, los cuales son nuevos y nunca les hemos hecho versionamiento antes (no-track.html y si-track.html). 

Para el archivo que queremos versionar, ejecutamos el comando add, pero ahora de manera específica sobre él. git add si-track.html. Luego vamos a ejecutar nuestro comando preferido: git status

Acá podremos ver ahora que la terminal de comandos nos dice: “Changes to be committed”, seguido por la línea “new file: si track.html”. Esto quiere decir que este archivo ya se encuentra en el Staging area, listo para formar parte del repositorio. 

Después, le diremos a Git que no queremos versionar el archivo restante. Para hacer esto, debemos configurar un archivo nuevo que vamos a conocer hoy, es el archivo.gitignore. Este archivo debe ser creado por nosotros en la raíz del proyecto, es decir, al mismo nivel en el que se encuentra nuestra carpeta .git.

El archivo .gitignore va a contener todas las rutas que nosotros no queremos versionar. Podemos incluso colocar rutas de una carpeta completa, y de esa manera no versionaríamos nada que esté dentro de ella. 

Por ahora ignoraremos el archivo no-track.html; incluimos su nombre tal cual en el .gitignore, en una línea: 

.gitignore

1 Lines 

Así, volvemos a nuestra línea de comandos y vamos a ejecutar: git status. 

Como podemos observar, ha desaparecido el archivo no-track.html. De ahora en adelante Git no nos va a preguntar si queremos versionar dicho archivo. Estos escenarios se suelen dar cuando tenemos archivos en nuestro proyecto para personalizar nuestro entorno local. En esos casos no es necesario que un archivo así llegue hasta el repositorio principal. 

Por otro lado, Git nos ha dicho que tenemos un nuevo archivo llamado .gitignore. Este sí será necesario versionarlo para nuestros futuros avances en caso de que decidamos ir añadiendo nuevas rutas. 

A partir de ahora haremos un add al archivo faltante git add .gitignore y posteriormente un commit, como ustedes en este momento ya lo saben realizar. git commit -m "Aprendiendo del archivo gitignore xD". 

Checkout

Nuestro proyecto ha sufrido otro cambio: hemos creado un archivo principal llamado app.js

Ahora bien, digamos que tenemos la necesidad de seguir desarrollando dentro de ese mismo archivo para otras funcionalidades. Resulta que las creamos, pero el archivo ya no funciona como antes: tenemos múltiples errores y no sabemos cómo resolverlos. Nuestra necesidad más básica ahora es volver a la versión del archivo que teníamos antes, y así empezar nuevamente la construcción de las funcionalidades. 

Para realizar dicha tarea, vamos a conocer un comando muy útil en Git: checkout. En la medida que vamos desarrollando la serie, veremos muchas utilidades que posee el comando checkout. No obstante, en este caso lo vamos a utilizar para revertir cambios ocurridos en un archivo en particular. 

Primero, vamos a ver cómo está nuestro repositorio, así que ejecutaremos ungit status. Ahí encontramos que nuestro archivo app.js ha sufrido cambios, pero nosotros queremos revertir al punto en que estaba el archivo antes de realizar esos cambios. En pocas palabras, llevarlo a la versión en la que se encontraba el archivo en el último commit. Para tal fin, vamos a ejecutar el siguiente comando: 

Con las líneas -- le estamos diciendo a Git que revierta la siguiente ruta al estado en que se encontraba el archivo en el último commit realizado. Luego de haber ejecutado ese comando, si revisamos nuestro archivo, deberíamos verlo como estaba antes de realizar los cambios. 

Git nos ofrece herramientas para corregir errores en caso de haber realizado un mal desarrollo. Asimismo, podemos ver también que es muy eficaz realizar commits granulados o atómicos. Esto quiere decir que al momento de desarrollar no deberíamos realizar commit a funcionalidades incompletas, solo a métodos que realmente funcionen y no comprometan la integridad del desarrollo, de tal forma que, si en algún momento queremos revertir cambios usando checkout, no perdamos una cantidad muy grande de desarrollo. 

Este último ítem está muy relacionado con la filosofía de tener un buen flujo y una metodología de trabajo, que explicaremos más adelante. 

Stash 

Supongamos por un momento que hemos desarrollado algunas líneas nuevas en nuestro archivo app.js y que realmente la funcionalidad está correcta: se encuentra bien desarrollado, solo que sentimos que pudimos haberlo hecho mejor y quisiéramos hacer un refactor de este desarrollo. 

Acá tenemos dos opciones: podemos realizar un commit, hacer el refactor y, en caso de que quede mal, revertir los cambios como lo hicimos en el paso anterior, o hacerlo con el comando stash. En este caso vamos a elegir la segunda para conocer de qué se trata. 

Bien, decíamos que tenemos el desarrollo ya realizado sobre el archivo y que, si realizáramos un git status, la terminal de comandos nos diría que el archivo ha sido modificado de la siguiente forma: modified: app.js. 

Para hacer el refactor, necesitamos llevarlo al sitio en que se encontraba antes de los cambios y luego empezar a desarrollar. Solo que, si hiciéramos un checkout, se perdería totalmente el desarrollo realizado. Por eso, es mejor ejecutar los siguientes comandos: 

Como podemos ver luego de tener el estado, Git nos dice que no tenemos cambios en nuestro “working directory” y que se encuentra limpio (working directory clean). Por un momento podríamos asustarnos y pensar que hemos perdido el desarrollo, pero nada de eso. 

Con el comando stash le hemos pedido a Git que guarde temporalmente todos los archivos que teníamos en ese momento modificados en el “working directory” y que nos deje todo como estaba en el último commit que habíamos realizado.

De hecho, si quisiéramos ver dónde Git guardó estos cambios, podríamos verlos con facilidad ejecutando el siguiente comando.git stash list. 

Git nos muestra en una lista la cantidad de stash que tengamos guardados. Ahora imaginemos que estamos preparados para realizar nuestros nuevos ajustes y ver si lo hicimos de una mejor manera; sin embargo, al finalizar el desarrollo vemos que no. No hemos podido optimizarlo y queremos traernos del stash los cambios que teníamos antes para quedarnos definitivamente con ese código. 

En ese punto debemos hacer dos cosas: devolver los cambios de nuestro archivo actual, es decir, ejecutar un checkout para dejar nuestro “working directory” limpio (como lo explicamos en el punto anterior) y a continuación ejecutar el siguiente comando: git stash apply 

Lo que hemos hecho es traer los cambios que teníamos guardados en el stash y volverlos agregar al working directory. Ya de aquí en adelante podríamos realizar el add y commit, como lo sabemos realizar. 

Podemos tener un listado de cambios guardados de manera temporal en el stash y traer solo los que nos importen. Al ejecutar anteriormente el comando git stash list vimos que en el listado solo se encontraba almacenado un ítem de cambios, pero bien podríamos haber tenido muchos más. 

De ese listado podríamos traer solo el ítem de cambios que queramos. Para hacer eso debemos considerar el índice del ítem del listado que queremos traer. En este ejemplo pudimos haber ejecutado el siguiente comando en sustitución del apply anterior: git stash apply --0 y sería exactamente lo mismo, ya que en ese momento en el listado solo se encontraba un ítem. Cuando hay más items en el listado, ejecutar apply sin índice nos traerá el último que se almacenó. 

Si quisiéramos limpiar el listado del stash, lo podríamos hacer con el siguiente comando:

git stash clear. 

De esa forma el stash quedaría limpio. Debemos tener en cuenta que perderíamos todos los cambios almacenados en ese listado temporal. 

Tag 

Cuando estamos desarrollando una aplicación o cualquier otro desarrollo, nos vemos en la necesidad de crear versiones estables con las que podamos salir a producción, mientras estamos desarrollando la siguiente versión en otro ambiente. 

Git nos ofrece la posibilidad de colocar una etiqueta, o tag, en un commit específico en el que nosotros sabemos que nuestras funcionalidades son deseadas, correctas y listas para establecer una versión. 

Digamos que en el proyecto que venimos desarrollando estamos satisfechos con su estado actual. Todo funciona correctamente y esta sería nuestra versión 1.0 para salir a producción. Entonces necesitamos identificar el commit de una manera más inmediata. Vamos usar el comando tag. Por tanto, al momento de crear nuestro tag debemos ejecutar la siguiente línea de comando:

Así, hemos etiquetado el commit en que nos encontrábamos en ese momento con el tag que hicimos. Para verificar nuestro listado de tags creados podemos usar el siguiente comando: git tag

En el listado podemos ver el nombre que le hemos designado. Si quisiéramos ver el detalle de un tag en específico, ejecutaríamos el siguiente comando: git show v1.0

Con ese comando podemos ver todos los datos resultantes de la etiqueta creada, así como observar el nombre, quién, cuándo y en qué commit la creó. 

Ahora bien, supongamos que he creado un tag de manera equivocada, bien sea en el nombre o el mensaje que le dimos, o porque simplemente no era el commit para realizarlo. En esa eventualidad podemos eliminar la etiqueta con el comando: 

git tag -d v1.0

De tal manera que al volver a listar los tags no lo veremos. Usar tags es muy importante porque nos dará más orden a nuestro control de versiones o si en algún momento queremos ir a un tag en específico para realizar mejoras a una versión que se encuentra en producción o algo parecido. 

Esto ha sido todo por esta ocasión. Hemos abarcado muchos conceptos básicos hasta ahora; sin embargo, lo mejor está por venir. En la próxima entrada estaremos explicando la filosofía en repositorios distribuidos e iniciar el control de flujos. Seguramente vendrán muchos conceptos nuevos que aprender. Nos vemos en un próximo post.

Te puede interesar

Otros artículos de Desarrollo de software

Suscríbete