Git básico para científicos

Pero, ¿qué es git?

Tienes razón, mejor empezamos por el principio.

Git es un sistema de control distribuido para poder hacer seguimiento de cambios en código fuente (y otras cosas). En palabras más mundanas, es un vigilante de las cosas que vamos haciendo (cambios de código, cambios de nombres de ficheros,…) en un carpeta de ficheros en un ordenador.

Git se ha convertido en un estándar de facto al haber sido adoptado por sitios como github o gitlab.

¿Qué significa que sea distribuido?

Significa que el repositorio completo de código, sus cambios, sus mensajes de nuevo código,…, se pueden encontrar en distintos ordenadores.

Normalmente, hay un repositorio central de código. Este repositorio central de código puede alojarse en sitios como github, gitlab o bitbucket y así puedes tener una interfaz web para recibir informes de errores, poder hacer revisiones de código, poder repartir tareas,…

¿Y para qué necesito yo git si me organizo muy bien?

Fuente: https://giphy.com/gifs/mess-nBjOqZ6h0ili0

El uso de git no es un capricho, es una necesidad, Algunas posibles razones para su uso:

  • A la larga ahorrarás tiempo.
  • Podrás rehacer y deshacer funcionalidad teniendo múltiples versiones de tus experimentos junto con seguimiento de lo que ha ido funcionando y lo que no.
  • Podrás trabajar en funcionalidad específica en paralelo y solo unir esa nueva funcionalidad si merece la pena.
  • Evitarás tener algún esperpento como lo de más abajo, es decir, tendrás una única versión que funciona bajo cierto entorno:
    • fichero_codigo.py
    • fichero_codigo_20120203-py
    • fichero_codigo_20120203_rev1.py
    • fichero_codigo_nuevo.py
  • Puedes trabajar de forma colaborativa con otros compañeros de tu laboratorio, empresa o de cualquier otra parte del mundo.
  • Cuando añades nuevo codigo puedes acompañarlo de mensajes útiles.
  • Otros pueden auditar tu código permitiendo que te puedan informar de errores.
  • Seguramente tengas una copia en caso de que te roben el PC, se te queme, le caiga agua encima,…
  • Puedes integrarlo con muchas otras herramientas para hacer pruebas, comprobar funcionamiento en distintos entornos,…
  • Otros pueden usar tu código encontrando nuevos usos en los que no habías caido o reproduciendo tus resultados (reproducibilidad).
  • Tienes formas de mantener tu código privado en caso de que lo necesites.
  • Tienes control absoluto de lo que quieres integrar y de lo que no en tu proyecto.

¿He logrado convencerte para usar git? Vamos, pues, a instalarlo

Perfecto, vamos a instalarlo primero. Te diré como lo hago yo pero hay otras formas.

Normalmente tengo un entorno conda de herramientas. Puedes crear uno de la siguiente forma (desde la línea de comandos):

Lo bueno de lo anterior es que se hace igual en Windows, Linux y/o Mac.

Y ya estaría instalado y se podría usar desde la línea de comandos con el entorno tools activado.

¿Algunos comandos git indispensables?

Esto no pretende ser un tutorial extenso ni detallado sobre como usar git. Más bien se puede ver como una chuleta de comandos con los cuales resuelves el mayor porcentaje de lo que tienes que hacer con git en tu día a día.

Primero hemos de configurar git para identificarnos y que aparezcamos como los autores cuando estamos interactuando con el repositorio de código.

En lo anterior he definido el nombre de usuario y el correo de forma global y será el que se use desde la máquina en la que os encontráis.

Muy bien, ya nos hemos identificado pero queremos empezar a toquetear código. Para ello podemos crear un repositorio nuevo o ‘clonar’ (hacer una especie de copia) uno ya existente. Lo podemos hacer de la siguiente forma:

Para un repositorio nuevo:

Con lo anterior hemos creado una carpeta llamada “mi_repo” y desde dentro de la misma he inicializado un repositorio indicándole a git que quiero que siga los cambios que se produzcan en esa carpeta.

Si el repositorio ya existiera podríamos clonarlo así:

Con lo anterior hemos clonado un repositorio ya existente que se encuentra en github.com, en la cuenta de kikocorreoso y con nombre pyboqt.

Eso nos descarga una carpeta con el código a la que podemos acceder. Esa carpeta está sometida al seguimiento de cambios por parte de git.

Si una vez que estás dentro de la carpeta del repositorio haces algún cambio y quieres que git sea consciente de ello puedes hacer:

Ahora has añadido nuevos ficheros al índice pero tienes que informar de los cambios y puedes aportar un mensaje descriptivo:

Para ver cómo se encuentra el estátus del repositorio puedes usar:

Y te informará del estado actual de las cosas.

Si ya has añadido cambios en tu repositorio local y los quieres enviar al repositorio remoto (que puede estar en github, por ejemplo) puedes usar:

Es decir, envía los cambios locales (origin) al repositorio remoto (master).

Lo anterior puede que falle si no has informado a git de cual será el remositorio remoto. Lo podrías hacer así:

Ver más sobre esto aquí.

Para verificar que hemos añadido correctamente el repositorio remoto podemos hacer uso de:

Hasta ahora hemos visto lo más básico. Imagina ahora que quieres añadir una nueva rama de código para comprobar la viabilidad de añadir una nueva funcionalidad o para trabajar en un reformateo de código o para trabajar en un bug,… Podemos hacer:

Para cambiar a la nueva rama que hemos creado podemos usar:

Ahora podríamos empezar a trabajar en esta nueva rama sin modificar lo que ya tenemos en la rama original, normalmente llamada master.

Si no nos convence lo que hemos hecho en la nueva rama la podemos eliminar usando:

Si nos convence pero no hemos terminado aun podemos enviarla al remoto para seguir trabajando en otro momento usando:

Puede que tengas más de una rama. Las puedes ver usando:

Puedes mandar todas las ramas locales al remoto usando:

Si has cambiado de opinión con respecto a una rama que ya habías mandado al remoto puedes eliminarla usando:

Muy bien, estamos en otro PC que ya tiene el repositorio y queremos seguir trabajando con nuestro repositorio. Lo podemos actualizar haciendo

Si creemos que la funcionalidad que estábamos desarrollando en una nueva rama está lista para ser integrada podemos unirla a la rama que tengamos activa, que normalmente será master, usando:

Antes de unir nada puedes usar:

Para ver las diferencias.

En el caso de que ya hayas unido algo y te hayas arrepentido puedes deshacer los cambios usando:

Puedes acceder a un log de lo que has ido haciendo usando

También puedes guardar ‘versiones’ usando etiquetas que te permiten etiquetar determinados momentos de tu desarrollo. Por ejemplo, si consideras que has llegado a una nueva versión la puedes etiquetar usando:

Lo último, id_del_commit, no es estrictamente necesario y usará el último “commit”. Podemos añadir un mensaje también usando:

Esta etiqueta estará en tu repositorio local. Si la quieres mandar también al remoto puedes usar:

Para borrar tags en remoto y en local, respectivamente, se puede usar:

Puedes borrar cosas para que dejen de estar controladas por git usando, por ejemplo:

git pull puede ser un comando destructivo puesto que hace dos cosas en una, git fetch y git merge, es decir, descarga datos del repositorio remoto y los intenta unir. Si al hacer la unión aparecen problemas pueden complicarse las cosas.

Es por ello que si no sabes muy bien lo que estás haciendo quizá sea más seguro usar esos dos comandos por separado.

descarga la información del repositorio remoto pero no hace nada con ello. Solo la tenemos ahí para inspeccionarla. Normalmente es buena idea hacer eso antes de usar git merge.

Si se producen problemas con un git merge puedes leer aquí.

Muy bien, muchas cosas, ¿practicamos?

Vamos a hacer uso de algunos de los comandos anteriores con un repositorio nuevo. El repositorio, en muchas ocasiones lo creamos primero en el sitio donde centralizaremos el desarrollo. No voy a explicar aquí como crear un repositorio nuevo en Github, GitLab, BitBucket u otros servicios:

El que yo he creado para este ejemplo se llama pybogit y está en github. Visualmente lo podéis ver como:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Para traernos el repositorio a nuestro PC local uso (siempre considero que estás trabajando desde la línea de comandos y con el entorno tools activado, mira más arriba, que es donde hemos instalado git):

Visualmente lo podéis ver como:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Ahora que ya lo tenemos en nuestro PC nos movemos a esa carpeta:

Y ahí podemos crear una carpeta llamada src y dentro de esa carpeta podemos crear un fichero que se llame mi_modulo.py:

Lo anterior habrá creado una carpeta y un fichero dentro de ella. Lo podéis hacer de otras formas. En windows, por ejemplo, podéis usar el notepad. Si ahora le preguntamos a git por el estátus del repositorio nos dirá lo siguiente:

El anterior mensaje me dice que me encuentro en la rama master (luego vemos esto) y que tengo cosas en la carpeta que no están bajo el seguimiento de git. Para decirle a git que tenga en cuenta el nuevo fichero puedo hacer, por ejemplo:

Si volvemos a mirar el estátus nos dirá:

Me indica que he añadido un nuevo fichero al repositorio pero los cambios todavía no han sido confirmados a git. Para confirmarlos hacemos un commit:

En la consola podré leer un mensaje parecido a:

Si ahora miramos de nuevo el estátus:

Vemos que todos los cambios han sido integrados:

Pero me dice que están en mi rama local y que la remota está un ‘cambio’ (commit) por detrás. La situación actual vista gráficamente sería algo así:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

En este momento podríamos mandar los cambios al repositorio remoto (siempre es buena idea hacer esto). Lo podemos hacer de la siguiente forma:

Visto visualmente sería algo así:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Y ahora estariamos en esta situación:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Es decir, tenemos la misma información en local y en remoto.

Vamos a hacer un nuevo cambio en el fichero que hemos estado usando. Meto el siguiente código:

Guardo el fichero y si miro el estátus veré que git me dice que:

Añadimos y ‘commiteamos’ (sí, la jerga es la que es) y lo mandamos al remoto:

La situación actual sería:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Se me ocurre ahora añadir una función experimental. Voy a crear una rama nueva para meter esta función experimental. La rama master podéis verla como el tronco principal del árbol. Siempre partimos con una sola rama principal o master. Pero al árbol le podemos añadir ramas y vamos a aprovechar este momento para hacer eso mismo. Para crear la rama y cambiarnos a ella en un único comando podemos hacer:

Lo anterior es un atajo para los dos siguiente comandos:

Ahora, git considera que estamos trabajando en una nueva rama. Lo podemos ver preguntando nuevamente el estátus (git status):

y los cambios que hagamos no irán al tronco (la rama master). Hagamos algún cambio añadiendo nuestra funcionalidad experimental. Modificamos el fichero que hemos creado anteriormente añadiendo el siguiente código:

Añadimos los nuevos cambios a la rama en la que nos encontramos usando:

La situación actual sería algo así:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Podemos mandar esa nueva rama al repositorio remoto usando (cuidado, enviaría TODAS las ramas al remoto, en este caso solo tengo una por lo que me vale):

Y me sale un mensaje parecido a:

Ahora que la rama local está también en el remoto tendríamos algo así:

Para hacer esta imagen se han usado iconos de FontAwesome sin modificar. Licencia.

Y podríamos pedir a nuestros colaboradores que revisasen esa nueva rama, si creen que es útil, si mejor eliminar ese código por la razón que sea,…

Hemos decidido eliminarla. La elimino del local y del remoto. Primero salgo de la rama:

Podemos ver las ramas que tenemos y en la que nos encontramos usando:

Que nos mostrará algo como:

Con el asterisco indicando que estamos ahora en la rama master. Voy a coger la sierra y a cortar la rama nueva_rama:

La opción -D es importante que esté en mayúscula. Probadlo primero en minúscula. Cojo la sierra y me la llevo hasta el servidor y corto la rama en el remoto:

Ahora podéis mirar las ramas que os quedan y deberíais ver solo la rama master.

Y podríamos seguir probando cosas pero lo voy a dejar aquí para no aburrirte. Espero que si no sabías nada de git este artículo te haya abierto un poco el apetito y te ayude a guiarte mínimamente. Si tienes dudas usa los comentarios.

Tienes este artículo convertido en chuleta gracias a Geocurios (@borlafgis). La puedes descargar de aquí.

Para los que prefieren aprender de forma más visual

Si te gusta más que te cuenten las cosas en lugar de leer añado la siguiente charla de Sofía Denner en la PyConAr2018:

Deja un comentario

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

forty two + = 44