git status para coding agents: porcelain, XY, no el long
Resumen
git status lista index vs HEAD, worktree vs index y untracked. El long no es API. Un agente parsea --porcelain=v1 -z; para humanos, -sb. XY es dos letras, no un párrafo. GitHub status checks no son git status. Git 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 status no es un párrafo para el LLM. El man (git-status(1), Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-status HTTP 200): muestra paths con diff index vs HEAD, worktree vs index, y untracked que no ignora gitignore(5). El long es plantilla de commit: “subject to change at any time”. Un agente que lo vuelca al prompt mezcla color, traducciones y diffs.
Esta guía no sustituye add ni gitignore. El contrato: qué forma corre un agente, qué XY significa, y qué no es un status check de GitHub.
Long vs short vs porcelain
El man (OUTPUT): el long es para humanos. -s / --short es compacto. --porcelain[=<version>] es para scripts: estable entre versiones de Git y sin color.status ni status.relativePaths. Default del porcelain: v1.
git status -sb # humano: short + rama/upstream
git status --porcelain=v1 # script: LF, paths desde la raíz del repo
git status --porcelain=v1 -z # script: NUL; sin quoting C
-z implica porcelain v1 si no hay otro formato. En -z, el -> de un rename desaparece, el orden es to luego from, y los nombres no se entrecomillan. Un parser que parte por espacio sobre -s se rompe con un path con espacio.
-b antepone ## <branch> <tracking>. --ahead-behind (default true) pone conteos vs upstream. Eso no es pull: status no trae objetos.

Qué es XY
En short/porcelain v1, cada path es <xy> <path> o <xy> <orig> -> <path>. Fuera de conflicto: X = index, Y = worktree. Untracked: ??. Ignored solo con --ignored: !!.
| XY | Significado (man, tabla Short Format) |
|---|---|
M | worktree cambió; index intacto |
M | index actualizado; worktree igual al index |
MM | index y worktree distintos del HEAD y entre sí |
A | añadido al index |
D | borrado del index |
?? | untracked |
UU | unmerged, ambos modificados |
AA | unmerged, ambos añadidos |
DU / UD | unmerged, borrado por un lado |
U en cualquier lado = no resuelto. Un agente no commitea ni hace add masivo sobre U. Restaurar unstaged es restore, no adivinar el path desde el long.
Submódulos (short, no porcelain v1): M HEAD distinto, m contenido modificado, ? untracked dentro. Porcelain v1 reporta el submódulo sucio como M, no m/?.
Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| ¿Hay sucio? (humano) | git status -sb | git status long al LLM |
| Parsear paths | git status --porcelain=v1 -z | partir -s por espacios |
| ¿Untracked? | porcelain; ?? | -uno y luego “el árbol está limpio” |
| ¿Ignored listado? | --ignored | asumir que !! sale siempre |
| CI de un PR | checks de GitHub | confundir con git status |
Prohibido en autónomo:
- Volcar
git status/-v/-vval prompt.-vesgit diff --cached; dos veces, también el unstaged. Es el parche entero. - Parsear color. Porcelain apaga
color.status. - Tratar paths del long como relativos a la raíz. El man: el long es relativo al cwd; porcelain v1 es relativo a la raíz del repo.
git add .“porque status era largo”. Paths salen de porcelain, no de un glob.-uallen un monorepo para “ver todo”. Default-unormallista el directorio untracked, no cada archivo.status.showUntrackedFilescambia el default; un agente pasa-uexplícito.- Confundir status checks de un PR (GitHub Docs, HTTP 200, Status checks: commits
pending/success/failure/errorvía API/gh) con el working tree. Un check rojo no se arregla congit status.
-- + pathspecs. Sin --, un path que coincide con un ref es ref.
Receta (60 segundos)
Solo en un worktree propio:
git status -sb
git status --porcelain=v1 -z | tr '\0' '\n'
Si sale ??, decide path a path (add); no clean -fdx. Si hay U, para: conflicto, no commit. Integrar remoto es pull --ff-only tras un fetch, no un status.

Scripts y seguridad
Porcelain v1 no respeta status.relativePaths. Un agente que corre status desde src/ y luego git add foo.ts añade src/foo.ts mal si copió el path del long. Copia del porcelain.
-z es el único formato seguro con espacios, quotes y renames. Un split por LF + espacio miente en R old -> new file.ts.
--ignored=matching lista paths que matchean ignore, no el contenido de un dir ignored. No uses eso para borrar: clean -n primero.
gitignore no es sandbox (sandboxing): status no lista ignored salvo --ignored, pero el agente sí puede leerlos del disco.
Checklist
- Worktree propio. Humano:
git status -sb. Script:--porcelain=v1 -z. - XY: X index, Y worktree.
??untracked.U= parar. - Cero long /
-v/-vval LLM. Cero color. - Add por paths del porcelain. Cero
git add .. - Status checks de GitHub ≠
git status. - Cero push a
main. PR con gh.
FAQ
¿git status es estable para un parser? No el long. El man: porcelain v1 no cambia por versión ni por config de color/paths.
¿-s y --porcelain son lo mismo? Casi el XY; porcelain apaga color, fija paths a la raíz, y -z cambia quoting y renames.
¿Por qué no veo ignored? El man: ignored no se listan sin --ignored. !! no sale en el default.
¿Un check rojo en el PR es git status sucio? No. GitHub Docs (Status checks): es CI sobre el commit. El working tree local puede estar limpio.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. Status no es sandbox ni clean.
Verificado 2026-09-03 contra git-status(1) (Git 2.50.1 / Apple Git-155), git-scm.com/docs/git-status (HTTP 200) y GitHub Docs “Status checks” (HTTP 200, /pull-requests/reference/status-checks).
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

Reusable workflows: workflow_call, no copies el YAML entre repos

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

git log para coding agents: A..B, A...B y no volcar historia
