mirror of
https://github.com/zed-industries/zed.git
synced 2024-10-28 01:07:09 +00:00
Recompute ignore status when .gitignore changes or for new entries
This commit is contained in:
parent
499e55e950
commit
af3bc236b7
2 changed files with 189 additions and 21 deletions
|
@ -17,11 +17,12 @@ use postage::{
|
||||||
};
|
};
|
||||||
use smol::{channel::Sender, Timer};
|
use smol::{channel::Sender, Timer};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{BTreeMap, HashMap, HashSet},
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fmt, fs,
|
fmt, fs,
|
||||||
future::Future,
|
future::Future,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
|
mem,
|
||||||
ops::{AddAssign, Deref},
|
ops::{AddAssign, Deref},
|
||||||
os::unix::fs::MetadataExt,
|
os::unix::fs::MetadataExt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -30,6 +31,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
const GITIGNORE: &'static str = ".gitignore";
|
const GITIGNORE: &'static str = ".gitignore";
|
||||||
|
const EDIT_BATCH_LEN: usize = 2000;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum ScanState {
|
enum ScanState {
|
||||||
|
@ -58,6 +60,7 @@ impl Worktree {
|
||||||
let id = ctx.model_id();
|
let id = ctx.model_id();
|
||||||
let snapshot = Snapshot {
|
let snapshot = Snapshot {
|
||||||
id,
|
id,
|
||||||
|
scan_id: 0,
|
||||||
path: path.into(),
|
path: path.into(),
|
||||||
root_inode: None,
|
root_inode: None,
|
||||||
ignores: Default::default(),
|
ignores: Default::default(),
|
||||||
|
@ -230,9 +233,10 @@ impl fmt::Debug for Worktree {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Snapshot {
|
pub struct Snapshot {
|
||||||
id: usize,
|
id: usize,
|
||||||
|
scan_id: usize,
|
||||||
path: Arc<Path>,
|
path: Arc<Path>,
|
||||||
root_inode: Option<u64>,
|
root_inode: Option<u64>,
|
||||||
ignores: HashMap<u64, Gitignore>,
|
ignores: HashMap<u64, (Arc<Gitignore>, usize)>,
|
||||||
entries: SumTree<Entry>,
|
entries: SumTree<Entry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,15 +276,7 @@ impl Snapshot {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_path_ignored(&self, path: impl AsRef<Path>) -> Result<bool> {
|
fn is_inode_ignored(&self, mut inode: u64) -> Result<bool> {
|
||||||
if let Some(inode) = self.inode_for_path(path.as_ref()) {
|
|
||||||
self.is_inode_ignored(inode)
|
|
||||||
} else {
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_inode_ignored(&self, mut inode: u64) -> Result<bool> {
|
|
||||||
let mut components = Vec::new();
|
let mut components = Vec::new();
|
||||||
let mut relative_path = PathBuf::new();
|
let mut relative_path = PathBuf::new();
|
||||||
let mut entry = self
|
let mut entry = self
|
||||||
|
@ -297,7 +293,7 @@ impl Snapshot {
|
||||||
components.push(child_name.as_ref());
|
components.push(child_name.as_ref());
|
||||||
inode = parent;
|
inode = parent;
|
||||||
|
|
||||||
if let Some(ignore) = self.ignores.get(&inode) {
|
if let Some((ignore, _)) = self.ignores.get(&inode) {
|
||||||
relative_path.clear();
|
relative_path.clear();
|
||||||
relative_path.extend(components.iter().rev());
|
relative_path.extend(components.iter().rev());
|
||||||
match ignore.matched_path_or_any_parents(&relative_path, entry.is_dir()) {
|
match ignore.matched_path_or_any_parents(&relative_path, entry.is_dir()) {
|
||||||
|
@ -506,7 +502,8 @@ impl Snapshot {
|
||||||
log::info!("error in ignore file {:?} - {:?}", path, err);
|
log::info!("error in ignore file {:?} - {:?}", path, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ignores.insert(dir_inode, ignore);
|
self.ignores
|
||||||
|
.insert(dir_inode, (Arc::new(ignore), self.scan_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_ignore_file(&mut self, dir_inode: u64) {
|
fn remove_ignore_file(&mut self, dir_inode: u64) {
|
||||||
|
@ -585,16 +582,37 @@ pub enum Entry {
|
||||||
is_symlink: bool,
|
is_symlink: bool,
|
||||||
children: Arc<[(u64, Arc<OsStr>)]>,
|
children: Arc<[(u64, Arc<OsStr>)]>,
|
||||||
pending: bool,
|
pending: bool,
|
||||||
|
is_ignored: Option<bool>,
|
||||||
},
|
},
|
||||||
File {
|
File {
|
||||||
inode: u64,
|
inode: u64,
|
||||||
parent: Option<u64>,
|
parent: Option<u64>,
|
||||||
is_symlink: bool,
|
is_symlink: bool,
|
||||||
path: PathEntry,
|
path: PathEntry,
|
||||||
|
is_ignored: Option<bool>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entry {
|
impl Entry {
|
||||||
|
fn is_ignored(&self) -> Option<bool> {
|
||||||
|
match self {
|
||||||
|
Entry::Dir { is_ignored, .. } => *is_ignored,
|
||||||
|
Entry::File { is_ignored, .. } => *is_ignored,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_ignored(&mut self, ignored: bool) {
|
||||||
|
match self {
|
||||||
|
Entry::Dir { is_ignored, .. } => *is_ignored = Some(ignored),
|
||||||
|
Entry::File {
|
||||||
|
is_ignored, path, ..
|
||||||
|
} => {
|
||||||
|
*is_ignored = Some(ignored);
|
||||||
|
path.is_ignored = Some(ignored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inode(&self) -> u64 {
|
fn inode(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
Entry::Dir { inode, .. } => *inode,
|
Entry::Dir { inode, .. } => *inode,
|
||||||
|
@ -625,6 +643,7 @@ impl sum_tree::Item for Entry {
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
recompute_is_ignored: self.is_ignored().is_none(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,12 +660,14 @@ impl sum_tree::KeyedItem for Entry {
|
||||||
pub struct EntrySummary {
|
pub struct EntrySummary {
|
||||||
max_ino: u64,
|
max_ino: u64,
|
||||||
file_count: usize,
|
file_count: usize,
|
||||||
|
recompute_is_ignored: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AddAssign<&'a EntrySummary> for EntrySummary {
|
impl<'a> AddAssign<&'a EntrySummary> for EntrySummary {
|
||||||
fn add_assign(&mut self, rhs: &'a EntrySummary) {
|
fn add_assign(&mut self, rhs: &'a EntrySummary) {
|
||||||
self.max_ino = rhs.max_ino;
|
self.max_ino = rhs.max_ino;
|
||||||
self.file_count += rhs.file_count;
|
self.file_count += rhs.file_count;
|
||||||
|
self.recompute_is_ignored |= rhs.recompute_is_ignored;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,6 +742,8 @@ impl BackgroundScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_dirs(&self) -> io::Result<()> {
|
fn scan_dirs(&self) -> io::Result<()> {
|
||||||
|
self.snapshot.lock().scan_id += 1;
|
||||||
|
|
||||||
let path = self.path();
|
let path = self.path();
|
||||||
let metadata = fs::metadata(&path)?;
|
let metadata = fs::metadata(&path)?;
|
||||||
let inode = metadata.ino();
|
let inode = metadata.ino();
|
||||||
|
@ -735,6 +758,7 @@ impl BackgroundScanner {
|
||||||
is_symlink,
|
is_symlink,
|
||||||
children: Arc::from([]),
|
children: Arc::from([]),
|
||||||
pending: true,
|
pending: true,
|
||||||
|
is_ignored: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -776,14 +800,17 @@ impl BackgroundScanner {
|
||||||
None,
|
None,
|
||||||
Entry::File {
|
Entry::File {
|
||||||
parent: None,
|
parent: None,
|
||||||
path: PathEntry::new(inode, &relative_path),
|
path: PathEntry::new(inode, &relative_path, None),
|
||||||
inode,
|
inode,
|
||||||
is_symlink,
|
is_symlink,
|
||||||
|
is_ignored: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
snapshot.root_inode = Some(inode);
|
snapshot.root_inode = Some(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.recompute_ignore_statuses();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,6 +838,7 @@ impl BackgroundScanner {
|
||||||
is_symlink: child_is_symlink,
|
is_symlink: child_is_symlink,
|
||||||
children: Arc::from([]),
|
children: Arc::from([]),
|
||||||
pending: true,
|
pending: true,
|
||||||
|
is_ignored: None,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
new_jobs.push(ScanJob {
|
new_jobs.push(ScanJob {
|
||||||
|
@ -824,9 +852,10 @@ impl BackgroundScanner {
|
||||||
child_name,
|
child_name,
|
||||||
Entry::File {
|
Entry::File {
|
||||||
parent: Some(job.inode),
|
parent: Some(job.inode),
|
||||||
path: PathEntry::new(child_inode, &child_relative_path),
|
path: PathEntry::new(child_inode, &child_relative_path, None),
|
||||||
inode: child_inode,
|
inode: child_inode,
|
||||||
is_symlink: child_is_symlink,
|
is_symlink: child_is_symlink,
|
||||||
|
is_ignored: None,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
@ -842,6 +871,8 @@ impl BackgroundScanner {
|
||||||
|
|
||||||
fn process_events(&self, mut events: Vec<fsevent::Event>) -> bool {
|
fn process_events(&self, mut events: Vec<fsevent::Event>) -> bool {
|
||||||
let mut snapshot = self.snapshot();
|
let mut snapshot = self.snapshot();
|
||||||
|
snapshot.scan_id += 1;
|
||||||
|
|
||||||
let root_path = if let Ok(path) = snapshot.path.canonicalize() {
|
let root_path = if let Ok(path) = snapshot.path.canonicalize() {
|
||||||
path
|
path
|
||||||
} else {
|
} else {
|
||||||
|
@ -910,9 +941,133 @@ impl BackgroundScanner {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.recompute_ignore_statuses();
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn recompute_ignore_statuses(&self) {
|
||||||
|
self.compute_ignore_status_for_new_ignores();
|
||||||
|
self.compute_ignore_status_for_new_entries();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_ignore_status_for_new_ignores(&self) {
|
||||||
|
struct IgnoreJob {
|
||||||
|
inode: u64,
|
||||||
|
ignore_queue_tx: crossbeam_channel::Sender<IgnoreJob>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let snapshot = self.snapshot.lock().clone();
|
||||||
|
|
||||||
|
let mut new_ignore_parents = BTreeMap::new();
|
||||||
|
for (parent_inode, (_, scan_id)) in &snapshot.ignores {
|
||||||
|
if *scan_id == snapshot.scan_id {
|
||||||
|
let parent_path = snapshot.path_for_inode(*parent_inode, false).unwrap();
|
||||||
|
new_ignore_parents.insert(parent_path, *parent_inode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut new_ignores = new_ignore_parents.into_iter().peekable();
|
||||||
|
|
||||||
|
let (ignore_queue_tx, ignore_queue_rx) = crossbeam_channel::unbounded();
|
||||||
|
while let Some((parent_path, parent_inode)) = new_ignores.next() {
|
||||||
|
while new_ignores
|
||||||
|
.peek()
|
||||||
|
.map_or(false, |(p, _)| p.starts_with(&parent_path))
|
||||||
|
{
|
||||||
|
new_ignores.next().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
ignore_queue_tx
|
||||||
|
.send(IgnoreJob {
|
||||||
|
inode: parent_inode,
|
||||||
|
ignore_queue_tx: ignore_queue_tx.clone(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
drop(ignore_queue_tx);
|
||||||
|
|
||||||
|
self.thread_pool.scoped(|scope| {
|
||||||
|
let (edits_tx, edits_rx) = crossbeam_channel::unbounded();
|
||||||
|
|
||||||
|
scope.execute(move || {
|
||||||
|
let mut edits = Vec::new();
|
||||||
|
while let Ok(edit) = edits_rx.recv() {
|
||||||
|
edits.push(edit);
|
||||||
|
while let Ok(edit) = edits_rx.try_recv() {
|
||||||
|
edits.push(edit);
|
||||||
|
if edits.len() == EDIT_BATCH_LEN {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.snapshot.lock().entries.edit(mem::take(&mut edits));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for _ in 0..self.thread_pool.thread_count() - 1 {
|
||||||
|
let edits_tx = edits_tx.clone();
|
||||||
|
scope.execute(|| {
|
||||||
|
let edits_tx = edits_tx;
|
||||||
|
while let Ok(job) = ignore_queue_rx.recv() {
|
||||||
|
let mut entry = snapshot.entries.get(&job.inode).unwrap().clone();
|
||||||
|
entry.set_ignored(snapshot.is_inode_ignored(job.inode).unwrap());
|
||||||
|
if let Entry::Dir { children, .. } = &entry {
|
||||||
|
for (child_inode, _) in children.as_ref() {
|
||||||
|
job.ignore_queue_tx
|
||||||
|
.send(IgnoreJob {
|
||||||
|
inode: *child_inode,
|
||||||
|
ignore_queue_tx: job.ignore_queue_tx.clone(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
edits_tx.send(Edit::Insert(entry)).unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_ignore_status_for_new_entries(&self) {
|
||||||
|
let snapshot = self.snapshot.lock().clone();
|
||||||
|
|
||||||
|
let (entries_tx, entries_rx) = crossbeam_channel::unbounded();
|
||||||
|
self.thread_pool.scoped(|scope| {
|
||||||
|
let (edits_tx, edits_rx) = crossbeam_channel::unbounded();
|
||||||
|
scope.execute(move || {
|
||||||
|
let mut edits = Vec::new();
|
||||||
|
while let Ok(edit) = edits_rx.recv() {
|
||||||
|
edits.push(edit);
|
||||||
|
while let Ok(edit) = edits_rx.try_recv() {
|
||||||
|
edits.push(edit);
|
||||||
|
if edits.len() == EDIT_BATCH_LEN {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.snapshot.lock().entries.edit(mem::take(&mut edits));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.execute(|| {
|
||||||
|
let entries_tx = entries_tx;
|
||||||
|
for entry in snapshot.entries.filter::<_, ()>(|e| e.recompute_is_ignored) {
|
||||||
|
entries_tx.send(entry.clone()).unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for _ in 0..self.thread_pool.thread_count() - 2 {
|
||||||
|
let edits_tx = edits_tx.clone();
|
||||||
|
scope.execute(|| {
|
||||||
|
let edits_tx = edits_tx;
|
||||||
|
while let Ok(mut entry) = entries_rx.recv() {
|
||||||
|
entry.set_ignored(snapshot.is_inode_ignored(entry.inode()).unwrap());
|
||||||
|
edits_tx.send(Edit::Insert(entry)).unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn fs_entry_for_path(&self, root_path: &Path, path: &Path) -> Result<Option<Entry>> {
|
fn fs_entry_for_path(&self, root_path: &Path, path: &Path) -> Result<Option<Entry>> {
|
||||||
let metadata = match fs::metadata(&path) {
|
let metadata = match fs::metadata(&path) {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -947,6 +1102,7 @@ impl BackgroundScanner {
|
||||||
is_symlink,
|
is_symlink,
|
||||||
pending: true,
|
pending: true,
|
||||||
children: Arc::from([]),
|
children: Arc::from([]),
|
||||||
|
is_ignored: None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Entry::File {
|
Entry::File {
|
||||||
|
@ -958,7 +1114,9 @@ impl BackgroundScanner {
|
||||||
root_path
|
root_path
|
||||||
.parent()
|
.parent()
|
||||||
.map_or(path, |parent| path.strip_prefix(parent).unwrap()),
|
.map_or(path, |parent| path.strip_prefix(parent).unwrap()),
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
|
is_ignored: None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1143,8 +1301,10 @@ mod tests {
|
||||||
app.read(|ctx| tree.read(ctx).scan_complete()).await;
|
app.read(|ctx| tree.read(ctx).scan_complete()).await;
|
||||||
app.read(|ctx| {
|
app.read(|ctx| {
|
||||||
let tree = tree.read(ctx);
|
let tree = tree.read(ctx);
|
||||||
assert!(!tree.is_path_ignored("tracked-dir/tracked-file1").unwrap());
|
let tracked = tree.entry_for_path("tracked-dir/tracked-file1").unwrap();
|
||||||
assert!(tree.is_path_ignored("ignored-dir/ignored-file1").unwrap());
|
let ignored = tree.entry_for_path("ignored-dir/ignored-file1").unwrap();
|
||||||
|
assert_eq!(tracked.is_ignored(), Some(false));
|
||||||
|
assert_eq!(ignored.is_ignored(), Some(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
fs::write(dir.path().join("tracked-dir/tracked-file2"), "").unwrap();
|
fs::write(dir.path().join("tracked-dir/tracked-file2"), "").unwrap();
|
||||||
|
@ -1152,8 +1312,10 @@ mod tests {
|
||||||
app.read(|ctx| tree.read(ctx).next_scan_complete()).await;
|
app.read(|ctx| tree.read(ctx).next_scan_complete()).await;
|
||||||
app.read(|ctx| {
|
app.read(|ctx| {
|
||||||
let tree = tree.read(ctx);
|
let tree = tree.read(ctx);
|
||||||
assert!(!tree.is_path_ignored("tracked-dir/tracked-file2").unwrap());
|
let tracked = tree.entry_for_path("tracked-dir/tracked-file2").unwrap();
|
||||||
assert!(tree.is_path_ignored("ignored-dir/ignored-file2").unwrap());
|
let ignored = tree.entry_for_path("ignored-dir/ignored-file2").unwrap();
|
||||||
|
assert_eq!(tracked.is_ignored(), Some(false));
|
||||||
|
assert_eq!(ignored.is_ignored(), Some(true));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1189,6 +1351,7 @@ mod tests {
|
||||||
let scanner = BackgroundScanner::new(
|
let scanner = BackgroundScanner::new(
|
||||||
Arc::new(Mutex::new(Snapshot {
|
Arc::new(Mutex::new(Snapshot {
|
||||||
id: 0,
|
id: 0,
|
||||||
|
scan_id: 0,
|
||||||
path: root_dir.path().into(),
|
path: root_dir.path().into(),
|
||||||
root_inode: None,
|
root_inode: None,
|
||||||
entries: Default::default(),
|
entries: Default::default(),
|
||||||
|
@ -1219,6 +1382,7 @@ mod tests {
|
||||||
let new_scanner = BackgroundScanner::new(
|
let new_scanner = BackgroundScanner::new(
|
||||||
Arc::new(Mutex::new(Snapshot {
|
Arc::new(Mutex::new(Snapshot {
|
||||||
id: 0,
|
id: 0,
|
||||||
|
scan_id: 0,
|
||||||
path: root_dir.path().into(),
|
path: root_dir.path().into(),
|
||||||
root_inode: None,
|
root_inode: None,
|
||||||
entries: Default::default(),
|
entries: Default::default(),
|
||||||
|
|
|
@ -21,10 +21,11 @@ pub struct PathEntry {
|
||||||
pub path_chars: CharBag,
|
pub path_chars: CharBag,
|
||||||
pub path: Arc<[char]>,
|
pub path: Arc<[char]>,
|
||||||
pub lowercase_path: Arc<[char]>,
|
pub lowercase_path: Arc<[char]>,
|
||||||
|
pub is_ignored: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathEntry {
|
impl PathEntry {
|
||||||
pub fn new(ino: u64, path: &Path) -> Self {
|
pub fn new(ino: u64, path: &Path, is_ignored: Option<bool>) -> Self {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
let lowercase_path = path.to_lowercase().chars().collect::<Vec<_>>().into();
|
let lowercase_path = path.to_lowercase().chars().collect::<Vec<_>>().into();
|
||||||
let path: Arc<[char]> = path.chars().collect::<Vec<_>>().into();
|
let path: Arc<[char]> = path.chars().collect::<Vec<_>>().into();
|
||||||
|
@ -35,6 +36,7 @@ impl PathEntry {
|
||||||
path_chars,
|
path_chars,
|
||||||
path,
|
path,
|
||||||
lowercase_path,
|
lowercase_path,
|
||||||
|
is_ignored,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +198,7 @@ fn match_single_tree_paths<'a>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !include_ignored && snapshot.is_inode_ignored(path_entry.ino).unwrap_or(true) {
|
if !include_ignored && path_entry.is_ignored.unwrap_or(false) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,6 +502,7 @@ mod tests {
|
||||||
path_chars,
|
path_chars,
|
||||||
path,
|
path,
|
||||||
lowercase_path,
|
lowercase_path,
|
||||||
|
is_ignored: Some(false),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,6 +515,7 @@ mod tests {
|
||||||
match_single_tree_paths(
|
match_single_tree_paths(
|
||||||
&Snapshot {
|
&Snapshot {
|
||||||
id: 0,
|
id: 0,
|
||||||
|
scan_id: 0,
|
||||||
path: PathBuf::new().into(),
|
path: PathBuf::new().into(),
|
||||||
root_inode: None,
|
root_inode: None,
|
||||||
ignores: Default::default(),
|
ignores: Default::default(),
|
||||||
|
|
Loading…
Reference in a new issue