Guía9 min

git show-ref para coding agents: refs locales, no el dump al LLM

Resumen

git show-ref lista refs locales. Default: heads, tags y remotes; HEAD solo con --head. --verify pide el path exacto. --exists sale 0/2/1. Un agente no vuelca el repo, no lee .git/refs, no usa --exclude-existing. Git 2.50.1.

GitHub
Las refs locales se listan con SHA; HEAD no aparece salvo --head

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 show-ref no habla con el remoto. El man (git-show-ref(1); git-scm.com/docs/git-show-ref HTTP 200, last-modified 2026-08-31; pie del man local Git 2.54.0, 2026-04-19; binario Git 2.50.1 / Apple Git-155) lista referencias del clone con el object ID asociado. HEAD, index y working tree no se mueven. Default: tags, heads y remote refs. HEAD no sale salvo --head.

Eso no es ls-remote (refs del remoto, cero objetos) ni rev-parse (resolver un nombre a SHA). El man anima a usarlo en vez de leer .git/refs/* o packed-refs.

GitHub Docs (REST API endpoints for Git references, HTTP 200 2026-09-04): una ref es un archivo con un SHA. List matching references pide Contents read. Create / Update / Delete a reference piden Contents write. Ninguno sustituye el listado local.

Contrato: filtrar, --verify con path completo, --exists para 0/2, cero dump.

Lista local, no el remoto

OUTPUT del man: SHA, un espacio, el nombre de la ref, newline. Verificado 2026-09-04: SHA de 40 hex y un espacio, no TAB (TAB es ls-remote).

PreguntaComandoQué imprime
¿Qué refs hay?git show-refheads, tags, remotes; sin HEAD
¿Y HEAD?git show-ref --headHEAD primero, luego el resto
¿Solo ramas?git show-ref --branchesrefs/heads/*
¿Solo tags?git show-ref --tagsrefs/tags/*
¿Existe este path?git show-ref --verify --quiet -- refs/heads/mainnada; exit 0 / 1
¿Existe sin resolver?git show-ref --exists refs/heads/mainnada; exit 0 / 2 / 1

Verificado 2026-09-04 (Git 2.50.1 / Apple Git-155):

  • Default no incluye HEAD. --head sí.
  • --branches y --tags se combinan: heads y tags, sin refs/remotes.
  • Patrón main: match por parte completa al final del nombre (refs/heads/main). mymain no entra. Sin match: stdout vacío, 1.
  • Repo recién init sin commits: 1 (también con --head).
  • --verify refs/heads/main: SHA + ref, 0. --verify main: not a valid ref, 128 — el man pide el path exacto.
  • --verify --quiet refs/heads/main: silencio, 0. Missing con --quiet: silencio, 1. Missing sin --quiet: not a valid ref, 128.
  • --exists refs/heads/main: silencio, 0. Missing: reference does not exist, 2. main corto: 2. Sin args / dos args: requires a reference / exactly one, 128. --exists HEAD: 0.
  • -d --tags en un tag anotado: la ref del tag y ref^{} con el objeto peeled. Lightweight: una línea, sin ^{}.
  • --hash --branches: solo el SHA, sin el nombre. Con --dereference, el peeled sigue saliendo como ref^{}.
  • --exclude-existing: stdin filter. refs/heads/main (existe) se traga; refs/heads/ghost se imprime. Exit 0.

El man: --exists no comprueba que la ref resuelva a un objeto. Comprueba que el nombre está. Para “¿este SHA es un objeto?” usa cat-file -e.

Default lista heads/tags/remotes; HEAD solo con --head

Lo que el agente sí / no corre

QuieroComandoTrampa
¿Está main local?git show-ref --verify --quiet -- refs/heads/maingit show-ref main al LLM
¿Existe el nombre?git show-ref --exists refs/heads/featleer .git/refs/heads/feat
¿HEAD apunta a qué SHA?git show-ref --verify -- HEADcat .git/HEAD
Refs del remoto sin fetchls-remote originshow-ref creyendo que habla con GitHub

Prohibido en autónomo:

  • Volcar git show-ref / --head / --dereference de un clone real al LLM. Un repo con decenas de origin/* es ruido. Filtra --branches, --tags o un patrón, o pregunta --verify / --exists de una ref.
  • --verify con nombre corto (main, v1). El man: path exacto. Verificado: 128.
  • Tratar el 128 de --verify sin --quiet como “no existe”. Missing con --quiet es 1. 128 también sale si el string ni siquiera es un ref path.
  • --exists con nombre corto salvo HEAD. Verificado: main2, igual que una rama ausente. No es un fuzzy match.
  • --hash cuando el ticket pregunta cuál ref. Pierdes el nombre; dos ramas en el mismo SHA se ven iguales.
  • --exclude-existing como REPL. Lee stdin; no es “lista lo que falta en origin”.
  • Leer .git/refs/* o packed-refs. El man: Use of this utility is encouraged in favor of directly accessing files under the .git directory. Packed-refs miente si solo listaste el directorio.
  • Create / Update / Delete a reference en GitHub. Contents write. show-ref es local y de lectura.

--heads es sinónimo deprecado de --branches. El man: may be removed. Un agente usa --branches.

Receta (60 segundos)

Solo en un worktree propio:

git status -sb
git show-ref --verify --quiet -- refs/heads/main; echo $?
git show-ref --exists refs/heads/main; echo $?
git show-ref --branches

Si el ticket es “¿existe esta rama local?”: --verify --quiet -- refs/heads/$name (1 = no) o --exists refs/heads/$name (2 = no). No parsees fatal.

Si el ticket es “¿qué hay en github.com?”: ls-remote, no show-ref.

Cero dump. Cero .git/refs. Cero REST write.

--exists sale 0 o 2; --verify sin --quiet puede ser 128

Local vs remoto vs UI

show-ref lee este clone. ls-remote pregunta al remoto sin bajar objetos. fetch actualiza origin/* y después show-ref puede ver esas refs locales.

GitHub List matching references es el remoto. No es este working tree. Un agente que quiere “¿está feat en este checkout?” corre show-ref; el que quiere “¿está en origin?” corre ls-remote.

tag crea refs; show-ref --tags las lista. branch crea heads; show-ref --branches las lista. Ninguno de esos comandos es el listado.

Checklist

  • Worktree propio. git status -sb. Un modo por invocación.
  • Existencia: --verify --quiet -- refs/heads/… o --exists refs/heads/….
  • Cero dump de show-ref sin filtro. Cero --hash si hace falta el nombre.
  • Cero --verify main. Cero --heads. Cero .git/refs.
  • Remoto = ls-remote. Resolver SHA = rev-parse.
  • Cero Create/Update/Delete a reference.

FAQ

¿show-ref incluye HEAD? No, salvo --head. Verificado. cat .git/HEAD no es el sustituto.

¿Por qué --verify main es 128 y --exists main es 2? --verify exige el path completo; un string que no lo es → not a valid ref, 128. --exists no resuelve alias: main no es una ref, sale 2 como missing. Usa refs/heads/main.

¿El 1 del man es el missing de --verify? El man: sin match → 1; en verificación, además imprime error. Verificado: missing con --quiet1; sin --quiet128. Un agente siempre pone --quiet si va a ramificar por el código.

El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. show-ref no es ls-remote: lista este clone; no pregunta al remoto.