fix(file-tree): add Refresh to directory right-click menu#10551
Conversation
|
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 Powered by Oz |
There was a problem hiding this comment.
Overview
This PR adds a directory-only Refresh action to the file tree context menu and routes it through the existing local repo metadata directory-loading path.
Concerns
- The refresh helper uses the displayed file-tree root as the repository metadata key. Displayed roots can be subdirectories of the indexed repository, so refresh fails with RepoNotFound and does not update the tree in common cwd-inside-repo cases.
- This is a user-visible menu change, but the provided context includes only a manual verification note and no screenshot or screen recording. Manual testing evidence is required for changes that can be visually verified; please include screenshots or a recording showing the menu item and refresh behavior, or justify why that is not possible.
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
| return; | ||
| }; | ||
| let dir_path = item.path().clone(); | ||
| let root_path = id.root.clone(); |
There was a problem hiding this comment.
RepoNotFound for common cwd-inside-repo trees.
| let root_path = id.root.clone(); | |
| let root_path = (**root_dir.entry.root_directory()).clone(); |
42b6dd0 to
397a5a8
Compare
|
Addressed concern #1 (RepoNotFound in cwd-inside-repo case): Force-pushed a squashed single commit ( Concern #2 (visual evidence): I'll attach a screenshot/recording in a follow-up comment shortly.
|
|
/oz-review |
|
I'm re-reviewing this pull request in response to a review request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This PR adds a directory-only Refresh action to the file tree context menu and routes it through the existing local repo metadata load_directory path.
Concerns
refresh_directorycalls the existingload_directorypath for a loaded directory, but that path overlays rebuilt entries without clearing stale child mappings first. A refresh can therefore leave removed entries visible instead of reconciling the directory with disk.- Manual testing evidence is missing for this user-visible context-menu change. Please include screenshots or a screen recording that show the menu entry and refresh behavior end to end, or justify why visual evidence is not possible.
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
| .find_repository_for_path(&local_path, ctx) | ||
| .unwrap_or_else(|| id.root.clone()); | ||
| self.repository_metadata_model.update(ctx, |model, ctx| { | ||
| if let Err(err) = model.load_directory(&repo_root, &dir_path, ctx) { |
There was a problem hiding this comment.
load_directory overlays the rebuilt subtree without clearing stale child mappings first. For refresh, this leaves removed entries visible when the directory becomes empty or when expanded child directories had old descendants; replace or remove the existing subtree before loading so the UI reconciles deletions.
Adds a Refresh menu item under directory headers in the file tree right-click context menu. Re-reads the clicked directory's contents from disk (one level deep, matching lazy-load behavior) via the existing LocalRepoMetadataModel::load_directory path. Mitigates warpdotdev#10205 (and the related warpdotdev#9190, warpdotdev#9890) — Project Explorer not reflecting filesystem changes — by giving users a deliberate way to reconcile the in-memory tree with disk after watcher events drop or apply_file_tree_mutations silently skips a mutation under lazy_load when a parent's loaded flag is false. Surgical: only the targeted subtree is re-scanned, avoiding the cost of re-indexing the entire root. Resolves the indexed repository root via the existing wrapper RepoMetadataModel::find_repository_for_path before dispatching to load_directory, since the displayed file-tree root (id.root) can be a subdirectory of the indexed repository in cwd-inside-repo cases — passing the displayed root would return RepoNotFound and refresh would silently fail. Falls back to the displayed root for standalone lazy-loaded paths where the two coincide. Also fixes FileTreeState::load_at_path to clear stale entries before re-inserting. Previously it called insert_entry_at_path which only `extend`s state_map and parent_to_child_map, leaving entries for files that were deleted on disk between loads still visible in the tree. The fix is one line — `self.remove(path)` before insert. Safe for the existing first-time-expand callers (view.rs:1375 / 1413, server_model.rs:1167) because their pre-load entry is just an unloaded placeholder with no descendants in the maps, so the remove is a no-op for them. This does NOT fix the underlying watcher event drop in apply_file_tree_mutations, nor does it implement the Command Palette action requested in warpdotdev#10003 (which is tracked separately by spec PR warpdotdev#10025). Both are intentionally scoped out — this PR is only the right-click escape hatch.
397a5a8 to
1042ccf
Compare
|
Addressed the stale-entry concern. Added one line to entry.load(gitignores)?;
self.remove(path); // ← NEW: clear stale entries before re-inserting
self.insert_entry_at_path(child_path, entry);The bot is correct that Verified safe for the three existing callers of Force-pushed a single squashed commit ( Visual evidence still pending — will follow up.
|
Summary
Adds a
Refreshmenu item under directory headers in the file tree right-click context menu. Re-reads the clicked directory's contents from disk (one level deep, matching lazy-load behavior) via the existingLocalRepoMetadataModel::load_directorypath.Why
Long-standing open issues report Project Explorer / file tree failing to reflect filesystem changes after the initial scan:
Source-level: in
apply_file_tree_mutations(crates/repo_metadata/src/local_model.rs), three branches doif lazy_load && !is_parent_loaded_in_entry { continue }, silently dropping watcher mutations when a parent directory is not loaded. Combined with FSEvents itself being best-effort, the in-memory tree drifts from disk and there is currently no API or UI to reconcile.What this PR does
FileTreeAction::RefreshDirectory { id }variantRefreshafterOpen in new tabrefresh_directoryhelperRepoMetadataModel::load_directory(repo_root, dir_path, ctx), which delegates toLocalRepoMetadataModel::load_directory→Entry::load→Entry::build_tree(force-reads from disk)Surgical scope: only the targeted subtree is re-scanned. No watcher churn, no full root re-index.
FileTreeItem::Filedoes not get the option since files don't have contents to refresh.What this PR does NOT do (intentionally scoped out)
continuepaths inapply_file_tree_mutationsstill silently skip mutations. That is a separate, deeper architectural fix (would need observability + force-rescan + reconciliation hooks layered on top, see analysis in Project Explorer does not refresh to show newly created files and folders #10205).refresh_directoryhelper.Files
app/src/code/file_tree/view.rs— +42 lines, 0 deletionsVerification
cargo check -p warp --bin warp-osscleancargo clippy -p warp --bin warp-oss --no-depsno new warningswarp-ossbundle: right-click any directory header →Refreshappears afterOpen in new tab; selecting it reconciles a drifted subtreeCloses #10205