git check-ignore para coding agents: regla ganadora, no adivinar
Resumen
git check-ignore dice si un pathname cae en las reglas exclude. Por default no muestra tracked. -v imprime fuente, línea y patrón. -q solo admite un path. Una negación con ! sale 0 con -v y 1 sin él: coincidir no es estar ignorado. Un agente nombra el path y no adivina .gitignore. 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 check-ignore no es un sandbox ni un linter de .gitignore. El man (git-check-ignore(1), Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-check-ignore HTTP 200, last-modified 2026-08-31) toma pathnames por argv o --stdin y, si el exclude los cubre, imprime el path. Default: tracked no aparecen, porque no están sujetos a exclude. --no-index salta el index.
GitHub Docs (Ignoring files, HTTP 200 2026-09-04) explica dónde poner reglas (.gitignore de repo, exclude global, .git/info/exclude). No sustituye este comando. Un agente que “lee el .gitignore a ojo” se equivoca con !, con tracked y con info/exclude.
Esta guía no sustituye gitignore (precedencia y disco del agente) ni ls-files (-o -i). El contrato: qué forma corre un agente, qué exit code significa, y por qué -v sobre una negación no es “está ignorado”.
Tres salidas, un pathname
| Pregunta | Comando | Exit si aplica |
|---|---|---|
| ¿Este untracked está ignorado? | git check-ignore -v -- path | 0 imprime fuente:línea:patrón + tab + path |
| ¿Sí / no, un path? | git check-ignore -q -- path | 0 ignorado, 1 no |
| ¿Por qué un tracked “debería” ignorarse? | git check-ignore -v --no-index -- path | 0 si el patrón habría ganado |
¿Llegó algún patrón, incluso !? | git check-ignore -v -- path | 0 si coincidió; lee el patrón |
| Stream de paths | git check-ignore -v -z --stdin | 0 si alguno ignorado |
El man (OUTPUT): sin -v, solo paths excluidos, uno por línea. Sin match: nada para ese path. Con -v: <source> <COLON> <linenum> <COLON> <pattern> <HT> <pathname>. source es absoluto si es core.excludesFile; relativo a la raíz si es .gitignore o .git/info/exclude. El ! y el / final se conservan.
Exit (man): 0 uno o más paths ignorados; 1 ninguno; 128 fatal. Verificado 2026-09-04: sin path → no path specified, 128. -q con dos paths → --quiet is only valid with a single pathname, 128. -z sin --stdin → -z only makes sense with --stdin, 128. -n sin -v → --non-matching is only valid with --verbose, 128.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
¿.env cae en exclude? | git check-ignore -v -- .env | Abrir .gitignore y “parece que sí” |
| Sí/no de un path | git check-ignore -q -- .env | -q de una lista |
| Tracked que “no debería estar” | --no-index -v -- path | Default (exit 1, silencioso) |
| Lote | -v -z --stdin | -z en argv |
| No match explícito | -v -n -- path | -n solo |
Prohibido en autónomo:
- Inferir ignore leyendo
.gitignore. El man manda a gitignore(5) para precedencia.info/excludeycore.excludesFileno están en el working tree. - Tratar exit 0 de
-vcomo “ignorado” si el patrón empieza por!. El man: coincidir un!significa que el path NO está excluido. Verificado:!keep.envcon-vimprime el patrón y sale 0; sin-vno imprime y sale 1;-qsale 1. -qcon más de un pathname. Fatal 128.-zsin--stdin. En 2.50.1 es fatal, no “output NUL”.--no-index“por si acaso” en untracked. El man lo reserva para debug de tracked (git add ./git add -f) o para diseñar negaciones. Default ya cubre untracked.- Usar el comando como deny-list del runtime. gitignore no es sandbox: un
.envignorado sigue en disco. - Encadenar a add
-fporque “el patrón ya está”.-fsalta exclude; es incidente. - Dump de
check-ignore -v -nsobre el árbol entero. Nombra el path del ticket.
-n / --non-matching (solo con -v): paths sin patrón salen con campos vacíos (::\tpath). El man: sin esto, un proceso largo con --stdin no distingue “aún no hay output” de “no match”. Un agente one-shot nombra un path; no necesita el stream.
Receta (60 segundos)
Solo en un worktree propio:
git status -sb
git check-ignore -v -- .env
git check-ignore -q -- .env; echo $?
Si el humano dice “este file ya está en Git y aún así debería ignorarse”:
git ls-files --error-unmatch -- path
git check-ignore -v --no-index -- path
Default sobre tracked: silencio, exit 1. Verificado: a.ts tracked + patrón posterior a.ts en .gitignore → default exit 1; --no-index → .gitignore:5:a.ts y exit 0. Para sacarlo del index sin borrar disco: rm --cached, no este comando.
Untracked que sí ignorar: no hace falta clean para “comprobar”. Untracked a borrar: clean -n primero.

UI de GitHub vs clone local
GitHub Docs (Ignoring files): .gitignore en la raíz se commitea para compartirlo. Exclude global (core.excludesFile) y .git/info/exclude son de esa máquina. check-ignore -v te dice cuál ganó; la UI de GitHub no corre este comando sobre tu worktree.
Un patrón de directorio con / final casa el dir y sus hijos. Verificado: node_modules/ → node_modules y node_modules/pkg.js, misma línea. Un agente que pregunta solo por el dir no asume el contenido.
--stdin lee un path por línea; con -z, NUL. Buffering según GIT_FLUSH (git(1)). No cuelgues el pipe.
Verificado 2026-09-04 en esta máquina (Git 2.50.1 / Apple Git-155): .env con patrón .env → .gitignore:2:.env exit 0. *.log → debug.log. scratch.tmp vía .git/info/exclude. Path inexistente → exit 1; con -v -n → ::\tdoes-not-exist. Varios paths: si uno está ignorado, exit 0 y solo se imprimen los que aplican.
Checklist
- Worktree propio.
git status -sb. Path nombrado, no el repo entero. -
-vpara ver fuente:línea:patrón.-qsolo con un path. - Tracked: default no aplica.
--no-indexsi el ticket es “por qué se trackeó”. -
!en-v= no ignorado. Confirma con-q(exit 1). - Cero
-zsin--stdin, cero-nsin-v, cero add-f. - Ignore ≠ sandbox. El agente igual puede leer el file.
FAQ
¿check-ignore es lo mismo que ls-files -o -i? No. ls-files lista conjuntos. Este comando explica un path. -i en ls-files exige -c/-o y un --exclude*.
¿Por qué un tracked no sale? El man: no están sujetos a exclude. GitHub Docs: un file ya commiteado sigue en el árbol aunque agregues el patrón. --no-index debuggea el patrón; no destagea.
¿Exit 0 con -v y el path “se queda”? Patrón !. Coincidir ≠ excluido. -q y la forma sin -v siguen el “está ignorado”.
¿Puedo parsear -v por espacios? No. Separadores: dos : y un tab. Paths con espacio. Para lote: -z --stdin.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. check-ignore no es status: no resume XY; responde un pathname contra exclude.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git cat-file para coding agents: tipo y talla, no el blob al LLM

git ls-tree para coding agents: tree object, no el disco

git submodule para coding agents: gitlink 160000, no un clone extra
