> ## Documentation Index
> Fetch the complete documentation index at: https://apuntes.simulab.es/llms.txt
> Use this file to discover all available pages before exploring further.

# Git desde cero: commits, ramas, merge, GitHub y comandos básicos

> Introducción a Git y GitHub: qué es el control de versiones, repositorio, área de preparación y commits, comandos básicos (init, add, commit, status, log, diff), ramas y merge, resolver conflictos, remotos (clone, push, pull), pull requests, .gitignore, deshacer cambios y buenas prácticas, con ejemplos.

¿Has tenido alguna vez archivos llamados `trabajo_final.docx`, `trabajo_final_v2.docx` y `trabajo_final_ahora_si.docx`? **Git** resuelve eso para el código: guarda la historia completa de un proyecto, permite volver a cualquier versión anterior, trabajar en varias ideas a la vez sin mezclarlas y colaborar con otras personas sin pisarse. Es la herramienta que usan prácticamente todos los equipos de software del mundo, y **GitHub** es el sitio más usado para alojar los proyectos.

## Lo que vas a aprender

* Qué es el control de versiones y cómo organiza Git los cambios.
* Los comandos básicos para guardar versiones.
* Qué son las ramas y cómo se fusionan.
* Cómo resolver un conflicto.
* Cómo trabajar con un repositorio remoto y con pull requests.
* Cómo deshacer cambios sin perder trabajo.

## Fundamentos

### Las tres zonas

| Zona | Qué hay |
| - | - |
| **Directorio de trabajo** | Los archivos tal como los estás editando |
| **Área de preparación** (*staging*) | Los cambios elegidos para el próximo commit |
| **Repositorio** | La historia de commits guardada |

Un **commit** es una foto del proyecto en un momento, con un mensaje, un autor, una fecha y un identificador único (*hash*, como `a3f9c21`). Cada commit apunta al anterior: la historia es una cadena.

### Comandos básicos

```bash theme={null}
git init                      # crea un repositorio en la carpeta actual
git status                    # qué ha cambiado
git add archivo.py            # prepara un archivo para el commit
git add .                     # prepara todos los cambios
git commit -m "Añade cálculo del área"
git log --oneline             # historia resumida
git diff                      # cambios todavía sin preparar
git diff --staged             # cambios preparados
```

Configuración inicial, una vez por ordenador:

```bash theme={null}
git config --global user.name "Tu Nombre"
git config --global user.email "tu@correo.es"
```

### Ramas

Una **rama** es una línea de desarrollo independiente. Se crea para trabajar en algo nuevo sin tocar la versión principal (`main`):

```bash theme={null}
git switch -c nueva-funcion   # crea la rama y se cambia a ella
# ... cambios y commits ...
git switch main               # vuelve a la rama principal
git merge nueva-funcion       # trae los cambios de la rama
git branch -d nueva-funcion   # borra la rama ya fusionada
```

Crear una rama es instantáneo: solo es un puntero a un commit.

### Conflictos

Si dos ramas cambian **las mismas líneas** de un archivo, Git no sabe con cuál quedarse y marca el conflicto:

```text theme={null}
<<<<<<< HEAD
precio = base * 1.21
=======
precio = base * IVA
>>>>>>> nueva-funcion
```

Se edita el archivo dejando la versión correcta (quitando las marcas), y luego `git add archivo` y `git commit`. Si se quiere abandonar: `git merge --abort`.

### Repositorios remotos

```bash theme={null}
git clone https://github.com/usuario/proyecto.git   # copia un repositorio
git remote -v                                       # ver los remotos
git push origin main                                # sube tus commits
git pull                                            # trae y fusiona los cambios de otros
git fetch                                           # trae sin fusionar
```

`origin` es el nombre por defecto del remoto del que se clonó.

### Pull requests

En GitHub (o GitLab), el flujo habitual de un equipo es:

1. Crear una rama para el cambio.
2. Hacer commits y subirla con `git push`.
3. Abrir una **pull request**: una petición para fusionar la rama en `main`.
4. Otras personas **revisan** el código, comentan y se pasan las pruebas automáticas.
5. Cuando todo está bien, se **fusiona**.

### .gitignore

Un archivo con los patrones que Git debe ignorar: archivos compilados, dependencias descargadas, contraseñas.

```text theme={null}
__pycache__/
*.pyc
node_modules/
.env
*.log
```

Nunca se suben contraseñas ni claves: aunque se borren después, quedan en la historia.

### Deshacer cambios

| Situación | Comando |
| - | - |
| Descartar cambios sin preparar de un archivo | `git restore archivo` |
| Quitar un archivo del área de preparación | `git restore --staged archivo` |
| Cambiar el mensaje del último commit (aún no subido) | `git commit --amend` |
| Deshacer un commit ya subido, creando uno que lo invierte | `git revert <hash>` |
| Volver la rama a un commit anterior (¡reescribe la historia!) | `git reset --hard <hash>` |
| Guardar cambios a medias para más tarde | `git stash` y luego `git stash pop` |

Regla de oro: **no reescribas la historia que ya has compartido** (`reset`, `--amend`, `rebase` sobre commits subidos). Usa `revert`.

### Buenas prácticas

* Commits **pequeños** y con un solo propósito.
* Mensajes que digan **qué y por qué**: "Corrige el cálculo del IVA en facturas con descuento", no "cambios".
* Haz `git pull` antes de empezar a trabajar.
* Una rama por cada funcionalidad o corrección.

## Ejemplos resueltos

> [accordion] Ejemplo 1 · Empezar un proyecto y subirlo a GitHub
>
> ```bash theme={null}
> mkdir practica && cd practica
> git init
> echo "# Práctica 1" > README.md
> git add README.md
> git commit -m "Primer commit"
> git branch -M main
> git remote add origin https://github.com/usuario/practica.git
> git push -u origin main
> ```
>
> El `-u` deja configurado el remoto: los siguientes `push` y `pull` ya no necesitan argumentos.

> [accordion] Ejemplo 2 · Encontrar qué commit rompió algo
>
> `git bisect` hace una [búsqueda binaria](https://apuntes.simulab.es/programacion/algoritmos/busqueda-binaria.md) por la historia:
>
> ```bash theme={null}
> git bisect start
> git bisect bad                 # la versión actual falla
> git bisect good v1.0           # esta versión funcionaba
> # Git va proponiendo commits; en cada uno pruebas y dices good o bad
> git bisect reset
> ```
>
> Con 1000 commits entre medias, encuentra el culpable en unos 10 pasos.

> [accordion] Ejemplo 3 · Me he equivocado de rama
>
> Has hecho cambios en `main` que deberían ir en una rama nueva, pero aún no has hecho commit:
>
> ```bash theme={null}
> git switch -c arreglo-login   # la rama nueva se lleva los cambios sin guardar
> git add . && git commit -m "Arregla el inicio de sesión"
> ```

## Errores frecuentes

* **Subir contraseñas o claves** al repositorio. Usa `.gitignore` y variables de entorno.
* **Hacer `git push --force`** en una rama compartida: borra el trabajo de otros.
* **Commits enormes con mensajes vacíos.** Dificultan entender y deshacer los cambios.
* **Trabajar siempre en `main`.** Con ramas se puede experimentar sin romper la versión buena.
* **Subir archivos generados** (compilados, dependencias): ocupan mucho y dan conflictos constantes.

## Preguntas frecuentes

> [accordion] ¿Git y GitHub son lo mismo?
>
> No. Git es el programa de control de versiones, que funciona en tu ordenador sin conexión. GitHub (y GitLab, Bitbucket) es un servicio web que aloja repositorios de Git y añade colaboración: pull requests, revisiones, incidencias y automatización.

> [accordion] ¿Sirve para algo que no sea código?
>
> Para cualquier archivo de texto: documentación, apuntes en Markdown, artículos en LaTeX, configuraciones. Estos mismos apuntes se escriben en archivos de texto y se gestionan con Git y GitHub. Con archivos binarios grandes (vídeos, Word) funciona peor, porque no puede mostrar ni fusionar las diferencias.

## Temas relacionados

> [card] [Fundamentos de Python](https://apuntes.simulab.es/programacion/python/fundamentos-python.md)
>
> Tu primer proyecto para versionar.

> [card] [Expresiones regulares](https://apuntes.simulab.es/programacion/herramientas/expresiones-regulares.md)
>
> Otra herramienta del día a día.

> [card] [Búsqueda binaria](https://apuntes.simulab.es/programacion/algoritmos/busqueda-binaria.md)
>
> La idea detrás de git bisect.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.