A clean whitespace check against the working tree does not establish that the staged snapshot is clean. Once a problematic file is staged, check the index with git diff --cached --check. This is useful before committing because the index determines the proposed commit contents.

The official git diff reference documents --check and --cached, including comparison behavior when no HEAD commit exists. The following laboratory deliberately starts with a new repository and never creates a commit, so no author identity configuration is needed.

Prerequisites

Use Git, Bash, ripgrep, and mktemp on Linux. Save the complete script below as whitespace.sh and run it from a writable scratch directory. It creates a uniquely named child directory and removes that directory on exit. Configuration changes are local to the disposable repository.

#!/usr/bin/env bash
set -eu
lab=$(mktemp -d ./git-whitespace.XXXXXX)
trap 'rm -rf -- "$lab"' EXIT
cd "$lab"
git init -q
git config core.whitespace trailing-space,space-before-tab
printf 'clean\n' > sample.txt
git add sample.txt
printf 'dirty  \n' > sample.txt
if git diff --check > report.txt 2>&1; then
  echo 'expected working-tree whitespace failure' >&2
  exit 1
fi
rg -q 'trailing whitespace' report.txt
git add sample.txt
if git diff --cached --check > report.txt 2>&1; then
  echo 'expected staged whitespace failure' >&2
  exit 1
fi
rg -q 'trailing whitespace' report.txt
printf 'clean again\n' > sample.txt
git add sample.txt
git diff --cached --check
printf 'working-tree and staged whitespace checks passed\n'

Run and expected output

bash whitespace.sh
working-tree and staged whitespace checks passed

Read the experiment

First, the script stages a clean file and introduces trailing spaces only in its working copy. The ordinary diff check must fail. It captures diagnostics and requires the expected trailing-whitespace message, so an unrelated command failure cannot silently count as the intended result.

Next, the script stages the bad content and runs the cached check. That check must also fail and produce the whitespace diagnostic. Finally, it writes and stages clean replacement content. The cached check must now succeed. The final message is reached only after both negative cases and the positive case behave as expected.

Use the correct comparison

In an existing project, run the cached check to inspect proposed commit content. Run the ordinary check when inspecting edits that have not yet been staged. Neither command replaces reviewing the diff itself. An untracked file that has never been added is outside these comparisons.

Whitespace policy can vary by repository. The laboratory sets two rules locally so the demonstration is explicit. Real projects may have attributes or configuration that require different handling, particularly for generated files or whitespace-sensitive formats. Agree on the policy before using a check as an automated gate.

Edge cases and troubleshooting

A nonzero status is the signal that the check did not pass; avoid relying on one exact numeric exit code. The script places expected failures inside if statements, allowing set -e to remain enabled without terminating before the diagnostics are examined.

If the diagnostic assertion fails on a localized installation, inspect report.txt while adapting the lab and use the equivalent diagnostic text. If a staged check passes unexpectedly, confirm that the offending content was actually added to the index. Do not add --exit-code to this demonstration: it would also make ordinary content differences affect the result and obscure what is being tested.

For related workflow examples, visit the Git category and Linux category.