git ls-tree lists the files and subtrees recorded in a commit or tree object.
When you need the file layout of a specific commit - not the working tree - ls-tree reads it straight from the object store, including modes and blob ids, which is perfect for build manifests.
What it does
git ls-tree shows the entries of a tree object: each line carries the file mode, object type, object id, and path. With -r it recurses into subtrees.
Common usage
Terminal
git ls-tree HEAD
git ls-tree -r HEAD --name-only
git ls-tree -r -l HEAD # include blob sizes
git ls-tree HEAD:src/ # contents of a subdirectory
Options
Flag
What it does
-r
Recurse into subtrees
--name-only
Print only paths
-l / --long
Include blob sizes
-d
Show only tree entries (directories)
-z
NUL-terminate output lines
Common errors in CI
fatal: not a tree object - you passed a blob or an invalid ref; use a commit, a tree, or <rev>:<path> that resolves to a directory. Without -r, only top-level entries appear, so subdirectory files seem "missing"; add -r for the full file list.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
.github/workflows/ci.yml
- uses:actions/checkout@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
Frequently asked questions
git ls-tree: Usage, Options & Common CI Errors?
When you need the file layout of a specific commit - not the working tree - ls-tree reads it straight from the object store, including modes and blob ids, which is perfect for build manifests.
What it does?
git ls-tree shows the entries of a tree object: each line carries the file mode, object type, object id, and path. With -r it recurses into subtrees.
Common errors in CI?
fatal: not a tree object - you passed a blob or an invalid ref; use a commit, a tree, or <rev>:<path> that resolves to a directory. Without -r, only top-level entries appear, so subdirectory files seem "missing"; add -r for the full file list.