# Unintuitive behavior of git-archive and git-checkout-index on tree objects

1 messages from 2026-04-16 to 2026-04-16. Participants: Runxi Yu.
Thread: https://gitlist.dev/t/65494

## Runxi Yu, 2026-04-16 15:39

Subject: Unintuitive behavior of git-archive and git-checkout-index on tree objects
Message-ID: <CALLBc2Ph163mUAqr4H-AJPz_rxQz1bzGh=jxna-u-A=SwhF=0A@mail.gmail.com>

```
Dear all,

Consider the following commands.

/ztank/programming/runxiyu.org/content $ git checkout
43aa0d7ea653e17e70a3bdff91143bf0a064169c96c14c55ed150623902f8ed0
fatal: Cannot switch branch to a non-commit
'43aa0d7ea653e17e70a3bdff91143bf0a064169c96c14c55ed150623902f8ed0'
128 /ztank/programming/runxiyu.org/content $ git archive
43aa0d7ea653e17e70a3bdff91143bf0a064169c96c14c55ed150623902f8ed0 >
/tmp/kd
/ztank/programming/runxiyu.org/content $ xxd /tmp/kd | grep -v '0000
0000 0000 0000 0000 0000 0000 0000'
1 /ztank/programming/runxiyu.org/content $ # empty tarball it seems.
/ztank/programming/runxiyu.org/content $ ls -l /tmp/kd
-rw-r--r-- 1 runxiyu runxiyu 10240 Apr 16 15:13 /tmp/kd
/ztank/programming/runxiyu.org/content $ export GIT_INDEX_FILE=$(mktemp)
/ztank/programming/runxiyu.org/content $ git read-tree
43aa0d7ea653e17e70a3bdff91143bf0a064169c96c14c55ed150623902f8ed0
/ztank/programming/runxiyu.org/content $ git checkout-index -a --prefix=/tmp/kdd
/ztank/programming/runxiyu.org/content $ ls /tmp/kdd
/ztank/programming/runxiyu.org/content $ ls -a /tmp/kdd
./  ../
/ztank/programming/runxiyu.org/content $ git cat-file -p
43aa0d7ea653e17e70a3bdff91143bf0a064169c96c14c55ed150623902f8ed0 |
head -n 10
100644 blob 450ae52cc72fe249f3b42e5776fb9c5b6cbb303306ede27052c5a52e2e4d65d3
   _index.md
100644 blob cc4b067a0128a1c2ffcf36c164c2275e82f2082355db81e0335783dffb117487
   dust.md
100644 blob 68222f364217131e1924aa8828ba6dfcdad95dec4a54834b4f4a006821078d1c
   flicker.md
100644 blob 36fd1fc4eac70880bdc98b44a87bb4bd408582565516b5c370188da6f67e78f4
   inundating.md
100644 blob 7fd5618b7c1416f3d9b84bfedb7290de5c3d09298669b66e582ec306ed8fdfa8
   kat.md
100644 blob a129e79f3edbe7558246a5012d0e09e7b8dece22da55a449df9915bc2e24d9b9
   leaf.md
100644 blob 8715a9815094190a401842cd3e0f6bc1f29e5ba3a15b2a9f396528124f4605b7
   multiplicity.md
100644 blob 97dde2285aa0abb1456f1c11840e939c92762419eaeceeaed9fdfa7851d8450c
   orbits.md
100644 blob 953f577fd76120938fedd645260addff3b0b5e55aebc07a300722a6a13611d33
   rings.md
100644 blob 957ab79860c3a1bb3ca411d53e8391ed799f496036d7c36d54d3aceb9d581b61
   seventeen-days.md
/ztank/programming/runxiyu.org/content $ and yes this is a sha256 repo
but that doesn't matter.

/ztank/programming/runxiyu.org/content $ git fsck --full --strict
Checking ref database: 100% (1/1), done.
Checking object directories: 100% (256/256), done.
Checking objects: 100% (441/441), done.
Verifying commits in commit graph: 100% (78/78), done.
/ztank/programming/runxiyu.org/content $  # and yes this does prove
the blobs exist; also a normal checkout works fine.

 /ztank/programming/runxiyu.org/content $ file /tmp/tmp.LIP8s2hdGM
/tmp/tmp.LIP8s2hdGM: Git index, version 2, 19 entries
/ztank/programming/runxiyu.org/content $ xxd /tmp/tmp.LIP8s2hdGM | head -n 15
00000000: 4449 5243 0000 0002 0000 0013 0000 0000  DIRC............
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 81a4 0000 0000 0000 0000  ................
00000030: 0000 0000 450a e52c c72f e249 f3b4 2e57  ....E..,./.I...W
00000040: 76fb 9c5b 6cbb 3033 06ed e270 52c5 a52e  v..[l.03...pR...
00000050: 2e4d 65d3 0009 5f69 6e64 6578 2e6d 6400  .Me..._index.md.
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 81a4  ................
00000080: 0000 0000 0000 0000 0000 0000 cc4b 067a  .............K.z
00000090: 0128 a1c2 ffcf 36c1 64c2 275e 82f2 0823  .(....6.d.'^...#
000000a0: 55db 81e0 3357 83df fb11 7487 0007 6475  U...3W....t...du
000000b0: 7374 2e6d 6400 0000 0000 0000 0000 0000  st.md...........
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 81a4 0000 0000 0000 0000  ................
000000e0: 0000 0000 6822 2f36 4217 131e 1924 aa88  ....h"/6B....$..
/ztank/programming/runxiyu.org/content $

/ztank/programming/runxiyu.org/content $ git checkout-index -a -f
--prefix=/tmp/kdd
/ztank/programming/runxiyu.org/content $ ls /tmp/kdd

/ztank/programming/runxiyu.org/content $ git checkout-index -a -f
--prefix=/tmp/kdd/
/ztank/programming/runxiyu.org/content $ ls /tmp/kdd

------------------------ >8 ------------------------

I understand it for git-archive, albeit unintuitive:

       <path>
           Without an optional path parameter, all files and
           subdirectories of the current working directory are
           included in the archive. If one or more paths are
           specified, only these are included.

But it's difficult to understand this behavior for git-checkout-index.

Particularly,

       -a, --all
           checks out all files in the index except for those with
           the skip-worktree bit set (see
           --ignore-skip-worktree-bits). Cannot be used together with
           explicit filenames.

If the behavior is to be kept, should this be changed to "all
files in the index that match the implicit pathspec (of the
current directory)"?

Or an idiomatic way to check a tree out, other than
-C "$(git rev-parse --show-toplevel)"?

Thanks!

Please reply-all since I'm not on the list.

Thanks!

-- 
Best regards,

Runxi Yu (they/them)
University of Michigan, Ann Arbor
runxiyu@umich.edu
me@runxiyu.org

```
