fix: remove untracked .gsd/ state files before milestone merge checkout (#827) (#834)

When merging a milestone back to main, `git checkout main` fails if
untracked .gsd/ state files (STATE.md, completed-units.json, auto.lock)
in the working tree conflict with tracked files on the branch.

Remove these known GSD-managed state files before checkout. They are
runtime artifacts regenerated by doctor/rebuildState and are not
meaningful in the main working tree — the worktree had the real state.
This commit is contained in:
Tom Boucher 2026-03-17 09:49:26 -04:00 committed by GitHub
parent d94728aa7e
commit 2f459b5d03

View file

@ -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);
}