Guía9 min

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

Resumen

git prune-packed borra objetos sueltos que ya viven en un pack. Diagnóstico: -n. Cero a pelo. Cero porque prune-packable > 0. No es prune, ni gc, ni repack, ni count-objects. Git 2.50.1.

GitHub
Objetos sueltos duplicados junto a un pack: prune-packed solo borra los que ya están empaquetados

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 prune-packed borra objetos sueltos que también existen en un pack. El man (git-prune-packed(1); git-scm.com/docs/git-prune-packed HTTP 200, last-modified 2026-08-31; last updated in 2.43.0; pie del man local Git 2.50.1.428.g0e8243, 2025-07-22; binario Git 2.50.1 / Apple Git-155): Remove extra objects that are already in pack files. SYNOPSIS: git prune-packed [-n | --dry-run] [-q | --quiet].

Recorre $GIT_OBJECT_DIRECTORY y, para cada objeto que está a la vez suelto y empaquetado, elimina el suelto. El pack se queda. HEAD, el índice y el working tree no se tocan.

No es prune. prune tira sueltos inalcanzables (y, sin -n, ya llama a prune-packed). prune-packed no mira refs ni alcanzabilidad. Un blob reachable que ya está en un pack sí cae.

Tampoco es gc. gc es porcelain: empaqueta, recorta reflog y decide cuándo podar. El contrato autónomo de housekeeping sigue siendo gc --auto --quiet.

Ni repack. repack escribe packs. prune-packed borra sueltos duplicados. Un repack sin -d deja prune-packable > 0; eso no autoriza a un agente a compactar a mano.

Ni count-objects. count-objects Count unpacked number of objects and their disk consumption. El campo prune-packable es un entero. El man de count-objects dice could be pruned using git prune-packed. Could no es must.

Contrato: git prune-packed -n. Cero a pelo. Cero porque prune-packable > 0. Cero dump de rm -f al LLM. Housekeeping = gc --auto --quiet.

Qué hace (y qué no)

Sin flags escribe: busca sueltos que ya están en un pack y los borra. En Git 2.50.1, con un repo de prueba (6 sueltos + 1 pack, prune-packable: 6), el comando salió 0, stdout vacío, HEAD igual, y count-objects -v pasó a count: 0 / prune-packable: 0 / in-pack: 6. Los objetos siguen vivos dentro del pack.

-n / --dry-run: Don't actually remove any objects, only show those that would have been removed. Imprime una línea rm -f .git/objects/ab/cdef… por objeto. Es el único modo autónomo. En el mismo repo de prueba: 0 y 6 líneas rm -f. Tras el dry-run, count-objects igual. HEAD igual.

-q / --quiet: Squelch the progress indicator. No es “silencio total”. En el binario 2.50.1 / Apple Git-155, git prune-packed -n -q siguió listando las 6 líneas rm -f. -q no tapa el reporte de dry-run. Un agente no combina -n -q para “ver menos”: si el dry-run es largo, recorta el reporte; no pidas quiet para esconder evidencia.

El usage del binario también acepta --no-dry-run y --no-quiet (--[no-]dry-run, --[no-]quiet). --no-dry-run escribe. Un agente no lo pasa “por simetría”. SYNOPSIS canónico: -n y -q.

No toma paths. Un argumento extra: 129, fatal: too many arguments. No es git rm. No es git prune -- <head>.

Verificado 2026-09-06 (Git 2.50.1 / Apple Git-155). Lab propio (git init, dos commits, git repack -q sin -d para dejar sueltos duplicados). Worktree limpio:

  • sin args (hay packable): 0. stdout vacío. rev-parse HEAD igual. status -sb sin cambios. count 6 → 0.
  • git prune-packed -n: 0. 6 × rm -f .git/objects/…. HEAD igual. count-objects igual.
  • git prune-packed --dry-run: 0. Idéntico a -n.
  • git prune-packed -q (hay packable): 0. stdout vacío. Escribe igual que sin flags.
  • git prune-packed -n -q: 0. Mismas 6 líneas rm -f que -n. -q no silenció el dry-run.
  • sin packable (segunda pasada): 0. stdout vacío con o sin -n.
  • git prune-packed extra: 129, fatal: too many arguments.
  • --foo: 129, unknown option `foo'.
  • fuera de repo (git -C /tmp prune-packed): 128, not a git repository.

Dry-run: lista rm -f de sueltos ya en el pack; no borra hasta quitar -n

Lo que el agente sí / no corre

QuieroComandoTrampa
¿Qué sueltos ya están en un pack?git prune-packed -na pelo “porque son duplicados”
¿Cuántos hay?count-objects -vprune-packable > 0 → prune-packed
¿Borrar inalcanzables?prune -nprune-packed como fsck
Housekeepinggc --auto --quietprune-packed + repack a mano
¿Este pack está íntegro?verify-pack -sprune-packed como CRC

Prohibido en autónomo:

  • Sin -n. Sin flags borra. El man no pide confirmación.
  • Encadenarlo porque count-objects imprimió prune-packable > 0. Ese campo es inventario. Could ≠ must.
  • Encadenarlo tras repack sin -d. Si el humano pidió compactar, el contrato de repack ya es -d -q (borra sueltos empaquetados como parte de esa receta). Un agente no añade un segundo comando “por higiene”.
  • Confundirlo con prune. prune mira alcanzabilidad. prune-packed mira duplicado suelto + pack. Un commit de HEAD cae del directorio suelto si ya está empaquetado.
  • rm a mano de .git/objects/??/* copiando las líneas del dry-run. El reporte es evidencia, no un script.
  • -q para no ver el dry-run. En 2.50.1 no esconde rm -f. Si la lista es larga, resume: N paths, cero pegar 400 SHA al contexto.
  • Inventar --expire, -v, --progress, un path, un SHA. SYNOPSIS: -n y -q.
  • --no-dry-run “para ser explícito”. Escribe.
  • Correrlo en el clone del humano. Solo worktree propio, y solo dry-run salvo que el humano pida el write.
  • Tratar exit 0 sin stdout como “no había nada” cuando no usaste -n: también es el caso feliz del write.

Receta (60 segundos)

Solo en un worktree propio, y solo si ya estás diagnosticando disco / sueltos (no “por higiene”):

git status -sb
git count-objects -v
git prune-packed -n
echo $?
git rev-parse HEAD

En un worktree vinculado, el object database vive en git rev-parse --git-common-dir. prune-packed opera sobre ese store, no sobre el working tree corto.

  • 0 y cero líneas: no hay sueltos duplicados. Cierra con eso. Cero write.
  • 0 y N × rm -f: hay N duplicados. Reporta N, no las rutas. Cero segunda invocación sin -n.
  • 128: no hay repo. Distinto de verify-pack, que puede validar un .idx con cwd fuera.
  • 129: usage, opción desconocida o argumentos de más. No añadas flags de prune.

Si el humano pide borrar los duplicados: git prune-packed -n otra vez, enseña N, después git prune-packed (sin -n) en el mismo worktree. Cierre = exit 0 + count-objects -v (prune-packable: 0). Cero commit. Cero push a main.

El write solo quita el suelto duplicado; el objeto sigue dentro del pack

prune-packed vs prune vs gc vs count-objects vs repack

prune: sueltos inalcanzables. Contrato autónomo -n. Sin -n también llama prune-packed. No sustituyas prune por este comando.

gc: --auto --quiet. Porcelain. Es el housekeeping. prune-packed no lo dispara ni lo reemplaza.

count-objects: -v. Inventario. prune-packable describe could. Cero encadenar.

repack: no autónomo. Si el humano pide compactar: -d -q. -d ya elimina sueltos que acabaron en el pack. No hace falta un prune-packed extra.

pack-objects escribe un pack. verify-pack valida un .idx. Ninguno borra sueltos.

fsck mira el grafo. prune-packed no valida hashes ni dangling.

FAQ

¿prune-packable > 0 autoriza el write? No. El man de count-objects dice could be pruned. Diagnóstico primero: -n. Housekeeping = gc.

¿Borra commits de HEAD? Borra la copia suelta si ese objeto ya está en un pack. rev-parse HEAD no cambia. El objeto sigue en el .pack. No es un reset.

¿Es lo mismo que git prune? No. prune usa alcanzabilidad (fsck --unreachable). prune-packed usa “¿ya está en un pack?”. Un objeto reachable empaquetado es candidato aquí y no de prune.

¿-q hace el dry-run seguro de pegar al LLM? No. En 2.50.1 -n -q lista igual. Recorta a un entero N.

¿Lo corro después de cada repack? No. Si hubo repack, o fue -d -q (ya limpió) o no debías correrlo en autónomo.

El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. prune-packed borra duplicados sueltos; el agente reporta el dry-run, no compacta el object database.