fix: gstack-upgrade uses ff-only merge before the hard reset

The upgrade flow uses `git reset --hard origin/main` to advance HEAD.
This trips destructive-command blockers (Claude Code PreToolUse hooks,
pre-commit wrappers, /careful, /guard) and can abort auto-upgrades
mid-flow.

Switch to `git merge --ff-only origin/main` as the primary path. Falls
back to the old behavior if fast-forward fails (divergent history,
local commits). Clean global installs never hit the destructive flag.

Also switches `git stash` to `git stash push --include-untracked -m
"pre-upgrade-<date>"` so untracked build artifacts (.bak/, compiled
binaries) don't block the merge, and the stash is self-describing.

Tested on Windows 11 with a Claude Code PreToolUse guard that blocks
destructive git operations. Upgraded from v0.16.2.0 to v0.18.1.0
cleanly via the ff-only path, setup regenerated customizations as
expected.
This commit is contained in:
Charlie 2026-04-17 10:18:07 +10:00
parent 822e843a60
commit f2286b7c6a
1 changed files with 9 additions and 2 deletions

View File

@ -125,9 +125,16 @@ Use the install type and directory detected in Step 2:
**For git installs** (global-git, local-git):
```bash
cd "$INSTALL_DIR"
STASH_OUTPUT=$(git stash 2>&1)
STASH_OUTPUT=$(git stash push --include-untracked -m "pre-upgrade-$(date +%Y-%m-%d)" 2>&1)
git fetch origin
git reset --hard origin/main
# Try fast-forward first. Safer than reset --hard and passes through guard
# hooks (Claude Code PreToolUse, pre-commit wrappers) that block destructive
# ops. Falls back to reset for divergent history — no-op when the working
# tree is clean and there are no local commits, which is the expected state
# for a global install.
if ! git merge --ff-only origin/main 2>/dev/null; then
git reset --hard origin/main
fi
./setup
```
If `$STASH_OUTPUT` contains "Saved working directory", warn the user: "Note: local changes were stashed. Run `git stash pop` in the skill directory to restore them."