Skip to content

worktree: isolate concurrent runs#16

Merged
arighi merged 1 commit into
NVIDIA:mainfrom
fallintoplace:fix/isolate-worktree-runs
Jul 10, 2026
Merged

worktree: isolate concurrent runs#16
arighi merged 1 commit into
NVIDIA:mainfrom
fallintoplace:fix/isolate-worktree-runs

Conversation

@fallintoplace

Copy link
Copy Markdown
Contributor

Summary

  • Put generated worktrees under a process-specific run directory so same-command runs do not share <command>/<sha> paths.
  • Make startup cleanup non-destructive: it still prunes missing Git worktree records, but leaves existing on-disk worktree directories alone.
  • Add tests for the new path layout, actual worktree creation, and preserving existing command worktree dirs during startup cleanup.

Testing

  • cargo test worktree::tests
  • cargo test

Comment thread src/worktree.rs Outdated
/// present, so the worktree dirs don't show up as untracked in
/// `git status` of the main checkout.
pub fn sweep_stale(main_repo: &Path, command_label: &str, dest: &VerboseDest) -> Result<()> {
pub fn sweep_stale(main_repo: &Path, _command_label: &str, dest: &VerboseDest) -> Result<()> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're not properly cleaning stale worktrees now, sweep_stale() only runs git worktree prune, which removes registry entries only when their directories are already missing. In case of a crash/SIGKILL the worktree directory still exists. Can you check if that's the case / fix this? Thanks.

@arighi

arighi commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Can you add your Signed-off-by line to the commit message? Thanks.

@nirmoy nirmoy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two cleanup regressions need addressing.

  1. sweep_stale() at src/worktree.rs:146-159 now leaves every existing directory and only runs git worktree prune --expire=now. Prune retains registered worktrees whose directories still exist, exactly the state left by SIGKILL, a host crash, or failed Drop cleanup. Repeated interrupted build/test runs can therefore retain full worktrees and large in-tree build artifacts indefinitely. A shell reproducer confirmed the worktree remained both present and registered after the new sweep.

  2. The new layout creates <command>/<run-id>/<sha>, but Drop removes only the <sha> worktree. Neither Drop nor the revised sweep removes the empty run-ID parent, so every successful boro invocation leaves one directory behind. A normal create/drop reproducer left the parent present.

Please introduce a safe ownership/liveness mechanism for stale run cleanup (for example, a per-run lease/lock plus conservative stale detection), remove empty run parents after successful cleanup, and cover both crash-orphan and normal-drop behavior with tests. Do not reintroduce deletion of another live process's worktree.

Also add the mandatory Signed-off-by trailer.

The three new worktree tests and current CI pass, but they currently assert preservation without covering eventual stale reclamation.

@arighi arighi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the conflict with the latest main, with this change a cleanup may follow a symlink outside its intended directory and delete unrelated data. Cleanup should reject symlinked directories and verify that every deletion remains within the expected directory tree.

@fallintoplace fallintoplace force-pushed the fix/isolate-worktree-runs branch from 6c719cf to 35518a4 Compare July 9, 2026 17:35
Generated worktrees now live under per-run directories so the same
command can review, build, or test the same commit concurrently
without reusing one shared <command>/<sha> checkout.

Each run keeps a lease lock file. sweep_stale() only reclaims runs
whose lease can be acquired, which lets us clean up crash-orphaned
registered worktrees without deleting another live process's checkout.
Unknown no-lock directories are still preserved conservatively.

Drop and startup sweep now remove empty run and command directories
when cleanup succeeds. The stale sweep also rejects symlinked cleanup
paths and only deletes direct child directories under the expected
command tree.

The tests cover the new path layout, stale registered worktree
reclamation, live-run preservation, empty parent cleanup, and the new
symlink safety guardrails.

Signed-off-by: Minh Vu <vuhoangminh97@gmail.com>
@fallintoplace fallintoplace force-pushed the fix/isolate-worktree-runs branch from 35518a4 to 15bf584 Compare July 9, 2026 17:44

@arighi arighi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@arighi arighi merged commit ecaa042 into NVIDIA:main Jul 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants