INE Educa: Clases abiertas de R

Git para usuarios y usuarias de R

Proyecto Ciencia de Datos

Diciembre 2023

Bienvenidas y bienvenidos

Contenidos de la clase

  • ¿Qué es Git y para qué sirve?
  • Principales conceptos asociados a Git
  • Árbol de commits
  • Uso de ramas
  • Trabajo remoto
  • Conflictos de merge
  • El .gitignore
  • Casos de uso
  • Recomendaciones sobre uso de git

Objetivo de la clase

  • Mostrar herramientas que permiten el uso básico de git (git clone, git push, git pull) en conjunto con la herramienta Rstudio

Contenidos de la clase

MUY IMPORTANTE:

  • La clase no está pensada para ser seguida en vivo. Se recomienda hacerlo cuando sea subida a las redes sociales del INE.

  • Se recomienda seguir la clase desde computadores personales, pues plataformas como GitHub suelen estar sujetas a bloqueos institucionales.

  • La clase se realizará utilizando GitHub como plataforma de control de versiones. Es necesario crear una cuenta para seguir la clase en su totalidad.

    • Otras alternativas: Gitlab, Bitbucket.
  • La clase está basada en Sistemas Operativos Windows, sin embargo, no debiesen existir grandes diferencias al aplicar lo enseñado en Sistemas Mac o Linux.

¿Qué es Git y para qué sirve?

¿Qué es Git y para qué sirve?

Es un sistema de control de versiones (VCS).

  • Permiten a personas o equipos administrar los cambios del código de un proyecto en el tiempo.

Funciona como una máquina del tiempo

  • Cada cierto tiempo sacamos una “foto” del estado de todos los archivos del proyecto

  • Estas fotos no desaparecen

  • Siempre es posible volver a una foto anterior

  • Incluyen nombre y fecha de quién sacó la foto, además de un mensaje explicativo de qué cambios incluye

Permite que varias personas trabajen en un mismo proyecto sin molestarse unos a otros

Ilustración por Sara A. Metwalli, https://saraametwalli.medium.com/

¿Qué es Git y para qué sirve?

Nos protege:

  • De nuestros propios errores

  • De fallas en el almacenamiento físico (podemos sincronizar nuestros cambios en la nube)

Veamos rápidamente cómo instalarlo

¿Qué es Git y para qué sirve?

Nos acercamos a la reproducibilidad

Aún nos falta manejar las dependencias para llegar al estándar dorado (sistemas como Docker nos permiten llegar ahí)

¿Qué es Git y para qué sirve?

¿Cuándo sirve?

  • Proyectos de código de naturaleza no lineal (ciclos de experimentación, código que evoluciona e itera, etc).
  • Proyectos de código colaborativo.

¿Cuándo no sirve?

  • Proyectos de desarrollo lineal (no hay necesidad de volver atrás).
  • Proyectos cuyos documentos principales (scripts o documentaciones) no estén basados en texto plano (por ejemplo, archivos .docx de Microsoft Word).
  • Proyectos de muy baja complejidad (el costo de implementarlo resulta mayor al beneficio).

Pequeña excepción: si queremos hacer público un proyecto, aunque no cumpla con las condiciones, las plataformas como Github son una buena forma de hacerlo.

Principales conceptos

Git nos permite navegar de manera “sencilla” por las distintas versiones de un archivo

Podemos rastrear dónde y cuándo se producen los errores

Estados en Git

Tenemos 3 estados para nuestros archivos:

  • Modificado

  • “En escena” (staging area)

  • Confirmado o comprometido (committed)

El mueble

  • Para aterrizar los conceptos usaremos el proyecto de creación de un escritorio como analogía.

  • En este momento nuestro escritorio es solo un plan: un repositorio vacío.

    • Tenemos una idea de qué queremos construir, pero no sabemos el camino exacto: materiales, colores, formas pueden ir cambiando en el camino.
  • En la medida en que vayamos avanzando iremos haciendo commits que guarden nuestro progreso.

  • Por ejemplo, luego de tomar una tabla, cortarla, barnizarla, etc, tenemos nuestro primer hito: tenemos una pata lista.

    • Este podría ser merecedor de un primer commit!
  • Tal vez querríamos guardar nuestro progreso antes del barnizado. En ese caso nuestro commit sería antes
  • Esto nos permitiría volver atrás y cambiar el color del barniz si nos arrepentimos en algún momento.

Principales conceptos

Ciclos sucesivos de modificar, poner en escena y confirmar van generando el historial de cambios de nuestro repositorio

Cada commit es una foto del estado de nuestros archivos a la que podemos acceder cuando queramos

  • NO podemos acceder a estados intermedios entre dos commit

  • Queremos hacer commit frecuentemente y con un número de cambios manejable

Commit 1

Commit 2

Creemos nuestro primer repositorio en RStudio y realicemos nuestros commit iniciales!

El árbol de commits

El árbol de commits es una representación visual de la historia de nuestro proyecto.

Nos muestra cada commit, nos permite acceder a sus contenidos y nos muestra dónde nos encontramos actualmente en la historia del árbol y dónde se encuentran las otras ramas, en caso de existir.

¿Qué es una rama? Simplemente es un puntero a un commit específico, que contiene la información de sus ancestros (commits anteriores a este).

El árbol de commits

El árbol de commits es una representación visual de la historia de nuestro proyecto.

Nos muestra cada commit, nos permite acceder a sus contenidos y nos muestra dónde nos encontramos actualmente en la historia del árbol y dónde se encuentran las otras ramas, en caso de existir.

¿Qué es una rama? Simplemente es un puntero a un commit específico, que contiene la información de sus ancestros (commits anteriores a este).

Si nos encontramos parados en una rama y realizamos un commit el puntero de la rama se moverá al commit más reciente.

El árbol de commits

El árbol de commits es una representación visual de la historia de nuestro proyecto.

Nos muestra cada commit, nos permite acceder a sus contenidos y nos muestra dónde nos encontramos actualmente en la historia del árbol y dónde se encuentran las otras ramas, en caso de existir.

¿Qué es una rama? Simplemente es un puntero a un commit específico, que contiene la información de sus ancestros (commits anteriores a este).

Si nos encontramos parados en una rama y realizamos un commit el puntero de la rama se moverá al commit más reciente.

La rama principal se llama main o master, que aloja la versión oficial de nuestro proyecto, pero podemos crear tantas como queramos

Cada rama es independiente en este sentido, por lo que los cambios que aquí se realicen no estarán presentes en la rama principal hasta que uno lo decida

El árbol de commits

El árbol de commits es una representación visual de la historia de nuestro proyecto.

Nos muestra cada commit, nos permite acceder a sus contenidos y nos muestra dónde nos encontramos actualmente en la historia del árbol y dónde se encuentran las otras ramas, en caso de existir.

¿Qué es una rama? Simplemente es un puntero a un commit específico, que contiene la información de sus ancestros (commits anteriores a este).

Si nos encontramos parados en una rama y realizamos un commit el puntero de la rama se moverá al commit más reciente.

La rama principal se llama main o master, que aloja la versión oficial de nuestro proyecto, pero podemos crear tantas como queramos

Cada rama es independiente en este sentido, por lo que los cambios que aquí se realicen no estarán presentes en la rama principal hasta que uno lo decida

Todo software compatible con git presenta alguna forma de acceder a este árbol; en Rstudio se encuentra en Tools -> Version control -> History.

El árbol de commits

El árbol de commits es una representación visual de la historia de nuestro proyecto.

Nos muestra cada commit, nos permite acceder a sus contenidos y nos muestra dónde nos encontramos actualmente en la historia del árbol y dónde se encuentran las otras ramas, en caso de existir.

¿Qué es una rama? Simplemente es un puntero a un commit específico, que contiene la información de sus ancestros (commits anteriores a este).

Si nos encontramos parados en una rama y realizamos un commit el puntero de la rama se moverá al commit más reciente.

La rama principal se llama main o master, que aloja la versión oficial de nuestro proyecto, pero podemos crear tantas como queramos

Cada rama es independiente en este sentido, por lo que los cambios que aquí se realicen no estarán presentes en la rama principal hasta que uno lo decida

Todo software compatible con git presenta alguna forma de acceder a este árbol; en Rstudio se encuentra en Tools -> Version control -> History.

¡Veamos el árbol de commits de nuestro proyecto actual!

Trabajando con ramas

  • Es la forma más segura de trabajar en git: nuestro trabajo no tocará la rama principal hasta que lo decidamos

  • Cada persona desarrolladora puede trabajar en una rama independiente, sin molestar a los demás

  • En proyectos grandes, quienes desarrollan el proyecto, en general, no tienen permiso para empujar directamente a la rama main/master, tienen que “pedir permiso” para hacerlo

  • Existe una persona administradora encargada de revisar y unir (merge) las contribuciones a la rama central

    • Decide si el aporte debe incorporarse

    • Resuelve conflictos

  • Por ahora nos centraremos en el caso básico en que tenemos total libertad subir nuestros cambios (más detalles en la sección de trabajo remoto).

Trabajando con ramas

Plan original (rama main)

Nuevo plan (rama prueba_cajon_redondo)

Nuevo plan commit #1 (rama prueba_cajon_redondo)

Nuevo plan commit #2 (rama prueba_cajon_redondo)

Plan original (rama main)

Por otro lado, las ramas son particularmente útiles en un contexto experimental: queremos probar una variación y no estamos seguros si será incorporada o no.

Volvamos a nuestro mueble. Digamos que su estado de avance es el siguiente:

Sin embargo, se nos ocurre innovar y probar un nuevo tipo de cajón

Avanzamos en nuestros commits

Terminamos nuestro experimento y vemos que no nos resultó satisfactorio

Podemos volver sin problemas a nuestro commit inicial y abandonar nuestra rama

Si quiero trabajar de manera individual, no necesito más que lo que hemos visto hasta ahora

¡Probemos en RStudio cómo crear nuestras primeras ramas!

Trabajo remoto

¿Qué pasa si necesito trabajar con más personas? ¿Si quiero un respaldo online de mi trabajo?

Gitlab, Github, etc se usan para trabajar con más personas, agregando el concepto del repositorio remoto

Trabajo remoto

Ilustración por Allison Horst, https://allisonhorst.com/git-github

Repositorio remoto

Varias personas aportan a un mismo repositorio

Esquema de trabajo en Git

Luego de hacer nuestros commit, usualmente vamos a querer enviarlos al repositorio remoto para que el resto pueda verlos a través de un push

Antes de hacer un push, es necesario actualizar nuestro proyecto con los cambios que otros/as colegas puedan haber realizado desde la última vez que nos sincronizamos con el repositorio remoto. Para esto, usamos git pull

Si es que fue posible traer los cambios remotos sin problemas y teniendo seguridad que nuestro código funciona, procedemos a empujar nuestros cambios con un git push

Por lo tanto, el flujo normal de trabajo es siempre:

commit - pull - push

Veamos cómo crear y clonar un repositorio remoto en Github

¿Sin problemas?

Al hacer pull traemos los cambios que han hecho el resto de colegas a nuestro repositorio local y git trata de incorporarlo con los commit que hemos realizado desde la última vez que hicimos pull. A esto se le llama merge.

Si los cambios que existen en nuestros commit no tienen intersección con los de los commit de nuestros colegas, no habrá problema. Dos casos:

  • Cambios en archivos diferentes
  • Cambios en el mismo archivo, pero distintas líneas

Ahora, si nuestros commit y algún commit recibido en el pull cambian la misma línea de un archivo, tendremos problemas: un conflicto de merge.

Conflicto de merge

<– Su script se verá similar a esto

Básicamente git nos muestra cómo están las líneas que tienen cambios simultáneos en nuestro repositorio y en el script en el repositorio remoto (o en el de la rama que queremos incorporar a través del merge).

Aquí debemos editar el script para que quede funcional, de acuerdo a los objetivos del proyecto y del script. Para esto no existe receta, podrían mantenerse ambos cambios, uno de los dos o ninguno:

Luego de editar el script, es necesario realizar un commit y luego un push con lo que se soluciona el conflicto de merge.

Nota importante: cuando hacemos un pull con conflicto de merge, nos aparecerán todos los cambios al repositorio que ha habido desde la última vez que hicimos pull en la pestaña Git. Solo debemos preocuparnos por los archivos que aparezcan con un símbolo de “U”, que implican que ese archivo específico tiene conflicto de merge.

Conflicto de merge

Ejemplo de lo anterior:

La terminal también nos indicará los archivos con conflicto:

Probemos cómo generar y resolver un conflicto de merge

El .gitignore

Cuando trabajamos con repositorios remotos, muchas veces existen archivos que queremos mantener solo en nuestro computador o que no son realmente compatibles con un repositorio git, por lo que no queremos subirlos a la nube:

  • Archivos que no son pertinentes al objetivo del proyecto.

  • Archivos temporales y de caché.

  • Archivos personales (por ejemplo, .Rprofile, scripts de pruebas).

  • Archivos muy grandes (por ejemplo, tablas de datos pesadas).

Estos los anotamos en el archivo .gitignore, que es un archivo de texto simple.

Importante: .gitignore tiene algunas notaciones particulares, pero lo más relevante es que el * sirve como comodín

¡Hagamos pruebas de uso del .gitignore!

Casos de uso dentro del INE

  • Un equipo dentro del INE necesitaba reformular la imputación de una de sus variables. Este era un proceso complejo, por lo que fue necesario el uso de una rama para su desarrollo.

  • La marcha blanca de una encuesta contenía scripts que eran diferentes al del resto del procesamiento de la encuesta. Para no tener que lidiar con ellos, se optó por marcar el commit final de la marcha blanca con una rama, luego, si era necesario volver a esos scripts, bastaba con realizar un git checkout scripts_mb para volver a estos.

  • Luego de sincronizar mi código con lo que está en la nube (git pull) cierto código dejó de funcionar. Bastó con revisar el historial de commits para notar quién había hecho cambios en el script, lo que permitió resolver el problema rápidamente luego de una conversación.

Recomendaciones sobre cómo interactuar con git

En esta clase nos centramos en la interacción con git a través de RStudio

Este nos permite acceder a los comandos básicos que revisamos

Sin embargo, si queremos hacer un uso más avanzado de git, tendríamos que usar la consola

Algunos comandos a los que no tenemos acceso desde RStudio: git merge, git tag, git cherry-pick, git status, git reset (con todas sus opciones)

En particular para el merge de ramas, usar la consola nos resultará inevitable.

Resumiendo

  • Aprendimos qué es git, cuándo usarlo y cuándo no

  • Revisamos conceptos básicos y su aplicación en RStudio:

    • add
    • commit
    • merge
    • pull
    • push
    • árboles de commits
    • ramas
    • .gitignore.
  • Revisamos algunos casos de uso dentro de las oficinas del INE

Comandos más comunes

git add .: poner todo en escena

git add : poner <nombre_archivo> en escena

git commit -m “mensaje personalizado”: confirmar cambios

git push nombre_rama: empujar rama al remoto

git clone url_repositorio: clonar un repositorio (puede ser por SSH o HTTPS)

git pull nombre_rama: traer cambios de rama nombre_rama desde el repositorio remoto

git checkout nombre_rama: ir a una rama

git branch: ver todas las ramas

git branch nombre_rama: crear una rama

Referencias

Ciencia Social Abierta - Prof. Juan Carlos Castillo

Documentación oficial de git

Guía muy completa en español

Git con enfoque en R

Learn Git Branching

INE Educa: Clases abiertas de R

Git para usuarios y usuarias de R

Proyecto Ciencia de Datos

Diciembre 2023