From 43b57c13f12fd364ac0a3da87324fdc72ba5505e Mon Sep 17 00:00:00 2001 From: Jason Han Date: Tue, 7 Jul 2026 00:56:58 -0400 Subject: [PATCH] fix: `Repository::kind()` detects linked worktrees of bare repos --- gix/src/repository/location.rs | 3 +- gix/tests/fixtures/make_worktree_repo.sh | 5 +++ gix/tests/gix/repository/open.rs | 45 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/gix/src/repository/location.rs b/gix/src/repository/location.rs index 50f0ca99a19..f4e72028b54 100644 --- a/gix/src/repository/location.rs +++ b/gix/src/repository/location.rs @@ -127,9 +127,10 @@ impl crate::Repository { pub fn kind(&self) -> crate::repository::Kind { use gix_discover::path::RepositoryKind::*; match gix_discover::path::repository_kind(self.git_dir()) { - None | Some(Common) => crate::repository::Kind::Common, Some(Submodule) => crate::repository::Kind::Submodule, Some(LinkedWorktree) => crate::repository::Kind::LinkedWorkTree, + None | Some(Common) if self.git_dir() != self.common_dir() => crate::repository::Kind::LinkedWorkTree, + None | Some(Common) => crate::repository::Kind::Common, } } diff --git a/gix/tests/fixtures/make_worktree_repo.sh b/gix/tests/fixtures/make_worktree_repo.sh index b9617b953fe..d30d278020c 100755 --- a/gix/tests/fixtures/make_worktree_repo.sh +++ b/gix/tests/fixtures/make_worktree_repo.sh @@ -64,3 +64,8 @@ git init non-bare-turned-bare git worktree add ../worktree-of-bare-repo ) + +git clone --bare --shared repo natively-bare-repo +(cd natively-bare-repo + git worktree add ../worktree-of-natively-bare-repo +) diff --git a/gix/tests/gix/repository/open.rs b/gix/tests/gix/repository/open.rs index 6341500f912..6e5a5feac0e 100644 --- a/gix/tests/gix/repository/open.rs +++ b/gix/tests/gix/repository/open.rs @@ -190,6 +190,51 @@ fn worktree_of_bare_repo() -> crate::Result { Ok(()) } +#[test] +fn worktree_of_natively_bare_repo() -> crate::Result { + let repo = named_subrepo_opts( + "make_worktree_repo.sh", + "worktree-of-natively-bare-repo", + gix::open::Options::isolated(), + )?; + assert_ne!( + repo.workdir(), + None, + "we have opened the repo through a worktree, which is never bare" + ); + assert!( + !repo + .worktree() + .expect("the worktree is available, it's linked") + .is_main(), + "linked worktrees can exist for any repository, even bare" + ); + assert!( + repo.is_bare(), + "the shared config has core.bare=true, which a linked worktree inherits even though it has a workdir" + ); + assert_eq!(repo.kind(), gix::repository::Kind::LinkedWorkTree); + Ok(()) +} + +#[test] +fn natively_bare_repo_itself_is_common() -> crate::Result { + let repo = named_subrepo_opts( + "make_worktree_repo.sh", + "natively-bare-repo", + gix::open::Options::isolated(), + )?; + assert!(repo.is_bare()); + assert_eq!(repo.workdir(), None, "the bare repository itself has no worktree"); + assert_eq!( + repo.git_dir(), + repo.common_dir(), + "there is no linked-worktree redirection" + ); + assert_eq!(repo.kind(), gix::repository::Kind::Common); + Ok(()) +} + #[test] fn non_bare_non_git_repo_without_worktree() -> crate::Result { let repo = named_subrepo_opts(