Skip to content
Git Basics: Search Working Files, the Index, and Commits

Git Basics: Search Working Files, the Index, and Commits

October 27, 2026

A search result depends on which version of a file you inspect. git grep can search tracked working files, staged content, or a named commit. Comparing all three is useful when an edit seems to disappear from a review.

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 1

Run the example

Save this as demonstrate-grep.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 'mode=committed\n' > settings.txt
git add settings.txt
git commit -qm 'Initial settings'
printf 'mode=staged\n' > settings.txt
git add settings.txt
printf 'mode=working\n' > settings.txt
printf 'mode=untracked\n' > scratch.txt
printf 'Working tree:\n'
git grep -n -F 'mode=' -- '*.txt'
printf 'Index:\n'
git grep --cached -n -F 'mode=' -- '*.txt'
printf 'Commit:\n'
git grep -n -F 'mode=' HEAD -- '*.txt'
if git grep -q -F 'missing-value' -- '*.txt'; then
  exit 1
else
  status=$?
  test "$status" -eq 1
  printf 'No match status: %s\n' "$status"
fi

Run it:

bash demonstrate-grep.sh

Observed output:

Working tree:
settings.txt:1:mode=working
Index:
settings.txt:1:mode=staged
Commit:
HEAD:settings.txt:1:mode=committed
No match status: 1

Read the result

The default search sees the working version of tracked settings.txt. --cached reads the index, and HEAD reads the committed tree. scratch.txt is untracked, so it is absent from these default tracked-file searches. -F treats the pattern literally; the quoted pathspec is passed to Git rather than expanded by Bash. The -- separates revisions and options from paths.

Apply it carefully

Exit status 1 means no selected lines matched. Treat other failures separately instead of turning every nonzero status into “not found.” A working-tree search does not prove what is staged or committed. Binary detection, submodules, ignored files, and --no-index change the search scope; choose options deliberately when moving beyond tracked text.

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-grep.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

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

Acknowledgements

This post was created with assistance from AI.

Last updated on