mod util; use git_testtools::Env;use serial_test::serial;use util::{assert_section_value, Condition, GitEnv}; use crate::file::init::from_paths::escape_backslashes; #[test]fn relative_path_with_trailing_slash_matches_like_star_star() -> crate::Result { assert_section_value(Condition::new("gitdir:worktree/"), GitEnv::repo_name("worktree")?)} #[test]fn relative_path_without_trailing_slash_does_not_match() -> crate::Result { assert_section_value( Condition::new("gitdir:worktree").expect_original_value(), GitEnv::repo_name("worktree")?, )} #[test]fn relative_path_without_trailing_slash_and_dot_git_suffix_matches() -> crate::Result { assert_section_value(Condition::new("gitdir:worktree/.git"), GitEnv::repo_name("worktree")?)} #[test]fn tilde_slash_expands_the_current_user_home() -> crate::Result { let env = GitEnv::repo_name(std::path::Path::new("subdir").join("worktree"))?; assert_section_value(Condition::new("gitdir:~/subdir/worktree/"), env)} #[test]fn tilde_alone_does_not_match_even_if_home_is_git_directory() -> crate::Result { let env = GitEnv::repo_in_home()?; assert_section_value(Condition::new("gitdir:~").expect_original_value(), env)} #[test]fn explicit_star_star_prefix_and_suffix_match_zero_or_more_path_components() -> crate::Result { assert_section_value(Condition::new("gitdir:**/worktree/**"), GitEnv::repo_name("worktree")?)} #[test]fn double_slash_does_not_match() -> crate::Result { assert_section_value( Condition::new("gitdir://worktree").expect_original_value(), GitEnv::repo_name("worktree")?, )} #[test]fn absolute_git_dir_with_os_separators_match() -> crate::Result { assert_section_value( original_value_on_windows(Condition::new("gitdir:$gitdir")), GitEnv::repo_name("worktree")?, )} #[test]fn absolute_worktree_dir_with_os_separators_does_not_match_if_trailing_slash_is_missing() -> crate::Result { assert_section_value( Condition::new("gitdir:$worktree").expect_original_value(), GitEnv::repo_name("worktree")?, )} #[test]fn absolute_worktree_dir_with_os_separators_matches_with_trailing_glob() -> crate::Result { assert_section_value( original_value_on_windows(Condition::new(format!( "gitdir:$worktree{}**", std::path::MAIN_SEPARATOR ))), GitEnv::repo_name("worktree")?, )} #[test]fn dot_slash_path_is_replaced_with_directory_containing_the_including_config_file() -> crate::Result { assert_section_value( Condition::new("gitdir:./").set_user_config_instead_of_repo_config(), GitEnv::repo_name("worktree")?, // the user configuration is in $HOME, which is parent to $HOME/worktree, and the pattern path ends up being $HOME/**, including worktree/.git )} #[test]#[serial]fn dot_slash_from_environment_causes_error() -> crate::Result { let env = GitEnv::repo_name("worktree")?; { let _environment = Env::new() .set("GIT_CONFIG_COUNT", "1") .set( "GIT_CONFIG_KEY_0", format!("includeIf.gitdir:{}.path", escape_backslashes(env.git_dir())), ) .set("GIT_CONFIG_VALUE_0", "./include.path"); let res = git_config::File::from_env(env.to_init_options()); assert!( matches!( res, Err(git_config::file::init::from_env::Error::Includes( git_config::file::includes::Error::MissingConfigPath )) ), "this is a failure of resolving the include path, after trying to include it" ); } let absolute_path = escape_backslashes(env.home_dir().join("include.config")); { let _environment = Env::new() .set("GIT_CONFIG_COUNT", "1") .set("GIT_CONFIG_KEY_0", "includeIf.gitdir:./worktree/.path") .set("GIT_CONFIG_VALUE_0", &absolute_path); let res = git_config::File::from_env(env.to_init_options()); assert!( matches!( res, Err(git_config::file::init::from_env::Error::Includes( git_config::file::includes::Error::MissingConfigPath )) ), "here the pattern path tries to be resolved and fails as target config isn't set" ); } { let _environment = Env::new() .set("GIT_CONFIG_COUNT", "1") .set( "GIT_CONFIG_KEY_0", format!("includeIf.gitdir:{}.path", escape_backslashes(env.git_dir())), ) .set("GIT_CONFIG_VALUE_0", absolute_path); let res = git_config::File::from_env(env.to_init_options()); assert!(res.is_ok(), "missing paths are ignored as before"); } Ok(())} #[test]fn dot_dot_slash_prefixes_are_not_special_and_are_not_what_you_want() -> crate::Result { assert_section_value( Condition::new("gitdir:../") .set_user_config_instead_of_repo_config() .expect_no_value(), GitEnv::repo_name("worktree")?, )} #[test]fn leading_dots_are_not_special() -> crate::Result { assert_section_value(Condition::new("gitdir:.hidden/"), GitEnv::repo_name(".hidden")?)} #[test]fn dot_slash_path_with_dot_git_suffix_matches() -> crate::Result { assert_section_value( Condition::new("gitdir:./worktree/.git").set_user_config_instead_of_repo_config(), GitEnv::repo_name("worktree")?, )} #[test]fn globbing_and_wildcards() -> crate::Result { assert_section_value( Condition::new("gitdir:stan?ard/glo*ng/[xwz]ildcards/.git").set_user_config_instead_of_repo_config(), GitEnv::repo_name("standard/globbing/wildcards")?, )} #[test]fn case_insensitive_matches_any_case() -> crate::Result { assert_section_value(Condition::new("gitdir/i:WORKTREE/"), GitEnv::repo_name("worktree")?)?; assert_section_value( Condition::new("gitdir:WORKTREE/").expect_original_value(), GitEnv::repo_name("worktree")?, )} #[test]fn pattern_with_escaped_backslash() -> crate::Result { assert_section_value( original_value_on_windows(Condition::new(r#"gitdir:\\work\\tree\\/"#)), GitEnv::repo_name("worktree")?, )} #[test]fn pattern_with_backslash() -> crate::Result { assert_section_value(Condition::new(r#"gitdir:work\tree/"#), GitEnv::repo_name("worktree")?)} #[test]fn star_star_in_the_middle() -> crate::Result { assert_section_value( Condition::new("gitdir:**/dir/**/worktree/**"), GitEnv::repo_name("dir/worktree")?, )} #[test]#[cfg(not(windows))]fn tilde_expansion_with_symlink() -> crate::Result { let env = util::git_env_with_symlinked_repo()?; assert_section_value(Condition::new("gitdir:~/worktree/"), env)} #[test]#[cfg(not(windows))]fn dot_path_with_symlink() -> crate::Result { let env = util::git_env_with_symlinked_repo()?; assert_section_value( Condition::new("gitdir:./symlink-worktree/.git").set_user_config_instead_of_repo_config(), env, )} #[test]#[cfg(not(windows))]fn relative_path_matching_symlink() -> crate::Result { let env = util::git_env_with_symlinked_repo()?; assert_section_value( Condition::new("gitdir:symlink-worktree/").set_user_config_instead_of_repo_config(), env, )} #[test]#[cfg(not(windows))]fn dot_path_matching_symlink_with_icase() -> crate::Result { let env = util::git_env_with_symlinked_repo()?; assert_section_value( Condition::new("gitdir/i:SYMLINK-WORKTREE/").set_user_config_instead_of_repo_config(), env, )} fn original_value_on_windows(c: Condition) -> Condition { if cfg!(windows) { c.expect_original_value() } else { c }}
mod util;
use git_testtools::Env;
use serial_test::serial;
use util::{assert_section_value, Condition, GitEnv};
use crate::file::init::from_paths::escape_backslashes;
#[test]
fn relative_path_with_trailing_slash_matches_like_star_star() -> crate::Result {
assert_section_value(Condition::new("gitdir:worktree/"), GitEnv::repo_name("worktree")?)
}
#[test]
fn relative_path_without_trailing_slash_does_not_match() -> crate::Result {
assert_section_value(
Condition::new("gitdir:worktree").expect_original_value(),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn relative_path_without_trailing_slash_and_dot_git_suffix_matches() -> crate::Result {
assert_section_value(Condition::new("gitdir:worktree/.git"), GitEnv::repo_name("worktree")?)
}
#[test]
fn tilde_slash_expands_the_current_user_home() -> crate::Result {
let env = GitEnv::repo_name(std::path::Path::new("subdir").join("worktree"))?;
assert_section_value(Condition::new("gitdir:~/subdir/worktree/"), env)
}
#[test]
fn tilde_alone_does_not_match_even_if_home_is_git_directory() -> crate::Result {
let env = GitEnv::repo_in_home()?;
assert_section_value(Condition::new("gitdir:~").expect_original_value(), env)
}
#[test]
fn explicit_star_star_prefix_and_suffix_match_zero_or_more_path_components() -> crate::Result {
assert_section_value(Condition::new("gitdir:**/worktree/**"), GitEnv::repo_name("worktree")?)
}
#[test]
fn double_slash_does_not_match() -> crate::Result {
assert_section_value(
Condition::new("gitdir://worktree").expect_original_value(),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn absolute_git_dir_with_os_separators_match() -> crate::Result {
assert_section_value(
original_value_on_windows(Condition::new("gitdir:$gitdir")),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn absolute_worktree_dir_with_os_separators_does_not_match_if_trailing_slash_is_missing() -> crate::Result {
assert_section_value(
Condition::new("gitdir:$worktree").expect_original_value(),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn absolute_worktree_dir_with_os_separators_matches_with_trailing_glob() -> crate::Result {
assert_section_value(
original_value_on_windows(Condition::new(format!(
"gitdir:$worktree{}**",
std::path::MAIN_SEPARATOR
))),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn dot_slash_path_is_replaced_with_directory_containing_the_including_config_file() -> crate::Result {
assert_section_value(
Condition::new("gitdir:./").set_user_config_instead_of_repo_config(),
GitEnv::repo_name("worktree")?,
// the user configuration is in $HOME, which is parent to $HOME/worktree, and the pattern path ends up being $HOME/**, including worktree/.git
)
}
#[test]
#[serial]
fn dot_slash_from_environment_causes_error() -> crate::Result {
let env = GitEnv::repo_name("worktree")?;
{
let _environment = Env::new()
.set("GIT_CONFIG_COUNT", "1")
.set(
"GIT_CONFIG_KEY_0",
format!("includeIf.gitdir:{}.path", escape_backslashes(env.git_dir())),
)
.set("GIT_CONFIG_VALUE_0", "./include.path");
let res = git_config::File::from_env(env.to_init_options());
assert!(
matches!(
res,
Err(git_config::file::init::from_env::Error::Includes(
git_config::file::includes::Error::MissingConfigPath
))
),
"this is a failure of resolving the include path, after trying to include it"
);
}
let absolute_path = escape_backslashes(env.home_dir().join("include.config"));
{
let _environment = Env::new()
.set("GIT_CONFIG_COUNT", "1")
.set("GIT_CONFIG_KEY_0", "includeIf.gitdir:./worktree/.path")
.set("GIT_CONFIG_VALUE_0", &absolute_path);
let res = git_config::File::from_env(env.to_init_options());
assert!(
matches!(
res,
Err(git_config::file::init::from_env::Error::Includes(
git_config::file::includes::Error::MissingConfigPath
))
),
"here the pattern path tries to be resolved and fails as target config isn't set"
);
}
{
let _environment = Env::new()
.set("GIT_CONFIG_COUNT", "1")
.set(
"GIT_CONFIG_KEY_0",
format!("includeIf.gitdir:{}.path", escape_backslashes(env.git_dir())),
)
.set("GIT_CONFIG_VALUE_0", absolute_path);
let res = git_config::File::from_env(env.to_init_options());
assert!(res.is_ok(), "missing paths are ignored as before");
}
Ok(())
}
#[test]
fn dot_dot_slash_prefixes_are_not_special_and_are_not_what_you_want() -> crate::Result {
assert_section_value(
Condition::new("gitdir:../")
.set_user_config_instead_of_repo_config()
.expect_no_value(),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn leading_dots_are_not_special() -> crate::Result {
assert_section_value(Condition::new("gitdir:.hidden/"), GitEnv::repo_name(".hidden")?)
}
#[test]
fn dot_slash_path_with_dot_git_suffix_matches() -> crate::Result {
assert_section_value(
Condition::new("gitdir:./worktree/.git").set_user_config_instead_of_repo_config(),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn globbing_and_wildcards() -> crate::Result {
assert_section_value(
Condition::new("gitdir:stan?ard/glo*ng/[xwz]ildcards/.git").set_user_config_instead_of_repo_config(),
GitEnv::repo_name("standard/globbing/wildcards")?,
)
}
#[test]
fn case_insensitive_matches_any_case() -> crate::Result {
assert_section_value(Condition::new("gitdir/i:WORKTREE/"), GitEnv::repo_name("worktree")?)?;
assert_section_value(
Condition::new("gitdir:WORKTREE/").expect_original_value(),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn pattern_with_escaped_backslash() -> crate::Result {
assert_section_value(
original_value_on_windows(Condition::new(r#"gitdir:\\work\\tree\\/"#)),
GitEnv::repo_name("worktree")?,
)
}
#[test]
fn pattern_with_backslash() -> crate::Result {
assert_section_value(Condition::new(r#"gitdir:work\tree/"#), GitEnv::repo_name("worktree")?)
}
#[test]
fn star_star_in_the_middle() -> crate::Result {
assert_section_value(
Condition::new("gitdir:**/dir/**/worktree/**"),
GitEnv::repo_name("dir/worktree")?,
)
}
#[test]
#[cfg(not(windows))]
fn tilde_expansion_with_symlink() -> crate::Result {
let env = util::git_env_with_symlinked_repo()?;
assert_section_value(Condition::new("gitdir:~/worktree/"), env)
}
#[test]
#[cfg(not(windows))]
fn dot_path_with_symlink() -> crate::Result {
let env = util::git_env_with_symlinked_repo()?;
assert_section_value(
Condition::new("gitdir:./symlink-worktree/.git").set_user_config_instead_of_repo_config(),
env,
)
}
#[test]
#[cfg(not(windows))]
fn relative_path_matching_symlink() -> crate::Result {
let env = util::git_env_with_symlinked_repo()?;
assert_section_value(
Condition::new("gitdir:symlink-worktree/").set_user_config_instead_of_repo_config(),
env,
)
}
#[test]
#[cfg(not(windows))]
fn dot_path_matching_symlink_with_icase() -> crate::Result {
let env = util::git_env_with_symlinked_repo()?;
assert_section_value(
Condition::new("gitdir/i:SYMLINK-WORKTREE/").set_user_config_instead_of_repo_config(),
env,
)
}
fn original_value_on_windows(c: Condition) -> Condition {
if cfg!(windows) {
c.expect_original_value()
} else {
c
}
}