project: Always allocate WorktreeIDs on the remote client (#47936)

Closes https://github.com/zed-industries/zed/issues/40342

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth authored and GitHub committed 2026-01-29 15:31:13 +00:00
1 parent 7efedfa812
commit b26bc404ea
13 files changed
+187 -48

No files matched your search

+1 -1
View File
@@ -2575,7 +2575,7 @@ mod tests {
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1);
WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize)
worktrees[0].read(cx).id()
});
// Open a file in dir2 to create navigation history.
@@ -388,6 +388,7 @@ mod tests {
use fs::FakeFs;
use gpui::TestAppContext;
use project::WorktreeId;
use rand::Rng as _;
use serde_json::json;
use settings::SettingsStore;
@@ -736,6 +737,7 @@ mod tests {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -760,6 +762,7 @@ mod tests {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -819,6 +822,7 @@ mod tests {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
+11 -16
View File
@@ -1210,10 +1210,7 @@ async fn test_create_file_for_multiple_worktrees(cx: &mut TestAppContext) {
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let (_worktree_id1, worktree_id2) = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
(
WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize),
WorktreeId::from_usize(worktrees[1].entity_id().as_u64() as usize),
)
(worktrees[0].read(cx).id(), worktrees[1].read(cx).id())
});
let b_path = ProjectPath {
@@ -1342,7 +1339,7 @@ async fn test_path_distance_ordering(cx: &mut TestAppContext) {
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1);
WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize)
worktrees[0].read(cx).id()
});
// When workspace has an active item, sort items which are closer to that item
@@ -1430,7 +1427,7 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1);
WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize)
worktrees[0].read(cx).id()
});
// Open and close panels, getting their history items afterwards.
@@ -1650,7 +1647,7 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1,);
WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize)
worktrees[0].read(cx).id()
});
workspace
.update_in(cx, |workspace, window, cx| {
@@ -1674,14 +1671,12 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
"External file should get opened in a new worktree"
);
WorktreeId::from_usize(
worktrees
.into_iter()
.find(|worktree| worktree.entity_id().as_u64() as usize != worktree_id.to_usize())
.expect("New worktree should have a different id")
.entity_id()
.as_u64() as usize,
)
worktrees
.into_iter()
.find(|worktree| worktree.read(cx).id() != worktree_id)
.expect("New worktree should have a different id")
.read(cx)
.id()
});
cx.dispatch_action(workspace::CloseActiveItem {
save_intent: None,
@@ -1807,7 +1802,7 @@ async fn test_search_preserves_history_items(cx: &mut gpui::TestAppContext) {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1,);
WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize)
worktrees[0].read(cx).id()
});
// generate some history to select from
+8 -3
View File
@@ -40,6 +40,7 @@ use crate::{
lsp_store::{SymbolLocation, log_store::LogKind},
project_search::SearchResultsHandle,
trusted_worktrees::{PathTrust, RemoteHostLocation, TrustedWorktrees},
worktree_store::WorktreeIdCounter,
};
pub use agent_registry_store::{AgentRegistryStore, RegistryAgent};
pub use agent_server_store::{
@@ -1118,7 +1119,8 @@ impl Project {
cx.spawn(async move |this, cx| Self::send_buffer_ordered_messages(this, rx, cx).await)
.detach();
let snippets = SnippetProvider::new(fs.clone(), BTreeSet::from_iter([]), cx);
let worktree_store = cx.new(|_| WorktreeStore::local(false, fs.clone()));
let worktree_store =
cx.new(|cx| WorktreeStore::local(false, fs.clone(), WorktreeIdCounter::get(cx)));
if flags.init_worktree_trust {
trusted_worktrees::track_worktree_trust(
worktree_store.clone(),
@@ -1325,12 +1327,13 @@ impl Project {
remote.connection_options(),
)
});
let worktree_store = cx.new(|_| {
let worktree_store = cx.new(|cx| {
WorktreeStore::remote(
false,
remote_proto.clone(),
REMOTE_SERVER_PROJECT_ID,
path_style,
WorktreeIdCounter::get(cx),
)
});
@@ -1553,6 +1556,7 @@ impl Project {
remote_proto.add_entity_message_handler(Self::handle_find_search_candidates_cancel);
BufferStore::init(&remote_proto);
WorktreeStore::init_remote(&remote_proto);
LspStore::init(&remote_proto);
SettingsObserver::init(&remote_proto);
TaskStore::init(Some(&remote_proto));
@@ -1632,12 +1636,13 @@ impl Project {
PathStyle::Posix
};
let worktree_store = cx.new(|_| {
let worktree_store = cx.new(|cx| {
WorktreeStore::remote(
true,
client.clone().into(),
response.payload.project_id,
path_style,
WorktreeIdCounter::get(cx),
)
});
let buffer_store = cx.new(|cx| {
+79 -3
View File
@@ -1,6 +1,9 @@
use std::{
path::{Path, PathBuf},
sync::{Arc, atomic::AtomicUsize},
sync::{
Arc,
atomic::{AtomicU64, AtomicUsize},
},
};
use anyhow::{Context as _, Result, anyhow, bail};
@@ -8,8 +11,10 @@ use collections::HashMap;
use fs::{Fs, copy_recursive};
use futures::{FutureExt, future::Shared};
use gpui::{
App, AppContext as _, AsyncApp, Context, Entity, EntityId, EventEmitter, Task, WeakEntity,
App, AppContext as _, AsyncApp, Context, Entity, EntityId, EventEmitter, Global, Task,
WeakEntity,
};
use itertools::Either;
use rpc::{
AnyProtoClient, ErrorExt, TypedEnvelope,
proto::{self, REMOTE_SERVER_PROJECT_ID},
@@ -38,8 +43,30 @@ enum WorktreeStoreState {
},
}
#[derive(Clone)]
pub struct WorktreeIdCounter(Arc<AtomicU64>);
impl Default for WorktreeIdCounter {
fn default() -> Self {
Self(Arc::new(AtomicU64::new(1)))
}
}
impl WorktreeIdCounter {
pub fn get(cx: &mut App) -> Self {
cx.default_global::<Self>().clone()
}
fn next(&self) -> u64 {
self.0.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
}
}
impl Global for WorktreeIdCounter {}
pub struct WorktreeStore {
next_entry_id: Arc<AtomicUsize>,
next_worktree_id: WorktreeIdCounter,
downstream_client: Option<(AnyProtoClient, u64)>,
retain_worktrees: bool,
worktrees: Vec<WorktreeHandle>,
@@ -74,9 +101,18 @@ impl WorktreeStore {
client.add_entity_request_handler(Self::handle_expand_all_for_project_entry);
}
pub fn local(retain_worktrees: bool, fs: Arc<dyn Fs>) -> Self {
pub fn init_remote(client: &AnyProtoClient) {
client.add_entity_request_handler(Self::handle_allocate_worktree_id);
}
pub fn local(
retain_worktrees: bool,
fs: Arc<dyn Fs>,
next_worktree_id: WorktreeIdCounter,
) -> Self {
Self {
next_entry_id: Default::default(),
next_worktree_id,
loading_worktrees: Default::default(),
downstream_client: None,
worktrees: Vec::new(),
@@ -92,9 +128,11 @@ impl WorktreeStore {
upstream_client: AnyProtoClient,
upstream_project_id: u64,
path_style: PathStyle,
next_worktree_id: WorktreeIdCounter,
) -> Self {
Self {
next_entry_id: Default::default(),
next_worktree_id,
loading_worktrees: Default::default(),
downstream_client: None,
worktrees: Vec::new(),
@@ -109,6 +147,31 @@ impl WorktreeStore {
}
}
pub fn next_worktree_id(&self) -> impl Future<Output = Result<WorktreeId>> + use<> {
let strategy = match (&self.state, &self.downstream_client) {
// we are a remote server, the client is in charge of assigning worktree ids
(WorktreeStoreState::Local { .. }, Some((client, REMOTE_SERVER_PROJECT_ID))) => {
Either::Left(client.clone())
}
// we are just a local zed project, we can assign ids
(WorktreeStoreState::Local { .. }, _) => Either::Right(self.next_worktree_id.next()),
// we are connected to a remote server, we are in charge of assigning worktree ids
(WorktreeStoreState::Remote { .. }, _) => Either::Right(self.next_worktree_id.next()),
};
async move {
match strategy {
Either::Left(client) => Ok(client
.request(proto::AllocateWorktreeId {
project_id: REMOTE_SERVER_PROJECT_ID,
})
.await?
.worktree_id),
Either::Right(id) => Ok(id),
}
.map(WorktreeId::from_proto)
}
}
pub fn disable_scanner(&mut self) {
self.scanning_enabled = false;
}
@@ -600,13 +663,17 @@ impl WorktreeStore {
let next_entry_id = self.next_entry_id.clone();
let scanning_enabled = self.scanning_enabled;
let next_worktree_id = self.next_worktree_id();
cx.spawn(async move |this, cx| {
let worktree_id = next_worktree_id.await?;
let worktree = Worktree::local(
SanitizedPath::cast_arc(abs_path.clone()),
visible,
fs,
next_entry_id,
scanning_enabled,
worktree_id,
cx,
)
.await?;
@@ -1078,6 +1145,15 @@ impl WorktreeStore {
Worktree::handle_expand_all_for_entry(worktree, envelope.payload, cx).await
}
pub async fn handle_allocate_worktree_id(
_this: Entity<Self>,
_envelope: TypedEnvelope<proto::AllocateWorktreeId>,
cx: AsyncApp,
) -> Result<proto::AllocateWorktreeIdResponse> {
let worktree_id = cx.update(|cx| WorktreeIdCounter::get(cx).next());
Ok(proto::AllocateWorktreeIdResponse { worktree_id })
}
pub fn fs(&self) -> Option<Arc<dyn Fs>> {
match &self.state {
WorktreeStoreState::Local { fs } => Some(fs.clone()),
@@ -2,8 +2,8 @@ use anyhow::Result;
use collections::HashMap;
use gpui::{AppContext, AsyncApp, SharedString, Task, TestAppContext};
use node_runtime::NodeRuntime;
use project::agent_server_store::*;
use project::worktree_store::WorktreeStore;
use project::{agent_server_store::*, worktree_store::WorktreeIdCounter};
use std::{any::Any, path::PathBuf, sync::Arc};
#[test]
@@ -131,7 +131,8 @@ fn archive_launcher_constructs_with_all_fields() {
async fn archive_agent_uses_extension_and_agent_id_for_cache_key(cx: &mut TestAppContext) {
let fs = fs::FakeFs::new(cx.background_executor.clone());
let http_client = http_client::FakeHttpClient::with_404_response();
let worktree_store = cx.new(|_| WorktreeStore::local(false, fs.clone()));
let worktree_store =
cx.new(|cx| WorktreeStore::local(false, fs.clone(), WorktreeIdCounter::get(cx)));
let project_environment = cx.new(|cx| {
crate::ProjectEnvironment::new(None, worktree_store.downgrade(), None, false, cx)
});
@@ -212,7 +213,8 @@ async fn test_node_command_uses_managed_runtime(cx: &mut TestAppContext) {
let fs = fs::FakeFs::new(cx.background_executor.clone());
let http_client = http_client::FakeHttpClient::with_404_response();
let node_runtime = NodeRuntime::unavailable();
let worktree_store = cx.new(|_| WorktreeStore::local(false, fs.clone()));
let worktree_store =
cx.new(|cx| WorktreeStore::local(false, fs.clone(), WorktreeIdCounter::get(cx)));
let project_environment = cx.new(|cx| {
crate::ProjectEnvironment::new(None, worktree_store.downgrade(), None, false, cx)
});
@@ -255,7 +257,8 @@ async fn test_commands_run_in_extraction_directory(cx: &mut TestAppContext) {
let fs = fs::FakeFs::new(cx.background_executor.clone());
let http_client = http_client::FakeHttpClient::with_404_response();
let node_runtime = NodeRuntime::unavailable();
let worktree_store = cx.new(|_| WorktreeStore::local(false, fs.clone()));
let worktree_store =
cx.new(|cx| WorktreeStore::local(false, fs.clone(), WorktreeIdCounter::get(cx)));
let project_environment = cx.new(|cx| {
crate::ProjectEnvironment::new(None, worktree_store.downgrade(), None, false, cx)
});
+21 -10
View File
@@ -162,22 +162,33 @@ message UpdateUserSettings {
}
message TrustWorktrees {
uint64 project_id = 1;
repeated PathTrust trusted_paths = 2;
uint64 project_id = 1;
repeated PathTrust trusted_paths = 2;
}
message PathTrust {
oneof content {
uint64 worktree_id = 2;
string abs_path = 3;
}
oneof content {
uint64 worktree_id = 2;
string abs_path = 3;
}
reserved 1;
reserved 1;
}
message RestrictWorktrees {
uint64 project_id = 1;
repeated uint64 worktree_ids = 3;
uint64 project_id = 1;
repeated uint64 worktree_ids = 3;
reserved 2;
reserved 2;
}
// Request from the remote server to the client to allocate a new worktree ID.
// This allows the client to maintain a single WorktreeIdCounter that prevents
// ID collisions when connected to multiple remote servers.
message AllocateWorktreeId {
uint64 project_id = 1;
}
message AllocateWorktreeIdResponse {
uint64 worktree_id = 1;
}
+4 -1
View File
@@ -455,7 +455,10 @@ message Envelope {
FindSearchCandidatesChunk find_search_candidates_chunk = 409;
FindSearchCandidatesCancelled find_search_candidates_cancelled = 410;
GetContextServerCommand get_context_server_command = 411;
ContextServerCommand context_server_command = 412; // current max
ContextServerCommand context_server_command = 412;
AllocateWorktreeId allocate_worktree_id = 413;
AllocateWorktreeIdResponse allocate_worktree_id_response = 414; // current max
}
reserved 87 to 88;
+4
View File
@@ -33,6 +33,8 @@ messages!(
(AddWorktree, Foreground),
(AddWorktreeResponse, Foreground),
(AdvertiseContexts, Foreground),
(AllocateWorktreeId, Foreground),
(AllocateWorktreeIdResponse, Foreground),
(ApplyCodeAction, Background),
(ApplyCodeActionResponse, Background),
(ApplyCompletionAdditionalEdits, Background),
@@ -352,6 +354,7 @@ messages!(
);
request_messages!(
(AllocateWorktreeId, AllocateWorktreeIdResponse),
(ApplyCodeAction, ApplyCodeActionResponse),
(
ApplyCompletionAdditionalEdits,
@@ -561,6 +564,7 @@ entity_messages!(
{project_id, ShareProject},
AddProjectCollaborator,
AddWorktree,
AllocateWorktreeId,
ApplyCodeAction,
ApplyCompletionAdditionalEdits,
BlameBuffer,
+10 -4
View File
@@ -25,7 +25,7 @@ use project::{
search::SearchQuery,
task_store::TaskStore,
trusted_worktrees::{PathTrust, RemoteHostLocation, TrustedWorktrees},
worktree_store::WorktreeStore,
worktree_store::{WorktreeIdCounter, WorktreeStore},
};
use rpc::{
AnyProtoClient, TypedEnvelope,
@@ -98,7 +98,7 @@ impl HeadlessProject {
languages::init(languages.clone(), fs.clone(), node_runtime.clone(), cx);
let worktree_store = cx.new(|cx| {
let mut store = WorktreeStore::local(true, fs.clone());
let mut store = WorktreeStore::local(true, fs.clone(), WorktreeIdCounter::get(cx));
store.shared(REMOTE_SERVER_PROJECT_ID, session.clone(), cx);
store
});
@@ -482,7 +482,12 @@ impl HeadlessProject {
}
}
};
let next_worktree_id = this
.update(&mut cx, |this, cx| {
this.worktree_store
.update(cx, |worktree_store, _| worktree_store.next_worktree_id())
})
.await?;
let worktree = this
.read_with(&cx.clone(), |this, _| {
Worktree::local(
@@ -491,6 +496,7 @@ impl HeadlessProject {
this.fs.clone(),
this.next_entry_id.clone(),
true,
next_worktree_id,
&mut cx,
)
})
@@ -754,7 +760,7 @@ impl HeadlessProject {
buffer_store.open_buffer(
ProjectPath {
worktree_id: worktree.read(cx).id(),
path: path,
path,
},
cx,
)
+6 -5
View File
@@ -368,6 +368,7 @@ impl Worktree {
fs: Arc<dyn Fs>,
next_entry_id: Arc<AtomicUsize>,
scanning_enabled: bool,
worktree_id: WorktreeId,
cx: &mut AsyncApp,
) -> Result<Entity<Self>> {
let abs_path = path.into();
@@ -404,7 +405,7 @@ impl Worktree {
repo_exclude_by_work_dir_abs_path: Default::default(),
git_repositories: Default::default(),
snapshot: Snapshot::new(
cx.entity_id().as_u64(),
worktree_id,
abs_path
.file_name()
.and_then(|f| f.to_str())
@@ -493,7 +494,7 @@ impl Worktree {
) -> Entity<Self> {
cx.new(|cx: &mut Context<Self>| {
let snapshot = Snapshot::new(
worktree.id,
WorktreeId::from_proto(worktree.id),
RelPath::from_proto(&worktree.root_name)
.unwrap_or_else(|_| RelPath::empty().into()),
Path::new(&worktree.abs_path).into(),
@@ -1831,7 +1832,7 @@ impl LocalWorktree {
.unbounded_send((self.snapshot(), Arc::default()))
.ok();
let worktree_id = cx.entity_id().as_u64();
let worktree_id = self.id.to_proto();
let _maintain_remote_snapshot = cx.background_spawn(async move {
let mut is_first = true;
while let Some((snapshot, entry_changes)) = snapshots_rx.next().await {
@@ -2137,13 +2138,13 @@ impl RemoteWorktree {
impl Snapshot {
pub fn new(
id: u64,
id: WorktreeId,
root_name: Arc<RelPath>,
abs_path: Arc<Path>,
path_style: PathStyle,
) -> Self {
Snapshot {
id: WorktreeId::from_usize(id as usize),
id,
abs_path: SanitizedPath::from_arc(abs_path),
path_style,
root_char_bag: root_name
+30 -1
View File
@@ -12,7 +12,7 @@ use rand::prelude::*;
use worktree::{Entry, EntryKind, Event, PathChange, Worktree, WorktreeModelHandle};
use serde_json::json;
use settings::SettingsStore;
use settings::{SettingsStore, WorktreeId};
use std::{
env,
fmt::Write,
@@ -49,6 +49,7 @@ async fn test_traversal(cx: &mut TestAppContext) {
fs,
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -114,6 +115,7 @@ async fn test_circular_symlinks(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -214,6 +216,7 @@ async fn test_symlinks_pointing_outside(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -365,6 +368,7 @@ async fn test_renaming_case_only(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -443,6 +447,7 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -608,6 +613,7 @@ async fn test_dirs_no_longer_ignored(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -709,6 +715,7 @@ async fn test_write_file(cx: &mut TestAppContext) {
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -807,6 +814,7 @@ async fn test_file_scan_inclusions(cx: &mut TestAppContext) {
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -873,6 +881,7 @@ async fn test_file_scan_exclusions_overrules_inclusions(cx: &mut TestAppContext)
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -932,6 +941,7 @@ async fn test_file_scan_inclusions_reindexes_on_setting_change(cx: &mut TestAppC
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1018,6 +1028,7 @@ async fn test_file_scan_exclusions(cx: &mut TestAppContext) {
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1100,6 +1111,7 @@ async fn test_hidden_files(cx: &mut TestAppContext) {
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1211,6 +1223,7 @@ async fn test_fs_events_in_exclusions(cx: &mut TestAppContext) {
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1323,6 +1336,7 @@ async fn test_fs_events_in_dot_git_worktree(cx: &mut TestAppContext) {
Arc::new(RealFs::new(None, cx.executor())),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1362,6 +1376,7 @@ async fn test_create_directory_during_initial_scan(cx: &mut TestAppContext) {
fs,
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1431,6 +1446,7 @@ async fn test_create_dir_all_on_create_entry(cx: &mut TestAppContext) {
fs_fake,
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1473,6 +1489,7 @@ async fn test_create_dir_all_on_create_entry(cx: &mut TestAppContext) {
fs_real,
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1582,6 +1599,7 @@ async fn test_create_file_in_expanded_gitignored_dir(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1678,6 +1696,7 @@ async fn test_fs_event_for_gitignored_dir_does_not_lose_contents(cx: &mut TestAp
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1756,6 +1775,7 @@ async fn test_random_worktree_operations_during_initial_scan(
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1847,6 +1867,7 @@ async fn test_random_worktree_changes(cx: &mut TestAppContext, mut rng: StdRng)
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -1920,6 +1941,7 @@ async fn test_random_worktree_changes(cx: &mut TestAppContext, mut rng: StdRng)
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2244,6 +2266,7 @@ async fn test_private_single_file_worktree(cx: &mut TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2277,6 +2300,7 @@ async fn test_repository_above_root(executor: BackgroundExecutor, cx: &mut TestA
fs.clone(),
Arc::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2343,6 +2367,7 @@ async fn test_global_gitignore(executor: BackgroundExecutor, cx: &mut TestAppCon
fs.clone(),
Arc::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2449,6 +2474,7 @@ async fn test_repo_exclude(executor: BackgroundExecutor, cx: &mut TestAppContext
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2665,6 +2691,7 @@ async fn test_load_file_encoding(cx: &mut TestAppContext) {
fs,
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2728,6 +2755,7 @@ async fn test_write_file_encoding(cx: &mut gpui::TestAppContext) {
fs.clone(),
Default::default(),
true,
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
@@ -2866,6 +2894,7 @@ async fn test_refresh_entries_for_paths_creates_ancestors(cx: &mut TestAppContex
fs.clone(),
Default::default(),
false, // Disable scanning so the initial scan doesn't discover any entries
WorktreeId::from_proto(0),
&mut cx.to_async(),
)
.await
+2
View File
@@ -5,6 +5,7 @@ use std::{
use fs::RealFs;
use gpui::Application;
use settings::WorktreeId;
use worktree::Worktree;
fn main() {
@@ -27,6 +28,7 @@ fn main() {
fs,
Arc::new(AtomicUsize::new(0)),
true,
WorktreeId::from_proto(0),
cx,
)
.await