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.
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 →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:
mkdir test-terminal && cd test-terminalecho "Hola Git" > prueba.txtcat prueba.txtls -lacd ..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!
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.zipmi-proyecto-final-v2.zipmi-proyecto-final-DEFINITIVO.zipmi-proyecto-final-DEFINITIVO-ahora-si.zipmi-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:
-
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ó.
-
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.
-
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:
sudo apt updatesudo apt install gitEl 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.
git --version# Si no está instalado, aparecerá un diálogo para instalarloAlternativa con Homebrew (si lo tienes): brew install git
Para verificar que se instaló correctamente:
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:
git config --global user.name "Tu Nombre Completo"Reemplaza "Tu Nombre Completo" por tu nombre real (con las comillas).
Configura tu correo electrónico:
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:
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:
git config --global init.defaultBranch mainNo 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:
git config --list# user.name=Tu Nombre Completo# user.email=tu@correo.com# core.editor=code --wait# init.defaultbranch=mainSi 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:
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:
git config --global core.editor "code --wait"Ejercicio 4: Verifica que toda tu configuración está correcta:
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!
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:
- Primero preparas a las personas para la foto (staging)
- Luego tomas la foto (commit)
- 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 proyectogit 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.
# Crear una carpeta para nuestro proyectomkdir mi-recetacd mi-receta
# Activar Git en esta carpetagit init# Initialized empty Git repository in /home/tu-usuario/mi-receta/.git/
# Verificar que se creó la carpeta oculta .gitls -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:
# 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:
# Crear un archivoecho "# 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”.
# Agregar un archivo específico al staginggit 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:
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.
# Primero, modifiquemos nuestro archivoecho "Pasta con salsa de tomate" >> receta.txt
# Ver los cambios ANTES de hacer addgit 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 tomateEse +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:
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:
git add receta.txtgit 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 cambioLos tipos más comunes:
| Tipo | Significado | Ejemplo |
|---|---|---|
feat: | Nueva funcionalidad | feat: agrega filtro por categoría |
fix: | Corrección de error | fix: corrige validación de email vacío |
docs: | Documentación | docs: actualiza guía de instalación |
refactor: | Reestructurar sin cambiar funcionalidad | refactor: extrae función de validación |
chore: | Mantenimiento (dependencias, config) | chore: actualiza dependencias |
# Con Conventional Commitsgit 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.
git log# commit a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 (HEAD -> main)# Author: Tu Nombre <tu@correo.com># Date: Lun Ene 15 11:30:00 2024## Agrega receta inicial de pastaPara una versión más compacta (muy útil cuando tienes muchos commits):
git log --oneline# a1b2c3d Agrega receta inicial de pastaCada 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:
# Crear .gitignore línea por líneaecho "# Archivos del sistema operativo" > .gitignoreecho ".DS_Store" >> .gitignoreecho "Thumbs.db" >> .gitignoreecho "" >> .gitignoreecho "# Archivos con contraseñas o datos sensibles" >> .gitignoreecho ".env" >> .gitignoreecho "*.secret" >> .gitignoreecho "" >> .gitignoreecho "# Carpetas de dependencias (se regeneran)" >> .gitignoreecho "node_modules/" >> .gitignoreecho "" >> .gitignoreecho "# Archivos temporales" >> .gitignoreecho "*.tmp" >> .gitignoreecho "*.log" >> .gitignore
git add .gitignoregit 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:
# 1. Crear y entrar al proyectomkdir mi-receta && cd mi-receta
# 2. Activar Gitgit init
# 3. Crear .gitignore (siempre hazlo antes de tu primer commit)echo "# Archivos del sistema operativo" > .gitignoreecho ".DS_Store" >> .gitignoreecho "Thumbs.db" >> .gitignoreecho "" >> .gitignoreecho "# Archivos con datos sensibles" >> .gitignoreecho ".env" >> .gitignoreecho "" >> .gitignoreecho "# Carpetas de dependencias" >> .gitignoreecho "node_modules/" >> .gitignoreecho "" >> .gitignoreecho "# Archivos temporales" >> .gitignoreecho "*.tmp" >> .gitignoreecho "*.log" >> .gitignore
# 4. Crear el primer archivoecho "# Receta de Pasta" > receta.txt
# 5. Ver el estado (archivos en rojo, sin seguimiento)git status
# 6. Preparar los archivos para la fotogit 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 contenidoecho "" >> receta.txtecho "## Ingredientes" >> receta.txtecho "- 500g de pasta" >> receta.txtecho "- 1 lata de tomate" >> receta.txtecho "- Sal y pimienta" >> receta.txt
# 10. Ver qué cambiógit diff
# 11. Preparar y tomar otra fotogit add receta.txtgit commit -m "feat: agrega lista de ingredientes"
# 12. Ver el álbum de fotosgit 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.
mkdir practica-gitcd practica-gitgit initls -la# ¿Ves la carpeta .git? ¡Git está activado!Ejercicio 2: Crea un archivo notas.txt y escribe algo dentro:
echo "Hola Git, este es mi primer archivo" > notas.txtEjercicio 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:
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:
echo "Hoy aprendí git add y git commit" >> notas.txtgit diff# Deberías ver la línea nueva con un + en verdegit add notas.txtgit commit -m "docs: agrega nota sobre lo aprendido hoy"git log --oneline# Deberías ver 2 commits¡Ya sabes lo fundamental!
El flujo git status → git add → git 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!
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:
- Respaldo: Tu código está seguro en la nube
- Colaboración: Otras personas pueden ver, descargar y contribuir a tu código
Crear tu cuenta en GitHub
Si todavía no tienes cuenta:
- Ve a github.com y haz clic en “Sign up”
- Usa el mismo correo que configuraste en Git (Módulo 2)
- Elige un nombre de usuario que te guste (será tu identidad como desarrollador)
- 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:
- 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
- Configurar otros computadores es trivial: si mañana usas otro computador, solo ejecutas
gh auth loginy apruebas desde el teléfono — sin copiar tokens ni generar llaves SSH
Cómo instalarla:
- Descarga GitHub Mobile desde la App Store (iOS) o Google Play (Android)
- Inicia sesión con la cuenta de GitHub que acabas de crear
- 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:
- En GitHub, haz clic en el botón verde “New” (o en el
+de la esquina superior derecha → “New repository”) - Ponle un nombre (ejemplo:
mi-receta) - NO marques “Add a README file” (queremos un repo vacío)
- NO selecciones un
.gitignoreni licencia por ahora - 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):
sudo apt updatesudo apt install ghSi 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:
brew install ghAutenticarte:
gh auth loginSigue 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.
# Conectar tu repo local con GitHubgit 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ó:
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.
# Primera vez: necesitas el -u para establecer la conexióngit 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:
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.
# Clonar un repositoriogit clone https://github.com/usuario/nombre-repo.git# Cloning into 'nombre-repo'...# remote: Enumerating objects: 20, done.# ...
# Entrar al repo clonadocd nombre-repo
# Ya tiene todo configuradogit 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
mkdir mi-proyecto-web && cd mi-proyecto-webgit initPaso 2: Crear .gitignore y hacer el primer commit
Siempre crea el .gitignore antes de empezar a trabajar (como aprendiste en el Módulo 3):
echo ".DS_Store" > .gitignoreecho "Thumbs.db" >> .gitignoreecho ".env" >> .gitignoreecho "node_modules/" >> .gitignoreecho "*.tmp" >> .gitignoreecho "*.log" >> .gitignore
git add .gitignoregit commit -m "chore: agrega .gitignore"Paso 3: Crear los archivos del proyecto y hacer el segundo commit
echo "<!DOCTYPE html><html><body><h1>Hola Mundo</h1></body></html>" > index.htmlecho "body { font-family: sans-serif; }" > estilos.css
git add index.html estilos.cssgit commit -m "feat: crea estructura básica del sitio web"Paso 4: Crear un repositorio vacío en GitHub
- En GitHub, haz clic en el botón ”+” (esquina superior derecha) → “New repository”
- Ponle el nombre
mi-proyecto-web - NO marques “Add a README file”
- NO selecciones un
.gitignoretemplate - NO selecciones una licencia
- 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)
gh auth login# Sigue las instrucciones: GitHub.com → HTTPS → Login with a web browserSi ya te autenticaste antes, este paso no es necesario.
Paso 6: Conectar tu repo local con GitHub
git remote add origin https://github.com/tu-usuario/mi-proyecto-web.git
# Verificar la conexióngit 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
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:
# Editar un archivoecho "<p>Bienvenido a mi sitio</p>" >> index.html
# El flujo de siempre: status → add → commitgit add index.htmlgit 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:
git remote add origin https://github.com/tu-usuario/tu-repo.gitgit remote -v# ¿Ves las dos líneas (fetch y push)?Ejercicio 3: Sube tu trabajo con git push -u origin main:
git push -u origin mainEjercicio 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:
cd ~git clone https://github.com/paulovillarroel/curso-git-github.git curso-git-github-copiacd curso-git-github-copialsgit 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!
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.
git log --oneline# d4e5f6a Agrega instrucciones de preparación# b2c3d4e Agrega lista de ingredientes# a1b2c3d Agrega receta inicial de pastaEsos 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.
# Viajar al primer commitgit switch --detach a1b2c3d# HEAD is now at a1b2c3d Agrega receta inicial de pasta
# Ahora tu proyecto está exactamente como estaba en ese momentocat 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:
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.
# Supongamos que el último commit agregó algo que no queríasgit 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 commitgit 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 cambiogit 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.
# Acabas de hacer un commit con un typo en el mensajegit 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 commitgit status# Changes to be committed:# modified: receta.txt
# Ahora puedes hacer el commit de nuevo con el mensaje correctogit 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:
# Tienes cambios sin commiteargit status# modified: archivo.txt
# Guardar los cambios en el cajóngit stash# Saved working directory and index state WIP on main
# Ahora tu carpeta está limpiagit status# nothing to commit, working tree clean
# Puedes cambiar de rama tranquilogit switch otra-rama# ... hacer lo que necesitas ...git switch main
# Recuperar tus cambios del cajóngit 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 --detach | Sí, para explorar | Para visitar el pasado (los commits que hagas aquí se pierden si no creas una rama) |
git revert | Sí, es la opción recomendada | Para deshacer un cambio manteniendo la historia |
git reset --soft | Sí, los archivos no se pierden | Para corregir un mensaje de commit o agregar archivos olvidados |
git stash / git stash pop | Sí, es temporal y reversible | Para 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):
mkdir practica-tiempo && cd practica-tiempogit initecho "Línea 1: Hola" > archivo.txtgit add . && git commit -m "feat: agrega línea 1"echo "Línea 2: Mundo" >> archivo.txtgit add . && git commit -m "feat: agrega línea 2"echo "Línea 3: Git es genial" >> archivo.txtgit 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).
echo "Línea extra de prueba" >> archivo.txtgit add . && git commit -m "feat: agrega línea extra"git reset --soft HEAD~1git 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.
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 --- EEn 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.
git branch# * mainSolo 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).
# Crear una nueva rama y movernos a ellagit switch -c feature/saludo# Switched to a new branch 'feature/saludo'
git branch# main# * feature/saludoAhora 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 loginfix/error-calculo— estás arreglando un error en un cálculomejora/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 add → git commit.
# Estamos en feature/saludoecho "¡Hola Mundo desde Git!" > saludo.txtgit add saludo.txtgit commit -m "feat: agrega archivo de saludo"
# Hacer otro cambioecho "Bienvenido al curso de Git" >> saludo.txtgit add saludo.txtgit 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.
# Volver a maingit 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).
# 1. Asegúrate de estar en maingit switch main
# 2. Traer los cambios de feature/saludogit merge feature/saludo# Updating a1b2c3d..e5f6a7b# Fast-forward# saludo.txt | 2 ++# 1 file changed, 2 insertions(+)# create mode 100644 saludo.txt
# 3. Verificarls# 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:
<<<<<<< HEADPasta con salsa de tomate=======Pasta con salsa boloñesa>>>>>>> feature/nueva-recetaLos 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:
- Abre el archivo en tu editor de texto
- Decide qué mantener: elimina los tres marcadores (
<<<<<<<,=======,>>>>>>>) y deja solo el contenido correcto - Guarda el archivo
- Haz add y commit:
# Después de editar el archivo y resolver el conflictogit add receta.txtgit 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.
# 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:
# Borrar la rama en GitHubgit push origin --delete feature/saludoLimpieza completa después de un merge
Acostúmbrate a este flujo cada vez que termines con una rama:
# 1. Borrar la rama localgit branch -d feature/saludo
# 2. Borrar la rama remota (si la subiste a GitHub)git push origin --delete feature/saludoEn 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):
git branch -D feature/experimento-fallidoEsto 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:
git switch -c feature/despedidaecho "¡Adiós desde una rama!" > despedida.txtgit add despedida.txtgit commit -m "feat: agrega archivo de despedida"Ejercicio 2: Vuelve a main y verifica que el archivo despedida.txt NO está:
git switch mainls# ¿Ves despedida.txt? No debería estarEjercicio 3: Mergea la rama a main y verifica que el archivo AHORA SÍ está:
git merge feature/despedidals# Ahora despedida.txt debería aparecerEjercicio 4: Borra la rama con git branch -d:
git branch -d feature/despedidagit branch# Solo debería quedar mainEjercicio 5 (Desafío): Crea un conflicto a propósito y resuélvelo:
# Crear un archivo baseecho "Color favorito: azul" > preferencias.txtgit add . && git commit -m "feat: agrega preferencias"
# Crear una rama y cambiar el colorgit switch -c feature/colorecho "Color favorito: rojo" > preferencias.txtgit add . && git commit -m "feat: cambia color a rojo"
# Volver a main y cambiar el color diferentegit switch mainecho "Color favorito: verde" > preferencias.txtgit 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.txtgit 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.
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 equipo | Como contribuidor externo | |
|---|---|---|
| ¿Cuándo? | Tienes permisos de escritura en el repo | No tienes permisos (proyecto open source, repo ajeno) |
| Primer paso | git clone del repo | Fork en GitHub, luego git clone de tu fork |
| ¿Dónde haces push? | Directamente al repo original | A tu fork |
| ¿Cómo llegan tus cambios? | PR dentro del mismo repo | PR 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:
- Crear una rama para tu tarea
- Trabajar y hacer commits en esa rama
- Subir la rama a GitHub
- Crear un Pull Request (pedir revisión)
- Revisión y aprobación por parte del equipo
- Merge en GitHub (el código entra a
main) - Actualizar tu copia local
Veamos cada paso en detalle.
Paso 1-2: Crear rama y trabajar
Esto ya lo sabes del Módulo 6:
# Crear rama para tu tareagit switch -c feature/mi-cambio
# Hacer tu trabajoecho "Nueva funcionalidad" > feature.txtgit add feature.txtgit commit -m "Agrega nueva funcionalidad"
# Puedes hacer más commitsecho "Más detalles" >> feature.txtgit add feature.txtgit 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:
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-cambioAhora 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:
- Ve a tu repositorio en GitHub
- Verás un banner amarillo que dice “Compare & pull request” — haz clic ahí
- (Si no aparece el banner, ve a la pestaña “Pull requests” → “New pull request”)
- Título: Escribe un resumen corto de lo que hiciste (ejemplo: “Agrega nueva funcionalidad de saludo”)
- Descripción: Explica con más detalle:
- Qué cambiaste
- Por qué lo cambiaste
- Cualquier nota para los revisores
- 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:
# Hacer los cambios pedidosecho "Cambio solicitado en revisión" >> feature.txtgit add feature.txtgit commit -m "Aplica cambios de la revisión de código"git pushEl 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:
| Estrategia | Qué hace | Resultado en main |
|---|---|---|
| Squash and merge | Combina todos tus commits en uno solo | Un commit limpio por tarea |
| Create a merge commit | Mantiene todos los commits + agrega commit de merge | Historial completo pero más ruidoso |
| Rebase and merge | Re-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:
# Volver a maingit switch main
# Traer los cambios de GitHubgit 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:
# 1. Asegúrate de estar en main y actualizadogit switch maingit pull
# 2. Crear rama para tu tareagit switch -c feature/agregar-footer
# 3. Trabajarecho "<footer>© 2024 Mi Proyecto</footer>" > footer.htmlgit add footer.htmlgit commit -m "Agrega footer con copyright"
# 4. Subir la rama a GitHubgit 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 localgit switch maingit pullgit branch -d feature/agregar-footerResumen del flujo profesional
| Paso | Dónde | Comando / Acción |
|---|---|---|
| Crear rama | Terminal | git switch -c feature/nombre |
| Trabajar | Terminal | git add + git commit (repetir) |
| Subir rama | Terminal | git push -u origin feature/nombre |
| Crear PR | GitHub web | Botón “Compare & pull request” |
| Revisión | GitHub web | Comentarios, aprobación |
| Merge | GitHub web | Botón verde “Merge pull request” |
| Actualizar local | Terminal | git switch main + git pull |
| Limpieza | Terminal | git 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 equipo | Como contribuidor externo | |
|---|---|---|
| Primer paso | git clone del repo | Fork en GitHub → git clone de tu fork |
| Push va a | El repo del equipo | Tu fork |
| PR va | Dentro del mismo repo | Desde 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):
# Verificar que está instalado y autenticadogh auth status# ✓ Logged in to github.com account tu-usuarioCrear un PR desde la terminal:
# Después de hacer push de tu ramagh 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 createVer y mergear PRs:
# Listar PRs abiertosgh pr list
# Ver detalles del PR actualgh pr view
# Ver los cambios (diff)gh pr diff 1
# Mergear con squash (nuestra recomendación)gh pr merge --squashCrear repositorios desde la terminal:
# Crear repo público desde la carpeta actualgh repo create mi-proyecto --public --source=. --push# Esto reemplaza: ir a GitHub → crear repo → copiar URL → git remote add → git pushGestionar issues:
gh issue list # Listar issues abiertosgh issue create --title "..." # Crear un issuegh issue view 5 # Ver un issuegh issue close 5 # Cerrar un issueFlujo profesional acelerado con gh
Con gh, el flujo completo se queda en la terminal:
git switch -c feature/mi-cambio# ... hacer cambios, commits ...git push -u origin feature/mi-cambiogh pr create --title "feat: mi cambio" --body "Descripción"# ... esperar revisión ...gh pr merge --squashgit switch main && git pullgit branch -d feature/mi-cambioTabla 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:
git switch -c feature/mi-cambioecho "Este es un cambio de prueba" > cambio.txtgit add cambio.txtgit commit -m "Agrega archivo de prueba para PR"Ejercicio 2: Sube la rama a GitHub:
git push -u origin feature/mi-cambioEjercicio 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:
git switch maingit pullgit branch -d feature/mi-cambioVerifica 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.
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.
# Esto BORRA el último commit y todos sus cambiosgit reset --hard HEAD~1# HEAD is now at b2c3d4e Agrega lista de ingredientesDespué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 revert | Sí, es la opción recomendada | Para deshacer un cambio manteniendo la historia |
git reset --soft | Sí, los archivos no se pierden | Para corregir un mensaje de commit o agregar archivos olvidados |
git reset --hard | NO, destruye cambios | Solo 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:
# Estando en tu rama featuregit rebase mainEsto “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):
# Estás en tu rama feature/mi-cambio
# 1. Traer los cambios más recientes de maingit switch maingit pull
# 2. Volver a tu rama y hacer rebasegit switch feature/mi-cambiogit rebase main
# 3. Si hay conflictos, resolverlos y continuar# (editar archivo, resolver conflicto)git add archivo-resuelto.txtgit rebase --continue
# 4. Si todo sale mal, puedes cancelar y volver al estado anteriorgit 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:
# Estando en tu rama feature/mi-cambiogit pull --rebase origin mainEsto 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:
git push --force-with-leaseUsamos --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:
- Hacer fork del proyecto (ahora tienes tu propia copia en GitHub)
- Clonar tu fork a tu computador
- Hacer tus cambios y push a tu fork
- Crear un Pull Request desde tu fork al proyecto original
Cómo hacer un fork:
- Ve al repositorio en GitHub que quieres copiar
- Haz clic en el botón “Fork” (esquina superior derecha)
- Selecciona tu cuenta como destino
- ¡Listo! Ahora tienes una copia en
github.com/tu-usuario/nombre-repo
Trabajar con tu fork:
# 1. Clonar TU fork (no el repo original)git clone https://github.com/tu-usuario/nombre-repo.gitcd nombre-repo
# Verificar: origin apunta a TU forkgit 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 commitecho "Mi mejora" >> archivo.txtgit add archivo.txtgit commit -m "Agrega mejora al archivo"
# 4. Subir la rama a TU forkgit push -u origin feature/mi-mejoraDespué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:
# 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 forkgit fetch upstreamgit switch maingit merge upstream/maingit push# Ahora tu fork está al día con el proyecto originalupstream 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.
git fetch# Si hay cambios nuevos, te muestra información# Si no hay cambios, no muestra nadaEs ú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 cambiangit pull: descarga Y aplica los cambios (es unfetch+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:
git fetch— descarga los cambios del remotogit 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:
# Pull normal (fetch + merge) — comportamiento por defectogit 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 rebasegit 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 casosgit pull --rebase: cuando quieres mantener la historia linealgit pull --no-rebase: cuando configuraste rebase por defecto pero para un caso puntual quieres mergegit 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óngit 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.
# Antes de pull, siempre:git status# Si hay cambios pendientes:git add .git commit -m "Guarda cambios antes de pull"# Ahora sí:git pullTabla 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:
mkdir practica-avanzado && cd practica-avanzadogit initecho "Línea 1" > archivo.txtgit add . && git commit -m "Commit 1"echo "Línea 2" >> archivo.txtgit add . && git commit -m "Commit 2"echo "Línea 3" >> archivo.txtgit add . && git commit -m "Commit 3"
# Ver historialgit log --oneline# Ahora borra el último commitgit reset --hard HEAD~1git log --onelinecat archivo.txt# La línea 3 desapareció por completoEjercicio 2: Practica rebase entre ramas:
# Crear commits en mainecho "Base actualizada" >> archivo.txtgit add . && git commit -m "Actualiza base en main"
# Crear rama y trabajargit switch -c feature/prueba-rebaseecho "Cambio en rama" > rama.txtgit add . && git commit -m "Agrega archivo en rama"
# Volver a main y agregar otro commitgit switch mainecho "Otro cambio en main" >> archivo.txtgit add . && git commit -m "Otro cambio en main"
# Rebase: actualizar la ramagit switch feature/prueba-rebasegit rebase maingit log --oneline# Tu commit de rama aparece DESPUÉS de los de main
# Limpiezagit switch maingit merge feature/prueba-rebasegit branch -d feature/prueba-rebaseEjercicio 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:
# En un repo conectado a GitHubgit fetchgit log --oneline origin/main# Ves los commits remotos sin que tus archivos cambiengit pull# Ahora sí se aplicanEstas 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.
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:
npm install -g @anthropic-ai/claude-codeUso básico:
# Iniciar Claude Code en tu proyectocd mi-proyectoclaudeSe 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 detalladaClaude Code puede usar git y gh directamente, así que puede:
- Hacer
git add,git commitygit pushpor 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 revertogit resetsegú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:
npm install -g @google/gemini-cliUso básico:
cd mi-proyectogeminiAl 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 loginGitHub Copilot CLI
Si tienes suscripción a GitHub Copilot, también puedes usarlo desde la terminal con la extensión de gh:
# Instalar la extensióngh extension install github/gh-copilot
# Pedir ayuda con comandosgh 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:
# 1. Crear un proyecto nuevomkdir mi-app && cd mi-appgit initecho "# Mi App" > README.mdgit add . && git commit -m "chore: commit inicial"gh repo create mi-app --public --source=. --push
# 2. Iniciar tu agente de IAclaude # 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 mergeargh pr viewgh pr merge --squash
# 5. Actualizar localgit switch maingit pullEjercicios 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:
# Opción A: Claude Codenpm install -g @anthropic-ai/claude-codecd tu-proyectoclaude
# Opción B: Gemini CLInpm install -g @google/gemini-clicd tu-proyectogeminiPrueba 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:
# 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 CommitsPrimero 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.
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-breveLos tipos más comunes:
| Prefijo | Cuándo usarlo | Ejemplo |
|---|---|---|
feature/ | Nueva funcionalidad | feature/filtro-busqueda |
fix/ | Corrección de bug | fix/login-timeout |
hotfix/ | Arreglo urgente en producción | hotfix/crash-pagina-inicio |
docs/ | Cambios de documentación | docs/actualizar-readme |
refactor/ | Reestructurar código sin cambiar funcionalidad | refactor/limpiar-utils |
# Biengit switch -c feature/carrito-comprasgit switch -c fix/error-validacion-emailgit switch -c docs/guia-instalacion
# Malgit switch -c mi-ramagit switch -c cambios-pedrogit switch -c arreglo-cosaLa 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:
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:
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 detokens 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:
- Ve a tu repositorio en GitHub
- Settings → Branches
- Haz clic en Add branch ruleset (o “Add rule” en repos más antiguos)
- En “Branch name pattern” escribe:
main - Activa estas reglas:
| Regla | Qué hace |
|---|---|
| Require a pull request before merging | Nadie puede hacer push directo a main |
| Require approvals (1) | Al menos una persona debe aprobar el PR |
| Do not allow bypassing the above settings | Ni siquiera los admins pueden saltarse las reglas |
# Con branch protection activado:
# Esto FALLA (push directo a main)git switch mainecho "cambio directo" >> archivo.txtgit add . && git commit -m "cambio directo"git push# ❌ remote: error: GH006: Protected branch update failed
# Esto FUNCIONA (via PR)git switch -c fix/mi-cambioecho "cambio via PR" >> archivo.txtgit add . && git commit -m "fix: cambio correcto via PR"git push -u origin fix/mi-cambiogh pr create --title "Fix: mi cambio" --body "Descripción"# ✅ PR creado, esperando revisiónBranch 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:
# Desde la raíz de tu proyectomkdir -p .githubPuedes crear este archivo directamente en VS Code: crea la carpeta .github/ y dentro el archivo pull_request_template.md con el siguiente contenido:
## ¿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# Agregar al proyectogit add .github/pull_request_template.mdgit commit -m "chore: agrega template de Pull Request"git pushAhora, 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:
- Settings → General → Pull Requests
- Desmarca “Allow merge commits” y “Allow rebase merge”
- 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:
- Divide el trabajo por archivos/componentes. Si Ana trabaja en el header y Bob en el footer, no habrá conflictos.
- Haz pull frecuentemente. Actualiza tu rama diariamente, no cada 3 días.
- Ramas pequeñas, PRs frecuentes. Una rama de 2 días tiene menos conflictos que una de 2 semanas.
- 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
# MAL: un commit con 47 archivos modificadosgit add .git commit -m "muchos cambios"# Imposible de revisar, imposible de revertir parcialmente
# BIEN: commits atómicosgit add src/auth/login.jsgit commit -m "feat: agrega validación de email en login"git add src/auth/register.jsgit commit -m "feat: agrega validación de email en registro"2. Trabajar directamente en main
# MALgit switch main# ... hacer cambios durante 3 días ...git push# Acabas de romper main para todos
# BIENgit switch -c feature/mi-cambio# ... trabajar tranquilo en tu rama ...3. No hacer pull antes de empezar a trabajar
# MAL: empezar a trabajar sin actualizargit switch -c feature/nueva# Tu rama está basada en un main desactualizado# Vas a tener conflictos innecesarios
# BIEN: siempre actualizar primerogit switch maingit pullgit switch -c feature/nueva# Ahora tu rama está basada en la versión más reciente4. Acumular ramas que ya se mergearon
# MAL: nunca limpiargit 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 mergegit branch -d feature/mi-rama-mergeada# O limpiar todas las ramas mergeadas de una vezgit branch --merged main | grep -v main | xargs git branch -d5. Force push a main
# NUNCA hagas estogit 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
## 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# Agregar al proyectogit add AGENTS.mdgit 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í:
cd mi-proyectoclaude# 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ónCada 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ón | Qué poner | Ejemplo |
|---|---|---|
| Flujo de Git | Cómo hacer commits, ramas, PRs | ”Usar squash merge, ramas con prefijo tipo/“ |
| Idioma | En qué idioma escribir commits, docs, código | ”Commits en español, código en inglés” |
| Estilo de código | Convenciones de formato y naming | ”snake_case para Python, camelCase para JS” |
| Testing | Cómo correr y escribir tests | ”Correr npm test antes de hacer commit” |
| Restricciones | Qué 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:
mkdir proyecto-equipo-10 && cd proyecto-equipo-10git initecho "# Proyecto con convenciones" > README.mdgit add . && git commit -m "chore: inicializa proyecto"
# Crea un PR templatemkdir -p .githubecho "## ¿Qué hace este PR?" > .github/pull_request_template.mdecho "" >> .github/pull_request_template.mdecho "## Tipo de cambio" >> .github/pull_request_template.mdecho "- [ ] Feature" >> .github/pull_request_template.mdecho "- [ ] Fix" >> .github/pull_request_template.mdecho "- [ ] Docs" >> .github/pull_request_template.mdecho "" >> .github/pull_request_template.mdecho "## ¿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:
# Crea una rama con nombre correctogit switch -c feature/agregar-estilos
# Haz commits con Conventional Commitsecho "body { margin: 0; }" > estilos.cssgit add . && git commit -m "feat: agrega estilos base del proyecto"
echo "h1 { color: blue; }" >> estilos.cssgit add . && git commit -m "feat: agrega estilo para títulos"
# Vuelve a maingit switch mainEjercicio 3: Simula el flujo completo de equipo (si tienes un repo en GitHub):
# Sube el proyectogh 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.mdgit add . && git commit -m "test: push directo"git push# ❌ Debería fallar
# Hazlo correctamente via PRgit switch -c fix/actualizar-readmegit push -u origin fix/actualizar-readmegh pr create --title "fix: actualiza README" --body "Cambio hecho correctamente via PR"gh pr merge --squashgit switch main && git pullEjercicio 4: Limpia ramas mergeadas:
# Ver todas las ramasgit branch
# Eliminar ramas que ya se mergearongit branch --merged main | grep -v main | xargs git branch -d
# Verificar que solo queda maingit branchConvenciones = 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:
# 1. Ir a la rama principalgit switch main
# 2. Traer los cambios que tus compañeros subierongit 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).
git statusSi 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:
git add scripts/03_analisis_descriptivo.RPaso 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:
# 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:
# 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 pushRutina 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.
# 1. Rutina de cierre normalgit statusgit 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é faltaPiensa 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:
# Creaste la rama con un typogit 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/loginLa 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:
# Renombrar en localgit branch -m feature/logni feature/login
# Borrar la rama vieja del remotogit push origin --delete feature/logni
# Subir la rama con el nombre correctogit 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:
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:
# Traer los cambios remotos y fusionarlos con los tuyosgit pull origin main
# Si no hay conflictos, ahora sí puedes hacer pushgit push origin mainSi 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:
# Verificar que estás en maingit 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ásgit 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:
# Ir a la rama que debía recibir los commitsgit switch feature/mis-cambios
# Traer los commits de maingit merge main
# Volver a main y limpiarlagit switch maingit reset --keep HEAD~3Solo 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.
# Deshacer el último commit, archivos quedan en staging (listos para commit)git reset --soft HEAD~1
# Verificargit status# Tus archivos siguen ahí, en verde, listos para un nuevo commitAhora puedes:
- Corregir el mensaje:
git commit -m "Mensaje correcto" - Agregar un archivo olvidado:
git add archivo-olvidado.txty luegogit 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):
# Restaurar un archivo al estado del último commitgit 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):
# Primero sacarlo del staginggit restore --staged archivo.txt
# Luego restaurar el contenidogit restore archivo.txtEsto 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):
# Descartar todos los cambios en archivos trackedgit restore .
# Actualizar con lo último del remotogit pullgit 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:
# Descartar cambios en archivos trackedgit restore .
# Borrar archivos y carpetas no rastreados por Gitgit clean -fd
# Actualizargit pullEsto 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):
# Sacar un archivo del staging (sin borrarlo)git restore --staged archivo-secreto.env
# Verificargit status# El archivo vuelve a "Untracked" o "Modified", pero NO se borra del discoSi ya hiciste commit de ese archivo y quieres sacarlo del seguimiento de Git sin borrarlo del disco:
# Dejar de rastrear el archivo (sin borrarlo)git rm --cached archivo-secreto.env
# Agregarlo al .gitignore para que no vuelva a pasarecho "archivo-secreto.env" >> .gitignore
# Hacer commit del cambiogit add .gitignoregit 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:
# 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):
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:
git status# xcrun: error: invalid active developer path# (/Library/Developer/CommandLineTools),Solución:
xcode-select --installTe 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:
- Reinicia tu Mac
- Si persiste:
sudo xcode-select --reset - Ú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:
# 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 mergegit 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:
# Ver el contenido de un archivo en un commit específicogit show abc1234:ruta/al/archivo.txt
# Ver cómo era el archivo hace 3 commitsgit show HEAD~3:ruta/al/archivo.txtEsto solo muestra el contenido en la terminal, no modifica nada.
Si quieres recuperar esa versión del archivo:
# Restaurar un archivo a como era en un commit específicogit restore --source=abc1234 ruta/al/archivo.txt
# Ahora el archivo en tu carpeta tiene el contenido antiguo# Puedes hacer add y commit si quieres conservarloTabla 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:
mkdir ~/ejercicios-git && cd ~/ejercicios-gitAsí 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
# Crear el proyectomkdir mi-portafolio && cd mi-portafoliogit init
# Crear estructura de carpetasmkdir css js img
# Crear el HTML principalcat > 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 basegit add .git commit -m "Crea estructura base del portafolio con HTML"
# Agregar estiloscat > 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: estilosgit add .git commit -m "Agrega estilos CSS para el portafolio"
# Agregar JavaScriptcat > js/app.js << 'EOF'document.addEventListener('DOMContentLoaded', () => { console.log('Portafolio cargado correctamente');});EOF
# Tercer commit: JavaScriptgit add .git commit -m "Agrega archivo JavaScript inicial"
# Verificar historialgit log --oneline# Deberías ver 3 commits
# Crear repositorio vacío en GitHub (desde el navegador)# Nombre: mi-portafolio, sin README
# Conectar y subirgit remote add origin https://github.com/tu-usuario/mi-portafolio.gitgit 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
# Preparación: crear repo con 5 commitsmkdir maquina-del-tiempo && cd maquina-del-tiempogit init
echo "Línea 1: Inicio del viaje" > diario.txtgit add . && git commit -m "Agrega línea 1"
echo "Línea 2: Primer descubrimiento" >> diario.txtgit add . && git commit -m "Agrega línea 2"
echo "Línea 3: Todo va bien" >> diario.txtgit add . && git commit -m "Agrega línea 3"
echo "Línea 4: Un error terrible" >> diario.txtgit add . && git commit -m "Agrega línea 4 (error)"
echo "Línea 5: Intentando arreglar" >> diario.txtgit add . && git commit -m "Agrega línea 5"
# Ver el historialgit log --oneline# Verás 5 commits, anota los hashes
# --- VIAJE 1: Visitar el commit #2 ---# Usa el hash de tu segundo commitgit switch --detach HEAD~3# (HEAD~3 = 3 commits atrás = commit #2)cat diario.txt# Solo debería tener las líneas 1 y 2git switch main# ¡De vuelta al presente!
# --- VIAJE 2: Revertir el commit #4 (el "error") ---# Busca el hash del commit #4git 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 principiocat 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.txtgit add . && git commit -m "Commit que vamos a deshacer"git reset --soft HEAD~1git 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 staginggit restore diario.txt# Descarta los cambios del archivoEjercicio 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
# Crear proyecto basemkdir lab-ramas && cd lab-ramasgit init
# Crear archivo basecat > pagina.html << 'EOF'<!DOCTYPE html><html><body> <!-- Aquí va el header --> <!-- Aquí va el contenido --> <!-- Aquí va el footer --></body></html>EOFgit add . && git commit -m "Crea estructura base de la página"
# --- RAMA 1: feature/header ---git switch -c feature/headercat > pagina.html << 'EOF'<!DOCTYPE html><html><body> <header><h1>Mi Sitio Web</h1></header> <!-- Aquí va el contenido --> <!-- Aquí va el footer --></body></html>EOFgit add . && git commit -m "Agrega header con título"
# --- RAMA 2: feature/contenido ---git switch maingit switch -c feature/contenidocat > 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>EOFgit add . && git commit -m "Agrega contenido principal"
# --- RAMA 3: feature/footer ---git switch maingit switch -c feature/footercat > pagina.html << 'EOF'<!DOCTYPE html><html><body> <!-- Aquí va el header --> <!-- Aquí va el contenido --> <footer><p>© 2024 Mi Sitio</p></footer></body></html>EOFgit add . && git commit -m "Agrega footer con copyright"
# --- MERGE 1: header (limpio) ---git switch maingit 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>EOFgit add pagina.htmlgit 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>EOFgit add pagina.htmlgit commit -m "Resuelve conflicto: agrega footer a la página completa"
# --- LIMPIEZA ---git branch -d feature/header feature/contenido feature/footergit 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
# 1. Crear repo base y subirlo a GitHubmkdir proyecto-equipo && cd proyecto-equipogit initecho "# Proyecto del Equipo" > README.mdecho "Lista de tareas:" > tareas.txtgit 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.gitgit push -u origin main
# 2. Simular dos personas clonando el repocd ..git clone https://github.com/tu-usuario/proyecto-equipo.git persona-alicegit clone https://github.com/tu-usuario/proyecto-equipo.git persona-bob
# 3. Alice trabaja en su featurecd persona-alicegit switch -c feature/alice-diseñoecho "- [ ] Diseñar la página principal" >> tareas.txtecho "Alice estuvo aquí" > alice.txtgit 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 featurecd ../persona-bobgit switch -c feature/bob-backendecho "- [ ] Crear la API REST" >> tareas.txtecho "Bob estuvo aquí" > bob.txtgit 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 localcd ../persona-alicegit switch maingit pull
cd ../persona-bobgit switch maingit 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
# ===== FASE 1: Crear el proyecto =====mkdir diario-aprendizaje && cd diario-aprendizajegit init
# Crear .gitignorecat > .gitignore << 'EOF'# Archivos del sistema.DS_StoreThumbs.db
# Archivos temporales*.tmp*.log
# Carpeta de notas privadasprivado/EOF
# Crear estructuramkdir entradas recursosecho "# Diario de Aprendizaje Git" > README.mdecho "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-1cat > 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 statusEOFgit add . && git commit -m "Agrega entrada del día 1: primeros pasos"git switch maingit merge entrada/dia-1git branch -d entrada/dia-1
# --- Rama: entrada del día 2 ---git switch -c entrada/dia-2cat > 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 logEOFgit add . && git commit -m "Agrega entrada del día 2: commits"
# También actualizar README desde esta ramaecho "" >> README.mdecho "## Entradas" >> README.mdecho "- Día 1: Primeros pasos" >> README.mdecho "- Día 2: Commits" >> README.mdgit add . && git commit -m "Actualiza README con lista de entradas"git switch main
# --- Provocar un conflicto en README ---echo "" >> README.mdecho "## Notas" >> README.mdecho "Este diario lo empecé en el curso de Git." >> README.mdgit add . && git commit -m "Agrega sección de notas al README"
# Merge con conflictogit merge entrada/dia-2# CONFLICT en README.md
# Resolver: combinar ambos cambioscat > README.md << 'EOF'# Diario de Aprendizaje GitUn diario personal donde documento mi viaje aprendiendo Git.
## Entradas- Día 1: Primeros pasos- Día 2: Commits
## NotasEste diario lo empecé en el curso de Git.EOFgit add README.mdgit 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.mdgit add . && git commit -m "Agrega texto incorrecto al README"
# Revertir el errorgit revert HEAD --no-editgit 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.gitgit push -u origin main
# ===== FASE 5: Pull Request workflow =====git switch -c entrada/dia-3cat > 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 pullEOF
echo "- Día 3: Ramas y GitHub" >> README.mdgit 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 maingit pullgit branch -d entrada/dia-3
# Verificar que todo está limpiogit statusgit branchgit 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)
| Comando | Qué 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 main | Rama principal como main |
git config --list | Ver toda tu configuración |
Flujo básico diario
# El flujo que usarás el 90% del tiempo:git status # 1. ¿Qué cambió?git add archivo.txt # 2. Preparar cambiosgit commit -m "mensaje" # 3. Guardar snapshotgit push # 4. Subir a GitHubCrear y gestionar repositorios
| Comando | Qué hace |
|---|---|
git init | Activar 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 -v | Ver conexiones remotas |
Ver estado e historial
| Comando | Qué hace |
|---|---|
git status | Ver qué archivos cambiaron |
git diff | Ver cambios antes de add |
git diff --staged | Ver cambios después de add |
git log --oneline | Historial compacto |
git log --oneline --graph | Historial con ramas visuales |
Staging y commits
| Comando | Qué hace |
|---|---|
git add archivo.txt | Preparar un archivo |
git add . | Preparar todos los archivos |
git commit -m "mensaje" | Guardar snapshot |
git restore --staged archivo.txt | Sacar del staging (sin perder cambios) |
git restore archivo.txt | Descartar cambios no commiteados |
git restore . | Descartar TODOS los cambios no commiteados |
Ramas
| Comando | Qué hace |
|---|---|
git branch | Listar ramas |
git switch -c nombre-rama | Crear rama y moverse a ella |
git switch nombre-rama | Cambiar de rama |
git merge nombre-rama | Traer cambios de otra rama |
git branch -d nombre-rama | Borrar rama (ya mergeada) |
git branch -m viejo nuevo | Renombrar rama |
Sincronización con GitHub
| Comando | Qué hace |
|---|---|
git push -u origin main | Subir (primera vez) |
git push | Subir (siguientes veces) |
git pull | Descargar y aplicar cambios |
git fetch | Revisar cambios sin aplicar |
git push -u origin nombre-rama | Subir una rama |
Viajes en el tiempo
| Comando | Qué hace |
|---|---|
git switch --detach <hash> | Visitar un commit pasado |
git switch main | Volver al presente |
git revert <hash> | Deshacer un commit (seguro) |
git reset --soft HEAD~1 | Deshacer commit, archivos en staging |
git reset --hard HEAD~1 | Deshacer commit y BORRAR cambios |
Emergencias
| Comando | Qué hace |
|---|---|
git merge --abort | Cancelar un merge con conflictos |
git restore . | Descartar todos los cambios locales |
git clean -fd | Borrar archivos/carpetas no rastreados |
git rm --cached archivo.txt | Dejar de rastrear sin borrar |
git show HEAD~3:archivo.txt | Ver archivo en un commit pasado |
git stash | Guardar cambios temporalmente |
git stash pop | Recuperar cambios guardados |
Esc → :q! → Enter | Escapar de Vim |
GitHub CLI (gh)
| Comando | Qué hace |
|---|---|
gh auth login | Autenticarse con GitHub |
gh repo create nombre --public --source=. --push | Crear repo y subir |
gh pr create --title "..." --body "..." | Crear Pull Request |
gh pr list | Listar PRs abiertos |
gh pr merge --squash | Mergear un PR (squash merge) |
gh issue create --title "..." | Crear un issue |
gh repo view --web | Abrir repo en el navegador |
.gitignore (patrones comunes)
# Archivos del sistema.DS_StoreThumbs.db
# Variables de entorno y secretos.env*.secret
# Dependencias (se regeneran)node_modules/vendor/
# Archivos compilados / temporales*.log*.tmpdist/build/Flujo profesional (GitHub Flow)
1. git switch main && git pull ← Partir actualizado2. git switch -c feature/mi-tarea ← Crear rama3. (trabajar, git add, git commit) ← Hacer cambios4. git push -u origin feature/mi-tarea ← Subir rama5. Crear Pull Request en GitHub ← Pedir revisión6. Merge en GitHub ← Aprobar y fusionar7. git switch main && git pull ← Actualizar local8. git branch -d feature/mi-tarea ← LimpiezaResolver conflictos (paso a paso)
# 1. Git te avisa del conflicto al hacer mergegit 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 commitgit add archivo.txtgit 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!