diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ce15b36f6a2bde4c28c6acfdea8abd835037568d..34291fbc33874f9a3c29304fc906ccf243f3e2f1 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -89,6 +89,7 @@ pub use multi_buffer::{ use ordered_float::OrderedFloat; use parking_lot::{Mutex, RwLock}; use project::project_settings::{GitGutterSetting, ProjectSettings}; +use project::Item; use project::{FormatTrigger, Location, Project, ProjectPath, ProjectTransaction}; use rand::prelude::*; use rpc::proto::*; @@ -8657,22 +8658,23 @@ impl Editor { fn get_permalink_to_line(&mut self, cx: &mut ViewContext) -> Result { use git::permalink::{build_permalink, BuildPermalinkParams}; - let project = self.project.clone().ok_or_else(|| anyhow!("no project"))?; - let project = project.read(cx); - - let worktree = project - .visible_worktrees(cx) - .next() - .ok_or_else(|| anyhow!("no worktree"))?; - - let mut cwd = worktree.read(cx).abs_path().to_path_buf(); - cwd.push(".git"); + let (path, repo) = maybe!({ + let project_handle = self.project.as_ref()?.clone(); + let project = project_handle.read(cx); + let buffer = self.buffer().read(cx).as_singleton()?; + let path = buffer + .read(cx) + .file()? + .as_local()? + .path() + .to_str()? + .to_string(); + let repo = project.get_repo(&buffer.read(cx).project_path(cx)?, cx)?; + Some((path, repo)) + }) + .ok_or_else(|| anyhow!("unable to open git repository"))?; const REMOTE_NAME: &str = "origin"; - let repo = project - .fs() - .open_repo(&cwd) - .ok_or_else(|| anyhow!("no Git repo"))?; let origin_url = repo .lock() .remote_url(REMOTE_NAME) @@ -8681,14 +8683,6 @@ impl Editor { .lock() .head_sha() .ok_or_else(|| anyhow!("failed to read HEAD SHA"))?; - - let path = maybe!({ - let buffer = self.buffer().read(cx).as_singleton()?; - let file = buffer.read(cx).file().and_then(|f| f.as_local())?; - file.path().to_str().map(|path| path.to_string()) - }) - .ok_or_else(|| anyhow!("failed to determine file path"))?; - let selections = self.selections.all::(cx); let selection = selections.iter().peekable().next(); diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 8661ceada0b381c6b9cb1283bfd66cf6395b3e6b..aff690b348c9a36bd1149eb3bf42fb457030e895 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -16,6 +16,7 @@ use clock::ReplicaId; use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque}; use copilot::Copilot; use debounced_delay::DebouncedDelay; +use fs::repository::GitRepository; use futures::{ channel::mpsc::{self, UnboundedReceiver}, future::{try_join_all, Shared}, @@ -7302,6 +7303,18 @@ impl Project { }) } + pub fn get_repo( + &self, + project_path: &ProjectPath, + cx: &AppContext, + ) -> Option>> { + self.worktree_for_id(project_path.worktree_id, cx)? + .read(cx) + .as_local()? + .snapshot() + .local_git_repo(&project_path.path) + } + // RPC message handlers async fn handle_unshare_project( diff --git a/crates/project_core/src/worktree.rs b/crates/project_core/src/worktree.rs index e5d50557f9cf2921932cdfb742f9eb5d5b71731e..1f9e9a8e151452974218a2413cadd81ff1e4def0 100644 --- a/crates/project_core/src/worktree.rs +++ b/crates/project_core/src/worktree.rs @@ -2116,6 +2116,11 @@ impl LocalSnapshot { Some((path, self.git_repositories.get(&repo.work_directory_id())?)) } + pub fn local_git_repo(&self, path: &Path) -> Option>> { + self.local_repo_for_path(path) + .map(|(_, entry)| entry.repo_ptr.clone()) + } + fn build_update( &self, project_id: u64,