git reset para coding agents: mueve HEAD; --hard no es el undo
Resumen
git reset mueve la punta de la rama. --soft deja index y disco; --mixed (default) destagea; --hard pisa working tree y puede borrar untracked. Un agente no corre --hard ni reset de historia publicada. Pathspec destagea; para un archivo usa restore.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
git reset no es undo de un archivo. El man page de Git (2.50, Apple Git-155) lo parte en dos: con <commit> mueve HEAD (y, según el modo, index y disco); con <pathspec> solo destagea. git(1) lo contrapone a restore (paths, no mueve la rama) y a revert (commit nuevo que deshace otro). Un coding agent que “limpia” con reset --hard tira el working tree entero, no el path que rompió.
Esta guía no sustituye worktrees ni gitignore. El contrato: cuándo un agente puede resetear HEAD, qué modos están prohibidos, y por qué pathspec no es --hard.
Tres capas (oficial)
Antes de reset [<mode>] <commit>, Git copia el tip actual a ORIG_HEAD. Luego:
| Modo | HEAD | Index | Working tree |
|---|---|---|---|
--soft | Mueve | Igual | Igual |
--mixed (default) | Mueve | Iguala al nuevo HEAD; nada staged | Igual |
--hard | Mueve | Iguala | Pisa tracked; puede borrar untracked |
--keep | Mueve | Iguala paths distintos entre commit y HEAD | Iguala esos paths; aborta si hay edits locales ahí |
--merge | Mueve | Resetea unmerged | Conserva edits no staged; aborta si un path distinto commit↔index tiene unstaged |
--hard: “Overwrite all files and directories with the version from <commit>, and may overwrite untracked files”. Tracked que no están en <commit> se borran. No es “descartar un hunk”.

Pathspec: destagear, no rebobinar
git reset [--] <pathspec> no mueve HEAD. Pone el index de esos paths al tree-ish (default HEAD). Es el inverso de git add <pathspec> y equivale a git restore --staged <pathspec>. El disco no cambia.
git reset -p es interactivo (inverso de git add -p). Un harness headless no lo corre.
Un agente que quiere “sacar este archivo del commit” no hace reset --hard HEAD~1. Hace git reset -- src/foo.ts (o restore --staged) y un commit nuevo. Historia publicada: PR con gh, no reset.
Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| Destagear paths, dejar disco | git reset -- src/foo.ts | Sin --, un path que parezca opción se come |
| Rehacer el último commit local no pusheado | git reset --soft HEAD^ + git commit | HEAD^ en un merge es el primer padre; nombra el SHA |
| Destagear todo, dejar edits | git reset (= --mixed HEAD) | No toca untracked; no es clean |
| Abortar un merge sucio conservando edits locales | git reset --merge ORIG_HEAD | --hard ORIG_HEAD tira esos edits |
| Aislar commits prematuros | git branch topic/wip antes de mover main | El man: crea rama, después --hard HEAD~n en la rama que vas a rebobinar |
Prohibido en autónomo:
git reset --hard(con o sin commit). El man avisa overwrite de untracked. El humano lo pide por escrito o no se corre.git reset --hard HEAD~nen una rama ya pusheada / compartida. El man: “Do not do this if you have already given these commits to somebody else.”git resetsin pathspec en el checkout del humano. Mueve su HEAD.--patch. Interactivo.- Confundir
reset --soft HEAD^con amend+force-push. Soft deja el árbol; el force es otro comando y otro permiso.
Receta para un agente (60 segundos)
El default correcto no es reset. Si el agente está en un worktree propio y solo necesita destagear:
git status
git reset -- src/lib/foo.ts src/lib/bar.ts
git status
git diff --cached
Si el último commit es suyo, no está en origin, y el ticket pide rehacer el mensaje/árbol:
git log -1 --oneline
git status -sb # no debe decir ahead of origin con others
git reset --soft HEAD^
# edits / git add paths explícitos
git commit -c ORIG_HEAD
--soft HEAD^ + commit -c ORIG_HEAD es el ejemplo oficial de “undo a commit and redo”. No uses --hard. No uses HEAD~5 “por si acaso”.
ORIG_HEAD es el tip antes del reset. Úsalo para volver (git reset --keep ORIG_HEAD) si el soft/mixed salió mal. --keep aborta si hay edits locales en paths que cambiarían.

Reset vs restore vs revert
git(1):
- revert: commit nuevo que deshace otros. Historia hacia adelante. Eso va a un PR.
- restore: copia paths desde index o un commit. No mueve la rama.
- reset: mueve la punta de la rama (o, con pathspec, solo el index).
Un agente que “deshace el PR mergeado” no resetea main. Abre un revert en rama y abre PR.
Untracked: reset --mixed no los toca. reset --hard puede pisarlos. Quitar untracked es otro comando (git clean) y otro permiso.
Checklist
- El agente no corre
--hardsalvo orden explícita del humano en su worktree. - Pathspec lleva
--. Destagea; no rebobina. - Soft/mixed solo en commits no publicados.
status -sbantes. - Historia compartida: revert + PR, no reset.
-
ORIG_HEADexiste después del reset; no asumas queHEAD^sigue siendo el mismo. -
--keep/--mergesi hay edits locales que no quieres tirar. No improvisar--hard. - Cero reset en el checkout del humano.
FAQ
¿git reset sin args es seguro? Es --mixed HEAD: destagea todo, deja disco. No borra untracked. Sigue siendo un cambio de index en el repo del humano si no estás en worktree propio.
¿--soft HEAD^ pierde el commit? El commit queda reachable desde ORIG_HEAD y reflog. Deja de ser tip de la rama. Si ya lo pusheaste, el remoto no se entera hasta un force.
¿Puedo resetear un solo archivo a un commit viejo y el disco? No con reset <commit> -- file (solo index). Para disco: git restore --source=<commit> -- file. Reset pathspec no actualiza working tree.
¿--hard borra untracked? El man: may overwrite untracked files. No lo trates como “solo tracked”.
¿Submódulos? --recurse-submodules resetea el working tree de submódulos activos al commit del superproyecto (HEAD detached). Default: no. Un agente no lo añade.
El curso instalar un agente cubre el loop local. Aislamiento de red y secretos: sandboxing. Reset mueve punteros, no es sandbox.
Verificado 2026-09-03 contra git-reset(1) y git(1) (Git 2.50.1 / Apple Git-155).
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git status para coding agents: porcelain, XY, no el long

Reusable workflows: workflow_call, no copies el YAML entre repos

schedule (cron) en GitHub Actions: UTC, no cada minuto
