git pack-objects para coding agents: plumbing de packs, no compactar el repo
Resumen
git pack-objects lee objetos por stdin y escribe un .pack/.idx o un stream. Es el motor de gc, repack y bundle. Un agente no lo corre autónomo: no escribe en objects/pack, no usa --thin ni --cruft. Distinto de repack, gc, prune y pack-refs. 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 pack-objects crea un archivo empaquetado de objetos. El man (git-pack-objects(1); git-scm.com/docs/git-pack-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): Create a packed archive of objects. SYNOPSIS: lee una lista por stdin y escribe o un par .pack + .idx con <base-name>, o el pack a --stdout.
Es plumbing. No lista refs. No mueve HEAD. No toca el índice ni el working tree. Solo comprime objetos (enteros o como delta) y los deja en un archivo. Por eso es más peligroso que repack: git repack -d -q es porcelain que sí llama a pack-objects con flags seguros (--delta-base-offset en Git moderno) y deja el pack dentro de $GIT_OBJECT_DIRECTORY/pack. pack-objects crudo escribe donde le digas el <base-name> o al stdout. Un agente que lo dispara “para compactar” puede dejar un .pack huérfano en el cwd, un pack thin inválido, o un cruft pack que el humano no pidió.
No es gc. gc decide si compactar (--auto) y orquesta pack-objects + prune. Tampoco es prune (borra loose inalcanzables) ni count-objects (diagnóstico -v). Ni pack-refs: ese comando empaqueta nombres de refs en packed-refs, no blobs ni trees.
Tampoco es bundle. El man de bundle lo dice: Bundles are .pack files (see git-pack-objects(1)) with a header. Bundle añade un encabezado de refs; pack-objects solo el archivo de objetos. Un .pack suelto no se clona con git clone.
Ni rev-list: ese comando enumera. pack-objects consume esa enumeración. El man: --revs Read the revision arguments from the standard input, instead of individual object names. The revision arguments are processed the same way as git rev-list with the --objects flag.
Git 2.50.1. Contrato: no corras git pack-objects autónomo. Compactar el repo = repack si el humano lo pide, o maintenance / gc --auto --quiet. Diagnóstico = count-objects -v. Transferir un snapshot = bundle o archive. Si el humano pide explícitamente un pack: --non-empty -q + <base-name> fuera de .git/objects/pack, lista de objetos acotada, cero --thin, cero --cruft, cero --filter, cero --stdout hacia un pipe que nadie consume.
Stdin, base-name y stdout
El man parte el contrato en dos salidas:
| Forma | Qué escribe | Agente |
|---|---|---|
<base-name> | <base-name>-<SHA-1>.pack + .idx; imprime el SHA a stdout | Solo si el humano da el path fuera del object store |
--stdout | el .pack crudo al stdout; sin .idx | Cero autónomo; el receptor debe ser index-pack o un peer |
--non-empty | no crea pack vacío | Obligatorio si el humano pide el comando |
-q | silencia progreso en stderr | Preferible; --progress ensucia logs |
Sin --revs, stdin son nombres de objeto (SHA), no commits. Con --revs, stdin son argumentos de revisión como git rev-list --objects. --unpacked implica --revs y limita a objetos que aún no están en un pack. --all implica --revs y finge que todas las refs bajo refs/ están en la lista.
Un agente que hace git pack-objects pack sin stdin se queda colgado esperando. Uno que redirige el repo entero a --stdout y lo tira al log del LLM descarga megas de binario. Cero dumps.

Deltas, window y thin packs
El man: In a packed archive, an object is either stored as a compressed whole or as a difference from some other object. El formato .pack es autocontenido: each object that a delta depends upon must be present within the pack.
--window=<n> (default 10) y --depth=<n> (default 50, máximo 4095) controlan la búsqueda de deltas. Subir window/depth “para compactar más” multiplica CPU y RAM (--threads multiplica la memoria de la ventana). --window-memory escala la ventana para no OOM. Un agente no toca esos knobs.
--thin rompe el formato: A thin pack violates the packed archive format by omitting required objects and is thus unusable by Git without making it self-contained. El arreglo canónico es git index-pack --fix-thin (git-index-pack(1); git-scm.com/docs/git-index-pack HTTP 200, last-modified 2026-08-31). Porcelain de red (fetch/push) lo usa entre peers. Un coding agent no escribe thin packs en disco.
--delta-base-offset ahorra 3–5 % usando offset en el stream en vez de 20 bytes de SHA. El man: Porcelain commands such as git gc, git repack pass this option by default in modern Git when they put objects in your repository into pack files. So does git bundle. Por eso el agente no reimplementa gc con pack-objects a mano: perdería ese flag (y --sparse, bitmaps, cruft) y dejaría un pack peor.
--no-reuse-delta / --no-reuse-object fuerzan recomputar todo. Útiles solo si el humano pide un nivel de compresión uniforme. Cero autónomo: en un repo grande son minutos de CPU.
Qué no es (y qué no toques)
| Comando | Rol | pack-objects |
|---|---|---|
| repack | porcelain: reescribe packs del object store | el motor; el agente llama a repack, no al motor |
| gc | orquesta auto + prune | no sustituye --auto |
| prune | borra loose inalcanzables | pack-objects no borra |
| count-objects | diagnóstico count/size-pack | no compacta |
| bundle | pack + header de refs | no es un bundle |
| pack-refs | packed-refs | otro archivo, otras refs |
| unpack-objects | loose desde un .pack por stdin | inverso; tampoco autónomo |
| index-pack | construye .idx (y --fix-thin) | pareja de --stdout |
Flags vetados para un agente, aunque el humano pida “compacta”:
--cruft/--cruft-expiration: packs de inalcanzables con.mtimes. El man: Typically used by git repack --cruft. No es tu trabajo.--filter=<spec>: omite blobs (partial clone). Cambia qué objetos existen.--keep-unreachable/--pack-loose-unreachable/--unpack-unreachable: implican--revsy mueven inalcanzables.--max-pack-size: parte el pack; may result in a larger and slower repository.--stdin-packs/--incremental/--local/--honor-pack-keep: semántica de qué se ignora; fácil dejar objetos sueltos.--index-version: intended to be used by the test suite only.--missing=allow-any: omite objetos faltantes en silencio (partial clone debug).
--sparse con --revs acelera packs chicos (only walks trees that appear in paths that introduce new objects) y es el default de pack.useSparse. No lo apagues. No lo enciendas a mano.
Checklist del agente
- Diagnóstico, no packing.
git count-objects -v. Sisize-packes enorme, reporta; no compactes. - Si el humano pide compactar el repo: repack
-d -q(su guía: cero-a/-A/-fautónomos). Nopack-objects. - Si el humano pide un archivo
.packconcreto: confirma path fuera de.git/objects/pack.git rev-list --objects <rango>acotado |git pack-objects --non-empty -q <base-name>. Verifica que salieron.pack+.idx. - Cero
--stdoutal chat. El pack es binario. - Cero
--thin. Sinindex-pack --fix-thinel archivo no es un pack Git. - Cero
--cruft,--filter,--no-reuse-object,--threadsinventados. - No pipes a unpack-objects sobre el repo de trabajo: Objects that already exist in the repository will not be unpacked — y si el pack trae objetos nuevos, los deja loose.
- Tras cualquier packing pedido:
git status -sbygit count-objects -v. El working tree no debe cambiar. Si cambió, parar.

FAQ
¿Puedo usarlo para “acelerar clone” del worktree del humano? No. Clone ya negocia packs. Un pack local no sustituye clone ni bundle create.
¿--stdout + index-pack --stdin es el flujo de fetch? Sí, entre peers. En un coding agent es un side-channel para meter objetos en .git/objects sin commit visible. Cero autónomo.
¿Por qué no copiar git gc a mano? Porque gc pasa --delta-base-offset, respeta pack.*, puede escribir bitmaps y cruft, y decide con --auto. pack-objects suelto no.
¿--all es seguro? Empaqueta todo lo alcanzable desde refs/. En un repo con notes, replace y stash es más de lo que el humano suele querer. Cero autónomo.
¿Y unpack-objects -n? Dry-run del inverso. Sigue siendo plumbing de pack. Si hay duda de integridad, fsck, no unpack.
Relacionado
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

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

git update-ref para coding agents: plumbing de refs, no mover HEAD

git pack-refs para coding agents: packed-refs, no el dump al LLM
