fix(lanes,git): harden the lane git surface and fix client races in the Changes panel
Server (git-diff.js, git-ops.js, worktree.js, routes/lanes.js): - Every lane git call runs with GIT_LITERAL_PATHSPECS=1 and -z porcelain, so a file name is a file name, never a glob, and odd names parse correctly. - A lane that is a subdirectory of its repo sees and acts on ONLY its own paths (reads, stage/unstage/discard/commit, and gitFacts.files). - Any file named settings.local.json (the lane's router API key) is refused as 403 ESECRET on disk (symlinks resolved) and at every committed rev. - commit refuses with 400 ESTAGEDOUTSIDE while anything outside the lane is staged (checked with --no-renames, so a move into the lane is caught). - push resolves its remote (upstream → only remote → origin), else 400 ENOREMOTE; unstaging a rename unstages both halves. - Git writes serialize on the repo's git dir, not the lane id, so two lanes on one index cannot collide on index.lock. - git refusing an action (a numeric exit status) answers 409 EGIT with git's stderr instead of a 500 carrying a numeric code; one shared parseNumstat. Client: - Changes panel: no stale answer from a previous lane or an older quick-open query repaints the panel; discard disarms on lane switch; Enter on a file path opens it instead of folding; bounded tree expand-all. - Large diffs (> 500 rows) render only the visible rows, with stable width and in-sync split columns; mirrored split scroll is clamped. - Git bar: no "in sync" without counts, a clear no-remote message, branch list re-read after a switch, and no previous-lane facts after a lane switch. - Tooltips no longer flicker or close on unrelated scrolls.
This commit is contained in:
@@ -245,10 +245,11 @@ describe("AddLaneModal — picking an existing branch (issue #34)", () => {
|
||||
await user.type(repoField, "/Users/tester/projects/repo");
|
||||
await screen.findByLabelText("Branch to fork from");
|
||||
await user.type(screen.getByLabelText("Title"), "Auto named");
|
||||
// The placeholder previews the name the server will pick.
|
||||
// No `feat/…` guess: the prefix is the server's LANE_BRANCH_PREFIX, which
|
||||
// the form cannot see, so the placeholder only says the field is optional.
|
||||
expect(screen.getByLabelText("New branch name")).toHaveAttribute(
|
||||
"placeholder",
|
||||
"feat/auto-named"
|
||||
"Automatic — named from the title"
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Add lane" }));
|
||||
|
||||
Reference in New Issue
Block a user