Módulo 1 · Fundamentos que sostienen todo

Lección 06 — Git profesional

Ramas, rebase, conflictos y flujos de equipo: la herramienta de colaboración del oficio.

Publicada
En esta lección
  1. Ejercicio 1 — Commits con intención
  2. Ejercicio 2 — Rebase interactivo
  3. Ejercicio 3 — Conflicto simulado
  4. Ejercicio 4 — Reflog
  5. Ejercicio 5 — Bisect automático
  6. Ejercicio 6 — GitHub Flow
  7. Resumen del profesor

La mecánica se aprende rompiendo. Si algún ejercicio no "falló" como esperabas, repítelo leyendo cada mensaje de Git: casi siempre te está explicando la respuesta.


Ejercicio 1 — Commits con intención

  1. Dos commits, cada uno con un tipo y un propósito: fix: corrige mensaje de error (el hunk del typo) y feat: añade función X (el hunk nuevo). Con hunks pegados, e (edit) permite borrar del hunk lo que no va en ese commit y s (split) divide hunks grandes.
  2. Con git add. y un commit "update": el historial dice "cambió app.py" — ni qué ni por qué. Consecuencias operativas: el revert de ese commit deshace también el fix (o la feature), el bisect no puede distinguir cuál introdujo un bug, y el reviewer lee dos temas mezclados (el 90% de las PRs gigantes nacen así).

Ejercicio 2 — Rebase interactivo

  1. Un único commit feat: añade contadores a a.txt con el contenido final. Los tres hashes viejos dejan de existir: el rebase reescribe commits (nuevos hashes, misma fecha de autor).
  2. Es seguro aquí porque nadie más tiene esos commits (tu rama local, recién creada). Es peligroso en ramas compartidas porque los clones con los hashes viejos chocan con la historia nueva: cada compañero vería "duplicados" al hacer pull. La ley: rebase de lo tuyo no publicado; nunca lo publicado.

Ejercicio 3 — Conflicto simulado

  1. Git dice CONFLICT (content): Merge conflict in README.md y deja el merge en pausa (MERGE_HEAD existe). El fichero muestra ambos bloques con marcadores.
  2. Tras resolver, add y commit, git log --graph muestra la bifurcación con un commit de merge uniendo las dos líneas: la historia es fiel a lo que pasó (dos trabajos paralelos, un punto de integración).
  3. Con rebase, el grafo final es lineal: tu commit "se reescribe" encima de main, como si hubieras empezado después. Diferencia esencial: merge preserva la bifurcación real; rebase reescribe para contar una historia lineal. En PRs del curso: rebase tu rama para actualizarla; squash-merge al integrar (main lineal Y cada cambio como unidad).

Ejercicio 4 — Reflog

  1. El commit ya no aparece en git log y el working tree volvió al estado anterior.
  2. git reflog muestra la entrada reset: moving to HEAD~1 y, debajo, el commit: original. git reset --hard HEAD@{1} (o el hash) lo recupera con todo su contenido. Nada se borra de verdad en ~90 días.
  3. Reflog: para recuperar tu trabajo local (reset, rebase accidentales). Revert: para deshacer un commit ya compartido — crea un commit nuevo inverso sin reescribir historia (seguro en main). Regla: local y no publicado → reflog/reset; publicado → revert.

Ejercicio 5 — Bisect automático

  1. Git hace checkout del commit intermedio, test.sh corre, y en ~2-3 pasos señala el commit exacto que creó bug.txt. Output final: <hash> is the first bad commit.
  2. Con 5 commits: 2-3 pruebas automáticas (log2(5) redondeado). A mano, en el peor caso, 4 (y con 300 commits: 9 vs 300). El valor real: bisect run con tus pruebas convierte "esto se rompió la semana pasada" en un commit culpable con nombre y autor en menos de un minuto.

Ejercicio 6 — GitHub Flow

2-3. El commit convencional con cuerpo del porqué; la PR con contexto y checklist; el self-review honesto (p. ej. "este uptime vendría mejor de /proc/uptime que del tiempo del proceso" y "falta un test del endpoint") son exactamente lo que pedirás a un compañero: practicar en solitario construye el hábito.

  1. Con squash, main muestra un único commit feat(salud): endpoint de detalle... (#N) — la historia de main queda como lista de intenciones, no como borradores. La rama borrada evita el cementerio de feat/... antiguos.

Resumen del profesor

  • El commit es la unidad de intención: tipo + porqué; add -p para que el historial cuente pasos, no ruido.
  • Rebase lo tuyo no publicado; merge/squash al integrar; jamás reescribas historia ajena.
  • Conflictos: mecánica de 4 pasos; se previenen con ramas cortas y PRs pequeñas.
  • Reflog rescata tu trabajo local; revert deshace lo compartido; bisect (automatizado) encuentra al culpable.
  • GitHub Flow: main desplegable, PR pequeña, CI verde, squash, revert como primera respuesta a la rotura.

Con esto cierras el Módulo 1 entero (01-06): protocolo, redes, concurrencia, algoritmos, sistema y herramienta de equipo. Al entregar estos ejercicios corregimos, actualizo tu marcador y abrimos el Módulo 2 — Bases de datos con la Lección 07 — SQL avanzado sobre PostgreSQL.