diff --git a/src/resources/extensions/gsd/auto-worktree.ts b/src/resources/extensions/gsd/auto-worktree.ts index c7081335e..874a9e699 100644 --- a/src/resources/extensions/gsd/auto-worktree.ts +++ b/src/resources/extensions/gsd/auto-worktree.ts @@ -6,7 +6,7 @@ * manages create, enter, detect, and teardown for auto-mode worktrees. */ -import { existsSync, cpSync, readFileSync, writeFileSync, readdirSync, mkdirSync, realpathSync, utimesSync } from "node:fs"; +import { existsSync, cpSync, readFileSync, writeFileSync, readdirSync, mkdirSync, realpathSync, utimesSync, unlinkSync } from "node:fs"; import { isAbsolute, join, resolve } from "node:path"; import { copyWorktreeDb, reconcileWorktreeDb, isDbAvailable } from "./gsd-db.js"; import { execSync, execFileSync } from "node:child_process"; @@ -560,6 +560,16 @@ export function mergeMilestoneToMain( // when main is already checked out in the project-root worktree, #757) const currentBranchAtBase = nativeGetCurrentBranch(originalBasePath_); if (currentBranchAtBase !== mainBranch) { + // Remove untracked .gsd/ state files that may conflict with the branch + // being checked out. These are regenerated by doctor/rebuildState and + // are not meaningful in the main working tree — the worktree had the + // real state. Without this, `git checkout main` fails with + // "Your local changes would be overwritten" (#827). + const gsdStateFiles = ["STATE.md", "completed-units.json", "auto.lock"]; + for (const f of gsdStateFiles) { + const p = join(originalBasePath_, ".gsd", f); + try { unlinkSync(p); } catch { /* non-fatal — file may not exist */ } + } nativeCheckoutBranch(originalBasePath_, mainBranch); }