Skip to content

Commit

Permalink
fix: respect core.bare=true in conjunction with the main worktree (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Nov 17, 2024
1 parent 3506afb commit 88d9d43
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 10 deletions.
34 changes: 26 additions & 8 deletions gix/src/open/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,15 +303,33 @@ impl ThreadSafeRepository {
}
}

match worktree_dir {
None if !config.is_bare && refs.git_dir().file_name() == Some(OsStr::new(gix_discover::DOT_GIT_DIR)) => {
worktree_dir = Some(git_dir.parent().expect("parent is always available").to_owned());
}
Some(_) => {
// note that we might be bare even with a worktree directory - work trees don't have to be
// the parent of a non-bare repository.
{
let looks_like_standard_git_dir =
|| refs.git_dir().file_name() == Some(OsStr::new(gix_discover::DOT_GIT_DIR));
match worktree_dir {
None if !config.is_bare && looks_like_standard_git_dir() => {
worktree_dir = Some(git_dir.parent().expect("parent is always available").to_owned());
}
Some(_) => {
// We may assume that the presence of a worktree-dir means it's not bare, but only if there
// is no configuration saying otherwise.
// Thus, if we are here and the common-dir config claims it's bare and we have inferred a worktree anyway,
// forget about it.
if looks_like_standard_git_dir()
&& config
.resolved
.boolean_filter("core.bare", |md| md.source == gix_config::Source::Local)
.transpose()
.ok()
.flatten()
.is_some()
&& config.is_bare
{
worktree_dir = None;
}
}
None => {}
}
None => {}
}

refs.write_reflog = config::cache::util::reflog_or_default(config.reflog, worktree_dir.is_some());
Expand Down
8 changes: 8 additions & 0 deletions gix/tests/fixtures/make_worktree_repo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,11 @@ mkdir $worktree && touch $worktree/file
git add file
git commit -m "make sure na index exists"
)

git init non-bare-turned-bare
(cd non-bare-turned-bare
git commit --allow-empty -m 'empty'
git config core.bare true

git worktree add ../worktree-of-bare-repo
)
35 changes: 33 additions & 2 deletions gix/tests/gix/repository/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,37 @@ fn bare_repo_with_index() -> crate::Result {
Ok(())
}

#[test]
fn non_bare_turned_bare() -> crate::Result {
let repo = named_subrepo_opts(
"make_worktree_repo.sh",
"non-bare-turned-bare",
gix::open::Options::isolated(),
)?;
assert!(
repo.is_bare(),
"the configuration dictates this, even though it looks like a main worktree"
);
assert_eq!(repo.work_dir(), None);
Ok(())
}

#[test]
fn worktree_of_bare_repo() -> crate::Result {
let repo = named_subrepo_opts(
"make_worktree_repo.sh",
"worktree-of-bare-repo",
gix::open::Options::isolated(),
)?;
assert!(!repo.is_bare(), "even though the main worktree is bare, this isn't");
assert_ne!(
repo.work_dir(),
None,
"we have opened the repo through a worktree, which is never bare"
);
Ok(())
}

#[test]
fn non_bare_non_git_repo_without_worktree() -> crate::Result {
let repo = named_subrepo_opts(
Expand Down Expand Up @@ -182,12 +213,12 @@ mod missing_config_file {
"worktree-no-config",
gix::open::Options::isolated(),
)?;
assert!(repo.work_dir().is_some());
assert!(repo.worktree().is_some());
assert!(
!repo.is_bare(),
"without config, we can't really know what the repo is actually but can guess as there is a worktree"
);
assert!(repo.work_dir().is_some());
assert!(repo.worktree().is_some());
assert_eq!(
repo.config_snapshot().meta().source,
gix::config::Source::Local,
Expand Down

0 comments on commit 88d9d43

Please sign in to comment.