Git & GitHub
Curso para principiantes

Curso de Git y GitHub

Aprende control de versiones desde cero. Un curso práctico y progresivo que te llevará desde la configuración inicial hasta flujos de trabajo colaborativos profesionales con GitHub.

Incluye instrucciones para WSL (Windows) y macOS. No necesitas experiencia previa con Git: si puedes usar la terminal básica, puedes aprender Git.

~10 horas
10 módulos
Desde cero

El timer Pomodoro te ayuda a estudiar en bloques cortos de concentración (25 min) con descansos. Está demostrado que mejora el aprendizaje y reduce la fatiga mental.

💻

Prerequisito: Terminal básica

Necesitas saber abrir una terminal y ejecutar comandos básicos (cd, ls, mkdir). Si aún no lo dominas, haz primero el curso de Terminal y Bash.

Ir al curso de Terminal y Bash →
⚙️

Prerequisito: Entorno de desarrollo

Antes de empezar, necesitas tener tu entorno listo: terminal, editor de código, Git y Node.js instalados. Si aún no configuraste tu computador, sigue primero esta guía paso a paso.

Ir a Configuración del Entorno →
📊

Parte de Hazla con Datos

Este curso es un recurso complementario de Hazla con Datos, una comunidad enfocada en programación y ciencia de datos en salud. Encuentra más cursos, recursos y herramientas para tu camino profesional.

Visitar hazlacondatos.com →
01

Prerequisitos de terminal

Antes de empezar: lo que necesitas saber de la terminal

Git es una herramienta que se usa desde la terminal. Para seguir este curso, necesitas poder navegar entre carpetas, crear archivos y ver su contenido. No necesitas ser experto — solo manejar estos comandos básicos.

💡

¿Nunca has usado la terminal?

Si es tu primera vez, completa primero el curso de Terminal y Bash. Te tomará poco tiempo y te dará la base que necesitas. Si ya lo hiciste o ya te manejas con la terminal, sigue directo al Módulo 2.

¿Cómo abro la terminal?

En WSL (Windows): Busca “Ubuntu 24.04” o “Terminal” en el menú de inicio.

En macOS: Abre Spotlight con Cmd + Espacio, escribe “Terminal” y presiona Enter.

En Linux: Busca “Terminal” en tus aplicaciones o usa el atajo Ctrl + Alt + T.


Checklist de comandos esenciales

Antes de continuar, asegúrate de que puedes hacer cada una de estas cosas en tu terminal. Si alguna te suena desconocida, revisa el curso de Terminal y Bash.

Comando Descripción
pwd Saber en qué carpeta estás
ls -la Ver archivos, incluyendo ocultos (necesario para ver .git)
cd carpeta / cd .. / cd ~ Moverte entre carpetas
mkdir nombre Crear carpetas
touch archivo Crear archivos vacíos
echo "texto" > archivo Crear un archivo con contenido (> sobreescribe, >> agrega)
cat archivo Ver el contenido de un archivo

Verificación rápida

Si puedes ejecutar estos comandos sin problema, estás listo:

Terminal window
mkdir test-terminal && cd test-terminal
echo "Hola Git" > prueba.txt
cat prueba.txt
ls -la
cd ..

Tab: tu mejor amigo

Cuando escribas nombres de carpetas o archivos, presiona Tab para autocompletar. Los programadores profesionales lo usan todo el tiempo — es más rápido y evita errores de tipeo.

Si todo funciona, ya tienes lo que necesitas. ¡Vamos al Módulo 2!

02

Configuración inicial

Presentarte ante Git, como el primer día de clases

Antes de usar Git, necesitas entender qué es, por qué existe y cómo piensa. Después lo configuraremos con tu identidad para que puedas empezar a usarlo.


El problema que Git resuelve

Imagina que estás escribiendo un informe importante. Llevas horas trabajando y haces un cambio que rompe todo. ¿Qué haces? Probablemente piensas “ojalá pudiera volver a la versión de hace 5 minutos”.

Ahora imagina algo peor: trabajas con 3 compañeros en el mismo proyecto. Cada uno tiene una copia del código en su computador. Alguien modifica un archivo, otro modifica el mismo archivo, un tercero borra algo sin querer. ¿Cómo juntan todo sin volverse locos? ¿Cómo saben quién cambió qué, cuándo y por qué?

Antes de Git, la gente resolvía esto de formas… creativas:

mi-proyecto-final.zip
mi-proyecto-final-v2.zip
mi-proyecto-final-DEFINITIVO.zip
mi-proyecto-final-DEFINITIVO-ahora-si.zip
mi-proyecto-final-NO-TOCAR.zip

¿Te suena familiar? Este sistema “funciona” para una persona con un documento pequeño. Pero en software, donde un proyecto puede tener cientos de archivos y decenas de personas trabajando al mismo tiempo, es una receta para el desastre.

Git nació para resolver exactamente este caos.


¿Qué es Git?

Git es un sistema de control de versiones. En palabras simples: es un programa que registra todos los cambios que haces en tus archivos, te permite volver a cualquier versión anterior y coordinar el trabajo de múltiples personas sobre el mismo proyecto.

Piensa en Git como tres cosas a la vez:

  1. Una máquina del tiempo — Puedes volver a cualquier punto en la historia de tu proyecto. ¿El código funcionaba el martes pero hoy no? Vuelves al martes y comparas qué cambió.

  2. Un cuaderno de bitácora — Cada cambio queda registrado: qué se modificó, quién lo hizo, cuándo y por qué. Es un historial completo y detallado de la evolución de tu proyecto.

  3. Un coordinador de equipo — Permite que varias personas trabajen en el mismo proyecto simultáneamente, cada una en su propia “copia de trabajo”, y luego combinar todos los cambios de forma ordenada.

¿Cómo funciona conceptualmente?

Git funciona tomando “fotos” (snapshots) de tu proyecto. Cada vez que le dices “guarda este momento” (lo que se llama un commit), Git registra el estado exacto de todos tus archivos en ese instante.

Commit 1 Commit 2 Commit 3 Commit 4
📸 📸 📸 📸
"Proyecto "Agrego "Corrijo "Agrego
vacío" login" un bug" estilos"

Estas fotos se encadenan en una línea de tiempo. Puedes moverte hacia adelante y hacia atrás por esa línea, comparar fotos entre sí, o incluso crear líneas paralelas (ramas) para experimentar sin afectar el trabajo principal.

Lo más importante: Git vive en tu computador. Todo funciona sin internet. Cada copia de un proyecto con Git tiene la historia completa, no depende de un servidor central. Esto es lo que significa que sea “distribuido”: cada persona tiene la película entera, no solo el último fotograma.

💡

Un poco de historia

Git fue creado en 2005 por Linus Torvalds, el mismo creador de Linux. Lo construyó porque necesitaba una herramienta rápida y confiable para coordinar el trabajo de miles de programadores que contribuyen al kernel de Linux. Hoy, Git es el estándar de la industria: lo usan desde startups de 2 personas hasta empresas como Google, Microsoft y Meta.


¿Qué NO es Git?

Esto genera mucha confusión al principio, así que vamos a dejarlo claro:

Git NO es GitHub. Esta es la confusión más común. Son cosas diferentes que trabajan juntas:

  • Git es la herramienta que se instala en tu computador. Registra cambios, crea versiones, maneja ramas. Funciona completamente offline.
  • GitHub es un servicio web (una página de internet) donde puedes subir tus proyectos Git para tener un respaldo en la nube y colaborar con otras personas.

La analogía: Git es tu cámara de fotos (toma y organiza las fotos). GitHub es la galería en la nube donde las compartes (como Google Photos o iCloud). Puedes usar la cámara sin la galería, y la galería no sirve sin fotos.

Existen otros servicios similares a GitHub: GitLab, Bitbucket, Codeberg… todos usan Git por debajo, solo cambia la plataforma web. Si aprendes Git, puedes usar cualquiera de ellos.

Git NO es solo para programadores. Funciona con cualquier archivo de texto: documentación, configuraciones, notas, datos en CSV, scripts de análisis. Si trabajas con archivos de texto, Git puede ayudarte.

Git NO sube nada a internet automáticamente. Todo lo que haces con Git es local hasta que tú decides subirlo. Puedes trabajar semanas sin conexión y subir todo después. Tú controlas cuándo y qué compartes.

Git NO guarda copias completas de cada versión repetida. Es más inteligente que eso: internamente guarda snapshots (fotos) de tus archivos, pero si un archivo no cambió entre versiones, reutiliza el que ya tiene en vez de duplicarlo. Esto lo hace increíblemente eficiente. Un proyecto con miles de versiones puede ocupar menos espacio que unas pocas copias manuales de archivos zip.


Instalación de Git

WSL (Windows) y Linux

Abre tu terminal y ejecuta estos dos comandos:

Terminal window
sudo apt update
sudo apt install git

El primero actualiza la lista de programas disponibles. El segundo instala Git. Te puede pedir tu contraseña (es la contraseña de tu usuario en Linux/WSL).

macOS

La forma más fácil: simplemente ejecuta git en la terminal. Si no está instalado, macOS te ofrecerá instalarlo automáticamente.

Terminal window
git --version
# Si no está instalado, aparecerá un diálogo para instalarlo

Alternativa con Homebrew (si lo tienes): brew install git

Para verificar que se instaló correctamente:

Terminal window
git --version
# git version 2.43.0 (o la versión que sea)

Si ves un número de versión, ¡perfecto! Git está instalado.


Configurar tu identidad

Git necesita saber quién eres para firmar tus cambios. Es como poner tu nombre en un trabajo de la escuela: cada cambio que guardes llevará tu nombre.

Configura tu nombre:

Terminal window
git config --global user.name "Tu Nombre Completo"

Reemplaza "Tu Nombre Completo" por tu nombre real (con las comillas).

Configura tu correo electrónico:

Terminal window
git config --global user.email "tu@correo.com"
⚠️

Usa el mismo correo que en GitHub

Cuando crees tu cuenta de GitHub (en el Módulo 4), usa el mismo correo que pusiste aquí. Así GitHub reconocerá tus contribuciones automáticamente.

¿Qué significa --global? Que esta configuración aplica para todos tus proyectos en este computador. Solo necesitas hacerlo una vez.


Configurar el editor de texto

Cuando Git necesita que escribas algo (como un mensaje largo), abre un editor de texto. Por defecto puede abrir Vim, que es un editor muy poderoso pero confuso para principiantes.

💡

La trampa de Vim

Si alguna vez tu terminal se queda “atrapada” en una pantalla rara con tildes (~) por todos lados… ¡caíste en Vim! No te preocupes, le pasa a todo el mundo. Para escapar: presiona Esc, escribe :q! y presiona Enter. Listo, estás libre.

Para evitar ese problema, configuramos VS Code como editor:

Terminal window
git config --global core.editor "code --wait"

El --wait le dice a Git que espere a que cierres el archivo en VS Code antes de continuar.


Configurar la rama principal

Por convención moderna, la rama principal se llama main. Configuremos eso:

Terminal window
git config --global init.defaultBranch main

No te preocupes si no entiendes qué son las “ramas” todavía. Lo veremos en el Módulo 6. Por ahora solo estamos dejando todo bien configurado.


Verificar tu configuración

Para ver todo lo que configuraste:

Terminal window
git config --list
# user.name=Tu Nombre Completo
# user.email=tu@correo.com
# core.editor=code --wait
# init.defaultbranch=main

Si ves tus datos ahí, ¡todo está perfecto!

⚠️

Esto se hace UNA SOLA VEZ

Toda esta configuración se hace una sola vez por computador. No necesitas repetirla en cada proyecto nuevo.

¿Te equivocaste?

Si escribiste mal tu nombre o correo, simplemente ejecuta el comando de nuevo con el valor correcto. El nuevo valor reemplaza al anterior. No pasa nada malo.


Tabla resumen

Comando Descripción
git --version Verificar que Git está instalado
git config --global user.name "nombre" Configurar tu nombre
git config --global user.email "correo" Configurar tu correo
git config --global core.editor "code --wait" Configurar VS Code como editor
git config --global init.defaultBranch main Configurar la rama principal como main
git config --list Ver toda tu configuración

Ejercicios del módulo

Ejercicio 1: Instala Git en tu computador y verifica la instalación con git --version. ¿Qué versión tienes?

Ejercicio 2: Configura tu nombre y correo electrónico:

Terminal window
git config --global user.name "Tu Nombre"
git config --global user.email "tu@correo.com"

Ejercicio 3: Configura VS Code como tu editor por defecto:

Terminal window
git config --global core.editor "code --wait"

Ejercicio 4: Verifica que toda tu configuración está correcta:

Terminal window
git config --list

¿Aparecen tu nombre, correo y editor? ¡Excelente, estás listo para empezar a usar Git!

💡

¡Configuración completa!

Ya tienes Git instalado y configurado. En el siguiente módulo vamos a crear nuestro primer repositorio y hacer nuestros primeros commits. ¡Ahí es donde empieza la magia!

03

El ciclo de vida local

Git como un fotógrafo: preparar la foto y tomarla

Este es el módulo más importante del curso. Aquí aprenderás el flujo fundamental de Git que usarás el 90% del tiempo. Si entiendes este módulo, entiendes Git.

Piensa en Git como un fotógrafo profesional:

  1. Primero preparas a las personas para la foto (staging)
  2. Luego tomas la foto (commit)
  3. Esa foto queda guardada en un álbum (repositorio)

En términos de Git:

Carpeta de trabajo → Área de staging → Repositorio
(Working Directory) (git add) (git commit)
Donde editas tus Donde preparas Donde se guardan
archivos normalmente lo que quieres las "fotos" de
guardar tu proyecto

git init — Activar los poderes de Git en una carpeta

git init le dice a Git: “quiero que vigiles esta carpeta”. Crea una carpeta oculta llamada .git/ donde Git guarda toda su información.

Terminal window
# Crear una carpeta para nuestro proyecto
mkdir mi-receta
cd mi-receta
# Activar Git en esta carpeta
git init
# Initialized empty Git repository in /home/tu-usuario/mi-receta/.git/
# Verificar que se creó la carpeta oculta .git
ls -la
# drwxr-xr-x 7 tu-usuario tu-usuario 4096 ene 15 11:00 .git

¡Esa carpeta .git es donde vive toda la magia! Mientras exista, Git está vigilando tu proyecto.

⚠️

¡Cuidado con los git init anidados!

Nunca hagas git init dentro de una carpeta que ya está dentro de otro repositorio Git. Esto crea problemas muy confusos. Si no estás seguro, haz git status primero: si dice “not a git repository”, entonces sí puedes hacer git init.


git status — El radar (tu comando favorito)

Si solo pudieras aprender UN comando de Git, debería ser este. git status te dice exactamente qué está pasando en tu proyecto: qué archivos cambiaste, qué está listo para guardar y qué falta.

Vamos a ver cómo funciona paso a paso:

Terminal window
# Justo después de git init, sin archivos:
git status
# On branch main
# No commits yet
# nothing to commit (create/copy files and use "git add" to track)

Git te dice: “Estás en la rama main, no hay commits todavía, y no hay nada que guardar”. Perfecto.

Ahora creemos un archivo:

Terminal window
# Crear un archivo
echo "# Mi primera receta" > receta.txt
git status
# On branch main
# No commits yet
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# receta.txt
# nothing added to commit but untracked files present

¿Ves que receta.txt aparece en rojo como Untracked (sin seguimiento)? Git lo ve, pero no lo está vigilando todavía. Es como alguien que está en la habitación pero no está en la foto.


git add — Preparar la foto (staging)

git add mueve archivos al área de staging (zona de preparación). Es como decirle a alguien “ponte aquí para la foto”.

Terminal window
# Agregar un archivo específico al staging
git add receta.txt
git status
# On branch main
# No commits yet
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
# new file: receta.txt

¡Ahora el archivo aparece en verde bajo “Changes to be committed”! Está listo para la foto.

Si tienes varios archivos y quieres agregar todos de una vez:

Terminal window
git add .

El punto (.) significa “todo lo que hay en esta carpeta”.

El hábito más importante

Siempre revisa git status ANTES y DESPUÉS de git add. Es como mirar antes y después de cruzar la calle. Te va a ahorrar muchos dolores de cabeza.


git diff — La lupa antes de guardar

git diff te muestra exactamente qué cambió en tus archivos, línea por línea. Las líneas con + (en verde) son lo que agregaste, y las líneas con - (en rojo) son lo que eliminaste.

Terminal window
# Primero, modifiquemos nuestro archivo
echo "Pasta con salsa de tomate" >> receta.txt
# Ver los cambios ANTES de hacer add
git diff
# diff --git a/receta.txt b/receta.txt
# --- a/receta.txt
# +++ b/receta.txt
# @@ -1 +1,2 @@
# # Mi primera receta
# +Pasta con salsa de tomate

Ese +Pasta con salsa de tomate en verde te dice que esa línea fue agregada.

Si ya hiciste git add y quieres ver qué está en el staging:

Terminal window
git diff --staged
💡

¿Por qué git diff muestra cambios si ya hicimos git add?

Porque modificamos el archivo después de hacer git add. El git add anterior preparó la versión original del archivo (solo con ”# Mi primera receta”). La línea que agregamos después existe en tu carpeta de trabajo pero NO está en el staging. Para incluirla, tendrías que hacer git add receta.txt de nuevo. Esto es importante: git add captura el estado del archivo en ese momento, no los cambios futuros.


git commit -m "mensaje" — Tomar la foto

git commit toma la “foto” de todo lo que está en el staging y la guarda permanentemente en el historial. El -m te permite escribir un mensaje que describe qué hiciste.

Antes de hacer el commit, agreguemos la línea nueva al staging:

Terminal window
git add receta.txt
git commit -m "feat: agrega receta inicial de pasta"
# [main (root-commit) a1b2c3d] feat: agrega receta inicial de pasta
# 1 file changed, 2 insertions(+)
# create mode 100644 receta.txt

¡Felicidades, acabas de crear tu primer commit! Git te confirma:

  • La rama donde estás (main)
  • Un identificador único (a1b2c3d — el tuyo será diferente)
  • Tu mensaje
  • Cuántos archivos cambiaron

Buenos mensajes de commit

Buenos mensajes: “Agrega formulario de contacto”, “Corrige error en el cálculo de precios”, “Actualiza estilos del header”

Malos mensajes: “cambios”, “fix”, “asdfg”, “wip”, “cosas”

Un buen mensaje responde a: “¿Qué hice y por qué?” Tu yo del futuro te lo agradecerá.


Conventional Commits — El formato profesional (recomendado)

Existe un estándar muy usado en equipos profesionales llamado Conventional Commits. La idea es agregar un prefijo al mensaje que indica el tipo de cambio:

tipo: descripción breve del cambio

Los tipos más comunes:

TipoSignificadoEjemplo
feat:Nueva funcionalidadfeat: agrega filtro por categoría
fix:Corrección de errorfix: corrige validación de email vacío
docs:Documentacióndocs: actualiza guía de instalación
refactor:Reestructurar sin cambiar funcionalidadrefactor: extrae función de validación
chore:Mantenimiento (dependencias, config)chore: actualiza dependencias
Terminal window
# Con Conventional Commits
git commit -m "feat: agrega botón de exportar a PDF"
git commit -m "fix: corrige cálculo de impuestos en factura"
git commit -m "docs: agrega sección de FAQ al README"

No es obligatorio usarlo al inicio, pero te recomendamos adoptarlo desde ahora. Cuando trabajes en equipo (Módulo 10), será la convención estándar. Y si lo practicas desde aquí, ya te saldrá natural.

💡

Reglas prácticas para mensajes

  • Usa el imperativo: “agrega”, “corrige”, “elimina” (no “agregué” ni “agregando”)
  • Primera línea: máximo 72 caracteres
  • Que responda a “¿Qué hice y por qué?”

git log — El álbum de fotos

git log te muestra el historial de todos los commits (fotos) que has tomado. Es tu álbum de fotos del proyecto.

Terminal window
git log
# commit a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 (HEAD -> main)
# Author: Tu Nombre <tu@correo.com>
# Date: Lun Ene 15 11:30:00 2024
#
# Agrega receta inicial de pasta

Para una versión más compacta (muy útil cuando tienes muchos commits):

Terminal window
git log --oneline
# a1b2c3d Agrega receta inicial de pasta

Cada línea es un commit. El código raro del principio (a1b2c3d) es el hash: un identificador único para ese commit. Es como el número de serie de cada foto.


.gitignore — Archivos que Git debe ignorar

No todos los archivos deben ser rastreados por Git. Archivos temporales, contraseñas, configuraciones locales… hay cosas que no quieres en tu repositorio. Para eso existe .gitignore.

Crea un archivo llamado .gitignore (con el punto al inicio) en la raíz de tu proyecto:

Terminal window
# Crear .gitignore línea por línea
echo "# Archivos del sistema operativo" > .gitignore
echo ".DS_Store" >> .gitignore
echo "Thumbs.db" >> .gitignore
echo "" >> .gitignore
echo "# Archivos con contraseñas o datos sensibles" >> .gitignore
echo ".env" >> .gitignore
echo "*.secret" >> .gitignore
echo "" >> .gitignore
echo "# Carpetas de dependencias (se regeneran)" >> .gitignore
echo "node_modules/" >> .gitignore
echo "" >> .gitignore
echo "# Archivos temporales" >> .gitignore
echo "*.tmp" >> .gitignore
echo "*.log" >> .gitignore
git add .gitignore
git commit -m "chore: agrega .gitignore"

Recuerda: > crea el archivo (o lo sobreescribe), >> agrega al final sin borrar lo anterior.

Cada línea es un patrón. Los archivos que coincidan serán invisibles para Git: no aparecerán en git status ni se subirán a GitHub.

¿Cuándo crear el .gitignore?

Idealmente al inicio de tu proyecto, como uno de los primeros archivos. Así evitas subir accidentalmente archivos que no deberían estar en el repositorio. En los ejercicios finales lo practicarás.


Ejemplo práctico completo

Hagamos un ejercicio guiado de principio a fin. Escribe cada comando y observa el resultado:

Terminal window
# 1. Crear y entrar al proyecto
mkdir mi-receta && cd mi-receta
# 2. Activar Git
git init
# 3. Crear .gitignore (siempre hazlo antes de tu primer commit)
echo "# Archivos del sistema operativo" > .gitignore
echo ".DS_Store" >> .gitignore
echo "Thumbs.db" >> .gitignore
echo "" >> .gitignore
echo "# Archivos con datos sensibles" >> .gitignore
echo ".env" >> .gitignore
echo "" >> .gitignore
echo "# Carpetas de dependencias" >> .gitignore
echo "node_modules/" >> .gitignore
echo "" >> .gitignore
echo "# Archivos temporales" >> .gitignore
echo "*.tmp" >> .gitignore
echo "*.log" >> .gitignore
# 4. Crear el primer archivo
echo "# Receta de Pasta" > receta.txt
# 5. Ver el estado (archivos en rojo, sin seguimiento)
git status
# 6. Preparar los archivos para la foto
git add .gitignore receta.txt
# 7. Ver el estado (archivos en verde, listos)
git status
# 8. Tomar la foto (hacer commit)
git commit -m "feat: agrega receta inicial y .gitignore"
# 9. Agregar más contenido
echo "" >> receta.txt
echo "## Ingredientes" >> receta.txt
echo "- 500g de pasta" >> receta.txt
echo "- 1 lata de tomate" >> receta.txt
echo "- Sal y pimienta" >> receta.txt
# 10. Ver qué cambió
git diff
# 11. Preparar y tomar otra foto
git add receta.txt
git commit -m "feat: agrega lista de ingredientes"
# 12. Ver el álbum de fotos
git log --oneline
# b2c3d4e feat: agrega lista de ingredientes
# a1b2c3d feat: agrega receta inicial y .gitignore

¿Ves que el .gitignore fue parte del primer commit? Así cualquier archivo temporal o sensible queda excluido desde el inicio (revisa la sección de .gitignore más arriba para entender cada línea).

¡Acabas de crear un proyecto con dos commits! Tienes dos “fotos” guardadas de tu proyecto. Podrías volver a cualquiera de ellas en cualquier momento (lo veremos en el módulo siguiente).

💡

¿Y cómo comparto esto con el mundo?

Todo lo que acabas de hacer vive solo en tu computador. Si tu disco duro muere mañana, pierdes todo. En el Módulo 4 aprenderás a subir tu proyecto a GitHub para tener un respaldo en la nube y poder compartirlo con otras personas.


Tabla resumen

Comando Descripción
git init Activar Git en la carpeta actual
git status Ver el estado de tus archivos (¡úsalo siempre!)
git add archivo Preparar un archivo para el commit
git add . Preparar TODOS los archivos modificados
git diff Ver cambios que aún no están en staging
git diff --staged Ver cambios que ya están en staging
git commit -m "mensaje" Guardar una "foto" del proyecto
git log Ver historial completo de commits
git log --oneline Ver historial compacto de commits

Ejercicios del módulo

Ejercicio 1: Crea una carpeta practica-git, inicialízala con git init y verifica con ls -la que existe la carpeta .git.

Terminal window
mkdir practica-git
cd practica-git
git init
ls -la
# ¿Ves la carpeta .git? ¡Git está activado!

Ejercicio 2: Crea un archivo notas.txt y escribe algo dentro:

Terminal window
echo "Hola Git, este es mi primer archivo" > notas.txt

Ejercicio 3: Usa git status. ¿De qué color aparece el archivo? (Debería aparecer en rojo como “Untracked”).

Ejercicio 4: Haz git add notas.txt y luego git status otra vez. ¿Cambió el color? (Ahora debería estar en verde).

Ejercicio 5: Haz tu primer commit con un mensaje descriptivo:

Terminal window
git commit -m "feat: agrega archivo de notas inicial"

Ejercicio 6: Modifica el archivo, usa git diff para ver los cambios, luego haz add y commit:

Terminal window
echo "Hoy aprendí git add y git commit" >> notas.txt
git diff
# Deberías ver la línea nueva con un + en verde
git add notas.txt
git commit -m "docs: agrega nota sobre lo aprendido hoy"
git log --oneline
# Deberías ver 2 commits
💡

¡Ya sabes lo fundamental!

El flujo git statusgit addgit commit es lo que usarás el 90% del tiempo. Si dominas esto, dominas lo esencial de Git. Lo demás es construir sobre esta base. ¡No te preocupes si necesitas repetir estos ejercicios varias veces!

04

GitHub: tu código en la nube

GitHub es como Google Drive pero para código

Hasta ahora, todo lo que has hecho con Git es local: vive solo en tu computador. Si tu disco duro muere mañana, pierdes todo.

GitHub es un servicio en la nube donde puedes subir tus repositorios Git. Piensa en la diferencia así:

  • Git = la herramienta que instalaste en tu computador (la cámara de fotos)
  • GitHub = un servicio web donde subes tus repositorios (Instagram para código)

GitHub te da dos cosas fundamentales:

  1. Respaldo: Tu código está seguro en la nube
  2. Colaboración: Otras personas pueden ver, descargar y contribuir a tu código

Crear tu cuenta en GitHub

Si todavía no tienes cuenta:

  1. Ve a github.com y haz clic en “Sign up”
  2. Usa el mismo correo que configuraste en Git (Módulo 2)
  3. Elige un nombre de usuario que te guste (será tu identidad como desarrollador)
  4. Completa el proceso de verificación

Instalar la app de GitHub (recomendado)

Antes de seguir, instala la app de GitHub en tu teléfono. La app te permite aprobar solicitudes de autenticación desde una notificación: cuando necesites autenticarte (por ejemplo con gh auth login), GitHub te manda una notificación al teléfono en vez de pedirte tokens o contraseñas.

Dos razones para instalarla ahora:

  1. Seguridad: la app te permite activar verificación en dos pasos (2FA) usándola como método de aprobación, sin necesidad de configurar SMS ni apps de códigos
  2. Configurar otros computadores es trivial: si mañana usas otro computador, solo ejecutas gh auth login y apruebas desde el teléfono — sin copiar tokens ni generar llaves SSH

Cómo instalarla:

  1. Descarga GitHub Mobile desde la App Store (iOS) o Google Play (Android)
  2. Inicia sesión con la cuenta de GitHub que acabas de crear
  3. Acepta los permisos de notificaciones

Esto te va a servir en unos minutos

Cuando lleguemos a gh auth login en la sección de autenticación, vas a poder aprobar la conexión directamente desde tu teléfono — sin copiar códigos ni abrir el navegador.


Crear un repositorio en GitHub

Vamos a crear un repositorio vacío en GitHub para subir nuestro proyecto:

  1. En GitHub, haz clic en el botón verde “New” (o en el + de la esquina superior derecha → “New repository”)
  2. Ponle un nombre (ejemplo: mi-receta)
  3. NO marques “Add a README file” (queremos un repo vacío)
  4. NO selecciones un .gitignore ni licencia por ahora
  5. Haz clic en “Create repository”

GitHub te mostrará una página con instrucciones. Esas instrucciones son exactamente lo que haremos a continuación.


Configurar autenticación

Para que Git pueda subir código a GitHub, necesitas autenticarte. La forma más fácil para principiantes:

Opción recomendada: GitHub CLI (gh)

La forma más fácil de autenticarte es con GitHub CLI:

Instalar en WSL/Linux (Ubuntu 24.04):

Terminal window
sudo apt update
sudo apt install gh

Si apt no encuentra el paquete gh, visita cli.github.com para ver cómo agregar el repositorio oficial de GitHub CLI a tu sistema.

Instalar en macOS:

Terminal window
brew install gh

Autenticarte:

Terminal window
gh auth login

Sigue las instrucciones en pantalla: elige “GitHub.com”, “HTTPS”, y “Login with a web browser”. Se abrirá tu navegador para autorizar.

Si instalaste la app de GitHub en tu teléfono, la autorización te llega como notificación — solo aprueba desde ahí y listo.

💡

¿Existe otra forma de autenticarse?

Sí: SSH y tokens personales. Pero gh auth login es la forma más simple y segura para empezar. Configura todo automáticamente y no necesitas manejar tokens ni llaves. Si más adelante necesitas alternativas, puedes buscarlas en la documentación oficial de GitHub.


git remote add origin — Conectar tu carpeta con la nube

Ahora necesitamos decirle a Git local: “este proyecto se conecta con este repositorio de GitHub”. Eso se hace con git remote.

Terminal window
# Conectar tu repo local con GitHub
git remote add origin https://github.com/tu-usuario/mi-receta.git

¿Qué significa cada parte?

  • git remote add: “agrega una conexión remota”
  • origin: es un nombre para esa conexión (es convención usar “origin” para la principal)
  • https://github.com/...: la URL de tu repositorio en GitHub

Para verificar que la conexión se creó:

Terminal window
git remote -v
# origin https://github.com/tu-usuario/mi-receta.git (fetch)
# origin https://github.com/tu-usuario/mi-receta.git (push)

Si ves las dos líneas (fetch y push), la conexión está lista.


git push -u origin main — Subir tu trabajo a la nube

¡El momento de la verdad! git push sube tus commits locales a GitHub.

Terminal window
# Primera vez: necesitas el -u para establecer la conexión
git push -u origin main
# Enumerating objects: 6, done.
# Counting objects: 100% (6/6), done.
# Writing objects: 100% (6/6), 523 bytes | 523.00 KiB/s, done.
# Total 6 (delta 0), reused 0 (delta 0)
# To https://github.com/tu-usuario/mi-receta.git
# * [new branch] main -> main
# Branch 'main' set up to track remote branch 'main' from 'origin'.

¿Qué significa -u? Le dice a Git “recuerda que main local se conecta con main en GitHub”. Después de la primera vez, solo necesitas:

Terminal window
git push
# (sin -u, sin origin, sin main, Git ya recuerda)

¡Ve a GitHub en tu navegador y actualiza la página de tu repositorio! Deberías ver tus archivos ahí.


git clone — Descargar un proyecto de internet

git clone descarga una copia completa de un repositorio de GitHub a tu computador. Ya viene con todo configurado: la conexión remota, el historial de commits, todo.

Terminal window
# Clonar un repositorio
git clone https://github.com/usuario/nombre-repo.git
# Cloning into 'nombre-repo'...
# remote: Enumerating objects: 20, done.
# ...
# Entrar al repo clonado
cd nombre-repo
# Ya tiene todo configurado
git remote -v
# origin https://github.com/usuario/nombre-repo.git (fetch)
# origin https://github.com/usuario/nombre-repo.git (push)
git log --oneline
# (todo el historial del proyecto)

Flujo completo: de la idea a GitHub

Este es el flujo más importante que aprenderás. Conecta todo lo que viste en el Módulo 3 (repositorio local) con GitHub. Sigue cada paso en orden:

Paso 1: Crear la carpeta del proyecto e inicializar Git

Terminal window
mkdir mi-proyecto-web && cd mi-proyecto-web
git init

Paso 2: Crear .gitignore y hacer el primer commit

Siempre crea el .gitignore antes de empezar a trabajar (como aprendiste en el Módulo 3):

Terminal window
echo ".DS_Store" > .gitignore
echo "Thumbs.db" >> .gitignore
echo ".env" >> .gitignore
echo "node_modules/" >> .gitignore
echo "*.tmp" >> .gitignore
echo "*.log" >> .gitignore
git add .gitignore
git commit -m "chore: agrega .gitignore"

Paso 3: Crear los archivos del proyecto y hacer el segundo commit

Terminal window
echo "<!DOCTYPE html><html><body><h1>Hola Mundo</h1></body></html>" > index.html
echo "body { font-family: sans-serif; }" > estilos.css
git add index.html estilos.css
git commit -m "feat: crea estructura básica del sitio web"

Paso 4: Crear un repositorio vacío en GitHub

  1. En GitHub, haz clic en el botón ”+” (esquina superior derecha) → “New repository”
  2. Ponle el nombre mi-proyecto-web
  3. NO marques “Add a README file”
  4. NO selecciones un .gitignore template
  5. NO selecciones una licencia
  6. Haz clic en “Create repository”

GitHub te mostrará una página con instrucciones. Los comandos que necesitas son los de la sección “push an existing repository”.

⚠️

¡Crea el repo vacío!

Si marcas la casilla “Add a README file”, GitHub creará un commit inicial que tu repo local no tiene. Cuando intentes hacer push, tendrás un conflicto. Siempre crea el repo sin ningún archivo cuando vas a subir un proyecto existente.

Paso 5: Autenticarte (si no lo has hecho antes)

Terminal window
gh auth login
# Sigue las instrucciones: GitHub.com → HTTPS → Login with a web browser

Si ya te autenticaste antes, este paso no es necesario.

Paso 6: Conectar tu repo local con GitHub

Terminal window
git remote add origin https://github.com/tu-usuario/mi-proyecto-web.git
# Verificar la conexión
git remote -v
# origin https://github.com/tu-usuario/mi-proyecto-web.git (fetch)
# origin https://github.com/tu-usuario/mi-proyecto-web.git (push)

Paso 7: Subir tu código a GitHub por primera vez

Terminal window
git push -u origin main
# Enumerating objects: 8, done.
# ...
# To https://github.com/tu-usuario/mi-proyecto-web.git
# * [new branch] main -> main
# Branch 'main' set up to track remote branch 'main' from 'origin'.

El -u le dice a Git “recuerda que main local se conecta con main en GitHub”.

Paso 8: Verificar en GitHub

Abre tu navegador, ve a github.com/tu-usuario/mi-proyecto-web y actualiza la página. Deberías ver tus archivos (index.html, estilos.css, .gitignore) y tus commits.

Paso 9: Hacer un cambio, commit y push (flujo del día a día)

A partir de ahora, el flujo diario es mucho más simple:

Terminal window
# Editar un archivo
echo "<p>Bienvenido a mi sitio</p>" >> index.html
# El flujo de siempre: status → add → commit
git add index.html
git commit -m "feat: agrega mensaje de bienvenida"
# Subir a GitHub (ya no necesitas -u ni origin ni main)
git push

¡Eso es todo! A partir del primer push con -u, solo necesitas git push para subir tus nuevos commits.


Tabla resumen

Comando Descripción
git remote add origin <URL> Conectar repo local con GitHub
git remote -v Ver las conexiones remotas configuradas
git push -u origin main Subir código a GitHub (primera vez)
git push Subir código a GitHub (siguientes veces)
git clone <URL> Descargar un repositorio de GitHub

Ejercicios del módulo

Ejercicio 1: Crea un repositorio vacío en GitHub (sin README, sin .gitignore). Anota la URL que te da.

Ejercicio 2: Conecta tu repo local de práctica con GitHub:

Terminal window
git remote add origin https://github.com/tu-usuario/tu-repo.git
git remote -v
# ¿Ves las dos líneas (fetch y push)?

Ejercicio 3: Sube tu trabajo con git push -u origin main:

Terminal window
git push -u origin main

Ejercicio 4: Ve a GitHub en tu navegador y verifica que tus archivos están ahí. ¿Puedes ver los commits? ¿Los archivos?

Ejercicio 5: Clona un repositorio público a tu máquina. Puedes clonar el repositorio de este mismo curso:

Terminal window
cd ~
git clone https://github.com/paulovillarroel/curso-git-github.git curso-git-github-copia
cd curso-git-github-copia
ls
git log --oneline
💡

¡Tu código está en la nube!

Ahora tienes un respaldo de tu trabajo en GitHub. Si tu computador se pierde, tu código sigue a salvo. Además, cualquier persona puede ver y clonar tu repositorio público. ¡Eso es el poder de GitHub!

05

Viajes en el tiempo

Git es tu red de seguridad

Si el experimento falla, siempre puedes volver atrás. Esa es la gran promesa de Git: que puedes experimentar sin miedo porque nada se pierde de verdad (siempre y cuando hagas commits).

En este módulo vas a aprender a viajar en el tiempo por tu proyecto, deshacer errores y corregir metidas de pata. Todos cometemos errores, y Git está diseñado para eso.


git log --oneline — Repaso: tu mapa del tiempo

Antes de viajar, necesitas saber a dónde puedes ir. Cada commit tiene un hash único: esos 7 caracteres raros al inicio de cada línea.

Terminal window
git log --oneline
# d4e5f6a Agrega instrucciones de preparación
# b2c3d4e Agrega lista de ingredientes
# a1b2c3d Agrega receta inicial de pasta

Esos hashes (d4e5f6a, b2c3d4e, a1b2c3d) son como las coordenadas de cada punto en el tiempo. Los vas a usar para decirle a Git a dónde quieres ir.


git switch --detach — Modo turista al pasado

¿Quieres ver cómo era tu proyecto hace 3 commits? git switch --detach te lleva ahí como un turista: puedes mirar pero no deberías cambiar nada.

Terminal window
# Viajar al primer commit
git switch --detach a1b2c3d
# HEAD is now at a1b2c3d Agrega receta inicial de pasta
# Ahora tu proyecto está exactamente como estaba en ese momento
cat receta.txt
# # Receta de Pasta
# (solo la primera línea, porque los ingredientes se agregaron después)

Piensa en esto como visitar un museo: puedes mirar todo, pero si quieres hacer cambios permanentes, deberías volver a tu rama primero.

Git te va a mostrar un mensaje que dice “HEAD detached”. No te asustes, es normal. Significa que estás visitando el pasado pero no estás “parado” en ninguna rama.

💡

Detached HEAD: puedes mirar (y técnicamente editar), pero ten cuidado

Mientras estés en “detached HEAD”, puedes explorar e incluso hacer commits. Pero esos commits no pertenecen a ninguna rama, así que si cambias de rama sin guardarlos, se perderán. Para explorar es completamente seguro. Si quieres hacer cambios permanentes, primero crea una rama con git switch -c nombre-rama.

Para volver al presente:

Terminal window
git switch main
# Switched to branch 'main'
# ¡De vuelta al presente! Tus archivos vuelven a su estado actual.

git revert — El antídoto seguro

git revert es la forma recomendada de deshacer un cambio. Es como tachar algo con corrector en vez de arrancar la página: el error original sigue en la historia, pero creas un nuevo commit que lo deshace.

Terminal window
# Supongamos que el último commit agregó algo que no querías
git log --oneline
# d4e5f6a Agrega instrucciones de preparación ← este fue un error
# b2c3d4e Agrega lista de ingredientes
# a1b2c3d Agrega receta inicial de pasta
# Revertir el último commit
git revert d4e5f6a
# Se abre tu editor para el mensaje del commit de reversión
# (guarda y cierra el editor)
# Ahora el historial tiene un commit nuevo que deshace el cambio
git log --oneline
# e5f6a7b Revert "Agrega instrucciones de preparación"
# d4e5f6a Agrega instrucciones de preparación
# b2c3d4e Agrega lista de ingredientes
# a1b2c3d Agrega receta inicial de pasta

¿Ves? El commit original sigue ahí (la historia no se borró), pero hay un nuevo commit que deshace sus cambios. Es la forma más limpia y segura.

¿Cuándo usar revert?

Usa git revert cuando ya compartiste tu código con otras personas (lo subiste a GitHub). Es seguro porque no borra historia, solo agrega un nuevo commit que deshace el cambio.


git reset --soft HEAD~1 — “Oops, me equivoqué en el mensaje”

¿Hiciste un commit pero te equivocaste en el mensaje? ¿O te olvidaste de agregar un archivo? git reset --soft deshace el commit pero deja tus archivos intactos en el staging.

Terminal window
# Acabas de hacer un commit con un typo en el mensaje
git log --oneline
# f6a7b8c Agrega ingredentes ← ups, "ingredentes" tiene un typo
# Deshacer el commit (los archivos quedan en staging)
git reset --soft HEAD~1
# Verificar: los archivos siguen listos para commit
git status
# Changes to be committed:
# modified: receta.txt
# Ahora puedes hacer el commit de nuevo con el mensaje correcto
git commit -m "Agrega ingredientes"

¿Qué significa HEAD~1? Es como decir “un paso atrás desde donde estoy”. HEAD es “donde estoy ahora” y ~1 es “menos uno”.


git stash — Guardar cambios en un cajón temporal

Imagina que estás trabajando en algo y de repente necesitas cambiar de rama urgentemente (un compañero te pide revisar algo, o descubriste un bug en main). Pero tus cambios actuales están a medio hacer — no quieres hacer un commit de algo incompleto.

git stash guarda tus cambios en un “cajón temporal” y deja tu carpeta limpia:

Terminal window
# Tienes cambios sin commitear
git status
# modified: archivo.txt
# Guardar los cambios en el cajón
git stash
# Saved working directory and index state WIP on main
# Ahora tu carpeta está limpia
git status
# nothing to commit, working tree clean
# Puedes cambiar de rama tranquilo
git switch otra-rama
# ... hacer lo que necesitas ...
git switch main
# Recuperar tus cambios del cajón
git stash pop
# Tus cambios están de vuelta, como si nada hubiera pasado

¿Cuándo usar stash?

Úsalo cuando necesitas cambiar de rama pero tienes cambios sin commitear. Es temporal — guarda, haz lo que necesitas, y recupera con pop. Si no estás seguro de querer recuperarlos, usa git stash apply (que los recupera pero los deja también en el cajón por si acaso).


Tabla resumen

Comando Descripción
git log --oneline Ver historial compacto con hashes
git switch --detach <hash> Visitar un commit pasado (modo turista)
git switch main Volver al presente
git revert <hash> Deshacer un commit de forma segura (crea nuevo commit)
git reset --soft HEAD~1 Deshacer el último commit, archivos quedan en staging
git stash Guardar cambios temporalmente en un cajón
git stash pop Recuperar los cambios guardados con stash
Comando¿Es seguro?¿Cuándo usarlo?
git switch --detachSí, para explorarPara visitar el pasado (los commits que hagas aquí se pierden si no creas una rama)
git revertSí, es la opción recomendadaPara deshacer un cambio manteniendo la historia
git reset --softSí, los archivos no se pierdenPara corregir un mensaje de commit o agregar archivos olvidados
git stash / git stash popSí, es temporal y reversiblePara guardar cambios sin commitear cuando necesitas cambiar de rama

Ejercicios del módulo

Ejercicio 1: Crea un repo de práctica con 3 commits (uno por cada cambio en un archivo):

Terminal window
mkdir practica-tiempo && cd practica-tiempo
git init
echo "Línea 1: Hola" > archivo.txt
git add . && git commit -m "feat: agrega línea 1"
echo "Línea 2: Mundo" >> archivo.txt
git add . && git commit -m "feat: agrega línea 2"
echo "Línea 3: Git es genial" >> archivo.txt
git add . && git commit -m "feat: agrega línea 3"

Ejercicio 2: Usa git log --oneline para ver el historial. Deberías ver 3 commits con sus hashes.

Ejercicio 3: Viaja al primer commit con git switch --detach <hash> (usa el hash de tu primer commit). Mira el contenido del archivo con cat archivo.txt. ¿Solo tiene la línea 1? Vuelve al presente con git switch main.

Ejercicio 4: Usa git revert para deshacer el último commit. Revisa con git log --oneline que se creó un nuevo commit de reversión. Verifica con cat archivo.txt que la línea 3 desapareció.

Ejercicio 5: Haz un commit nuevo y luego deshazlo con git reset --soft HEAD~1. Verifica con git status que los archivos siguen en staging (en verde).

Terminal window
echo "Línea extra de prueba" >> archivo.txt
git add . && git commit -m "feat: agrega línea extra"
git reset --soft HEAD~1
git status
# Deberías ver los cambios en staging (verde)

¡No te preocupes si te equivocas!

Estos ejercicios son para experimentar. Si algo sale mal, simplemente borra la carpeta (cd .. && rm -rf practica-tiempo) y empieza de nuevo. Esa es la belleza de los repos de práctica: puedes destruirlos sin consecuencias.

06

Universos paralelos (Ramas)

Las ramas son como universos paralelos

Imagina que eres un científico y quieres probar una idea loca. No vas a experimentar en tu laboratorio principal (podrías romper algo), así que creas un laboratorio paralelo. Si el experimento funciona, traes los resultados al laboratorio principal. Si no funciona, simplemente cierras el laboratorio paralelo y todo sigue igual.

Eso es exactamente lo que hacen las ramas en Git.

main: A --- B --- C
\
feature: D --- E

En este diagrama, main es tu laboratorio principal con los commits A, B y C. Luego creaste una rama feature donde hiciste los commits D y E. Mientras trabajas en feature, main no se ve afectado para nada.


git branch — Ver en qué universo estás

git branch te muestra todas las ramas que existen y marca con un asterisco (*) en la que estás parado.

Terminal window
git branch
# * main

Solo tenemos una rama: main. Y el * nos dice que estamos ahí.


git switch -c — Crear un laboratorio nuevo

git switch -c crea una rama nueva y te mueve a ella automáticamente. La -c viene de “create” (crear).

Terminal window
# Crear una nueva rama y movernos a ella
git switch -c feature/saludo
# Switched to a new branch 'feature/saludo'
git branch
# main
# * feature/saludo

Ahora estás en la rama feature/saludo. Todo lo que hagas aquí (commits, cambios) NO afecta a main.

Nombres descriptivos para tus ramas

Usa nombres que digan qué estás haciendo:

  • feature/login — estás creando la funcionalidad de login
  • fix/error-calculo — estás arreglando un error en un cálculo
  • mejora/diseño-header — estás mejorando el diseño del header

Evita nombres genéricos como test, prueba o rama1.


Trabajar en tu rama

Una vez en tu rama, el flujo es exactamente el mismo que aprendiste: editar → git addgit commit.

Terminal window
# Estamos en feature/saludo
echo "¡Hola Mundo desde Git!" > saludo.txt
git add saludo.txt
git commit -m "feat: agrega archivo de saludo"
# Hacer otro cambio
echo "Bienvenido al curso de Git" >> saludo.txt
git add saludo.txt
git commit -m "feat: agrega mensaje de bienvenida al saludo"

Estos commits solo existen en feature/saludo. La rama main no sabe nada de ellos.


git switch main — Volver a la realidad

Cuando vuelves a main, tus archivos cambian para reflejar el estado de main. Es como magia.

Terminal window
# Volver a main
git switch main
# Switched to branch 'main'
# Verificar: ¿existe saludo.txt?
ls
# receta.txt
# (¡No hay saludo.txt! Solo existe en la otra rama)
💡

¡No te asustes!

Tus cambios no se perdieron. Están seguros en la rama feature/saludo. Si vuelves a ella con git switch feature/saludo, el archivo saludo.txt reaparece. Git mueve los archivos automáticamente según la rama en la que estés.


git merge — Traer el experimento exitoso a la realidad

Cuando estás satisfecho con tu trabajo en una rama, puedes mezclar (merge) esos cambios en main. Es como decir: “el experimento funcionó, traigan todo al laboratorio principal”.

Importante: Primero debes estar en la rama que recibe los cambios (generalmente main).

Terminal window
# 1. Asegúrate de estar en main
git switch main
# 2. Traer los cambios de feature/saludo
git merge feature/saludo
# Updating a1b2c3d..e5f6a7b
# Fast-forward
# saludo.txt | 2 ++
# 1 file changed, 2 insertions(+)
# create mode 100644 saludo.txt
# 3. Verificar
ls
# receta.txt saludo.txt ← ¡ahora saludo.txt está en main!
git log --oneline
# e5f6a7b Agrega mensaje de bienvenida al saludo
# d4e5f6a Agrega archivo de saludo
# ... (commits anteriores de main)

Conflictos de merge

A veces, cuando intentas hacer merge, Git encuentra un conflicto: dos ramas modificaron la misma línea del mismo archivo, y Git no sabe cuál elegir.

Esto no es un error. Es Git pidiendo tu ayuda para decidir.

Así se ve un archivo con conflicto:

<<<<<<< HEAD
Pasta con salsa de tomate
=======
Pasta con salsa boloñesa
>>>>>>> feature/nueva-receta

Los marcadores significan:

  • <<<<<<< HEAD: lo que tiene tu rama actual (main)
  • =======: separador
  • >>>>>>> feature/nueva-receta: lo que tiene la otra rama

Cómo resolver un conflicto paso a paso:

  1. Abre el archivo en tu editor de texto
  2. Decide qué mantener: elimina los tres marcadores (<<<<<<<, =======, >>>>>>>) y deja solo el contenido correcto
  3. Guarda el archivo
  4. Haz add y commit:
Terminal window
# Después de editar el archivo y resolver el conflicto
git add receta.txt
git commit -m "Resuelve conflicto: elige salsa boloñesa"

Los conflictos NO son errores

Los conflictos son normales y esperables cuando trabajas con ramas. Git simplemente te pide ayuda para decidir qué versión mantener. No te asustes cuando veas uno.


git branch -d — Limpieza de ramas

Cuando una rama ya fue mergeada, debes borrarla. Una rama que ya cumplió su propósito no tiene razón de seguir existiendo. Dejarla ahí solo genera confusión: con el tiempo, el repositorio se llena de ramas viejas y nadie sabe cuáles están activas y cuáles son basura.

La regla es simple: rama mergeada = rama borrada.

Terminal window
# Borrar la rama local (solo funciona si ya fue mergeada)
git branch -d feature/saludo
# Deleted branch feature/saludo (was e5f6a7b).

La -d (de “delete”) es la forma segura de borrar: Git verifica que la rama ya fue mergeada antes de borrarla. Si no fue mergeada, te avisa para que no pierdas trabajo accidentalmente.

Si la rama también fue subida a GitHub, necesitas borrarla en el remoto también:

Terminal window
# Borrar la rama en GitHub
git push origin --delete feature/saludo

Limpieza completa después de un merge

Acostúmbrate a este flujo cada vez que termines con una rama:

Terminal window
# 1. Borrar la rama local
git branch -d feature/saludo
# 2. Borrar la rama remota (si la subiste a GitHub)
git push origin --delete feature/saludo

En GitHub, cuando mergeas un Pull Request, te ofrece un botón para borrar la rama remota automáticamente. Úsalo siempre.

⚠️

¿Y si no la mergeé pero quiero borrarla igual?

Si decidiste descartar una rama experimental que no funcionó, Git no te dejará borrarla con -d porque detecta que perderías trabajo. Si estás seguro de que quieres borrarla, usa -D (mayúscula):

Terminal window
git branch -D feature/experimento-fallido

Esto fuerza el borrado. Úsalo solo cuando estés seguro de que no necesitas esos cambios.


Tabla resumen

Comando Descripción
git branch Listar ramas y ver la actual (*)
git switch -c nombre-rama Crear una rama nueva y moverte a ella
git switch nombre-rama Cambiar de rama
git merge nombre-rama Traer los cambios de una rama a la actual
git branch -d nombre-rama Borrar una rama local ya mergeada
git push origin --delete nombre-rama Borrar una rama remota en GitHub
git branch -D nombre-rama Forzar borrado de rama no mergeada

Ejercicios del módulo

Ejercicio 1: Crea una rama feature/despedida, agrega un archivo despedida.txt con algún contenido, y haz commit:

Terminal window
git switch -c feature/despedida
echo "¡Adiós desde una rama!" > despedida.txt
git add despedida.txt
git commit -m "feat: agrega archivo de despedida"

Ejercicio 2: Vuelve a main y verifica que el archivo despedida.txt NO está:

Terminal window
git switch main
ls
# ¿Ves despedida.txt? No debería estar

Ejercicio 3: Mergea la rama a main y verifica que el archivo AHORA SÍ está:

Terminal window
git merge feature/despedida
ls
# Ahora despedida.txt debería aparecer

Ejercicio 4: Borra la rama con git branch -d:

Terminal window
git branch -d feature/despedida
git branch
# Solo debería quedar main

Ejercicio 5 (Desafío): Crea un conflicto a propósito y resuélvelo:

Terminal window
# Crear un archivo base
echo "Color favorito: azul" > preferencias.txt
git add . && git commit -m "feat: agrega preferencias"
# Crear una rama y cambiar el color
git switch -c feature/color
echo "Color favorito: rojo" > preferencias.txt
git add . && git commit -m "feat: cambia color a rojo"
# Volver a main y cambiar el color diferente
git switch main
echo "Color favorito: verde" > preferencias.txt
git add . && git commit -m "feat: cambia color a verde"
# Intentar merge (¡conflicto!)
git merge feature/color
# CONFLICT (content): Merge conflict in preferencias.txt
# Abre preferencias.txt, resuelve el conflicto, luego:
git add preferencias.txt
git commit -m "Resuelve conflicto: elige color verde"
git branch -d feature/color
💡

¡Las ramas son tu superpoder!

Con ramas puedes experimentar libremente sin miedo. Crea tantas ramas como quieras para probar ideas. Si funcionan, las mergeas. Si no, las borras. Así de simple.

07

Flujo profesional colaborativo

Trabajar en equipo como una cocina profesional

En una cocina profesional, cada cocinero trabaja en su estación. Nadie toca directamente el plato final sin que el chef lo revise primero. En desarrollo de software, funciona igual: nadie toca main directamente. Todo pasa por un proceso de revisión.

Este módulo te enseña el GitHub Flow, el flujo de trabajo que usan la mayoría de equipos profesionales.


¿Por qué no trabajar directamente en main?

Imagina que 5 personas pushen cambios directamente a main al mismo tiempo. Sería un caos:

  • Nadie sabe qué cambió quién
  • Si algo se rompe, no sabes quién lo rompió
  • No hay revisión de calidad

Por eso existe el flujo con Pull Requests (PR): cada cambio pasa por una revisión antes de llegar a main.


Dos caminos para contribuir a un proyecto

Antes de ver el flujo completo, es importante entender que existen dos caminos para contribuir, y cuál uses depende de tus permisos en el repositorio:

Como miembro del equipoComo contribuidor externo
¿Cuándo?Tienes permisos de escritura en el repoNo tienes permisos (proyecto open source, repo ajeno)
Primer pasogit clone del repoFork en GitHub, luego git clone de tu fork
¿Dónde haces push?Directamente al repo originalA tu fork
¿Cómo llegan tus cambios?PR dentro del mismo repoPR desde tu fork al repo original

En este módulo veremos primero el camino de equipo paso a paso. Al final verás el camino de contribuidor externo, que es casi idéntico: la única diferencia es que primero haces fork (lo verás en detalle en el Módulo 8) y el PR va desde tu fork al repo original.


El flujo GitHub Flow

Este es el proceso completo que seguirás en tu trabajo:

  1. Crear una rama para tu tarea
  2. Trabajar y hacer commits en esa rama
  3. Subir la rama a GitHub
  4. Crear un Pull Request (pedir revisión)
  5. Revisión y aprobación por parte del equipo
  6. Merge en GitHub (el código entra a main)
  7. Actualizar tu copia local

Veamos cada paso en detalle.


Paso 1-2: Crear rama y trabajar

Esto ya lo sabes del Módulo 6:

Terminal window
# Crear rama para tu tarea
git switch -c feature/mi-cambio
# Hacer tu trabajo
echo "Nueva funcionalidad" > feature.txt
git add feature.txt
git commit -m "Agrega nueva funcionalidad"
# Puedes hacer más commits
echo "Más detalles" >> feature.txt
git add feature.txt
git commit -m "Agrega más detalles a la funcionalidad"

Paso 3: Subir la rama a GitHub

Ahora que tu rama tiene commits, la subes a GitHub:

Terminal window
git push -u origin feature/mi-cambio
# Enumerating objects: 4, done.
# ...
# To https://github.com/tu-usuario/mi-proyecto.git
# * [new branch] feature/mi-cambio -> feature/mi-cambio

Ahora la rama existe tanto en tu computador como en GitHub.


Paso 4: Crear un Pull Request (PR)

Un Pull Request es una solicitud formal para que tu código entre a main. Es como decir: “Terminé mi parte, ¿pueden revisarla antes de juntarla con el proyecto principal?”

Cómo crear un PR desde GitHub:

  1. Ve a tu repositorio en GitHub
  2. Verás un banner amarillo que dice “Compare & pull request” — haz clic ahí
  3. (Si no aparece el banner, ve a la pestaña “Pull requests” → “New pull request”)
  4. Título: Escribe un resumen corto de lo que hiciste (ejemplo: “Agrega nueva funcionalidad de saludo”)
  5. Descripción: Explica con más detalle:
    • Qué cambiaste
    • Por qué lo cambiaste
    • Cualquier nota para los revisores
  6. Haz clic en “Create pull request”

Un buen Pull Request describe QUÉ y POR QUÉ

Buen PR: “Agrega formulario de contacto con validación de email. Se necesitaba porque los usuarios reportaban que no podían comunicarse con soporte.”

Mal PR: “Cambios”, “Actualizaciones”, “Fix”


Paso 5: Code Review (revisión de código)

Los Pull Requests permiten que otros miembros del equipo revisen tu código antes de aceptarlo:

  • Comentarios línea por línea: Pueden sugerir mejoras en líneas específicas
  • Aprobar: Si todo está bien, aprueban el PR
  • Pedir cambios: Si hay algo que mejorar, te lo piden

Si te piden cambios, simplemente haz más commits en la misma rama y sube:

Terminal window
# Hacer los cambios pedidos
echo "Cambio solicitado en revisión" >> feature.txt
git add feature.txt
git commit -m "Aplica cambios de la revisión de código"
git push

El PR se actualiza automáticamente con los nuevos commits.


Paso 6: Merge en GitHub

Una vez que el PR está aprobado, es hora del merge. En GitHub verás un botón verde grande:

  • “Merge pull request”: Haz clic aquí
  • “Confirm merge”: Confirma

GitHub te dará tres opciones de merge. Entender la diferencia es importante:

EstrategiaQué haceResultado en main
Squash and mergeCombina todos tus commits en uno soloUn commit limpio por tarea
Create a merge commitMantiene todos los commits + agrega commit de mergeHistorial completo pero más ruidoso
Rebase and mergeRe-aplica cada commit sobre main (sin commit de merge)Lineal, pero cada commit individual se mantiene

Nuestra recomendación: usa “Squash and merge” como default. Cada commit en main debería representar una tarea completa, no 15 commits intermedios como “WIP”, “fix typo”, “ahora sí funciona”. Con squash, tus commits de trabajo se combinan en uno limpio con el título del PR como mensaje.

# Sin squash (todos los commits de la rama llegan a main):
main: ... → WIP → fix typo → ahora sí → merge commit
# Con squash (un solo commit limpio):
main: ... → feat: agrega filtro de búsqueda

¿Cuándo NO usar squash?

Si cada commit en tu rama es intencional y significativo (no hay WIP ni correcciones intermedias), puedes usar “Rebase and merge” para mantener esa granularidad en main. Pero para la mayoría de equipos, squash es el default correcto.

Después del merge, GitHub te dará la opción de borrar la rama remota. ¡Hazlo! Ya cumplió su propósito.


Paso 7: Actualizar tu copia local

Después de que el PR se mergea en GitHub, tu copia local de main está desactualizada. Necesitas traer los cambios:

Terminal window
# Volver a main
git switch main
# Traer los cambios de GitHub
git pull
# Verás todos los cambios del merge
# Borrar la rama local (ya fue mergeada)
git branch -d feature/mi-cambio
# Deleted branch feature/mi-cambio

¡Listo! Tu copia local está actualizada y la rama fue limpiada.


Flujo completo de ejemplo

Veamos todo el flujo de principio a fin, como lo harías en tu día a día:

Terminal window
# 1. Asegúrate de estar en main y actualizado
git switch main
git pull
# 2. Crear rama para tu tarea
git switch -c feature/agregar-footer
# 3. Trabajar
echo "<footer>© 2024 Mi Proyecto</footer>" > footer.html
git add footer.html
git commit -m "Agrega footer con copyright"
# 4. Subir la rama a GitHub
git push -u origin feature/agregar-footer
# 5. Ir a GitHub → crear Pull Request
# (desde el navegador)
# 6. Esperar revisión y aprobación
# (si te piden cambios, haz commits y push)
# 7. Merge desde GitHub (botón verde)
# (borrar rama remota cuando GitHub lo ofrezca)
# 8. Actualizar local
git switch main
git pull
git branch -d feature/agregar-footer
💡

Resumen del flujo profesional

PasoDóndeComando / Acción
Crear ramaTerminalgit switch -c feature/nombre
TrabajarTerminalgit add + git commit (repetir)
Subir ramaTerminalgit push -u origin feature/nombre
Crear PRGitHub webBotón “Compare & pull request”
RevisiónGitHub webComentarios, aprobación
MergeGitHub webBotón verde “Merge pull request”
Actualizar localTerminalgit switch main + git pull
LimpiezaTerminalgit branch -d feature/nombre

Contribuir a un proyecto ajeno (via fork)

Si no tienes permisos de escritura en un repositorio (por ejemplo, un proyecto open source), el flujo es casi idéntico al de equipo, pero con un paso previo: necesitas hacer fork del proyecto. Un fork crea una copia del repositorio en tu cuenta de GitHub, donde sí tienes permisos para hacer push.

La explicación completa de fork (cómo hacerlo, cómo mantenerlo actualizado, cuándo usarlo vs clone) la verás en el Módulo 8. Por ahora, lo importante es entender la diferencia:

Como miembro del equipoComo contribuidor externo
Primer pasogit clone del repoFork en GitHub → git clone de tu fork
Push va aEl repo del equipoTu fork
PR vaDentro del mismo repoDesde tu fork al repo original

Todo lo demás (crear rama, commits, push, crear PR) es exactamente igual.


GitHub CLI (gh) — El flujo profesional sin salir de la terminal

Hasta ahora, para crear un PR tenías que ir al navegador. GitHub CLI (gh) te permite hacer todo desde la terminal: crear PRs, revisarlos, mergearlos, gestionar issues y más.

Si todavía no instalaste gh, hazlo ahora (ya lo usaste para autenticarte en el Módulo 4):

Terminal window
# Verificar que está instalado y autenticado
gh auth status
# ✓ Logged in to github.com account tu-usuario

Crear un PR desde la terminal:

Terminal window
# Después de hacer push de tu rama
gh pr create --title "feat: agrega filtro de búsqueda" --body "Descripción de los cambios"
# Si prefieres que se abra un editor interactivo:
gh pr create

Ver y mergear PRs:

Terminal window
# Listar PRs abiertos
gh pr list
# Ver detalles del PR actual
gh pr view
# Ver los cambios (diff)
gh pr diff 1
# Mergear con squash (nuestra recomendación)
gh pr merge --squash

Crear repositorios desde la terminal:

Terminal window
# Crear repo público desde la carpeta actual
gh repo create mi-proyecto --public --source=. --push
# Esto reemplaza: ir a GitHub → crear repo → copiar URL → git remote add → git push

Gestionar issues:

Terminal window
gh issue list # Listar issues abiertos
gh issue create --title "..." # Crear un issue
gh issue view 5 # Ver un issue
gh issue close 5 # Cerrar un issue

Flujo profesional acelerado con gh

Con gh, el flujo completo se queda en la terminal:

Terminal window
git switch -c feature/mi-cambio
# ... hacer cambios, commits ...
git push -u origin feature/mi-cambio
gh pr create --title "feat: mi cambio" --body "Descripción"
# ... esperar revisión ...
gh pr merge --squash
git switch main && git pull
git branch -d feature/mi-cambio

Tabla resumen de comandos

Comando Descripción
git switch -c feature/nombre Crear rama para tu tarea
git push -u origin feature/nombre Subir tu rama a GitHub
git push Subir nuevos commits (después del -u)
git switch main Volver a la rama principal
git pull Actualizar main con los cambios de GitHub
git branch -d feature/nombre Borrar rama local después del merge
gh pr create --title "..." --body "..." Crear un Pull Request desde la terminal
gh pr list Listar Pull Requests abiertos
gh pr merge --squash Mergear PR con squash
gh issue list Listar issues abiertos
gh repo create nombre --public --source=. --push Crear repo y subir código

Ejercicios del módulo

Ejercicio 1: Asegúrate de tener un repo conectado a GitHub. Crea una rama feature/mi-cambio y haz un commit:

Terminal window
git switch -c feature/mi-cambio
echo "Este es un cambio de prueba" > cambio.txt
git add cambio.txt
git commit -m "Agrega archivo de prueba para PR"

Ejercicio 2: Sube la rama a GitHub:

Terminal window
git push -u origin feature/mi-cambio

Ejercicio 3: Ve a tu repositorio en GitHub y crea un Pull Request. Escribe un título descriptivo y una descripción de lo que hiciste.

Ejercicio 4: Mergea el PR desde GitHub (botón verde “Merge pull request” → “Confirm merge”). Si GitHub te ofrece borrar la rama, hazlo.

Ejercicio 5: Vuelve a tu terminal y actualiza tu copia local:

Terminal window
git switch main
git pull
git branch -d feature/mi-cambio

Verifica con ls que el archivo cambio.txt ahora está en main, y con git branch que la rama fue borrada.

¡Felicidades, ya conoces el flujo profesional!

Este flujo (rama → commits → push → PR → review → merge → pull) es exactamente lo que usan equipos de desarrollo en todo el mundo. Practícalo varias veces hasta que se sienta natural. En los ejercicios finales podrás practicar un flujo completo de colaboración simulada.

08

Técnicas avanzadas de Git

Herramientas de poder para cuando ya dominas lo básico

En los módulos anteriores aprendiste a trabajar con Git de forma segura y productiva. Ahora es momento de conocer las herramientas avanzadas que te dan más control sobre la historia, la sincronización y la colaboración.

Estos comandos son más poderosos, pero también requieren más cuidado. Úsalos cuando entiendas bien lo que hacen.


git reset --hard HEAD~1 — El botón nuclear

⚠️

PELIGRO: Este comando DESTRUYE cambios

git reset --hard elimina el commit Y todos los cambios en los archivos. No hay vuelta atrás. Úsalo solo si estás 100% seguro de que quieres borrar todo.

Terminal window
# Esto BORRA el último commit y todos sus cambios
git reset --hard HEAD~1
# HEAD is now at b2c3d4e Agrega lista de ingredientes

Después de ejecutar esto, es como si el último commit nunca hubiera existido. Los archivos vuelven al estado del commit anterior y los cambios se pierden para siempre.

¿Cuándo usarlo? Casi nunca. Solo cuando hiciste algo realmente mal y estás seguro de que quieres eliminarlo por completo. En la mayoría de los casos, git revert (Módulo 5) es mejor opción.

Comando¿Es seguro?¿Cuándo usarlo?
git revertSí, es la opción recomendadaPara deshacer un cambio manteniendo la historia
git reset --softSí, los archivos no se pierdenPara corregir un mensaje de commit o agregar archivos olvidados
git reset --hardNO, destruye cambiosSolo cuando estás 100% seguro de querer borrar todo

git rebase — Integrar cambios con historia lineal

En el Módulo 7 viste las tres estrategias de merge (squash, merge commit, rebase). Ahora vas a aprender a usar rebase desde la terminal.

La diferencia clave con merge es cómo queda la historia:

  • Merge crea un commit de merge que une las dos ramas
  • Rebase “reescribe” la historia para que sea lineal, como si hubieras hecho tus cambios después de todo lo que pasó en main
Merge: crea un commit de merge (M) que une las ramas
main: A --- B --- C --------- M
\ /
feature: D --- E
Rebase: mueve tus commits para que empiecen desde la punta de main
main: A --- B --- C --- D' --- E'

Con merge, la historia muestra “aquí se juntaron dos ramas”. Con rebase, la historia queda limpia y lineal: tus commits aparecen como una continuación directa de main.

El comando básico:

Terminal window
# Estando en tu rama feature
git rebase main

Esto “mueve” los commits de tu rama para que empiecen desde la punta de main. Tus commits D y E se convierten en D’ y E’ (copias con el mismo contenido pero en una nueva posición de la historia).

⚠️

Regla de oro del rebase

Nunca hagas rebase de commits que ya compartiste (que ya subiste con git push). Rebase reescribe la historia, y si alguien más ya tiene esos commits, van a tener problemas para sincronizar su trabajo. Si ya hiciste push, usa merge.

¿Merge o rebase?

Ambos logran lo mismo: integrar cambios de una rama a otra. Merge preserva la historia tal cual fue (con sus bifurcaciones y uniones). Rebase la simplifica (todo queda lineal). Para principiantes, merge es más seguro porque no reescribe la historia. Cuando te sientas cómodo con Git, prueba rebase — muchos equipos lo prefieren por mantener un historial más limpio.


Mantener tu rama actualizada con rebase (en Pull Requests)

Mientras trabajas en tu rama, tus compañeros siguen mergeando cambios a main. Después de unos días, tu rama está desactualizada: le faltan cambios que ya están en main. Esto puede causar conflictos más difíciles cuando quieras hacer merge, y hace que tu PR sea más difícil de revisar.

La solución es actualizar tu rama con rebase antes de crear el PR (o durante la revisión):

Terminal window
# Estás en tu rama feature/mi-cambio
# 1. Traer los cambios más recientes de main
git switch main
git pull
# 2. Volver a tu rama y hacer rebase
git switch feature/mi-cambio
git rebase main
# 3. Si hay conflictos, resolverlos y continuar
# (editar archivo, resolver conflicto)
git add archivo-resuelto.txt
git rebase --continue
# 4. Si todo sale mal, puedes cancelar y volver al estado anterior
git rebase --abort

¿Por qué rebase y no merge? Si haces git merge main dentro de tu rama, funciona, pero cuando las historias han divergido crea commits de merge extras que ensucian la historia y hacen tu PR más difícil de revisar. Con rebase, tu rama queda como si la hubieras creado recién desde el main más actualizado: limpia y fácil de revisar.


git pull --rebase — Atajo para actualizar tu rama

El flujo anterior (switch main → pull → switch feature → rebase) tiene un atajo. Si estás en tu rama y quieres actualizar directamente:

Terminal window
# Estando en tu rama feature/mi-cambio
git pull --rebase origin main

Esto hace git fetch + git rebase en un solo comando: trae los cambios de main del remoto y reaplica tus commits encima.

Por defecto, git pull sin flags hace un merge: trae los cambios remotos y crea un commit de merge para combinarlos (si las historias divergieron). La diferencia es la misma que ya conoces — --rebase mantiene la historia lineal, el merge por defecto preserva las bifurcaciones.


git push --force-with-lease — Push seguro después de rebase

⚠️

Si ya habías hecho push antes del rebase

Rebase reescribe la historia de tu rama. Si ya habías subido la rama con git push, después del rebase necesitas forzar la subida:

Terminal window
git push --force-with-lease

Usamos --force-with-lease en vez de --force porque es más seguro: verifica que nadie más haya subido commits a tu rama antes de sobrescribirla. Si alguien más subió cambios, el push falla en vez de borrar su trabajo.


Fork — Tu propia copia de un proyecto ajeno

Un fork es una copia completa de un repositorio de otra persona en tu cuenta de GitHub. Es diferente a clonar:

  • Clone: descarga un repo a tu computador (copia local)
  • Fork: crea una copia del repo en tu cuenta de GitHub (copia en la nube)

¿Para qué sirve? Imagina que encuentras un proyecto open source que quieres mejorar. No puedes hacer push directamente al repo de otra persona (no tienes permisos), pero puedes:

  1. Hacer fork del proyecto (ahora tienes tu propia copia en GitHub)
  2. Clonar tu fork a tu computador
  3. Hacer tus cambios y push a tu fork
  4. Crear un Pull Request desde tu fork al proyecto original

Cómo hacer un fork:

  1. Ve al repositorio en GitHub que quieres copiar
  2. Haz clic en el botón “Fork” (esquina superior derecha)
  3. Selecciona tu cuenta como destino
  4. ¡Listo! Ahora tienes una copia en github.com/tu-usuario/nombre-repo

Trabajar con tu fork:

Terminal window
# 1. Clonar TU fork (no el repo original)
git clone https://github.com/tu-usuario/nombre-repo.git
cd nombre-repo
# Verificar: origin apunta a TU fork
git remote -v
# origin https://github.com/tu-usuario/nombre-repo.git (fetch)
# origin https://github.com/tu-usuario/nombre-repo.git (push)
# 2. Crear una rama para tu contribución (nunca trabajes en main)
git switch -c feature/mi-mejora
# 3. Hacer tus cambios, add y commit
echo "Mi mejora" >> archivo.txt
git add archivo.txt
git commit -m "Agrega mejora al archivo"
# 4. Subir la rama a TU fork
git push -u origin feature/mi-mejora

Después ve a GitHub y crea un Pull Request desde tu fork al repositorio original. GitHub detecta automáticamente la rama que subiste y te ofrece crear el PR.

Fork vs Clone: ¿cuándo usar cada uno?

  • Clone: cuando quieres descargar un repo para verlo o usarlo localmente
  • Fork: cuando quieres hacer cambios y eventualmente proponerlos al proyecto original, o cuando quieres tu propia versión independiente de un proyecto

Mantener tu fork actualizado con upstream

Con el tiempo, el proyecto original seguirá avanzando. Para traer esos cambios a tu fork:

Terminal window
# Agregar una conexión al repo original (se hace una sola vez)
git remote add upstream https://github.com/autor-original/nombre-repo.git
# Traer los cambios del original y actualizar tu fork
git fetch upstream
git switch main
git merge upstream/main
git push
# Ahora tu fork está al día con el proyecto original

upstream es el nombre convencional para el repositorio original (el que forkeaste). origin sigue siendo tu fork.


git fetch — Preguntar si hay novedades

git fetch revisa si hay cambios nuevos en GitHub sin aplicarlos a tus archivos. Es como mirar el buzón sin abrir las cartas.

Terminal window
git fetch
# Si hay cambios nuevos, te muestra información
# Si no hay cambios, no muestra nada

Es útil para verificar si alguien más subió cambios antes de traerlos. La diferencia con git pull:

  • git fetch: solo descarga la información, tus archivos no cambian
  • git pull: descarga Y aplica los cambios (es un fetch + merge)

git pull avanzado

Ya conoces git pull del Módulo 4. Aquí van los detalles más avanzados.

El comportamiento por defecto de git pull es hacer merge. Cuando ejecutas git pull sin flags, Git hace dos cosas automáticamente:

  1. git fetch — descarga los cambios del remoto
  2. git merge — fusiona esos cambios con tu rama local

Como el merge ya viene “de fábrica”, no existe un flag --merge. Si intentas git pull --merge, Git te dará un error. Es lógico pensar que debería existir (sobre todo porque sí existe --rebase), pero sería redundante.

Los flags que sí existen:

Terminal window
# Pull normal (fetch + merge) — comportamiento por defecto
git pull
# Pull con rebase (fetch + rebase, historia lineal)
git pull --rebase origin main
# Forzar commit de merge explícito (incluso cuando fast-forward es posible)
git pull --no-ff
# Forzar merge aunque tu config global diga rebase
git pull --no-rebase
# Solo funciona si no hay divergencia (el más seguro)
git pull --ff-only

¿Cuál usar?

  • git pull (sin flags): suficiente para el 90% de los casos
  • git pull --rebase: cuando quieres mantener la historia lineal
  • git pull --no-rebase: cuando configuraste rebase por defecto pero para un caso puntual quieres merge
  • git pull --ff-only: el más seguro — si tu historial local divergió del remoto, falla en vez de intentar fusionar. Así evitas commits de merge accidentales y decides tú cómo resolver la situación
  • git pull --no-ff: cuando quieres dejar registro explícito de que se integraron cambios externos, incluso cuando un fast-forward sería posible
⚠️

Siempre haz commit antes de pull

Antes de hacer git pull, asegúrate de haber hecho commit de todos tus cambios locales. Si tienes cambios sin guardar y los cambios remotos tocan los mismos archivos, podrías tener conflictos difíciles de resolver.

Terminal window
# Antes de pull, siempre:
git status
# Si hay cambios pendientes:
git add .
git commit -m "Guarda cambios antes de pull"
# Ahora sí:
git pull

Tabla resumen

Comando Descripción
git reset --hard HEAD~1 ⚠️ BORRAR último commit y todos sus cambios
git rebase main Reescribir tu rama para que empiece desde la punta de main
git rebase --continue Continuar rebase después de resolver conflicto
git rebase --abort Cancelar rebase y volver al estado anterior
git pull --rebase origin main Actualizar tu rama con rebase en un solo comando
git push --force-with-lease Push seguro después de rebase (verifica que nadie más subió)
Fork (botón en GitHub) Crear tu propia copia de un repo ajeno
git remote add upstream <URL> Conectar con el repo original (después de fork)
git fetch Revisar si hay cambios nuevos (sin aplicar)
git fetch upstream Traer cambios del repo original (fork)
git pull Descargar y aplicar cambios de GitHub (merge por defecto)
git pull --ff-only Pull seguro: falla si el historial divergió
git pull --no-rebase Forzar merge aunque tu config diga rebase

Ejercicios del módulo

Ejercicio 1: Practica git reset --hard en un repo desechable:

Terminal window
mkdir practica-avanzado && cd practica-avanzado
git init
echo "Línea 1" > archivo.txt
git add . && git commit -m "Commit 1"
echo "Línea 2" >> archivo.txt
git add . && git commit -m "Commit 2"
echo "Línea 3" >> archivo.txt
git add . && git commit -m "Commit 3"
# Ver historial
git log --oneline
# Ahora borra el último commit
git reset --hard HEAD~1
git log --oneline
cat archivo.txt
# La línea 3 desapareció por completo

Ejercicio 2: Practica rebase entre ramas:

Terminal window
# Crear commits en main
echo "Base actualizada" >> archivo.txt
git add . && git commit -m "Actualiza base en main"
# Crear rama y trabajar
git switch -c feature/prueba-rebase
echo "Cambio en rama" > rama.txt
git add . && git commit -m "Agrega archivo en rama"
# Volver a main y agregar otro commit
git switch main
echo "Otro cambio en main" >> archivo.txt
git add . && git commit -m "Otro cambio en main"
# Rebase: actualizar la rama
git switch feature/prueba-rebase
git rebase main
git log --oneline
# Tu commit de rama aparece DESPUÉS de los de main
# Limpieza
git switch main
git merge feature/prueba-rebase
git branch -d feature/prueba-rebase

Ejercicio 3: Haz fork de un repositorio público: ve a cualquier repo en GitHub, haz clic en “Fork”, clona tu fork y verifica con git remote -v que apunta a tu cuenta.

Ejercicio 4: Practica git fetch para ver cambios sin aplicarlos:

Terminal window
# En un repo conectado a GitHub
git fetch
git log --oneline origin/main
# Ves los commits remotos sin que tus archivos cambien
git pull
# Ahora sí se aplican

Estas herramientas son poderosas pero opcionales

Todo lo que aprendiste en los módulos 1-7 es suficiente para trabajar profesionalmente con Git. Las técnicas de este módulo te dan más control, pero solo úsalas cuando las necesites. No compliques tu flujo si merge y pull básico te funcionan bien.

09

Agentes de IA como asistentes de Git

Agentes de IA: tu asistente experto en la terminal

💡

Módulo bonus — opcional

Este módulo es complementario. Los agentes de IA son herramientas poderosas pero opcionales, que requieren cuentas o API keys adicionales. Todo lo que necesitas para trabajar profesionalmente con Git ya lo aprendiste en los módulos anteriores.

Los agentes de IA son asistentes que funcionan directamente en tu terminal. Entienden tu código, pueden ejecutar comandos de Git y gh, crear archivos, hacer commits y hasta crear Pull Requests — todo con instrucciones en lenguaje natural.

Piensa en ellos como un programador senior sentado a tu lado, disponible 24/7, al que le puedes preguntar cualquier cosa.


Claude Code

Claude Code es un agente de IA de Anthropic que vive en tu terminal. Puede leer tu código, ejecutar comandos, crear archivos, hacer commits y hasta crear Pull Requests.

Instalación:

Terminal window
npm install -g @anthropic-ai/claude-code

Uso básico:

Terminal window
# Iniciar Claude Code en tu proyecto
cd mi-proyecto
claude

Se abre una sesión interactiva donde puedes pedirle cosas como:

> Revisa mi código y dime si hay errores
> Crea un .gitignore apropiado para un proyecto Node.js
> Haz commit de todos los cambios con un buen mensaje
> Crea un Pull Request con descripción detallada

Claude Code puede usar git y gh directamente, así que puede:

  • Hacer git add, git commit y git push por ti
  • Crear Pull Requests con gh pr create
  • Revisar el estado de tu repo con git status
  • Resolver conflictos de merge explicándote qué está pasando

Claude Code + Git = superpoder

En vez de recordar todos los comandos de Git, puedes decirle a Claude Code en lenguaje natural lo que quieres hacer:

  • “Guarda mis cambios con un mensaje descriptivo” → hace git add + git commit
  • “Sube mi rama y crea un PR” → hace git push + gh pr create
  • “¿Qué cambié desde el último commit?” → ejecuta git diff
  • “Vuelve al estado anterior” → ejecuta git revert o git reset según corresponda

Si quieres profundizar, Anthropic tiene un curso oficial gratuito: Claude Code in Action.


Gemini CLI

Gemini CLI es el agente de IA de Google que también funciona en la terminal. Es open source y gratuito con tu cuenta de Google.

Instalación:

Terminal window
npm install -g @google/gemini-cli

Uso básico:

Terminal window
cd mi-proyecto
gemini

Al igual que Claude Code, puedes pedirle que interactúe con Git:

> Inicializa este proyecto con Git y haz el primer commit
> Muéstrame el historial de cambios
> Crea una rama para trabajar en el login

GitHub Copilot CLI

Si tienes suscripción a GitHub Copilot, también puedes usarlo desde la terminal con la extensión de gh:

Terminal window
# Instalar la extensión
gh extension install github/gh-copilot
# Pedir ayuda con comandos
gh copilot suggest "cómo deshacer el último commit sin perder cambios"
# Sugerencia: git reset --soft HEAD~1
gh copilot explain "git rebase -i HEAD~3"
# Te explica qué hace ese comando en detalle
💡

¿Cuál agente elegir?

  • Claude Code: Muy capaz para tareas complejas, entiende contexto del proyecto completo. Requiere API key de Anthropic.
  • Gemini CLI: Gratuito con cuenta de Google, open source, bueno para tareas generales.
  • GitHub Copilot CLI: Integrado con gh, perfecto para sugerencias de comandos Git. Requiere suscripción Copilot.

Puedes probar los tres y quedarte con el que más te guste. Todos funcionan bien con Git y GitHub.


Ejemplo práctico: flujo con un agente de IA

Así se ve un flujo de trabajo combinando gh (que aprendiste en el Módulo 7) y un agente de IA:

Terminal window
# 1. Crear un proyecto nuevo
mkdir mi-app && cd mi-app
git init
echo "# Mi App" > README.md
git add . && git commit -m "chore: commit inicial"
gh repo create mi-app --public --source=. --push
# 2. Iniciar tu agente de IA
claude # o gemini, según tu preferencia
# 3. Pedirle al agente que trabaje
> Crea una estructura básica para una app web con HTML, CSS y JS
> Haz commit de los cambios
> Crea una rama feature/estilos y mejora el CSS
> Sube la rama y crea un PR
# 4. Revisar y mergear
gh pr view
gh pr merge --squash
# 5. Actualizar local
git switch main
git pull

Ejercicios del módulo

Ejercicio 1 (Exploración): Si te interesa, instala uno de los agentes de IA y pruébalo en un proyecto de Git:

Terminal window
# Opción A: Claude Code
npm install -g @anthropic-ai/claude-code
cd tu-proyecto
claude
# Opción B: Gemini CLI
npm install -g @google/gemini-cli
cd tu-proyecto
gemini

Prueba pedirle: “Muéstrame el estado de Git de este proyecto” o “Haz commit de mis cambios con un buen mensaje”.

Ejercicio 2: Si instalaste un agente, prueba un flujo completo:

Terminal window
# Inicia el agente en un proyecto con Git
# Pídele que cree una rama, haga cambios, commit y PR
# Verifica que los commits sigan Conventional Commits
💡

Primero los fundamentos, después las herramientas

Los agentes de IA son aceleradores, no reemplazos. Primero aprende los fundamentos (los módulos 1 al 8 de este curso). Entender qué hace cada comando es esencial para poder verificar que las herramientas están haciendo lo correcto. Un agente que hace cosas que no entiendes es un riesgo, no una ayuda.

10

Git para equipos de trabajo

Cómo trabajar en equipo sin destruir el proyecto

Hasta ahora has aprendido Git como herramienta individual: commits, ramas, PRs, rebase. Pero cuando trabajas en equipo, la herramienta sola no basta. Necesitas convenciones: reglas compartidas que evitan el caos.

Imagina una cocina de restaurante. Todos los chefs saben cocinar, pero si cada uno guarda los ingredientes donde quiere, usa los cuchillos de otro y no avisa cuándo enciende el horno, el resultado es un desastre. La solución no es mejor equipo de cocina — es tener acuerdos sobre cómo trabajar juntos.

Este módulo te enseña esos acuerdos para Git: cómo nombrar ramas, escribir commits, proteger main, crear templates de PR, y evitar los errores más comunes en equipo.


Convenciones de ramas

Cuando trabajas solo, puedes nombrar tus ramas como quieras. En equipo, eso no funciona. Si una persona crea arreglo-login, otra fix/login-bug y otra hotfix_auth, nadie sabe qué está pasando.

La convención estándar:

tipo/descripcion-breve

Los tipos más comunes:

PrefijoCuándo usarloEjemplo
feature/Nueva funcionalidadfeature/filtro-busqueda
fix/Corrección de bugfix/login-timeout
hotfix/Arreglo urgente en producciónhotfix/crash-pagina-inicio
docs/Cambios de documentacióndocs/actualizar-readme
refactor/Reestructurar código sin cambiar funcionalidadrefactor/limpiar-utils
Terminal window
# Bien
git switch -c feature/carrito-compras
git switch -c fix/error-validacion-email
git switch -c docs/guia-instalacion
# Mal
git switch -c mi-rama
git switch -c cambios-pedro
git switch -c arreglo-cosa

La regla de oro: una tarea = una rama. Cada rama debe hacer una cosa específica. Si tu rama hace 5 cosas diferentes, va a ser imposible de revisar y dolorosa de mergear.

¿Cómo sé que mi rama es demasiado grande?

Si no puedes describir tu rama en una frase corta, probablemente necesitas dividirla. “Agrega filtro de búsqueda por categoría” es buena. “Mejora varias cosas del frontend” es señal de que debes dividir en varias ramas.


Convenciones de commits en equipo

En el Módulo 3 aprendiste Conventional Commits (feat:, fix:, docs:, etc.). En equipo, esto deja de ser una recomendación y se vuelve una regla: todos usan el mismo formato para que el historial sea legible y consistente.

Recordatorio rápido del formato:

Terminal window
git commit -m "feat: agrega botón de exportar a PDF"
git commit -m "fix: corrige cálculo de impuestos en factura"
git commit -m "docs: agrega sección de FAQ al README"
💡

¿Y los commits WIP?

Los commits “WIP” (Work In Progress) están bien mientras trabajas en tu rama. Son tu borrador. Lo importante es que al mergear el PR con squash merge (como viste en el Módulo 7), todos esos commits intermedios se combinan en uno limpio. Así el historial de main queda impecable.

Regla adicional para equipos: si necesitas más detalle, deja una línea en blanco y escribe un cuerpo descriptivo:

Terminal window
git commit -m "feat: agrega autenticación con Google
Implementa OAuth 2.0 para login con Google.
Incluye botón en la página de login y manejo de
tokens en el backend."

Branch protection en GitHub

Las convenciones de ramas y commits funcionan solo si todos las respetan. Pero, ¿qué pasa si alguien hace push directo a main por accidente? Para eso existen las reglas de protección de ramas.

Branch protection le dice a GitHub: “No dejes que nadie modifique main directamente. Todo debe pasar por un Pull Request”.

Cómo configurarlo:

  1. Ve a tu repositorio en GitHub
  2. SettingsBranches
  3. Haz clic en Add branch ruleset (o “Add rule” en repos más antiguos)
  4. En “Branch name pattern” escribe: main
  5. Activa estas reglas:
ReglaQué hace
Require a pull request before mergingNadie puede hacer push directo a main
Require approvals (1)Al menos una persona debe aprobar el PR
Do not allow bypassing the above settingsNi siquiera los admins pueden saltarse las reglas
Terminal window
# Con branch protection activado:
# Esto FALLA (push directo a main)
git switch main
echo "cambio directo" >> archivo.txt
git add . && git commit -m "cambio directo"
git push
# ❌ remote: error: GH006: Protected branch update failed
# Esto FUNCIONA (via PR)
git switch -c fix/mi-cambio
echo "cambio via PR" >> archivo.txt
git add . && git commit -m "fix: cambio correcto via PR"
git push -u origin fix/mi-cambio
gh pr create --title "Fix: mi cambio" --body "Descripción"
# ✅ PR creado, esperando revisión
⚠️

Branch protection es gratis para repos públicos

En repos privados, necesitas GitHub Team o Enterprise para configurar branch protection con todas las opciones. En repos públicos de GitHub, todas las reglas están disponibles de forma gratuita.


PR Templates

Cuando alguien crea un Pull Request, ¿cómo sabes qué debe incluir? Un PR template es un archivo que GitHub usa automáticamente como plantilla cada vez que alguien crea un PR.

Cómo crearlo:

Terminal window
# Desde la raíz de tu proyecto
mkdir -p .github

Puedes crear este archivo directamente en VS Code: crea la carpeta .github/ y dentro el archivo pull_request_template.md con el siguiente contenido:

.github/pull_request_template.md
## ¿Qué hace este PR?
<!-- Describe brevemente los cambios -->
## Tipo de cambio
- [ ] Nueva funcionalidad (feature)
- [ ] Corrección de bug (fix)
- [ ] Documentación (docs)
- [ ] Refactorización (refactor)
- [ ] Otro: ___
## ¿Cómo se probó?
<!-- Describe cómo verificaste que funciona -->
## Checklist
- [ ] Mi código sigue las convenciones del proyecto
- [ ] He probado mis cambios localmente
- [ ] He actualizado la documentación si es necesario
Terminal window
# Agregar al proyecto
git add .github/pull_request_template.md
git commit -m "chore: agrega template de Pull Request"
git push

Ahora, cada vez que alguien crea un PR en este repositorio, verá este template ya completado con las secciones. Solo tiene que rellenar los espacios.

Beneficio real del template

El template no es burocracia — es una checklist que evita errores. Sin template, los PRs suelen llegar sin descripción, sin pruebas y sin contexto. Con template, el revisor puede entender rápidamente qué hace el PR y cómo verificarlo.


Squash merge como convención de equipo

En el Módulo 7 viste las tres estrategias de merge y recomendamos squash merge como default. En equipo, esto se convierte en una configuración del repositorio:

Configurar squash como único método permitido:

  1. Settings → General → Pull Requests
  2. Desmarca “Allow merge commits” y “Allow rebase merge”
  3. Deja solo “Allow squash merging” marcado

Así ningún miembro del equipo puede mergear accidentalmente con otra estrategia. Todos los PRs producen un solo commit limpio en main.


Prevenir conflictos en equipo

En el Módulo 6 aprendiste a resolver conflictos técnicamente (los marcadores <<<<<<<, =======, >>>>>>>). En equipo, la clave no es solo resolverlos sino minimizarlos:

  1. Divide el trabajo por archivos/componentes. Si Ana trabaja en el header y Bob en el footer, no habrá conflictos.
  2. Haz pull frecuentemente. Actualiza tu rama diariamente, no cada 3 días.
  3. Ramas pequeñas, PRs frecuentes. Una rama de 2 días tiene menos conflictos que una de 2 semanas.
  4. Comunica antes de refactorizar. Mover archivos o renombrar funciones genera conflictos en todas las ramas activas. Avisa al equipo.
⚠️

Nunca resuelvas conflictos adivinando

Si no entiendes qué hace el código de la otra persona, pregunta. Resolver un conflicto adivinando puede introducir bugs que nadie detecta hasta producción.


Anti-patrones: lo que NO debes hacer en equipo

Estos son los errores más comunes que destruyen la productividad de un equipo. Si te reconoces en alguno, no te preocupes — todos los hemos cometido.

1. Commits gigantes

Terminal window
# MAL: un commit con 47 archivos modificados
git add .
git commit -m "muchos cambios"
# Imposible de revisar, imposible de revertir parcialmente
# BIEN: commits atómicos
git add src/auth/login.js
git commit -m "feat: agrega validación de email en login"
git add src/auth/register.js
git commit -m "feat: agrega validación de email en registro"

2. Trabajar directamente en main

Terminal window
# MAL
git switch main
# ... hacer cambios durante 3 días ...
git push
# Acabas de romper main para todos
# BIEN
git switch -c feature/mi-cambio
# ... trabajar tranquilo en tu rama ...

3. No hacer pull antes de empezar a trabajar

Terminal window
# MAL: empezar a trabajar sin actualizar
git switch -c feature/nueva
# Tu rama está basada en un main desactualizado
# Vas a tener conflictos innecesarios
# BIEN: siempre actualizar primero
git switch main
git pull
git switch -c feature/nueva
# Ahora tu rama está basada en la versión más reciente

4. Acumular ramas que ya se mergearon

feature/login
# MAL: nunca limpiar
git branch
# feature/header
# feature/footer-v1
# feature/footer-v2
# fix/bug-viejo
# ... 30 ramas más que ya se mergearon
# BIEN: limpiar después de cada merge
git branch -d feature/mi-rama-mergeada
# O limpiar todas las ramas mergeadas de una vez
git branch --merged main | grep -v main | xargs git branch -d

5. Force push a main

Terminal window
# NUNCA hagas esto
git push --force origin main
# Esto REESCRIBE el historial compartido
# Todos los miembros del equipo van a tener problemas
# Force push a TU rama está OK (con cuidado)
git push --force origin feature/mi-rama
# Esto está bien si solo tú trabajas en esa rama
⚠️

¿Se puede deshacer un force push a main?

Técnicamente sí, con git reflog en el servidor. Pero en la práctica, es un incendio. Cada miembro del equipo va a tener conflictos, referencias rotas y confusión. La regla es simple: nunca force push a ramas compartidas.


Guía rápida de decisión para equipos

¿Cómo colaborar? Si es un proyecto de tu equipo, usa clone + ramas + PR (Módulo 7). Si es un proyecto ajeno, usa fork (Módulo 8).

¿Cómo mergear PRs? Configura squash merge como default (como viste arriba). Es la opción más segura y mantiene main limpio.


Extra: AGENTS.md — tus convenciones para agentes de IA

Si usas agentes de IA como Claude Code o Gemini CLI (Módulo 9), cuando trabajas con ellos en un proyecto de equipo surge un problema: el agente no conoce las convenciones de tu equipo. Puede hacer commits con mensajes en inglés cuando tu equipo los escribe en español, o hacer push directo a main cuando tu equipo usa PRs.

La solución es un archivo AGENTS.md (o CLAUDE.md, dependiendo del agente) en la raíz de tu repositorio. Este archivo le dice al agente de IA las reglas del proyecto, exactamente igual que el PR template le dice a un humano cómo crear un PR.

Piénsalo así: el PR template es la “guía para humanos” y AGENTS.md es la “guía para IAs”.

¿Qué poner en un AGENTS.md?

Las mismas convenciones que le explicarías a un nuevo miembro del equipo:

AGENTS.md
# AGENTS.md
## Flujo de trabajo Git
Este equipo usa el flujo Feature Branch + Squash Merge.
### Reglas de Git
- Nunca hacer commit directo a main
- Crear ramas con formato: tipo/descripcion-corta
- Tipos: feature/, fix/, docs/, refactor/
- Mensajes de commit en español, imperativo, una línea
- Ejemplo: "Agregar filtro por región al dashboard"
- Antes de hacer push, verificar que el código corre sin errores
### Pull Requests
- Todo merge a main pasa por PR
- Usar squash merge
- Descripción del PR debe incluir: qué hace, por qué, cómo probarlo
- Borrar la rama después del merge
### Resolución de conflictos
- Al resolver conflictos, explicar qué versión se eligió y por qué
- No resolver conflictos automáticamente sin que el usuario entienda qué cambió
- Si el conflicto es ambiguo, mostrar ambas versiones y preguntar
### Convenciones del equipo
- Idioma: español para documentación, inglés para código
- Los nombres de variables y funciones en inglés
(snake_case para R, snake_case para Python)
- Los comentarios en el código pueden ser en español
Terminal window
# Agregar al proyecto
git add AGENTS.md
git commit -m "docs: agrega AGENTS.md con convenciones para agentes IA"
git push

¿Cómo funciona?

Cuando inicias un agente de IA en tu proyecto, este lee automáticamente el archivo AGENTS.md (o CLAUDE.md en el caso de Claude Code) y sigue las instrucciones. Así:

Terminal window
cd mi-proyecto
claude
# Claude Code lee CLAUDE.md automáticamente
> Haz commit de mis cambios
# Sin CLAUDE.md: "Update files" (genérico, en inglés)
# Con CLAUDE.md: "Agregar filtro por región al dashboard" (sigue las convenciones)
> Crea un PR con estos cambios
# Sin CLAUDE.md: push directo a main
# Con CLAUDE.md: crea rama feature/, push, crea PR con descripción

Cada agente tiene su archivo

  • Claude Code lee CLAUDE.md
  • Gemini CLI lee GEMINI.md
  • Formato genérico que varios agentes reconocen: AGENTS.md

Puedes tener los tres archivos en tu proyecto, o simplemente crear CLAUDE.md si tu equipo usa Claude Code. El contenido es el mismo — las convenciones de tu equipo escritas en lenguaje natural.

¿Qué incluir según tu proyecto?

SecciónQué ponerEjemplo
Flujo de GitCómo hacer commits, ramas, PRs”Usar squash merge, ramas con prefijo tipo/“
IdiomaEn qué idioma escribir commits, docs, código”Commits en español, código en inglés”
Estilo de códigoConvenciones de formato y naming”snake_case para Python, camelCase para JS”
TestingCómo correr y escribir tests”Correr npm test antes de hacer commit”
RestriccionesQué NO hacer”Nunca force push a main”
💡

AGENTS.md es documentación viva

Al igual que el README, el archivo AGENTS.md debería evolucionar con tu proyecto. Cuando el equipo adopte una nueva convención, agrégala al archivo. Así, tanto humanos como agentes de IA siguen las mismas reglas — y el código se mantiene consistente.

Para una guía completa con todo el contenido de este curso condensado para agentes de IA — incluyendo un template de AGENTS.md expandido con todas las secciones que puedes personalizar — revisa el archivo GUIA-GIT-AGENTES-IA.md en el repositorio del curso.


Tabla resumen de comandos

Comando Descripción
git switch -c feature/nombre Crear rama con convención de nombre
git commit -m "feat: descripción" Commit con Conventional Commits
git push -u origin feature/nombre Subir rama al remoto
gh pr create --title "..." --body "..." Crear PR desde la terminal
gh pr merge --squash Mergear PR con squash
git branch --merged main | grep -v main | xargs git branch -d Eliminar ramas ya mergeadas
git switch main && git pull Actualizar main antes de crear rama nueva
mkdir -p .github Crear carpeta para PR template

Ejercicios del módulo

Ejercicio 1: Crea un repositorio siguiendo todas las convenciones:

Terminal window
mkdir proyecto-equipo-10 && cd proyecto-equipo-10
git init
echo "# Proyecto con convenciones" > README.md
git add . && git commit -m "chore: inicializa proyecto"
# Crea un PR template
mkdir -p .github
echo "## ¿Qué hace este PR?" > .github/pull_request_template.md
echo "" >> .github/pull_request_template.md
echo "## Tipo de cambio" >> .github/pull_request_template.md
echo "- [ ] Feature" >> .github/pull_request_template.md
echo "- [ ] Fix" >> .github/pull_request_template.md
echo "- [ ] Docs" >> .github/pull_request_template.md
echo "" >> .github/pull_request_template.md
echo "## ¿Cómo se probó?" >> .github/pull_request_template.md
git add . && git commit -m "chore: agrega template de Pull Request"

Ejercicio 2: Practica el flujo de ramas con convenciones:

Terminal window
# Crea una rama con nombre correcto
git switch -c feature/agregar-estilos
# Haz commits con Conventional Commits
echo "body { margin: 0; }" > estilos.css
git add . && git commit -m "feat: agrega estilos base del proyecto"
echo "h1 { color: blue; }" >> estilos.css
git add . && git commit -m "feat: agrega estilo para títulos"
# Vuelve a main
git switch main

Ejercicio 3: Simula el flujo completo de equipo (si tienes un repo en GitHub):

Terminal window
# Sube el proyecto
gh repo create proyecto-equipo-10 --public --source=. --push
# Configura branch protection en Settings → Branches → Add rule
# Activa "Require a pull request before merging"
# Intenta push directo a main (debería fallar)
echo "cambio directo" >> README.md
git add . && git commit -m "test: push directo"
git push
# ❌ Debería fallar
# Hazlo correctamente via PR
git switch -c fix/actualizar-readme
git push -u origin fix/actualizar-readme
gh pr create --title "fix: actualiza README" --body "Cambio hecho correctamente via PR"
gh pr merge --squash
git switch main && git pull

Ejercicio 4: Limpia ramas mergeadas:

Terminal window
# Ver todas las ramas
git branch
# Eliminar ramas que ya se mergearon
git branch --merged main | grep -v main | xargs git branch -d
# Verificar que solo queda main
git branch
💡

Convenciones = menos fricción

Las convenciones no son reglas arbitrarias — son acuerdos que reducen la confusión y los errores en equipo. Al principio parecen “extra”, pero después de un par de semanas las haces automáticamente. Y cuando alguien nuevo se une al equipo, puede entender el proyecto rápido leyendo el historial de commits y las ramas activas.

Rutinas diarias

Tu código solo existe si está en la nube

Para profesionales que no vienen del mundo del desarrollo, hay una regla de oro: el código que solo vive en tu computador no existe para el resto del equipo. Si mañana te enfermas, te mandan a terreno o tu computador falla, el equipo necesita poder retomar tu trabajo.

Estas rutinas son hábitos que deberías incorporar desde el primer día. Con el tiempo se vuelven automáticas, como guardar un documento con Ctrl+S.


Rutina de apertura (mañana)

Antes de escribir una sola línea de código, asegúrate de estar trabajando con la versión más reciente del proyecto:

Terminal window
# 1. Ir a la rama principal
git switch main
# 2. Traer los cambios que tus compañeros subieron
git pull
# 3. Ir a tu rama de trabajo (o crear una nueva)
git switch mi-rama
# o si empiezas una tarea nueva:
git switch -c tu-nombre/nueva-tarea

¿Por qué es importante?

Si te saltas el git pull, podrías estar trabajando sobre una versión vieja del proyecto. Cuando intentes subir tus cambios, tendrás conflictos innecesarios que te van a hacer perder tiempo.


Rutina de cierre (antes de apagar el computador)

Esta es la rutina más importante. Úsala siempre antes de irte, incluso si tu código está a medias o el script tira errores. La meta no es entregar algo perfecto, sino respaldar tu progreso en la nube.

Paso 1: Mirar qué vas a guardar

Antes de subir nada, dale una mirada rápida a los archivos que modificaste. Este es el “ojo clínico” para asegurarte de que no estás subiendo un .csv o .xlsx por accidente (si te saltaste el .gitignore).

Terminal window
git status

Si ves archivos de datos en rojo, ¡alto ahí! No los subas. Agrégalos al .gitignore primero.

Paso 2: Empaquetar tus cambios

Selecciona los scripts o archivos en los que trabajaste hoy:

Terminal window
git add scripts/03_analisis_descriptivo.R

Paso 3: El commit de “fin de día” (WIP)

Si tu tarea está terminada, pon un mensaje normal. Pero si dejas un script a medias o con un error que vas a arreglar mañana, usa el prefijo WIP (Work In Progress / Trabajo en progreso). Esto le avisa a tus colegas que ese código es un borrador:

Terminal window
# Tarea terminada:
git commit -m "Agrega análisis descriptivo de variables clínicas"
# Tarea a medias (WIP):
git commit -m "WIP: avance en cruce de datos, falta revisar valores nulos"

Paso 4: Enviar a la nube (vital)

Este es el paso que realmente respalda tu trabajo. Si no haces esto, tus avances siguen atrapados en tu disco duro:

Terminal window
# Si es la primera vez que subes esta rama:
git push -u origin tu-nombre/analisis-datos
# Si ya la habías subido antes:
git push

Rutina de fin de semana

Los viernes (o el último día antes de un feriado largo) hay un paso extra: asegúrate de que tu trabajo esté no solo respaldado, sino comprensible para otro humano.

Terminal window
# 1. Rutina de cierre normal
git status
git add .
git commit -m "WIP: estado actual del análisis antes del fin de semana"
git push
# 2. (Opcional) Dejar una nota en el PR o en un issue
# Si tienes un Pull Request abierto, deja un comentario
# explicando en qué quedaste y qué falta
💡

Piensa en tu yo del lunes

El lunes vas a abrir tu computador y no vas a recordar en qué estabas. Un buen mensaje de commit WIP o un comentario en el PR te ahorra 30 minutos de “¿dónde quedé?”.


El día completo en 3 líneas

Para pegar en un post-it junto a tu pantalla:

☀️ Mañana: git switch main → git pull → git switch mi-rama
💻 Día: Escribir código sin tocar los archivos de datos originales
🌙 Tarde: git status → git add → git commit → git push
⚠️

¿Y si me fui sin hacer push?

No pasa nada grave (tus commits locales siguen ahí), pero pierdes la protección de la nube. Al día siguiente, lo primero que haces es el push pendiente antes de seguir trabajando. El hábito se forma con la repetición: después de unas semanas se vuelve automático.

Regla para equipos

Si lideras un equipo, establece la regla: nada queda solo en local al final del día. No importa si el código está incompleto — un commit WIP respaldado en GitHub es infinitamente mejor que código perfecto que solo existe en el disco duro de alguien.

Errores comunes y sus soluciones

Todos metemos la pata. Git está preparado para eso.

No importa cuánta experiencia tengas: tarde o temprano vas a cometer un error con Git. Un push que no debías, un commit en la rama equivocada, un mensaje con un typo vergonzoso… le pasa a todo el mundo.

Esta sección es tu botiquín de primeros auxilios. Guárdala en favoritos. Vuelve aquí cada vez que algo salga mal. Está organizada por el error que cometiste, con la solución paso a paso.

Regla de oro antes de cualquier arreglo

Siempre ejecuta git status y git log --oneline antes de intentar arreglar algo. Necesitas entender dónde estás parado antes de actuar.


”Me equivoqué en el nombre de la rama”

Con las prisas es facilísimo escribir mal el nombre de una rama. No necesitas borrarla y crearla de nuevo, simplemente renómbrala:

Terminal window
# Creaste la rama con un typo
git switch -c feature/logni
# ¡Ups! Era "login", no "logni"
# Renombrar la rama (estando en ella)
git branch -m feature/logni feature/login
# Listo, la rama ahora se llama feature/login

La flag -m viene de “move” (mover/renombrar).

¿Y si ya habías hecho push de la rama con el nombre mal escrito?

No pasa nada. Asegúrate de tener todos los cambios en local, renombra la rama y luego:

Terminal window
# Renombrar en local
git branch -m feature/logni feature/login
# Borrar la rama vieja del remoto
git push origin --delete feature/logni
# Subir la rama con el nombre correcto
git push -u origin feature/login

“Hice push y me da error (rejected)”

Este es probablemente el error más común para principiantes. Intentas hacer git push y Git te rechaza:

Terminal window
git push origin main
# ! [rejected] main -> main (non-fast-forward)
# error: failed to push some refs to 'github.com:tu-usuario/tu-repo.git'
# hint: Updates were rejected because the tip of your current branch is behind
# hint: its remote counterpart. Integrate the remote changes (e.g.
# hint: 'git pull ...') before pushing again.

¿Qué pasó? Tu versión local de main está “atrás” de la versión en GitHub. Alguien (o tú desde otra máquina) subió cambios que tú no tienes todavía.

Solución:

Terminal window
# Traer los cambios remotos y fusionarlos con los tuyos
git pull origin main
# Si no hay conflictos, ahora sí puedes hacer push
git push origin main

Si al hacer pull hay conflictos, resuélvelos como aprendiste en el Módulo 6 (editar el archivo, quitar los marcadores <<<<<<<, =======, >>>>>>>, hacer add y commit), y luego haz push.

Prevención

Acostúmbrate a hacer git pull antes de empezar a trabajar cada día. Así siempre partes con la versión más actualizada y reduces conflictos.


”Hice commits en main pero debían ir a otra rama”

A todos nos ha pasado. Te pusiste a trabajar directamente en main sin crear una rama. Tranquilo, tiene solución y no pierdes nada.

Caso 1: La rama todavía no existe

Imagina que hiciste 3 commits en main que debían ir a una rama nueva:

Terminal window
# Verificar que estás en main
git branch
# * main
# Crear la nueva rama (que tendrá todos los commits actuales de main)
git branch feature/mis-cambios
# OJO: git branch SIN -c, solo crea la rama, NO te mueve a ella
# Mover main 3 commits hacia atrás
git reset --keep HEAD~3
# Ahora cambiar a la nueva rama (que tiene los 3 commits)
git switch feature/mis-cambios
# ¡Tus commits están aquí, y main está limpio!

--keep es como un punto medio entre --soft y --hard: mueve la rama hacia atrás (deshace los commits) pero conserva los cambios en tus archivos si no causan conflictos. Es más seguro que --hard porque no destruye tu trabajo.

Caso 2: La rama ya existía

Si los commits debían ir a una rama que ya existía:

Terminal window
# Ir a la rama que debía recibir los commits
git switch feature/mis-cambios
# Traer los commits de main
git merge main
# Volver a main y limpiarla
git switch main
git reset --keep HEAD~3
⚠️

Solo si NO hiciste push

Esta solución funciona si los commits todavía no fueron subidos a GitHub. Si ya hiciste push a main, la situación es más compleja. En ese caso, es mejor usar git revert para deshacer los commits en main y luego hacer cherry-pick a la rama correcta.


”Quiero deshacer el último commit (pero conservar los archivos)”

Hiciste un commit pero te arrepentiste. Quizás el mensaje estaba mal, o te faltó agregar un archivo.

Terminal window
# Deshacer el último commit, archivos quedan en staging (listos para commit)
git reset --soft HEAD~1
# Verificar
git status
# Tus archivos siguen ahí, en verde, listos para un nuevo commit

Ahora puedes:

  • Corregir el mensaje: git commit -m "Mensaje correcto"
  • Agregar un archivo olvidado: git add archivo-olvidado.txt y luego git commit -m "..."
  • Hacer más cambios antes de commitear de nuevo

”Quiero deshacer cambios en un archivo que todavía no commitee”

Estás editando un archivo y de repente todo es un desastre. Quieres volver a como estaba en el último commit.

Si el archivo NO está en staging (no hiciste git add):

Terminal window
# Restaurar un archivo al estado del último commit
git restore archivo.txt

(Nota: en tutoriales antiguos verás git checkout -- archivo.txt. Hace lo mismo, pero git restore es la forma moderna y más clara.)

Si el archivo YA está en staging (hiciste git add):

Terminal window
# Primero sacarlo del staging
git restore --staged archivo.txt
# Luego restaurar el contenido
git restore archivo.txt
⚠️

Esto borra tus cambios

git restore descarta los cambios que hiciste en el archivo. Si no hiciste commit de esos cambios, se pierden. Asegúrate de que realmente quieres descartarlos.


”Quiero descartar TODOS los cambios locales y quedar igual al remoto”

A veces te fuiste por un camino que no funcionó y quieres empezar de cero con lo que hay en GitHub, sin conservar nada local.

Si solo tienes archivos modificados (sin archivos nuevos):

Terminal window
# Descartar todos los cambios en archivos tracked
git restore .
# Actualizar con lo último del remoto
git pull

git restore . descarta todos los cambios no commiteados de golpe. Es el equivalente a hacer git restore archivo.txt para cada archivo modificado.

Si además creaste archivos nuevos que quieres borrar:

Terminal window
# Descartar cambios en archivos tracked
git restore .
# Borrar archivos y carpetas no rastreados por Git
git clean -fd
# Actualizar
git pull
⚠️

Esto borra todo sin preguntar

git restore . y git clean -fd no piden confirmación. Si tenías cambios que querías conservar, se pierden. Siempre haz git status primero para verificar qué vas a descartar.

¿Solo quieres ver qué se borraría?

Usa git clean -n (dry run) para ver qué archivos se eliminarían, sin borrar nada.


”Hice git add de un archivo que no debía”

Agregaste un archivo al staging por error (quizás un .env con contraseñas o un archivo temporal):

Terminal window
# Sacar un archivo del staging (sin borrarlo)
git restore --staged archivo-secreto.env
# Verificar
git status
# El archivo vuelve a "Untracked" o "Modified", pero NO se borra del disco

Si ya hiciste commit de ese archivo y quieres sacarlo del seguimiento de Git sin borrarlo del disco:

Terminal window
# Dejar de rastrear el archivo (sin borrarlo)
git rm --cached archivo-secreto.env
# Agregarlo al .gitignore para que no vuelva a pasar
echo "archivo-secreto.env" >> .gitignore
# Hacer commit del cambio
git add .gitignore
git commit -m "Deja de rastrear archivo secreto y lo agrega a .gitignore"

“Me quedé atrapado en Vim”

Es un clásico. Git abrió un editor de texto raro lleno de tildes (~) y no puedes salir.

Eso es Vim, un editor de texto en terminal. Git lo abre cuando necesita que escribas un mensaje (por ejemplo, durante un merge o un revert sin -m).

Para escapar:

Terminal window
# Presiona estas teclas en orden:
# 1. Esc (para asegurarte de estar en modo normal)
# 2. Escribe :q! (dos puntos, q, exclamación)
# 3. Presiona Enter

:q! significa “salir sin guardar”. Si quieres guardar el mensaje y salir: :wq (write + quit).

Para que no vuelva a pasar, configura VS Code como editor (si no lo hiciste en el Módulo 2):

Terminal window
git config --global core.editor "code --wait"

“Error en macOS: xcrun: error: invalid active developer path”

Este error aparece frecuentemente después de actualizar macOS:

/Library/Developer/CommandLineTools/usr/bin/xcrun
git status
# xcrun: error: invalid active developer path
# (/Library/Developer/CommandLineTools),

Solución:

Terminal window
xcode-select --install

Te aparecerá una ventana pidiendo instalar las herramientas de desarrollo. Acéptala y espera a que termine (puede tardar unos minutos).

Si sigue sin funcionar después de instalar:

  1. Reinicia tu Mac
  2. Si persiste: sudo xcode-select --reset
  3. Último recurso: descarga manualmente las Command Line Tools desde developer.apple.com

”Hice merge y se hizo un desastre”

Si acabas de hacer un merge y todo salió mal (archivos rotos, conflictos por todos lados), puedes abortar el merge y volver al estado anterior:

Terminal window
# Si el merge todavía no se completó (estás en medio de conflictos)
git merge --abort
# Vuelves al estado exacto de antes del merge
# Si ya completaste el merge (hiciste commit)
git revert -m 1 HEAD
# -m 1 le dice a Git "quiero quedarme con el estado de la rama principal (main)"
# Crea un nuevo commit que deshace el merge

git merge --abort es tu botón de pánico. Úsalo sin miedo, es completamente seguro.


”Quiero ver qué tenía un archivo en un commit anterior”

A veces no quieres viajar al pasado completo, solo quieres espiar cómo era UN archivo en un momento específico:

Terminal window
# Ver el contenido de un archivo en un commit específico
git show abc1234:ruta/al/archivo.txt
# Ver cómo era el archivo hace 3 commits
git show HEAD~3:ruta/al/archivo.txt

Esto solo muestra el contenido en la terminal, no modifica nada.

Si quieres recuperar esa versión del archivo:

Terminal window
# Restaurar un archivo a como era en un commit específico
git restore --source=abc1234 ruta/al/archivo.txt
# Ahora el archivo en tu carpeta tiene el contenido antiguo
# Puedes hacer add y commit si quieres conservarlo

Tabla resumen de emergencias

Comando Descripción
git branch -m nombre-viejo nombre-nuevo Renombrar una rama
git pull origin main Arreglar error de push rejected
git reset --soft HEAD~1 Deshacer último commit (archivos quedan en staging)
git reset --keep HEAD~3 Mover rama N commits atrás (conservando archivos)
git restore archivo.txt Descartar cambios no commiteados en un archivo
git restore . Descartar TODOS los cambios no commiteados
git clean -fd Borrar archivos y carpetas no rastreados
git restore --staged archivo.txt Sacar un archivo del staging
git rm --cached archivo.txt Dejar de rastrear un archivo (sin borrarlo)
git merge --abort Cancelar un merge en progreso
git show HEAD~3:archivo.txt Ver cómo era un archivo en el pasado
git restore --source=hash archivo.txt Recuperar versión antigua de un archivo
Esc → :q! → Enter Escapar de Vim
💡

Recuerda: Git está de tu lado

Git fue diseñado para que puedas equivocarte. Casi todo tiene solución, y los pocos comandos realmente destructivos (--hard, --force) siempre requieren que tú explícitamente los pidas. Si no usas esas flags, es muy difícil perder trabajo de verdad.

Cuando algo salga mal, respira, haz git status, y busca tu error en esta lista. Vas a estar bien.

Ejercicios integradores finales

Pon a prueba todo lo que aprendiste

Estos ejercicios integradores combinan todos los conceptos del curso. Cada uno simula una situación real y te guía paso a paso.

Consejo antes de empezar

Crea una carpeta de trabajo para todos los ejercicios:

Terminal window
mkdir ~/ejercicios-git && cd ~/ejercicios-git

Así mantienes todo organizado. Cada ejercicio creará su propia carpeta dentro.

No te preocupes si necesitas consultar los módulos anteriores. Eso es totalmente normal y esperado. La idea es practicar, no memorizar.


Ejercicio 1: Mi Primer Portafolio en Git

Contexto: Vas a crear un mini sitio web personal desde cero, usando Git para controlar cada paso, y lo subirás a GitHub.

Lo que practicarás: git init, git add, git commit, git remote, git push

Requisitos:

  • Crear un repositorio local con git init
  • Crear una estructura de carpetas para un sitio web
  • Crear un archivo HTML básico
  • Hacer al menos 3 commits con mensajes descriptivos
  • Crear un repositorio en GitHub y subir tu código
Ver solución
Terminal window
# Crear el proyecto
mkdir mi-portafolio && cd mi-portafolio
git init
# Crear estructura de carpetas
mkdir css js img
# Crear el HTML principal
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Mi Portafolio</title>
<link rel="stylesheet" href="css/estilos.css">
</head>
<body>
<h1>Bienvenido a mi portafolio</h1>
<p>Esta es mi primera página con control de versiones.</p>
</body>
</html>
EOF
# Primer commit: estructura base
git add .
git commit -m "Crea estructura base del portafolio con HTML"
# Agregar estilos
cat > css/estilos.css << 'EOF'
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
h1 { color: #333; }
p { color: #666; line-height: 1.6; }
EOF
# Segundo commit: estilos
git add .
git commit -m "Agrega estilos CSS para el portafolio"
# Agregar JavaScript
cat > js/app.js << 'EOF'
document.addEventListener('DOMContentLoaded', () => {
console.log('Portafolio cargado correctamente');
});
EOF
# Tercer commit: JavaScript
git add .
git commit -m "Agrega archivo JavaScript inicial"
# Verificar historial
git log --oneline
# Deberías ver 3 commits
# Crear repositorio vacío en GitHub (desde el navegador)
# Nombre: mi-portafolio, sin README
# Conectar y subir
git remote add origin https://github.com/tu-usuario/mi-portafolio.git
git push -u origin main
# ¡Verificar en GitHub que todo está!

Ejercicio 2: La Máquina del Tiempo

Contexto: Vas a practicar todas las formas de “viajar en el tiempo” con Git: visitar el pasado, revertir cambios y usar reset.

Lo que practicarás: git log, git switch --detach, git revert, git reset --soft

Preparación: Crea un repo con 5 commits, cada uno agregando una línea a un archivo.

Requisitos:

  • Viajar al commit #2 y volver
  • Revertir el commit #4
  • Hacer reset soft del último commit
Ver solución
Terminal window
# Preparación: crear repo con 5 commits
mkdir maquina-del-tiempo && cd maquina-del-tiempo
git init
echo "Línea 1: Inicio del viaje" > diario.txt
git add . && git commit -m "Agrega línea 1"
echo "Línea 2: Primer descubrimiento" >> diario.txt
git add . && git commit -m "Agrega línea 2"
echo "Línea 3: Todo va bien" >> diario.txt
git add . && git commit -m "Agrega línea 3"
echo "Línea 4: Un error terrible" >> diario.txt
git add . && git commit -m "Agrega línea 4 (error)"
echo "Línea 5: Intentando arreglar" >> diario.txt
git add . && git commit -m "Agrega línea 5"
# Ver el historial
git log --oneline
# Verás 5 commits, anota los hashes
# --- VIAJE 1: Visitar el commit #2 ---
# Usa el hash de tu segundo commit
git switch --detach HEAD~3
# (HEAD~3 = 3 commits atrás = commit #2)
cat diario.txt
# Solo debería tener las líneas 1 y 2
git switch main
# ¡De vuelta al presente!
# --- VIAJE 2: Revertir el commit #4 (el "error") ---
# Busca el hash del commit #4
git log --oneline
# Copia el hash del commit "Agrega línea 4 (error)"
git revert HEAD~1
# (HEAD~1 = el penúltimo commit, que es el #4 si contamos desde el actual)
# Se abrirá tu editor. Guarda y cierra.
git log --oneline
# Verás un nuevo commit "Revert" al principio
cat diario.txt
# La línea 4 debería haber desaparecido
# --- VIAJE 3: Reset soft del último commit ---
echo "Línea extra para probar reset" >> diario.txt
git add . && git commit -m "Commit que vamos a deshacer"
git reset --soft HEAD~1
git status
# Los cambios están en staging (verde), el commit desapareció
# Puedes hacer un nuevo commit con mejor mensaje o seguir editando
# Si quieres descartar los cambios completamente:
git restore --staged diario.txt
# Saca los cambios del staging
git restore diario.txt
# Descarta los cambios del archivo

Ejercicio 3: El Laboratorio de Ramas

Contexto: Vas a simular el desarrollo de 3 features en paralelo, como si fueras un equipo de desarrollo.

Lo que practicarás: git switch -c, git merge, resolución de conflictos, git branch -d

Requisitos:

  • Crear una rama main con una base
  • Crear 3 ramas feature (header, contenido, footer)
  • Hacer commits en cada rama
  • Mergear en orden
  • Provocar y resolver un conflicto
Ver solución
Terminal window
# Crear proyecto base
mkdir lab-ramas && cd lab-ramas
git init
# Crear archivo base
cat > pagina.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
<!-- Aquí va el header -->
<!-- Aquí va el contenido -->
<!-- Aquí va el footer -->
</body>
</html>
EOF
git add . && git commit -m "Crea estructura base de la página"
# --- RAMA 1: feature/header ---
git switch -c feature/header
cat > pagina.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
<header><h1>Mi Sitio Web</h1></header>
<!-- Aquí va el contenido -->
<!-- Aquí va el footer -->
</body>
</html>
EOF
git add . && git commit -m "Agrega header con título"
# --- RAMA 2: feature/contenido ---
git switch main
git switch -c feature/contenido
cat > pagina.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
<!-- Aquí va el header -->
<main><p>Bienvenido a mi sitio web. Aquí encontrarás cosas geniales.</p></main>
<!-- Aquí va el footer -->
</body>
</html>
EOF
git add . && git commit -m "Agrega contenido principal"
# --- RAMA 3: feature/footer ---
git switch main
git switch -c feature/footer
cat > pagina.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
<!-- Aquí va el header -->
<!-- Aquí va el contenido -->
<footer><p>© 2024 Mi Sitio</p></footer>
</body>
</html>
EOF
git add . && git commit -m "Agrega footer con copyright"
# --- MERGE 1: header (limpio) ---
git switch main
git merge feature/header
# Fast-forward, sin conflictos
# --- MERGE 2: contenido (CONFLICTO) ---
git merge feature/contenido
# CONFLICT! Ambas ramas modificaron pagina.html
# Resolver el conflicto: edita pagina.html manualmente
# y deja el contenido combinado correctamente:
cat > pagina.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
<header><h1>Mi Sitio Web</h1></header>
<main><p>Bienvenido a mi sitio web. Aquí encontrarás cosas geniales.</p></main>
<!-- Aquí va el footer -->
</body>
</html>
EOF
git add pagina.html
git commit -m "Resuelve conflicto: combina header y contenido"
# --- MERGE 3: footer (CONFLICTO) ---
git merge feature/footer
# Otro conflicto, resolver igual:
cat > pagina.html << 'EOF'
<!DOCTYPE html>
<html>
<body>
<header><h1>Mi Sitio Web</h1></header>
<main><p>Bienvenido a mi sitio web. Aquí encontrarás cosas geniales.</p></main>
<footer><p>© 2024 Mi Sitio</p></footer>
</body>
</html>
EOF
git add pagina.html
git commit -m "Resuelve conflicto: agrega footer a la página completa"
# --- LIMPIEZA ---
git branch -d feature/header feature/contenido feature/footer
git log --oneline
# ¡Deberías ver todo el historial de merges!

Ejercicio 4: Colaboración Simulada

Contexto: Vas a simular trabajo en equipo usando GitHub. Clonarás el mismo repo en dos carpetas diferentes (como si fueran dos personas) y cada una creará cambios que se integrarán via Pull Request.

Lo que practicarás: git clone, git push, Pull Requests, git pull

Requisitos:

  • Crear un repo en GitHub
  • Clonarlo en 2 carpetas diferentes (simulando 2 personas)
  • Cada “persona” crea una rama, hace cambios, push y PR
  • Mergear ambos PRs
  • Actualizar ambas copias locales
Ver solución
Terminal window
# 1. Crear repo base y subirlo a GitHub
mkdir proyecto-equipo && cd proyecto-equipo
git init
echo "# Proyecto del Equipo" > README.md
echo "Lista de tareas:" > tareas.txt
git add . && git commit -m "Crea proyecto base del equipo"
# Crear repo en GitHub (nombre: proyecto-equipo, vacío)
git remote add origin https://github.com/tu-usuario/proyecto-equipo.git
git push -u origin main
# 2. Simular dos personas clonando el repo
cd ..
git clone https://github.com/tu-usuario/proyecto-equipo.git persona-alice
git clone https://github.com/tu-usuario/proyecto-equipo.git persona-bob
# 3. Alice trabaja en su feature
cd persona-alice
git switch -c feature/alice-diseño
echo "- [ ] Diseñar la página principal" >> tareas.txt
echo "Alice estuvo aquí" > alice.txt
git add . && git commit -m "Alice agrega tareas de diseño"
git push -u origin feature/alice-diseño
# Alice crea un PR desde GitHub
# 4. Bob trabaja en su feature
cd ../persona-bob
git switch -c feature/bob-backend
echo "- [ ] Crear la API REST" >> tareas.txt
echo "Bob estuvo aquí" > bob.txt
git add . && git commit -m "Bob agrega tareas de backend"
git push -u origin feature/bob-backend
# Bob crea un PR desde GitHub
# 5. Mergear PRs desde GitHub (uno por uno)
# Primero merge el PR de Alice
# Luego merge el PR de Bob (puede tener conflicto en tareas.txt)
# 6. Ambos actualizan su copia local
cd ../persona-alice
git switch main
git pull
cd ../persona-bob
git switch main
git pull
# ¡Ambos tienen el mismo código actualizado!

Ejercicio 5: Proyecto Integrador — Diario de Aprendizaje

Contexto: Este es el ejercicio final. Vas a crear un proyecto que usa TODOS los conceptos del curso: init, commits, ramas, merge con conflicto, revert, push, Pull Request y limpieza.

Lo que practicarás: Todo lo aprendido en los módulos 1-10.

Requisitos:

  • Crear un repositorio con estructura profesional
  • Crear un archivo .gitignore
  • Usar ramas para cada sección del diario
  • Mergear con al menos un conflicto
  • Revertir un “error”
  • Subir a GitHub
  • Crear y mergear un Pull Request
  • Limpieza final de ramas
Ver solución
Terminal window
# ===== FASE 1: Crear el proyecto =====
mkdir diario-aprendizaje && cd diario-aprendizaje
git init
# Crear .gitignore
cat > .gitignore << 'EOF'
# Archivos del sistema
.DS_Store
Thumbs.db
# Archivos temporales
*.tmp
*.log
# Carpeta de notas privadas
privado/
EOF
# Crear estructura
mkdir entradas recursos
echo "# Diario de Aprendizaje Git" > README.md
echo "Un diario personal donde documento mi viaje aprendiendo Git." >> README.md
git add . && git commit -m "Crea estructura base del diario con .gitignore"
# ===== FASE 2: Ramas para cada sección =====
# --- Rama: entrada del día 1 ---
git switch -c entrada/dia-1
cat > entradas/dia-01.md << 'EOF'
# Día 1: Primeros pasos con Git
Hoy aprendí qué es Git y cómo configurarlo.
Git es como una máquina del tiempo para mi código.
## Comandos aprendidos
- git init
- git config
- git status
EOF
git add . && git commit -m "Agrega entrada del día 1: primeros pasos"
git switch main
git merge entrada/dia-1
git branch -d entrada/dia-1
# --- Rama: entrada del día 2 ---
git switch -c entrada/dia-2
cat > entradas/dia-02.md << 'EOF'
# Día 2: Commits y el flujo básico
Hoy practiqué el flujo add-commit.
Es como preparar una foto y tomarla.
## Comandos aprendidos
- git add
- git commit
- git log
EOF
git add . && git commit -m "Agrega entrada del día 2: commits"
# También actualizar README desde esta rama
echo "" >> README.md
echo "## Entradas" >> README.md
echo "- Día 1: Primeros pasos" >> README.md
echo "- Día 2: Commits" >> README.md
git add . && git commit -m "Actualiza README con lista de entradas"
git switch main
# --- Provocar un conflicto en README ---
echo "" >> README.md
echo "## Notas" >> README.md
echo "Este diario lo empecé en el curso de Git." >> README.md
git add . && git commit -m "Agrega sección de notas al README"
# Merge con conflicto
git merge entrada/dia-2
# CONFLICT en README.md
# Resolver: combinar ambos cambios
cat > README.md << 'EOF'
# Diario de Aprendizaje Git
Un diario personal donde documento mi viaje aprendiendo Git.
## Entradas
- Día 1: Primeros pasos
- Día 2: Commits
## Notas
Este diario lo empecé en el curso de Git.
EOF
git add README.md
git commit -m "Resuelve conflicto: combina entradas y notas en README"
git branch -d entrada/dia-2
# ===== FASE 3: Simular un error y revertirlo =====
echo "ESTO ES UN ERROR TERRIBLE QUE NO DEBERÍA ESTAR AQUÍ" >> README.md
git add . && git commit -m "Agrega texto incorrecto al README"
# Revertir el error
git revert HEAD --no-edit
git log --oneline
# Verás el commit de revert
# ===== FASE 4: Subir a GitHub =====
# Crear repo en GitHub: diario-aprendizaje (vacío)
git remote add origin https://github.com/tu-usuario/diario-aprendizaje.git
git push -u origin main
# ===== FASE 5: Pull Request workflow =====
git switch -c entrada/dia-3
cat > entradas/dia-03.md << 'EOF'
# Día 3: Ramas y GitHub
Hoy aprendí sobre ramas y Pull Requests.
Las ramas son como universos paralelos.
## Comandos aprendidos
- git switch -c
- git merge
- git push
- git pull
EOF
echo "- Día 3: Ramas y GitHub" >> README.md
git add . && git commit -m "Agrega entrada del día 3: ramas y GitHub"
git push -u origin entrada/dia-3
# Crear PR desde GitHub, revisarlo y mergearlo
# ===== FASE 6: Limpieza final =====
git switch main
git pull
git branch -d entrada/dia-3
# Verificar que todo está limpio
git status
git branch
git log --oneline
# ¡Proyecto completo con historial profesional!

💡

¡Felicidades, completaste el curso!

Si llegaste hasta aquí y completaste los ejercicios, ya tienes las habilidades fundamentales para usar Git y GitHub en proyectos reales. Recuerda:

  • Practica regularmente: Usa Git en todos tus proyectos, aunque sean pequeños
  • No tengas miedo de equivocarte: Git está diseñado para que puedas corregir errores
  • Consulta la documentación: git help <comando> es tu amigo
  • Colabora: La mejor forma de aprender es trabajando con otras personas

¡Sigue practicando y feliz codificación!

Cheatsheet de Git

Tu referencia rápida de Git y GitHub

Imprime esta página o guárdala en favoritos. Cuando se te olvide un comando, vuelve aquí.

Consejo

No necesitas memorizar todo esto. Con el tiempo, los comandos que usas a diario se vuelven automáticos. Esta hoja es para los que usas de vez en cuando.


Configuración (una sola vez)

ComandoQué hace
git config --global user.name "Tu Nombre"Configura tu nombre
git config --global user.email "tu@correo.com"Configura tu correo
git config --global core.editor "code --wait"Configura VS Code como editor
git config --global init.defaultBranch mainRama principal como main
git config --listVer toda tu configuración

Flujo básico diario

Terminal window
# El flujo que usarás el 90% del tiempo:
git status # 1. ¿Qué cambió?
git add archivo.txt # 2. Preparar cambios
git commit -m "mensaje" # 3. Guardar snapshot
git push # 4. Subir a GitHub

Crear y gestionar repositorios

ComandoQué hace
git initActivar Git en la carpeta actual
git clone <URL>Descargar un repositorio de GitHub
git remote add origin <URL>Conectar repo local con GitHub
git remote -vVer conexiones remotas

Ver estado e historial

ComandoQué hace
git statusVer qué archivos cambiaron
git diffVer cambios antes de add
git diff --stagedVer cambios después de add
git log --onelineHistorial compacto
git log --oneline --graphHistorial con ramas visuales

Staging y commits

ComandoQué hace
git add archivo.txtPreparar un archivo
git add .Preparar todos los archivos
git commit -m "mensaje"Guardar snapshot
git restore --staged archivo.txtSacar del staging (sin perder cambios)
git restore archivo.txtDescartar cambios no commiteados
git restore .Descartar TODOS los cambios no commiteados

Ramas

ComandoQué hace
git branchListar ramas
git switch -c nombre-ramaCrear rama y moverse a ella
git switch nombre-ramaCambiar de rama
git merge nombre-ramaTraer cambios de otra rama
git branch -d nombre-ramaBorrar rama (ya mergeada)
git branch -m viejo nuevoRenombrar rama

Sincronización con GitHub

ComandoQué hace
git push -u origin mainSubir (primera vez)
git pushSubir (siguientes veces)
git pullDescargar y aplicar cambios
git fetchRevisar cambios sin aplicar
git push -u origin nombre-ramaSubir una rama

Viajes en el tiempo

ComandoQué hace
git switch --detach <hash>Visitar un commit pasado
git switch mainVolver al presente
git revert <hash>Deshacer un commit (seguro)
git reset --soft HEAD~1Deshacer commit, archivos en staging
git reset --hard HEAD~1Deshacer commit y BORRAR cambios

Emergencias

ComandoQué hace
git merge --abortCancelar un merge con conflictos
git restore .Descartar todos los cambios locales
git clean -fdBorrar archivos/carpetas no rastreados
git rm --cached archivo.txtDejar de rastrear sin borrar
git show HEAD~3:archivo.txtVer archivo en un commit pasado
git stashGuardar cambios temporalmente
git stash popRecuperar cambios guardados
Esc:q!EnterEscapar de Vim

GitHub CLI (gh)

ComandoQué hace
gh auth loginAutenticarse con GitHub
gh repo create nombre --public --source=. --pushCrear repo y subir
gh pr create --title "..." --body "..."Crear Pull Request
gh pr listListar PRs abiertos
gh pr merge --squashMergear un PR (squash merge)
gh issue create --title "..."Crear un issue
gh repo view --webAbrir repo en el navegador

.gitignore (patrones comunes)

Terminal window
# Archivos del sistema
.DS_Store
Thumbs.db
# Variables de entorno y secretos
.env
*.secret
# Dependencias (se regeneran)
node_modules/
vendor/
# Archivos compilados / temporales
*.log
*.tmp
dist/
build/

Flujo profesional (GitHub Flow)

1. git switch main && git pull ← Partir actualizado
2. git switch -c feature/mi-tarea ← Crear rama
3. (trabajar, git add, git commit) ← Hacer cambios
4. git push -u origin feature/mi-tarea ← Subir rama
5. Crear Pull Request en GitHub ← Pedir revisión
6. Merge en GitHub ← Aprobar y fusionar
7. git switch main && git pull ← Actualizar local
8. git branch -d feature/mi-tarea ← Limpieza

Resolver conflictos (paso a paso)

Terminal window
# 1. Git te avisa del conflicto al hacer merge
git merge otra-rama
# CONFLICT in archivo.txt
# 2. Abre el archivo y busca los marcadores:
# <<<<<<< HEAD
# (tu versión)
# =======
# (la otra versión)
# >>>>>>> otra-rama
# 3. Edita: borra los marcadores, deja el contenido correcto
# 4. Marca como resuelto y haz commit
git add archivo.txt
git commit -m "Resuelve conflicto en archivo.txt"
💡

¡Guarda esta página!

Con la práctica, cada vez necesitarás consultar menos esta hoja. Pero siempre es bueno tenerla a mano. ¡Feliz codificación!

Siguiente 1. Supervivencia en Terminal