wip
This commit is contained in:
parent
890ff160d7
commit
37336c6211
2 changed files with 54 additions and 31 deletions
|
@ -1,42 +1,60 @@
|
||||||
use ignore::gitignore::Gitignore;
|
use ignore::gitignore::Gitignore;
|
||||||
use std::{ffi::OsStr, path::Path, sync::Arc};
|
use std::{ffi::OsStr, path::Path, sync::Arc};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct IgnoreStack {
|
||||||
|
pub repo_root: Option<Arc<Path>>,
|
||||||
|
pub top: Arc<IgnoreStackEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum IgnoreStack {
|
pub enum IgnoreStackEntry {
|
||||||
None,
|
None,
|
||||||
Global {
|
Global {
|
||||||
repo_root: Option<Arc<Path>>,
|
|
||||||
ignore: Arc<Gitignore>,
|
ignore: Arc<Gitignore>,
|
||||||
},
|
},
|
||||||
Some {
|
Some {
|
||||||
abs_base_path: Arc<Path>,
|
abs_base_path: Arc<Path>,
|
||||||
ignore: Arc<Gitignore>,
|
ignore: Arc<Gitignore>,
|
||||||
parent: Arc<IgnoreStack>,
|
parent: Arc<IgnoreStackEntry>,
|
||||||
},
|
},
|
||||||
All,
|
All,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IgnoreStack {
|
impl IgnoreStack {
|
||||||
pub fn none() -> Arc<Self> {
|
pub fn none() -> Self {
|
||||||
Arc::new(Self::None)
|
Self {
|
||||||
|
repo_root: None,
|
||||||
|
top: Arc::new(IgnoreStackEntry::None),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all() -> Arc<Self> {
|
pub fn all() -> Self {
|
||||||
Arc::new(Self::All)
|
Self {
|
||||||
|
repo_root: None,
|
||||||
|
top: Arc::new(IgnoreStackEntry::All),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn global(repo_root: Option<Arc<Path>>, ignore: Arc<Gitignore>) -> Arc<Self> {
|
pub fn global(ignore: Arc<Gitignore>) -> Self {
|
||||||
Arc::new(Self::Global { repo_root, ignore })
|
Self {
|
||||||
|
repo_root: None,
|
||||||
|
top: Arc::new(IgnoreStackEntry::Global { ignore }),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append(self: Arc<Self>, abs_base_path: Arc<Path>, ignore: Arc<Gitignore>) -> Arc<Self> {
|
pub fn append(self, abs_base_path: Arc<Path>, ignore: Arc<Gitignore>) -> Self {
|
||||||
match self.as_ref() {
|
let top = match self.top.as_ref() {
|
||||||
IgnoreStack::All => self,
|
IgnoreStackEntry::All => self.top.clone(),
|
||||||
_ => Arc::new(Self::Some {
|
_ => Arc::new(IgnoreStackEntry::Some {
|
||||||
abs_base_path,
|
abs_base_path,
|
||||||
ignore,
|
ignore,
|
||||||
parent: self,
|
parent: self.top.clone(),
|
||||||
}),
|
}),
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
repo_root: self.repo_root,
|
||||||
|
top,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,12 +63,12 @@ impl IgnoreStack {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self {
|
match self.top.as_ref() {
|
||||||
Self::None => false,
|
IgnoreStackEntry::None => false,
|
||||||
Self::All => true,
|
IgnoreStackEntry::All => true,
|
||||||
Self::Global { repo_root, ignore } => {
|
IgnoreStackEntry::Global { ignore } => {
|
||||||
let combined_path;
|
let combined_path;
|
||||||
let abs_path = if let Some(repo_root) = repo_root {
|
let abs_path = if let Some(repo_root) = self.repo_root.as_ref() {
|
||||||
combined_path = ignore.path().join(
|
combined_path = ignore.path().join(
|
||||||
abs_path
|
abs_path
|
||||||
.strip_prefix(repo_root)
|
.strip_prefix(repo_root)
|
||||||
|
@ -66,12 +84,16 @@ impl IgnoreStack {
|
||||||
ignore::Match::Whitelist(_) => false,
|
ignore::Match::Whitelist(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Some {
|
IgnoreStackEntry::Some {
|
||||||
abs_base_path,
|
abs_base_path,
|
||||||
ignore,
|
ignore,
|
||||||
parent: prev,
|
parent: prev,
|
||||||
} => match ignore.matched(abs_path.strip_prefix(abs_base_path).unwrap(), is_dir) {
|
} => match ignore.matched(abs_path.strip_prefix(abs_base_path).unwrap(), is_dir) {
|
||||||
ignore::Match::None => prev.is_abs_path_ignored(abs_path, is_dir),
|
ignore::Match::None => IgnoreStack {
|
||||||
|
repo_root: self.repo_root.clone(),
|
||||||
|
top: prev.clone(),
|
||||||
|
}
|
||||||
|
.is_abs_path_ignored(abs_path, is_dir),
|
||||||
ignore::Match::Ignore(_) => true,
|
ignore::Match::Ignore(_) => true,
|
||||||
ignore::Match::Whitelist(_) => false,
|
ignore::Match::Whitelist(_) => false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2777,12 +2777,7 @@ impl LocalSnapshot {
|
||||||
inodes
|
inodes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ignore_stack_for_abs_path(
|
fn ignore_stack_for_abs_path(&self, abs_path: &Path, is_dir: bool, fs: &dyn Fs) -> IgnoreStack {
|
||||||
&self,
|
|
||||||
abs_path: &Path,
|
|
||||||
is_dir: bool,
|
|
||||||
fs: &dyn Fs,
|
|
||||||
) -> Arc<IgnoreStack> {
|
|
||||||
let mut new_ignores = Vec::new();
|
let mut new_ignores = Vec::new();
|
||||||
let mut repo_root = None;
|
let mut repo_root = None;
|
||||||
for (index, ancestor) in abs_path.ancestors().enumerate() {
|
for (index, ancestor) in abs_path.ancestors().enumerate() {
|
||||||
|
@ -2803,10 +2798,11 @@ impl LocalSnapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ignore_stack = if let Some(global_gitignore) = self.global_gitignore.clone() {
|
let mut ignore_stack = if let Some(global_gitignore) = self.global_gitignore.clone() {
|
||||||
IgnoreStack::global(repo_root, global_gitignore)
|
IgnoreStack::global(global_gitignore)
|
||||||
} else {
|
} else {
|
||||||
IgnoreStack::none()
|
IgnoreStack::none()
|
||||||
};
|
};
|
||||||
|
ignore_stack.repo_root = repo_root;
|
||||||
for (parent_abs_path, ignore) in new_ignores.into_iter().rev() {
|
for (parent_abs_path, ignore) in new_ignores.into_iter().rev() {
|
||||||
if ignore_stack.is_abs_path_ignored(parent_abs_path, true) {
|
if ignore_stack.is_abs_path_ignored(parent_abs_path, true) {
|
||||||
ignore_stack = IgnoreStack::all();
|
ignore_stack = IgnoreStack::all();
|
||||||
|
@ -4369,12 +4365,14 @@ impl BackgroundScanner {
|
||||||
swap_to_front(&mut child_paths, *GITIGNORE);
|
swap_to_front(&mut child_paths, *GITIGNORE);
|
||||||
swap_to_front(&mut child_paths, *DOT_GIT);
|
swap_to_front(&mut child_paths, *DOT_GIT);
|
||||||
|
|
||||||
|
let mut repo_root = None;
|
||||||
for child_abs_path in child_paths {
|
for child_abs_path in child_paths {
|
||||||
let child_abs_path: Arc<Path> = child_abs_path.into();
|
let child_abs_path: Arc<Path> = child_abs_path.into();
|
||||||
let child_name = child_abs_path.file_name().unwrap();
|
let child_name = child_abs_path.file_name().unwrap();
|
||||||
let child_path: Arc<Path> = job.path.join(child_name).into();
|
let child_path: Arc<Path> = job.path.join(child_name).into();
|
||||||
|
|
||||||
if child_name == *DOT_GIT {
|
if child_name == *DOT_GIT {
|
||||||
|
repo_root = Some(child_abs_path.clone());
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
state.insert_git_repository(
|
state.insert_git_repository(
|
||||||
child_path.clone(),
|
child_path.clone(),
|
||||||
|
@ -4386,6 +4384,9 @@ impl BackgroundScanner {
|
||||||
Ok(ignore) => {
|
Ok(ignore) => {
|
||||||
let ignore = Arc::new(ignore);
|
let ignore = Arc::new(ignore);
|
||||||
ignore_stack = ignore_stack.append(job.abs_path.clone(), ignore.clone());
|
ignore_stack = ignore_stack.append(job.abs_path.clone(), ignore.clone());
|
||||||
|
if let Some(repo_root) = repo_root.clone() {
|
||||||
|
ignore_stack.repo_root = Some(repo_root);
|
||||||
|
}
|
||||||
new_ignore = Some(ignore);
|
new_ignore = Some(ignore);
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
@ -4688,7 +4689,7 @@ impl BackgroundScanner {
|
||||||
&self,
|
&self,
|
||||||
scan_job_tx: Sender<ScanJob>,
|
scan_job_tx: Sender<ScanJob>,
|
||||||
prev_snapshot: LocalSnapshot,
|
prev_snapshot: LocalSnapshot,
|
||||||
mut ignores_to_update: impl Iterator<Item = (Arc<Path>, Arc<IgnoreStack>)>,
|
mut ignores_to_update: impl Iterator<Item = (Arc<Path>, IgnoreStack)>,
|
||||||
) {
|
) {
|
||||||
let (ignore_queue_tx, ignore_queue_rx) = channel::unbounded();
|
let (ignore_queue_tx, ignore_queue_rx) = channel::unbounded();
|
||||||
{
|
{
|
||||||
|
@ -5147,7 +5148,7 @@ fn char_bag_for_path(root_char_bag: CharBag, path: &Path) -> CharBag {
|
||||||
struct ScanJob {
|
struct ScanJob {
|
||||||
abs_path: Arc<Path>,
|
abs_path: Arc<Path>,
|
||||||
path: Arc<Path>,
|
path: Arc<Path>,
|
||||||
ignore_stack: Arc<IgnoreStack>,
|
ignore_stack: IgnoreStack,
|
||||||
scan_queue: Sender<ScanJob>,
|
scan_queue: Sender<ScanJob>,
|
||||||
ancestor_inodes: TreeSet<u64>,
|
ancestor_inodes: TreeSet<u64>,
|
||||||
is_external: bool,
|
is_external: bool,
|
||||||
|
@ -5155,7 +5156,7 @@ struct ScanJob {
|
||||||
|
|
||||||
struct UpdateIgnoreStatusJob {
|
struct UpdateIgnoreStatusJob {
|
||||||
abs_path: Arc<Path>,
|
abs_path: Arc<Path>,
|
||||||
ignore_stack: Arc<IgnoreStack>,
|
ignore_stack: IgnoreStack,
|
||||||
ignore_queue: Sender<UpdateIgnoreStatusJob>,
|
ignore_queue: Sender<UpdateIgnoreStatusJob>,
|
||||||
scan_queue: Sender<ScanJob>,
|
scan_queue: Sender<ScanJob>,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue