Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b80d604408 |
@@ -654,6 +654,11 @@ impl DraftPane {
|
||||
let project = visible[sel].project.clone();
|
||||
self.picked_cwd = Some(project.path.clone());
|
||||
self.cwd_raw_visible = false;
|
||||
// A directory that *is* a linked worktree defaults to spawning in
|
||||
// place (#91): creating a second worktree of its branch fails.
|
||||
// Turning it back on by hand still tries (git's own message),
|
||||
// which is deliberate (#91 non-goal).
|
||||
self.worktree_enabled = !project.is_worktree;
|
||||
// The scan already knows this directory's repo (#61): no probe
|
||||
// round trip needed, exactly like the web form.
|
||||
let repo = project
|
||||
@@ -1689,6 +1694,40 @@ mod tests {
|
||||
assert!(wt.create_branch);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picking_a_worktree_project_defaults_the_toggle_off() {
|
||||
let mut draft = DraftPane::default();
|
||||
let mut wt = repo_project("wt-91", "/repos/wt91", "/repos/main", 1, None);
|
||||
wt.is_worktree = true;
|
||||
draft.set_projects(
|
||||
vec![
|
||||
repo_project("main", "/repos/main", "/repos/main", 2, None),
|
||||
wt,
|
||||
],
|
||||
Utc::now(),
|
||||
);
|
||||
draft.focused_field = DraftField::DirPicker;
|
||||
typed(&mut draft, "wt-91");
|
||||
draft.on_input(&InputKey::Enter);
|
||||
|
||||
assert!(
|
||||
!draft.worktree_enabled,
|
||||
"the directory is already a worktree; spawning in place"
|
||||
);
|
||||
assert!(
|
||||
draft.build_request().unwrap().worktree.is_none(),
|
||||
"no worktree record — the session just runs there (#91)"
|
||||
);
|
||||
|
||||
// Deliberately re-enabling still works, and the scan-known base repo
|
||||
// survives so the toggle-on path needs no new probe.
|
||||
draft.focused_field = DraftField::WorktreeToggle;
|
||||
draft.on_input(&InputKey::Enter);
|
||||
assert!(draft.worktree_enabled);
|
||||
assert_eq!(draft.base_repo.as_deref(), Some(Path::new("/repos/main")));
|
||||
assert!(draft.take_gitroot_probe().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn raw_path_targets_probe_gitroot_and_resolution_feeds_the_spec() {
|
||||
let mut draft = DraftPane {
|
||||
|
||||
+13
-3
@@ -430,9 +430,19 @@ export function createSpawnForm(opts: SpawnFormOptions): SpawnFormHandle {
|
||||
cwdRawWrap.hidden = true;
|
||||
markActiveProject(project.path);
|
||||
// The scan already knows this directory is inside a repo (#61): the
|
||||
// toggle defaults back on and no /api/gitroot round trip is needed.
|
||||
wtEnabled.checked = true;
|
||||
applyProjectRepo(project.base_repo ?? project.path);
|
||||
// toggle defaults back on and no /api/gitroot round trip is needed —
|
||||
// unless the directory *is* a linked worktree itself (#91): spawning
|
||||
// in place is the only thing that works there, so default the toggle
|
||||
// off. Turning it back on by hand still tries (and fails with git's
|
||||
// own message), which is deliberate (#91 non-goal).
|
||||
wtEnabled.checked = !project.is_worktree;
|
||||
if (project.is_worktree) {
|
||||
inferredBaseRepo = null;
|
||||
wtBody.hidden = true;
|
||||
wtHint.hidden = true;
|
||||
} else {
|
||||
applyProjectRepo(project.base_repo ?? project.path);
|
||||
}
|
||||
emit();
|
||||
// Picking a project pre-selects the command it was last used with.
|
||||
const match = presets.find((p) => p.command === project.last_command && p.command !== "");
|
||||
|
||||
@@ -18,6 +18,7 @@ const BRANCHES = [
|
||||
* its branch list is still in flight. */
|
||||
function stubFetch(opts?: {
|
||||
gateBranches?: (release: () => void) => void;
|
||||
projects?: unknown[];
|
||||
}): string[] {
|
||||
const urls: string[] = [];
|
||||
const gated = new Promise<void>((resolve) => {
|
||||
@@ -37,7 +38,7 @@ function stubFetch(opts?: {
|
||||
return new Response(JSON.stringify(BRANCHES), { status: 200 });
|
||||
}
|
||||
if (url.includes("/api/projects")) {
|
||||
return new Response(JSON.stringify(PROJECTS), { status: 200 });
|
||||
return new Response(JSON.stringify(opts?.projects ?? PROJECTS), { status: 200 });
|
||||
}
|
||||
return new Response(
|
||||
JSON.stringify({ hostname: "h", version: "0", home_dir: "/home/user", presets: [] }),
|
||||
@@ -100,6 +101,34 @@ describe("spawnForm worktree defaults and branch picker (#61)", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("defaults the worktree toggle off for a row that is itself a worktree (#91)", async () => {
|
||||
urls = stubFetch({
|
||||
projects: [
|
||||
{
|
||||
path: "/home/user/wt-91",
|
||||
name: "wt-91",
|
||||
is_worktree: true,
|
||||
base_repo: "/home/user/maestro",
|
||||
last_activity: "2026-08-20T10:00:00Z",
|
||||
},
|
||||
],
|
||||
});
|
||||
handle = createSpawnForm({ onSuccess() {} });
|
||||
document.body.appendChild(handle.el);
|
||||
for (let i = 0; i < 40; i++) await Promise.resolve();
|
||||
|
||||
handle.el
|
||||
.querySelectorAll<HTMLButtonElement>(".project-row")
|
||||
.forEach((row) => row.dataset.cwd === "/home/user/wt-91" && row.click());
|
||||
await drain();
|
||||
|
||||
expect(handle.el.querySelector<HTMLInputElement>("input[name=worktree_enabled]")!.checked).toBe(
|
||||
false,
|
||||
);
|
||||
expect(urls.some((u) => u.includes("/api/gitroot"))).toBe(false);
|
||||
expect(handle.el.querySelector<HTMLElement>(".wt-body")!.hidden).toBe(true);
|
||||
});
|
||||
|
||||
it("still probes the gitroot for a free-text directory", async () => {
|
||||
const form = await mount();
|
||||
|
||||
|
||||
@@ -1215,9 +1215,6 @@ textarea {
|
||||
/* ---------- forms ---------- */
|
||||
|
||||
.spawn-form {
|
||||
width: 100%;
|
||||
max-width: 60ch;
|
||||
margin: 0 auto;
|
||||
padding: var(--sp-3);
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user