From 2b8b913b6b0008f47145f5652b91515d81e32887 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Tue, 5 Mar 2024 16:59:00 +0100 Subject: [PATCH] Use correct worktree when getting permalink to line (#8888) Previously this code would call `project.visible_worktrees(cx).next` which might not necessarily return the worktree matching the currently open file. What this change does is it adds `get_repo` method on `Project` that allows us to get the `GitRepository` for the current buffer. Release Notes: - Fixed `open permalink to line` not working when multiple folders are added to the project. Co-authored-by: Mikayla --- crates/editor/src/editor.rs | 38 ++++++++++++----------------- crates/project/src/project.rs | 13 ++++++++++ crates/project_core/src/worktree.rs | 5 ++++ 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ce15b36f6a..34291fbc33 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 8661ceada0..aff690b348 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 e5d50557f9..1f9e9a8e15 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,