diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index 19ba0d1238..37b79fa10d 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -18,6 +18,8 @@ pub trait GitRepository: Send + Sync + std::fmt::Debug { fn set_scan_id(&mut self, scan_id: usize); + fn reopen_git_repo(&mut self) -> bool; + fn git_repo(&self) -> Arc>; fn boxed_clone(&self) -> Box; @@ -79,18 +81,15 @@ impl GitRepository for RealGitRepository { async fn load_head_text(&self, relative_file_path: &Path) -> Option { fn logic(repo: &LibGitRepository, relative_file_path: &Path) -> Result> { - let object = repo - .head()? - .peel_to_tree()? - .get_path(relative_file_path)? - .to_object(&repo)?; - - let content = match object.as_blob() { - Some(blob) => blob.content().to_owned(), + const STAGE_NORMAL: i32 = 0; + let index = repo.index()?; + let oid = match index.get_path(relative_file_path, STAGE_NORMAL) { + Some(entry) => entry.id, None => return Ok(None), }; - let head_text = String::from_utf8(content.to_owned())?; + let content = repo.find_blob(oid)?.content().to_owned(); + let head_text = String::from_utf8(content)?; Ok(Some(head_text)) } @@ -101,6 +100,17 @@ impl GitRepository for RealGitRepository { None } + fn reopen_git_repo(&mut self) -> bool { + match LibGitRepository::open(&self.git_dir_path) { + Ok(repo) => { + self.libgit_repository = Arc::new(Mutex::new(repo)); + true + } + + Err(_) => false, + } + } + fn git_repo(&self) -> Arc> { self.libgit_repository.clone() } @@ -168,6 +178,10 @@ impl GitRepository for FakeGitRepository { unimplemented!() } + fn reopen_git_repo(&mut self) -> bool { + unimplemented!() + } + fn git_repo(&self) -> Arc> { unimplemented!() } diff --git a/crates/project/src/fs.rs b/crates/project/src/fs.rs index cc1f6101f4..c14edcd5e4 100644 --- a/crates/project/src/fs.rs +++ b/crates/project/src/fs.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Result}; use fsevent::EventStream; use futures::{future::BoxFuture, Stream, StreamExt}; -use git::repository::{FakeGitRepository, GitRepository, RealGitRepository}; +use git::repository::{GitRepository, RealGitRepository}; use language::LineEnding; use smol::io::{AsyncReadExt, AsyncWriteExt}; use std::{ @@ -854,7 +854,10 @@ impl Fs for FakeFs { } fn open_repo(&self, abs_dot_git: &Path) -> Option> { - Some(FakeGitRepository::open(abs_dot_git.into(), 0)) + Some(git::repository::FakeGitRepository::open( + abs_dot_git.into(), + 0, + )) } fn is_fake(&self) -> bool { diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 81eec4987f..1d47c843c5 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -2603,7 +2603,13 @@ impl BackgroundScanner { .git_repositories .iter() .map(|repo| repo.boxed_clone()) - .filter(|repo| git::libgit::Repository::open(repo.git_dir_path()).is_ok()) + .filter_map(|mut repo| { + if repo.reopen_git_repo() { + Some(repo) + } else { + None + } + }) .collect(); snapshot.git_repositories = new_repos;