diff --git a/gix-macros/src/momo.rs b/gix-macros/src/momo.rs index a007c1b2082..f8b8047dab4 100644 --- a/gix-macros/src/momo.rs +++ b/gix-macros/src/momo.rs @@ -184,13 +184,13 @@ fn convert( let pat_ident = match &mut *pat_type.pat { Pat::Ident(pat_ident) if pat_ident.by_ref.is_none() && pat_ident.subpat.is_none() => pat_ident, _ => { - pat_type.pat = Box::new(Pat::Ident(PatIdent { + *pat_type.pat = Pat::Ident(PatIdent { ident: Ident::new(&format!("arg_{i}_gen_by_momo_"), proc_macro2::Span::call_site()), attrs: Default::default(), by_ref: None, mutability: None, subpat: None, - })); + }); if let Pat::Ident(pat_ident) = &mut *pat_type.pat { pat_ident diff --git a/gix/src/repository/worktree.rs b/gix/src/repository/worktree.rs index db395c01dc3..5dc76603494 100644 --- a/gix/src/repository/worktree.rs +++ b/gix/src/repository/worktree.rs @@ -1,3 +1,4 @@ +use crate::bstr::BStr; use crate::{worktree, Worktree}; /// Interact with individual worktrees and their information. @@ -20,17 +21,22 @@ impl crate::Repository { for entry in iter { let entry = entry?; let worktree_git_dir = entry.path(); - if worktree_git_dir.join("gitdir").is_file() { - res.push(worktree::Proxy { - parent: self, - git_dir: worktree_git_dir, - }); - } + res.extend(worktree::Proxy::new_if_gitdir_file_exists(self, worktree_git_dir)); } res.sort_by(|a, b| a.git_dir.cmp(&b.git_dir)); Ok(res) } + /// Return the worktree that [is identified](Worktree::id) by the given `id`, if it exists at + /// `.git/worktrees/` and its `gitdir` file exists. + /// Return `None` otherwise. + pub fn worktree_proxy_by_id<'a>(&self, id: impl Into<&'a BStr>) -> Option> { + worktree::Proxy::new_if_gitdir_file_exists( + self, + self.common_dir().join("worktrees").join(gix_path::from_bstr(id.into())), + ) + } + /// Return the repository owning the main worktree, typically from a linked worktree. /// /// Note that it might be the one that is currently open if this repository doesn't point to a linked worktree. diff --git a/gix/src/worktree/proxy.rs b/gix/src/worktree/proxy.rs index e4b6672774c..b6f1b423e00 100644 --- a/gix/src/worktree/proxy.rs +++ b/gix/src/worktree/proxy.rs @@ -31,6 +31,15 @@ impl<'repo> Proxy<'repo> { git_dir: git_dir.into(), } } + + pub(crate) fn new_if_gitdir_file_exists(parent: &'repo Repository, git_dir: impl Into) -> Option { + let git_dir = git_dir.into(); + if git_dir.join("gitdir").is_file() { + Some(Proxy::new(parent, git_dir)) + } else { + None + } + } } impl Proxy<'_> { diff --git a/gix/tests/gix/repository/worktree.rs b/gix/tests/gix/repository/worktree.rs index 9ab8eb95c8c..773d875f2f1 100644 --- a/gix/tests/gix/repository/worktree.rs +++ b/gix/tests/gix/repository/worktree.rs @@ -350,8 +350,14 @@ fn run_assertions(main_repo: gix::Repository, should_be_bare: bool) { "in our case prunable repos have no worktree base" ); + assert_eq!( + main_repo.worktree_proxy_by_id(actual.id()).expect("exists").git_dir(), + actual.git_dir(), + "we can basically get the same proxy by its ID explicitly" + ); + let repo = if base.is_dir() { - let repo = actual.into_repo().unwrap(); + let repo = actual.clone().into_repo().unwrap(); assert_eq!( &gix::open(base).unwrap(), &repo, @@ -366,7 +372,7 @@ fn run_assertions(main_repo: gix::Repository, should_be_bare: bool) { ), "missing bases are detected" ); - actual.into_repo_with_possibly_inaccessible_worktree().unwrap() + actual.clone().into_repo_with_possibly_inaccessible_worktree().unwrap() }; let worktree = repo.worktree().expect("linked worktrees have at least a base path"); assert!(!worktree.is_main()); @@ -378,5 +384,19 @@ fn run_assertions(main_repo: gix::Repository, should_be_bare: bool) { main_repo, "main repo from worktree repo is the actual main repo" ); + + let proxy_by_id = repo + .worktree_proxy_by_id(actual.id()) + .expect("can get the proxy from a linked repo as well"); + assert_ne!( + proxy_by_id.git_dir(), + actual.git_dir(), + "The git directories might not look the same…" + ); + assert_eq!( + gix_path::realpath(proxy_by_id.git_dir()).ok(), + gix_path::realpath(actual.git_dir()).ok(), + "…but they are the same effectively" + ); } }