#!/bin/sh
# git-clean-check — Verify the git repo in PWD is clean and in sync.
#
# Checks that the working tree has no uncommitted changes, the current
# branch is main, and local main is in sync with origin/main.

die() { printf '%s\n' "error: $*" >&2; exit 1; }

# --- verify git is available ---

command -v git >/dev/null 2>&1 || die "git is required but not found"
git rev-parse --git-dir >/dev/null 2>&1 || die "not a git repository: $(pwd)"

# --- check working tree ---

_dirty=$(git status --porcelain) || die "failed to check git status"
if [ -n "$_dirty" ]; then
  printf '%s\n' "error: working tree is dirty — commit or stash changes first" >&2
  printf '%s\n' "$_dirty" >&2
  exit 1
fi

# --- check branch ---

_branch=$(git rev-parse --abbrev-ref HEAD) || die "failed to determine current branch"
[ "$_branch" = "main" ] || die "must be on main branch (currently on $_branch)"

# --- check remote sync ---

git fetch origin main >/dev/null 2>&1 || die "failed to fetch origin/main"

_local=$(git rev-parse HEAD) || die "failed to resolve HEAD"
_remote=$(git rev-parse origin/main 2>/dev/null) || die "failed to resolve origin/main"

if [ "$_local" != "$_remote" ]; then
  _ahead=$(git rev-list origin/main..HEAD --count 2>/dev/null)
  _behind=$(git rev-list HEAD..origin/main --count 2>/dev/null)
  die "local main is out of sync with origin/main (ahead: ${_ahead:-?}, behind: ${_behind:-?}) — pull or push first"
fi

exit 0
