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<()> {
|
||||
let root_char_bag;
|
||||
let root_abs_path;
|
||||
let next_entry_id;
|
||||
let is_dir;
|
||||
{
|
||||
let snapshot = self.snapshot.lock();
|
||||
root_char_bag = snapshot.root_char_bag;
|
||||
root_abs_path = snapshot.abs_path.clone();
|
||||
next_entry_id = snapshot.next_entry_id.clone();
|
||||
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 {
|
||||
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();
|
||||
self.executor
|
||||
.block(tx.send(ScanJob {
|
||||
abs_path: abs_path.to_path_buf(),
|
||||
abs_path: root_abs_path.to_path_buf(),
|
||||
path,
|
||||
ignore_stack: IgnoreStack::none(),
|
||||
ignore_stack,
|
||||
scan_queue: tx.clone(),
|
||||
}))
|
||||
.unwrap();
|
||||
|
@ -2313,14 +2330,15 @@ impl BackgroundScanner {
|
|||
let mut ignores_to_update = Vec::new();
|
||||
let mut ignores_to_delete = Vec::new();
|
||||
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 *scan_id == snapshot.scan_id && snapshot.entry_for_path(parent_path).is_some() {
|
||||
ignores_to_update.push(parent_abs_path.clone());
|
||||
}
|
||||
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() {
|
||||
ignores_to_update.push(parent_abs_path.clone());
|
||||
}
|
||||
|
||||
let ignore_path = parent_path.join(&*GITIGNORE);
|
||||
if snapshot.entry_for_path(ignore_path).is_none() {
|
||||
ignores_to_delete.push(parent_abs_path.clone());
|
||||
let ignore_path = parent_path.join(&*GITIGNORE);
|
||||
if snapshot.entry_for_path(ignore_path).is_none() {
|
||||
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_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 {
|
||||
|
@ -2797,23 +2801,28 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_rescan_with_gitignore(cx: &mut TestAppContext) {
|
||||
let dir = temp_tree(json!({
|
||||
".git": {},
|
||||
".gitignore": "ignored-dir\n",
|
||||
"tracked-dir": {
|
||||
"tracked-file1": "tracked contents",
|
||||
},
|
||||
"ignored-dir": {
|
||||
"ignored-file1": "ignored contents",
|
||||
let parent_dir = temp_tree(json!({
|
||||
".gitignore": "ancestor-ignored-file1\nancestor-ignored-file2\n",
|
||||
"tree": {
|
||||
".git": {},
|
||||
".gitignore": "ignored-dir\n",
|
||||
"tracked-dir": {
|
||||
"tracked-file1": "",
|
||||
"ancestor-ignored-file1": "",
|
||||
},
|
||||
"ignored-dir": {
|
||||
"ignored-file1": ""
|
||||
}
|
||||
}
|
||||
}));
|
||||
let dir = parent_dir.path().join("tree");
|
||||
|
||||
let http_client = FakeHttpClient::with_404_response();
|
||||
let client = Client::new(http_client.clone());
|
||||
|
||||
let tree = Worktree::local(
|
||||
client,
|
||||
dir.path(),
|
||||
dir.as_path(),
|
||||
true,
|
||||
Arc::new(RealFs),
|
||||
Default::default(),
|
||||
|
@ -2826,23 +2835,47 @@ mod tests {
|
|||
tree.flush_fs_events(&cx).await;
|
||||
cx.read(|cx| {
|
||||
let tree = tree.read(cx);
|
||||
let tracked = tree.entry_for_path("tracked-dir/tracked-file1").unwrap();
|
||||
let ignored = tree.entry_for_path("ignored-dir/ignored-file1").unwrap();
|
||||
assert_eq!(tracked.is_ignored, false);
|
||||
assert_eq!(ignored.is_ignored, true);
|
||||
assert!(
|
||||
!tree
|
||||
.entry_for_path("tracked-dir/tracked-file1")
|
||||
.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.path().join("ignored-dir/ignored-file2"), "").unwrap();
|
||||
std::fs::write(dir.join("tracked-dir/tracked-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;
|
||||
cx.read(|cx| {
|
||||
let tree = tree.read(cx);
|
||||
let dot_git = tree.entry_for_path(".git").unwrap();
|
||||
let tracked = tree.entry_for_path("tracked-dir/tracked-file2").unwrap();
|
||||
let ignored = tree.entry_for_path("ignored-dir/ignored-file2").unwrap();
|
||||
assert_eq!(tracked.is_ignored, false);
|
||||
assert_eq!(ignored.is_ignored, true);
|
||||
assert_eq!(dot_git.is_ignored, true);
|
||||
assert!(
|
||||
!tree
|
||||
.entry_for_path("tracked-dir/tracked-file2")
|
||||
.unwrap()
|
||||
.is_ignored
|
||||
);
|
||||
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