From cc97e682d5e51859e7c0bcc6ed4627cc5b148c80 Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Thu, 12 Dec 2024 01:53:00 -0500 Subject: [PATCH] worktree: Fix privacy check for singleton files (#21861) Closes #20676 Release Notes: - Fixed private files not being redacted when not part of a larger worktree --- crates/language/src/buffer.rs | 5 ---- crates/worktree/src/worktree.rs | 33 +++++++++++++++------------ crates/worktree/src/worktree_tests.rs | 23 +++++++++++++++++++ 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index b3a953084759b..925e648d9f9aa 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -427,11 +427,6 @@ pub trait LocalFile: File { /// Loads the file's contents from disk. fn load_bytes(&self, cx: &AppContext) -> Task>>; - - /// Returns true if the file should not be shared with collaborators. - fn is_private(&self, _: &AppContext) -> bool { - false - } } /// The auto-indent behavior associated with an editing operation. diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 86981687ce2a1..249d04cb7bac7 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -409,24 +409,11 @@ impl Worktree { abs_path .file_name() .map_or(String::new(), |f| f.to_string_lossy().to_string()), - abs_path, + abs_path.clone(), ), root_file_handle, }; - if let Some(metadata) = metadata { - snapshot.insert_entry( - Entry::new( - Arc::from(Path::new("")), - &metadata, - &next_entry_id, - snapshot.root_char_bag, - None, - ), - fs.as_ref(), - ); - } - let worktree_id = snapshot.id(); let settings_location = Some(SettingsLocation { worktree_id, @@ -445,10 +432,26 @@ impl Worktree { }) .detach(); + let share_private_files = false; + if let Some(metadata) = metadata { + let mut entry = Entry::new( + Arc::from(Path::new("")), + &metadata, + &next_entry_id, + snapshot.root_char_bag, + None, + ); + if !metadata.is_dir { + entry.is_private = !share_private_files + && settings.is_path_private(abs_path.file_name().unwrap().as_ref()); + } + snapshot.insert_entry(entry, fs.as_ref()); + } + let (scan_requests_tx, scan_requests_rx) = channel::unbounded(); let (path_prefixes_to_scan_tx, path_prefixes_to_scan_rx) = channel::unbounded(); let mut worktree = LocalWorktree { - share_private_files: false, + share_private_files, next_entry_id, snapshot, is_scanning: watch::channel_with(true), diff --git a/crates/worktree/src/worktree_tests.rs b/crates/worktree/src/worktree_tests.rs index 121caf0b7b2fc..8b93396e24b95 100644 --- a/crates/worktree/src/worktree_tests.rs +++ b/crates/worktree/src/worktree_tests.rs @@ -2712,6 +2712,29 @@ async fn test_propagate_git_statuses(cx: &mut TestAppContext) { ); } +#[gpui::test] +async fn test_private_single_file_worktree(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.background_executor.clone()); + fs.insert_tree("/", json!({".env": "PRIVATE=secret\n"})) + .await; + let tree = Worktree::local( + Path::new("/.env"), + true, + fs.clone(), + Default::default(), + &mut cx.to_async(), + ) + .await + .unwrap(); + cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) + .await; + tree.read_with(cx, |tree, _| { + let entry = tree.entry_for_path("").unwrap(); + assert!(entry.is_private); + }); +} + #[track_caller] fn check_propagated_statuses( snapshot: &Snapshot,