config: let sequence require a successful file
Teach `do_git_config_sequence()` to optionally report an error if no configuration files in the sequence were successfully processed. Gate this new behaviour with a flag and keep it disabled for now. Add tests to record existing behaviour and prevent regressions in the next patch, "config: read global scope via config_sequence", which adds a code path that enables the flag. When no global configuration file exists, `git config list` succeeds whereas `git config list --global` fails. The command output is irrelevant, so only check the exit code. Signed-off-by: Delilah Ashley Wu <delilahwu@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>jch
parent
f0a16901bd
commit
36e859020c
57
config.c
57
config.c
|
|
@ -1544,11 +1544,27 @@ int git_config_system(void)
|
|||
return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
|
||||
}
|
||||
|
||||
static void attempt_git_config_from_file_with_options(config_fn_t fn,
|
||||
const char *filename,
|
||||
void *data,
|
||||
enum config_scope scope,
|
||||
const struct config_options *opts,
|
||||
int *success_count,
|
||||
int *cumulative_ret)
|
||||
{
|
||||
int ret = git_config_from_file_with_options(fn, filename, data,
|
||||
scope, opts);
|
||||
if (!ret)
|
||||
(*success_count)++;
|
||||
*cumulative_ret += ret;
|
||||
}
|
||||
|
||||
static int do_git_config_sequence(const struct config_options *opts,
|
||||
const struct repository *repo,
|
||||
config_fn_t fn, void *data)
|
||||
const struct repository *repo, config_fn_t fn,
|
||||
void *data, int require_successful_config)
|
||||
{
|
||||
int ret = 0;
|
||||
int success_count = 0;
|
||||
char *system_config = git_system_config();
|
||||
char *xdg_config = NULL;
|
||||
char *user_config = NULL;
|
||||
|
|
@ -1574,32 +1590,35 @@ static int do_git_config_sequence(const struct config_options *opts,
|
|||
if (git_config_system() && system_config &&
|
||||
!access_or_die(system_config, R_OK,
|
||||
opts->system_gently ? ACCESS_EACCES_OK : 0))
|
||||
ret += git_config_from_file_with_options(fn, system_config,
|
||||
data, CONFIG_SCOPE_SYSTEM,
|
||||
NULL);
|
||||
attempt_git_config_from_file_with_options(fn, system_config, data,
|
||||
CONFIG_SCOPE_SYSTEM, NULL,
|
||||
&success_count, &ret);
|
||||
|
||||
git_global_config_paths(&user_config, &xdg_config);
|
||||
|
||||
if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK))
|
||||
ret += git_config_from_file_with_options(fn, xdg_config, data,
|
||||
CONFIG_SCOPE_GLOBAL, NULL);
|
||||
attempt_git_config_from_file_with_options(fn, xdg_config,
|
||||
data,
|
||||
CONFIG_SCOPE_GLOBAL,
|
||||
NULL, &success_count, &ret);
|
||||
|
||||
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
|
||||
ret += git_config_from_file_with_options(fn, user_config, data,
|
||||
CONFIG_SCOPE_GLOBAL, NULL);
|
||||
attempt_git_config_from_file_with_options(fn, user_config,
|
||||
data,
|
||||
CONFIG_SCOPE_GLOBAL,
|
||||
NULL, &success_count, &ret);
|
||||
|
||||
if (!opts->ignore_repo && repo_config &&
|
||||
!access_or_die(repo_config, R_OK, 0))
|
||||
ret += git_config_from_file_with_options(fn, repo_config, data,
|
||||
CONFIG_SCOPE_LOCAL, NULL);
|
||||
attempt_git_config_from_file_with_options(fn, repo_config, data,
|
||||
CONFIG_SCOPE_LOCAL, NULL, &success_count, &ret);
|
||||
|
||||
if (!opts->ignore_worktree && worktree_config &&
|
||||
repo && repo->repository_format_worktree_config &&
|
||||
!access_or_die(worktree_config, R_OK, 0)) {
|
||||
ret += git_config_from_file_with_options(fn, worktree_config, data,
|
||||
CONFIG_SCOPE_WORKTREE,
|
||||
NULL);
|
||||
}
|
||||
!access_or_die(worktree_config, R_OK, 0))
|
||||
attempt_git_config_from_file_with_options(fn, worktree_config, data,
|
||||
CONFIG_SCOPE_WORKTREE,
|
||||
NULL, &success_count, &ret);
|
||||
|
||||
if (!opts->ignore_cmdline && git_config_from_parameters(fn, data) < 0)
|
||||
die(_("unable to parse command-line config"));
|
||||
|
|
@ -1609,6 +1628,10 @@ static int do_git_config_sequence(const struct config_options *opts,
|
|||
free(user_config);
|
||||
free(repo_config);
|
||||
free(worktree_config);
|
||||
|
||||
if (require_successful_config && !success_count && !ret)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1644,7 +1667,7 @@ int config_with_options(config_fn_t fn, void *data,
|
|||
ret = git_config_from_blob_ref(fn, repo, config_source->blob,
|
||||
data, config_source->scope);
|
||||
} else {
|
||||
ret = do_git_config_sequence(opts, repo, fn, data);
|
||||
ret = do_git_config_sequence(opts, repo, fn, data, 0);
|
||||
}
|
||||
|
||||
if (inc.remote_urls) {
|
||||
|
|
|
|||
|
|
@ -2457,6 +2457,18 @@ test_expect_success '--show-scope with --default' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'list with nonexistent global config gracefully exits' '
|
||||
rm -f "$HOME"/.gitconfig "$HOME"/.config/git/config &&
|
||||
git config ${mode_prefix}list &&
|
||||
git config ${mode_prefix}list --show-scope
|
||||
'
|
||||
|
||||
test_expect_success 'list --global with nonexistent global config fails' '
|
||||
rm -f "$HOME"/.gitconfig "$HOME"/.config/git/config &&
|
||||
test_must_fail git config ${mode_prefix}list --global &&
|
||||
test_must_fail git config ${mode_prefix}list --global --show-scope
|
||||
'
|
||||
|
||||
test_expect_success 'override global and system config' '
|
||||
test_when_finished rm -f \"\$HOME\"/.gitconfig &&
|
||||
cat >"$HOME"/.gitconfig <<-EOF &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue