git grep para coding agents: tracked, pathspec y techo de líneas
Resumen
git grep busca un patrón en tracked del work tree, en el index o en un tree. Un agente usa -n -F, pathspec y -m; nunca -O, patrón vacío ni --untracked de ignorados. 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 grep no es grep -r ni la búsqueda de GitHub. El man (git-grep(1), Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-grep HTTP 200, last-modified 2026-08-31) busca patrones en tracked del work tree, blobs del index (--cached) o blobs de <tree>.... Sin tree ni --cached: working tree tracked. HEAD, index y working tree no se mueven.
GitHub Docs (Searching code (legacy), HTTP 200 2026-09-04): la UI/API indexa solo la default branch, files < 384 KB, repos con < 500 000 files. No es git grep. Un agente que quiere “dónde está este símbolo en este worktree” corre git grep; el que quiere “en GitHub.com” usa la UI o gh, no este comando.
Esta guía no sustituye status (XY del árbol) ni diff (parche). El contrato: qué forma corre un agente, qué flags fuerzan, y por qué el default no es un dump al LLM.
Tres superficies, un comando
| Superficie | Flag / args | Ve unstaged | Ve untracked |
|---|---|---|---|
| Work tree tracked | default | sí | no |
| Index | --cached | no | no |
Tree (HEAD, SHA) | <tree> | no | no |
| Untracked | --untracked | sí | untracked no ignorados |
| Ignorados | --untracked --no-exclude-standard | sí | también .gitignore |
| Fuera de Git | --no-index | n/a | el cwd; incompatible con --cached/--untracked |
Verificado 2026-09-04: un .env en .gitignore no sale con git grep TOKEN (exit 1) ni con --untracked (exit 1). Sale con --untracked --no-exclude-standard. Unstaged extra sí sale en default; --cached y HEAD no. Pathspec inexistente → exit 1. Tree inventado con -- → unable to resolve revision, exit 128.
El man: una cadena vacía como patrón casa todas las líneas. Verificado: git grep -e '' -- src/a.ts imprime el file entero.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| ¿Dónde está el símbolo? | git grep -n -F -e foo -- src/ | git grep foo del repo entero al LLM |
| ¿Qué files? | git grep -l -F -e foo -- src/ | -c de todo el árbol “para ver” |
| ¿Hay match? | git grep -q -F -e foo -- src/ | -O “para abrir el file” |
Literal con - | git grep -F -e --flag -- src/ | patrón suelto que Git toma por opción |
| Index, no disco | git grep --cached -n -F -e foo -- src/ | default (ve unstaged) |
| Tree commiteado | git grep -n -F -e foo HEAD -- src/ | HEAD + path sin -- |
Prohibido en autónomo:
-O/--open-files-in-pager. El man abre los files en el pager (less/vi). Un agente no interactúa con pager. El man:--threadsse ignora si hay-O.- Patrón vacío (
-e ''). El man: matches all lines. Dump del file. --untracked --no-exclude-standard. El man: ignora.gitignore. Verificado: saca.env. gitignore no es sandbox; este flag lo empeora.-a/--textsobre binarios. Default: Binary file X matches.-aimprime bytes con NUL al prompt.-Ilos salta (exit 1 si solo había binario).-C/-A/-B/-W/-panchos “por contexto”. El man imprime hunks;-Wla función entera. Un agente acota con-my pathspec, no con un radio de 50.-Psi el Git no se compiló con PCRE. El man: providing this option will cause it to die. Aquí 2.50.1 sí corre-P; no lo asumas en el VPS.- Varios
<tree>a ciegas. Cada tree prefixea output (HEAD:path). --no-indexdentro del repo “porque grep del sistema”. El man: ignoring that the current directory is managed by Git. Mezcla untracked e ignorados según--exclude-standard.- Pager. Fija
GIT_PAGER=cato--no-pager. - Sustituir esto por la búsqueda de GitHub. Legacy code search no ve tu branch de feature.
Exit: 0 hay match, 1 no hay, 128 revisión inválida. -q no imprime; 0/1 igual. -m 0 sale ya con no-cero (verificado: exit 1). -m -1 = ilimitado (el default).
Receta (60 segundos)
Solo en un worktree propio:
git grep -n -F --max-count=20 -e "$pat" -- src/
git grep -l -F -e "$pat" -- src/
Si el humano pidió un file:
git grep -n -F -e "$pat" -- "$path"
Si solo hace falta sí/no:
git grep -q -F -e "$pat" -- src/
-e siempre si el patrón puede empezar por -. -- delante de pathspec (gitglossary(7), HTTP 200). Globs del man: git grep 'time_t' -- '*.[ch]'.

grep vs GitHub vs grep(1)
| Pregunta | Comando | No |
|---|---|---|
| ¿En este clone, este path? | git grep -n -F -e pat -- path | grep -r del cwd |
| ¿En el commit? | git grep -n -F -e pat HEAD -- path | default (unstaged) |
| ¿En GitHub default branch? | UI / Code Search | git grep del feature |
| ¿Untracked a propósito? | --untracked sin --no-exclude-standard | volcar .env |
Booleanos del man: --or es default; --and tiene más precedencia; todos los patrones van con -e. --all-match: files que tienen ambas expresiones, no la misma línea. Verificado: git grep -e hello --and -e world -- src/a.ts casa la línea que tiene las dos.
--full-name: paths desde la raíz aunque el cwd sea un subdir. Un agente que parsea lo deja puesto.
Checklist
- Worktree propio. Patrón del ticket, no “buscar por si acaso”.
-
-n -F -e+ pathspec detrás de--.-lo-msi el hit-set puede ser grande. - Cero
-O, patrón vacío,-a,--untracked --no-exclude-standard. - Cero pager. Cero GitHub search como si fuera el worktree.
- 1 = no hay match (para). 128 = tree malo (para). No reintentes con otro SHA.
FAQ
¿git grep foo sin pathspec? El man recorre tracked del work tree. En un monorepo es un dump. Nombra src/, *.ts o el file del ticket.
¿--cached vs default? Default ve el disco (incluye unstaged). --cached ve el index. Para “¿ya está staged?” usa --cached; para “¿lo estoy editando?” el default.
¿Por qué no salió .env? Está ignorado. Default y --untracked lo respetan. No “arregles” con --no-exclude-standard.
¿-E o -F? -F si el símbolo es literal (useStore). -E si el humano pidió regex POSIX. Default del man: basic regexp (-G), no extended.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. git grep no es log: busca contenido, no historia.
Verificado 2026-09-04 contra git-grep(1) (Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-grep HTTP 200, last-modified 2026-08-31), gitglossary(7) pathspec (HTTP 200) y GitHub Docs “Searching code (legacy)” (HTTP 200; default branch, 384 KB). En esta máquina: no match exit 1; tree inválido con -- exit 128; .env ignorado salvo --untracked --no-exclude-standard; patrón vacío imprime todas las líneas; binario default no vuelca bytes; -a sí; -m 0 exit 1.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git describe para coding agents: nombre legible, no un Release

git merge-base para coding agents: ancestro común, no folklore

git check-ignore para coding agents: regla ganadora, no adivinar
