Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gix-macros/src/momo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 12 additions & 6 deletions gix/src/repository/worktree.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::bstr::BStr;
use crate::{worktree, Worktree};

/// Interact with individual worktrees and their information.
Expand All @@ -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/<id>` and its `gitdir` file exists.
/// Return `None` otherwise.
pub fn worktree_proxy_by_id<'a>(&self, id: impl Into<&'a BStr>) -> Option<worktree::Proxy<'_>> {
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.
Expand Down
9 changes: 9 additions & 0 deletions gix/src/worktree/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PathBuf>) -> Option<Self> {
let git_dir = git_dir.into();
if git_dir.join("gitdir").is_file() {
Some(Proxy::new(parent, git_dir))
} else {
None
}
}
}

impl Proxy<'_> {
Expand Down
24 changes: 22 additions & 2 deletions gix/tests/gix/repository/worktree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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());
Expand All @@ -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"
);
}
}
Loading