#!/usr/bin/env bash
# gstack-wtree — print a working-tree CONTENT fingerprint (a git tree hash).
#
# Builds a temp index seeded from HEAD, stages the full working tree into it
# (`git add -A`, so .gitignore'd scratch stays out and UNTRACKED source is
# included), and prints `git write-tree` of that index. Properties that make
# this the right staleness fingerprint, vs `git rev-parse HEAD^{tree}`:
#
#   - Committing identical content does NOT change the fingerprint, so a
#     record made on a dirty tree stays valid after the exact same content is
#     committed (the /ship Step 5 -> Step 16 case).
#   - Untracked new source files DO change the fingerprint, so "tests passed"
#     can't stay FRESH after a new file appears.
#   - Rebase/amend/squash that preserve content do not change it.
#
# The real repo index is never touched. Staged blobs land in the object store
# as unreachable objects and get gc'd like stash churn. Exit 1 outside a git
# repo or in a repo with no commits — callers treat that as "no fingerprint".
set -euo pipefail

TOP=$(git rev-parse --show-toplevel 2>/dev/null) || exit 1
TMPIDX=$(mktemp "${TMPDIR:-/tmp}/gstack-wtree-XXXXXX")
trap 'rm -f "$TMPIDX"' EXIT
export GIT_INDEX_FILE="$TMPIDX"
git -C "$TOP" read-tree HEAD 2>/dev/null || exit 1
git -C "$TOP" add -A 2>/dev/null || exit 1
git -C "$TOP" write-tree 2>/dev/null
