Skip to content

Commit

Permalink
fix: make GIT_WORK_TREE variable work as expected.
Browse files Browse the repository at this point in the history
Now it's picked up durign initialization.
  • Loading branch information
Byron committed Oct 21, 2024
1 parent 9c619e4 commit e9b3db8
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 14 deletions.
2 changes: 1 addition & 1 deletion gix/src/clone/fetch/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fn write_to_local_config(config: &gix_config::File<'static>, mode: WriteMode) ->
.append(matches!(mode, WriteMode::Append))
.open(config.meta().path.as_deref().expect("local config with path set"))?;
local_config.write_all(config.detect_newline_style())?;
config.write_to_filter(&mut local_config, &mut |s| s.meta().source == gix_config::Source::Local)
config.write_to_filter(&mut local_config, |s| s.meta().source == gix_config::Source::Local)
}

pub fn append_config_to_repo_config(repo: &mut Repository, config: gix_config::File<'static>) {
Expand Down
6 changes: 3 additions & 3 deletions gix/src/config/cache/access.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(clippy::result_large_err)]
use std::{borrow::Cow, path::PathBuf, time::Duration};

use gix_config::file::Metadata;
use gix_lock::acquire::Fail;
use std::{borrow::Cow, path::PathBuf, time::Duration};

use crate::{
config,
Expand Down Expand Up @@ -510,7 +510,7 @@ impl Cache {
pub(crate) fn trusted_file_path<'config>(
config: &'config gix_config::File<'_>,
key: impl gix_config::AsKey,
filter: &mut gix_config::file::MetadataFilter,
filter: impl FnMut(&Metadata) -> bool,
lenient_config: bool,
environment: crate::open::permissions::Environment,
) -> Option<Result<Cow<'config, std::path::Path>, gix_config::path::interpolate::Error>> {
Expand Down
9 changes: 9 additions & 0 deletions gix/src/config/cache/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,15 @@ fn apply_environment_overrides(

let mut env_override = gix_config::File::new(gix_config::file::Metadata::from(gix_config::Source::EnvOverride));
for (section_name, subsection_name, permission, data) in [
(
"core",
None,
git_prefix,
&[{
let key = &Core::WORKTREE;
(env(key), key.name)
}][..],
),
(
"http",
None,
Expand Down
6 changes: 3 additions & 3 deletions gix/src/config/snapshot/credential_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub(super) mod function {
mut url: gix_url::Url,
config: &gix_config::File<'_>,
is_lenient_config: bool,
filter: &mut gix_config::file::MetadataFilter,
mut filter: impl FnMut(&gix_config::file::Metadata) -> bool,
environment: crate::open::permissions::Environment,
mut use_http_path: bool,
) -> Result<
Expand All @@ -105,7 +105,7 @@ pub(super) mod function {
let url_had_user_initially = url.user().is_some();
normalize(&mut url);

if let Some(credential_sections) = config.sections_by_name_and_filter("credential", filter) {
if let Some(credential_sections) = config.sections_by_name_and_filter("credential", &mut filter) {
for section in credential_sections {
let section = match section.header().subsection_name() {
Some(pattern) => gix_url::parse(pattern).ok().and_then(|mut pattern| {
Expand Down Expand Up @@ -181,7 +181,7 @@ pub(super) mod function {
askpass: crate::config::cache::access::trusted_file_path(
config,
&Core::ASKPASS,
filter,
&mut filter,
is_lenient_config,
environment,
)
Expand Down
2 changes: 1 addition & 1 deletion gix/src/config/tree/sections/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl Core {
/// The `core.worktree` key.
pub const WORKTREE: keys::Any = keys::Any::new("worktree", &config::Tree::CORE)
.with_environment_override("GIT_WORK_TREE")
.with_deviation("Overriding the worktree with environment variables is supported using `ThreadSafeRepository::open_with_environment_overrides()");
.with_deviation("Command-line overrides also work, and they act lie an environment override. If set in the git configuration file, relative paths are relative to it.");
/// The `core.askPass` key.
pub const ASKPASS: keys::Executable = keys::Executable::new_executable("askPass", &config::Tree::CORE)
.with_environment_override("GIT_ASKPASS")
Expand Down
30 changes: 25 additions & 5 deletions gix/src/open/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl ThreadSafeRepository {
}

/// Try to open a git repository in `fallback_directory` (can be worktree or `.git` directory) only if there is no override
/// from of the `gitdir` using git environment variables.
/// of the `gitdir` using git environment variables.
///
/// Use the `trust_map` to apply options depending in the trust level for `directory` or the directory it's overridden with.
/// The `.git` directory whether given or computed is used for trust checks.
Expand Down Expand Up @@ -135,7 +135,7 @@ impl ThreadSafeRepository {
}
};

// The be altered later based on `core.precomposeUnicode`.
// To be altered later based on `core.precomposeUnicode`.
let cwd = gix_fs::current_dir(false)?;
let (git_dir, worktree_dir) = gix_discover::repository::Path::from_dot_git_dir(path, path_kind, &cwd)
.expect("we have sanitized path with is_git()")
Expand Down Expand Up @@ -258,15 +258,35 @@ impl ThreadSafeRepository {

// core.worktree might be used to overwrite the worktree directory
if !config.is_bare {
if let Some(wt) = config.resolved.path_filter(Core::WORKTREE, &mut filter_config_section) {
let mut key_source = None;
let worktree_path = config
.resolved
.path_filter(Core::WORKTREE, {
|section| {
let res = filter_config_section(section);
if res {
key_source = Some(section.source);
}
res
}
})
.zip(key_source);
if let Some((wt, key_source)) = worktree_path {
let wt_clone = wt.clone();
let wt_path = wt
.interpolate(interpolate_context(git_install_dir.as_deref(), home.as_deref()))
.map_err(|err| config::Error::PathInterpolation {
path: wt_clone.value.into_owned(),
source: err,
})?;
worktree_dir = gix_path::normalize(git_dir.join(wt_path).into(), current_dir).map(Cow::into_owned);
let wt_path = match key_source {
gix_config::Source::Env
| gix_config::Source::Cli
| gix_config::Source::Api
| gix_config::Source::EnvOverride => wt_path,
_ => git_dir.join(wt_path).into(),
};
worktree_dir = gix_path::normalize(wt_path, current_dir).map(Cow::into_owned);
#[allow(unused_variables)]
if let Some(worktree_path) = worktree_dir.as_deref().filter(|wtd| !wtd.is_dir()) {
gix_trace::warn!("The configured worktree path '{}' is not a directory or doesn't exist - `core.worktree` may be misleading", worktree_path.display());
Expand All @@ -284,7 +304,7 @@ impl ThreadSafeRepository {
}

match worktree_dir {
None if !config.is_bare && refs.git_dir().extension() == Some(OsStr::new(gix_discover::DOT_GIT_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(_) => {
Expand Down
2 changes: 1 addition & 1 deletion gix/tests/gix/repository/worktree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mod with_core_worktree_config {
assert_eq!(
repo.work_dir().unwrap(),
repo.git_dir().parent().unwrap().parent().unwrap().join("worktree"),
"work_dir is set to core.worktree config value, relative paths are appended to `git_dir() and made absolute`"
"{name}|{is_relative}: work_dir is set to core.worktree config value, relative paths are appended to `git_dir() and made absolute`"
);
} else {
assert_eq!(
Expand Down

0 comments on commit e9b3db8

Please sign in to comment.