git revert para coding agents: commit nuevo que deshace, no reset
Resumen
git revert graba commits nuevos que invierten un parche ya existente. Exige working tree limpio. Merge: -m no se adivina. Conflicto: --abort, no --continue. GitHub Revert abre otro PR. Un agente no usa reset --hard para deshacer historia publicada. Man git-revert 2.50.1.

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 revert no borra el commit malo. El man (Git 2.50.1 / Apple Git-155): “Given one or more existing commits, revert the changes that the related patches introduce, and record some new commits that record them.” El working tree tiene que estar limpio (sin modificaciones respecto a HEAD). El SHA original sigue en la historia.
No es reset (mueve HEAD; --hard pisa disco) ni restore (copia paths). git(1) lo parte en tres: revert = commit nuevo que deshace; restore = archivos, no mueve la rama; reset = mueve la punta. GitHub, con write, puede abrir un PR que revierte el merge commit; un coding agent usa el CLI y el sequencer.
Esta guía no sustituye worktrees ni PRs con gh. El contrato: cuándo un agente puede revertir, qué flags están prohibidos, y cómo abortar.
Qué hace (y qué no)
Un commit C ya está en main (o en cualquier punta publicada). git revert C aplica el inverso del diff de C y graba C′. Autor/committer = quien revierte. SHA distinto. C no desaparece.
El man contrapone explícitamente:
- Tirar cambios sin commitear →
git reset, en particular--hard. Eso no es revert. - Extraer un archivo como estaba en otro commit →
git restore --source.
Si el parche inverso no aplica:
- La rama y HEAD se quedan en el último revert exitoso.
- El sequencer queda en curso (
.git/sequencer). - Paths en conflicto: marcadores
<<<<<<</>>>>>>>. --abortvuelve al estado pre-secuencia.--quitsolo olvida el sequencer y no restaura.
No hay rewind de historia. No hay force-push. Es un parche inverso.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| Deshacer un SHA publicado | git revert --no-edit <sha> | --edit es el default en terminal; headless se cuelga del editor |
| Parar a mitad | git revert --abort | --quit olvida el sequencer y no vuelve al estado previo |
| Seguir tras resolver a mano | git add paths + git revert --continue | Headless no resuelve <<<<<<< |
| Saltar este commit del rango | git revert --skip | Solo con secuencia en curso |
| Aplicar sin commitear | git revert -n <sha> | Deja el inverso en index/disco. El index no tiene que coincidir con HEAD |
| Revertir un merge | git revert -m <n> <merge-sha> | -m es el padre (desde 1). No se adivina |
Prohibido en autónomo:
- Revert con working tree sucio. El man lo exige limpio.
- Revert de un merge commit sin
-m <n>escrito en el ticket. El man: “Usually you cannot revert a merge because you do not know which side of the merge should be considered the mainline.” Revertir un merge declara que nunca querrás el árbol que trajo esa fusión; merges posteriores solo traen cambios que no son ancestros de ese merge. Eso no es “deshacer el PR”. -X ours/-X theirs. Un agente no elige un lado.- Rangos (
master~5..master~2) salvo ticket que nombre exactamente el conjunto. Default: un SHA. --continuedespués de borrar marcadores a ciegas. Reportagit diff --name-only --diff-filter=Uy--abort.- Revert sobre
mainlocal + push. El inverso va a una rama topic y un PR. - Confundir revert con reset
--hard“para que main quede como antes”. Reset reescribe historia; en rama publicada eso pide force-push, que el agente no corre. - Revertir un revert en bucle. El man: sujetos tipo
Reapply "Reapply "<original>". Si hay que reaplicar, un commit nuevo con mensaje propio, norevertdelreverta ciegas.
--no-edit usa el mensaje automático (This reverts <sha>.). El man recomienda explicar por qué. Si el ticket trae la razón, --no-edit y luego git commit --amend solo si el commit aún no salió del worktree y no hay amend+force.
Receta (60 segundos)
Solo en un worktree propio, working tree limpio, SHA nombrado:
git status -sb # limpio; no revert in progress
git rev-parse --verify <sha>^{commit}
git revert --no-edit <sha>
Conflicto:
git diff --name-only --diff-filter=U
git revert --abort
Varios SHAs en orden, no un rango opaco:
git revert --no-edit abc123 def456
Cada uno genera su commit. Si el segundo falla, HEAD quedó en el primero.
GitHub (doc 200, 2026-09-03): el botón Revert de un PR ya mergeado abre otro PR que revierte el merge commit. Hace falta permiso write. Si no aparece, no hay write. Si el revert del PR pelea o el original no se mergeó en GitHub, la misma doc manda a git revert commit a commit. El agente no pulsa el botón; corre el man y abre el PR con gh.

Revert vs reset vs restore
| Comando | Historia | Uso del agente |
|---|---|---|
revert C | Commit nuevo que deshace el diff de C | Deshacer un commit/merge ya publicado, vía PR |
reset --hard C | Mueve HEAD a C; pisa disco | Prohibido en autónomo. No es undo de producción |
restore -- path | No mueve la rama | Deshacer edits locales de un path |
El ejemplo del man git revert HEAD~3 revierte un commit (el cuarto detrás de HEAD), no “los últimos tres”. git revert -n master~5..master~2 aplica el inverso de ese rango sin commitear. Un agente no traduce “quita lo de ayer” a HEAD~n.
Checklist
- Worktree propio,
git status -sblimpio, sin sequencer previo. - Un SHA (o lista explícita). Cero merges sin
-mpedido por escrito. -
--no-editen headless. Razón del ticket en el cuerpo si el humano la dio. - Conflicto →
--abort+ paths. Cero--continueautónomo. - El commit nuevo va a una rama topic + PR. Cero revert sobre
main. - No
reset --hardni force-push “para igualar”. - No revert-del-revert sin mensaje nuevo y ticket.
FAQ
¿Puedo revertir un merge con -m 1? El man lo permite: -m es el número de padre (desde 1) que cuentas como mainline, y replayea el inverso respecto a ese padre. Un agente no elige 1 vs 2. Si el ticket no dice el padre, no revierte el merge. El howto revert-a-faulty-merge (nota 1 del man) explica el efecto permanente en merges posteriores.
¿-n es más seguro? --no-commit aplica al index/disco y no crea commit. Útil para inspeccionar varios inversos juntos. Headless: no lo uses para “acumular y ya commiteo yo” sin git diff --cached revisado.
¿--skip vs --abort? Skip descarta este commit de la secuencia y sigue. Abort tira toda la secuencia y vuelve atrás. Con un solo SHA, abort.
¿El botón Revert de GitHub? Crea un PR nuevo del merge commit. Misma semántica que git revert -m 1 <merge> sobre la default branch, encapsulada en UI. Conflictos → commits sueltos con el CLI.
El curso instalar un agente cubre el loop local. Aislamiento: sandboxing. Revert no es sandbox ni undo de untracked (clean).
Verificado 2026-09-03 contra git-revert(1) y git(1) (Git 2.50.1 / Apple Git-155; man 2.54.0 2026-04-19) y GitHub Docs “Reverting a pull request” (HTTP 200).
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
