GIT para vaqueros solitarios: primeros pasos

Durante los últimos meses, he tenido este blog completamente abandonado. Actualmente, estoy involucrado en un nuevo proyecto que me absorbe completamente. Además, me ha supuesto orientarme hacia una serie de herramientas y tecnologías que había dejado en un segundo plano (y otras que no conocía). La verdad, es que estoy disfrutando mucho con ellas y se me ocurren muchas ideas para futuras entradas.

De momento, me gustaría dedicarle esta entrada a una herramienta con la que he disfrutado especialmente: la herramienta para gestión de versiones GIT.

Desde que comencé a desarrollar (hace ya unos cuantos años), siempre me he apoyado en alguna herramienta de gestión de versiones: Microsoft SourceSafe, CS-RCS y, en mis últimos años, Subversion:

  • Cuando trabajaba en solitario, me servía para «protegerme» de mí mismo, como paracaídas ante errores imprevistos.
  • Cuando trajaba en equipo, como herramienta para coordinar las distintas tareas en curso y poder revisar el código antes de pasarlo a producción.
  • Y, siempre, como medio para llevar un histórico de todo lo que ocurría durante la vida del desarrollo (a veces, con años de extensión).

En mi último proyecto, tuve que asumir el mantenimiento de un desarrollo extenso y complejo en PHP. Sin ninguna documentación ni gestión de versiones. Hablé con mi jefe, y decidimos darle una oportunidad a GIT. Inicialmente, por mi experiencia previa, esperaba un aprendizaje rápido… nada más lejos de la realidad. Sin embargo, os aseguro que el esfuerzo invertido ha merecido la pena con creces.

¿A qué se debe ese esfuerzo de entrada tan grande? En mi opinión, porque trabajar con GIT supone un cambio en el modo de trabajo. Si tuviera que hacer una analogía, diría que trabajar con Subversion es como tocar música clásica (todo ordenado, con partituras, ritmo, un director de orquesta marcando los tempos…) pero trabajar con GIT es como interpretar en una banda de Jazz (sin partituras, cada músico a su bola … pero todo suena de maravilla).

GIT es muy extenso, con muchas tareas y herramientas para gestionar nuestro código y mucha flexibilidad para usarlas. Para mí, al comienzo, fue abrumador. Pero el esfuerzo merece la pena, incluso trabajando en solitario. Por eso, en estas entradas, voy a intentar concentrarme en aquellas tareas que creo que pueden ayudar a resolver los problemas a los que se enfrenta un desarrollador independiente (el «vaquero solitario» del título).

Si alguien encuentra esta entrada y se decide a leerla, le sugiero humildemente que la lea tres veces:

  • En la primera lectura, se trata de comprobar si se identifica (o no) con los escenarios que le describo. La clave es pensar «Esto, me ocurre a mí. Ojalá tuviera una herramienta que me ayudara con estos problemas».
  • En la segunda lectura, se trata de leer las instrucciones GIT correspondientes a cada escenario. Sólo debe familiarizarse con ellas. Se trata de pensar «Estas instrucciones, parecen razonables, coherentes, fáciles de entender en ese contexto».
  • Por último, si ha decidido llegar hasta aquí, le sugiero que repita las instrucciones en su propio entorno de trabajo. Se trata de asimilarlas para convertirlas en parte de su propio conjunto de herramientas.

Sólo dos observaciones:

  • Para que no sea demasiado extensa en esta entrada, no explico cómo instalar GIT. Aunque estoy seguro que no tendréis problemas en encontrar buenos titulares al respecto).
  • En los ejemplos, me concentro en usar GIT dentro de la consola línux (concretamente, uso Ubuntu).

Bueno, basta de literatura y vamos por fin a jugar con GIT.

Someter un proyecto nuevo (o un proyecto existente) a GIT

Imaginemos que tenemos un proyecto entre manos: nos han pedido que hagamos un listado de obras por autor. Para ello:

  • Vamos a crear una carpeta proyecto_autores que va a contenter todos nuestros ficheros.
  • Dentro de esta carpeta, vamos a crear un fichero por autor.
  • En cada fichero, introduciremos una obra por línea.

Vamos a inicializar GIT en este proyecto. Para ello, ejecutamos git init en la carpeta raíz del proyecto:

Con la instrucción git init . le estamos pidiendo a GIT «supervisa el contenido de la carpeta xxx» (hay que pasarle como argumento la carpeta donde está la raíz de nuestro proyecto, en este caso la carpeta donde ejecutamos el comando). Cuando ejecutamos esta instrucción, GIT creará una subcarpeta .git donde guardará toda la información que necesita.

Ya está, nada más. Ni configurar servidores centrales ni instalar servicios adicionales en nuestro servidor. Con esta simple instrucción, ya tenemos supervisada por GIT nuestra carpeta proyecto_autores y absolutamente todo su contenido (aunque también podemos personalizar esto).

Vamos a pedirle a GIT que nos indique el estado de nuestro proyecto:

De momento, vamos a fijarnos en la siguiente información:

  • Initial commit quiere decir «estamos en la primera versión».
  • Untracked files nos lista nuestros dos ficheros. Lo que GIT nos está diciendo es «estos ficheros, no sé qué hacer con ellos».

Pedirle a GIT que incluya ficheros en el proyecto

¿Por qué nos dice que nuestros dos ficheros están Untracked? Porque en nuestro recién inicializado GIT, por defecto, está absolutamente limpio. No incluye absolutamente nada. Cualquier fichero que incluyamos, GIT lo considerará untracked hasta que nosotros le digamos qué debe hacer con ellos.

Vamos a indicarle a GIT que nuestros dos ficheros pertenecen a nuestro proyecto y que a partir de ahora debe supervisarlos:

Con la instrucción git add le pedimos a GIT «marca al fichero xxxx para seguirlo».

Una vez añadidos estos dos ficheros, hemos vuelto a pedirle el status a GIT. Ahora, nos dice que los dos ficheros están catalogados como "Changes to be committed" y han pasado de estado Untracked a estado new file.

¿Qué nos quiere decir esto? Para comprenderlo, debemos comprender el modo de trabajo básico con GIT:

  • Paso 1: modificamos nuestro proyecto (añadiendo ficheros, borrando ficheros, modificando ficheros,…).
  • Paso 2: le pedimos a GIT que marque los ficheros modificados y añadidos para el próximo commit (esto es lo que acabamos de hacer).
  • Paso 3: cuando estemos conformes con los cambios realizados, le pedimos a GIT que realice un commit de los cambios marcados en el paso anterior.

Hay terminología de GIT como commit que prefiero no traducir, prefiero usar la palabra inglesa original para no perder sentido. Pero ¿qué es un commit? Un commit es la unidad de trabajo de GIT: un conjunto de cambios que han sido enviados en una sola tanda por el programador a GIT. GIT ve el proyecto como una serie de sucesivos commits. Para GIT, lo importante son los commits: qué ficheros se incluyeron en el commit y qué cambios han provocado este commit al proyecto. Esto es muy importante para comprender GIT, aunque su importancia real no la comprenderemos hasta más adelante.

En otras palabras:

  • Primero, modificamos una serie de ficheros.
  • Segundo, cuando estamos conforme con los cambios, los marcamos para el próximo commit
  • Tercero, les damos el visto bueno realizando un commit con ellos.

En este ejemplo concreto:

  1. Hemos añadido dos ficheros al proyecto. git status nos ha avisado «tienes ficheros nuevos untracked».
  2. Con git add los hemos marcado para que que los incluya en el próximo commit. git status nos avisa ahora que «tienes ficheros marcados para el próximo commit».

Y, por último, como todo está correcto, realizamos git commit:

Una vez realizado el commit, le pedimos un git status y GIT nos responde nothing to commit (o sea, «sin novedad en el frente, lo tengo todo controlado»).

Ahora, vamos a seguir modificando ficheros

Vamos a añadir dos nuevos títulos a la lista de Pérez Reverte:

Cuando he añadido el segundo título, me he equivocado (a propósito) con el nombre del fichero destino. Cuando he pedido git status GIT me responde:

  • arturo_perez_reverte.txt está en estado modified.
  • arturo_perez.txt está untracked y en estado new.
  • También nos avisa que ambos ficheros están not staged for commit (o sea, que aunque están modificados todavía no los hemos marcado para ejecutar el commit con ellos).

En cuanto he visto el status me he dado cuenta que he metido la pata, así que lo voy a arreglar:

Ya tengo la tarea controlada: he borrado el fichero incorrecto y mi fichero de Pérez Reverte está correctamente modificado.

Ahora, como todavía es temprano y me siento con energías, voy a trabajar un poquito más:

Efectivamente, he trabajado un montón:

  • He añadido libros nuevos a las listas de Reverte y Orwell.
  • He comenzado con un nuevo autor, Jack London.

Pero GIT me avisa que no sabe qué hacer con el nuevo fichero jack_london.txt. Así que voy a pedirle a GIT que lo incluya en el próximo commit:

Ahora, me dice que «jack_london.txt» está marcado para el próximo commit (changes to be commited) y en estado new file.

Pero GIT también me avisa que arturo_perez_reverte.txt y george_orwell.txt están modified pero todavía no están marcados para commit (Changes not staged for commit). Efectivamente, debemos recordar lo que he explicado antes: primero, modificamos; segundo marcamos para el próximo commit; tercero, ejecutamos el commit. Vamos a marcarlos para el commit:

Ya tengo preparado mi commit, formado por los dos ficheros modificados y un fichero nuevo. Vamos a realizar el commit:

Después de realizar el commit, vuelvo a pedir un git status y ahora me responde de nuevo «sin novedad en el frente»

Modifica, marca y confirma; modifica, marca y confirma … modifica, marca y confirma

Esta es la pauta de trabajo con GIT:

  1. Modificar ficheros que necesites.
  2. Cuando consideres oportuno, marca los ficheros para commit.
  3. Por último, confirmas las modificaciones ejecutando un git commit con los ficheros marcados.

La clave es ¿cuándo es oportuno realizar un commit? ¿qué ficheros incluir en un commit?. Esta es una de las flexibilidades de GIT:

  • Puedes modificar los ficheros que quieras, pero puedes marcar para commit sólo los que creas necesario (por ejemplo, puedes marcar para el commit algunos ficheros porque los has estabilizado y dejar el resto de los ficheros modificandos pendientes para un commit posterior).
  • Puedes realizar los commits que quieras.

Personalmente, opino que cuantos más commits realices, mejor:

  • Procuro agrupar modificaciones de forma que un commit agrupa una serie de modificaciones relacionadas entre sí.
  • Le presto mucha atención a los comentarios que añado al commit, porque me dan mucha información histórica del proyecto.
  • Si voy a comenzar a modificar el código y no estoy seguro de lo que voy a hacer… realizo un commit para marcar el punto de inicio de esas modificaciones (efectivamente, ya veremos que puedo volver para atrás y restablecer el código al commit que quiera).

Antes de terminar esta entrada, vamos a ver un último comando:

Efectivamente, con git log le he pedido a GIT que me muestre un listado de los commits realizados. Si los comentarios que yo he proporcionado al ejecutar los commits hubieran sido más descriptivos (por ejemplo: «nuevo autor Jack London» o «Más libros para Pérez Reverte») los mensajes del log hubieran sido mucho más interesante para estudiar la vida de mi proyecto.

¿Conclusiones?

  • Ya hemos iniciado un proyecto supervisado por GIT.
  • Hemos hecho prácticas de la rutina de trabajo con GIT: modificar, marcar y confirmar:
    • Le hemos pedido a GIT que añadida ficheros al proyecto y hemos modificado ficheros.
    • Le hemos dado nuestro visto bueno a las modificaciones marcándolas para commit.
    • Hemos realizado el commit para confirmar nuestros cambios.
  • Por último, le hemos pedido a GIT que nos liste los commits que hemos realizado.

De momento, vamos a dejarlo aquí. No hemos hecho algo especialmente útil. Pero en una próxima entrada seguiremos trabajando en nuestro proyecto. Cometeremos algunos errores y tendremos que solucionar algunos imprevistos y entonces veremos lo realmente útil que puede ser GIT. Espero que esta entrada os haya gustado y que os animéis a leer las próximas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*
*
Sitio Web