Guía9 min

git rev-list para coding agents: SHA y --count, no el dump al LLM

Resumen

git rev-list es el plumbing de log: recorre parent links y emite SHA. Default: un objeto por línea, sin asunto. Un agente acota -n o --count. Cero --objects/--header/--all/--pretty al contexto. Git 2.50.1.

GitHub
El walk de parent links emite SHA; HEAD y el working tree no se mueven

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 rev-list no formatea un diario. El man (git-rev-list(1); git-scm.com/docs/git-rev-list HTTP 200, last-modified 2026-08-31; last updated in 2.55.0, 2026-06-29; binario Git 2.50.1 / Apple Git-155) lista commits alcanzables siguiendo parent links desde los commits dados y resta los alcanzables desde los que van con ^. Default: orden cronológico inverso. HEAD, index y working tree no se mueven.

Eso no es log (porcelain: asunto, autor, parche). rev-list es el mismo walk; el default no imprime el mensaje. Tampoco es show (un objeto) ni rev-parse (un nombre → SHA).

GitHub Docs (REST API endpoints for commits, HTTP 200 2026-09-04, API version 2026-03-10): List commits pide Contents read (público sin auth). Query sha: SHA o rama desde la que listar; default = rama default del repo. Eso habla con GitHub. rev-list lee el object store local.

Contrato: rango + -n o --count, cero dump de objetos, cero --pretty al LLM.

Conjuntos, no un diff

El man (DESCRIPTION): git rev-list foo bar ^baz = alcanzables desde foo o bar, menos los de baz.

FormaEquivale aQué ves
A..BB ^Aalcanzables desde B, no desde A
A...BA B --not $(git merge-base --all A B)diferencia simétrica
origin..HEADHEAD ^originlo que HEAD tiene y origin no

A..B en rev-list es rango de revisiones. En git diff, A..B compara dos árboles. Un agente no copia la notación.

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

  • Sin commit-ish: usage, 129. --count sin commit: 129.
  • Ref inexistente: ambiguous argument … unknown revision, 128.
  • Default -n 1 HEAD: 40 hex, sin asunto. log --oneline -n 1 sí lleva el subject.
  • --count HEAD: un entero (419 en este clone). --count HEAD..HEAD: 0, 0.
  • --count --max-count=3 HEAD: 3. -n recorta antes de contar.
  • --quiet -n 1 HEAD y --quiet HEAD..HEAD: ambos 0, stdout vacío. --quiet no es “¿hay commits?”. Pregunta --count.
  • --max-count=0: silencio, 0. --max-count=-1 en este binario no corta (listó igual que sin tope). No uses -1 como “todo”.
  • --all --count (776) ≠ --count HEAD (419). --all finge que todas las refs de refs/ más HEAD están en argv.
  • --objects -n 1 HEAD: el commit y tree/blobs del snapshot (2575 líneas aquí). --count --objects --max-count=1: 2575, no 1.
  • --filter=blob:none sin --objects: object filtering requires --objects, 128.
  • --header -n 1: raw del commit (tree/parent/author, 1232 bytes aquí).
  • --disk-usage HEAD: bytes (202874). --disk-usage=human: 198.12 KiB.
  • --bisect / --bisect-vars: el punto medio del walk. Lo usa bisect. Un agente one-shot no lo dispara.
  • --oneline existe en 2.50.1 y pega el subject. Sigue siendo un dump si olvidas -n.

Default: un SHA por línea; --count es el entero; --objects no

Lo que el agente sí / no corre

QuieroComandoTrampa
¿Cuántos commits hay en el topic?git rev-list --count origin/main..HEADgit log sin -n
¿Hay commits en el rango?git rev-list --count A..B0 / N--quiet (siempre 0)
Tres SHA, nada másgit rev-list -n 3 HEAD--pretty / --header
SHA de HEADrev-parse --verify --quiet HEADrev-list -n 1 “por si acaso”
Historia con asuntolog --oneline -n 20 A..Brev-list --pretty al LLM

Prohibido en autónomo:

  • git rev-list HEAD / --all / --branches / --objects sin -n ni --count. Este clone: 419 SHA con HEAD, 776 con --all, miles con --objects.
  • --pretty / --header / --parents / --children / --timestamp hacia el contexto. Son el commit crudo o el walk anotado. Para un objeto, show --stat / -s.
  • --oneline sin -n. El flag existe; el dump también.
  • Tratar --quiet como booleano. Verificado: rango vacío y rango con commits salen 0.
  • --filter=* sin --objects. 128.
  • --bisect / --bisect-vars / --bisect-all fuera de un bisect vivo. --bisect-vars imprime bisect_rev=… para eval en shell. Un agente no evalúa eso.
  • --stdin como REPL. El man: revisiones por stdin; mezclado con --not en argv no se pisan entre sí.
  • List commits / Get a commit / Compare two commits cuando el dato ya está en el clone. Contents read. No sustituyen --count local. Compare two commits no es A..B de rev-list.

-- antes de paths. git rev-list --count HEAD -- src/lib/posts.ts no se confunde si existe una rama src.

--objects enumera blobs del snapshot; un agente pide --count del rango

Receta (60 segundos)

Solo en un worktree propio:

git status -sb
git rev-list --count origin/main..HEAD
git rev-list -n 20 origin/main..HEAD

Si el ticket pide “¿cuántos?”: --count, un entero. Si pide “cuáles”: -n y SHA. Cero --objects. Cero --pretty. Para el asunto, log --oneline -n.

Checklist

  • Worktree propio. git status -sb.
  • Siempre un commit-ish o un rango. Sin args → 129.
  • --count para cardinalidad. -n / --max-count para listar SHA.
  • Cero --all / --objects / --header / --pretty / --bisect autónomo.
  • --quiet no decide. Ref inexistente → 128, no “cero commits”.
  • Historia con mensaje = log. Un SHA = rev-parse.

FAQ

¿rev-list cambia HEAD? No. Verificado: git status -sb sigue igual después de --count y de -n 3.

¿Por qué no git log --oneline | wc -l? log es porcelain. --count es el entero del walk, sin pretty ni pager. wc cuenta líneas del asunto; un mensaje multilínea lo infla.

¿--count con --objects cuenta commits? No. Verificado: --count --objects --max-count=1 HEAD → 2575 (commit + trees + blobs del tope), no 1. Para “N commits”, --count sin --objects.

El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. rev-list no es log: mismo conjunto; default sin mensaje.