# Git: un botón de guardar con memoria

Curso exprés sobre Git y el control de versiones. 21 conceptos — Version Control, Repository, Commit, Staging Area, HEAD, Branch, main, Merge, Merge Conflict, Remote y origin, Clone/Push/Pull/Fetch, Pull Request, Log, Revert y Reset, Rebase y más — cada uno con su nombre en inglés, una imagen, un diagrama y una ficha con un ejemplo. Al final: un mapa de relaciones y una hoja de referencia de una página. La idea principal: casi todo el miedo a Git son solo palabras desconocidas — apréndelas y se convierte en una red de seguridad tranquila.

- **Author:** Fedor Chishchin
- **Level:** intro
- **Reading time:** ~30 minutos de lectura
- **Published:** 2026-06-13
- **Source:** https://fedorthinks.com/es/learn/git-express

---

## 1. Por qué el control de versiones

Antes de los comandos, el problema. Una vez que sientes el dolor que el control de versiones elimina, cada función de Git se lee como una respuesta evidente en lugar de jerga arbitraria.

### El mapa: 21 conceptos en seis grupos

> Un mapa del metro: primero ves el conjunto de todas las líneas, y luego viajas estación por estación.

Primero lo **básico** — qué son el control de versiones, Git y un repository. Después un capítulo por grupo: el **commit** (cómo se guarda un snapshot), las **branches** (líneas de trabajo paralelas), el **merging** y los conflicts, los **remotes** y el trabajo en equipo, y el **historial** con el deshacer seguro. El último capítulo trata de los **buenos hábitos**, un mapa de relaciones y la hoja de referencia.

_Diagram: Seis grupos de conceptos — los capítulos 1–6 los siguen. El capítulo 7 son los hábitos que lo unen todo._

### Cómo leer cada concepto

> Un pasaporte: los mismos campos para todos, así que es fácil compararlos.

Cada concepto a partir de aquí tiene las mismas partes: su **nombre en inglés** (recuérdalo — es el término con el que buscarás en la documentación y en los errores de Git), una imagen de la vida cotidiana, un **diagrama** y una **ficha**: _qué es_, _cómo funciona_, un _ejemplo_ (a menudo con un comando), la _trampa_ y cómo se _relaciona_ con otros conceptos. Al final: un mapa de relaciones y una hoja de referencia.

### Version Control — en lugar de una carpeta de archivos _final_v2_FINAL

> Un escritorio sepultado en `report.doc`, `report_v2.doc`, `report_final.doc`, `report_final_FINAL.doc` — nadie sabe cuál es el actual, y la buena versión del martes se perdió para siempre.

Todos hemos vivido la forma manual de guardar versiones: copiar el archivo, añadir un sufijo, cruzar los dedos. Se desmorona al instante — no sabes cuál es el más nuevo, no puedes recuperar una versión que sobrescribiste, y que dos personas editen significa que una de ellas pierde su trabajo. El **control de versiones** es la herramienta creada para acabar con esto: un proyecto, con todo su historial guardado a salvo y cada versión recuperable.

_Diagram: Izquierda — un montón de copias y ni idea de cuál es la real. Derecha — un archivo más un historial completo: cualquier versión puede volver._

#### Version Control (control de versiones, VCS)

- **Problema:** Copias con sufijos: ni idea de cuál es la más nueva, la antigua desapareció, dos personas se sobrescriben.
- **Idea:** Un proyecto + un historial completo de cambios, donde cualquier versión se puede restaurar.
- **Ejemplo:** En lugar de `report_final_FINAL.doc` — un solo `report.doc` y un registro de cada versión suya.
- **Trampa:** Solo funciona si guardas los cambios dentro del sistema, no a su lado.
- **Relaciones:** **Git** es el sistema de control de versiones más popular. Guarda el historial en un **Repository**.

### Git — una línea de tiempo de snapshots

> Una cámara que fotografía todo tu proyecto cada vez que dices «guarda esto» — para que puedas volver a ver exactamente cómo se veía todo en cualquier momento del pasado.

**Git** es el sistema de control de versiones que usa casi todo el mundo. Registra tu proyecto como una serie de **snapshots** — cada uno una imagen completa de todos tus archivos en un momento que elegiste guardar. El resultado es una línea de tiempo por la que puedes viajar: ver qué cambió, cuándo y quién lo hizo, y volver a cualquier estado pasado. Es un botón de guardar que nunca olvida ni un solo guardado.

_Diagram: Cada guardado es un snapshot completo de todos los archivos. Los resaltados cambiaron desde el último guardado._

#### Git (sistema de control de versiones, snapshots)

- **Qué es:** El sistema de control de versiones más usado.
- **Cómo funciona:** Guarda el proyecto como una línea de tiempo de **snapshots** de todos los archivos en los momentos que eliges.
- **Ejemplo:** El snapshot 3 añadió `style.css`; un mes después puedes volver exactamente al snapshot 2.
- **Trampa:** Asusta por las palabras, no por la dificultad: los términos solo hay que aprenderlos.
- **Relaciones:** Cada snapshot es un **Commit**; la línea de tiempo vive en un **Repository**.

### Repository — el proyecto más todo su historial

> Un libro que lleva consigo cada borrador que alguna vez fue, encuadernado al final — sostienes el texto actual y el registro completo de cómo llegó hasta ahí, juntos.

Un **repository** (o **repo**) es la carpeta de tu proyecto una vez que Git la está siguiendo: los archivos actuales _más_ el historial oculto de cada snapshot tomado (vive en una carpeta oculta `.git`). Haz clone de un repo y obtienes no solo el código de hoy sino la historia completa. Es la unidad en la que trabajas — un repo es «un proyecto que Git recuerda», y todo lo demás en este curso es algo que haces dentro de uno.

_Diagram: Un repository = los archivos de trabajo que ves + una carpeta oculta .git con cada snapshot._

#### Repository (repo)

- **Qué es:** Una carpeta de proyecto que Git vigila: archivos + todo el historial.
- **Cómo funciona:** El historial vive en la carpeta oculta `.git`; los archivos de trabajo son lo que ves ahora mismo.
- **Ejemplo:** `git init` convierte una carpeta en un repo; `git clone` copia el repo de otra persona entero, historial incluido.
- **Trampa:** Borra `.git` y solo quedan los archivos — todo el historial se pierde.
- **Relaciones:** Está hecho de **Commits**; existe como **local** (el tuyo) y **remote** (en un servidor).

> **La pregunta de fondo:** «Si hice un cambio y mañana me arrepiento, o dos de nosotros editamos hoy el mismo archivo — ¿podría recuperarme sin problemas? El control de versiones es el sistema que hace que la respuesta sea siempre sí.»

> El control de versiones reemplaza la carpeta de copias _final_FINAL por un proyecto y un historial completo y recuperable. Git guarda ese historial como una línea de tiempo de snapshots.

## 2. El commit

La palabra más importante de Git es el commit — un snapshot guardado en la línea de tiempo. Entiende cómo se hace un commit y entenderás el latido de todo el sistema.

### Commit — un snapshot guardado

> Una fotografía de todo tu proyecto en un instante elegido, grapada a una nota sobre qué fue ese momento — clavada para siempre en la línea de tiempo.

Un **commit** es un snapshot del historial de tu proyecto: un estado registrado de los archivos, con un ID único (un hash como `e81f53`) y una nota. Cada commit apunta al anterior — su **parent** — formando una cadena que es tu historial. No haces commit constantemente, sino en puntos con sentido — «añadí el login», «arreglé el bug de la fecha» — para que la línea de tiempo se lea como una secuencia de pasos deliberados, cada uno un lugar al que puedes volver.

_Diagram: Cuatro commits: cada uno tiene un ID y un mensaje, y cada uno apunta al anterior. Esa cadena es el historial._

#### Commit (snapshot)

- **Qué es:** Un snapshot guardado del proyecto con ID, autor, hora y mensaje.
- **Cómo funciona:** Cada commit apunta a su parent; la cadena de parents es el historial.
- **Ejemplo:** `git commit -m "fix date bug"` crea el commit `e81f53`.
- **Trampa:** Un commit guarda solo lo que pusiste en la **staging area**, no cada edición que hiciste.
- **Relaciones:** Se arma en la **Staging Area**, lo etiqueta el **Commit Message**, y el último lo marca **HEAD**.

### Staging Area — llena la caja antes de sellarla

> Una caja de envío sobre tu escritorio: pones dentro exactamente los artículos de este envío, dejas otros aparte, y solo entonces la cierras con cinta y la mandas.

Git no hace snapshot de todo lo que cambiaste automáticamente. Primero eliges qué cambios entran en el siguiente commit haciendo **staging** de ellos (`git add`) — poniéndolos en la **staging area**, la caja que estás llenando. Luego `git commit` sella exactamente esa caja. Estos dos pasos — preparar lo que va junto y después hacer commit — son la razón de que el historial de Git pueda ser limpio: tú decides exactamente qué contiene cada snapshot, en lugar de volcar todos los cambios de golpe.

_Diagram: Cambiaron tres archivos, pero solo los dos sobre el login entraron en la caja (staging area). El commit sella exactamente esos; notes.txt espera su turno._

#### Staging Area (el índice, the index)

- **Qué es:** Una «caja» intermedia entre tus ediciones y un commit.
- **Cómo funciona:** `git add` pone cambios en la caja, `git commit` la sella en un snapshot.
- **Ejemplo:** Editaste `login.js`, `login.css` y `notes.txt` — preparaste solo los dos primeros y hiciste commit de «add login».
- **Trampa:** Si olvidas `git add`, el cambio no entrará en el commit.
- **Relaciones:** Se llena desde tus archivos de trabajo y se vacía en un **Commit**. Es la base de los **commits pequeños**.

### Commit Message — una nota para el futuro

> Etiquetar esa caja sellada con lo que contiene — para que meses después quien mire el estante sepa qué guarda cada una sin abrirla.

Cada commit lleva un **commit message** que explica qué cambió y por qué. Parece una tarea pesada, pero es oro puro más adelante: cuando buscas el cambio que rompió algo, o entiendes por qué existe una línea, los mensajes son la historia del proyecto. Un buen mensaje («fix timezone bug in invoice export») convierte el historial de un muro de IDs crípticos en un registro legible. Escríbelos para quien los lea dentro de seis meses — normalmente tú.

_Diagram: Izquierda — un registro que no te dice nada. Derecha — un registro que se lee como la historia del proyecto._

#### Commit Message (la nota de un commit)

- **Qué es:** Una nota corta en un commit: qué cambió y por qué.
- **Cómo funciona:** Se escribe con `git commit -m "…"`; luego aparece en el **log** junto a cada snapshot.
- **Ejemplo:** Mal: «fix», «wip». Bien: «fix timezone bug in invoice export».
- **Trampa:** Ahorrar cinco segundos ahora cuesta horas de búsqueda seis meses después.
- **Relaciones:** Etiqueta un **Commit**; hace legible el **Log**.

### HEAD — tu marcador de «estás aquí»

> El punto de «usted está aquí» en el mapa de la línea de tiempo — marca en qué snapshot estás parado ahora.

**HEAD** es el puntero de Git a dónde estás ahora mismo en el historial — normalmente el último commit de tu branch actual. Cuando haces un commit nuevo, se añade justo después de HEAD, y HEAD avanza hasta él. Rara vez tocas HEAD directamente, pero la palabra aparece por todas partes, y saber que simplemente significa «mi posición actual en la línea de tiempo» desmitifica casi todo lo que leerás.

_Diagram: HEAD apunta a la branch main, y main apunta al último commit. El siguiente commit cae después, y HEAD avanza._

#### HEAD (puntero «estás aquí»)

- **Qué es:** Un puntero al commit (normalmente a través de una branch) donde estás.
- **Cómo funciona:** Un commit nuevo va justo después de HEAD, y HEAD se mueve a él.
- **Ejemplo:** `HEAD → main → c4`: estás en main, en el commit c4. Haces commit — ahora estás en el nuevo.
- **Trampa:** La palabra asusta en los mensajes de Git, pero solo significa «posición actual».
- **Relaciones:** Se mueve con cada **Commit**; **Switch** lo mueve a otra branch.

> **La pregunta del commit:** «¿Este commit recoge un cambio coherente, con un mensaje que le diría a un desconocido — o a mi yo del futuro — qué hizo y por qué?»

> Un commit es un snapshot guardado. Preparas los cambios exactos que van juntos, los sellas con un mensaje — y HEAD marca dónde estás.

## 3. Branches

Las branches son donde Git deja de ser un botón de guardar sofisticado y se convierte en una forma de que muchas personas — o muchas ideas — avancen a la vez sin pisarse.

### Branch — una línea de trabajo paralela

> Fotocopiar un manuscrito para garabatear una reescritura audaz en tu copia, mientras el original sigue limpio y otros siguen trabajando en él.

Una **branch** es una línea de desarrollo independiente: tu propia copia de la línea de tiempo donde puedes hacer commits sin afectar el trabajo de nadie más. Creas una branch para construir una función o probar una idea, haces commits libremente en ella, y la versión principal queda intacta hasta que estés listo. Las branches son cómo un equipo trabaja en diez cosas a la vez en un repo sin caos: cada quien en su propia línea.

_Diagram: La branch feature/login sale de main. Sus commits f1–f3 viven aparte, y main no los ve._

#### Branch (línea de trabajo)

- **Qué es:** Una línea independiente de commits dentro de un repo.
- **Cómo funciona:** Una branch es solo una etiqueta móvil en el último commit de una línea; los commits nuevos la hacen avanzar.
- **Ejemplo:** `git switch -c feature/login` — crea una branch para el formulario de login y te mueve a ella.
- **Trampa:** Una branch que vive demasiado se aleja de main y se fusiona con dolor.
- **Relaciones:** Sale de **main**, vuelve mediante **Merge** o **Rebase**, se discute en un **Pull Request**.

### main — la línea de confianza

> La edición oficial, en la estantería, de un libro en el que todos confían — los borradores se hacen en otra parte, y solo el trabajo terminado y aprobado se encuaderna en ella.

Por convención, la branch principal se llama **main** (los repos más antiguos pueden llamarla **master**). Guarda la versión estable y funcional del proyecto — la que enviarías a producción. El trabajo nuevo ocurre en otras branches y se une a main solo cuando está listo y revisado. Tratar main como la línea de confianza, nunca como un borrador, es la disciplina simple detrás de la mayoría de los flujos de equipo sanos.

_Diagram: main corre en línea recta. Las branches feature/search y fix/date salen de ella y vuelven con un merge (M) solo cuando están listas._

#### main (branch principal, antes master)

- **Qué es:** La branch principal, que guarda la versión funcional lista para enviar.
- **Cómo funciona:** Nadie escribe en ella directamente; el trabajo llega desde otras branches mediante un merge tras la revisión.
- **Ejemplo:** Las branches `feature/search` y `fix/date` se fusionan en main cuando están listas.
- **Trampa:** Hacer commit directo en main arriesga romper lo que todos usan.
- **Relaciones:** Recibe trabajo mediante **Merge** y **Pull Request**; toda **Branch** parte de ella.

### Switch (checkout) — cambiar de branch cambia tus archivos

> Cambiar qué borrador está abierto en tu escritorio — el mismo escritorio, pero mostrando al instante una versión del trabajo completamente distinta.

Cuando haces **switch** a una branch (`git switch`, antes `git checkout`), Git cambia los archivos de tu carpeta para que coincidan con el snapshot de esa branch. Pasa a tu branch de la función y aparecen tus ediciones; vuelve a main y desaparecen de la vista (guardadas a salvo, no perdidas). Las branches en Git son baratas e instantáneas, así que crear una por función o arreglo es normal: no un acto pesado, sino un movimiento cotidiano.

_Diagram: La misma carpeta: en main tiene dos archivos; tras git switch feature/login — un app.js cambiado y un login.js nuevo._

#### Switch / Checkout (cambiar de branch)

- **Qué es:** El comando que te mueve a otra branch.
- **Cómo funciona:** Git reescribe los archivos de tu carpeta al snapshot de esa branch y mueve **HEAD** allí.
- **Ejemplo:** `git switch feature/login` — aparece `login.js`; `git switch main` — se oculta, pero está a salvo.
- **Trampa:** Las ediciones sin commit pueden bloquear un switch — haz commit de ellas primero.
- **Relaciones:** Mueve **HEAD** entre **Branches**.

> **La pregunta de la branch:** «¿Estoy haciendo este trabajo en su propia branch, manteniendo main limpia — para que una idea sin terminar o rota nunca toque la versión de confianza?»

> Una branch es una línea de trabajo paralela donde haces commits libremente sin molestar a nadie. main es la versión de confianza; el trabajo nuevo vive en su propia branch hasta que está listo.

## 4. Merging y conflicts

El trabajo que se dividió en branches tarde o temprano tiene que volver a juntarse. El merge es como Git reúne las líneas de trabajo, y un conflict es el único momento en que necesita que decidas tú.

### Merge — volver a unir dos branches

> Plegar las ediciones de tu borrador aparte de vuelta en el manuscrito oficial, para que el libro ahora contenga tanto el original como tu capítulo nuevo.

Un **merge** combina los commits de una branch en otra — normalmente devolviendo una branch de función terminada a main. Git mira qué cambió en cada lado y los teje en una sola línea de tiempo que contiene ambos trabajos, a menudo mediante un **merge commit** — un commit con dos parents. La mayoría de las veces es automático y sin esfuerzo: las dos branches tocaron archivos distintos o partes distintas, y Git simplemente las cose.

_Diagram: La branch de la función (f1, f2) vuelve a main. El merge commit M une ambas líneas — tiene dos parents._

#### Merge (unir branches)

- **Qué es:** Combinar el trabajo de una branch en otra.
- **Cómo funciona:** Git compara los cambios de ambos lados y crea un **merge commit** con dos parents.
- **Ejemplo:** `git switch main` → `git merge feature/login` — el formulario de login ya está en main.
- **Trampa:** Si ambos lados tocaron la misma línea, aparece un **conflict**, y decides tú.
- **Relaciones:** La alternativa es **Rebase**. Puede llevar a un **Merge Conflict**. En los equipos pasa por un **Pull Request**.

### Merge Conflict — dos ediciones de la misma línea

> Dos editores que reescribieron cada uno la misma frase de forma distinta — ninguna máquina sabe cuál querías, así que se detiene y te pregunta.

Un **merge conflict** ocurre cuando ambas branches cambiaron _la misma parte del mismo archivo_ de formas incompatibles. Git no puede adivinar qué versión es la correcta, así que se pausa, marca el lugar y te muestra ambas versiones lado a lado. No es un error ni un desastre — es Git negándose, con razón, a tirar en silencio el trabajo de alguien. Los conflicts asustan la primera vez justamente porque lo que está en juego (no perder trabajo) es claro.

_Diagram: En main la línea 3 pasó a ser «Hello, team!», en feature — «Hi, world!». Git no puede saber cuál es la correcta, así que se detiene._

#### Merge Conflict (conflict, conflicto de merge)

- **Qué es:** Dos branches cambiaron el mismo punto de un archivo de forma distinta.
- **Cómo funciona:** Git detiene el merge y marca las líneas en disputa en el archivo.
- **Ejemplo:** Línea 3 de `greeting.txt`: «Hello, team!» frente a «Hi, world!».
- **Trampa:** No es una avería — es Git negándose a descartar en silencio el trabajo de alguien.
- **Relaciones:** Surge durante un **Merge** o **Rebase**; se arregla con **Conflict Resolution**; es más raro con **branches cortas**.

### Conflict Resolution — resolver un conflict es solo elegir

> Leer ambas frases reescritas y luego escribir la versión final que de verdad quieres — quedándote con una, con la otra o con una mezcla — y seguir adelante.

**Resuelves** un conflict editando el archivo marcado hasta la versión que quieres — quedarte con la tuya, con la de ellos, o combinarlas — quitando los marcadores `<<<<<<<`, `=======`, `>>>>>>>`, y haciendo commit del resultado. Ese es todo el secreto: un conflict es Git entregándote una decisión que solo un humano puede tomar, y resolver es tomar esa decisión. Los conflicts se vuelven más pequeños y raros cuando las branches viven poco y haces merge a menudo, de modo que los dos lados nunca se alejan mucho.

_Diagram: Izquierda — el archivo con los marcadores de conflict: ambas versiones están entre ellos. Derecha — lo que eligió la persona. Luego git add y git commit._

#### Conflict Resolution (resolver)

- **Qué es:** Elegir a mano la versión final de un punto en disputa.
- **Cómo funciona:** Edita el archivo, quita los marcadores `<<<<<<<` / `=======` / `>>>>>>>`, luego `git add` y `git commit`.
- **Ejemplo:** «Hello, team!» y «Hi, world!» se convirtieron en «Hi, team!».
- **Trampa:** Para elegir bien debes entender ambas versiones — pregunta al autor si dudas.
- **Relaciones:** Completa un **Merge** tras un **Merge Conflict**.

> **La pregunta del merge:** «Cuando estas branches se reúnan, ¿tocaron las mismas líneas — y si Git me pide resolver un conflict, ¿entiendo ambas versiones lo bastante bien para elegir correctamente?»

> Un merge teje dos branches en una sola línea de tiempo. Un conflict son solo dos ediciones de la misma línea — Git negándose a adivinar y pidiéndote que elijas.

## 5. Remotes y el equipo

Hasta ahora todo vive en tu máquina. Trabajar con otros — o respaldar tu trabajo — significa conectar tu repo local con uno compartido en la nube.

### Local y Remote — dos copias, origin es la compartida

> Tu copia de trabajo personal del manuscrito en casa, y la copia maestra compartida en la oficina que todo el equipo mantiene sincronizada.

Git es **distribuido**: tienes una copia completa del repo en tu máquina (**local**), y normalmente hay una copia compartida en un servidor (**remote**) — en un servicio como GitHub o GitLab. Haces todo tu trabajo en local — rápido, incluso sin conexión — y sincronizas con el remote para compartirlo y traer el trabajo de otros. El remote por defecto se llama por convención **origin**. Dos copias, mantenidas a propósito al mismo paso.

_Diagram: Cada persona del equipo tiene una copia completa del repo. La copia compartida origin en GitHub o GitLab mantiene a todos sincronizados._

#### Local / Remote (repo local y remoto, origin)

- **Qué es:** Local es tu copia completa del repo; remote es la copia compartida en un servidor. El remote principal se llama **origin**.
- **Cómo funciona:** Trabajas en local (incluso sin conexión), luego sincronizas con el remote.
- **Ejemplo:** El repo en GitHub es origin; tú y tus compañeros tienen cada uno una copia en su portátil.
- **Trampa:** El trabajo que no has subido (push) vive solo en tu portátil — y muere con él.
- **Relaciones:** Las copias se sincronizan con **Clone / Push / Pull / Fetch**; los **Pull Requests** viven en el remote.

### Clone, Push, Pull, Fetch — los cuatro movimientos de sincronización

> Fotocopiar el original de la oficina para llevártelo a casa (clone), enviar de vuelta tus páginas terminadas (push), y recoger las páginas nuevas de todos los demás (pull).

Cuatro palabras mueven trabajo entre local y remote. **Clone** hace tu primera copia local de un repo remoto. **Push** envía tus commits al remote para que otros los vean. **Pull** trae los commits nuevos de otros a tu copia y los fusiona. **Fetch** descarga lo nuevo sin fusionarlo todavía, para que mires primero. Domina estos cuatro y podrás colaborar: son todo el vocabulario para mantenerse sincronizado.

_Diagram: Clone — la primera copia. Push — sube lo tuyo. Pull — baja lo de ellos y fusiona. Fetch — solo descarga, sin merge._

#### Clone / Push / Pull / Fetch (los cuatro comandos de sincronización)

- **Clone:** `git clone <url>` — tu primera copia local completa de un repo remoto.
- **Push:** `git push` — envía tus commits al remote.
- **Pull:** `git pull` — descarga los commits de otros y los fusiona (fetch + merge).
- **Fetch:** `git fetch` — descarga lo nuevo pero no lo fusiona todavía: mira primero.
- **Trampa:** Un push sin pull a menudo se rechaza: trae primero los cambios de otros y luego envía los tuyos.
- **Relaciones:** Mueven **Commits** entre **Local** y **Remote**; pull hace un **Merge** por dentro.

### Pull Request — cómo los equipos revisan el trabajo

> Entregar tu capítulo nuevo a editores que lo leen, comentan y aprueban antes de que se encuaderne en el libro oficial.

En plataformas como GitHub, normalmente no haces merge directo en main. Haces push de tu branch y abres un **pull request** (PR; en GitLab, un merge request) — una propuesta para fusionar tu trabajo, donde tus compañeros lo **revisan**, dejan comentarios y lo aprueban antes de que entre en main. Es el punto de control donde un segundo par de ojos detecta problemas y el equipo acuerda que un cambio está listo. El PR es donde ocurre la mayor parte del Git en equipo.

_Diagram: Haces push de la branch, abres un PR, los compañeros revisan. Piden cambios — arregla y haz push otra vez. Aprobado — merge en main._

#### Pull Request (PR, merge request)

- **Qué es:** Una propuesta para fusionar una branch en main, con discusión y revisión.
- **Cómo funciona:** Push de la branch → abrir un PR → comentarios y arreglos → aprobación → merge.
- **Ejemplo:** PR «add login form»: un compañero pide renombrar una función, subes el arreglo, el PR se aprueba.
- **Trampa:** Nadie lee de verdad un PR gigante — mantenlos pequeños.
- **Relaciones:** Vive en el **Remote**, lleva una **Branch**, termina en un **Merge** a **main**.

> **La pregunta del remote:** «¿Hice pull de lo último antes de empezar, y mi trabajo terminado está subido y propuesto — para que el equipo lo vea y nada viva solo en mi portátil?»

> Local es tu copia; remote (origin) es la compartida. Clone, push, pull y fetch las mantienen al mismo paso — y un pull request es donde el equipo revisa antes de fusionar.

## 6. Deshacer e historial

El consuelo más profundo de Git es que casi nada se pierde de verdad. Saber leer el historial y retroceder con seguridad es lo que convierte a Git de algo aterrador en algo tranquilizador.

### Log — la historia del proyecto

> Hojear una pila fechada y firmada de cada borrador — viendo exactamente qué cambió en cada paso y quién lo hizo.

El **log** (`git log`) es la lista de commits, el historial de tu proyecto en orden, cada uno con su mensaje, autor y hora. Responde a «¿qué pasó y cuándo?» y es el punto de partida para entender cualquier código o cazar cualquier bug. Cuando algo se rompe, el log te deja encontrar el commit exacto que lo introdujo, porque cada cambio está registrado. Un historial que puedes leer es un historial que puedes depurar.

_Diagram: git log: commits del más nuevo al más antiguo, con autor, fecha y mensaje. ¿Se rompieron las fechas? Busca el commit que cambió el análisis de fechas._

#### Log (historial de commits, git log)

- **Qué es:** La lista de cada commit: ID, autor, hora, mensaje.
- **Cómo funciona:** `git log` muestra el historial de los commits más nuevos a los más antiguos.
- **Ejemplo:** Las fechas se rompieron el 11 de junio — el log muestra el commit `e81f53` «change date parsing».
- **Trampa:** El log solo es tan útil como los mensajes de commit que contiene.
- **Relaciones:** Lee la cadena de **Commits**; su valor viene del **Commit Message**.

### Revert vs Reset — dos formas de deshacer: la honesta y la que reescribe

> Dos formas de deshacer un error: añadir al registro una corrección claramente marcada (revert), o arrancar en silencio la última página como si nunca hubiera pasado (reset).

Git te da formas seguras de volver atrás. **Revert** crea un commit nuevo que deshace uno anterior — el error se queda en el historial, con su deshacer registrado encima, lo cual es honesto y seguro para el trabajo compartido. **Reset** te mueve de vuelta a un commit anterior, reescribiendo el historial reciente como si esos commits nunca hubieran ocurrido — potente, pero peligroso con trabajo que otros ya tienen. Regla práctica: revert en todo lo público, reset solo en trabajo privado y local.

_Diagram: Arriba, revert: el error C se queda, y un commit nuevo lo deshace. Abajo, reset: HEAD salta de vuelta a B, y C desaparece del historial._

#### Revert vs Reset (deshacer con un commit / rebobinar el historial)

- **Revert:** `git revert C` — un commit nuevo que deshace C. El historial queda intacto.
- **Reset:** `git reset B` — mueve la branch de vuelta a B, como si C nunca hubiera ocurrido.
- **Ejemplo:** Rompiste producción con un commit en main — revert. La liaste en local, sin haber subido nada — reset.
- **Trampa:** Hacer reset de lo que tus compañeros ya bajaron desincroniza a todo el equipo.
- **Relaciones:** Trabajan sobre **Commits** y **HEAD**; reset, como **Rebase**, reescribe el historial.

### Rebase — reproduce tu trabajo; respeta la regla de oro

> En lugar de grapar tu borrador aparte al manuscrito con una costura visible (merge), reescribes tus ediciones limpiamente sobre la última versión, como si hubieras empezado desde ella (rebase).

**Rebase** es una alternativa al merge: en lugar de unir dos líneas con un merge commit, reproduce tus commits encima de otra branch, produciendo un historial ordenado y en línea recta. Es ideal para limpiar tu propia branch antes de compartirla. Pero _reescribe_ commits (crea copias nuevas de ellos), así que la **regla de oro**: nunca hagas rebase de un historial que otros ya bajaron. Reescribe historial compartido y desincronizas a todos. Haz rebase de tu trabajo privado; usa merge para combinar trabajo compartido.

_Diagram: Antes: X e Y salen de B. Después de git rebase main: sus copias X′ e Y′ quedan después de C — una sola línea recta, sin merge commit._

#### Rebase (reproducir commits)

- **Qué es:** Reproducir tus commits encima de otra branch.
- **Cómo funciona:** Git toma tus commits y recrea copias de ellos sobre la nueva base.
- **Ejemplo:** En `feature`, ejecuta `git rebase main` — tus X e Y quedan ahora después de la C nueva de main.
- **Trampa:** **Regla de oro**: nunca hagas rebase de un historial que otros ya bajaron.
- **Relaciones:** La alternativa a **Merge**; puede causar un **Merge Conflict**; reescribe el historial, como **Reset**.

> **La pregunta del historial:** «Si esto sale mal, ¿puedo leer el log para encontrar dónde — y estoy deshaciendo con la herramienta segura (revert para el trabajo compartido), sin reescribir nunca un historial que otros ya tienen?»

> El log es la historia legible; revert y reset son tus formas de volver atrás. Rebase hace un historial ordenado — pero nunca reescribas un historial que otros ya bajaron.

## 7. Usarlo bien

Git tiene muchos comandos, pero la buena práctica es una lista corta de hábitos. Síguelos y Git sigue siendo una red de seguridad tranquila en lugar de una crisis ocasional.

### Small Commits — commits pequeños y enfocados

> Un álbum de fotos donde cada imagen captura un momento claro con su pie de foto — mucho más útil que una sola foto borrosa de todo a la vez.

Haz commit **pequeño y a menudo** (commits pequeños, atómicos), de modo que cada commit sea un cambio coherente con un mensaje que lo explique. Los commits diminutos y bien etiquetados hacen el historial legible, los bugs fáciles de rastrear y los deshacer quirúrgicos: puedes hacer revert de un cambio preciso sin perder nada más. Un commit gigante que vuelca una semana de trabajo mezclado es lo contrario — imposible de revisar, desenredar o deshacer en parte. La disciplina cuesta segundos y rinde durante toda la vida del proyecto.

_Diagram: Un commit enorme de una semana frente a cuatro pequeños: cada uno sobre una sola cosa, y cualquiera se puede deshacer por separado._

#### Small Commits (commits pequeños atómicos)

- **Problema:** Un commit gigante no se puede revisar, desenredar ni deshacer en parte.
- **Idea:** Un commit = un cambio coherente + un mensaje claro.
- **Ejemplo:** En lugar de «week of work» — «add login form», «style login page», «fix date bug».
- **Coste:** Unos segundos para hacer `git add` de los archivos correctos y escribir el mensaje.
- **Relaciones:** Se apoya en la **Staging Area** y el **Commit Message**; hace útiles **Revert** y el **Log**.

### Feature Branch Workflow — una branch por función, fusionada a menudo

> Cada capítulo nuevo se redacta en su propia copia y se pliega de vuelta mientras aún es pequeño — así ningún borrador se aleja tanto del libro como para que reunirlo se vuelva una batalla.

Haz cada pieza de trabajo en **su propia branch** (una feature branch), mantenla de vida corta y fusiónala de vuelta a menudo. Las branches de larga vida se alejan mucho de main y convierten el merge en una dolorosa pila de conflicts; las branches pequeñas fusionadas con frecuencia siguen siendo fáciles. Combínalo con **pull antes de push** — trae primero los cambios de otros — para integrar de forma continua en lugar de chocar al final. Este ritmo es el corazón del Git de equipo fluido.

_Diagram: Arriba — branches cortas que vuelven rápido: los conflicts se quedan diminutos. Abajo — una branch larga que se alejó mucho: una gran pila de conflicts al final._

#### Feature Branch Workflow (una branch por función)

- **Problema:** Todos escriben en main — se rompen unos a otros; una branch larga — una montaña de conflicts al final.
- **Idea:** Una tarea — una branch corta, fusionada mediante un PR en días, no en semanas.
- **Ejemplo:** `fix/date`: pull, branch, dos commits, push, PR, revisión, merge — todo en un día.
- **Coste:** Hay que cortar el trabajo en piezas pequeñas y hacer pull de main a menudo.
- **Relaciones:** Une **Branch**, **Pull**, **Push**, **Pull Request** y **Merge**.

### Cómo se conectan los conceptos

> Una cadena de montaje: de una edición en un archivo a la versión de confianza — un solo camino con paradas claras.

Todo el camino se ve así. Las ediciones de tus **archivos de trabajo** pasan con `git add` a la **staging area**, y con `git commit` a un **commit**, que lees en el **log**. Los commits se acumulan en **branches**; las branches vuelven mediante **merge** o **rebase**, a veces con un **conflict**. En un equipo, haces **push** de la branch al **remote**, abres un **pull request**, y tras la revisión haces merge en **main**. Si algo sale mal — **revert** o **reset**.

_Diagram: Los enlaces principales entre los conceptos del curso: de una edición a main y de vuelta._

#### Tus hábitos diarios de Git

- Haz **pull de lo último** antes de empezar, para construir sobre el trabajo actual.
- Trabaja en una **branch**, nunca directamente en la frágil main.
- Haz **commits pequeños** con **mensajes claros** sobre la marcha.
- Haz **merge a menudo**, mientras las branches aún son cortas, para que los conflicts sean diminutos.
- Haz **push** de tu trabajo y abre un **pull request** para la revisión.
- Deshaz con **revert** en el trabajo compartido; nunca hagas **rebase** de un historial que otros tienen.

#### Señales de que usas bien Git

- Tu **historial se lee** como una historia clara de pasos pequeños y etiquetados.
- El trabajo nuevo vive en **branches**; **main** siempre funciona.
- Haces **pull antes de push** y fusionas mientras las branches aún son pequeñas.
- Recurres a **revert** en el trabajo compartido y nunca reescribes el **historial** compartido.
- Git se siente como una **red de seguridad** — experimentas con libertad, sabiendo que siempre puedes volver.

> Un buen Git son unos pocos hábitos: haz pull primero, pon tu trabajo en una branch, haz commits pequeños con mensajes claros, fusiona a menudo y revisa antes de hacer merge. Los comandos son muchos; la disciplina es corta.

## Hoja de referencia: los 21 conceptos

### Lo básico

- **Version Control** (VCS): Un proyecto + un historial completo; cualquier versión puede volver.
- **Git** (una línea de tiempo de snapshots): El sistema de control de versiones más popular; guarda el proyecto como snapshots.
- **Repository** (repo): Carpeta del proyecto + historial oculto en `.git`.

### El commit

- **Commit** (snapshot): Un snapshot guardado con un ID y un enlace a su parent.
- **Staging Area** (el índice): La caja antes de un commit: `git add` la llena, `git commit` la sella.
- **Commit Message** (la nota): Una nota para el futuro: qué cambió y por qué.
- **HEAD** (estás aquí): Puntero al commit actual; avanza con cada commit.

### Branches

- **Branch** (línea de trabajo): Una línea paralela de commits que no toca el trabajo de nadie más.
- **main** (branch principal (master)): La versión de confianza que siempre funciona.
- **Switch / Checkout** (cambiar de branch): Pasar a una branch: los archivos de la carpeta cambian a su snapshot.

### Merging y conflicts

- **Merge** (unir): Juntar branches; a menudo mediante un commit con dos parents.
- **Merge Conflict** (conflict): Dos branches editaron la misma línea de forma distinta; Git te pide decidir.
- **Conflict Resolution** (resolver): Elegir la versión final, quitar los marcadores, hacer commit.

### Remotes y el equipo

- **Local / Remote** (origin): Tu copia completa y la copia compartida en un servidor.
- **Clone / Push / Pull / Fetch** (sincronizar): Primera copia · subir lo tuyo · traer lo de ellos y fusionar · solo descargar.
- **Pull Request** (PR, revisión): Una propuesta para fusionar una branch en main tras la revisión.

### Deshacer e historial

- **Log** (historial): La lista de commits: quién, cuándo, qué y por qué.
- **Revert vs Reset** (deshacer): Revert — un commit nuevo que deshace (para trabajo compartido). Reset — reescribir (solo lo tuyo).
- **Rebase** (reproducir): Reproducir commits encima de otra branch. Nunca sobre historial compartido.

### Buenos hábitos

- **Small Commits** (commits atómicos): Un cambio — un commit con un mensaje claro.
- **Feature Branch Workflow** (una branch por función): Una branch corta por tarea, fusionada a menudo mediante un PR.

Fin del curso exprés · 7 capítulos · 21 conceptos

Lo que sigue es la práctica: toma cualquier proyecto pequeño, ejecuta `git init` y haz unos cuantos commits mientras lo cambias — luego crea una branch, haz una edición y fusiónala de vuelta. Provoca un conflict a propósito editando la misma línea en dos branches, y resuélvelo. El miedo se evapora en cuanto has hecho cada cosa una vez con algo que no importa. Pero quédate con una idea por encima de las demás: Git es un botón de guardar que nunca olvida, y una forma de que muchas personas trabajen sin sobrescribirse. Cada palabra intimidante es solo el nombre de un paso tranquilo y recuperable — y ahora tienes todas.
