git hash-object para coding agents: SHA del contenido, no un commit
Resumen
git hash-object calcula el OID de un blob. Sin -w no escribe. -w mete el objeto suelto: no mueve HEAD ni el index. Un agente no usa --literally, no fabrica commit/tree, no llama Create a blob. 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 hash-object no crea un commit. El man (git-hash-object(1); git-scm.com/docs/git-hash-object HTTP 200, last-modified 2026-08-31; last updated in 2.43.0, 2.43.1 → 2.55.0 sin cambios; pie del man local Git 2.54.0, 2026-04-19; binario Git 2.50.1 / Apple Git-155) calcula el object ID de un contenido con un tipo (default blob) y, si pasas -w, lo escribe al object database. El file puede estar fuera del work tree. Imprime el SHA a stdout. HEAD, index y working tree no se mueven.
Sin -w no hay objeto suelto. Verificado 2026-09-04: printf 'hello\n' | git hash-object --stdin → ce013625030ba8dba906f756967f9e9ca394464a; find .git/objects -type f → 0. Con -w, el mismo SHA queda como loose object; cat-file -t → blob, -s → 6. git status -sb sigue mostrando ??; git ls-files vacío. Eso no es add.
GitHub Docs (REST API endpoints for Git blobs, HTTP 200 2026-09-04, API version 2026-03-10): Create a blob pide Contents write y responde 201 con sha. Get a blob pide Contents read, tope 100 MB, JSON siempre Base64. Ninguno mueve una rama.
Contrato: hashear un path, cero -w, cero --literally, cero REST de escritura.
SHA no es commit
| Pregunta | Comando | Qué imprime |
|---|---|---|
| ¿Qué SHA tendría este file? | git hash-object -- path | 40 hex; no escribe |
| ¿Y si lo meto al store? | git hash-object -w -- path | el mismo SHA; objeto suelto |
| ¿Stdin? | git hash-object --stdin | SHA del payload |
| ¿Vacío? | git hash-object --stdin </dev/null | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 |
| ¿Tipo inválido? | git hash-object -t nope path | invalid object type, 128 |
Verificado 2026-09-04 (Git 2.50.1 / Apple Git-155):
- Default
-t=blob.-t blobexplícito da el mismo SHA que sin-t. -t commit/tree/tagconhello\n: object fails fsck / refusing to create malformed object, 128.- File que no existe: could not open … No such file or directory, 128.
--stdin-pathsconnope.txt: el mismo 128.--pathjunto a--no-filters: Can't use --path with --no-filters, 129.-h: usage, 129.- Dos paths: dos SHA, uno por línea, exit 0.
-wcon repo sin commits: HEAD sigue inexistente. El objeto vive; la rama no.
El man: --path no cambia el hash por el pathname; elige filtros (gitattributes, conversión EOL) como si el file viviera ahí. --no-filters hashea bytes crudos. Con --stdin, --no-filters va implícito salvo que pases --path.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| SHA de este path | git hash-object -- path | git hash-object -w “por si acaso” |
| ¿Coincide con HEAD? | hash-object -- path vs rev-parse HEAD:path | asumir que el SHA es el commit |
| Varios files | git hash-object -- a b | --stdin-paths con globs del shell |
| Inspeccionar un SHA ya en el store | cat-file -t / -s / -e | -p del blob al LLM |
Prohibido en autónomo:
-w. El man: Actually write the object into the object database. No actualiza index ni refs. Un objeto suelto huérfano sobrevive agcun tiempo y ensucia el clone. Si el ticket pide “commitear este file”, el camino es add + commit, nohash-object -w.--literally. El man: permite a--stdinhashear cualquier basura que no pasaríagit-fsck. Verificado:printf 'not-a-commit' | git hash-object -t commit --stdin→ 128; con--literally→ SHA1ee52eb1e0a77f156810678e1c8cc3f33cca9da3, exit 0. Sirve para stress-test de Git, no para un agente.-t commit/tree/tagsin un payload válido y un humano. El defaultblobcubre el 99 % de “hashea este file”.- Mezclar
--stdincon paths. Verificado:git hash-object --stdin f.txtcon stdin vacío imprime el blob vacío y el SHA del file. Un modo por invocación. - Encadenar el SHA a
git update-index --cacheinfo. Ese plumbing mete el blob al index sin pasar por el working tree. Un agente no lo corre. - Create a blob (
POST /repos/{owner}/{repo}/git/blobs). GitHub Docs: Contents write,contentobligatorio,encodingutf-8obase64(defaultutf-8), 201. No actualiza la rama. Un agente de lectura no lo llama. - Pegar secretos a
--stdin. El SHA no oculta el contenido: cualquiera con el objeto lo recupera con cat-file.
--stdin-paths: un pathname por línea, no el contenido. Verificado: pathname inexistente → 128, igual que un <file> faltante.
Receta (60 segundos)
Solo en un worktree propio:
git status -sb
git hash-object -- src/lib/posts.ts
git rev-parse --verify --quiet HEAD:src/lib/posts.ts
Si los SHA coinciden, el working tree de ese path es el blob de HEAD. Si rev-parse sale 1, el path no está en el tree; el hash-object igual funciona: el file puede estar fuera del work tree.
Para un payload chico por stdin (test, no secretos):
printf 'hello\n' | git hash-object --stdin
Cero -w. Cero --literally. Cero -t distinto de blob.

UI de GitHub vs clone local
Create a blob calcula el SHA-1 del contenido y lo guarda en la base Git del remoto. Get a blob lee hasta 100 MB. Ninguno sustituye el clone. Un agente que quiere el SHA de este file corre hash-object; el que quiere el blob de github.com usa Get a blob con Contents read, no inventa 40 hex ni hace POST.
hash-object no es cat-file: uno produce (o escribiría) el objeto; el otro inspecciona uno que ya existe. Tampoco es show.
Checklist
- Worktree propio.
git status -sb. Un modo por invocación. - Default:
git hash-object -- path. Cero-w. - Comparar con
HEAD:pathvía rev-parse, no asumir que el SHA es la rama. - Cero
--literally, cero-t commit|tree|tag, cero--stdin+ files. - Cero
update-index --cacheinfo. Cero Create a blob. - Inspección del objeto ya escrito: cat-file
-t/-s/-e, no dump.
FAQ
¿hash-object -w es un commit? No. Escribe un objeto suelto. Sin add no entra al index; sin commit no hay snapshot.
¿Por qué -t commit con texto suelto falla? El man lista commit, tree, blob, tag. Git corre fsck al crear. Un commit sin línea tree es basura: 128, salvo --literally.
¿Puedo hashear un file fuera del repo? Sí. El man lo dice. El SHA sale; -w lo mete a este object database, no al otro directorio.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. hash-object no es cat-file: calcula el SHA; no pretty-printa el objeto.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

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

git for-each-ref para coding agents: refs locales, cero update-ref

git ls-remote para coding agents: refs del remoto, cero fetch
