diff --git a/crates/fs/src/fake_git_repo.rs b/crates/fs/src/fake_git_repo.rs index c641988ab8..b6beb9fc6e 100644 --- a/crates/fs/src/fake_git_repo.rs +++ b/crates/fs/src/fake_git_repo.rs @@ -152,8 +152,8 @@ impl GitRepository for FakeGitRepository { }) } - fn remote_url(&self, _name: &str) -> Option { - None + fn remote_url(&self, _name: &str) -> BoxFuture<'_, Option> { + async move { None }.boxed() } fn diff_tree(&self, _request: DiffTreeType) -> BoxFuture<'_, Result> { diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index 23c5795209..e49b171590 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -420,7 +420,7 @@ pub trait GitRepository: Send + Sync { ) -> BoxFuture<'_, anyhow::Result<()>>; /// Returns the URL of the remote with the given name. - fn remote_url(&self, name: &str) -> Option; + fn remote_url(&self, name: &str) -> BoxFuture<'_, Option>; /// Resolve a list of refs to SHAs. fn revparse_batch(&self, revs: Vec) -> BoxFuture<'_, Result>>>; @@ -1085,10 +1085,16 @@ impl GitRepository for RealGitRepository { .boxed() } - fn remote_url(&self, name: &str) -> Option { - let repo = self.repository.lock(); - let remote = repo.find_remote(name).ok()?; - remote.url().map(|url| url.to_string()) + fn remote_url(&self, name: &str) -> BoxFuture<'_, Option> { + let repo = self.repository.clone(); + let name = name.to_owned(); + self.executor + .spawn(async move { + let repo = repo.lock(); + let remote = repo.find_remote(&name).ok()?; + remote.url().map(|url| url.to_string()) + }) + .boxed() } fn revparse_batch(&self, revs: Vec) -> BoxFuture<'_, Result>>> { @@ -1465,23 +1471,30 @@ impl GitRepository for RealGitRepository { fn blame(&self, path: RepoPath, content: Rope) -> BoxFuture<'_, Result> { let working_directory = self.working_directory(); let git_binary_path = self.any_git_binary_path.clone(); + let executor = self.executor.clone(); - let remote_url = self - .remote_url("upstream") - .or_else(|| self.remote_url("origin")); - - self.executor - .spawn(async move { - crate::blame::Blame::for_path( - &git_binary_path, - &working_directory?, - &path, - &content, - remote_url, - ) + async move { + let remote_url = if let Some(remote_url) = self.remote_url("upstream").await { + Some(remote_url) + } else if let Some(remote_url) = self.remote_url("origin").await { + Some(remote_url) + } else { + None + }; + executor + .spawn(async move { + crate::blame::Blame::for_path( + &git_binary_path, + &working_directory?, + &path, + &content, + remote_url, + ) + .await + }) .await - }) - .boxed() + } + .boxed() } fn file_history(&self, path: RepoPath) -> BoxFuture<'_, Result> { diff --git a/crates/git_hosting_providers/src/git_hosting_providers.rs b/crates/git_hosting_providers/src/git_hosting_providers.rs index 6940ea382a..98ea301ec9 100644 --- a/crates/git_hosting_providers/src/git_hosting_providers.rs +++ b/crates/git_hosting_providers/src/git_hosting_providers.rs @@ -33,11 +33,11 @@ pub fn init(cx: &mut App) { /// /// These require information from the Git repository to construct, so their /// registration is deferred until we have a Git repository initialized. -pub fn register_additional_providers( +pub async fn register_additional_providers( provider_registry: Arc, repository: Arc, ) { - let Some(origin_url) = repository.remote_url("origin") else { + let Some(origin_url) = repository.remote_url("origin").await else { return; }; diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 58181e20e9..5bc3f4ee43 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -1130,6 +1130,7 @@ impl GitStore { RepositoryState::Local(LocalRepositoryState { backend, .. }) => { let origin_url = backend .remote_url(&remote) + .await .with_context(|| format!("remote \"{remote}\" not found"))?; let sha = backend.head_sha().await.context("reading HEAD SHA")?; @@ -5447,7 +5448,8 @@ impl Repository { git_hosting_providers::register_additional_providers( git_hosting_provider_registry, state.backend.clone(), - ); + ) + .await; } let state = RepositoryState::Local(state); let mut jobs = VecDeque::new(); @@ -6052,8 +6054,8 @@ async fn compute_snapshot( } // Used by edit prediction data collection - let remote_origin_url = backend.remote_url("origin"); - let remote_upstream_url = backend.remote_url("upstream"); + let remote_origin_url = backend.remote_url("origin").await; + let remote_upstream_url = backend.remote_url("upstream").await; let snapshot = RepositorySnapshot { id, diff --git a/crates/project/src/telemetry_snapshot.rs b/crates/project/src/telemetry_snapshot.rs index d12481ae5e..5f9155371d 100644 --- a/crates/project/src/telemetry_snapshot.rs +++ b/crates/project/src/telemetry_snapshot.rs @@ -96,7 +96,7 @@ impl TelemetryWorktreeSnapshot { }; }; - let remote_url = backend.remote_url("origin"); + let remote_url = backend.remote_url("origin").await; let head_sha = backend.head_sha().await; let diff = backend.diff(DiffType::HeadToWorktree).await.ok();