# Git aliases que uso cada día

Git es una herramienta enorme. La mayoría de desarrolladores conoce bien veinte comandos, apenas usa cinco y escribe los cinco sin parar durante ocho horas al día. Cuando escribes `git status` cien veces por día y `git checkout -b` otras treinta, cada carácter ahorrado empieza a sumar. Y más allá del ahorro de teclas, un buen conjunto de aliases te convierte ciertos comandos incómodos en comandos rápidos, y te evita los sustos que suelen venir de teclear mal algo con `--force`.

Este post es mi `.gitconfig` comentado, después de diez años afinándolo. No es exhaustivo: es el mínimo que me llevaría a cualquier máquina nueva.

## Dónde van los aliases

![Git aliases que uso cada día](fig-01.webp)

Los aliases de git viven en el fichero `~/.gitconfig` bajo la sección `[alias]`:

```ini
[alias]
    st = status
    co = checkout
    br = branch
```

Puedes añadirlos con `git config --global alias.st status` o editando el fichero a mano. Yo los edito a mano porque la mayoría son multilínea y el comando `git config` es incómodo para eso.

Los aliases que empiezan con `!` son comandos shell arbitrarios, no solo subcomandos de git. Esto abre la puerta a muchísimas cosas, como veremos más adelante.

## Los básicos (y por qué sí me molesto en tenerlos)

Empecemos por los aliases que son solo abreviaturas:

```ini
[alias]
    st = status
    co = checkout
    br = branch
    ci = commit
    sw = switch
    cp = cherry-pick
```

Parecen una tontería, pero estos seis aliases me ahorran, literalmente, horas al año. `git st` en vez de `git status` son cinco caracteres menos. Multiplicado por cien veces al día, por doscientos días al año, por diez años. Más lo que gano en momentum mental: no tengo que pararme a teclear una palabra larga cuando el pensamiento ya ha pasado a otra cosa.

Nota sobre `sw` y `co`: `switch` es el comando moderno para cambiar de rama (Git 2.23+). Lo prefiero a `checkout` cuando solo voy a cambiar de rama, porque `checkout` hace demasiadas cosas distintas y es fácil meter la pata. Para operaciones sobre ficheros sigo usando `checkout` o `restore`.

## Log decente

![Git aliases que uso cada día](fig-02.webp)

El log por defecto de git es feo y poco útil. Este alias es probablemente el que más uso en la vida:

```ini
[alias]
    lg = log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
```

Resultado: un árbol de commits con hash, referencias, mensaje, fecha relativa y autor, todo en una línea por commit. Cabe más historial en la pantalla y la estructura de ramas se ve de un vistazo.

Si el gráfico es demasiado para algún caso concreto:

```ini
[alias]
    lgo = log --oneline --decorate
```

Y para ver un log más rico cuando quiero investigar algo:

```ini
[alias]
    lgf = log --graph --pretty=fuller
```

## Diff y show útiles

Los diffs por defecto son correctos pero hay variantes que uso mucho:

```ini
[alias]
    dc = diff --cached
    ds = diff --stat
    dw = diff --word-diff
```

`dc` es el diff de lo que está staged, lo opuesto al diff por defecto. Cuando estás a punto de hacer commit, `git dc` te muestra exactamente lo que vas a committear.

`ds` te da un resumen de ficheros modificados con número de líneas añadidas/borradas. Útil cuando el diff es muy grande y quieres primero un mapa.

`dw` hace word-diff en vez de line-diff. Esencial para ver qué cambió en un fichero largo donde solo han cambiado palabras sueltas (documentación, config files).

## Commits rápidos y commits de emergencia

![Git aliases que uso cada día](fig-03.webp)

Algunos aliases que uso casi sin pensar:

```ini
[alias]
    cm = commit -m
    ca = commit -a -m
    amend = commit --amend --no-edit
    fixup = commit --fixup
    wip = commit -am "WIP"
```

`cm` es para commits con mensaje inline. `ca` añade todo lo modificado y hace commit en una línea. `amend` rehace el último commit sin cambiar el mensaje (útil cuando te has dejado algo fuera). `fixup` crea un commit marcado como fixup de otro, para luego hacer `rebase --autosquash`.

`wip` es el que uso cuando necesito cambiar de rama y no quiero pararme a pensar en el mensaje. Comiteo con "WIP", cambio de contexto, y cuando vuelvo hago `git reset HEAD~1` y retomo.

## Push y pull con menos tecla

```ini
[alias]
    ps = push
    psu = push -u origin HEAD
    pl = pull --rebase
```

`psu` es el que uso cuando empujo una rama nueva por primera vez: empuja HEAD a una rama con el mismo nombre en origin y establece el tracking. Me ahorro `git push -u origin nombre-de-la-rama` con riesgo de errata.

`pl` siempre con `--rebase` porque prefiero un historial lineal a un merge commit cada vez que tiro del repo.

## Deshacer sin romper nada

Los aliases para deshacer son los que más miedo me han ahorrado:

```ini
[alias]
    undo = reset HEAD~1 --mixed
    discard = checkout --
    unstage = reset HEAD --
```

`undo` deshace el último commit pero conserva los cambios como modificaciones. Si el commit era una mierda, editas y vuelves a committear.

`discard` descarta cambios no committeados en un fichero. `git discard src/main.go` y el fichero vuelve a como estaba en el último commit.

`unstage` saca del index cosas que habías añadido con `add` pero que no quieres committear todavía.

Estos tres aliases son el equivalente a "deshacer" en una interfaz gráfica. Son los que más suelo recomendar a gente que empieza con git.

## Ramas: limpiar y moverse

Estos son los que salvan la vida después de unas semanas de trabajo en un repo:

```ini
[alias]
    cleanup = "!git branch --merged main | grep -v '^\\*\\|main\\|master' | xargs -n 1 git branch -d"
    latest = "!git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)' | head -20"
    current = rev-parse --abbrev-ref HEAD
```

`cleanup` borra todas las ramas locales que ya están fusionadas a main. En un repo de trabajo acumulas fácilmente cincuenta ramas cerradas; esto las limpia en un comando.

`latest` te muestra las veinte ramas locales ordenadas por último commit. Perfecto para "¿cómo se llamaba la rama aquella de hace tres días?".

`current` escupe el nombre de la rama actual. Lo uso en scripts más que interactivamente.

## Rebase sin angustia

El rebase interactivo es donde más gente se queda atascada:

```ini
[alias]
    ri = rebase -i
    rim = "!git rebase -i $(git merge-base HEAD main)"
    continue = rebase --continue
    abort = rebase --abort
```

`rim` es el que uso más: hace rebase interactivo desde el punto de divergencia con main. No tengo que acordarme de qué commit es la base; git lo calcula solo.

`continue` y `abort` están porque durante un rebase conflictivo escribo `git continue` diez veces. Mejor un alias directo.

## Exploración de código

Estos son los que uso para navegar por repos que no conozco:

```ini
[alias]
    who = shortlog -sn --
    blame-line = "!f() { git log -L $1,$1:$2; }; f"
    recent = "!git log --since='2 weeks ago' --pretty=format:'%h %s (%an, %cr)'"
    contributors = shortlog -sn --no-merges
```

`who` te dice quién ha committeado más veces en un fichero. Útil para saber a quién preguntar.

`blame-line` te da la historia completa de una línea concreta de un fichero. `git blame-line 42 src/main.go` te muestra todos los commits que tocaron la línea 42 de ese fichero, no solo el último.

`recent` es un log filtrado por "las últimas dos semanas". Perfecto cuando vuelves de vacaciones y necesitas ponerte al día.

## Stash: guardar y recuperar

```ini
[alias]
    ss = stash save
    sp = stash pop
    sl = stash list
    sd = stash drop
```

No hay mucho que explicar aquí: son las operaciones de stash abreviadas. El stash es una herramienta infrautilizada; con aliases cortos la uso mucho más.

## El alias que me salvó varios días

Uno específico que merece mención aparte:

```ini
[alias]
    saveme = "!git stash && git checkout main && git pull && git checkout - && git stash pop"
```

Traducción: guarda cambios, cambia a main, actualiza, vuelve a tu rama, recupera cambios. Lo uso cuando estoy a medio código y necesito una versión actualizada de algo en main sin perder lo que tengo hecho. Escribir esa secuencia a mano es un foco de errores; un alias la hace atómica.

## Aliases que no recomiendo

He visto a gente tener aliases que son malas ideas:

**Aliases para `push --force`**. El force push es peligroso: puede borrar trabajo de otros en ramas compartidas. Si vas a hacer force push, quiero que cueste teclearlo. Nunca lo abrevio.

**Aliases para `reset --hard`**. Igual. Si vas a destruir cambios, quiero que sean dos palabras completas, no un atajo. La fricción es una feature, no un bug.

**Aliases con secretos hardcodeados**. Los aliases viven en `.gitconfig`, que a veces está en repos (dotfiles). No metas ahí tokens, credenciales ni nada que no puedas compartir.

## Mi fichero completo

El `.gitconfig` que llevo a cada máquina cabe en unas cuarenta líneas. Lo tengo en mi repo de dotfiles y lo clono con el resto de mi setup cuando monto un entorno nuevo. No es una gran inversión de tiempo y el ROI es enorme: una vez que tu muscle memory tiene `git st`, `git lg` y `git psu`, no vuelves atrás.

## La recomendación real

Si estás pensando "voy a copiar todos estos aliases de golpe", no. Hazlo al revés: añade uno cada vez que notes que estás escribiendo el mismo comando largo por tercera vez. Así, en tres meses, tendrás una colección personalizada a tu forma de trabajar, y cada alias te va a importar. Copiar treinta aliases de una lista es ruido; descubrirlos por necesidad propia es productividad real.
