Remove git repos from worktree when deleted on storage
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
4251e0f5f1
commit
d2b18790a0
2 changed files with 50 additions and 20 deletions
|
@ -56,7 +56,7 @@ impl GitRepository {
|
||||||
self.last_scan_id = scan_id;
|
self.last_scan_id = scan_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_repo(&mut self, f: Box<dyn FnOnce(&mut git2::Repository)>) {
|
pub fn with_repo<F: FnOnce(&mut git2::Repository)>(&mut self, f: F) {
|
||||||
let mut git2 = self.libgit_repository.lock();
|
let mut git2 = self.libgit_repository.lock();
|
||||||
f(&mut git2)
|
f(&mut git2)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1311,9 +1311,7 @@ impl LocalSnapshot {
|
||||||
self.git_repositories
|
self.git_repositories
|
||||||
.iter()
|
.iter()
|
||||||
.rev() //git_repository is ordered lexicographically
|
.rev() //git_repository is ordered lexicographically
|
||||||
.find(|repo| {
|
.find(|repo| repo.is_path_managed_by(&self.abs_path.join(path)))
|
||||||
repo.is_path_managed_by(&self.abs_path.join(path))
|
|
||||||
})
|
|
||||||
.map(|repo| repo.clone())
|
.map(|repo| repo.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2548,13 +2546,16 @@ impl BackgroundScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_git_repositories(&self) {
|
async fn update_git_repositories(&self) {
|
||||||
let mut snapshot = self.snapshot();
|
let mut snapshot = self.snapshot.lock();
|
||||||
let mut git_repositories = mem::take(&mut snapshot.git_repositories);
|
|
||||||
git_repositories.retain(|git_repository| {
|
let new_repos = snapshot
|
||||||
let dot_git_path = git_repository.content_path().join(&*DOT_GIT);
|
.git_repositories
|
||||||
snapshot.entry_for_path(dot_git_path).is_some()
|
.iter()
|
||||||
});
|
.cloned()
|
||||||
snapshot.git_repositories = git_repositories;
|
.filter(|repo| git2::Repository::open(repo.git_dir_path()).is_ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
snapshot.git_repositories = new_repos;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_ignore_status(&self, job: UpdateIgnoreStatusJob, snapshot: &LocalSnapshot) {
|
async fn update_ignore_status(&self, job: UpdateIgnoreStatusJob, snapshot: &LocalSnapshot) {
|
||||||
|
@ -3179,30 +3180,59 @@ mod tests {
|
||||||
.git_repository_for_file_path("dir1/src/b.txt".as_ref())
|
.git_repository_for_file_path("dir1/src/b.txt".as_ref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Need to update the file system for anything involving git
|
assert_eq!(
|
||||||
// Goal: Make this test pass
|
repo.content_path(),
|
||||||
// Up Next: Invalidating git repos!
|
root.path().join("dir1").canonicalize().unwrap()
|
||||||
assert_eq!(repo.content_path(), root.path().join("dir1").canonicalize().unwrap());
|
);
|
||||||
assert_eq!(repo.git_dir_path(), root.path().join("dir1/.git").canonicalize().unwrap());
|
assert_eq!(
|
||||||
|
repo.git_dir_path(),
|
||||||
|
root.path().join("dir1/.git").canonicalize().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let repo = tree
|
let repo = tree
|
||||||
.git_repository_for_file_path("dir1/deps/dep1/src/a.txt".as_ref())
|
.git_repository_for_file_path("dir1/deps/dep1/src/a.txt".as_ref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(repo.content_path(), root.path().join("dir1/deps/dep1").canonicalize().unwrap());
|
assert_eq!(
|
||||||
assert_eq!(repo.git_dir_path(), root.path().join("dir1/deps/dep1/.git").canonicalize().unwrap());
|
repo.content_path(),
|
||||||
|
root.path().join("dir1/deps/dep1").canonicalize().unwrap()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
repo.git_dir_path(),
|
||||||
|
root.path()
|
||||||
|
.join("dir1/deps/dep1/.git")
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let repo = tree
|
let repo = tree
|
||||||
.git_repository_for_git_data("dir1/.git/HEAD".as_ref())
|
.git_repository_for_git_data("dir1/.git/HEAD".as_ref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(repo.content_path(), root.path().join("dir1").canonicalize().unwrap());
|
assert_eq!(
|
||||||
assert_eq!(repo.git_dir_path(), root.path().join("dir1/.git").canonicalize().unwrap());
|
repo.content_path(),
|
||||||
|
root.path().join("dir1").canonicalize().unwrap()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
repo.git_dir_path(),
|
||||||
|
root.path().join("dir1/.git").canonicalize().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
assert!(tree.does_git_repository_track_file_path(&repo, "dir1/src/b.txt".as_ref()));
|
assert!(tree.does_git_repository_track_file_path(&repo, "dir1/src/b.txt".as_ref()));
|
||||||
assert!(!tree
|
assert!(!tree
|
||||||
.does_git_repository_track_file_path(&repo, "dir1/deps/dep1/src/a.txt".as_ref()));
|
.does_git_repository_track_file_path(&repo, "dir1/deps/dep1/src/a.txt".as_ref()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::fs::remove_dir_all(root.path().join("dir1/.git")).unwrap();
|
||||||
|
tree.flush_fs_events(cx).await;
|
||||||
|
|
||||||
|
tree.read_with(cx, |tree, _cx| {
|
||||||
|
let tree = tree.as_local().unwrap();
|
||||||
|
|
||||||
|
assert!(tree
|
||||||
|
.git_repository_for_file_path("dir1/src/b.txt".as_ref())
|
||||||
|
.is_none());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue