mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-10 05:37:29 +03:00
Merge pull request #2477 from zed-industries/fixup-some-more-worktree-bugs
Fixup some more worktree bugs
This commit is contained in:
commit
16cab5d021
@ -572,15 +572,15 @@ impl FakeFs {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn pause_events(&self) {
|
||||
pub fn pause_events(&self) {
|
||||
self.state.lock().events_paused = true;
|
||||
}
|
||||
|
||||
pub async fn buffered_event_count(&self) -> usize {
|
||||
pub fn buffered_event_count(&self) -> usize {
|
||||
self.state.lock().buffered_events.len()
|
||||
}
|
||||
|
||||
pub async fn flush_events(&self, count: usize) {
|
||||
pub fn flush_events(&self, count: usize) {
|
||||
self.state.lock().flush_events(count);
|
||||
}
|
||||
|
||||
@ -832,14 +832,16 @@ impl Fs for FakeFs {
|
||||
|
||||
let old_path = normalize_path(old_path);
|
||||
let new_path = normalize_path(new_path);
|
||||
|
||||
let mut state = self.state.lock();
|
||||
let moved_entry = state.write_path(&old_path, |e| {
|
||||
if let btree_map::Entry::Occupied(e) = e {
|
||||
Ok(e.remove())
|
||||
Ok(e.get().clone())
|
||||
} else {
|
||||
Err(anyhow!("path does not exist: {}", &old_path.display()))
|
||||
}
|
||||
})?;
|
||||
|
||||
state.write_path(&new_path, |e| {
|
||||
match e {
|
||||
btree_map::Entry::Occupied(mut e) => {
|
||||
@ -855,6 +857,17 @@ impl Fs for FakeFs {
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
state
|
||||
.write_path(&old_path, |e| {
|
||||
if let btree_map::Entry::Occupied(e) = e {
|
||||
Ok(e.remove())
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
state.emit_event(&[old_path, new_path]);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ impl<'a> From<ProjectEntryId> for WorkDirectoryEntry {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LocalSnapshot {
|
||||
ignores_by_parent_abs_path: HashMap<Arc<Path>, (Arc<Gitignore>, usize)>,
|
||||
ignores_by_parent_abs_path: HashMap<Arc<Path>, (Arc<Gitignore>, bool)>, // (gitignore, needs_update)
|
||||
// The ProjectEntryId corresponds to the entry for the .git dir
|
||||
// work_directory_id
|
||||
git_repositories: TreeMap<ProjectEntryId, LocalRepositoryEntry>,
|
||||
@ -1882,10 +1882,8 @@ impl LocalSnapshot {
|
||||
let abs_path = self.abs_path.join(&entry.path);
|
||||
match smol::block_on(build_gitignore(&abs_path, fs)) {
|
||||
Ok(ignore) => {
|
||||
self.ignores_by_parent_abs_path.insert(
|
||||
abs_path.parent().unwrap().into(),
|
||||
(Arc::new(ignore), self.scan_id),
|
||||
);
|
||||
self.ignores_by_parent_abs_path
|
||||
.insert(abs_path.parent().unwrap().into(), (Arc::new(ignore), true));
|
||||
}
|
||||
Err(error) => {
|
||||
log::error!(
|
||||
@ -1955,10 +1953,8 @@ impl LocalSnapshot {
|
||||
}
|
||||
|
||||
if let Some(ignore) = ignore {
|
||||
self.ignores_by_parent_abs_path.insert(
|
||||
self.abs_path.join(&parent_path).into(),
|
||||
(ignore, self.scan_id),
|
||||
);
|
||||
self.ignores_by_parent_abs_path
|
||||
.insert(self.abs_path.join(&parent_path).into(), (ignore, false));
|
||||
}
|
||||
|
||||
if parent_path.file_name() == Some(&DOT_GIT) {
|
||||
@ -2062,11 +2058,11 @@ impl LocalSnapshot {
|
||||
|
||||
if path.file_name() == Some(&GITIGNORE) {
|
||||
let abs_parent_path = self.abs_path.join(path.parent().unwrap());
|
||||
if let Some((_, scan_id)) = self
|
||||
if let Some((_, needs_update)) = self
|
||||
.ignores_by_parent_abs_path
|
||||
.get_mut(abs_parent_path.as_path())
|
||||
{
|
||||
*scan_id = self.snapshot.scan_id;
|
||||
*needs_update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2609,7 +2605,7 @@ impl BackgroundScanner {
|
||||
self.snapshot
|
||||
.lock()
|
||||
.ignores_by_parent_abs_path
|
||||
.insert(ancestor.into(), (ignore.into(), 0));
|
||||
.insert(ancestor.into(), (ignore.into(), false));
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -2662,7 +2658,7 @@ impl BackgroundScanner {
|
||||
// these before handling changes reported by the filesystem.
|
||||
request = self.refresh_requests_rx.recv().fuse() => {
|
||||
let Ok((paths, barrier)) = request else { break };
|
||||
if !self.process_refresh_request(paths, barrier).await {
|
||||
if !self.process_refresh_request(paths.clone(), barrier).await {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2673,7 +2669,7 @@ impl BackgroundScanner {
|
||||
while let Poll::Ready(Some(more_events)) = futures::poll!(events_rx.next()) {
|
||||
paths.extend(more_events.into_iter().map(|e| e.path));
|
||||
}
|
||||
self.process_events(paths).await;
|
||||
self.process_events(paths.clone()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3181,16 +3177,18 @@ impl BackgroundScanner {
|
||||
let mut snapshot = self.snapshot.lock().clone();
|
||||
let mut ignores_to_update = Vec::new();
|
||||
let mut ignores_to_delete = Vec::new();
|
||||
for (parent_abs_path, (_, scan_id)) in &snapshot.ignores_by_parent_abs_path {
|
||||
if let Ok(parent_path) = parent_abs_path.strip_prefix(&snapshot.abs_path) {
|
||||
if *scan_id > snapshot.completed_scan_id
|
||||
&& snapshot.entry_for_path(parent_path).is_some()
|
||||
{
|
||||
ignores_to_update.push(parent_abs_path.clone());
|
||||
let abs_path = snapshot.abs_path.clone();
|
||||
for (parent_abs_path, (_, needs_update)) in &mut snapshot.ignores_by_parent_abs_path {
|
||||
if let Ok(parent_path) = parent_abs_path.strip_prefix(&abs_path) {
|
||||
if *needs_update {
|
||||
*needs_update = false;
|
||||
if snapshot.snapshot.entry_for_path(parent_path).is_some() {
|
||||
ignores_to_update.push(parent_abs_path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let ignore_path = parent_path.join(&*GITIGNORE);
|
||||
if snapshot.entry_for_path(ignore_path).is_none() {
|
||||
if snapshot.snapshot.entry_for_path(ignore_path).is_none() {
|
||||
ignores_to_delete.push(parent_abs_path.clone());
|
||||
}
|
||||
}
|
||||
@ -4632,6 +4630,7 @@ mod tests {
|
||||
.detach();
|
||||
});
|
||||
|
||||
fs.as_fake().pause_events();
|
||||
let mut snapshots = Vec::new();
|
||||
let mut mutations_len = operations;
|
||||
while mutations_len > 1 {
|
||||
@ -4641,16 +4640,16 @@ mod tests {
|
||||
randomly_mutate_worktree(worktree, &mut rng, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
.log_err();
|
||||
} else {
|
||||
randomly_mutate_fs(&fs, root_dir, 1.0, &mut rng).await;
|
||||
}
|
||||
|
||||
let buffered_event_count = fs.as_fake().buffered_event_count().await;
|
||||
let buffered_event_count = fs.as_fake().buffered_event_count();
|
||||
if buffered_event_count > 0 && rng.gen_bool(0.3) {
|
||||
let len = rng.gen_range(0..=buffered_event_count);
|
||||
log::info!("flushing {} events", len);
|
||||
fs.as_fake().flush_events(len).await;
|
||||
fs.as_fake().flush_events(len);
|
||||
} else {
|
||||
randomly_mutate_fs(&fs, root_dir, 0.6, &mut rng).await;
|
||||
mutations_len -= 1;
|
||||
@ -4666,7 +4665,7 @@ mod tests {
|
||||
}
|
||||
|
||||
log::info!("quiescing");
|
||||
fs.as_fake().flush_events(usize::MAX).await;
|
||||
fs.as_fake().flush_events(usize::MAX);
|
||||
cx.foreground().run_until_parked();
|
||||
let snapshot = worktree.read_with(cx, |tree, _| tree.as_local().unwrap().snapshot());
|
||||
snapshot.check_invariants();
|
||||
@ -4726,6 +4725,7 @@ mod tests {
|
||||
rng: &mut impl Rng,
|
||||
cx: &mut ModelContext<Worktree>,
|
||||
) -> Task<Result<()>> {
|
||||
log::info!("mutating worktree");
|
||||
let worktree = worktree.as_local_mut().unwrap();
|
||||
let snapshot = worktree.snapshot();
|
||||
let entry = snapshot.entries(false).choose(rng).unwrap();
|
||||
@ -4787,6 +4787,7 @@ mod tests {
|
||||
insertion_probability: f64,
|
||||
rng: &mut impl Rng,
|
||||
) {
|
||||
log::info!("mutating fs");
|
||||
let mut files = Vec::new();
|
||||
let mut dirs = Vec::new();
|
||||
for path in fs.as_fake().paths() {
|
||||
|
Loading…
Reference in New Issue
Block a user