mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-11 05:00:16 +00:00
Keep ignore status up-to-date as events are processed
This commit is contained in:
parent
f770a70929
commit
111d98d6c1
2 changed files with 209 additions and 211 deletions
|
@ -19,7 +19,7 @@ use postage::{
|
|||
use smol::{channel::Sender, Timer};
|
||||
use std::{
|
||||
cmp,
|
||||
collections::{BTreeMap, HashSet},
|
||||
collections::{HashMap, HashSet},
|
||||
ffi::{CStr, OsStr},
|
||||
fmt, fs,
|
||||
future::Future,
|
||||
|
@ -216,7 +216,7 @@ pub struct Snapshot {
|
|||
scan_id: usize,
|
||||
abs_path: Arc<Path>,
|
||||
root_name_chars: Vec<char>,
|
||||
ignores: BTreeMap<u64, Arc<Gitignore>>,
|
||||
ignores: HashMap<Arc<Path>, (Arc<Gitignore>, usize)>,
|
||||
entries: SumTree<Entry>,
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,10 @@ impl Snapshot {
|
|||
FileIter::visible(self, start)
|
||||
}
|
||||
|
||||
fn child_entries<'a>(&'a self, path: &'a Path) -> ChildEntriesIter<'a> {
|
||||
ChildEntriesIter::new(path, self)
|
||||
}
|
||||
|
||||
pub fn root_entry(&self) -> &Entry {
|
||||
self.entry_for_path("").unwrap()
|
||||
}
|
||||
|
@ -269,37 +273,16 @@ impl Snapshot {
|
|||
self.entry_for_path(path.as_ref()).map(|e| e.inode())
|
||||
}
|
||||
|
||||
fn is_path_ignored(&self, path: &Path) -> Result<bool> {
|
||||
todo!();
|
||||
Ok(false)
|
||||
// let mut entry = self
|
||||
// .entry_for_path(path)
|
||||
// .ok_or_else(|| anyhow!("entry does not exist in worktree"))?;
|
||||
|
||||
// if path.starts_with(".git") {
|
||||
// Ok(true)
|
||||
// } else {
|
||||
// while let Some(parent_entry) =
|
||||
// entry.path().parent().and_then(|p| self.entry_for_path(p))
|
||||
// {
|
||||
// let parent_path = parent_entry.path();
|
||||
// if let Some((ignore, _)) = self.ignores.get(parent_path) {
|
||||
// let relative_path = path.strip_prefix(parent_path).unwrap();
|
||||
// match ignore.matched_path_or_any_parents(relative_path, entry.is_dir()) {
|
||||
// ::ignore::Match::Whitelist(_) => return Ok(false),
|
||||
// ::ignore::Match::Ignore(_) => return Ok(true),
|
||||
// ::ignore::Match::None => {}
|
||||
// }
|
||||
// }
|
||||
// entry = parent_entry;
|
||||
// }
|
||||
// Ok(false)
|
||||
// }
|
||||
}
|
||||
|
||||
fn insert_entry(&mut self, entry: Entry) {
|
||||
if !entry.is_dir() && entry.path().file_name() == Some(&GITIGNORE) {
|
||||
self.insert_ignore_file(entry.path());
|
||||
let (ignore, err) = Gitignore::new(self.abs_path.join(entry.path()));
|
||||
if let Some(err) = err {
|
||||
log::error!("error in ignore file {:?} - {:?}", entry.path(), err);
|
||||
}
|
||||
|
||||
let ignore_dir_path = entry.path().parent().unwrap();
|
||||
self.ignores
|
||||
.insert(ignore_dir_path.into(), (Arc::new(ignore), self.scan_id));
|
||||
}
|
||||
self.entries.insert(entry);
|
||||
}
|
||||
|
@ -312,9 +295,13 @@ impl Snapshot {
|
|||
) {
|
||||
let mut edits = Vec::new();
|
||||
|
||||
let mut parent_entry = self.entries.get(&PathKey(parent_path)).unwrap().clone();
|
||||
let mut parent_entry = self
|
||||
.entries
|
||||
.get(&PathKey(parent_path.clone()))
|
||||
.unwrap()
|
||||
.clone();
|
||||
if let Some(ignore) = ignore {
|
||||
self.ignores.insert(parent_entry.inode, ignore);
|
||||
self.ignores.insert(parent_path, (ignore, self.scan_id));
|
||||
}
|
||||
if matches!(parent_entry.kind, EntryKind::PendingDir) {
|
||||
parent_entry.kind = EntryKind::Dir;
|
||||
|
@ -324,9 +311,6 @@ impl Snapshot {
|
|||
edits.push(Edit::Insert(parent_entry));
|
||||
|
||||
for entry in entries {
|
||||
if !entry.is_dir() && entry.path().file_name() == Some(&GITIGNORE) {
|
||||
self.insert_ignore_file(entry.path());
|
||||
}
|
||||
edits.push(Edit::Insert(entry));
|
||||
}
|
||||
self.entries.edit(edits);
|
||||
|
@ -342,22 +326,38 @@ impl Snapshot {
|
|||
};
|
||||
self.entries = new_entries;
|
||||
|
||||
// if path.file_name() == Some(&GITIGNORE) {
|
||||
// if let Some((_, scan_id)) = self.ignores.get_mut(path.parent().unwrap()) {
|
||||
// *scan_id = self.scan_id;
|
||||
// }
|
||||
// }
|
||||
if path.file_name() == Some(&GITIGNORE) {
|
||||
if let Some((_, scan_id)) = self.ignores.get_mut(path.parent().unwrap()) {
|
||||
*scan_id = self.scan_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_ignore_file(&mut self, path: &Path) -> Arc<Gitignore> {
|
||||
let (ignore, err) = Gitignore::new(self.abs_path.join(path));
|
||||
if let Some(err) = err {
|
||||
log::error!("error in ignore file {:?} - {:?}", path, err);
|
||||
fn ignore_stack_for_path(&self, path: &Path, is_dir: bool) -> Arc<IgnoreStack> {
|
||||
let mut new_ignores = Vec::new();
|
||||
for ancestor in path.ancestors().skip(1) {
|
||||
if let Some((ignore, _)) = self.ignores.get(ancestor) {
|
||||
new_ignores.push((ancestor, Some(ignore.clone())));
|
||||
} else {
|
||||
new_ignores.push((ancestor, None));
|
||||
}
|
||||
let ignore = Arc::new(ignore);
|
||||
let ignore_parent_inode = self.entry_for_path(path.parent().unwrap()).unwrap().inode;
|
||||
self.ignores.insert(ignore_parent_inode, ignore.clone());
|
||||
ignore
|
||||
}
|
||||
|
||||
let mut ignore_stack = IgnoreStack::none();
|
||||
for (parent_path, ignore) in new_ignores.into_iter().rev() {
|
||||
if ignore_stack.is_path_ignored(&parent_path, true) {
|
||||
ignore_stack = IgnoreStack::all();
|
||||
break;
|
||||
} else if let Some(ignore) = ignore {
|
||||
ignore_stack = ignore_stack.append(Arc::from(parent_path), ignore);
|
||||
}
|
||||
}
|
||||
|
||||
if ignore_stack.is_path_ignored(path, is_dir) {
|
||||
ignore_stack = IgnoreStack::all();
|
||||
}
|
||||
|
||||
ignore_stack
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,14 +417,10 @@ impl Entry {
|
|||
self.inode
|
||||
}
|
||||
|
||||
fn is_ignored(&self) -> bool {
|
||||
pub fn is_ignored(&self) -> bool {
|
||||
self.is_ignored
|
||||
}
|
||||
|
||||
fn set_ignored(&mut self, ignored: bool) {
|
||||
self.is_ignored = ignored;
|
||||
}
|
||||
|
||||
fn is_dir(&self) -> bool {
|
||||
matches!(self.kind, EntryKind::Dir | EntryKind::PendingDir)
|
||||
}
|
||||
|
@ -617,8 +613,6 @@ impl BackgroundScanner {
|
|||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
event_stream.run(move |events| {
|
||||
if smol::block_on(self.notify.send(ScanState::Scanning)).is_err() {
|
||||
return false;
|
||||
|
@ -687,8 +681,6 @@ impl BackgroundScanner {
|
|||
});
|
||||
}
|
||||
|
||||
self.recompute_ignore_statuses();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -816,15 +808,17 @@ impl BackgroundScanner {
|
|||
snapshot.remove_path(&path);
|
||||
|
||||
match self.fs_entry_for_path(path.clone(), &abs_path) {
|
||||
Ok(Some(fs_entry)) => {
|
||||
Ok(Some(mut fs_entry)) => {
|
||||
let is_dir = fs_entry.is_dir();
|
||||
let ignore_stack = snapshot.ignore_stack_for_path(&path, is_dir);
|
||||
fs_entry.is_ignored = ignore_stack.is_all();
|
||||
snapshot.insert_entry(fs_entry);
|
||||
if is_dir {
|
||||
scan_queue_tx
|
||||
.send(ScanJob {
|
||||
abs_path,
|
||||
path,
|
||||
ignore_stack: todo!(),
|
||||
ignore_stack,
|
||||
scan_queue: scan_queue_tx.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
|
@ -854,124 +848,95 @@ impl BackgroundScanner {
|
|||
}
|
||||
});
|
||||
|
||||
self.recompute_ignore_statuses();
|
||||
self.update_ignore_statuses();
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn recompute_ignore_statuses(&self) {
|
||||
self.compute_ignore_status_for_new_ignores();
|
||||
self.compute_ignore_status_for_new_entries();
|
||||
fn update_ignore_statuses(&self) {
|
||||
let mut snapshot = self.snapshot();
|
||||
|
||||
let mut ignores_to_update = Vec::new();
|
||||
let mut ignores_to_delete = Vec::new();
|
||||
for (parent_path, (_, scan_id)) in &snapshot.ignores {
|
||||
if *scan_id == snapshot.scan_id && snapshot.entry_for_path(parent_path).is_some() {
|
||||
ignores_to_update.push(parent_path.clone());
|
||||
}
|
||||
|
||||
fn compute_ignore_status_for_new_ignores(&self) {
|
||||
// let mut snapshot = self.snapshot();
|
||||
|
||||
// let mut ignores_to_delete = Vec::new();
|
||||
// let mut changed_ignore_parents = Vec::new();
|
||||
// for (parent_path, (_, scan_id)) in &snapshot.ignores {
|
||||
// let prev_ignore_parent = changed_ignore_parents.last();
|
||||
// if *scan_id == snapshot.scan_id
|
||||
// && prev_ignore_parent.map_or(true, |l| !parent_path.starts_with(l))
|
||||
// {
|
||||
// changed_ignore_parents.push(parent_path.clone());
|
||||
// }
|
||||
|
||||
// let ignore_parent_exists = snapshot.entry_for_path(parent_path).is_some();
|
||||
// let ignore_exists = snapshot
|
||||
// .entry_for_path(parent_path.join(&*GITIGNORE))
|
||||
// .is_some();
|
||||
// if !ignore_parent_exists || !ignore_exists {
|
||||
// ignores_to_delete.push(parent_path.clone());
|
||||
// }
|
||||
// }
|
||||
|
||||
// for parent_path in ignores_to_delete {
|
||||
// snapshot.ignores.remove(&parent_path);
|
||||
// self.snapshot.lock().ignores.remove(&parent_path);
|
||||
// }
|
||||
|
||||
// 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);
|
||||
// }
|
||||
// self.snapshot.lock().entries.edit(mem::take(&mut edits));
|
||||
// }
|
||||
// });
|
||||
|
||||
// scope.execute(|| {
|
||||
// let entries_tx = entries_tx;
|
||||
// let mut cursor = snapshot.entries.cursor::<_, ()>();
|
||||
// for ignore_parent_path in &changed_ignore_parents {
|
||||
// cursor.seek(&PathSearch::Exact(ignore_parent_path), SeekBias::Right);
|
||||
// while let Some(entry) = cursor.item() {
|
||||
// if entry.path().starts_with(ignore_parent_path) {
|
||||
// entries_tx.send(entry.clone()).unwrap();
|
||||
// cursor.next();
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// 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_path_ignored(entry.path()).unwrap());
|
||||
// edits_tx.send(Edit::Insert(entry)).unwrap();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
let ignore_path = parent_path.join(&*GITIGNORE);
|
||||
if snapshot.entry_for_path(ignore_path).is_none() {
|
||||
ignores_to_delete.push(parent_path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_ignore_status_for_new_entries(&self) {
|
||||
// let snapshot = self.snapshot.lock().clone();
|
||||
for parent_path in ignores_to_delete {
|
||||
snapshot.ignores.remove(&parent_path);
|
||||
self.snapshot.lock().ignores.remove(&parent_path);
|
||||
}
|
||||
|
||||
// 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);
|
||||
// }
|
||||
// self.snapshot.lock().entries.edit(mem::take(&mut edits));
|
||||
// }
|
||||
// });
|
||||
let (ignore_queue_tx, ignore_queue_rx) = crossbeam_channel::unbounded();
|
||||
ignores_to_update.sort_unstable();
|
||||
let mut ignores_to_update = ignores_to_update.into_iter().peekable();
|
||||
while let Some(parent_path) = ignores_to_update.next() {
|
||||
while ignores_to_update
|
||||
.peek()
|
||||
.map_or(false, |p| p.starts_with(&parent_path))
|
||||
{
|
||||
ignores_to_update.next().unwrap();
|
||||
}
|
||||
|
||||
// scope.execute(|| {
|
||||
// let entries_tx = entries_tx;
|
||||
// for entry in snapshot
|
||||
// .entries
|
||||
// .filter::<_, ()>(|e| e.recompute_ignore_status)
|
||||
// {
|
||||
// entries_tx.send(entry.clone()).unwrap();
|
||||
// }
|
||||
// });
|
||||
let ignore_stack = snapshot.ignore_stack_for_path(&parent_path, true);
|
||||
ignore_queue_tx
|
||||
.send(UpdateIgnoreStatusJob {
|
||||
path: parent_path,
|
||||
ignore_stack,
|
||||
ignore_queue: ignore_queue_tx.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
drop(ignore_queue_tx);
|
||||
|
||||
// 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_path_ignored(entry.path()).unwrap());
|
||||
// edits_tx.send(Edit::Insert(entry)).unwrap();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
self.thread_pool.scoped(|scope| {
|
||||
for _ in 0..self.thread_pool.thread_count() {
|
||||
scope.execute(|| {
|
||||
while let Ok(job) = ignore_queue_rx.recv() {
|
||||
self.update_ignore_status(job, &snapshot);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn update_ignore_status(&self, job: UpdateIgnoreStatusJob, snapshot: &Snapshot) {
|
||||
let mut ignore_stack = job.ignore_stack;
|
||||
if let Some((ignore, _)) = snapshot.ignores.get(&job.path) {
|
||||
ignore_stack = ignore_stack.append(job.path.clone(), ignore.clone());
|
||||
}
|
||||
|
||||
let mut edits = Vec::new();
|
||||
for mut entry in snapshot.child_entries(&job.path).cloned() {
|
||||
let was_ignored = entry.is_ignored;
|
||||
entry.is_ignored = ignore_stack.is_path_ignored(entry.path(), entry.is_dir());
|
||||
if entry.is_dir() {
|
||||
let child_ignore_stack = if entry.is_ignored {
|
||||
IgnoreStack::all()
|
||||
} else {
|
||||
ignore_stack.clone()
|
||||
};
|
||||
job.ignore_queue
|
||||
.send(UpdateIgnoreStatusJob {
|
||||
path: entry.path().clone(),
|
||||
ignore_stack: child_ignore_stack,
|
||||
ignore_queue: job.ignore_queue.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
if entry.is_ignored != was_ignored {
|
||||
edits.push(Edit::Insert(entry));
|
||||
}
|
||||
}
|
||||
self.snapshot.lock().entries.edit(edits);
|
||||
}
|
||||
|
||||
fn fs_entry_for_path(&self, path: Arc<Path>, abs_path: &Path) -> Result<Option<Entry>> {
|
||||
|
@ -1020,6 +985,12 @@ struct ScanJob {
|
|||
scan_queue: crossbeam_channel::Sender<ScanJob>,
|
||||
}
|
||||
|
||||
struct UpdateIgnoreStatusJob {
|
||||
path: Arc<Path>,
|
||||
ignore_stack: Arc<IgnoreStack>,
|
||||
ignore_queue: crossbeam_channel::Sender<UpdateIgnoreStatusJob>,
|
||||
}
|
||||
|
||||
pub trait WorktreeHandle {
|
||||
fn file(&self, path: impl AsRef<Path>, app: &AppContext) -> Result<FileHandle>;
|
||||
}
|
||||
|
@ -1088,6 +1059,40 @@ impl<'a> Iterator for FileIter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
struct ChildEntriesIter<'a> {
|
||||
parent_path: &'a Path,
|
||||
cursor: Cursor<'a, Entry, PathSearch<'a>, ()>,
|
||||
}
|
||||
|
||||
impl<'a> ChildEntriesIter<'a> {
|
||||
fn new(parent_path: &'a Path, snapshot: &'a Snapshot) -> Self {
|
||||
let mut cursor = snapshot.entries.cursor();
|
||||
cursor.seek(&PathSearch::Exact(parent_path), SeekBias::Right);
|
||||
Self {
|
||||
parent_path,
|
||||
cursor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ChildEntriesIter<'a> {
|
||||
type Item = &'a Entry;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(item) = self.cursor.item() {
|
||||
if item.path().starts_with(self.parent_path) {
|
||||
self.cursor
|
||||
.seek_forward(&PathSearch::Successor(item.path()), SeekBias::Left);
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mounted_volume_paths() -> Vec<PathBuf> {
|
||||
unsafe {
|
||||
let mut stat_ptr: *mut libc::statfs = std::ptr::null_mut();
|
||||
|
@ -1260,16 +1265,6 @@ mod tests {
|
|||
|
||||
let tree = app.add_model(|ctx| Worktree::new(dir.path(), ctx));
|
||||
app.read(|ctx| tree.read(ctx).scan_complete()).await;
|
||||
|
||||
app.read(|ctx| {
|
||||
let paths = tree
|
||||
.read(ctx)
|
||||
.paths()
|
||||
.map(|p| p.to_str().unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
println!("paths {:?}", paths);
|
||||
});
|
||||
|
||||
app.read(|ctx| {
|
||||
let tree = tree.read(ctx);
|
||||
let tracked = tree.entry_for_path("tracked-dir/tracked-file1").unwrap();
|
||||
|
@ -1278,8 +1273,6 @@ mod tests {
|
|||
assert_eq!(ignored.is_ignored(), true);
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
fs::write(dir.path().join("tracked-dir/tracked-file2"), "").unwrap();
|
||||
fs::write(dir.path().join("ignored-dir/ignored-file2"), "").unwrap();
|
||||
app.read(|ctx| tree.read(ctx).next_scan_complete()).await;
|
||||
|
@ -1540,12 +1533,29 @@ mod tests {
|
|||
assert!(files.next().is_none());
|
||||
assert!(visible_files.next().is_none());
|
||||
|
||||
// for (ignore_parent_path, _) in &self.ignores {
|
||||
// assert!(self.entry_for_path(ignore_parent_path).is_some());
|
||||
// assert!(self
|
||||
// .entry_for_path(ignore_parent_path.join(&*GITIGNORE))
|
||||
// .is_some());
|
||||
// }
|
||||
let mut bfs_paths = Vec::new();
|
||||
let mut stack = vec![Path::new("")];
|
||||
while let Some(path) = stack.pop() {
|
||||
bfs_paths.push(path);
|
||||
let ix = stack.len();
|
||||
for child_entry in self.child_entries(path) {
|
||||
stack.insert(ix, child_entry.path());
|
||||
}
|
||||
}
|
||||
|
||||
let dfs_paths = self
|
||||
.entries
|
||||
.cursor::<(), ()>()
|
||||
.map(|e| e.path().as_ref())
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(bfs_paths, dfs_paths);
|
||||
|
||||
for (ignore_parent_path, _) in &self.ignores {
|
||||
assert!(self.entry_for_path(ignore_parent_path).is_some());
|
||||
assert!(self
|
||||
.entry_for_path(ignore_parent_path.join(&*GITIGNORE))
|
||||
.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<(&Path, u64, bool)> {
|
||||
|
|
|
@ -21,8 +21,11 @@ impl IgnoreStack {
|
|||
Arc::new(Self::All)
|
||||
}
|
||||
|
||||
pub fn is_all(&self) -> bool {
|
||||
matches!(self, IgnoreStack::All)
|
||||
}
|
||||
|
||||
pub fn append(self: Arc<Self>, base: Arc<Path>, ignore: Arc<Gitignore>) -> Arc<Self> {
|
||||
log::info!("appending ignore {:?}", base);
|
||||
match self.as_ref() {
|
||||
IgnoreStack::All => self,
|
||||
_ => Arc::new(Self::Some {
|
||||
|
@ -34,33 +37,18 @@ impl IgnoreStack {
|
|||
}
|
||||
|
||||
pub fn is_path_ignored(&self, path: &Path, is_dir: bool) -> bool {
|
||||
println!("is_path_ignored? {:?} {}", path, is_dir);
|
||||
match self {
|
||||
Self::None => {
|
||||
println!("none case");
|
||||
false
|
||||
}
|
||||
Self::All => {
|
||||
println!("all case");
|
||||
true
|
||||
}
|
||||
Self::None => false,
|
||||
Self::All => true,
|
||||
Self::Some {
|
||||
base,
|
||||
ignore,
|
||||
parent: prev,
|
||||
} => {
|
||||
println!(
|
||||
"some case {:?} {:?}",
|
||||
base,
|
||||
path.strip_prefix(base).unwrap()
|
||||
);
|
||||
|
||||
match ignore.matched(path.strip_prefix(base).unwrap(), is_dir) {
|
||||
} => match ignore.matched(path.strip_prefix(base).unwrap(), is_dir) {
|
||||
ignore::Match::None => prev.is_path_ignored(path, is_dir),
|
||||
ignore::Match::Ignore(_) => true,
|
||||
ignore::Match::Whitelist(_) => false,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue