git unpack-objects para coding agents: stdin a loose, no explode el object store
Resumen
git unpack-objects lee un .pack por stdin y escribe objetos loose. Diagnóstico: -n -q. Cero unpack a pelo. Cero path como argumento. No es pack-objects ni verify-pack ni repack. 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 unpack-objects expande un packed archive a objetos loose: lee un .pack desde stdin, escribe un archivo por objeto en el object database y no crea .idx. El man (git-unpack-objects(1); git-scm.com/docs/git-unpack-objects HTTP 200, last-modified 2026-08-31; pie del man local Git 2.50.1.428.g0e8243, 2025-07-22; binario Git 2.50.1 / Apple Git-155): Unpack objects from a packed archive. SYNOPSIS: git unpack-objects [-n] [-q] [-r] [--strict].
Eso es un stream. No hay <pack-file> en la línea de comandos. Pasar el path como argumento es usage 129. No recorre refs. No mueve HEAD. No escribe el .pack (eso es pack-objects). No valida un .idx (eso es verify-pack). No compacta el object store (repack no es autónomo).
El man: Objects that already exist in the repository will not be unpacked from the packfile. Therefore, nothing will be unpacked if you use this command on a packfile that exists within the target repository. En Git 2.50.1 / Apple Git-155, sobre un pack de 3 objetos generado con pack-objects --non-empty -q fuera del object store: en el repo que ya tenía esos blobs, -n -q y -q salieron 0 y count-objects no cambió (count: 3, in-pack: 0). En un git init vacío, el mismo pack por stdin con -q salió 0 y dejó count: 3 loose. El comando “funcionó”; el daño es llenar el repo de sueltos.
Contrato: si el humano no pidió explotar un pack a loose, no lo corras. Si pide diagnóstico: -n -q y el exit code. Cero unpack a pelo. Cero path. Cero -r autónomo.
Qué hace (y qué no)
Sin flags, el pack entra por stdin. El man: The command usually shows percentage progress. En el pack de 3 objetos (208 bytes) Git 2.50.1 no imprimió barra visible; igual pasa -q. El progreso no es el veredicto.
-n: Dry run. Check the pack file without actually unpacking the objects. Es el único modo de inspección. Exit 0 si el pack parsea. No lista SHA. No escribe. En el experimento, -n -q sobre el pack sano: 0, stdout vacío.
-q: This flag suppresses it (el progreso). Siempre. Un coding agent no necesita el porcentaje.
-r: When unpacking a corrupt packfile, the command dies at the first corruption. This flag tells it to keep going and make the best effort to recover as many objects as possible. Es recuperación. No es “más robusto”. En un pack sano 2.50.1, -r -q salió 0 e escribió los 3 objetos en el repo vacío. No lo uses “por si acaso”.
--strict: Don’t write objects with broken content or links. No es un fsck del repo: no mira refs ni alcanzabilidad. En el pack sano: --strict -q exit 0 y sí escribió. No es dry-run.
--max-input-size=<size>: Die, if the pack is larger than <size>. En 2.50.1, --max-input-size=10 sobre el pack de 208 bytes: fatal: pack exceeds maximum allowed size, exit 128. Techo, no diagnóstico. No lo inventes.
Stdin vacío o basura: fatal: early EOF, exit 128. Path como argumento: usage: git unpack-objects [-n] [-q] [-r] [--strict], exit 129. Fuera de un repo: fatal: not a git repository, 128.

Límites del agente (no hagas esto)
- Unpack a pelo porque “quiero ver qué hay dentro”. Escribe loose. Sobre un pack del mismo repo, el man promete que no desempaca; sobre un pack ajeno o de bundle, llena
objects/. El diagnóstico es-n -q, no la explosión. - Pasar el
.packcomo argumento. SYNOPSIS no tiene<pack-file>. 129. Redirige stdin (< pack.pack) o no lo corras. -r“para no morir”. Recupera basura. Un pack corrupto se reporta; no se “arregla” a loose.--strictcomo fsck rápido. fsck mira el grafo. unpack mira un stream.- Encadenar repack o gc “para volver a empacar”. unpack no es el paso previo de compactar. gc autónomo es
--auto --quiet; unpack no lo dispara. - Tratar exit 0 como “no pasó nada”. En repo vacío, 0 sí escribió 3 objetos. Cierre = exit code +
git count-objects -v(count/in-pack), no un “ok” inventado. - Correrlo en el clone del humano “por higiene”. Solo worktree propio, y solo si el humano pidió unpack o un
.packfuera del object store es el problema. - Inventar
-v,-s,--stdin,-o. Esas banderas son de verify-pack / index-pack. Aquí el pack ya es stdin. --max-input-sizea ciegas. Si el humano no puso un techo, no lo pongas tú.
Receta (60 segundos)
Solo en un worktree propio, y solo si el humano pidió inspeccionar un .pack que no vive en objects/pack/ (archivo suelto, bundle extraído, pack de un fetch a medias copiado fuera):
git status -sb
git unpack-objects -n -q < /ruta/al/pack-<id>.pack
echo $?
git count-objects -v
git rev-parse HEAD
0+ stdout vacío: el pack parsea. No desempacó. Reporta el exit. Para.128+early EOF: stdin vacío o no es un pack. No reintentes sin-n. No pases el path.128+not a git repository: cwd sin.git. No inits para “tener dónde unpack”.128+pack exceeds maximum allowed size: alguien puso--max-input-size. Quita el techo solo si el humano lo pidió.129: usage. Quitaste-nmal o añadiste un path. SYNOPSIS:[-n] [-q] [-r] [--strict].
Si el humano pide escribir los loose (raro; casi nunca es la herramienta correcta frente a git clone / git fetch / git bundle):
git unpack-objects -q < /ruta/al/pack-<id>.pack
echo $?
git count-objects -v
Cierre = exit code + count / in-pack. Cero commit. Cero push a main. Cero -r. Cero unpack de un pack que ya está en el repo: nothing will be unpacked.

unpack vs pack-objects vs verify-pack vs repack
pack-objects escribe el .pack. Contrato autónomo: --non-empty -q + base-name fuera del object store. Cero --thin / --stdout / --filter. unpack lee ese pack por stdin y lo explota a loose. No es el inverso seguro: pack-objects compacta; unpack dispersa.
verify-pack lee un .idx y comprueba el .pack. Diagnóstico: -s. Cero -v dump. No escribe objetos. Si el par ya está en objects/pack/, verifica; no unpack.
repack: no autónomo. Si el humano pide compactar: -d -q. Cero -a/-f. unpack no es el paso previo; es el contrario.
count-objects cuenta sueltos y packs. Úsalo después de un unpack pedido para ver si count subió. No sustituye -n.
fsck diagnostica el object database y las refs. Un unpack 0 no dice que el grafo esté sano.
git index-pack (man git-index-pack(1); git-scm.com/docs/git-index-pack HTTP 200, last-modified 2026-08-31) construye el .idx de un .pack existente. No escribe loose. Si el problema es “falta el idx”, index-pack — no unpack.
FAQ
¿Puedo pasar el archivo en vez de stdin? No. SYNOPSIS no tiene <pack-file>. En 2.50.1, git unpack-objects -q pack.pack → usage 129. Redirige o no lo corras.
¿-n lista los objetos? Dry-run. En el pack de prueba, stdout vacío y exit 0. No es un dump. Para histograma de un pack ya indexado, verify-pack -s.
¿Sobre el pack del propio repo “no hace nada”? El man: objetos que ya existen no se desempacan. En 2.50.1, exit 0 y count igual. Sigue siendo un write-path: no lo uses de ping.
¿Es más seguro que git clone de un bundle? No. bundle verify + clone/fetch es el camino. unpack es plumbing de loose.
¿--strict evita escribir? Evita objetos rotos. Un pack sano se escribe igual. Dry-run es -n.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. unpack-objects lee stdin; el agente reporta -n -q, no llena objects/ de sueltos.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git prune-packed para coding agents: borrar sueltos ya empaquetados, no housekeeping

git index-pack para coding agents: idx de un .pack, no unpack ni --stdin a ciegas

git verify-pack para coding agents: validar un pack, no volcar el object database
