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 <mikayla@zed.dev>
This commit is contained in:
Thorsten Ball 2024-03-05 16:59:00 +01:00 committed by GitHub
parent d286c56ebb
commit 2b8b913b6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 22 deletions

View File

@ -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<Self>) -> Result<url::Url> {
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::<Point>(cx);
let selection = selections.iter().peekable().next();

View File

@ -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<Arc<Mutex<dyn GitRepository>>> {
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(

View File

@ -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<Arc<Mutex<dyn GitRepository>>> {
self.local_repo_for_path(path)
.map(|(_, entry)| entry.repo_ptr.clone())
}
fn build_update(
&self,
project_id: u64,