Skip to content
Git Basics: List a Committed Snapshot Without Checking It Out

Git Basics: List a Committed Snapshot Without Checking It Out

October 28, 2026

A build audit may need the files in a commit even when the working tree contains edits. ls-tree reads the saved tree directly, leaving the current checkout alone.

Prepare a scratch directory

Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need Bash, a text editor, the named runtime, and standard mktemp, rm, and rmdir utilities. The examples use only controlled local data; generated fixture directories are cleaned automatically.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-ls-tree.sh:

#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author'
export GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_AUTHOR_DATE='2026-10-28T00:00:00+00:00'
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git init -q -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config commit.gpgsign false
git config core.hooksPath /dev/null
mkdir src
printf 'version one\n' > src/app.txt
printf 'guide\n' > README.txt
git add src README.txt
git commit -qm 'Save snapshot'
printf 'local edit\n' > src/app.txt
printf 'untracked\n' > scratch.txt
printf 'Committed paths:\n'
git ls-tree -r --name-only HEAD
printf 'Committed src paths from repository root:\n'
git ls-tree -r --name-only --full-tree HEAD -- src/
printf 'Committed content:\n'
git show HEAD:src/app.txt
printf 'Working content:\n'
cat src/app.txt
test "$(git show HEAD:src/app.txt)" = 'version one'

Run it:

bash demonstrate-ls-tree.sh

Observed output:

Committed paths:
README.txt
src/app.txt
Committed src paths from repository root:
src/app.txt
Committed content:
version one
Working content:
local edit

Read the result

The recursive tree listing includes committed files only. scratch.txt is absent, and the saved app content differs from the local edit. --full-tree makes the path interpretation and output independent of the current subdirectory.

Apply it carefully

ls-tree inventories objects in a tree, while ls-files describes the index. For machine processing use -z with a NUL-aware parser. A submodule entry points to another commit and does not recursively enumerate that repository contents. Run this script from an ordinary shell with no repository-selection variables such as GIT_DIR or GIT_WORK_TREE set. All commits and cleanup stay inside the newly created temporary fixture.

The official reference describes the behavior and options. These checks cover the fixture above rather than every input or platform.

Clean up

Remove the saved source, return to the starting directory, then remove the empty practice directory:

rm -- demonstrate-ls-tree.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect its remaining contents rather than deleting unknown files.

Acknowledgements

This post was created with assistance from AI.

Last updated on