Git Basics: Inspect Stored Objects with cat-file
A checkout shows one view of a repository. git cat-file lets a diagnostic script inspect stored objects directly: their types, sizes, and contents. A small committed file makes the difference between a blob and the working copy visible.
Prepare a scratch directory
Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need the named runtime, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. The script creates a second temporary fixture directory and removes only that directory through its exit trap. Run it in a normal Bash terminal, outside any Git hook or Git wrapper. No global Git configuration is changed.
Keep using the same terminal. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-cat-file.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
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE
git init -q -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config user.name 'Practice Author'
git config user.email 'practice@example.invalid'
printf 'hello\n' > note.txt
git add note.txt
git commit -qm 'Store a note'
printf 'Commit type: %s\n' "$(git cat-file -t HEAD)"
printf 'Tree type: %s\n' "$(git cat-file -t 'HEAD^{tree}')"
printf 'Blob type: %s\n' "$(git cat-file -t HEAD:note.txt)"
test "$(git cat-file -s HEAD:note.txt)" -eq 6
printf 'Blob bytes: %s\n' "$(git cat-file -s HEAD:note.txt)"
printf 'changed locally\n' > note.txt
printf 'Stored contents:\n'
git cat-file -p HEAD:note.txt
printf 'Batch type and size:\n'
printf 'HEAD:note.txt\nHEAD:missing.txt\n' \
| git cat-file --batch-check='%(objecttype) %(objectsize)'
test "$(git cat-file -p HEAD:note.txt)" = helloRun it:
bash demonstrate-cat-file.shObserved output:
Commit type: commit
Tree type: tree
Blob type: blob
Blob bytes: 6
Stored contents:
hello
Batch type and size:
blob 6
HEAD:missing.txt missingRead the result
HEAD identifies a commit, HEAD^{tree} selects its tree, and HEAD:note.txt selects the stored file blob. The size includes the newline after hello. Editing the working file does not alter that blob. Batch mode accepts one object expression per input line; the valid expression gets the requested fields, while the missing path is reported as missing.
Apply it carefully
Object size is the logical uncompressed size, not disk usage inside a pack file. Blob bytes have no inherent filename, text encoding, or executable permission; a tree supplies path and mode information. Batch output can contain special missing-object records, so do not assume every line has the custom format. Use this on repositories you control and avoid dumping large or sensitive blobs into logs.
The official reference describes the API and its options. The checks above cover the specific fixture, not every possible input or environment.
Clean up
Remove the source and then the empty practice directory:
rm -- demonstrate-cat-file.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect the remaining files rather than deleting unknown contents.
Acknowledgements
This post was created with assistance from AI.