Skip to content

Do not eagerly expand subtrees on lazy loaded repo update#12211

Merged
kevinyang372 merged 2 commits into
masterfrom
kevin/lazy-root-placeholder-on-create
Jun 5, 2026
Merged

Do not eagerly expand subtrees on lazy loaded repo update#12211
kevinyang372 merged 2 commits into
masterfrom
kevin/lazy-root-placeholder-on-create

Conversation

@kevinyang372
Copy link
Copy Markdown
Member

@kevinyang372 kevinyang372 commented Jun 4, 2026

Description

For lazy-loaded (non-git) roots, the file watcher previously eagerly materialized the full subtree of any newly-created directory, even though lazy roots only materialize what the user has actually expanded. This PR inserts a newly-created directory as an unloaded placeholder instead; its subtree is built on demand when the user expands it via load_directory.

Concretely, in compute_file_tree_mutations, when lazy_load is set, a created directory now emits an AddEmptyDirectory placeholder mutation and skips the eager build_tree traversal entirely. Eager (git/recursive) roots are unchanged and still build the full subtree.

This also removes the now-unnecessary watch-on-create (new_dirs) logic: because lazy roots no longer eagerly load descendants, there are no loaded-but-unwatched directories. On Linux (non-recursive watching) this closes a gap where a bulk-created nested directory tree could leave descendant directories loaded but unwatched — they are now placeholders, watched only when expanded (which already registers a watch via watch_subdir).

Net effect in local_model.rs is a reduction in code.

Linked Issue

  • The linked issue is labeled ready-to-spec or ready-to-implement.
  • Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).

Testing

This is internal repo-metadata logic with no UI surface, covered by unit tests:

  • Added lazy_root_created_directory_inserted_as_placeholder: asserts a lazy root inserts the created directory as an unloaded placeholder with its subtree not materialized, while an eager root fully materializes it.

  • Existing compute_file_tree_mutations call sites updated for the new lazy_load argument.

  • cargo nextest run -p repo_metadata --features local_fs passes (100 tests), with cargo clippy and ./script/format clean.

  • I have manually tested my changes locally with ./script/run

Screenshots / Videos

N/A — no user-visible/UI change.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Warp conversation: https://staging.warp.dev/conversation/652230d5-e5fb-41bf-af9d-b478310176cf

CHANGELOG-NONE

@cla-bot cla-bot Bot added the cla-signed label Jun 4, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented Jun 4, 2026

@kevinyang372

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Member Author

kevinyang372 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR changes lazy-loaded repository updates so newly created directories are inserted as unloaded placeholders instead of eagerly materializing their subtrees, and updates tests for lazy vs eager roots.

Concerns

  • The new lazy directory branch skips the standing-query and directory-symlink handling that the existing subtree builder performed, so project rules/skills created under a new lazy directory can remain undiscovered until the directory is expanded.
  • This is a user-facing file-tree behavior change, but the PR description does not include screenshots or a screen recording demonstrating the lazy directory creation/expansion flow end to end. Please attach visual evidence from a local desktop run or a coding agent with computer use enabled.

Security

No security-specific findings from the supplemental pass.

Spec validation

No approved or repository spec context was provided for this PR.

Verdict

Found: 0 critical, 2 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread crates/repo_metadata/src/local_model.rs
@kevinyang372 kevinyang372 force-pushed the kevin/register-non-recursive-watcher-for-linux branch from 909261e to cbd84ec Compare June 4, 2026 20:18
@kevinyang372 kevinyang372 force-pushed the kevin/lazy-root-placeholder-on-create branch 2 times, most recently from 88a3753 to 2134af0 Compare June 4, 2026 20:24
@kevinyang372 kevinyang372 requested a review from alokedesai June 4, 2026 21:29
Comment on lines -597 to -609
// Only a non-recursive root (lazy non-git roots on
// Linux) needs to watch newly added directories: nothing
// under such a root is covered by a recursive watch, so
// each new dir needs its own watch. Collect them before
// the mutations are consumed.
//
// Recursive roots don't need this: non-ignored new dirs
// are auto-followed by the recursive backend, and
// gitignored new dirs are added as lazy placeholders that
// get watched only when the user expands them (see
// `load_directory`).
let new_dirs: Vec<StandardizedPath> = if matches!(
model.repo_watches.get(&repo_path).map(|w| w.root_mode),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What was this trying to do before? Like what necessitated it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not really anything necessitated it -- the agent added it and I realized the whole architecture of updating the repo metadata tree for lazy loaded repos is borked

Comment thread crates/repo_metadata/src/local_model.rs Outdated
@kevinyang372 kevinyang372 force-pushed the kevin/lazy-root-placeholder-on-create branch from 2134af0 to 63532cd Compare June 5, 2026 03:22
@kevinyang372 kevinyang372 force-pushed the kevin/register-non-recursive-watcher-for-linux branch from 49fb6f8 to b614b4e Compare June 5, 2026 03:22
Base automatically changed from kevin/register-non-recursive-watcher-for-linux to master June 5, 2026 03:39
For lazy (non-git) roots, the file watcher eagerly materialized the full
subtree of any newly-created directory, even though lazy roots only
materialize what the user has expanded. On Linux (non-recursive watching)
this also left the loaded descendants unwatched (only the subtree root got a
watch), so changes inside them were missed.

Build added directories as unloaded placeholders for lazy roots instead
(depth 0), still collecting standing-query results across their descendants so
skills/rules are discovered. The directory is materialized and watched on
demand when the user expands it via load_directory. This removes the
now-unnecessary watch-on-create logic.
@kevinyang372 kevinyang372 force-pushed the kevin/lazy-root-placeholder-on-create branch from fba4d15 to a04c130 Compare June 5, 2026 03:40
@kevinyang372 kevinyang372 enabled auto-merge (squash) June 5, 2026 03:40
@kevinyang372 kevinyang372 merged commit 03ad9ea into master Jun 5, 2026
26 checks passed
@kevinyang372 kevinyang372 deleted the kevin/lazy-root-placeholder-on-create branch June 5, 2026 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants