Taller de Git: ramas, Pull Requests y resolución de conflictos
- Modalidad: Asíncrona, por fuera de clase.
- Formato: En grupos de 2 a 5 integrantes, según grupos del proyecto del curso.
- Entregable: Repositorio grupal suministrado por el equipo docente con los cambios realizados en la rama
main.
Objetivos de aprendizaje
Sección titulada «Objetivos de aprendizaje»Al finalizar este taller, cada estudiante debe ser capaz de:
- Entender el área de staging y cómo se relaciona con los commits.
- Clonar un repositorio y trabajar en ramas (branches) sin afectar directamente la rama principal (
main). - Sincronizar su trabajo con el de sus compañeros usando
fetch,pullypush. - Guardar cambios temporalmente con
git stashy deshacer commits congit reset. - Abrir y revisar Pull Requests en GitHub.
- Identificar, entender y resolver personalmente un conflicto de merge, tanto desde la terminal como desde un editor de código.
Parte 1: Marco teórico
Sección titulada «Parte 1: Marco teórico»Contexto: ¿qué es Git y qué es GitHub?
Sección titulada «Contexto: ¿qué es Git y qué es GitHub?»Git es un sistema de control de versiones: una herramienta que corre en tu computador y que permite registrar el historial de cambios de un proyecto, crear líneas de desarrollo paralelas (ramas), y combinar el trabajo de varias personas sobre los mismos archivos.
GitHub es una plataforma web que aloja repositorios de Git en la nube y añade funcionalidades de colaboración: control de acceso, revisión de código mediante Pull Requests (PRs), issues, y más. En resumen:
- Git = la herramienta que versiona tu código (funciona incluso sin internet).
- GitHub = un servicio en línea que usa Git por debajo, y facilita que varias personas colaboren sobre un mismo repositorio remoto.
En este taller usarán ambos: Git para trabajar localmente, y GitHub para sincronizar su trabajo con el resto del grupo y para hacer las revisiones de código (PRs).
Conceptos y comandos que usarán
Sección titulada «Conceptos y comandos que usarán»El área de staging y los commits
Sección titulada «El área de staging y los commits»Git maneja tres “zonas” para tus archivos:
- Directorio de trabajo (working directory): los archivos tal como los ves y editas normalmente en tu computador.
- Área de staging (staging area o índice): una zona intermedia donde “preparas” los cambios que quieres incluir en el próximo commit. Cuando ejecutas
git add <archivo>, ese archivo (con sus cambios actuales) pasa del directorio de trabajo al área de staging. - Repositorio (historial de commits): cuando ejecutas
git commit, Git toma todo lo que esté en el área de staging en ese momento y lo guarda como un nuevo punto permanente en el historial.
El flujo de un cambio a través de las tres zonas se ve así:
flowchart LR
A["Directorio de trabajo<br/>(working directory)"] -->|"git add"| B["Área de staging<br/>(staging area)"]
B -->|"git commit"| C["Repositorio<br/>(historial de commits)"]
Esta separación es útil porque te permite elegir exactamente qué cambios quieres incluir en cada commit (por ejemplo, si modificaste dos archivos pero solo quieres confirmar uno, simplemente no le haces add al otro).
Cada git commit agrega un punto al historial. Una rama es simplemente una línea de trabajo paralela: te separas de main, haces tus propios commits sin afectar a los demás, y más adelante combinas (merge) tu trabajo de vuelta. Así se ve un historial con una rama que se crea y luego se mezcla:
gitGraph
commit id: "primer commit"
commit id: "segundo commit"
branch nueva-funcionalidad
checkout nueva-funcionalidad
commit id: "trabajo en la rama"
checkout main
commit id: "otro commit en main"
merge nueva-funcionalidad
commit id: "continúa el trabajo"
Comandos básicos
Sección titulada «Comandos básicos»| Comando | Qué hace |
|---|---|
git clone <url> |
Descarga una copia local de un repositorio remoto. |
git status |
Muestra el estado actual de tus archivos (modificados, en staging, etc.). |
git add <archivo> |
Mueve los cambios de un archivo del directorio de trabajo al área de staging. |
git commit -m "mensaje" |
Guarda lo que esté en el área de staging como un nuevo punto en el historial. |
git branch <nombre> |
Crea una nueva rama. |
git checkout <rama> / git switch <rama> |
Cambia a la rama indicada. |
git fetch |
Descarga los cambios del repositorio remoto, pero no los mezcla con tu trabajo local. |
git pull |
Equivale a fetch + merge: descarga y mezcla los cambios remotos en tu rama actual. |
git push |
Sube tus commits locales al repositorio remoto. |
git merge <rama> |
Combina los cambios de otra rama en la rama actual. |
git stash |
Guarda temporalmente los cambios que no has confirmado, dejando tu directorio de trabajo limpio. |
git stash pop |
Recupera el último cambio guardado con stash y lo vuelve a aplicar sobre tu directorio de trabajo. |
git reset --soft <commit> |
Mueve tu rama a un commit anterior, pero conserva tus cambios en el área de staging. |
git reset --hard <commit> |
Mueve tu rama a un commit anterior y descarta cualquier cambio posterior, tanto del área de staging como del directorio de trabajo. |
git stash y git stash pop
Sección titulada «git stash y git stash pop»A veces estás en medio de un cambio que no quieres (o no puedes) confirmar todavía, pero necesitas cambiar de rama momentáneamente, por ejemplo, para revisar el PR de un compañero. Si intentas cambiar de rama con cambios sin confirmar que chocan con la otra rama, Git no te va a dejar.
Para eso sirve git stash: guarda tus cambios actuales en una pila y deja tu directorio de trabajo limpio, como si no hubieras tocado nada.
flowchart LR
A["Directorio de trabajo<br/>(con cambios sin confirmar)"] -->|"git stash"| B["Directorio limpio<br/>(cambios guardados en la pila de stash)"]
B -->|"git stash pop"| C["Directorio de trabajo<br/>(con los cambios de vuelta)"]
git stash # guarda tus cambios sin confirmargit switch main # ahora puedes cambiar de rama sin problema# ... revisas el PR de tu compañero, por ejemplo ...git switch ronda-1-<tu-nombre> # vuelves a tu ramagit stash pop # recuperas los cambios que habías guardadogit stash pop aplica el último cambio guardado y lo elimina de la lista de “cambios guardados”.
git reset: soft vs. hard
Sección titulada «git reset: soft vs. hard»git reset mueve el puntero de tu rama actual a un commit anterior. Existen varias modalidades; las dos que deben conocer son:
git reset --soft <commit>: mueve tu rama al commit indicado, pero conserva todos los cambios posteriores en el área de staging, listos para volver a confirmarlos. Es útil, por ejemplo, para combinar varios commits pequeños en uno solo (deshaces los commits, pero no pierdes el trabajo).git reset --hard <commit>: mueve tu rama al commit indicado y descarta por completo cualquier cambio posterior, tanto del área de staging como del directorio de trabajo. Es útil cuando quieres “empezar de nuevo” desde un punto anterior y no te importa perder lo que hiciste después.
Imagina este historial, donde tu rama (HEAD) está en el commit D y quieres hacer git reset al commit B:
gitGraph
commit id: "A"
commit id: "B" type: HIGHLIGHT tag: "reset aquí"
commit id: "C" type: REVERSE
commit id: "D" type: REVERSE tag: "HEAD (antes)"
git reset B mueve HEAD de vuelta a B. Lo que cambia entre --soft y --hard es qué pasa con los cambios de los commits C y D que quedan por fuera: con --soft esos cambios quedan en el área de staging, con --hard se descartan por completo.
Cómo abrir y revisar un Pull Request en GitHub
Sección titulada «Cómo abrir y revisar un Pull Request en GitHub»Un Pull Request (PR) es una solicitud para mezclar los cambios de una rama hacia otra (en este taller, siempre de tu rama hacia main), que otra persona debe revisar antes de que se confirme la mezcla. No es un comando de Git, sino una funcionalidad de GitHub que se apoya en Git: primero subes tu rama con git push, y luego, desde GitHub, abres el PR para que quede disponible para revisión. Es el mecanismo que usan en este taller para asegurar que nadie mezcle cambios a main sin que alguien más del grupo los haya visto primero.
Abrir un Pull Request
Sección titulada «Abrir un Pull Request»-
Después de hacer
pushde tu rama, entra a la página del repositorio en GitHub. -
GitHub normalmente muestra un banner amarillo del tipo “
<tu-rama>had recent pushes” con un botón “Compare & pull request”; haz clic ahí. Si no aparece, ve a la pestaña “Pull requests” → “New pull request”.
-
Verifica que la rama base sea
mainy la rama compare sea la tuya (ronda-1-<tu-nombre>). GitHub te confirma si las ramas se pueden mezclar automáticamente (“Able to merge”) o si ya hay conflicto. -
Escribe un título claro (por ejemplo,
Agrega fila de <tu nombre> a la bitácora) y, en la descripción, una línea explicando qué hiciste.
-
Haz clic en “Create pull request”. Vas a caer en la página del PR ya creado, con pestañas para Conversation, Commits, Checks y Files changed, y un panel a la derecha con Reviewers, Assignees, Labels, etc. Si el repositorio tiene activada la protección de rama (ver la sección Preparación), vas a ver un aviso de “Review required” y el botón “Merge pull request” deshabilitado hasta que alguien más lo apruebe.

-
En el panel derecho, bajo “Reviewers”, haz clic en el ícono de engranaje ⚙️ para abrir el buscador, escribe el usuario de GitHub de un compañero y selecciónalo de la lista de sugerencias para pedirle explícitamente que revise tu PR. Esto no es obligatorio (cualquier colaborador con acceso puede revisar y aprobar igual), pero ayuda a que tu compañero se entere más rápido.

-
Mientras nadie haya revisado, el panel de “Reviewers” muestra a la persona solicitada con un punto naranja (revisión pendiente).

-
Cuando tu compañero aprueba el PR (ver la sección Revisar un Pull Request), el punto naranja cambia a un ✅ verde y aparece un mensaje como “
<usuario>approved these changes” en la conversación del PR. A partir de ahí, si no quedan más revisiones pendientes, el botón “Merge pull request” se habilita.
Revisar un Pull Request
Sección titulada «Revisar un Pull Request»-
Entra a la pestaña “Pull requests” del repositorio. Si te asignaron como reviewer de alguno, al pasar el mouse sobre su título vas a ver un aviso de “You have a pending review request”; ábrelo.

-
Dentro del PR, ve a la pestaña “Files changed” para ver el diff línea por línea: las líneas en verde son las que se agregaron, las líneas en rojo son las que se eliminaron. Arriba a la derecha vas a ver el botón “Submit review” (el equivalente al “Review changes” de versiones anteriores de GitHub) y un contador “0 / 1 viewed” con el que puedes ir marcando cada archivo como revisado.

-
Si el PR tiene un conflicto con
main, GitHub va a mostrar una advertencia tipo “This branch has conflicts that must be resolved”. Avísale a quien abrió el PR para que lo resuelva localmente (ver la sección Resolviendo conflictos, más abajo). -
Si quieres comentar algo puntual, pasa el mouse sobre una línea específica en “Files changed” y haz clic en el ícono
+azul que aparece a la izquierda de esa línea para dejar un comentario ahí.
-
Cuando estés de acuerdo con los cambios (y no haya conflictos pendientes), haz clic en “Submit review”. Se abre un panel “Finish your review” donde puedes escribir un comentario general y elegir una de tres opciones: “Comment” (feedback sin aprobar ni rechazar), “Approve” (aprueba y habilita la mezcla) o “Request changes” (pide que se corrija algo antes de aprobar). Selecciona “Approve” y haz clic en “Submit review” para confirmar.

-
De vuelta en la conversación del PR vas a ver tu aprobación reflejada como “
<tu-usuario>approved these changes”, junto con el aviso “Changes approved” y, si no hay conflictos, “No conflicts with base branch”. Desde ahí, cualquier integrante del grupo (usualmente quien lo revisó) puede hacer clic en “Merge pull request” y confirmar la mezcla amain.
Resolviendo conflictos: desde la terminal y desde el editor
Sección titulada «Resolviendo conflictos: desde la terminal y desde el editor»Cuando aparece un conflicto de merge, Git marca el archivo con marcas especiales:
<<<<<<< HEAD(el contenido que ya tenías en tu rama)=======(el contenido que viene de la otra rama)>>>>>>> origin/mainPueden resolverlo de dos formas:
Desde la terminal / un editor de texto simple: abren el archivo, deciden qué contenido conservar (el de arriba, el de abajo, o ambos), lo dejan escrito tal como debe quedar, y borran manualmente las tres marcas (<<<<<<<, =======, >>>>>>>).
Desde un editor con soporte de Git, como VSCode: VSCode detecta automáticamente los archivos en conflicto y muestra, justo encima de cada bloque en conflicto, botones como:

- “Accept Current Change”: conserva solo el contenido de tu rama (lo que está antes de
=======). - “Accept Incoming Change”: conserva solo el contenido que viene de la otra rama (lo que está después de
=======). - “Accept Both Changes”: conserva ambos bloques, uno después del otro.
- “Compare Changes”: abre una vista lado a lado para comparar antes de decidir.
Al hacer clic en cualquiera de estas opciones, VSCode elimina automáticamente las marcas de conflicto y deja solo el contenido elegido. En este taller, la resolución correcta casi siempre es “Accept Both Changes” (porque quieren conservar las filas de todos los integrantes), pero igual deben revisar el resultado con cuidado, ya que “ambos cambios” a veces necesita ajustes de formato (por ejemplo, el orden de las filas en la tabla). Después de resolver, el flujo sigue siendo el mismo: git add, git commit, git push.
Parte 2: Formato de trabajo
Sección titulada «Parte 2: Formato de trabajo»- Trabajarán en grupos de acuerdo a la asignación de grupos definida para el curso.
- Para esto, el grupo debe seleccionar a un integrante, que será inicialmente el
Integrante 1y será el encargado de crear el repositorio en GitHub a partir de este enunciado (o de la plantilla que les entregue el profesor), agregar a todo el resto del grupo como colaboradores, y hacer el primer PR con la asignación de integrantes que se describe en el siguiente paso. - Ningún cambio se sube directamente a
main. Todo cambio debe:- Hacerse en una rama distinta a
main. - Subirse (
push) a GitHub. - Convertirse en un Pull Request.
- Ser revisado y aprobado por otro integrante del grupo distinto de quien lo abrió antes de mezclarse (merge) a
main.
- Hacerse en una rama distinta a
- Nadie puede aprobar ni mezclar su propio PR, en ningún momento del taller. Esta regla queda configurada técnicamente en GitHub desde la preparación del repositorio (ver la sección Preparación, más abajo).
- El taller está diseñado para que cada integrante resuelva, en algún momento, un conflicto por sí mismo, no solo quienes tengan más experiencia previa con Git.
Parte 3: Instrucciones paso a paso
Sección titulada «Parte 3: Instrucciones paso a paso»Preparación
Sección titulada «Preparación»-
Cada integrante del grupo debe tener Git instalado en su computador:
- Windows: Git no viene instalado por defecto. Descárguenlo desde git-scm.com/download/win e instálenlo con las opciones por defecto.
- macOS y Linux: Git normalmente ya viene instalado. Pueden verificarlo abriendo una terminal y ejecutando
git --version; si no aparece una versión, instálenlo desde git-scm.com/downloads.
Necesitan una cuenta de GitHub asociada al correo Uniandes para todos los integrantes del grupo y haber informado su usuario de GitHub al equipo docente.
-
Un integrante, que de ahora en adelante llamaremos
Integrante 1, crea el repositorio del grupo y agrega al resto de integrantes como colaboradores. En este curso el repositorio no se crea directamente en GitHub, sino a través de Classroom 50:-
Inicia sesión en classroom50.org con tu cuenta de GitHub. En Classroom 50 organizations, busca la organización del curso (Ing. Software Moderna - ISIS2211) y haz clic en Open.

-
En My classrooms, ubica tu sección y entra con View assignments.

-
En la lista Assignments, busca la tarea grupal del taller (aparece marcada como Group y con estado Not accepted) y haz clic en Accept assignment.

-
Revisa que estés registrado con tu usuario correcto y que el repositorio se vaya a crear con el nombre esperado (algo como
ISIS2211/...-taller-git-<tu-usuario>). Confirma con Accept assignment.
-
Cuando aparezca Assignment accepted, haz clic en Edit collaborators para agregar al resto del grupo.

-
En la ventana de colaboradores, escribe el usuario de GitHub de un compañero en el campo de texto y haz clic en + Add. Repite para cada integrante del grupo.

-
Verifica que todos los integrantes aparezcan en Group members y guarda con Save collaborators.

-
Una vez que todos los integrantes hayan aceptado la invitación a la organización del curso, el
Integrante 1puede abrir el repositorio en GitHub con Open repository y continuar con los pasos siguientes.
-
-
(Obligatorio) El
Integrante 1configura una regla de protección de rama sobremain: enSettings > Branches > Branch protection rules, agrega una regla paramainy activa “Require a pull request before merging” junto con “Require approvals” (al menos 1). Esto hace que GitHub bloquee técnicamente cualquier intento de mezclar sin que otro integrante haya aprobado, en vez de depender solo de que el grupo respete la regla por acuerdo. Sin este paso, el taller no está correctamente configurado. -
Todos clonan el repositorio localmente:
Ventana de terminal git clone <url-del-repo> -
El resto del grupo (
Integrante 2aIntegrante N) acuerda el orden en el que van a mezclar sus PRs en cada ronda. -
El
Integrante 1registra ese orden enbitacora.md, siguiendo el mismo flujo de trabajo que se va a usar durante todo el taller:-
Crea una rama llamada
asignacion-integrantes:Ventana de terminal git switch -c asignacion-integrantes -
Escribe el orden acordado al inicio de
bitacora.md. -
Hace commit y push de la rama, y abre un Pull Request hacia
main:Ventana de terminal git add bitacora.mdgit commit -m "Agrega orden de integrantes a la bitácora"git push --set-upstream origin asignacion-integrantes -
Otro integrante del grupo revisa y aprueba el PR antes de mezclarlo.
-
El archivo bitacora.md ya viene con una sección ## Bitácora del equipo con esta tabla, donde cada integrante va a agregar su fila más adelante:
| Integrante | Rama |
|---|---|
Ronda 1
Sección titulada «Ronda 1»Paso 1.1: Trabajo en paralelo
Sección titulada «Paso 1.1: Trabajo en paralelo»Todos los integrantes, al mismo tiempo y sin esperarse entre sí, crean su propia rama desde el mismo punto de main y agregan una fila a la tabla de bitacora.md con su información:
git switch -c ronda-1-<tu-nombre>Edita bitacora.md y agrega tu fila a la tabla, luego:
git add bitacora.mdgit commit -m "Agrega fila de <tu nombre> a la bitácora"git push --set-upstream origin ronda-1-<tu-nombre>Paso 1.2: Abrir y mezclar los PRs en el orden acordado
Sección titulada «Paso 1.2: Abrir y mezclar los PRs en el orden acordado»-
Cada integrante abre un Pull Request de su rama hacia
main(ver la sección Cómo abrir y revisar un Pull Request en GitHub). -
Van mezclando los PRs uno a la vez, en el orden acordado (
Integrante 1primero, luegoIntegrante 2, y así sucesivamente hastaIntegrante N). Cada PR debe ser revisado y aprobado por un integrante distinto de quien lo abrió antes de mezclarse. -
El PR de
Integrante 1no debería tener conflicto, porque es el primero en mezclarse. -
A partir del PR de
Integrante 2en adelante, cada uno va a encontrar un conflicto contra elmainya actualizado por los PRs anteriores. Quien esté en ese turno debe resolverlo localmente, por su cuenta:Ventana de terminal git fetch origingit merge origin/main -
Resuelve el conflicto (en la terminal o en el editor, ver la sección Resolviendo conflictos), dejando todas las filas en la tabla (la tuya y las que ya estaban), sin perder información de nadie.
-
Confirma la resolución y actualiza tu PR:
Ventana de terminal git add bitacora.mdgit commit -m "Resuelve conflicto de merge en la bitácora"git push -
Otro integrante revisa el PR ya sin conflictos, lo aprueba, y lo mezclan.
-
Repitan los pasos 4 a 7 para cada integrante restante, en el orden acordado, hasta que los
NPRs de la ronda estén mezclados.
Ronda 2
Sección titulada «Ronda 2»Al terminar la Ronda 1, cada integrante quedó trabajando en su propia rama ronda-1-<tu-nombre>. Antes de empezar la Ronda 2, todos deben volver a main y traer los cambios más recientes:
git switch maingit pullDesde ahí, repitan exactamente la misma mecánica de la Ronda 1 (todos crean una nueva rama desde el main actualizado y agregan una nueva fila a la tabla, esta vez nombrando sus ramas ronda-2-<tu-nombre>), pero esta vez mezclen los PRs en el orden inverso (Integrante N primero, …, Integrante 1 al final).
De esta forma, quien no tuvo que resolver un conflicto en la Ronda 1 (Integrante 1, por ser el primero) sí lo hará en la Ronda 2 (por quedar de último), y viceversa para Integrante N. Al final de las dos rondas, cada integrante del grupo habrá resuelto al menos un conflicto de merge por su cuenta, y nadie habrá aprobado o mezclado su propio PR. También va a quedar con 2 filas en la tabla de la bitácora, una por cada ronda.
Entregable final
Sección titulada «Entregable final»- Todos los PRs de ambas rondas mezclados a
main. - Los conflictos resueltos correctamente en
bitacora.md(la tabla debe contener las filas de todos los integrantes en cada ronda, sin marcas de conflicto remanentes). - La regla de protección de rama sobre
mainconfigurada (ver la sección Preparación).
El entregable final es el repositorio grupal completo con todos los cambios en la rama main, con todo el historial de commits y PRs, subido a GitHub. No se requiere entregar un archivo comprimido ni un enlace adicional: el repositorio en GitHub es suficiente.
Recomendaciones
Sección titulada «Recomendaciones»-
Hagan
commits pequeños y con mensajes descriptivos. Por ejemplo:Ventana de terminal git commit -m "Agrega fila de Juan a la bitácora"Eviten mensajes genéricos como:
Ventana de terminal git commit -m "cambios"y eviten juntar varios cambios distintos (por ejemplo, agregar tu fila y corregir algo de formato en otra parte del archivo) en un mismo commit. Los commits pequeños y descriptivos facilitan que tu compañero entienda qué cambió al revisar tu PR, y hacen más fácil ubicar en qué punto del historial se introdujo un error si algo sale mal.
-
Coordínense sobre el orden acordado antes de empezar. Si dos personas intentan mezclar al mismo tiempo sin seguir el orden, pueden generarse conflictos adicionales no planeados que también deberán resolver.
-
Si algo sale mal, no borren el repositorio: pregunten primero, casi todos los errores de Git son reversibles.
-
Recuerden que esta semana también tienen otra entrega asincrónica del curso. No dejen este taller para el último momento: la resolución de conflictos puede tomar algo de tiempo la primera vez, y en grupos más grandes hay más turnos que completar.