mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-09 14:38:59 +02:00
fix(upgrade): fast-forward first; reset --hard only behind a proved-safe gate (#2517)
/gstack-upgrade went straight to stash + reset --hard origin/main. Now it tries git pull --ff-only --autostash first (the same policy session-update's auto-upgrade uses). The destructive fallback runs unprompted ONLY when both git status --porcelain AND git rev-list origin/main..HEAD are empty — a clean tree with unpushed local commits is NOT safe, reset destroys them. Anything else requires an explicit one-way-door confirmation that lists every dirty file and unpushed commit being discarded. Fixes #2517. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c856472034
commit
6ad9db51fb
@@ -123,20 +123,42 @@ OLD_VERSION=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "unknown")
|
||||
Use the install type and directory detected in Step 2:
|
||||
|
||||
**For git installs** (global-git, local-git):
|
||||
|
||||
Fast-forward first (#2517) — the same policy the session-update auto-upgrade
|
||||
uses. `--autostash` carries local edits over the pull; render-footprint dirt
|
||||
is discarded first because it is regenerable and poisons stashes (#2569):
|
||||
```bash
|
||||
cd "$INSTALL_DIR"
|
||||
# Discard render-footprint dirt BEFORE stashing (#2569): pre-v1.67
|
||||
# gbrain-enabled installs ran gen:skill-docs:user IN PLACE, leaving
|
||||
# generated SKILL.md / sections/*.md files permanently modified. Stashing
|
||||
# that dirt poisons the stash: the post-upgrade `git stash pop` would
|
||||
# restore STALE generated markdown over the fresh checkout permanently.
|
||||
# These files are regenerable (setup re-renders brain-aware variants to
|
||||
# ~/.gstack/render), so discarding is lossless; anything else the user
|
||||
# changed still reaches the stash untouched. Same file classification as
|
||||
# migrations/v1.67.0.0.sh, which remains for manual git-pull flows.
|
||||
# Discard render-footprint dirt (#2569): pre-v1.67 gbrain-enabled installs
|
||||
# ran gen:skill-docs:user IN PLACE, leaving generated SKILL.md / sections
|
||||
# files permanently modified. They are regenerable (setup re-renders to
|
||||
# ~/.gstack/render), so discarding is lossless.
|
||||
git checkout -- 'SKILL.md' '*/SKILL.md' '*/sections/*.md' 2>/dev/null || true
|
||||
STASH_OUTPUT=$(git stash 2>&1)
|
||||
git fetch origin
|
||||
git pull --ff-only --autostash origin main && ./setup && echo "FF_OK"
|
||||
```
|
||||
|
||||
If the output ends with `FF_OK`, the upgrade is done — skip the fallback
|
||||
below entirely.
|
||||
|
||||
**Fallback (ff-only refused — local commits or divergence).** `git reset
|
||||
--hard` DESTROYS things: a clean tree with unpushed local commits still loses
|
||||
those commits. Gate it (#2517):
|
||||
|
||||
1. Run `git status --porcelain` and `git rev-list origin/main..HEAD --oneline`
|
||||
in `$INSTALL_DIR`.
|
||||
2. If BOTH are empty, the reset is provably safe — run the fallback block
|
||||
below without asking.
|
||||
3. Otherwise ask via AskUserQuestion (one-way door — destructive), listing
|
||||
exactly what will be discarded: each dirty file and each unpushed commit
|
||||
by hash + subject. Options: **A)** Discard them and upgrade (reset) —
|
||||
requires the explicit letter; **B)** Abort the upgrade so the user can
|
||||
rescue their work first (recommended when local commits exist). Never
|
||||
proceed on a vague reply.
|
||||
|
||||
```bash
|
||||
cd "$INSTALL_DIR"
|
||||
STASH_OUTPUT=$(git stash 2>&1)
|
||||
git reset --hard origin/main
|
||||
./setup
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user