Honor gitignores above worktree root
This commit is contained in:
parent
9328ab121a
commit
e66144104f
1 changed files with 78 additions and 45 deletions
|
@ -2046,24 +2046,41 @@ impl BackgroundScanner {
|
||||||
|
|
||||||
async fn scan_dirs(&mut self) -> Result<()> {
|
async fn scan_dirs(&mut self) -> Result<()> {
|
||||||
let root_char_bag;
|
let root_char_bag;
|
||||||
|
let root_abs_path;
|
||||||
let next_entry_id;
|
let next_entry_id;
|
||||||
let is_dir;
|
let is_dir;
|
||||||
{
|
{
|
||||||
let snapshot = self.snapshot.lock();
|
let snapshot = self.snapshot.lock();
|
||||||
root_char_bag = snapshot.root_char_bag;
|
root_char_bag = snapshot.root_char_bag;
|
||||||
|
root_abs_path = snapshot.abs_path.clone();
|
||||||
next_entry_id = snapshot.next_entry_id.clone();
|
next_entry_id = snapshot.next_entry_id.clone();
|
||||||
is_dir = snapshot.root_entry().map_or(false, |e| e.is_dir())
|
is_dir = snapshot.root_entry().map_or(false, |e| e.is_dir())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Populate ignores above the root.
|
||||||
|
for ancestor in root_abs_path.ancestors().skip(1) {
|
||||||
|
if let Ok(ignore) = build_gitignore(&ancestor.join(&*GITIGNORE), self.fs.as_ref()).await
|
||||||
|
{
|
||||||
|
self.snapshot
|
||||||
|
.lock()
|
||||||
|
.ignores_by_abs_path
|
||||||
|
.insert(ancestor.into(), (ignore.into(), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if is_dir {
|
if is_dir {
|
||||||
let path: Arc<Path> = Arc::from(Path::new(""));
|
let path: Arc<Path> = Arc::from(Path::new(""));
|
||||||
let abs_path = self.abs_path();
|
let ignore_stack = self
|
||||||
|
.snapshot
|
||||||
|
.lock()
|
||||||
|
.ignore_stack_for_abs_path(&root_abs_path, true);
|
||||||
|
|
||||||
let (tx, rx) = channel::unbounded();
|
let (tx, rx) = channel::unbounded();
|
||||||
self.executor
|
self.executor
|
||||||
.block(tx.send(ScanJob {
|
.block(tx.send(ScanJob {
|
||||||
abs_path: abs_path.to_path_buf(),
|
abs_path: root_abs_path.to_path_buf(),
|
||||||
path,
|
path,
|
||||||
ignore_stack: IgnoreStack::none(),
|
ignore_stack,
|
||||||
scan_queue: tx.clone(),
|
scan_queue: tx.clone(),
|
||||||
}))
|
}))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -2313,14 +2330,15 @@ impl BackgroundScanner {
|
||||||
let mut ignores_to_update = Vec::new();
|
let mut ignores_to_update = Vec::new();
|
||||||
let mut ignores_to_delete = Vec::new();
|
let mut ignores_to_delete = Vec::new();
|
||||||
for (parent_abs_path, (_, scan_id)) in &snapshot.ignores_by_abs_path {
|
for (parent_abs_path, (_, scan_id)) in &snapshot.ignores_by_abs_path {
|
||||||
let parent_path = parent_abs_path.strip_prefix(&snapshot.abs_path).unwrap();
|
if let Ok(parent_path) = parent_abs_path.strip_prefix(&snapshot.abs_path) {
|
||||||
if *scan_id == snapshot.scan_id && snapshot.entry_for_path(parent_path).is_some() {
|
if *scan_id == snapshot.scan_id && snapshot.entry_for_path(parent_path).is_some() {
|
||||||
ignores_to_update.push(parent_abs_path.clone());
|
ignores_to_update.push(parent_abs_path.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let ignore_path = parent_path.join(&*GITIGNORE);
|
let ignore_path = parent_path.join(&*GITIGNORE);
|
||||||
if snapshot.entry_for_path(ignore_path).is_none() {
|
if snapshot.entry_for_path(ignore_path).is_none() {
|
||||||
ignores_to_delete.push(parent_abs_path.clone());
|
ignores_to_delete.push(parent_abs_path.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2410,20 +2428,6 @@ impl BackgroundScanner {
|
||||||
snapshot.entries_by_path.edit(entries_by_path_edits, &());
|
snapshot.entries_by_path.edit(entries_by_path_edits, &());
|
||||||
snapshot.entries_by_id.edit(entries_by_id_edits, &());
|
snapshot.entries_by_id.edit(entries_by_id_edits, &());
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_root_ignore_stack(&self) {
|
|
||||||
// let parent_abs_path = if let Some(path) = self.abs_path().parent() {
|
|
||||||
// path
|
|
||||||
// } else {
|
|
||||||
// return IgnoreStack::none()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut cur_path = PathBuf::new();
|
|
||||||
// for component in self.abs_path().components() {
|
|
||||||
// // self.snapshot.lock().ignores.insert(parent_path, (ignore, self.scan_id));
|
|
||||||
// cur_path.push(compo)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn char_bag_for_path(root_char_bag: CharBag, path: &Path) -> CharBag {
|
fn char_bag_for_path(root_char_bag: CharBag, path: &Path) -> CharBag {
|
||||||
|
@ -2797,23 +2801,28 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_rescan_with_gitignore(cx: &mut TestAppContext) {
|
async fn test_rescan_with_gitignore(cx: &mut TestAppContext) {
|
||||||
let dir = temp_tree(json!({
|
let parent_dir = temp_tree(json!({
|
||||||
".git": {},
|
".gitignore": "ancestor-ignored-file1\nancestor-ignored-file2\n",
|
||||||
".gitignore": "ignored-dir\n",
|
"tree": {
|
||||||
"tracked-dir": {
|
".git": {},
|
||||||
"tracked-file1": "tracked contents",
|
".gitignore": "ignored-dir\n",
|
||||||
},
|
"tracked-dir": {
|
||||||
"ignored-dir": {
|
"tracked-file1": "",
|
||||||
"ignored-file1": "ignored contents",
|
"ancestor-ignored-file1": "",
|
||||||
|
},
|
||||||
|
"ignored-dir": {
|
||||||
|
"ignored-file1": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
let dir = parent_dir.path().join("tree");
|
||||||
|
|
||||||
let http_client = FakeHttpClient::with_404_response();
|
let http_client = FakeHttpClient::with_404_response();
|
||||||
let client = Client::new(http_client.clone());
|
let client = Client::new(http_client.clone());
|
||||||
|
|
||||||
let tree = Worktree::local(
|
let tree = Worktree::local(
|
||||||
client,
|
client,
|
||||||
dir.path(),
|
dir.as_path(),
|
||||||
true,
|
true,
|
||||||
Arc::new(RealFs),
|
Arc::new(RealFs),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
@ -2826,23 +2835,47 @@ mod tests {
|
||||||
tree.flush_fs_events(&cx).await;
|
tree.flush_fs_events(&cx).await;
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let tree = tree.read(cx);
|
let tree = tree.read(cx);
|
||||||
let tracked = tree.entry_for_path("tracked-dir/tracked-file1").unwrap();
|
assert!(
|
||||||
let ignored = tree.entry_for_path("ignored-dir/ignored-file1").unwrap();
|
!tree
|
||||||
assert_eq!(tracked.is_ignored, false);
|
.entry_for_path("tracked-dir/tracked-file1")
|
||||||
assert_eq!(ignored.is_ignored, true);
|
.unwrap()
|
||||||
|
.is_ignored
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
tree.entry_for_path("tracked-dir/ancestor-ignored-file1")
|
||||||
|
.unwrap()
|
||||||
|
.is_ignored
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
tree.entry_for_path("ignored-dir/ignored-file1")
|
||||||
|
.unwrap()
|
||||||
|
.is_ignored
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
std::fs::write(dir.path().join("tracked-dir/tracked-file2"), "").unwrap();
|
std::fs::write(dir.join("tracked-dir/tracked-file2"), "").unwrap();
|
||||||
std::fs::write(dir.path().join("ignored-dir/ignored-file2"), "").unwrap();
|
std::fs::write(dir.join("tracked-dir/ancestor-ignored-file2"), "").unwrap();
|
||||||
|
std::fs::write(dir.join("ignored-dir/ignored-file2"), "").unwrap();
|
||||||
tree.flush_fs_events(&cx).await;
|
tree.flush_fs_events(&cx).await;
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let tree = tree.read(cx);
|
let tree = tree.read(cx);
|
||||||
let dot_git = tree.entry_for_path(".git").unwrap();
|
assert!(
|
||||||
let tracked = tree.entry_for_path("tracked-dir/tracked-file2").unwrap();
|
!tree
|
||||||
let ignored = tree.entry_for_path("ignored-dir/ignored-file2").unwrap();
|
.entry_for_path("tracked-dir/tracked-file2")
|
||||||
assert_eq!(tracked.is_ignored, false);
|
.unwrap()
|
||||||
assert_eq!(ignored.is_ignored, true);
|
.is_ignored
|
||||||
assert_eq!(dot_git.is_ignored, true);
|
);
|
||||||
|
assert!(
|
||||||
|
tree.entry_for_path("tracked-dir/ancestor-ignored-file2")
|
||||||
|
.unwrap()
|
||||||
|
.is_ignored
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
tree.entry_for_path("ignored-dir/ignored-file2")
|
||||||
|
.unwrap()
|
||||||
|
.is_ignored
|
||||||
|
);
|
||||||
|
assert!(tree.entry_for_path(".git").unwrap().is_ignored);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue