git restore --staged: el reemplazo de git reset HEAD
Mezclaste refactor y feature en el mismo staging. Commitear solo la feature sin perder los cambios del refactor: eso es exactamente para lo que existe este comando.
# Unstage un archivo; working tree intacto
git restore --staged src/utils/legacy.ts
# Unstage todo de una
git restore --staged .git reset HEAD <file> hacía lo mismo, pero como efecto colateral. Su modo default (--mixed) mueve HEAD al mismo commit y resetea el índice; cuando le pasás un archivo específico, solo aplica la parte del índice, HEAD no se mueve. El resultado es correcto. La intención no es obvia.
git restore no toca HEAD. Nunca. Lo que declarás en los flags es exactamente lo que cambia, sin más:
| Aspecto | git reset HEAD <file> | git restore --staged <file> |
|---|---|---|
| Mueve HEAD | No (efecto colateral de --mixed) | No (por diseño explícito) |
| Modifica el índice | Sí | Sí |
| Toca el working tree | No | No |
| Intención legible | Implícita | Explícita |
Dos combos que vale tener en el músculo:
# Unstage + descartar cambios en working tree (nuke local)
git restore --staged --worktree src/utils/legacy.ts
# el viejo equivalente: git checkout HEAD src/utils/legacy.ts
# Restaurar un archivo desde otro branch directamente al staging
git restore --source=main --staged src/config/prod.tsDisponible desde Git 2.23.0 (agosto 2019). Si trabajás en equipos con versiones viejas, git --version antes de asumirlo.
🔗 Sugerencias de lectura
- git absorb: el fixup automático que no sabías que necesitabas: Después de unstage selectivo,
git absorblimpia los fixup commits sin abrir el editor de rebase. - La Cerca de Chesterton en el Refactoring Senior: Por qué entender el contexto original antes de mover o descartar código.