Skip to content

worktree: release frees slots with a missing lease record or directory - #9759

Open
TrapsterDK wants to merge 2 commits into
mainfrom
fix-worktree-release
Open

TrapsterDK wants to merge 2 commits into
mainfrom
fix-worktree-release

Conversation

@TrapsterDK

@TrapsterDK TrapsterDK commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #9755

release now frees a slot whose checkout is registered but whose lease record is missing (the usual dirty/unpushed checks still run), and returns success when the slot directory is already gone instead of failing with 'cannot start git'. Tests added for both. Ran //cli/worktree:dx_worktree_test; no nested-Bazel or consumer tests run.
A slot whose directory is gone is dropped before the lease-holder check, so any session can drop another session's record; nothing is left to lose there. A missing record leaves the holder unknown, so releasing needs a clean, pushed checkout or --force.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xut2hwESun1HL2eSVd1d5B

@TrapsterDK TrapsterDK added the needs-review Touches review paths; needs a second-session Review: comment label Nov 9, 2026
@TrapsterDK

Copy link
Copy Markdown
Collaborator Author

Review: changes requested

CI: the only analysis failure is the @dx_elixir / elixir_toolchain one that #9760 fixed on main. I found no other failing check.

  1. cli/worktree/src/ops.rs:1004 (gone_slot): a free slot is locked in git with FREE_LOCK_REASON (set at ops.rs:1104), and git worktree prune skips locked worktrees. If the directory of a free slot is deleted, release drops the record and reports success, but git keeps the registration. next_slot then hands out the same number, because the record and the directory are both gone, and git worktree add for that path fails with "is a missing but locked worktree". Run worktree unlock <path> before prune, as teardown does at ops.rs:1154. release_succeeds_when_the_slot_directory_is_already_gone only covers a held slot, which is not locked. Please add a case for a free slot with its directory removed, followed by ops::add.
  2. cli/worktree/src/ops.rs:1020: orphan_record builds a record held by the caller. That makes record.held_by(who) true, so a missing record skips the "leased to another holder" refusal. The dirty and unpushed checks still protect the work, but stop_server still runs against a slot another live session may be using. Consider requiring --force, or leaving the holder unknown, when the record is missing and the checkout is not detached and clean.
  3. cli/worktree/src/ops.rs:1030: gone_slot runs before the held_by / slot_leased check. Any session can therefore drop another session's lease record when the directory is missing. This is probably fine, since nothing is left to lose, but it is a behaviour change worth stating in the PR description.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xut2hwESun1HL2eSVd1d5B

@TrapsterDK
TrapsterDK force-pushed the fix-worktree-release branch from 50fcc2c to 873da87 Compare November 9, 2026 11:42
@TrapsterDK

Copy link
Copy Markdown
Collaborator Author

Fixed: (1) gone_slot now runs worktree unlock before prune, with a test releasing a free slot whose directory is gone followed by ops::add reusing it; (2) orphan_record no longer claims the releaser as holder (holder unknown), so the holder check stays: a record-less slot needs a clean pushed tree or --force, with a test; (3) stated the gone-directory behaviour in the PR description. Rebased on origin/main; dx_worktree_test passes.

🤖 Generated with Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review Touches review paths; needs a second-session Review: comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dx worktree release fails with 'no lease record' and 'cannot start git'

1 participant