Skip to content

fix 1985 #1987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2025
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
51 changes: 30 additions & 21 deletions gix/src/open/repository.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#![allow(clippy::result_large_err)]
use gix_config::file::Metadata;
use gix_features::threading::OwnShared;
use gix_object::bstr::ByteSlice;
use gix_path::RelativePath;
use std::path::Path;
use std::{
borrow::Cow,
collections::{btree_map::Entry, BTreeMap},
ffi::OsStr,
path::PathBuf,
};

use gix_features::threading::OwnShared;
use gix_object::bstr::ByteSlice;
use gix_path::RelativePath;

use super::{Error, Options};
use crate::{
bstr::BString,
Expand Down Expand Up @@ -257,26 +258,32 @@ impl ThreadSafeRepository {
// core.worktree might be used to overwrite the worktree directory
if !config.is_bare {
let mut key_source = None;
fn assure_config_is_from_current_repo(
section: &gix_config::file::Metadata,
git_dir: &Path,
current_dir: &Path,
filter_config_section: &mut fn(&Metadata) -> bool,
) -> bool {
if !filter_config_section(section) {
return false;
}
// ignore worktree settings that aren't from our repository. This can happen
// with worktrees of submodules for instance.
section
.path
.as_deref()
.and_then(|p| gix_path::normalize(p.into(), current_dir))
.is_some_and(|config_path| config_path.starts_with(git_dir))
}
let worktree_path = config
.resolved
.path_filter(Core::WORKTREE, {
|section| {
if !filter_config_section(section) {
return false;
}
// ignore worktree settings that aren't from our repository. This can happen
// with worktrees of submodules for instance.
let is_config_in_our_repo = section
.path
.as_deref()
.and_then(|p| gix_path::normalize(p.into(), current_dir))
.is_some_and(|config_path| config_path.starts_with(&git_dir));
if !is_config_in_our_repo {
return false;
}
.path_filter(Core::WORKTREE, |section| {
let res =
assure_config_is_from_current_repo(section, &git_dir, current_dir, &mut filter_config_section);
if res {
key_source = Some(section.source);
true
}
res
})
.zip(key_source);
if let Some((wt, key_source)) = worktree_path {
Expand All @@ -302,7 +309,9 @@ impl ThreadSafeRepository {
} else if !config.lenient_config
&& config
.resolved
.boolean_filter(Core::WORKTREE, &mut filter_config_section)
.boolean_filter(Core::WORKTREE, |section| {
assure_config_is_from_current_repo(section, &git_dir, current_dir, &mut filter_config_section)
})
.is_some()
{
return Err(Error::from(config::Error::ConfigTypedString(
Expand Down
44 changes: 34 additions & 10 deletions gix/tests/gix-init.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
#![allow(clippy::result_large_err)]

use gix::open::Permissions;
use gix::{Repository, ThreadSafeRepository};
use gix_sec::Permission;
use serial_test::serial;

pub fn named_subrepo_opts(
fixture: &str,
name: &str,
opts: gix::open::Options,
) -> std::result::Result<Repository, gix::open::Error> {
let repo_path = gix_testtools::scripted_fixture_read_only(fixture).unwrap().join(name);
Ok(ThreadSafeRepository::open_opts(repo_path, opts)?.to_thread_local())
}

mod with_overrides {
use std::borrow::Cow;

use gix::{Repository, ThreadSafeRepository};
use crate::named_subrepo_opts;
use gix_object::bstr::BStr;
use gix_sec::Permission;
use gix_testtools::Env;
use serial_test::serial;

pub fn named_subrepo_opts(
fixture: &str,
name: &str,
opts: gix::open::Options,
) -> std::result::Result<Repository, gix::open::Error> {
let repo_path = gix_testtools::scripted_fixture_read_only(fixture).unwrap().join(name);
Ok(ThreadSafeRepository::open_opts(repo_path, opts)?.to_thread_local())
}

#[test]
#[serial]
fn order_from_api_and_cli_and_environment() -> gix_testtools::Result {
Expand Down Expand Up @@ -264,3 +270,21 @@ mod with_overrides {
Cow::Borrowed(s.into())
}
}

#[test]
#[serial]
fn git_worktree_and_strict_config() -> gix_testtools::Result {
let _restore_env_on_drop = gix_testtools::Env::new().set("GIT_WORK_TREE", ".");
let _repo = named_subrepo_opts(
"make_empty_repo.sh",
"",
gix::open::Options::isolated()
.permissions({
let mut perm = Permissions::isolated();
perm.env.git_prefix = Permission::Allow;
perm
})
.strict_config(true),
)?;
Ok(())
}
Loading