Taller de control de versiones para el grupo Mobility Frontiers
29 de julio, 2026
En un grupo de investigación, los problemas de control de versiones rara vez se anticipan: se descubren cuando una persona sobrescribe sin saberlo el trabajo de otra, o cuando un script deja de ejecutarse después de una actualización y no queda claro a qué versión anterior conviene volver. Este documento reúne los conceptos y procedimientos de Git y GitHub necesarios para evitar ese tipo de incidentes, aplicados al flujo de trabajo habitual del grupo: repositorios en R, análisis que se desarrollan de forma incremental, y colaboración simultánea de varias personas sobre un mismo pipeline.
Los ejercicios se hacen sobre taller-git-positron-codex, un repositorio creado para esta actividad — no sobre sfb-mobility-networks ni ningún otro repo real del grupo.
Requisitos previos: Positron instalado; Git configurado con nombre de usuario y correo electrónico (git config --global user.name / user.email); una cuenta de GitHub con acceso al repositorio de práctica.
Lo primero, antes de clonar nada: Positron necesita saber con qué cuenta de GitHub va a trabajar. El ícono de cuenta está en la esquina inferior izquierda de la barra de actividad. Si todavía no hay sesión iniciada, ese menú ofrece iniciar sesión con GitHub — el texto exacto de la opción varía según qué la esté pidiendo (por ejemplo, Sign in with GitHub to use GitHub Copilot si es la extensión de Copilot); una vez conectado, el mismo lugar pasa a mostrar el nombre de usuario:
Al elegir “Sign in with GitHub”, Positron pide confirmar en el navegador: se abre una pestaña nueva, se ingresa un código de un solo uso, y se autoriza el acceso. Desde ese momento, Positron queda conectado con esa cuenta para todo lo que sigue — clonar, hacer pull, push, y abrir pull requests sin tener que autenticarse de nuevo cada vez.
Ejercicio 1 — Conectar tu cuenta de GitHub
Con la cuenta ya conectada, cada persona necesita su propia copia local del repositorio. En Positron, el comando específico para esto es Workspaces: New Folder from Git… (es la variante propia de Positron del “Git: Clone” de VS Code — usa “carpeta” en vez de “folder abierto” porque así organiza los proyectos):
Cmd/Ctrl+Shift+P) → Workspaces: New Folder from Git….taller-git-positron-codex, o pegar la URL directamente si aparece esa opción.Al terminar, Positron pregunta si se quiere abrir la carpeta — elegir Open. También va a pedir confirmar que se confía en el repositorio (Workspace Trust) — al ser un repositorio del propio grupo, se confirma.
Ejercicio 2 — Clonar el repositorio de práctica
Aquí conviene aclarar algo antes de seguir: si ya conectaste tu cuenta en el ejercicio anterior y vas a trabajar desde el panel de Positron (el camino recomendado en este taller), la autenticación para push y pull ya quedó resuelta — Positron la maneja con esa misma sesión, sin pedir nada adicional. Este token hace falta en un caso distinto: cuando se usa la terminal directamente, ya que ahí Git no tiene forma de aprovechar la sesión de Positron y va a pedir credenciales por su cuenta.
Desde hace algunos años, GitHub no acepta la contraseña de la cuenta para operaciones por HTTPS. Si la terminal solicita usuario y contraseña al ejecutar push y se ingresa la contraseña de la cuenta, la operación fallará. En su lugar, GitHub requiere un token de acceso personal, que reemplaza a la contraseña en este tipo de operaciones.
Vale la pena tener uno igual, incluso trabajando siempre desde el panel: sirve como respaldo si por algún motivo la sesión de la cuenta se cae, y es lo que se necesita apenas se quiera usar la terminal para algo puntual.
Procedimiento, desde github.com:
positron-taller) y una fecha de expiración razonable — 90 días es suficiente para no dejarlo indefinido ni tener que repetir el procedimiento con frecuencia.taller-git-positron-codex, además de cualquier otro repositorio del grupo en el que se vaya a trabajar.push.Con el token disponible, la primera vez que la terminal pida credenciales al ejecutar git push:
Tras el primer uso, el sistema operativo almacena la credencial (Keychain en macOS, Credential Manager en Windows, o el credential helper configurado en Linux), y no vuelve a solicitarse hasta que el token expire.
El token equivale a una contraseña con permisos acotados: no debe compartirse por canales de mensajería ni incluirse en ningún archivo del repositorio. Si se expone por error, debe revocarse de inmediato desde la misma página de Personal access tokens y generarse uno nuevo.
Ejercicio 3 — Generar el token
Un archivo pasa por tres estados antes de quedar registrado en la historia del proyecto:
edición marcado registro
(working dir) → (staging, git add) → (commit)
git add no envía nada a GitHub — únicamente indica qué cambios se incluirán en el próximo commit. El commit en sí es una fotografía local del proyecto; nada de esto llega al repositorio remoto hasta que se ejecuta un push. En sentido inverso, pull incorpora los cambios que otras personas ya subieron:
GitHub (origin) --pull--> copia local
copia local --push--> GitHub (origin)
De este esquema se desprende la práctica más importante del taller: ejecutar pull antes de comenzar a trabajar. No se trata de una formalidad, sino de una necesidad — si otra persona subió cambios entre el último pull y el próximo push, Git exigirá resolver esa diferencia. Es preferible hacerlo al inicio de la sesión de trabajo que al final, bajo presión de tiempo.
Con taller-git-positron-codex abierto en Positron, el panel de control de código fuente (ícono de rama en la barra lateral izquierda) concentra la mayor parte de las acciones.
Desde Positron (recomendado):
Paso 1. Sincronizar antes de realizar cualquier modificación, mediante el botón de sincronización o “Pull” del panel. Si el repositorio ya está actualizado, se continúa; si trae cambios nuevos, se confirma que el mecanismo de sincronización funciona correctamente.
Paso 2. Abrir practica/notas.md y añadir una línea con nombre y fecha. Al guardar, el archivo aparece en el panel de control de código fuente como modificado.
Paso 3. Revisar el diff antes de continuar — la vista comparativa muestra en rojo el contenido eliminado y en verde el contenido añadido. Esta revisión permite detectar modificaciones no intencionadas antes de registrarlas.
Paso 4. Marcar el archivo (equivalente a git add) y confirmar el commit con un mensaje descriptivo — por ejemplo, docs: agrega nota de práctica de Roberto, no cambios o fix. El commit queda registrado únicamente en la copia local.
Paso 5. Ejecutar push. El commit queda entonces disponible en GitHub para el resto del grupo.
El panel completo, con los cinco pasos anteriores en el mismo lugar, se ve así:
Alternativa: terminal integrada de Positron. El mismo procedimiento, escrito directamente en la terminal (Terminal → New Terminal en Positron):
git pull
git add practica/notas.md
git commit -m "docs: agrega nota de práctica de Roberto"
git pushAmbos métodos producen el mismo resultado; la terminal queda ahí para quien ya la use por costumbre.
Ejercicio 4 — Pull, editar, commit, push
Ejecutar pull antes de trabajar evita la mayoría de los conflictos, aunque no todos. Si dos personas modifican la misma línea de un archivo en un intervalo breve, se produce un conflicto — un resultado esperado del funcionamiento de Git, no un error.
Para observarlo en la práctica: en parejas, ambas personas parten del mismo commit en practica/ejemplo_analisis.R y modifican la misma línea de la función diversidad_dominios() sin ejecutar pull entre ambas ediciones. La primera persona en hacer push no encuentra problemas; la segunda recibe un rechazo, y al ejecutar pull, Git marca el archivo de la siguiente manera:
diversidad_dominios <- function(df) {
df %>%
<<<<<<< HEAD
group_by(id, dominio) %>%
summarise(n = n(), .groups = "drop")
=======
group_by(id) %>%
summarise(n_dominios = n_distinct(dominio), .groups = "drop")
>>>>>>> origin/main
}Desde Positron (recomendado): el editor presenta este mismo bloque con opciones sobre cada sección en conflicto — Accept Current, Accept Incoming, Accept Both — para seleccionar la versión que corresponde, o combinar ambas manualmente. Así se ve dentro del editor:
ejemplo_analisis.R tal como aparece en el editor de Positron, con los botones Accept Current Change, Accept Incoming Change, Accept Both Changes y Compare Changes sobre el bloque en conflicto.Una vez resuelto, se guarda el archivo, se marca (add) y se confirma el commit desde el panel de control de código fuente, tal como en el ejercicio anterior, y finalmente se ejecuta push.
Alternativa: terminal. Editar el archivo a mano para eliminar las marcas (<<<<<<<, =======, >>>>>>>) dejando el contenido correcto, y luego:
git add practica/ejemplo_analisis.R
git commit -m "fix: resuelve conflicto en diversidad_dominios"
git pushLa frecuencia de estos conflictos se reduce mediante hábitos de trabajo, no mediante herramientas: trabajar en una rama propia en lugar de directamente sobre main; notificar al equipo antes de modificar un script utilizado por varias personas; y realizar commits pequeños y frecuentes en lugar de uno extenso al final de la jornada. Una regla sin excepciones: no debe ejecutarse push --force sobre una rama utilizada por otras personas, ya que reescribe la historia y puede eliminar commits ajenos sin advertencia.
Ejercicio 5 — Provocar y resolver un conflicto (en parejas)
Una rama es una copia paralela del proyecto que permite experimentar sin afectar main; los cambios permanecen aislados hasta que se decide integrarlos.
A partir de este taller, el siguiente procedimiento queda establecido como estándar para los repositorios del grupo, no solo como recomendación:
main. Todo cambio, por pequeño que sea, se hace en una rama.nombre/descripción-corta — por ejemplo, roberto/limpieza-datos-gps o consuelo/modelo-difusion-v2. El nombre identifica de inmediato quién está trabajando en qué, algo especialmente útil cuando varias personas tienen ramas abiertas al mismo tiempo.main se hace exclusivamente mediante pull request, con revisión de al menos otra persona del grupo antes del merge.Desde Positron (recomendado): el nombre de la rama actual aparece en la esquina inferior izquierda de la ventana. Al hacer clic ahí, Positron despliega un listado con la opción “Create new branch…” y las ramas existentes; al escribir el nombre siguiendo la convención (tu-nombre/descripción-corta) y confirmar, Positron cambia automáticamente a esa rama nueva:
El ciclo de edición, commit y push se ejecuta después de manera idéntica al descrito en el ejercicio anterior; la única diferencia es que los cambios quedan aislados en esa rama.
Alternativa: terminal.
git checkout -b tu-nombre/practica-tallermain en GitHubLa convención anterior depende de que cada persona la respete por su cuenta. GitHub permite además declararla a nivel de repositorio, para que quede visible y no dependa solo de la memoria de cada quien. Esta configuración se hace una sola vez por repositorio, idealmente por quien lo administra:
main.main llegue por PR (con la salvedad que se explica abajo).Important
En un repositorio privado dentro de una organización de GitHub en el plan gratuito, esta regla queda configurada pero GitHub advierte que no se aplica técnicamente hasta actualizar la organización a GitHub Team o Enterprise — la página de configuración lo indica explícitamente. Mientras eso no ocurra, la regla funciona como una política declarada y visible para todo el grupo, pero el cumplimiento real sigue dependiendo de la convención acordada en esta sección, no de un bloqueo técnico.
Esa integración se solicita mediante un pull request: una propuesta formal de incorporar los cambios de una rama a main, sujeta a revisión previa. La primera vez que se hace push de una rama nueva, Positron muestra este aviso:
El PR se crea sin salir de Positron: Positron incluye la extensión GitHub Pull Requests and Issues, con su propia vista Pull Requests en la barra de actividad. Ahí aparece el botón Create Pull Request, que abre un formulario dentro del editor con la rama base, la rama de comparación, el título y la descripción:
Una vez creado, el PR se revisa desde esa misma vista — se visualiza el diff completo, se pueden agregar comentarios, y solo tras la aprobación correspondiente se habilita el merge:
Una vez integrada, la rama puede eliminarse sin pérdida de información, ya que su historia permanece en main.
En un repositorio de investigación compartido, el pull request cumple una función concreta: otra persona revisa el cambio antes de que se mezcle con el análisis principal, y eso es lo que atrapa errores que de otro modo pasarían inadvertidos — una columna mal nombrada, un filtro aplicado de más — antes de que terminen en un resultado.
Ejercicio 6 — Crear tu rama siguiendo la convención del grupo
Positron incorpora un panel dedicado a Codex, el agente de código de OpenAI, disponible como pestaña propia en el panel lateral derecho (junto a Session, Connections, History y Claude Code). A diferencia de pedirle algo a un asistente genérico, Codex opera directamente sobre los archivos del proyecto abierto: puede explicar una función existente, generar una nueva, corregir un error a partir del mensaje de la consola, y proponer los cambios como un diff editable antes de aplicarlos.
Codex no tiene un único modelo detrás — y la elección afecta tanto la calidad del resultado como el tiempo de respuesta y la cuota de uso disponible:
gpt-5.4-mini). Responde más rápido y consume menos cuota; es suficiente para tareas que no requieren razonamiento extenso, como leer una función y resumir qué hace.gpt-5.3-codex o la versión más reciente disponible). Tiene mejor desempeño en tareas agénticas de código — seguir instrucciones de varios pasos, mantener consistencia con el resto del script — a costa de mayor tiempo de respuesta.Regla práctica para un uso eficiente: empezar con el modelo liviano para explorar y entender el código, y escalar al modelo especializado solo cuando la tarea es efectivamente generar o corregir algo con cierta complejidad. Usar el modelo más potente para preguntas simples es un gasto de cuota innecesario; usar el liviano para generar código nuevo suele dar resultados menos confiables. El modelo se cambia desde el selector del panel, en cualquier momento de la sesión.
Sobre practica/ejemplo_analisis.R, dos solicitudes de prueba, cada una con el modelo que le corresponde:
Con el modelo liviano: Explica qué hace
diversidad_dominios()y qué ocurriría sidominiocontuviera valoresNA.
Con el modelo especializado en código: Escribe una función que reciba un data.frame con columnas
id,dominioyfecha, y devuelva el conteo de dominios distintos poridy por mes.
El código generado por Codex sigue el mismo procedimiento que cualquier otra modificación: se revisa el diff antes de aplicarlo, se ejecuta para confirmar que cumple lo esperado, y si se integra a un repositorio compartido, se somete a revisión mediante pull request, siguiendo la convención de ramas establecida en la sección anterior. Codex acelera la escritura del código; no sustituye la comprensión de su funcionamiento ni la revisión de lo que produce.
Ejercicio 7 — Usar Codex con el modelo adecuado para cada tarea
La siguiente tabla reúne los mensajes de error más habituales en este tipo de flujo de trabajo.
| Mensaje | Causa | Solución |
|---|---|---|
fatal: not a git repository |
La carpeta actual no corresponde al repositorio, o este no se clonó correctamente | Verificar la existencia de una carpeta .git; en caso contrario, clonar nuevamente |
Please tell me who you are |
Git no ha sido configurado en esta máquina | Ejecutar git config --global user.name y user.email |
could not read Username for 'https://github.com' |
No hay credenciales almacenadas para el repositorio remoto | Reintentar el push e ingresar usuario y token cuando se solicite (ver sección de autenticación) |
rejected — non-fast-forward |
Existen commits en GitHub que la copia local no posee | Ejecutar pull (o sincronizar en Positron) antes de reintentar el push |
Permission denied (publickey) |
GitHub no reconoce la llave SSH configurada, o esta no existe | Utilizar HTTPS en lugar de SSH para el remoto, o revisar la configuración en GitHub → Settings → SSH Keys |
Marcas <<<<<<< en un archivo |
Dos personas modificaron la misma línea | Resolver manualmente en Positron (ver sección de conflictos), guardar, commit, push |
taller-git-positron-codex queda ahí después de hoy — sigue siendo el lugar para volver a probar cualquiera de estos escenarios cuando haga falta.