You can use Git to compare two generated files without staging them or creating a repository. The --no-index form compares filesystem paths directly. This is useful when a local build produces an artifact that you want to compare with a reviewed baseline.

Prerequisites are Bash, Git and ordinary Unix utilities. Run this example in a writable scratch directory. It creates two tiny files in a temporary subdirectory, checks the comparison behavior, and removes that subdirectory on exit. It does not alter repository history or configuration.

Complete example

Save as compare.sh:

#!/usr/bin/env bash
set -eu
work=$(mktemp -d ./compare.XXXXXX)
trap 'rm -rf -- "$work"' EXIT
printf 'one\n' > "$work/old"
printf 'two\n' > "$work/new"
compare() {
    if [[ ! -f "$1" || ! -r "$1" || ! -f "$2" || ! -r "$2" ]]; then
        printf 'two readable regular files required\n' >&2
        return 2
    fi
    local status=0
    git diff --no-index --no-ext-diff --no-textconv --quiet -- "$1" "$2" || status=$?
    case "$status" in
        0) printf 'same\n' ;;
        1) printf 'different\n' ;;
        *) printf 'comparison failed (%s)\n' "$status" >&2; return "$status" ;;
    esac
}
[[ $(compare "$work/old" "$work/old") == same ]]
[[ $(compare "$work/old" "$work/new") == different ]]
if compare "$work/missing" "$work/new" > "$work/out" 2> "$work/err"; then
    printf 'missing file unexpectedly accepted\n' >&2
    exit 1
fi
printf 'same, different and missing-file cases passed\n'

Run

bash compare.sh

Expected output:

same, different and missing-file cases passed

A difference is an expected comparison result, so the command captures its exit status through an OR list instead of allowing set -e to stop the script. The wrapper returns success after printing either same or different; callers can branch on that output. Unexpected statuses are propagated.

The explicit file checks matter. On the tested Git 2.43.0 installation, a missing input also returned status 1. Interpreting every 1 as a valid difference would therefore hide a missing artifact. The wrapper rejects missing and non-readable regular-file inputs before invoking Git.

Limitations and troubleshooting

The preflight checks and comparison are not atomic. A file can disappear or change between them. Use this example for stable local artifacts, and retain Git's diagnostics when investigating failures. It is not a universal error classifier for concurrently changing filesystems.

External diff helpers and text conversion are disabled explicitly. The quiet comparison answers whether Git considers the inputs different; it does not generate a review patch. For visual investigation, run a separate non-quiet comparison on your controlled files and inspect its output.

If the script stops before printing the final line, verify that Bash is used, that Git is installed, and that the scratch directory permits temporary-file creation. The quoted paths and option terminator protect ordinary names containing spaces or leading punctuation.

Primary reference

Read the official git diff documentation, including no-index mode and comparison options. Find related examples in the Git category.