refactor(workspaces): drop the unused locked worktree flag

Nothing consumed GitWorktreeInfo.locked: a locked worktree is a real checkout
and stays a usable workspace, so no caller needs to distinguish it. Unknown
porcelain keys are already ignored, so parsing it was speculative.

The parser test still feeds a real `locked` line and asserts it is ignored, and
the service test still pins that a present, non-prunable worktree is kept, so
the policy stays covered without the field.
This commit is contained in:
Federico Jaramillo Martinez
2026-07-26 22:25:59 +02:00
parent d7fc25312d
commit 9848fc3e40
3 changed files with 7 additions and 8 deletions
@@ -38,15 +38,17 @@ describe("parseGitWorktreeList", () => {
]); ]);
}); });
it("reports prunable with its reason and locked with or without a reason", () => { it("reports prunable, and leaves a locked worktree looking like the usable checkout it is", () => {
expect(parseGitWorktreeList(removedAndLocked)).toEqual([ expect(parseGitWorktreeList(removedAndLocked)).toEqual([
{ path: "/repo", branch: "main" }, { path: "/repo", branch: "main" },
{ path: "/repo-worktrees/gone", branch: "gone", prunable: true }, { path: "/repo-worktrees/gone", branch: "gone", prunable: true },
{ path: "/repo-worktrees/kept", branch: "kept", locked: true }, // `locked` is ignored: a locked worktree is a real checkout and stays a usable
// workspace, so nothing downstream needs to distinguish it.
{ path: "/repo-worktrees/kept", branch: "kept" },
]); ]);
const bareLocked = ["worktree /repo-worktrees/kept", "HEAD abc", "detached", "locked", ""].join("\n"); const bareLocked = ["worktree /repo-worktrees/kept", "HEAD abc", "detached", "locked", ""].join("\n");
expect(parseGitWorktreeList(bareLocked)).toEqual([{ path: "/repo-worktrees/kept", detached: true, locked: true }]); expect(parseGitWorktreeList(bareLocked)).toEqual([{ path: "/repo-worktrees/kept", detached: true }]);
}); });
it("reads bare repositories and ignores chunks without a worktree path", () => { it("reads bare repositories and ignores chunks without a worktree path", () => {
@@ -11,8 +11,6 @@ export interface GitWorktreeInfo {
detached?: boolean; detached?: boolean;
/** Git reports a linked worktree as prunable when its checkout directory no longer exists. */ /** Git reports a linked worktree as prunable when its checkout directory no longer exists. */
prunable?: boolean; prunable?: boolean;
/** Git reports a locked worktree with a bare `locked` line, optionally followed by a reason. */
locked?: boolean;
} }
export async function isGitRepository(path: string): Promise<boolean> { export async function isGitRepository(path: string): Promise<boolean> {
@@ -46,7 +44,6 @@ export function parseGitWorktreeList(stdout: string): GitWorktreeInfo[] {
if (key === "bare") info.bare = true; if (key === "bare") info.bare = true;
if (key === "detached") info.detached = true; if (key === "detached") info.detached = true;
if (key === "prunable") info.prunable = true; if (key === "prunable") info.prunable = true;
if (key === "locked") info.locked = true;
} }
return info; return info;
}).filter((w) => w.path); }).filter((w) => w.path);
@@ -31,10 +31,10 @@ describe("WorkspaceService.list", () => {
expect(workspaces.map((workspace) => workspace.path)).toEqual(["/repo", "/repo-worktrees/live"]); expect(workspaces.map((workspace) => workspace.path)).toEqual(["/repo", "/repo-worktrees/live"]);
}); });
it("keeps a locked worktree, which is still a real checkout", async () => { it("keeps a worktree that is present but not prunable, such as a locked one", async () => {
const service = serviceFor([ const service = serviceFor([
{ path: "/repo", branch: "main" }, { path: "/repo", branch: "main" },
{ path: "/repo-worktrees/kept", branch: "kept", locked: true }, { path: "/repo-worktrees/kept", branch: "kept" },
]); ]);
const workspaces = await service.list(project); const workspaces = await service.list(project);