Worktree paths in git panel, take 2 (#26047)
Modified version of #25950. We still use worktree paths, but repo paths with a status that lie outside the worktree are not excluded; instead, we relativize them by adding `..`. This makes the list in the git panel match what you'd get from running `git status` (with the repo's worktree root as the working directory). - [x] Implement + test new unrelativization logic - [x] ~~When collecting repositories, dedup by .git abs path, so worktrees can share a repo at the project level~~ dedup repos at the repository selector layer, with repos coming from larger worktrees being preferred - [x] Open single-file worktree with diff when activating a path not in the worktree Release Notes: - N/A
This commit is contained in:
parent
330e799293
commit
1763dd714b
23 changed files with 724 additions and 184 deletions
|
@ -58,7 +58,7 @@ use std::{
|
|||
future::Future,
|
||||
mem::{self},
|
||||
ops::{Deref, DerefMut},
|
||||
path::{Path, PathBuf},
|
||||
path::{Component, Path, PathBuf},
|
||||
pin::Pin,
|
||||
sync::{
|
||||
atomic::{self, AtomicU32, AtomicUsize, Ordering::SeqCst},
|
||||
|
@ -212,7 +212,11 @@ impl RepositoryEntry {
|
|||
self.work_directory.relativize(path)
|
||||
}
|
||||
|
||||
pub fn unrelativize(&self, path: &RepoPath) -> Option<Arc<Path>> {
|
||||
pub fn try_unrelativize(&self, path: &RepoPath) -> Option<Arc<Path>> {
|
||||
self.work_directory.try_unrelativize(path)
|
||||
}
|
||||
|
||||
pub fn unrelativize(&self, path: &RepoPath) -> Arc<Path> {
|
||||
self.work_directory.unrelativize(path)
|
||||
}
|
||||
|
||||
|
@ -491,7 +495,7 @@ impl WorkDirectory {
|
|||
}
|
||||
|
||||
/// This is the opposite operation to `relativize` above
|
||||
pub fn unrelativize(&self, path: &RepoPath) -> Option<Arc<Path>> {
|
||||
pub fn try_unrelativize(&self, path: &RepoPath) -> Option<Arc<Path>> {
|
||||
match self {
|
||||
WorkDirectory::InProject { relative_path } => Some(relative_path.join(path).into()),
|
||||
WorkDirectory::AboveProject {
|
||||
|
@ -504,6 +508,33 @@ impl WorkDirectory {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unrelativize(&self, path: &RepoPath) -> Arc<Path> {
|
||||
match self {
|
||||
WorkDirectory::InProject { relative_path } => relative_path.join(path).into(),
|
||||
WorkDirectory::AboveProject {
|
||||
location_in_repo, ..
|
||||
} => {
|
||||
if &path.0 == location_in_repo {
|
||||
// Single-file worktree
|
||||
return location_in_repo
|
||||
.file_name()
|
||||
.map(Path::new)
|
||||
.unwrap_or(Path::new(""))
|
||||
.into();
|
||||
}
|
||||
let mut location_in_repo = &**location_in_repo;
|
||||
let mut parents = PathBuf::new();
|
||||
loop {
|
||||
if let Ok(segment) = path.strip_prefix(location_in_repo) {
|
||||
return parents.join(segment).into();
|
||||
}
|
||||
location_in_repo = location_in_repo.parent().unwrap_or(Path::new(""));
|
||||
parents.push(Component::ParentDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_name(&self) -> String {
|
||||
match self {
|
||||
WorkDirectory::InProject { relative_path } => relative_path.display().to_string(),
|
||||
|
@ -1422,6 +1453,19 @@ impl Worktree {
|
|||
worktree_scan_id: scan_id as u64,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn dot_git_abs_path(&self, work_directory: &WorkDirectory) -> PathBuf {
|
||||
let mut path = match work_directory {
|
||||
WorkDirectory::InProject { relative_path } => self.abs_path().join(relative_path),
|
||||
WorkDirectory::AboveProject { absolute_path, .. } => absolute_path.as_ref().to_owned(),
|
||||
};
|
||||
path.push(".git");
|
||||
path
|
||||
}
|
||||
|
||||
pub fn is_single_file(&self) -> bool {
|
||||
self.root_dir().is_none()
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalWorktree {
|
||||
|
@ -5509,7 +5553,7 @@ impl BackgroundScanner {
|
|||
|
||||
let mut new_entries_by_path = SumTree::new(&());
|
||||
for (repo_path, status) in statuses.entries.iter() {
|
||||
let project_path = repository.work_directory.unrelativize(repo_path);
|
||||
let project_path = repository.work_directory.try_unrelativize(repo_path);
|
||||
|
||||
new_entries_by_path.insert_or_replace(
|
||||
StatusEntry {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue