From eb3357e1de4678821e77617733634fd600fd8c61 Mon Sep 17 00:00:00 2001 From: Aylin Tokuc Date: Wed, 8 Apr 2026 18:03:29 +0100 Subject: [PATCH] Fix recursive backup trees during gstack upgrade --- gstack-upgrade/SKILL.md | 6 ++++-- gstack-upgrade/SKILL.md.tmpl | 6 ++++-- test/gen-skill-docs.test.ts | 7 +++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gstack-upgrade/SKILL.md b/gstack-upgrade/SKILL.md index 07fe75192..8431c02e8 100644 --- a/gstack-upgrade/SKILL.md +++ b/gstack-upgrade/SKILL.md @@ -122,6 +122,7 @@ cd "$INSTALL_DIR" STASH_OUTPUT=$(git stash 2>&1) git fetch origin git reset --hard origin/main +find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + ./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." @@ -171,8 +172,9 @@ Tell user: "Removed vendored copy at `$LOCAL_GSTACK` (team mode active — globa **If `LOCAL_GSTACK` is non-empty AND `TEAM_MODE` is NOT `true`:** Update it by copying from the freshly-upgraded primary install (same approach as README vendored install): ```bash mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak" -cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK" -rm -rf "$LOCAL_GSTACK/.git" +mkdir -p "$LOCAL_GSTACK" +rsync -a --exclude='.git' --exclude='.bak*' "$INSTALL_DIR/" "$LOCAL_GSTACK/" +find "$LOCAL_GSTACK" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + cd "$LOCAL_GSTACK" && ./setup rm -rf "$LOCAL_GSTACK.bak" ``` diff --git a/gstack-upgrade/SKILL.md.tmpl b/gstack-upgrade/SKILL.md.tmpl index af4bcd236..063cff034 100644 --- a/gstack-upgrade/SKILL.md.tmpl +++ b/gstack-upgrade/SKILL.md.tmpl @@ -124,6 +124,7 @@ cd "$INSTALL_DIR" STASH_OUTPUT=$(git stash 2>&1) git fetch origin git reset --hard origin/main +find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + ./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." @@ -173,8 +174,9 @@ Tell user: "Removed vendored copy at `$LOCAL_GSTACK` (team mode active — globa **If `LOCAL_GSTACK` is non-empty AND `TEAM_MODE` is NOT `true`:** Update it by copying from the freshly-upgraded primary install (same approach as README vendored install): ```bash mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak" -cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK" -rm -rf "$LOCAL_GSTACK/.git" +mkdir -p "$LOCAL_GSTACK" +rsync -a --exclude='.git' --exclude='.bak*' "$INSTALL_DIR/" "$LOCAL_GSTACK/" +find "$LOCAL_GSTACK" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + cd "$LOCAL_GSTACK" && ./setup rm -rf "$LOCAL_GSTACK.bak" ``` diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index a555104d1..1330d5f93 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -354,6 +354,13 @@ describe('gen-skill-docs', () => { expect(qaOnlyContent).toContain('Phase 6'); }); + test('gstack-upgrade generated skill excludes backup trees during upgrade sync', () => { + const content = fs.readFileSync(path.join(ROOT, 'gstack-upgrade', 'SKILL.md'), 'utf-8'); + expect(content).toContain(`find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} +`); + expect(content).toContain(`rsync -a --exclude='.git' --exclude='.bak*' "$INSTALL_DIR/" "$LOCAL_GSTACK/"`); + expect(content).toContain(`find "$LOCAL_GSTACK" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} +`); + }); + test('qa-only has no-fix guardrails', () => { const qaOnlyContent = fs.readFileSync(path.join(ROOT, 'qa-only', 'SKILL.md'), 'utf-8'); expect(qaOnlyContent).toContain('Never fix bugs');