Guía9 min

git checkout-index para coding agents: index al disco, no checkout

Resumen

git checkout-index copia paths del index al working tree y no pisa archivos existentes salvo -f. Sin args no hace nada; -a es all. Plumbing, no porcelain. Cero autónomo con -f/-a/--prefix/--temp. Distinto de checkout, restore y read-tree. Git 2.50.1.

GitHub
El index de Git materializa archivos al working tree sin mover HEAD

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 checkout-index copia del index al working tree. El man (git-checkout-index(1); git-scm.com/docs/git-checkout-index 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.50.1.428.g0e8243, 2025-07-22; binario Git 2.50.1 / Apple Git-155): Copy files from the index to the working tree. DESCRIPTION: Copies all listed files from the index to the working directory (not overwriting existing files). SYNOPSIS mezcla -u -q -a -f -n --prefix --stage --temp --stdin y <file>....

Sin argumentos no hace nada. El man: Just doing git checkout-index does nothing. You probably meant git checkout-index -a. Intuitiveness is not the goal here. Repeatability is. Un script que lista paths no puede permitirse que una línea vacía signifique “todo el árbol”.

No es checkout: checkout mueve HEAD o restaura paths como porcelain. No es restore: restore pisa paths con contrato de source/worktree. No es read-tree: read-tree escribe el index; checkout-index materializa el index al disco. El man de read-tree remite a checkout-index para el paso de archivos.

Contrato: no corras git checkout-index autónomo sobre el working tree del humano. Restaurar un path = restore. Cambiar de rama = switch o checkout. Inspección = ls-files. Cero -f. Cero -a. Cero --prefix. Cero --temp. Cero --stage.

Qué hace (y qué no)

Lista de paths → blobs del index → archivos en el working tree. Si el archivo ya existe, se niega. Verificado 2026-09-06 (Git 2.50.1 / Apple Git-155): git checkout-index sin args → exit 0, silencio, disco intacto. Tras rm a.txt, git checkout-index -a recrea a.txt con el contenido del index (hello). Con a.txt sucio (dirty) y sin -f: a.txt already exists, no checkout, exit 1, el disco sigue dirty. Con -f -a pisa y vuelve a hello.

-a / --all: checks out all files in the index except for those with the skip-worktree bit set. No se mezcla con filenames. Verificado: git checkout-index -a a.txtfatal: git checkout-index: don't mix '--all' and explicit filenames, 128.

-n / --no-create: Don't checkout new files, only refresh files already checked out. Verificado: rm a.txt && git checkout-index -n -a → exit 0, a.txt sigue ausente.

--prefix=<string>: When creating files, prepend <string> (usually a directory including a trailing /). El slash final importa: el man exporta con --prefix=git-export-dir/ -a. Verificado: --prefix=export/ -a crea export/a.txt y no toca el a.txt de la raíz. Sin slash, el prefix es literal sobre el filename.

--stage=<number>|all y --temp: copian stages a temporales, no al path tracked. --stage=all implica --temp. Sirve a un mergetool, no a un agente que “quiere ver el conflicto”.

-h: usage, 129.

el index materializa paths al disco; un archivo existente bloquea sin -f

Lo que el agente sí / no corre

QuieroComandoTrampa
Restaurar un path suciorestore -- <path>checkout-index -f -- path pisa sin porcelain
Ver qué hay en el indexls-files -z-a “para listar” materializa
Cambiar de ramaswitchcheckout-index no mueve HEAD
Exportar un tree a un dirgit archive o un humano con --prefix--prefix autónomo escribe un árbol paralelo
Sparse / skip-worktreesparse-checkout--ignore-skip-worktree-bits saca lo que sparse escondió

Prohibido en autónomo:

  • -f / --force. El default existe para no pisar. Verificado: sin -f el working tree sucio sobrevive (exit 1). Con -f se pierde.
  • -a sobre el checkout del humano. Es “todo el index menos skip-worktree”. En un repo real son miles de paths.
  • --prefix autónomo. Exporta una copia. El man lo vende como “export an entire tree”. Un agente no duplica el working tree a git-export-dir/.
  • --temp / --stage=all. Escribe temporales y un listing a stdout. El modelo no necesita los tres stages en /tmp.
  • --ignore-skip-worktree-bits. Verificado: con skip-worktree, -a no recrea a.txt; con el flag, sí. Sparse-checkout usa ese bit. Un agente no lo ignora.
  • -u / --index autónomo. update stat information for the checked out entries in the index file. Toca el index además del disco.
  • Mezclar -a y filenames. 128, don't mix.
  • Encadenar read-tree -u + checkout-index -f -a. Doble escritura al disco.

El porcelain de restore/checkout ya cubre el caso “quiero el archivo del index”. Este verbo existe para scripts que necesitan repeatability: from scripts you are supposed to be able to do find … \| git checkout-index -f -z --stdin. Eso es un humano o un export, no un tick de agente.

Receta (60 segundos)

Solo en un worktree propio, y solo si un humano pidió este verbo:

git status -sb
git ls-files -- a.txt
git checkout-index -- a.txt

Tres líneas. status te dice si el path está sucio (entonces para: sin -f va a 1; con -f pisa). ls-files confirma que el path está en el index. checkout-index sin -f recrea el archivo solo si no existe.

Si el archivo existe y quieres el del index, el camino es restore, no este plumbing.

Para inspeccionar skip-worktree:

git ls-files -v -- a.txt

Una S al frente es skip-worktree. No uses --ignore-skip-worktree-bits para “arreglarlo”.

Trampas que ya vimos

  1. “Sin args refresca todo.” No. Exit 0 y cero I/O. El man lo dice dos veces. Quien quiso -a tiene que pedirlo.
  2. “Es lo mismo que checkout path.” checkout (modo path) y restore son porcelain. checkout-index no desambigua ramas, no mueve HEAD, no corre el flujo de switch. Un filename -a se interpreta como opción si olvidas --.
  3. -f “porque already exists.” Ese mensaje es el safety default. Forzar es borrar el working tree sucio. En el demo, dirty volvió a hello.
  4. --prefix sin slash. El man: el exported name is literally just prefixed with the specified string. --prefix=.merged- Makefile.merged-Makefile, no un directorio.
  5. -a + path. 128. El all y la lista son mutuamente excluyentes.
  6. skip-worktree. -a respeta el bit. --ignore-skip-worktree-bits lo rompe. Sparse-checkout no es un bug.
  7. -n como dry-run de “¿puedo?” -n no crea files nuevos; no es un --dry-run de errores. Si el path falta, exit 0 y sigue faltando.
  8. --stdin sin -z. Paths separados por LF. Un path con newline se parte. El man recomienda -z --stdin junto a find -print0.
  9. Creer que actualiza el index. Salvo -u, solo toca el working tree. El inverse es update-index.

Checklist

  • Worktree propio, no el checkout del humano.
  • git status -sb leído antes. Path sucio → para.
  • Quiero materializar el index, no cambiar de rama.
  • Paths explícitos + --. Cero -a. Cero -f.
  • Cero --prefix, --temp, --stage, --ignore-skip-worktree-bits.
  • Si el path existe: restore, no force.
  • Si el ticket pide “exportar el árbol”: archive, no prefix autónomo.
  • Si el ticket pide “volver al commit”: restore o checkout, no este verbo.

FAQ

¿checkout-index mueve HEAD? No. Solo copia blobs del index al disco. HEAD y las refs no cambian.

¿Por qué no overwrite por default? Repeatability en scripts: un find que alimenta paths no debe borrar working trees ajenos si un path ya está. El man lo explica con el ejemplo de *.h.

¿Cuándo sí -a? Cuando un humano pide exportar o refrescar todo el index en un directorio vacío o con --prefix. Nunca en el working tree vivo de otra sesión.

¿Y read-tree -u? read-tree -u materializa después de reescribir el index. Doble contrato, doble daño. El agente autónomo no encadena esos dos.

¿Dónde encaja esto? En el hub de comparativas y decisiones, junto a checkout y restore. Si estás armando el primer agente, empieza por el curso.

sin -f el archivo sucio sobrevive; -a no se mezcla con filenames