62 lines
2.6 KiB
Bash
Executable File
62 lines
2.6 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Pre-push hook: catch stray uncommitted work and doomed non-fast-forward pushes
|
|
# BEFORE contacting the remote, with clearer messages than git's own errors.
|
|
#
|
|
# History: an earlier version of this hook also *blocked* whenever local commits
|
|
# existed that weren't on origin (an "unpushed commits" check). That is
|
|
# self-defeating — having commits to push is what a push IS — so it rejected
|
|
# every meaningful push and forced --no-verify. Removed 2026-07-11. The useful
|
|
# intent behind it (spot surprise commits from other sessions/tools sharing this
|
|
# branch) is now served by the informational listing below, which never blocks.
|
|
#
|
|
|
|
set -e
|
|
|
|
echo "--- pre-push: checking for uncommitted changes ---"
|
|
|
|
if ! git diff --quiet --exit-code; then
|
|
echo "⚠️ WARNING: You have uncommitted working-tree changes."
|
|
echo " These may be VS Code auto-saves or edits you forgot to stage."
|
|
echo " Run 'git diff' to review, then commit or stash before pushing."
|
|
echo ""
|
|
echo " To push anyway, run: git push --no-verify"
|
|
exit 1
|
|
fi
|
|
|
|
if ! git diff --cached --quiet --exit-code; then
|
|
echo "⚠️ WARNING: You have staged but uncommitted changes."
|
|
echo " These may be VS Code auto-stages or partial commits."
|
|
echo " Run 'git diff --cached' to review, then commit before pushing."
|
|
echo ""
|
|
echo " To push anyway, run: git push --no-verify"
|
|
exit 1
|
|
fi
|
|
|
|
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
REMOTE="origin/$BRANCH"
|
|
|
|
if git rev-parse --verify "$REMOTE" >/dev/null 2>&1; then
|
|
# Fail fast (with clear advice) if the remote-tracking ref already has commits
|
|
# we lack — the push would be rejected as non-fast-forward anyway. This catches
|
|
# the "another session pushed first" race with a better message than git's.
|
|
# (Based on the last fetch; a race newer than that is still caught by git itself.)
|
|
BEHIND=$(git rev-list --count "$BRANCH..$REMOTE" 2>/dev/null || echo 0)
|
|
if [ "$BEHIND" -gt 0 ]; then
|
|
echo "⚠️ BLOCKED: $REMOTE has $BEHIND commit(s) you don't have — this push would be rejected."
|
|
echo " Another session/tool likely pushed first (as of your last fetch)."
|
|
echo " Run: git pull --rebase then push again."
|
|
exit 1
|
|
fi
|
|
|
|
# Informational only — never blocks: show exactly what this push will publish,
|
|
# so commits made by other sessions/tools on this branch get noticed.
|
|
AHEAD=$(git rev-list --count "$REMOTE..$BRANCH" 2>/dev/null || echo 0)
|
|
if [ "$AHEAD" -gt 0 ]; then
|
|
echo "--- pre-push: publishing $AHEAD commit(s): ---"
|
|
git log --oneline "$REMOTE..$BRANCH" | sed 's/^/ /'
|
|
fi
|
|
fi
|
|
|
|
echo "--- pre-push: all checks passed ---"
|