🎯 Meta: usar Git como un profesional, no solo
add/commit/push. Saber ramificar, revisar, deshacer sin miedo y trabajar en equipo sin pisarte con nadie. Git es la herramienta que usarás todos los días de tu carrera.
E.1 · El modelo mental de Git
Git guarda fotos (snapshots) de tu proyecto en el tiempo. Cada foto es un commit. Hay tres "zonas" por las que pasa un cambio:
Working Directory → Staging Area → Repositorio → Remoto (GitHub)
(tus archivos) (git add) (git commit) (git push)
editas ──add──► preparado ──commit──► guardado ──push──► compartido🧠 La clave que confunde a todos:
git addNO guarda nada; solo marca qué cambios entran en el próximo commit (staging).git commitsí los graba en la historia. Esta separación te permite hacer commits limpios (elegir qué incluir), no volcar todo de golpe.
E.2 · El ciclo diario
git status # ¿qué cambió? (úsalo SIEMPRE, a cada paso)
git diff # ver los cambios sin preparar
git diff --staged # ver lo que ya está en staging
git add archivo.py # preparar un archivo
git add -p # ⭐ preparar POR TROZOS (revisa cada cambio antes de incluirlo)
git commit -m "feat: añade login con JWT"
git log --oneline --graph # ver la historia de forma compacta
git push # subir al remoto
git pull --rebase # traer cambios de otros SIN crear merges sucios💡
git add -pes el hábito que te hace pro. Te muestra cada trozo de cambio y decides si entra o no. Resultado: commits pequeños y coherentes (uno por idea), no "cambié 10 cosas" en un solo commit gigante. Revisas tu propio código antes de subirlo y cazasconsole.logolvidados.
E.3 · Mensajes de commit (Conventional Commits)
Un buen mensaje explica qué y por qué. El estándar más usado es Conventional Commits:
<tipo>(<ámbito opcional>): <descripción corta en imperativo>
feat: nueva funcionalidad feat(auth): añade refresh tokens
fix: corrige un bug fix: evita división por cero en total
docs: documentación docs: actualiza README de instalación
refactor: cambio interno sin feature refactor: extrae ServicioEmail
test: añade/cambia tests test: cubre casos límite de descuento
chore: tareas de mantenimiento chore: actualiza dependencias
perf: mejora de rendimiento perf: añade índice a pedidos.usuario_id🧠 Por qué importa: con mensajes convencionales puedes generar el changelog automáticamente, versionar por semántica (feat = minor, fix = patch,
!= breaking = major) y entender la historia de un vistazo. Además, ungit log --onelinelegible es un regalo para tu yo futuro.
⚠️ Malos mensajes que todos hemos escrito:
"cambios","fix","asdf","ya funciona". No dicen nada. Dentro de 3 meses no sabrás qué hiciste. El commit es documentación.
E.4 · Ramas (branches)
Una rama es una línea de trabajo independiente. Trabajas en una rama para no tocar la principal (main) hasta que tu cambio esté listo y revisado.
git switch -c feature/carrito # crea y cámbiate a una rama nueva (o: git checkout -b)
# ...trabajas, commits...
git push -u origin feature/carrito # súbela al remoto
# Volver a main y actualizar:
git switch main
git pull
# Borrar la rama cuando ya se fusionó:
git branch -d feature/carritoConvención de nombres: feature/, fix/, hotfix/, chore/ + descripción corta: feature/pago-stripe, fix/login-timeout.
E.5 · Estrategias de ramificación
Cómo organiza el equipo sus ramas. Las dos más comunes en 2026:
GitHub Flow (simple, el recomendado para la mayoría)
main ────●────●────●────●──► (siempre desplegable)
\ /
feature ●──●──● (ramas cortas, se fusionan por PR y se borran)mainsiempre está listo para desplegar.- Para cada tarea, creas una rama corta desde
main. - Abres un Pull Request, se revisa, pasan los tests (CI, cap. 09), se fusiona.
- Se despliega. La rama se borra.
Trunk-Based (para equipos con CI/CD maduro)
Ramas muy cortas (horas, no días) que se integran a main constantemente. Reduce los conflictos de fusión. Requiere buena automatización y feature flags.
💡 Recomendación: empieza con GitHub Flow. Es simple y cubre el 95% de los casos. Git Flow (con ramas
develop,release, etc.) quedó obsoleto para la mayoría de proyectos con despliegue continuo — añade ceremonia que ya no necesitas.
E.6 · Pull Requests y revisión de código
Un Pull Request (PR) propone fusionar tu rama a main. Es donde ocurre la revisión de código (code review): otro humano lee tus cambios antes de que entren.
Un buen PR:
- Es pequeño (más fácil de revisar; un PR de 2000 líneas nadie lo revisa bien).
- Tiene un título y descripción claros: qué hace, por qué, cómo probarlo.
- Pasa el CI (tests verdes) antes de pedir revisión.
- Hace una cosa (no mezcles un refactor con una feature nueva).
🧠 La revisión de código no es un examen, es aprendizaje mutuo. Se revisa el código, no a la persona. Como autor, no te lo tomes personal; como revisor, sé amable y explica el porqué. Buenas preguntas: ¿se entiende? ¿tiene tests? ¿hay casos límite sin cubrir? ¿algún riesgo de seguridad (apéndice C)?
E.7 · Deshacer cosas (sin pánico)
El superpoder de Git: casi todo se puede deshacer. Los comandos que salvan el día:
# Descartar cambios de un archivo (aún no commiteados)
git restore archivo.py
# Quitar de staging (pero conservar el cambio)
git restore --staged archivo.py
# Corregir el ÚLTIMO commit (mensaje o archivos olvidados) — solo si NO lo has pusheado
git commit --amend
# Deshacer un commit pero MANTENER los cambios en tu working dir
git reset --soft HEAD~1
# Revertir un commit ya publicado (crea un commit que lo deshace, seguro en equipo)
git revert <hash>
# Ver TODO lo que has hecho, incluso lo "perdido" (tu red de seguridad definitiva)
git reflog⚠️
reset --hardes la única operación peligrosa: borra cambios sin guardar, de verdad. Úsalo con cuidado. Y nunca hagaspush --forcea una rama compartida (main): reescribes la historia de todos. Si de verdad lo necesitas en tu propia rama, usa--force-with-lease(más seguro).
💡
git refloges tu paracaídas. ¿Borraste una rama? ¿Un reset se comió tu trabajo? El reflog registra dónde estuvoHEADen cada momento; casi siempre puedes recuperar lo "perdido". Muy poca gente lo conoce y salva carreras.
E.8 · Conflictos de fusión (merge conflicts)
Ocurren cuando dos personas cambian las mismas líneas. Git no sabe cuál elegir y te pregunta:
<<<<<<< HEAD
precio = 100 (tu versión)
=======
precio = 120 (la versión que traes)
>>>>>>> feature/preciosEditas el archivo, dejas la versión correcta (borrando los marcadores <<<, ===, >>>), y:
git add archivo.py
git commit # (o git rebase --continue si estabas en rebase)💡 Para reducir conflictos: ramas cortas,
git pull --rebasefrecuente, y commits pequeños. Cuanto más tiempo vive una rama sin integrarse, más divergente y más conflictos tendrá.
E.9 · .gitignore y qué NO subir
# .env y secretos — ¡NUNCA! (apéndice C, cap. 00)
.env
*.pem
*.key
# Dependencias (se reinstalan)
node_modules/
vendor/
.venv/
target/
# Artefactos de build
dist/
build/
*.log
# Basura del sistema/editor
.DS_Store
.idea/
.vscode/⚠️ Lo más importante que NO va a git: secretos (
.env), dependencias (pesan y se reinstalan) y artefactos generados. Configura el.gitignoreel primer día. Si ya subiste un secreto por error, no basta con borrarlo: rótalo (apéndice C) porque queda en la historia.
E.10 · Git + CI/CD (el círculo completo)
Git es el disparador de todo tu pipeline (cap. 09 y 14):
git push a una rama → abre PR → CI corre tests 🔴/🟢 → revisión → merge a main
↓
CD despliega a producción 🚀Cada pieza que aprendiste se conecta aquí: los tests (cap. 09) protegen el merge; el CI/CD (cap. 14) despliega tras el merge; los Conventional Commits generan el changelog. Git es el sistema nervioso de tu flujo de trabajo.
✅ Ejercicio del apéndice
1. En un repo de práctica, crea una rama feature/, haz 3 commits pequeños con
Conventional Commits usando `git add -p`.
2. Provoca un conflicto a propósito (edita la misma línea en main y en tu rama)
y resuélvelo.
3. Practica deshacer: amend, reset --soft, restore, revert. Observa la diferencia.
4. "Pierde" trabajo con un reset --hard y recupéralo con git reflog.
5. Abre un Pull Request (aunque trabajes solo) y escríbele una buena descripción.
6. Conecta el repo a GitHub Actions para que corra los tests en cada push (cap. 09).💡 Pistas
git add -pte deja revisar hunk a hunk qué entra en cada commit — perfecto para separar cambios mezclados en commits pequeños y con sentido, en vez de un commit gigante al final.- Para el punto 4, primero confirma con
git reflogque el commit "perdido" sigue ahí (lo está, durante semanas) antes de asustarte —reset --hardno borra commits, solo mueve dónde apunta la rama. - Diferencia clave para el punto 3:
revertcrea un commit NUEVO que deshace cambios (seguro en ramas compartidas);resetreescribe el historial (solo en tu rama local, nunca enmainya empujada).
🧠 Autoevaluación
Porque no borra los commits, solo mueve el puntero de la rama a otro commit — los commits "perdidos" siguen existiendo en el repositorio hasta que el recolector de basura de git los limpia (semanas después por defecto), y git reflog te deja recuperarlos mientras tanto.
revert. Reescribir el historial de una rama que otros ya tienen (reset + force push) rompe el trabajo de cualquiera que haya hecho pull de esos commits. revert añade un commit nuevo que deshace los cambios, manteniendo el historial intacto y compartible.
No. El archivo sigue existiendo en el historial de git (en el commit anterior al borrado), y cualquiera con acceso al repo — o que lo haya clonado antes del borrado — puede recuperarlo. La única solución real es rotar todos los secretos que contenía (apéndice C).
Permite generar un changelog automático a partir de los mensajes, facilita el git bisect para encontrar qué commit introdujo un bug, y hace que cada Pull Request sea más fácil de revisar — un commit con una sola intención clara es mucho más rápido de auditar que uno que mezcla cinco cambios distintos.
Volver al: README.md · Relacionado: 09-testing.md, 14-servidores-devops.md