@@ -161,6 +161,7 @@ impl Worktree {
entries_by_id_edits.push(Edit::Insert(PathEntry {
id: entry.id,
path: entry.path.clone(),
+ is_ignored: entry.is_ignored,
scan_id: 0,
}));
entries_by_path_edits.push(Edit::Insert(entry));
@@ -1083,7 +1084,7 @@ impl LocalWorktree {
async move {
let mut prev_snapshot = snapshot;
while let Ok(snapshot) = snapshots_to_send_rx.recv().await {
- let message = snapshot.build_update(&prev_snapshot, remote_id);
+ let message = snapshot.build_update(&prev_snapshot, remote_id, false);
match rpc.send(message).await {
Ok(()) => prev_snapshot = snapshot,
Err(err) => log::error!("error sending snapshot diff {}", err),
@@ -1140,6 +1141,7 @@ impl LocalWorktree {
let entries = snapshot
.entries_by_path
.cursor::<(), ()>()
+ .filter(|e| !e.is_ignored)
.map(Into::into)
.collect();
proto::ShareWorktree {
@@ -1373,11 +1375,24 @@ impl Snapshot {
self.id
}
- pub fn build_update(&self, other: &Self, worktree_id: u64) -> proto::UpdateWorktree {
+ pub fn build_update(
+ &self,
+ other: &Self,
+ worktree_id: u64,
+ include_ignored: bool,
+ ) -> proto::UpdateWorktree {
let mut updated_entries = Vec::new();
let mut removed_entries = Vec::new();
- let mut self_entries = self.entries_by_id.cursor::<(), ()>().peekable();
- let mut other_entries = other.entries_by_id.cursor::<(), ()>().peekable();
+ let mut self_entries = self
+ .entries_by_id
+ .cursor::<(), ()>()
+ .filter(|e| include_ignored || !e.is_ignored)
+ .peekable();
+ let mut other_entries = other
+ .entries_by_id
+ .cursor::<(), ()>()
+ .filter(|e| include_ignored || !e.is_ignored)
+ .peekable();
loop {
match (self_entries.peek(), other_entries.peek()) {
(Some(self_entry), Some(other_entry)) => match self_entry.id.cmp(&other_entry.id) {
@@ -1443,6 +1458,7 @@ impl Snapshot {
entries_by_id_edits.push(Edit::Insert(PathEntry {
id: entry.id,
path: entry.path.clone(),
+ is_ignored: entry.is_ignored,
scan_id,
}));
entries_by_path_edits.push(Edit::Insert(entry));
@@ -1526,6 +1542,7 @@ impl Snapshot {
PathEntry {
id: entry.id,
path: entry.path.clone(),
+ is_ignored: entry.is_ignored,
scan_id: self.scan_id,
},
&(),
@@ -1561,6 +1578,7 @@ impl Snapshot {
entries_by_id_edits.push(Edit::Insert(PathEntry {
id: entry.id,
path: entry.path.clone(),
+ is_ignored: entry.is_ignored,
scan_id: self.scan_id,
}));
entries_by_path_edits.push(Edit::Insert(entry));
@@ -1933,6 +1951,7 @@ impl sum_tree::Summary for EntrySummary {
struct PathEntry {
id: usize,
path: Arc<Path>,
+ is_ignored: bool,
scan_id: usize,
}
@@ -2436,6 +2455,7 @@ impl BackgroundScanner {
if entry.is_ignored != was_ignored {
let mut path_entry = snapshot.entries_by_id.get(&entry.id, &()).unwrap().clone();
path_entry.scan_id = snapshot.scan_id;
+ path_entry.is_ignored = entry.is_ignored;
entries_by_id_edits.push(Edit::Insert(path_entry));
entries_by_path_edits.push(Edit::Insert(entry));
}
@@ -3007,10 +3027,10 @@ mod tests {
// Update the remote worktree. Check that it becomes consistent with the
// local worktree.
remote.update(&mut cx, |remote, cx| {
- let update_message = tree
- .read(cx)
- .snapshot()
- .build_update(&initial_snapshot, worktree_id);
+ let update_message =
+ tree.read(cx)
+ .snapshot()
+ .build_update(&initial_snapshot, worktree_id, true);
remote
.as_remote_mut()
.unwrap()
@@ -3182,6 +3202,7 @@ mod tests {
scanner.snapshot().check_invariants();
let mut events = Vec::new();
+ let mut snapshots = Vec::new();
let mut mutations_len = operations;
while mutations_len > 1 {
if !events.is_empty() && rng.gen_bool(0.4) {
@@ -3194,6 +3215,10 @@ mod tests {
events.extend(randomly_mutate_tree(root_dir.path(), 0.6, &mut rng).unwrap());
mutations_len -= 1;
}
+
+ if rng.gen_bool(0.2) {
+ snapshots.push(scanner.snapshot());
+ }
}
log::info!("Quiescing: {:#?}", events);
smol::block_on(scanner.process_events(events));
@@ -3207,7 +3232,40 @@ mod tests {
scanner.executor.clone(),
);
smol::block_on(new_scanner.scan_dirs()).unwrap();
- assert_eq!(scanner.snapshot().to_vec(), new_scanner.snapshot().to_vec());
+ assert_eq!(
+ scanner.snapshot().to_vec(true),
+ new_scanner.snapshot().to_vec(true)
+ );
+
+ for mut prev_snapshot in snapshots {
+ let include_ignored = rng.gen::<bool>();
+ if !include_ignored {
+ let mut entries_by_path_edits = Vec::new();
+ let mut entries_by_id_edits = Vec::new();
+ for entry in prev_snapshot
+ .entries_by_id
+ .cursor::<(), ()>()
+ .filter(|e| e.is_ignored)
+ {
+ entries_by_path_edits.push(Edit::Remove(PathKey(entry.path.clone())));
+ entries_by_id_edits.push(Edit::Remove(entry.id));
+ }
+
+ prev_snapshot
+ .entries_by_path
+ .edit(entries_by_path_edits, &());
+ prev_snapshot.entries_by_id.edit(entries_by_id_edits, &());
+ }
+
+ let update = scanner
+ .snapshot()
+ .build_update(&prev_snapshot, 0, include_ignored);
+ prev_snapshot.apply_update(update).unwrap();
+ assert_eq!(
+ prev_snapshot.to_vec(true),
+ scanner.snapshot().to_vec(include_ignored)
+ );
+ }
}
fn randomly_mutate_tree(
@@ -3397,10 +3455,12 @@ mod tests {
}
}
- fn to_vec(&self) -> Vec<(&Path, u64, bool)> {
+ fn to_vec(&self, include_ignored: bool) -> Vec<(&Path, u64, bool)> {
let mut paths = Vec::new();
for entry in self.entries_by_path.cursor::<(), ()>() {
- paths.push((entry.path.as_ref(), entry.inode, entry.is_ignored));
+ if include_ignored || !entry.is_ignored {
+ paths.push((entry.path.as_ref(), entry.inode, entry.is_ignored));
+ }
}
paths.sort_by(|a, b| a.0.cmp(&b.0));
paths